Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH 2/3 v2] cfg80211/nl80211: separate unicast/multicast default TX keys
From: Johannes Berg @ 2010-12-09 18:58 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless
In-Reply-To: <20101209185002.763284359@sipsolutions.net>

From: Johannes Berg <johannes.berg@intel.com>

Allow userspace to specify that a given key
is default only for unicast and/or multicast
transmissions. Only WEP keys are for both,
WPA/RSN keys set here are GTKs for multicast
only. For more future flexibility, allow to
specify all combiations.

Wireless extensions can only set both so use
nl80211; WEP keys (connect keys) must be set
as default for both (but 802.1X WEP is still
possible).

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
v2: oops, forgot to heed my own advice of adding the new attributes to
the policies ...

 drivers/net/wireless/iwmc3200wifi/cfg80211.c |    3 
 drivers/net/wireless/libertas/cfg.c          |    3 
 drivers/net/wireless/rndis_wlan.c            |    4 
 include/linux/nl80211.h                      |   27 +++++
 include/net/cfg80211.h                       |    5 -
 net/mac80211/cfg.c                           |    3 
 net/wireless/nl80211.c                       |  125 +++++++++++++++++++++++----
 net/wireless/util.c                          |    3 
 net/wireless/wext-compat.c                   |    8 -
 9 files changed, 152 insertions(+), 29 deletions(-)

--- wireless-testing.orig/include/linux/nl80211.h	2010-12-09 19:54:46.000000000 +0100
+++ wireless-testing/include/linux/nl80211.h	2010-12-09 19:54:50.000000000 +0100
@@ -851,6 +851,10 @@ enum nl80211_commands {
  *
  * @NL80211_ATTR_BSS_HTOPMODE: HT operation mode (u16)
  *
+ * @NL80211_ATTR_KEY_DEFAULT_TYPES: A nested attribute containing flags
+ *	attributes, specifying what a key should be set as default as.
+ *	See &enum nl80211_key_default_types.
+ *
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
  */
@@ -1029,6 +1033,8 @@ enum nl80211_attrs {
 
 	NL80211_ATTR_BSS_HT_OPMODE,
 
+	NL80211_ATTR_KEY_DEFAULT_TYPES,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
@@ -1775,6 +1781,23 @@ enum nl80211_wpa_versions {
 };
 
 /**
+ * enum nl80211_key_default_types - key default types
+ * @__NL80211_KEY_DEFAULT_TYPE_INVALID: invalid
+ * @NL80211_KEY_DEFAULT_TYPE_UNICAST: key should be used as default
+ *	unicast key
+ * @NL80211_KEY_DEFAULT_TYPE_MULTICAST: key should be used as default
+ *	multicast key
+ * @NUM_NL80211_KEY_DEFAULT_TYPES: number of default types
+ */
+enum nl80211_key_default_types {
+	__NL80211_KEY_DEFAULT_TYPE_INVALID,
+	NL80211_KEY_DEFAULT_TYPE_UNICAST,
+	NL80211_KEY_DEFAULT_TYPE_MULTICAST,
+
+	NUM_NL80211_KEY_DEFAULT_TYPES
+};
+
+/**
  * enum nl80211_key_attributes - key attributes
  * @__NL80211_KEY_INVALID: invalid
  * @NL80211_KEY_DATA: (temporal) key data; for TKIP this consists of
@@ -1790,6 +1813,9 @@ enum nl80211_wpa_versions {
  * @NL80211_KEY_TYPE: the key type from enum nl80211_key_type, if not
  *	specified the default depends on whether a MAC address was
  *	given with the command using the key or not (u32)
+ * @NL80211_KEY_DEFAULT_TYPES: A nested attribute containing flags
+ *	attributes, specifying what a key should be set as default as.
+ *	See &enum nl80211_key_default_types.
  * @__NL80211_KEY_AFTER_LAST: internal
  * @NL80211_KEY_MAX: highest key attribute
  */
@@ -1802,6 +1828,7 @@ enum nl80211_key_attributes {
 	NL80211_KEY_DEFAULT,
 	NL80211_KEY_DEFAULT_MGMT,
 	NL80211_KEY_TYPE,
+	NL80211_KEY_DEFAULT_TYPES,
 
 	/* keep last */
 	__NL80211_KEY_AFTER_LAST,
--- wireless-testing.orig/drivers/net/wireless/iwmc3200wifi/cfg80211.c	2010-12-09 19:54:46.000000000 +0100
+++ wireless-testing/drivers/net/wireless/iwmc3200wifi/cfg80211.c	2010-12-09 19:54:50.000000000 +0100
@@ -225,7 +225,8 @@ static int iwm_cfg80211_del_key(struct w
 
 static int iwm_cfg80211_set_default_key(struct wiphy *wiphy,
 					struct net_device *ndev,
-					u8 key_index)
+					u8 key_index, bool unicast,
+					bool multicast)
 {
 	struct iwm_priv *iwm = ndev_to_iwm(ndev);
 
--- wireless-testing.orig/drivers/net/wireless/libertas/cfg.c	2010-12-09 19:54:46.000000000 +0100
+++ wireless-testing/drivers/net/wireless/libertas/cfg.c	2010-12-09 19:54:50.000000000 +0100
@@ -1422,7 +1422,8 @@ static int lbs_cfg_disconnect(struct wip
 
 static int lbs_cfg_set_default_key(struct wiphy *wiphy,
 				   struct net_device *netdev,
-				   u8 key_index)
+				   u8 key_index, bool unicast,
+				   bool multicast)
 {
 	struct lbs_private *priv = wiphy_priv(wiphy);
 
--- wireless-testing.orig/drivers/net/wireless/rndis_wlan.c	2010-12-09 19:54:46.000000000 +0100
+++ wireless-testing/drivers/net/wireless/rndis_wlan.c	2010-12-09 19:54:50.000000000 +0100
@@ -554,7 +554,7 @@ static int rndis_del_key(struct wiphy *w
 			 u8 key_index, bool pairwise, const u8 *mac_addr);
 
 static int rndis_set_default_key(struct wiphy *wiphy, struct net_device *netdev,
-								u8 key_index);
+				 u8 key_index, bool unicast, bool multicast);
 
 static int rndis_get_station(struct wiphy *wiphy, struct net_device *dev,
 					u8 *mac, struct station_info *sinfo);
@@ -2381,7 +2381,7 @@ static int rndis_del_key(struct wiphy *w
 }
 
 static int rndis_set_default_key(struct wiphy *wiphy, struct net_device *netdev,
-								u8 key_index)
+				 u8 key_index, bool unicast, bool multicast)
 {
 	struct rndis_wlan_private *priv = wiphy_priv(wiphy);
 	struct usbnet *usbdev = priv->usbdev;
--- wireless-testing.orig/include/net/cfg80211.h	2010-12-09 19:54:46.000000000 +0100
+++ wireless-testing/include/net/cfg80211.h	2010-12-09 19:54:50.000000000 +0100
@@ -1211,7 +1211,7 @@ struct cfg80211_ops {
 			   u8 key_index, bool pairwise, const u8 *mac_addr);
 	int	(*set_default_key)(struct wiphy *wiphy,
 				   struct net_device *netdev,
-				   u8 key_index);
+				   u8 key_index, bool unicast, bool multicast);
 	int	(*set_default_mgmt_key)(struct wiphy *wiphy,
 					struct net_device *netdev,
 					u8 key_index);
@@ -1393,6 +1393,8 @@ struct cfg80211_ops {
  *	control port protocol ethertype. The device also honours the
  *	control_port_no_encrypt flag.
  * @WIPHY_FLAG_IBSS_RSN: The device supports IBSS RSN.
+ * @WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS: The device supports separate
+ *	unicast and multicast TX keys.
  */
 enum wiphy_flags {
 	WIPHY_FLAG_CUSTOM_REGULATORY		= BIT(0),
@@ -1404,6 +1406,7 @@ enum wiphy_flags {
 	WIPHY_FLAG_4ADDR_STATION		= BIT(6),
 	WIPHY_FLAG_CONTROL_PORT_PROTOCOL	= BIT(7),
 	WIPHY_FLAG_IBSS_RSN			= BIT(8),
+	WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS= BIT(9),
 };
 
 struct mac_address {
--- wireless-testing.orig/net/wireless/nl80211.c	2010-12-09 19:54:46.000000000 +0100
+++ wireless-testing/net/wireless/nl80211.c	2010-12-09 19:56:01.000000000 +0100
@@ -171,6 +171,7 @@ static const struct nla_policy nl80211_p
 	[NL80211_ATTR_WIPHY_ANTENNA_RX] = { .type = NLA_U32 },
 	[NL80211_ATTR_MCAST_RATE] = { .type = NLA_U32 },
 	[NL80211_ATTR_OFFCHANNEL_TX_OK] = { .type = NLA_FLAG },
+	[NL80211_ATTR_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
 };
 
 /* policy for the key attributes */
@@ -182,6 +183,14 @@ static const struct nla_policy nl80211_k
 	[NL80211_KEY_DEFAULT] = { .type = NLA_FLAG },
 	[NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG },
 	[NL80211_KEY_TYPE] = { .type = NLA_U32 },
+	[NL80211_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
+};
+
+/* policy for the key default flags */
+static const struct nla_policy
+nl80211_key_default_policy[NUM_NL80211_KEY_DEFAULT_TYPES] = {
+	[NL80211_KEY_DEFAULT_TYPE_UNICAST] = { .type = NLA_FLAG },
+	[NL80211_KEY_DEFAULT_TYPE_MULTICAST] = { .type = NLA_FLAG },
 };
 
 /* ifidx get helper */
@@ -314,6 +323,7 @@ struct key_parse {
 	int idx;
 	int type;
 	bool def, defmgmt;
+	bool def_uni, def_multi;
 };
 
 static int nl80211_parse_key_new(struct nlattr *key, struct key_parse *k)
@@ -327,6 +337,13 @@ static int nl80211_parse_key_new(struct
 	k->def = !!tb[NL80211_KEY_DEFAULT];
 	k->defmgmt = !!tb[NL80211_KEY_DEFAULT_MGMT];
 
+	if (k->def) {
+		k->def_uni = true;
+		k->def_multi = true;
+	}
+	if (k->defmgmt)
+		k->def_multi = true;
+
 	if (tb[NL80211_KEY_IDX])
 		k->idx = nla_get_u8(tb[NL80211_KEY_IDX]);
 
@@ -349,6 +366,19 @@ static int nl80211_parse_key_new(struct
 			return -EINVAL;
 	}
 
+	if (tb[NL80211_KEY_DEFAULT_TYPES]) {
+		struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
+		int err = nla_parse_nested(kdt,
+					   NUM_NL80211_KEY_DEFAULT_TYPES - 1,
+					   tb[NL80211_KEY_DEFAULT_TYPES],
+					   nl80211_key_default_policy);
+		if (err)
+			return err;
+
+		k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST];
+		k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST];
+	}
+
 	return 0;
 }
 
@@ -373,12 +403,32 @@ static int nl80211_parse_key_old(struct
 	k->def = !!info->attrs[NL80211_ATTR_KEY_DEFAULT];
 	k->defmgmt = !!info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT];
 
+	if (k->def) {
+		k->def_uni = true;
+		k->def_multi = true;
+	}
+	if (k->defmgmt)
+		k->def_multi = true;
+
 	if (info->attrs[NL80211_ATTR_KEY_TYPE]) {
 		k->type = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]);
 		if (k->type < 0 || k->type >= NUM_NL80211_KEYTYPES)
 			return -EINVAL;
 	}
 
+	if (info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES]) {
+		struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
+		int err = nla_parse_nested(
+				kdt, NUM_NL80211_KEY_DEFAULT_TYPES - 1,
+				info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES],
+				nl80211_key_default_policy);
+		if (err)
+			return err;
+
+		k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST];
+		k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST];
+	}
+
 	return 0;
 }
 
@@ -401,6 +451,11 @@ static int nl80211_parse_key(struct genl
 	if (k->def && k->defmgmt)
 		return -EINVAL;
 
+	if (k->defmgmt) {
+		if (k->def_uni || !k->def_multi)
+			return -EINVAL;
+	}
+
 	if (k->idx != -1) {
 		if (k->defmgmt) {
 			if (k->idx < 4 || k->idx > 5)
@@ -450,6 +505,8 @@ nl80211_parse_connkeys(struct cfg80211_r
 				goto error;
 			def = 1;
 			result->def = parse.idx;
+			if (!parse.def_uni || !parse.def_multi)
+				goto error;
 		} else if (parse.defmgmt)
 			goto error;
 		err = cfg80211_validate_key_settings(rdev, &parse.p,
@@ -1575,8 +1632,6 @@ static int nl80211_set_key(struct sk_buf
 	struct key_parse key;
 	int err;
 	struct net_device *dev = info->user_ptr[1];
-	int (*func)(struct wiphy *wiphy, struct net_device *netdev,
-		    u8 key_index);
 
 	err = nl80211_parse_key(info, &key);
 	if (err)
@@ -1589,27 +1644,61 @@ static int nl80211_set_key(struct sk_buf
 	if (!key.def && !key.defmgmt)
 		return -EINVAL;
 
-	if (key.def)
-		func = rdev->ops->set_default_key;
-	else
-		func = rdev->ops->set_default_mgmt_key;
+	wdev_lock(dev->ieee80211_ptr);
 
-	if (!func)
-		return -EOPNOTSUPP;
+	if (key.def) {
+		if (!rdev->ops->set_default_key) {
+			err = -EOPNOTSUPP;
+			goto out;
+		}
 
-	wdev_lock(dev->ieee80211_ptr);
-	err = nl80211_key_allowed(dev->ieee80211_ptr);
-	if (!err)
-		err = func(&rdev->wiphy, dev, key.idx);
+		err = nl80211_key_allowed(dev->ieee80211_ptr);
+		if (err)
+			goto out;
+
+		if (!(rdev->wiphy.flags &
+				WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS)) {
+			if (!key.def_uni || !key.def_multi) {
+				err = -EOPNOTSUPP;
+				goto out;
+			}
+		}
+
+		err = rdev->ops->set_default_key(&rdev->wiphy, dev, key.idx,
+						 key.def_uni, key.def_multi);
+
+		if (err)
+			goto out;
 
 #ifdef CONFIG_CFG80211_WEXT
-	if (!err) {
-		if (func == rdev->ops->set_default_key)
-			dev->ieee80211_ptr->wext.default_key = key.idx;
-		else
-			dev->ieee80211_ptr->wext.default_mgmt_key = key.idx;
-	}
+		dev->ieee80211_ptr->wext.default_key = key.idx;
+#endif
+	} else {
+		if (key.def_uni || !key.def_multi) {
+			err = -EINVAL;
+			goto out;
+		}
+
+		if (!rdev->ops->set_default_mgmt_key) {
+			err = -EOPNOTSUPP;
+			goto out;
+		}
+
+		err = nl80211_key_allowed(dev->ieee80211_ptr);
+		if (err)
+			goto out;
+
+		err = rdev->ops->set_default_mgmt_key(&rdev->wiphy,
+						      dev, key.idx);
+		if (err)
+			goto out;
+
+#ifdef CONFIG_CFG80211_WEXT
+		dev->ieee80211_ptr->wext.default_mgmt_key = key.idx;
 #endif
+	}
+
+ out:
 	wdev_unlock(dev->ieee80211_ptr);
 
 	return err;
--- wireless-testing.orig/net/mac80211/cfg.c	2010-12-09 19:54:46.000000000 +0100
+++ wireless-testing/net/mac80211/cfg.c	2010-12-09 19:54:50.000000000 +0100
@@ -295,7 +295,8 @@ static int ieee80211_get_key(struct wiph
 
 static int ieee80211_config_default_key(struct wiphy *wiphy,
 					struct net_device *dev,
-					u8 key_idx)
+					u8 key_idx, bool uni,
+					bool multi)
 {
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
--- wireless-testing.orig/net/wireless/util.c	2010-12-09 19:54:46.000000000 +0100
+++ wireless-testing/net/wireless/util.c	2010-12-09 19:54:50.000000000 +0100
@@ -689,7 +689,8 @@ void cfg80211_upload_connect_keys(struct
 			continue;
 		}
 		if (wdev->connect_keys->def == i)
-			if (rdev->ops->set_default_key(wdev->wiphy, dev, i)) {
+			if (rdev->ops->set_default_key(wdev->wiphy, dev,
+						       i, true, true)) {
 				netdev_err(dev, "failed to set defkey %d\n", i);
 				continue;
 			}
--- wireless-testing.orig/net/wireless/wext-compat.c	2010-12-09 19:54:46.000000000 +0100
+++ wireless-testing/net/wireless/wext-compat.c	2010-12-09 19:54:50.000000000 +0100
@@ -548,8 +548,8 @@ static int __cfg80211_set_encryption(str
 				__cfg80211_leave_ibss(rdev, wdev->netdev, true);
 				rejoin = true;
 			}
-			err = rdev->ops->set_default_key(&rdev->wiphy,
-							 dev, idx);
+			err = rdev->ops->set_default_key(&rdev->wiphy, dev,
+							 idx, true, true);
 		}
 		if (!err) {
 			wdev->wext.default_key = idx;
@@ -627,8 +627,8 @@ int cfg80211_wext_siwencode(struct net_d
 		err = 0;
 		wdev_lock(wdev);
 		if (wdev->current_bss)
-			err = rdev->ops->set_default_key(&rdev->wiphy,
-							 dev, idx);
+			err = rdev->ops->set_default_key(&rdev->wiphy, dev,
+							 idx, true, true);
 		if (!err)
 			wdev->wext.default_key = idx;
 		wdev_unlock(wdev);



^ permalink raw reply

* [PATCH 3/3] mac80211: support separate default keys
From: Johannes Berg @ 2010-12-09 18:49 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless
In-Reply-To: <20101209184859.155955840@sipsolutions.net>

From: Johannes Berg <johannes.berg@intel.com>

Add support for split default keys (unicast
and multicast) in mac80211.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 net/mac80211/cfg.c         |    2 +-
 net/mac80211/debugfs_key.c |   37 +++++++++++++++++++++----------------
 net/mac80211/debugfs_key.h |    8 ++------
 net/mac80211/ieee80211_i.h |    5 +++--
 net/mac80211/key.c         |   45 ++++++++++++++++++++++++++-------------------
 net/mac80211/key.h         |    3 ++-
 net/mac80211/main.c        |    3 ++-
 net/mac80211/tx.c          |    6 +++++-
 8 files changed, 62 insertions(+), 47 deletions(-)

--- wireless-testing.orig/net/mac80211/ieee80211_i.h	2010-12-07 22:42:52.000000000 +0100
+++ wireless-testing/net/mac80211/ieee80211_i.h	2010-12-07 22:43:04.000000000 +0100
@@ -558,7 +558,7 @@ struct ieee80211_sub_if_data {
 	unsigned int fragment_next;
 
 	struct ieee80211_key *keys[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS];
-	struct ieee80211_key *default_key;
+	struct ieee80211_key *default_unicast_key, *default_multicast_key;
 	struct ieee80211_key *default_mgmt_key;
 
 	u16 sequence_number;
@@ -596,7 +596,8 @@ struct ieee80211_sub_if_data {
 	struct {
 		struct dentry *dir;
 		struct dentry *subdir_stations;
-		struct dentry *default_key;
+		struct dentry *default_unicast_key;
+		struct dentry *default_multicast_key;
 		struct dentry *default_mgmt_key;
 	} debugfs;
 #endif
--- wireless-testing.orig/net/mac80211/tx.c	2010-12-07 22:42:49.000000000 +0100
+++ wireless-testing/net/mac80211/tx.c	2010-12-07 22:43:04.000000000 +0100
@@ -539,7 +539,11 @@ ieee80211_tx_h_select_key(struct ieee802
 		 ieee80211_is_robust_mgmt_frame(hdr) &&
 		 (key = rcu_dereference(tx->sdata->default_mgmt_key)))
 		tx->key = key;
-	else if ((key = rcu_dereference(tx->sdata->default_key)))
+	else if (is_multicast_ether_addr(hdr->addr1) &&
+		 (key = rcu_dereference(tx->sdata->default_multicast_key)))
+		tx->key = key;
+	else if (!is_multicast_ether_addr(hdr->addr1) &&
+		 (key = rcu_dereference(tx->sdata->default_unicast_key)))
 		tx->key = key;
 	else if (tx->sdata->drop_unencrypted &&
 		 (tx->skb->protocol != tx->sdata->control_port_protocol) &&
--- wireless-testing.orig/net/mac80211/debugfs_key.c	2010-12-07 22:40:44.000000000 +0100
+++ wireless-testing/net/mac80211/debugfs_key.c	2010-12-07 22:43:04.000000000 +0100
@@ -274,7 +274,8 @@ void ieee80211_debugfs_key_remove(struct
 	debugfs_remove_recursive(key->debugfs.dir);
 	key->debugfs.dir = NULL;
 }
-void ieee80211_debugfs_key_add_default(struct ieee80211_sub_if_data *sdata)
+
+void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata)
 {
 	char buf[50];
 	struct ieee80211_key *key;
@@ -282,25 +283,29 @@ void ieee80211_debugfs_key_add_default(s
 	if (!sdata->debugfs.dir)
 		return;
 
-	/* this is running under the key lock */
+	lockdep_assert_held(&sdata->local->key_mtx);
 
-	key = sdata->default_key;
-	if (key) {
+	if (sdata->default_unicast_key) {
+		key = sdata->default_unicast_key;
 		sprintf(buf, "../keys/%d", key->debugfs.cnt);
-		sdata->debugfs.default_key =
-			debugfs_create_symlink("default_key",
+		sdata->debugfs.default_unicast_key =
+			debugfs_create_symlink("default_unicast_key",
 					       sdata->debugfs.dir, buf);
-	} else
-		ieee80211_debugfs_key_remove_default(sdata);
-}
+	} else {
+		debugfs_remove(sdata->debugfs.default_unicast_key);
+		sdata->debugfs.default_unicast_key = NULL;
+	}
 
-void ieee80211_debugfs_key_remove_default(struct ieee80211_sub_if_data *sdata)
-{
-	if (!sdata)
-		return;
-
-	debugfs_remove(sdata->debugfs.default_key);
-	sdata->debugfs.default_key = NULL;
+	if (sdata->default_multicast_key) {
+		key = sdata->default_multicast_key;
+		sprintf(buf, "../keys/%d", key->debugfs.cnt);
+		sdata->debugfs.default_multicast_key =
+			debugfs_create_symlink("default_multicast_key",
+					       sdata->debugfs.dir, buf);
+	} else {
+		debugfs_remove(sdata->debugfs.default_multicast_key);
+		sdata->debugfs.default_multicast_key = NULL;
+	}
 }
 
 void ieee80211_debugfs_key_add_mgmt_default(struct ieee80211_sub_if_data *sdata)
--- wireless-testing.orig/net/mac80211/debugfs_key.h	2010-12-07 22:40:45.000000000 +0100
+++ wireless-testing/net/mac80211/debugfs_key.h	2010-12-07 22:43:04.000000000 +0100
@@ -4,8 +4,7 @@
 #ifdef CONFIG_MAC80211_DEBUGFS
 void ieee80211_debugfs_key_add(struct ieee80211_key *key);
 void ieee80211_debugfs_key_remove(struct ieee80211_key *key);
-void ieee80211_debugfs_key_add_default(struct ieee80211_sub_if_data *sdata);
-void ieee80211_debugfs_key_remove_default(struct ieee80211_sub_if_data *sdata);
+void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata);
 void ieee80211_debugfs_key_add_mgmt_default(
 	struct ieee80211_sub_if_data *sdata);
 void ieee80211_debugfs_key_remove_mgmt_default(
@@ -17,10 +16,7 @@ static inline void ieee80211_debugfs_key
 {}
 static inline void ieee80211_debugfs_key_remove(struct ieee80211_key *key)
 {}
-static inline void ieee80211_debugfs_key_add_default(
-	struct ieee80211_sub_if_data *sdata)
-{}
-static inline void ieee80211_debugfs_key_remove_default(
+static inline void ieee80211_debugfs_key_update_default(
 	struct ieee80211_sub_if_data *sdata)
 {}
 static inline void ieee80211_debugfs_key_add_mgmt_default(
--- wireless-testing.orig/net/mac80211/key.c	2010-12-07 22:40:44.000000000 +0100
+++ wireless-testing/net/mac80211/key.c	2010-12-07 22:43:04.000000000 +0100
@@ -178,7 +178,7 @@ void ieee80211_key_removed(struct ieee80
 EXPORT_SYMBOL_GPL(ieee80211_key_removed);
 
 static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata,
-					int idx)
+					int idx, bool uni, bool multi)
 {
 	struct ieee80211_key *key = NULL;
 
@@ -187,18 +187,19 @@ static void __ieee80211_set_default_key(
 	if (idx >= 0 && idx < NUM_DEFAULT_KEYS)
 		key = sdata->keys[idx];
 
-	rcu_assign_pointer(sdata->default_key, key);
+	if (uni)
+		rcu_assign_pointer(sdata->default_unicast_key, key);
+	if (multi)
+		rcu_assign_pointer(sdata->default_multicast_key, key);
 
-	if (key) {
-		ieee80211_debugfs_key_remove_default(key->sdata);
-		ieee80211_debugfs_key_add_default(key->sdata);
-	}
+	ieee80211_debugfs_key_update_default(sdata);
 }
 
-void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx)
+void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx,
+			       bool uni, bool multi)
 {
 	mutex_lock(&sdata->local->key_mtx);
-	__ieee80211_set_default_key(sdata, idx);
+	__ieee80211_set_default_key(sdata, idx, uni, multi);
 	mutex_unlock(&sdata->local->key_mtx);
 }
 
@@ -215,10 +216,7 @@ __ieee80211_set_default_mgmt_key(struct
 
 	rcu_assign_pointer(sdata->default_mgmt_key, key);
 
-	if (key) {
-		ieee80211_debugfs_key_remove_mgmt_default(key->sdata);
-		ieee80211_debugfs_key_add_mgmt_default(key->sdata);
-	}
+	ieee80211_debugfs_key_update_default(sdata);
 }
 
 void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata,
@@ -236,7 +234,8 @@ static void __ieee80211_key_replace(stru
 				    struct ieee80211_key *old,
 				    struct ieee80211_key *new)
 {
-	int idx, defkey, defmgmtkey;
+	int idx;
+	bool defunikey, defmultikey, defmgmtkey;
 
 	if (new)
 		list_add(&new->list, &sdata->key_list);
@@ -257,17 +256,24 @@ static void __ieee80211_key_replace(stru
 		else
 			idx = new->conf.keyidx;
 
-		defkey = old && sdata->default_key == old;
+		defunikey = old && sdata->default_unicast_key == old;
+		defmultikey = old && sdata->default_multicast_key == old;
 		defmgmtkey = old && sdata->default_mgmt_key == old;
 
-		if (defkey && !new)
-			__ieee80211_set_default_key(sdata, -1);
+		if (defunikey && !new)
+			__ieee80211_set_default_key(sdata, -1, true, false);
+		if (defmultikey && !new)
+			__ieee80211_set_default_key(sdata, -1, false, true);
 		if (defmgmtkey && !new)
 			__ieee80211_set_default_mgmt_key(sdata, -1);
 
 		rcu_assign_pointer(sdata->keys[idx], new);
-		if (defkey && new)
-			__ieee80211_set_default_key(sdata, new->conf.keyidx);
+		if (defunikey && new)
+			__ieee80211_set_default_key(sdata, new->conf.keyidx,
+						    true, false);
+		if (defmultikey && new)
+			__ieee80211_set_default_key(sdata, new->conf.keyidx,
+						    false, true);
 		if (defmgmtkey && new)
 			__ieee80211_set_default_mgmt_key(sdata,
 							 new->conf.keyidx);
@@ -509,11 +515,12 @@ void ieee80211_free_keys(struct ieee8021
 
 	mutex_lock(&sdata->local->key_mtx);
 
-	ieee80211_debugfs_key_remove_default(sdata);
 	ieee80211_debugfs_key_remove_mgmt_default(sdata);
 
 	list_for_each_entry_safe(key, tmp, &sdata->key_list, list)
 		__ieee80211_key_free(key);
 
+	ieee80211_debugfs_key_update_default(sdata);
+
 	mutex_unlock(&sdata->local->key_mtx);
 }
--- wireless-testing.orig/net/mac80211/key.h	2010-12-07 22:40:44.000000000 +0100
+++ wireless-testing/net/mac80211/key.h	2010-12-07 22:43:04.000000000 +0100
@@ -138,7 +138,8 @@ int __must_check ieee80211_key_link(stru
 				    struct sta_info *sta);
 void ieee80211_key_free(struct ieee80211_local *local,
 			struct ieee80211_key *key);
-void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx);
+void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx,
+			       bool uni, bool multi);
 void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata,
 				    int idx);
 void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata);
--- wireless-testing.orig/net/mac80211/main.c	2010-12-07 22:42:46.000000000 +0100
+++ wireless-testing/net/mac80211/main.c	2010-12-07 22:43:04.000000000 +0100
@@ -519,7 +519,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(
 
 	wiphy->flags |= WIPHY_FLAG_NETNS_OK |
 			WIPHY_FLAG_4ADDR_AP |
-			WIPHY_FLAG_4ADDR_STATION;
+			WIPHY_FLAG_4ADDR_STATION |
+			WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS;
 	wiphy->privid = mac80211_wiphy_privid;
 
 	wiphy->bss_priv_size = sizeof(struct ieee80211_bss);
--- wireless-testing.orig/net/mac80211/cfg.c	2010-12-07 22:43:03.000000000 +0100
+++ wireless-testing/net/mac80211/cfg.c	2010-12-07 22:43:04.000000000 +0100
@@ -300,7 +300,7 @@ static int ieee80211_config_default_key(
 {
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
-	ieee80211_set_default_key(sdata, key_idx);
+	ieee80211_set_default_key(sdata, key_idx, uni, multi);
 
 	return 0;
 }



^ permalink raw reply

* [PATCH 2/3] cfg80211/nl80211: separate unicast/multicast default TX keys
From: Johannes Berg @ 2010-12-09 18:49 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless
In-Reply-To: <20101209184859.155955840@sipsolutions.net>

From: Johannes Berg <johannes.berg@intel.com>

Allow userspace to specify that a given key
is default only for unicast and/or multicast
transmissions. Only WEP keys are for both,
WPA/RSN keys set here are GTKs for multicast
only. For more future flexibility, allow to
specify all combiations.

Wireless extensions can only set both so use
nl80211; WEP keys (connect keys) must be set
as default for both (but 802.1X WEP is still
possible).

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 drivers/net/wireless/iwmc3200wifi/cfg80211.c |    3 
 drivers/net/wireless/libertas/cfg.c          |    3 
 drivers/net/wireless/rndis_wlan.c            |    4 
 include/linux/nl80211.h                      |   27 +++++
 include/net/cfg80211.h                       |    5 -
 net/mac80211/cfg.c                           |    3 
 net/wireless/nl80211.c                       |  123 +++++++++++++++++++++++----
 net/wireless/util.c                          |    3 
 net/wireless/wext-compat.c                   |    8 -
 9 files changed, 150 insertions(+), 29 deletions(-)

--- wireless-testing.orig/include/linux/nl80211.h	2010-12-06 10:44:24.000000000 +0100
+++ wireless-testing/include/linux/nl80211.h	2010-12-06 10:45:11.000000000 +0100
@@ -849,6 +849,10 @@ enum nl80211_commands {
  *	flag isn't set, the frame will be rejected. This is also used as an
  *	nl80211 capability flag.
  *
+ * @NL80211_ATTR_KEY_DEFAULT_TYPES: A nested attribute containing flags
+ *	attributes, specifying what a key should be set as default as.
+ *	See &enum nl80211_key_default_types.
+ *
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
  */
@@ -1025,6 +1029,8 @@ enum nl80211_attrs {
 
 	NL80211_ATTR_OFFCHANNEL_TX_OK,
 
+	NL80211_ATTR_KEY_DEFAULT_TYPES,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
@@ -1769,6 +1775,23 @@ enum nl80211_wpa_versions {
 };
 
 /**
+ * enum nl80211_key_default_types - key default types
+ * @__NL80211_KEY_DEFAULT_TYPE_INVALID: invalid
+ * @NL80211_KEY_DEFAULT_TYPE_UNICAST: key should be used as default
+ *	unicast key
+ * @NL80211_KEY_DEFAULT_TYPE_MULTICAST: key should be used as default
+ *	multicast key
+ * @NUM_NL80211_KEY_DEFAULT_TYPES: number of default types
+ */
+enum nl80211_key_default_types {
+	__NL80211_KEY_DEFAULT_TYPE_INVALID,
+	NL80211_KEY_DEFAULT_TYPE_UNICAST,
+	NL80211_KEY_DEFAULT_TYPE_MULTICAST,
+
+	NUM_NL80211_KEY_DEFAULT_TYPES
+};
+
+/**
  * enum nl80211_key_attributes - key attributes
  * @__NL80211_KEY_INVALID: invalid
  * @NL80211_KEY_DATA: (temporal) key data; for TKIP this consists of
@@ -1784,6 +1807,9 @@ enum nl80211_wpa_versions {
  * @NL80211_KEY_TYPE: the key type from enum nl80211_key_type, if not
  *	specified the default depends on whether a MAC address was
  *	given with the command using the key or not (u32)
+ * @NL80211_KEY_DEFAULT_TYPES: A nested attribute containing flags
+ *	attributes, specifying what a key should be set as default as.
+ *	See &enum nl80211_key_default_types.
  * @__NL80211_KEY_AFTER_LAST: internal
  * @NL80211_KEY_MAX: highest key attribute
  */
@@ -1796,6 +1822,7 @@ enum nl80211_key_attributes {
 	NL80211_KEY_DEFAULT,
 	NL80211_KEY_DEFAULT_MGMT,
 	NL80211_KEY_TYPE,
+	NL80211_KEY_DEFAULT_TYPES,
 
 	/* keep last */
 	__NL80211_KEY_AFTER_LAST,
--- wireless-testing.orig/drivers/net/wireless/iwmc3200wifi/cfg80211.c	2010-12-06 10:44:24.000000000 +0100
+++ wireless-testing/drivers/net/wireless/iwmc3200wifi/cfg80211.c	2010-12-06 10:45:11.000000000 +0100
@@ -225,7 +225,8 @@ static int iwm_cfg80211_del_key(struct w
 
 static int iwm_cfg80211_set_default_key(struct wiphy *wiphy,
 					struct net_device *ndev,
-					u8 key_index)
+					u8 key_index, bool unicast,
+					bool multicast)
 {
 	struct iwm_priv *iwm = ndev_to_iwm(ndev);
 
--- wireless-testing.orig/drivers/net/wireless/libertas/cfg.c	2010-12-06 10:44:24.000000000 +0100
+++ wireless-testing/drivers/net/wireless/libertas/cfg.c	2010-12-06 10:45:11.000000000 +0100
@@ -1422,7 +1422,8 @@ static int lbs_cfg_disconnect(struct wip
 
 static int lbs_cfg_set_default_key(struct wiphy *wiphy,
 				   struct net_device *netdev,
-				   u8 key_index)
+				   u8 key_index, bool unicast,
+				   bool multicast)
 {
 	struct lbs_private *priv = wiphy_priv(wiphy);
 
--- wireless-testing.orig/drivers/net/wireless/rndis_wlan.c	2010-12-06 10:44:24.000000000 +0100
+++ wireless-testing/drivers/net/wireless/rndis_wlan.c	2010-12-06 10:45:11.000000000 +0100
@@ -554,7 +554,7 @@ static int rndis_del_key(struct wiphy *w
 			 u8 key_index, bool pairwise, const u8 *mac_addr);
 
 static int rndis_set_default_key(struct wiphy *wiphy, struct net_device *netdev,
-								u8 key_index);
+				 u8 key_index, bool unicast, bool multicast);
 
 static int rndis_get_station(struct wiphy *wiphy, struct net_device *dev,
 					u8 *mac, struct station_info *sinfo);
@@ -2381,7 +2381,7 @@ static int rndis_del_key(struct wiphy *w
 }
 
 static int rndis_set_default_key(struct wiphy *wiphy, struct net_device *netdev,
-								u8 key_index)
+				 u8 key_index, bool unicast, bool multicast)
 {
 	struct rndis_wlan_private *priv = wiphy_priv(wiphy);
 	struct usbnet *usbdev = priv->usbdev;
--- wireless-testing.orig/include/net/cfg80211.h	2010-12-06 10:44:24.000000000 +0100
+++ wireless-testing/include/net/cfg80211.h	2010-12-06 10:45:11.000000000 +0100
@@ -1204,7 +1204,7 @@ struct cfg80211_ops {
 			   u8 key_index, bool pairwise, const u8 *mac_addr);
 	int	(*set_default_key)(struct wiphy *wiphy,
 				   struct net_device *netdev,
-				   u8 key_index);
+				   u8 key_index, bool unicast, bool multicast);
 	int	(*set_default_mgmt_key)(struct wiphy *wiphy,
 					struct net_device *netdev,
 					u8 key_index);
@@ -1386,6 +1386,8 @@ struct cfg80211_ops {
  *	control port protocol ethertype. The device also honours the
  *	control_port_no_encrypt flag.
  * @WIPHY_FLAG_IBSS_RSN: The device supports IBSS RSN.
+ * @WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS: The device supports separate
+ *	unicast and multicast TX keys.
  */
 enum wiphy_flags {
 	WIPHY_FLAG_CUSTOM_REGULATORY		= BIT(0),
@@ -1397,6 +1399,7 @@ enum wiphy_flags {
 	WIPHY_FLAG_4ADDR_STATION		= BIT(6),
 	WIPHY_FLAG_CONTROL_PORT_PROTOCOL	= BIT(7),
 	WIPHY_FLAG_IBSS_RSN			= BIT(8),
+	WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS= BIT(9),
 };
 
 struct mac_address {
--- wireless-testing.orig/net/wireless/nl80211.c	2010-12-06 10:44:24.000000000 +0100
+++ wireless-testing/net/wireless/nl80211.c	2010-12-06 10:45:11.000000000 +0100
@@ -183,6 +183,13 @@ static const struct nla_policy nl80211_k
 	[NL80211_KEY_TYPE] = { .type = NLA_U32 },
 };
 
+/* policy for the key default flags */
+static const struct nla_policy
+nl80211_key_default_policy[NUM_NL80211_KEY_DEFAULT_TYPES] = {
+	[NL80211_KEY_DEFAULT_TYPE_UNICAST] = { .type = NLA_FLAG },
+	[NL80211_KEY_DEFAULT_TYPE_MULTICAST] = { .type = NLA_FLAG },
+};
+
 /* ifidx get helper */
 static int nl80211_get_ifidx(struct netlink_callback *cb)
 {
@@ -313,6 +320,7 @@ struct key_parse {
 	int idx;
 	int type;
 	bool def, defmgmt;
+	bool def_uni, def_multi;
 };
 
 static int nl80211_parse_key_new(struct nlattr *key, struct key_parse *k)
@@ -326,6 +334,13 @@ static int nl80211_parse_key_new(struct
 	k->def = !!tb[NL80211_KEY_DEFAULT];
 	k->defmgmt = !!tb[NL80211_KEY_DEFAULT_MGMT];
 
+	if (k->def) {
+		k->def_uni = true;
+		k->def_multi = true;
+	}
+	if (k->defmgmt)
+		k->def_multi = true;
+
 	if (tb[NL80211_KEY_IDX])
 		k->idx = nla_get_u8(tb[NL80211_KEY_IDX]);
 
@@ -348,6 +363,19 @@ static int nl80211_parse_key_new(struct
 			return -EINVAL;
 	}
 
+	if (tb[NL80211_KEY_DEFAULT_TYPES]) {
+		struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
+		int err = nla_parse_nested(kdt,
+					   NUM_NL80211_KEY_DEFAULT_TYPES - 1,
+					   tb[NL80211_KEY_DEFAULT_TYPES],
+					   nl80211_key_default_policy);
+		if (err)
+			return err;
+
+		k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST];
+		k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST];
+	}
+
 	return 0;
 }
 
@@ -372,12 +400,32 @@ static int nl80211_parse_key_old(struct
 	k->def = !!info->attrs[NL80211_ATTR_KEY_DEFAULT];
 	k->defmgmt = !!info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT];
 
+	if (k->def) {
+		k->def_uni = true;
+		k->def_multi = true;
+	}
+	if (k->defmgmt)
+		k->def_multi = true;
+
 	if (info->attrs[NL80211_ATTR_KEY_TYPE]) {
 		k->type = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]);
 		if (k->type < 0 || k->type >= NUM_NL80211_KEYTYPES)
 			return -EINVAL;
 	}
 
+	if (info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES]) {
+		struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
+		int err = nla_parse_nested(
+				kdt, NUM_NL80211_KEY_DEFAULT_TYPES - 1,
+				info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES],
+				nl80211_key_default_policy);
+		if (err)
+			return err;
+
+		k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST];
+		k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST];
+	}
+
 	return 0;
 }
 
@@ -400,6 +448,11 @@ static int nl80211_parse_key(struct genl
 	if (k->def && k->defmgmt)
 		return -EINVAL;
 
+	if (k->defmgmt) {
+		if (k->def_uni || !k->def_multi)
+			return -EINVAL;
+	}
+
 	if (k->idx != -1) {
 		if (k->defmgmt) {
 			if (k->idx < 4 || k->idx > 5)
@@ -449,6 +502,8 @@ nl80211_parse_connkeys(struct cfg80211_r
 				goto error;
 			def = 1;
 			result->def = parse.idx;
+			if (!parse.def_uni || !parse.def_multi)
+				goto error;
 		} else if (parse.defmgmt)
 			goto error;
 		err = cfg80211_validate_key_settings(rdev, &parse.p,
@@ -1574,8 +1629,6 @@ static int nl80211_set_key(struct sk_buf
 	struct key_parse key;
 	int err;
 	struct net_device *dev = info->user_ptr[1];
-	int (*func)(struct wiphy *wiphy, struct net_device *netdev,
-		    u8 key_index);
 
 	err = nl80211_parse_key(info, &key);
 	if (err)
@@ -1588,27 +1641,61 @@ static int nl80211_set_key(struct sk_buf
 	if (!key.def && !key.defmgmt)
 		return -EINVAL;
 
-	if (key.def)
-		func = rdev->ops->set_default_key;
-	else
-		func = rdev->ops->set_default_mgmt_key;
+	wdev_lock(dev->ieee80211_ptr);
 
-	if (!func)
-		return -EOPNOTSUPP;
+	if (key.def) {
+		if (!rdev->ops->set_default_key) {
+			err = -EOPNOTSUPP;
+			goto out;
+		}
 
-	wdev_lock(dev->ieee80211_ptr);
-	err = nl80211_key_allowed(dev->ieee80211_ptr);
-	if (!err)
-		err = func(&rdev->wiphy, dev, key.idx);
+		err = nl80211_key_allowed(dev->ieee80211_ptr);
+		if (err)
+			goto out;
+
+		if (!(rdev->wiphy.flags &
+				WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS)) {
+			if (!key.def_uni || !key.def_multi) {
+				err = -EOPNOTSUPP;
+				goto out;
+			}
+		}
+
+		err = rdev->ops->set_default_key(&rdev->wiphy, dev, key.idx,
+						 key.def_uni, key.def_multi);
+
+		if (err)
+			goto out;
 
 #ifdef CONFIG_CFG80211_WEXT
-	if (!err) {
-		if (func == rdev->ops->set_default_key)
-			dev->ieee80211_ptr->wext.default_key = key.idx;
-		else
-			dev->ieee80211_ptr->wext.default_mgmt_key = key.idx;
-	}
+		dev->ieee80211_ptr->wext.default_key = key.idx;
+#endif
+	} else {
+		if (key.def_uni || !key.def_multi) {
+			err = -EINVAL;
+			goto out;
+		}
+
+		if (!rdev->ops->set_default_mgmt_key) {
+			err = -EOPNOTSUPP;
+			goto out;
+		}
+
+		err = nl80211_key_allowed(dev->ieee80211_ptr);
+		if (err)
+			goto out;
+
+		err = rdev->ops->set_default_mgmt_key(&rdev->wiphy,
+						      dev, key.idx);
+		if (err)
+			goto out;
+
+#ifdef CONFIG_CFG80211_WEXT
+		dev->ieee80211_ptr->wext.default_mgmt_key = key.idx;
 #endif
+	}
+
+ out:
 	wdev_unlock(dev->ieee80211_ptr);
 
 	return err;
--- wireless-testing.orig/net/mac80211/cfg.c	2010-12-06 10:44:24.000000000 +0100
+++ wireless-testing/net/mac80211/cfg.c	2010-12-06 10:45:11.000000000 +0100
@@ -295,7 +295,8 @@ static int ieee80211_get_key(struct wiph
 
 static int ieee80211_config_default_key(struct wiphy *wiphy,
 					struct net_device *dev,
-					u8 key_idx)
+					u8 key_idx, bool uni,
+					bool multi)
 {
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
--- wireless-testing.orig/net/wireless/util.c	2010-12-06 10:44:24.000000000 +0100
+++ wireless-testing/net/wireless/util.c	2010-12-06 10:45:11.000000000 +0100
@@ -689,7 +689,8 @@ void cfg80211_upload_connect_keys(struct
 			continue;
 		}
 		if (wdev->connect_keys->def == i)
-			if (rdev->ops->set_default_key(wdev->wiphy, dev, i)) {
+			if (rdev->ops->set_default_key(wdev->wiphy, dev,
+						       i, true, true)) {
 				netdev_err(dev, "failed to set defkey %d\n", i);
 				continue;
 			}
--- wireless-testing.orig/net/wireless/wext-compat.c	2010-12-06 10:44:24.000000000 +0100
+++ wireless-testing/net/wireless/wext-compat.c	2010-12-06 10:45:11.000000000 +0100
@@ -548,8 +548,8 @@ static int __cfg80211_set_encryption(str
 				__cfg80211_leave_ibss(rdev, wdev->netdev, true);
 				rejoin = true;
 			}
-			err = rdev->ops->set_default_key(&rdev->wiphy,
-							 dev, idx);
+			err = rdev->ops->set_default_key(&rdev->wiphy, dev,
+							 idx, true, true);
 		}
 		if (!err) {
 			wdev->wext.default_key = idx;
@@ -627,8 +627,8 @@ int cfg80211_wext_siwencode(struct net_d
 		err = 0;
 		wdev_lock(wdev);
 		if (wdev->current_bss)
-			err = rdev->ops->set_default_key(&rdev->wiphy,
-							 dev, idx);
+			err = rdev->ops->set_default_key(&rdev->wiphy, dev,
+							 idx, true, true);
 		if (!err)
 			wdev->wext.default_key = idx;
 		wdev_unlock(wdev);



^ permalink raw reply

* [PATCH 1/3] mac80211: clean up RX key checks
From: Johannes Berg @ 2010-12-09 18:49 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless
In-Reply-To: <20101209184859.155955840@sipsolutions.net>

From: Johannes Berg <johannes.berg@intel.com>

Using the default key for "any key set" isn't
quite what we should do. It works, but with the
upcoming changes it makes life unnecessarily
complex, so do something better here and really
check for "any key".

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 net/mac80211/rx.c |   23 +++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)

--- wireless-testing.orig/net/mac80211/rx.c	2010-12-05 18:09:51.000000000 +0100
+++ wireless-testing/net/mac80211/rx.c	2010-12-05 18:09:52.000000000 +0100
@@ -955,12 +955,31 @@ ieee80211_rx_h_decrypt(struct ieee80211_
 		 * have been expected.
 		 */
 		struct ieee80211_key *key = NULL;
+		struct ieee80211_sub_if_data *sdata = rx->sdata;
+		int i;
+
 		if (ieee80211_is_mgmt(fc) &&
 		    is_multicast_ether_addr(hdr->addr1) &&
 		    (key = rcu_dereference(rx->sdata->default_mgmt_key)))
 			rx->key = key;
-		else if ((key = rcu_dereference(rx->sdata->default_key)))
-			rx->key = key;
+		else {
+			if (rx->sta) {
+				for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
+					key = rcu_dereference(rx->sta->gtk[i]);
+					if (key)
+						break;
+				}
+			}
+			if (!key) {
+				for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
+					key = rcu_dereference(sdata->keys[i]);
+					if (key)
+						break;
+				}
+			}
+			if (key)
+				rx->key = key;
+		}
 		return RX_CONTINUE;
 	} else {
 		u8 keyid;



^ permalink raw reply

* [PATCH 0/3] key handling for IBSS RSN
From: Johannes Berg @ 2010-12-09 18:48 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless

These patches improve key handling to actually
make IBSS RSN work.

johannes


^ permalink raw reply

* [PATCH v3] mac80211: Fix NULL-pointer deference on ibss merge when not ready
From: Tim Harvey @ 2010-12-09 18:43 UTC (permalink / raw)
  To: linux-wireless; +Cc: Tim Harvey

dev_open will eventually call ieee80211_ibss_join which sets up the
skb used for beacons/probe-responses however it is possible to
receive beacons that attempt to merge before this occurs causing
a null pointer dereference.  Check ssid_len as that is the last
thing set in ieee80211_ibss_join.

This occurs quite easily in the presence of adhoc nodes with hidden SSID's

revised previous patch to check further up based on irc feedback

Signed-off-by: Tim Harvey <harvey.tim@gmail.com>
---
 net/mac80211/ibss.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 410d104..53c7077 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -780,6 +780,9 @@ void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
 
 	mutex_lock(&sdata->u.ibss.mtx);
 
+	if (!sdata->u.ibss.ssid_len)
+		goto mgmt_out; /* not ready to merge yet */
+
 	switch (fc & IEEE80211_FCTL_STYPE) {
 	case IEEE80211_STYPE_PROBE_REQ:
 		ieee80211_rx_mgmt_probe_req(sdata, mgmt, skb->len);
@@ -797,6 +800,7 @@ void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
 		break;
 	}
 
+ mgmt_out:
 	mutex_unlock(&sdata->u.ibss.mtx);
 }
 
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 2/2] iwlagn: implement layout-agnostic EEPROM reading
From: Wey-Yi Guy @ 2010-12-09 18:19 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Wey-Yi Guy, Johannes Berg
In-Reply-To: <1291918780-10882-1-git-send-email-wey-yi.w.guy@intel.com>

From: Johannes Berg <johannes.berg@intel.com>

The current EEPROM reading code has some layout
assumptions that now turned out to be false with
some newer versions of the EEPROM. Luckily, we
can avoid all such assumptions by using data in
the EEPROM itself, so implement using that.

However, for risk mitigation purposes, keep the
old reading code for current hardware for now.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-1000.c       |    2 +
 drivers/net/wireless/iwlwifi/iwl-6000.c       |   12 ++++
 drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c |   85 ++++++++++++++++++++++++-
 drivers/net/wireless/iwlwifi/iwl-agn-lib.c    |    6 ++
 drivers/net/wireless/iwlwifi/iwl-core.h       |    1 +
 drivers/net/wireless/iwlwifi/iwl-eeprom.h     |   15 +++++
 6 files changed, 120 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index db54091..0e027f7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -315,6 +315,7 @@ struct iwl_cfg iwl100_bgn_cfg = {
 	.mod_params = &iwlagn_mod_params,
 	.base_params = &iwl1000_base_params,
 	.ht_params = &iwl1000_ht_params,
+	.use_new_eeprom_reading = true,
 };
 
 struct iwl_cfg iwl100_bg_cfg = {
@@ -330,6 +331,7 @@ struct iwl_cfg iwl100_bg_cfg = {
 	.ops = &iwl1000_ops,
 	.mod_params = &iwlagn_mod_params,
 	.base_params = &iwl1000_base_params,
+	.use_new_eeprom_reading = true,
 };
 
 MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 11e6532..0ceeaac 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -561,6 +561,7 @@ struct iwl_cfg iwl6000g2a_2agn_cfg = {
 	.ht_params = &iwl6000_ht_params,
 	.need_dc_calib = true,
 	.need_temp_offset_calib = true,
+	.use_new_eeprom_reading = true,
 };
 
 struct iwl_cfg iwl6000g2a_2abg_cfg = {
@@ -578,6 +579,7 @@ struct iwl_cfg iwl6000g2a_2abg_cfg = {
 	.base_params = &iwl6000_base_params,
 	.need_dc_calib = true,
 	.need_temp_offset_calib = true,
+	.use_new_eeprom_reading = true,
 };
 
 struct iwl_cfg iwl6000g2a_2bg_cfg = {
@@ -595,6 +597,7 @@ struct iwl_cfg iwl6000g2a_2bg_cfg = {
 	.base_params = &iwl6000_base_params,
 	.need_dc_calib = true,
 	.need_temp_offset_calib = true,
+	.use_new_eeprom_reading = true,
 };
 
 struct iwl_cfg iwl6000g2b_2agn_cfg = {
@@ -616,6 +619,7 @@ struct iwl_cfg iwl6000g2b_2agn_cfg = {
 	.need_temp_offset_calib = true,
 	/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
 	.scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
+	.use_new_eeprom_reading = true,
 };
 
 struct iwl_cfg iwl6000g2b_2abg_cfg = {
@@ -636,6 +640,7 @@ struct iwl_cfg iwl6000g2b_2abg_cfg = {
 	.need_temp_offset_calib = true,
 	/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
 	.scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
+	.use_new_eeprom_reading = true,
 };
 
 struct iwl_cfg iwl6000g2b_2bgn_cfg = {
@@ -657,6 +662,7 @@ struct iwl_cfg iwl6000g2b_2bgn_cfg = {
 	.need_temp_offset_calib = true,
 	/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
 	.scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
+	.use_new_eeprom_reading = true,
 };
 
 struct iwl_cfg iwl6000g2b_2bg_cfg = {
@@ -677,6 +683,7 @@ struct iwl_cfg iwl6000g2b_2bg_cfg = {
 	.need_temp_offset_calib = true,
 	/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
 	.scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
+	.use_new_eeprom_reading = true,
 };
 
 struct iwl_cfg iwl6000g2b_bgn_cfg = {
@@ -698,6 +705,7 @@ struct iwl_cfg iwl6000g2b_bgn_cfg = {
 	.need_temp_offset_calib = true,
 	/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
 	.scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
+	.use_new_eeprom_reading = true,
 };
 
 struct iwl_cfg iwl6000g2b_bg_cfg = {
@@ -718,6 +726,7 @@ struct iwl_cfg iwl6000g2b_bg_cfg = {
 	.need_temp_offset_calib = true,
 	/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
 	.scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
+	.use_new_eeprom_reading = true,
 };
 
 /*
@@ -804,6 +813,7 @@ struct iwl_cfg iwl6050g2_bgn_cfg = {
 	.base_params = &iwl6050_base_params,
 	.ht_params = &iwl6000_ht_params,
 	.need_dc_calib = true,
+	.use_new_eeprom_reading = true,
 };
 
 struct iwl_cfg iwl6050_2abg_cfg = {
@@ -857,6 +867,7 @@ struct iwl_cfg iwl130_bgn_cfg = {
 	.need_dc_calib = true,
 	/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
 	.scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
+	.use_new_eeprom_reading = true,
 };
 
 struct iwl_cfg iwl130_bg_cfg = {
@@ -876,6 +887,7 @@ struct iwl_cfg iwl130_bg_cfg = {
 	.need_dc_calib = true,
 	/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
 	.scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
+	.use_new_eeprom_reading = true,
 };
 
 MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c
index 9651060..9eeeda1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c
@@ -392,7 +392,7 @@ static s8 iwl_update_channel_txpower(struct iwl_priv *priv,
 /**
  * iwlcore_eeprom_enhanced_txpower: process enhanced tx power info
  */
-void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv)
+static void iwlcore_eeprom_enhanced_txpower_old(struct iwl_priv *priv)
 {
 	int eeprom_section_count = 0;
 	int section, element;
@@ -453,3 +453,86 @@ void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv)
 		}
 	}
 }
+
+static void
+iwlcore_eeprom_enh_txp_read_element(struct iwl_priv *priv,
+				    struct iwl_eeprom_enhanced_txpwr *txp,
+				    s8 max_txpower_avg)
+{
+	int ch_idx;
+	bool is_ht40 = txp->flags & IWL_EEPROM_ENH_TXP_FL_40MHZ;
+	enum ieee80211_band band;
+
+	band = txp->flags & IWL_EEPROM_ENH_TXP_FL_BAND_52G ?
+		IEEE80211_BAND_5GHZ : IEEE80211_BAND_2GHZ;
+
+	for (ch_idx = 0; ch_idx < priv->channel_count; ch_idx++) {
+		struct iwl_channel_info *ch_info = &priv->channel_info[ch_idx];
+
+		/* update matching channel or from common data only */
+		if (txp->channel != 0 && ch_info->channel != txp->channel)
+			continue;
+
+		/* update matching band only */
+		if (band != ch_info->band)
+			continue;
+
+		if (ch_info->max_power_avg < max_txpower_avg && !is_ht40) {
+			ch_info->max_power_avg = max_txpower_avg;
+			ch_info->curr_txpow = max_txpower_avg;
+			ch_info->scan_power = max_txpower_avg;
+		}
+
+		if (is_ht40 && ch_info->ht40_max_power_avg < max_txpower_avg)
+			ch_info->ht40_max_power_avg = max_txpower_avg;
+	}
+}
+
+#define EEPROM_TXP_OFFS	(0x00 | INDIRECT_ADDRESS | INDIRECT_TXP_LIMIT)
+#define EEPROM_TXP_ENTRY_LEN sizeof(struct iwl_eeprom_enhanced_txpwr)
+#define EEPROM_TXP_SZ_OFFS (0x00 | INDIRECT_ADDRESS | INDIRECT_TXP_LIMIT_SIZE)
+
+static void iwlcore_eeprom_enhanced_txpower_new(struct iwl_priv *priv)
+{
+	struct iwl_eeprom_enhanced_txpwr *txp_array, *txp;
+	int idx, entries;
+	__le16 *txp_len;
+	s8 max_txp_avg, max_txp_avg_halfdbm;
+
+	BUILD_BUG_ON(sizeof(struct iwl_eeprom_enhanced_txpwr) != 8);
+
+	/* the length is in 16-bit words, but we want entries */
+	txp_len = (__le16 *) iwlagn_eeprom_query_addr(priv, EEPROM_TXP_SZ_OFFS);
+	entries = le16_to_cpup(txp_len) * 2 / EEPROM_TXP_ENTRY_LEN;
+
+	txp_array = (void *) iwlagn_eeprom_query_addr(priv, EEPROM_TXP_OFFS);
+	for (idx = 0; idx < entries; idx++) {
+		txp = &txp_array[idx];
+
+		/* skip invalid entries */
+		if (!(txp->flags & IWL_EEPROM_ENH_TXP_FL_VALID))
+			continue;
+
+		max_txp_avg = iwl_get_max_txpower_avg(priv, txp_array, idx,
+						      &max_txp_avg_halfdbm);
+
+		/*
+		 * Update the user limit values values to the highest
+		 * power supported by any channel
+		 */
+		if (max_txp_avg > priv->tx_power_user_lmt)
+			priv->tx_power_user_lmt = max_txp_avg;
+		if (max_txp_avg_halfdbm > priv->tx_power_lmt_in_half_dbm)
+			priv->tx_power_lmt_in_half_dbm = max_txp_avg_halfdbm;
+
+		iwlcore_eeprom_enh_txp_read_element(priv, txp, max_txp_avg);
+	}
+}
+
+void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv)
+{
+	if (priv->cfg->use_new_eeprom_reading)
+		iwlcore_eeprom_enhanced_txpower_new(priv);
+	else
+		iwlcore_eeprom_enhanced_txpower_old(priv);
+}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index b555edd..554afb7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -569,6 +569,12 @@ static u32 eeprom_indirect_address(const struct iwl_priv *priv, u32 address)
 	case INDIRECT_REGULATORY:
 		offset = iwl_eeprom_query16(priv, EEPROM_LINK_REGULATORY);
 		break;
+	case INDIRECT_TXP_LIMIT:
+		offset = iwl_eeprom_query16(priv, EEPROM_LINK_TXP_LIMIT);
+		break;
+	case INDIRECT_TXP_LIMIT_SIZE:
+		offset = iwl_eeprom_query16(priv, EEPROM_LINK_TXP_LIMIT_SIZE);
+		break;
 	case INDIRECT_CALIBRATION:
 		offset = iwl_eeprom_query16(priv, EEPROM_LINK_CALIBRATION);
 		break;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 64527de..954ecc2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -390,6 +390,7 @@ struct iwl_cfg {
 	const bool need_temp_offset_calib; /* if used set to true */
 	u8 scan_rx_antennas[IEEE80211_NUM_BANDS];
 	u8 scan_tx_antennas[IEEE80211_NUM_BANDS];
+	const bool use_new_eeprom_reading; /* temporary, remove later */
 };
 
 /***************************
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
index 310e345..e3a279d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
@@ -120,6 +120,17 @@ struct iwl_eeprom_channel {
 	s8 max_power_avg;	/* max power (dBm) on this chnl, limit 31 */
 } __packed;
 
+enum iwl_eeprom_enhanced_txpwr_flags {
+	IWL_EEPROM_ENH_TXP_FL_VALID		= BIT(0),
+	IWL_EEPROM_ENH_TXP_FL_BAND_52G		= BIT(1),
+	IWL_EEPROM_ENH_TXP_FL_OFDM		= BIT(2),
+	IWL_EEPROM_ENH_TXP_FL_40MHZ		= BIT(3),
+	IWL_EEPROM_ENH_TXP_FL_HT_AP		= BIT(4),
+	IWL_EEPROM_ENH_TXP_FL_RES1		= BIT(5),
+	IWL_EEPROM_ENH_TXP_FL_RES2		= BIT(6),
+	IWL_EEPROM_ENH_TXP_FL_COMMON_TYPE	= BIT(7),
+};
+
 /**
  * iwl_eeprom_enhanced_txpwr structure
  *    This structure presents the enhanced regulatory tx power limit layout
@@ -188,6 +199,8 @@ struct iwl_eeprom_enhanced_txpwr {
 #define EEPROM_LINK_CALIBRATION      (2*0x67)
 #define EEPROM_LINK_PROCESS_ADJST    (2*0x68)
 #define EEPROM_LINK_OTHERS           (2*0x69)
+#define EEPROM_LINK_TXP_LIMIT        (2*0x6a)
+#define EEPROM_LINK_TXP_LIMIT_SIZE   (2*0x6b)
 
 /* agn regulatory - indirect access */
 #define EEPROM_REG_BAND_1_CHANNELS       ((0x08)\
@@ -391,6 +404,8 @@ struct iwl_eeprom_calib_info {
 #define INDIRECT_CALIBRATION        0x00040000
 #define INDIRECT_PROCESS_ADJST      0x00050000
 #define INDIRECT_OTHERS             0x00060000
+#define INDIRECT_TXP_LIMIT          0x00070000
+#define INDIRECT_TXP_LIMIT_SIZE     0x00080000
 #define INDIRECT_ADDRESS            0x00100000
 
 /* General */
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 0/2] iwlwifi fix for 2.6.37
From: Wey-Yi Guy @ 2010-12-09 18:19 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Wey-Yi Guy

The original method used to parsing EEPROM Tx Power Table was hardcode and
not forward compatible with newer devices. Fix it here to be layout agnostic

John, we split EEPROM reading patches to two stage, for .37 release,
the existing devices will not change, only the newer devices will use
the new EEPROM reading method; we will remove the old EEPROM reading method
all together in separated patch for .38 release. Please let me know if this
is ok

Johannes Berg (1):
  iwlagn: rename enhanced txpower fields

Wey-Yi Guy (1):
  iwlagn: implement layout-agnostic EEPROM reading

these patches are also available from wireless-2.6 branch on
 git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-2.6.git

 drivers/net/wireless/iwlwifi/iwl-1000.c       |    2 +
 drivers/net/wireless/iwlwifi/iwl-6000.c       |   12 ++++
 drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c |   88 ++++++++++++++++++++++++-
 drivers/net/wireless/iwlwifi/iwl-agn-lib.c    |    6 ++
 drivers/net/wireless/iwlwifi/iwl-core.h       |    1 +
 drivers/net/wireless/iwlwifi/iwl-eeprom.h     |   25 ++++++-
 6 files changed, 128 insertions(+), 6 deletions(-)


^ permalink raw reply

* [PATCH 1/2] iwlagn: rename enhanced txpower fields
From: Wey-Yi Guy @ 2010-12-09 18:19 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Johannes Berg, Wey-Yi Guy
In-Reply-To: <1291918780-10882-1-git-send-email-wey-yi.w.guy@intel.com>

From: Johannes Berg <johannes.berg@intel.com>

Some fields we didn't previously use from the
enhanced TX power structure will be needed in
the next patch, so rename them to their correct
names to be able to use them and change code
reading them accordingly.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c |    3 ++-
 drivers/net/wireless/iwlwifi/iwl-eeprom.h     |   10 ++++++----
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c
index a650bab..9651060 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c
@@ -419,7 +419,8 @@ void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv)
 		 * always check for valid entry before process
 		 * the information
 		 */
-		if (!enhanced_txpower->common || enhanced_txpower->reserved)
+		if (!(enhanced_txpower->flags || enhanced_txpower->channel) ||
+		    enhanced_txpower->delta_20_in_40)
 			continue;
 
 		for (element = 0; element < eeprom_section_count; element++) {
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
index d9b5906..310e345 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
@@ -127,21 +127,23 @@ struct iwl_eeprom_channel {
  *    Enhanced regulatory tx power portion of eeprom image can be broken down
  *    into individual structures; each one is 8 bytes in size and contain the
  *    following information
- * @common: (desc + channel) not used by driver, should _NOT_ be "zero"
+ * @flags: entry flags
+ * @channel: channel number
  * @chain_a_max_pwr: chain a max power in 1/2 dBm
  * @chain_b_max_pwr: chain b max power in 1/2 dBm
  * @chain_c_max_pwr: chain c max power in 1/2 dBm
- * @reserved: not used, should be "zero"
+ * @delta_20_in_40: 20-in-40 deltas (hi/lo)
  * @mimo2_max_pwr: mimo2 max power in 1/2 dBm
  * @mimo3_max_pwr: mimo3 max power in 1/2 dBm
  *
  */
 struct iwl_eeprom_enhanced_txpwr {
-	__le16 common;
+	u8 flags;
+	u8 channel;
 	s8 chain_a_max;
 	s8 chain_b_max;
 	s8 chain_c_max;
-	s8 reserved;
+	u8 delta_20_in_40;
 	s8 mimo2_max;
 	s8 mimo3_max;
 } __packed;
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH v2] mac80211: Fix NULL-pointer deference on ibss merge when not ready
From: Tim Harvey @ 2010-12-09 18:11 UTC (permalink / raw)
  To: linux-wireless; +Cc: Tim Harvey

dev_open will eventually call ieee80211_ibss_join which sets up the
skb used for beacons/probe-responses however it is possible to
receive beacons that attempt to merge before this occurs causing
a null pointer dereference.  Check ssid_len as that is the last
thing set in ieee80211_ibss_join.

This occurs quite easily in the presence of adhoc nodes with hidden SSID's

Signed-off-by: Tim Harvey <harvey.tim@gmail.com>
---
 net/mac80211/ibss.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 410d104..93926c0 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -85,6 +85,8 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
 	/* Reset own TSF to allow time synchronization work. */
 	drv_reset_tsf(local);
 
+	if (!ifibss->ssid_len)
+		return; /* not ready to merge yet */
 	skb = ifibss->skb;
 	rcu_assign_pointer(ifibss->presp, NULL);
 	synchronize_rcu();
-- 
1.7.0.4


^ permalink raw reply related

* Re: [PATCH] mac80211: Fix NULL-pointer deference on ibss merge when not ready
From: John W. Linville @ 2010-12-09 17:19 UTC (permalink / raw)
  To: Tim Harvey; +Cc: linux-wireless
In-Reply-To: <1291913039-20801-1-git-send-email-harvey.tim@gmail.com>

On Thu, Dec 09, 2010 at 08:43:59AM -0800, Tim Harvey wrote:
> dev_open will eventually call ieee80211_ibss_join which sets up the
> skb used for beacons/probe-responses however it is possible to
> receive beacons that attempt to merge before this occurs causing
> a null pointer dereference.
> 
> This occurs quite easily in the presence of adhoc nodes with hidden SSID's
> ---
>  net/mac80211/ibss.c |    2 ++
>  1 files changed, 2 insertions(+), 0 deletions(-)

Signed-off-by?

-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.

^ permalink raw reply

* Re: [PATCH] mac80211: Fix deadlock in ieee80211_do_stop.
From: Ben Greear @ 2010-12-09 17:27 UTC (permalink / raw)
  To: Tejun Heo; +Cc: Johannes Berg, Luis R. Rodriguez, linux-wireless
In-Reply-To: <4D010114.5020604@gmail.com>

On 12/09/2010 08:17 AM, Tejun Heo wrote:
> On 12/09/2010 03:46 PM, Tejun Heo wrote:
>>> Right, so we're flushing here under RTNL ... I believe this is the one
>>> that Ben hacked up to not flush or so?
>>
>> He made it to cancel instead of flush.
>
> This makes me think that it's more likely to be a problem in the
> flush_work() implementation.  I went over the code carefully again but
> couldn't find anything suspicious.  Plus, most of the implementation
> is shared between cancel and flush.
>
> I'm gonna write some test code and see whether the flush code behaves
> as expected but in the mean time can you please apply the following
> patch, trigger the problem and report the kernel log?  Also, please
> include the sysrq task dump.  Let's see whether the worker is always
> stuck at the same spot.

I'll test this later today and let you know how it turns out..

Thanks,
Ben

>
> Thanks.
>
> diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
> index b80c386..0ebc386 100644
> --- a/net/mac80211/ieee80211_i.h
> +++ b/net/mac80211/ieee80211_i.h
> @@ -933,6 +933,10 @@ struct ieee80211_local {
>   	struct net_device napi_dev;
>
>   	struct napi_struct napi;
> +
> +	struct timer_list iface_work_timer;
> +	unsigned long iface_work_tstmp;
> +	unsigned int iface_work_runcnt;
>   };
>
>   static inline struct ieee80211_sub_if_data *
> diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
> index 7aa8559..074d5bd 100644
> --- a/net/mac80211/iface.c
> +++ b/net/mac80211/iface.c
> @@ -715,6 +715,14 @@ static void ieee80211_if_setup(struct net_device *dev)
>   	dev->destructor = free_netdev;
>   }
>
> +static void dbg_watchdog_timer(unsigned long __arg)
> +{
> +	struct ieee80211_local *local = (void *)__arg;
> +
> +	pr_warning("ieee80211_iface_work ran for>  5secs, processed %u\n",
> +		   local->iface_work_runcnt);
> +}
> +
>   static void ieee80211_iface_work(struct work_struct *work)
>   {
>   	struct ieee80211_sub_if_data *sdata =
> @@ -738,10 +746,21 @@ static void ieee80211_iface_work(struct work_struct *work)
>   		 "interface work scheduled while going to suspend\n"))
>   		return;
>
> +	local->iface_work_tstmp = jiffies;
> +	local->iface_work_runcnt = 0;
> +
> +	init_timer(&local->iface_work_timer);
> +	local->iface_work_timer.function = dbg_watchdog_timer;
> +	local->iface_work_timer.data = (unsigned long)local;
> +	local->iface_work_timer.expires = local->iface_work_tstmp + 5 * HZ;
> +	add_timer(&local->iface_work_timer);
> +
>   	/* first process frames */
>   	while ((skb = skb_dequeue(&sdata->skb_queue))) {
>   		struct ieee80211_mgmt *mgmt = (void *)skb->data;
>
> +		local->iface_work_runcnt++;
> +
>   		if (skb->pkt_type == IEEE80211_SDATA_QUEUE_AGG_START) {
>   			ra_tid = (void *)&skb->cb;
>   			ieee80211_start_tx_ba_cb(&sdata->vif, ra_tid->ra,
> @@ -843,6 +862,12 @@ static void ieee80211_iface_work(struct work_struct *work)
>   	default:
>   		break;
>   	}
> +
> +	del_timer_sync(&local->iface_work_timer);
> +	if (time_after(jiffies, local->iface_work_tstmp + 4 * HZ))
> +		pr_warning("iee80211_iface_work ran for %lu seconds, runcnt=%u\n",
> +			   (jiffies - local->iface_work_tstmp) / HZ,
> +			   local->iface_work_runcnt);
>   }
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


-- 
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc  http://www.candelatech.com


^ permalink raw reply

* Re: ath5k: Weird Retransmission Behaviour
From: Bob Copeland @ 2010-12-09 17:00 UTC (permalink / raw)
  To: Jonathan Guerin
  Cc: Helmut Schaa, Bruno Randolf, linux-wireless, ath5k-devel, nbd
In-Reply-To: <AANLkTinmsG9NhiiigOrFZQUS+pdDaHSvxpN7JnjdUXs=@mail.gmail.com>

On Fri, Dec 10, 2010 at 12:34:19AM +1000, Jonathan Guerin wrote:
> > For what it's worth, I tested pid and minstrel a while ago with a
> > modified mac80211_hwsim, and found minstrel to be quite a bit better
> > at rate adaptation.  So while it may be worth testing out for this
> > particular use case, minstrel is probably the way to go in general.
> 
> So, while I say this with no idea how to do it, might it be worth
> fixing Minstrel so that it adheres to mac80211's maximum retry values?
 
Yeah, so that's what the linked patch I posted tries to do :)

-- 
Bob Copeland %% www.bobcopeland.com


^ permalink raw reply

* [PATCH] mac80211: Fix NULL-pointer deference on ibss merge when not ready
From: Tim Harvey @ 2010-12-09 16:43 UTC (permalink / raw)
  To: linux-wireless; +Cc: Tim Harvey

dev_open will eventually call ieee80211_ibss_join which sets up the
skb used for beacons/probe-responses however it is possible to
receive beacons that attempt to merge before this occurs causing
a null pointer dereference.

This occurs quite easily in the presence of adhoc nodes with hidden SSID's
---
 net/mac80211/ibss.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 410d104..24e2482 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -86,6 +86,8 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
 	drv_reset_tsf(local);
 
 	skb = ifibss->skb;
+	if (!skb)
+		return; /* not ready to merge yet */
 	rcu_assign_pointer(ifibss->presp, NULL);
 	synchronize_rcu();
 	skb->data = skb->head;
-- 
1.7.0.4


^ permalink raw reply related

* Re: [PATCH] libertas: fix potential NULL-pointer dereference
From: Dan Williams @ 2010-12-09 16:18 UTC (permalink / raw)
  To: Sven Neumann; +Cc: linux-wireless
In-Reply-To: <1291883916.1924.0.camel@sven>

On Thu, 2010-12-09 at 09:38 +0100, Sven Neumann wrote:
> The code wants to check if there's a channel and it is not disabled,
> but it used to check if channel is not NULL and accessed the channel
> struct if this check failed.
> 
> Signed-off-by: Sven Neumann <s.neumann@raumfeld.com>

Acked-by: Dan Williams <dcbw@redhat.com>

> ---
>  drivers/net/wireless/libertas/cfg.c |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c
> index 373930a..113f4f2 100644
> --- a/drivers/net/wireless/libertas/cfg.c
> +++ b/drivers/net/wireless/libertas/cfg.c
> @@ -619,7 +619,7 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy,
>  				     print_ssid(ssid_buf, ssid, ssid_len),
>  				     LBS_SCAN_RSSI_TO_MBM(rssi)/100);
>  
> -			if (channel ||
> +			if (channel &&
>  			    !(channel->flags & IEEE80211_CHAN_DISABLED))
>  				cfg80211_inform_bss(wiphy, channel,
>  					bssid, le64_to_cpu(*(__le64 *)tsfdesc),



^ permalink raw reply

* [PATCH] ath9k: clean up hardware code for beacon handling
From: Mohammed Shafi Shajakhan @ 2010-12-09 16:18 UTC (permalink / raw)
  To: linville
  Cc: linux-wireless, lrodriguez, Mohammed Shafi Shajakhan, doug dahlby

From: Mohammed Shafi Shajakhan <mshajakhan@atheros.com>

The registers TBTT_TIMER ,DMA_BEACON_ALERT ,NEXT_SWBA are need to be
configured only for AP and IBSS mode.

SWBA register is used for generating software interrupts so that beacon
frames will be created by the software.DMA beacon alert register is
to indicate the hardware to DMA the contents of beacon buffer to PCU buffer
and TBTT to start transmitting the packet buffer to the base band.
Clearly these things are not needed for station/monitor mode so
remove configuring them.

Cc: doug dahlby <ddahlby@atheros.com>
Signed-off-by: Mohammed Shafi Shajakhan <mshajakhan@atheros.com>
---
 drivers/net/wireless/ath/ath9k/hw.c |   14 --------------
 1 files changed, 0 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 516227f..1beb896 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1632,12 +1632,6 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period)
 	ENABLE_REGWRITE_BUFFER(ah);
 
 	switch (ah->opmode) {
-	case NL80211_IFTYPE_STATION:
-		REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
-		REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 0xffff);
-		REG_WRITE(ah, AR_NEXT_SWBA, 0x7ffff);
-		flags |= AR_TBTT_TIMER_EN;
-		break;
 	case NL80211_IFTYPE_ADHOC:
 	case NL80211_IFTYPE_MESH_POINT:
 		REG_SET_BIT(ah, AR_TXCFG,
@@ -1661,14 +1655,6 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period)
 			AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN;
 		break;
 	default:
-		if (ah->is_monitoring) {
-			REG_WRITE(ah, AR_NEXT_TBTT_TIMER,
-					TU_TO_USEC(next_beacon));
-			REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 0xffff);
-			REG_WRITE(ah, AR_NEXT_SWBA, 0x7ffff);
-			flags |= AR_TBTT_TIMER_EN;
-			break;
-		}
 		ath_dbg(ath9k_hw_common(ah), ATH_DBG_BEACON,
 			"%s: unsupported opmode: %d\n",
 			__func__, ah->opmode);
-- 
1.7.0.4


^ permalink raw reply related

* Re: [PATCH] mac80211: Fix deadlock in ieee80211_do_stop.
From: Tejun Heo @ 2010-12-09 16:17 UTC (permalink / raw)
  To: Johannes Berg, Ben Greear; +Cc: Luis R. Rodriguez, linux-wireless
In-Reply-To: <4D00EBD8.4090805@kernel.org>

On 12/09/2010 03:46 PM, Tejun Heo wrote:
>> Right, so we're flushing here under RTNL ... I believe this is the one
>> that Ben hacked up to not flush or so?
> 
> He made it to cancel instead of flush.

This makes me think that it's more likely to be a problem in the
flush_work() implementation.  I went over the code carefully again but
couldn't find anything suspicious.  Plus, most of the implementation
is shared between cancel and flush.

I'm gonna write some test code and see whether the flush code behaves
as expected but in the mean time can you please apply the following
patch, trigger the problem and report the kernel log?  Also, please
include the sysrq task dump.  Let's see whether the worker is always
stuck at the same spot.

Thanks.

diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index b80c386..0ebc386 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -933,6 +933,10 @@ struct ieee80211_local {
 	struct net_device napi_dev;

 	struct napi_struct napi;
+
+	struct timer_list iface_work_timer;
+	unsigned long iface_work_tstmp;
+	unsigned int iface_work_runcnt;
 };

 static inline struct ieee80211_sub_if_data *
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 7aa8559..074d5bd 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -715,6 +715,14 @@ static void ieee80211_if_setup(struct net_device *dev)
 	dev->destructor = free_netdev;
 }

+static void dbg_watchdog_timer(unsigned long __arg)
+{
+	struct ieee80211_local *local = (void *)__arg;
+
+	pr_warning("ieee80211_iface_work ran for > 5secs, processed %u\n",
+		   local->iface_work_runcnt);
+}
+
 static void ieee80211_iface_work(struct work_struct *work)
 {
 	struct ieee80211_sub_if_data *sdata =
@@ -738,10 +746,21 @@ static void ieee80211_iface_work(struct work_struct *work)
 		 "interface work scheduled while going to suspend\n"))
 		return;

+	local->iface_work_tstmp = jiffies;
+	local->iface_work_runcnt = 0;
+
+	init_timer(&local->iface_work_timer);
+	local->iface_work_timer.function = dbg_watchdog_timer;
+	local->iface_work_timer.data = (unsigned long)local;
+	local->iface_work_timer.expires = local->iface_work_tstmp + 5 * HZ;
+	add_timer(&local->iface_work_timer);
+
 	/* first process frames */
 	while ((skb = skb_dequeue(&sdata->skb_queue))) {
 		struct ieee80211_mgmt *mgmt = (void *)skb->data;

+		local->iface_work_runcnt++;
+
 		if (skb->pkt_type == IEEE80211_SDATA_QUEUE_AGG_START) {
 			ra_tid = (void *)&skb->cb;
 			ieee80211_start_tx_ba_cb(&sdata->vif, ra_tid->ra,
@@ -843,6 +862,12 @@ static void ieee80211_iface_work(struct work_struct *work)
 	default:
 		break;
 	}
+
+	del_timer_sync(&local->iface_work_timer);
+	if (time_after(jiffies, local->iface_work_tstmp + 4 * HZ))
+		pr_warning("iee80211_iface_work ran for %lu seconds, runcnt=%u\n",
+			   (jiffies - local->iface_work_tstmp) / HZ,
+			   local->iface_work_runcnt);
 }



^ permalink raw reply related

* Re: [PATCH 0/4] Make N-PHY support experimental
From: Rafał Miłecki @ 2010-12-09 16:10 UTC (permalink / raw)
  To: Larry Finger
  Cc: Gábor Stefanik, linux-wireless, John W. Linville, b43-dev
In-Reply-To: <4D00F3C3.6040801@lwfinger.net>

2010/12/9 Larry Finger <Larry.Finger@lwfinger.net>:
> I am willing to buy a higher PHY rev device for testing. Any idea what is in a
> 4324A-BRCM1036? See
> http://cgi.ebay.com/Broadcom-Mini-PCI-e-802-11-a-b-g-n-Wireless-Card-/190477425068?pt=LH_DefaultDomain_0&hash=item2c5956d9ac.

Shipping to: United States

:(

-- 
Rafał

^ permalink raw reply

* Re: [PATCH 0/4] Make N-PHY support experimental
From: Larry Finger @ 2010-12-09 16:03 UTC (permalink / raw)
  To: Rafał Miłecki
  Cc: Johannes Berg, Gábor Stefanik, linux-wireless,
	John W. Linville, b43-dev
In-Reply-To: <AANLkTin133Lq1z1paMboMczaATkAE6zv3gVfXCPSB=hq@mail.gmail.com>

On 12/09/2010 09:37 AM, Rafał Miłecki wrote:
> 2010/12/9 Johannes Berg <johannes@sipsolutions.net>:
>> On Thu, 2010-12-09 at 16:28 +0100, Rafał Miłecki wrote:
>>> I actually asked for some hardware donations on my blog and in news on
>>> polish portal, but didn't receive any serious offer.
>>
>> There probably are still money donations left to buy some ... ?
> 
> The problem I was afraid of was recognizing PHY revision without
> buying a card, just from looking at photos. It seems however, that
> will be the only solution.
> 
> 
>>> Johannes: is there any chance you could put this card in some machine
>>> I could get ssh access to? Or is that some daily-user-card or you
>>> don't really have free machine? Of course I don't need that now, first
>>> we have to make PHY 2 support more complete. But maybe after
>>> Christmas/new year I could focus on that.
>>
>> I can't, unless I magically get a new laptop -- this card is built into
>> my macbook that I use all the time. I'd have a mostly-free machine, and
>> I don't use the card, but it's not a replacable part.
> 
> OK, I'll just think about buying some card :)

I sent a question to the seller of the card I mentioned earlier asking them to
tell me the PCI IDs and explaining why I needed to know. If they answer, we will
at least know if it is a 14e4:432b. If so, then it certainly will have a PHY rev
> 2. At that price, I'm willing to buy it myself, but there should be money
available to get things for Rafał. Who has those funds? I think the last time I
got something though the donations, it was Stefano, but that was a long time ago.

Rafał: If I get a rev > 2 card, you can certainly ssh into my computer for
testing, or I can do the runs here and send you the dumps.

Larry


Larry

^ permalink raw reply

* Re: [PATCH 0/4] Make N-PHY support experimental
From: Rafał Miłecki @ 2010-12-09 15:37 UTC (permalink / raw)
  To: Johannes Berg
  Cc: Larry Finger, Gábor Stefanik, linux-wireless,
	John W. Linville, b43-dev
In-Reply-To: <1291908833.3540.18.camel@jlt3.sipsolutions.net>

2010/12/9 Johannes Berg <johannes@sipsolutions.net>:
> On Thu, 2010-12-09 at 16:28 +0100, Rafał Miłecki wrote:
>> I actually asked for some hardware donations on my blog and in news on
>> polish portal, but didn't receive any serious offer.
>
> There probably are still money donations left to buy some ... ?

The problem I was afraid of was recognizing PHY revision without
buying a card, just from looking at photos. It seems however, that
will be the only solution.


>> Johannes: is there any chance you could put this card in some machine
>> I could get ssh access to? Or is that some daily-user-card or you
>> don't really have free machine? Of course I don't need that now, first
>> we have to make PHY 2 support more complete. But maybe after
>> Christmas/new year I could focus on that.
>
> I can't, unless I magically get a new laptop -- this card is built into
> my macbook that I use all the time. I'd have a mostly-free machine, and
> I don't use the card, but it's not a replacable part.

OK, I'll just think about buying some card :)

-- 
Rafał

^ permalink raw reply

* Re: [PATCH 0/4] Make N-PHY support experimental
From: Johannes Berg @ 2010-12-09 15:33 UTC (permalink / raw)
  To: Rafał Miłecki
  Cc: Larry Finger, Gábor Stefanik, linux-wireless,
	John W. Linville, b43-dev
In-Reply-To: <AANLkTimZTzMbQenxs6-1awdoGBhbJz2kyGBSO9v2+fzn@mail.gmail.com>

On Thu, 2010-12-09 at 16:28 +0100, Rafał Miłecki wrote:

> I actually asked for some hardware donations on my blog and in news on
> polish portal, but didn't receive any serious offer.

There probably are still money donations left to buy some ... ?

> Johannes: is there any chance you could put this card in some machine
> I could get ssh access to? Or is that some daily-user-card or you
> don't really have free machine? Of course I don't need that now, first
> we have to make PHY 2 support more complete. But maybe after
> Christmas/new year I could focus on that.

I can't, unless I magically get a new laptop -- this card is built into
my macbook that I use all the time. I'd have a mostly-free machine, and
I don't use the card, but it's not a replacable part.

johannes


^ permalink raw reply

* Re: [PATCH 0/4] Make N-PHY support experimental
From: Rafał Miłecki @ 2010-12-09 15:28 UTC (permalink / raw)
  To: Johannes Berg
  Cc: Larry Finger, Gábor Stefanik, linux-wireless,
	John W. Linville, b43-dev
In-Reply-To: <1291908338.3540.16.camel@jlt3.sipsolutions.net>

2010/12/9 Johannes Berg <johannes@sipsolutions.net>:
> On Thu, 2010-12-09 at 09:20 -0600, Larry Finger wrote:
>
>> It has a rev 2 PHY, and a rev 4 0x2055 radio.
>>
>> I am willing to buy a higher PHY rev device for testing. Any idea what is in a
>> 4324A-BRCM1036?
>
> It says BCM94322 on the image, and if that's any indication, I have a
> 4322 with pci ID 14e4:432b (but it's an Apple build):
>
> b43-phy0: Broadcom 4322 WLAN found (core revision 16)
> b43-phy0 debug: Found PHY: Analog 8, Type 4, Revision 4
> b43-phy0 debug: Found Radio: Manuf 0x17F, Version 0x2056, Revision 3

I actually asked for some hardware donations on my blog and in news on
polish portal, but didn't receive any serious offer.

Johannes: is there any chance you could put this card in some machine
I could get ssh access to? Or is that some daily-user-card or you
don't really have free machine? Of course I don't need that now, first
we have to make PHY 2 support more complete. But maybe after
Christmas/new year I could focus on that.

-- 
Rafał

^ permalink raw reply

* Re: [PATCH 0/4] Make N-PHY support experimental
From: Johannes Berg @ 2010-12-09 15:25 UTC (permalink / raw)
  To: Larry Finger
  Cc: Rafał Miłecki, Gábor Stefanik, linux-wireless,
	John W. Linville, b43-dev
In-Reply-To: <4D00F3C3.6040801@lwfinger.net>

On Thu, 2010-12-09 at 09:20 -0600, Larry Finger wrote:

> It has a rev 2 PHY, and a rev 4 0x2055 radio.
> 
> I am willing to buy a higher PHY rev device for testing. Any idea what is in a
> 4324A-BRCM1036?

It says BCM94322 on the image, and if that's any indication, I have a
4322 with pci ID 14e4:432b (but it's an Apple build):

b43-phy0: Broadcom 4322 WLAN found (core revision 16)
b43-phy0 debug: Found PHY: Analog 8, Type 4, Revision 4
b43-phy0 debug: Found Radio: Manuf 0x17F, Version 0x2056, Revision 3

johannes


^ permalink raw reply

* Re: [PATCH 0/4] Make N-PHY support experimental
From: Larry Finger @ 2010-12-09 15:20 UTC (permalink / raw)
  To: Rafał Miłecki
  Cc: Gábor Stefanik, linux-wireless, John W. Linville, b43-dev
In-Reply-To: <AANLkTi=mDh9wkp+u3ebuXqF8Q-rTW_YCtee3CmCBdWTh@mail.gmail.com>

On 12/09/2010 08:11 AM, Rafał Miłecki wrote:
> 2010/12/8 Larry Finger <Larry.Finger@lwfinger.net>:
>> I have a bit more info regarding the problem with WPA2 encryption on an N PHY.
>> As shown in the NetworkManager log attached, Authentication is successful, but
>> DHCP fails. Either the transmit data is improperly encrypted, or the decryption
>> fails. I will use wireshark to sort that out. Note: Using software encryption
>> makes no difference.
> 
> Hm, I expected software encryption to work, that's weird. I don't
> really have nice access to my development machine, so some tests would
> be great.

Actually, when I got wireshark all setup on my netbook and tried again, WPA2
worked with hardware encryption. I'm not sure what the problem was the first time.

I still have no idea why OFDM rates are failing. Any thoughts?

My device lists the following:

Network controller [0280]: Broadcom Corporation BCM4321 802.11a/b/g/n
[14e4:4328] (rev 03)
ssb: Core 0 found: ChipCommon (cc 0x800, rev 0x13, vendor 0x4243)
ssb: Core 1 found: IEEE 802.11 (cc 0x812, rev 0x0C, vendor 0x4243)
ssb: Core 2 found: PCI-E (cc 0x820, rev 0x04, vendor 0x4243)
ssb: Core 3 found: PCI (cc 0x804, rev 0x0D, vendor 0x4243)
ssb: Core 4 found: USB 1.1 Host (cc 0x817, rev 0x04, vendor 0x4243)

It has a rev 2 PHY, and a rev 4 0x2055 radio.

I am willing to buy a higher PHY rev device for testing. Any idea what is in a
4324A-BRCM1036? See
http://cgi.ebay.com/Broadcom-Mini-PCI-e-802-11-a-b-g-n-Wireless-Card-/190477425068?pt=LH_DefaultDomain_0&hash=item2c5956d9ac.

Larry

^ permalink raw reply

* [PATCH] staging: brcm80211: Remove redundant unlikely()
From: Tobias Klauser @ 2010-12-09 15:01 UTC (permalink / raw)
  To: Brett Rudley, Henry Ptasinski, Nohee Ko, Greg Kroah-Hartman
  Cc: linux-wireless, devel, kernel-janitors

IS_ERR() already implies unlikely(), so it can be omitted here.

Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
---
 drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c
index 0d7aa4a..edf300d 100644
--- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c
@@ -3196,7 +3196,7 @@ s32 wl_cfg80211_attach(struct net_device *ndev, void *data)
 	}
 	WL_DBG(("func %p\n", wl_cfg80211_get_sdio_func()));
 	wdev = wl_alloc_wdev(sizeof(struct wl_iface), &wl_cfg80211_get_sdio_func()->dev);
-	if (unlikely(IS_ERR(wdev)))
+	if (IS_ERR(wdev))
 		return -ENOMEM;
 
 	wdev->iftype = wl_mode_to_nl80211_iftype(WL_MODE_BSS);
-- 
1.7.0.4


^ 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