Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH 3/3 v3] mac80211: Send mesh non-HWMP path selection frames to userspace
From: Javier Cardona @ 2010-12-17  1:37 UTC (permalink / raw)
  To: John W. Linville
  Cc: Javier Cardona, Steve Derosier, devel, Johannes Berg,
	linux-wireless
In-Reply-To: <1292525513.3612.26.camel@jlt3.sipsolutions.net>

Let path selection frames for protocols other than HWMP be sent to
userspace via NL80211_CMD_REGISTER_FRAME.  Also allow userspace to send
and receive mesh path selection frames.

Signed-off-by: Javier Cardona <javier@cozybit.com>
---
v2: - update patch description (Johannes)
    - remove mesh_ids_set_default and initialize ids in start_mesh (Johannes)
    - more elegant check for mesh_path_sel_is_hwmp (Johannes)
v3: - no change, just rebased

 net/mac80211/cfg.c     |    1 +
 net/mac80211/main.c    |    4 ++++
 net/mac80211/mesh.c    |   13 +++----------
 net/mac80211/mesh.h    |    7 +++++++
 net/mac80211/rx.c      |    5 ++++-
 net/wireless/nl80211.c |    2 ++
 6 files changed, 21 insertions(+), 11 deletions(-)

diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index ae2c712..5892b03 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1670,6 +1670,7 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
 	case NL80211_IFTYPE_AP:
 	case NL80211_IFTYPE_AP_VLAN:
 	case NL80211_IFTYPE_P2P_GO:
+	case NL80211_IFTYPE_MESH_POINT:
 		if (!ieee80211_is_action(mgmt->frame_control) ||
 		    mgmt->u.action.category == WLAN_CATEGORY_PUBLIC)
 			break;
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index a9454cb..bbe8e0a 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -484,6 +484,10 @@ ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
 			BIT(IEEE80211_STYPE_DEAUTH >> 4) |
 			BIT(IEEE80211_STYPE_ACTION >> 4),
 	},
+	[NL80211_IFTYPE_MESH_POINT] = {
+		.tx = 0xffff,
+		.rx = BIT(IEEE80211_STYPE_ACTION >> 4),
+	},
 };
 
 struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index c326e00..8b5906c 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -124,15 +124,6 @@ void mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata)
 		ieee80211_mesh_housekeeping_timer((unsigned long) sdata);
 }
 
-void mesh_ids_set_default(struct ieee80211_if_mesh *sta)
-{
-	sta->mesh_pp_id = 0;	/* HWMP */
-	sta->mesh_pm_id = 0;	/* Airtime */
-	sta->mesh_cc_id = 0;	/* Disabled */
-	sta->mesh_sp_id = 0;	/* Neighbor Offset */
-	sta->mesh_auth_id = 0;	/* Disabled */
-}
-
 int mesh_rmc_init(struct ieee80211_sub_if_data *sdata)
 {
 	int i;
@@ -525,6 +516,9 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
 	atomic_inc(&local->iff_allmultis);
 	ieee80211_configure_filter(local);
 
+	ifmsh->mesh_cc_id = 0;	/* Disabled */
+	ifmsh->mesh_sp_id = 0;	/* Neighbor Offset */
+	ifmsh->mesh_auth_id = 0;	/* Disabled */
 	set_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags);
 	ieee80211_mesh_root_setup(ifmsh);
 	ieee80211_queue_work(&local->hw, &sdata->work);
@@ -695,7 +689,6 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
 	/* Allocate all mesh structures when creating the first mesh interface. */
 	if (!mesh_allocated)
 		ieee80211s_init();
-	mesh_ids_set_default(ifmsh);
 	setup_timer(&ifmsh->mesh_path_timer,
 		    ieee80211_mesh_path_timer,
 		    (unsigned long) sdata);
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 5b828fa..890dd19 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -284,6 +284,11 @@ static inline void mesh_path_activate(struct mesh_path *mpath)
 	mpath->flags |= MESH_PATH_ACTIVE | MESH_PATH_RESOLVED;
 }
 
+static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata)
+{
+	return sdata->u.mesh.mesh_pp_id == IEEE80211_PATH_PROTOCOL_HWMP;
+}
+
 #define for_each_mesh_entry(x, p, node, i) \
 	for (i = 0; i <= x->hash_mask; i++) \
 		hlist_for_each_entry_rcu(node, p, &x->hash_buckets[i], list)
@@ -304,6 +309,8 @@ static inline void ieee80211_mesh_restart(struct ieee80211_sub_if_data *sdata)
 {}
 static inline void mesh_plink_quiesce(struct sta_info *sta) {}
 static inline void mesh_plink_restart(struct sta_info *sta) {}
+static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata)
+{ return false; }
 #endif
 
 #endif /* IEEE80211S_H */
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index f39524b..cdbc824 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2143,10 +2143,13 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
 		}
 		break;
 	case WLAN_CATEGORY_MESH_PLINK:
-	case WLAN_CATEGORY_MESH_PATH_SEL:
 		if (!ieee80211_vif_is_mesh(&sdata->vif))
 			break;
 		goto queue;
+	case WLAN_CATEGORY_MESH_PATH_SEL:
+		if (!mesh_path_sel_is_hwmp(sdata))
+			break;
+		goto queue;
 	}
 
 	return RX_CONTINUE;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 356c33e..177ea21 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -4445,6 +4445,7 @@ static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info)
 	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT &&
 	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
 	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
+	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
 	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
 		return -EOPNOTSUPP;
 
@@ -4485,6 +4486,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
 	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT &&
 	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
 	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
+	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
 	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
 		return -EOPNOTSUPP;
 
-- 
1.7.1


^ permalink raw reply related

* [PATCH 2/3 v3] mac80211: Let userspace enable and configure vendor specific path selection.
From: Javier Cardona @ 2010-12-17  1:37 UTC (permalink / raw)
  To: John W. Linville
  Cc: Javier Cardona, Steve Derosier, devel, Johannes Berg,
	linux-wireless
In-Reply-To: <1292525513.3612.26.camel@jlt3.sipsolutions.net>

Userspace will now be allowed to toggle between the default path
selection algorithm (HWMP, implemented in the kernel), and a vendor
specific alternative.  Also in the same patch, allow userspace to add
information elements to mesh beacons.  This is accordance with the
Extensible Path Selection Framework specified in version 7.0 of the
802.11s draft.

Signed-off-by: Javier Cardona <javier@cozybit.com>
---
v2: - don't substruct vendor_ie and mark as const (Johannes)
    - move vendor_ie to mesh_setup (Johannes)
    - rename MESH_PATH_* -> IEEE80211_PATH_* (Johannes)
    - define a new nested attribute NL80211_ATTR_MESH_SETUP for mesh setup
      parameters
v3: - use kmemdup (Johannes)
    - take vendor_ie size into account when allocating skbuf (Johannes)
    - check vendor_ie has a valid format (Johannes)
    - fix erroneous old_ie assignment introduced in v2

 include/linux/ieee80211.h  |   25 +++++++++++++++++
 include/linux/nl80211.h    |   47 ++++++++++++++++++++++++++++++---
 include/net/cfg80211.h     |    8 +++++
 net/mac80211/cfg.c         |   39 ++++++++++++++++++++++++---
 net/mac80211/ieee80211_i.h |    2 +
 net/mac80211/mesh.c        |    7 +++++
 net/mac80211/mesh_plink.c  |    3 +-
 net/mac80211/tx.c          |    3 +-
 net/wireless/core.c        |   22 +++++++++++----
 net/wireless/core.h        |    5 ++-
 net/wireless/mesh.c        |   24 +++++++++-------
 net/wireless/nl80211.c     |   63 ++++++++++++++++++++++++++++++++++++++++---
 12 files changed, 214 insertions(+), 34 deletions(-)

diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 7f23545..cd68168 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -1291,6 +1291,31 @@ enum ieee80211_key_len {
 	WLAN_KEY_LEN_AES_CMAC = 16,
 };
 
+/**
+ * enum - mesh path selection protocol identifier
+ *
+ * @IEEE80211_PATH_PROTOCOL_HWMP: the default path selection protocol
+ * @IEEE80211_PATH_PROTOCOL_VENDOR: a vendor specific protocol that will
+ * be specified in a vendor specific information element
+ */
+enum {
+	IEEE80211_PATH_PROTOCOL_HWMP = 0,
+	IEEE80211_PATH_PROTOCOL_VENDOR = 255,
+};
+
+/**
+ * enum - mesh path selection metric identifier
+ *
+ * @IEEE80211_PATH_METRIC_AIRTIME: the default path selection metric
+ * @IEEE80211_PATH_METRIC_VENDOR: a vendor specific metric that will be
+ * specified in a vendor specific information element
+ */
+enum {
+	IEEE80211_PATH_METRIC_AIRTIME = 0,
+	IEEE80211_PATH_METRIC_VENDOR = 255,
+};
+
+
 /*
  * IEEE 802.11-2007 7.3.2.9 Country information element
  *
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index d626ad2..3493410 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -862,6 +862,9 @@ enum nl80211_commands {
  *	attributes, specifying what a key should be set as default as.
  *	See &enum nl80211_key_default_types.
  *
+ * @NL80211_ATTR_MESH_SETUP: Optional mesh setup parameters.  These cannot be
+ * changed once the mesh is active.
+ *
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
  */
@@ -1044,6 +1047,8 @@ enum nl80211_attrs {
 
 	NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION,
 
+	NL80211_ATTR_MESH_SETUP,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
@@ -1554,7 +1559,8 @@ enum nl80211_mntr_flags {
 /**
  * enum nl80211_meshconf_params - mesh configuration parameters
  *
- * Mesh configuration parameters
+ * Mesh configuration parameters. These can be changed while the mesh is
+ * active.
  *
  * @__NL80211_MESHCONF_INVALID: internal use
  *
@@ -1577,9 +1583,6 @@ enum nl80211_mntr_flags {
  * @NL80211_MESHCONF_TTL: specifies the value of TTL field set at a source mesh
  * point.
  *
- * @NL80211_MESHCONF_ELEMENT_TTL: specifies the value of TTL field set at a
- * source mesh point for path selection elements.
- *
  * @NL80211_MESHCONF_AUTO_OPEN_PLINKS: whether we should automatically
  * open peer links when we detect compatible mesh peers.
  *
@@ -1606,6 +1609,9 @@ enum nl80211_mntr_flags {
  *
  * @NL80211_MESHCONF_ROOTMODE: whether root mode is enabled or not
  *
+ * @NL80211_MESHCONF_ELEMENT_TTL: specifies the value of TTL field set at a
+ * source mesh point for path selection elements.
+ *
  * @NL80211_MESHCONF_ATTR_MAX: highest possible mesh configuration attribute
  *
  * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use
@@ -1634,6 +1640,39 @@ enum nl80211_meshconf_params {
 };
 
 /**
+ * enum nl80211_mesh_setup_params - mesh setup parameters
+ *
+ * Mesh setup parameters.  These are used to start/join a mesh and cannot be
+ * changed while the mesh is active.
+ *
+ * @__NL80211_MESH_SETUP_INVALID: Internal use
+ *
+ * @NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL: Enable this option to use a
+ * vendor specific path selection algorithm or disable it to use the default
+ * HWMP.
+ *
+ * @NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC: Enable this option to use a
+ * vendor specific path metric or disable it to use the default Airtime
+ * metric.
+ *
+ * @NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE: A vendor specific information
+ * element that vendors will use to identify the path selection methods and
+ * metrics in use.
+ *
+ * @__NL80211_MESH_SETUP_ATTR_AFTER_LAST: Internal use
+ */
+enum nl80211_mesh_setup_params {
+	__NL80211_MESH_SETUP_INVALID,
+	NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL,
+	NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC,
+	NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE,
+
+	/* keep last */
+	__NL80211_MESH_SETUP_ATTR_AFTER_LAST,
+	NL80211_MESH_SETUP_ATTR_MAX = __NL80211_MESH_SETUP_ATTR_AFTER_LAST - 1
+};
+
+/**
  * enum nl80211_txq_attr - TX queue parameter attributes
  * @__NL80211_TXQ_ATTR_INVALID: Attribute number 0 is reserved
  * @NL80211_TXQ_ATTR_QUEUE: TX queue identifier (NL80211_TXQ_Q_*)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 1bac74a..a6041a7 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -649,12 +649,20 @@ struct mesh_config {
  * struct mesh_setup - 802.11s mesh setup configuration
  * @mesh_id: the mesh ID
  * @mesh_id_len: length of the mesh ID, at least 1 and at most 32 bytes
+ * @path_sel_proto: which path selection protocol to use
+ * @path_metric: which metric to use
+ * @vendor_ie: vendor information elements (optional)
+ * @vendor_ie_len: length of vendor information elements
  *
  * These parameters are fixed when the mesh is created.
  */
 struct mesh_setup {
 	const u8 *mesh_id;
 	u8 mesh_id_len;
+	u8  path_sel_proto;
+	u8  path_metric;
+	const u8 *vendor_ie;
+	u8 vendor_ie_len;
 };
 
 /**
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 1c94a2a..ae2c712 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1000,6 +1000,36 @@ static inline bool _chg_mesh_attr(enum nl80211_meshconf_params parm, u32 mask)
 	return (mask >> (parm-1)) & 0x1;
 }
 
+static int copy_mesh_setup(struct ieee80211_if_mesh *ifmsh,
+		const struct mesh_setup *setup)
+{
+	u8 *new_ie;
+	const u8 *old_ie;
+
+	/* first allocate the new vendor information element */
+	new_ie = NULL;
+	old_ie = ifmsh->vendor_ie;
+
+	ifmsh->vendor_ie_len = setup->vendor_ie_len;
+	if (setup->vendor_ie_len) {
+		new_ie = kmemdup(setup->vendor_ie, setup->vendor_ie_len,
+				GFP_KERNEL);
+		if (!new_ie)
+			return -ENOMEM;
+	}
+
+	/* now copy the rest of the setup parameters */
+	ifmsh->mesh_id_len = setup->mesh_id_len;
+	memcpy(ifmsh->mesh_id, setup->mesh_id, ifmsh->mesh_id_len);
+	ifmsh->mesh_pp_id = setup->path_sel_proto;
+	ifmsh->mesh_pm_id = setup->path_metric;
+	ifmsh->vendor_ie = new_ie;
+
+	kfree(old_ie);
+
+	return 0;
+}
+
 static int ieee80211_update_mesh_config(struct wiphy *wiphy,
 					struct net_device *dev, u32 mask,
 					const struct mesh_config *nconf)
@@ -1059,11 +1089,12 @@ static int ieee80211_join_mesh(struct wiphy *wiphy, struct net_device *dev,
 {
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 	struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
+	int err;
 
-	memcpy(&sdata->u.mesh.mshcfg, conf, sizeof(struct mesh_config));
-	ifmsh->mesh_id_len = setup->mesh_id_len;
-	memcpy(ifmsh->mesh_id, setup->mesh_id, ifmsh->mesh_id_len);
-
+	memcpy(&ifmsh->mshcfg, conf, sizeof(struct mesh_config));
+	err = copy_mesh_setup(ifmsh, setup);
+	if (err)
+		return err;
 	ieee80211_start_mesh(sdata);
 
 	return 0;
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 0817ec6..cc7c367 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -485,6 +485,8 @@ struct ieee80211_if_mesh {
 	struct mesh_config mshcfg;
 	u32 mesh_seqnum;
 	bool accepting_plinks;
+	const u8 *vendor_ie;
+	u8 vendor_ie_len;
 };
 
 #ifdef CONFIG_MAC80211_MESH
@@ -588,9 +588,7 @@ struct ieee80211_sub_if_data {
 		struct ieee80211_if_vlan vlan;
 		struct ieee80211_if_managed mgd;
 		struct ieee80211_if_ibss ibss;
-#ifdef CONFIG_MAC80211_MESH
 		struct ieee80211_if_mesh mesh;
-#endif
 		u32 mntr_flags;
 	} u;
 
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 63e1188..c326e00 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -287,6 +287,13 @@ void mesh_mgmt_ies_add(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
 	*pos++ |= sdata->u.mesh.accepting_plinks ?
 	    MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00;
 	*pos++ = 0x00;
+
+	if (sdata->u.mesh.vendor_ie) {
+		int len = sdata->u.mesh.vendor_ie_len;
+		const u8 *data = sdata->u.mesh.vendor_ie;
+		if (skb_tailroom(skb) > len)
+			memcpy(skb_put(skb, len), data, len);
+	}
 }
 
 u32 mesh_table_hash(u8 *addr, struct ieee80211_sub_if_data *sdata, struct mesh_table *tbl)
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 1c91f0f..44b5393 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -160,7 +160,8 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
 		enum plink_frame_type action, u8 *da, __le16 llid, __le16 plid,
 		__le16 reason) {
 	struct ieee80211_local *local = sdata->local;
-	struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400);
+	struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400 +
+			sdata->u.mesh.vendor_ie_len);
 	struct ieee80211_mgmt *mgmt;
 	bool include_plid = false;
 	static const u8 meshpeeringproto[] = { 0x00, 0x0F, 0xAC, 0x2A };
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 898e864..b97f603 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -2293,7 +2293,8 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
 		u8 *pos;
 
 		/* headroom, head length, tail length and maximum TIM length */
-		skb = dev_alloc_skb(local->tx_headroom + 400);
+		skb = dev_alloc_skb(local->tx_headroom + 400 +
+				sdata->u.mesh.vendor_ie_len);
 		if (!skb)
 			goto out;
 
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 79772fc..e9a5f8c 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -789,13 +789,23 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
 			cfg80211_mgd_wext_connect(rdev, wdev);
 			break;
 #endif
+#ifdef CONFIG_MAC80211_MESH
 		case NL80211_IFTYPE_MESH_POINT:
-			/* backward compat code ... */
-			if (wdev->mesh_id_up_len)
-				__cfg80211_join_mesh(rdev, dev, wdev->ssid,
-						     wdev->mesh_id_up_len,
-						     &default_mesh_config);
-			break;
+			{
+				/* backward compat code... */
+				struct mesh_setup setup;
+				memcpy(&setup, &default_mesh_setup,
+						sizeof(setup));
+				 /* back compat only needed for mesh_id */
+				setup.mesh_id = wdev->ssid;
+				setup.mesh_id_len = wdev->mesh_id_up_len;
+				if (wdev->mesh_id_up_len)
+					__cfg80211_join_mesh(rdev, dev,
+							&setup,
+							&default_mesh_config);
+				break;
+			}
+#endif
 		default:
 			break;
 		}
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 743203b..26a0a08 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -287,13 +287,14 @@ int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
 
 /* mesh */
 extern const struct mesh_config default_mesh_config;
+extern const struct mesh_setup default_mesh_setup;
 int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
 			 struct net_device *dev,
-			 const u8 *mesh_id, u8 mesh_id_len,
+			 const struct mesh_setup *setup,
 			 const struct mesh_config *conf);
 int cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
 		       struct net_device *dev,
-		       const u8 *mesh_id, u8 mesh_id_len,
+		       const struct mesh_setup *setup,
 		       const struct mesh_config *conf);
 int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
 			struct net_device *dev);
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index e0b9747..73e39c1 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -50,17 +50,19 @@ const struct mesh_config default_mesh_config = {
 	.min_discovery_timeout = MESH_MIN_DISCOVERY_TIMEOUT,
 };
 
+const struct mesh_setup default_mesh_setup = {
+	.path_sel_proto = IEEE80211_PATH_PROTOCOL_HWMP,
+	.path_metric = IEEE80211_PATH_METRIC_AIRTIME,
+	.vendor_ie = NULL,
+	.vendor_ie_len = 0,
+};
 
 int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
 			 struct net_device *dev,
-			 const u8 *mesh_id, u8 mesh_id_len,
+			 const struct mesh_setup *setup,
 			 const struct mesh_config *conf)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
-	struct mesh_setup setup = {
-		.mesh_id = mesh_id,
-		.mesh_id_len = mesh_id_len,
-	};
 	int err;
 
 	BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN != IEEE80211_MAX_MESH_ID_LEN);
@@ -73,16 +75,16 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
 	if (wdev->mesh_id_len)
 		return -EALREADY;
 
-	if (!mesh_id_len)
+	if (!setup->mesh_id_len)
 		return -EINVAL;
 
 	if (!rdev->ops->join_mesh)
 		return -EOPNOTSUPP;
 
-	err = rdev->ops->join_mesh(&rdev->wiphy, dev, conf, &setup);
+	err = rdev->ops->join_mesh(&rdev->wiphy, dev, conf, setup);
 	if (!err) {
-		memcpy(wdev->ssid, mesh_id, mesh_id_len);
-		wdev->mesh_id_len = mesh_id_len;
+		memcpy(wdev->ssid, setup->mesh_id, setup->mesh_id_len);
+		wdev->mesh_id_len = setup->mesh_id_len;
 	}
 
 	return err;
@@ -90,14 +92,14 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
 
 int cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
 		       struct net_device *dev,
-		       const u8 *mesh_id, u8 mesh_id_len,
+		       const struct mesh_setup *setup,
 		       const struct mesh_config *conf)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	int err;
 
 	wdev_lock(wdev);
-	err = __cfg80211_join_mesh(rdev, dev, mesh_id, mesh_id_len, conf);
+	err = __cfg80211_join_mesh(rdev, dev, setup, conf);
 	wdev_unlock(wdev);
 
 	return err;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index d783dca..356c33e 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -2773,6 +2773,14 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A
 	[NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 },
 };
 
+static const struct nla_policy
+	nl80211_mesh_setup_params_policy[NL80211_MESH_SETUP_ATTR_MAX+1] = {
+	[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 },
+	[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 },
+	[NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE] = { .type = NLA_BINARY,
+		.len = IEEE80211_MAX_DATA_LEN },
+};
+
 static int nl80211_parse_mesh_config(struct genl_info *info,
 				     struct mesh_config *cfg,
 				     u32 *mask_out)
@@ -2839,14 +2847,50 @@ do {\
 			dot11MeshHWMPRootMode, mask,
 			NL80211_MESHCONF_HWMP_ROOTMODE,
 			nla_get_u8);
-
 	if (mask_out)
 		*mask_out = mask;
+
 	return 0;
 
 #undef FILL_IN_MESH_PARAM_IF_SET
 }
 
+static int nl80211_parse_mesh_setup(struct genl_info *info,
+				     struct mesh_setup *setup)
+{
+	struct nlattr *tb[NL80211_MESH_SETUP_ATTR_MAX + 1];
+
+	if (!info->attrs[NL80211_ATTR_MESH_SETUP])
+		return -EINVAL;
+	if (nla_parse_nested(tb, NL80211_MESH_SETUP_ATTR_MAX,
+			     info->attrs[NL80211_ATTR_MESH_SETUP],
+			     nl80211_mesh_setup_params_policy))
+		return -EINVAL;
+
+	if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])
+		setup->path_sel_proto =
+		(nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])) ?
+		 IEEE80211_PATH_PROTOCOL_VENDOR :
+		 IEEE80211_PATH_PROTOCOL_HWMP;
+
+	if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC])
+		setup->path_metric =
+		(nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC])) ?
+		 IEEE80211_PATH_METRIC_VENDOR :
+		 IEEE80211_PATH_METRIC_AIRTIME;
+
+	if (tb[NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE]) {
+		struct nlattr *ieattr =
+			tb[NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE];
+		if (!is_valid_ie_attr(ieattr))
+			return -EINVAL;
+		setup->vendor_ie = nla_data(ieattr);
+		setup->vendor_ie_len = nla_len(ieattr);
+	}
+
+	return 0;
+}
+
 static int nl80211_update_mesh_config(struct sk_buff *skb,
 				      struct genl_info *info)
 {
@@ -4667,10 +4711,12 @@ static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
 	struct net_device *dev = info->user_ptr[1];
 	struct mesh_config cfg;
+	struct mesh_setup setup;
 	int err;
 
 	/* start with default */
 	memcpy(&cfg, &default_mesh_config, sizeof(cfg));
+	memcpy(&setup, &default_mesh_setup, sizeof(setup));
 
 	if (info->attrs[NL80211_ATTR_MESH_CONFIG]) {
 		/* and parse parameters if given */
@@ -4683,10 +4729,17 @@ static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
 	    !nla_len(info->attrs[NL80211_ATTR_MESH_ID]))
 		return -EINVAL;
 
-	return cfg80211_join_mesh(rdev, dev,
-				  nla_data(info->attrs[NL80211_ATTR_MESH_ID]),
-				  nla_len(info->attrs[NL80211_ATTR_MESH_ID]),
-				  &cfg);
+	setup.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
+	setup.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
+
+	if (info->attrs[NL80211_ATTR_MESH_SETUP]) {
+		/* parse additional setup parameters if given */
+		err = nl80211_parse_mesh_setup(info, &setup);
+		if (err)
+			return err;
+	}
+
+	return cfg80211_join_mesh(rdev, dev, &setup, &cfg);
 }
 
 static int nl80211_leave_mesh(struct sk_buff *skb, struct genl_info *info)
-- 
1.7.1


^ permalink raw reply related

* [PATCH 1/3 v3] mac80211: Rename mesh_params to mesh_config to prepare for mesh_setup
From: Javier Cardona @ 2010-12-17  1:37 UTC (permalink / raw)
  To: John W. Linville
  Cc: Javier Cardona, Steve Derosier, devel, Johannes Berg,
	linux-wireless
In-Reply-To: <1292525513.3612.26.camel@jlt3.sipsolutions.net>

Mesh parameters can be to setup a mesh or to configure it.
This patch renames the ambiguous name mesh_params to mesh_config
in preparation for mesh_setup.

Signed-off-by: Javier Cardona <javier@cozybit.com>
---
v2: - separate mesh config and setup parametres and split the original patch
v3: - add #defines for source-level API compatibility

 include/linux/nl80211.h |   15 ++++++++++-----
 include/net/cfg80211.h  |    8 ++++----
 net/mac80211/cfg.c      |    8 ++++----
 net/wireless/nl80211.c  |   40 ++++++++++++++++++++--------------------
 4 files changed, 38 insertions(+), 33 deletions(-)

diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 1cee56b..d626ad2 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -172,10 +172,10 @@
  * 	to the specified ISO/IEC 3166-1 alpha2 country code. The core will
  * 	store this as a valid request and then query userspace for it.
  *
- * @NL80211_CMD_GET_MESH_PARAMS: Get mesh networking properties for the
+ * @NL80211_CMD_GET_MESH_CONFIG: Get mesh networking properties for the
  *	interface identified by %NL80211_ATTR_IFINDEX
  *
- * @NL80211_CMD_SET_MESH_PARAMS: Set mesh networking properties for the
+ * @NL80211_CMD_SET_MESH_CONFIG: Set mesh networking properties for the
  *      interface identified by %NL80211_ATTR_IFINDEX
  *
  * @NL80211_CMD_SET_MGMT_EXTRA_IE: Set extra IEs for management frames. The
@@ -441,8 +441,8 @@ enum nl80211_commands {
 	NL80211_CMD_SET_REG,
 	NL80211_CMD_REQ_SET_REG,
 
-	NL80211_CMD_GET_MESH_PARAMS,
-	NL80211_CMD_SET_MESH_PARAMS,
+	NL80211_CMD_GET_MESH_CONFIG,
+	NL80211_CMD_SET_MESH_CONFIG,
 
 	NL80211_CMD_SET_MGMT_EXTRA_IE /* reserved; not used */,
 
@@ -528,6 +528,10 @@ enum nl80211_commands {
 #define NL80211_CMD_DISASSOCIATE NL80211_CMD_DISASSOCIATE
 #define NL80211_CMD_REG_BEACON_HINT NL80211_CMD_REG_BEACON_HINT
 
+/* source-level API compatibility */
+#define NL80211_CMD_GET_MESH_PARAMS NL80211_CMD_GET_MESH_CONFIG
+#define NL80211_CMD_SET_MESH_PARAMS NL80211_CMD_SET_MESH_CONFIG
+
 /**
  * enum nl80211_attrs - nl80211 netlink attributes
  *
@@ -912,7 +916,7 @@ enum nl80211_attrs {
 	NL80211_ATTR_REG_ALPHA2,
 	NL80211_ATTR_REG_RULES,
 
-	NL80211_ATTR_MESH_PARAMS,
+	NL80211_ATTR_MESH_CONFIG,
 
 	NL80211_ATTR_BSS_BASIC_RATES,
 
@@ -1048,6 +1052,7 @@ enum nl80211_attrs {
 
 /* source-level API compatibility */
 #define NL80211_ATTR_SCAN_GENERATION NL80211_ATTR_GENERATION
+#define	NL80211_ATTR_MESH_PARAMS NL80211_ATTR_MESH_CONFIG
 
 /*
  * Allow user space programs to use #ifdef on new attributes by defining them
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index f45e15f..1bac74a 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1096,9 +1096,9 @@ struct cfg80211_pmksa {
  * @get_mpath: get a mesh path for the given parameters
  * @dump_mpath: dump mesh path callback -- resume dump at index @idx
  *
- * @get_mesh_params: Put the current mesh parameters into *params
+ * @get_mesh_config: Get the current mesh configuration
  *
- * @update_mesh_params: Update mesh parameters on a running mesh.
+ * @update_mesh_config: Update mesh parameters on a running mesh.
  *	The mask is a bitfield which tells us which parameters to
  *	set, and which to leave alone.
  *
@@ -1246,10 +1246,10 @@ struct cfg80211_ops {
 	int	(*dump_mpath)(struct wiphy *wiphy, struct net_device *dev,
 			       int idx, u8 *dst, u8 *next_hop,
 			       struct mpath_info *pinfo);
-	int	(*get_mesh_params)(struct wiphy *wiphy,
+	int	(*get_mesh_config)(struct wiphy *wiphy,
 				struct net_device *dev,
 				struct mesh_config *conf);
-	int	(*update_mesh_params)(struct wiphy *wiphy,
+	int	(*update_mesh_config)(struct wiphy *wiphy,
 				      struct net_device *dev, u32 mask,
 				      const struct mesh_config *nconf);
 	int	(*join_mesh)(struct wiphy *wiphy, struct net_device *dev,
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index ea06f92..1c94a2a 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -984,7 +984,7 @@ static int ieee80211_dump_mpath(struct wiphy *wiphy, struct net_device *dev,
 	return 0;
 }
 
-static int ieee80211_get_mesh_params(struct wiphy *wiphy,
+static int ieee80211_get_mesh_config(struct wiphy *wiphy,
 				struct net_device *dev,
 				struct mesh_config *conf)
 {
@@ -1000,7 +1000,7 @@ static inline bool _chg_mesh_attr(enum nl80211_meshconf_params parm, u32 mask)
 	return (mask >> (parm-1)) & 0x1;
 }
 
-static int ieee80211_update_mesh_params(struct wiphy *wiphy,
+static int ieee80211_update_mesh_config(struct wiphy *wiphy,
 					struct net_device *dev, u32 mask,
 					const struct mesh_config *nconf)
 {
@@ -1787,8 +1787,8 @@ struct cfg80211_ops mac80211_config_ops = {
 	.change_mpath = ieee80211_change_mpath,
 	.get_mpath = ieee80211_get_mpath,
 	.dump_mpath = ieee80211_dump_mpath,
-	.update_mesh_params = ieee80211_update_mesh_params,
-	.get_mesh_params = ieee80211_get_mesh_params,
+	.update_mesh_config = ieee80211_update_mesh_config,
+	.get_mesh_config = ieee80211_get_mesh_config,
 	.join_mesh = ieee80211_join_mesh,
 	.leave_mesh = ieee80211_leave_mesh,
 #endif
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 594a6ac..d783dca 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -123,7 +123,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
 					   .len = NL80211_MAX_SUPP_RATES },
 	[NL80211_ATTR_BSS_HT_OPMODE] = { .type = NLA_U16 },
 
-	[NL80211_ATTR_MESH_PARAMS] = { .type = NLA_NESTED },
+	[NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED },
 
 	[NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY,
 					 .len = NL80211_HT_CAPABILITY_LEN },
@@ -719,7 +719,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
 	CMD(add_beacon, NEW_BEACON);
 	CMD(add_station, NEW_STATION);
 	CMD(add_mpath, NEW_MPATH);
-	CMD(update_mesh_params, SET_MESH_PARAMS);
+	CMD(update_mesh_config, SET_MESH_CONFIG);
 	CMD(change_bss, SET_BSS);
 	CMD(auth, AUTHENTICATE);
 	CMD(assoc, ASSOCIATE);
@@ -2673,7 +2673,7 @@ static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
 	return r;
 }
 
-static int nl80211_get_mesh_params(struct sk_buff *skb,
+static int nl80211_get_mesh_config(struct sk_buff *skb,
 				   struct genl_info *info)
 {
 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -2688,7 +2688,7 @@ static int nl80211_get_mesh_params(struct sk_buff *skb,
 	if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
 		return -EOPNOTSUPP;
 
-	if (!rdev->ops->get_mesh_params)
+	if (!rdev->ops->get_mesh_config)
 		return -EOPNOTSUPP;
 
 	wdev_lock(wdev);
@@ -2696,7 +2696,7 @@ static int nl80211_get_mesh_params(struct sk_buff *skb,
 	if (!wdev->mesh_id_len)
 		memcpy(&cur_params, &default_mesh_config, sizeof(cur_params));
 	else
-		err = rdev->ops->get_mesh_params(&rdev->wiphy, dev,
+		err = rdev->ops->get_mesh_config(&rdev->wiphy, dev,
 						 &cur_params);
 	wdev_unlock(wdev);
 
@@ -2708,10 +2708,10 @@ static int nl80211_get_mesh_params(struct sk_buff *skb,
 	if (!msg)
 		return -ENOMEM;
 	hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
-			     NL80211_CMD_GET_MESH_PARAMS);
+			     NL80211_CMD_GET_MESH_CONFIG);
 	if (!hdr)
 		goto nla_put_failure;
-	pinfoattr = nla_nest_start(msg, NL80211_ATTR_MESH_PARAMS);
+	pinfoattr = nla_nest_start(msg, NL80211_ATTR_MESH_CONFIG);
 	if (!pinfoattr)
 		goto nla_put_failure;
 	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
@@ -2773,7 +2773,7 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A
 	[NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 },
 };
 
-static int nl80211_parse_mesh_params(struct genl_info *info,
+static int nl80211_parse_mesh_config(struct genl_info *info,
 				     struct mesh_config *cfg,
 				     u32 *mask_out)
 {
@@ -2789,10 +2789,10 @@ do {\
 } while (0);\
 
 
-	if (!info->attrs[NL80211_ATTR_MESH_PARAMS])
+	if (!info->attrs[NL80211_ATTR_MESH_CONFIG])
 		return -EINVAL;
 	if (nla_parse_nested(tb, NL80211_MESHCONF_ATTR_MAX,
-			     info->attrs[NL80211_ATTR_MESH_PARAMS],
+			     info->attrs[NL80211_ATTR_MESH_CONFIG],
 			     nl80211_meshconf_params_policy))
 		return -EINVAL;
 
@@ -2847,7 +2847,7 @@ do {\
 #undef FILL_IN_MESH_PARAM_IF_SET
 }
 
-static int nl80211_update_mesh_params(struct sk_buff *skb,
+static int nl80211_update_mesh_config(struct sk_buff *skb,
 				      struct genl_info *info)
 {
 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -2860,10 +2860,10 @@ static int nl80211_update_mesh_params(struct sk_buff *skb,
 	if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
 		return -EOPNOTSUPP;
 
-	if (!rdev->ops->update_mesh_params)
+	if (!rdev->ops->update_mesh_config)
 		return -EOPNOTSUPP;
 
-	err = nl80211_parse_mesh_params(info, &cfg, &mask);
+	err = nl80211_parse_mesh_config(info, &cfg, &mask);
 	if (err)
 		return err;
 
@@ -2872,7 +2872,7 @@ static int nl80211_update_mesh_params(struct sk_buff *skb,
 		err = -ENOLINK;
 
 	if (!err)
-		err = rdev->ops->update_mesh_params(&rdev->wiphy, dev,
+		err = rdev->ops->update_mesh_config(&rdev->wiphy, dev,
 						    mask, &cfg);
 
 	wdev_unlock(wdev);
@@ -4672,9 +4672,9 @@ static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
 	/* start with default */
 	memcpy(&cfg, &default_mesh_config, sizeof(cfg));
 
-	if (info->attrs[NL80211_ATTR_MESH_PARAMS]) {
+	if (info->attrs[NL80211_ATTR_MESH_CONFIG]) {
 		/* and parse parameters if given */
-		err = nl80211_parse_mesh_params(info, &cfg, NULL);
+		err = nl80211_parse_mesh_config(info, &cfg, NULL);
 		if (err)
 			return err;
 	}
@@ -4952,16 +4952,16 @@ static struct genl_ops nl80211_ops[] = {
 		.flags = GENL_ADMIN_PERM,
 	},
 	{
-		.cmd = NL80211_CMD_GET_MESH_PARAMS,
-		.doit = nl80211_get_mesh_params,
+		.cmd = NL80211_CMD_GET_MESH_CONFIG,
+		.doit = nl80211_get_mesh_config,
 		.policy = nl80211_policy,
 		/* can be retrieved by unprivileged users */
 		.internal_flags = NL80211_FLAG_NEED_NETDEV |
 				  NL80211_FLAG_NEED_RTNL,
 	},
 	{
-		.cmd = NL80211_CMD_SET_MESH_PARAMS,
-		.doit = nl80211_update_mesh_params,
+		.cmd = NL80211_CMD_SET_MESH_CONFIG,
+		.doit = nl80211_update_mesh_config,
 		.policy = nl80211_policy,
 		.flags = GENL_ADMIN_PERM,
 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
-- 
1.7.1


^ permalink raw reply related

* [PATCH v2] mac80211: Remove unused third address from mesh address extension header.
From: Javier Cardona @ 2010-12-17  1:23 UTC (permalink / raw)
  To: John W. Linville
  Cc: Javier Cardona, Steve Derosier, devel, Johannes Berg,
	linux-wireless
In-Reply-To: <AANLkTimpmCdAx_8OqfqALwbWkX3NVaP98FzbxS4yJUFm@mail.gmail.com>

The Mesh Control header only includes 0, 1 or 2 addresses. If there is
one address, it should be interpreted as Address 4.  If there are 2,
they are interpreted as Addresses 5 and 6 (Address 4 being the 4th
address in the 802.11 header).

The address extension used to hold up to 3 addresses instead of the current 2.
I'm not sure which draft version changed this, but it is very unlikely that it
will change again given the state of the approval process of this draft.  See
section 7.1.3.6.3 in current draft (8.0).

Also, note that the extra address that I'm removing was not being used, so this
change has no effect on over-the-air frame formats.  But I thought I better
remove it before someone does start using it.

Signed-off-by: Javier Cardona <javier@cozybit.com>
---
v2: - more detailed patch description
    - changed ieee80211_fill_mesh_addresses() to just accept at most 2
      addresses and avoid confusions.

 include/linux/ieee80211.h |    1 -
 net/mac80211/mesh.c       |   32 +++++++++++++-------------------
 net/mac80211/mesh.h       |    4 ++--
 net/mac80211/tx.c         |    4 +---
 4 files changed, 16 insertions(+), 25 deletions(-)

diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index cd68168..6042228 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -536,7 +536,6 @@ struct ieee80211s_hdr {
 	__le32 seqnum;
 	u8 eaddr1[6];
 	u8 eaddr2[6];
-	u8 eaddr3[6];
 } __attribute__ ((packed));
 
 /* Mesh flags */
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 8b5906c..ca3af46 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -410,39 +410,33 @@ int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc,
  * ieee80211_new_mesh_header - create a new mesh header
  * @meshhdr:    uninitialized mesh header
  * @sdata:	mesh interface to be used
- * @addr4:	addr4 of the mesh frame (1st in ae header)
- *              may be NULL
- * @addr5:	addr5 of the mesh frame (1st or 2nd in ae header)
- *              may be NULL unless addr6 is present
- * @addr6:	addr6 of the mesh frame (2nd or 3rd in ae header)
- * 		may be NULL unless addr5 is present
+ * @addr4or5:   1st address in the ae header, which may correspond to address 4
+ *              (if addr6 is NULL) or address 5 (if addr6 is present). It may
+ *              be NULL.
+ * @addr6:	2nd address in the ae header, which corresponds to addr6 of the
+ *              mesh frame
  *
  * Return the header length.
  */
 int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr,
-		struct ieee80211_sub_if_data *sdata, char *addr4,
-		char *addr5, char *addr6)
+		struct ieee80211_sub_if_data *sdata, char *addr4or5,
+		char *addr6)
 {
 	int aelen = 0;
+	BUG_ON(!addr4or5 && addr6);
 	memset(meshhdr, 0, sizeof(*meshhdr));
 	meshhdr->ttl = sdata->u.mesh.mshcfg.dot11MeshTTL;
 	put_unaligned(cpu_to_le32(sdata->u.mesh.mesh_seqnum), &meshhdr->seqnum);
 	sdata->u.mesh.mesh_seqnum++;
-	if (addr4) {
+	if (addr4or5 && !addr6) {
 		meshhdr->flags |= MESH_FLAGS_AE_A4;
 		aelen += ETH_ALEN;
-		memcpy(meshhdr->eaddr1, addr4, ETH_ALEN);
-	}
-	if (addr5 && addr6) {
+		memcpy(meshhdr->eaddr1, addr4or5, ETH_ALEN);
+	} else if (addr4or5 && addr6) {
 		meshhdr->flags |= MESH_FLAGS_AE_A5_A6;
 		aelen += 2 * ETH_ALEN;
-		if (!addr4) {
-			memcpy(meshhdr->eaddr1, addr5, ETH_ALEN);
-			memcpy(meshhdr->eaddr2, addr6, ETH_ALEN);
-		} else {
-			memcpy(meshhdr->eaddr2, addr5, ETH_ALEN);
-			memcpy(meshhdr->eaddr3, addr6, ETH_ALEN);
-		}
+		memcpy(meshhdr->eaddr1, addr4or5, ETH_ALEN);
+		memcpy(meshhdr->eaddr2, addr6, ETH_ALEN);
 	}
 	return 6 + aelen;
 }
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 890dd19..b99e230 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -187,8 +187,8 @@ struct mesh_rmc {
 int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc,
 				  const u8 *da, const u8 *sa);
 int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr,
-		struct ieee80211_sub_if_data *sdata, char *addr4,
-		char *addr5, char *addr6);
+		struct ieee80211_sub_if_data *sdata, char *addr4or5,
+		char *addr6);
 int mesh_rmc_check(u8 *addr, struct ieee80211s_hdr *mesh_hdr,
 		struct ieee80211_sub_if_data *sdata);
 bool mesh_matches_local(struct ieee802_11_elems *ie,
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index b97f603..10a81b8 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1814,7 +1814,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
 			hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc,
 					skb->data, skb->data + ETH_ALEN);
 			meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr,
-					sdata, NULL, NULL, NULL);
+					sdata, NULL, NULL);
 		} else {
 			/* packet from other interface */
 			struct mesh_path *mppath;
@@ -1847,13 +1847,11 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
 					ieee80211_new_mesh_header(&mesh_hdr,
 							sdata,
 							skb->data + ETH_ALEN,
-							NULL,
 							NULL);
 			else
 				meshhdrlen =
 					ieee80211_new_mesh_header(&mesh_hdr,
 							sdata,
-							NULL,
 							skb->data,
 							skb->data + ETH_ALEN);
 
-- 
1.7.1


^ permalink raw reply related

* Problem bringing up wlan0 interface up with mainline wl1271 drivers
From: Elvis Dowson @ 2010-12-17  0:23 UTC (permalink / raw)
  To: Ohad Ben-Cohen; +Cc: Linux Wireless Mailing List, panduranga, Pedro Jara
In-Reply-To: <AANLkTikESPwcaxUSDd3B=Oh7kBD-QpndKRHmu9-roDqs@mail.gmail.com>

Hi,

On Dec 12, 2010, at 1:24 AM, Ohad Ben-Cohen wrote:

>> When I build the TI WiLink drivers from the ti rowboat hardware/ti/wlan project
> 
> The linux-omap community can help you with mainline drivers, but no so
> much with proprietary ones. Why don't you use the upstream wl12xx
> driver ?

I've built linux kernel 2.6.37-rc6, and patched board-omap3beagle.c to interface with MMC2 SDIO controller, 
but I'm unable to bring the wlan0 interface up.

Here are the messages during kernel boot:

[    0.000000] wlan_mux_init: Configuring mux settings for wl1271 wlan module
[    0.077117] regulator: vwl1271: 1850 mV normal standby
[    2.171813] mmc1: mmc_rescan: trying to init card at 400000 Hz
[    2.323120] mmc1: card claims to support voltages below the defined range. These will be ignored.
[    2.368865] mmc1: queuing unknown CIS tuple 0x91 (3 bytes)
[    2.392150] mmc1: new SDIO card at address 0001
[    2.787597] wl1271: loaded
[    2.790802] wl1271: initialized

# ifconfig -a
lo        Link encap:Local Loopback  
          LOOPBACK  MTU:16436  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)

wlan0     Link encap:Ethernet  HWaddr 00:00:00:00:00:00  
          BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)

# ifconfig wlan0 up
SIOCSIFFLAGS: Cannot assign requested address

What could the reason be?

Elvis Dowson

^ permalink raw reply

* [PATCH 1/2] ath9k: fix queue depth check for forming new aggregates
From: Felix Fietkau @ 2010-12-16 23:57 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville, lrodriguez, Felix Fietkau

To improve aggregation length, there should not be more than two fully formed
A-MPDU frames in the hardware queue. To ensure this, the code checks the tx
queue length before forming new A-MPDUs. This can reduce the throughput (or
maybe even starve out A-MPDU traffic) when too many non-aggregated frames are
in the queue.
Fix this by keeping track of pending A-MPDU frames (even when they're sent out
as single frames), but exclude rate control probing frames to improve
performance.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/ath9k.h |    1 +
 drivers/net/wireless/ath/ath9k/xmit.c  |   21 ++++++++++++++++++---
 2 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index b0b1216..9fd9519 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -189,6 +189,7 @@ struct ath_txq {
 	struct list_head axq_q;
 	spinlock_t axq_lock;
 	u32 axq_depth;
+	u32 axq_ampdu_depth;
 	bool stopped;
 	bool axq_tx_inprogress;
 	struct list_head axq_acq;
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 96623695..332d1fe 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -838,7 +838,7 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
 		ath_tx_txqaddbuf(sc, txq, &bf_q);
 		TX_STAT_INC(txq->axq_qnum, a_aggr);
 
-	} while (txq->axq_depth < ATH_AGGR_MIN_QDEPTH &&
+	} while (txq->axq_ampdu_depth < ATH_AGGR_MIN_QDEPTH &&
 		 status != ATH_AGGR_BAW_CLOSED);
 }
 
@@ -999,6 +999,7 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
 		INIT_LIST_HEAD(&txq->axq_acq);
 		spin_lock_init(&txq->axq_lock);
 		txq->axq_depth = 0;
+		txq->axq_ampdu_depth = 0;
 		txq->axq_tx_inprogress = false;
 		sc->tx.txqsetup |= 1<<qnum;
 
@@ -1068,6 +1069,12 @@ int ath_cabq_update(struct ath_softc *sc)
 	return 0;
 }
 
+static bool bf_is_ampdu_not_probing(struct ath_buf *bf)
+{
+    struct ieee80211_tx_info *info = IEEE80211_SKB_CB(bf->bf_mpdu);
+    return bf_isampdu(bf) && !(info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE);
+}
+
 /*
  * Drain a given TX queue (could be Beacon or Data)
  *
@@ -1126,7 +1133,8 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
 		}
 
 		txq->axq_depth--;
-
+		if (bf_is_ampdu_not_probing(bf))
+			txq->axq_ampdu_depth--;
 		spin_unlock_bh(&txq->axq_lock);
 
 		if (bf_isampdu(bf))
@@ -1316,6 +1324,8 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
 		ath9k_hw_txstart(ah, txq->axq_qnum);
 	}
 	txq->axq_depth++;
+	if (bf_is_ampdu_not_probing(bf))
+		txq->axq_ampdu_depth++;
 }
 
 static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
@@ -1336,7 +1346,7 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
 	 */
 	if (!list_empty(&tid->buf_q) || tid->paused ||
 	    !BAW_WITHIN(tid->seq_start, tid->baw_size, fi->seqno) ||
-	    txctl->txq->axq_depth >= ATH_AGGR_MIN_QDEPTH) {
+	    txctl->txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) {
 		/*
 		 * Add this frame to software queue for scheduling later
 		 * for aggregation.
@@ -2040,6 +2050,9 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
 		txq->axq_tx_inprogress = false;
 		if (bf_held)
 			list_del(&bf_held->list);
+
+		if (bf_is_ampdu_not_probing(bf))
+			txq->axq_ampdu_depth--;
 		spin_unlock_bh(&txq->axq_lock);
 
 		if (bf_held)
@@ -2168,6 +2181,8 @@ void ath_tx_edma_tasklet(struct ath_softc *sc)
 		INCR(txq->txq_tailidx, ATH_TXFIFO_DEPTH);
 		txq->axq_depth--;
 		txq->axq_tx_inprogress = false;
+		if (bf_is_ampdu_not_probing(bf))
+			txq->axq_ampdu_depth--;
 		spin_unlock_bh(&txq->axq_lock);
 
 		txok = !(txs.ts_status & ATH9K_TXERR_MASK);
-- 
1.7.3.2


^ permalink raw reply related

* [PATCH 2/2] ath9k_hw: remove baseband rfsilent support
From: Felix Fietkau @ 2010-12-16 23:57 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville, lrodriguez, Felix Fietkau
In-Reply-To: <1292543821-95686-1-git-send-email-nbd@openwrt.org>

When rfkill is enabled, ath9k_hw unnecessarily configured the baseband to
turn off based on GPIO input, however that code was hardcoded to GPIO 0
instead of ah->rfkill_gpio.
Since ath9k uses software rfkill anyway, this code is completely unnecessary
and should be removed in case anything else ever uses GPIO 0.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/ar5008_phy.c |   13 -------------
 drivers/net/wireless/ath/ath9k/ar9003_phy.c |   23 -----------------------
 drivers/net/wireless/ath/ath9k/hw-ops.h     |    5 -----
 drivers/net/wireless/ath/ath9k/hw.c         |    2 +-
 drivers/net/wireless/ath/ath9k/hw.h         |    1 -
 5 files changed, 1 insertions(+), 43 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
index 059330a..ffcf44a 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -961,18 +961,6 @@ static void ar5008_hw_rfbus_done(struct ath_hw *ah)
 	REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
 }
 
-static void ar5008_hw_enable_rfkill(struct ath_hw *ah)
-{
-	REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
-		    AR_GPIO_INPUT_EN_VAL_RFSILENT_BB);
-
-	REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2,
-		    AR_GPIO_INPUT_MUX2_RFSILENT);
-
-	ath9k_hw_cfg_gpio_input(ah, ah->rfkill_gpio);
-	REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB);
-}
-
 static void ar5008_restore_chainmask(struct ath_hw *ah)
 {
 	int rx_chainmask = ah->rxchainmask;
@@ -1629,7 +1617,6 @@ void ar5008_hw_attach_phy_ops(struct ath_hw *ah)
 	priv_ops->set_delta_slope = ar5008_hw_set_delta_slope;
 	priv_ops->rfbus_req = ar5008_hw_rfbus_req;
 	priv_ops->rfbus_done = ar5008_hw_rfbus_done;
-	priv_ops->enable_rfkill = ar5008_hw_enable_rfkill;
 	priv_ops->restore_chainmask = ar5008_restore_chainmask;
 	priv_ops->set_diversity = ar5008_set_diversity;
 	priv_ops->do_getnf = ar5008_hw_do_getnf;
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index da4a571..cdf46c1 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -748,28 +748,6 @@ static void ar9003_hw_rfbus_done(struct ath_hw *ah)
 	REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
 }
 
-/*
- * Set the interrupt and GPIO values so the ISR can disable RF
- * on a switch signal.  Assumes GPIO port and interrupt polarity
- * are set prior to call.
- */
-static void ar9003_hw_enable_rfkill(struct ath_hw *ah)
-{
-	/* Connect rfsilent_bb_l to baseband */
-	REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
-		    AR_GPIO_INPUT_EN_VAL_RFSILENT_BB);
-	/* Set input mux for rfsilent_bb_l to GPIO #0 */
-	REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2,
-		    AR_GPIO_INPUT_MUX2_RFSILENT);
-
-	/*
-	 * Configure the desired GPIO port for input and
-	 * enable baseband rf silence.
-	 */
-	ath9k_hw_cfg_gpio_input(ah, ah->rfkill_gpio);
-	REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB);
-}
-
 static void ar9003_hw_set_diversity(struct ath_hw *ah, bool value)
 {
 	u32 v = REG_READ(ah, AR_PHY_CCK_DETECT);
@@ -1206,7 +1184,6 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
 	priv_ops->set_delta_slope = ar9003_hw_set_delta_slope;
 	priv_ops->rfbus_req = ar9003_hw_rfbus_req;
 	priv_ops->rfbus_done = ar9003_hw_rfbus_done;
-	priv_ops->enable_rfkill = ar9003_hw_enable_rfkill;
 	priv_ops->set_diversity = ar9003_hw_set_diversity;
 	priv_ops->ani_control = ar9003_hw_ani_control;
 	priv_ops->do_getnf = ar9003_hw_do_getnf;
diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h
index 0a4ad34..c8f254f 100644
--- a/drivers/net/wireless/ath/ath9k/hw-ops.h
+++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
@@ -223,11 +223,6 @@ static inline void ath9k_hw_rfbus_done(struct ath_hw *ah)
 	return ath9k_hw_private_ops(ah)->rfbus_done(ah);
 }
 
-static inline void ath9k_enable_rfkill(struct ath_hw *ah)
-{
-	return ath9k_hw_private_ops(ah)->enable_rfkill(ah);
-}
-
 static inline void ath9k_hw_restore_chainmask(struct ath_hw *ah)
 {
 	if (!ath9k_hw_private_ops(ah)->restore_chainmask)
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 0f373be..beb513d 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1383,7 +1383,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 	ath9k_hw_init_qos(ah);
 
 	if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
-		ath9k_enable_rfkill(ah);
+		ath9k_hw_cfg_gpio_input(ah, ah->rfkill_gpio);
 
 	ath9k_hw_init_global_settings(ah);
 
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 97f22c4..a461e67 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -576,7 +576,6 @@ struct ath_hw_private_ops {
 	void (*set_delta_slope)(struct ath_hw *ah, struct ath9k_channel *chan);
 	bool (*rfbus_req)(struct ath_hw *ah);
 	void (*rfbus_done)(struct ath_hw *ah);
-	void (*enable_rfkill)(struct ath_hw *ah);
 	void (*restore_chainmask)(struct ath_hw *ah);
 	void (*set_diversity)(struct ath_hw *ah, bool value);
 	u32 (*compute_pll_control)(struct ath_hw *ah,
-- 
1.7.3.2


^ permalink raw reply related

* [PATCH] rtl8192ce: drop 'rtl8192c-' prefix from files
From: John W. Linville @ 2010-12-16 20:43 UTC (permalink / raw)
  To: linux-wireless; +Cc: Larry Finger, Chaoming Li, John W. Linville

Signed-off-by: John W. Linville <linville@tuxdriver.com>
---
Any objections?  It's less to type/read/whatever...

 drivers/net/wireless/rtlwifi/rtl8192ce/Makefile    |   18 +++++++++---------
 .../rtlwifi/rtl8192ce/{rtl8192c-def.h => def.h}    |    0
 .../rtlwifi/rtl8192ce/{rtl8192c-dm.c => dm.c}      |   10 +++++-----
 .../rtlwifi/rtl8192ce/{rtl8192c-dm.h => dm.h}      |    0
 .../rtlwifi/rtl8192ce/{rtl8192c-fw.c => fw.c}      |    8 ++++----
 .../rtlwifi/rtl8192ce/{rtl8192c-fw.h => fw.h}      |    0
 .../rtlwifi/rtl8192ce/{rtl8192c-hw.c => hw.c}      |   14 +++++++-------
 .../rtlwifi/rtl8192ce/{rtl8192c-hw.h => hw.h}      |    0
 .../rtlwifi/rtl8192ce/{rtl8192c-led.c => led.c}    |    4 ++--
 .../rtlwifi/rtl8192ce/{rtl8192c-led.h => led.h}    |    0
 .../rtlwifi/rtl8192ce/{rtl8192c-phy.c => phy.c}    |   12 ++++++------
 .../rtlwifi/rtl8192ce/{rtl8192c-phy.h => phy.h}    |    0
 .../rtlwifi/rtl8192ce/{rtl8192c-reg.h => reg.h}    |    0
 .../rtlwifi/rtl8192ce/{rtl8192c-rf.c => rf.c}      |   10 +++++-----
 .../rtlwifi/rtl8192ce/{rtl8192c-rf.h => rf.h}      |    0
 .../rtlwifi/rtl8192ce/{rtl8192c-sw.c => sw.c}      |   16 ++++++++--------
 .../rtlwifi/rtl8192ce/{rtl8192c-sw.h => sw.h}      |    0
 .../rtl8192ce/{rtl8192c-table.c => table.c}        |    2 +-
 .../rtl8192ce/{rtl8192c-table.h => table.h}        |    0
 .../rtlwifi/rtl8192ce/{rtl8192c-trx.c => trx.c}    |   10 +++++-----
 .../rtlwifi/rtl8192ce/{rtl8192c-trx.h => trx.h}    |    0
 21 files changed, 52 insertions(+), 52 deletions(-)
 rename drivers/net/wireless/rtlwifi/rtl8192ce/{rtl8192c-def.h => def.h} (100%)
 rename drivers/net/wireless/rtlwifi/rtl8192ce/{rtl8192c-dm.c => dm.c} (99%)
 rename drivers/net/wireless/rtlwifi/rtl8192ce/{rtl8192c-dm.h => dm.h} (100%)
 rename drivers/net/wireless/rtlwifi/rtl8192ce/{rtl8192c-fw.c => fw.c} (99%)
 rename drivers/net/wireless/rtlwifi/rtl8192ce/{rtl8192c-fw.h => fw.h} (100%)
 rename drivers/net/wireless/rtlwifi/rtl8192ce/{rtl8192c-hw.c => hw.c} (99%)
 rename drivers/net/wireless/rtlwifi/rtl8192ce/{rtl8192c-hw.h => hw.h} (100%)
 rename drivers/net/wireless/rtlwifi/rtl8192ce/{rtl8192c-led.c => led.c} (98%)
 rename drivers/net/wireless/rtlwifi/rtl8192ce/{rtl8192c-led.h => led.h} (100%)
 rename drivers/net/wireless/rtlwifi/rtl8192ce/{rtl8192c-phy.c => phy.c} (99%)
 rename drivers/net/wireless/rtlwifi/rtl8192ce/{rtl8192c-phy.h => phy.h} (100%)
 rename drivers/net/wireless/rtlwifi/rtl8192ce/{rtl8192c-reg.h => reg.h} (100%)
 rename drivers/net/wireless/rtlwifi/rtl8192ce/{rtl8192c-rf.c => rf.c} (99%)
 rename drivers/net/wireless/rtlwifi/rtl8192ce/{rtl8192c-rf.h => rf.h} (100%)
 rename drivers/net/wireless/rtlwifi/rtl8192ce/{rtl8192c-sw.c => sw.c} (97%)
 rename drivers/net/wireless/rtlwifi/rtl8192ce/{rtl8192c-sw.h => sw.h} (100%)
 rename drivers/net/wireless/rtlwifi/rtl8192ce/{rtl8192c-table.c => table.c} (99%)
 rename drivers/net/wireless/rtlwifi/rtl8192ce/{rtl8192c-table.h => table.h} (100%)
 rename drivers/net/wireless/rtlwifi/rtl8192ce/{rtl8192c-trx.c => trx.c} (99%)
 rename drivers/net/wireless/rtlwifi/rtl8192ce/{rtl8192c-trx.h => trx.h} (100%)

diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/Makefile b/drivers/net/wireless/rtlwifi/rtl8192ce/Makefile
index f3d7682..0f0be7c 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/Makefile
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/Makefile
@@ -1,12 +1,12 @@
 rtl8192ce-objs :=		\
-	rtl8192c-dm.o		\
-	rtl8192c-fw.o		\
-	rtl8192c-hw.o		\
-	rtl8192c-led.o		\
-	rtl8192c-phy.o		\
-	rtl8192c-rf.o		\
-	rtl8192c-sw.o		\
-	rtl8192c-table.o	\
-	rtl8192c-trx.o
+		dm.o		\
+		fw.o		\
+		hw.o		\
+		led.o		\
+		phy.o		\
+		rf.o		\
+		sw.o		\
+		table.o		\
+		trx.o
 
 obj-$(CONFIG_RTL8192CE) += rtl8192ce.o
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-def.h b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h
similarity index 100%
rename from drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-def.h
rename to drivers/net/wireless/rtlwifi/rtl8192ce/def.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-dm.c b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c
similarity index 99%
rename from drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-dm.c
rename to drivers/net/wireless/rtlwifi/rtl8192ce/dm.c
index 4896899..62e7c64 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-dm.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c
@@ -29,11 +29,11 @@
 
 #include "../wifi.h"
 #include "../base.h"
-#include "rtl8192c-reg.h"
-#include "rtl8192c-def.h"
-#include "rtl8192c-phy.h"
-#include "rtl8192c-dm.h"
-#include "rtl8192c-fw.h"
+#include "reg.h"
+#include "def.h"
+#include "phy.h"
+#include "dm.h"
+#include "fw.h"
 
 struct dig_t dm_digtable;
 static struct ps_t dm_pstable;
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-dm.h b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h
similarity index 100%
rename from drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-dm.h
rename to drivers/net/wireless/rtlwifi/rtl8192ce/dm.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-fw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/fw.c
similarity index 99%
rename from drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-fw.c
rename to drivers/net/wireless/rtlwifi/rtl8192ce/fw.c
index 80ee6ff..11dd22b 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-fw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/fw.c
@@ -31,10 +31,10 @@
 #include "../wifi.h"
 #include "../pci.h"
 #include "../base.h"
-#include "rtl8192c-reg.h"
-#include "rtl8192c-def.h"
-#include "rtl8192c-fw.h"
-#include "rtl8192c-table.h"
+#include "reg.h"
+#include "def.h"
+#include "fw.h"
+#include "table.h"
 
 static void _rtl92c_enable_fw_download(struct ieee80211_hw *hw, bool enable)
 {
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-fw.h b/drivers/net/wireless/rtlwifi/rtl8192ce/fw.h
similarity index 100%
rename from drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-fw.h
rename to drivers/net/wireless/rtlwifi/rtl8192ce/fw.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
similarity index 99%
rename from drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-hw.c
rename to drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
index c649f65..1266dbe 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
@@ -33,13 +33,13 @@
 #include "../cam.h"
 #include "../ps.h"
 #include "../pci.h"
-#include "rtl8192c-reg.h"
-#include "rtl8192c-def.h"
-#include "rtl8192c-phy.h"
-#include "rtl8192c-dm.h"
-#include "rtl8192c-fw.h"
-#include "rtl8192c-led.h"
-#include "rtl8192c-hw.h"
+#include "reg.h"
+#include "def.h"
+#include "phy.h"
+#include "dm.h"
+#include "fw.h"
+#include "led.h"
+#include "hw.h"
 
 #define LLT_CONFIG	5
 
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-hw.h b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h
similarity index 100%
rename from drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-hw.h
rename to drivers/net/wireless/rtlwifi/rtl8192ce/hw.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-led.c b/drivers/net/wireless/rtlwifi/rtl8192ce/led.c
similarity index 98%
rename from drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-led.c
rename to drivers/net/wireless/rtlwifi/rtl8192ce/led.c
index 6091084..78a0569 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-led.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/led.c
@@ -29,8 +29,8 @@
 
 #include "../wifi.h"
 #include "../pci.h"
-#include "rtl8192c-reg.h"
-#include "rtl8192c-led.h"
+#include "reg.h"
+#include "led.h"
 
 void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
 {
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-led.h b/drivers/net/wireless/rtlwifi/rtl8192ce/led.h
similarity index 100%
rename from drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-led.h
rename to drivers/net/wireless/rtlwifi/rtl8192ce/led.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-phy.c b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c
similarity index 99%
rename from drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-phy.c
rename to drivers/net/wireless/rtlwifi/rtl8192ce/phy.c
index 13d7b38..4504411 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-phy.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c
@@ -30,12 +30,12 @@
 #include "../wifi.h"
 #include "../pci.h"
 #include "../ps.h"
-#include "rtl8192c-reg.h"
-#include "rtl8192c-def.h"
-#include "rtl8192c-phy.h"
-#include "rtl8192c-rf.h"
-#include "rtl8192c-dm.h"
-#include "rtl8192c-table.h"
+#include "reg.h"
+#include "def.h"
+#include "phy.h"
+#include "rf.h"
+#include "dm.h"
+#include "table.h"
 
 static u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw,
 					 enum radio_path rfpath, u32 offset);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-phy.h b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h
similarity index 100%
rename from drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-phy.h
rename to drivers/net/wireless/rtlwifi/rtl8192ce/phy.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-reg.h b/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h
similarity index 100%
rename from drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-reg.h
rename to drivers/net/wireless/rtlwifi/rtl8192ce/reg.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-rf.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c
similarity index 99%
rename from drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-rf.c
rename to drivers/net/wireless/rtlwifi/rtl8192ce/rf.c
index a2d58df..ffd8e04 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-rf.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c
@@ -28,11 +28,11 @@
  *****************************************************************************/
 
 #include "../wifi.h"
-#include "rtl8192c-reg.h"
-#include "rtl8192c-def.h"
-#include "rtl8192c-phy.h"
-#include "rtl8192c-rf.h"
-#include "rtl8192c-dm.h"
+#include "reg.h"
+#include "def.h"
+#include "phy.h"
+#include "rf.h"
+#include "dm.h"
 
 static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw);
 
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-rf.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h
similarity index 100%
rename from drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-rf.h
rename to drivers/net/wireless/rtlwifi/rtl8192ce/rf.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
similarity index 97%
rename from drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.c
rename to drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
index 4c76ad6..b366e88 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
@@ -32,14 +32,14 @@
 #include "../wifi.h"
 #include "../core.h"
 #include "../pci.h"
-#include "rtl8192c-reg.h"
-#include "rtl8192c-def.h"
-#include "rtl8192c-phy.h"
-#include "rtl8192c-dm.h"
-#include "rtl8192c-hw.h"
-#include "rtl8192c-sw.h"
-#include "rtl8192c-trx.h"
-#include "rtl8192c-led.h"
+#include "reg.h"
+#include "def.h"
+#include "phy.h"
+#include "dm.h"
+#include "hw.h"
+#include "sw.h"
+#include "trx.h"
+#include "led.h"
 
 int rtl92c_init_sw_vars(struct ieee80211_hw *hw)
 {
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.h b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h
similarity index 100%
rename from drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.h
rename to drivers/net/wireless/rtlwifi/rtl8192ce/sw.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-table.c b/drivers/net/wireless/rtlwifi/rtl8192ce/table.c
similarity index 99%
rename from drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-table.c
rename to drivers/net/wireless/rtlwifi/rtl8192ce/table.c
index 2a9bbbe..ba938b9 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-table.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/table.c
@@ -29,7 +29,7 @@
  *
  *****************************************************************************/
 
-#include "rtl8192c-table.h"
+#include "table.h"
 
 
 u32 RTL8192CEPHY_REG_2TARRAY[PHY_REG_2TARRAY_LENGTH] = {
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-table.h b/drivers/net/wireless/rtlwifi/rtl8192ce/table.h
similarity index 100%
rename from drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-table.h
rename to drivers/net/wireless/rtlwifi/rtl8192ce/table.h
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
similarity index 99%
rename from drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-trx.c
rename to drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
index cf35418..bf5852f 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
@@ -30,11 +30,11 @@
 #include "../wifi.h"
 #include "../pci.h"
 #include "../base.h"
-#include "rtl8192c-reg.h"
-#include "rtl8192c-def.h"
-#include "rtl8192c-phy.h"
-#include "rtl8192c-trx.h"
-#include "rtl8192c-led.h"
+#include "reg.h"
+#include "def.h"
+#include "phy.h"
+#include "trx.h"
+#include "led.h"
 
 static enum rtl_desc_qsel _rtl92ce_map_hwqueue_to_fwqueue(u16 fc,
 							  unsigned int
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-trx.h b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h
similarity index 100%
rename from drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-trx.h
rename to drivers/net/wireless/rtlwifi/rtl8192ce/trx.h
-- 
1.7.3.3


^ permalink raw reply related

* Re: [PATCH 04/17] rt2x00: fix hang when unplugging USB device in use
From: Ivo Van Doorn @ 2010-12-16 20:43 UTC (permalink / raw)
  To: Walter Goldens; +Cc: js, linux-wireless, users
In-Reply-To: <370262.79515.qm@web56806.mail.re3.yahoo.com>

Hi,

> Even with the latest patches, rmmod'ing the rt2xXXX stuff causes a complete system freeze. Unless I bring down the interface first via 'ifconfig wlanX down', unloading the driver while operational equates OS hang and hard reset.

Odd I have been testing this while stresstesting the card, and either
unplugging, rmmod or ifdown, and I couldn't
reproduce any crashes. Has the stacktrace changed after these patches?

Ivo

^ permalink raw reply

* Help with Libertas error
From: Matt Rosenthal @ 2010-12-16 20:32 UTC (permalink / raw)
  To: linux-wireless

Hi,
If possible can someone help point me in the right direction.  I am
building an embedded android device.  I am currently using the froyo
code base on the 2.6.32 Linux kernel.
My system works well but under some heave wifi loads the wifi stops
working.  I am using the Marvell 8686 wifi chip connected to a TI
OMAP3 processor.

The way to create the problem is to download large files over wifi or
continuously stream data over wifi.

Below is an error message I see on the console.
---------------------------------------------------------------------
libertas: Excessive timeouts submitting command 0x000b
libertas: PREP_CMD: command 0x000b failed: -110
libertas: PREP_CMD: command 0x000b failed: -110
libertas: requeueing command 0x000b due to timeout (#1)
libertas: command 0x000b timed out
libertas: requeueing command 0x000b due to timeout (#2)
libertas: command 0x000b timed out
libertas: requeueing command 0x000b due to timeout (#3)
libertas: command 0x000b timed out
libertas: Excessive timeouts submitting command 0x000b
libertas: PREP_CMD: command 0x000b failed: -110
libertas: command 0x000b timed out
libertas: requeueing command 0x000b due to timeout (#1)
libertas: command 0x000b timed out
libertas: requeueing command 0x000b due to timeout (#2)
libertas: command 0x000b timed out
libertas: requeueing command 0x000b due to timeout (#3)
libertas: command 0x000b timed out
libertas: Excessive timeouts submitting command 0x000b
libertas: PREP_CMD: command 0x000b failed: -110
libertas: command 0x000b timed out
libertas: requeueing command 0x000b due to timeout (#1)
libertas: command 0x000b timed out
libertas: requeueing command 0x000b due to timeout (#2)
libertas: command 0x000b timed out
libertas: requeueing command 0x000b due to timeout (#3)
------------------------------------------------------------------------

After this error message shows up the wifi no longer functions at all.
 Any help is much appreciated.
Thanks

Matt

-- 
Matthew Rosenthal
TPK USA, LLC
Touch Revolution BU

Confidentiality Disclaimer: This e-mail message and any attachments
are private communication sent by TPK USA LLC, and may contain
confidential, legally privileged information meant solely for the
intended recipient. If you are not the intended recipient, you are
hereby notified that any use, dissemination, distribution or copying
of this communication is strictly prohibited. Please notify the sender
immediately by replying to this message, then delete the e-mail and
any attachments from your system. Thank you.

^ permalink raw reply

* Compat-wireless release for 2010-12-16 is baked
From: Compat-wireless cronjob account @ 2010-12-16 20:04 UTC (permalink / raw)
  To: linux-wireless

>From git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next
   1e0e84f..03f2848  history    -> origin/history
 + e3d7018...46f736e master     -> origin/master  (forced update)
   3373c3d..a4851d8  stable     -> origin/stable
 * [new tag]         next-20101216 -> next-20101216

compat-wireless code metrics

    752909 - Total upstream lines of code being pulled
      2198 - backport code changes
      1935 - backport code additions
       263 - backport code deletions
      6639 - backport from compat module
      8837 - total backport code
    1.1737 - % of code consists of backport work
      1532 - Crap changes not yet posted
      1489 - Crap additions not yet posted
        43 - Crap deletions not yet posted
    0.2035 - % of crap code

Base tree: linux-next.git
Base tree version: next-20101216
compat-wireless release: compat-wireless-2010-12-10-3-g880bb0b-pc

^ permalink raw reply

* [RFT] rtlwifi: use alloc_workqueue
From: John W. Linville @ 2010-12-16 19:59 UTC (permalink / raw)
  To: linux-wireless; +Cc: Tejun Heo, Larry Finger, John W. Linville

create_workqueue is deprecated.  The workqueue usage does not seem to
demand any special treatment, so do not set any flags either.

Signed-off-by: John W. Linville <linville@tuxdriver.com>
---
I don't have the hardware to test...

 drivers/net/wireless/rtlwifi/base.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c
index 9e860ff..24a7cd3 100644
--- a/drivers/net/wireless/rtlwifi/base.c
+++ b/drivers/net/wireless/rtlwifi/base.c
@@ -225,7 +225,7 @@ static void _rtl_init_deferred_work(struct ieee80211_hw *hw)
 
 	/* <2> work queue */
 	rtlpriv->works.hw = hw;
-	rtlpriv->works.rtl_wq = create_workqueue(rtlpriv->cfg->name);
+	rtlpriv->works.rtl_wq = alloc_workqueue(rtlpriv->cfg->name, 0, 0);
 	INIT_DELAYED_WORK(&rtlpriv->works.watchdog_wq,
 			  (void *)rtl_watchdog_wq_callback);
 	INIT_DELAYED_WORK(&rtlpriv->works.ips_nic_off_wq,
-- 
1.7.3.3


^ permalink raw reply related

* Re: [PATCH] mac80211: Remove unused third address from mesh address extension header.
From: Javier Cardona @ 2010-12-16 19:58 UTC (permalink / raw)
  To: Johannes Berg; +Cc: John W. Linville, Steve Derosier, devel, linux-wireless
In-Reply-To: <1292525806.3612.31.camel@jlt3.sipsolutions.net>

Johannes,

On Thu, Dec 16, 2010 at 10:56 AM, Johannes Berg
<johannes@sipsolutions.net> wrote:
> On Thu, 2010-12-16 at 10:30 -0800, Javier Cardona wrote:
>> The Mesh Control header only includes 0, 1 or 2 addresses. If there is
>> one address, it should be interpreted as Address 4.  If there are 2,
>> they are interpreted as Addresses 5 and 6 (Address 4 being the 4th
>> address in the 802.11 header).
>
> Is this a draft change? Not sure I understand.

Yes, the address extension used to hold up to 3 addresses instead of
the current 2.  I don't recall the draft version when this changed,
but it is very unlikely that it will change again.  See section
7.1.3.6.3 in current draft (8.0).

Also, note that the extra address that I'm removing was not being
used.  I thought I better remove it before someone does start using
it.

Cheers,

Javier



-- 
Javier Cardona
cozybit Inc.
http://www.cozybit.com

^ permalink raw reply

* Re: [PATCH] mac80211: Push idle state to driver before stop
From: Luis R. Rodriguez @ 2010-12-16 19:12 UTC (permalink / raw)
  To: Paul Stewart
  Cc: Johannes Berg, linux-wireless@vger.kernel.org, Luis Rodriguez
In-Reply-To: <AANLkTimcALT7STVZyfgaWeCCpfCBM-tchZL94=ONLUL3@mail.gmail.com>

On Thu, Dec 16, 2010 at 11:08 AM, Paul Stewart <pstew@google.com> wrote:
> On Thu, Dec 16, 2010 at 9:44 AM, Luis R. Rodriguez
> <lrodriguez@atheros.com> wrote:
>> Try this:
>
> I'm now on vacation and thousands of miles (and more importantly a few
> firewalls) away from my build system.  If you want to know if this
> works before the end of the end of the year, you can try to replicate
> the conditions (scan active during ieee80211_do_stop()), otherwise we
> can go back to this next year.

2011 looks so futuristic, but yeah I'm sure this can wait, if I get a
chance maybe I'll try to hack my CR48 with my own kernel to test this.
We'll see I guess.

  Luis

^ permalink raw reply

* Re: [PATCH] mac80211: Push idle state to driver before stop
From: Paul Stewart @ 2010-12-16 19:08 UTC (permalink / raw)
  To: Luis R. Rodriguez
  Cc: Johannes Berg, linux-wireless@vger.kernel.org, Luis Rodriguez
In-Reply-To: <20101216174410.GB5677@tux>

On Thu, Dec 16, 2010 at 9:44 AM, Luis R. Rodriguez
<lrodriguez@atheros.com> wrote:
> Try this:

I'm now on vacation and thousands of miles (and more importantly a few
firewalls) away from my build system.  If you want to know if this
works before the end of the end of the year, you can try to replicate
the conditions (scan active during ieee80211_do_stop()), otherwise we
can go back to this next year.

--
Paul

^ permalink raw reply

* Re: [PATCH] mac80211: Remove unused third address from mesh address extension header.
From: Johannes Berg @ 2010-12-16 18:56 UTC (permalink / raw)
  To: Javier Cardona; +Cc: John W. Linville, Steve Derosier, devel, linux-wireless
In-Reply-To: <1292524241-14837-1-git-send-email-javier@cozybit.com>

On Thu, 2010-12-16 at 10:30 -0800, Javier Cardona wrote:
> The Mesh Control header only includes 0, 1 or 2 addresses. If there is
> one address, it should be interpreted as Address 4.  If there are 2,
> they are interpreted as Addresses 5 and 6 (Address 4 being the 4th
> address in the 802.11 header).

Is this a draft change? Not sure I understand.

johannes


^ permalink raw reply

* Re: [PATCH 3/3 v2] mac80211: Send mesh non-HWMP path selection frames to userspace
From: Johannes Berg @ 2010-12-16 18:56 UTC (permalink / raw)
  To: Javier Cardona; +Cc: John W. Linville, Steve Derosier, devel, linux-wireless
In-Reply-To: <1292524200-14791-3-git-send-email-javier@cozybit.com>

On Thu, 2010-12-16 at 10:30 -0800, Javier Cardona wrote:
> Let path selection frames for protocols other than HWMP be sent to
> userspace via NL80211_CMD_REGISTER_FRAME.  Also allow userspace to send
> and receive mesh path selection frames.

Looks fine, thanks.

johannes


^ permalink raw reply

* Re: [PATCH 2/3 v2] mac80211: Let userspace enable and configure vendor specific path selection.
From: Johannes Berg @ 2010-12-16 18:55 UTC (permalink / raw)
  To: Javier Cardona; +Cc: John W. Linville, Steve Derosier, devel, linux-wireless
In-Reply-To: <1292524200-14791-2-git-send-email-javier@cozybit.com>

On Thu, 2010-12-16 at 10:29 -0800, Javier Cardona wrote:

> +	ifmsh->vendor_ie_len = setup->vendor_ie_len;
> +	if (setup->vendor_ie_len) {
> +		new_ie = kmalloc(setup->vendor_ie_len, GFP_KERNEL);
> +		if (new_ie)
> +			new_ie = memcpy(new_ie, setup->vendor_ie,
> +					setup->vendor_ie_len);

kmemdup?


> @@ -287,6 +287,12 @@ void mesh_mgmt_ies_add(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
>  	*pos++ |= sdata->u.mesh.accepting_plinks ?
>  	    MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00;
>  	*pos++ = 0x00;
> +
> +	if (sdata->u.mesh.vendor_ie) {
> +		int len = sdata->u.mesh.vendor_ie_len;
> +		const u8 *data = sdata->u.mesh.vendor_ie;
> +		memcpy(skb_put(skb, len), data, len);
> +	}

don't you have to account for the size of these in the skb allocation?


> +	if (tb[NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE]) {
> +		setup->vendor_ie =
> +			nla_data(tb[NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE]);
> +		setup->vendor_ie_len =
> +			nla_len(tb[NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE]);

I think you should check that these are well-formed IEs, there's a
utility function for that somewhere.

johannes


^ permalink raw reply

* Re: [PATCH 1/3 v2] mac80211: Rename mesh_params to mesh_config to prepare for mesh_setup
From: Johannes Berg @ 2010-12-16 18:51 UTC (permalink / raw)
  To: Javier Cardona; +Cc: John W. Linville, Steve Derosier, devel, linux-wireless
In-Reply-To: <1292524200-14791-1-git-send-email-javier@cozybit.com>

On Thu, 2010-12-16 at 10:29 -0800, Javier Cardona wrote:

> -	NL80211_CMD_GET_MESH_PARAMS,
> -	NL80211_CMD_SET_MESH_PARAMS,
> +	NL80211_CMD_GET_MESH_CONFIG,
> +	NL80211_CMD_SET_MESH_CONFIG,
>  
>  	NL80211_CMD_SET_MGMT_EXTRA_IE /* reserved; not used */,
>  
> @@ -912,7 +912,7 @@ enum nl80211_attrs {
>  	NL80211_ATTR_REG_ALPHA2,
>  	NL80211_ATTR_REG_RULES,
>  
> -	NL80211_ATTR_MESH_PARAMS,
> +	NL80211_ATTR_MESH_CONFIG,

ack, but I think you should add #define's for the old names for backward
compatibility with existing code like iw?
 
johannes


^ permalink raw reply

* [PATCH] mac80211: Remove unused third address from mesh address extension header.
From: Javier Cardona @ 2010-12-16 18:30 UTC (permalink / raw)
  To: John W. Linville
  Cc: Javier Cardona, Steve Derosier, devel, Johannes Berg,
	linux-wireless

The Mesh Control header only includes 0, 1 or 2 addresses. If there is
one address, it should be interpreted as Address 4.  If there are 2,
they are interpreted as Addresses 5 and 6 (Address 4 being the 4th
address in the 802.11 header).

Signed-off-by: Javier Cardona <javier@cozybit.com>
---
 include/linux/ieee80211.h |    1 -
 net/mac80211/mesh.c       |   10 +++-------
 2 files changed, 3 insertions(+), 8 deletions(-)

diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index cd68168..6042228 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -536,7 +536,6 @@ struct ieee80211s_hdr {
 	__le32 seqnum;
 	u8 eaddr1[6];
 	u8 eaddr2[6];
-	u8 eaddr3[6];
 } __attribute__ ((packed));
 
 /* Mesh flags */
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 32d55d2..7de2119 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -423,6 +423,7 @@ int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr,
 		char *addr5, char *addr6)
 {
 	int aelen = 0;
+	BUG_ON(addr4 && addr5 && addr6);
 	memset(meshhdr, 0, sizeof(*meshhdr));
 	meshhdr->ttl = sdata->u.mesh.mshcfg.dot11MeshTTL;
 	put_unaligned(cpu_to_le32(sdata->u.mesh.mesh_seqnum), &meshhdr->seqnum);
@@ -435,13 +436,8 @@ int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr,
 	if (addr5 && addr6) {
 		meshhdr->flags |= MESH_FLAGS_AE_A5_A6;
 		aelen += 2 * ETH_ALEN;
-		if (!addr4) {
-			memcpy(meshhdr->eaddr1, addr5, ETH_ALEN);
-			memcpy(meshhdr->eaddr2, addr6, ETH_ALEN);
-		} else {
-			memcpy(meshhdr->eaddr2, addr5, ETH_ALEN);
-			memcpy(meshhdr->eaddr3, addr6, ETH_ALEN);
-		}
+		memcpy(meshhdr->eaddr1, addr5, ETH_ALEN);
+		memcpy(meshhdr->eaddr2, addr6, ETH_ALEN);
 	}
 	return 6 + aelen;
 }
-- 
1.7.1


^ permalink raw reply related

* [PATCH 2/3 v2] mac80211: Let userspace enable and configure vendor specific path selection.
From: Javier Cardona @ 2010-12-16 18:29 UTC (permalink / raw)
  To: John W. Linville
  Cc: Javier Cardona, Steve Derosier, devel, Johannes Berg,
	linux-wireless
In-Reply-To: <1292234643.3539.6.camel@jlt3.sipsolutions.net>

Userspace will now be allowed to toggle between the default path
selection algorithm (HWMP, implemented in the kernel), and a vendor
specific alternative.  Also in the same patch, allow userspace to add
information elements to mesh beacons.  This is accordance with the
Extensible Path Selection Framework specified in version 7.0 of the
802.11s draft.

Signed-off-by: Javier Cardona <javier@cozybit.com>
---
v2: - don't substruct vendor_ie and mark as const (Johannes)
    - move vendor_ie to mesh_setup (Johannes)
    - rename MESH_PATH_* -> IEEE80211_PATH_* (Johannes)
    - define a new nested attribute NL80211_ATTR_MESH_SETUP for mesh setup
      parameters

 include/linux/ieee80211.h  |   25 ++++++++++++++++++
 include/linux/nl80211.h    |   47 +++++++++++++++++++++++++++++++---
 include/net/cfg80211.h     |    8 ++++++
 net/mac80211/cfg.c         |   41 ++++++++++++++++++++++++++---
 net/mac80211/ieee80211_i.h |    2 +
 net/mac80211/mesh.c        |    6 ++++
 net/wireless/core.c        |   22 +++++++++++----
 net/wireless/core.h        |    5 ++-
 net/wireless/mesh.c        |   24 +++++++++--------
 net/wireless/nl80211.c     |   61 ++++++++++++++++++++++++++++++++++++++++---
 10 files changed, 209 insertions(+), 32 deletions(-)

diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 7f23545..cd68168 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -1291,6 +1291,31 @@ enum ieee80211_key_len {
 	WLAN_KEY_LEN_AES_CMAC = 16,
 };
 
+/**
+ * enum - mesh path selection protocol identifier
+ *
+ * @IEEE80211_PATH_PROTOCOL_HWMP: the default path selection protocol
+ * @IEEE80211_PATH_PROTOCOL_VENDOR: a vendor specific protocol that will
+ * be specified in a vendor specific information element
+ */
+enum {
+	IEEE80211_PATH_PROTOCOL_HWMP = 0,
+	IEEE80211_PATH_PROTOCOL_VENDOR = 255,
+};
+
+/**
+ * enum - mesh path selection metric identifier
+ *
+ * @IEEE80211_PATH_METRIC_AIRTIME: the default path selection metric
+ * @IEEE80211_PATH_METRIC_VENDOR: a vendor specific metric that will be
+ * specified in a vendor specific information element
+ */
+enum {
+	IEEE80211_PATH_METRIC_AIRTIME = 0,
+	IEEE80211_PATH_METRIC_VENDOR = 255,
+};
+
+
 /*
  * IEEE 802.11-2007 7.3.2.9 Country information element
  *
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 1d677c0..93d48fd 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -858,6 +858,9 @@ enum nl80211_commands {
  *	attributes, specifying what a key should be set as default as.
  *	See &enum nl80211_key_default_types.
  *
+ * @NL80211_ATTR_MESH_SETUP: Optional mesh setup parameters.  These cannot be
+ * changed once the mesh is active.
+ *
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
  */
@@ -1040,6 +1043,8 @@ enum nl80211_attrs {
 
 	NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION,
 
+	NL80211_ATTR_MESH_SETUP,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
@@ -1549,7 +1554,8 @@ enum nl80211_mntr_flags {
 /**
  * enum nl80211_meshconf_params - mesh configuration parameters
  *
- * Mesh configuration parameters
+ * Mesh configuration parameters. These can be changed while the mesh is
+ * active.
  *
  * @__NL80211_MESHCONF_INVALID: internal use
  *
@@ -1572,9 +1578,6 @@ enum nl80211_mntr_flags {
  * @NL80211_MESHCONF_TTL: specifies the value of TTL field set at a source mesh
  * point.
  *
- * @NL80211_MESHCONF_ELEMENT_TTL: specifies the value of TTL field set at a
- * source mesh point for path selection elements.
- *
  * @NL80211_MESHCONF_AUTO_OPEN_PLINKS: whether we should automatically
  * open peer links when we detect compatible mesh peers.
  *
@@ -1601,6 +1604,9 @@ enum nl80211_mntr_flags {
  *
  * @NL80211_MESHCONF_ROOTMODE: whether root mode is enabled or not
  *
+ * @NL80211_MESHCONF_ELEMENT_TTL: specifies the value of TTL field set at a
+ * source mesh point for path selection elements.
+ *
  * @NL80211_MESHCONF_ATTR_MAX: highest possible mesh configuration attribute
  *
  * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use
@@ -1629,6 +1635,39 @@ enum nl80211_meshconf_params {
 };
 
 /**
+ * enum nl80211_mesh_setup_params - mesh setup parameters
+ *
+ * Mesh setup parameters.  These are used to start/join a mesh and cannot be
+ * changed while the mesh is active.
+ *
+ * @__NL80211_MESH_SETUP_INVALID: Internal use
+ *
+ * @NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL: Enable this option to use a
+ * vendor specific path selection algorithm or disable it to use the default
+ * HWMP.
+ *
+ * @NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC: Enable this option to use a
+ * vendor specific path metric or disable it to use the default Airtime
+ * metric.
+ *
+ * @NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE: A vendor specific information
+ * element that vendors will use to identify the path selection methods and
+ * metrics in use.
+ *
+ * @__NL80211_MESH_SETUP_ATTR_AFTER_LAST: Internal use
+ */
+enum nl80211_mesh_setup_params {
+	__NL80211_MESH_SETUP_INVALID,
+	NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL,
+	NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC,
+	NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE,
+
+	/* keep last */
+	__NL80211_MESH_SETUP_ATTR_AFTER_LAST,
+	NL80211_MESH_SETUP_ATTR_MAX = __NL80211_MESH_SETUP_ATTR_AFTER_LAST - 1
+};
+
+/**
  * enum nl80211_txq_attr - TX queue parameter attributes
  * @__NL80211_TXQ_ATTR_INVALID: Attribute number 0 is reserved
  * @NL80211_TXQ_ATTR_QUEUE: TX queue identifier (NL80211_TXQ_Q_*)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 1bac74a..a6041a7 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -649,12 +649,20 @@ struct mesh_config {
  * struct mesh_setup - 802.11s mesh setup configuration
  * @mesh_id: the mesh ID
  * @mesh_id_len: length of the mesh ID, at least 1 and at most 32 bytes
+ * @path_sel_proto: which path selection protocol to use
+ * @path_metric: which metric to use
+ * @vendor_ie: vendor information elements (optional)
+ * @vendor_ie_len: length of vendor information elements
  *
  * These parameters are fixed when the mesh is created.
  */
 struct mesh_setup {
 	const u8 *mesh_id;
 	u8 mesh_id_len;
+	u8  path_sel_proto;
+	u8  path_metric;
+	const u8 *vendor_ie;
+	u8 vendor_ie_len;
 };
 
 /**
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 1c94a2a..6cdf113 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1000,6 +1000,38 @@ static inline bool _chg_mesh_attr(enum nl80211_meshconf_params parm, u32 mask)
 	return (mask >> (parm-1)) & 0x1;
 }
 
+static int copy_mesh_setup(struct ieee80211_if_mesh *ifmsh,
+		const struct mesh_setup *setup)
+{
+	u8 *new_ie;
+	const u8 *old_ie;
+
+	/* first allocate the new vendor information element */
+	new_ie = NULL;
+	old_ie = setup->vendor_ie;
+
+	ifmsh->vendor_ie_len = setup->vendor_ie_len;
+	if (setup->vendor_ie_len) {
+		new_ie = kmalloc(setup->vendor_ie_len, GFP_KERNEL);
+		if (new_ie)
+			new_ie = memcpy(new_ie, setup->vendor_ie,
+					setup->vendor_ie_len);
+		else
+			return -ENOMEM;
+	}
+
+	/* now copy the rest of the setup parameters */
+	ifmsh->mesh_id_len = setup->mesh_id_len;
+	memcpy(ifmsh->mesh_id, setup->mesh_id, ifmsh->mesh_id_len);
+	ifmsh->mesh_pp_id = setup->path_sel_proto;
+	ifmsh->mesh_pm_id = setup->path_metric;
+	ifmsh->vendor_ie = new_ie;
+
+	kfree(old_ie);
+
+	return 0;
+}
+
 static int ieee80211_update_mesh_config(struct wiphy *wiphy,
 					struct net_device *dev, u32 mask,
 					const struct mesh_config *nconf)
@@ -1059,11 +1091,12 @@ static int ieee80211_join_mesh(struct wiphy *wiphy, struct net_device *dev,
 {
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 	struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
+	int err;
 
-	memcpy(&sdata->u.mesh.mshcfg, conf, sizeof(struct mesh_config));
-	ifmsh->mesh_id_len = setup->mesh_id_len;
-	memcpy(ifmsh->mesh_id, setup->mesh_id, ifmsh->mesh_id_len);
-
+	memcpy(&ifmsh->mshcfg, conf, sizeof(struct mesh_config));
+	err = copy_mesh_setup(ifmsh, setup);
+	if (err)
+		return err;
 	ieee80211_start_mesh(sdata);
 
 	return 0;
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 0817ec6..cc7c367 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -485,6 +485,8 @@ struct ieee80211_if_mesh {
 	struct mesh_config mshcfg;
 	u32 mesh_seqnum;
 	bool accepting_plinks;
+	const u8 *vendor_ie;
+	u8 vendor_ie_len;
 };
 
 #ifdef CONFIG_MAC80211_MESH
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 63e1188..03430df 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -287,6 +287,12 @@ void mesh_mgmt_ies_add(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
 	*pos++ |= sdata->u.mesh.accepting_plinks ?
 	    MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00;
 	*pos++ = 0x00;
+
+	if (sdata->u.mesh.vendor_ie) {
+		int len = sdata->u.mesh.vendor_ie_len;
+		const u8 *data = sdata->u.mesh.vendor_ie;
+		memcpy(skb_put(skb, len), data, len);
+	}
 }
 
 u32 mesh_table_hash(u8 *addr, struct ieee80211_sub_if_data *sdata, struct mesh_table *tbl)
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 79772fc..e9a5f8c 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -789,13 +789,23 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
 			cfg80211_mgd_wext_connect(rdev, wdev);
 			break;
 #endif
+#ifdef CONFIG_MAC80211_MESH
 		case NL80211_IFTYPE_MESH_POINT:
-			/* backward compat code ... */
-			if (wdev->mesh_id_up_len)
-				__cfg80211_join_mesh(rdev, dev, wdev->ssid,
-						     wdev->mesh_id_up_len,
-						     &default_mesh_config);
-			break;
+			{
+				/* backward compat code... */
+				struct mesh_setup setup;
+				memcpy(&setup, &default_mesh_setup,
+						sizeof(setup));
+				 /* back compat only needed for mesh_id */
+				setup.mesh_id = wdev->ssid;
+				setup.mesh_id_len = wdev->mesh_id_up_len;
+				if (wdev->mesh_id_up_len)
+					__cfg80211_join_mesh(rdev, dev,
+							&setup,
+							&default_mesh_config);
+				break;
+			}
+#endif
 		default:
 			break;
 		}
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 743203b..26a0a08 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -287,13 +287,14 @@ int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
 
 /* mesh */
 extern const struct mesh_config default_mesh_config;
+extern const struct mesh_setup default_mesh_setup;
 int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
 			 struct net_device *dev,
-			 const u8 *mesh_id, u8 mesh_id_len,
+			 const struct mesh_setup *setup,
 			 const struct mesh_config *conf);
 int cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
 		       struct net_device *dev,
-		       const u8 *mesh_id, u8 mesh_id_len,
+		       const struct mesh_setup *setup,
 		       const struct mesh_config *conf);
 int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
 			struct net_device *dev);
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index e0b9747..73e39c1 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -50,17 +50,19 @@ const struct mesh_config default_mesh_config = {
 	.min_discovery_timeout = MESH_MIN_DISCOVERY_TIMEOUT,
 };
 
+const struct mesh_setup default_mesh_setup = {
+	.path_sel_proto = IEEE80211_PATH_PROTOCOL_HWMP,
+	.path_metric = IEEE80211_PATH_METRIC_AIRTIME,
+	.vendor_ie = NULL,
+	.vendor_ie_len = 0,
+};
 
 int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
 			 struct net_device *dev,
-			 const u8 *mesh_id, u8 mesh_id_len,
+			 const struct mesh_setup *setup,
 			 const struct mesh_config *conf)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
-	struct mesh_setup setup = {
-		.mesh_id = mesh_id,
-		.mesh_id_len = mesh_id_len,
-	};
 	int err;
 
 	BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN != IEEE80211_MAX_MESH_ID_LEN);
@@ -73,16 +75,16 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
 	if (wdev->mesh_id_len)
 		return -EALREADY;
 
-	if (!mesh_id_len)
+	if (!setup->mesh_id_len)
 		return -EINVAL;
 
 	if (!rdev->ops->join_mesh)
 		return -EOPNOTSUPP;
 
-	err = rdev->ops->join_mesh(&rdev->wiphy, dev, conf, &setup);
+	err = rdev->ops->join_mesh(&rdev->wiphy, dev, conf, setup);
 	if (!err) {
-		memcpy(wdev->ssid, mesh_id, mesh_id_len);
-		wdev->mesh_id_len = mesh_id_len;
+		memcpy(wdev->ssid, setup->mesh_id, setup->mesh_id_len);
+		wdev->mesh_id_len = setup->mesh_id_len;
 	}
 
 	return err;
@@ -90,14 +92,14 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
 
 int cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
 		       struct net_device *dev,
-		       const u8 *mesh_id, u8 mesh_id_len,
+		       const struct mesh_setup *setup,
 		       const struct mesh_config *conf)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	int err;
 
 	wdev_lock(wdev);
-	err = __cfg80211_join_mesh(rdev, dev, mesh_id, mesh_id_len, conf);
+	err = __cfg80211_join_mesh(rdev, dev, setup, conf);
 	wdev_unlock(wdev);
 
 	return err;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index d783dca..b4dc191 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -2773,6 +2773,14 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A
 	[NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 },
 };
 
+static const struct nla_policy
+	nl80211_mesh_setup_params_policy[NL80211_MESH_SETUP_ATTR_MAX+1] = {
+	[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 },
+	[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 },
+	[NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE] = { .type = NLA_BINARY,
+		.len = IEEE80211_MAX_DATA_LEN },
+};
+
 static int nl80211_parse_mesh_config(struct genl_info *info,
 				     struct mesh_config *cfg,
 				     u32 *mask_out)
@@ -2839,14 +2847,48 @@ do {\
 			dot11MeshHWMPRootMode, mask,
 			NL80211_MESHCONF_HWMP_ROOTMODE,
 			nla_get_u8);
-
 	if (mask_out)
 		*mask_out = mask;
+
 	return 0;
 
 #undef FILL_IN_MESH_PARAM_IF_SET
 }
 
+static int nl80211_parse_mesh_setup(struct genl_info *info,
+				     struct mesh_setup *setup)
+{
+	struct nlattr *tb[NL80211_MESH_SETUP_ATTR_MAX + 1];
+
+	if (!info->attrs[NL80211_ATTR_MESH_SETUP])
+		return -EINVAL;
+	if (nla_parse_nested(tb, NL80211_MESH_SETUP_ATTR_MAX,
+			     info->attrs[NL80211_ATTR_MESH_SETUP],
+			     nl80211_mesh_setup_params_policy))
+		return -EINVAL;
+
+	if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])
+		setup->path_sel_proto =
+		(nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])) ?
+		 IEEE80211_PATH_PROTOCOL_VENDOR :
+		 IEEE80211_PATH_PROTOCOL_HWMP;
+
+	if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC])
+		setup->path_metric =
+		(nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC])) ?
+		 IEEE80211_PATH_METRIC_VENDOR :
+		 IEEE80211_PATH_METRIC_AIRTIME;
+
+	if (tb[NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE]) {
+		setup->vendor_ie =
+			nla_data(tb[NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE]);
+		setup->vendor_ie_len =
+			nla_len(tb[NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE]);
+	}
+
+	return 0;
+}
+
 static int nl80211_update_mesh_config(struct sk_buff *skb,
 				      struct genl_info *info)
 {
@@ -4667,10 +4709,12 @@ static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
 	struct net_device *dev = info->user_ptr[1];
 	struct mesh_config cfg;
+	struct mesh_setup setup;
 	int err;
 
 	/* start with default */
 	memcpy(&cfg, &default_mesh_config, sizeof(cfg));
+	memcpy(&setup, &default_mesh_setup, sizeof(setup));
 
 	if (info->attrs[NL80211_ATTR_MESH_CONFIG]) {
 		/* and parse parameters if given */
@@ -4683,10 +4727,17 @@ static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
 	    !nla_len(info->attrs[NL80211_ATTR_MESH_ID]))
 		return -EINVAL;
 
-	return cfg80211_join_mesh(rdev, dev,
-				  nla_data(info->attrs[NL80211_ATTR_MESH_ID]),
-				  nla_len(info->attrs[NL80211_ATTR_MESH_ID]),
-				  &cfg);
+	setup.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
+	setup.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
+
+	if (info->attrs[NL80211_ATTR_MESH_SETUP]) {
+		/* parse additional setup parameters if given */
+		err = nl80211_parse_mesh_setup(info, &setup);
+		if (err)
+			return err;
+	}
+
+	return cfg80211_join_mesh(rdev, dev, &setup, &cfg);
 }
 
 static int nl80211_leave_mesh(struct sk_buff *skb, struct genl_info *info)
-- 
1.7.1


^ permalink raw reply related

* [PATCH 3/3 v2] mac80211: Send mesh non-HWMP path selection frames to userspace
From: Javier Cardona @ 2010-12-16 18:30 UTC (permalink / raw)
  To: John W. Linville
  Cc: Javier Cardona, Steve Derosier, devel, Johannes Berg,
	linux-wireless
In-Reply-To: <1292234643.3539.6.camel@jlt3.sipsolutions.net>

Let path selection frames for protocols other than HWMP be sent to
userspace via NL80211_CMD_REGISTER_FRAME.  Also allow userspace to send
and receive mesh path selection frames.

Signed-off-by: Javier Cardona <javier@cozybit.com>
---
v2: - update patch description (Johannes)
    - remove mesh_ids_set_default and initialize ids in start_mesh (Johannes)
    - More elegant check for mesh_path_sel_is_hwmp (Johannes)

 net/mac80211/cfg.c     |    1 +
 net/mac80211/main.c    |    4 ++++
 net/mac80211/mesh.c    |   13 +++----------
 net/mac80211/mesh.h    |    7 +++++++
 net/mac80211/rx.c      |    5 ++++-
 net/wireless/nl80211.c |    2 ++
 6 files changed, 21 insertions(+), 11 deletions(-)

diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 6cdf113..969f888 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1672,6 +1672,7 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
 	case NL80211_IFTYPE_AP:
 	case NL80211_IFTYPE_AP_VLAN:
 	case NL80211_IFTYPE_P2P_GO:
+	case NL80211_IFTYPE_MESH_POINT:
 		if (!ieee80211_is_action(mgmt->frame_control) ||
 		    mgmt->u.action.category == WLAN_CATEGORY_PUBLIC)
 			break;
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index a9454cb..bbe8e0a 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -484,6 +484,10 @@ ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
 			BIT(IEEE80211_STYPE_DEAUTH >> 4) |
 			BIT(IEEE80211_STYPE_ACTION >> 4),
 	},
+	[NL80211_IFTYPE_MESH_POINT] = {
+		.tx = 0xffff,
+		.rx = BIT(IEEE80211_STYPE_ACTION >> 4),
+	},
 };
 
 struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 03430df..32d55d2 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -124,15 +124,6 @@ void mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata)
 		ieee80211_mesh_housekeeping_timer((unsigned long) sdata);
 }
 
-void mesh_ids_set_default(struct ieee80211_if_mesh *sta)
-{
-	sta->mesh_pp_id = 0;	/* HWMP */
-	sta->mesh_pm_id = 0;	/* Airtime */
-	sta->mesh_cc_id = 0;	/* Disabled */
-	sta->mesh_sp_id = 0;	/* Neighbor Offset */
-	sta->mesh_auth_id = 0;	/* Disabled */
-}
-
 int mesh_rmc_init(struct ieee80211_sub_if_data *sdata)
 {
 	int i;
@@ -524,6 +515,9 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
 	atomic_inc(&local->iff_allmultis);
 	ieee80211_configure_filter(local);
 
+	ifmsh->mesh_cc_id = 0;	/* Disabled */
+	ifmsh->mesh_sp_id = 0;	/* Neighbor Offset */
+	ifmsh->mesh_auth_id = 0;	/* Disabled */
 	set_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags);
 	ieee80211_mesh_root_setup(ifmsh);
 	ieee80211_queue_work(&local->hw, &sdata->work);
@@ -694,7 +688,6 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
 	/* Allocate all mesh structures when creating the first mesh interface. */
 	if (!mesh_allocated)
 		ieee80211s_init();
-	mesh_ids_set_default(ifmsh);
 	setup_timer(&ifmsh->mesh_path_timer,
 		    ieee80211_mesh_path_timer,
 		    (unsigned long) sdata);
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 5b828fa..890dd19 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -284,6 +284,11 @@ static inline void mesh_path_activate(struct mesh_path *mpath)
 	mpath->flags |= MESH_PATH_ACTIVE | MESH_PATH_RESOLVED;
 }
 
+static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata)
+{
+	return sdata->u.mesh.mesh_pp_id == IEEE80211_PATH_PROTOCOL_HWMP;
+}
+
 #define for_each_mesh_entry(x, p, node, i) \
 	for (i = 0; i <= x->hash_mask; i++) \
 		hlist_for_each_entry_rcu(node, p, &x->hash_buckets[i], list)
@@ -304,6 +309,8 @@ static inline void ieee80211_mesh_restart(struct ieee80211_sub_if_data *sdata)
 {}
 static inline void mesh_plink_quiesce(struct sta_info *sta) {}
 static inline void mesh_plink_restart(struct sta_info *sta) {}
+static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata)
+{ return false; }
 #endif
 
 #endif /* IEEE80211S_H */
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index f39524b..cdbc824 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2143,10 +2143,13 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
 		}
 		break;
 	case WLAN_CATEGORY_MESH_PLINK:
-	case WLAN_CATEGORY_MESH_PATH_SEL:
 		if (!ieee80211_vif_is_mesh(&sdata->vif))
 			break;
 		goto queue;
+	case WLAN_CATEGORY_MESH_PATH_SEL:
+		if (!mesh_path_sel_is_hwmp(sdata))
+			break;
+		goto queue;
 	}
 
 	return RX_CONTINUE;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index b4dc191..98f276f 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -4443,6 +4443,7 @@ static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info)
 	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT &&
 	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
 	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
+	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
 	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
 		return -EOPNOTSUPP;
 
@@ -4483,6 +4484,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
 	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT &&
 	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
 	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
+	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
 	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
 		return -EOPNOTSUPP;
 
-- 
1.7.1


^ permalink raw reply related

* [PATCH 1/3 v2] mac80211: Rename mesh_params to mesh_config to prepare for mesh_setup
From: Javier Cardona @ 2010-12-16 18:29 UTC (permalink / raw)
  To: John W. Linville
  Cc: Javier Cardona, Steve Derosier, devel, Johannes Berg,
	linux-wireless
In-Reply-To: <1292234643.3539.6.camel@jlt3.sipsolutions.net>

Mesh parameters can be to setup a mesh or to configure it.
This patch renames the ambiguous name mesh_params to mesh_config
in preparation for mesh_setup (introduced in next patch).

Signed-off-by: Javier Cardona <javier@cozybit.com>
---
v2: - separate mesh config and setup parametres and split the original patch

 include/linux/nl80211.h |   10 +++++-----
 include/net/cfg80211.h  |    8 ++++----
 net/mac80211/cfg.c      |    8 ++++----
 net/wireless/nl80211.c  |   40 ++++++++++++++++++++--------------------
 4 files changed, 33 insertions(+), 33 deletions(-)

diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 1cee56b..1d677c0 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -172,10 +172,10 @@
  * 	to the specified ISO/IEC 3166-1 alpha2 country code. The core will
  * 	store this as a valid request and then query userspace for it.
  *
- * @NL80211_CMD_GET_MESH_PARAMS: Get mesh networking properties for the
+ * @NL80211_CMD_GET_MESH_CONFIG: Get mesh networking properties for the
  *	interface identified by %NL80211_ATTR_IFINDEX
  *
- * @NL80211_CMD_SET_MESH_PARAMS: Set mesh networking properties for the
+ * @NL80211_CMD_SET_MESH_CONFIG: Set mesh networking properties for the
  *      interface identified by %NL80211_ATTR_IFINDEX
  *
  * @NL80211_CMD_SET_MGMT_EXTRA_IE: Set extra IEs for management frames. The
@@ -441,8 +441,8 @@ enum nl80211_commands {
 	NL80211_CMD_SET_REG,
 	NL80211_CMD_REQ_SET_REG,
 
-	NL80211_CMD_GET_MESH_PARAMS,
-	NL80211_CMD_SET_MESH_PARAMS,
+	NL80211_CMD_GET_MESH_CONFIG,
+	NL80211_CMD_SET_MESH_CONFIG,
 
 	NL80211_CMD_SET_MGMT_EXTRA_IE /* reserved; not used */,
 
@@ -912,7 +912,7 @@ enum nl80211_attrs {
 	NL80211_ATTR_REG_ALPHA2,
 	NL80211_ATTR_REG_RULES,
 
-	NL80211_ATTR_MESH_PARAMS,
+	NL80211_ATTR_MESH_CONFIG,
 
 	NL80211_ATTR_BSS_BASIC_RATES,
 
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index f45e15f..1bac74a 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1096,9 +1096,9 @@ struct cfg80211_pmksa {
  * @get_mpath: get a mesh path for the given parameters
  * @dump_mpath: dump mesh path callback -- resume dump at index @idx
  *
- * @get_mesh_params: Put the current mesh parameters into *params
+ * @get_mesh_config: Get the current mesh configuration
  *
- * @update_mesh_params: Update mesh parameters on a running mesh.
+ * @update_mesh_config: Update mesh parameters on a running mesh.
  *	The mask is a bitfield which tells us which parameters to
  *	set, and which to leave alone.
  *
@@ -1246,10 +1246,10 @@ struct cfg80211_ops {
 	int	(*dump_mpath)(struct wiphy *wiphy, struct net_device *dev,
 			       int idx, u8 *dst, u8 *next_hop,
 			       struct mpath_info *pinfo);
-	int	(*get_mesh_params)(struct wiphy *wiphy,
+	int	(*get_mesh_config)(struct wiphy *wiphy,
 				struct net_device *dev,
 				struct mesh_config *conf);
-	int	(*update_mesh_params)(struct wiphy *wiphy,
+	int	(*update_mesh_config)(struct wiphy *wiphy,
 				      struct net_device *dev, u32 mask,
 				      const struct mesh_config *nconf);
 	int	(*join_mesh)(struct wiphy *wiphy, struct net_device *dev,
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index ea06f92..1c94a2a 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -984,7 +984,7 @@ static int ieee80211_dump_mpath(struct wiphy *wiphy, struct net_device *dev,
 	return 0;
 }
 
-static int ieee80211_get_mesh_params(struct wiphy *wiphy,
+static int ieee80211_get_mesh_config(struct wiphy *wiphy,
 				struct net_device *dev,
 				struct mesh_config *conf)
 {
@@ -1000,7 +1000,7 @@ static inline bool _chg_mesh_attr(enum nl80211_meshconf_params parm, u32 mask)
 	return (mask >> (parm-1)) & 0x1;
 }
 
-static int ieee80211_update_mesh_params(struct wiphy *wiphy,
+static int ieee80211_update_mesh_config(struct wiphy *wiphy,
 					struct net_device *dev, u32 mask,
 					const struct mesh_config *nconf)
 {
@@ -1787,8 +1787,8 @@ struct cfg80211_ops mac80211_config_ops = {
 	.change_mpath = ieee80211_change_mpath,
 	.get_mpath = ieee80211_get_mpath,
 	.dump_mpath = ieee80211_dump_mpath,
-	.update_mesh_params = ieee80211_update_mesh_params,
-	.get_mesh_params = ieee80211_get_mesh_params,
+	.update_mesh_config = ieee80211_update_mesh_config,
+	.get_mesh_config = ieee80211_get_mesh_config,
 	.join_mesh = ieee80211_join_mesh,
 	.leave_mesh = ieee80211_leave_mesh,
 #endif
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 594a6ac..d783dca 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -123,7 +123,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
 					   .len = NL80211_MAX_SUPP_RATES },
 	[NL80211_ATTR_BSS_HT_OPMODE] = { .type = NLA_U16 },
 
-	[NL80211_ATTR_MESH_PARAMS] = { .type = NLA_NESTED },
+	[NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED },
 
 	[NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY,
 					 .len = NL80211_HT_CAPABILITY_LEN },
@@ -719,7 +719,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
 	CMD(add_beacon, NEW_BEACON);
 	CMD(add_station, NEW_STATION);
 	CMD(add_mpath, NEW_MPATH);
-	CMD(update_mesh_params, SET_MESH_PARAMS);
+	CMD(update_mesh_config, SET_MESH_CONFIG);
 	CMD(change_bss, SET_BSS);
 	CMD(auth, AUTHENTICATE);
 	CMD(assoc, ASSOCIATE);
@@ -2673,7 +2673,7 @@ static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
 	return r;
 }
 
-static int nl80211_get_mesh_params(struct sk_buff *skb,
+static int nl80211_get_mesh_config(struct sk_buff *skb,
 				   struct genl_info *info)
 {
 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -2688,7 +2688,7 @@ static int nl80211_get_mesh_params(struct sk_buff *skb,
 	if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
 		return -EOPNOTSUPP;
 
-	if (!rdev->ops->get_mesh_params)
+	if (!rdev->ops->get_mesh_config)
 		return -EOPNOTSUPP;
 
 	wdev_lock(wdev);
@@ -2696,7 +2696,7 @@ static int nl80211_get_mesh_params(struct sk_buff *skb,
 	if (!wdev->mesh_id_len)
 		memcpy(&cur_params, &default_mesh_config, sizeof(cur_params));
 	else
-		err = rdev->ops->get_mesh_params(&rdev->wiphy, dev,
+		err = rdev->ops->get_mesh_config(&rdev->wiphy, dev,
 						 &cur_params);
 	wdev_unlock(wdev);
 
@@ -2708,10 +2708,10 @@ static int nl80211_get_mesh_params(struct sk_buff *skb,
 	if (!msg)
 		return -ENOMEM;
 	hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
-			     NL80211_CMD_GET_MESH_PARAMS);
+			     NL80211_CMD_GET_MESH_CONFIG);
 	if (!hdr)
 		goto nla_put_failure;
-	pinfoattr = nla_nest_start(msg, NL80211_ATTR_MESH_PARAMS);
+	pinfoattr = nla_nest_start(msg, NL80211_ATTR_MESH_CONFIG);
 	if (!pinfoattr)
 		goto nla_put_failure;
 	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
@@ -2773,7 +2773,7 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A
 	[NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 },
 };
 
-static int nl80211_parse_mesh_params(struct genl_info *info,
+static int nl80211_parse_mesh_config(struct genl_info *info,
 				     struct mesh_config *cfg,
 				     u32 *mask_out)
 {
@@ -2789,10 +2789,10 @@ do {\
 } while (0);\
 
 
-	if (!info->attrs[NL80211_ATTR_MESH_PARAMS])
+	if (!info->attrs[NL80211_ATTR_MESH_CONFIG])
 		return -EINVAL;
 	if (nla_parse_nested(tb, NL80211_MESHCONF_ATTR_MAX,
-			     info->attrs[NL80211_ATTR_MESH_PARAMS],
+			     info->attrs[NL80211_ATTR_MESH_CONFIG],
 			     nl80211_meshconf_params_policy))
 		return -EINVAL;
 
@@ -2847,7 +2847,7 @@ do {\
 #undef FILL_IN_MESH_PARAM_IF_SET
 }
 
-static int nl80211_update_mesh_params(struct sk_buff *skb,
+static int nl80211_update_mesh_config(struct sk_buff *skb,
 				      struct genl_info *info)
 {
 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -2860,10 +2860,10 @@ static int nl80211_update_mesh_params(struct sk_buff *skb,
 	if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
 		return -EOPNOTSUPP;
 
-	if (!rdev->ops->update_mesh_params)
+	if (!rdev->ops->update_mesh_config)
 		return -EOPNOTSUPP;
 
-	err = nl80211_parse_mesh_params(info, &cfg, &mask);
+	err = nl80211_parse_mesh_config(info, &cfg, &mask);
 	if (err)
 		return err;
 
@@ -2872,7 +2872,7 @@ static int nl80211_update_mesh_params(struct sk_buff *skb,
 		err = -ENOLINK;
 
 	if (!err)
-		err = rdev->ops->update_mesh_params(&rdev->wiphy, dev,
+		err = rdev->ops->update_mesh_config(&rdev->wiphy, dev,
 						    mask, &cfg);
 
 	wdev_unlock(wdev);
@@ -4672,9 +4672,9 @@ static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
 	/* start with default */
 	memcpy(&cfg, &default_mesh_config, sizeof(cfg));
 
-	if (info->attrs[NL80211_ATTR_MESH_PARAMS]) {
+	if (info->attrs[NL80211_ATTR_MESH_CONFIG]) {
 		/* and parse parameters if given */
-		err = nl80211_parse_mesh_params(info, &cfg, NULL);
+		err = nl80211_parse_mesh_config(info, &cfg, NULL);
 		if (err)
 			return err;
 	}
@@ -4952,16 +4952,16 @@ static struct genl_ops nl80211_ops[] = {
 		.flags = GENL_ADMIN_PERM,
 	},
 	{
-		.cmd = NL80211_CMD_GET_MESH_PARAMS,
-		.doit = nl80211_get_mesh_params,
+		.cmd = NL80211_CMD_GET_MESH_CONFIG,
+		.doit = nl80211_get_mesh_config,
 		.policy = nl80211_policy,
 		/* can be retrieved by unprivileged users */
 		.internal_flags = NL80211_FLAG_NEED_NETDEV |
 				  NL80211_FLAG_NEED_RTNL,
 	},
 	{
-		.cmd = NL80211_CMD_SET_MESH_PARAMS,
-		.doit = nl80211_update_mesh_params,
+		.cmd = NL80211_CMD_SET_MESH_CONFIG,
+		.doit = nl80211_update_mesh_config,
 		.policy = nl80211_policy,
 		.flags = GENL_ADMIN_PERM,
 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
-- 
1.7.1


^ permalink raw reply related

* Re: [PATCH] mac80211: Push idle state to driver before stop
From: Luis R. Rodriguez @ 2010-12-16 17:49 UTC (permalink / raw)
  To: Paul Stewart
  Cc: Johannes Berg, linux-wireless@vger.kernel.org, Luis Rodriguez
In-Reply-To: <20101216174410.GB5677@tux>

On Thu, Dec 16, 2010 at 9:44 AM, Luis R. Rodriguez
<lrodriguez@atheros.com> wrote:
> On Thu, Dec 16, 2010 at 08:02:27AM -0800, Paul Stewart wrote:
>> On Thu, Dec 16, 2010 at 4:53 AM, Johannes Berg
>> <johannes@sipsolutions.net> wrote:
>> > On Thu, 2010-12-16 at 04:46 -0800, Paul Stewart wrote:
>> > Not really -- the driver may throw away all internal state, mac80211
>> > will (attempt to) restore it all through drv_config() with changed = ~0.
>> > Evidently ath9k has some magic that makes this fail?
>>
>> The magic in question is as follows (ath9k_config()):
>>
>>     if (changed & IEEE80211_CONF_CHANGE_IDLE) {
>>         bool enable_radio;
>>         bool all_wiphys_idle;
>>         bool idle = !!(conf->flags & IEEE80211_CONF_IDLE);
>>
>>         spin_lock_bh(&sc->wiphy_lock);
>>         all_wiphys_idle =  ath9k_all_wiphys_idle(sc);
>>        ath9k_set_wiphy_idle(aphy, idle);
>>
>>         enable_radio = (!idle && all_wiphys_idle);
>>
>>         /*
>>          * After we unlock here its possible another wiphy
>>          * can be re-renabled so to account for that we will
>>          * only disable the radio toward the end of this routine
>>          * if by then all wiphys are still idle.
>>          */
>>         spin_unlock_bh(&sc->wiphy_lock);
>>
>>         if (enable_radio) {
>>             sc->ps_idle = false;
>>             ath_radio_enable(sc, hw);
>>             ath_dbg(common, ATH_DBG_CONFIG,
>>                     "not-idle: enabling radio\n");
>>         }
>>     }
>>
>> So, ath9k enables and disables the radio based on ps_idle (the
>> internal state), but that's not re-evaluated unless the wiphys
>> actually change.  In this case they do not change because ath9k was
>> never informed that the wiphy went idle (all_wiphys_idle evaluates to
>> false).  One solution would be to do an ah9k_set_wiphy_idle(aphy,
>> true) in ath9k_stop() instead of Luis' previous suggestion of setting
>> sc->ps_idle directly.  Perhaps in January when I return from vacation
>> I'll test this to make sure that performs as intended in the
>> suspend-resume-while-associated case.  It's a little bit of a lie to
>> do it in this case since in fact as far as mac80211 is concerned, the
>> wiphy is not idle in this case.
>
> Try this:
>
> diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
> index c68205d..3de3dbf 100644
> --- a/drivers/net/wireless/ath/ath9k/main.c
> +++ b/drivers/net/wireless/ath/ath9k/main.c
> @@ -1350,6 +1350,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
>        ath9k_ps_restore(sc);
>
>        sc->ps_idle = true;
> +       ath9k_set_wiphy_idle(aphy, true);
>        ath_radio_disable(sc, hw);
>
>        sc->sc_flags |= SC_OP_INVALID;
> diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
> index 7ca8499..4538283 100644
> --- a/drivers/net/wireless/ath/ath9k/pci.c
> +++ b/drivers/net/wireless/ath/ath9k/pci.c
> @@ -310,6 +310,7 @@ static int ath_pci_resume(struct device *device)
>        ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
>
>        sc->ps_idle = true;
> +       ath9k_set_wiphy_idle(aphy, true);
>        ath_radio_disable(sc, hw);
>
>        return 0;

If this does not work then yes, I will argue that mac80211 is not
turning us on when it needs to. I was concered about the resume case
given that mac80211 only calls drv_start() when open_count is > 0. So
we'll see.

  Luis

^ permalink raw reply

* Re: [PATCH] mac80211: Push idle state to driver before stop
From: Luis R. Rodriguez @ 2010-12-16 17:44 UTC (permalink / raw)
  To: Paul Stewart
  Cc: Johannes Berg, linux-wireless@vger.kernel.org, Luis Rodriguez
In-Reply-To: <AANLkTinWkYK2Zu1LsKw9YQ4dAXJ2b_quEvZLc59-c_5q@mail.gmail.com>

On Thu, Dec 16, 2010 at 08:02:27AM -0800, Paul Stewart wrote:
> On Thu, Dec 16, 2010 at 4:53 AM, Johannes Berg
> <johannes@sipsolutions.net> wrote:
> > On Thu, 2010-12-16 at 04:46 -0800, Paul Stewart wrote:
> > Not really -- the driver may throw away all internal state, mac80211
> > will (attempt to) restore it all through drv_config() with changed = ~0.
> > Evidently ath9k has some magic that makes this fail?
> 
> The magic in question is as follows (ath9k_config()):
> 
>     if (changed & IEEE80211_CONF_CHANGE_IDLE) {
>         bool enable_radio;
>         bool all_wiphys_idle;
>         bool idle = !!(conf->flags & IEEE80211_CONF_IDLE);
> 
>         spin_lock_bh(&sc->wiphy_lock);
>         all_wiphys_idle =  ath9k_all_wiphys_idle(sc);
>        ath9k_set_wiphy_idle(aphy, idle);
> 
>         enable_radio = (!idle && all_wiphys_idle);
> 
>         /*
>          * After we unlock here its possible another wiphy
>          * can be re-renabled so to account for that we will
>          * only disable the radio toward the end of this routine
>          * if by then all wiphys are still idle.
>          */
>         spin_unlock_bh(&sc->wiphy_lock);
> 
>         if (enable_radio) {
>             sc->ps_idle = false;
>             ath_radio_enable(sc, hw);
>             ath_dbg(common, ATH_DBG_CONFIG,
>                     "not-idle: enabling radio\n");
>         }
>     }
> 
> So, ath9k enables and disables the radio based on ps_idle (the
> internal state), but that's not re-evaluated unless the wiphys
> actually change.  In this case they do not change because ath9k was
> never informed that the wiphy went idle (all_wiphys_idle evaluates to
> false).  One solution would be to do an ah9k_set_wiphy_idle(aphy,
> true) in ath9k_stop() instead of Luis' previous suggestion of setting
> sc->ps_idle directly.  Perhaps in January when I return from vacation
> I'll test this to make sure that performs as intended in the
> suspend-resume-while-associated case.  It's a little bit of a lie to
> do it in this case since in fact as far as mac80211 is concerned, the
> wiphy is not idle in this case.

Try this:

diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index c68205d..3de3dbf 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1350,6 +1350,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
 	ath9k_ps_restore(sc);
 
 	sc->ps_idle = true;
+	ath9k_set_wiphy_idle(aphy, true);
 	ath_radio_disable(sc, hw);
 
 	sc->sc_flags |= SC_OP_INVALID;
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index 7ca8499..4538283 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -310,6 +310,7 @@ static int ath_pci_resume(struct device *device)
 	ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
 
 	sc->ps_idle = true;
+	ath9k_set_wiphy_idle(aphy, true);
 	ath_radio_disable(sc, hw);
 
 	return 0;

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox