All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC 00/11] cfg80211 connect API + wireless extension move
@ 2009-06-24 12:07 Johannes Berg
  2009-06-24 12:07 ` [RFC 01/11] cfg80211: connect/disconnect API Johannes Berg
                   ` (11 more replies)
  0 siblings, 12 replies; 20+ messages in thread
From: Johannes Berg @ 2009-06-24 12:07 UTC (permalink / raw)
  To: linux-wireless

This finally introduces nl80211 and cfg80211 connect API,
and makes wireless extensions entirely self-contained in
cfg80211.

YES.

The last four patches still need more work:
 * the combine patches require getting iwm ported
 * the internalise patch requires getting orinoco
   and rndis ported.

Samuel, who also worked a lot on the first three bits of   
this series, is working on getting iwm ported, and then    
we can stick this into the tree except for the last patch, 
and gradually work on the rest. Maybe we even decide to    
not internalise it this way because orinoco wants to keep  
some ioctls that we'll not offer in cfg80211, not sure yet.

Also, this still needs a bit of work for auth algorithms.  
Currently, the series breaks shared key auth. For iwm, the 
device will only try the auth algorithm you ask it to use, 
but mac80211 is able to select the algorithm automatically.
It might make most sense to make cfg80211 try different 
algorithms if userspace didn't specify which one to use.

Anyway, comments welcome!

johannes


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

* [RFC 01/11] cfg80211: connect/disconnect API
  2009-06-24 12:07 [RFC 00/11] cfg80211 connect API + wireless extension move Johannes Berg
@ 2009-06-24 12:07 ` Johannes Berg
  2009-06-24 15:30   ` Samuel Ortiz
  2009-06-24 12:07 ` [RFC 02/11] cfg80211: emulate connect with auth/assoc Johannes Berg
                   ` (10 subsequent siblings)
  11 siblings, 1 reply; 20+ messages in thread
From: Johannes Berg @ 2009-06-24 12:07 UTC (permalink / raw)
  To: linux-wireless; +Cc: Samuel Ortiz

From: Samuel Ortiz <sameo@linux.intel.com>

This patch introduces the cfg80211 connect/disconnect API.
The goal here is to run the AUTH and ASSOC steps in one call.
This is needed for some fullmac cards that run both steps
directly from the target, after the host driver sends a
connect command.

Signed-off-by: Samuel Ortiz <samuel.ortiz@intel.com>
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
v2: * everything changed/split up differently

 include/linux/nl80211.h |   32 +++++
 include/net/cfg80211.h  |  100 ++++++++++++++++++
 net/wireless/Makefile   |    2 
 net/wireless/core.c     |   16 ++
 net/wireless/core.h     |    7 +
 net/wireless/nl80211.c  |  264 ++++++++++++++++++++++++++++++++++++++++++++++++
 net/wireless/nl80211.h  |   11 ++
 net/wireless/sme.c      |  206 +++++++++++++++++++++++++++++++++++++
 8 files changed, 633 insertions(+), 5 deletions(-)

--- wireless-testing.orig/include/linux/nl80211.h	2009-06-24 13:53:14.000000000 +0200
+++ wireless-testing/include/linux/nl80211.h	2009-06-24 13:54:05.000000000 +0200
@@ -242,6 +242,22 @@
  * @NL80211_CMD_LEAVE_IBSS: Leave the IBSS -- no special arguments, the IBSS is
  *	determined by the network interface.
  *
+ * @NL80211_CMD_CONNECT: connection request and notification; this command
+ *	requests to connect to a specified network but without separating
+ *	auth and assoc steps. For this, you need to specify the SSID in a
+ *	%NL80211_ATTR_SSID attribute, and can optionally specify the association
+ *	IEs in %NL80211_ATTR_IE, %NL80211_ATTR_AUTH_TYPE, %NL80211_ATTR_MAC,
+ *	%NL80211_ATTR_WIPHY_FREQ and %NL80211_ATTR_CONTROL_PORT.
+ *	It is also sent as an event, with the BSSID and response IEs when the
+ *	connection is established or failed to be established. This can be
+ *	determined by the STATUS_CODE attribute.
+ * @NL80211_CMD_ROAM: request that the card roam (currently not implemented),
+ *	sent as an event when the card/driver roamed by itself.
+ * @NL80211_CMD_DISCONNECT: drop a given connection; also used to notify
+ *	userspace that a connection was dropped by the AP or due to other
+ *	reasons, for this the %NL80211_ATTR_DISCONNECTED_BY_AP and
+ *	%NL80211_ATTR_REASON_CODE attributes are used.
+ *
  * @NL80211_CMD_MAX: highest used command number
  * @__NL80211_CMD_AFTER_LAST: internal use
  */
@@ -310,6 +326,10 @@ enum nl80211_commands {
 	NL80211_CMD_JOIN_IBSS,
 	NL80211_CMD_LEAVE_IBSS,
 
+	NL80211_CMD_CONNECT,
+	NL80211_CMD_ROAM,
+	NL80211_CMD_DISCONNECT,
+
 	/* add new commands above here */
 
 	/* used to define NL80211_CMD_MAX below */
@@ -511,6 +531,14 @@ enum nl80211_commands {
  *	authorized by user space. Otherwise, port is marked authorized by
  *	default in station mode.
  *
+ * @NL80211_ATTR_DISCONNECTED_BY_AP: A flag indicating that the DISCONNECT
+ *	event was due to the AP disconnecting the station, and not due to
+ *	a local disconnect request.
+ * @NL80211_ATTR_STATUS_CODE: StatusCode for the %NL80211_CMD_CONNECT
+ *	event (u16)
+ * @NL80211_ATTR_PRIVACY: Flag attribute, used with connect(), indicating
+ *	that protected APs should be used.
+ *
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
  */
@@ -618,6 +646,10 @@ enum nl80211_attrs {
 	NL80211_ATTR_STA_FLAGS2,
 
 	NL80211_ATTR_CONTROL_PORT,
+	NL80211_ATTR_PRIVACY,
+
+	NL80211_ATTR_DISCONNECTED_BY_AP,
+	NL80211_ATTR_STATUS_CODE,
 
 	/* add attributes here, update the policy in nl80211.c */
 
--- wireless-testing.orig/include/net/cfg80211.h	2009-06-24 13:54:05.000000000 +0200
+++ wireless-testing/include/net/cfg80211.h	2009-06-24 13:54:05.000000000 +0200
@@ -738,6 +738,39 @@ struct cfg80211_ibss_params {
 };
 
 /**
+ * struct cfg80211_connect_params - Connection parameters
+ *
+ * This structure provides information needed to complete IEEE 802.11
+ * authentication and association.
+ *
+ * @channel: The channel to use or %NULL if not specified (auto-select based
+ *	on scan results)
+ * @bssid: The AP BSSID or %NULL if not specified (auto-select based on scan
+ *	results)
+ * @ssid: SSID
+ * @ssid_len: Length of ssid in octets
+ * @auth_type: Authentication type (algorithm)
+ * @assoc_ie: IEs for association request
+ * @assoc_ie_len: Length of assoc_ie in octets
+ * @control_port: Whether user space controls IEEE 802.1X port, i.e.,
+ *	sets/clears %NL80211_STA_FLAG_AUTHORIZED. If true, the driver is
+ *	required to assume that the port is unauthorized until authorized by
+ *	user space. Otherwise, port is marked authorized by default.
+ * @privacy: indicates whether privacy-enabled APs should be used
+ */
+struct cfg80211_connect_params {
+	struct ieee80211_channel *channel;
+	u8 *bssid;
+	u8 *ssid;
+	size_t ssid_len;
+	enum nl80211_auth_type auth_type;
+	u8 *ie;
+	size_t ie_len;
+	bool control_port;
+	bool privacy;
+};
+
+/**
  * enum wiphy_params_flags - set_wiphy_params bitfield values
  * WIPHY_PARAM_RETRY_SHORT: wiphy->retry_short has changed
  * WIPHY_PARAM_RETRY_LONG: wiphy->retry_long has changed
@@ -841,6 +874,12 @@ enum tx_power_setting {
  * @deauth: Request to deauthenticate from the specified peer
  * @disassoc: Request to disassociate from the specified peer
  *
+ * @connect: Connect to the ESS with the specified parameters. When connected,
+ *	call cfg80211_connect_result() with status code %WLAN_STATUS_SUCCESS.
+ *	If the connection fails for some reason, call cfg80211_connect_result()
+ *	with the status from the AP.
+ * @disconnect: Disconnect from the BSS/ESS.
+ *
  * @join_ibss: Join the specified IBSS (or create if necessary). Once done, call
  *	cfg80211_ibss_joined(), also call that function when changing BSSID due
  *	to a merge.
@@ -944,6 +983,11 @@ struct cfg80211_ops {
 	int	(*disassoc)(struct wiphy *wiphy, struct net_device *dev,
 			    struct cfg80211_disassoc_request *req);
 
+	int	(*connect)(struct wiphy *wiphy, struct net_device *dev,
+			   struct cfg80211_connect_params *sme);
+	int	(*disconnect)(struct wiphy *wiphy, struct net_device *dev,
+			      u16 reason_code);
+
 	int	(*join_ibss)(struct wiphy *wiphy, struct net_device *dev,
 			     struct cfg80211_ibss_params *params);
 	int	(*leave_ibss)(struct wiphy *wiphy, struct net_device *dev);
@@ -1168,10 +1212,15 @@ struct wireless_dev {
 	struct list_head list;
 	struct net_device *netdev;
 
-	/* currently used for IBSS - might be rearranged in the future */
+	/* currently used for IBSS and SME - might be rearranged later */
 	struct cfg80211_bss *current_bss;
 	u8 ssid[IEEE80211_MAX_SSID_LEN];
 	u8 ssid_len;
+	enum {
+		CFG80211_SME_IDLE,
+		CFG80211_SME_CONNECTING, /* ->connect called */
+		CFG80211_SME_CONNECTED,
+	} sme_state;
 
 #ifdef CONFIG_WIRELESS_EXT
 	/* wext data */
@@ -1705,4 +1754,53 @@ void wiphy_rfkill_start_polling(struct w
  */
 void wiphy_rfkill_stop_polling(struct wiphy *wiphy);
 
+/**
+ * cfg80211_connect_result - notify cfg80211 of connection result
+ *
+ * @dev: network device
+ * @bssid: the BSSID of the AP
+ * @ie: association response IEs (may be %NULL)
+ * @ie_len: assoc response IEs length
+ * @status: status code, 0 for successful connection, use
+ *	%WLAN_STATUS_UNSPECIFIED_FAILURE if your device cannot give you
+ *	the real status code for failures.
+ * @gfp: allocation flags
+ *
+ * It should be called by the underlying driver whenever connect() has
+ * succeeded.
+ */
+void cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
+			     u8 *ie, size_t ie_len, u16 status, gfp_t gfp);
+
+/**
+ * cfg80211_roamed - notify cfg80211 of roaming
+ *
+ * @dev: network device
+ * @bssid: the BSSID of the new AP
+ * @ie: association response IEs (may be %NULL)
+ * @ie_len: assoc response IEs length
+ * @gfp: allocation flags
+ *
+ * It should be called by the underlying driver whenever it roamed
+ * from one AP to another while connected.
+ */
+void cfg80211_roamed(struct net_device *dev, const u8 *bssid,
+		     u8 *ie, size_t ie_len, gfp_t gfp);
+
+/**
+ * cfg80211_disconnected - notify cfg80211 that connection was dropped
+ *
+ * @dev: network device
+ * @ie: information elements of the deauth/disassoc frame (may be %NULL)
+ * @ie_len: length of IEs
+ * @reason: reason code for the disconnection, set it to 0 if unknown
+ * @gfp: allocation flags
+ *
+ * After it calls this function, the driver should enter an idle state
+ * and not try to connect to any AP any more.
+ */
+void cfg80211_disconnected(struct net_device *dev, u16 reason,
+			   u8 *ie, size_t ie_len, gfp_t gfp);
+
+
 #endif /* __NET_CFG80211_H */
--- wireless-testing.orig/net/wireless/Makefile	2009-06-24 13:53:14.000000000 +0200
+++ wireless-testing/net/wireless/Makefile	2009-06-24 13:54:05.000000000 +0200
@@ -5,7 +5,7 @@ obj-$(CONFIG_LIB80211_CRYPT_WEP) += lib8
 obj-$(CONFIG_LIB80211_CRYPT_CCMP) += lib80211_crypt_ccmp.o
 obj-$(CONFIG_LIB80211_CRYPT_TKIP) += lib80211_crypt_tkip.o
 
-cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o mlme.o ibss.o
+cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o mlme.o ibss.o sme.o
 cfg80211-$(CONFIG_CFG80211_DEBUGFS) += debugfs.o
 cfg80211-$(CONFIG_WIRELESS_EXT) += wext-compat.o
 
--- wireless-testing.orig/net/wireless/core.h	2009-06-24 13:53:14.000000000 +0200
+++ wireless-testing/net/wireless/core.h	2009-06-24 13:54:05.000000000 +0200
@@ -170,6 +170,13 @@ void cfg80211_clear_ibss(struct net_devi
 int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
 			struct net_device *dev, bool nowext);
 
+/* SME */
+int cfg80211_connect(struct cfg80211_registered_device *rdev,
+		     struct net_device *dev,
+		     struct cfg80211_connect_params *connect);
+int cfg80211_disconnect(struct cfg80211_registered_device *rdev,
+			struct net_device *dev, u16 reason);
+
 /* internal helpers */
 int cfg80211_validate_key_settings(struct key_params *params, int key_idx,
 				   const u8 *mac_addr);
--- wireless-testing.orig/net/wireless/nl80211.c	2009-06-24 13:54:04.000000000 +0200
+++ wireless-testing/net/wireless/nl80211.c	2009-06-24 13:54:05.000000000 +0200
@@ -128,6 +128,7 @@ static struct nla_policy nl80211_policy[
 		.len = sizeof(struct nl80211_sta_flag_update),
 	},
 	[NL80211_ATTR_CONTROL_PORT] = { .type = NLA_FLAG },
+	[NL80211_ATTR_PRIVACY] = { .type = NLA_FLAG },
 };
 
 /* IE validation */
@@ -347,6 +348,17 @@ static int nl80211_send_wiphy(struct sk_
 	CMD(join_ibss, JOIN_IBSS);
 
 #undef CMD
+
+	if (dev->ops->connect) {
+		i++;
+		NLA_PUT_U32(msg, i, NL80211_CMD_CONNECT);
+	}
+
+	if (dev->ops->disconnect) {
+		i++;
+		NLA_PUT_U32(msg, i, NL80211_CMD_DISCONNECT);
+	}
+
 	nla_nest_end(msg, nl_cmds);
 
 	return genlmsg_end(msg, hdr);
@@ -3415,6 +3427,129 @@ unlock_rtnl:
 	return err;
 }
 
+static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
+{
+	struct cfg80211_registered_device *drv;
+	struct net_device *dev;
+	struct cfg80211_connect_params connect;
+	struct wiphy *wiphy;
+	int err;
+
+	memset(&connect, 0, sizeof(connect));
+
+	if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
+		return -EINVAL;
+
+	if (!info->attrs[NL80211_ATTR_SSID] ||
+	    !nla_len(info->attrs[NL80211_ATTR_SSID]))
+		return -EINVAL;
+
+	rtnl_lock();
+
+	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	if (err)
+		goto unlock_rtnl;
+
+	if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) {
+		err = -EOPNOTSUPP;
+		goto out;
+	}
+
+	if (!netif_running(dev)) {
+		err = -ENETDOWN;
+		goto out;
+	}
+
+	wiphy = &drv->wiphy;
+
+	connect.bssid = NULL;
+	connect.channel = NULL;
+	connect.auth_type = NL80211_AUTHTYPE_OPEN_SYSTEM;
+
+	if (info->attrs[NL80211_ATTR_MAC])
+		connect.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
+	connect.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
+	connect.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
+
+	if (info->attrs[NL80211_ATTR_IE]) {
+		connect.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
+		connect.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
+	}
+
+	if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
+		connect.channel =
+			ieee80211_get_channel(wiphy,
+			    nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
+		if (!connect.channel ||
+		    connect.channel->flags & IEEE80211_CHAN_DISABLED) {
+			err = -EINVAL;
+			goto out;
+		}
+	}
+
+	if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
+		connect.auth_type =
+			nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
+		if (!nl80211_valid_auth_type(connect.auth_type)) {
+			err = -EINVAL;
+			goto out;
+		}
+	}
+
+	connect.control_port = info->attrs[NL80211_ATTR_CONTROL_PORT];
+	connect.privacy = info->attrs[NL80211_ATTR_PRIVACY];
+
+	err = cfg80211_connect(drv, dev, &connect);
+
+out:
+	cfg80211_put_dev(drv);
+	dev_put(dev);
+unlock_rtnl:
+	rtnl_unlock();
+	return err;
+}
+
+static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info)
+{
+	struct cfg80211_registered_device *drv;
+	struct net_device *dev;
+	int err;
+	u16 reason;
+
+	if (!info->attrs[NL80211_ATTR_REASON_CODE])
+		reason = WLAN_REASON_DEAUTH_LEAVING;
+	else
+		reason = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
+
+	if (reason == 0)
+		return -EINVAL;
+
+	rtnl_lock();
+
+	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	if (err)
+		goto unlock_rtnl;
+
+	if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) {
+		err = -EOPNOTSUPP;
+		goto out;
+	}
+
+	if (!netif_running(dev)) {
+		err = -ENETDOWN;
+		goto out;
+	}
+
+	err = cfg80211_disconnect(drv, dev, reason);
+
+out:
+	cfg80211_put_dev(drv);
+	dev_put(dev);
+unlock_rtnl:
+	rtnl_unlock();
+	return err;
+}
+
 static struct genl_ops nl80211_ops[] = {
 	{
 		.cmd = NL80211_CMD_GET_WIPHY,
@@ -3628,6 +3763,18 @@ static struct genl_ops nl80211_ops[] = {
 		.policy = nl80211_policy,
 		.flags = GENL_ADMIN_PERM,
 	},
+	{
+		.cmd = NL80211_CMD_CONNECT,
+		.doit = nl80211_connect,
+		.policy = nl80211_policy,
+		.flags = GENL_ADMIN_PERM,
+	},
+	{
+		.cmd = NL80211_CMD_DISCONNECT,
+		.doit = nl80211_disconnect,
+		.policy = nl80211_policy,
+		.flags = GENL_ADMIN_PERM,
+	},
 };
 static struct genl_multicast_group nl80211_mlme_mcgrp = {
 	.name = "mlme",
@@ -3946,6 +4093,123 @@ void nl80211_send_assoc_timeout(struct c
 				  addr, gfp);
 }
 
+void nl80211_send_connect_result(struct cfg80211_registered_device *rdev,
+				 struct net_device *netdev, const u8 *bssid,
+				 const u8 *ie, size_t ie_len, u16 status,
+				 gfp_t gfp)
+{
+	struct sk_buff *msg;
+	void *hdr;
+
+	msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
+	if (!msg)
+		return;
+
+	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONNECT);
+	if (!hdr) {
+		nlmsg_free(msg);
+		return;
+	}
+
+	NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
+	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
+	if (bssid)
+		NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid);
+	NLA_PUT_U16(msg, NL80211_ATTR_STATUS_CODE, status);
+	if (ie)
+		NLA_PUT(msg, NL80211_ATTR_IE, ie_len, ie);
+
+	if (genlmsg_end(msg, hdr) < 0) {
+		nlmsg_free(msg);
+		return;
+	}
+
+	genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp);
+	return;
+
+ nla_put_failure:
+	genlmsg_cancel(msg, hdr);
+	nlmsg_free(msg);
+
+}
+
+void nl80211_send_roamed(struct cfg80211_registered_device *rdev,
+			 struct net_device *netdev, const u8 *bssid,
+			 const u8 *ie, size_t ie_len, gfp_t gfp)
+{
+	struct sk_buff *msg;
+	void *hdr;
+
+	msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
+	if (!msg)
+		return;
+
+	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_ROAM);
+	if (!hdr) {
+		nlmsg_free(msg);
+		return;
+	}
+
+	NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
+	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
+	NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid);
+	if (ie)
+		NLA_PUT(msg, NL80211_ATTR_IE, ie_len, ie);
+
+	if (genlmsg_end(msg, hdr) < 0) {
+		nlmsg_free(msg);
+		return;
+	}
+
+	genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp);
+	return;
+
+ nla_put_failure:
+	genlmsg_cancel(msg, hdr);
+	nlmsg_free(msg);
+
+}
+
+void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
+			       struct net_device *netdev, u16 reason,
+			       u8 *ie, size_t ie_len, bool from_ap, gfp_t gfp)
+{
+	struct sk_buff *msg;
+	void *hdr;
+
+	msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
+	if (!msg)
+		return;
+
+	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_DISCONNECT);
+	if (!hdr) {
+		nlmsg_free(msg);
+		return;
+	}
+
+	NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
+	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
+	if (from_ap && reason)
+		NLA_PUT_U16(msg, NL80211_ATTR_REASON_CODE, reason);
+	if (from_ap)
+		NLA_PUT_FLAG(msg, NL80211_ATTR_DISCONNECTED_BY_AP);
+	if (ie)
+		NLA_PUT(msg, NL80211_ATTR_IE, ie_len, ie);
+
+	if (genlmsg_end(msg, hdr) < 0) {
+		nlmsg_free(msg);
+		return;
+	}
+
+	genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp);
+	return;
+
+ nla_put_failure:
+	genlmsg_cancel(msg, hdr);
+	nlmsg_free(msg);
+
+}
+
 void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
 			     struct net_device *netdev, const u8 *bssid,
 			     gfp_t gfp)
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ wireless-testing/net/wireless/sme.c	2009-06-24 13:54:05.000000000 +0200
@@ -0,0 +1,206 @@
+/*
+ * SME code for cfg80211's connect emulation.
+ *
+ * Copyright 2009	Johannes Berg <johannes@sipsolutions.net>
+ * Copyright (C) 2009   Intel Corporation. All rights reserved.
+ */
+
+#include <linux/etherdevice.h>
+#include <linux/if_arp.h>
+#include <linux/workqueue.h>
+#include <net/cfg80211.h>
+#include <net/rtnetlink.h>
+#include "nl80211.h"
+
+
+void cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
+			     u8 *ie, size_t ie_len, u16 status, gfp_t gfp)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_bss *bss;
+#ifdef CONFIG_WIRELESS_EXT
+	union iwreq_data wrqu;
+#endif
+
+	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION))
+		return;
+
+	if (WARN_ON(wdev->sme_state != CFG80211_SME_CONNECTING))
+		return;
+
+	if (wdev->current_bss) {
+		cfg80211_unhold_bss(wdev->current_bss);
+		cfg80211_put_bss(wdev->current_bss);
+		wdev->current_bss = NULL;
+	}
+
+	if (status == WLAN_STATUS_SUCCESS) {
+		bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid,
+				       wdev->ssid, wdev->ssid_len,
+				       WLAN_CAPABILITY_ESS,
+				       WLAN_CAPABILITY_ESS);
+
+		if (WARN_ON(!bss))
+			return;
+
+		cfg80211_hold_bss(bss);
+		wdev->current_bss = bss;
+
+		wdev->sme_state = CFG80211_SME_CONNECTED;
+	} else {
+		wdev->sme_state = CFG80211_SME_IDLE;
+	}
+
+	nl80211_send_connect_result(wiphy_to_dev(wdev->wiphy), dev, bssid,
+				    ie, ie_len, status, gfp);
+
+#ifdef CONFIG_WIRELESS_EXT
+	if (ie && status == WLAN_STATUS_SUCCESS) {
+		memset(&wrqu, 0, sizeof(wrqu));
+		wrqu.data.length = ie_len;
+		wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu, ie);
+	}
+
+	memset(&wrqu, 0, sizeof(wrqu));
+	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+	if (bssid)
+		memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN);
+	wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
+#endif
+}
+EXPORT_SYMBOL(cfg80211_connect_result);
+
+void cfg80211_roamed(struct net_device *dev, const u8 *bssid,
+		     u8 *ie, size_t ie_len, gfp_t gfp)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_bss *bss;
+#ifdef CONFIG_WIRELESS_EXT
+	union iwreq_data wrqu;
+#endif
+
+	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION))
+		return;
+
+	if (WARN_ON(wdev->sme_state != CFG80211_SME_CONNECTED))
+		return;
+
+	/* internal error -- how did we get to CONNECTED w/o BSS? */
+	if (WARN_ON(!wdev->current_bss)) {
+		return;
+	}
+
+	cfg80211_unhold_bss(wdev->current_bss);
+	cfg80211_put_bss(wdev->current_bss);
+	wdev->current_bss = NULL;
+
+	bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid,
+			       wdev->ssid, wdev->ssid_len,
+			       WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
+
+	if (WARN_ON(!bss))
+		return;
+
+	cfg80211_hold_bss(bss);
+	wdev->current_bss = bss;
+
+	nl80211_send_roamed(wiphy_to_dev(wdev->wiphy), dev, bssid,
+			    ie, ie_len, gfp);
+
+#ifdef CONFIG_WIRELESS_EXT
+	if (ie) {
+		memset(&wrqu, 0, sizeof(wrqu));
+		wrqu.data.length = ie_len;
+		wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu, ie);
+	}
+
+	memset(&wrqu, 0, sizeof(wrqu));
+	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+	memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN);
+	wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
+#endif
+}
+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)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+#ifdef CONFIG_WIRELESS_EXT
+	union iwreq_data wrqu;
+#endif
+
+	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION))
+		return;
+
+	if (WARN_ON(wdev->sme_state != CFG80211_SME_CONNECTED))
+		return;
+
+	if (wdev->current_bss) {
+		cfg80211_unhold_bss(wdev->current_bss);
+		cfg80211_put_bss(wdev->current_bss);
+	}
+
+	wdev->current_bss = NULL;
+	wdev->sme_state = CFG80211_SME_IDLE;
+
+	nl80211_send_disconnected(wiphy_to_dev(wdev->wiphy), dev,
+				  reason, ie, ie_len, from_ap, gfp);
+
+#ifdef CONFIG_WIRELESS_EXT
+	memset(&wrqu, 0, sizeof(wrqu));
+	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+	wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
+#endif
+}
+
+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);
+}
+EXPORT_SYMBOL(cfg80211_disconnected);
+
+int cfg80211_connect(struct cfg80211_registered_device *rdev,
+		     struct net_device *dev,
+		     struct cfg80211_connect_params *connect)
+{
+	int err;
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+	if (wdev->sme_state != CFG80211_SME_IDLE)
+		return -EALREADY;
+
+	if (!rdev->ops->connect) {
+		return -EOPNOTSUPP;
+	} else {
+		err = rdev->ops->connect(&rdev->wiphy, dev, connect);
+		if (err)
+			return err;
+		wdev->sme_state = CFG80211_SME_CONNECTING;
+	}
+
+	memcpy(wdev->ssid, connect->ssid, connect->ssid_len);
+	wdev->ssid_len = connect->ssid_len;
+
+	return 0;
+}
+
+int cfg80211_disconnect(struct cfg80211_registered_device *rdev,
+			struct net_device *dev, u16 reason)
+{
+	int err;
+
+	if (!rdev->ops->disconnect) {
+		return -EOPNOTSUPP;
+	} else {
+		err = rdev->ops->disconnect(&rdev->wiphy, dev, reason);
+		if (err)
+			return err;
+	}
+
+	__cfg80211_disconnected(dev, 0, NULL, 0, false, GFP_KERNEL);
+
+	return 0;
+}
--- wireless-testing.orig/net/wireless/core.c	2009-06-24 13:54:04.000000000 +0200
+++ wireless-testing/net/wireless/core.c	2009-06-24 13:54:05.000000000 +0200
@@ -546,6 +546,7 @@ static int cfg80211_netdev_notifier_call
 				"symlink to netdev!\n");
 		}
 		wdev->netdev = dev;
+		wdev->sme_state = CFG80211_SME_IDLE;
 #ifdef CONFIG_WIRELESS_EXT
 		wdev->wext.default_key = -1;
 		wdev->wext.default_mgmt_key = -1;
@@ -553,11 +554,20 @@ static int cfg80211_netdev_notifier_call
 		mutex_unlock(&rdev->devlist_mtx);
 		break;
 	case NETDEV_GOING_DOWN:
-		if (wdev->iftype != NL80211_IFTYPE_ADHOC)
-			break;
 		if (!wdev->ssid_len)
 			break;
-		cfg80211_leave_ibss(rdev, dev, true);
+
+		switch (wdev->iftype) {
+		case NL80211_IFTYPE_ADHOC:
+			cfg80211_leave_ibss(rdev, dev, true);
+			break;
+		case NL80211_IFTYPE_STATION:
+			cfg80211_disconnect(rdev, dev,
+					    WLAN_REASON_DEAUTH_LEAVING);
+			break;
+		default:
+			break;
+		}
 		break;
 	case NETDEV_UP:
 #ifdef CONFIG_WIRELESS_EXT
--- wireless-testing.orig/net/wireless/nl80211.h	2009-06-24 13:54:04.000000000 +0200
+++ wireless-testing/net/wireless/nl80211.h	2009-06-24 13:54:05.000000000 +0200
@@ -31,6 +31,17 @@ void nl80211_send_auth_timeout(struct cf
 void nl80211_send_assoc_timeout(struct cfg80211_registered_device *rdev,
 				struct net_device *netdev,
 				const u8 *addr, gfp_t gfp);
+void nl80211_send_connect_result(struct cfg80211_registered_device *rdev,
+				 struct net_device *netdev, const u8 *bssid,
+				 const u8 *ie, size_t ie_len, u16 status,
+				 gfp_t gfp);
+void nl80211_send_roamed(struct cfg80211_registered_device *rdev,
+			 struct net_device *netdev, const u8 *bssid,
+			 const u8 *ie, size_t ie_len, gfp_t gfp);
+void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
+			       struct net_device *netdev, u16 reason,
+			       u8 *ie, size_t ie_len, bool from_ap, gfp_t gfp);
+
 void
 nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
 			    struct net_device *netdev, const u8 *addr,

-- 


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

* [RFC 02/11] cfg80211: emulate connect with auth/assoc
  2009-06-24 12:07 [RFC 00/11] cfg80211 connect API + wireless extension move Johannes Berg
  2009-06-24 12:07 ` [RFC 01/11] cfg80211: connect/disconnect API Johannes Berg
@ 2009-06-24 12:07 ` Johannes Berg
  2009-06-24 12:07 ` [RFC 03/11] cfg80211: managed mode wext compatibility Johannes Berg
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: Johannes Berg @ 2009-06-24 12:07 UTC (permalink / raw)
  To: linux-wireless

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>
---
 include/net/cfg80211.h |   17 ++
 net/wireless/core.c    |    3 
 net/wireless/core.h    |    7 +
 net/wireless/mlme.c    |   94 ++++++++++++---
 net/wireless/nl80211.c |    4 
 net/wireless/scan.c    |    7 +
 net/wireless/sme.c     |  299 ++++++++++++++++++++++++++++++++++++++++++++++---
 7 files changed, 399 insertions(+), 32 deletions(-)

--- wireless-testing.orig/net/wireless/core.h	2009-06-24 13:54:05.000000000 +0200
+++ wireless-testing/net/wireless/core.h	2009-06-24 13:54:06.000000000 +0200
@@ -58,6 +58,8 @@ struct cfg80211_registered_device {
 	struct cfg80211_scan_request *scan_req; /* protected by RTNL */
 	unsigned long suspend_at;
 
+	struct work_struct conn_work;
+
 #ifdef CONFIG_CFG80211_DEBUGFS
 	/* Debugfs entries */
 	struct wiphy_debugfsdentries {
@@ -177,8 +179,13 @@ 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);
 
 #endif /* __NET_WIRELESS_CORE_H */
--- wireless-testing.orig/net/wireless/nl80211.c	2009-06-24 13:54:05.000000000 +0200
+++ wireless-testing/net/wireless/nl80211.c	2009-06-24 13:54:06.000000000 +0200
@@ -349,12 +349,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-06-24 13:54:05.000000000 +0200
+++ wireless-testing/net/wireless/sme.c	2009-06-24 13:54:06.000000000 +0200
@@ -12,6 +12,198 @@
 #include <net/rtnetlink.h>
 #include "nl80211.h"
 
+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);
+	int err;
+	union {
+		struct cfg80211_auth_request auth_req;
+		struct cfg80211_assoc_request assoc_req;
+	} u;
+
+	memset(&u, 0, sizeof(u));
+
+	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;
+		err = drv->ops->auth(wdev->wiphy, wdev->netdev, &u.auth_req);
+		if (!err)
+			wdev->conn.state = CFG80211_CONN_AUTHENTICATING;
+		return err;
+	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;
+		u.assoc_req.control_port = wdev->conn.params.control_port;
+		err = drv->ops->assoc(wdev->wiphy, wdev->netdev,
+				      &u.assoc_req);
+		if (!err)
+			wdev->conn.state = CFG80211_CONN_ASSOCIATING;
+		return err;
+	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,
+						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 (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,
+						WLAN_STATUS_UNSPECIFIED_FAILURE,
+						GFP_ATOMIC);
+		return;
+	}
+}
 
 void cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
 			     u8 *ie, size_t ie_len, u16 status, gfp_t gfp)
@@ -63,7 +255,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
@@ -122,9 +314,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
@@ -145,6 +336,9 @@ static void __cfg80211_disconnected(stru
 	wdev->current_bss = NULL;
 	wdev->sme_state = CFG80211_SME_IDLE;
 
+	kfree(wdev->conn.ie);
+	wdev->conn.ie = NULL;
+
 	nl80211_send_disconnected(wiphy_to_dev(wdev->wiphy), dev,
 				  reason, ie, ie_len, from_ap, gfp);
 
@@ -158,7 +352,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);
 
@@ -173,34 +367,113 @@ int cfg80211_connect(struct cfg80211_reg
 		return -EALREADY;
 
 	if (!rdev->ops->connect) {
-		return -EOPNOTSUPP;
+		if (!rdev->ops->auth || !rdev->ops->assoc)
+			return -EOPNOTSUPP;
+
+		/*
+		 * Keep the 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;
+		}
+
+		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);
+
+		/* 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_CONNECTING;
+
+		return err;
 	} else {
 		err = rdev->ops->connect(&rdev->wiphy, dev, connect);
 		if (err)
 			return err;
-		wdev->sme_state = CFG80211_SME_CONNECTING;
-	}
 
-	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];
+
+		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,
+					WLAN_STATUS_UNSPECIFIED_FAILURE,
+					GFP_KERNEL);
 
 	return 0;
 }
--- wireless-testing.orig/net/wireless/mlme.c	2009-06-24 13:54:04.000000000 +0200
+++ wireless-testing/net/wireless/mlme.c	2009-06-24 13:54:06.000000000 +0200
@@ -14,51 +14,110 @@
 
 void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len, gfp_t gfp)
 {
-	struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
+	u16 status_code;
+	struct ieee80211_mgmt *mgmt;
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct wiphy *wiphy = wdev->wiphy;
 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+
+	mgmt = (struct ieee80211_mgmt *)buf;
+	status_code = le16_to_cpu(mgmt->u.auth.status_code);
+
 	nl80211_send_rx_auth(rdev, dev, buf, len, gfp);
+
+	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);
+	}
 }
 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);
+
+	if (wdev->sme_state == CFG80211_SME_CONNECTING)
+		cfg80211_connect_result(dev, mgmt->bssid, ie, len - ieoffs,
+					status_code, gfp);
+	if (status_code != WLAN_STATUS_SUCCESS) {
+		/* XXX: try other auth algs? */
+	}
 }
 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);
+	} else if (wdev->sme_state == CFG80211_SME_CONNECTING) {
+		cfg80211_connect_result(dev, mgmt->bssid, 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;
+	u8 *ie = mgmt->u.assoc_resp.variable;
+	int ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
+
 	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.deauth.reason_code);
+
+		from_ap = memcmp(mgmt->da, dev->dev_addr, ETH_ALEN) == 0;
+		__cfg80211_disconnected(dev, gfp, ie, len - ieoffs,
+					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 cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 	nl80211_send_auth_timeout(rdev, dev, addr, gfp);
-	cfg80211_wext_disconnected(dev);
+	if (dev->ieee80211_ptr->sme_state == CFG80211_SME_CONNECTING)
+		cfg80211_connect_result(dev, addr, NULL, 0,
+					WLAN_STATUS_UNSPECIFIED_FAILURE, gfp);
+	dev->ieee80211_ptr->sme_state = CFG80211_SME_IDLE;
 }
 EXPORT_SYMBOL(cfg80211_send_auth_timeout);
 
@@ -67,7 +126,10 @@ void cfg80211_send_assoc_timeout(struct 
 	struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 	nl80211_send_assoc_timeout(rdev, dev, addr, gfp);
-	cfg80211_wext_disconnected(dev);
+	if (dev->ieee80211_ptr->sme_state == CFG80211_SME_CONNECTING)
+		cfg80211_connect_result(dev, addr, NULL, 0,
+					WLAN_STATUS_UNSPECIFIED_FAILURE, gfp);
+	dev->ieee80211_ptr->sme_state = CFG80211_SME_IDLE;
 }
 EXPORT_SYMBOL(cfg80211_send_assoc_timeout);
 
--- wireless-testing.orig/net/wireless/core.c	2009-06-24 13:54:05.000000000 +0200
+++ wireless-testing/net/wireless/core.c	2009-06-24 13:54:06.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
--- wireless-testing.orig/include/net/cfg80211.h	2009-06-24 13:54:05.000000000 +0200
+++ wireless-testing/include/net/cfg80211.h	2009-06-24 13:54:06.000000000 +0200
@@ -1218,9 +1218,24 @@ struct wireless_dev {
 	u8 ssid_len;
 	enum {
 		CFG80211_SME_IDLE,
-		CFG80211_SME_CONNECTING, /* ->connect called */
+		CFG80211_SME_CONNECTING,
 		CFG80211_SME_CONNECTED,
 	} sme_state;
+	struct {
+		struct cfg80211_connect_params params;
+		/* these are sub-states of the _CONNECTING sme_state */
+		enum {
+			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;
+	} conn;
 
 #ifdef CONFIG_WIRELESS_EXT
 	/* wext data */
--- wireless-testing.orig/net/wireless/scan.c	2009-06-24 13:53:13.000000000 +0200
+++ wireless-testing/net/wireless/scan.c	2009-06-24 13:54:06.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	[flat|nested] 20+ messages in thread

* [RFC 03/11] cfg80211: managed mode wext compatibility
  2009-06-24 12:07 [RFC 00/11] cfg80211 connect API + wireless extension move Johannes Berg
  2009-06-24 12:07 ` [RFC 01/11] cfg80211: connect/disconnect API Johannes Berg
  2009-06-24 12:07 ` [RFC 02/11] cfg80211: emulate connect with auth/assoc Johannes Berg
@ 2009-06-24 12:07 ` Johannes Berg
  2009-06-24 12:07 ` [RFC 04/11] cfg80211: implement iwpower Johannes Berg
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: Johannes Berg @ 2009-06-24 12:07 UTC (permalink / raw)
  To: linux-wireless

This adds code to make it possible to use the cfg80211
connect() API with wireless extensions, and because the
previous patch added emulation of that API with auth()
and assoc(), by extension also supports wext on that.
At the same time, removes code from mac80211 for wext,
but doesn't yet clean up mac80211's mlme code more.

Signed-off-by: Samuel Ortiz <samuel.ortiz@intel.com>
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
 include/net/cfg80211.h     |   36 ++++-
 net/mac80211/mlme.c        |   69 ---------
 net/mac80211/wext.c        |  206 ++--------------------------
 net/wireless/Makefile      |    2 
 net/wireless/core.c        |   22 ++-
 net/wireless/core.h        |    3 
 net/wireless/nl80211.c     |    2 
 net/wireless/sme.c         |   45 +++---
 net/wireless/wext-compat.c |   90 ++++++------
 net/wireless/wext-sme.c    |  322 +++++++++++++++++++++++++++++++++++++++++++++
 10 files changed, 470 insertions(+), 327 deletions(-)

--- wireless-testing.orig/include/net/cfg80211.h	2009-06-24 13:54:06.000000000 +0200
+++ wireless-testing/include/net/cfg80211.h	2009-06-24 13:54:06.000000000 +0200
@@ -1240,8 +1240,14 @@ struct wireless_dev {
 #ifdef CONFIG_WIRELESS_EXT
 	/* wext data */
 	struct {
-		struct cfg80211_ibss_params ibss;
+		union {
+			struct cfg80211_ibss_params ibss;
+			struct cfg80211_connect_params connect;
+		};
+		u8 *ie;
+		size_t ie_len;
 		u8 bssid[ETH_ALEN];
+		u8 ssid[IEEE80211_MAX_SSID_LEN];
 		s8 default_key, default_mgmt_key;
 	} wext;
 #endif
@@ -1522,6 +1528,34 @@ int cfg80211_ibss_wext_giwap(struct net_
 			     struct iw_request_info *info,
 			     struct sockaddr *ap_addr, char *extra);
 
+int cfg80211_mgd_wext_siwfreq(struct net_device *dev,
+			      struct iw_request_info *info,
+			      struct iw_freq *freq, char *extra);
+int cfg80211_mgd_wext_giwfreq(struct net_device *dev,
+			      struct iw_request_info *info,
+			      struct iw_freq *freq, char *extra);
+int cfg80211_mgd_wext_siwessid(struct net_device *dev,
+			       struct iw_request_info *info,
+			       struct iw_point *data, char *ssid);
+int cfg80211_mgd_wext_giwessid(struct net_device *dev,
+			       struct iw_request_info *info,
+			       struct iw_point *data, char *ssid);
+int cfg80211_mgd_wext_siwap(struct net_device *dev,
+			    struct iw_request_info *info,
+			    struct sockaddr *ap_addr, char *extra);
+int cfg80211_mgd_wext_giwap(struct net_device *dev,
+			    struct iw_request_info *info,
+			    struct sockaddr *ap_addr, char *extra);
+int cfg80211_wext_siwgenie(struct net_device *dev,
+			   struct iw_request_info *info,
+			   struct iw_point *data, char *extra);
+int cfg80211_wext_siwauth(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_param *data, char *extra);
+int cfg80211_wext_giwauth(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_param *data, char *extra);
+
 struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy,
 					     struct iw_freq *freq);
 
--- wireless-testing.orig/net/wireless/Makefile	2009-06-24 13:54:05.000000000 +0200
+++ wireless-testing/net/wireless/Makefile	2009-06-24 13:54:06.000000000 +0200
@@ -7,6 +7,6 @@ obj-$(CONFIG_LIB80211_CRYPT_TKIP) += lib
 
 cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o mlme.o ibss.o sme.o
 cfg80211-$(CONFIG_CFG80211_DEBUGFS) += debugfs.o
-cfg80211-$(CONFIG_WIRELESS_EXT) += wext-compat.o
+cfg80211-$(CONFIG_WIRELESS_EXT) += wext-compat.o wext-sme.o
 
 ccflags-y += -D__CHECK_ENDIAN__
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ wireless-testing/net/wireless/wext-sme.c	2009-06-24 13:54:06.000000000 +0200
@@ -0,0 +1,322 @@
+/*
+ * cfg80211 wext compat for managed mode.
+ *
+ * Copyright 2009	Johannes Berg <johannes@sipsolutions.net>
+ * Copyright (C) 2009   Intel Corporation. All rights reserved.
+ */
+
+#include <linux/etherdevice.h>
+#include <linux/if_arp.h>
+#include <net/cfg80211.h>
+#include "nl80211.h"
+
+static int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev,
+				     struct wireless_dev *wdev)
+{
+	int err;
+
+	if (!netif_running(wdev->netdev))
+		return 0;
+
+	wdev->wext.connect.ie = wdev->wext.ie;
+	wdev->wext.connect.ie_len = wdev->wext.ie_len;
+	wdev->wext.connect.privacy = wdev->wext.default_key != -1;
+
+	err = 0;
+	if (wdev->wext.connect.ssid_len != 0)
+		err = cfg80211_connect(rdev, wdev->netdev,
+					&wdev->wext.connect);
+
+	return err;
+}
+
+int cfg80211_mgd_wext_siwfreq(struct net_device *dev,
+			      struct iw_request_info *info,
+			      struct iw_freq *freq, char *extra)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+	struct ieee80211_channel *chan;
+	int err;
+
+	/* call only for station! */
+	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION))
+		return -EINVAL;
+
+	chan = cfg80211_wext_freq(wdev->wiphy, freq);
+	if (chan && IS_ERR(chan))
+		return PTR_ERR(chan);
+
+	if (chan && (chan->flags & IEEE80211_CHAN_DISABLED))
+		return -EINVAL;
+
+	if (wdev->wext.connect.channel == chan)
+		return 0;
+
+	if (wdev->sme_state != CFG80211_SME_IDLE) {
+		bool event = true;
+		/* if SSID set, we'll try right again, avoid event */
+		if (wdev->wext.connect.ssid_len)
+			event = false;
+		err = cfg80211_disconnect(wiphy_to_dev(wdev->wiphy),
+					  dev, WLAN_REASON_DEAUTH_LEAVING,
+					  event);
+		if (err)
+			return err;
+	}
+
+	wdev->wext.connect.channel = chan;
+
+	/* SSID is not set, we just want to switch channel */
+	if (wdev->wext.connect.ssid_len && chan) {
+		if (!rdev->ops->set_channel)
+			return -EOPNOTSUPP;
+
+		return rdev->ops->set_channel(wdev->wiphy, chan,
+					      NL80211_CHAN_NO_HT);
+	}
+
+	return cfg80211_mgd_wext_connect(wiphy_to_dev(wdev->wiphy), wdev);
+}
+/* temporary symbol - mark GPL - in the future the handler won't be */
+EXPORT_SYMBOL_GPL(cfg80211_mgd_wext_siwfreq);
+
+int cfg80211_mgd_wext_giwfreq(struct net_device *dev,
+			      struct iw_request_info *info,
+			      struct iw_freq *freq, char *extra)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct ieee80211_channel *chan = NULL;
+
+	/* call only for station! */
+	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION))
+		return -EINVAL;
+
+	if (wdev->current_bss)
+		chan = wdev->current_bss->channel;
+	else if (wdev->wext.connect.channel)
+		chan = wdev->wext.connect.channel;
+
+	if (chan) {
+		freq->m = chan->center_freq;
+		freq->e = 6;
+		return 0;
+	}
+
+	/* no channel if not joining */
+	return -EINVAL;
+}
+/* temporary symbol - mark GPL - in the future the handler won't be */
+EXPORT_SYMBOL_GPL(cfg80211_mgd_wext_giwfreq);
+
+int cfg80211_mgd_wext_siwessid(struct net_device *dev,
+			       struct iw_request_info *info,
+			       struct iw_point *data, char *ssid)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	size_t len = data->length;
+	int err;
+
+	/* call only for station! */
+	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION))
+		return -EINVAL;
+
+	if (wdev->sme_state != CFG80211_SME_IDLE) {
+		bool event = true;
+		/* if SSID set now, we'll try to connect, avoid event */
+		if (len)
+			event = false;
+		err = cfg80211_disconnect(wiphy_to_dev(wdev->wiphy),
+					  dev, WLAN_REASON_DEAUTH_LEAVING,
+					  event);
+		if (err)
+			return err;
+	}
+
+	/* iwconfig uses nul termination in SSID.. */
+	if (len > 0 && ssid[len - 1] == '\0')
+		len--;
+
+	if (data->flags) {
+		wdev->wext.connect.ssid = wdev->wext.ssid;
+		memcpy(wdev->wext.ssid, ssid, len);
+		wdev->wext.connect.ssid_len = len;
+	} else
+		wdev->wext.connect.ssid_len = 0;
+
+	wdev->wext.connect.control_port = false;
+
+	return cfg80211_mgd_wext_connect(wiphy_to_dev(wdev->wiphy), wdev);
+}
+/* temporary symbol - mark GPL - in the future the handler won't be */
+EXPORT_SYMBOL_GPL(cfg80211_mgd_wext_siwessid);
+
+int cfg80211_mgd_wext_giwessid(struct net_device *dev,
+			       struct iw_request_info *info,
+			       struct iw_point *data, char *ssid)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+	/* call only for station! */
+	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION))
+		return -EINVAL;
+
+	data->flags = 0;
+
+	if (wdev->ssid_len) {
+		data->flags = 1;
+		data->length = wdev->ssid_len;
+		memcpy(ssid, wdev->ssid, data->length);
+	} else if (wdev->wext.connect.ssid && wdev->wext.connect.ssid_len) {
+		data->flags = 1;
+		data->length = wdev->wext.connect.ssid_len;
+		memcpy(ssid, wdev->wext.connect.ssid, data->length);
+	} else
+		data->flags = 0;
+
+	return 0;
+}
+/* temporary symbol - mark GPL - in the future the handler won't be */
+EXPORT_SYMBOL_GPL(cfg80211_mgd_wext_giwessid);
+
+int cfg80211_mgd_wext_siwap(struct net_device *dev,
+			    struct iw_request_info *info,
+			    struct sockaddr *ap_addr, char *extra)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	u8 *bssid = ap_addr->sa_data;
+	int err;
+
+	/* call only for station! */
+	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION))
+		return -EINVAL;
+
+	if (ap_addr->sa_family != ARPHRD_ETHER)
+		return -EINVAL;
+
+	/* automatic mode */
+	if (is_zero_ether_addr(bssid) || is_broadcast_ether_addr(bssid))
+		bssid = NULL;
+
+	/* both automatic */
+	if (!bssid && !wdev->wext.connect.bssid)
+		return 0;
+
+	/* fixed already - and no change */
+	if (wdev->wext.connect.bssid && bssid &&
+	    compare_ether_addr(bssid, wdev->wext.connect.bssid) == 0)
+		return 0;
+
+	if (wdev->sme_state != CFG80211_SME_IDLE) {
+		err = cfg80211_disconnect(wiphy_to_dev(wdev->wiphy),
+					  dev, WLAN_REASON_DEAUTH_LEAVING,
+					  false);
+		if (err)
+			return err;
+	}
+
+	if (bssid) {
+		memcpy(wdev->wext.bssid, bssid, ETH_ALEN);
+		wdev->wext.connect.bssid = wdev->wext.bssid;
+	} else
+		wdev->wext.connect.bssid = NULL;
+
+	return cfg80211_mgd_wext_connect(wiphy_to_dev(wdev->wiphy), wdev);
+}
+/* temporary symbol - mark GPL - in the future the handler won't be */
+EXPORT_SYMBOL_GPL(cfg80211_mgd_wext_siwap);
+
+int cfg80211_mgd_wext_giwap(struct net_device *dev,
+			    struct iw_request_info *info,
+			    struct sockaddr *ap_addr, char *extra)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+	/* call only for station! */
+	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION))
+		return -EINVAL;
+
+	ap_addr->sa_family = ARPHRD_ETHER;
+
+	if (wdev->current_bss)
+		memcpy(ap_addr->sa_data, wdev->current_bss->bssid, ETH_ALEN);
+	else
+		memcpy(ap_addr->sa_data, wdev->wext.connect.bssid, ETH_ALEN);
+
+	return 0;
+}
+/* temporary symbol - mark GPL - in the future the handler won't be */
+EXPORT_SYMBOL_GPL(cfg80211_mgd_wext_giwap);
+
+int cfg80211_wext_siwgenie(struct net_device *dev,
+			   struct iw_request_info *info,
+			   struct iw_point *data, char *extra)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+	u8 *ie = extra;
+	int ie_len = data->length, err;
+
+	if (wdev->iftype != NL80211_IFTYPE_STATION)
+		return -EOPNOTSUPP;
+
+	if (!ie_len)
+		ie = NULL;
+
+	/* no change */
+	if (wdev->wext.ie_len == ie_len &&
+	    memcmp(wdev->wext.ie, ie, ie_len) == 0)
+		return 0;
+
+	if (ie_len) {
+		ie = kmemdup(extra, ie_len, GFP_KERNEL);
+		if (!ie)
+			return -ENOMEM;
+	} else
+		ie = NULL;
+
+	kfree(wdev->wext.ie);
+	wdev->wext.ie = ie;
+	wdev->wext.ie_len = ie_len;
+
+	if (wdev->sme_state != CFG80211_SME_IDLE) {
+		err = cfg80211_disconnect(rdev, dev,
+					  WLAN_REASON_DEAUTH_LEAVING, false);
+		if (err)
+			return err;
+	}
+
+	/* userspace better not think we'll reconnect */
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_siwgenie);
+
+int cfg80211_wext_siwmlme(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_point *data, char *extra)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct iw_mlme *mlme = (struct iw_mlme *)extra;
+	struct cfg80211_registered_device *rdev;
+
+	if (!wdev)
+		return -EOPNOTSUPP;
+
+	rdev = wiphy_to_dev(wdev->wiphy);
+
+	if (wdev->iftype != NL80211_IFTYPE_STATION)
+		return -EINVAL;
+
+	if (mlme->addr.sa_family != ARPHRD_ETHER)
+		return -EINVAL;
+
+	switch (mlme->cmd) {
+	case IW_MLME_DEAUTH:
+	case IW_MLME_DISASSOC:
+		return cfg80211_disconnect(rdev, dev, mlme->reason_code,
+					   true);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_siwmlme);
--- wireless-testing.orig/net/wireless/core.c	2009-06-24 13:54:06.000000000 +0200
+++ wireless-testing/net/wireless/core.c	2009-06-24 13:54:06.000000000 +0200
@@ -565,8 +565,13 @@ static int cfg80211_netdev_notifier_call
 			cfg80211_leave_ibss(rdev, dev, true);
 			break;
 		case NL80211_IFTYPE_STATION:
+#ifdef CONFIG_WIRELESS_EXT
+			kfree(wdev->wext.ie);
+			wdev->wext.ie = NULL;
+			wdev->wext.ie_len = 0;
+#endif
 			cfg80211_disconnect(rdev, dev,
-					    WLAN_REASON_DEAUTH_LEAVING);
+					    WLAN_REASON_DEAUTH_LEAVING, true);
 			break;
 		default:
 			break;
@@ -574,11 +579,20 @@ static int cfg80211_netdev_notifier_call
 		break;
 	case NETDEV_UP:
 #ifdef CONFIG_WIRELESS_EXT
-		if (wdev->iftype != NL80211_IFTYPE_ADHOC)
+		switch (wdev->iftype) {
+		case NL80211_IFTYPE_ADHOC:
+			if (wdev->wext.ibss.ssid_len)
+				cfg80211_join_ibss(rdev, dev,
+						   &wdev->wext.ibss);
+			break;
+		case NL80211_IFTYPE_STATION:
+			if (wdev->wext.connect.ssid_len)
+				cfg80211_connect(rdev, dev,
+						 &wdev->wext.connect);
 			break;
-		if (!wdev->wext.ibss.ssid_len)
+		default:
 			break;
-		cfg80211_join_ibss(rdev, dev, &wdev->wext.ibss);
+		}
 #endif
 		break;
 	case NETDEV_UNREGISTER:
--- wireless-testing.orig/net/mac80211/wext.c	2009-06-24 13:53:13.000000000 +0200
+++ wireless-testing/net/mac80211/wext.c	2009-06-24 13:54:06.000000000 +0200
@@ -27,29 +27,6 @@
 #include "aes_ccm.h"
 
 
-static int ieee80211_ioctl_siwgenie(struct net_device *dev,
-				    struct iw_request_info *info,
-				    struct iw_point *data, char *extra)
-{
-	struct ieee80211_sub_if_data *sdata;
-
-	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-
-	if (sdata->vif.type == NL80211_IFTYPE_STATION) {
-		int ret = ieee80211_sta_set_extra_ie(sdata, extra, data->length);
-		if (ret && ret != -EALREADY)
-			return ret;
-		sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL;
-		sdata->u.mgd.flags &= ~IEEE80211_STA_EXT_SME;
-		sdata->u.mgd.flags &= ~IEEE80211_STA_CONTROL_PORT;
-		if (ret != -EALREADY)
-			ieee80211_sta_req_auth(sdata);
-		return 0;
-	}
-
-	return -EOPNOTSUPP;
-}
-
 static int ieee80211_ioctl_siwfreq(struct net_device *dev,
 				   struct iw_request_info *info,
 				   struct iw_freq *freq, char *extra)
@@ -61,7 +38,7 @@ static int ieee80211_ioctl_siwfreq(struc
 	if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
 		return cfg80211_ibss_wext_siwfreq(dev, info, freq, extra);
 	else if (sdata->vif.type == NL80211_IFTYPE_STATION)
-		sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_CHANNEL_SEL;
+		return cfg80211_mgd_wext_siwfreq(dev, info, freq, extra);
 
 	/* freq->e == 0: freq->m = channel; otherwise freq = m * 10^e */
 	if (freq->e == 0) {
@@ -95,9 +72,6 @@ static int ieee80211_ioctl_siwfreq(struc
 	if (local->oper_channel == chan)
 		return 0;
 
-	if (sdata->vif.type == NL80211_IFTYPE_STATION)
-		ieee80211_sta_req_auth(sdata);
-
 	local->oper_channel = chan;
 	local->oper_channel_type = NL80211_CHAN_NO_HT;
 	ieee80211_hw_config(local, 0);
@@ -115,6 +89,8 @@ static int ieee80211_ioctl_giwfreq(struc
 
 	if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
 		return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra);
+	else if (sdata->vif.type == NL80211_IFTYPE_STATION)
+		return cfg80211_mgd_wext_giwfreq(dev, info, freq, extra);
 
 	freq->m = local->oper_channel->center_freq;
 	freq->e = 6;
@@ -128,31 +104,11 @@ static int ieee80211_ioctl_siwessid(stru
 				    struct iw_point *data, char *ssid)
 {
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-	size_t len = data->length;
-	int ret;
 
 	if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
 		return cfg80211_ibss_wext_siwessid(dev, info, data, ssid);
-
-	/* iwconfig uses nul termination in SSID.. */
-	if (len > 0 && ssid[len - 1] == '\0')
-		len--;
-
-	if (sdata->vif.type == NL80211_IFTYPE_STATION) {
-		if (data->flags)
-			sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_SSID_SEL;
-		else
-			sdata->u.mgd.flags |= IEEE80211_STA_AUTO_SSID_SEL;
-
-		ret = ieee80211_sta_set_ssid(sdata, ssid, len);
-		if (ret)
-			return ret;
-
-		sdata->u.mgd.flags &= ~IEEE80211_STA_EXT_SME;
-		sdata->u.mgd.flags &= ~IEEE80211_STA_CONTROL_PORT;
-		ieee80211_sta_req_auth(sdata);
-		return 0;
-	}
+	else if (sdata->vif.type == NL80211_IFTYPE_STATION)
+		return cfg80211_mgd_wext_siwessid(dev, info, data, ssid);
 
 	return -EOPNOTSUPP;
 }
@@ -162,23 +118,14 @@ static int ieee80211_ioctl_giwessid(stru
 				    struct iw_request_info *info,
 				    struct iw_point *data, char *ssid)
 {
-	size_t len;
 	struct ieee80211_sub_if_data *sdata;
 
 	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
 	if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
 		return cfg80211_ibss_wext_giwessid(dev, info, data, ssid);
-
-	if (sdata->vif.type == NL80211_IFTYPE_STATION) {
-		int res = ieee80211_sta_get_ssid(sdata, ssid, &len);
-		if (res == 0) {
-			data->length = len;
-			data->flags = 1;
-		} else
-			data->flags = 0;
-		return res;
-	}
+	else if (sdata->vif.type == NL80211_IFTYPE_STATION)
+		return cfg80211_mgd_wext_giwessid(dev, info, data, ssid);
 
 	return -EOPNOTSUPP;
 }
@@ -193,24 +140,10 @@ static int ieee80211_ioctl_siwap(struct 
 	if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
 		return cfg80211_ibss_wext_siwap(dev, info, ap_addr, extra);
 
-	if (sdata->vif.type == NL80211_IFTYPE_STATION) {
-		int ret;
+	if (sdata->vif.type == NL80211_IFTYPE_STATION)
+		return cfg80211_mgd_wext_siwap(dev, info, ap_addr, extra);
 
-		if (is_zero_ether_addr((u8 *) &ap_addr->sa_data))
-			sdata->u.mgd.flags |= IEEE80211_STA_AUTO_BSSID_SEL |
-				IEEE80211_STA_AUTO_CHANNEL_SEL;
-		else if (is_broadcast_ether_addr((u8 *) &ap_addr->sa_data))
-			sdata->u.mgd.flags |= IEEE80211_STA_AUTO_BSSID_SEL;
-		else
-			sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL;
-		ret = ieee80211_sta_set_bssid(sdata, (u8 *) &ap_addr->sa_data);
-		if (ret)
-			return ret;
-		sdata->u.mgd.flags &= ~IEEE80211_STA_EXT_SME;
-		sdata->u.mgd.flags &= ~IEEE80211_STA_CONTROL_PORT;
-		ieee80211_sta_req_auth(sdata);
-		return 0;
-	} else if (sdata->vif.type == NL80211_IFTYPE_WDS) {
+	if (sdata->vif.type == NL80211_IFTYPE_WDS) {
 		/*
 		 * If it is necessary to update the WDS peer address
 		 * while the interface is running, then we need to do
@@ -240,14 +173,10 @@ static int ieee80211_ioctl_giwap(struct 
 	if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
 		return cfg80211_ibss_wext_giwap(dev, info, ap_addr, extra);
 
-	if (sdata->vif.type == NL80211_IFTYPE_STATION) {
-		if (sdata->u.mgd.state == IEEE80211_STA_MLME_ASSOCIATED) {
-			ap_addr->sa_family = ARPHRD_ETHER;
-			memcpy(&ap_addr->sa_data, sdata->u.mgd.bssid, ETH_ALEN);
-		} else
-			memset(&ap_addr->sa_data, 0, ETH_ALEN);
-		return 0;
-	} else if (sdata->vif.type == NL80211_IFTYPE_WDS) {
+	if (sdata->vif.type == NL80211_IFTYPE_STATION)
+		return cfg80211_mgd_wext_giwap(dev, info, ap_addr, extra);
+
+	if (sdata->vif.type == NL80211_IFTYPE_WDS) {
 		ap_addr->sa_family = ARPHRD_ETHER;
 		memcpy(&ap_addr->sa_data, sdata->u.wds.remote_addr, ETH_ALEN);
 		return 0;
@@ -395,85 +324,6 @@ static int ieee80211_ioctl_giwpower(stru
 	return 0;
 }
 
-static int ieee80211_ioctl_siwauth(struct net_device *dev,
-				   struct iw_request_info *info,
-				   struct iw_param *data, char *extra)
-{
-	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-	int ret = 0;
-
-	switch (data->flags & IW_AUTH_INDEX) {
-	case IW_AUTH_WPA_VERSION:
-	case IW_AUTH_CIPHER_GROUP:
-	case IW_AUTH_WPA_ENABLED:
-	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
-	case IW_AUTH_KEY_MGMT:
-	case IW_AUTH_CIPHER_GROUP_MGMT:
-		break;
-	case IW_AUTH_CIPHER_PAIRWISE:
-		if (sdata->vif.type == NL80211_IFTYPE_STATION) {
-			if (data->value & (IW_AUTH_CIPHER_WEP40 |
-			    IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_TKIP))
-				sdata->u.mgd.flags |=
-					IEEE80211_STA_TKIP_WEP_USED;
-			else
-				sdata->u.mgd.flags &=
-					~IEEE80211_STA_TKIP_WEP_USED;
-		}
-		break;
-	case IW_AUTH_DROP_UNENCRYPTED:
-		sdata->drop_unencrypted = !!data->value;
-		break;
-	case IW_AUTH_PRIVACY_INVOKED:
-		if (sdata->vif.type != NL80211_IFTYPE_STATION)
-			ret = -EINVAL;
-		else {
-			sdata->u.mgd.flags &= ~IEEE80211_STA_PRIVACY_INVOKED;
-			/*
-			 * Privacy invoked by wpa_supplicant, store the
-			 * value and allow associating to a protected
-			 * network without having a key up front.
-			 */
-			if (data->value)
-				sdata->u.mgd.flags |=
-					IEEE80211_STA_PRIVACY_INVOKED;
-		}
-		break;
-	case IW_AUTH_80211_AUTH_ALG:
-		if (sdata->vif.type == NL80211_IFTYPE_STATION)
-			sdata->u.mgd.auth_algs = data->value;
-		else
-			ret = -EOPNOTSUPP;
-		break;
-	case IW_AUTH_MFP:
-		if (!(sdata->local->hw.flags & IEEE80211_HW_MFP_CAPABLE)) {
-			ret = -EOPNOTSUPP;
-			break;
-		}
-		if (sdata->vif.type == NL80211_IFTYPE_STATION) {
-			switch (data->value) {
-			case IW_AUTH_MFP_DISABLED:
-				sdata->u.mgd.mfp = IEEE80211_MFP_DISABLED;
-				break;
-			case IW_AUTH_MFP_OPTIONAL:
-				sdata->u.mgd.mfp = IEEE80211_MFP_OPTIONAL;
-				break;
-			case IW_AUTH_MFP_REQUIRED:
-				sdata->u.mgd.mfp = IEEE80211_MFP_REQUIRED;
-				break;
-			default:
-				ret = -EINVAL;
-			}
-		} else
-			ret = -EOPNOTSUPP;
-		break;
-	default:
-		ret = -EOPNOTSUPP;
-		break;
-	}
-	return ret;
-}
-
 /* Get wireless statistics.  Called by /proc/net/wireless and by SIOCGIWSTATS */
 static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *dev)
 {
@@ -541,28 +391,6 @@ static struct iw_statistics *ieee80211_g
 	return wstats;
 }
 
-static int ieee80211_ioctl_giwauth(struct net_device *dev,
-				   struct iw_request_info *info,
-				   struct iw_param *data, char *extra)
-{
-	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-	int ret = 0;
-
-	switch (data->flags & IW_AUTH_INDEX) {
-	case IW_AUTH_80211_AUTH_ALG:
-		if (sdata->vif.type == NL80211_IFTYPE_STATION)
-			data->value = sdata->u.mgd.auth_algs;
-		else
-			ret = -EOPNOTSUPP;
-		break;
-	default:
-		ret = -EOPNOTSUPP;
-		break;
-	}
-	return ret;
-}
-
-
 /* Structures to export the Wireless Handlers */
 
 static const iw_handler ieee80211_handler[] =
@@ -615,10 +443,10 @@ static const iw_handler ieee80211_handle
 	(iw_handler) ieee80211_ioctl_giwpower,		/* SIOCGIWPOWER */
 	(iw_handler) NULL,				/* -- hole -- */
 	(iw_handler) NULL,				/* -- hole -- */
-	(iw_handler) ieee80211_ioctl_siwgenie,		/* SIOCSIWGENIE */
+	(iw_handler) cfg80211_wext_siwgenie,		/* SIOCSIWGENIE */
 	(iw_handler) NULL,				/* SIOCGIWGENIE */
-	(iw_handler) ieee80211_ioctl_siwauth,		/* SIOCSIWAUTH */
-	(iw_handler) ieee80211_ioctl_giwauth,		/* SIOCGIWAUTH */
+	(iw_handler) cfg80211_wext_siwauth,		/* SIOCSIWAUTH */
+	(iw_handler) cfg80211_wext_giwauth,		/* SIOCGIWAUTH */
 	(iw_handler) cfg80211_wext_siwencodeext,	/* SIOCSIWENCODEEXT */
 	(iw_handler) NULL,				/* SIOCGIWENCODEEXT */
 	(iw_handler) NULL,				/* SIOCSIWPMKSA */
--- wireless-testing.orig/net/mac80211/mlme.c	2009-06-24 13:54:04.000000000 +0200
+++ wireless-testing/net/mac80211/mlme.c	2009-06-24 13:54:06.000000000 +0200
@@ -870,70 +870,6 @@ static u32 ieee80211_handle_bss_capabili
 	return changed;
 }
 
-static void ieee80211_sta_send_apinfo(struct ieee80211_sub_if_data *sdata)
-{
-	union iwreq_data wrqu;
-
-	memset(&wrqu, 0, sizeof(wrqu));
-	if (sdata->u.mgd.flags & IEEE80211_STA_ASSOCIATED)
-		memcpy(wrqu.ap_addr.sa_data, sdata->u.mgd.bssid, ETH_ALEN);
-	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
-	wireless_send_event(sdata->dev, SIOCGIWAP, &wrqu, NULL);
-}
-
-static void ieee80211_sta_send_associnfo(struct ieee80211_sub_if_data *sdata)
-{
-	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
-	char *buf;
-	size_t len;
-	int i;
-	union iwreq_data wrqu;
-
-	if (!ifmgd->assocreq_ies && !ifmgd->assocresp_ies)
-		return;
-
-	buf = kmalloc(50 + 2 * (ifmgd->assocreq_ies_len +
-				ifmgd->assocresp_ies_len), GFP_KERNEL);
-	if (!buf)
-		return;
-
-	len = sprintf(buf, "ASSOCINFO(");
-	if (ifmgd->assocreq_ies) {
-		len += sprintf(buf + len, "ReqIEs=");
-		for (i = 0; i < ifmgd->assocreq_ies_len; i++) {
-			len += sprintf(buf + len, "%02x",
-				       ifmgd->assocreq_ies[i]);
-		}
-	}
-	if (ifmgd->assocresp_ies) {
-		if (ifmgd->assocreq_ies)
-			len += sprintf(buf + len, " ");
-		len += sprintf(buf + len, "RespIEs=");
-		for (i = 0; i < ifmgd->assocresp_ies_len; i++) {
-			len += sprintf(buf + len, "%02x",
-				       ifmgd->assocresp_ies[i]);
-		}
-	}
-	len += sprintf(buf + len, ")");
-
-	if (len > IW_CUSTOM_MAX) {
-		len = sprintf(buf, "ASSOCRESPIE=");
-		for (i = 0; i < ifmgd->assocresp_ies_len; i++) {
-			len += sprintf(buf + len, "%02x",
-				       ifmgd->assocresp_ies[i]);
-		}
-	}
-
-	if (len <= IW_CUSTOM_MAX) {
-		memset(&wrqu, 0, sizeof(wrqu));
-		wrqu.data.length = len;
-		wireless_send_event(sdata->dev, IWEVCUSTOM, &wrqu, buf);
-	}
-
-	kfree(buf);
-}
-
-
 static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
 				     u32 bss_info_changed)
 {
@@ -966,7 +902,6 @@ static void ieee80211_set_associated(str
 
 	ifmgd->flags |= IEEE80211_STA_PREV_BSSID_SET;
 	memcpy(ifmgd->prev_bssid, sdata->u.mgd.bssid, ETH_ALEN);
-	ieee80211_sta_send_associnfo(sdata);
 
 	ifmgd->last_probe = jiffies;
 	ieee80211_led_assoc(local, 1);
@@ -993,8 +928,6 @@ static void ieee80211_set_associated(str
 
 	netif_tx_start_all_queues(sdata->dev);
 	netif_carrier_on(sdata->dev);
-
-	ieee80211_sta_send_apinfo(sdata);
 }
 
 static void ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata)
@@ -1147,8 +1080,6 @@ static void ieee80211_set_disassoc(struc
 	changed |= BSS_CHANGED_ASSOC;
 	sdata->vif.bss_conf.assoc = false;
 
-	ieee80211_sta_send_apinfo(sdata);
-
 	if (self_disconnected || reason == WLAN_REASON_DISASSOC_STA_HAS_LEFT) {
 		ifmgd->state = IEEE80211_STA_MLME_DISABLED;
 		ieee80211_rx_bss_remove(sdata, ifmgd->bssid,
--- wireless-testing.orig/net/wireless/wext-compat.c	2009-06-24 13:53:13.000000000 +0200
+++ wireless-testing/net/wireless/wext-compat.c	2009-06-24 13:54:06.000000000 +0200
@@ -261,50 +261,6 @@ int cfg80211_wext_giwrange(struct net_de
 }
 EXPORT_SYMBOL_GPL(cfg80211_wext_giwrange);
 
-int cfg80211_wext_siwmlme(struct net_device *dev,
-			  struct iw_request_info *info,
-			  struct iw_point *data, char *extra)
-{
-	struct wireless_dev *wdev = dev->ieee80211_ptr;
-	struct iw_mlme *mlme = (struct iw_mlme *)extra;
-	struct cfg80211_registered_device *rdev;
-	union {
-		struct cfg80211_disassoc_request disassoc;
-		struct cfg80211_deauth_request deauth;
-	} cmd;
-
-	if (!wdev)
-		return -EOPNOTSUPP;
-
-	rdev = wiphy_to_dev(wdev->wiphy);
-
-	if (wdev->iftype != NL80211_IFTYPE_STATION)
-		return -EINVAL;
-
-	if (mlme->addr.sa_family != ARPHRD_ETHER)
-		return -EINVAL;
-
-	memset(&cmd, 0, sizeof(cmd));
-
-	switch (mlme->cmd) {
-	case IW_MLME_DEAUTH:
-		if (!rdev->ops->deauth)
-			return -EOPNOTSUPP;
-		cmd.deauth.peer_addr = mlme->addr.sa_data;
-		cmd.deauth.reason_code = mlme->reason_code;
-		return rdev->ops->deauth(wdev->wiphy, dev, &cmd.deauth);
-	case IW_MLME_DISASSOC:
-		if (!rdev->ops->disassoc)
-			return -EOPNOTSUPP;
-		cmd.disassoc.peer_addr = mlme->addr.sa_data;
-		cmd.disassoc.reason_code = mlme->reason_code;
-		return rdev->ops->disassoc(wdev->wiphy, dev, &cmd.disassoc);
-	default:
-		return -EOPNOTSUPP;
-	}
-}
-EXPORT_SYMBOL_GPL(cfg80211_wext_siwmlme);
-
 
 /**
  * cfg80211_wext_freq - get wext frequency for non-"auto"
@@ -846,3 +802,49 @@ int cfg80211_wext_giwtxpower(struct net_
 	return 0;
 }
 EXPORT_SYMBOL_GPL(cfg80211_wext_giwtxpower);
+
+int cfg80211_wext_siwauth(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_param *data, char *extra)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	int ret;
+
+	if (wdev->iftype != NL80211_IFTYPE_STATION)
+		return -EOPNOTSUPP;
+
+	switch (data->flags & IW_AUTH_INDEX) {
+	case IW_AUTH_PRIVACY_INVOKED:
+		wdev->wext.connect.privacy = data->value;
+		ret = 0;
+		break;
+	case IW_AUTH_WPA_VERSION:
+	case IW_AUTH_CIPHER_GROUP:
+	case IW_AUTH_WPA_ENABLED:
+	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+	case IW_AUTH_KEY_MGMT:
+	case IW_AUTH_CIPHER_GROUP_MGMT:
+	case IW_AUTH_CIPHER_PAIRWISE:
+	case IW_AUTH_DROP_UNENCRYPTED:
+	case IW_AUTH_80211_AUTH_ALG:
+	case IW_AUTH_MFP:
+		ret = 0;
+		break;
+	default:
+		ret = -EOPNOTSUPP;
+		break;
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_siwauth);
+
+int cfg80211_wext_giwauth(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_param *data, char *extra)
+{
+	/* XXX: what do we need? */
+
+	return -EOPNOTSUPP;
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_giwauth);
--- wireless-testing.orig/net/wireless/core.h	2009-06-24 13:54:06.000000000 +0200
+++ wireless-testing/net/wireless/core.h	2009-06-24 13:54:06.000000000 +0200
@@ -177,7 +177,8 @@ int cfg80211_connect(struct cfg80211_reg
 		     struct net_device *dev,
 		     struct cfg80211_connect_params *connect);
 int cfg80211_disconnect(struct cfg80211_registered_device *rdev,
-			struct net_device *dev, u16 reason);
+			struct net_device *dev, u16 reason,
+			bool wextev);
 
 void cfg80211_conn_work(struct work_struct *work);
 
--- wireless-testing.orig/net/wireless/nl80211.c	2009-06-24 13:54:06.000000000 +0200
+++ wireless-testing/net/wireless/nl80211.c	2009-06-24 13:54:06.000000000 +0200
@@ -3540,7 +3540,7 @@ static int nl80211_disconnect(struct sk_
 		goto out;
 	}
 
-	err = cfg80211_disconnect(drv, dev, reason);
+	err = cfg80211_disconnect(drv, dev, reason, true);
 
 out:
 	cfg80211_put_dev(drv);
--- wireless-testing.orig/net/wireless/sme.c	2009-06-24 13:54:06.000000000 +0200
+++ wireless-testing/net/wireless/sme.c	2009-06-24 13:54:06.000000000 +0200
@@ -205,8 +205,9 @@ void cfg80211_sme_scan_done(struct net_d
 	}
 }
 
-void cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
-			     u8 *ie, size_t ie_len, u16 status, gfp_t gfp)
+static void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
+				      u8 *ie, size_t ie_len, u16 status,
+				      bool wextev, gfp_t gfp)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct cfg80211_bss *bss;
@@ -243,23 +244,33 @@ void cfg80211_connect_result(struct net_
 		wdev->sme_state = CFG80211_SME_IDLE;
 	}
 
-	nl80211_send_connect_result(wiphy_to_dev(wdev->wiphy), dev, bssid,
-				    ie, ie_len, status, gfp);
+	nl80211_send_connect_result(wiphy_to_dev(wdev->wiphy), dev,
+				    bssid, ie, ie_len, status, gfp);
 
 #ifdef CONFIG_WIRELESS_EXT
-	if (ie && status == WLAN_STATUS_SUCCESS) {
+	if (wextev) {
+		if (ie && status == WLAN_STATUS_SUCCESS) {
+			memset(&wrqu, 0, sizeof(wrqu));
+			wrqu.data.length = ie_len;
+			wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu, ie);
+			printk(KERN_DEBUG "IWEVASSOCRESPIE EVENT\n");
+		}
+
 		memset(&wrqu, 0, sizeof(wrqu));
-		wrqu.data.length = ie_len;
-		wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu, ie);
+		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);
 	}
-
-	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,
+			     u8 *ie, size_t ie_len, u16 status, gfp_t gfp)
+{
+	bool wextev = status == WLAN_STATUS_SUCCESS;
+	__cfg80211_connect_result(dev, bssid, ie, ie_len, status, wextev, gfp);
+}
 EXPORT_SYMBOL(cfg80211_connect_result);
 
 void cfg80211_roamed(struct net_device *dev, const u8 *bssid,
@@ -430,7 +441,7 @@ int cfg80211_connect(struct cfg80211_reg
 }
 
 int cfg80211_disconnect(struct cfg80211_registered_device *rdev,
-			struct net_device *dev, u16 reason)
+			struct net_device *dev, u16 reason, bool wextev)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	int err;
@@ -471,9 +482,9 @@ int cfg80211_disconnect(struct cfg80211_
 	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,
-					WLAN_STATUS_UNSPECIFIED_FAILURE,
-					GFP_KERNEL);
+		__cfg80211_connect_result(dev, NULL, NULL, 0,
+					  WLAN_STATUS_UNSPECIFIED_FAILURE,
+					  wextev, GFP_KERNEL);
 
 	return 0;
 }

-- 


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

* [RFC 04/11] cfg80211: implement iwpower
  2009-06-24 12:07 [RFC 00/11] cfg80211 connect API + wireless extension move Johannes Berg
                   ` (2 preceding siblings ...)
  2009-06-24 12:07 ` [RFC 03/11] cfg80211: managed mode wext compatibility Johannes Berg
@ 2009-06-24 12:07 ` Johannes Berg
  2009-06-24 12:07 ` [RFC 05/11] cfg80211: implement IWAP for WDS Johannes Berg
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: Johannes Berg @ 2009-06-24 12:07 UTC (permalink / raw)
  To: linux-wireless

Just on/off and timeout, and with a hacky cfg80211 method
until we figure out what we want, though this is probably
sufficient as we want to use pm_qos for wifi everywhere.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
 drivers/net/wireless/iwmc3200wifi/cfg80211.c |   22 ++++++++
 drivers/net/wireless/iwmc3200wifi/wext.c     |   47 ------------------
 include/net/cfg80211.h                       |   13 +++++
 net/mac80211/Kconfig                         |   16 ------
 net/mac80211/cfg.c                           |   26 ++++++++++
 net/mac80211/mlme.c                          |    5 -
 net/mac80211/wext.c                          |   70 ---------------------------
 net/wireless/Kconfig                         |   16 ++++++
 net/wireless/core.c                          |   11 +++-
 net/wireless/wext-compat.c                   |   60 +++++++++++++++++++++++
 10 files changed, 151 insertions(+), 135 deletions(-)

--- wireless-testing.orig/include/net/cfg80211.h	2009-06-24 13:54:06.000000000 +0200
+++ wireless-testing/include/net/cfg80211.h	2009-06-24 13:54:07.000000000 +0200
@@ -999,6 +999,10 @@ struct cfg80211_ops {
 	int	(*get_tx_power)(struct wiphy *wiphy, int *dbm);
 
 	void	(*rfkill_poll)(struct wiphy *wiphy);
+
+	/* some temporary stuff to finish wext */
+	int	(*set_power_mgmt)(struct wiphy *wiphy, struct net_device *dev,
+				  bool enabled, int timeout);
 };
 
 /*
@@ -1249,6 +1253,8 @@ struct wireless_dev {
 		u8 bssid[ETH_ALEN];
 		u8 ssid[IEEE80211_MAX_SSID_LEN];
 		s8 default_key, default_mgmt_key;
+		bool ps;
+		int ps_timeout;
 	} wext;
 #endif
 };
@@ -1593,6 +1599,13 @@ int cfg80211_wext_giwtxpower(struct net_
 			     struct iw_request_info *info,
 			     union iwreq_data *data, char *keybuf);
 
+int cfg80211_wext_siwpower(struct net_device *dev,
+			   struct iw_request_info *info,
+			   struct iw_param *wrq, char *extra);
+int cfg80211_wext_giwpower(struct net_device *dev,
+			   struct iw_request_info *info,
+			   struct iw_param *wrq, char *extra);
+
 /*
  * callbacks for asynchronous cfg80211 methods, notification
  * functions and BSS handling helpers
--- wireless-testing.orig/net/mac80211/Kconfig	2009-06-24 13:53:12.000000000 +0200
+++ wireless-testing/net/mac80211/Kconfig	2009-06-24 13:54:07.000000000 +0200
@@ -14,22 +14,6 @@ config MAC80211
 comment "CFG80211 needs to be enabled for MAC80211"
 	depends on CFG80211=n
 
-config MAC80211_DEFAULT_PS
-	bool "enable powersave by default"
-	depends on MAC80211
-	default y
-	help
-	  This option enables powersave mode by default.
-
-	  If this causes your applications to misbehave you should fix your
-	  applications instead -- they need to register their network
-	  latency requirement, see Documentation/power/pm_qos_interface.txt.
-
-config MAC80211_DEFAULT_PS_VALUE
-	int
-	default 1 if MAC80211_DEFAULT_PS
-	default 0
-
 menu "Rate control algorithm selection"
 	depends on MAC80211 != n
 
--- wireless-testing.orig/net/mac80211/wext.c	2009-06-24 13:54:06.000000000 +0200
+++ wireless-testing/net/mac80211/wext.c	2009-06-24 13:54:07.000000000 +0200
@@ -258,72 +258,6 @@ static int ieee80211_ioctl_giwrate(struc
 	return 0;
 }
 
-static int ieee80211_ioctl_siwpower(struct net_device *dev,
-				    struct iw_request_info *info,
-				    struct iw_param *wrq,
-				    char *extra)
-{
-	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-	struct ieee80211_conf *conf = &local->hw.conf;
-	int timeout = 0;
-	bool ps;
-
-	if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS))
-		return -EOPNOTSUPP;
-
-	if (sdata->vif.type != NL80211_IFTYPE_STATION)
-		return -EINVAL;
-
-	if (wrq->disabled) {
-		ps = false;
-		timeout = 0;
-		goto set;
-	}
-
-	switch (wrq->flags & IW_POWER_MODE) {
-	case IW_POWER_ON:       /* If not specified */
-	case IW_POWER_MODE:     /* If set all mask */
-	case IW_POWER_ALL_R:    /* If explicitely state all */
-		ps = true;
-		break;
-	default:                /* Otherwise we ignore */
-		return -EINVAL;
-	}
-
-	if (wrq->flags & ~(IW_POWER_MODE | IW_POWER_TIMEOUT))
-		return -EINVAL;
-
-	if (wrq->flags & IW_POWER_TIMEOUT)
-		timeout = wrq->value / 1000;
-
- set:
-	if (ps == sdata->u.mgd.powersave && timeout == conf->dynamic_ps_timeout)
-		return 0;
-
-	sdata->u.mgd.powersave = ps;
-	conf->dynamic_ps_timeout = timeout;
-
-	if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)
-		ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
-
-	ieee80211_recalc_ps(local, -1);
-
-	return 0;
-}
-
-static int ieee80211_ioctl_giwpower(struct net_device *dev,
-				    struct iw_request_info *info,
-				    union iwreq_data *wrqu,
-				    char *extra)
-{
-	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-
-	wrqu->power.disabled = !sdata->u.mgd.powersave;
-
-	return 0;
-}
-
 /* Get wireless statistics.  Called by /proc/net/wireless and by SIOCGIWSTATS */
 static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *dev)
 {
@@ -439,8 +373,8 @@ static const iw_handler ieee80211_handle
 	(iw_handler) cfg80211_wext_giwretry,		/* SIOCGIWRETRY */
 	(iw_handler) cfg80211_wext_siwencode,		/* SIOCSIWENCODE */
 	(iw_handler) cfg80211_wext_giwencode,		/* SIOCGIWENCODE */
-	(iw_handler) ieee80211_ioctl_siwpower,		/* SIOCSIWPOWER */
-	(iw_handler) ieee80211_ioctl_giwpower,		/* SIOCGIWPOWER */
+	(iw_handler) cfg80211_wext_siwpower,		/* SIOCSIWPOWER */
+	(iw_handler) cfg80211_wext_giwpower,		/* SIOCGIWPOWER */
 	(iw_handler) NULL,				/* -- hole -- */
 	(iw_handler) NULL,				/* -- hole -- */
 	(iw_handler) cfg80211_wext_siwgenie,		/* SIOCSIWGENIE */
--- wireless-testing.orig/net/wireless/Kconfig	2009-06-24 13:54:03.000000000 +0200
+++ wireless-testing/net/wireless/Kconfig	2009-06-24 13:54:07.000000000 +0200
@@ -11,6 +11,22 @@ config CFG80211_REG_DEBUG
 
 	  If unsure, say N.
 
+config CFG80211_DEFAULT_PS
+	bool "enable powersave by default"
+	depends on CFG80211
+	default y
+	help
+	  This option enables powersave mode by default.
+
+	  If this causes your applications to misbehave you should fix your
+	  applications instead -- they need to register their network
+	  latency requirement, see Documentation/power/pm_qos_interface.txt.
+
+config CFG80211_DEFAULT_PS_VALUE
+	int
+	default 1 if CFG80211_DEFAULT_PS
+	default 0
+
 config CFG80211_DEBUGFS
 	bool "cfg80211 DebugFS entries"
 	depends on CFG80211 && DEBUG_FS
--- wireless-testing.orig/net/wireless/core.c	2009-06-24 13:54:06.000000000 +0200
+++ wireless-testing/net/wireless/core.c	2009-06-24 13:54:07.000000000 +0200
@@ -550,11 +550,20 @@ static int cfg80211_netdev_notifier_call
 		}
 		wdev->netdev = dev;
 		wdev->sme_state = CFG80211_SME_IDLE;
+		mutex_unlock(&rdev->devlist_mtx);
 #ifdef CONFIG_WIRELESS_EXT
 		wdev->wext.default_key = -1;
 		wdev->wext.default_mgmt_key = -1;
+		wdev->wext.ps = CONFIG_CFG80211_DEFAULT_PS_VALUE;
+		wdev->wext.ps_timeout = 500;
+		if (rdev->ops->set_power_mgmt)
+			if (rdev->ops->set_power_mgmt(wdev->wiphy, dev,
+						      wdev->wext.ps,
+						      wdev->wext.ps_timeout)) {
+				/* assume this means it's off */
+				wdev->wext.ps = false;
+			}
 #endif
-		mutex_unlock(&rdev->devlist_mtx);
 		break;
 	case NETDEV_GOING_DOWN:
 		if (!wdev->ssid_len)
--- wireless-testing.orig/net/wireless/wext-compat.c	2009-06-24 13:54:06.000000000 +0200
+++ wireless-testing/net/wireless/wext-compat.c	2009-06-24 13:54:07.000000000 +0200
@@ -848,3 +848,63 @@ int cfg80211_wext_giwauth(struct net_dev
 	return -EOPNOTSUPP;
 }
 EXPORT_SYMBOL_GPL(cfg80211_wext_giwauth);
+
+int cfg80211_wext_siwpower(struct net_device *dev,
+			   struct iw_request_info *info,
+			   struct iw_param *wrq, char *extra)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+	bool ps = wdev->wext.ps;
+	int timeout = wdev->wext.ps_timeout;
+	int err;
+
+	if (wdev->iftype != NL80211_IFTYPE_STATION)
+		return -EINVAL;
+
+	if (!rdev->ops->set_power_mgmt)
+		return -EOPNOTSUPP;
+
+	if (wrq->disabled) {
+		ps = false;
+	} else {
+		switch (wrq->flags & IW_POWER_MODE) {
+		case IW_POWER_ON:       /* If not specified */
+		case IW_POWER_MODE:     /* If set all mask */
+		case IW_POWER_ALL_R:    /* If explicitely state all */
+			ps = true;
+			break;
+		default:                /* Otherwise we ignore */
+			return -EINVAL;
+		}
+
+		if (wrq->flags & ~(IW_POWER_MODE | IW_POWER_TIMEOUT))
+			return -EINVAL;
+
+		if (wrq->flags & IW_POWER_TIMEOUT)
+			timeout = wrq->value / 1000;
+	}
+
+	err = rdev->ops->set_power_mgmt(wdev->wiphy, dev, ps, timeout);
+	if (err)
+		return err;
+
+	wdev->wext.ps = ps;
+	wdev->wext.ps_timeout = timeout;
+
+	return 0;
+
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_siwpower);
+
+int cfg80211_wext_giwpower(struct net_device *dev,
+			   struct iw_request_info *info,
+			   struct iw_param *wrq, char *extra)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+	wrq->disabled = !wdev->wext.ps;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_giwpower);
--- wireless-testing.orig/net/mac80211/cfg.c	2009-06-24 13:53:12.000000000 +0200
+++ wireless-testing/net/mac80211/cfg.c	2009-06-24 13:54:07.000000000 +0200
@@ -1376,6 +1376,31 @@ static void ieee80211_rfkill_poll(struct
 	drv_rfkill_poll(local);
 }
 
+static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
+				    bool enabled, int timeout)
+{
+	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+	struct ieee80211_conf *conf = &local->hw.conf;
+
+	if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS))
+		return -EOPNOTSUPP;
+
+	if (enabled == sdata->u.mgd.powersave &&
+	    timeout == conf->dynamic_ps_timeout)
+		return 0;
+
+	sdata->u.mgd.powersave = enabled;
+	conf->dynamic_ps_timeout = timeout;
+
+	if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)
+		ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
+
+	ieee80211_recalc_ps(local, -1);
+
+	return 0;
+}
+
 struct cfg80211_ops mac80211_config_ops = {
 	.add_virtual_intf = ieee80211_add_iface,
 	.del_virtual_intf = ieee80211_del_iface,
@@ -1418,4 +1443,5 @@ struct cfg80211_ops mac80211_config_ops 
 	.set_tx_power = ieee80211_set_tx_power,
 	.get_tx_power = ieee80211_get_tx_power,
 	.rfkill_poll = ieee80211_rfkill_poll,
+	.set_power_mgmt = ieee80211_set_power_mgmt,
 };
--- wireless-testing.orig/net/mac80211/mlme.c	2009-06-24 13:54:06.000000000 +0200
+++ wireless-testing/net/mac80211/mlme.c	2009-06-24 13:54:07.000000000 +0200
@@ -2354,11 +2354,6 @@ void ieee80211_sta_setup_sdata(struct ie
 		ifmgd->flags |= IEEE80211_STA_WMM_ENABLED;
 
 	hw_flags = sdata->local->hw.flags;
-
-	if (hw_flags & IEEE80211_HW_SUPPORTS_PS) {
-		ifmgd->powersave = CONFIG_MAC80211_DEFAULT_PS_VALUE;
-		sdata->local->hw.conf.dynamic_ps_timeout = 500;
-	}
 }
 
 /* configuration hooks */
--- wireless-testing.orig/drivers/net/wireless/iwmc3200wifi/cfg80211.c	2009-06-24 13:53:12.000000000 +0200
+++ wireless-testing/drivers/net/wireless/iwmc3200wifi/cfg80211.c	2009-06-24 13:54:07.000000000 +0200
@@ -522,6 +522,27 @@ static int iwm_cfg80211_get_txpower(stru
 	return 0;
 }
 
+static int iwm_cfg80211_set_power_mgmt(struct wiphy *wiphy,
+				       struct net_device *dev,
+				       bool enabled, int timeout)
+{
+	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
+	u32 power_index;
+
+	if (enabled)
+		power_index = IWM_POWER_INDEX_DEFAULT;
+	else
+		power_index = IWM_POWER_INDEX_MIN;
+
+	if (power_index == iwm->conf.power_index)
+		return 0;
+
+	iwm->conf.power_index = power_index;
+
+	return iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
+				       CFG_POWER_INDEX, iwm->conf.power_index);
+}
+
 static struct cfg80211_ops iwm_cfg80211_ops = {
 	.change_virtual_intf = iwm_cfg80211_change_iface,
 	.add_key = iwm_cfg80211_add_key,
@@ -534,6 +555,7 @@ static struct cfg80211_ops iwm_cfg80211_
 	.leave_ibss = iwm_cfg80211_leave_ibss,
 	.set_tx_power = iwm_cfg80211_set_txpower,
 	.get_tx_power = iwm_cfg80211_get_txpower,
+	.set_power_mgmt = iwm_cfg80211_set_power_mgmt,
 };
 
 struct wireless_dev *iwm_wdev_alloc(int sizeof_bus, struct device *dev)
--- wireless-testing.orig/drivers/net/wireless/iwmc3200wifi/wext.c	2009-06-24 13:53:12.000000000 +0200
+++ wireless-testing/drivers/net/wireless/iwmc3200wifi/wext.c	2009-06-24 13:54:07.000000000 +0200
@@ -238,49 +238,6 @@ static int iwm_set_wpa_version(struct iw
 	return 0;
 }
 
-static int iwm_wext_siwpower(struct net_device *dev,
-			     struct iw_request_info *info,
-			     struct iw_param *wrq, char *extra)
-{
-	struct iwm_priv *iwm = ndev_to_iwm(dev);
-	u32 power_index;
-
-	if (wrq->disabled) {
-		power_index = IWM_POWER_INDEX_MIN;
-		goto set;
-	} else
-		power_index = IWM_POWER_INDEX_DEFAULT;
-
-	switch (wrq->flags & IW_POWER_MODE) {
-	case IW_POWER_ON:
-	case IW_POWER_MODE:
-	case IW_POWER_ALL_R:
-		break;
-	default:
-		return -EINVAL;
-	}
-
- set:
-	if (power_index == iwm->conf.power_index)
-		return 0;
-
-	iwm->conf.power_index = power_index;
-
-	return iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
-				       CFG_POWER_INDEX, iwm->conf.power_index);
-}
-
-static int iwm_wext_giwpower(struct net_device *dev,
-			     struct iw_request_info *info,
-			     union iwreq_data *wrqu, char *extra)
-{
-	struct iwm_priv *iwm = ndev_to_iwm(dev);
-
-	wrqu->power.disabled = (iwm->conf.power_index == IWM_POWER_INDEX_MIN);
-
-	return 0;
-}
-
 static int iwm_set_key_mgt(struct iwm_priv *iwm, u8 key_mgt)
 {
 	u8 *auth_type = &iwm->umac_profile->sec.auth_type;
@@ -458,8 +415,8 @@ static const iw_handler iwm_handlers[] =
 	(iw_handler) NULL,				/* SIOCGIWRETRY */
 	(iw_handler) cfg80211_wext_siwencode,		/* SIOCSIWENCODE */
 	(iw_handler) cfg80211_wext_giwencode,		/* SIOCGIWENCODE */
-	(iw_handler) iwm_wext_siwpower,			/* SIOCSIWPOWER */
-	(iw_handler) iwm_wext_giwpower,			/* SIOCGIWPOWER */
+	(iw_handler) cfg80211_wext_siwpower,		/* SIOCSIWPOWER */
+	(iw_handler) cfg80211_wext_giwpower,		/* SIOCGIWPOWER */
 	(iw_handler) NULL,				/* -- hole -- */
 	(iw_handler) NULL,				/* -- hole -- */
 	(iw_handler) NULL,                              /* SIOCSIWGENIE */

-- 


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

* [RFC 05/11] cfg80211: implement IWAP for WDS
  2009-06-24 12:07 [RFC 00/11] cfg80211 connect API + wireless extension move Johannes Berg
                   ` (3 preceding siblings ...)
  2009-06-24 12:07 ` [RFC 04/11] cfg80211: implement iwpower Johannes Berg
@ 2009-06-24 12:07 ` Johannes Berg
  2009-06-24 12:07 ` [RFC 06/11] cfg80211: implement IWRATE Johannes Berg
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: Johannes Berg @ 2009-06-24 12:07 UTC (permalink / raw)
  To: linux-wireless

This implements siocsiwap/giwap for WDS mode.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
 include/net/cfg80211.h     |   10 +++++++++
 net/mac80211/cfg.c         |   11 ++++++++++
 net/mac80211/wext.c        |   26 +++----------------------
 net/wireless/wext-compat.c |   46 +++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 71 insertions(+), 22 deletions(-)

--- wireless-testing.orig/include/net/cfg80211.h	2009-06-24 13:54:07.000000000 +0200
+++ wireless-testing/include/net/cfg80211.h	2009-06-24 13:54:08.000000000 +0200
@@ -998,6 +998,9 @@ struct cfg80211_ops {
 				enum tx_power_setting type, int dbm);
 	int	(*get_tx_power)(struct wiphy *wiphy, int *dbm);
 
+	int	(*set_wds_peer)(struct wiphy *wiphy, struct net_device *dev,
+				u8 *addr);
+
 	void	(*rfkill_poll)(struct wiphy *wiphy);
 
 	/* some temporary stuff to finish wext */
@@ -1606,6 +1609,13 @@ int cfg80211_wext_giwpower(struct net_de
 			   struct iw_request_info *info,
 			   struct iw_param *wrq, char *extra);
 
+int cfg80211_wds_wext_siwap(struct net_device *dev,
+			    struct iw_request_info *info,
+			    struct sockaddr *addr, char *extra);
+int cfg80211_wds_wext_giwap(struct net_device *dev,
+			    struct iw_request_info *info,
+			    struct sockaddr *addr, char *extra);
+
 /*
  * callbacks for asynchronous cfg80211 methods, notification
  * functions and BSS handling helpers
--- wireless-testing.orig/net/mac80211/wext.c	2009-06-24 13:54:07.000000000 +0200
+++ wireless-testing/net/mac80211/wext.c	2009-06-24 13:54:08.000000000 +0200
@@ -143,23 +143,8 @@ static int ieee80211_ioctl_siwap(struct 
 	if (sdata->vif.type == NL80211_IFTYPE_STATION)
 		return cfg80211_mgd_wext_siwap(dev, info, ap_addr, extra);
 
-	if (sdata->vif.type == NL80211_IFTYPE_WDS) {
-		/*
-		 * If it is necessary to update the WDS peer address
-		 * while the interface is running, then we need to do
-		 * more work here, namely if it is running we need to
-		 * add a new and remove the old STA entry, this is
-		 * normally handled by _open() and _stop().
-		 */
-		if (netif_running(dev))
-			return -EBUSY;
-
-		memcpy(&sdata->u.wds.remote_addr, (u8 *) &ap_addr->sa_data,
-		       ETH_ALEN);
-
-		return 0;
-	}
-
+	if (sdata->vif.type == NL80211_IFTYPE_WDS)
+		return cfg80211_wds_wext_siwap(dev, info, ap_addr, extra);
 	return -EOPNOTSUPP;
 }
 
@@ -176,11 +161,8 @@ static int ieee80211_ioctl_giwap(struct 
 	if (sdata->vif.type == NL80211_IFTYPE_STATION)
 		return cfg80211_mgd_wext_giwap(dev, info, ap_addr, extra);
 
-	if (sdata->vif.type == NL80211_IFTYPE_WDS) {
-		ap_addr->sa_family = ARPHRD_ETHER;
-		memcpy(&ap_addr->sa_data, sdata->u.wds.remote_addr, ETH_ALEN);
-		return 0;
-	}
+	if (sdata->vif.type == NL80211_IFTYPE_WDS)
+		return cfg80211_wds_wext_giwap(dev, info, ap_addr, extra);
 
 	return -EOPNOTSUPP;
 }
--- wireless-testing.orig/net/wireless/wext-compat.c	2009-06-24 13:54:07.000000000 +0200
+++ wireless-testing/net/wireless/wext-compat.c	2009-06-24 13:54:08.000000000 +0200
@@ -908,3 +908,49 @@ int cfg80211_wext_giwpower(struct net_de
 	return 0;
 }
 EXPORT_SYMBOL_GPL(cfg80211_wext_giwpower);
+
+int cfg80211_wds_wext_siwap(struct net_device *dev,
+			    struct iw_request_info *info,
+			    struct sockaddr *addr, char *extra)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+	int err;
+
+	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_WDS))
+		return -EINVAL;
+
+	if (addr->sa_family != ARPHRD_ETHER)
+		return -EINVAL;
+
+	if (netif_running(dev))
+		return -EBUSY;
+
+	if (!rdev->ops->set_wds_peer)
+		return -EOPNOTSUPP;
+
+	err = rdev->ops->set_wds_peer(wdev->wiphy, dev, (u8 *) &addr->sa_data);
+	if (err)
+		return err;
+
+	memcpy(&wdev->wext.bssid, (u8 *) &addr->sa_data, ETH_ALEN);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cfg80211_wds_wext_siwap);
+
+int cfg80211_wds_wext_giwap(struct net_device *dev,
+			    struct iw_request_info *info,
+			    struct sockaddr *addr, char *extra)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_WDS))
+		return -EINVAL;
+
+	addr->sa_family = ARPHRD_ETHER;
+	memcpy(&addr->sa_data, wdev->wext.bssid, ETH_ALEN);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cfg80211_wds_wext_giwap);
--- wireless-testing.orig/net/mac80211/cfg.c	2009-06-24 13:54:07.000000000 +0200
+++ wireless-testing/net/mac80211/cfg.c	2009-06-24 13:54:08.000000000 +0200
@@ -1369,6 +1369,16 @@ static int ieee80211_get_tx_power(struct
 	return 0;
 }
 
+static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev,
+				  u8 *addr)
+{
+	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+
+	memcpy(&sdata->u.wds.remote_addr, addr, ETH_ALEN);
+
+	return 0;
+}
+
 static void ieee80211_rfkill_poll(struct wiphy *wiphy)
 {
 	struct ieee80211_local *local = wiphy_priv(wiphy);
@@ -1442,6 +1452,7 @@ struct cfg80211_ops mac80211_config_ops 
 	.set_wiphy_params = ieee80211_set_wiphy_params,
 	.set_tx_power = ieee80211_set_tx_power,
 	.get_tx_power = ieee80211_get_tx_power,
+	.set_wds_peer = ieee80211_set_wds_peer,
 	.rfkill_poll = ieee80211_rfkill_poll,
 	.set_power_mgmt = ieee80211_set_power_mgmt,
 };

-- 


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

* [RFC 06/11] cfg80211: implement IWRATE
  2009-06-24 12:07 [RFC 00/11] cfg80211 connect API + wireless extension move Johannes Berg
                   ` (4 preceding siblings ...)
  2009-06-24 12:07 ` [RFC 05/11] cfg80211: implement IWAP for WDS Johannes Berg
@ 2009-06-24 12:07 ` Johannes Berg
  2009-06-24 12:07 ` [RFC 07/11] cfg80211: implement get_wireless_stats Johannes Berg
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: Johannes Berg @ 2009-06-24 12:07 UTC (permalink / raw)
  To: linux-wireless

For now, let's implement that using a very hackish way:
simply mirror the wext API in the cfg80211 API. This
will have to be changed later when we implement proper
bitrate API.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
 include/net/cfg80211.h     |   11 ++++++
 net/mac80211/cfg.c         |   73 +++++++++++++++++++++++++++++++++++++++++++
 net/mac80211/wext.c        |   76 +--------------------------------------------
 net/wireless/wext-compat.c |   28 ++++++++++++++++
 4 files changed, 114 insertions(+), 74 deletions(-)

--- wireless-testing.orig/include/net/cfg80211.h	2009-06-24 13:54:08.000000000 +0200
+++ wireless-testing/include/net/cfg80211.h	2009-06-24 13:54:08.000000000 +0200
@@ -1006,6 +1006,10 @@ struct cfg80211_ops {
 	/* some temporary stuff to finish wext */
 	int	(*set_power_mgmt)(struct wiphy *wiphy, struct net_device *dev,
 				  bool enabled, int timeout);
+	int	(*set_bitrate)(struct wiphy *wiphy, struct net_device *dev,
+			       struct iw_param *rate);
+	int	(*get_bitrate)(struct wiphy *wiphy, struct net_device *dev,
+			       struct iw_param *rate);
 };
 
 /*
@@ -1568,6 +1572,13 @@ int cfg80211_wext_giwauth(struct net_dev
 struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy,
 					     struct iw_freq *freq);
 
+int cfg80211_wext_siwrate(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_param *rate, char *extra);
+int cfg80211_wext_giwrate(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_param *rate, char *extra);
+
 int cfg80211_wext_siwrts(struct net_device *dev,
 			 struct iw_request_info *info,
 			 struct iw_param *rts, char *extra);
--- wireless-testing.orig/net/mac80211/cfg.c	2009-06-24 13:54:08.000000000 +0200
+++ wireless-testing/net/mac80211/cfg.c	2009-06-24 13:54:08.000000000 +0200
@@ -1411,6 +1411,77 @@ static int ieee80211_set_power_mgmt(stru
 	return 0;
 }
 
+static int ieee80211_set_bitrate(struct wiphy *wiphy,
+				 struct net_device *dev,
+				 struct iw_param *rate)
+{
+	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+	int i, err = -EINVAL;
+	u32 target_rate = rate->value / 100000;
+	struct ieee80211_supported_band *sband;
+
+	sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
+
+	/* target_rate = -1, rate->fixed = 0 means auto only, so use all rates
+	 * target_rate = X, rate->fixed = 1 means only rate X
+	 * target_rate = X, rate->fixed = 0 means all rates <= X */
+	sdata->max_ratectrl_rateidx = -1;
+	sdata->force_unicast_rateidx = -1;
+	if (rate->value < 0)
+		return 0;
+
+	for (i=0; i< sband->n_bitrates; i++) {
+		struct ieee80211_rate *brate = &sband->bitrates[i];
+		int this_rate = brate->bitrate;
+
+		if (target_rate == this_rate) {
+			sdata->max_ratectrl_rateidx = i;
+			if (rate->fixed)
+				sdata->force_unicast_rateidx = i;
+			err = 0;
+			break;
+		}
+	}
+
+	return err;
+}
+
+static int ieee80211_get_bitrate(struct wiphy *wiphy,
+				 struct net_device *dev,
+				 struct iw_param *rate)
+{
+	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+	struct sta_info *sta;
+	struct ieee80211_supported_band *sband;
+
+	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+
+	if (sdata->vif.type != NL80211_IFTYPE_STATION)
+		return -EOPNOTSUPP;
+
+	sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
+
+	rcu_read_lock();
+
+	sta = sta_info_get(local, sdata->u.mgd.bssid);
+
+	if (sta && !(sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS))
+		rate->value = sband->bitrates[sta->last_tx_rate.idx].bitrate;
+	else
+		rate->value = 0;
+
+	rcu_read_unlock();
+
+	if (!sta)
+		return -ENODEV;
+
+	rate->value *= 100000;
+
+	return 0;
+}
+
 struct cfg80211_ops mac80211_config_ops = {
 	.add_virtual_intf = ieee80211_add_iface,
 	.del_virtual_intf = ieee80211_del_iface,
@@ -1455,4 +1526,6 @@ struct cfg80211_ops mac80211_config_ops 
 	.set_wds_peer = ieee80211_set_wds_peer,
 	.rfkill_poll = ieee80211_rfkill_poll,
 	.set_power_mgmt = ieee80211_set_power_mgmt,
+	.set_bitrate = ieee80211_set_bitrate,
+	.get_bitrate = ieee80211_get_bitrate,
 };
--- wireless-testing.orig/net/mac80211/wext.c	2009-06-24 13:54:08.000000000 +0200
+++ wireless-testing/net/mac80211/wext.c	2009-06-24 13:54:08.000000000 +0200
@@ -168,78 +168,6 @@ static int ieee80211_ioctl_giwap(struct 
 }
 
 
-static int ieee80211_ioctl_siwrate(struct net_device *dev,
-				  struct iw_request_info *info,
-				  struct iw_param *rate, char *extra)
-{
-	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-	int i, err = -EINVAL;
-	u32 target_rate = rate->value / 100000;
-	struct ieee80211_sub_if_data *sdata;
-	struct ieee80211_supported_band *sband;
-
-	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-
-	sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
-
-	/* target_rate = -1, rate->fixed = 0 means auto only, so use all rates
-	 * target_rate = X, rate->fixed = 1 means only rate X
-	 * target_rate = X, rate->fixed = 0 means all rates <= X */
-	sdata->max_ratectrl_rateidx = -1;
-	sdata->force_unicast_rateidx = -1;
-	if (rate->value < 0)
-		return 0;
-
-	for (i=0; i< sband->n_bitrates; i++) {
-		struct ieee80211_rate *brate = &sband->bitrates[i];
-		int this_rate = brate->bitrate;
-
-		if (target_rate == this_rate) {
-			sdata->max_ratectrl_rateidx = i;
-			if (rate->fixed)
-				sdata->force_unicast_rateidx = i;
-			err = 0;
-			break;
-		}
-	}
-	return err;
-}
-
-static int ieee80211_ioctl_giwrate(struct net_device *dev,
-				  struct iw_request_info *info,
-				  struct iw_param *rate, char *extra)
-{
-	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-	struct sta_info *sta;
-	struct ieee80211_sub_if_data *sdata;
-	struct ieee80211_supported_band *sband;
-
-	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-
-	if (sdata->vif.type != NL80211_IFTYPE_STATION)
-		return -EOPNOTSUPP;
-
-	sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
-
-	rcu_read_lock();
-
-	sta = sta_info_get(local, sdata->u.mgd.bssid);
-
-	if (sta && !(sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS))
-		rate->value = sband->bitrates[sta->last_tx_rate.idx].bitrate;
-	else
-		rate->value = 0;
-
-	rcu_read_unlock();
-
-	if (!sta)
-		return -ENODEV;
-
-	rate->value *= 100000;
-
-	return 0;
-}
-
 /* Get wireless statistics.  Called by /proc/net/wireless and by SIOCGIWSTATS */
 static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *dev)
 {
@@ -343,8 +271,8 @@ static const iw_handler ieee80211_handle
 	(iw_handler) NULL,				/* SIOCGIWNICKN */
 	(iw_handler) NULL,				/* -- hole -- */
 	(iw_handler) NULL,				/* -- hole -- */
-	(iw_handler) ieee80211_ioctl_siwrate,		/* SIOCSIWRATE */
-	(iw_handler) ieee80211_ioctl_giwrate,		/* SIOCGIWRATE */
+	(iw_handler) cfg80211_wext_siwrate,		/* SIOCSIWRATE */
+	(iw_handler) cfg80211_wext_giwrate,		/* SIOCGIWRATE */
 	(iw_handler) cfg80211_wext_siwrts,		/* SIOCSIWRTS */
 	(iw_handler) cfg80211_wext_giwrts,		/* SIOCGIWRTS */
 	(iw_handler) cfg80211_wext_siwfrag,		/* SIOCSIWFRAG */
--- wireless-testing.orig/net/wireless/wext-compat.c	2009-06-24 13:54:08.000000000 +0200
+++ wireless-testing/net/wireless/wext-compat.c	2009-06-24 13:54:08.000000000 +0200
@@ -954,3 +954,31 @@ int cfg80211_wds_wext_giwap(struct net_d
 	return 0;
 }
 EXPORT_SYMBOL_GPL(cfg80211_wds_wext_giwap);
+
+int cfg80211_wext_siwrate(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_param *rate, char *extra)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+
+	if (!rdev->ops->set_bitrate)
+		return -EOPNOTSUPP;
+
+	return rdev->ops->set_bitrate(wdev->wiphy, dev, rate);
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_siwrate);
+
+int cfg80211_wext_giwrate(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_param *rate, char *extra)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+
+	if (!rdev->ops->get_bitrate)
+		return -EOPNOTSUPP;
+
+	return rdev->ops->get_bitrate(wdev->wiphy, dev, rate);
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_giwrate);

-- 


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

* [RFC 07/11] cfg80211: implement get_wireless_stats
  2009-06-24 12:07 [RFC 00/11] cfg80211 connect API + wireless extension move Johannes Berg
                   ` (5 preceding siblings ...)
  2009-06-24 12:07 ` [RFC 06/11] cfg80211: implement IWRATE Johannes Berg
@ 2009-06-24 12:07 ` Johannes Berg
  2009-06-24 12:07 ` [RFC 08/11] cfg80211: combine iwfreq implementations Johannes Berg
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: Johannes Berg @ 2009-06-24 12:07 UTC (permalink / raw)
  To: linux-wireless

With just a new method to get the current channel noise,
we can implement wireless stats in cfg80211. We also
make the handler return NULL if we have no information,
which is possible thanks to the recent wext change.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
 include/net/cfg80211.h     |    3 +
 net/mac80211/cfg.c         |   27 +++++++++++++++++
 net/mac80211/wext.c        |   69 --------------------------------------------
 net/wireless/wext-compat.c |   70 +++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 101 insertions(+), 68 deletions(-)

--- wireless-testing.orig/net/mac80211/wext.c	2009-06-24 13:54:08.000000000 +0200
+++ wireless-testing/net/mac80211/wext.c	2009-06-24 13:54:09.000000000 +0200
@@ -168,73 +168,6 @@ static int ieee80211_ioctl_giwap(struct 
 }
 
 
-/* Get wireless statistics.  Called by /proc/net/wireless and by SIOCGIWSTATS */
-static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *dev)
-{
-	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-	struct iw_statistics *wstats = &local->wstats;
-	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-	struct sta_info *sta = NULL;
-
-	rcu_read_lock();
-
-	if (sdata->vif.type == NL80211_IFTYPE_STATION)
-		sta = sta_info_get(local, sdata->u.mgd.bssid);
-
-	if (!sta) {
-		wstats->discard.fragment = 0;
-		wstats->discard.misc = 0;
-		wstats->qual.qual = 0;
-		wstats->qual.level = 0;
-		wstats->qual.noise = 0;
-		wstats->qual.updated = IW_QUAL_ALL_INVALID;
-	} else {
-		wstats->qual.updated = 0;
-		/*
-		 * mirror what cfg80211 does for iwrange/scan results,
-		 * otherwise userspace gets confused.
-		 */
-		if (local->hw.flags & (IEEE80211_HW_SIGNAL_UNSPEC |
-				       IEEE80211_HW_SIGNAL_DBM)) {
-			wstats->qual.updated |= IW_QUAL_LEVEL_UPDATED;
-			wstats->qual.updated |= IW_QUAL_QUAL_UPDATED;
-		} else {
-			wstats->qual.updated |= IW_QUAL_LEVEL_INVALID;
-			wstats->qual.updated |= IW_QUAL_QUAL_INVALID;
-		}
-
-		if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC) {
-			wstats->qual.level = sta->last_signal;
-			wstats->qual.qual = sta->last_signal;
-		} else if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) {
-			int sig = sta->last_signal;
-
-			wstats->qual.updated |= IW_QUAL_DBM;
-			wstats->qual.level = sig;
-			if (sig < -110)
-				sig = -110;
-			else if (sig > -40)
-				sig = -40;
-			wstats->qual.qual = sig + 110;
-		}
-
-		if (local->hw.flags & IEEE80211_HW_NOISE_DBM) {
-			/*
-			 * This assumes that if driver reports noise, it also
-			 * reports signal in dBm.
-			 */
-			wstats->qual.noise = sta->last_noise;
-			wstats->qual.updated |= IW_QUAL_NOISE_UPDATED;
-		} else {
-			wstats->qual.updated |= IW_QUAL_NOISE_INVALID;
-		}
-	}
-
-	rcu_read_unlock();
-
-	return wstats;
-}
-
 /* Structures to export the Wireless Handlers */
 
 static const iw_handler ieee80211_handler[] =
@@ -301,5 +234,5 @@ const struct iw_handler_def ieee80211_iw
 {
 	.num_standard	= ARRAY_SIZE(ieee80211_handler),
 	.standard	= (iw_handler *) ieee80211_handler,
-	.get_wireless_stats = ieee80211_get_wireless_stats,
+	.get_wireless_stats = cfg80211_wireless_stats,
 };
--- wireless-testing.orig/net/wireless/wext-compat.c	2009-06-24 13:54:08.000000000 +0200
+++ wireless-testing/net/wireless/wext-compat.c	2009-06-24 13:54:09.000000000 +0200
@@ -982,3 +982,73 @@ int cfg80211_wext_giwrate(struct net_dev
 	return rdev->ops->get_bitrate(wdev->wiphy, dev, rate);
 }
 EXPORT_SYMBOL_GPL(cfg80211_wext_giwrate);
+
+/* Get wireless statistics.  Called by /proc/net/wireless and by SIOCGIWSTATS */
+struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+	/* we are under RTNL - globally locked - so can use static structs */
+	static struct iw_statistics wstats;
+	static struct station_info sinfo;
+	u8 *addr;
+
+	if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION)
+		return NULL;
+
+	if (!rdev->ops->get_station)
+		return NULL;
+
+	addr = wdev->wext.connect.bssid;
+	if (!addr)
+		return NULL;
+
+	if (rdev->ops->get_station(&rdev->wiphy, dev, addr, &sinfo))
+		return NULL;
+
+	memset(&wstats, 0, sizeof(wstats));
+
+	switch (rdev->wiphy.signal_type) {
+	case CFG80211_SIGNAL_TYPE_MBM:
+		if (sinfo.filled & STATION_INFO_SIGNAL) {
+			int sig = sinfo.signal;
+			wstats.qual.updated |= IW_QUAL_LEVEL_UPDATED;
+			wstats.qual.updated |= IW_QUAL_QUAL_UPDATED;
+			wstats.qual.updated |= IW_QUAL_DBM;
+			wstats.qual.level = sig;
+			if (sig < -110)
+				sig = -110;
+			else if (sig > -40)
+				sig = -40;
+			wstats.qual.qual = sig + 110;
+			break;
+		}
+	case CFG80211_SIGNAL_TYPE_UNSPEC:
+		if (sinfo.filled & STATION_INFO_SIGNAL) {
+			wstats.qual.updated |= IW_QUAL_LEVEL_UPDATED;
+			wstats.qual.updated |= IW_QUAL_QUAL_UPDATED;
+			wstats.qual.level = sinfo.signal;
+			wstats.qual.qual = sinfo.signal;
+			break;
+		}
+	default:
+		wstats.qual.updated |= IW_QUAL_LEVEL_INVALID;
+		wstats.qual.updated |= IW_QUAL_QUAL_INVALID;
+	}
+
+	/*
+	 * This assumes that if the driver does dBm, it also
+	 * reports the noise in dBm...
+	 */
+	if (rdev->ops->get_noise) {
+		int noise;
+		if (rdev->ops->get_noise(wdev->wiphy, dev, &noise)) {
+			wstats.qual.noise = noise;
+			wstats.qual.updated |= IW_QUAL_NOISE_INVALID;
+		} else
+			wstats.qual.updated |= IW_QUAL_NOISE_UPDATED;
+	}
+
+	return &wstats;
+}
+EXPORT_SYMBOL_GPL(cfg80211_wireless_stats);
--- wireless-testing.orig/include/net/cfg80211.h	2009-06-24 13:54:08.000000000 +0200
+++ wireless-testing/include/net/cfg80211.h	2009-06-24 13:54:09.000000000 +0200
@@ -1010,6 +1010,8 @@ struct cfg80211_ops {
 			       struct iw_param *rate);
 	int	(*get_bitrate)(struct wiphy *wiphy, struct net_device *dev,
 			       struct iw_param *rate);
+	int	(*get_noise)(struct wiphy *wiphy, struct net_device *dev,
+			     int *noise);
 };
 
 /*
@@ -1612,6 +1614,7 @@ int cfg80211_wext_siwtxpower(struct net_
 int cfg80211_wext_giwtxpower(struct net_device *dev,
 			     struct iw_request_info *info,
 			     union iwreq_data *data, char *keybuf);
+struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev);
 
 int cfg80211_wext_siwpower(struct net_device *dev,
 			   struct iw_request_info *info,
--- wireless-testing.orig/net/mac80211/cfg.c	2009-06-24 13:54:08.000000000 +0200
+++ wireless-testing/net/mac80211/cfg.c	2009-06-24 13:54:09.000000000 +0200
@@ -381,6 +381,32 @@ static void sta_set_sinfo(struct sta_inf
 	}
 }
 
+static int ieee80211_get_noise(struct wiphy *wiphy, struct net_device *dev,
+			       int *noise)
+{
+	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+	struct sta_info *sta;
+	int err = -EINVAL;
+
+	/* XXX: this is all wrong */
+
+	if (!(local->hw.flags & IEEE80211_HW_NOISE_DBM))
+		return -EOPNOTSUPP;
+
+	if (sdata->vif.type != NL80211_IFTYPE_STATION)
+		return -EOPNOTSUPP;
+
+	rcu_read_lock();
+	sta = sta_info_get(local, sdata->u.mgd.bssid);
+	if (sta) {
+		*noise = sta->last_noise;
+		err = 0;
+	}
+	rcu_read_unlock();
+
+	return err;
+}
 
 static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
 				 int idx, u8 *mac, struct station_info *sinfo)
@@ -1528,4 +1554,5 @@ struct cfg80211_ops mac80211_config_ops 
 	.set_power_mgmt = ieee80211_set_power_mgmt,
 	.set_bitrate = ieee80211_set_bitrate,
 	.get_bitrate = ieee80211_get_bitrate,
+	.get_noise = ieee80211_get_noise,
 };

-- 


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

* [RFC 08/11] cfg80211: combine iwfreq implementations
  2009-06-24 12:07 [RFC 00/11] cfg80211 connect API + wireless extension move Johannes Berg
                   ` (6 preceding siblings ...)
  2009-06-24 12:07 ` [RFC 07/11] cfg80211: implement get_wireless_stats Johannes Berg
@ 2009-06-24 12:07 ` Johannes Berg
  2009-06-24 12:07 ` [RFC 09/11] cfg80211: combine IWAP handlers Johannes Berg
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: Johannes Berg @ 2009-06-24 12:07 UTC (permalink / raw)
  To: linux-wireless

Until now we implemented iwfreq for managed mode, we
needed to keep the implementations separate, but now
that we have all versions implemented we can combine
them and export just one handler.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
 include/net/cfg80211.h     |   20 +++--------
 net/mac80211/wext.c        |   76 +--------------------------------------------
 net/wireless/core.h        |    3 +
 net/wireless/ibss.c        |    5 --
 net/wireless/nl80211.c     |    2 +
 net/wireless/wext-compat.c |   54 +++++++++++++++++++++++++++++++
 net/wireless/wext-compat.h |   21 ++++++++++++
 net/wireless/wext-sme.c    |    5 --
 8 files changed, 89 insertions(+), 97 deletions(-)

--- wireless-testing.orig/include/net/cfg80211.h	2009-06-24 13:54:09.000000000 +0200
+++ wireless-testing/include/net/cfg80211.h	2009-06-24 13:54:09.000000000 +0200
@@ -1524,12 +1524,6 @@ int cfg80211_wext_siwmlme(struct net_dev
 int cfg80211_wext_giwrange(struct net_device *dev,
 			   struct iw_request_info *info,
 			   struct iw_point *data, char *extra);
-int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
-			       struct iw_request_info *info,
-			       struct iw_freq *freq, char *extra);
-int cfg80211_ibss_wext_giwfreq(struct net_device *dev,
-			       struct iw_request_info *info,
-			       struct iw_freq *freq, char *extra);
 int cfg80211_ibss_wext_siwessid(struct net_device *dev,
 				struct iw_request_info *info,
 				struct iw_point *data, char *ssid);
@@ -1543,12 +1537,6 @@ int cfg80211_ibss_wext_giwap(struct net_
 			     struct iw_request_info *info,
 			     struct sockaddr *ap_addr, char *extra);
 
-int cfg80211_mgd_wext_siwfreq(struct net_device *dev,
-			      struct iw_request_info *info,
-			      struct iw_freq *freq, char *extra);
-int cfg80211_mgd_wext_giwfreq(struct net_device *dev,
-			      struct iw_request_info *info,
-			      struct iw_freq *freq, char *extra);
 int cfg80211_mgd_wext_siwessid(struct net_device *dev,
 			       struct iw_request_info *info,
 			       struct iw_point *data, char *ssid);
@@ -1571,8 +1559,12 @@ int cfg80211_wext_giwauth(struct net_dev
 			  struct iw_request_info *info,
 			  struct iw_param *data, char *extra);
 
-struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy,
-					     struct iw_freq *freq);
+int cfg80211_wext_siwfreq(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_freq *freq, char *extra);
+int cfg80211_wext_giwfreq(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_freq *freq, char *extra);
 
 int cfg80211_wext_siwrate(struct net_device *dev,
 			  struct iw_request_info *info,
--- wireless-testing.orig/net/mac80211/wext.c	2009-06-24 13:54:09.000000000 +0200
+++ wireless-testing/net/mac80211/wext.c	2009-06-24 13:54:09.000000000 +0200
@@ -27,78 +27,6 @@
 #include "aes_ccm.h"
 
 
-static int ieee80211_ioctl_siwfreq(struct net_device *dev,
-				   struct iw_request_info *info,
-				   struct iw_freq *freq, char *extra)
-{
-	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-	struct ieee80211_local *local = sdata->local;
-	struct ieee80211_channel *chan;
-
-	if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
-		return cfg80211_ibss_wext_siwfreq(dev, info, freq, extra);
-	else if (sdata->vif.type == NL80211_IFTYPE_STATION)
-		return cfg80211_mgd_wext_siwfreq(dev, info, freq, extra);
-
-	/* freq->e == 0: freq->m = channel; otherwise freq = m * 10^e */
-	if (freq->e == 0) {
-		if (freq->m < 0) {
-			if (sdata->vif.type == NL80211_IFTYPE_STATION)
-				sdata->u.mgd.flags |=
-					IEEE80211_STA_AUTO_CHANNEL_SEL;
-			return 0;
-		} else
-			chan = ieee80211_get_channel(local->hw.wiphy,
-				ieee80211_channel_to_frequency(freq->m));
-	} else {
-		int i, div = 1000000;
-		for (i = 0; i < freq->e; i++)
-			div /= 10;
-		if (div <= 0)
-			return -EINVAL;
-		chan = ieee80211_get_channel(local->hw.wiphy, freq->m / div);
-	}
-
-	if (!chan)
-		return -EINVAL;
-
-	if (chan->flags & IEEE80211_CHAN_DISABLED)
-		return -EINVAL;
-
-	/*
-	 * no change except maybe auto -> fixed, ignore the HT
-	 * setting so you can fix a channel you're on already
-	 */
-	if (local->oper_channel == chan)
-		return 0;
-
-	local->oper_channel = chan;
-	local->oper_channel_type = NL80211_CHAN_NO_HT;
-	ieee80211_hw_config(local, 0);
-
-	return 0;
-}
-
-
-static int ieee80211_ioctl_giwfreq(struct net_device *dev,
-				   struct iw_request_info *info,
-				   struct iw_freq *freq, char *extra)
-{
-	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-
-	if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
-		return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra);
-	else if (sdata->vif.type == NL80211_IFTYPE_STATION)
-		return cfg80211_mgd_wext_giwfreq(dev, info, freq, extra);
-
-	freq->m = local->oper_channel->center_freq;
-	freq->e = 6;
-
-	return 0;
-}
-
-
 static int ieee80211_ioctl_siwessid(struct net_device *dev,
 				    struct iw_request_info *info,
 				    struct iw_point *data, char *ssid)
@@ -176,8 +104,8 @@ static const iw_handler ieee80211_handle
 	(iw_handler) cfg80211_wext_giwname,		/* SIOCGIWNAME */
 	(iw_handler) NULL,				/* SIOCSIWNWID */
 	(iw_handler) NULL,				/* SIOCGIWNWID */
-	(iw_handler) ieee80211_ioctl_siwfreq,		/* SIOCSIWFREQ */
-	(iw_handler) ieee80211_ioctl_giwfreq,		/* SIOCGIWFREQ */
+	(iw_handler) cfg80211_wext_siwfreq,		/* SIOCSIWFREQ */
+	(iw_handler) cfg80211_wext_giwfreq,		/* SIOCGIWFREQ */
 	(iw_handler) cfg80211_wext_siwmode,		/* SIOCSIWMODE */
 	(iw_handler) cfg80211_wext_giwmode,		/* SIOCGIWMODE */
 	(iw_handler) NULL,				/* SIOCSIWSENS */
--- wireless-testing.orig/net/wireless/ibss.c	2009-06-24 13:54:05.000000000 +0200
+++ wireless-testing/net/wireless/ibss.c	2009-06-24 13:54:09.000000000 +0200
@@ -7,6 +7,7 @@
 #include <linux/etherdevice.h>
 #include <linux/if_arp.h>
 #include <net/cfg80211.h>
+#include "wext-compat.h"
 #include "nl80211.h"
 
 
@@ -197,8 +198,6 @@ int cfg80211_ibss_wext_siwfreq(struct ne
 
 	return cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev);
 }
-/* temporary symbol - mark GPL - in the future the handler won't be */
-EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwfreq);
 
 int cfg80211_ibss_wext_giwfreq(struct net_device *dev,
 			       struct iw_request_info *info,
@@ -225,8 +224,6 @@ int cfg80211_ibss_wext_giwfreq(struct ne
 	/* no channel if not joining */
 	return -EINVAL;
 }
-/* temporary symbol - mark GPL - in the future the handler won't be */
-EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_giwfreq);
 
 int cfg80211_ibss_wext_siwessid(struct net_device *dev,
 				struct iw_request_info *info,
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ wireless-testing/net/wireless/wext-compat.h	2009-06-24 13:54:09.000000000 +0200
@@ -0,0 +1,21 @@
+#ifndef __WEXT_COMPAT
+#define __WEXT_COMPAT
+
+int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
+			       struct iw_request_info *info,
+			       struct iw_freq *freq, char *extra);
+int cfg80211_ibss_wext_giwfreq(struct net_device *dev,
+			       struct iw_request_info *info,
+			       struct iw_freq *freq, char *extra);
+
+int cfg80211_mgd_wext_siwfreq(struct net_device *dev,
+			      struct iw_request_info *info,
+			      struct iw_freq *freq, char *extra);
+int cfg80211_mgd_wext_giwfreq(struct net_device *dev,
+			      struct iw_request_info *info,
+			      struct iw_freq *freq, char *extra);
+
+struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy,
+					     struct iw_freq *freq);
+
+#endif /* __WEXT_COMPAT */
--- wireless-testing.orig/net/wireless/wext-sme.c	2009-06-24 13:54:06.000000000 +0200
+++ wireless-testing/net/wireless/wext-sme.c	2009-06-24 13:54:09.000000000 +0200
@@ -8,6 +8,7 @@
 #include <linux/etherdevice.h>
 #include <linux/if_arp.h>
 #include <net/cfg80211.h>
+#include "wext-compat.h"
 #include "nl80211.h"
 
 static int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev,
@@ -78,8 +79,6 @@ int cfg80211_mgd_wext_siwfreq(struct net
 
 	return cfg80211_mgd_wext_connect(wiphy_to_dev(wdev->wiphy), wdev);
 }
-/* temporary symbol - mark GPL - in the future the handler won't be */
-EXPORT_SYMBOL_GPL(cfg80211_mgd_wext_siwfreq);
 
 int cfg80211_mgd_wext_giwfreq(struct net_device *dev,
 			      struct iw_request_info *info,
@@ -106,8 +105,6 @@ int cfg80211_mgd_wext_giwfreq(struct net
 	/* no channel if not joining */
 	return -EINVAL;
 }
-/* temporary symbol - mark GPL - in the future the handler won't be */
-EXPORT_SYMBOL_GPL(cfg80211_mgd_wext_giwfreq);
 
 int cfg80211_mgd_wext_siwessid(struct net_device *dev,
 			       struct iw_request_info *info,
--- wireless-testing.orig/net/wireless/core.h	2009-06-24 13:54:06.000000000 +0200
+++ wireless-testing/net/wireless/core.h	2009-06-24 13:54:09.000000000 +0200
@@ -60,6 +60,9 @@ struct cfg80211_registered_device {
 
 	struct work_struct conn_work;
 
+	/* current channel */
+	struct ieee80211_channel *channel;
+
 #ifdef CONFIG_CFG80211_DEBUGFS
 	/* Debugfs entries */
 	struct wiphy_debugfsdentries {
--- wireless-testing.orig/net/wireless/nl80211.c	2009-06-24 13:54:06.000000000 +0200
+++ wireless-testing/net/wireless/nl80211.c	2009-06-24 13:54:09.000000000 +0200
@@ -559,6 +559,8 @@ static int nl80211_set_wiphy(struct sk_b
 						channel_type);
 		if (result)
 			goto bad_res;
+
+		rdev->channel = chan;
 	}
 
 	changed = 0;
--- wireless-testing.orig/net/wireless/wext-compat.c	2009-06-24 13:54:09.000000000 +0200
+++ wireless-testing/net/wireless/wext-compat.c	2009-06-24 13:54:09.000000000 +0200
@@ -14,6 +14,7 @@
 #include <linux/etherdevice.h>
 #include <net/iw_handler.h>
 #include <net/cfg80211.h>
+#include "wext-compat.h"
 #include "core.h"
 
 int cfg80211_wext_giwname(struct net_device *dev,
@@ -301,7 +302,6 @@ struct ieee80211_channel *cfg80211_wext_
 		return ERR_PTR(-EINVAL);
 	return chan;
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_freq);
 
 int cfg80211_wext_siwrts(struct net_device *dev,
 			 struct iw_request_info *info,
@@ -720,6 +720,58 @@ int cfg80211_wext_giwencode(struct net_d
 }
 EXPORT_SYMBOL_GPL(cfg80211_wext_giwencode);
 
+int cfg80211_wext_siwfreq(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_freq *freq, char *extra)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+	struct ieee80211_channel *chan;
+	int err;
+
+	switch (wdev->iftype) {
+	case NL80211_IFTYPE_STATION:
+		return cfg80211_mgd_wext_siwfreq(dev, info, freq, extra);
+	case NL80211_IFTYPE_ADHOC:
+		return cfg80211_ibss_wext_siwfreq(dev, info, freq, extra);
+	default:
+		chan = cfg80211_wext_freq(wdev->wiphy, freq);
+		if (!chan)
+			return -EINVAL;
+		if (IS_ERR(chan))
+			return PTR_ERR(chan);
+		err = rdev->ops->set_channel(wdev->wiphy, chan,
+					     NL80211_CHAN_NO_HT);
+		if (err)
+			return err;
+		rdev->channel = chan;
+		return 0;
+	}
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_siwfreq);
+
+int cfg80211_wext_giwfreq(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_freq *freq, char *extra)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+
+	switch (wdev->iftype) {
+	case NL80211_IFTYPE_STATION:
+		return cfg80211_mgd_wext_giwfreq(dev, info, freq, extra);
+	case NL80211_IFTYPE_ADHOC:
+		return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra);
+	default:
+		if (!rdev->channel)
+			return -EINVAL;
+		freq->m = rdev->channel->center_freq;
+		freq->e = 6;
+		return 0;
+	}
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_giwfreq);
+
 int cfg80211_wext_siwtxpower(struct net_device *dev,
 			     struct iw_request_info *info,
 			     union iwreq_data *data, char *extra)

-- 


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

* [RFC 09/11] cfg80211: combine IWAP handlers
  2009-06-24 12:07 [RFC 00/11] cfg80211 connect API + wireless extension move Johannes Berg
                   ` (7 preceding siblings ...)
  2009-06-24 12:07 ` [RFC 08/11] cfg80211: combine iwfreq implementations Johannes Berg
@ 2009-06-24 12:07 ` Johannes Berg
  2009-06-24 12:07 ` [RFC 10/11] cfg80211: combine IWESSID handlers Johannes Berg
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: Johannes Berg @ 2009-06-24 12:07 UTC (permalink / raw)
  To: linux-wireless

Since we now have IWAP handlers for all modes, we can
combine them into one.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
 include/net/cfg80211.h     |   24 +++++----------------
 net/mac80211/wext.c        |   41 +-----------------------------------
 net/wireless/ibss.c        |    4 ---
 net/wireless/wext-compat.c |   51 ++++++++++++++++++++++++++++++++++++++-------
 net/wireless/wext-compat.h |   12 ++++++++++
 net/wireless/wext-sme.c    |    4 ---
 6 files changed, 64 insertions(+), 72 deletions(-)

--- wireless-testing.orig/include/net/cfg80211.h	2009-06-24 13:54:09.000000000 +0200
+++ wireless-testing/include/net/cfg80211.h	2009-06-24 13:54:10.000000000 +0200
@@ -1530,12 +1530,6 @@ int cfg80211_ibss_wext_siwessid(struct n
 int cfg80211_ibss_wext_giwessid(struct net_device *dev,
 				struct iw_request_info *info,
 				struct iw_point *data, char *ssid);
-int cfg80211_ibss_wext_siwap(struct net_device *dev,
-			     struct iw_request_info *info,
-			     struct sockaddr *ap_addr, char *extra);
-int cfg80211_ibss_wext_giwap(struct net_device *dev,
-			     struct iw_request_info *info,
-			     struct sockaddr *ap_addr, char *extra);
 
 int cfg80211_mgd_wext_siwessid(struct net_device *dev,
 			       struct iw_request_info *info,
@@ -1543,12 +1537,6 @@ int cfg80211_mgd_wext_siwessid(struct ne
 int cfg80211_mgd_wext_giwessid(struct net_device *dev,
 			       struct iw_request_info *info,
 			       struct iw_point *data, char *ssid);
-int cfg80211_mgd_wext_siwap(struct net_device *dev,
-			    struct iw_request_info *info,
-			    struct sockaddr *ap_addr, char *extra);
-int cfg80211_mgd_wext_giwap(struct net_device *dev,
-			    struct iw_request_info *info,
-			    struct sockaddr *ap_addr, char *extra);
 int cfg80211_wext_siwgenie(struct net_device *dev,
 			   struct iw_request_info *info,
 			   struct iw_point *data, char *extra);
@@ -1615,12 +1603,12 @@ int cfg80211_wext_giwpower(struct net_de
 			   struct iw_request_info *info,
 			   struct iw_param *wrq, char *extra);
 
-int cfg80211_wds_wext_siwap(struct net_device *dev,
-			    struct iw_request_info *info,
-			    struct sockaddr *addr, char *extra);
-int cfg80211_wds_wext_giwap(struct net_device *dev,
-			    struct iw_request_info *info,
-			    struct sockaddr *addr, char *extra);
+int cfg80211_wext_siwap(struct net_device *dev,
+			struct iw_request_info *info,
+			struct sockaddr *ap_addr, char *extra);
+int cfg80211_wext_giwap(struct net_device *dev,
+			struct iw_request_info *info,
+			struct sockaddr *ap_addr, char *extra);
 
 /*
  * callbacks for asynchronous cfg80211 methods, notification
--- wireless-testing.orig/net/mac80211/wext.c	2009-06-24 13:54:09.000000000 +0200
+++ wireless-testing/net/mac80211/wext.c	2009-06-24 13:54:10.000000000 +0200
@@ -59,43 +59,6 @@ static int ieee80211_ioctl_giwessid(stru
 }
 
 
-static int ieee80211_ioctl_siwap(struct net_device *dev,
-				 struct iw_request_info *info,
-				 struct sockaddr *ap_addr, char *extra)
-{
-	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-
-	if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
-		return cfg80211_ibss_wext_siwap(dev, info, ap_addr, extra);
-
-	if (sdata->vif.type == NL80211_IFTYPE_STATION)
-		return cfg80211_mgd_wext_siwap(dev, info, ap_addr, extra);
-
-	if (sdata->vif.type == NL80211_IFTYPE_WDS)
-		return cfg80211_wds_wext_siwap(dev, info, ap_addr, extra);
-	return -EOPNOTSUPP;
-}
-
-
-static int ieee80211_ioctl_giwap(struct net_device *dev,
-				 struct iw_request_info *info,
-				 struct sockaddr *ap_addr, char *extra)
-{
-	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-
-	if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
-		return cfg80211_ibss_wext_giwap(dev, info, ap_addr, extra);
-
-	if (sdata->vif.type == NL80211_IFTYPE_STATION)
-		return cfg80211_mgd_wext_giwap(dev, info, ap_addr, extra);
-
-	if (sdata->vif.type == NL80211_IFTYPE_WDS)
-		return cfg80211_wds_wext_giwap(dev, info, ap_addr, extra);
-
-	return -EOPNOTSUPP;
-}
-
-
 /* Structures to export the Wireless Handlers */
 
 static const iw_handler ieee80211_handler[] =
@@ -120,8 +83,8 @@ static const iw_handler ieee80211_handle
 	(iw_handler) NULL,				/* SIOCGIWSPY */
 	(iw_handler) NULL,				/* SIOCSIWTHRSPY */
 	(iw_handler) NULL,				/* SIOCGIWTHRSPY */
-	(iw_handler) ieee80211_ioctl_siwap,		/* SIOCSIWAP */
-	(iw_handler) ieee80211_ioctl_giwap,		/* SIOCGIWAP */
+	(iw_handler) cfg80211_wext_siwap,		/* SIOCSIWAP */
+	(iw_handler) cfg80211_wext_giwap,		/* SIOCGIWAP */
 	(iw_handler) cfg80211_wext_siwmlme,		/* SIOCSIWMLME */
 	(iw_handler) NULL,				/* SIOCGIWAPLIST */
 	(iw_handler) cfg80211_wext_siwscan,		/* SIOCSIWSCAN */
--- wireless-testing.orig/net/wireless/wext-compat.c	2009-06-24 13:54:09.000000000 +0200
+++ wireless-testing/net/wireless/wext-compat.c	2009-06-24 13:54:10.000000000 +0200
@@ -961,9 +961,9 @@ int cfg80211_wext_giwpower(struct net_de
 }
 EXPORT_SYMBOL_GPL(cfg80211_wext_giwpower);
 
-int cfg80211_wds_wext_siwap(struct net_device *dev,
-			    struct iw_request_info *info,
-			    struct sockaddr *addr, char *extra)
+static int cfg80211_wds_wext_siwap(struct net_device *dev,
+				   struct iw_request_info *info,
+				   struct sockaddr *addr, char *extra)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -989,11 +989,10 @@ int cfg80211_wds_wext_siwap(struct net_d
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(cfg80211_wds_wext_siwap);
 
-int cfg80211_wds_wext_giwap(struct net_device *dev,
-			    struct iw_request_info *info,
-			    struct sockaddr *addr, char *extra)
+static int cfg80211_wds_wext_giwap(struct net_device *dev,
+				   struct iw_request_info *info,
+				   struct sockaddr *addr, char *extra)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 
@@ -1104,3 +1103,41 @@ struct iw_statistics *cfg80211_wireless_
 	return &wstats;
 }
 EXPORT_SYMBOL_GPL(cfg80211_wireless_stats);
+
+int cfg80211_wext_siwap(struct net_device *dev,
+			struct iw_request_info *info,
+			struct sockaddr *ap_addr, char *extra)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+	switch (wdev->iftype) {
+	case NL80211_IFTYPE_ADHOC:
+		return cfg80211_ibss_wext_siwap(dev, info, ap_addr, extra);
+	case NL80211_IFTYPE_STATION:
+		return cfg80211_mgd_wext_siwap(dev, info, ap_addr, extra);
+	case NL80211_IFTYPE_WDS:
+		return cfg80211_wds_wext_siwap(dev, info, ap_addr, extra);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_siwap);
+
+int cfg80211_wext_giwap(struct net_device *dev,
+			struct iw_request_info *info,
+			struct sockaddr *ap_addr, char *extra)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+	switch (wdev->iftype) {
+	case NL80211_IFTYPE_ADHOC:
+		return cfg80211_ibss_wext_giwap(dev, info, ap_addr, extra);
+	case NL80211_IFTYPE_STATION:
+		return cfg80211_mgd_wext_giwap(dev, info, ap_addr, extra);
+	case NL80211_IFTYPE_WDS:
+		return cfg80211_wds_wext_giwap(dev, info, ap_addr, extra);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_giwap);
--- wireless-testing.orig/net/wireless/wext-compat.h	2009-06-24 13:54:09.000000000 +0200
+++ wireless-testing/net/wireless/wext-compat.h	2009-06-24 13:54:10.000000000 +0200
@@ -7,6 +7,12 @@ int cfg80211_ibss_wext_siwfreq(struct ne
 int cfg80211_ibss_wext_giwfreq(struct net_device *dev,
 			       struct iw_request_info *info,
 			       struct iw_freq *freq, char *extra);
+int cfg80211_ibss_wext_siwap(struct net_device *dev,
+			     struct iw_request_info *info,
+			     struct sockaddr *ap_addr, char *extra);
+int cfg80211_ibss_wext_giwap(struct net_device *dev,
+			     struct iw_request_info *info,
+			     struct sockaddr *ap_addr, char *extra);
 
 int cfg80211_mgd_wext_siwfreq(struct net_device *dev,
 			      struct iw_request_info *info,
@@ -14,6 +20,12 @@ int cfg80211_mgd_wext_siwfreq(struct net
 int cfg80211_mgd_wext_giwfreq(struct net_device *dev,
 			      struct iw_request_info *info,
 			      struct iw_freq *freq, char *extra);
+int cfg80211_mgd_wext_siwap(struct net_device *dev,
+			    struct iw_request_info *info,
+			    struct sockaddr *ap_addr, char *extra);
+int cfg80211_mgd_wext_giwap(struct net_device *dev,
+			    struct iw_request_info *info,
+			    struct sockaddr *ap_addr, char *extra);
 
 struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy,
 					     struct iw_freq *freq);
--- wireless-testing.orig/net/wireless/ibss.c	2009-06-24 13:54:09.000000000 +0200
+++ wireless-testing/net/wireless/ibss.c	2009-06-24 13:54:10.000000000 +0200
@@ -333,8 +333,6 @@ int cfg80211_ibss_wext_siwap(struct net_
 
 	return cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev);
 }
-/* temporary symbol - mark GPL - in the future the handler won't be */
-EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwap);
 
 int cfg80211_ibss_wext_giwap(struct net_device *dev,
 			     struct iw_request_info *info,
@@ -354,6 +352,4 @@ int cfg80211_ibss_wext_giwap(struct net_
 		memcpy(ap_addr->sa_data, wdev->wext.ibss.bssid, ETH_ALEN);
 	return 0;
 }
-/* temporary symbol - mark GPL - in the future the handler won't be */
-EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_giwap);
 #endif
--- wireless-testing.orig/net/wireless/wext-sme.c	2009-06-24 13:54:09.000000000 +0200
+++ wireless-testing/net/wireless/wext-sme.c	2009-06-24 13:54:10.000000000 +0200
@@ -220,8 +220,6 @@ int cfg80211_mgd_wext_siwap(struct net_d
 
 	return cfg80211_mgd_wext_connect(wiphy_to_dev(wdev->wiphy), wdev);
 }
-/* temporary symbol - mark GPL - in the future the handler won't be */
-EXPORT_SYMBOL_GPL(cfg80211_mgd_wext_siwap);
 
 int cfg80211_mgd_wext_giwap(struct net_device *dev,
 			    struct iw_request_info *info,
@@ -242,8 +240,6 @@ int cfg80211_mgd_wext_giwap(struct net_d
 
 	return 0;
 }
-/* temporary symbol - mark GPL - in the future the handler won't be */
-EXPORT_SYMBOL_GPL(cfg80211_mgd_wext_giwap);
 
 int cfg80211_wext_siwgenie(struct net_device *dev,
 			   struct iw_request_info *info,

-- 


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

* [RFC 10/11] cfg80211: combine IWESSID handlers
  2009-06-24 12:07 [RFC 00/11] cfg80211 connect API + wireless extension move Johannes Berg
                   ` (8 preceding siblings ...)
  2009-06-24 12:07 ` [RFC 09/11] cfg80211: combine IWAP handlers Johannes Berg
@ 2009-06-24 12:07 ` Johannes Berg
  2009-06-24 12:07 ` [RFC 11/11] cfg80211: self-contained wext handling Johannes Berg
  2009-06-24 20:24 ` [RFC 00/11] cfg80211 connect API + wireless extension move Luis R. Rodriguez
  11 siblings, 0 replies; 20+ messages in thread
From: Johannes Berg @ 2009-06-24 12:07 UTC (permalink / raw)
  To: linux-wireless

Since we now have handlers IWESSID for all modes, we can
combine them into one.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
 include/net/cfg80211.h     |   20 ++++++--------------
 net/mac80211/wext.c        |   35 ++---------------------------------
 net/wireless/ibss.c        |    4 ----
 net/wireless/wext-compat.c |   34 ++++++++++++++++++++++++++++++++++
 net/wireless/wext-compat.h |   12 ++++++++++++
 net/wireless/wext-sme.c    |    4 ----
 6 files changed, 54 insertions(+), 55 deletions(-)

--- wireless-testing.orig/include/net/cfg80211.h	2009-06-24 13:54:10.000000000 +0200
+++ wireless-testing/include/net/cfg80211.h	2009-06-24 13:54:10.000000000 +0200
@@ -1524,19 +1524,6 @@ int cfg80211_wext_siwmlme(struct net_dev
 int cfg80211_wext_giwrange(struct net_device *dev,
 			   struct iw_request_info *info,
 			   struct iw_point *data, char *extra);
-int cfg80211_ibss_wext_siwessid(struct net_device *dev,
-				struct iw_request_info *info,
-				struct iw_point *data, char *ssid);
-int cfg80211_ibss_wext_giwessid(struct net_device *dev,
-				struct iw_request_info *info,
-				struct iw_point *data, char *ssid);
-
-int cfg80211_mgd_wext_siwessid(struct net_device *dev,
-			       struct iw_request_info *info,
-			       struct iw_point *data, char *ssid);
-int cfg80211_mgd_wext_giwessid(struct net_device *dev,
-			       struct iw_request_info *info,
-			       struct iw_point *data, char *ssid);
 int cfg80211_wext_siwgenie(struct net_device *dev,
 			   struct iw_request_info *info,
 			   struct iw_point *data, char *extra);
@@ -1553,7 +1540,12 @@ int cfg80211_wext_siwfreq(struct net_dev
 int cfg80211_wext_giwfreq(struct net_device *dev,
 			  struct iw_request_info *info,
 			  struct iw_freq *freq, char *extra);
-
+int cfg80211_wext_siwessid(struct net_device *dev,
+			   struct iw_request_info *info,
+			   struct iw_point *data, char *ssid);
+int cfg80211_wext_giwessid(struct net_device *dev,
+			   struct iw_request_info *info,
+			   struct iw_point *data, char *ssid);
 int cfg80211_wext_siwrate(struct net_device *dev,
 			  struct iw_request_info *info,
 			  struct iw_param *rate, char *extra);
--- wireless-testing.orig/net/wireless/wext-compat.c	2009-06-24 13:54:10.000000000 +0200
+++ wireless-testing/net/wireless/wext-compat.c	2009-06-24 13:54:10.000000000 +0200
@@ -1141,3 +1141,37 @@ int cfg80211_wext_giwap(struct net_devic
 	}
 }
 EXPORT_SYMBOL_GPL(cfg80211_wext_giwap);
+
+int cfg80211_wext_siwessid(struct net_device *dev,
+			   struct iw_request_info *info,
+			   struct iw_point *data, char *ssid)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+	switch (wdev->iftype) {
+	case NL80211_IFTYPE_ADHOC:
+		return cfg80211_ibss_wext_siwessid(dev, info, data, ssid);
+	case NL80211_IFTYPE_STATION:
+		return cfg80211_mgd_wext_siwessid(dev, info, data, ssid);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_siwessid);
+
+int cfg80211_wext_giwessid(struct net_device *dev,
+			   struct iw_request_info *info,
+			   struct iw_point *data, char *ssid)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+	switch (wdev->iftype) {
+	case NL80211_IFTYPE_ADHOC:
+		return cfg80211_ibss_wext_giwessid(dev, info, data, ssid);
+	case NL80211_IFTYPE_STATION:
+		return cfg80211_mgd_wext_giwessid(dev, info, data, ssid);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_giwessid);
--- wireless-testing.orig/net/wireless/wext-compat.h	2009-06-24 13:54:10.000000000 +0200
+++ wireless-testing/net/wireless/wext-compat.h	2009-06-24 13:54:10.000000000 +0200
@@ -13,6 +13,12 @@ int cfg80211_ibss_wext_siwap(struct net_
 int cfg80211_ibss_wext_giwap(struct net_device *dev,
 			     struct iw_request_info *info,
 			     struct sockaddr *ap_addr, char *extra);
+int cfg80211_ibss_wext_siwessid(struct net_device *dev,
+				struct iw_request_info *info,
+				struct iw_point *data, char *ssid);
+int cfg80211_ibss_wext_giwessid(struct net_device *dev,
+				struct iw_request_info *info,
+				struct iw_point *data, char *ssid);
 
 int cfg80211_mgd_wext_siwfreq(struct net_device *dev,
 			      struct iw_request_info *info,
@@ -26,6 +32,12 @@ int cfg80211_mgd_wext_siwap(struct net_d
 int cfg80211_mgd_wext_giwap(struct net_device *dev,
 			    struct iw_request_info *info,
 			    struct sockaddr *ap_addr, char *extra);
+int cfg80211_mgd_wext_siwessid(struct net_device *dev,
+			       struct iw_request_info *info,
+			       struct iw_point *data, char *ssid);
+int cfg80211_mgd_wext_giwessid(struct net_device *dev,
+			       struct iw_request_info *info,
+			       struct iw_point *data, char *ssid);
 
 struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy,
 					     struct iw_freq *freq);
--- wireless-testing.orig/net/mac80211/wext.c	2009-06-24 13:54:10.000000000 +0200
+++ wireless-testing/net/mac80211/wext.c	2009-06-24 13:54:10.000000000 +0200
@@ -27,37 +27,6 @@
 #include "aes_ccm.h"
 
 
-static int ieee80211_ioctl_siwessid(struct net_device *dev,
-				    struct iw_request_info *info,
-				    struct iw_point *data, char *ssid)
-{
-	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-
-	if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
-		return cfg80211_ibss_wext_siwessid(dev, info, data, ssid);
-	else if (sdata->vif.type == NL80211_IFTYPE_STATION)
-		return cfg80211_mgd_wext_siwessid(dev, info, data, ssid);
-
-	return -EOPNOTSUPP;
-}
-
-
-static int ieee80211_ioctl_giwessid(struct net_device *dev,
-				    struct iw_request_info *info,
-				    struct iw_point *data, char *ssid)
-{
-	struct ieee80211_sub_if_data *sdata;
-
-	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-
-	if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
-		return cfg80211_ibss_wext_giwessid(dev, info, data, ssid);
-	else if (sdata->vif.type == NL80211_IFTYPE_STATION)
-		return cfg80211_mgd_wext_giwessid(dev, info, data, ssid);
-
-	return -EOPNOTSUPP;
-}
-
 
 /* Structures to export the Wireless Handlers */
 
@@ -89,8 +58,8 @@ static const iw_handler ieee80211_handle
 	(iw_handler) NULL,				/* SIOCGIWAPLIST */
 	(iw_handler) cfg80211_wext_siwscan,		/* SIOCSIWSCAN */
 	(iw_handler) cfg80211_wext_giwscan,		/* SIOCGIWSCAN */
-	(iw_handler) ieee80211_ioctl_siwessid,		/* SIOCSIWESSID */
-	(iw_handler) ieee80211_ioctl_giwessid,		/* SIOCGIWESSID */
+	(iw_handler) cfg80211_wext_siwessid,		/* SIOCSIWESSID */
+	(iw_handler) cfg80211_wext_giwessid,		/* SIOCGIWESSID */
 	(iw_handler) NULL,				/* SIOCSIWNICKN */
 	(iw_handler) NULL,				/* SIOCGIWNICKN */
 	(iw_handler) NULL,				/* -- hole -- */
--- wireless-testing.orig/net/wireless/wext-sme.c	2009-06-24 13:54:10.000000000 +0200
+++ wireless-testing/net/wireless/wext-sme.c	2009-06-24 13:54:10.000000000 +0200
@@ -145,8 +145,6 @@ int cfg80211_mgd_wext_siwessid(struct ne
 
 	return cfg80211_mgd_wext_connect(wiphy_to_dev(wdev->wiphy), wdev);
 }
-/* temporary symbol - mark GPL - in the future the handler won't be */
-EXPORT_SYMBOL_GPL(cfg80211_mgd_wext_siwessid);
 
 int cfg80211_mgd_wext_giwessid(struct net_device *dev,
 			       struct iw_request_info *info,
@@ -173,8 +171,6 @@ int cfg80211_mgd_wext_giwessid(struct ne
 
 	return 0;
 }
-/* temporary symbol - mark GPL - in the future the handler won't be */
-EXPORT_SYMBOL_GPL(cfg80211_mgd_wext_giwessid);
 
 int cfg80211_mgd_wext_siwap(struct net_device *dev,
 			    struct iw_request_info *info,
--- wireless-testing.orig/net/wireless/ibss.c	2009-06-24 13:54:10.000000000 +0200
+++ wireless-testing/net/wireless/ibss.c	2009-06-24 13:54:10.000000000 +0200
@@ -257,8 +257,6 @@ int cfg80211_ibss_wext_siwessid(struct n
 
 	return cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev);
 }
-/* temporary symbol - mark GPL - in the future the handler won't be */
-EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwessid);
 
 int cfg80211_ibss_wext_giwessid(struct net_device *dev,
 				struct iw_request_info *info,
@@ -284,8 +282,6 @@ int cfg80211_ibss_wext_giwessid(struct n
 
 	return 0;
 }
-/* temporary symbol - mark GPL - in the future the handler won't be */
-EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_giwessid);
 
 int cfg80211_ibss_wext_siwap(struct net_device *dev,
 			     struct iw_request_info *info,

-- 


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

* [RFC 11/11] cfg80211: self-contained wext handling
  2009-06-24 12:07 [RFC 00/11] cfg80211 connect API + wireless extension move Johannes Berg
                   ` (9 preceding siblings ...)
  2009-06-24 12:07 ` [RFC 10/11] cfg80211: combine IWESSID handlers Johannes Berg
@ 2009-06-24 12:07 ` Johannes Berg
  2009-06-24 20:24 ` [RFC 00/11] cfg80211 connect API + wireless extension move Luis R. Rodriguez
  11 siblings, 0 replies; 20+ messages in thread
From: Johannes Berg @ 2009-06-24 12:07 UTC (permalink / raw)
  To: linux-wireless

Finally! This is what you've all been waiting for!

This patch makes cfg80211 take care of wext emulation
_completely_ by itself, the driver doesn't even need
to use the handlers and create a handler struct etc.
any more, all handled by cfg80211. This means we can
also clean up mac80211's Kconfig and make it possible
to build mac80211 w/o WEXT now!

		WEXT IS DEAD.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
 include/net/cfg80211.h     |  103 ------------------
 net/mac80211/Kconfig       |    1 
 net/mac80211/Makefile      |    1 
 net/mac80211/ieee80211_i.h |    4 
 net/mac80211/iface.c       |    1 
 net/mac80211/scan.c        |    1 
 net/mac80211/wext.c        |   98 -----------------
 net/wireless/core.c        |    2 
 net/wireless/scan.c        |    3 
 net/wireless/wext-compat.c |  257 +++++++++++++++++++++++++--------------------
 net/wireless/wext-compat.h |   14 ++
 net/wireless/wext-sme.c    |    2 
 12 files changed, 164 insertions(+), 323 deletions(-)

--- wireless-testing.orig/net/mac80211/wext.c	2009-06-24 13:54:10.000000000 +0200
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,98 +0,0 @@
-/*
- * Copyright 2002-2005, Instant802 Networks, Inc.
- * Copyright 2005-2006, Devicescape Software, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/skbuff.h>
-#include <linux/etherdevice.h>
-#include <linux/if_arp.h>
-#include <linux/wireless.h>
-#include <net/iw_handler.h>
-#include <asm/uaccess.h>
-
-#include <net/mac80211.h>
-#include "ieee80211_i.h"
-#include "led.h"
-#include "rate.h"
-#include "wpa.h"
-#include "aes_ccm.h"
-
-
-
-/* Structures to export the Wireless Handlers */
-
-static const iw_handler ieee80211_handler[] =
-{
-	(iw_handler) NULL,				/* SIOCSIWCOMMIT */
-	(iw_handler) cfg80211_wext_giwname,		/* SIOCGIWNAME */
-	(iw_handler) NULL,				/* SIOCSIWNWID */
-	(iw_handler) NULL,				/* SIOCGIWNWID */
-	(iw_handler) cfg80211_wext_siwfreq,		/* SIOCSIWFREQ */
-	(iw_handler) cfg80211_wext_giwfreq,		/* SIOCGIWFREQ */
-	(iw_handler) cfg80211_wext_siwmode,		/* SIOCSIWMODE */
-	(iw_handler) cfg80211_wext_giwmode,		/* SIOCGIWMODE */
-	(iw_handler) NULL,				/* SIOCSIWSENS */
-	(iw_handler) NULL,				/* SIOCGIWSENS */
-	(iw_handler) NULL /* not used */,		/* SIOCSIWRANGE */
-	(iw_handler) cfg80211_wext_giwrange,		/* SIOCGIWRANGE */
-	(iw_handler) NULL /* not used */,		/* SIOCSIWPRIV */
-	(iw_handler) NULL /* kernel code */,		/* SIOCGIWPRIV */
-	(iw_handler) NULL /* not used */,		/* SIOCSIWSTATS */
-	(iw_handler) NULL /* kernel code */,		/* SIOCGIWSTATS */
-	(iw_handler) NULL,				/* SIOCSIWSPY */
-	(iw_handler) NULL,				/* SIOCGIWSPY */
-	(iw_handler) NULL,				/* SIOCSIWTHRSPY */
-	(iw_handler) NULL,				/* SIOCGIWTHRSPY */
-	(iw_handler) cfg80211_wext_siwap,		/* SIOCSIWAP */
-	(iw_handler) cfg80211_wext_giwap,		/* SIOCGIWAP */
-	(iw_handler) cfg80211_wext_siwmlme,		/* SIOCSIWMLME */
-	(iw_handler) NULL,				/* SIOCGIWAPLIST */
-	(iw_handler) cfg80211_wext_siwscan,		/* SIOCSIWSCAN */
-	(iw_handler) cfg80211_wext_giwscan,		/* SIOCGIWSCAN */
-	(iw_handler) cfg80211_wext_siwessid,		/* SIOCSIWESSID */
-	(iw_handler) cfg80211_wext_giwessid,		/* SIOCGIWESSID */
-	(iw_handler) NULL,				/* SIOCSIWNICKN */
-	(iw_handler) NULL,				/* SIOCGIWNICKN */
-	(iw_handler) NULL,				/* -- hole -- */
-	(iw_handler) NULL,				/* -- hole -- */
-	(iw_handler) cfg80211_wext_siwrate,		/* SIOCSIWRATE */
-	(iw_handler) cfg80211_wext_giwrate,		/* SIOCGIWRATE */
-	(iw_handler) cfg80211_wext_siwrts,		/* SIOCSIWRTS */
-	(iw_handler) cfg80211_wext_giwrts,		/* SIOCGIWRTS */
-	(iw_handler) cfg80211_wext_siwfrag,		/* SIOCSIWFRAG */
-	(iw_handler) cfg80211_wext_giwfrag,		/* SIOCGIWFRAG */
-	(iw_handler) cfg80211_wext_siwtxpower,		/* SIOCSIWTXPOW */
-	(iw_handler) cfg80211_wext_giwtxpower,		/* SIOCGIWTXPOW */
-	(iw_handler) cfg80211_wext_siwretry,		/* SIOCSIWRETRY */
-	(iw_handler) cfg80211_wext_giwretry,		/* SIOCGIWRETRY */
-	(iw_handler) cfg80211_wext_siwencode,		/* SIOCSIWENCODE */
-	(iw_handler) cfg80211_wext_giwencode,		/* SIOCGIWENCODE */
-	(iw_handler) cfg80211_wext_siwpower,		/* SIOCSIWPOWER */
-	(iw_handler) cfg80211_wext_giwpower,		/* SIOCGIWPOWER */
-	(iw_handler) NULL,				/* -- hole -- */
-	(iw_handler) NULL,				/* -- hole -- */
-	(iw_handler) cfg80211_wext_siwgenie,		/* SIOCSIWGENIE */
-	(iw_handler) NULL,				/* SIOCGIWGENIE */
-	(iw_handler) cfg80211_wext_siwauth,		/* SIOCSIWAUTH */
-	(iw_handler) cfg80211_wext_giwauth,		/* SIOCGIWAUTH */
-	(iw_handler) cfg80211_wext_siwencodeext,	/* SIOCSIWENCODEEXT */
-	(iw_handler) NULL,				/* SIOCGIWENCODEEXT */
-	(iw_handler) NULL,				/* SIOCSIWPMKSA */
-	(iw_handler) NULL,				/* -- hole -- */
-};
-
-const struct iw_handler_def ieee80211_iw_handler_def =
-{
-	.num_standard	= ARRAY_SIZE(ieee80211_handler),
-	.standard	= (iw_handler *) ieee80211_handler,
-	.get_wireless_stats = cfg80211_wireless_stats,
-};
--- wireless-testing.orig/net/wireless/wext-compat.c	2009-06-24 13:54:10.000000000 +0200
+++ wireless-testing/net/wireless/wext-compat.c	2009-06-24 13:54:11.000000000 +0200
@@ -17,9 +17,9 @@
 #include "wext-compat.h"
 #include "core.h"
 
-int cfg80211_wext_giwname(struct net_device *dev,
-			  struct iw_request_info *info,
-			  char *name, char *extra)
+static int cfg80211_wext_giwname(struct net_device *dev,
+				 struct iw_request_info *info,
+				 char *name, char *extra)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct ieee80211_supported_band *sband;
@@ -59,10 +59,10 @@ int cfg80211_wext_giwname(struct net_dev
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_giwname);
 
-int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info,
-			  u32 *mode, char *extra)
+static int cfg80211_wext_siwmode(struct net_device *dev,
+				 struct iw_request_info *info,
+				 u32 *mode, char *extra)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct cfg80211_registered_device *rdev;
@@ -110,10 +110,10 @@ int cfg80211_wext_siwmode(struct net_dev
 
 	return ret;
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_siwmode);
 
-int cfg80211_wext_giwmode(struct net_device *dev, struct iw_request_info *info,
-			  u32 *mode, char *extra)
+static int cfg80211_wext_giwmode(struct net_device *dev,
+				 struct iw_request_info *info,
+				 u32 *mode, char *extra)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 
@@ -145,12 +145,11 @@ int cfg80211_wext_giwmode(struct net_dev
 	}
 	return 0;
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_giwmode);
 
 
-int cfg80211_wext_giwrange(struct net_device *dev,
-			   struct iw_request_info *info,
-			   struct iw_point *data, char *extra)
+static int cfg80211_wext_giwrange(struct net_device *dev,
+				  struct iw_request_info *info,
+				  struct iw_point *data, char *extra)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct iw_range *range = (struct iw_range *) extra;
@@ -260,8 +259,6 @@ int cfg80211_wext_giwrange(struct net_de
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_giwrange);
-
 
 /**
  * cfg80211_wext_freq - get wext frequency for non-"auto"
@@ -303,9 +300,9 @@ struct ieee80211_channel *cfg80211_wext_
 	return chan;
 }
 
-int cfg80211_wext_siwrts(struct net_device *dev,
-			 struct iw_request_info *info,
-			 struct iw_param *rts, char *extra)
+static int cfg80211_wext_siwrts(struct net_device *dev,
+				struct iw_request_info *info,
+				struct iw_param *rts, char *extra)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -326,11 +323,10 @@ int cfg80211_wext_siwrts(struct net_devi
 
 	return err;
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_siwrts);
 
-int cfg80211_wext_giwrts(struct net_device *dev,
-			 struct iw_request_info *info,
-			 struct iw_param *rts, char *extra)
+static int cfg80211_wext_giwrts(struct net_device *dev,
+				struct iw_request_info *info,
+				struct iw_param *rts, char *extra)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 
@@ -340,11 +336,10 @@ int cfg80211_wext_giwrts(struct net_devi
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_giwrts);
 
-int cfg80211_wext_siwfrag(struct net_device *dev,
-			  struct iw_request_info *info,
-			  struct iw_param *frag, char *extra)
+static int cfg80211_wext_siwfrag(struct net_device *dev,
+				 struct iw_request_info *info,
+				 struct iw_param *frag, char *extra)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -367,11 +362,10 @@ int cfg80211_wext_siwfrag(struct net_dev
 
 	return err;
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_siwfrag);
 
-int cfg80211_wext_giwfrag(struct net_device *dev,
-			  struct iw_request_info *info,
-			  struct iw_param *frag, char *extra)
+static int cfg80211_wext_giwfrag(struct net_device *dev,
+				 struct iw_request_info *info,
+				 struct iw_param *frag, char *extra)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 
@@ -381,11 +375,10 @@ int cfg80211_wext_giwfrag(struct net_dev
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_giwfrag);
 
-int cfg80211_wext_siwretry(struct net_device *dev,
-			   struct iw_request_info *info,
-			   struct iw_param *retry, char *extra)
+static int cfg80211_wext_siwretry(struct net_device *dev,
+				  struct iw_request_info *info,
+				  struct iw_param *retry, char *extra)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -422,11 +415,10 @@ int cfg80211_wext_siwretry(struct net_de
 
 	return err;
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_siwretry);
 
-int cfg80211_wext_giwretry(struct net_device *dev,
-			   struct iw_request_info *info,
-			   struct iw_param *retry, char *extra)
+static int cfg80211_wext_giwretry(struct net_device *dev,
+				  struct iw_request_info *info,
+				  struct iw_param *retry, char *extra)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 
@@ -452,7 +444,6 @@ int cfg80211_wext_giwretry(struct net_de
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_giwretry);
 
 static int cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
 				   struct net_device *dev, const u8 *addr,
@@ -519,9 +510,9 @@ static int cfg80211_set_encryption(struc
 	}
 }
 
-int cfg80211_wext_siwencode(struct net_device *dev,
-			    struct iw_request_info *info,
-			    struct iw_point *erq, char *keybuf)
+static int cfg80211_wext_siwencode(struct net_device *dev,
+				   struct iw_request_info *info,
+				   struct iw_point *erq, char *keybuf)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -569,11 +560,10 @@ int cfg80211_wext_siwencode(struct net_d
 				       wdev->wext.default_key == -1,
 				       idx, &params);
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_siwencode);
 
-int cfg80211_wext_siwencodeext(struct net_device *dev,
-			       struct iw_request_info *info,
-			       struct iw_point *erq, char *extra)
+static int cfg80211_wext_siwencodeext(struct net_device *dev,
+				      struct iw_request_info *info,
+				      struct iw_point *erq, char *extra)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -655,7 +645,6 @@ int cfg80211_wext_siwencodeext(struct ne
 			ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY,
 			idx, &params);
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_siwencodeext);
 
 struct giwencode_cookie {
 	size_t buflen;
@@ -675,9 +664,9 @@ static void giwencode_get_key_cb(void *c
 	memcpy(data->keybuf, params->key, data->buflen);
 }
 
-int cfg80211_wext_giwencode(struct net_device *dev,
-			    struct iw_request_info *info,
-			    struct iw_point *erq, char *keybuf)
+static int cfg80211_wext_giwencode(struct net_device *dev,
+				   struct iw_request_info *info,
+				   struct iw_point *erq, char *keybuf)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -718,11 +707,10 @@ int cfg80211_wext_giwencode(struct net_d
 
 	return err;
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_giwencode);
 
-int cfg80211_wext_siwfreq(struct net_device *dev,
-			  struct iw_request_info *info,
-			  struct iw_freq *freq, char *extra)
+static int cfg80211_wext_siwfreq(struct net_device *dev,
+				 struct iw_request_info *info,
+				 struct iw_freq *freq, char *extra)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -748,11 +736,10 @@ int cfg80211_wext_siwfreq(struct net_dev
 		return 0;
 	}
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_siwfreq);
 
-int cfg80211_wext_giwfreq(struct net_device *dev,
-			  struct iw_request_info *info,
-			  struct iw_freq *freq, char *extra)
+static int cfg80211_wext_giwfreq(struct net_device *dev,
+				 struct iw_request_info *info,
+				 struct iw_freq *freq, char *extra)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -770,11 +757,10 @@ int cfg80211_wext_giwfreq(struct net_dev
 		return 0;
 	}
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_giwfreq);
 
-int cfg80211_wext_siwtxpower(struct net_device *dev,
-			     struct iw_request_info *info,
-			     union iwreq_data *data, char *extra)
+static int cfg80211_wext_siwtxpower(struct net_device *dev,
+				    struct iw_request_info *info,
+				    union iwreq_data *data, char *extra)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -823,11 +809,10 @@ int cfg80211_wext_siwtxpower(struct net_
 
 	return rdev->ops->set_tx_power(wdev->wiphy, type, dbm);;
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_siwtxpower);
 
-int cfg80211_wext_giwtxpower(struct net_device *dev,
-			     struct iw_request_info *info,
-			     union iwreq_data *data, char *extra)
+static int cfg80211_wext_giwtxpower(struct net_device *dev,
+				    struct iw_request_info *info,
+				    union iwreq_data *data, char *extra)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -853,11 +838,10 @@ int cfg80211_wext_giwtxpower(struct net_
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_giwtxpower);
 
-int cfg80211_wext_siwauth(struct net_device *dev,
-			  struct iw_request_info *info,
-			  struct iw_param *data, char *extra)
+static int cfg80211_wext_siwauth(struct net_device *dev,
+				 struct iw_request_info *info,
+				 struct iw_param *data, char *extra)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	int ret;
@@ -889,21 +873,19 @@ int cfg80211_wext_siwauth(struct net_dev
 
 	return ret;
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_siwauth);
 
-int cfg80211_wext_giwauth(struct net_device *dev,
-			  struct iw_request_info *info,
-			  struct iw_param *data, char *extra)
+static int cfg80211_wext_giwauth(struct net_device *dev,
+				 struct iw_request_info *info,
+				 struct iw_param *data, char *extra)
 {
 	/* XXX: what do we need? */
 
 	return -EOPNOTSUPP;
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_giwauth);
 
-int cfg80211_wext_siwpower(struct net_device *dev,
-			   struct iw_request_info *info,
-			   struct iw_param *wrq, char *extra)
+static int cfg80211_wext_siwpower(struct net_device *dev,
+				  struct iw_request_info *info,
+				  struct iw_param *wrq, char *extra)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -947,11 +929,10 @@ int cfg80211_wext_siwpower(struct net_de
 	return 0;
 
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_siwpower);
 
-int cfg80211_wext_giwpower(struct net_device *dev,
-			   struct iw_request_info *info,
-			   struct iw_param *wrq, char *extra)
+static int cfg80211_wext_giwpower(struct net_device *dev,
+				  struct iw_request_info *info,
+				  struct iw_param *wrq, char *extra)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 
@@ -959,7 +940,6 @@ int cfg80211_wext_giwpower(struct net_de
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_giwpower);
 
 static int cfg80211_wds_wext_siwap(struct net_device *dev,
 				   struct iw_request_info *info,
@@ -1004,11 +984,10 @@ static int cfg80211_wds_wext_giwap(struc
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(cfg80211_wds_wext_giwap);
 
-int cfg80211_wext_siwrate(struct net_device *dev,
-			  struct iw_request_info *info,
-			  struct iw_param *rate, char *extra)
+static int cfg80211_wext_siwrate(struct net_device *dev,
+				 struct iw_request_info *info,
+				 struct iw_param *rate, char *extra)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -1018,11 +997,10 @@ int cfg80211_wext_siwrate(struct net_dev
 
 	return rdev->ops->set_bitrate(wdev->wiphy, dev, rate);
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_siwrate);
 
-int cfg80211_wext_giwrate(struct net_device *dev,
-			  struct iw_request_info *info,
-			  struct iw_param *rate, char *extra)
+static int cfg80211_wext_giwrate(struct net_device *dev,
+				 struct iw_request_info *info,
+				 struct iw_param *rate, char *extra)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -1032,10 +1010,9 @@ int cfg80211_wext_giwrate(struct net_dev
 
 	return rdev->ops->get_bitrate(wdev->wiphy, dev, rate);
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_giwrate);
 
 /* Get wireless statistics.  Called by /proc/net/wireless and by SIOCGIWSTATS */
-struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev)
+static struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -1102,11 +1079,10 @@ struct iw_statistics *cfg80211_wireless_
 
 	return &wstats;
 }
-EXPORT_SYMBOL_GPL(cfg80211_wireless_stats);
 
-int cfg80211_wext_siwap(struct net_device *dev,
-			struct iw_request_info *info,
-			struct sockaddr *ap_addr, char *extra)
+static int cfg80211_wext_siwap(struct net_device *dev,
+			       struct iw_request_info *info,
+			       struct sockaddr *ap_addr, char *extra)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 
@@ -1121,11 +1097,10 @@ int cfg80211_wext_siwap(struct net_devic
 		return -EOPNOTSUPP;
 	}
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_siwap);
 
-int cfg80211_wext_giwap(struct net_device *dev,
-			struct iw_request_info *info,
-			struct sockaddr *ap_addr, char *extra)
+static int cfg80211_wext_giwap(struct net_device *dev,
+			       struct iw_request_info *info,
+			       struct sockaddr *ap_addr, char *extra)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 
@@ -1140,11 +1115,10 @@ int cfg80211_wext_giwap(struct net_devic
 		return -EOPNOTSUPP;
 	}
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_giwap);
 
-int cfg80211_wext_siwessid(struct net_device *dev,
-			   struct iw_request_info *info,
-			   struct iw_point *data, char *ssid)
+static int cfg80211_wext_siwessid(struct net_device *dev,
+				  struct iw_request_info *info,
+				  struct iw_point *data, char *ssid)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 
@@ -1157,11 +1131,10 @@ int cfg80211_wext_siwessid(struct net_de
 		return -EOPNOTSUPP;
 	}
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_siwessid);
 
-int cfg80211_wext_giwessid(struct net_device *dev,
-			   struct iw_request_info *info,
-			   struct iw_point *data, char *ssid)
+static int cfg80211_wext_giwessid(struct net_device *dev,
+				  struct iw_request_info *info,
+				  struct iw_point *data, char *ssid)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 
@@ -1174,4 +1147,68 @@ int cfg80211_wext_giwessid(struct net_de
 		return -EOPNOTSUPP;
 	}
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_giwessid);
+
+static const iw_handler ieee80211_handler[] = {
+	(iw_handler) NULL,				/* SIOCSIWCOMMIT */
+	(iw_handler) cfg80211_wext_giwname,		/* SIOCGIWNAME */
+	(iw_handler) NULL,				/* SIOCSIWNWID */
+	(iw_handler) NULL,				/* SIOCGIWNWID */
+	(iw_handler) cfg80211_wext_siwfreq,		/* SIOCSIWFREQ */
+	(iw_handler) cfg80211_wext_giwfreq,		/* SIOCGIWFREQ */
+	(iw_handler) cfg80211_wext_siwmode,		/* SIOCSIWMODE */
+	(iw_handler) cfg80211_wext_giwmode,		/* SIOCGIWMODE */
+	(iw_handler) NULL,				/* SIOCSIWSENS */
+	(iw_handler) NULL,				/* SIOCGIWSENS */
+	(iw_handler) NULL /* not used */,		/* SIOCSIWRANGE */
+	(iw_handler) cfg80211_wext_giwrange,		/* SIOCGIWRANGE */
+	(iw_handler) NULL /* not used */,		/* SIOCSIWPRIV */
+	(iw_handler) NULL /* kernel code */,		/* SIOCGIWPRIV */
+	(iw_handler) NULL /* not used */,		/* SIOCSIWSTATS */
+	(iw_handler) NULL /* kernel code */,		/* SIOCGIWSTATS */
+	(iw_handler) NULL,				/* SIOCSIWSPY */
+	(iw_handler) NULL,				/* SIOCGIWSPY */
+	(iw_handler) NULL,				/* SIOCSIWTHRSPY */
+	(iw_handler) NULL,				/* SIOCGIWTHRSPY */
+	(iw_handler) cfg80211_wext_siwap,		/* SIOCSIWAP */
+	(iw_handler) cfg80211_wext_giwap,		/* SIOCGIWAP */
+	(iw_handler) cfg80211_wext_siwmlme,		/* SIOCSIWMLME */
+	(iw_handler) NULL,				/* SIOCGIWAPLIST */
+	(iw_handler) cfg80211_wext_siwscan,		/* SIOCSIWSCAN */
+	(iw_handler) cfg80211_wext_giwscan,		/* SIOCGIWSCAN */
+	(iw_handler) cfg80211_wext_siwessid,		/* SIOCSIWESSID */
+	(iw_handler) cfg80211_wext_giwessid,		/* SIOCGIWESSID */
+	(iw_handler) NULL,				/* SIOCSIWNICKN */
+	(iw_handler) NULL,				/* SIOCGIWNICKN */
+	(iw_handler) NULL,				/* -- hole -- */
+	(iw_handler) NULL,				/* -- hole -- */
+	(iw_handler) cfg80211_wext_siwrate,		/* SIOCSIWRATE */
+	(iw_handler) cfg80211_wext_giwrate,		/* SIOCGIWRATE */
+	(iw_handler) cfg80211_wext_siwrts,		/* SIOCSIWRTS */
+	(iw_handler) cfg80211_wext_giwrts,		/* SIOCGIWRTS */
+	(iw_handler) cfg80211_wext_siwfrag,		/* SIOCSIWFRAG */
+	(iw_handler) cfg80211_wext_giwfrag,		/* SIOCGIWFRAG */
+	(iw_handler) cfg80211_wext_siwtxpower,		/* SIOCSIWTXPOW */
+	(iw_handler) cfg80211_wext_giwtxpower,		/* SIOCGIWTXPOW */
+	(iw_handler) cfg80211_wext_siwretry,		/* SIOCSIWRETRY */
+	(iw_handler) cfg80211_wext_giwretry,		/* SIOCGIWRETRY */
+	(iw_handler) cfg80211_wext_siwencode,		/* SIOCSIWENCODE */
+	(iw_handler) cfg80211_wext_giwencode,		/* SIOCGIWENCODE */
+	(iw_handler) cfg80211_wext_siwpower,		/* SIOCSIWPOWER */
+	(iw_handler) cfg80211_wext_giwpower,		/* SIOCGIWPOWER */
+	(iw_handler) NULL,				/* -- hole -- */
+	(iw_handler) NULL,				/* -- hole -- */
+	(iw_handler) cfg80211_wext_siwgenie,		/* SIOCSIWGENIE */
+	(iw_handler) NULL,				/* SIOCGIWGENIE */
+	(iw_handler) cfg80211_wext_siwauth,		/* SIOCSIWAUTH */
+	(iw_handler) cfg80211_wext_giwauth,		/* SIOCGIWAUTH */
+	(iw_handler) cfg80211_wext_siwencodeext,	/* SIOCSIWENCODEEXT */
+	(iw_handler) NULL,				/* SIOCGIWENCODEEXT */
+	(iw_handler) NULL,				/* SIOCSIWPMKSA */
+	(iw_handler) NULL,				/* -- hole -- */
+};
+
+const struct iw_handler_def cfg80211_wext_handler = {
+	.num_standard	= ARRAY_SIZE(ieee80211_handler),
+	.standard	= (iw_handler *) ieee80211_handler,
+	.get_wireless_stats = cfg80211_wireless_stats,
+};
--- wireless-testing.orig/net/wireless/wext-compat.h	2009-06-24 13:54:10.000000000 +0200
+++ wireless-testing/net/wireless/wext-compat.h	2009-06-24 13:54:11.000000000 +0200
@@ -38,8 +38,22 @@ int cfg80211_mgd_wext_siwessid(struct ne
 int cfg80211_mgd_wext_giwessid(struct net_device *dev,
 			       struct iw_request_info *info,
 			       struct iw_point *data, char *ssid);
+int cfg80211_wext_siwgenie(struct net_device *dev,
+			   struct iw_request_info *info,
+			   struct iw_point *data, char *extra);
+int cfg80211_wext_siwmlme(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_point *data, char *extra);
+
+int cfg80211_wext_siwscan(struct net_device *dev,
+			  struct iw_request_info *info,
+			  union iwreq_data *wrqu, char *extra);
+int cfg80211_wext_giwscan(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_point *data, char *extra);
 
 struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy,
 					     struct iw_freq *freq);
 
+extern const struct iw_handler_def cfg80211_wext_handler;
 #endif /* __WEXT_COMPAT */
--- wireless-testing.orig/net/mac80211/Kconfig	2009-06-24 13:54:07.000000000 +0200
+++ wireless-testing/net/mac80211/Kconfig	2009-06-24 13:54:11.000000000 +0200
@@ -6,7 +6,6 @@ config MAC80211
 	select CRYPTO_ARC4
 	select CRYPTO_AES
 	select CRC32
-	select WIRELESS_EXT
 	---help---
 	  This option enables the hardware independent IEEE 802.11
 	  networking stack.
--- wireless-testing.orig/net/mac80211/Makefile	2009-06-24 13:48:25.000000000 +0200
+++ wireless-testing/net/mac80211/Makefile	2009-06-24 13:54:11.000000000 +0200
@@ -3,7 +3,6 @@ obj-$(CONFIG_MAC80211) += mac80211.o
 # mac80211 objects
 mac80211-y := \
 	main.o \
-	wext.o \
 	sta_info.o \
 	wep.o \
 	wpa.o \
--- wireless-testing.orig/net/mac80211/scan.c	2009-06-24 13:48:25.000000000 +0200
+++ wireless-testing/net/mac80211/scan.c	2009-06-24 13:54:11.000000000 +0200
@@ -18,7 +18,6 @@
 #include <linux/if_arp.h>
 #include <linux/rtnetlink.h>
 #include <net/mac80211.h>
-#include <net/iw_handler.h>
 
 #include "ieee80211_i.h"
 #include "driver-ops.h"
--- wireless-testing.orig/net/mac80211/ieee80211_i.h	2009-06-24 13:54:04.000000000 +0200
+++ wireless-testing/net/mac80211/ieee80211_i.h	2009-06-24 13:54:11.000000000 +0200
@@ -24,7 +24,6 @@
 #include <linux/spinlock.h>
 #include <linux/etherdevice.h>
 #include <net/cfg80211.h>
-#include <net/iw_handler.h>
 #include <net/mac80211.h>
 #include "key.h"
 #include "sta_info.h"
@@ -935,9 +934,6 @@ void ieee80211_bss_info_change_notify(st
 void ieee80211_configure_filter(struct ieee80211_local *local);
 u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata);
 
-/* wireless extensions */
-extern const struct iw_handler_def ieee80211_iw_handler_def;
-
 /* STA code */
 void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata);
 ieee80211_rx_result ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata,
--- wireless-testing.orig/net/mac80211/iface.c	2009-06-24 13:53:16.000000000 +0200
+++ wireless-testing/net/mac80211/iface.c	2009-06-24 13:54:11.000000000 +0200
@@ -694,7 +694,6 @@ static void ieee80211_if_setup(struct ne
 {
 	ether_setup(dev);
 	dev->netdev_ops = &ieee80211_dataif_ops;
-	dev->wireless_handlers = &ieee80211_iw_handler_def;
 	dev->destructor = free_netdev;
 }
 
--- wireless-testing.orig/net/wireless/scan.c	2009-06-24 13:54:06.000000000 +0200
+++ wireless-testing/net/wireless/scan.c	2009-06-24 13:54:11.000000000 +0200
@@ -14,6 +14,7 @@
 #include <net/iw_handler.h>
 #include "core.h"
 #include "nl80211.h"
+#include "wext-compat.h"
 
 #define IEEE80211_SCAN_RESULT_EXPIRE	(10 * HZ)
 
@@ -661,7 +662,6 @@ int cfg80211_wext_siwscan(struct net_dev
 	cfg80211_put_dev(rdev);
 	return err;
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_siwscan);
 
 static void ieee80211_scan_add_ies(struct iw_request_info *info,
 				   struct cfg80211_bss *bss,
@@ -970,5 +970,4 @@ int cfg80211_wext_giwscan(struct net_dev
 	cfg80211_put_dev(rdev);
 	return res;
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_giwscan);
 #endif
--- wireless-testing.orig/net/wireless/core.c	2009-06-24 13:54:07.000000000 +0200
+++ wireless-testing/net/wireless/core.c	2009-06-24 13:54:11.000000000 +0200
@@ -19,6 +19,7 @@
 #include "core.h"
 #include "sysfs.h"
 #include "debugfs.h"
+#include "wext-compat.h"
 
 /* name for sysfs, %d is appended */
 #define PHY_NAME "phy"
@@ -552,6 +553,7 @@ static int cfg80211_netdev_notifier_call
 		wdev->sme_state = CFG80211_SME_IDLE;
 		mutex_unlock(&rdev->devlist_mtx);
 #ifdef CONFIG_WIRELESS_EXT
+		dev->wireless_handlers = &cfg80211_wext_handler;
 		wdev->wext.default_key = -1;
 		wdev->wext.default_mgmt_key = -1;
 		wdev->wext.ps = CONFIG_CFG80211_DEFAULT_PS_VALUE;
--- wireless-testing.orig/include/net/cfg80211.h	2009-06-24 13:54:10.000000000 +0200
+++ wireless-testing/include/net/cfg80211.h	2009-06-24 13:54:11.000000000 +0200
@@ -1500,109 +1500,6 @@ extern int freq_reg_info(struct wiphy *w
 			 const struct ieee80211_reg_rule **reg_rule);
 
 /*
- * Temporary wext handlers & helper functions
- *
- * In the future cfg80211 will simply assign the entire wext handler
- * structure to netdevs it manages, but we're not there yet.
- */
-int cfg80211_wext_giwname(struct net_device *dev,
-			  struct iw_request_info *info,
-			  char *name, char *extra);
-int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info,
-			  u32 *mode, char *extra);
-int cfg80211_wext_giwmode(struct net_device *dev, struct iw_request_info *info,
-			  u32 *mode, char *extra);
-int cfg80211_wext_siwscan(struct net_device *dev,
-			  struct iw_request_info *info,
-			  union iwreq_data *wrqu, char *extra);
-int cfg80211_wext_giwscan(struct net_device *dev,
-			  struct iw_request_info *info,
-			  struct iw_point *data, char *extra);
-int cfg80211_wext_siwmlme(struct net_device *dev,
-			  struct iw_request_info *info,
-			  struct iw_point *data, char *extra);
-int cfg80211_wext_giwrange(struct net_device *dev,
-			   struct iw_request_info *info,
-			   struct iw_point *data, char *extra);
-int cfg80211_wext_siwgenie(struct net_device *dev,
-			   struct iw_request_info *info,
-			   struct iw_point *data, char *extra);
-int cfg80211_wext_siwauth(struct net_device *dev,
-			  struct iw_request_info *info,
-			  struct iw_param *data, char *extra);
-int cfg80211_wext_giwauth(struct net_device *dev,
-			  struct iw_request_info *info,
-			  struct iw_param *data, char *extra);
-
-int cfg80211_wext_siwfreq(struct net_device *dev,
-			  struct iw_request_info *info,
-			  struct iw_freq *freq, char *extra);
-int cfg80211_wext_giwfreq(struct net_device *dev,
-			  struct iw_request_info *info,
-			  struct iw_freq *freq, char *extra);
-int cfg80211_wext_siwessid(struct net_device *dev,
-			   struct iw_request_info *info,
-			   struct iw_point *data, char *ssid);
-int cfg80211_wext_giwessid(struct net_device *dev,
-			   struct iw_request_info *info,
-			   struct iw_point *data, char *ssid);
-int cfg80211_wext_siwrate(struct net_device *dev,
-			  struct iw_request_info *info,
-			  struct iw_param *rate, char *extra);
-int cfg80211_wext_giwrate(struct net_device *dev,
-			  struct iw_request_info *info,
-			  struct iw_param *rate, char *extra);
-
-int cfg80211_wext_siwrts(struct net_device *dev,
-			 struct iw_request_info *info,
-			 struct iw_param *rts, char *extra);
-int cfg80211_wext_giwrts(struct net_device *dev,
-			 struct iw_request_info *info,
-			 struct iw_param *rts, char *extra);
-int cfg80211_wext_siwfrag(struct net_device *dev,
-			  struct iw_request_info *info,
-			  struct iw_param *frag, char *extra);
-int cfg80211_wext_giwfrag(struct net_device *dev,
-			  struct iw_request_info *info,
-			  struct iw_param *frag, char *extra);
-int cfg80211_wext_siwretry(struct net_device *dev,
-			   struct iw_request_info *info,
-			   struct iw_param *retry, char *extra);
-int cfg80211_wext_giwretry(struct net_device *dev,
-			   struct iw_request_info *info,
-			   struct iw_param *retry, char *extra);
-int cfg80211_wext_siwencodeext(struct net_device *dev,
-			       struct iw_request_info *info,
-			       struct iw_point *erq, char *extra);
-int cfg80211_wext_siwencode(struct net_device *dev,
-			    struct iw_request_info *info,
-			    struct iw_point *erq, char *keybuf);
-int cfg80211_wext_giwencode(struct net_device *dev,
-			    struct iw_request_info *info,
-			    struct iw_point *erq, char *keybuf);
-int cfg80211_wext_siwtxpower(struct net_device *dev,
-			     struct iw_request_info *info,
-			     union iwreq_data *data, char *keybuf);
-int cfg80211_wext_giwtxpower(struct net_device *dev,
-			     struct iw_request_info *info,
-			     union iwreq_data *data, char *keybuf);
-struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev);
-
-int cfg80211_wext_siwpower(struct net_device *dev,
-			   struct iw_request_info *info,
-			   struct iw_param *wrq, char *extra);
-int cfg80211_wext_giwpower(struct net_device *dev,
-			   struct iw_request_info *info,
-			   struct iw_param *wrq, char *extra);
-
-int cfg80211_wext_siwap(struct net_device *dev,
-			struct iw_request_info *info,
-			struct sockaddr *ap_addr, char *extra);
-int cfg80211_wext_giwap(struct net_device *dev,
-			struct iw_request_info *info,
-			struct sockaddr *ap_addr, char *extra);
-
-/*
  * callbacks for asynchronous cfg80211 methods, notification
  * functions and BSS handling helpers
  */
--- wireless-testing.orig/net/wireless/wext-sme.c	2009-06-24 13:54:10.000000000 +0200
+++ wireless-testing/net/wireless/wext-sme.c	2009-06-24 13:54:11.000000000 +0200
@@ -278,7 +278,6 @@ int cfg80211_wext_siwgenie(struct net_de
 	/* userspace better not think we'll reconnect */
 	return 0;
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_siwgenie);
 
 int cfg80211_wext_siwmlme(struct net_device *dev,
 			  struct iw_request_info *info,
@@ -308,4 +307,3 @@ int cfg80211_wext_siwmlme(struct net_dev
 		return -EOPNOTSUPP;
 	}
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_siwmlme);

-- 


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

* Re: [RFC 01/11] cfg80211: connect/disconnect API
  2009-06-24 12:07 ` [RFC 01/11] cfg80211: connect/disconnect API Johannes Berg
@ 2009-06-24 15:30   ` Samuel Ortiz
  0 siblings, 0 replies; 20+ messages in thread
From: Samuel Ortiz @ 2009-06-24 15:30 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless

Hi Johannes,

On Wed, Jun 24, 2009 at 05:07:46AM -0700, Johannes Berg wrote:
> From: Samuel Ortiz <sameo@linux.intel.com>
> 
> This patch introduces the cfg80211 connect/disconnect API.
> The goal here is to run the AUTH and ASSOC steps in one call.
> This is needed for some fullmac cards that run both steps
> directly from the target, after the host driver sends a
> connect command.
With this API, we should now be able to support the iwconfig key restricted
stuff, with a patch like that:

---
 net/wireless/wext-compat.c |    5 +++++
 1 file changed, 5 insertions(+)

Index: iwm-2.6/net/wireless/wext-compat.c
===================================================================
--- iwm-2.6.orig/net/wireless/wext-compat.c	2009-06-24 17:25:37.000000000 +0200
+++ iwm-2.6/net/wireless/wext-compat.c	2009-06-24 17:25:41.000000000 +0200
@@ -555,6 +555,11 @@ int cfg80211_wext_siwencode(struct net_d
 		return err;
 	}
 
+	if (erq->flags & IW_ENCODE_RESTRICTED)
+		wdev->wext.connect.auth_type = NL80211_AUTHTYPE_SHARED_KEY;
+	else
+		wdev->wext.connect.auth_type = NL80211_AUTHTYPE_OPEN_SYSTEM;
+
 	memset(&params, 0, sizeof(params));
 	params.key = keybuf;
 	params.key_len = erq->length;



-- 
Intel Open Source Technology Centre
http://oss.intel.com/
---------------------------------------------------------------------
Intel Corporation SAS (French simplified joint stock company)
Registered headquarters: "Les Montalets"- 2, rue de Paris, 
92196 Meudon Cedex, France
Registration Number:  302 456 199 R.C.S. NANTERRE
Capital: 4,572,000 Euros

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.


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

* Re: [RFC 00/11] cfg80211 connect API + wireless extension move
  2009-06-24 12:07 [RFC 00/11] cfg80211 connect API + wireless extension move Johannes Berg
                   ` (10 preceding siblings ...)
  2009-06-24 12:07 ` [RFC 11/11] cfg80211: self-contained wext handling Johannes Berg
@ 2009-06-24 20:24 ` Luis R. Rodriguez
  2009-06-25 20:37   ` Dave
  11 siblings, 1 reply; 20+ messages in thread
From: Luis R. Rodriguez @ 2009-06-24 20:24 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless

On Wed, Jun 24, 2009 at 5:07 AM, Johannes Berg<johannes@sipsolutions.net> wrote:

>  Maybe we even decide to
> not internalise it this way because orinoco wants to keep
> some ioctls that we'll not offer in cfg80211, not sure yet.

Hm, which ones?

  Luis

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

* Re: [RFC 00/11] cfg80211 connect API + wireless extension move
  2009-06-24 20:24 ` [RFC 00/11] cfg80211 connect API + wireless extension move Luis R. Rodriguez
@ 2009-06-25 20:37   ` Dave
  2009-06-26 20:18     ` Johannes Berg
  2009-06-26 21:01     ` Johannes Berg
  0 siblings, 2 replies; 20+ messages in thread
From: Dave @ 2009-06-25 20:37 UTC (permalink / raw)
  To: Luis R. Rodriguez; +Cc: Johannes Berg, linux-wireless

Luis R. Rodriguez wrote:
> On Wed, Jun 24, 2009 at 5:07 AM, Johannes Berg<johannes@sipsolutions.net> wrote:
> 
>>  Maybe we even decide to
>> not internalise it this way because orinoco wants to keep
>> some ioctls that we'll not offer in cfg80211, not sure yet.

Do we need to maintain these interfaces? I think allowing the same
functionality via other means should be acceptable (since any software
using these interfaces clearly doesn't work with any other hardware).

> Hm, which ones?

orinoco has the following private wext handlers:

reset firmware
reset card
get/set adhoc port
get/set short preamble
get/set ibss port
get rid

I've only ever had occasion to use the reset ioctls recently, when my
card started seriously misbehaving (I suspect it's about to fail).
debugfs or something?

The get/set things could be done as module parameters. Preferred values
will be model/fw specific - though I expect we have reasonable defaults
picked during initialisation.

Get RID reads settings off the card. Useful for debugging or reverse
engineering, but I hope no-one uses it for anything else. Remove completely?


Regarding patch 11 (the internalise one), would it be better to:
 * continue to export cfg80211_wext_* for now
 * set mac80211s dev->wireless_handler to &cfg80211_wext_handler in
iface.c (via a #define that's NULL if !CONFIG_WEXT)
 * specify a release when we expect all drivers, or at least those
anyone cares about, to have converted?

That removes the WE dependency from mac80211 but allows drivers to
gradually implement cfg80211 support. I originally attempted doing it in
one hit - that sucked, but may have been due to not having a clear idea
of how cfg80211 is supposed to work.

It also means orinoco can keep its wext private functions for a bit longer.


Thanks,

Dave.

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

* Re: [RFC 00/11] cfg80211 connect API + wireless extension move
  2009-06-25 20:37   ` Dave
@ 2009-06-26 20:18     ` Johannes Berg
  2009-06-28  9:26       ` Dave
  2009-06-26 21:01     ` Johannes Berg
  1 sibling, 1 reply; 20+ messages in thread
From: Johannes Berg @ 2009-06-26 20:18 UTC (permalink / raw)
  To: Dave; +Cc: Luis R. Rodriguez, linux-wireless

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

On Thu, 2009-06-25 at 21:37 +0100, Dave wrote:

> Do we need to maintain these interfaces? I think allowing the same
> functionality via other means should be acceptable (since any software
> using these interfaces clearly doesn't work with any other hardware).

True.

> > Hm, which ones?
> 
> orinoco has the following private wext handlers:
> 
> reset firmware
> reset card
> get/set adhoc port
> get/set short preamble
> get/set ibss port
> get rid
> 
> I've only ever had occasion to use the reset ioctls recently, when my
> card started seriously misbehaving (I suspect it's about to fail).
> debugfs or something?

Sounds appropriate.

> The get/set things could be done as module parameters. Preferred values
> will be model/fw specific - though I expect we have reasonable defaults
> picked during initialisation.

That too.

> Get RID reads settings off the card. Useful for debugging or reverse
> engineering, but I hope no-one uses it for anything else. Remove completely?

I suspect you can get rid of it, yes.

> Regarding patch 11 (the internalise one), would it be better to:
>  * continue to export cfg80211_wext_* for now
>  * set mac80211s dev->wireless_handler to &cfg80211_wext_handler in
> iface.c (via a #define that's NULL if !CONFIG_WEXT)
>  * specify a release when we expect all drivers, or at least those
> anyone cares about, to have converted?

Sure. I don't think we need to specify a release since there's only
three drivers so far -- orinoco, rndis and iwm. The latter is taken care
of, and the two others shouldn't be much of a problem either.

> That removes the WE dependency from mac80211 but allows drivers to
> gradually implement cfg80211 support. I originally attempted doing it in
> one hit - that sucked, but may have been due to not having a clear idea
> of how cfg80211 is supposed to work.

Yeah, I agree, doing it in one go will probably overwork anyone who
attempts it, otoh once we actually convert everything in the tree all
the remaining drivers will have to be done in one go. So I think we
should just wait until all drivers are converted and then simply swap. I
can help with rndis/orinoco too.

> It also means orinoco can keep its wext private functions for a bit longer.

Yes. Mind you, I was not only talking about iwpriv, but also about
things like orinoco's spy support or get/set sensitivity. The latter we
don't quite understand -- can you tell us what it actually does? Spy
support should just be removed, I think.

Additionally, at the wireless summit today (yesterday by the time you
read this) we decided to allow cfg80211 drivers to continue exporting
iwpriv handlers, so that existing factory calibration interfaces or
similar can be maintained going forward even with future drivers.
However, this is understood to be purely for backward compatibility with
existing calibration or similar tools.

johannes

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

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

* Re: [RFC 00/11] cfg80211 connect API + wireless extension move
  2009-06-25 20:37   ` Dave
  2009-06-26 20:18     ` Johannes Berg
@ 2009-06-26 21:01     ` Johannes Berg
  2009-06-28  8:43       ` Dave
  1 sibling, 1 reply; 20+ messages in thread
From: Johannes Berg @ 2009-06-26 21:01 UTC (permalink / raw)
  To: Dave; +Cc: Luis R. Rodriguez, linux-wireless

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

On Thu, 2009-06-25 at 21:37 +0100, Dave wrote:

> Regarding patch 11 (the internalise one), would it be better to:
>  * continue to export cfg80211_wext_* for now
>  * set mac80211s dev->wireless_handler to &cfg80211_wext_handler in
> iface.c (via a #define that's NULL if !CONFIG_WEXT)
>  * specify a release when we expect all drivers, or at least those
> anyone cares about, to have converted?
> 
> That removes the WE dependency from mac80211 but allows drivers to
> gradually implement cfg80211 support. I originally attempted doing it in
> one hit - that sucked, but may have been due to not having a clear idea
> of how cfg80211 is supposed to work.

Another idea I just had is that we could do everything like my
internalise patch, but have an if (!netdev->wireless_handlers) before
the assignment. That way, people could still have their own wireless
handlers. Additionally, subject to a Kconfig symbol, we could still
export the handlers, something like this:

config NEED_CFG80211_WEXT_HANDLERS
	bool

#ifdef CONFIG_NEED_...
#define EXPORT_WEXT(sym)		EXPORT_SYMBOL_GPL(sym)
#define __wext_static
static inline void cfg80211_assign_wext_handlers(netdev, handlers)
{
	if (!dev->wireless_handlers)
		dev->wireless_handlers = h;
}
#else
#warn "Having custom wireless handlers is deprecated!!"
#define EXPORT_WEXT(sym)
#define __wext_static		static
static inline void cfg80211_assign_wext_handlers(netdev, handlers)
{
	dev->wireless_handlers = h;
}
#endif

or something like that. Then drivers that are in transition could select
NEED_... and transition call by call even in the future after we switch
to the central model. Is it worth it? I don't know.

johannes

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

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

* Re: [RFC 00/11] cfg80211 connect API + wireless extension move
  2009-06-26 21:01     ` Johannes Berg
@ 2009-06-28  8:43       ` Dave
  0 siblings, 0 replies; 20+ messages in thread
From: Dave @ 2009-06-28  8:43 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Luis R. Rodriguez, linux-wireless

Johannes Berg wrote:
> On Thu, 2009-06-25 at 21:37 +0100, Dave wrote:
> 
>> That removes the WE dependency from mac80211 but allows drivers to
>> gradually implement cfg80211 support. I originally attempted doing it in
>> one hit - that sucked, but may have been due to not having a clear idea
>> of how cfg80211 is supposed to work.
> 
> Another idea I just had is that we could do everything like my
> internalise patch, but have an if (!netdev->wireless_handlers) before
> the assignment. That way, people could still have their own wireless
> handlers.

I had that same thought...

> Additionally, subject to a Kconfig symbol, we could still
> export the handlers, something like this:

<snip>

> or something like that. Then drivers that are in transition could select
> NEED_... and transition call by call even in the future after we switch
> to the central model. Is it worth it? I don't know.

Neat. I tend to prefer avoiding these indirections and keeping things
clean. I'd vote (if I had one) to take the NEED_ behaviour now, and
transition at some point.


Thanks,

Dave.

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

* Re: [RFC 00/11] cfg80211 connect API + wireless extension move
  2009-06-26 20:18     ` Johannes Berg
@ 2009-06-28  9:26       ` Dave
  2009-06-29  8:35         ` Johannes Berg
  0 siblings, 1 reply; 20+ messages in thread
From: Dave @ 2009-06-28  9:26 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Luis R. Rodriguez, linux-wireless

Johannes Berg wrote:
> Yes. Mind you, I was not only talking about iwpriv, but also about
> things like orinoco's spy support or get/set sensitivity. The latter we
> don't quite understand -- can you tell us what it actually does? Spy
> support should just be removed, I think.

I've had a closer look at this.

The sensitivity basically controls the roaming threshold when handled by
firmware. It is a firmware setting, though the Agere driver also
validates the multicast rates based on it. The drivers/firmware use
terms like system scale, AP density, distance between APs.

There are 3 valid values:

3 - high density of APs. Maintain 11Mbps by roaming.
2 - medium density of APs. Maintain 2Mbps.
1 - low density. Maintain 1Mbps.

Although the values are defined in terms of the usable bitrate, the
(Intersil) documentation states that the implementation is based on SNR.



Dave.

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

* Re: [RFC 00/11] cfg80211 connect API + wireless extension move
  2009-06-28  9:26       ` Dave
@ 2009-06-29  8:35         ` Johannes Berg
  0 siblings, 0 replies; 20+ messages in thread
From: Johannes Berg @ 2009-06-29  8:35 UTC (permalink / raw)
  To: Dave; +Cc: Luis R. Rodriguez, linux-wireless

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

On Sun, 2009-06-28 at 10:26 +0100, Dave wrote:
> Johannes Berg wrote:
> > Yes. Mind you, I was not only talking about iwpriv, but also about
> > things like orinoco's spy support or get/set sensitivity. The latter we
> > don't quite understand -- can you tell us what it actually does? Spy
> > support should just be removed, I think.
> 
> I've had a closer look at this.

Thanks!

> The sensitivity basically controls the roaming threshold when handled by
> firmware. It is a firmware setting, though the Agere driver also
> validates the multicast rates based on it. The drivers/firmware use
> terms like system scale, AP density, distance between APs.
> 
> There are 3 valid values:
> 
> 3 - high density of APs. Maintain 11Mbps by roaming.
> 2 - medium density of APs. Maintain 2Mbps.
> 1 - low density. Maintain 1Mbps.
> 
> Although the values are defined in terms of the usable bitrate, the
> (Intersil) documentation states that the implementation is based on SNR.

That's actually what people suspected when I asked around at the summit,
and it seemed the general consensus is that we need a proper setting for
that in nl80211 along with some of the roaming capability exports.

So until that happens, the last patch won't get in anyway, and we'll see
about the NEED_... stuff later.

johannes

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

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

end of thread, other threads:[~2009-06-29  8:35 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-06-24 12:07 [RFC 00/11] cfg80211 connect API + wireless extension move Johannes Berg
2009-06-24 12:07 ` [RFC 01/11] cfg80211: connect/disconnect API Johannes Berg
2009-06-24 15:30   ` Samuel Ortiz
2009-06-24 12:07 ` [RFC 02/11] cfg80211: emulate connect with auth/assoc Johannes Berg
2009-06-24 12:07 ` [RFC 03/11] cfg80211: managed mode wext compatibility Johannes Berg
2009-06-24 12:07 ` [RFC 04/11] cfg80211: implement iwpower Johannes Berg
2009-06-24 12:07 ` [RFC 05/11] cfg80211: implement IWAP for WDS Johannes Berg
2009-06-24 12:07 ` [RFC 06/11] cfg80211: implement IWRATE Johannes Berg
2009-06-24 12:07 ` [RFC 07/11] cfg80211: implement get_wireless_stats Johannes Berg
2009-06-24 12:07 ` [RFC 08/11] cfg80211: combine iwfreq implementations Johannes Berg
2009-06-24 12:07 ` [RFC 09/11] cfg80211: combine IWAP handlers Johannes Berg
2009-06-24 12:07 ` [RFC 10/11] cfg80211: combine IWESSID handlers Johannes Berg
2009-06-24 12:07 ` [RFC 11/11] cfg80211: self-contained wext handling Johannes Berg
2009-06-24 20:24 ` [RFC 00/11] cfg80211 connect API + wireless extension move Luis R. Rodriguez
2009-06-25 20:37   ` Dave
2009-06-26 20:18     ` Johannes Berg
2009-06-28  9:26       ` Dave
2009-06-29  8:35         ` Johannes Berg
2009-06-26 21:01     ` Johannes Berg
2009-06-28  8:43       ` Dave

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