static int nl80211_get_reg_do(struct sk_buff *skb, struct genl_info *info)
{
	const struct ieee80211_regdomain *regdom = NULL;
	struct cfg80211_registered_device *rdev;
	struct wiphy *wiphy = NULL;
	struct sk_buff *msg;
	void *hdr;

	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
	if (!msg)
		return -ENOBUFS;

	hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
			     NL80211_CMD_GET_REG);
	if (!hdr)
		goto put_failure;

	if (info->attrs[NL80211_ATTR_WIPHY]) {
		bool self_managed;

		rdev = cfg80211_get_dev_from_info(genl_info_net(info), info);
		if (IS_ERR(rdev)) {
			nlmsg_free(msg);
			return PTR_ERR(rdev);
		}

		wiphy = &rdev->wiphy;
		self_managed = wiphy->regulatory_flags &
			       REGULATORY_WIPHY_SELF_MANAGED;
		regdom = get_wiphy_regdom(wiphy);

		/* a self-managed-reg device must have a private regdom */
		if (WARN_ON(!regdom && self_managed)) {
			nlmsg_free(msg);
			return -EINVAL;
		}

		if (regdom &&
		    nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
			goto nla_put_failure;
	}

	if (!wiphy && reg_last_request_cell_base() &&
	    nla_put_u32(msg, NL80211_ATTR_USER_REG_HINT_TYPE,
			NL80211_USER_REG_HINT_CELL_BASE))
		goto nla_put_failure;

	rcu_read_lock();

	if (!regdom)
		regdom = rcu_dereference(cfg80211_regdomain);

	if (nl80211_put_regdom(regdom, msg))
		goto nla_put_failure_rcu;

	rcu_read_unlock();

	genlmsg_end(msg, hdr);
	return genlmsg_reply(msg, info);

nla_put_failure_rcu:
	rcu_read_unlock();
nla_put_failure:
put_failure:
	nlmsg_free(msg);
	return -EMSGSIZE;
}
static int nl80211_get_reg_do(struct sk_buff *skb, struct genl_info *info)
{
	const struct ieee80211_regdomain *regdom = NULL;
	struct cfg80211_registered_device *rdev;
	struct wiphy *wiphy = NULL;
	struct sk_buff *msg;
	void *hdr;

	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
	if (!msg)
		return -ENOBUFS;

	hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
			     NL80211_CMD_GET_REG);
	if (!hdr)
		goto put_failure;

	if (info->attrs[NL80211_ATTR_WIPHY]) {
		bool self_managed;

		rdev = cfg80211_get_dev_from_info(genl_info_net(info), info);
		if (IS_ERR(rdev)) {
			nlmsg_free(msg);
			return PTR_ERR(rdev);
		}

		wiphy = &rdev->wiphy;
		self_managed = wiphy->regulatory_flags &
			       REGULATORY_WIPHY_SELF_MANAGED;
		regdom = get_wiphy_regdom(wiphy);

		 
		if (WARN_ON(!regdom && self_managed)) {
			nlmsg_free(msg);
			return -EINVAL;
		}

		if (regdom &&
		    nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
			goto nla_put_failure;
	}

	if (!wiphy && reg_last_request_cell_base() &&
	    nla_put_u32(msg, NL80211_ATTR_USER_REG_HINT_TYPE,
			NL80211_USER_REG_HINT_CELL_BASE))
		goto nla_put_failure;

	rcu_read_lock();

	if (!regdom)
		regdom = rcu_dereference(cfg80211_regdomain);

	if (nl80211_put_regdom(regdom, msg))
		goto nla_put_failure_rcu;

	rcu_read_unlock();

	genlmsg_end(msg, hdr);
	return genlmsg_reply(msg, info);

nla_put_failure_rcu:
	rcu_read_unlock();
nla_put_failure:
put_failure:
	nlmsg_free(msg);
	return -EMSGSIZE;
}