All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v8 1/4] cfg80211: allow usermode to query wiphy specific regdom
@ 2014-12-03 16:08 Arik Nemtsov
  2014-12-03 16:08 ` [PATCH v8 2/4] cfg80211: allow wiphy specific regdomain management Arik Nemtsov
                   ` (3 more replies)
  0 siblings, 4 replies; 11+ messages in thread
From: Arik Nemtsov @ 2014-12-03 16:08 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg, Luis R. Rodriguez, Arik Nemtsov

If a wiphy-idx is specified, the kernel will return the wiphy specific
regdomain, if such exists. Otherwise return the global regdom.

When no wiphy-idx is specified, return the global regdomain as well as
all wiphy-specific regulatory domains in the system, via a new nested
list of attributes.

Add a new attribute for each wiphy-specific regdomain, for usermode to
identify it as such.

Signed-off-by: Arik Nemtsov <arikx.nemtsov@intel.com>
---
v8: remove bogus documentation from cfg80211.h

 include/uapi/linux/nl80211.h |   8 +-
 net/wireless/nl80211.c       | 178 +++++++++++++++++++++++++++++++++++--------
 net/wireless/reg.c           |   2 +-
 net/wireless/reg.h           |   1 +
 4 files changed, 154 insertions(+), 35 deletions(-)

diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index b37bd5a..62176a6 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -252,7 +252,13 @@
  *	%NL80211_ATTR_IFINDEX.
  *
  * @NL80211_CMD_GET_REG: ask the wireless core to send us its currently set
- * 	regulatory domain.
+ *	regulatory domain. If %NL80211_ATTR_WIPHY is specified and the device
+ *	has a private regulatory domain, it will be returned. Otherwise, the
+ *	global regdomain will be returned.
+ *	A device will have a private regulatory domain if it uses the
+ *	regulatory_hint() API. Even when a private regdomain is used the channel
+ *	information will still be mended according to further hints from
+ *	the regulatory core to help with compliance.
  * @NL80211_CMD_SET_REG: Set current regulatory domain. CRDA sends this command
  *	after being queried by the kernel. CRDA replies by sending a regulatory
  *	domain structure which consists of %NL80211_ATTR_REG_ALPHA set to our
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index a17d6bc..6736eae 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -5327,42 +5327,20 @@ static int nl80211_update_mesh_config(struct sk_buff *skb,
 	return err;
 }
 
-static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info)
+static int nl80211_put_regdom(const struct ieee80211_regdomain *regdom,
+			      struct sk_buff *msg)
 {
-	const struct ieee80211_regdomain *regdom;
-	struct sk_buff *msg;
-	void *hdr = NULL;
 	struct nlattr *nl_reg_rules;
 	unsigned int i;
 
-	if (!cfg80211_regdomain)
-		return -EINVAL;
-
-	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 (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();
-	regdom = rcu_dereference(cfg80211_regdomain);
-
 	if (nla_put_string(msg, NL80211_ATTR_REG_ALPHA2, regdom->alpha2) ||
 	    (regdom->dfs_region &&
 	     nla_put_u8(msg, NL80211_ATTR_DFS_REGION, regdom->dfs_region)))
-		goto nla_put_failure_rcu;
+		goto nla_put_failure;
 
 	nl_reg_rules = nla_nest_start(msg, NL80211_ATTR_REG_RULES);
 	if (!nl_reg_rules)
-		goto nla_put_failure_rcu;
+		goto nla_put_failure;
 
 	for (i = 0; i < regdom->n_reg_rules; i++) {
 		struct nlattr *nl_reg_rule;
@@ -5377,7 +5355,7 @@ static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info)
 
 		nl_reg_rule = nla_nest_start(msg, i);
 		if (!nl_reg_rule)
-			goto nla_put_failure_rcu;
+			goto nla_put_failure;
 
 		max_bandwidth_khz = freq_range->max_bandwidth_khz;
 		if (!max_bandwidth_khz)
@@ -5398,13 +5376,69 @@ static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info)
 				power_rule->max_eirp) ||
 		    nla_put_u32(msg, NL80211_ATTR_DFS_CAC_TIME,
 				reg_rule->dfs_cac_ms))
-			goto nla_put_failure_rcu;
+			goto nla_put_failure;
 
 		nla_nest_end(msg, nl_reg_rule);
 	}
-	rcu_read_unlock();
 
 	nla_nest_end(msg, nl_reg_rules);
+	return 0;
+
+nla_put_failure:
+	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]) {
+		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;
+		regdom = get_wiphy_regdom(wiphy);
+
+		if (regdom &&
+		    nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
+			goto nla_put_failure;
+	}
+
+	if (!regdom && !cfg80211_regdomain) {
+		nlmsg_free(msg);
+		return -EINVAL;
+	}
+
+	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);
@@ -5418,6 +5452,79 @@ put_failure:
 	return -EMSGSIZE;
 }
 
+static int nl80211_send_regdom(struct sk_buff *msg, struct netlink_callback *cb,
+			       u32 seq, int flags, struct wiphy *wiphy,
+			       const struct ieee80211_regdomain *regdom)
+{
+	void *hdr = nl80211hdr_put(msg, NETLINK_CB(cb->skb).portid, seq, flags,
+				   NL80211_CMD_GET_REG);
+
+	if (!hdr)
+		return -1;
+
+	genl_dump_check_consistent(cb, hdr, &nl80211_fam);
+
+	if (nl80211_put_regdom(regdom, msg))
+		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;
+
+	if (wiphy &&
+	    nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
+		goto nla_put_failure;
+
+	return genlmsg_end(msg, hdr);
+
+nla_put_failure:
+	genlmsg_cancel(msg, hdr);
+	return -EMSGSIZE;
+}
+
+static int nl80211_get_reg_dump(struct sk_buff *skb,
+				struct netlink_callback *cb)
+{
+	const struct ieee80211_regdomain *regdom = NULL;
+	struct cfg80211_registered_device *rdev;
+	int err, reg_idx, start = cb->args[2];
+
+	rtnl_lock();
+
+	if (cfg80211_regdomain && start == 0) {
+		err = nl80211_send_regdom(skb, cb, cb->nlh->nlmsg_seq,
+					  NLM_F_MULTI, NULL,
+					  rtnl_dereference(cfg80211_regdomain));
+		if (err < 0)
+			goto out_err;
+	}
+
+	/* the global regdom is idx 0 */
+	reg_idx = 1;
+	list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
+		regdom = get_wiphy_regdom(&rdev->wiphy);
+		if (!regdom)
+			continue;
+
+		if (++reg_idx <= start)
+			continue;
+
+		err = nl80211_send_regdom(skb, cb, cb->nlh->nlmsg_seq,
+					  NLM_F_MULTI, &rdev->wiphy, regdom);
+		if (err < 0) {
+			reg_idx--;
+			break;
+		}
+	}
+
+	cb->args[2] = reg_idx;
+	err = skb->len;
+out_err:
+	rtnl_unlock();
+	return err;
+}
+
 static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
 {
 	struct nlattr *tb[NL80211_REG_RULE_ATTR_MAX + 1];
@@ -10225,7 +10332,8 @@ static const struct genl_ops nl80211_ops[] = {
 	},
 	{
 		.cmd = NL80211_CMD_GET_REG,
-		.doit = nl80211_get_reg,
+		.doit = nl80211_get_reg_do,
+		.dumpit = nl80211_get_reg_dump,
 		.policy = nl80211_policy,
 		.internal_flags = NL80211_FLAG_NEED_RTNL,
 		/* can be retrieved by unprivileged users */
@@ -10983,9 +11091,13 @@ void nl80211_send_reg_change_event(struct regulatory_request *request)
 			goto nla_put_failure;
 	}
 
-	if (request->wiphy_idx != WIPHY_IDX_INVALID &&
-	    nla_put_u32(msg, NL80211_ATTR_WIPHY, request->wiphy_idx))
-		goto nla_put_failure;
+	if (request->wiphy_idx != WIPHY_IDX_INVALID) {
+		struct wiphy *wiphy = wiphy_idx_to_wiphy(request->wiphy_idx);
+
+		if (wiphy &&
+		    nla_put_u32(msg, NL80211_ATTR_WIPHY, request->wiphy_idx))
+			goto nla_put_failure;
+	}
 
 	genlmsg_end(msg, hdr);
 
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 47be616..48d90da 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -142,7 +142,7 @@ static const struct ieee80211_regdomain *get_cfg80211_regdom(void)
 	return rtnl_dereference(cfg80211_regdomain);
 }
 
-static const struct ieee80211_regdomain *get_wiphy_regdom(struct wiphy *wiphy)
+const struct ieee80211_regdomain *get_wiphy_regdom(struct wiphy *wiphy)
 {
 	return rtnl_dereference(wiphy->regd);
 }
diff --git a/net/wireless/reg.h b/net/wireless/reg.h
index 5e48031..4b45d6e 100644
--- a/net/wireless/reg.h
+++ b/net/wireless/reg.h
@@ -38,6 +38,7 @@ unsigned int reg_get_max_bandwidth(const struct ieee80211_regdomain *rd,
 				   const struct ieee80211_reg_rule *rule);
 
 bool reg_last_request_cell_base(void);
+const struct ieee80211_regdomain *get_wiphy_regdom(struct wiphy *wiphy);
 
 /**
  * regulatory_hint_found_beacon - hints a beacon was found on a channel
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v8 2/4] cfg80211: allow wiphy specific regdomain management
  2014-12-03 16:08 [PATCH v8 1/4] cfg80211: allow usermode to query wiphy specific regdom Arik Nemtsov
@ 2014-12-03 16:08 ` Arik Nemtsov
  2014-12-12 12:39   ` Johannes Berg
  2014-12-03 16:08 ` [PATCH v8 3/4] cfg80211: return private regdom for self-managed devices Arik Nemtsov
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 11+ messages in thread
From: Arik Nemtsov @ 2014-12-03 16:08 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg, Luis R. Rodriguez, Jonathan Doron

From: Jonathan Doron <jond@wizery.com>

Add a new regulatory flag that allows a driver to manage regdomain
changes/updates for its own wiphy.
A self-managed wiphys only employs regulatory information obtained from
the FW and driver and does not use other cfg80211 sources like
beacon-hints, country-code IEs and hints from other devices on the same
system. Conversely, a self-managed wiphy does not share its regulatory
hints with other devices in the system. If a system contains several
devices, one or more of which are self-managed, there might be
contradictory regulatory settings between them. Usage of flag is
generally discouraged. Only use it if the FW/driver is incompatible
with non-locally originated hints.

A new API lets the driver send a complete regdomain, to be applied on
its wiphy only.

After a wiphy-specific regdomain change takes place, usermode will get
a new type of change notification. The regulatory core also takes care
enforce regulatory restrictions, in case some interfaces are on
forbidden channels.

Signed-off-by: Jonathan Doron <jonathanx.doron@intel.com>
Signed-off-by: Arik Nemtsov <arikx.nemtsov@intel.com>
Reviewed-by: Luis R. Rodriguez <mcgrof@suse.com>
---
 include/net/cfg80211.h       | 14 +++++++
 include/net/regulatory.h     | 19 ++++++++++
 include/uapi/linux/nl80211.h |  6 +++
 net/wireless/core.c          |  8 ++++
 net/wireless/core.h          |  7 ++++
 net/wireless/nl80211.c       | 59 ++++++++++++++++++++---------
 net/wireless/nl80211.h       |  1 +
 net/wireless/reg.c           | 88 ++++++++++++++++++++++++++++++++++++++++++++
 8 files changed, 184 insertions(+), 18 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 4ebb816..4bc1fc9 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -3808,6 +3808,20 @@ const u8 *cfg80211_find_vendor_ie(unsigned int oui, u8 oui_type,
 int regulatory_hint(struct wiphy *wiphy, const char *alpha2);
 
 /**
+ * regulatory_set_wiphy_regd - set regdom info for self managed drivers
+ * @wiphy: the wireless device we want to process the regulatory domain on
+ * @rd: the regulatory domain informatoin to use for this wiphy
+ *
+ * Set the regulatory domain information for self-managed wiphys, only they
+ * may use this function. See %REGULATORY_WIPHY_SELF_MANAGED for more
+ * information.
+ *
+ * Return: 0 on success. -EINVAL, -EPERM
+ */
+int regulatory_set_wiphy_regd(struct wiphy *wiphy,
+			      struct ieee80211_regdomain *rd);
+
+/**
  * wiphy_apply_custom_regulatory - apply a custom driver regulatory domain
  * @wiphy: the wireless device we want to process the regulatory domain on
  * @regd: the custom regulatory domain to use for this wiphy
diff --git a/include/net/regulatory.h b/include/net/regulatory.h
index b776d72..ebc5a2e 100644
--- a/include/net/regulatory.h
+++ b/include/net/regulatory.h
@@ -147,6 +147,24 @@ struct regulatory_request {
  *	NL80211_IFTYPE_P2P_CLIENT, NL80211_IFTYPE_P2P_GO,
  *	NL80211_IFTYPE_P2P_DEVICE. The flag will be set by default if a device
  *	includes any modes unsupported for enforcement checking.
+ * @REGULATORY_WIPHY_SELF_MANAGED: for devices that employ wiphy-specific
+ *	regdom management. These devices will ignore all regdom changes not
+ *	originating from their own wiphy.
+ *	A self-managed wiphys only employs regulatory information obtained from
+ *	the FW and driver and does not use other cfg80211 sources like
+ *	beacon-hints, country-code IEs and hints from other devices on the same
+ *	system. Conversely, a self-managed wiphy does not share its regulatory
+ *	hints with other devices in the system. If a system contains several
+ *	devices, one or more of which are self-managed, there might be
+ *	contradictory regulatory settings between them. Usage of flag is
+ *	generally discouraged. Only use it if the FW/driver is incompatible
+ *	with non-locally originated hints.
+ *	This flag is incompatible with the flags: %REGULATORY_CUSTOM_REG,
+ *	%REGULATORY_STRICT_REG, %REGULATORY_COUNTRY_IE_FOLLOW_POWER,
+ *	%REGULATORY_COUNTRY_IE_IGNORE and %REGULATORY_DISABLE_BEACON_HINTS.
+ *	Mixing any of the above flags with this flag will result in a failure
+ *	to register the wiphy. This flag implies
+ *	%REGULATORY_DISABLE_BEACON_HINTS and %REGULATORY_COUNTRY_IE_IGNORE.
  */
 enum ieee80211_regulatory_flags {
 	REGULATORY_CUSTOM_REG			= BIT(0),
@@ -156,6 +174,7 @@ enum ieee80211_regulatory_flags {
 	REGULATORY_COUNTRY_IE_IGNORE		= BIT(4),
 	REGULATORY_ENABLE_RELAX_NO_IR           = BIT(5),
 	REGULATORY_IGNORE_STALE_KICKOFF         = BIT(6),
+	REGULATORY_WIPHY_SELF_MANAGED		= BIT(7),
 };
 
 struct ieee80211_freq_range {
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 62176a6..9ee06de 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -780,6 +780,10 @@
  *	peer given by %NL80211_ATTR_MAC. Both peers must be on the base channel
  *	when this command completes.
  *
+ * @NL80211_CMD_WIPHY_REG_CHANGE: Similar to %NL80211_CMD_REG_CHANGE, but used
+ *	as an event to indicate changes for devices with wiphy-specific regdom
+ *	management.
+ *
  * @NL80211_CMD_MAX: highest used command number
  * @__NL80211_CMD_AFTER_LAST: internal use
  */
@@ -964,6 +968,8 @@ enum nl80211_commands {
 	NL80211_CMD_TDLS_CHANNEL_SWITCH,
 	NL80211_CMD_TDLS_CANCEL_CHANNEL_SWITCH,
 
+	NL80211_CMD_WIPHY_REG_CHANGE,
+
 	/* add new commands above here */
 
 	/* used to define NL80211_CMD_MAX below */
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 53dda77..ec4e0e1 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -560,6 +560,14 @@ int wiphy_register(struct wiphy *wiphy)
 				       BIT(NL80211_IFTYPE_MONITOR)))
 		wiphy->regulatory_flags |= REGULATORY_IGNORE_STALE_KICKOFF;
 
+	if (WARN_ON((wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED) &&
+		    (wiphy->regulatory_flags &
+					(REGULATORY_CUSTOM_REG |
+					 REGULATORY_STRICT_REG |
+					 REGULATORY_COUNTRY_IE_FOLLOW_POWER |
+					 REGULATORY_COUNTRY_IE_IGNORE))))
+		return -EINVAL;
+
 	if (WARN_ON(wiphy->coalesce &&
 		    (!wiphy->coalesce->n_rules ||
 		     !wiphy->coalesce->n_patterns) &&
diff --git a/net/wireless/core.h b/net/wireless/core.h
index faa5b16..e87cae5 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -36,6 +36,13 @@ struct cfg80211_registered_device {
 	 * the country on the country IE changed. */
 	char country_ie_alpha2[2];
 
+	/*
+	 * the driver requests the regulatory core to set this regulatory
+	 * domain as the wiphy's. Only used for %REGULATORY_WIPHY_SELF_MANAGED
+	 * devices using the regulatory_set_wiphy_regd() API
+	 */
+	const struct ieee80211_regdomain *requested_regd;
+
 	/* If a Country IE has been received this tells us the environment
 	 * which its telling us its in. This defaults to ENVIRON_ANY */
 	enum environment_cap env;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 6736eae..de523aa 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -11047,25 +11047,9 @@ void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev,
 				NL80211_MCGRP_SCAN, GFP_KERNEL);
 }
 
-/*
- * This can happen on global regulatory changes or device specific settings
- * based on custom world regulatory domains.
- */
-void nl80211_send_reg_change_event(struct regulatory_request *request)
+static bool nl80211_reg_change_event_fill(struct sk_buff *msg,
+					  struct regulatory_request *request)
 {
-	struct sk_buff *msg;
-	void *hdr;
-
-	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
-	if (!msg)
-		return;
-
-	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_REG_CHANGE);
-	if (!hdr) {
-		nlmsg_free(msg);
-		return;
-	}
-
 	/* Userspace can always count this one always being set */
 	if (nla_put_u8(msg, NL80211_ATTR_REG_INITIATOR, request->initiator))
 		goto nla_put_failure;
@@ -11099,6 +11083,35 @@ void nl80211_send_reg_change_event(struct regulatory_request *request)
 			goto nla_put_failure;
 	}
 
+	return true;
+
+nla_put_failure:
+	return false;
+}
+
+/*
+ * This can happen on global regulatory changes or device specific settings
+ * based on custom regulatory domains.
+ */
+static void nl80211_common_reg_change_event(enum nl80211_commands cmd_id,
+					    struct regulatory_request *request)
+{
+	struct sk_buff *msg;
+	void *hdr;
+
+	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+	if (!msg)
+		return;
+
+	hdr = nl80211hdr_put(msg, 0, 0, 0, cmd_id);
+	if (!hdr) {
+		nlmsg_free(msg);
+		return;
+	}
+
+	if (nl80211_reg_change_event_fill(msg, request) == false)
+		goto nla_put_failure;
+
 	genlmsg_end(msg, hdr);
 
 	rcu_read_lock();
@@ -11113,6 +11126,16 @@ nla_put_failure:
 	nlmsg_free(msg);
 }
 
+void nl80211_send_reg_change_event(struct regulatory_request *request)
+{
+	nl80211_common_reg_change_event(NL80211_CMD_REG_CHANGE, request);
+}
+
+void nl80211_send_wiphy_reg_change_event(struct regulatory_request *request)
+{
+	nl80211_common_reg_change_event(NL80211_CMD_WIPHY_REG_CHANGE, request);
+}
+
 static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev,
 				    struct net_device *netdev,
 				    const u8 *buf, size_t len,
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index 7ad70d6..b91b9c5 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -18,6 +18,7 @@ void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev,
 void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev,
 				     struct net_device *netdev);
 void nl80211_send_reg_change_event(struct regulatory_request *request);
+void nl80211_send_wiphy_reg_change_event(struct regulatory_request *request);
 void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev,
 			  struct net_device *netdev,
 			  const u8 *buf, size_t len, gfp_t gfp);
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 48d90da..c3e6f80 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -1307,6 +1307,9 @@ static bool ignore_reg_update(struct wiphy *wiphy,
 {
 	struct regulatory_request *lr = get_last_request();
 
+	if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED)
+		return true;
+
 	if (!lr) {
 		REG_DBG_PRINT("Ignoring regulatory request set by %s "
 			      "since last_request is not set\n",
@@ -2147,11 +2150,52 @@ static void reg_process_pending_beacon_hints(void)
 	spin_unlock_bh(&reg_pending_beacons_lock);
 }
 
+static void reg_process_self_managed_hints(void)
+{
+	struct cfg80211_registered_device *rdev;
+	struct wiphy *wiphy;
+	const struct ieee80211_regdomain *tmp;
+	const struct ieee80211_regdomain *regd;
+	enum ieee80211_band band;
+	struct regulatory_request request = {};
+
+	list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
+		wiphy = &rdev->wiphy;
+
+		spin_lock(&reg_requests_lock);
+		regd = rdev->requested_regd;
+		rdev->requested_regd = NULL;
+		spin_unlock(&reg_requests_lock);
+
+		if (regd == NULL)
+			continue;
+
+		tmp = get_wiphy_regdom(wiphy);
+		rcu_assign_pointer(wiphy->regd, regd);
+		rcu_free_regdom(tmp);
+
+		for (band = 0; band < IEEE80211_NUM_BANDS; band++)
+			handle_band_custom(wiphy, wiphy->bands[band], regd);
+
+		reg_process_ht_flags(wiphy);
+
+		request.wiphy_idx = get_wiphy_idx(wiphy);
+		request.alpha2[0] = regd->alpha2[0];
+		request.alpha2[1] = regd->alpha2[1];
+		request.initiator = NL80211_REGDOM_SET_BY_DRIVER;
+
+		nl80211_send_wiphy_reg_change_event(&request);
+	}
+
+	reg_check_channels();
+}
+
 static void reg_todo(struct work_struct *work)
 {
 	rtnl_lock();
 	reg_process_pending_hints();
 	reg_process_pending_beacon_hints();
+	reg_process_self_managed_hints();
 	rtnl_unlock();
 }
 
@@ -2432,6 +2476,8 @@ static void restore_regulatory_settings(bool reset_user)
 	world_alpha2[1] = cfg80211_world_regdom->alpha2[1];
 
 	list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
+		if (rdev->wiphy.regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED)
+			continue;
 		if (rdev->wiphy.regulatory_flags & REGULATORY_CUSTOM_REG)
 			restore_custom_reg_settings(&rdev->wiphy);
 	}
@@ -2835,10 +2881,52 @@ int set_regdom(const struct ieee80211_regdomain *rd)
 	return 0;
 }
 
+int regulatory_set_wiphy_regd(struct wiphy *wiphy,
+			      struct ieee80211_regdomain *rd)
+{
+	const struct ieee80211_regdomain *regd;
+	const struct ieee80211_regdomain *prev_regd;
+	struct cfg80211_registered_device *rdev;
+
+	if (WARN_ON(!wiphy || !rd))
+		return -EINVAL;
+
+	if (WARN(!(wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED),
+		 "wiphy should have REGULATORY_WIPHY_SELF_MANAGED\n"))
+		return -EPERM;
+
+	if (WARN(!is_valid_rd(rd), "Invalid regulatory domain detected\n")) {
+		print_regdomain_info(rd);
+		return -EINVAL;
+	}
+
+	regd = reg_copy_regd(rd);
+	if (IS_ERR(regd))
+		return PTR_ERR(regd);
+
+	rdev = wiphy_to_rdev(wiphy);
+
+	spin_lock(&reg_requests_lock);
+	prev_regd = rdev->requested_regd;
+	rdev->requested_regd = regd;
+	spin_unlock(&reg_requests_lock);
+
+	kfree(prev_regd);
+
+	schedule_work(&reg_work);
+	return 0;
+}
+EXPORT_SYMBOL(regulatory_set_wiphy_regd);
+
 void wiphy_regulatory_register(struct wiphy *wiphy)
 {
 	struct regulatory_request *lr;
 
+	/* self-managed devices ignore external hints */
+	if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED)
+		wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS |
+					   REGULATORY_COUNTRY_IE_IGNORE;
+
 	if (!reg_dev_ignore_cell_hint(wiphy))
 		reg_num_devs_support_basehint++;
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v8 3/4] cfg80211: return private regdom for self-managed devices
  2014-12-03 16:08 [PATCH v8 1/4] cfg80211: allow usermode to query wiphy specific regdom Arik Nemtsov
  2014-12-03 16:08 ` [PATCH v8 2/4] cfg80211: allow wiphy specific regdomain management Arik Nemtsov
@ 2014-12-03 16:08 ` Arik Nemtsov
  2014-12-03 16:08 ` [PATCH v8 4/4] cfg80211: correctly check ad-hoc channels Arik Nemtsov
  2014-12-12 12:37 ` [PATCH v8 1/4] cfg80211: allow usermode to query wiphy specific regdom Johannes Berg
  3 siblings, 0 replies; 11+ messages in thread
From: Arik Nemtsov @ 2014-12-03 16:08 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg, Luis R. Rodriguez, Arik Nemtsov

If a device has self-managed regulatory, insist on returning the wiphy
specific regdomain if a wiphy-idx is specified. The global regdomain is
meaningless for such devices.

Also add an attribute for self-managed devices, so usermode can
distinguish them as such.

Signed-off-by: Arik Nemtsov <arikx.nemtsov@intel.com>
Reviewed-by: Luis R. Rodriguez <mcgrof@suse.com>
---
v8: no need to add more splits to the wiphy info

 include/uapi/linux/nl80211.h | 10 ++++++++++
 net/wireless/nl80211.c       | 24 ++++++++++++++++++++++++
 2 files changed, 34 insertions(+)

diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 9ee06de..5a13958 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -259,6 +259,9 @@
  *	regulatory_hint() API. Even when a private regdomain is used the channel
  *	information will still be mended according to further hints from
  *	the regulatory core to help with compliance.
+ *	If a wiphy is self-managed (%NL80211_ATTR_WIPHY_SELF_MANAGED_REG), then
+ *	its private regdomain is the only valid one for it. The regulatory
+ *	core is not used to help with compliance in this case.
  * @NL80211_CMD_SET_REG: Set current regulatory domain. CRDA sends this command
  *	after being queried by the kernel. CRDA replies by sending a regulatory
  *	domain structure which consists of %NL80211_ATTR_REG_ALPHA set to our
@@ -1700,6 +1703,11 @@ enum nl80211_commands {
  *
  * @NL80211_ATTR_MAC_MASK: MAC address mask
  *
+ * @NL80211_ATTR_WIPHY_SELF_MANAGED_REG: flag attribute indicating this device
+ *	is self-managing its regulatory information and any regulatory domain
+ *	obtained from it is coming from the device's wiphy and not the global
+ *	cfg80211 regdomain.
+ *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -2057,6 +2065,8 @@ enum nl80211_attrs {
 
 	NL80211_ATTR_MAC_MASK,
 
+	NL80211_ATTR_WIPHY_SELF_MANAGED_REG,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index de523aa..cd85a9f 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -396,6 +396,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
 	[NL80211_ATTR_ADMITTED_TIME] = { .type = NLA_U16 },
 	[NL80211_ATTR_SMPS_MODE] = { .type = NLA_U8 },
 	[NL80211_ATTR_MAC_MASK] = { .len = ETH_ALEN },
+	[NL80211_ATTR_WIPHY_SELF_MANAGED_REG] = { .type = NLA_FLAG },
 };
 
 /* policy for the key attributes */
@@ -1701,6 +1702,10 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
 			       rdev->wiphy.max_num_csa_counters))
 			goto nla_put_failure;
 
+		if (rdev->wiphy.regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
+		    nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
+			goto nla_put_failure;
+
 		/* done */
 		state->split_start = 0;
 		break;
@@ -5406,6 +5411,8 @@ static int nl80211_get_reg_do(struct sk_buff *skb, struct genl_info *info)
 		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);
@@ -5413,8 +5420,16 @@ static int nl80211_get_reg_do(struct sk_buff *skb, struct genl_info *info)
 		}
 
 		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;
@@ -5476,6 +5491,10 @@ static int nl80211_send_regdom(struct sk_buff *msg, struct netlink_callback *cb,
 	    nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
 		goto nla_put_failure;
 
+	if (wiphy && wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
+	    nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
+		goto nla_put_failure;
+
 	return genlmsg_end(msg, hdr);
 
 nla_put_failure:
@@ -11081,6 +11100,11 @@ static bool nl80211_reg_change_event_fill(struct sk_buff *msg,
 		if (wiphy &&
 		    nla_put_u32(msg, NL80211_ATTR_WIPHY, request->wiphy_idx))
 			goto nla_put_failure;
+
+		if (wiphy &&
+		    wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
+		    nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
+			goto nla_put_failure;
 	}
 
 	return true;
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v8 4/4] cfg80211: correctly check ad-hoc channels
  2014-12-03 16:08 [PATCH v8 1/4] cfg80211: allow usermode to query wiphy specific regdom Arik Nemtsov
  2014-12-03 16:08 ` [PATCH v8 2/4] cfg80211: allow wiphy specific regdomain management Arik Nemtsov
  2014-12-03 16:08 ` [PATCH v8 3/4] cfg80211: return private regdom for self-managed devices Arik Nemtsov
@ 2014-12-03 16:08 ` Arik Nemtsov
  2014-12-12 12:40   ` Johannes Berg
  2014-12-12 12:37 ` [PATCH v8 1/4] cfg80211: allow usermode to query wiphy specific regdom Johannes Berg
  3 siblings, 1 reply; 11+ messages in thread
From: Arik Nemtsov @ 2014-12-03 16:08 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg, Luis R. Rodriguez, Arik Nemtsov

Ad-hoc requires beaconing for regulatory purposes. Validate that the
channel is valid for beaconing, and not only enabled.

Signed-off-by: Arik Nemtsov <arikx.nemtsov@intel.com>
Reviewed-by: Luis R. Rodriguez <mcgrof@suse.com>
---
 net/wireless/reg.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index c3e6f80..004ea14 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -1552,9 +1552,15 @@ static bool reg_wdev_chan_valid(struct wiphy *wiphy, struct wireless_dev *wdev)
 		ret = cfg80211_reg_can_beacon(wiphy,
 					      &wdev->chandef, wdev->iftype);
 		break;
+	case NL80211_IFTYPE_ADHOC:
+		if (!wdev->ssid_len)
+			goto out;
+
+		ret = cfg80211_reg_can_beacon(wiphy,
+					      &wdev->chandef, wdev->iftype);
+		break;
 	case NL80211_IFTYPE_STATION:
 	case NL80211_IFTYPE_P2P_CLIENT:
-	case NL80211_IFTYPE_ADHOC:
 		if (!wdev->current_bss ||
 		    !wdev->current_bss->pub.channel)
 			goto out;
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH v8 1/4] cfg80211: allow usermode to query wiphy specific regdom
  2014-12-03 16:08 [PATCH v8 1/4] cfg80211: allow usermode to query wiphy specific regdom Arik Nemtsov
                   ` (2 preceding siblings ...)
  2014-12-03 16:08 ` [PATCH v8 4/4] cfg80211: correctly check ad-hoc channels Arik Nemtsov
@ 2014-12-12 12:37 ` Johannes Berg
  2014-12-15 17:07   ` Arik Nemtsov
  3 siblings, 1 reply; 11+ messages in thread
From: Johannes Berg @ 2014-12-12 12:37 UTC (permalink / raw)
  To: Arik Nemtsov; +Cc: linux-wireless, Luis R. Rodriguez

On Wed, 2014-12-03 at 18:08 +0200, Arik Nemtsov wrote:

>   * @NL80211_CMD_GET_REG: ask the wireless core to send us its currently set
> - * 	regulatory domain.
> + *	regulatory domain. If %NL80211_ATTR_WIPHY is specified and the device
> + *	has a private regulatory domain, it will be returned. Otherwise, the
> + *	global regdomain will be returned.
> + *	A device will have a private regulatory domain if it uses the
> + *	regulatory_hint() API. Even when a private regdomain is used the channel
> + *	information will still be mended according to further hints from
> + *	the regulatory core to help with compliance.

I think you need to document the new availability of the dump version of
this now.

> +	if (!regdom && !cfg80211_regdomain) {

I'm not sure why sparse doesn't warn here, but I think that should
probably use rcu_access_pointer(cfg80211_regdomain).

More realistically, the regdomain can never be NULL I think, so is that
even needed? OTOH, if it can be NULL, then you must make this check
after the rcu_dereference, which would make this code easier to follow.

> +		nlmsg_free(msg);
> +		return -EINVAL;
> +	}
> +
> +	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);

i.e. move the check into this if here

johannes


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v8 2/4] cfg80211: allow wiphy specific regdomain management
  2014-12-03 16:08 ` [PATCH v8 2/4] cfg80211: allow wiphy specific regdomain management Arik Nemtsov
@ 2014-12-12 12:39   ` Johannes Berg
  2014-12-15 17:12     ` Arik Nemtsov
  0 siblings, 1 reply; 11+ messages in thread
From: Johannes Berg @ 2014-12-12 12:39 UTC (permalink / raw)
  To: Arik Nemtsov; +Cc: linux-wireless, Luis R. Rodriguez, Jonathan Doron

On Wed, 2014-12-03 at 18:08 +0200, Arik Nemtsov wrote:

> +void nl80211_send_reg_change_event(struct regulatory_request *request)
> +{
> +	nl80211_common_reg_change_event(NL80211_CMD_REG_CHANGE, request);
> +}
> +
> +void nl80211_send_wiphy_reg_change_event(struct regulatory_request *request)
> +{
> +	nl80211_common_reg_change_event(NL80211_CMD_WIPHY_REG_CHANGE, request);
> +}

These are trivial wrappers, I'd make them inlines.

johannes


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v8 4/4] cfg80211: correctly check ad-hoc channels
  2014-12-03 16:08 ` [PATCH v8 4/4] cfg80211: correctly check ad-hoc channels Arik Nemtsov
@ 2014-12-12 12:40   ` Johannes Berg
  0 siblings, 0 replies; 11+ messages in thread
From: Johannes Berg @ 2014-12-12 12:40 UTC (permalink / raw)
  To: Arik Nemtsov; +Cc: linux-wireless, Luis R. Rodriguez

On Wed, 2014-12-03 at 18:08 +0200, Arik Nemtsov wrote:
> Ad-hoc requires beaconing for regulatory purposes. Validate that the
> channel is valid for beaconing, and not only enabled.

Applied.

johannes


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v8 1/4] cfg80211: allow usermode to query wiphy specific regdom
  2014-12-12 12:37 ` [PATCH v8 1/4] cfg80211: allow usermode to query wiphy specific regdom Johannes Berg
@ 2014-12-15 17:07   ` Arik Nemtsov
  0 siblings, 0 replies; 11+ messages in thread
From: Arik Nemtsov @ 2014-12-15 17:07 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, Luis R. Rodriguez

On Fri, Dec 12, 2014 at 2:37 PM, Johannes Berg
<johannes@sipsolutions.net> wrote:
> On Wed, 2014-12-03 at 18:08 +0200, Arik Nemtsov wrote:
>
>>   * @NL80211_CMD_GET_REG: ask the wireless core to send us its currently set
>> - *   regulatory domain.
>> + *   regulatory domain. If %NL80211_ATTR_WIPHY is specified and the device
>> + *   has a private regulatory domain, it will be returned. Otherwise, the
>> + *   global regdomain will be returned.
>> + *   A device will have a private regulatory domain if it uses the
>> + *   regulatory_hint() API. Even when a private regdomain is used the channel
>> + *   information will still be mended according to further hints from
>> + *   the regulatory core to help with compliance.
>
> I think you need to document the new availability of the dump version of
> this now.

Sure.

>
>> +     if (!regdom && !cfg80211_regdomain) {
>
> I'm not sure why sparse doesn't warn here, but I think that should
> probably use rcu_access_pointer(cfg80211_regdomain).
>
> More realistically, the regdomain can never be NULL I think, so is that
> even needed? OTOH, if it can be NULL, then you must make this check
> after the rcu_dereference, which would make this code easier to follow.

You're right. I'll remove the check. I don't see a way where it can be
set to NULL at any point.

Arik

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v8 2/4] cfg80211: allow wiphy specific regdomain management
  2014-12-12 12:39   ` Johannes Berg
@ 2014-12-15 17:12     ` Arik Nemtsov
  2014-12-15 18:41       ` Johannes Berg
  0 siblings, 1 reply; 11+ messages in thread
From: Arik Nemtsov @ 2014-12-15 17:12 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, Luis R. Rodriguez, Jonathan Doron

On Fri, Dec 12, 2014 at 2:39 PM, Johannes Berg
<johannes@sipsolutions.net> wrote:
> On Wed, 2014-12-03 at 18:08 +0200, Arik Nemtsov wrote:
>
>> +void nl80211_send_reg_change_event(struct regulatory_request *request)
>> +{
>> +     nl80211_common_reg_change_event(NL80211_CMD_REG_CHANGE, request);
>> +}
>> +
>> +void nl80211_send_wiphy_reg_change_event(struct regulatory_request *request)
>> +{
>> +     nl80211_common_reg_change_event(NL80211_CMD_WIPHY_REG_CHANGE, request);
>> +}
>
> These are trivial wrappers, I'd make them inlines.

You mean inline here or in the header header? I'll do it here..

Arik

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v8 2/4] cfg80211: allow wiphy specific regdomain management
  2014-12-15 17:12     ` Arik Nemtsov
@ 2014-12-15 18:41       ` Johannes Berg
  2014-12-15 19:28         ` Arik Nemtsov
  0 siblings, 1 reply; 11+ messages in thread
From: Johannes Berg @ 2014-12-15 18:41 UTC (permalink / raw)
  To: Arik Nemtsov; +Cc: linux-wireless, Luis R. Rodriguez, Jonathan Doron

On Mon, 2014-12-15 at 19:12 +0200, Arik Nemtsov wrote:
> On Fri, Dec 12, 2014 at 2:39 PM, Johannes Berg
> <johannes@sipsolutions.net> wrote:
> > On Wed, 2014-12-03 at 18:08 +0200, Arik Nemtsov wrote:
> >
> >> +void nl80211_send_reg_change_event(struct regulatory_request *request)
> >> +{
> >> +     nl80211_common_reg_change_event(NL80211_CMD_REG_CHANGE, request);
> >> +}
> >> +
> >> +void nl80211_send_wiphy_reg_change_event(struct regulatory_request *request)
> >> +{
> >> +     nl80211_common_reg_change_event(NL80211_CMD_WIPHY_REG_CHANGE, request);
> >> +}
> >
> > These are trivial wrappers, I'd make them inlines.
> 
> You mean inline here or in the header header? I'll do it here..

Inline here makes no sense since it's declared in the header - it'd have
to be in the header.

johannes


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v8 2/4] cfg80211: allow wiphy specific regdomain management
  2014-12-15 18:41       ` Johannes Berg
@ 2014-12-15 19:28         ` Arik Nemtsov
  0 siblings, 0 replies; 11+ messages in thread
From: Arik Nemtsov @ 2014-12-15 19:28 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, Luis R. Rodriguez, Jonathan Doron

On Mon, Dec 15, 2014 at 8:41 PM, Johannes Berg
<johannes@sipsolutions.net> wrote:
> On Mon, 2014-12-15 at 19:12 +0200, Arik Nemtsov wrote:
>> On Fri, Dec 12, 2014 at 2:39 PM, Johannes Berg
>> <johannes@sipsolutions.net> wrote:
>> > On Wed, 2014-12-03 at 18:08 +0200, Arik Nemtsov wrote:
>> >
>> >> +void nl80211_send_reg_change_event(struct regulatory_request *request)
>> >> +{
>> >> +     nl80211_common_reg_change_event(NL80211_CMD_REG_CHANGE, request);
>> >> +}
>> >> +
>> >> +void nl80211_send_wiphy_reg_change_event(struct regulatory_request *request)
>> >> +{
>> >> +     nl80211_common_reg_change_event(NL80211_CMD_WIPHY_REG_CHANGE, request);
>> >> +}
>> >
>> > These are trivial wrappers, I'd make them inlines.
>>
>> You mean inline here or in the header header? I'll do it here..
>
> Inline here makes no sense since it's declared in the header - it'd have
> to be in the header.

Yea, that's where I put it in v10.

Arik

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2014-12-15 19:28 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-12-03 16:08 [PATCH v8 1/4] cfg80211: allow usermode to query wiphy specific regdom Arik Nemtsov
2014-12-03 16:08 ` [PATCH v8 2/4] cfg80211: allow wiphy specific regdomain management Arik Nemtsov
2014-12-12 12:39   ` Johannes Berg
2014-12-15 17:12     ` Arik Nemtsov
2014-12-15 18:41       ` Johannes Berg
2014-12-15 19:28         ` Arik Nemtsov
2014-12-03 16:08 ` [PATCH v8 3/4] cfg80211: return private regdom for self-managed devices Arik Nemtsov
2014-12-03 16:08 ` [PATCH v8 4/4] cfg80211: correctly check ad-hoc channels Arik Nemtsov
2014-12-12 12:40   ` Johannes Berg
2014-12-12 12:37 ` [PATCH v8 1/4] cfg80211: allow usermode to query wiphy specific regdom Johannes Berg
2014-12-15 17:07   ` Arik Nemtsov

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.