Linux wireless drivers development
 help / color / mirror / Atom feed
* Re: Insist on cfg80211 for new drivers?
From: Christoph Hellwig @ 2009-07-02  9:19 UTC (permalink / raw)
  To: Marcel Holtmann
  Cc: Luis R. Rodriguez, Greg KH, John W. Linville, Dan Williams, Dave,
	Karl Relton, dwmw2, linux-wireless
In-Reply-To: <1246486104.12994.169.camel@localhost.localdomain>

On Wed, Jul 01, 2009 at 03:08:24PM -0700, Marcel Holtmann wrote:
> that is what Greg mentioned to me. If there is no activity for 6 month
> and the driver is not getting anywhere, he going to drop it.

If that were true and not just an excuse the whole initial batch and a
couple of later drivers would be gone now.


^ permalink raw reply

* [PATCH] cfg80211: send events for userspace SME
From: Johannes Berg @ 2009-07-02  7:58 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless
In-Reply-To: <20090701192641.072258140@sipsolutions.net>

When the userspace SME is in control, we are currently not sending
events, but this means that any userspace applications using wext
or nl80211 to receive events will not know what's going on unless
they can also interpret the nl80211 assoc event. Since we have all
the required code, let the SME follow events from the userspace
SME, this even means that you will be refused to connect() while
the userspace SME is in control and connected.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
 net/wireless/sme.c |   64 +++++++++++++++++++++++++++++++----------------------
 1 file changed, 38 insertions(+), 26 deletions(-)

--- wireless-testing.orig/net/wireless/sme.c	2009-07-02 09:56:39.000000000 +0200
+++ wireless-testing/net/wireless/sme.c	2009-07-02 09:56:43.000000000 +0200
@@ -287,6 +287,44 @@ static void __cfg80211_connect_result(st
 	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION))
 		return;
 
+	if (wdev->sme_state == CFG80211_SME_CONNECTED)
+		nl80211_send_roamed(wiphy_to_dev(wdev->wiphy), dev,
+				    bssid, req_ie, req_ie_len,
+				    resp_ie, resp_ie_len, gfp);
+	else
+		nl80211_send_connect_result(wiphy_to_dev(wdev->wiphy), dev,
+					    bssid, req_ie, req_ie_len,
+					    resp_ie, resp_ie_len,
+					    status, gfp);
+
+#ifdef CONFIG_WIRELESS_EXT
+	if (wextev) {
+		if (req_ie && status == WLAN_STATUS_SUCCESS) {
+			memset(&wrqu, 0, sizeof(wrqu));
+			wrqu.data.length = req_ie_len;
+			wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu, req_ie);
+		}
+
+		if (resp_ie && status == WLAN_STATUS_SUCCESS) {
+			memset(&wrqu, 0, sizeof(wrqu));
+			wrqu.data.length = resp_ie_len;
+			wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu, resp_ie);
+		}
+
+		memset(&wrqu, 0, sizeof(wrqu));
+		wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+		if (bssid && status == WLAN_STATUS_SUCCESS)
+			memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN);
+		wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
+	}
+#endif
+
+	if (status == WLAN_STATUS_SUCCESS &&
+	    wdev->sme_state == CFG80211_SME_IDLE) {
+		wdev->sme_state = CFG80211_SME_CONNECTED;
+		return;
+	}
+
 	if (wdev->sme_state != CFG80211_SME_CONNECTING)
 		return;
 
@@ -315,32 +353,6 @@ static void __cfg80211_connect_result(st
 
 	if (wdev->conn)
 		wdev->conn->state = CFG80211_CONN_IDLE;
-
-	nl80211_send_connect_result(wiphy_to_dev(wdev->wiphy), dev, bssid,
-				    req_ie, req_ie_len, resp_ie, resp_ie_len,
-				    status, gfp);
-
-#ifdef CONFIG_WIRELESS_EXT
-	if (wextev) {
-		if (req_ie && status == WLAN_STATUS_SUCCESS) {
-			memset(&wrqu, 0, sizeof(wrqu));
-			wrqu.data.length = req_ie_len;
-			wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu, req_ie);
-		}
-
-		if (resp_ie && status == WLAN_STATUS_SUCCESS) {
-			memset(&wrqu, 0, sizeof(wrqu));
-			wrqu.data.length = resp_ie_len;
-			wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu, resp_ie);
-		}
-
-		memset(&wrqu, 0, sizeof(wrqu));
-		wrqu.ap_addr.sa_family = ARPHRD_ETHER;
-		if (bssid && status == WLAN_STATUS_SUCCESS)
-			memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN);
-		wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
-	}
-#endif
 }
 
 void cfg80211_connect_result(struct net_device *dev, const u8 *bssid,



^ permalink raw reply

* [PATCH 14/20 v4.1] cfg80211: emulate connect with auth/assoc
From: Johannes Berg @ 2009-07-02  7:13 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless, Samuel Ortiz
In-Reply-To: <20090701193420.934470582@sipsolutions.net>

This adds code to cfg80211 so that drivers (mac80211 right
now) that don't implement connect but rather auth/assoc can
still be used with the nl80211 connect command. This will
also be necessary for the wext compat code.

Signed-off-by: Samuel Ortiz <samuel.ortiz@intel.com>
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
v4: dynamically allocate conn data
v4.1: fix warnings with userspace SME

 include/net/cfg80211.h |    6 
 net/wireless/core.c    |    7 
 net/wireless/core.h    |    8 
 net/wireless/mlme.c    |   81 +++++++---
 net/wireless/nl80211.c |    4 
 net/wireless/scan.c    |    7 
 net/wireless/sme.c     |  395 +++++++++++++++++++++++++++++++++++++++++++++++--
 7 files changed, 475 insertions(+), 33 deletions(-)

--- wireless-testing.orig/net/wireless/core.h	2009-07-01 21:28:15.000000000 +0200
+++ wireless-testing/net/wireless/core.h	2009-07-02 08:46:10.000000000 +0200
@@ -62,6 +62,8 @@ struct cfg80211_registered_device {
 	struct genl_info *testmode_info;
 #endif
 
+	struct work_struct conn_work;
+
 #ifdef CONFIG_CFG80211_DEBUGFS
 	/* Debugfs entries */
 	struct wiphy_debugfsdentries {
@@ -181,8 +183,14 @@ int cfg80211_connect(struct cfg80211_reg
 int cfg80211_disconnect(struct cfg80211_registered_device *rdev,
 			struct net_device *dev, u16 reason);
 
+void cfg80211_conn_work(struct work_struct *work);
+
 /* internal helpers */
 int cfg80211_validate_key_settings(struct key_params *params, int key_idx,
 				   const u8 *mac_addr);
+void __cfg80211_disconnected(struct net_device *dev, gfp_t gfp, u8 *ie,
+			     size_t ie_len, u16 reason, bool from_ap);
+void cfg80211_sme_scan_done(struct net_device *dev);
+void cfg80211_sme_rx_auth(struct net_device *dev, const u8 *buf, size_t len);
 
 #endif /* __NET_WIRELESS_CORE_H */
--- wireless-testing.orig/net/wireless/nl80211.c	2009-07-01 21:28:15.000000000 +0200
+++ wireless-testing/net/wireless/nl80211.c	2009-07-02 08:46:10.000000000 +0200
@@ -351,12 +351,12 @@ static int nl80211_send_wiphy(struct sk_
 
 #undef CMD
 
-	if (dev->ops->connect) {
+	if (dev->ops->connect || dev->ops->auth) {
 		i++;
 		NLA_PUT_U32(msg, i, NL80211_CMD_CONNECT);
 	}
 
-	if (dev->ops->disconnect) {
+	if (dev->ops->disconnect || dev->ops->deauth) {
 		i++;
 		NLA_PUT_U32(msg, i, NL80211_CMD_DISCONNECT);
 	}
--- wireless-testing.orig/net/wireless/sme.c	2009-07-01 21:28:15.000000000 +0200
+++ wireless-testing/net/wireless/sme.c	2009-07-02 08:47:45.000000000 +0200
@@ -12,6 +12,266 @@
 #include <net/rtnetlink.h>
 #include "nl80211.h"
 
+struct cfg80211_conn {
+	struct cfg80211_connect_params params;
+	/* these are sub-states of the _CONNECTING sme_state */
+	enum {
+		CFG80211_CONN_IDLE,
+		CFG80211_CONN_SCANNING,
+		CFG80211_CONN_SCAN_AGAIN,
+		CFG80211_CONN_AUTHENTICATE_NEXT,
+		CFG80211_CONN_AUTHENTICATING,
+		CFG80211_CONN_ASSOCIATE_NEXT,
+		CFG80211_CONN_ASSOCIATING,
+	} state;
+	u8 bssid[ETH_ALEN];
+	u8 *ie;
+	size_t ie_len;
+	bool auto_auth;
+};
+
+
+static int cfg80211_conn_scan(struct wireless_dev *wdev)
+{
+	struct cfg80211_registered_device *drv = wiphy_to_dev(wdev->wiphy);
+	struct cfg80211_scan_request *request;
+	int n_channels, err;
+
+	ASSERT_RTNL();
+
+	if (drv->scan_req)
+		return -EBUSY;
+
+	if (wdev->conn->params.channel) {
+		n_channels = 1;
+	} else {
+		enum ieee80211_band band;
+		n_channels = 0;
+
+		for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+			if (!wdev->wiphy->bands[band])
+				continue;
+			n_channels += wdev->wiphy->bands[band]->n_channels;
+		}
+	}
+	request = kzalloc(sizeof(*request) + sizeof(request->ssids[0]) +
+			  sizeof(request->channels[0]) * n_channels,
+			  GFP_KERNEL);
+	if (!request)
+		return -ENOMEM;
+
+	request->channels = (void *)((char *)request + sizeof(*request));
+	if (wdev->conn->params.channel)
+		request->channels[0] = wdev->conn->params.channel;
+	else {
+		int i = 0, j;
+		enum ieee80211_band band;
+
+		for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+			if (!wdev->wiphy->bands[band])
+				continue;
+			for (j = 0; j < wdev->wiphy->bands[band]->n_channels;
+			     i++, j++)
+				request->channels[i] =
+					&wdev->wiphy->bands[band]->channels[j];
+		}
+	}
+	request->n_channels = n_channels;
+	request->ssids = (void *)(request->channels + n_channels);
+	request->n_ssids = 1;
+
+	memcpy(request->ssids[0].ssid, wdev->conn->params.ssid,
+		wdev->conn->params.ssid_len);
+	request->ssids[0].ssid_len = wdev->conn->params.ssid_len;
+
+	request->ifidx = wdev->netdev->ifindex;
+	request->wiphy = &drv->wiphy;
+
+	drv->scan_req = request;
+
+	err = drv->ops->scan(wdev->wiphy, wdev->netdev, request);
+	if (!err) {
+		wdev->conn->state = CFG80211_CONN_SCANNING;
+		nl80211_send_scan_start(drv, wdev->netdev);
+	} else {
+		drv->scan_req = NULL;
+		kfree(request);
+	}
+	return err;
+}
+
+static int cfg80211_conn_do_work(struct wireless_dev *wdev)
+{
+	struct cfg80211_registered_device *drv = wiphy_to_dev(wdev->wiphy);
+	union {
+		struct cfg80211_auth_request auth_req;
+		struct cfg80211_assoc_request assoc_req;
+	} u;
+
+	memset(&u, 0, sizeof(u));
+
+	if (!wdev->conn)
+		return 0;
+
+	switch (wdev->conn->state) {
+	case CFG80211_CONN_SCAN_AGAIN:
+		return cfg80211_conn_scan(wdev);
+	case CFG80211_CONN_AUTHENTICATE_NEXT:
+		u.auth_req.chan = wdev->conn->params.channel;
+		u.auth_req.peer_addr = wdev->conn->params.bssid;
+		u.auth_req.ssid = wdev->conn->params.ssid;
+		u.auth_req.ssid_len = wdev->conn->params.ssid_len;
+		u.auth_req.auth_type = wdev->conn->params.auth_type;
+		u.auth_req.ie = NULL;
+		u.auth_req.ie_len = 0;
+		wdev->conn->state = CFG80211_CONN_AUTHENTICATING;
+		BUG_ON(!drv->ops->auth);
+		return drv->ops->auth(wdev->wiphy, wdev->netdev, &u.auth_req);
+	case CFG80211_CONN_ASSOCIATE_NEXT:
+		u.assoc_req.chan = wdev->conn->params.channel;
+		u.assoc_req.peer_addr = wdev->conn->params.bssid;
+		u.assoc_req.ssid = wdev->conn->params.ssid;
+		u.assoc_req.ssid_len = wdev->conn->params.ssid_len;
+		u.assoc_req.ie = wdev->conn->params.ie;
+		u.assoc_req.ie_len = wdev->conn->params.ie_len;
+		u.assoc_req.use_mfp = false;
+		memcpy(&u.assoc_req.crypto, &wdev->conn->params.crypto,
+			sizeof(u.assoc_req.crypto));
+		wdev->conn->state = CFG80211_CONN_ASSOCIATING;
+		BUG_ON(!drv->ops->assoc);
+		return drv->ops->assoc(wdev->wiphy, wdev->netdev,
+					&u.assoc_req);
+	default:
+		return 0;
+	}
+}
+
+void cfg80211_conn_work(struct work_struct *work)
+{
+	struct cfg80211_registered_device *drv =
+		container_of(work, struct cfg80211_registered_device, conn_work);
+	struct wireless_dev *wdev;
+
+	rtnl_lock();
+	mutex_lock(&drv->devlist_mtx);
+
+	list_for_each_entry(wdev, &drv->netdev_list, list) {
+		if (!netif_running(wdev->netdev))
+			continue;
+		if (wdev->sme_state != CFG80211_SME_CONNECTING)
+			continue;
+		if (cfg80211_conn_do_work(wdev))
+			cfg80211_connect_result(wdev->netdev,
+						wdev->conn->params.bssid,
+						NULL, 0, NULL, 0,
+						WLAN_STATUS_UNSPECIFIED_FAILURE,
+						GFP_ATOMIC);
+	}
+
+	mutex_unlock(&drv->devlist_mtx);
+	rtnl_unlock();
+}
+
+static bool cfg80211_get_conn_bss(struct wireless_dev *wdev)
+{
+	struct cfg80211_registered_device *drv = wiphy_to_dev(wdev->wiphy);
+	struct cfg80211_bss *bss;
+	u16 capa = WLAN_CAPABILITY_ESS;
+
+	if (wdev->conn->params.privacy)
+		capa |= WLAN_CAPABILITY_PRIVACY;
+
+	bss = cfg80211_get_bss(wdev->wiphy, NULL, wdev->conn->params.bssid,
+			       wdev->conn->params.ssid,
+			       wdev->conn->params.ssid_len,
+			       WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_PRIVACY,
+			       capa);
+
+	if (!bss)
+		return false;
+
+	memcpy(wdev->conn->bssid, bss->bssid, ETH_ALEN);
+	wdev->conn->params.bssid = wdev->conn->bssid;
+	wdev->conn->params.channel = bss->channel;
+	wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT;
+	schedule_work(&drv->conn_work);
+
+	cfg80211_put_bss(bss);
+	return true;
+}
+
+void cfg80211_sme_scan_done(struct net_device *dev)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_registered_device *drv = wiphy_to_dev(wdev->wiphy);
+
+	if (wdev->sme_state != CFG80211_SME_CONNECTING)
+		return;
+
+	if (WARN_ON(!wdev->conn))
+		return;
+
+	if (wdev->conn->state != CFG80211_CONN_SCANNING &&
+	    wdev->conn->state != CFG80211_CONN_SCAN_AGAIN)
+		return;
+
+	if (!cfg80211_get_conn_bss(wdev)) {
+		/* not found */
+		if (wdev->conn->state == CFG80211_CONN_SCAN_AGAIN)
+			schedule_work(&drv->conn_work);
+		else
+			cfg80211_connect_result(dev, wdev->conn->params.bssid,
+						NULL, 0, NULL, 0,
+						WLAN_STATUS_UNSPECIFIED_FAILURE,
+						GFP_ATOMIC);
+		return;
+	}
+}
+
+void cfg80211_sme_rx_auth(struct net_device *dev, const u8 *buf, size_t len)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct wiphy *wiphy = wdev->wiphy;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
+	u16 status_code = le16_to_cpu(mgmt->u.auth.status_code);
+
+	/* should only RX auth frames when connecting */
+	if (wdev->sme_state != CFG80211_SME_CONNECTING)
+		return;
+
+	if (WARN_ON(!wdev->conn))
+		return;
+
+	if (status_code == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG &&
+	    wdev->conn->auto_auth &&
+	    wdev->conn->params.auth_type != NL80211_AUTHTYPE_NETWORK_EAP) {
+		/* select automatically between only open, shared, leap */
+		switch (wdev->conn->params.auth_type) {
+		case NL80211_AUTHTYPE_OPEN_SYSTEM:
+			wdev->conn->params.auth_type =
+				NL80211_AUTHTYPE_SHARED_KEY;
+			break;
+		case NL80211_AUTHTYPE_SHARED_KEY:
+			wdev->conn->params.auth_type =
+				NL80211_AUTHTYPE_NETWORK_EAP;
+			break;
+		default:
+			/* huh? */
+			wdev->conn->params.auth_type =
+				NL80211_AUTHTYPE_OPEN_SYSTEM;
+			break;
+		}
+		wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT;
+		schedule_work(&rdev->conn_work);
+	} else if (status_code != WLAN_STATUS_SUCCESS)
+		wdev->sme_state = CFG80211_SME_IDLE;
+	else if (wdev->sme_state == CFG80211_SME_CONNECTING &&
+		 wdev->conn->state == CFG80211_CONN_AUTHENTICATING) {
+		wdev->conn->state = CFG80211_CONN_ASSOCIATE_NEXT;
+		schedule_work(&rdev->conn_work);
+	}
+}
 
 void cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
 			     const u8 *req_ie, size_t req_ie_len,
@@ -27,7 +287,7 @@ void cfg80211_connect_result(struct net_
 	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION))
 		return;
 
-	if (WARN_ON(wdev->sme_state != CFG80211_SME_CONNECTING))
+	if (wdev->sme_state != CFG80211_SME_CONNECTING)
 		return;
 
 	if (wdev->current_bss) {
@@ -53,6 +313,9 @@ void cfg80211_connect_result(struct net_
 		wdev->sme_state = CFG80211_SME_IDLE;
 	}
 
+	if (wdev->conn)
+		wdev->conn->state = CFG80211_CONN_IDLE;
+
 	nl80211_send_connect_result(wiphy_to_dev(wdev->wiphy), dev, bssid,
 				    req_ie, req_ie_len, resp_ie, resp_ie_len,
 				    status, gfp);
@@ -72,7 +335,7 @@ void cfg80211_connect_result(struct net_
 
 	memset(&wrqu, 0, sizeof(wrqu));
 	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
-	if (bssid)
+	if (bssid && status == WLAN_STATUS_SUCCESS)
 		memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN);
 	wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
 #endif
@@ -138,9 +401,8 @@ void cfg80211_roamed(struct net_device *
 }
 EXPORT_SYMBOL(cfg80211_roamed);
 
-static void __cfg80211_disconnected(struct net_device *dev, gfp_t gfp,
-				    u8 *ie, size_t ie_len, u16 reason,
-				    bool from_ap)
+void __cfg80211_disconnected(struct net_device *dev, gfp_t gfp, u8 *ie,
+			     size_t ie_len, u16 reason, bool from_ap)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 #ifdef CONFIG_WIRELESS_EXT
@@ -161,6 +423,11 @@ static void __cfg80211_disconnected(stru
 	wdev->current_bss = NULL;
 	wdev->sme_state = CFG80211_SME_IDLE;
 
+	if (wdev->conn) {
+		kfree(wdev->conn->ie);
+		wdev->conn->ie = NULL;
+	}
+
 	nl80211_send_disconnected(wiphy_to_dev(wdev->wiphy), dev,
 				  reason, ie, ie_len, from_ap, gfp);
 
@@ -174,7 +441,7 @@ static void __cfg80211_disconnected(stru
 void cfg80211_disconnected(struct net_device *dev, u16 reason,
 			   u8 *ie, size_t ie_len, gfp_t gfp)
 {
-	__cfg80211_disconnected(dev, reason, ie, ie_len, true, gfp);
+	__cfg80211_disconnected(dev, gfp, ie, ie_len, reason, true);
 }
 EXPORT_SYMBOL(cfg80211_disconnected);
 
@@ -189,7 +456,74 @@ int cfg80211_connect(struct cfg80211_reg
 		return -EALREADY;
 
 	if (!rdev->ops->connect) {
-		return -EOPNOTSUPP;
+		if (!rdev->ops->auth || !rdev->ops->assoc)
+			return -EOPNOTSUPP;
+
+		if (!wdev->conn) {
+			wdev->conn = kzalloc(sizeof(*wdev->conn), GFP_KERNEL);
+			if (!wdev->conn)
+				return -ENOMEM;
+		} else
+			memset(wdev->conn, 0, sizeof(*wdev->conn));
+
+		/*
+		 * Copy all parameters, and treat explicitly IEs, BSSID, SSID.
+		 */
+		memcpy(&wdev->conn->params, connect, sizeof(*connect));
+		if (connect->bssid) {
+			wdev->conn->params.bssid = wdev->conn->bssid;
+			memcpy(wdev->conn->bssid, connect->bssid, ETH_ALEN);
+		}
+
+		if (connect->ie) {
+			wdev->conn->ie = kmemdup(connect->ie, connect->ie_len,
+						GFP_KERNEL);
+			wdev->conn->params.ie = wdev->conn->ie;
+			if (!wdev->conn->ie)
+				return -ENOMEM;
+		}
+
+		if (connect->auth_type == NL80211_AUTHTYPE_AUTOMATIC) {
+			wdev->conn->auto_auth = true;
+			/* start with open system ... should mostly work */
+			wdev->conn->params.auth_type =
+				NL80211_AUTHTYPE_OPEN_SYSTEM;
+		} else {
+			wdev->conn->auto_auth = false;
+		}
+
+		memcpy(wdev->ssid, connect->ssid, connect->ssid_len);
+		wdev->ssid_len = connect->ssid_len;
+		wdev->conn->params.ssid = wdev->ssid;
+		wdev->conn->params.ssid_len = connect->ssid_len;
+
+		/* don't care about result -- but fill bssid & channel */
+		if (!wdev->conn->params.bssid || !wdev->conn->params.channel)
+			cfg80211_get_conn_bss(wdev);
+
+		wdev->sme_state = CFG80211_SME_CONNECTING;
+
+		/* we're good if we have both BSSID and channel */
+		if (wdev->conn->params.bssid && wdev->conn->params.channel) {
+			wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT;
+			err = cfg80211_conn_do_work(wdev);
+		} else {
+			/* otherwise we'll need to scan for the AP first */
+			err = cfg80211_conn_scan(wdev);
+			/*
+			 * If we can't scan right now, then we need to scan again
+			 * after the current scan finished, since the parameters
+			 * changed (unless we find a good AP anyway).
+			 */
+			if (err == -EBUSY) {
+				err = 0;
+				wdev->conn->state = CFG80211_CONN_SCAN_AGAIN;
+			}
+		}
+		if (err)
+			wdev->sme_state = CFG80211_SME_IDLE;
+
+		return err;
 	} else {
 		wdev->sme_state = CFG80211_SME_CONNECTING;
 		err = rdev->ops->connect(&rdev->wiphy, dev, connect);
@@ -197,28 +531,63 @@ int cfg80211_connect(struct cfg80211_reg
 			wdev->sme_state = CFG80211_SME_IDLE;
 			return err;
 		}
-	}
 
-	memcpy(wdev->ssid, connect->ssid, connect->ssid_len);
-	wdev->ssid_len = connect->ssid_len;
+		memcpy(wdev->ssid, connect->ssid, connect->ssid_len);
+		wdev->ssid_len = connect->ssid_len;
 
-	return 0;
+		return 0;
+	}
 }
 
 int cfg80211_disconnect(struct cfg80211_registered_device *rdev,
 			struct net_device *dev, u16 reason)
 {
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	int err;
 
+	if (wdev->sme_state == CFG80211_SME_IDLE)
+		return -EINVAL;
+
 	if (!rdev->ops->disconnect) {
-		return -EOPNOTSUPP;
+		struct cfg80211_deauth_request deauth;
+		u8 bssid[ETH_ALEN];
+
+		/* internal bug. */
+		if (WARN_ON(!wdev->conn))
+			return -EINVAL;
+
+		if (wdev->sme_state == CFG80211_SME_CONNECTING &&
+		    (wdev->conn->state == CFG80211_CONN_SCANNING ||
+		     wdev->conn->state == CFG80211_CONN_SCAN_AGAIN)) {
+			wdev->sme_state = CFG80211_SME_IDLE;
+			return 0;
+		}
+
+		if (!rdev->ops->deauth)
+			return -EOPNOTSUPP;
+
+		memset(&deauth, 0, sizeof(deauth));
+
+		/* wdev->conn->params.bssid must be set if > SCANNING */
+		memcpy(bssid, wdev->conn->params.bssid, ETH_ALEN);
+		deauth.peer_addr = bssid;
+		deauth.reason_code = reason;
+
+		err = rdev->ops->deauth(&rdev->wiphy, dev, &deauth);
+		if (err)
+			return err;
 	} else {
 		err = rdev->ops->disconnect(&rdev->wiphy, dev, reason);
 		if (err)
 			return err;
 	}
 
-	__cfg80211_disconnected(dev, 0, NULL, 0, false, GFP_KERNEL);
+	if (wdev->sme_state == CFG80211_SME_CONNECTED)
+		__cfg80211_disconnected(dev, GFP_KERNEL, NULL, 0, 0, false);
+	else if (wdev->sme_state == CFG80211_SME_CONNECTING)
+		cfg80211_connect_result(dev, NULL, NULL, 0, NULL, 0,
+					WLAN_STATUS_UNSPECIFIED_FAILURE,
+					GFP_KERNEL);
 
 	return 0;
 }
--- wireless-testing.orig/net/wireless/mlme.c	2009-07-01 21:28:14.000000000 +0200
+++ wireless-testing/net/wireless/mlme.c	2009-07-01 21:28:15.000000000 +0200
@@ -16,58 +16,105 @@ void cfg80211_send_rx_auth(struct net_de
 {
 	struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+
 	nl80211_send_rx_auth(rdev, dev, buf, len, gfp);
+	cfg80211_sme_rx_auth(dev, buf, len);
 }
 EXPORT_SYMBOL(cfg80211_send_rx_auth);
 
 void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len, gfp_t gfp)
 {
-	struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
-	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+	u16 status_code;
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct wiphy *wiphy = wdev->wiphy;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
+	u8 *ie = mgmt->u.assoc_resp.variable;
+	int ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
+
+	status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
+
 	nl80211_send_rx_assoc(rdev, dev, buf, len, gfp);
+
+	cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs,
+				status_code, gfp);
 }
 EXPORT_SYMBOL(cfg80211_send_rx_assoc);
 
 void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len, gfp_t gfp)
 {
-	struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct wiphy *wiphy = wdev->wiphy;
 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
+
 	nl80211_send_deauth(rdev, dev, buf, len, gfp);
+
+	if (wdev->sme_state == CFG80211_SME_CONNECTED) {
+		u16 reason_code;
+		bool from_ap;
+
+		reason_code = le16_to_cpu(mgmt->u.deauth.reason_code);
+
+		from_ap = memcmp(mgmt->da, dev->dev_addr, ETH_ALEN) == 0;
+		__cfg80211_disconnected(dev, gfp, NULL, 0,
+					reason_code, from_ap);
+
+		wdev->sme_state = CFG80211_SME_IDLE;
+	} else if (wdev->sme_state == CFG80211_SME_CONNECTING) {
+		cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, NULL, 0,
+					WLAN_STATUS_UNSPECIFIED_FAILURE, gfp);
+	}
 }
 EXPORT_SYMBOL(cfg80211_send_deauth);
 
 void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len, gfp_t gfp)
 {
-	struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct wiphy *wiphy = wdev->wiphy;
 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
+
 	nl80211_send_disassoc(rdev, dev, buf, len, gfp);
-}
-EXPORT_SYMBOL(cfg80211_send_disassoc);
 
-static void cfg80211_wext_disconnected(struct net_device *dev)
-{
-#ifdef CONFIG_WIRELESS_EXT
-	union iwreq_data wrqu;
-	memset(&wrqu, 0, sizeof(wrqu));
-	wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
-#endif
+	if (wdev->sme_state == CFG80211_SME_CONNECTED) {
+		u16 reason_code;
+		bool from_ap;
+
+		reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
+
+		from_ap = memcmp(mgmt->da, dev->dev_addr, ETH_ALEN) == 0;
+		__cfg80211_disconnected(dev, gfp, NULL, 0,
+					reason_code, from_ap);
+
+		wdev->sme_state = CFG80211_SME_IDLE;
+	}
 }
+EXPORT_SYMBOL(cfg80211_send_disassoc);
 
 void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr, gfp_t gfp)
 {
-	struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct wiphy *wiphy = wdev->wiphy;
 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 	nl80211_send_auth_timeout(rdev, dev, addr, gfp);
-	cfg80211_wext_disconnected(dev);
+	if (wdev->sme_state == CFG80211_SME_CONNECTING)
+		cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
+					WLAN_STATUS_UNSPECIFIED_FAILURE, gfp);
+	wdev->sme_state = CFG80211_SME_IDLE;
 }
 EXPORT_SYMBOL(cfg80211_send_auth_timeout);
 
 void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr, gfp_t gfp)
 {
-	struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct wiphy *wiphy = wdev->wiphy;
 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 	nl80211_send_assoc_timeout(rdev, dev, addr, gfp);
-	cfg80211_wext_disconnected(dev);
+	if (wdev->sme_state == CFG80211_SME_CONNECTING)
+		cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
+					WLAN_STATUS_UNSPECIFIED_FAILURE, gfp);
+	wdev->sme_state = CFG80211_SME_IDLE;
 }
 EXPORT_SYMBOL(cfg80211_send_assoc_timeout);
 
--- wireless-testing.orig/net/wireless/core.c	2009-07-01 21:28:15.000000000 +0200
+++ wireless-testing/net/wireless/core.c	2009-07-02 08:46:10.000000000 +0200
@@ -321,6 +321,7 @@ struct wiphy *wiphy_new(const struct cfg
 	}
 
 	INIT_WORK(&drv->rfkill_sync, cfg80211_rfkill_sync_work);
+	INIT_WORK(&drv->conn_work, cfg80211_conn_work);
 
 	/*
 	 * Initialize wiphy parameters to IEEE 802.11 MIB default values.
@@ -481,6 +482,8 @@ void wiphy_unregister(struct wiphy *wiph
 	/* unlock again before freeing */
 	mutex_unlock(&drv->mtx);
 
+	cancel_work_sync(&drv->conn_work);
+
 	cfg80211_debugfs_drv_del(drv);
 
 	/* If this device got a regulatory hint tell core its
@@ -569,6 +572,10 @@ static int cfg80211_netdev_notifier_call
 			break;
 		}
 		break;
+	case NETDEV_DOWN:
+		kfree(wdev->conn);
+		wdev->conn = NULL;
+		break;
 	case NETDEV_UP:
 #ifdef CONFIG_WIRELESS_EXT
 		if (wdev->iftype != NL80211_IFTYPE_ADHOC)
--- wireless-testing.orig/include/net/cfg80211.h	2009-07-01 21:28:15.000000000 +0200
+++ wireless-testing/include/net/cfg80211.h	2009-07-02 08:46:10.000000000 +0200
@@ -1209,6 +1209,9 @@ extern void wiphy_unregister(struct wiph
  */
 extern void wiphy_free(struct wiphy *wiphy);
 
+/* internal struct */
+struct cfg80211_conn;
+
 /**
  * struct wireless_dev - wireless per-netdev state
  *
@@ -1242,9 +1245,10 @@ struct wireless_dev {
 	u8 ssid_len;
 	enum {
 		CFG80211_SME_IDLE,
-		CFG80211_SME_CONNECTING, /* ->connect called */
+		CFG80211_SME_CONNECTING,
 		CFG80211_SME_CONNECTED,
 	} sme_state;
+	struct cfg80211_conn *conn;
 
 #ifdef CONFIG_WIRELESS_EXT
 	/* wext data */
--- wireless-testing.orig/net/wireless/scan.c	2009-07-01 21:24:42.000000000 +0200
+++ wireless-testing/net/wireless/scan.c	2009-07-01 21:28:15.000000000 +0200
@@ -30,6 +30,13 @@ void cfg80211_scan_done(struct cfg80211_
 
 	WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req);
 
+	/*
+	 * This must be before sending the other events!
+	 * Otherwise, wpa_supplicant gets completely confused with
+	 * wext events.
+	 */
+	cfg80211_sme_scan_done(dev);
+
 	if (aborted)
 		nl80211_send_scan_aborted(wiphy_to_dev(request->wiphy), dev);
 	else



^ permalink raw reply

* Re: [PATCH] net: remove skb->do_not_encrypt from skbuff.c
From: Kalle Valo @ 2009-07-02  6:16 UTC (permalink / raw)
  To: Larry Finger; +Cc: John W Linville, Johannes Berg, linux-wireless
In-Reply-To: <4a4bd294.Hac6+C1W4gkNIlOX%Larry.Finger@lwfinger.net>

Larry Finger <Larry.Finger@lwfinger.net> writes:

> Commit 38ba8fb67d6be3258a ("net: remove unused skb->do_not_encrypt")
> removed the variable from struct skbuff, but the usage in net/core/skbuff.c
> crept back in, probably in the merge between mainline and wireless-testing.
>
> Signed-off-by: Larry.Finger <Larry.Finger@lwfinger.net>

Tested-by: Kalle Valo <kalle.valo@iki.fi>

> John,
>
> This fixes the build problem I reported earlier.

I had exactly the same error. Thanks for fixing this.

John, try to push this to wireless-testing at your earliest convenience
because this fixes a compilation error.

-- 
Kalle Valo

^ permalink raw reply

* Re: Insist on cfg80211 for new drivers?
From: Greg KH @ 2009-07-01 22:42 UTC (permalink / raw)
  To: Marcel Holtmann
  Cc: Luis R. Rodriguez, John W. Linville, Dan Williams, Dave,
	Karl Relton, dwmw2, linux-wireless
In-Reply-To: <1246486729.12994.176.camel@localhost.localdomain>

On Wed, Jul 01, 2009 at 03:18:49PM -0700, Marcel Holtmann wrote:
> Hi Greg,
> 
> > > > >> > That's really all I
> > > > >> > care about, I don't want another WEXT-based driver accepted; I want all
> > > > >> > the new ones using cfg80211.
> > > > >>
> > > > >> Now there is a discussion we should have had in Berlin...is it time
> > > > >> to insist on cfg80211-based configuration for all new drivers?
> > > > >
> > > > > there is really nothing much to discuss on this topic. The plan is to
> > > > > deprecate WEXT, that simple. So if the driver has no cfg80211 support,
> > > > > then it will not be included. Period.
> > > > >
> > > > > Send such drivers off to staging and let them have their 6 month.  Then
> > > > > we either remove them again or they got ported to cfg80211.
> > > > 
> > > > 6 months only in staging ? Is this a rule now for staging?
> > > 
> > > that is what Greg mentioned to me. If there is no activity for 6 month
> > > and the driver is not getting anywhere, he going to drop it.
> > 
> > That is "within reason".  If a driver is still needed there, I'l
> > probably keep it, and will take each one on a case-by-case basis.
> 
> what do you mean "within reason". If the driver is just sitting there
> and no effort in making in upstream ready it is doing clearly more harm
> than any good.

Who is it "harming"?  You?  no.

> And I am not talking about removing some kernel version details or
> typedefs or coding style. Drivers with missing cfg80211 need active
> porting. And it is not that hard. See the orinoco one for an example.

Let me know if anything needs to be ported/fixed in the staging
directory.  Never use anything in that directory as a reason to not
change any kernel apis, I will always fix up things as needed.

> If we see developers committed to fixing it that is a different story,
> but a lot of drivers in staging are getting no attention all. So they
> are fully pointless and are not doing any good for Linux. We need to
> send the vendors a clear message that code drops of their crappy Windows
> code are not desired.

Oh yeah, "clear messages", I'm _sure_ that would get through to them...

{sigh}

Seriously, I will take each driver on a case-by-case basis.

thanks,

greg k-h

^ permalink raw reply

* Re: Insist on cfg80211 for new drivers?
From: Marcel Holtmann @ 2009-07-01 22:18 UTC (permalink / raw)
  To: Greg KH
  Cc: Luis R. Rodriguez, John W. Linville, Dan Williams, Dave,
	Karl Relton, dwmw2, linux-wireless
In-Reply-To: <20090701221359.GA2604@kroah.com>

Hi Greg,

> > > >> > That's really all I
> > > >> > care about, I don't want another WEXT-based driver accepted; I want all
> > > >> > the new ones using cfg80211.
> > > >>
> > > >> Now there is a discussion we should have had in Berlin...is it time
> > > >> to insist on cfg80211-based configuration for all new drivers?
> > > >
> > > > there is really nothing much to discuss on this topic. The plan is to
> > > > deprecate WEXT, that simple. So if the driver has no cfg80211 support,
> > > > then it will not be included. Period.
> > > >
> > > > Send such drivers off to staging and let them have their 6 month.  Then
> > > > we either remove them again or they got ported to cfg80211.
> > > 
> > > 6 months only in staging ? Is this a rule now for staging?
> > 
> > that is what Greg mentioned to me. If there is no activity for 6 month
> > and the driver is not getting anywhere, he going to drop it.
> 
> That is "within reason".  If a driver is still needed there, I'l
> probably keep it, and will take each one on a case-by-case basis.

what do you mean "within reason". If the driver is just sitting there
and no effort in making in upstream ready it is doing clearly more harm
than any good. And I am not talking about removing some kernel version
details or typedefs or coding style. Drivers with missing cfg80211 need
active porting. And it is not that hard. See the orinoco one for an
example.

If we see developers committed to fixing it that is a different story,
but a lot of drivers in staging are getting no attention all. So they
are fully pointless and are not doing any good for Linux. We need to
send the vendors a clear message that code drops of their crappy Windows
code are not desired.

Regards

Marcel



^ permalink raw reply

* Re: Insist on cfg80211 for new drivers?
From: Greg KH @ 2009-07-01 22:13 UTC (permalink / raw)
  To: Marcel Holtmann
  Cc: Luis R. Rodriguez, John W. Linville, Dan Williams, Dave,
	Karl Relton, dwmw2, linux-wireless
In-Reply-To: <1246486104.12994.169.camel@localhost.localdomain>

On Wed, Jul 01, 2009 at 03:08:24PM -0700, Marcel Holtmann wrote:
> Hi Luis,
> 
> > >> > That's really all I
> > >> > care about, I don't want another WEXT-based driver accepted; I want all
> > >> > the new ones using cfg80211.
> > >>
> > >> Now there is a discussion we should have had in Berlin...is it time
> > >> to insist on cfg80211-based configuration for all new drivers?
> > >
> > > there is really nothing much to discuss on this topic. The plan is to
> > > deprecate WEXT, that simple. So if the driver has no cfg80211 support,
> > > then it will not be included. Period.
> > >
> > > Send such drivers off to staging and let them have their 6 month.  Then
> > > we either remove them again or they got ported to cfg80211.
> > 
> > 6 months only in staging ? Is this a rule now for staging?
> 
> that is what Greg mentioned to me. If there is no activity for 6 month
> and the driver is not getting anywhere, he going to drop it.

That is "within reason".  If a driver is still needed there, I'l
probably keep it, and will take each one on a case-by-case basis.

thanks,

greg k-h

^ permalink raw reply

* Re: Unable to complete a connection with nl80211 and wpa_supplicant?
From: Johannes Berg @ 2009-07-01 22:12 UTC (permalink / raw)
  To: Jon Loeliger; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <1246486226.11632.50.camel@jdl-desktop>

[-- Attachment #1: Type: text/plain, Size: 683 bytes --]

On Wed, 2009-07-01 at 17:10 -0500, Jon Loeliger wrote:

> CTRL-EVENT-SCAN-RESULTS 
> Trying to associate with 00:1e:58:f2:f5:71 (SSID='bigfoot' freq=2422 MHz)
> CTRL-EVENT-DISCONNECTED - Disconnect event - remove keys
> Associated with 00:1e:58:f2:f5:71
> Authentication with 00:1e:58:f2:f5:71 timed out.
> CTRL-EVENT-DISCONNECTED - Disconnect event - remove keys
> CTRL-EVENT-DISCONNECTED - Disconnect event - remove keys
> CTRL-EVENT-SCAN-RESULTS 
> Trying to associate with 00:1e:58:f2:f5:71 (SSID='bigfoot' freq=2422 MHz)
> Associated with 00:1e:58:f2:f5:71
> Authentication with 00:1e:58:f2:f5:71 timed out.

Huh. Can you show dmesg during this time?

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply

* Unable to complete a connection with nl80211 and wpa_supplicant?
From: Jon Loeliger @ 2009-07-01 22:10 UTC (permalink / raw)
  To: linux-wireless@vger.kernel.org

Guys,

Does the following log showing wpa_supplicant's inability
to assoc/auth using the nl80211 driver look familiar
to anyone?  The same setup and config works using the
wext driver. Do I just need a more recent wireless-testing
kernel?  This is wireless-testing at d1a6d5c2f6.  And
if it matters, it's the ar9170 driver below that.

Thanks,
jdl


# cat /etc/wpa_supplicant.conf 
network={
	ssid="bigfoot"
	scan_ssid=1
	key_mgmt=WPA-PSK
	psk="my-secret"
}


# wpa_supplicant -c /etc/wpa_supplicant.conf  -Dnl80211 -i wlan0

CTRL-EVENT-SCAN-RESULTS 
Trying to associate with 00:1e:58:f2:f5:71 (SSID='bigfoot' freq=2422 MHz)
CTRL-EVENT-DISCONNECTED - Disconnect event - remove keys
Associated with 00:1e:58:f2:f5:71
Authentication with 00:1e:58:f2:f5:71 timed out.
CTRL-EVENT-DISCONNECTED - Disconnect event - remove keys
CTRL-EVENT-DISCONNECTED - Disconnect event - remove keys
CTRL-EVENT-SCAN-RESULTS 
Trying to associate with 00:1e:58:f2:f5:71 (SSID='bigfoot' freq=2422 MHz)
Associated with 00:1e:58:f2:f5:71
Authentication with 00:1e:58:f2:f5:71 timed out.
CTRL-EVENT-DISCONNECTED - Disconnect event - remove keys
CTRL-EVENT-DISCONNECTED - Disconnect event - remove keys
CTRL-EVENT-SCAN-RESULTS 
Trying to associate with 00:1e:58:f2:f5:71 (SSID='bigfoot_' freq=2422 MHz)






^ permalink raw reply

* Re: Insist on cfg80211 for new drivers?
From: Marcel Holtmann @ 2009-07-01 22:08 UTC (permalink / raw)
  To: Luis R. Rodriguez
  Cc: Greg KH, John W. Linville, Dan Williams, Dave, Karl Relton, dwmw2,
	linux-wireless
In-Reply-To: <43e72e890907011456q7e3d9f5al1057f940a7655cda@mail.gmail.com>

Hi Luis,

> >> > That's really all I
> >> > care about, I don't want another WEXT-based driver accepted; I want all
> >> > the new ones using cfg80211.
> >>
> >> Now there is a discussion we should have had in Berlin...is it time
> >> to insist on cfg80211-based configuration for all new drivers?
> >
> > there is really nothing much to discuss on this topic. The plan is to
> > deprecate WEXT, that simple. So if the driver has no cfg80211 support,
> > then it will not be included. Period.
> >
> > Send such drivers off to staging and let them have their 6 month.  Then
> > we either remove them again or they got ported to cfg80211.
> 
> 6 months only in staging ? Is this a rule now for staging?

that is what Greg mentioned to me. If there is no activity for 6 month
and the driver is not getting anywhere, he going to drop it.

Regards

Marcel



^ permalink raw reply

* Re: Insist on cfg80211 for new drivers?
From: Luis R. Rodriguez @ 2009-07-01 21:56 UTC (permalink / raw)
  To: Marcel Holtmann, Greg KH
  Cc: John W. Linville, Dan Williams, Dave, Karl Relton, dwmw2,
	linux-wireless
In-Reply-To: <1246485123.12994.168.camel@localhost.localdomain>

On Wed, Jul 1, 2009 at 2:52 PM, Marcel Holtmann<marcel@holtmann.org> wrote:
> Hi John,
>
>> > That's really all I
>> > care about, I don't want another WEXT-based driver accepted; I want all
>> > the new ones using cfg80211.
>>
>> Now there is a discussion we should have had in Berlin...is it time
>> to insist on cfg80211-based configuration for all new drivers?
>
> there is really nothing much to discuss on this topic. The plan is to
> deprecate WEXT, that simple. So if the driver has no cfg80211 support,
> then it will not be included. Period.
>
> Send such drivers off to staging and let them have their 6 month.  Then
> we either remove them again or they got ported to cfg80211.

6 months only in staging ? Is this a rule now for staging?

  Luis

^ permalink raw reply

* Re: Insist on cfg80211 for new drivers?
From: Marcel Holtmann @ 2009-07-01 21:52 UTC (permalink / raw)
  To: John W. Linville
  Cc: Dan Williams, Luis R. Rodriguez, Dave, Karl Relton, dwmw2,
	linux-wireless
In-Reply-To: <20090701193657.GD3473@tuxdriver.com>

Hi John,

> > That's really all I
> > care about, I don't want another WEXT-based driver accepted; I want all
> > the new ones using cfg80211.
> 
> Now there is a discussion we should have had in Berlin...is it time
> to insist on cfg80211-based configuration for all new drivers?

there is really nothing much to discuss on this topic. The plan is to
deprecate WEXT, that simple. So if the driver has no cfg80211 support,
then it will not be included. Period.

Send such drivers off to staging and let them have their 6 month. Then
we either remove them again or they got ported to cfg80211.

Regards

Marcel



^ permalink raw reply

* [PATCH 3/3 v3] net/compat/wext: send different messages to compat tasks
From: Johannes Berg @ 2009-07-01 21:26 UTC (permalink / raw)
  To: netdev; +Cc: linux-wireless
In-Reply-To: <20090624113731.935845071@sipsolutions.net>

Wireless extensions have the unfortunate problem that events
are multicast netlink messages, and are not independent of
pointer size. Thus, currently 32-bit tasks on 64-bit platforms
cannot properly receive events and fail with all kinds of
strange problems, for instance wpa_supplicant never notices
disassociations, due to the way the 64-bit event looks (to a
32-bit process), the fact that the address is all zeroes is
lost, it thinks instead it is 00:00:00:00:01:00.

The same problem existed with the ioctls, until David Miller
fixed those some time ago in an heroic effort.

A different problem caused by this is that we cannot send the
ASSOCREQIE/ASSOCRESPIE events because sending them causes a
32-bit wpa_supplicant on a 64-bit system to overwrite its
internal information, which is worse than it not getting the
information at all -- so we currently resort to sending a
custom string event that it then parses. This, however, has a
severe size limitation we are frequently hitting with modern
access points; this limitation would can be lifted after this
patch by sending the correct binary, not custom, event.

A similar problem apparently happens for some other netlink
users on x86_64 with 32-bit tasks due to the alignment for
64-bit quantities.

In order to fix these problems, I have implemented a way to
send compat messages to tasks. When sending an event, we send
the non-compat event data together with a compat event data in
skb_shinfo(main_skb)->frag_list. Then, when the event is read
from the socket, the netlink code makes sure to pass out only
the skb that is compatible with the task. This approach was
suggested by David Miller, my original approach required
always sending two skbs but that had various small problems.

To determine whether compat is needed or not, I have used the
MSG_CMSG_COMPAT flag, and adjusted the call path for recv and
recvfrom to include it, even if those calls do not have a cmsg
parameter.

I have not solved one small part of the problem, and I don't
think it is necessary to: if a 32-bit application uses read()
rather than any form of recvmsg() it will still get the wrong
(64-bit) event. However, neither do applications actually do
this, nor would it be a regression.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
v2: * after some discussion with davem, use frag_list as noted,
      and note that there are more possible uses for this
    * add another Kconfig symbol for code that can use select
      for the feature
    * add help, in Kconfig, describing the feature
v3: * don't NULL out frag_list incorrectly, keep as required

 arch/mips/kernel/scall64-n32.S |    2 -
 arch/mips/kernel/scall64-o32.S |    4 +-
 arch/sparc/kernel/sys32.S      |    2 -
 include/linux/wireless.h       |    8 ++++
 net/Kconfig                    |   20 ++++++++++
 net/compat.c                   |   17 +++++++-
 net/netlink/af_netlink.c       |   36 ++++++++++++++++++
 net/wireless/wext.c            |   78 +++++++++++++++++++++++++++++++++++++++++
 8 files changed, 160 insertions(+), 7 deletions(-)

--- wireless-testing.orig/net/wireless/wext.c	2009-07-01 21:46:44.000000000 +0200
+++ wireless-testing/net/wireless/wext.c	2009-07-01 21:46:47.000000000 +0200
@@ -417,6 +417,21 @@ static const int event_type_size[] = {
 	IW_EV_QUAL_LEN,			/* IW_HEADER_TYPE_QUAL */
 };
 
+#ifdef CONFIG_COMPAT
+static const int compat_event_type_size[] = {
+	IW_EV_COMPAT_LCP_LEN,		/* IW_HEADER_TYPE_NULL */
+	0,
+	IW_EV_COMPAT_CHAR_LEN,		/* IW_HEADER_TYPE_CHAR */
+	0,
+	IW_EV_COMPAT_UINT_LEN,		/* IW_HEADER_TYPE_UINT */
+	IW_EV_COMPAT_FREQ_LEN,		/* IW_HEADER_TYPE_FREQ */
+	IW_EV_COMPAT_ADDR_LEN,		/* IW_HEADER_TYPE_ADDR */
+	0,
+	IW_EV_COMPAT_POINT_LEN,		/* Without variable payload */
+	IW_EV_COMPAT_PARAM_LEN,		/* IW_HEADER_TYPE_PARAM */
+	IW_EV_COMPAT_QUAL_LEN,		/* IW_HEADER_TYPE_QUAL */
+};
+#endif
 
 /************************ COMMON SUBROUTINES ************************/
 /*
@@ -1348,6 +1363,22 @@ void wireless_send_event(struct net_devi
 	struct sk_buff *skb;
 	struct nlmsghdr *nlh;
 	struct nlattr *nla;
+#ifdef CONFIG_COMPAT
+	struct __compat_iw_event *compat_event;
+	struct compat_iw_point compat_wrqu;
+	struct sk_buff *compskb;
+#endif
+
+	/*
+	 * Nothing in the kernel sends scan events with data, be safe.
+	 * This is necessary because we cannot fix up scan event data
+	 * for compat, due to being contained in 'extra', but normally
+	 * applications are required to retrieve the scan data anyway
+	 * and no data is included in the event, this codifies that
+	 * practice.
+	 */
+	if (WARN_ON(cmd == SIOCGIWSCAN && extra))
+		extra = NULL;
 
 	/* Get the description of the Event */
 	if (cmd <= SIOCIWLAST) {
@@ -1446,7 +1477,54 @@ void wireless_send_event(struct net_devi
 		memcpy(((char *) event) + hdr_len, extra, extra_len);
 
 	nlmsg_end(skb, nlh);
+#ifdef CONFIG_COMPAT
+	hdr_len = compat_event_type_size[descr->header_type];
+	event_len = hdr_len + extra_len;
+
+	compskb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
+	if (!compskb) {
+		kfree_skb(skb);
+		return;
+	}
+
+	/* Send via the RtNetlink event channel */
+	nlh = rtnetlink_ifinfo_prep(dev, compskb);
+	if (WARN_ON(!nlh)) {
+		kfree_skb(skb);
+		kfree_skb(compskb);
+		return;
+	}
+
+	/* Add the wireless events in the netlink packet */
+	nla = nla_reserve(compskb, IFLA_WIRELESS, event_len);
+	if (!nla) {
+		kfree_skb(skb);
+		kfree_skb(compskb);
+		return;
+	}
+	compat_event = nla_data(nla);
+
+	compat_event->len = event_len;
+	compat_event->cmd = cmd;
+	if (descr->header_type == IW_HEADER_TYPE_POINT) {
+		compat_wrqu.length = wrqu->data.length;
+		compat_wrqu.flags = wrqu->data.flags;
+		memcpy(&compat_event->pointer,
+			((char *) &compat_wrqu) + IW_EV_COMPAT_POINT_OFF,
+			hdr_len - IW_EV_COMPAT_LCP_LEN);
+		if (extra_len)
+			memcpy(((char *) compat_event) + hdr_len,
+				extra, extra_len);
+	} else {
+		/* extra_len must be zero, so no if (extra) needed */
+		memcpy(&compat_event->pointer, wrqu,
+			hdr_len - IW_EV_COMPAT_LCP_LEN);
+	}
 
+	nlmsg_end(compskb, nlh);
+
+	skb_shinfo(skb)->frag_list = compskb;
+#endif
 	skb_queue_tail(&dev_net(dev)->wext_nlevents, skb);
 	schedule_work(&wireless_nlevent_work);
 }
--- wireless-testing.orig/net/Kconfig	2009-07-01 21:24:31.000000000 +0200
+++ wireless-testing/net/Kconfig	2009-07-01 21:46:47.000000000 +0200
@@ -23,6 +23,26 @@ menuconfig NET
 
 if NET
 
+config WANT_COMPAT_NETLINK_MESSAGES
+	bool
+	help
+	  This option can be selected by other options that need compat
+	  netlink messages.
+
+config COMPAT_NETLINK_MESSAGES
+	def_bool y
+	depends on COMPAT
+	depends on WIRELESS_EXT || WANT_COMPAT_NETLINK_MESSAGES
+	help
+	  This option makes it possible to send different netlink messages
+	  to tasks depending on whether the task is a compat task or not. To
+	  achieve this, you need to set skb_shinfo(skb)->frag_list to the
+	  compat skb before sending the skb, the netlink code will sort out
+	  which message to actually pass to the task.
+
+	  Newly written code should NEVER need this option but do
+	  compat-independent messages instead!
+
 menu "Networking options"
 
 source "net/packet/Kconfig"
--- wireless-testing.orig/net/netlink/af_netlink.c	2009-07-01 21:24:31.000000000 +0200
+++ wireless-testing/net/netlink/af_netlink.c	2009-07-01 23:24:21.000000000 +0200
@@ -1356,7 +1356,7 @@ static int netlink_recvmsg(struct kiocb 
 	struct netlink_sock *nlk = nlk_sk(sk);
 	int noblock = flags&MSG_DONTWAIT;
 	size_t copied;
-	struct sk_buff *skb;
+	struct sk_buff *skb, *frag __maybe_unused = NULL;
 	int err;
 
 	if (flags&MSG_OOB)
@@ -1368,6 +1368,35 @@ static int netlink_recvmsg(struct kiocb 
 	if (skb == NULL)
 		goto out;
 
+#ifdef CONFIG_COMPAT_NETLINK_MESSAGES
+	if (unlikely(skb_shinfo(skb)->frag_list)) {
+		bool need_compat = !!(flags & MSG_CMSG_COMPAT);
+
+		/*
+		 * If this skb has a frag_list, then here that means that
+		 * we will have to use the frag_list skb for compat tasks
+		 * and the regular skb for non-compat tasks.
+		 *
+		 * The skb might (and likely will) be cloned, so we can't
+		 * just reset frag_list and go on with things -- we need to
+		 * keep that. For the compat case that's easy -- simply get
+		 * a reference to the compat skb and free the regular one
+		 * including the frag. For the non-compat case, we need to
+		 * avoid sending the frag to the user -- so assign NULL but
+		 * restore it below before freeing the skb.
+		 */
+		if (need_compat) {
+			struct sk_buff *compskb = skb_shinfo(skb)->frag_list;
+			skb_get(compskb);
+			kfree_skb(skb);
+			skb = compskb;
+		} else {
+			frag = skb_shinfo(skb)->frag_list;
+			skb_shinfo(skb)->frag_list = NULL;
+		}
+	}
+#endif
+
 	msg->msg_namelen = 0;
 
 	copied = skb->len;
@@ -1398,6 +1427,11 @@ static int netlink_recvmsg(struct kiocb 
 	siocb->scm->creds = *NETLINK_CREDS(skb);
 	if (flags & MSG_TRUNC)
 		copied = skb->len;
+
+#ifdef CONFIG_COMPAT_NETLINK_MESSAGES
+	skb_shinfo(skb)->frag_list = frag;
+#endif
+
 	skb_free_datagram(sk, skb);
 
 	if (nlk->cb && atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf / 2)
--- wireless-testing.orig/net/compat.c	2009-07-01 21:24:31.000000000 +0200
+++ wireless-testing/net/compat.c	2009-07-01 21:46:47.000000000 +0200
@@ -743,6 +743,18 @@ asmlinkage long compat_sys_recvmsg(int f
 	return sys_recvmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT);
 }
 
+asmlinkage long compat_sys_recv(int fd, void __user *buf, size_t len, unsigned flags)
+{
+	return sys_recv(fd, buf, len, flags | MSG_CMSG_COMPAT);
+}
+
+asmlinkage long compat_sys_recvfrom(int fd, void __user *buf, size_t len,
+				    unsigned flags, struct sockaddr __user *addr,
+				    int __user *addrlen)
+{
+	return sys_recvfrom(fd, buf, len, flags | MSG_CMSG_COMPAT, addr, addrlen);
+}
+
 asmlinkage long compat_sys_socketcall(int call, u32 __user *args)
 {
 	int ret;
@@ -788,10 +800,11 @@ asmlinkage long compat_sys_socketcall(in
 		ret = sys_sendto(a0, compat_ptr(a1), a[2], a[3], compat_ptr(a[4]), a[5]);
 		break;
 	case SYS_RECV:
-		ret = sys_recv(a0, compat_ptr(a1), a[2], a[3]);
+		ret = compat_sys_recv(a0, compat_ptr(a1), a[2], a[3]);
 		break;
 	case SYS_RECVFROM:
-		ret = sys_recvfrom(a0, compat_ptr(a1), a[2], a[3], compat_ptr(a[4]), compat_ptr(a[5]));
+		ret = compat_sys_recvfrom(a0, compat_ptr(a1), a[2], a[3],
+					  compat_ptr(a[4]), compat_ptr(a[5]));
 		break;
 	case SYS_SHUTDOWN:
 		ret = sys_shutdown(a0,a1);
--- wireless-testing.orig/include/linux/wireless.h	2009-07-01 21:24:32.000000000 +0200
+++ wireless-testing/include/linux/wireless.h	2009-07-01 21:46:47.000000000 +0200
@@ -1132,6 +1132,14 @@ struct __compat_iw_event {
 };
 #define IW_EV_COMPAT_LCP_LEN offsetof(struct __compat_iw_event, pointer)
 #define IW_EV_COMPAT_POINT_OFF offsetof(struct compat_iw_point, length)
+
+/* Size of the various events for compat */
+#define IW_EV_COMPAT_CHAR_LEN	(IW_EV_COMPAT_LCP_LEN + IFNAMSIZ)
+#define IW_EV_COMPAT_UINT_LEN	(IW_EV_COMPAT_LCP_LEN + sizeof(__u32))
+#define IW_EV_COMPAT_FREQ_LEN	(IW_EV_COMPAT_LCP_LEN + sizeof(struct iw_freq))
+#define IW_EV_COMPAT_PARAM_LEN	(IW_EV_COMPAT_LCP_LEN + sizeof(struct iw_param))
+#define IW_EV_COMPAT_ADDR_LEN	(IW_EV_COMPAT_LCP_LEN + sizeof(struct sockaddr))
+#define IW_EV_COMPAT_QUAL_LEN	(IW_EV_COMPAT_LCP_LEN + sizeof(struct iw_quality))
 #define IW_EV_COMPAT_POINT_LEN	\
 	(IW_EV_COMPAT_LCP_LEN + sizeof(struct compat_iw_point) - \
 	 IW_EV_COMPAT_POINT_OFF)
--- wireless-testing.orig/arch/sparc/kernel/sys32.S	2009-07-01 21:24:31.000000000 +0200
+++ wireless-testing/arch/sparc/kernel/sys32.S	2009-07-01 21:46:48.000000000 +0200
@@ -121,7 +121,7 @@ SIGN2(sys32_syslog, sys_syslog, %o0, %o2
 SIGN1(sys32_umask, sys_umask, %o0)
 SIGN3(sys32_tgkill, sys_tgkill, %o0, %o1, %o2)
 SIGN1(sys32_sendto, sys_sendto, %o0)
-SIGN1(sys32_recvfrom, sys_recvfrom, %o0)
+SIGN1(sys32_recvfrom, compat_sys_recvfrom, %o0)
 SIGN3(sys32_socket, sys_socket, %o0, %o1, %o2)
 SIGN2(sys32_connect, sys_connect, %o0, %o2)
 SIGN2(sys32_bind, sys_bind, %o0, %o2)
--- wireless-testing.orig/arch/mips/kernel/scall64-n32.S	2009-07-01 21:24:31.000000000 +0200
+++ wireless-testing/arch/mips/kernel/scall64-n32.S	2009-07-01 21:46:48.000000000 +0200
@@ -164,7 +164,7 @@ EXPORT(sysn32_call_table)
 	PTR	sys_connect
 	PTR	sys_accept
 	PTR	sys_sendto
-	PTR	sys_recvfrom
+	PTR	compat_sys_recvfrom
 	PTR	compat_sys_sendmsg		/* 6045 */
 	PTR	compat_sys_recvmsg
 	PTR	sys_shutdown
--- wireless-testing.orig/arch/mips/kernel/scall64-o32.S	2009-07-01 21:24:31.000000000 +0200
+++ wireless-testing/arch/mips/kernel/scall64-o32.S	2009-07-01 21:46:48.000000000 +0200
@@ -378,8 +378,8 @@ sys_call_table:
 	PTR	sys_getsockname
 	PTR	sys_getsockopt
 	PTR	sys_listen
-	PTR	sys_recv			/* 4175 */
-	PTR	sys_recvfrom
+	PTR	compat_sys_recv			/* 4175 */
+	PTR	compat_sys_recvfrom
 	PTR	compat_sys_recvmsg
 	PTR	sys_send
 	PTR	compat_sys_sendmsg



^ permalink raw reply

* [PATCH] net: remove skb->do_not_encrypt from skbuff.c
From: Larry Finger @ 2009-07-01 21:18 UTC (permalink / raw)
  To: John W Linville, Johannes Berg; +Cc: linux-wireless

Commit 38ba8fb67d6be3258a ("net: remove unused skb->do_not_encrypt")
removed the variable from struct skbuff, but the usage in net/core/skbuff.c
crept back in, probably in the merge between mainline and wireless-testing.

Signed-off-by: Larry.Finger <Larry.Finger@lwfinger.net>
---

John,

This fixes the build problem I reported earlier.

Larry
---

Index: wireless-testing/net/core/skbuff.c
===================================================================
--- wireless-testing.orig/net/core/skbuff.c
+++ wireless-testing/net/core/skbuff.c
@@ -559,9 +559,6 @@ static void __copy_skb_header(struct sk_
 #endif
 #endif
 	new->vlan_tci		= old->vlan_tci;
-#if defined(CONFIG_MAC80211) || defined(CONFIG_MAC80211_MODULE)
-	new->do_not_encrypt	= old->do_not_encrypt;
-#endif
 
 	skb_copy_secmark(new, old);
 }

^ permalink raw reply

* [PATCH hostap/wpa_supplicant] Allow wpa_supplicant to use libnl-2.0
From: Jon Loeliger @ 2009-07-01 20:59 UTC (permalink / raw)
  To: jouni.malinen; +Cc: linux-wireless@vger.kernel.org

Introduce CONFIG_LIBNL20 .config parameter and propogate
that as a CFLAG in the Makefile.

Add forward-compatibility code to allow the existing code
to also use libnl-2.0.

Signed-off-by: Jon Loeliger <jdl@bigfootnetworks.com>
---

This patch applies to:
    git://w1.fi/srv/git/hostap-06.git
    fa4e296f542af01da135d997358d6d45a32dd59e

Also, I suspect that this define:

    +#define nl_handle nl_sock

may need to be added to the hostapd side as well, but
I'm not using that and haven't investigated or tested that.

jdl


 src/drivers/driver_nl80211.c |   17 +++++++++++++++++
 wpa_supplicant/Makefile      |    4 ++++
 2 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index a7b351a..66288f6 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -47,6 +47,15 @@
 #endif
 
 
+#ifdef CONFIG_LIBNL20
+/* libnl 2.0 compatibility code */
+
+#define nl_handle nl_sock
+#define nl_handle_alloc_cb nl_socket_alloc_cb
+#define nl_handle_destroy nl_socket_free
+#endif /* CONFIG_LIBNL20 */
+
+
 struct wpa_driver_nl80211_data {
 	void *ctx;
 	int wext_event_sock;
@@ -1441,12 +1450,20 @@ static void * wpa_driver_nl80211_init(void *ctx, const char *ifname)
 		goto err3;
 	}
 
+#ifdef CONFIG_LIBNL20
+	if (genl_ctrl_alloc_cache(drv->nl_handle, &drv->nl_cache) < 0) {
+	    wpa_printf(MSG_ERROR, "nl80211: Failed to allocate generic "
+			   "netlink cache");
+		goto err3;
+	}
+#else
 	drv->nl_cache = genl_ctrl_alloc_cache(drv->nl_handle);
 	if (drv->nl_cache == NULL) {
 		wpa_printf(MSG_ERROR, "nl80211: Failed to allocate generic "
 			   "netlink cache");
 		goto err3;
 	}
+#endif
 
 	drv->nl80211 = genl_ctrl_search_by_name(drv->nl_cache, "nl80211");
 	if (drv->nl80211 == NULL) {
diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile
index 45d6ada..fa43a0c 100644
--- a/wpa_supplicant/Makefile
+++ b/wpa_supplicant/Makefile
@@ -135,6 +135,10 @@ ifdef CONFIG_DRIVER_NL80211
 CFLAGS += -DCONFIG_DRIVER_NL80211
 OBJS_d += ../src/drivers/driver_nl80211.o
 LIBS += -lnl
+ifdef CONFIG_LIBNL20
+LIBS += -lnl-genl
+CFLAGS += -DCONFIG_LIBNL20
+endif
 ifdef CONFIG_CLIENT_MLME
 OBJS_d += ../src/drivers/radiotap.o
 endif
-- 
1.6.3.GIT




^ permalink raw reply related

* Re: Compiling wpa_supplicant?
From: Jon Loeliger @ 2009-07-01 20:57 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <1246473271.8154.5.camel@johannes.local>

On Wed, 2009-07-01 at 20:34 +0200, Johannes Berg wrote:
> On Wed, 2009-07-01 at 11:50 -0500, Jon Loeliger wrote:
> 
> > Is there a version of hostapd/wpa_suppliant that is more
> > up-to-date WRT libnl-2.0?  Or should I just use the wext
> > driver for now?
> 
> I would suggest you compile against a released version of libnl, namely
> 1.1 :)

I was afraid someone would say something like that... :-)
And since that seems to be effort in the wrong direction,
I was even more afraid someone would say something like:

> Otherwise, you can rip the compat code out off iw and stick it
> into wpa_supplicant/hostapd.

So I did something like that.  Patch to follow.

> johannes

Thanks,
jdl



^ permalink raw reply

* Build error in 2.6.31-rc1-wl
From: Larry Finger @ 2009-07-01 20:43 UTC (permalink / raw)
  To: John Linville, Johannes Berg; +Cc: wireless

When building the above kernel based on a fress pull of
wireless-testing, I get the following build error:

  CC      net/core/skbuff.o
net/core/skbuff.c: In function ‘__copy_skb_header’:
net/core/skbuff.c:563: error: ‘struct sk_buff’ has no member named
‘do_not_encrypt’
net/core/skbuff.c:563: error: ‘const struct sk_buff’ has no member
named ‘do_not_encrypt’
make[2]: *** [net/core/skbuff.o] Error 1

The code that errors is

        new->vlan_tci           = old->vlan_tci;
#if defined(CONFIG_MAC80211) || defined(CONFIG_MAC80211_MODULE)
        new->do_not_encrypt     = old->do_not_encrypt;
#endif

        skb_copy_secmark(new, old);
}

Larry

^ permalink raw reply

* Re: Insist on cfg80211 for new drivers?
From: Kalle Valo @ 2009-07-01 20:40 UTC (permalink / raw)
  To: John W. Linville
  Cc: Dan Williams, Luis R. Rodriguez, Dave, Karl Relton, dwmw2,
	linux-wireless
In-Reply-To: <20090701193657.GD3473@tuxdriver.com>

"John W. Linville" <linville@tuxdriver.com> writes:

> On Wed, Jul 01, 2009 at 02:35:00PM -0400, Dan Williams wrote:
>
>> That's really all I
>> care about, I don't want another WEXT-based driver accepted; I want all
>> the new ones using cfg80211.
>
> Now there is a discussion we should have had in Berlin...

Yes, we missed this one.

> is it time to insist on cfg80211-based configuration for all new
> drivers?

I vote for yes. In my books wext is depreceated and its use should be
avoided. After Johannes' excellent work we need to start pushing the use
of cfg80211 and nl80211.

-- 
Kalle Valo

^ permalink raw reply

* Re: Insist on cfg80211 for new drivers?
From: Johannes Berg @ 2009-07-01 19:53 UTC (permalink / raw)
  To: John W. Linville
  Cc: Dan Williams, Luis R. Rodriguez, Dave, Karl Relton, dwmw2,
	linux-wireless
In-Reply-To: <20090701193657.GD3473@tuxdriver.com>

[-- Attachment #1: Type: text/plain, Size: 771 bytes --]

On Wed, 2009-07-01 at 15:36 -0400, John W. Linville wrote:
> On Wed, Jul 01, 2009 at 02:35:00PM -0400, Dan Williams wrote:
> 
> > That's really all I
> > care about, I don't want another WEXT-based driver accepted; I want all
> > the new ones using cfg80211.
> 
> Now there is a discussion we should have had in Berlin...is it time
> to insist on cfg80211-based configuration for all new drivers?

Can't imagine there would have been much discussion on that with the
crowd that was there -- I think we should. In fact, on the notes was
"publish a wext deprecation statement" or something like that.

Just like we insist that nobody adds an entirely new wireless stack, we
should insist that nobody add a new way of interpreting wext commands.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply

* Re: Insist on cfg80211 for new drivers?
From: Luis R. Rodriguez @ 2009-07-01 19:49 UTC (permalink / raw)
  To: John W. Linville; +Cc: Dan Williams, Dave, Karl Relton, dwmw2, linux-wireless
In-Reply-To: <20090701193657.GD3473@tuxdriver.com>

On Wed, Jul 1, 2009 at 12:36 PM, John W. Linville<linville@tuxdriver.com> wrote:
> On Wed, Jul 01, 2009 at 02:35:00PM -0400, Dan Williams wrote:
>
>> That's really all I
>> care about, I don't want another WEXT-based driver accepted; I want all
>> the new ones using cfg80211.
>
> Now there is a discussion we should have had in Berlin...is it time
> to insist on cfg80211-based configuration for all new drivers?

Otherwise they get sent to staging? :)

  Luis

^ permalink raw reply

* Re: [PATCH] Add prism 2/3 usb adaptor firmware for use with staging/wlan-ng driver.
From: David Woodhouse @ 2009-07-01 19:46 UTC (permalink / raw)
  To: Karl Relton; +Cc: Luis R. Rodriguez, linux-wireless
In-Reply-To: <1246464991.4331.18.camel@localhost>

On Wed, 2009-07-01 at 17:16 +0100, Karl Relton wrote:
> On Tue, 2009-06-30 at 14:58 -0700, Luis R. Rodriguez wrote:
> > On Tue, Jun 30, 2009 at 2:09 PM, Karl
> > Relton<karllinuxtest.relton@ntlworld.com> wrote:
> > > On Tue, 2009-06-30 at 12:17 -0700, Luis R. Rodriguez wrote:
> > >> On Tue, Jun 30, 2009 at 12:05 PM, Karl
> > >> Relton<karllinuxtest.relton@ntlworld.com> wrote:
> > >> > Signed-Off-By: Karl Relton
> > >> > Signed-Off-By: Mark S. Mathews
> > >>
> > >> The commit log is empty. Where is this driver? Is it in staging at
> > >> least? If so does this get users of the driver a usable firmware? What
> > >> is the future of the driver BTW?
> > >>
> > >
> > > Oops - put text in wrong part of patch documentation. I can move this up
> > > to the 'commit log' part.
> > >
> > > The driver is under 'staging' - maintained by Greg Koah-Hartman
> > >
> > > The firmware blob in 'srec' format for prism 2/3 usb adaptors.
> > > The driver will read the srec file using a standard request_firmware()
> > > call, and will convert it into the appropriate binary format and upload to
> > > the adaptor. Note the processing is left to the driver (rather than
> > > pre-compiling) because the driver needs to insert runtime data obtained from
> > > the adaptor into the blob. The appropriate insertion locations are conveyed
> > > by the srec format.
> > 
> > Why all the srec->binary conversion? Doesn't this waste space on
> > people's firmware directories?
> > 
> Yes, technically it does. The srec file is ~185KB, a binary image would
> be ~64KB.
> 
> The reason it was left is that the driver has to do some runtime
> plugging of data into the image, so pre-compilation would have meant
> inventing both a compiler tool and an intermediate format for the driver
> to read and process. Putting all the srec processing in the driver was
> more expedient (just meant porting existing userspace code into driver
> space).

The kernel has support for a binary form of srec files (well, of ihex
files, which are fairly much the same thing).

See include/linux/ihex.h and firmware/ihex2fw.c.
 
-- 
David Woodhouse                            Open Source Technology Centre
David.Woodhouse@intel.com                              Intel Corporation


^ permalink raw reply

* Insist on cfg80211 for new drivers?
From: John W. Linville @ 2009-07-01 19:36 UTC (permalink / raw)
  To: Dan Williams; +Cc: Luis R. Rodriguez, Dave, Karl Relton, dwmw2, linux-wireless
In-Reply-To: <1246473300.30522.10.camel@localhost.localdomain>

On Wed, Jul 01, 2009 at 02:35:00PM -0400, Dan Williams wrote:

> That's really all I
> care about, I don't want another WEXT-based driver accepted; I want all
> the new ones using cfg80211.

Now there is a discussion we should have had in Berlin...is it time
to insist on cfg80211-based configuration for all new drivers?

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

^ permalink raw reply

* [PATCH 22/20 v4] mac80211: remove dead code, clean up
From: Johannes Berg @ 2009-07-01 19:41 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless
In-Reply-To: <20090701192641.072258140@sipsolutions.net>

With mac80211 now always controlled by an external SME,
a lot of code is dead -- SSID, BSSID, channel selection
is always done externally, etc. Additionally, rename
IEEE80211_STA_TKIP_WEP_USED to IEEE80211_STA_DISABLE_11N
and clean up the code a bit.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
 net/mac80211/cfg.c            |   39 ++-----
 net/mac80211/debugfs_netdev.c |    4 
 net/mac80211/ieee80211_i.h    |   42 +++----
 net/mac80211/iface.c          |    2 
 net/mac80211/mlme.c           |  231 ++++--------------------------------------
 5 files changed, 54 insertions(+), 264 deletions(-)

--- wireless-testing.orig/net/mac80211/cfg.c	2009-07-01 20:29:51.000000000 +0200
+++ wireless-testing/net/mac80211/cfg.c	2009-07-01 20:29:52.000000000 +0200
@@ -1194,18 +1194,14 @@ static int ieee80211_auth(struct wiphy *
 	}
 
 	memcpy(sdata->u.mgd.bssid, req->peer_addr, ETH_ALEN);
-	sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL;
-	sdata->u.mgd.flags |= IEEE80211_STA_BSSID_SET;
 
-	/* TODO: req->chan */
-	sdata->u.mgd.flags |= IEEE80211_STA_AUTO_CHANNEL_SEL;
+	sdata->local->oper_channel = req->chan;
+	ieee80211_hw_config(sdata->local, 0);
 
-	if (req->ssid) {
-		sdata->u.mgd.flags |= IEEE80211_STA_SSID_SET;
-		memcpy(sdata->u.mgd.ssid, req->ssid, req->ssid_len);
-		sdata->u.mgd.ssid_len = req->ssid_len;
-		sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_SSID_SEL;
-	}
+	if (!req->ssid)
+		return -EINVAL;
+	memcpy(sdata->u.mgd.ssid, req->ssid, req->ssid_len);
+	sdata->u.mgd.ssid_len = req->ssid_len;
 
 	kfree(sdata->u.mgd.sme_auth_ie);
 	sdata->u.mgd.sme_auth_ie = NULL;
@@ -1218,7 +1214,6 @@ static int ieee80211_auth(struct wiphy *
 		sdata->u.mgd.sme_auth_ie_len = req->ie_len;
 	}
 
-	sdata->u.mgd.flags |= IEEE80211_STA_EXT_SME;
 	sdata->u.mgd.state = IEEE80211_STA_MLME_DIRECT_PROBE;
 	ieee80211_sta_req_auth(sdata);
 	return 0;
@@ -1236,27 +1231,22 @@ static int ieee80211_assoc(struct wiphy 
 	    !(sdata->u.mgd.flags & IEEE80211_STA_AUTHENTICATED))
 		return -ENOLINK; /* not authenticated */
 
-	sdata->u.mgd.flags &= ~IEEE80211_STA_TKIP_WEP_USED;
+	sdata->u.mgd.flags &= ~IEEE80211_STA_DISABLE_11N;
 
 	for (i = 0; i < req->crypto.n_ciphers_pairwise; i++)
 		if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 ||
 		    req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP ||
 		    req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP104)
-			sdata->u.mgd.flags |= IEEE80211_STA_TKIP_WEP_USED;
+			sdata->u.mgd.flags |= IEEE80211_STA_DISABLE_11N;
 
-	sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL;
-	sdata->u.mgd.flags |= IEEE80211_STA_BSSID_SET;
+	sdata->local->oper_channel = req->chan;
+	ieee80211_hw_config(sdata->local, 0);
 
-	/* TODO: req->chan */
-	sdata->u.mgd.flags |= IEEE80211_STA_AUTO_CHANNEL_SEL;
+	if (!req->ssid)
+		return -EINVAL;
 
-	if (req->ssid) {
-		sdata->u.mgd.flags |= IEEE80211_STA_SSID_SET;
-		memcpy(sdata->u.mgd.ssid, req->ssid, req->ssid_len);
-		sdata->u.mgd.ssid_len = req->ssid_len;
-		sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_SSID_SEL;
-	} else
-		sdata->u.mgd.flags |= IEEE80211_STA_AUTO_SSID_SEL;
+	memcpy(sdata->u.mgd.ssid, req->ssid, req->ssid_len);
+	sdata->u.mgd.ssid_len = req->ssid_len;
 
 	ret = ieee80211_sta_set_extra_ie(sdata, req->ie, req->ie_len);
 	if (ret && ret != -EALREADY)
@@ -1275,7 +1265,6 @@ static int ieee80211_assoc(struct wiphy 
 	else
 		sdata->u.mgd.flags &= ~IEEE80211_STA_CONTROL_PORT;
 
-	sdata->u.mgd.flags |= IEEE80211_STA_EXT_SME;
 	sdata->u.mgd.state = IEEE80211_STA_MLME_ASSOCIATE;
 	ieee80211_sta_req_auth(sdata);
 	return 0;
--- wireless-testing.orig/net/mac80211/ieee80211_i.h	2009-07-01 20:29:51.000000000 +0200
+++ wireless-testing/net/mac80211/ieee80211_i.h	2009-07-01 20:29:52.000000000 +0200
@@ -228,28 +228,24 @@ struct mesh_preq_queue {
 };
 
 /* flags used in struct ieee80211_if_managed.flags */
-#define IEEE80211_STA_SSID_SET		BIT(0)
-#define IEEE80211_STA_BSSID_SET		BIT(1)
-#define IEEE80211_STA_PREV_BSSID_SET	BIT(2)
-#define IEEE80211_STA_AUTHENTICATED	BIT(3)
-#define IEEE80211_STA_ASSOCIATED	BIT(4)
-#define IEEE80211_STA_PROBEREQ_POLL	BIT(5)
-#define IEEE80211_STA_CREATE_IBSS	BIT(6)
-#define IEEE80211_STA_CONTROL_PORT	BIT(7)
-#define IEEE80211_STA_WMM_ENABLED	BIT(8)
-/* hole at 9, please re-use */
-#define IEEE80211_STA_AUTO_SSID_SEL	BIT(10)
-#define IEEE80211_STA_AUTO_BSSID_SEL	BIT(11)
-#define IEEE80211_STA_AUTO_CHANNEL_SEL	BIT(12)
-#define IEEE80211_STA_PRIVACY_INVOKED	BIT(13)
-#define IEEE80211_STA_TKIP_WEP_USED	BIT(14)
-#define IEEE80211_STA_CSA_RECEIVED	BIT(15)
-#define IEEE80211_STA_MFP_ENABLED	BIT(16)
-#define IEEE80211_STA_EXT_SME		BIT(17)
+enum ieee80211_sta_flags {
+	IEEE80211_STA_PREV_BSSID_SET	= BIT(0),
+	IEEE80211_STA_AUTHENTICATED	= BIT(1),
+	IEEE80211_STA_ASSOCIATED	= BIT(2),
+	IEEE80211_STA_PROBEREQ_POLL	= BIT(3),
+	IEEE80211_STA_CONTROL_PORT	= BIT(4),
+	IEEE80211_STA_WMM_ENABLED	= BIT(5),
+	IEEE80211_STA_DISABLE_11N	= BIT(6),
+	IEEE80211_STA_CSA_RECEIVED	= BIT(7),
+	IEEE80211_STA_MFP_ENABLED	= BIT(8),
+};
+
 /* flags for MLME request */
-#define IEEE80211_STA_REQ_SCAN 0
-#define IEEE80211_STA_REQ_AUTH 1
-#define IEEE80211_STA_REQ_RUN  2
+enum ieee80211_sta_request {
+	IEEE80211_STA_REQ_SCAN,
+	IEEE80211_STA_REQ_AUTH,
+	IEEE80211_STA_REQ_RUN,
+};
 
 struct ieee80211_if_managed {
 	struct timer_list timer;
@@ -934,10 +930,6 @@ extern const struct iw_handler_def ieee8
 void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata);
 ieee80211_rx_result ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata,
 					  struct sk_buff *skb);
-int ieee80211_sta_commit(struct ieee80211_sub_if_data *sdata);
-int ieee80211_sta_set_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t len);
-int ieee80211_sta_get_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t *len);
-int ieee80211_sta_set_bssid(struct ieee80211_sub_if_data *sdata, u8 *bssid);
 void ieee80211_sta_req_auth(struct ieee80211_sub_if_data *sdata);
 int ieee80211_sta_deauthenticate(struct ieee80211_sub_if_data *sdata, u16 reason);
 int ieee80211_sta_disassociate(struct ieee80211_sub_if_data *sdata, u16 reason);
--- wireless-testing.orig/net/mac80211/mlme.c	2009-07-01 20:29:51.000000000 +0200
+++ wireless-testing/net/mac80211/mlme.c	2009-07-01 20:29:52.000000000 +0200
@@ -347,7 +347,7 @@ static void ieee80211_send_assoc(struct 
 	    sband->ht_cap.ht_supported &&
 	    (ht_ie = ieee80211_bss_get_ie(bss, WLAN_EID_HT_INFORMATION)) &&
 	    ht_ie[1] >= sizeof(struct ieee80211_ht_info) &&
-	    (!(ifmgd->flags & IEEE80211_STA_TKIP_WEP_USED))) {
+	    (!(ifmgd->flags & IEEE80211_STA_DISABLE_11N))) {
 		struct ieee80211_ht_info *ht_info =
 			(struct ieee80211_ht_info *)(ht_ie + 2);
 		u16 cap = sband->ht_cap.cap;
@@ -981,8 +981,6 @@ static void ieee80211_authenticate(struc
 {
 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 	struct ieee80211_local *local = sdata->local;
-	u8 *ies;
-	size_t ies_len;
 
 	ifmgd->auth_tries++;
 	if (ifmgd->auth_tries > IEEE80211_AUTH_MAX_TRIES) {
@@ -1010,15 +1008,8 @@ static void ieee80211_authenticate(struc
 	printk(KERN_DEBUG "%s: authenticate with AP %pM\n",
 	       sdata->dev->name, ifmgd->bssid);
 
-	if (ifmgd->flags & IEEE80211_STA_EXT_SME) {
-		ies = ifmgd->sme_auth_ie;
-		ies_len = ifmgd->sme_auth_ie_len;
-	} else {
-		ies = NULL;
-		ies_len = 0;
-	}
-	ieee80211_send_auth(sdata, 1, ifmgd->auth_alg, ies, ies_len,
-			    ifmgd->bssid, 0);
+	ieee80211_send_auth(sdata, 1, ifmgd->auth_alg, ifmgd->sme_auth_ie,
+			    ifmgd->sme_auth_ie_len, ifmgd->bssid, 0);
 	ifmgd->auth_transaction = 2;
 
 	mod_timer(&ifmgd->timer, jiffies + IEEE80211_AUTH_TIMEOUT);
@@ -1128,44 +1119,6 @@ static void ieee80211_set_disassoc(struc
 	sta_info_destroy(sta);
 }
 
-static int ieee80211_sta_wep_configured(struct ieee80211_sub_if_data *sdata)
-{
-	if (!sdata || !sdata->default_key ||
-	    sdata->default_key->conf.alg != ALG_WEP)
-		return 0;
-	return 1;
-}
-
-static int ieee80211_privacy_mismatch(struct ieee80211_sub_if_data *sdata)
-{
-	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
-	struct ieee80211_local *local = sdata->local;
-	struct ieee80211_bss *bss;
-	int bss_privacy;
-	int wep_privacy;
-	int privacy_invoked;
-
-	if (!ifmgd || (ifmgd->flags & IEEE80211_STA_EXT_SME))
-		return 0;
-
-	bss = ieee80211_rx_bss_get(local, ifmgd->bssid,
-				   local->hw.conf.channel->center_freq,
-				   ifmgd->ssid, ifmgd->ssid_len);
-	if (!bss)
-		return 0;
-
-	bss_privacy = !!(bss->cbss.capability & WLAN_CAPABILITY_PRIVACY);
-	wep_privacy = !!ieee80211_sta_wep_configured(sdata);
-	privacy_invoked = !!(ifmgd->flags & IEEE80211_STA_PRIVACY_INVOKED);
-
-	ieee80211_rx_bss_put(local, bss);
-
-	if ((bss_privacy == wep_privacy) || (bss_privacy == privacy_invoked))
-		return 0;
-
-	return 1;
-}
-
 static void ieee80211_associate(struct ieee80211_sub_if_data *sdata)
 {
 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
@@ -1195,14 +1148,6 @@ static void ieee80211_associate(struct i
 	ifmgd->state = IEEE80211_STA_MLME_ASSOCIATE;
 	printk(KERN_DEBUG "%s: associate with AP %pM\n",
 	       sdata->dev->name, ifmgd->bssid);
-	if (ieee80211_privacy_mismatch(sdata)) {
-		printk(KERN_DEBUG "%s: mismatch in privacy configuration and "
-		       "mixed-cell disabled - abort association\n", sdata->dev->name);
-		ifmgd->state = IEEE80211_STA_MLME_DISABLED;
-		ieee80211_recalc_idle(local);
-		return;
-	}
-
 	ieee80211_send_assoc(sdata);
 
 	mod_timer(&ifmgd->timer, jiffies + IEEE80211_ASSOC_TIMEOUT);
@@ -1360,12 +1305,9 @@ static void ieee80211_auth_completed(str
 
 	printk(KERN_DEBUG "%s: authenticated\n", sdata->dev->name);
 	ifmgd->flags |= IEEE80211_STA_AUTHENTICATED;
-	if (ifmgd->flags & IEEE80211_STA_EXT_SME) {
-		/* Wait for SME to request association */
-		ifmgd->state = IEEE80211_STA_MLME_DISABLED;
-		ieee80211_recalc_idle(sdata->local);
-	} else
-		ieee80211_associate(sdata);
+	/* Wait for SME to request association */
+	ifmgd->state = IEEE80211_STA_MLME_DISABLED;
+	ieee80211_recalc_idle(sdata->local);
 }
 
 
@@ -1460,15 +1402,6 @@ static void ieee80211_rx_mgmt_deauth(str
 		printk(KERN_DEBUG "%s: deauthenticated (Reason: %u)\n",
 				sdata->dev->name, reason_code);
 
-	if (!(ifmgd->flags & IEEE80211_STA_EXT_SME) &&
-	    (ifmgd->state == IEEE80211_STA_MLME_AUTHENTICATE ||
-	     ifmgd->state == IEEE80211_STA_MLME_ASSOCIATE ||
-	     ifmgd->state == IEEE80211_STA_MLME_ASSOCIATED)) {
-		ifmgd->state = IEEE80211_STA_MLME_DIRECT_PROBE;
-		mod_timer(&ifmgd->timer, jiffies +
-				      IEEE80211_RETRY_AUTH_INTERVAL);
-	}
-
 	ieee80211_set_disassoc(sdata, true, false, 0);
 	ifmgd->flags &= ~IEEE80211_STA_AUTHENTICATED;
 	cfg80211_send_deauth(sdata->dev, (u8 *) mgmt, len, GFP_KERNEL);
@@ -1494,13 +1427,6 @@ static void ieee80211_rx_mgmt_disassoc(s
 		printk(KERN_DEBUG "%s: disassociated (Reason: %u)\n",
 				sdata->dev->name, reason_code);
 
-	if (!(ifmgd->flags & IEEE80211_STA_EXT_SME) &&
-	    ifmgd->state == IEEE80211_STA_MLME_ASSOCIATED) {
-		ifmgd->state = IEEE80211_STA_MLME_ASSOCIATE;
-		mod_timer(&ifmgd->timer, jiffies +
-				      IEEE80211_RETRY_AUTH_INTERVAL);
-	}
-
 	ieee80211_set_disassoc(sdata, false, false, reason_code);
 	cfg80211_send_disassoc(sdata->dev, (u8 *) mgmt, len, GFP_KERNEL);
 }
@@ -1573,11 +1499,9 @@ static void ieee80211_rx_mgmt_assoc_resp
 		ifmgd->flags &= ~IEEE80211_STA_PREV_BSSID_SET;
 		cfg80211_send_rx_assoc(sdata->dev, (u8 *) mgmt, len,
 				       GFP_KERNEL);
-		if (ifmgd->flags & IEEE80211_STA_EXT_SME) {
-			/* Wait for SME to decide what to do next */
-			ifmgd->state = IEEE80211_STA_MLME_DISABLED;
-			ieee80211_recalc_idle(local);
-		}
+		/* Wait for SME to decide what to do next */
+		ifmgd->state = IEEE80211_STA_MLME_DISABLED;
+		ieee80211_recalc_idle(local);
 		return;
 	}
 
@@ -1683,8 +1607,7 @@ static void ieee80211_rx_mgmt_assoc_resp
 	else
 		sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE;
 
-	/* If TKIP/WEP is used, no need to parse AP's HT capabilities */
-	if (elems.ht_cap_elem && !(ifmgd->flags & IEEE80211_STA_TKIP_WEP_USED))
+	if (elems.ht_cap_elem && !(ifmgd->flags & IEEE80211_STA_DISABLE_11N))
 		ieee80211_ht_cap_ie_to_sta_ht_cap(sband,
 				elems.ht_cap_elem, &sta->sta.ht_cap);
 
@@ -1718,7 +1641,7 @@ static void ieee80211_rx_mgmt_assoc_resp
 
 	if (elems.ht_info_elem && elems.wmm_param &&
 	    (ifmgd->flags & IEEE80211_STA_WMM_ENABLED) &&
-	    !(ifmgd->flags & IEEE80211_STA_TKIP_WEP_USED))
+	    !(ifmgd->flags & IEEE80211_STA_DISABLE_11N))
 		changed |= ieee80211_enable_ht(sdata, elems.ht_info_elem,
 					       ap_ht_cap_flags);
 
@@ -1931,7 +1854,7 @@ static void ieee80211_rx_mgmt_beacon(str
 
 
 	if (elems.ht_cap_elem && elems.ht_info_elem && elems.wmm_param &&
-	    !(ifmgd->flags & IEEE80211_STA_TKIP_WEP_USED)) {
+	    !(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) {
 		struct sta_info *sta;
 		struct ieee80211_supported_band *sband;
 		u16 ap_ht_cap_flags;
@@ -2090,26 +2013,6 @@ static int ieee80211_sta_config_auth(str
 	u16 capa_val = WLAN_CAPABILITY_ESS;
 	struct ieee80211_channel *chan = local->oper_channel;
 
-	if (!(ifmgd->flags & IEEE80211_STA_EXT_SME) &&
-	    ifmgd->flags & (IEEE80211_STA_AUTO_SSID_SEL |
-			    IEEE80211_STA_AUTO_BSSID_SEL |
-			    IEEE80211_STA_AUTO_CHANNEL_SEL)) {
-		capa_mask |= WLAN_CAPABILITY_PRIVACY;
-		if (sdata->default_key)
-			capa_val |= WLAN_CAPABILITY_PRIVACY;
-	}
-
-	if (ifmgd->flags & IEEE80211_STA_AUTO_CHANNEL_SEL)
-		chan = NULL;
-
-	if (ifmgd->flags & IEEE80211_STA_AUTO_BSSID_SEL)
-		bssid = NULL;
-
-	if (ifmgd->flags & IEEE80211_STA_AUTO_SSID_SEL) {
-		ssid = NULL;
-		ssid_len = 0;
-	}
-
 	bss = (void *)cfg80211_get_bss(local->hw.wiphy, chan,
 				       bssid, ssid, ssid_len,
 				       capa_mask, capa_val);
@@ -2119,10 +2022,6 @@ static int ieee80211_sta_config_auth(str
 		local->oper_channel_type = NL80211_CHAN_NO_HT;
 		ieee80211_hw_config(local, 0);
 
-		if (!(ifmgd->flags & IEEE80211_STA_SSID_SET))
-			ieee80211_sta_set_ssid(sdata, bss->ssid,
-					       bss->ssid_len);
-		ieee80211_sta_set_bssid(sdata, bss->cbss.bssid);
 		ieee80211_sta_def_wmm_params(sdata, bss->supp_rates_len,
 						    bss->supp_rates);
 		if (sdata->u.mgd.mfp == IEEE80211_MFP_REQUIRED)
@@ -2232,14 +2131,6 @@ static void ieee80211_sta_work(struct wo
 		WARN_ON(1);
 		break;
 	}
-
-	if (ieee80211_privacy_mismatch(sdata)) {
-		printk(KERN_DEBUG "%s: privacy configuration mismatch and "
-		       "mixed-cell disabled - disassociate\n", sdata->dev->name);
-
-		ieee80211_set_disassoc(sdata, false, true,
-					WLAN_REASON_UNSPECIFIED);
-	}
 }
 
 static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata)
@@ -2306,9 +2197,7 @@ void ieee80211_sta_setup_sdata(struct ie
 	skb_queue_head_init(&ifmgd->skb_queue);
 
 	ifmgd->capab = WLAN_CAPABILITY_ESS;
-	ifmgd->flags |= IEEE80211_STA_CREATE_IBSS |
-		IEEE80211_STA_AUTO_BSSID_SEL |
-		IEEE80211_STA_AUTO_CHANNEL_SEL;
+	ifmgd->flags = 0;
 	if (sdata->local->hw.queues >= 4)
 		ifmgd->flags |= IEEE80211_STA_WMM_ENABLED;
 
@@ -2324,96 +2213,20 @@ void ieee80211_sta_req_auth(struct ieee8
 	if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
 		return;
 
-	if ((ifmgd->flags & (IEEE80211_STA_BSSID_SET |
-			     IEEE80211_STA_AUTO_BSSID_SEL)) &&
-	    (ifmgd->flags & (IEEE80211_STA_SSID_SET |
-			     IEEE80211_STA_AUTO_SSID_SEL))) {
-
-		if (ifmgd->state == IEEE80211_STA_MLME_ASSOCIATED)
-			ieee80211_set_disassoc(sdata, true, true,
-					       WLAN_REASON_DEAUTH_LEAVING);
-
-		if (ifmgd->ssid_len == 0) {
-			/*
-			 * Only allow association to be started if a valid SSID
-			 * is configured.
-			 */
-			return;
-		}
-
-		if (!(ifmgd->flags & IEEE80211_STA_EXT_SME) ||
-		    ifmgd->state != IEEE80211_STA_MLME_ASSOCIATE)
-			set_bit(IEEE80211_STA_REQ_AUTH, &ifmgd->request);
-		else if (ifmgd->flags & IEEE80211_STA_EXT_SME)
-			set_bit(IEEE80211_STA_REQ_RUN, &ifmgd->request);
-		queue_work(local->hw.workqueue, &ifmgd->work);
-	}
-}
-
-int ieee80211_sta_commit(struct ieee80211_sub_if_data *sdata)
-{
-	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
-
-	if (ifmgd->ssid_len)
-		ifmgd->flags |= IEEE80211_STA_SSID_SET;
-	else
-		ifmgd->flags &= ~IEEE80211_STA_SSID_SET;
-
-	return 0;
-}
-
-int ieee80211_sta_set_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t len)
-{
-	struct ieee80211_if_managed *ifmgd;
-
-	if (len > IEEE80211_MAX_SSID_LEN)
-		return -EINVAL;
-
-	ifmgd = &sdata->u.mgd;
-
-	if (ifmgd->ssid_len != len || memcmp(ifmgd->ssid, ssid, len) != 0) {
-		if (ifmgd->state == IEEE80211_STA_MLME_ASSOCIATED)
-			ieee80211_set_disassoc(sdata, true, true,
-					       WLAN_REASON_DEAUTH_LEAVING);
-
-		/*
-		 * Do not use reassociation if SSID is changed (different ESS).
-		 */
-		ifmgd->flags &= ~IEEE80211_STA_PREV_BSSID_SET;
-		memset(ifmgd->ssid, 0, sizeof(ifmgd->ssid));
-		memcpy(ifmgd->ssid, ssid, len);
-		ifmgd->ssid_len = len;
-	}
-
-	return ieee80211_sta_commit(sdata);
-}
-
-int ieee80211_sta_get_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t *len)
-{
-	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
-	memcpy(ssid, ifmgd->ssid, ifmgd->ssid_len);
-	*len = ifmgd->ssid_len;
-	return 0;
-}
-
-int ieee80211_sta_set_bssid(struct ieee80211_sub_if_data *sdata, u8 *bssid)
-{
-	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
-
-	if (compare_ether_addr(bssid, ifmgd->bssid) != 0 &&
-	    ifmgd->state == IEEE80211_STA_MLME_ASSOCIATED)
+	if (WARN_ON(ifmgd->state == IEEE80211_STA_MLME_ASSOCIATED))
 		ieee80211_set_disassoc(sdata, true, true,
 				       WLAN_REASON_DEAUTH_LEAVING);
 
-	if (is_valid_ether_addr(bssid)) {
-		memcpy(ifmgd->bssid, bssid, ETH_ALEN);
-		ifmgd->flags |= IEEE80211_STA_BSSID_SET;
-	} else {
-		memset(ifmgd->bssid, 0, ETH_ALEN);
-		ifmgd->flags &= ~IEEE80211_STA_BSSID_SET;
+	if (WARN_ON(ifmgd->ssid_len == 0)) {
+		/*
+		 * Only allow association to be started if a valid SSID
+		 * is configured.
+		 */
+		return;
 	}
 
-	return ieee80211_sta_commit(sdata);
+	set_bit(IEEE80211_STA_REQ_RUN, &ifmgd->request);
+	queue_work(local->hw.workqueue, &ifmgd->work);
 }
 
 int ieee80211_sta_set_extra_ie(struct ieee80211_sub_if_data *sdata,
--- wireless-testing.orig/net/mac80211/debugfs_netdev.c	2009-07-01 20:29:52.000000000 +0200
+++ wireless-testing/net/mac80211/debugfs_netdev.c	2009-07-01 20:29:52.000000000 +0200
@@ -111,9 +111,7 @@ IEEE80211_IF_FILE(auth_transaction, u.mg
 static ssize_t ieee80211_if_fmt_flags(
 	const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
 {
-	return scnprintf(buf, buflen, "%s%s%s%s%s%s%s\n",
-		 sdata->u.mgd.flags & IEEE80211_STA_SSID_SET ? "SSID\n" : "",
-		 sdata->u.mgd.flags & IEEE80211_STA_BSSID_SET ? "BSSID\n" : "",
+	return scnprintf(buf, buflen, "%s%s%s%s%s\n",
 		 sdata->u.mgd.flags & IEEE80211_STA_PREV_BSSID_SET ? "prev BSSID\n" : "",
 		 sdata->u.mgd.flags & IEEE80211_STA_AUTHENTICATED ? "AUTH\n" : "",
 		 sdata->u.mgd.flags & IEEE80211_STA_ASSOCIATED ? "ASSOC\n" : "",
--- wireless-testing.orig/net/mac80211/iface.c	2009-07-01 13:27:46.000000000 +0200
+++ wireless-testing/net/mac80211/iface.c	2009-07-01 20:29:52.000000000 +0200
@@ -485,8 +485,6 @@ static int ieee80211_stop(struct net_dev
 		synchronize_rcu();
 		skb_queue_purge(&sdata->u.mgd.skb_queue);
 
-		sdata->u.mgd.flags &= ~(IEEE80211_STA_PRIVACY_INVOKED |
-					IEEE80211_STA_TKIP_WEP_USED);
 		kfree(sdata->u.mgd.extra_ie);
 		sdata->u.mgd.extra_ie = NULL;
 		sdata->u.mgd.extra_ie_len = 0;



^ permalink raw reply

* [PATCH 21/20 v4] mac80211: remove auth algorithm retry
From: Johannes Berg @ 2009-07-01 19:40 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless
In-Reply-To: <20090701192641.072258140@sipsolutions.net>

The automatic auth algorithm issue is now solved in
cfg80211, so mac80211 no longer needs code to try
different algorithms -- just using whatever cfg80211
asked for is good.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
 net/mac80211/cfg.c            |    8 +++----
 net/mac80211/debugfs_netdev.c |    3 --
 net/mac80211/ieee80211_i.h    |    8 -------
 net/mac80211/mlme.c           |   47 ------------------------------------------
 4 files changed, 4 insertions(+), 62 deletions(-)

--- wireless-testing.orig/net/mac80211/ieee80211_i.h	2009-07-01 13:27:46.000000000 +0200
+++ wireless-testing/net/mac80211/ieee80211_i.h	2009-07-01 20:29:51.000000000 +0200
@@ -251,12 +251,6 @@ struct mesh_preq_queue {
 #define IEEE80211_STA_REQ_AUTH 1
 #define IEEE80211_STA_REQ_RUN  2
 
-/* bitfield of allowed auth algs */
-#define IEEE80211_AUTH_ALG_OPEN BIT(0)
-#define IEEE80211_AUTH_ALG_SHARED_KEY BIT(1)
-#define IEEE80211_AUTH_ALG_LEAP BIT(2)
-#define IEEE80211_AUTH_ALG_FT BIT(3)
-
 struct ieee80211_if_managed {
 	struct timer_list timer;
 	struct timer_list chswitch_timer;
@@ -303,7 +297,6 @@ struct ieee80211_if_managed {
 
 	unsigned int flags;
 
-	unsigned int auth_algs; /* bitfield of allowed auth algs */
 	int auth_alg; /* currently used IEEE 802.11 authentication algorithm */
 	int auth_transaction;
 
@@ -488,7 +481,6 @@ struct ieee80211_sub_if_data {
 			struct dentry *extra_ie_len;
 			struct dentry *auth_tries;
 			struct dentry *assoc_tries;
-			struct dentry *auth_algs;
 			struct dentry *auth_alg;
 			struct dentry *auth_transaction;
 			struct dentry *flags;
--- wireless-testing.orig/net/mac80211/mlme.c	2009-07-01 20:29:35.000000000 +0200
+++ wireless-testing/net/mac80211/mlme.c	2009-07-01 20:29:51.000000000 +0200
@@ -1414,39 +1414,6 @@ static void ieee80211_rx_mgmt_auth(struc
 		return;
 
 	if (status_code != WLAN_STATUS_SUCCESS) {
-		if (status_code == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) {
-			u8 algs[3];
-			const int num_algs = ARRAY_SIZE(algs);
-			int i, pos;
-			algs[0] = algs[1] = algs[2] = 0xff;
-			if (ifmgd->auth_algs & IEEE80211_AUTH_ALG_OPEN)
-				algs[0] = WLAN_AUTH_OPEN;
-			if (ifmgd->auth_algs & IEEE80211_AUTH_ALG_SHARED_KEY)
-				algs[1] = WLAN_AUTH_SHARED_KEY;
-			if (ifmgd->auth_algs & IEEE80211_AUTH_ALG_LEAP)
-				algs[2] = WLAN_AUTH_LEAP;
-			if (ifmgd->auth_alg == WLAN_AUTH_OPEN)
-				pos = 0;
-			else if (ifmgd->auth_alg == WLAN_AUTH_SHARED_KEY)
-				pos = 1;
-			else
-				pos = 2;
-			for (i = 0; i < num_algs; i++) {
-				pos++;
-				if (pos >= num_algs)
-					pos = 0;
-				if (algs[pos] == ifmgd->auth_alg ||
-				    algs[pos] == 0xff)
-					continue;
-				if (algs[pos] == WLAN_AUTH_SHARED_KEY &&
-				    !ieee80211_sta_wep_configured(sdata))
-					continue;
-				ifmgd->auth_alg = algs[pos];
-				ifmgd->auth_tries = 0;
-				return;
-			}
-		}
-		/* nothing else to try -- give up */
 		cfg80211_send_rx_auth(sdata->dev, (u8 *) mgmt, len,
 				      GFP_KERNEL);
 		ifmgd->state = IEEE80211_STA_MLME_DISABLED;
@@ -2102,18 +2069,6 @@ static void ieee80211_sta_reset_auth(str
 	drv_reset_tsf(local);
 
 	ifmgd->wmm_last_param_set = -1; /* allow any WMM update */
-
-
-	if (ifmgd->auth_algs & IEEE80211_AUTH_ALG_OPEN)
-		ifmgd->auth_alg = WLAN_AUTH_OPEN;
-	else if (ifmgd->auth_algs & IEEE80211_AUTH_ALG_SHARED_KEY)
-		ifmgd->auth_alg = WLAN_AUTH_SHARED_KEY;
-	else if (ifmgd->auth_algs & IEEE80211_AUTH_ALG_LEAP)
-		ifmgd->auth_alg = WLAN_AUTH_LEAP;
-	else if (ifmgd->auth_algs & IEEE80211_AUTH_ALG_FT)
-		ifmgd->auth_alg = WLAN_AUTH_FT;
-	else
-		ifmgd->auth_alg = WLAN_AUTH_OPEN;
 	ifmgd->auth_transaction = -1;
 	ifmgd->flags &= ~IEEE80211_STA_ASSOCIATED;
 	ifmgd->assoc_scan_tries = 0;
@@ -2351,8 +2306,6 @@ void ieee80211_sta_setup_sdata(struct ie
 	skb_queue_head_init(&ifmgd->skb_queue);
 
 	ifmgd->capab = WLAN_CAPABILITY_ESS;
-	ifmgd->auth_algs = IEEE80211_AUTH_ALG_OPEN |
-		IEEE80211_AUTH_ALG_SHARED_KEY;
 	ifmgd->flags |= IEEE80211_STA_CREATE_IBSS |
 		IEEE80211_STA_AUTO_BSSID_SEL |
 		IEEE80211_STA_AUTO_CHANNEL_SEL;
--- wireless-testing.orig/net/mac80211/cfg.c	2009-07-01 20:29:47.000000000 +0200
+++ wireless-testing/net/mac80211/cfg.c	2009-07-01 20:29:51.000000000 +0200
@@ -1178,16 +1178,16 @@ static int ieee80211_auth(struct wiphy *
 
 	switch (req->auth_type) {
 	case NL80211_AUTHTYPE_OPEN_SYSTEM:
-		sdata->u.mgd.auth_algs = IEEE80211_AUTH_ALG_OPEN;
+		sdata->u.mgd.auth_alg = WLAN_AUTH_OPEN;
 		break;
 	case NL80211_AUTHTYPE_SHARED_KEY:
-		sdata->u.mgd.auth_algs = IEEE80211_AUTH_ALG_SHARED_KEY;
+		sdata->u.mgd.auth_alg = WLAN_AUTH_SHARED_KEY;
 		break;
 	case NL80211_AUTHTYPE_FT:
-		sdata->u.mgd.auth_algs = IEEE80211_AUTH_ALG_FT;
+		sdata->u.mgd.auth_alg = WLAN_AUTH_FT;
 		break;
 	case NL80211_AUTHTYPE_NETWORK_EAP:
-		sdata->u.mgd.auth_algs = IEEE80211_AUTH_ALG_LEAP;
+		sdata->u.mgd.auth_alg = WLAN_AUTH_LEAP;
 		break;
 	default:
 		return -EOPNOTSUPP;
--- wireless-testing.orig/net/mac80211/debugfs_netdev.c	2009-07-01 13:27:46.000000000 +0200
+++ wireless-testing/net/mac80211/debugfs_netdev.c	2009-07-01 20:29:52.000000000 +0200
@@ -105,7 +105,6 @@ IEEE80211_IF_FILE(capab, u.mgd.capab, HE
 IEEE80211_IF_FILE(extra_ie_len, u.mgd.extra_ie_len, SIZE);
 IEEE80211_IF_FILE(auth_tries, u.mgd.auth_tries, DEC);
 IEEE80211_IF_FILE(assoc_tries, u.mgd.assoc_tries, DEC);
-IEEE80211_IF_FILE(auth_algs, u.mgd.auth_algs, HEX);
 IEEE80211_IF_FILE(auth_alg, u.mgd.auth_alg, DEC);
 IEEE80211_IF_FILE(auth_transaction, u.mgd.auth_transaction, DEC);
 
@@ -194,7 +193,6 @@ static void add_sta_files(struct ieee802
 	DEBUGFS_ADD(extra_ie_len, sta);
 	DEBUGFS_ADD(auth_tries, sta);
 	DEBUGFS_ADD(assoc_tries, sta);
-	DEBUGFS_ADD(auth_algs, sta);
 	DEBUGFS_ADD(auth_alg, sta);
 	DEBUGFS_ADD(auth_transaction, sta);
 	DEBUGFS_ADD(flags, sta);
@@ -327,7 +325,6 @@ static void del_sta_files(struct ieee802
 	DEBUGFS_DEL(extra_ie_len, sta);
 	DEBUGFS_DEL(auth_tries, sta);
 	DEBUGFS_DEL(assoc_tries, sta);
-	DEBUGFS_DEL(auth_algs, sta);
 	DEBUGFS_DEL(auth_alg, sta);
 	DEBUGFS_DEL(auth_transaction, sta);
 	DEBUGFS_DEL(flags, sta);



^ permalink raw reply

* [PATCH 20/20 v4] mac80211: re-add HT disabling
From: Johannes Berg @ 2009-07-01 19:27 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless
In-Reply-To: <20090701192641.072258140@sipsolutions.net>

The IEEE80211_STA_TKIP_WEP_USED flag is used internally to
disable HT when WEP or TKIP are used. Now that cfg80211 is
giving us the required information, we can set the flag
appropriately again.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
 net/mac80211/cfg.c |   10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

--- wireless-testing.orig/net/mac80211/cfg.c	2009-07-01 20:29:45.000000000 +0200
+++ wireless-testing/net/mac80211/cfg.c	2009-07-01 20:29:47.000000000 +0200
@@ -1228,7 +1228,7 @@ static int ieee80211_assoc(struct wiphy 
 			   struct cfg80211_assoc_request *req)
 {
 	struct ieee80211_sub_if_data *sdata;
-	int ret;
+	int ret, i;
 
 	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
@@ -1236,6 +1236,14 @@ static int ieee80211_assoc(struct wiphy 
 	    !(sdata->u.mgd.flags & IEEE80211_STA_AUTHENTICATED))
 		return -ENOLINK; /* not authenticated */
 
+	sdata->u.mgd.flags &= ~IEEE80211_STA_TKIP_WEP_USED;
+
+	for (i = 0; i < req->crypto.n_ciphers_pairwise; i++)
+		if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 ||
+		    req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP ||
+		    req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP104)
+			sdata->u.mgd.flags |= IEEE80211_STA_TKIP_WEP_USED;
+
 	sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL;
 	sdata->u.mgd.flags |= IEEE80211_STA_BSSID_SET;
 

-- 


^ permalink raw reply


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