linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/23] orinoco: initiate cfg80211 conversion
@ 2009-06-18 22:21 David Kilroy
  2009-06-18 22:21 ` [PATCH 01/23] cfg80211: add wrapper function to get wiphy from priv pointer David Kilroy
                   ` (23 more replies)
  0 siblings, 24 replies; 32+ messages in thread
From: David Kilroy @ 2009-06-18 22:21 UTC (permalink / raw)
  To: linux-wireless; +Cc: orinoco-devel, David Kilroy

Compared to the last RFC, this series:
 * addresses Marcels comments, using a switch instead of an if (2,3,4)
 * fixes scanning problems for older firmware (21)
 * depends on cfg80211 rather than selecting it (in line with "cfg80211:
   fix Kconfig for users of cfg80211") (14).
 * updates change_vif argument from ifindex to net_device (in line with
   "cfg80211: pass netdev to change_virtual_intf") (20)

Patches 1-5 modify cfg80211, mostly so it can advertise (the more
restrictive) orinoco capabilities correctly.

Patches 6-13 refactor the orinoco internal interfaces and initialisation
to make the switch to cfg80211 easier. The main thrust is to avoid using
net_device in the device drivers allowing us to register the net_device
later.

Patch 14 starts the cfg80211 conversion, before patches 15-19 cleanup
the fallout from the conversion.

Patches 20 though 23 convert a few of the WE handlers to cfg80211
handlers.

This series is intended for the wireless-testing tree.

---
David Kilroy (23):
  cfg80211: add wrapper function to get wiphy from priv pointer
  cfg80211: Advertise ciphers via WE according to driver capability
  cfg80211: allow drivers that can't scan for specific ssids
  cfg80211: set WE encoding size based on available ciphers
  cfg80211: infer WPA and WPA2 support from TKIP and CCMP
  orinoco: Move firmware capability determination into hw.c
  orinoco: Move card reading code into hw.c
  orinoco: Move FID allocation to hw.c
  orinoco: use dev_err in early initialisation routines
  orinoco: firmware helpers should use dev_err and friends
  orinoco: Replace net_device with orinoco_private in driver interfaces
  orinoco: initialise independently of netdev
  orinoco: Change set_tkip to use orinoco_private instead of hermes_t
  orinoco: initiate cfg80211 conversion
  orinoco: make firmware download less verbose
  orinoco: move netdev interface creation to main driver
  airport: store irq in card private structure
  orinoco: Handle suspend/restore in core driver
  orinoco: provide generic commit function
  orinoco: convert mode setting to cfg80211
  orinoco: convert scanning to cfg80211
  orinoco: convert giwrange to cfg80211
  orinoco: remove WE nickname support

 drivers/net/wireless/orinoco/Kconfig          |    1 +
 drivers/net/wireless/orinoco/Makefile         |    2 +-
 drivers/net/wireless/orinoco/airport.c        |   98 +--
 drivers/net/wireless/orinoco/cfg.c            |  162 ++++
 drivers/net/wireless/orinoco/cfg.h            |   15 +
 drivers/net/wireless/orinoco/fw.c             |   41 +-
 drivers/net/wireless/orinoco/hermes.h         |    2 +-
 drivers/net/wireless/orinoco/hermes_dld.c     |   50 +-
 drivers/net/wireless/orinoco/hw.c             |  668 +++++++++++++++-
 drivers/net/wireless/orinoco/hw.h             |   11 +-
 drivers/net/wireless/orinoco/main.c           | 1133 +++++++++----------------
 drivers/net/wireless/orinoco/main.h           |    3 +-
 drivers/net/wireless/orinoco/orinoco.h        |   49 +-
 drivers/net/wireless/orinoco/orinoco_cs.c     |   96 +--
 drivers/net/wireless/orinoco/orinoco_nortel.c |   38 +-
 drivers/net/wireless/orinoco/orinoco_pci.c    |   38 +-
 drivers/net/wireless/orinoco/orinoco_pci.h    |   57 +--
 drivers/net/wireless/orinoco/orinoco_plx.c    |   38 +-
 drivers/net/wireless/orinoco/orinoco_tmd.c    |   38 +-
 drivers/net/wireless/orinoco/scan.c           |  285 +++----
 drivers/net/wireless/orinoco/scan.h           |   21 +-
 drivers/net/wireless/orinoco/spectrum_cs.c    |   96 +--
 drivers/net/wireless/orinoco/wext.c           |  878 ++------------------
 include/net/cfg80211.h                        |   11 +
 net/wireless/core.c                           |    3 -
 net/wireless/wext-compat.c                    |   31 +-
 26 files changed, 1748 insertions(+), 2117 deletions(-)
 create mode 100644 drivers/net/wireless/orinoco/cfg.c
 create mode 100644 drivers/net/wireless/orinoco/cfg.h


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

* [PATCH 01/23] cfg80211: add wrapper function to get wiphy from priv pointer
  2009-06-18 22:21 [PATCH 00/23] orinoco: initiate cfg80211 conversion David Kilroy
@ 2009-06-18 22:21 ` David Kilroy
  2009-06-18 22:21 ` [PATCH 02/23] cfg80211: Advertise ciphers via WE according to driver capability David Kilroy
                   ` (22 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: David Kilroy @ 2009-06-18 22:21 UTC (permalink / raw)
  To: linux-wireless; +Cc: orinoco-devel, David Kilroy

Signed-off-by: David Kilroy <kilroyd@googlemail.com>
Acked-by: Johannes Berg <johannes@sipsolutions.net>
---
 include/net/cfg80211.h |   11 +++++++++++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 90f9bfa..dba7874 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1059,6 +1059,17 @@ static inline void *wiphy_priv(struct wiphy *wiphy)
 }
 
 /**
+ * priv_to_wiphy - return the wiphy containing the priv
+ *
+ * @priv: a pointer previously returned by wiphy_priv
+ */
+static inline struct wiphy *priv_to_wiphy(void *priv)
+{
+	BUG_ON(!priv);
+	return container_of(priv, struct wiphy, priv);
+}
+
+/**
  * set_wiphy_dev - set device pointer for wiphy
  *
  * @wiphy: The wiphy whose device to bind
-- 
1.6.0.6


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

* [PATCH 02/23] cfg80211: Advertise ciphers via WE according to driver capability
  2009-06-18 22:21 [PATCH 00/23] orinoco: initiate cfg80211 conversion David Kilroy
  2009-06-18 22:21 ` [PATCH 01/23] cfg80211: add wrapper function to get wiphy from priv pointer David Kilroy
@ 2009-06-18 22:21 ` David Kilroy
  2009-06-18 23:38   ` Julian Calaby
  2009-06-18 22:21 ` [PATCH 03/23] cfg80211: allow drivers that can't scan for specific ssids David Kilroy
                   ` (21 subsequent siblings)
  23 siblings, 1 reply; 32+ messages in thread
From: David Kilroy @ 2009-06-18 22:21 UTC (permalink / raw)
  To: linux-wireless; +Cc: orinoco-devel, David Kilroy

Signed-off-by: David Kilroy <kilroyd@googlemail.com>
Acked-by: Johannes Berg <johannes@sipsolutions.net>
---
 net/wireless/wext-compat.c |   15 +++++++++++++--
 1 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 9e56f35..7dbe6c6 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -204,8 +204,19 @@ int cfg80211_wext_giwrange(struct net_device *dev,
 	range->avg_qual.noise = range->max_qual.noise / 2;
 	range->avg_qual.updated = range->max_qual.updated;
 
-	range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
-			  IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
+	range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2;
+
+	for (c = 0; c < wdev->wiphy->n_cipher_suites; c++) {
+		switch (wdev->wiphy->cipher_suites[c]) {
+		case WLAN_CIPHER_SUITE_TKIP:
+			range->enc_capa |= IW_ENC_CAPA_CIPHER_TKIP;
+			break;
+
+		case WLAN_CIPHER_SUITE_CCMP:
+			range->enc_capa |= IW_ENC_CAPA_CIPHER_CCMP;
+			break;
+		}
+	}
 
 	for (band = 0; band < IEEE80211_NUM_BANDS; band ++) {
 		int i;
-- 
1.6.0.6


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

* [PATCH 03/23] cfg80211: allow drivers that can't scan for specific ssids
  2009-06-18 22:21 [PATCH 00/23] orinoco: initiate cfg80211 conversion David Kilroy
  2009-06-18 22:21 ` [PATCH 01/23] cfg80211: add wrapper function to get wiphy from priv pointer David Kilroy
  2009-06-18 22:21 ` [PATCH 02/23] cfg80211: Advertise ciphers via WE according to driver capability David Kilroy
@ 2009-06-18 22:21 ` David Kilroy
  2009-06-18 22:21 ` [PATCH 04/23] cfg80211: set WE encoding size based on available ciphers David Kilroy
                   ` (20 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: David Kilroy @ 2009-06-18 22:21 UTC (permalink / raw)
  To: linux-wireless; +Cc: orinoco-devel, David Kilroy

Signed-off-by: David Kilroy <kilroyd@googlemail.com>
Acked-by: Johannes Berg <johannes@sipsolutions.net>
---
 net/wireless/core.c        |    3 ---
 net/wireless/wext-compat.c |    3 ++-
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/net/wireless/core.c b/net/wireless/core.c
index d585029..a98670c 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -346,9 +346,6 @@ int wiphy_register(struct wiphy *wiphy)
 	int i;
 	u16 ifmodes = wiphy->interface_modes;
 
-	if (WARN_ON(wiphy->max_scan_ssids < 1))
-		return -EINVAL;
-
 	/* sanity check ifmodes */
 	WARN_ON(!ifmodes);
 	ifmodes &= ((1 << __NL80211_IFTYPE_AFTER_LAST) - 1) & ~1;
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 7dbe6c6..bb97061 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -247,7 +247,8 @@ int cfg80211_wext_giwrange(struct net_device *dev,
 	IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
 	IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
 
-	range->scan_capa |= IW_SCAN_CAPA_ESSID;
+	if (wdev->wiphy->max_scan_ssids > 0)
+		range->scan_capa |= IW_SCAN_CAPA_ESSID;
 
 	return 0;
 }
-- 
1.6.0.6


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

* [PATCH 04/23] cfg80211: set WE encoding size based on available ciphers
  2009-06-18 22:21 [PATCH 00/23] orinoco: initiate cfg80211 conversion David Kilroy
                   ` (2 preceding siblings ...)
  2009-06-18 22:21 ` [PATCH 03/23] cfg80211: allow drivers that can't scan for specific ssids David Kilroy
@ 2009-06-18 22:21 ` David Kilroy
  2009-06-18 22:21 ` [PATCH 05/23] cfg80211: infer WPA and WPA2 support from TKIP and CCMP David Kilroy
                   ` (19 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: David Kilroy @ 2009-06-18 22:21 UTC (permalink / raw)
  To: linux-wireless; +Cc: orinoco-devel, David Kilroy

Only set the sizes for WEP40 and WEP104.

Signed-off-by: David Kilroy <kilroyd@googlemail.com>
Acked-by: Johannes Berg <johannes@sipsolutions.net>
---
 net/wireless/wext-compat.c |   13 ++++++++++---
 1 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index bb97061..2f7e776 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -173,9 +173,6 @@ int cfg80211_wext_giwrange(struct net_device *dev,
 	range->min_frag = 256;
 	range->max_frag = 2346;
 
-	range->encoding_size[0] = 5;
-	range->encoding_size[1] = 13;
-	range->num_encoding_sizes = 2;
 	range->max_encoding_tokens = 4;
 
 	range->max_qual.updated = IW_QUAL_NOISE_INVALID;
@@ -215,6 +212,16 @@ int cfg80211_wext_giwrange(struct net_device *dev,
 		case WLAN_CIPHER_SUITE_CCMP:
 			range->enc_capa |= IW_ENC_CAPA_CIPHER_CCMP;
 			break;
+
+		case WLAN_CIPHER_SUITE_WEP40:
+			range->encoding_size[range->num_encoding_sizes++] =
+				WLAN_KEY_LEN_WEP40;
+			break;
+
+		case WLAN_CIPHER_SUITE_WEP104:
+			range->encoding_size[range->num_encoding_sizes++] =
+				WLAN_KEY_LEN_WEP104;
+			break;
 		}
 	}
 
-- 
1.6.0.6


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

* [PATCH 05/23] cfg80211: infer WPA and WPA2 support from TKIP and CCMP
  2009-06-18 22:21 [PATCH 00/23] orinoco: initiate cfg80211 conversion David Kilroy
                   ` (3 preceding siblings ...)
  2009-06-18 22:21 ` [PATCH 04/23] cfg80211: set WE encoding size based on available ciphers David Kilroy
@ 2009-06-18 22:21 ` David Kilroy
  2009-06-18 22:21 ` [PATCH 06/23] orinoco: Move firmware capability determination into hw.c David Kilroy
                   ` (18 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: David Kilroy @ 2009-06-18 22:21 UTC (permalink / raw)
  To: linux-wireless; +Cc: orinoco-devel, David Kilroy

Signed-off-by: David Kilroy <kilroyd@googlemail.com>
Acked-by: Johannes Berg <johannes@sipsolutions.net>
---
 net/wireless/wext-compat.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 2f7e776..cae3b52 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -201,16 +201,16 @@ int cfg80211_wext_giwrange(struct net_device *dev,
 	range->avg_qual.noise = range->max_qual.noise / 2;
 	range->avg_qual.updated = range->max_qual.updated;
 
-	range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2;
-
 	for (c = 0; c < wdev->wiphy->n_cipher_suites; c++) {
 		switch (wdev->wiphy->cipher_suites[c]) {
 		case WLAN_CIPHER_SUITE_TKIP:
-			range->enc_capa |= IW_ENC_CAPA_CIPHER_TKIP;
+			range->enc_capa |= (IW_ENC_CAPA_CIPHER_TKIP |
+					    IW_ENC_CAPA_WPA);
 			break;
 
 		case WLAN_CIPHER_SUITE_CCMP:
-			range->enc_capa |= IW_ENC_CAPA_CIPHER_CCMP;
+			range->enc_capa |= (IW_ENC_CAPA_CIPHER_CCMP |
+					    IW_ENC_CAPA_WPA2);
 			break;
 
 		case WLAN_CIPHER_SUITE_WEP40:
-- 
1.6.0.6


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

* [PATCH 06/23] orinoco: Move firmware capability determination into hw.c
  2009-06-18 22:21 [PATCH 00/23] orinoco: initiate cfg80211 conversion David Kilroy
                   ` (4 preceding siblings ...)
  2009-06-18 22:21 ` [PATCH 05/23] cfg80211: infer WPA and WPA2 support from TKIP and CCMP David Kilroy
@ 2009-06-18 22:21 ` David Kilroy
  2009-06-18 22:21 ` [PATCH 07/23] orinoco: Move card reading code " David Kilroy
                   ` (17 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: David Kilroy @ 2009-06-18 22:21 UTC (permalink / raw)
  To: linux-wireless; +Cc: orinoco-devel, David Kilroy

This is part of refactorring the initialisation code so that we can load
the firmware before registerring with netdev.

Signed-off-by: David Kilroy <kilroyd@googlemail.com>
---
 drivers/net/wireless/orinoco/hw.c   |  216 ++++++++++++++++++++++++++++++++++
 drivers/net/wireless/orinoco/hw.h   |    1 +
 drivers/net/wireless/orinoco/main.c |  218 +----------------------------------
 3 files changed, 219 insertions(+), 216 deletions(-)

diff --git a/drivers/net/wireless/orinoco/hw.c b/drivers/net/wireless/orinoco/hw.c
index 632fac8..209c6be 100644
--- a/drivers/net/wireless/orinoco/hw.c
+++ b/drivers/net/wireless/orinoco/hw.c
@@ -13,6 +13,8 @@
 
 #include "hw.h"
 
+#define SYMBOL_MAX_VER_LEN	(14)
+
 /********************************************************************/
 /* Data tables                                                      */
 /********************************************************************/
@@ -36,6 +38,220 @@ static const struct {
 };
 #define BITRATE_TABLE_SIZE ARRAY_SIZE(bitrate_table)
 
+/* Firmware version encoding */
+struct comp_id {
+	u16 id, variant, major, minor;
+} __attribute__ ((packed));
+
+static inline fwtype_t determine_firmware_type(struct comp_id *nic_id)
+{
+	if (nic_id->id < 0x8000)
+		return FIRMWARE_TYPE_AGERE;
+	else if (nic_id->id == 0x8000 && nic_id->major == 0)
+		return FIRMWARE_TYPE_SYMBOL;
+	else
+		return FIRMWARE_TYPE_INTERSIL;
+}
+
+/* Set priv->firmware type, determine firmware properties */
+int determine_fw_capabilities(struct orinoco_private *priv)
+{
+	struct net_device *dev = priv->ndev;
+	hermes_t *hw = &priv->hw;
+	int err;
+	struct comp_id nic_id, sta_id;
+	unsigned int firmver;
+	char tmp[SYMBOL_MAX_VER_LEN+1] __attribute__((aligned(2)));
+
+	/* Get the hardware version */
+	err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_NICID, &nic_id);
+	if (err) {
+		printk(KERN_ERR "%s: Cannot read hardware identity: error %d\n",
+		       dev->name, err);
+		return err;
+	}
+
+	le16_to_cpus(&nic_id.id);
+	le16_to_cpus(&nic_id.variant);
+	le16_to_cpus(&nic_id.major);
+	le16_to_cpus(&nic_id.minor);
+	printk(KERN_DEBUG "%s: Hardware identity %04x:%04x:%04x:%04x\n",
+	       dev->name, nic_id.id, nic_id.variant,
+	       nic_id.major, nic_id.minor);
+
+	priv->firmware_type = determine_firmware_type(&nic_id);
+
+	/* Get the firmware version */
+	err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_STAID, &sta_id);
+	if (err) {
+		printk(KERN_ERR "%s: Cannot read station identity: error %d\n",
+		       dev->name, err);
+		return err;
+	}
+
+	le16_to_cpus(&sta_id.id);
+	le16_to_cpus(&sta_id.variant);
+	le16_to_cpus(&sta_id.major);
+	le16_to_cpus(&sta_id.minor);
+	printk(KERN_DEBUG "%s: Station identity  %04x:%04x:%04x:%04x\n",
+	       dev->name, sta_id.id, sta_id.variant,
+	       sta_id.major, sta_id.minor);
+
+	switch (sta_id.id) {
+	case 0x15:
+		printk(KERN_ERR "%s: Primary firmware is active\n",
+		       dev->name);
+		return -ENODEV;
+	case 0x14b:
+		printk(KERN_ERR "%s: Tertiary firmware is active\n",
+		       dev->name);
+		return -ENODEV;
+	case 0x1f:	/* Intersil, Agere, Symbol Spectrum24 */
+	case 0x21:	/* Symbol Spectrum24 Trilogy */
+		break;
+	default:
+		printk(KERN_NOTICE "%s: Unknown station ID, please report\n",
+		       dev->name);
+		break;
+	}
+
+	/* Default capabilities */
+	priv->has_sensitivity = 1;
+	priv->has_mwo = 0;
+	priv->has_preamble = 0;
+	priv->has_port3 = 1;
+	priv->has_ibss = 1;
+	priv->has_wep = 0;
+	priv->has_big_wep = 0;
+	priv->has_alt_txcntl = 0;
+	priv->has_ext_scan = 0;
+	priv->has_wpa = 0;
+	priv->do_fw_download = 0;
+
+	/* Determine capabilities from the firmware version */
+	switch (priv->firmware_type) {
+	case FIRMWARE_TYPE_AGERE:
+		/* Lucent Wavelan IEEE, Lucent Orinoco, Cabletron RoamAbout,
+		   ELSA, Melco, HP, IBM, Dell 1150, Compaq 110/210 */
+		snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
+			 "Lucent/Agere %d.%02d", sta_id.major, sta_id.minor);
+
+		firmver = ((unsigned long)sta_id.major << 16) | sta_id.minor;
+
+		priv->has_ibss = (firmver >= 0x60006);
+		priv->has_wep = (firmver >= 0x40020);
+		priv->has_big_wep = 1; /* FIXME: this is wrong - how do we tell
+					  Gold cards from the others? */
+		priv->has_mwo = (firmver >= 0x60000);
+		priv->has_pm = (firmver >= 0x40020); /* Don't work in 7.52 ? */
+		priv->ibss_port = 1;
+		priv->has_hostscan = (firmver >= 0x8000a);
+		priv->do_fw_download = 1;
+		priv->broken_monitor = (firmver >= 0x80000);
+		priv->has_alt_txcntl = (firmver >= 0x90000); /* All 9.x ? */
+		priv->has_ext_scan = (firmver >= 0x90000); /* All 9.x ? */
+		priv->has_wpa = (firmver >= 0x9002a);
+		/* Tested with Agere firmware :
+		 *	1.16 ; 4.08 ; 4.52 ; 6.04 ; 6.16 ; 7.28 => Jean II
+		 * Tested CableTron firmware : 4.32 => Anton */
+		break;
+	case FIRMWARE_TYPE_SYMBOL:
+		/* Symbol , 3Com AirConnect, Intel, Ericsson WLAN */
+		/* Intel MAC : 00:02:B3:* */
+		/* 3Com MAC : 00:50:DA:* */
+		memset(tmp, 0, sizeof(tmp));
+		/* Get the Symbol firmware version */
+		err = hermes_read_ltv(hw, USER_BAP,
+				      HERMES_RID_SECONDARYVERSION_SYMBOL,
+				      SYMBOL_MAX_VER_LEN, NULL, &tmp);
+		if (err) {
+			printk(KERN_WARNING
+			       "%s: Error %d reading Symbol firmware info. "
+			       "Wildly guessing capabilities...\n",
+			       dev->name, err);
+			firmver = 0;
+			tmp[0] = '\0';
+		} else {
+			/* The firmware revision is a string, the format is
+			 * something like : "V2.20-01".
+			 * Quick and dirty parsing... - Jean II
+			 */
+			firmver = ((tmp[1] - '0') << 16)
+				| ((tmp[3] - '0') << 12)
+				| ((tmp[4] - '0') << 8)
+				| ((tmp[6] - '0') << 4)
+				| (tmp[7] - '0');
+
+			tmp[SYMBOL_MAX_VER_LEN] = '\0';
+		}
+
+		snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
+			 "Symbol %s", tmp);
+
+		priv->has_ibss = (firmver >= 0x20000);
+		priv->has_wep = (firmver >= 0x15012);
+		priv->has_big_wep = (firmver >= 0x20000);
+		priv->has_pm = (firmver >= 0x20000 && firmver < 0x22000) ||
+			       (firmver >= 0x29000 && firmver < 0x30000) ||
+			       firmver >= 0x31000;
+		priv->has_preamble = (firmver >= 0x20000);
+		priv->ibss_port = 4;
+
+		/* Symbol firmware is found on various cards, but
+		 * there has been no attempt to check firmware
+		 * download on non-spectrum_cs based cards.
+		 *
+		 * Given that the Agere firmware download works
+		 * differently, we should avoid doing a firmware
+		 * download with the Symbol algorithm on non-spectrum
+		 * cards.
+		 *
+		 * For now we can identify a spectrum_cs based card
+		 * because it has a firmware reset function.
+		 */
+		priv->do_fw_download = (priv->stop_fw != NULL);
+
+		priv->broken_disableport = (firmver == 0x25013) ||
+				(firmver >= 0x30000 && firmver <= 0x31000);
+		priv->has_hostscan = (firmver >= 0x31001) ||
+				     (firmver >= 0x29057 && firmver < 0x30000);
+		/* Tested with Intel firmware : 0x20015 => Jean II */
+		/* Tested with 3Com firmware : 0x15012 & 0x22001 => Jean II */
+		break;
+	case FIRMWARE_TYPE_INTERSIL:
+		/* D-Link, Linksys, Adtron, ZoomAir, and many others...
+		 * Samsung, Compaq 100/200 and Proxim are slightly
+		 * different and less well tested */
+		/* D-Link MAC : 00:40:05:* */
+		/* Addtron MAC : 00:90:D1:* */
+		snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
+			 "Intersil %d.%d.%d", sta_id.major, sta_id.minor,
+			 sta_id.variant);
+
+		firmver = ((unsigned long)sta_id.major << 16) |
+			((unsigned long)sta_id.minor << 8) | sta_id.variant;
+
+		priv->has_ibss = (firmver >= 0x000700); /* FIXME */
+		priv->has_big_wep = priv->has_wep = (firmver >= 0x000800);
+		priv->has_pm = (firmver >= 0x000700);
+		priv->has_hostscan = (firmver >= 0x010301);
+
+		if (firmver >= 0x000800)
+			priv->ibss_port = 0;
+		else {
+			printk(KERN_NOTICE "%s: Intersil firmware earlier "
+			       "than v0.8.x - several features not supported\n",
+			       dev->name);
+			priv->ibss_port = 1;
+		}
+		break;
+	}
+	printk(KERN_DEBUG "%s: Firmware determined as %s\n", dev->name,
+	       priv->fw_name);
+
+	return 0;
+}
+
 int orinoco_get_bitratemode(int bitrate, int automatic)
 {
 	int ratemode = -1;
diff --git a/drivers/net/wireless/orinoco/hw.h b/drivers/net/wireless/orinoco/hw.h
index dc3f23a..f7845b8 100644
--- a/drivers/net/wireless/orinoco/hw.h
+++ b/drivers/net/wireless/orinoco/hw.h
@@ -23,6 +23,7 @@
 struct orinoco_private;
 struct dev_addr_list;
 
+int determine_fw_capabilities(struct orinoco_private *priv);
 int orinoco_get_bitratemode(int bitrate, int automatic);
 void orinoco_get_ratemode_cfg(int ratemode, int *bitrate, int *automatic);
 
diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c
index 345593c..33326d6 100644
--- a/drivers/net/wireless/orinoco/main.c
+++ b/drivers/net/wireless/orinoco/main.c
@@ -142,7 +142,6 @@ static const u8 encaps_hdr[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
 #define ORINOCO_MIN_MTU		256
 #define ORINOCO_MAX_MTU		(IEEE80211_MAX_DATA_LEN - ENCAPS_OVERHEAD)
 
-#define SYMBOL_MAX_VER_LEN	(14)
 #define MAX_IRQLOOPS_PER_IRQ	10
 #define MAX_IRQLOOPS_PER_JIFFY	(20000/HZ) /* Based on a guestimate of
 					    * how many events the
@@ -2096,219 +2095,6 @@ static void orinoco_unregister_pm_notifier(struct orinoco_private *priv)
 /* Initialization                                                   */
 /********************************************************************/
 
-struct comp_id {
-	u16 id, variant, major, minor;
-} __attribute__ ((packed));
-
-static inline fwtype_t determine_firmware_type(struct comp_id *nic_id)
-{
-	if (nic_id->id < 0x8000)
-		return FIRMWARE_TYPE_AGERE;
-	else if (nic_id->id == 0x8000 && nic_id->major == 0)
-		return FIRMWARE_TYPE_SYMBOL;
-	else
-		return FIRMWARE_TYPE_INTERSIL;
-}
-
-/* Set priv->firmware type, determine firmware properties */
-static int determine_firmware(struct net_device *dev)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	hermes_t *hw = &priv->hw;
-	int err;
-	struct comp_id nic_id, sta_id;
-	unsigned int firmver;
-	char tmp[SYMBOL_MAX_VER_LEN+1] __attribute__((aligned(2)));
-
-	/* Get the hardware version */
-	err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_NICID, &nic_id);
-	if (err) {
-		printk(KERN_ERR "%s: Cannot read hardware identity: error %d\n",
-		       dev->name, err);
-		return err;
-	}
-
-	le16_to_cpus(&nic_id.id);
-	le16_to_cpus(&nic_id.variant);
-	le16_to_cpus(&nic_id.major);
-	le16_to_cpus(&nic_id.minor);
-	printk(KERN_DEBUG "%s: Hardware identity %04x:%04x:%04x:%04x\n",
-	       dev->name, nic_id.id, nic_id.variant,
-	       nic_id.major, nic_id.minor);
-
-	priv->firmware_type = determine_firmware_type(&nic_id);
-
-	/* Get the firmware version */
-	err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_STAID, &sta_id);
-	if (err) {
-		printk(KERN_ERR "%s: Cannot read station identity: error %d\n",
-		       dev->name, err);
-		return err;
-	}
-
-	le16_to_cpus(&sta_id.id);
-	le16_to_cpus(&sta_id.variant);
-	le16_to_cpus(&sta_id.major);
-	le16_to_cpus(&sta_id.minor);
-	printk(KERN_DEBUG "%s: Station identity  %04x:%04x:%04x:%04x\n",
-	       dev->name, sta_id.id, sta_id.variant,
-	       sta_id.major, sta_id.minor);
-
-	switch (sta_id.id) {
-	case 0x15:
-		printk(KERN_ERR "%s: Primary firmware is active\n",
-		       dev->name);
-		return -ENODEV;
-	case 0x14b:
-		printk(KERN_ERR "%s: Tertiary firmware is active\n",
-		       dev->name);
-		return -ENODEV;
-	case 0x1f:	/* Intersil, Agere, Symbol Spectrum24 */
-	case 0x21:	/* Symbol Spectrum24 Trilogy */
-		break;
-	default:
-		printk(KERN_NOTICE "%s: Unknown station ID, please report\n",
-		       dev->name);
-		break;
-	}
-
-	/* Default capabilities */
-	priv->has_sensitivity = 1;
-	priv->has_mwo = 0;
-	priv->has_preamble = 0;
-	priv->has_port3 = 1;
-	priv->has_ibss = 1;
-	priv->has_wep = 0;
-	priv->has_big_wep = 0;
-	priv->has_alt_txcntl = 0;
-	priv->has_ext_scan = 0;
-	priv->has_wpa = 0;
-	priv->do_fw_download = 0;
-
-	/* Determine capabilities from the firmware version */
-	switch (priv->firmware_type) {
-	case FIRMWARE_TYPE_AGERE:
-		/* Lucent Wavelan IEEE, Lucent Orinoco, Cabletron RoamAbout,
-		   ELSA, Melco, HP, IBM, Dell 1150, Compaq 110/210 */
-		snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
-			 "Lucent/Agere %d.%02d", sta_id.major, sta_id.minor);
-
-		firmver = ((unsigned long)sta_id.major << 16) | sta_id.minor;
-
-		priv->has_ibss = (firmver >= 0x60006);
-		priv->has_wep = (firmver >= 0x40020);
-		priv->has_big_wep = 1; /* FIXME: this is wrong - how do we tell
-					  Gold cards from the others? */
-		priv->has_mwo = (firmver >= 0x60000);
-		priv->has_pm = (firmver >= 0x40020); /* Don't work in 7.52 ? */
-		priv->ibss_port = 1;
-		priv->has_hostscan = (firmver >= 0x8000a);
-		priv->do_fw_download = 1;
-		priv->broken_monitor = (firmver >= 0x80000);
-		priv->has_alt_txcntl = (firmver >= 0x90000); /* All 9.x ? */
-		priv->has_ext_scan = (firmver >= 0x90000); /* All 9.x ? */
-		priv->has_wpa = (firmver >= 0x9002a);
-		/* Tested with Agere firmware :
-		 *	1.16 ; 4.08 ; 4.52 ; 6.04 ; 6.16 ; 7.28 => Jean II
-		 * Tested CableTron firmware : 4.32 => Anton */
-		break;
-	case FIRMWARE_TYPE_SYMBOL:
-		/* Symbol , 3Com AirConnect, Intel, Ericsson WLAN */
-		/* Intel MAC : 00:02:B3:* */
-		/* 3Com MAC : 00:50:DA:* */
-		memset(tmp, 0, sizeof(tmp));
-		/* Get the Symbol firmware version */
-		err = hermes_read_ltv(hw, USER_BAP,
-				      HERMES_RID_SECONDARYVERSION_SYMBOL,
-				      SYMBOL_MAX_VER_LEN, NULL, &tmp);
-		if (err) {
-			printk(KERN_WARNING
-			       "%s: Error %d reading Symbol firmware info. "
-			       "Wildly guessing capabilities...\n",
-			       dev->name, err);
-			firmver = 0;
-			tmp[0] = '\0';
-		} else {
-			/* The firmware revision is a string, the format is
-			 * something like : "V2.20-01".
-			 * Quick and dirty parsing... - Jean II
-			 */
-			firmver = ((tmp[1] - '0') << 16)
-				| ((tmp[3] - '0') << 12)
-				| ((tmp[4] - '0') << 8)
-				| ((tmp[6] - '0') << 4)
-				| (tmp[7] - '0');
-
-			tmp[SYMBOL_MAX_VER_LEN] = '\0';
-		}
-
-		snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
-			 "Symbol %s", tmp);
-
-		priv->has_ibss = (firmver >= 0x20000);
-		priv->has_wep = (firmver >= 0x15012);
-		priv->has_big_wep = (firmver >= 0x20000);
-		priv->has_pm = (firmver >= 0x20000 && firmver < 0x22000) ||
-			       (firmver >= 0x29000 && firmver < 0x30000) ||
-			       firmver >= 0x31000;
-		priv->has_preamble = (firmver >= 0x20000);
-		priv->ibss_port = 4;
-
-		/* Symbol firmware is found on various cards, but
-		 * there has been no attempt to check firmware
-		 * download on non-spectrum_cs based cards.
-		 *
-		 * Given that the Agere firmware download works
-		 * differently, we should avoid doing a firmware
-		 * download with the Symbol algorithm on non-spectrum
-		 * cards.
-		 *
-		 * For now we can identify a spectrum_cs based card
-		 * because it has a firmware reset function.
-		 */
-		priv->do_fw_download = (priv->stop_fw != NULL);
-
-		priv->broken_disableport = (firmver == 0x25013) ||
-				(firmver >= 0x30000 && firmver <= 0x31000);
-		priv->has_hostscan = (firmver >= 0x31001) ||
-				     (firmver >= 0x29057 && firmver < 0x30000);
-		/* Tested with Intel firmware : 0x20015 => Jean II */
-		/* Tested with 3Com firmware : 0x15012 & 0x22001 => Jean II */
-		break;
-	case FIRMWARE_TYPE_INTERSIL:
-		/* D-Link, Linksys, Adtron, ZoomAir, and many others...
-		 * Samsung, Compaq 100/200 and Proxim are slightly
-		 * different and less well tested */
-		/* D-Link MAC : 00:40:05:* */
-		/* Addtron MAC : 00:90:D1:* */
-		snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
-			 "Intersil %d.%d.%d", sta_id.major, sta_id.minor,
-			 sta_id.variant);
-
-		firmver = ((unsigned long)sta_id.major << 16) |
-			((unsigned long)sta_id.minor << 8) | sta_id.variant;
-
-		priv->has_ibss = (firmver >= 0x000700); /* FIXME */
-		priv->has_big_wep = priv->has_wep = (firmver >= 0x000800);
-		priv->has_pm = (firmver >= 0x000700);
-		priv->has_hostscan = (firmver >= 0x010301);
-
-		if (firmver >= 0x000800)
-			priv->ibss_port = 0;
-		else {
-			printk(KERN_NOTICE "%s: Intersil firmware earlier "
-			       "than v0.8.x - several features not supported\n",
-			       dev->name);
-			priv->ibss_port = 1;
-		}
-		break;
-	}
-	printk(KERN_DEBUG "%s: Firmware determined as %s\n", dev->name,
-	       priv->fw_name);
-
-	return 0;
-}
-
 static int orinoco_init(struct net_device *dev)
 {
 	struct orinoco_private *priv = netdev_priv(dev);
@@ -2330,7 +2116,7 @@ static int orinoco_init(struct net_device *dev)
 		goto out;
 	}
 
-	err = determine_firmware(dev);
+	err = determine_fw_capabilities(priv);
 	if (err != 0) {
 		printk(KERN_ERR "%s: Incompatible firmware, aborting\n",
 		       dev->name);
@@ -2347,7 +2133,7 @@ static int orinoco_init(struct net_device *dev)
 			priv->do_fw_download = 0;
 
 		/* Check firmware version again */
-		err = determine_firmware(dev);
+		err = determine_fw_capabilities(priv);
 		if (err != 0) {
 			printk(KERN_ERR "%s: Incompatible firmware, aborting\n",
 			       dev->name);
-- 
1.6.0.6


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

* [PATCH 07/23] orinoco: Move card reading code into hw.c
  2009-06-18 22:21 [PATCH 00/23] orinoco: initiate cfg80211 conversion David Kilroy
                   ` (5 preceding siblings ...)
  2009-06-18 22:21 ` [PATCH 06/23] orinoco: Move firmware capability determination into hw.c David Kilroy
@ 2009-06-18 22:21 ` David Kilroy
  2009-06-18 22:21 ` [PATCH 08/23] orinoco: Move FID allocation to hw.c David Kilroy
                   ` (16 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: David Kilroy @ 2009-06-18 22:21 UTC (permalink / raw)
  To: linux-wireless; +Cc: orinoco-devel, David Kilroy

This is part of refactorring the initialisation code so that we can
load the firmware before registerring with netdev.

Signed-off-by: David Kilroy <kilroyd@googlemail.com>
---
 drivers/net/wireless/orinoco/hw.c   |  112 +++++++++++++++++++++++++++++++++++
 drivers/net/wireless/orinoco/hw.h   |    1 +
 drivers/net/wireless/orinoco/main.c |  102 +-------------------------------
 3 files changed, 115 insertions(+), 100 deletions(-)

diff --git a/drivers/net/wireless/orinoco/hw.c b/drivers/net/wireless/orinoco/hw.c
index 209c6be..40dc25c 100644
--- a/drivers/net/wireless/orinoco/hw.c
+++ b/drivers/net/wireless/orinoco/hw.c
@@ -252,6 +252,118 @@ int determine_fw_capabilities(struct orinoco_private *priv)
 	return 0;
 }
 
+/* Read settings from EEPROM into our private structure.
+ * MAC address gets dropped into callers buffer */
+int orinoco_hw_read_card_settings(struct orinoco_private *priv, u8 *dev_addr)
+{
+	struct net_device *dev = priv->ndev;
+	struct hermes_idstring nickbuf;
+	hermes_t *hw = &priv->hw;
+	int len;
+	int err;
+	u16 reclen;
+
+	/* Get the MAC address */
+	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
+			      ETH_ALEN, NULL, dev_addr);
+	if (err) {
+		printk(KERN_WARNING "%s: failed to read MAC address!\n",
+		       dev->name);
+		goto out;
+	}
+
+	printk(KERN_DEBUG "%s: MAC address %pM\n",
+	       dev->name, dev_addr);
+
+	/* Get the station name */
+	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
+			      sizeof(nickbuf), &reclen, &nickbuf);
+	if (err) {
+		printk(KERN_ERR "%s: failed to read station name\n",
+		       dev->name);
+		goto out;
+	}
+	if (nickbuf.len)
+		len = min(IW_ESSID_MAX_SIZE, (int)le16_to_cpu(nickbuf.len));
+	else
+		len = min(IW_ESSID_MAX_SIZE, 2 * reclen);
+	memcpy(priv->nick, &nickbuf.val, len);
+	priv->nick[len] = '\0';
+
+	printk(KERN_DEBUG "%s: Station name \"%s\"\n", dev->name, priv->nick);
+
+	/* Get allowed channels */
+	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CHANNELLIST,
+				  &priv->channel_mask);
+	if (err) {
+		printk(KERN_ERR "%s: failed to read channel list!\n",
+		       dev->name);
+		goto out;
+	}
+
+	/* Get initial AP density */
+	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFSYSTEMSCALE,
+				  &priv->ap_density);
+	if (err || priv->ap_density < 1 || priv->ap_density > 3)
+		priv->has_sensitivity = 0;
+
+	/* Get initial RTS threshold */
+	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD,
+				  &priv->rts_thresh);
+	if (err) {
+		printk(KERN_ERR "%s: failed to read RTS threshold!\n",
+		       dev->name);
+		goto out;
+	}
+
+	/* Get initial fragmentation settings */
+	if (priv->has_mwo)
+		err = hermes_read_wordrec(hw, USER_BAP,
+					  HERMES_RID_CNFMWOROBUST_AGERE,
+					  &priv->mwo_robust);
+	else
+		err = hermes_read_wordrec(hw, USER_BAP,
+					  HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
+					  &priv->frag_thresh);
+	if (err) {
+		printk(KERN_ERR "%s: failed to read fragmentation settings!\n",
+		       dev->name);
+		goto out;
+	}
+
+	/* Power management setup */
+	if (priv->has_pm) {
+		priv->pm_on = 0;
+		priv->pm_mcast = 1;
+		err = hermes_read_wordrec(hw, USER_BAP,
+					  HERMES_RID_CNFMAXSLEEPDURATION,
+					  &priv->pm_period);
+		if (err) {
+			printk(KERN_ERR "%s: failed to read power management "
+			       "period!\n", dev->name);
+			goto out;
+		}
+		err = hermes_read_wordrec(hw, USER_BAP,
+					  HERMES_RID_CNFPMHOLDOVERDURATION,
+					  &priv->pm_timeout);
+		if (err) {
+			printk(KERN_ERR "%s: failed to read power management "
+			       "timeout!\n", dev->name);
+			goto out;
+		}
+	}
+
+	/* Preamble setup */
+	if (priv->has_preamble) {
+		err = hermes_read_wordrec(hw, USER_BAP,
+					  HERMES_RID_CNFPREAMBLE_SYMBOL,
+					  &priv->preamble);
+	}
+
+out:
+	return err;
+}
+
 int orinoco_get_bitratemode(int bitrate, int automatic)
 {
 	int ratemode = -1;
diff --git a/drivers/net/wireless/orinoco/hw.h b/drivers/net/wireless/orinoco/hw.h
index f7845b8..6186e44 100644
--- a/drivers/net/wireless/orinoco/hw.h
+++ b/drivers/net/wireless/orinoco/hw.h
@@ -24,6 +24,7 @@ struct orinoco_private;
 struct dev_addr_list;
 
 int determine_fw_capabilities(struct orinoco_private *priv);
+int orinoco_hw_read_card_settings(struct orinoco_private *priv, u8 *dev_addr);
 int orinoco_get_bitratemode(int bitrate, int automatic);
 void orinoco_get_ratemode_cfg(int ratemode, int *bitrate, int *automatic);
 
diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c
index 33326d6..0fe9420 100644
--- a/drivers/net/wireless/orinoco/main.c
+++ b/drivers/net/wireless/orinoco/main.c
@@ -2100,9 +2100,6 @@ static int orinoco_init(struct net_device *dev)
 	struct orinoco_private *priv = netdev_priv(dev);
 	hermes_t *hw = &priv->hw;
 	int err = 0;
-	struct hermes_idstring nickbuf;
-	u16 reclen;
-	int len;
 
 	/* No need to lock, the hw_unavailable flag is already set in
 	 * alloc_orinocodev() */
@@ -2166,34 +2163,9 @@ static int orinoco_init(struct net_device *dev)
 		goto out;
 	orinoco_bss_data_init(priv);
 
-	/* Get the MAC address */
-	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
-			      ETH_ALEN, NULL, dev->dev_addr);
-	if (err) {
-		printk(KERN_WARNING "%s: failed to read MAC address!\n",
-		       dev->name);
-		goto out;
-	}
-
-	printk(KERN_DEBUG "%s: MAC address %pM\n",
-	       dev->name, dev->dev_addr);
-
-	/* Get the station name */
-	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
-			      sizeof(nickbuf), &reclen, &nickbuf);
-	if (err) {
-		printk(KERN_ERR "%s: failed to read station name\n",
-		       dev->name);
+	err = orinoco_hw_read_card_settings(priv, dev->dev_addr);
+	if (err)
 		goto out;
-	}
-	if (nickbuf.len)
-		len = min(IW_ESSID_MAX_SIZE, (int)le16_to_cpu(nickbuf.len));
-	else
-		len = min(IW_ESSID_MAX_SIZE, 2 * reclen);
-	memcpy(priv->nick, &nickbuf.val, len);
-	priv->nick[len] = '\0';
-
-	printk(KERN_DEBUG "%s: Station name \"%s\"\n", dev->name, priv->nick);
 
 	err = orinoco_allocate_fid(dev);
 	if (err) {
@@ -2202,76 +2174,6 @@ static int orinoco_init(struct net_device *dev)
 		goto out;
 	}
 
-	/* Get allowed channels */
-	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CHANNELLIST,
-				  &priv->channel_mask);
-	if (err) {
-		printk(KERN_ERR "%s: failed to read channel list!\n",
-		       dev->name);
-		goto out;
-	}
-
-	/* Get initial AP density */
-	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFSYSTEMSCALE,
-				  &priv->ap_density);
-	if (err || priv->ap_density < 1 || priv->ap_density > 3)
-		priv->has_sensitivity = 0;
-
-	/* Get initial RTS threshold */
-	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD,
-				  &priv->rts_thresh);
-	if (err) {
-		printk(KERN_ERR "%s: failed to read RTS threshold!\n",
-		       dev->name);
-		goto out;
-	}
-
-	/* Get initial fragmentation settings */
-	if (priv->has_mwo)
-		err = hermes_read_wordrec(hw, USER_BAP,
-					  HERMES_RID_CNFMWOROBUST_AGERE,
-					  &priv->mwo_robust);
-	else
-		err = hermes_read_wordrec(hw, USER_BAP,
-					  HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
-					  &priv->frag_thresh);
-	if (err) {
-		printk(KERN_ERR "%s: failed to read fragmentation settings!\n",
-		       dev->name);
-		goto out;
-	}
-
-	/* Power management setup */
-	if (priv->has_pm) {
-		priv->pm_on = 0;
-		priv->pm_mcast = 1;
-		err = hermes_read_wordrec(hw, USER_BAP,
-					  HERMES_RID_CNFMAXSLEEPDURATION,
-					  &priv->pm_period);
-		if (err) {
-			printk(KERN_ERR "%s: failed to read power management period!\n",
-			       dev->name);
-			goto out;
-		}
-		err = hermes_read_wordrec(hw, USER_BAP,
-					  HERMES_RID_CNFPMHOLDOVERDURATION,
-					  &priv->pm_timeout);
-		if (err) {
-			printk(KERN_ERR "%s: failed to read power management timeout!\n",
-			       dev->name);
-			goto out;
-		}
-	}
-
-	/* Preamble setup */
-	if (priv->has_preamble) {
-		err = hermes_read_wordrec(hw, USER_BAP,
-					  HERMES_RID_CNFPREAMBLE_SYMBOL,
-					  &priv->preamble);
-		if (err)
-			goto out;
-	}
-
 	/* Set up the default configuration */
 	priv->iw_mode = IW_MODE_INFRA;
 	/* By default use IEEE/IBSS ad-hoc mode if we have it */
-- 
1.6.0.6


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

* [PATCH 08/23] orinoco: Move FID allocation to hw.c
  2009-06-18 22:21 [PATCH 00/23] orinoco: initiate cfg80211 conversion David Kilroy
                   ` (6 preceding siblings ...)
  2009-06-18 22:21 ` [PATCH 07/23] orinoco: Move card reading code " David Kilroy
@ 2009-06-18 22:21 ` David Kilroy
  2009-06-18 22:21 ` [PATCH 09/23] orinoco: use dev_err in early initialisation routines David Kilroy
                   ` (15 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: David Kilroy @ 2009-06-18 22:21 UTC (permalink / raw)
  To: linux-wireless; +Cc: orinoco-devel, David Kilroy

This is part of refactorring the initialisation code so that we can
load the firmware before registerring with netdev.

Signed-off-by: David Kilroy <kilroyd@googlemail.com>
---
 drivers/net/wireless/orinoco/hw.c   |   23 +++++++++++++++++++++++
 drivers/net/wireless/orinoco/hw.h   |    1 +
 drivers/net/wireless/orinoco/main.c |   25 ++-----------------------
 3 files changed, 26 insertions(+), 23 deletions(-)

diff --git a/drivers/net/wireless/orinoco/hw.c b/drivers/net/wireless/orinoco/hw.c
index 40dc25c..0f6426d 100644
--- a/drivers/net/wireless/orinoco/hw.c
+++ b/drivers/net/wireless/orinoco/hw.c
@@ -15,6 +15,9 @@
 
 #define SYMBOL_MAX_VER_LEN	(14)
 
+/* Symbol firmware has a bug allocating buffers larger than this */
+#define TX_NICBUF_SIZE_BUG	1585
+
 /********************************************************************/
 /* Data tables                                                      */
 /********************************************************************/
@@ -364,6 +367,26 @@ out:
 	return err;
 }
 
+int orinoco_hw_allocate_fid(struct orinoco_private *priv)
+{
+	struct net_device *dev = priv->ndev;
+	struct hermes *hw = &priv->hw;
+	int err;
+
+	err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
+	if (err == -EIO && priv->nicbuf_size > TX_NICBUF_SIZE_BUG) {
+		/* Try workaround for old Symbol firmware bug */
+		priv->nicbuf_size = TX_NICBUF_SIZE_BUG;
+		err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
+
+		printk(KERN_WARNING "%s: firmware ALLOC bug detected "
+		       "(old Symbol firmware?). Work around %s\n",
+		       dev->name, err ? "failed!" : "ok.");
+	}
+
+	return err;
+}
+
 int orinoco_get_bitratemode(int bitrate, int automatic)
 {
 	int ratemode = -1;
diff --git a/drivers/net/wireless/orinoco/hw.h b/drivers/net/wireless/orinoco/hw.h
index 6186e44..89277de 100644
--- a/drivers/net/wireless/orinoco/hw.h
+++ b/drivers/net/wireless/orinoco/hw.h
@@ -25,6 +25,7 @@ struct dev_addr_list;
 
 int determine_fw_capabilities(struct orinoco_private *priv);
 int orinoco_hw_read_card_settings(struct orinoco_private *priv, u8 *dev_addr);
+int orinoco_hw_allocate_fid(struct orinoco_private *priv);
 int orinoco_get_bitratemode(int bitrate, int automatic);
 void orinoco_get_ratemode_cfg(int ratemode, int *bitrate, int *automatic);
 
diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c
index 0fe9420..58a48db 100644
--- a/drivers/net/wireless/orinoco/main.c
+++ b/drivers/net/wireless/orinoco/main.c
@@ -147,7 +147,6 @@ static const u8 encaps_hdr[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
 					    * how many events the
 					    * device could
 					    * legitimately generate */
-#define TX_NICBUF_SIZE_BUG	1585		/* Bug in Symbol firmware */
 
 #define DUMMY_FID		0xFFFF
 
@@ -1574,26 +1573,6 @@ int __orinoco_down(struct net_device *dev)
 }
 EXPORT_SYMBOL(__orinoco_down);
 
-static int orinoco_allocate_fid(struct net_device *dev)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	struct hermes *hw = &priv->hw;
-	int err;
-
-	err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
-	if (err == -EIO && priv->nicbuf_size > TX_NICBUF_SIZE_BUG) {
-		/* Try workaround for old Symbol firmware bug */
-		priv->nicbuf_size = TX_NICBUF_SIZE_BUG;
-		err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
-
-		printk(KERN_WARNING "%s: firmware ALLOC bug detected "
-		       "(old Symbol firmware?). Work around %s\n",
-		       dev->name, err ? "failed!" : "ok.");
-	}
-
-	return err;
-}
-
 int orinoco_reinit_firmware(struct net_device *dev)
 {
 	struct orinoco_private *priv = netdev_priv(dev);
@@ -1607,7 +1586,7 @@ int orinoco_reinit_firmware(struct net_device *dev)
 			priv->do_fw_download = 0;
 	}
 	if (!err)
-		err = orinoco_allocate_fid(dev);
+		err = orinoco_hw_allocate_fid(priv);
 
 	return err;
 }
@@ -2167,7 +2146,7 @@ static int orinoco_init(struct net_device *dev)
 	if (err)
 		goto out;
 
-	err = orinoco_allocate_fid(dev);
+	err = orinoco_hw_allocate_fid(priv);
 	if (err) {
 		printk(KERN_ERR "%s: failed to allocate NIC buffer!\n",
 		       dev->name);
-- 
1.6.0.6


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

* [PATCH 09/23] orinoco: use dev_err in early initialisation routines
  2009-06-18 22:21 [PATCH 00/23] orinoco: initiate cfg80211 conversion David Kilroy
                   ` (7 preceding siblings ...)
  2009-06-18 22:21 ` [PATCH 08/23] orinoco: Move FID allocation to hw.c David Kilroy
@ 2009-06-18 22:21 ` David Kilroy
  2009-06-18 22:21 ` [PATCH 10/23] orinoco: firmware helpers should use dev_err and friends David Kilroy
                   ` (14 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: David Kilroy @ 2009-06-18 22:21 UTC (permalink / raw)
  To: linux-wireless; +Cc: orinoco-devel, David Kilroy

This allows us to use determine_fw_capabilities,
orinoco_hw_read_card_setting and orinoco_hw_allocate_fid prior to
netdev registration.

Since dev_dbg only prints if DEBUG is defined (or dynamic debug is
enabled), move a couple of the more useful prints up to info.

Signed-off-by: David Kilroy <kilroyd@googlemail.com>
---
 drivers/net/wireless/orinoco/hw.c |   92 +++++++++++++++++--------------------
 1 files changed, 42 insertions(+), 50 deletions(-)

diff --git a/drivers/net/wireless/orinoco/hw.c b/drivers/net/wireless/orinoco/hw.c
index 0f6426d..4a26d68 100644
--- a/drivers/net/wireless/orinoco/hw.c
+++ b/drivers/net/wireless/orinoco/hw.c
@@ -3,6 +3,7 @@
  * See copyright notice in main.c
  */
 #include <linux/kernel.h>
+#include <linux/device.h>
 #include <linux/if_arp.h>
 #include <linux/ieee80211.h>
 #include <linux/wireless.h>
@@ -56,10 +57,13 @@ static inline fwtype_t determine_firmware_type(struct comp_id *nic_id)
 		return FIRMWARE_TYPE_INTERSIL;
 }
 
-/* Set priv->firmware type, determine firmware properties */
+/* Set priv->firmware type, determine firmware properties
+ * This function can be called before we have registerred with netdev,
+ * so all errors go out with dev_* rather than printk
+ */
 int determine_fw_capabilities(struct orinoco_private *priv)
 {
-	struct net_device *dev = priv->ndev;
+	struct device *dev = priv->dev;
 	hermes_t *hw = &priv->hw;
 	int err;
 	struct comp_id nic_id, sta_id;
@@ -69,8 +73,8 @@ int determine_fw_capabilities(struct orinoco_private *priv)
 	/* Get the hardware version */
 	err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_NICID, &nic_id);
 	if (err) {
-		printk(KERN_ERR "%s: Cannot read hardware identity: error %d\n",
-		       dev->name, err);
+		dev_err(dev, "Cannot read hardware identity: error %d\n",
+			err);
 		return err;
 	}
 
@@ -78,17 +82,16 @@ int determine_fw_capabilities(struct orinoco_private *priv)
 	le16_to_cpus(&nic_id.variant);
 	le16_to_cpus(&nic_id.major);
 	le16_to_cpus(&nic_id.minor);
-	printk(KERN_DEBUG "%s: Hardware identity %04x:%04x:%04x:%04x\n",
-	       dev->name, nic_id.id, nic_id.variant,
-	       nic_id.major, nic_id.minor);
+	dev_info(dev, "Hardware identity %04x:%04x:%04x:%04x\n",
+		 nic_id.id, nic_id.variant, nic_id.major, nic_id.minor);
 
 	priv->firmware_type = determine_firmware_type(&nic_id);
 
 	/* Get the firmware version */
 	err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_STAID, &sta_id);
 	if (err) {
-		printk(KERN_ERR "%s: Cannot read station identity: error %d\n",
-		       dev->name, err);
+		dev_err(dev, "Cannot read station identity: error %d\n",
+			err);
 		return err;
 	}
 
@@ -96,25 +99,21 @@ int determine_fw_capabilities(struct orinoco_private *priv)
 	le16_to_cpus(&sta_id.variant);
 	le16_to_cpus(&sta_id.major);
 	le16_to_cpus(&sta_id.minor);
-	printk(KERN_DEBUG "%s: Station identity  %04x:%04x:%04x:%04x\n",
-	       dev->name, sta_id.id, sta_id.variant,
-	       sta_id.major, sta_id.minor);
+	dev_info(dev, "Station identity  %04x:%04x:%04x:%04x\n",
+		 sta_id.id, sta_id.variant, sta_id.major, sta_id.minor);
 
 	switch (sta_id.id) {
 	case 0x15:
-		printk(KERN_ERR "%s: Primary firmware is active\n",
-		       dev->name);
+		dev_err(dev, "Primary firmware is active\n");
 		return -ENODEV;
 	case 0x14b:
-		printk(KERN_ERR "%s: Tertiary firmware is active\n",
-		       dev->name);
+		dev_err(dev, "Tertiary firmware is active\n");
 		return -ENODEV;
 	case 0x1f:	/* Intersil, Agere, Symbol Spectrum24 */
 	case 0x21:	/* Symbol Spectrum24 Trilogy */
 		break;
 	default:
-		printk(KERN_NOTICE "%s: Unknown station ID, please report\n",
-		       dev->name);
+		dev_notice(dev, "Unknown station ID, please report\n");
 		break;
 	}
 
@@ -168,10 +167,8 @@ int determine_fw_capabilities(struct orinoco_private *priv)
 				      HERMES_RID_SECONDARYVERSION_SYMBOL,
 				      SYMBOL_MAX_VER_LEN, NULL, &tmp);
 		if (err) {
-			printk(KERN_WARNING
-			       "%s: Error %d reading Symbol firmware info. "
-			       "Wildly guessing capabilities...\n",
-			       dev->name, err);
+			dev_warn(dev, "Error %d reading Symbol firmware info. "
+				 "Wildly guessing capabilities...\n", err);
 			firmver = 0;
 			tmp[0] = '\0';
 		} else {
@@ -242,24 +239,24 @@ int determine_fw_capabilities(struct orinoco_private *priv)
 		if (firmver >= 0x000800)
 			priv->ibss_port = 0;
 		else {
-			printk(KERN_NOTICE "%s: Intersil firmware earlier "
-			       "than v0.8.x - several features not supported\n",
-			       dev->name);
+			dev_notice(dev, "Intersil firmware earlier than v0.8.x"
+				   " - several features not supported\n");
 			priv->ibss_port = 1;
 		}
 		break;
 	}
-	printk(KERN_DEBUG "%s: Firmware determined as %s\n", dev->name,
-	       priv->fw_name);
+	dev_info(dev, "Firmware determined as %s\n", priv->fw_name);
 
 	return 0;
 }
 
 /* Read settings from EEPROM into our private structure.
- * MAC address gets dropped into callers buffer */
+ * MAC address gets dropped into callers buffer
+ * Can be called before netdev registration.
+ */
 int orinoco_hw_read_card_settings(struct orinoco_private *priv, u8 *dev_addr)
 {
-	struct net_device *dev = priv->ndev;
+	struct device *dev = priv->dev;
 	struct hermes_idstring nickbuf;
 	hermes_t *hw = &priv->hw;
 	int len;
@@ -270,20 +267,17 @@ int orinoco_hw_read_card_settings(struct orinoco_private *priv, u8 *dev_addr)
 	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
 			      ETH_ALEN, NULL, dev_addr);
 	if (err) {
-		printk(KERN_WARNING "%s: failed to read MAC address!\n",
-		       dev->name);
+		dev_warn(dev, "Failed to read MAC address!\n");
 		goto out;
 	}
 
-	printk(KERN_DEBUG "%s: MAC address %pM\n",
-	       dev->name, dev_addr);
+	dev_dbg(dev, "MAC address %pM\n", dev_addr);
 
 	/* Get the station name */
 	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
 			      sizeof(nickbuf), &reclen, &nickbuf);
 	if (err) {
-		printk(KERN_ERR "%s: failed to read station name\n",
-		       dev->name);
+		dev_err(dev, "failed to read station name\n");
 		goto out;
 	}
 	if (nickbuf.len)
@@ -293,14 +287,13 @@ int orinoco_hw_read_card_settings(struct orinoco_private *priv, u8 *dev_addr)
 	memcpy(priv->nick, &nickbuf.val, len);
 	priv->nick[len] = '\0';
 
-	printk(KERN_DEBUG "%s: Station name \"%s\"\n", dev->name, priv->nick);
+	dev_dbg(dev, "Station name \"%s\"\n", priv->nick);
 
 	/* Get allowed channels */
 	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CHANNELLIST,
 				  &priv->channel_mask);
 	if (err) {
-		printk(KERN_ERR "%s: failed to read channel list!\n",
-		       dev->name);
+		dev_err(dev, "Failed to read channel list!\n");
 		goto out;
 	}
 
@@ -314,8 +307,7 @@ int orinoco_hw_read_card_settings(struct orinoco_private *priv, u8 *dev_addr)
 	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD,
 				  &priv->rts_thresh);
 	if (err) {
-		printk(KERN_ERR "%s: failed to read RTS threshold!\n",
-		       dev->name);
+		dev_err(dev, "Failed to read RTS threshold!\n");
 		goto out;
 	}
 
@@ -329,8 +321,7 @@ int orinoco_hw_read_card_settings(struct orinoco_private *priv, u8 *dev_addr)
 					  HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
 					  &priv->frag_thresh);
 	if (err) {
-		printk(KERN_ERR "%s: failed to read fragmentation settings!\n",
-		       dev->name);
+		dev_err(dev, "Failed to read fragmentation settings!\n");
 		goto out;
 	}
 
@@ -342,16 +333,16 @@ int orinoco_hw_read_card_settings(struct orinoco_private *priv, u8 *dev_addr)
 					  HERMES_RID_CNFMAXSLEEPDURATION,
 					  &priv->pm_period);
 		if (err) {
-			printk(KERN_ERR "%s: failed to read power management "
-			       "period!\n", dev->name);
+			dev_err(dev, "Failed to read power management "
+				"period!\n");
 			goto out;
 		}
 		err = hermes_read_wordrec(hw, USER_BAP,
 					  HERMES_RID_CNFPMHOLDOVERDURATION,
 					  &priv->pm_timeout);
 		if (err) {
-			printk(KERN_ERR "%s: failed to read power management "
-			       "timeout!\n", dev->name);
+			dev_err(dev, "Failed to read power management "
+				"timeout!\n");
 			goto out;
 		}
 	}
@@ -367,9 +358,10 @@ out:
 	return err;
 }
 
+/* Can be called before netdev registration */
 int orinoco_hw_allocate_fid(struct orinoco_private *priv)
 {
-	struct net_device *dev = priv->ndev;
+	struct device *dev = priv->dev;
 	struct hermes *hw = &priv->hw;
 	int err;
 
@@ -379,9 +371,9 @@ int orinoco_hw_allocate_fid(struct orinoco_private *priv)
 		priv->nicbuf_size = TX_NICBUF_SIZE_BUG;
 		err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
 
-		printk(KERN_WARNING "%s: firmware ALLOC bug detected "
-		       "(old Symbol firmware?). Work around %s\n",
-		       dev->name, err ? "failed!" : "ok.");
+		dev_warn(dev, "Firmware ALLOC bug detected "
+			 "(old Symbol firmware?). Work around %s\n",
+			 err ? "failed!" : "ok.");
 	}
 
 	return err;
-- 
1.6.0.6


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

* [PATCH 10/23] orinoco: firmware helpers should use dev_err and friends
  2009-06-18 22:21 [PATCH 00/23] orinoco: initiate cfg80211 conversion David Kilroy
                   ` (8 preceding siblings ...)
  2009-06-18 22:21 ` [PATCH 09/23] orinoco: use dev_err in early initialisation routines David Kilroy
@ 2009-06-18 22:21 ` David Kilroy
  2009-06-18 22:21 ` [PATCH 11/23] orinoco: Replace net_device with orinoco_private in driver interfaces David Kilroy
                   ` (13 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: David Kilroy @ 2009-06-18 22:21 UTC (permalink / raw)
  To: linux-wireless; +Cc: orinoco-devel, David Kilroy

We should be able to call these routines before we register with
netdev, so avoid printks using the netdev name.

Signed-off-by: David Kilroy <kilroyd@googlemail.com>
---
 drivers/net/wireless/orinoco/fw.c |   41 +++++++++++++++---------------------
 1 files changed, 17 insertions(+), 24 deletions(-)

diff --git a/drivers/net/wireless/orinoco/fw.c b/drivers/net/wireless/orinoco/fw.c
index 1084b43..1257250 100644
--- a/drivers/net/wireless/orinoco/fw.c
+++ b/drivers/net/wireless/orinoco/fw.c
@@ -4,6 +4,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/firmware.h>
+#include <linux/device.h>
 
 #include "hermes.h"
 #include "hermes_dld.h"
@@ -99,7 +100,7 @@ orinoco_dl_firmware(struct orinoco_private *priv,
 	const void *end;
 	const char *firmware;
 	const char *fw_err;
-	struct net_device *dev = priv->ndev;
+	struct device *dev = priv->dev;
 	int err = 0;
 
 	pda = kzalloc(fw->pda_size, GFP_KERNEL);
@@ -111,12 +112,11 @@ orinoco_dl_firmware(struct orinoco_private *priv,
 	else
 		firmware = fw->sta_fw;
 
-	printk(KERN_DEBUG "%s: Attempting to download firmware %s\n",
-	       dev->name, firmware);
+	dev_dbg(dev, "Attempting to download firmware %s\n", firmware);
 
 	/* Read current plug data */
 	err = hermes_read_pda(hw, pda, fw->pda_addr, fw->pda_size, 0);
-	printk(KERN_DEBUG "%s: Read PDA returned %d\n", dev->name, err);
+	dev_dbg(dev, "Read PDA returned %d\n", err);
 	if (err)
 		goto free;
 
@@ -124,8 +124,7 @@ orinoco_dl_firmware(struct orinoco_private *priv,
 		err = request_firmware(&fw_entry, firmware, priv->dev);
 
 		if (err) {
-			printk(KERN_ERR "%s: Cannot find firmware %s\n",
-			       dev->name, firmware);
+			dev_err(dev, "Cannot find firmware %s\n", firmware);
 			err = -ENOENT;
 			goto free;
 		}
@@ -136,16 +135,15 @@ orinoco_dl_firmware(struct orinoco_private *priv,
 
 	fw_err = validate_fw(hdr, fw_entry->size);
 	if (fw_err) {
-		printk(KERN_WARNING "%s: Invalid firmware image detected (%s). "
-		       "Aborting download\n",
-		       dev->name, fw_err);
+		dev_warn(dev, "Invalid firmware image detected (%s). "
+			 "Aborting download\n", fw_err);
 		err = -EINVAL;
 		goto abort;
 	}
 
 	/* Enable aux port to allow programming */
 	err = hermesi_program_init(hw, le32_to_cpu(hdr->entry_point));
-	printk(KERN_DEBUG "%s: Program init returned %d\n", dev->name, err);
+	dev_dbg(dev, "Program init returned %d\n", err);
 	if (err != 0)
 		goto abort;
 
@@ -156,7 +154,7 @@ orinoco_dl_firmware(struct orinoco_private *priv,
 	end = fw_entry->data + fw_entry->size;
 
 	err = hermes_program(hw, first_block, end);
-	printk(KERN_DEBUG "%s: Program returned %d\n", dev->name, err);
+	dev_dbg(dev, "Program returned %d\n", err);
 	if (err != 0)
 		goto abort;
 
@@ -167,19 +165,18 @@ orinoco_dl_firmware(struct orinoco_private *priv,
 
 	err = hermes_apply_pda_with_defaults(hw, first_block, end, pda,
 					     &pda[fw->pda_size / sizeof(*pda)]);
-	printk(KERN_DEBUG "%s: Apply PDA returned %d\n", dev->name, err);
+	dev_dbg(dev, "Apply PDA returned %d\n", err);
 	if (err)
 		goto abort;
 
 	/* Tell card we've finished */
 	err = hermesi_program_end(hw);
-	printk(KERN_DEBUG "%s: Program end returned %d\n", dev->name, err);
+	dev_dbg(dev, "Program end returned %d\n", err);
 	if (err != 0)
 		goto abort;
 
 	/* Check if we're running */
-	printk(KERN_DEBUG "%s: hermes_present returned %d\n",
-	       dev->name, hermes_present(hw));
+	dev_dbg(dev, "hermes_present returned %d\n", hermes_present(hw));
 
 abort:
 	/* If we requested the firmware, release it. */
@@ -282,14 +279,13 @@ static int
 symbol_dl_firmware(struct orinoco_private *priv,
 		   const struct fw_info *fw)
 {
-	struct net_device *dev = priv->ndev;
+	struct device *dev = priv->dev;
 	int ret;
 	const struct firmware *fw_entry;
 
 	if (!orinoco_cached_fw_get(priv, true)) {
 		if (request_firmware(&fw_entry, fw->pri_fw, priv->dev) != 0) {
-			printk(KERN_ERR "%s: Cannot find firmware: %s\n",
-			       dev->name, fw->pri_fw);
+			dev_err(dev, "Cannot find firmware: %s\n", fw->pri_fw);
 			return -ENOENT;
 		}
 	} else
@@ -302,15 +298,13 @@ symbol_dl_firmware(struct orinoco_private *priv,
 	if (!orinoco_cached_fw_get(priv, true))
 		release_firmware(fw_entry);
 	if (ret) {
-		printk(KERN_ERR "%s: Primary firmware download failed\n",
-		       dev->name);
+		dev_err(dev, "Primary firmware download failed\n");
 		return ret;
 	}
 
 	if (!orinoco_cached_fw_get(priv, false)) {
 		if (request_firmware(&fw_entry, fw->sta_fw, priv->dev) != 0) {
-			printk(KERN_ERR "%s: Cannot find firmware: %s\n",
-			       dev->name, fw->sta_fw);
+			dev_err(dev, "Cannot find firmware: %s\n", fw->sta_fw);
 			return -ENOENT;
 		}
 	} else
@@ -322,8 +316,7 @@ symbol_dl_firmware(struct orinoco_private *priv,
 	if (!orinoco_cached_fw_get(priv, false))
 		release_firmware(fw_entry);
 	if (ret) {
-		printk(KERN_ERR "%s: Secondary firmware download failed\n",
-		       dev->name);
+		dev_err(dev, "Secondary firmware download failed\n");
 	}
 
 	return ret;
-- 
1.6.0.6


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

* [PATCH 11/23] orinoco: Replace net_device with orinoco_private in driver interfaces
  2009-06-18 22:21 [PATCH 00/23] orinoco: initiate cfg80211 conversion David Kilroy
                   ` (9 preceding siblings ...)
  2009-06-18 22:21 ` [PATCH 10/23] orinoco: firmware helpers should use dev_err and friends David Kilroy
@ 2009-06-18 22:21 ` David Kilroy
  2009-06-18 22:21 ` [PATCH 12/23] orinoco: initialise independently of netdev David Kilroy
                   ` (12 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: David Kilroy @ 2009-06-18 22:21 UTC (permalink / raw)
  To: linux-wireless; +Cc: orinoco-devel, David Kilroy

Move away from using net_device as the main structure in orinoco
function calls. Use orinoco_private instead.

This makes more sense when we move to cfg80211, and we get wiphys as
well.

Signed-off-by: David Kilroy <kilroyd@googlemail.com>
---
 drivers/net/wireless/orinoco/airport.c        |   36 +++++++++++-----------
 drivers/net/wireless/orinoco/main.c           |   31 +++++++++----------
 drivers/net/wireless/orinoco/orinoco.h        |   10 +++---
 drivers/net/wireless/orinoco/orinoco_cs.c     |   39 +++++++++++-------------
 drivers/net/wireless/orinoco/orinoco_nortel.c |   24 +++++++-------
 drivers/net/wireless/orinoco/orinoco_pci.c    |   24 +++++++-------
 drivers/net/wireless/orinoco/orinoco_pci.h    |   18 +++++-----
 drivers/net/wireless/orinoco/orinoco_plx.c    |   24 +++++++-------
 drivers/net/wireless/orinoco/orinoco_tmd.c    |   24 +++++++-------
 drivers/net/wireless/orinoco/spectrum_cs.c    |   41 +++++++++++-------------
 10 files changed, 132 insertions(+), 139 deletions(-)

diff --git a/drivers/net/wireless/orinoco/airport.c b/drivers/net/wireless/orinoco/airport.c
index 8c4065f..6559aee 100644
--- a/drivers/net/wireless/orinoco/airport.c
+++ b/drivers/net/wireless/orinoco/airport.c
@@ -34,8 +34,8 @@ struct airport {
 static int
 airport_suspend(struct macio_dev *mdev, pm_message_t state)
 {
-	struct net_device *dev = dev_get_drvdata(&mdev->ofdev.dev);
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = dev_get_drvdata(&mdev->ofdev.dev);
+	struct net_device *dev = priv->ndev;
 	unsigned long flags;
 	int err;
 
@@ -48,7 +48,7 @@ airport_suspend(struct macio_dev *mdev, pm_message_t state)
 		return 0;
 	}
 
-	err = __orinoco_down(dev);
+	err = __orinoco_down(priv);
 	if (err)
 		printk(KERN_WARNING "%s: PBOOK_SLEEP_NOW: Error %d downing interface\n",
 		       dev->name, err);
@@ -69,8 +69,8 @@ airport_suspend(struct macio_dev *mdev, pm_message_t state)
 static int
 airport_resume(struct macio_dev *mdev)
 {
-	struct net_device *dev = dev_get_drvdata(&mdev->ofdev.dev);
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = dev_get_drvdata(&mdev->ofdev.dev);
+	struct net_device *dev = priv->ndev;
 	unsigned long flags;
 	int err;
 
@@ -82,7 +82,7 @@ airport_resume(struct macio_dev *mdev)
 
 	enable_irq(dev->irq);
 
-	err = orinoco_reinit_firmware(dev);
+	err = orinoco_reinit_firmware(priv);
 	if (err) {
 		printk(KERN_ERR "%s: Error %d re-initializing firmware on PBOOK_WAKE\n",
 		       dev->name, err);
@@ -96,7 +96,7 @@ airport_resume(struct macio_dev *mdev)
 	priv->hw_unavailable--;
 
 	if (priv->open && (!priv->hw_unavailable)) {
-		err = __orinoco_up(dev);
+		err = __orinoco_up(priv);
 		if (err)
 			printk(KERN_ERR "%s: Error %d restarting card on PBOOK_WAKE\n",
 			       dev->name, err);
@@ -111,8 +111,8 @@ airport_resume(struct macio_dev *mdev)
 static int
 airport_detach(struct macio_dev *mdev)
 {
-	struct net_device *dev = dev_get_drvdata(&mdev->ofdev.dev);
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = dev_get_drvdata(&mdev->ofdev.dev);
+	struct net_device *dev = priv->ndev;
 	struct airport *card = priv->card;
 
 	if (card->ndev_registered)
@@ -120,7 +120,7 @@ airport_detach(struct macio_dev *mdev)
 	card->ndev_registered = 0;
 
 	if (card->irq_requested)
-		free_irq(dev->irq, dev);
+		free_irq(dev->irq, priv);
 	card->irq_requested = 0;
 
 	if (card->vaddr)
@@ -134,7 +134,7 @@ airport_detach(struct macio_dev *mdev)
 	ssleep(1);
 
 	macio_set_drvdata(mdev, NULL);
-	free_orinocodev(dev);
+	free_orinocodev(priv);
 
 	return 0;
 }
@@ -185,13 +185,13 @@ airport_attach(struct macio_dev *mdev, const struct of_device_id *match)
 	}
 
 	/* Allocate space for private device-specific data */
-	dev = alloc_orinocodev(sizeof(*card), &mdev->ofdev.dev,
-			       airport_hard_reset, NULL);
-	if (!dev) {
+	priv = alloc_orinocodev(sizeof(*card), &mdev->ofdev.dev,
+				airport_hard_reset, NULL);
+	if (!priv) {
 		printk(KERN_ERR PFX "Cannot allocate network device\n");
 		return -ENODEV;
 	}
-	priv = netdev_priv(dev);
+	dev = priv->ndev;
 	card = priv->card;
 
 	hw = &priv->hw;
@@ -199,13 +199,13 @@ airport_attach(struct macio_dev *mdev, const struct of_device_id *match)
 
 	if (macio_request_resource(mdev, 0, "airport")) {
 		printk(KERN_ERR PFX "can't request IO resource !\n");
-		free_orinocodev(dev);
+		free_orinocodev(priv);
 		return -EBUSY;
 	}
 
 	SET_NETDEV_DEV(dev, &mdev->ofdev.dev);
 
-	macio_set_drvdata(mdev, dev);
+	macio_set_drvdata(mdev, priv);
 
 	/* Setup interrupts & base address */
 	dev->irq = macio_irq(mdev, 0);
@@ -228,7 +228,7 @@ airport_attach(struct macio_dev *mdev, const struct of_device_id *match)
 	/* Reset it before we get the interrupt */
 	hermes_init(hw);
 
-	if (request_irq(dev->irq, orinoco_interrupt, 0, dev->name, dev)) {
+	if (request_irq(dev->irq, orinoco_interrupt, 0, dev->name, priv)) {
 		printk(KERN_ERR PFX "Couldn't get IRQ %d\n", dev->irq);
 		goto failed;
 	}
diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c
index 58a48db..4fa8264 100644
--- a/drivers/net/wireless/orinoco/main.c
+++ b/drivers/net/wireless/orinoco/main.c
@@ -252,7 +252,7 @@ static int orinoco_open(struct net_device *dev)
 	if (orinoco_lock(priv, &flags) != 0)
 		return -EBUSY;
 
-	err = __orinoco_up(dev);
+	err = __orinoco_up(priv);
 
 	if (!err)
 		priv->open = 1;
@@ -274,7 +274,7 @@ static int orinoco_stop(struct net_device *dev)
 
 	priv->open = 0;
 
-	err = __orinoco_down(dev);
+	err = __orinoco_down(priv);
 
 	spin_unlock_irq(&priv->lock);
 
@@ -1511,9 +1511,9 @@ static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw)
 /* Internal hardware control routines                               */
 /********************************************************************/
 
-int __orinoco_up(struct net_device *dev)
+int __orinoco_up(struct orinoco_private *priv)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct net_device *dev = priv->ndev;
 	struct hermes *hw = &priv->hw;
 	int err;
 
@@ -1541,9 +1541,9 @@ int __orinoco_up(struct net_device *dev)
 }
 EXPORT_SYMBOL(__orinoco_up);
 
-int __orinoco_down(struct net_device *dev)
+int __orinoco_down(struct orinoco_private *priv)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct net_device *dev = priv->ndev;
 	struct hermes *hw = &priv->hw;
 	int err;
 
@@ -1573,9 +1573,8 @@ int __orinoco_down(struct net_device *dev)
 }
 EXPORT_SYMBOL(__orinoco_down);
 
-int orinoco_reinit_firmware(struct net_device *dev)
+int orinoco_reinit_firmware(struct orinoco_private *priv)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
 	struct hermes *hw = &priv->hw;
 	int err;
 
@@ -1887,7 +1886,7 @@ void orinoco_reset(struct work_struct *work)
 		}
 	}
 
-	err = orinoco_reinit_firmware(dev);
+	err = orinoco_reinit_firmware(priv);
 	if (err) {
 		printk(KERN_ERR "%s: orinoco_reset: Error %d re-initializing firmware\n",
 		       dev->name, err);
@@ -1902,7 +1901,7 @@ void orinoco_reset(struct work_struct *work)
 	/* priv->open or priv->hw_unavailable might have changed while
 	 * we dropped the lock */
 	if (priv->open && (!priv->hw_unavailable)) {
-		err = __orinoco_up(dev);
+		err = __orinoco_up(priv);
 		if (err) {
 			printk(KERN_ERR "%s: orinoco_reset: Error %d reenabling card\n",
 			       dev->name, err);
@@ -1938,8 +1937,8 @@ static void __orinoco_ev_wterr(struct net_device *dev, hermes_t *hw)
 
 irqreturn_t orinoco_interrupt(int irq, void *dev_id)
 {
-	struct net_device *dev = dev_id;
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = dev_id;
+	struct net_device *dev = priv->ndev;
 	hermes_t *hw = &priv->hw;
 	int count = MAX_IRQLOOPS_PER_IRQ;
 	u16 evstat, events;
@@ -2192,7 +2191,7 @@ static const struct net_device_ops orinoco_netdev_ops = {
 	.ndo_get_stats		= orinoco_get_stats,
 };
 
-struct net_device
+struct orinoco_private
 *alloc_orinocodev(int sizeof_card,
 		  struct device *device,
 		  int (*hard_reset)(struct orinoco_private *),
@@ -2255,13 +2254,13 @@ struct net_device
 	/* Register PM notifiers */
 	orinoco_register_pm_notifier(priv);
 
-	return dev;
+	return priv;
 }
 EXPORT_SYMBOL(alloc_orinocodev);
 
-void free_orinocodev(struct net_device *dev)
+void free_orinocodev(struct orinoco_private *priv)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct net_device *dev = priv->ndev;
 	struct orinoco_rx_data *rx_data, *temp;
 
 	/* If the tasklet is scheduled when we call tasklet_kill it
diff --git a/drivers/net/wireless/orinoco/orinoco.h b/drivers/net/wireless/orinoco/orinoco.h
index 8e5a72c..b93e86c 100644
--- a/drivers/net/wireless/orinoco/orinoco.h
+++ b/drivers/net/wireless/orinoco/orinoco.h
@@ -182,14 +182,14 @@ extern int orinoco_debug;
 /* Exported prototypes                                              */
 /********************************************************************/
 
-extern struct net_device *alloc_orinocodev(
+extern struct orinoco_private *alloc_orinocodev(
 	int sizeof_card, struct device *device,
 	int (*hard_reset)(struct orinoco_private *),
 	int (*stop_fw)(struct orinoco_private *, int));
-extern void free_orinocodev(struct net_device *dev);
-extern int __orinoco_up(struct net_device *dev);
-extern int __orinoco_down(struct net_device *dev);
-extern int orinoco_reinit_firmware(struct net_device *dev);
+extern void free_orinocodev(struct orinoco_private *priv);
+extern int __orinoco_up(struct orinoco_private *priv);
+extern int __orinoco_down(struct orinoco_private *priv);
+extern int orinoco_reinit_firmware(struct orinoco_private *priv);
 extern irqreturn_t orinoco_interrupt(int irq, void *dev_id);
 
 /********************************************************************/
diff --git a/drivers/net/wireless/orinoco/orinoco_cs.c b/drivers/net/wireless/orinoco/orinoco_cs.c
index b381aed..fa8fe5b 100644
--- a/drivers/net/wireless/orinoco/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco/orinoco_cs.c
@@ -106,26 +106,24 @@ orinoco_cs_hard_reset(struct orinoco_private *priv)
 static int
 orinoco_cs_probe(struct pcmcia_device *link)
 {
-	struct net_device *dev;
 	struct orinoco_private *priv;
 	struct orinoco_pccard *card;
 
-	dev = alloc_orinocodev(sizeof(*card), &handle_to_dev(link),
-			       orinoco_cs_hard_reset, NULL);
-	if (!dev)
+	priv = alloc_orinocodev(sizeof(*card), &handle_to_dev(link),
+				orinoco_cs_hard_reset, NULL);
+	if (!priv)
 		return -ENOMEM;
-	priv = netdev_priv(dev);
 	card = priv->card;
 
 	/* Link both structures together */
 	card->p_dev = link;
-	link->priv = dev;
+	link->priv = priv;
 
 	/* Interrupt setup */
 	link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
 	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
 	link->irq.Handler = orinoco_interrupt;
-	link->irq.Instance = dev;
+	link->irq.Instance = priv;
 
 	/* General socket configuration defaults can go here.  In this
 	 * client, we assume very little, and rely on the CIS for
@@ -146,14 +144,14 @@ orinoco_cs_probe(struct pcmcia_device *link)
  */
 static void orinoco_cs_detach(struct pcmcia_device *link)
 {
-	struct net_device *dev = link->priv;
+	struct orinoco_private *priv = link->priv;
 
 	if (link->dev_node)
-		unregister_netdev(dev);
+		unregister_netdev(priv->ndev);
 
 	orinoco_cs_release(link);
 
-	free_orinocodev(dev);
+	free_orinocodev(priv);
 }				/* orinoco_cs_detach */
 
 /*
@@ -239,9 +237,9 @@ next_entry:
 static int
 orinoco_cs_config(struct pcmcia_device *link)
 {
-	struct net_device *dev = link->priv;
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = link->priv;
 	struct orinoco_pccard *card = priv->card;
+	struct net_device *dev = priv->ndev;
 	hermes_t *hw = &priv->hw;
 	int last_fn, last_ret;
 	void __iomem *mem;
@@ -336,8 +334,7 @@ orinoco_cs_config(struct pcmcia_device *link)
 static void
 orinoco_cs_release(struct pcmcia_device *link)
 {
-	struct net_device *dev = link->priv;
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = link->priv;
 	unsigned long flags;
 
 	/* We're committed to taking the device away now, so mark the
@@ -353,9 +350,9 @@ orinoco_cs_release(struct pcmcia_device *link)
 
 static int orinoco_cs_suspend(struct pcmcia_device *link)
 {
-	struct net_device *dev = link->priv;
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = link->priv;
 	struct orinoco_pccard *card = priv->card;
+	struct net_device *dev = priv->ndev;
 	int err = 0;
 	unsigned long flags;
 
@@ -365,7 +362,7 @@ static int orinoco_cs_suspend(struct pcmcia_device *link)
 	if (!test_bit(0, &card->hard_reset_in_progress)) {
 		spin_lock_irqsave(&priv->lock, flags);
 
-		err = __orinoco_down(dev);
+		err = __orinoco_down(priv);
 		if (err)
 			printk(KERN_WARNING "%s: Error %d downing interface\n",
 			       dev->name, err);
@@ -381,14 +378,14 @@ static int orinoco_cs_suspend(struct pcmcia_device *link)
 
 static int orinoco_cs_resume(struct pcmcia_device *link)
 {
-	struct net_device *dev = link->priv;
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = link->priv;
 	struct orinoco_pccard *card = priv->card;
+	struct net_device *dev = priv->ndev;
 	int err = 0;
 	unsigned long flags;
 
 	if (!test_bit(0, &card->hard_reset_in_progress)) {
-		err = orinoco_reinit_firmware(dev);
+		err = orinoco_reinit_firmware(priv);
 		if (err) {
 			printk(KERN_ERR "%s: Error %d re-initializing firmware\n",
 			       dev->name, err);
@@ -401,7 +398,7 @@ static int orinoco_cs_resume(struct pcmcia_device *link)
 		priv->hw_unavailable--;
 
 		if (priv->open && !priv->hw_unavailable) {
-			err = __orinoco_up(dev);
+			err = __orinoco_up(priv);
 			if (err)
 				printk(KERN_ERR "%s: Error %d restarting card\n",
 				       dev->name, err);
diff --git a/drivers/net/wireless/orinoco/orinoco_nortel.c b/drivers/net/wireless/orinoco/orinoco_nortel.c
index b017262..4efd5a0 100644
--- a/drivers/net/wireless/orinoco/orinoco_nortel.c
+++ b/drivers/net/wireless/orinoco/orinoco_nortel.c
@@ -181,15 +181,15 @@ static int orinoco_nortel_init_one(struct pci_dev *pdev,
 	}
 
 	/* Allocate network device */
-	dev = alloc_orinocodev(sizeof(*card), &pdev->dev,
-			       orinoco_nortel_cor_reset, NULL);
-	if (!dev) {
+	priv = alloc_orinocodev(sizeof(*card), &pdev->dev,
+				orinoco_nortel_cor_reset, NULL);
+	if (!priv) {
 		printk(KERN_ERR PFX "Cannot allocate network device\n");
 		err = -ENOMEM;
 		goto fail_alloc;
 	}
 
-	priv = netdev_priv(dev);
+	dev = priv->ndev;
 	card = priv->card;
 	card->bridge_io = bridge_io;
 	card->attr_io = attr_io;
@@ -198,7 +198,7 @@ static int orinoco_nortel_init_one(struct pci_dev *pdev,
 	hermes_struct_init(&priv->hw, hermes_io, HERMES_16BIT_REGSPACING);
 
 	err = request_irq(pdev->irq, orinoco_interrupt, IRQF_SHARED,
-			  dev->name, dev);
+			  dev->name, priv);
 	if (err) {
 		printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq);
 		err = -EBUSY;
@@ -223,18 +223,18 @@ static int orinoco_nortel_init_one(struct pci_dev *pdev,
 		goto fail;
 	}
 
-	pci_set_drvdata(pdev, dev);
+	pci_set_drvdata(pdev, priv);
 	printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s\n", dev->name,
 	       pci_name(pdev));
 
 	return 0;
 
  fail:
-	free_irq(pdev->irq, dev);
+	free_irq(pdev->irq, priv);
 
  fail_irq:
 	pci_set_drvdata(pdev, NULL);
-	free_orinocodev(dev);
+	free_orinocodev(priv);
 
  fail_alloc:
 	pci_iounmap(pdev, hermes_io);
@@ -256,17 +256,17 @@ static int orinoco_nortel_init_one(struct pci_dev *pdev,
 
 static void __devexit orinoco_nortel_remove_one(struct pci_dev *pdev)
 {
-	struct net_device *dev = pci_get_drvdata(pdev);
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = pci_get_drvdata(pdev);
+	struct net_device *dev = priv->ndev;
 	struct orinoco_pci_card *card = priv->card;
 
 	/* Clear LEDs */
 	iowrite16(0, card->bridge_io + 10);
 
 	unregister_netdev(dev);
-	free_irq(pdev->irq, dev);
+	free_irq(pdev->irq, priv);
 	pci_set_drvdata(pdev, NULL);
-	free_orinocodev(dev);
+	free_orinocodev(priv);
 	pci_iounmap(pdev, priv->hw.iobase);
 	pci_iounmap(pdev, card->attr_io);
 	pci_iounmap(pdev, card->bridge_io);
diff --git a/drivers/net/wireless/orinoco/orinoco_pci.c b/drivers/net/wireless/orinoco/orinoco_pci.c
index 78cafff..12b9c6a 100644
--- a/drivers/net/wireless/orinoco/orinoco_pci.c
+++ b/drivers/net/wireless/orinoco/orinoco_pci.c
@@ -139,22 +139,22 @@ static int orinoco_pci_init_one(struct pci_dev *pdev,
 	}
 
 	/* Allocate network device */
-	dev = alloc_orinocodev(sizeof(*card), &pdev->dev,
-			       orinoco_pci_cor_reset, NULL);
-	if (!dev) {
+	priv = alloc_orinocodev(sizeof(*card), &pdev->dev,
+				orinoco_pci_cor_reset, NULL);
+	if (!priv) {
 		printk(KERN_ERR PFX "Cannot allocate network device\n");
 		err = -ENOMEM;
 		goto fail_alloc;
 	}
 
-	priv = netdev_priv(dev);
+	dev = priv->ndev;
 	card = priv->card;
 	SET_NETDEV_DEV(dev, &pdev->dev);
 
 	hermes_struct_init(&priv->hw, hermes_io, HERMES_32BIT_REGSPACING);
 
 	err = request_irq(pdev->irq, orinoco_interrupt, IRQF_SHARED,
-			  dev->name, dev);
+			  dev->name, priv);
 	if (err) {
 		printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq);
 		err = -EBUSY;
@@ -173,18 +173,18 @@ static int orinoco_pci_init_one(struct pci_dev *pdev,
 		goto fail;
 	}
 
-	pci_set_drvdata(pdev, dev);
+	pci_set_drvdata(pdev, priv);
 	printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s\n", dev->name,
 	       pci_name(pdev));
 
 	return 0;
 
  fail:
-	free_irq(pdev->irq, dev);
+	free_irq(pdev->irq, priv);
 
  fail_irq:
 	pci_set_drvdata(pdev, NULL);
-	free_orinocodev(dev);
+	free_orinocodev(priv);
 
  fail_alloc:
 	pci_iounmap(pdev, hermes_io);
@@ -200,13 +200,13 @@ static int orinoco_pci_init_one(struct pci_dev *pdev,
 
 static void __devexit orinoco_pci_remove_one(struct pci_dev *pdev)
 {
-	struct net_device *dev = pci_get_drvdata(pdev);
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = pci_get_drvdata(pdev);
+	struct net_device *dev = priv->ndev;
 
 	unregister_netdev(dev);
-	free_irq(pdev->irq, dev);
+	free_irq(pdev->irq, priv);
 	pci_set_drvdata(pdev, NULL);
-	free_orinocodev(dev);
+	free_orinocodev(priv);
 	pci_iounmap(pdev, priv->hw.iobase);
 	pci_release_regions(pdev);
 	pci_disable_device(pdev);
diff --git a/drivers/net/wireless/orinoco/orinoco_pci.h b/drivers/net/wireless/orinoco/orinoco_pci.h
index c655b4a..22aa630 100644
--- a/drivers/net/wireless/orinoco/orinoco_pci.h
+++ b/drivers/net/wireless/orinoco/orinoco_pci.h
@@ -21,8 +21,8 @@ struct orinoco_pci_card {
 #ifdef CONFIG_PM
 static int orinoco_pci_suspend(struct pci_dev *pdev, pm_message_t state)
 {
-	struct net_device *dev = pci_get_drvdata(pdev);
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = pci_get_drvdata(pdev);
+	struct net_device *dev = priv->ndev;
 	unsigned long flags;
 	int err;
 
@@ -33,7 +33,7 @@ static int orinoco_pci_suspend(struct pci_dev *pdev, pm_message_t state)
 		return err;
 	}
 
-	err = __orinoco_down(dev);
+	err = __orinoco_down(priv);
 	if (err)
 		printk(KERN_WARNING "%s: error %d bringing interface down "
 		       "for suspend\n", dev->name, err);
@@ -44,7 +44,7 @@ static int orinoco_pci_suspend(struct pci_dev *pdev, pm_message_t state)
 
 	orinoco_unlock(priv, &flags);
 
-	free_irq(pdev->irq, dev);
+	free_irq(pdev->irq, priv);
 	pci_save_state(pdev);
 	pci_disable_device(pdev);
 	pci_set_power_state(pdev, PCI_D3hot);
@@ -54,8 +54,8 @@ static int orinoco_pci_suspend(struct pci_dev *pdev, pm_message_t state)
 
 static int orinoco_pci_resume(struct pci_dev *pdev)
 {
-	struct net_device *dev = pci_get_drvdata(pdev);
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = pci_get_drvdata(pdev);
+	struct net_device *dev = priv->ndev;
 	unsigned long flags;
 	int err;
 
@@ -69,7 +69,7 @@ static int orinoco_pci_resume(struct pci_dev *pdev)
 	pci_restore_state(pdev);
 
 	err = request_irq(pdev->irq, orinoco_interrupt, IRQF_SHARED,
-			  dev->name, dev);
+			  dev->name, priv);
 	if (err) {
 		printk(KERN_ERR "%s: cannot re-allocate IRQ on resume\n",
 		       dev->name);
@@ -77,7 +77,7 @@ static int orinoco_pci_resume(struct pci_dev *pdev)
 		return -EBUSY;
 	}
 
-	err = orinoco_reinit_firmware(dev);
+	err = orinoco_reinit_firmware(priv);
 	if (err) {
 		printk(KERN_ERR "%s: error %d re-initializing firmware "
 		       "on resume\n", dev->name, err);
@@ -91,7 +91,7 @@ static int orinoco_pci_resume(struct pci_dev *pdev)
 	priv->hw_unavailable--;
 
 	if (priv->open && (!priv->hw_unavailable)) {
-		err = __orinoco_up(dev);
+		err = __orinoco_up(priv);
 		if (err)
 			printk(KERN_ERR "%s: Error %d restarting card on resume\n",
 			       dev->name, err);
diff --git a/drivers/net/wireless/orinoco/orinoco_plx.c b/drivers/net/wireless/orinoco/orinoco_plx.c
index a2a4471..77d5668 100644
--- a/drivers/net/wireless/orinoco/orinoco_plx.c
+++ b/drivers/net/wireless/orinoco/orinoco_plx.c
@@ -220,15 +220,15 @@ static int orinoco_plx_init_one(struct pci_dev *pdev,
 	}
 
 	/* Allocate network device */
-	dev = alloc_orinocodev(sizeof(*card), &pdev->dev,
-			       orinoco_plx_cor_reset, NULL);
-	if (!dev) {
+	priv = alloc_orinocodev(sizeof(*card), &pdev->dev,
+				orinoco_plx_cor_reset, NULL);
+	if (!priv) {
 		printk(KERN_ERR PFX "Cannot allocate network device\n");
 		err = -ENOMEM;
 		goto fail_alloc;
 	}
 
-	priv = netdev_priv(dev);
+	dev = priv->ndev;
 	card = priv->card;
 	card->bridge_io = bridge_io;
 	card->attr_io = attr_io;
@@ -237,7 +237,7 @@ static int orinoco_plx_init_one(struct pci_dev *pdev,
 	hermes_struct_init(&priv->hw, hermes_io, HERMES_16BIT_REGSPACING);
 
 	err = request_irq(pdev->irq, orinoco_interrupt, IRQF_SHARED,
-			  dev->name, dev);
+			  dev->name, priv);
 	if (err) {
 		printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq);
 		err = -EBUSY;
@@ -262,18 +262,18 @@ static int orinoco_plx_init_one(struct pci_dev *pdev,
 		goto fail;
 	}
 
-	pci_set_drvdata(pdev, dev);
+	pci_set_drvdata(pdev, priv);
 	printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s\n", dev->name,
 	       pci_name(pdev));
 
 	return 0;
 
  fail:
-	free_irq(pdev->irq, dev);
+	free_irq(pdev->irq, priv);
 
  fail_irq:
 	pci_set_drvdata(pdev, NULL);
-	free_orinocodev(dev);
+	free_orinocodev(priv);
 
  fail_alloc:
 	pci_iounmap(pdev, hermes_io);
@@ -295,14 +295,14 @@ static int orinoco_plx_init_one(struct pci_dev *pdev,
 
 static void __devexit orinoco_plx_remove_one(struct pci_dev *pdev)
 {
-	struct net_device *dev = pci_get_drvdata(pdev);
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = pci_get_drvdata(pdev);
+	struct net_device *dev = priv->ndev;
 	struct orinoco_pci_card *card = priv->card;
 
 	unregister_netdev(dev);
-	free_irq(pdev->irq, dev);
+	free_irq(pdev->irq, priv);
 	pci_set_drvdata(pdev, NULL);
-	free_orinocodev(dev);
+	free_orinocodev(priv);
 	pci_iounmap(pdev, priv->hw.iobase);
 	pci_iounmap(pdev, card->attr_io);
 	pci_iounmap(pdev, card->bridge_io);
diff --git a/drivers/net/wireless/orinoco/orinoco_tmd.c b/drivers/net/wireless/orinoco/orinoco_tmd.c
index cda0e6e..5f24c03 100644
--- a/drivers/net/wireless/orinoco/orinoco_tmd.c
+++ b/drivers/net/wireless/orinoco/orinoco_tmd.c
@@ -124,15 +124,15 @@ static int orinoco_tmd_init_one(struct pci_dev *pdev,
 	}
 
 	/* Allocate network device */
-	dev = alloc_orinocodev(sizeof(*card), &pdev->dev,
-			       orinoco_tmd_cor_reset, NULL);
-	if (!dev) {
+	priv = alloc_orinocodev(sizeof(*card), &pdev->dev,
+				orinoco_tmd_cor_reset, NULL);
+	if (!priv) {
 		printk(KERN_ERR PFX "Cannot allocate network device\n");
 		err = -ENOMEM;
 		goto fail_alloc;
 	}
 
-	priv = netdev_priv(dev);
+	dev = priv->ndev;
 	card = priv->card;
 	card->bridge_io = bridge_io;
 	SET_NETDEV_DEV(dev, &pdev->dev);
@@ -140,7 +140,7 @@ static int orinoco_tmd_init_one(struct pci_dev *pdev,
 	hermes_struct_init(&priv->hw, hermes_io, HERMES_16BIT_REGSPACING);
 
 	err = request_irq(pdev->irq, orinoco_interrupt, IRQF_SHARED,
-			  dev->name, dev);
+			  dev->name, priv);
 	if (err) {
 		printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq);
 		err = -EBUSY;
@@ -159,18 +159,18 @@ static int orinoco_tmd_init_one(struct pci_dev *pdev,
 		goto fail;
 	}
 
-	pci_set_drvdata(pdev, dev);
+	pci_set_drvdata(pdev, priv);
 	printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s\n", dev->name,
 	       pci_name(pdev));
 
 	return 0;
 
  fail:
-	free_irq(pdev->irq, dev);
+	free_irq(pdev->irq, priv);
 
  fail_irq:
 	pci_set_drvdata(pdev, NULL);
-	free_orinocodev(dev);
+	free_orinocodev(priv);
 
  fail_alloc:
 	pci_iounmap(pdev, hermes_io);
@@ -189,14 +189,14 @@ static int orinoco_tmd_init_one(struct pci_dev *pdev,
 
 static void __devexit orinoco_tmd_remove_one(struct pci_dev *pdev)
 {
-	struct net_device *dev = pci_get_drvdata(pdev);
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = pci_get_drvdata(pdev);
+	struct net_device *dev = priv->ndev;
 	struct orinoco_pci_card *card = priv->card;
 
 	unregister_netdev(dev);
-	free_irq(pdev->irq, dev);
+	free_irq(pdev->irq, priv);
 	pci_set_drvdata(pdev, NULL);
-	free_orinocodev(dev);
+	free_orinocodev(priv);
 	pci_iounmap(pdev, priv->hw.iobase);
 	pci_iounmap(pdev, card->bridge_io);
 	pci_release_regions(pdev);
diff --git a/drivers/net/wireless/orinoco/spectrum_cs.c b/drivers/net/wireless/orinoco/spectrum_cs.c
index 38e5198..ce909e4 100644
--- a/drivers/net/wireless/orinoco/spectrum_cs.c
+++ b/drivers/net/wireless/orinoco/spectrum_cs.c
@@ -178,27 +178,25 @@ spectrum_cs_stop_firmware(struct orinoco_private *priv, int idle)
 static int
 spectrum_cs_probe(struct pcmcia_device *link)
 {
-	struct net_device *dev;
 	struct orinoco_private *priv;
 	struct orinoco_pccard *card;
 
-	dev = alloc_orinocodev(sizeof(*card), &handle_to_dev(link),
-			       spectrum_cs_hard_reset,
-			       spectrum_cs_stop_firmware);
-	if (!dev)
+	priv = alloc_orinocodev(sizeof(*card), &handle_to_dev(link),
+				spectrum_cs_hard_reset,
+				spectrum_cs_stop_firmware);
+	if (!priv)
 		return -ENOMEM;
-	priv = netdev_priv(dev);
 	card = priv->card;
 
 	/* Link both structures together */
 	card->p_dev = link;
-	link->priv = dev;
+	link->priv = priv;
 
 	/* Interrupt setup */
 	link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
 	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
 	link->irq.Handler = orinoco_interrupt;
-	link->irq.Instance = dev;
+	link->irq.Instance = priv;
 
 	/* General socket configuration defaults can go here.  In this
 	 * client, we assume very little, and rely on the CIS for
@@ -219,14 +217,14 @@ spectrum_cs_probe(struct pcmcia_device *link)
  */
 static void spectrum_cs_detach(struct pcmcia_device *link)
 {
-	struct net_device *dev = link->priv;
+	struct orinoco_private *priv = link->priv;
 
 	if (link->dev_node)
-		unregister_netdev(dev);
+		unregister_netdev(priv->ndev);
 
 	spectrum_cs_release(link);
 
-	free_orinocodev(dev);
+	free_orinocodev(priv);
 }				/* spectrum_cs_detach */
 
 /*
@@ -306,9 +304,9 @@ next_entry:
 static int
 spectrum_cs_config(struct pcmcia_device *link)
 {
-	struct net_device *dev = link->priv;
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = link->priv;
 	struct orinoco_pccard *card = priv->card;
+	struct net_device *dev = priv->ndev;
 	hermes_t *hw = &priv->hw;
 	int last_fn, last_ret;
 	void __iomem *mem;
@@ -408,8 +406,7 @@ spectrum_cs_config(struct pcmcia_device *link)
 static void
 spectrum_cs_release(struct pcmcia_device *link)
 {
-	struct net_device *dev = link->priv;
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = link->priv;
 	unsigned long flags;
 
 	/* We're committed to taking the device away now, so mark the
@@ -427,15 +424,15 @@ spectrum_cs_release(struct pcmcia_device *link)
 static int
 spectrum_cs_suspend(struct pcmcia_device *link)
 {
-	struct net_device *dev = link->priv;
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = link->priv;
+	struct net_device *dev = priv->ndev;
 	unsigned long flags;
 	int err = 0;
 
 	/* Mark the device as stopped, to block IO until later */
 	spin_lock_irqsave(&priv->lock, flags);
 
-	err = __orinoco_down(dev);
+	err = __orinoco_down(priv);
 	if (err)
 		printk(KERN_WARNING "%s: Error %d downing interface\n",
 		       dev->name, err);
@@ -451,12 +448,12 @@ spectrum_cs_suspend(struct pcmcia_device *link)
 static int
 spectrum_cs_resume(struct pcmcia_device *link)
 {
-	struct net_device *dev = link->priv;
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = link->priv;
+	struct net_device *dev = priv->ndev;
 	unsigned long flags;
 	int err;
 
-	err = orinoco_reinit_firmware(dev);
+	err = orinoco_reinit_firmware(priv);
 	if (err) {
 		printk(KERN_ERR "%s: Error %d re-initializing firmware\n",
 		       dev->name, err);
@@ -469,7 +466,7 @@ spectrum_cs_resume(struct pcmcia_device *link)
 	priv->hw_unavailable--;
 
 	if (priv->open && !priv->hw_unavailable) {
-		err = __orinoco_up(dev);
+		err = __orinoco_up(priv);
 		if (err)
 			printk(KERN_ERR "%s: Error %d restarting card\n",
 			       dev->name, err);
-- 
1.6.0.6


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

* [PATCH 12/23] orinoco: initialise independently of netdev
  2009-06-18 22:21 [PATCH 00/23] orinoco: initiate cfg80211 conversion David Kilroy
                   ` (10 preceding siblings ...)
  2009-06-18 22:21 ` [PATCH 11/23] orinoco: Replace net_device with orinoco_private in driver interfaces David Kilroy
@ 2009-06-18 22:21 ` David Kilroy
  2009-06-18 22:21 ` [PATCH 13/23] orinoco: Change set_tkip to use orinoco_private instead of hermes_t David Kilroy
                   ` (11 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: David Kilroy @ 2009-06-18 22:21 UTC (permalink / raw)
  To: linux-wireless; +Cc: orinoco-devel, David Kilroy

Initialise the orinoco driver before registerring with netdev, which
will help when we get to cfg80211...

Signed-off-by: David Kilroy <kilroyd@googlemail.com>
---
 drivers/net/wireless/orinoco/airport.c        |    6 +++
 drivers/net/wireless/orinoco/main.c           |   44 +++++++++++-------------
 drivers/net/wireless/orinoco/orinoco.h        |    1 +
 drivers/net/wireless/orinoco/orinoco_cs.c     |    6 +++
 drivers/net/wireless/orinoco/orinoco_nortel.c |    6 +++
 drivers/net/wireless/orinoco/orinoco_pci.c    |    6 +++
 drivers/net/wireless/orinoco/orinoco_plx.c    |    6 +++
 drivers/net/wireless/orinoco/orinoco_tmd.c    |    6 +++
 drivers/net/wireless/orinoco/spectrum_cs.c    |    6 +++
 9 files changed, 63 insertions(+), 24 deletions(-)

diff --git a/drivers/net/wireless/orinoco/airport.c b/drivers/net/wireless/orinoco/airport.c
index 6559aee..9f90337 100644
--- a/drivers/net/wireless/orinoco/airport.c
+++ b/drivers/net/wireless/orinoco/airport.c
@@ -234,6 +234,12 @@ airport_attach(struct macio_dev *mdev, const struct of_device_id *match)
 	}
 	card->irq_requested = 1;
 
+	/* Initialise the main driver */
+	if (orinoco_init(priv) != 0) {
+		printk(KERN_ERR PFX "orinoco_init() failed\n");
+		goto failed;
+	}
+
 	/* Tell the stack we exist */
 	if (register_netdev(dev) != 0) {
 		printk(KERN_ERR PFX "register_netdev() failed\n");
diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c
index 4fa8264..ff869a2 100644
--- a/drivers/net/wireless/orinoco/main.c
+++ b/drivers/net/wireless/orinoco/main.c
@@ -80,6 +80,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/device.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/ethtool.h>
@@ -2073,9 +2074,9 @@ static void orinoco_unregister_pm_notifier(struct orinoco_private *priv)
 /* Initialization                                                   */
 /********************************************************************/
 
-static int orinoco_init(struct net_device *dev)
+int orinoco_init(struct orinoco_private *priv)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct device *dev = priv->dev;
 	hermes_t *hw = &priv->hw;
 	int err = 0;
 
@@ -2086,15 +2087,14 @@ static int orinoco_init(struct net_device *dev)
 	/* Initialize the firmware */
 	err = hermes_init(hw);
 	if (err != 0) {
-		printk(KERN_ERR "%s: failed to initialize firmware (err = %d)\n",
-		       dev->name, err);
+		dev_err(dev, "Failed to initialize firmware (err = %d)\n",
+			err);
 		goto out;
 	}
 
 	err = determine_fw_capabilities(priv);
 	if (err != 0) {
-		printk(KERN_ERR "%s: Incompatible firmware, aborting\n",
-		       dev->name);
+		dev_err(dev, "Incompatible firmware, aborting\n");
 		goto out;
 	}
 
@@ -2110,27 +2110,23 @@ static int orinoco_init(struct net_device *dev)
 		/* Check firmware version again */
 		err = determine_fw_capabilities(priv);
 		if (err != 0) {
-			printk(KERN_ERR "%s: Incompatible firmware, aborting\n",
-			       dev->name);
+			dev_err(dev, "Incompatible firmware, aborting\n");
 			goto out;
 		}
 	}
 
 	if (priv->has_port3)
-		printk(KERN_DEBUG "%s: Ad-hoc demo mode supported\n",
-		       dev->name);
+		dev_info(dev, "Ad-hoc demo mode supported\n");
 	if (priv->has_ibss)
-		printk(KERN_DEBUG "%s: IEEE standard IBSS ad-hoc mode supported\n",
-		       dev->name);
-	if (priv->has_wep) {
-		printk(KERN_DEBUG "%s: WEP supported, %s-bit key\n", dev->name,
-		       priv->has_big_wep ? "104" : "40");
-	}
+		dev_info(dev, "IEEE standard IBSS ad-hoc mode supported\n");
+	if (priv->has_wep)
+		dev_info(dev, "WEP supported, %s-bit key\n",
+			 priv->has_big_wep ? "104" : "40");
 	if (priv->has_wpa) {
-		printk(KERN_DEBUG "%s: WPA-PSK supported\n", dev->name);
+		dev_info(dev, "WPA-PSK supported\n");
 		if (orinoco_mic_init(priv)) {
-			printk(KERN_ERR "%s: Failed to setup MIC crypto "
-			       "algorithm. Disabling WPA support\n", dev->name);
+			dev_err(dev, "Failed to setup MIC crypto algorithm. "
+				"Disabling WPA support\n");
 			priv->has_wpa = 0;
 		}
 	}
@@ -2141,14 +2137,14 @@ static int orinoco_init(struct net_device *dev)
 		goto out;
 	orinoco_bss_data_init(priv);
 
-	err = orinoco_hw_read_card_settings(priv, dev->dev_addr);
+	/* Netdev has not initialised, but we have allocated the buffer. */
+	err = orinoco_hw_read_card_settings(priv, priv->ndev->dev_addr);
 	if (err)
 		goto out;
 
 	err = orinoco_hw_allocate_fid(priv);
 	if (err) {
-		printk(KERN_ERR "%s: failed to allocate NIC buffer!\n",
-		       dev->name);
+		dev_err(dev, "Failed to allocate NIC buffer!\n");
 		goto out;
 	}
 
@@ -2174,14 +2170,14 @@ static int orinoco_init(struct net_device *dev)
 	priv->hw_unavailable--;
 	spin_unlock_irq(&priv->lock);
 
-	printk(KERN_DEBUG "%s: ready\n", dev->name);
+	dev_dbg(dev, "Ready\n");
 
  out:
 	return err;
 }
+EXPORT_SYMBOL(orinoco_init);
 
 static const struct net_device_ops orinoco_netdev_ops = {
-	.ndo_init		= orinoco_init,
 	.ndo_open		= orinoco_open,
 	.ndo_stop		= orinoco_stop,
 	.ndo_start_xmit		= orinoco_xmit,
diff --git a/drivers/net/wireless/orinoco/orinoco.h b/drivers/net/wireless/orinoco/orinoco.h
index b93e86c..2e9d33f 100644
--- a/drivers/net/wireless/orinoco/orinoco.h
+++ b/drivers/net/wireless/orinoco/orinoco.h
@@ -187,6 +187,7 @@ extern struct orinoco_private *alloc_orinocodev(
 	int (*hard_reset)(struct orinoco_private *),
 	int (*stop_fw)(struct orinoco_private *, int));
 extern void free_orinocodev(struct orinoco_private *priv);
+extern int orinoco_init(struct orinoco_private *priv);
 extern int __orinoco_up(struct orinoco_private *priv);
 extern int __orinoco_down(struct orinoco_private *priv);
 extern int orinoco_reinit_firmware(struct orinoco_private *priv);
diff --git a/drivers/net/wireless/orinoco/orinoco_cs.c b/drivers/net/wireless/orinoco/orinoco_cs.c
index fa8fe5b..20abf02 100644
--- a/drivers/net/wireless/orinoco/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco/orinoco_cs.c
@@ -297,6 +297,12 @@ orinoco_cs_config(struct pcmcia_device *link)
 	dev->irq = link->irq.AssignedIRQ;
 	card->node.major = card->node.minor = 0;
 
+	/* Initialise the main driver */
+	if (orinoco_init(priv) != 0) {
+		printk(KERN_ERR PFX "orinoco_init() failed\n");
+		goto failed;
+	}
+
 	SET_NETDEV_DEV(dev, &handle_to_dev(link));
 	/* Tell the stack we exist */
 	if (register_netdev(dev) != 0) {
diff --git a/drivers/net/wireless/orinoco/orinoco_nortel.c b/drivers/net/wireless/orinoco/orinoco_nortel.c
index 4efd5a0..45cef81 100644
--- a/drivers/net/wireless/orinoco/orinoco_nortel.c
+++ b/drivers/net/wireless/orinoco/orinoco_nortel.c
@@ -217,6 +217,12 @@ static int orinoco_nortel_init_one(struct pci_dev *pdev,
 		goto fail;
 	}
 
+	err = orinoco_init(priv);
+	if (err) {
+		printk(KERN_ERR PFX "orinoco_init() failed\n");
+		goto fail;
+	}
+
 	err = register_netdev(dev);
 	if (err) {
 		printk(KERN_ERR PFX "Cannot register network device\n");
diff --git a/drivers/net/wireless/orinoco/orinoco_pci.c b/drivers/net/wireless/orinoco/orinoco_pci.c
index 12b9c6a..d0eb4ae 100644
--- a/drivers/net/wireless/orinoco/orinoco_pci.c
+++ b/drivers/net/wireless/orinoco/orinoco_pci.c
@@ -167,6 +167,12 @@ static int orinoco_pci_init_one(struct pci_dev *pdev,
 		goto fail;
 	}
 
+	err = orinoco_init(priv);
+	if (err) {
+		printk(KERN_ERR PFX "orinoco_init() failed\n");
+		goto fail;
+	}
+
 	err = register_netdev(dev);
 	if (err) {
 		printk(KERN_ERR PFX "Cannot register network device\n");
diff --git a/drivers/net/wireless/orinoco/orinoco_plx.c b/drivers/net/wireless/orinoco/orinoco_plx.c
index 77d5668..8f225d0 100644
--- a/drivers/net/wireless/orinoco/orinoco_plx.c
+++ b/drivers/net/wireless/orinoco/orinoco_plx.c
@@ -256,6 +256,12 @@ static int orinoco_plx_init_one(struct pci_dev *pdev,
 		goto fail;
 	}
 
+	err = orinoco_init(priv);
+	if (err) {
+		printk(KERN_ERR PFX "orinoco_init() failed\n");
+		goto fail;
+	}
+
 	err = register_netdev(dev);
 	if (err) {
 		printk(KERN_ERR PFX "Cannot register network device\n");
diff --git a/drivers/net/wireless/orinoco/orinoco_tmd.c b/drivers/net/wireless/orinoco/orinoco_tmd.c
index 5f24c03..3c04fae 100644
--- a/drivers/net/wireless/orinoco/orinoco_tmd.c
+++ b/drivers/net/wireless/orinoco/orinoco_tmd.c
@@ -153,6 +153,12 @@ static int orinoco_tmd_init_one(struct pci_dev *pdev,
 		goto fail;
 	}
 
+	err = orinoco_init(priv);
+	if (err) {
+		printk(KERN_ERR PFX "orinoco_init() failed\n");
+		goto fail;
+	}
+
 	err = register_netdev(dev);
 	if (err) {
 		printk(KERN_ERR PFX "Cannot register network device\n");
diff --git a/drivers/net/wireless/orinoco/spectrum_cs.c b/drivers/net/wireless/orinoco/spectrum_cs.c
index ce909e4..43e1aed 100644
--- a/drivers/net/wireless/orinoco/spectrum_cs.c
+++ b/drivers/net/wireless/orinoco/spectrum_cs.c
@@ -368,6 +368,12 @@ spectrum_cs_config(struct pcmcia_device *link)
 	if (spectrum_cs_hard_reset(priv) != 0)
 		goto failed;
 
+	/* Initialise the main driver */
+	if (orinoco_init(priv) != 0) {
+		printk(KERN_ERR PFX "orinoco_init() failed\n");
+		goto failed;
+	}
+
 	SET_NETDEV_DEV(dev, &handle_to_dev(link));
 	/* Tell the stack we exist */
 	if (register_netdev(dev) != 0) {
-- 
1.6.0.6


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

* [PATCH 13/23] orinoco: Change set_tkip to use orinoco_private instead of hermes_t
  2009-06-18 22:21 [PATCH 00/23] orinoco: initiate cfg80211 conversion David Kilroy
                   ` (11 preceding siblings ...)
  2009-06-18 22:21 ` [PATCH 12/23] orinoco: initialise independently of netdev David Kilroy
@ 2009-06-18 22:21 ` David Kilroy
  2009-06-18 22:21 ` [PATCH 14/23] orinoco: initiate cfg80211 conversion David Kilroy
                   ` (10 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: David Kilroy @ 2009-06-18 22:21 UTC (permalink / raw)
  To: linux-wireless; +Cc: orinoco-devel, David Kilroy

hw.h does not include hermes.h, and none of the other functions
requires types from that file. Also hermes_t is a (discouraged) typedef
so we can't add a forward declaration. Therefore change this function to
use orinoco_private.

Signed-off-by: David Kilroy <kilroyd@googlemail.com>
---
 drivers/net/wireless/orinoco/hw.c   |    5 +++--
 drivers/net/wireless/orinoco/hw.h   |    4 ++--
 drivers/net/wireless/orinoco/wext.c |    3 +--
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/orinoco/hw.c b/drivers/net/wireless/orinoco/hw.c
index 4a26d68..eaa89d3 100644
--- a/drivers/net/wireless/orinoco/hw.c
+++ b/drivers/net/wireless/orinoco/hw.c
@@ -677,8 +677,8 @@ int __orinoco_hw_setup_enc(struct orinoco_private *priv)
  * rsc must be 8 bytes
  * tsc must be 8 bytes or NULL
  */
-int __orinoco_hw_set_tkip_key(hermes_t *hw, int key_idx, int set_tx,
-			      u8 *key, u8 *rsc, u8 *tsc)
+int __orinoco_hw_set_tkip_key(struct orinoco_private *priv, int key_idx,
+			      int set_tx, u8 *key, u8 *rsc, u8 *tsc)
 {
 	struct {
 		__le16 idx;
@@ -688,6 +688,7 @@ int __orinoco_hw_set_tkip_key(hermes_t *hw, int key_idx, int set_tx,
 		u8 rx_mic[MIC_KEYLEN];
 		u8 tsc[IW_ENCODE_SEQ_MAX_SIZE];
 	} __attribute__ ((packed)) buf;
+	hermes_t *hw = &priv->hw;
 	int ret;
 	int err;
 	int k;
diff --git a/drivers/net/wireless/orinoco/hw.h b/drivers/net/wireless/orinoco/hw.h
index 89277de..84c108c 100644
--- a/drivers/net/wireless/orinoco/hw.h
+++ b/drivers/net/wireless/orinoco/hw.h
@@ -35,8 +35,8 @@ int orinoco_hw_get_act_bitrate(struct orinoco_private *priv, int *bitrate);
 int __orinoco_hw_set_wap(struct orinoco_private *priv);
 int __orinoco_hw_setup_wepkeys(struct orinoco_private *priv);
 int __orinoco_hw_setup_enc(struct orinoco_private *priv);
-int __orinoco_hw_set_tkip_key(hermes_t *hw, int key_idx, int set_tx,
-			      u8 *key, u8 *rsc, u8 *tsc);
+int __orinoco_hw_set_tkip_key(struct orinoco_private *priv, int key_idx,
+			      int set_tx, u8 *key, u8 *rsc, u8 *tsc);
 int orinoco_clear_tkip_key(struct orinoco_private *priv, int key_idx);
 int __orinoco_hw_set_multicast_list(struct orinoco_private *priv,
 				    struct dev_addr_list *mc_list,
diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c
index 3f08142..74fdfce 100644
--- a/drivers/net/wireless/orinoco/wext.c
+++ b/drivers/net/wireless/orinoco/wext.c
@@ -1079,7 +1079,6 @@ static int orinoco_ioctl_set_encodeext(struct net_device *dev,
 
 		case IW_ENCODE_ALG_TKIP:
 		{
-			hermes_t *hw = &priv->hw;
 			u8 *tkip_iv = NULL;
 
 			if (!priv->has_wpa ||
@@ -1094,7 +1093,7 @@ static int orinoco_ioctl_set_encodeext(struct net_device *dev,
 			if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
 				tkip_iv = &ext->rx_seq[0];
 
-			err = __orinoco_hw_set_tkip_key(hw, idx,
+			err = __orinoco_hw_set_tkip_key(priv, idx,
 				 ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY,
 				 (u8 *) &priv->tkip_key[idx],
 				 tkip_iv, NULL);
-- 
1.6.0.6


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

* [PATCH 14/23] orinoco: initiate cfg80211 conversion
  2009-06-18 22:21 [PATCH 00/23] orinoco: initiate cfg80211 conversion David Kilroy
                   ` (12 preceding siblings ...)
  2009-06-18 22:21 ` [PATCH 13/23] orinoco: Change set_tkip to use orinoco_private instead of hermes_t David Kilroy
@ 2009-06-18 22:21 ` David Kilroy
  2009-06-18 22:21 ` [PATCH 15/23] orinoco: make firmware download less verbose David Kilroy
                   ` (9 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: David Kilroy @ 2009-06-18 22:21 UTC (permalink / raw)
  To: linux-wireless; +Cc: orinoco-devel, David Kilroy

Initialise and register a wiphy.

Store the orinoco_private structure in the new wiphy, and use the
net_device private area to store the wireless_dev. This results in a
change to the way we navigate from a net_device to the driver private
orinoco_private, which we encapsulate in the inline function ndev_priv.
Most of the remaining calls to netdev_priv are thus replaced by
ndev_priv.

We can immediately rely on cfg80211 to handle SIOCGIWNAME, so
orinoco_ioctl_getname is removed.

Signed-off-by: David Kilroy <kilroyd@googlemail.com>
---
 drivers/net/wireless/orinoco/Kconfig   |    1 +
 drivers/net/wireless/orinoco/Makefile  |    2 +-
 drivers/net/wireless/orinoco/cfg.c     |   98 ++++++++++++++++++++++++++++
 drivers/net/wireless/orinoco/cfg.h     |   15 ++++
 drivers/net/wireless/orinoco/main.c    |  108 ++++++++++++++++++++++++-------
 drivers/net/wireless/orinoco/orinoco.h |   11 +++
 drivers/net/wireless/orinoco/wext.c    |  110 +++++++++++++------------------
 7 files changed, 256 insertions(+), 89 deletions(-)
 create mode 100644 drivers/net/wireless/orinoco/cfg.c
 create mode 100644 drivers/net/wireless/orinoco/cfg.h

diff --git a/drivers/net/wireless/orinoco/Kconfig b/drivers/net/wireless/orinoco/Kconfig
index 44411eb..83b635f 100644
--- a/drivers/net/wireless/orinoco/Kconfig
+++ b/drivers/net/wireless/orinoco/Kconfig
@@ -1,6 +1,7 @@
 config HERMES
 	tristate "Hermes chipset 802.11b support (Orinoco/Prism2/Symbol)"
 	depends on (PPC_PMAC || PCI || PCMCIA) && WLAN_80211
+	depends on CFG80211
 	select WIRELESS_EXT
 	select FW_LOADER
 	select CRYPTO
diff --git a/drivers/net/wireless/orinoco/Makefile b/drivers/net/wireless/orinoco/Makefile
index 1fc7409..9abd632 100644
--- a/drivers/net/wireless/orinoco/Makefile
+++ b/drivers/net/wireless/orinoco/Makefile
@@ -1,7 +1,7 @@
 #
 # Makefile for the orinoco wireless device drivers.
 #
-orinoco-objs := main.o fw.o hw.o mic.o scan.o wext.o hermes_dld.o hermes.o
+orinoco-objs := main.o fw.o hw.o mic.o scan.o wext.o hermes_dld.o hermes.o cfg.o
 
 obj-$(CONFIG_HERMES)		+= orinoco.o
 obj-$(CONFIG_PCMCIA_HERMES)	+= orinoco_cs.o
diff --git a/drivers/net/wireless/orinoco/cfg.c b/drivers/net/wireless/orinoco/cfg.c
new file mode 100644
index 0000000..9a616dd
--- /dev/null
+++ b/drivers/net/wireless/orinoco/cfg.c
@@ -0,0 +1,98 @@
+/* cfg80211 support
+ *
+ * See copyright notice in main.c
+ */
+#include <linux/ieee80211.h>
+#include <net/cfg80211.h>
+#include "hw.h"
+#include "main.h"
+#include "orinoco.h"
+
+#include "cfg.h"
+
+/* Supported bitrates. Must agree with hw.c */
+static struct ieee80211_rate orinoco_rates[] = {
+	{ .bitrate = 10 },
+	{ .bitrate = 20 },
+	{ .bitrate = 55 },
+	{ .bitrate = 110 },
+};
+
+static const void * const orinoco_wiphy_privid = &orinoco_wiphy_privid;
+
+/* Called after orinoco_private is allocated. */
+void orinoco_wiphy_init(struct wiphy *wiphy)
+{
+	struct orinoco_private *priv = wiphy_priv(wiphy);
+
+	wiphy->privid = orinoco_wiphy_privid;
+
+	set_wiphy_dev(wiphy, priv->dev);
+}
+
+/* Called after firmware is initialised */
+int orinoco_wiphy_register(struct wiphy *wiphy)
+{
+	struct orinoco_private *priv = wiphy_priv(wiphy);
+	int i, channels = 0;
+
+	if (priv->firmware_type == FIRMWARE_TYPE_AGERE)
+		wiphy->max_scan_ssids = 1;
+	else
+		wiphy->max_scan_ssids = 0;
+
+	wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
+
+	/* TODO: should we set if we only have demo ad-hoc?
+	 *       (priv->has_port3)
+	 */
+	if (priv->has_ibss)
+		wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
+
+	if (!priv->broken_monitor || force_monitor)
+		wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
+
+	priv->band.bitrates = orinoco_rates;
+	priv->band.n_bitrates = ARRAY_SIZE(orinoco_rates);
+
+	/* Only support channels allowed by the card EEPROM */
+	for (i = 0; i < NUM_CHANNELS; i++) {
+		if (priv->channel_mask & (1 << i)) {
+			priv->channels[i].center_freq =
+				ieee80211_dsss_chan_to_freq(i+1);
+			channels++;
+		}
+	}
+	priv->band.channels = priv->channels;
+	priv->band.n_channels = channels;
+
+	wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band;
+	wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
+
+	i = 0;
+	if (priv->has_wep) {
+		priv->cipher_suites[i] = WLAN_CIPHER_SUITE_WEP40;
+		i++;
+
+		if (priv->has_big_wep) {
+			priv->cipher_suites[i] = WLAN_CIPHER_SUITE_WEP104;
+			i++;
+		}
+	}
+	if (priv->has_wpa) {
+		priv->cipher_suites[i] = WLAN_CIPHER_SUITE_TKIP;
+		i++;
+	}
+	wiphy->cipher_suites = priv->cipher_suites;
+	wiphy->n_cipher_suites = i;
+
+	wiphy->rts_threshold = priv->rts_thresh;
+	if (!priv->has_mwo)
+		wiphy->frag_threshold = priv->frag_thresh;
+
+	return wiphy_register(wiphy);
+}
+
+const struct cfg80211_ops orinoco_cfg_ops = {
+
+};
diff --git a/drivers/net/wireless/orinoco/cfg.h b/drivers/net/wireless/orinoco/cfg.h
new file mode 100644
index 0000000..3ddc96a
--- /dev/null
+++ b/drivers/net/wireless/orinoco/cfg.h
@@ -0,0 +1,15 @@
+/* cfg80211 support.
+ *
+ * See copyright notice in main.c
+ */
+#ifndef ORINOCO_CFG_H
+#define ORINOCO_CFG_H
+
+#include <net/cfg80211.h>
+
+extern const struct cfg80211_ops orinoco_cfg_ops;
+
+void orinoco_wiphy_init(struct wiphy *wiphy);
+int orinoco_wiphy_register(struct wiphy *wiphy);
+
+#endif /* ORINOCO_CFG_H */
diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c
index ff869a2..5c1cf64 100644
--- a/drivers/net/wireless/orinoco/main.c
+++ b/drivers/net/wireless/orinoco/main.c
@@ -89,6 +89,7 @@
 #include <linux/wireless.h>
 #include <linux/ieee80211.h>
 #include <net/iw_handler.h>
+#include <net/cfg80211.h>
 
 #include "hermes_rid.h"
 #include "hermes_dld.h"
@@ -97,6 +98,7 @@
 #include "mic.h"
 #include "fw.h"
 #include "wext.h"
+#include "cfg.h"
 #include "main.h"
 
 #include "orinoco.h"
@@ -246,7 +248,7 @@ void set_port_type(struct orinoco_private *priv)
 
 static int orinoco_open(struct net_device *dev)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	unsigned long flags;
 	int err;
 
@@ -265,7 +267,7 @@ static int orinoco_open(struct net_device *dev)
 
 static int orinoco_stop(struct net_device *dev)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	int err = 0;
 
 	/* We mustn't use orinoco_lock() here, because we need to be
@@ -284,14 +286,14 @@ static int orinoco_stop(struct net_device *dev)
 
 static struct net_device_stats *orinoco_get_stats(struct net_device *dev)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 
 	return &priv->stats;
 }
 
 static void orinoco_set_multicast_list(struct net_device *dev)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	unsigned long flags;
 
 	if (orinoco_lock(priv, &flags) != 0) {
@@ -306,7 +308,7 @@ static void orinoco_set_multicast_list(struct net_device *dev)
 
 static int orinoco_change_mtu(struct net_device *dev, int new_mtu)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 
 	if ((new_mtu < ORINOCO_MIN_MTU) || (new_mtu > ORINOCO_MAX_MTU))
 		return -EINVAL;
@@ -327,7 +329,7 @@ static int orinoco_change_mtu(struct net_device *dev, int new_mtu)
 
 static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	struct net_device_stats *stats = &priv->stats;
 	hermes_t *hw = &priv->hw;
 	int err = 0;
@@ -517,7 +519,7 @@ static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
 
 static void __orinoco_ev_alloc(struct net_device *dev, hermes_t *hw)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	u16 fid = hermes_read_regn(hw, ALLOCFID);
 
 	if (fid != priv->txfid) {
@@ -532,7 +534,7 @@ static void __orinoco_ev_alloc(struct net_device *dev, hermes_t *hw)
 
 static void __orinoco_ev_tx(struct net_device *dev, hermes_t *hw)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	struct net_device_stats *stats = &priv->stats;
 
 	stats->tx_packets++;
@@ -544,7 +546,7 @@ static void __orinoco_ev_tx(struct net_device *dev, hermes_t *hw)
 
 static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	struct net_device_stats *stats = &priv->stats;
 	u16 fid = hermes_read_regn(hw, TXCOMPLFID);
 	u16 status;
@@ -600,7 +602,7 @@ static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw)
 
 static void orinoco_tx_timeout(struct net_device *dev)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	struct net_device_stats *stats = &priv->stats;
 	struct hermes *hw = &priv->hw;
 
@@ -649,7 +651,7 @@ static void orinoco_stat_gather(struct net_device *dev,
 				struct sk_buff *skb,
 				struct hermes_rx_descriptor *desc)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 
 	/* Using spy support with lots of Rx packets, like in an
 	 * infrastructure (AP), will really slow down everything, because
@@ -686,7 +688,7 @@ static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid,
 	int err;
 	int len;
 	struct sk_buff *skb;
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	struct net_device_stats *stats = &priv->stats;
 	hermes_t *hw = &priv->hw;
 
@@ -777,7 +779,7 @@ static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid,
 
 static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	struct net_device_stats *stats = &priv->stats;
 	struct iw_statistics *wstats = &priv->wstats;
 	struct sk_buff *skb = NULL;
@@ -901,7 +903,7 @@ static void orinoco_rx(struct net_device *dev,
 		       struct hermes_rx_descriptor *desc,
 		       struct sk_buff *skb)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	struct net_device_stats *stats = &priv->stats;
 	u16 status, fc;
 	int length;
@@ -1016,7 +1018,7 @@ static void orinoco_rx(struct net_device *dev,
 static void orinoco_rx_isr_tasklet(unsigned long data)
 {
 	struct net_device *dev = (struct net_device *) data;
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	struct orinoco_rx_data *rx_data, *temp;
 	struct hermes_rx_descriptor *desc;
 	struct sk_buff *skb;
@@ -1261,7 +1263,7 @@ static void orinoco_send_wevents(struct work_struct *work)
 
 static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	u16 infofid;
 	struct {
 		__le16 len;
@@ -1594,7 +1596,7 @@ EXPORT_SYMBOL(orinoco_reinit_firmware);
 
 int __orinoco_program_rids(struct net_device *dev)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	hermes_t *hw = &priv->hw;
 	int err;
 	struct hermes_idstring idbuf;
@@ -1825,7 +1827,7 @@ int __orinoco_program_rids(struct net_device *dev)
 static void
 __orinoco_set_multicast_list(struct net_device *dev)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	int err = 0;
 	int promisc, mc_count;
 
@@ -2077,6 +2079,7 @@ static void orinoco_unregister_pm_notifier(struct orinoco_private *priv)
 int orinoco_init(struct orinoco_private *priv)
 {
 	struct device *dev = priv->dev;
+	struct wiphy *wiphy = priv_to_wiphy(priv);
 	hermes_t *hw = &priv->hw;
 	int err = 0;
 
@@ -2137,10 +2140,10 @@ int orinoco_init(struct orinoco_private *priv)
 		goto out;
 	orinoco_bss_data_init(priv);
 
-	/* Netdev has not initialised, but we have allocated the buffer. */
-	err = orinoco_hw_read_card_settings(priv, priv->ndev->dev_addr);
+	err = orinoco_hw_read_card_settings(priv, wiphy->perm_addr);
 	if (err)
 		goto out;
+	memcpy(priv->ndev->dev_addr, wiphy->perm_addr, ETH_ALEN);
 
 	err = orinoco_hw_allocate_fid(priv);
 	if (err) {
@@ -2164,6 +2167,11 @@ int orinoco_init(struct orinoco_private *priv)
 	priv->wpa_ie_len = 0;
 	priv->wpa_ie = NULL;
 
+	if (orinoco_wiphy_register(wiphy)) {
+		err = -ENODEV;
+		goto out;
+	}
+
 	/* Make the hardware available, as long as it hasn't been
 	 * removed elsewhere (e.g. by PCMCIA hot unplug) */
 	spin_lock_irq(&priv->lock);
@@ -2187,6 +2195,31 @@ static const struct net_device_ops orinoco_netdev_ops = {
 	.ndo_get_stats		= orinoco_get_stats,
 };
 
+/* Allocate private data.
+ *
+ * This driver has a number of structures associated with it
+ *  netdev - Net device structure for each network interface
+ *  wiphy - structure associated with wireless phy
+ *  wireless_dev (wdev) - structure for each wireless interface
+ *  hw - structure for hermes chip info
+ *  card - card specific structure for use by the card driver
+ *         (airport, orinoco_cs)
+ *  priv - orinoco private data
+ *  device - generic linux device structure
+ *
+ *  +---------+    +---------+
+ *  |  wiphy  |    | netdev  |
+ *  | +-------+    | +-------+
+ *  | | priv  |    | | wdev  |
+ *  | | +-----+    +-+-------+
+ *  | | | hw  |
+ *  | +-+-----+
+ *  | | card  |
+ *  +-+-------+
+ *
+ * priv has a link to netdev and device
+ * wdev has a link to wiphy
+ */
 struct orinoco_private
 *alloc_orinocodev(int sizeof_card,
 		  struct device *device,
@@ -2195,12 +2228,27 @@ struct orinoco_private
 {
 	struct net_device *dev;
 	struct orinoco_private *priv;
+	struct wireless_dev *wdev;
+	struct wiphy *wiphy;
+
+	/* allocate wiphy
+	 * NOTE: We only support a single virtual interface
+	 *       but this may change when monitor mode is added
+	 */
+	wiphy = wiphy_new(&orinoco_cfg_ops,
+			  sizeof(struct orinoco_private) + sizeof_card);
+	if (!wiphy)
+		return NULL;
 
-	dev = alloc_etherdev(sizeof(struct orinoco_private) + sizeof_card);
-	if (!dev)
+	dev = alloc_etherdev(sizeof(struct wireless_dev));
+	if (!dev) {
+		wiphy_free(wiphy);
 		return NULL;
-	priv = netdev_priv(dev);
+	}
+
+	priv = wiphy_priv(wiphy);
 	priv->ndev = dev;
+
 	if (sizeof_card)
 		priv->card = (void *)((unsigned long)priv
 				      + sizeof(struct orinoco_private));
@@ -2208,7 +2256,15 @@ struct orinoco_private
 		priv->card = NULL;
 	priv->dev = device;
 
+	orinoco_wiphy_init(wiphy);
+
+	/* Initialise wireless_dev */
+	wdev = netdev_priv(dev);
+	wdev->wiphy = wiphy;
+	wdev->iftype = NL80211_IFTYPE_STATION;
+
 	/* Setup / override net_device fields */
+	dev->ieee80211_ptr = wdev;
 	dev->netdev_ops = &orinoco_netdev_ops;
 	dev->watchdog_timeo = HZ; /* 1 second timeout */
 	dev->ethtool_ops = &orinoco_ethtool_ops;
@@ -2257,8 +2313,11 @@ EXPORT_SYMBOL(alloc_orinocodev);
 void free_orinocodev(struct orinoco_private *priv)
 {
 	struct net_device *dev = priv->ndev;
+	struct wiphy *wiphy = priv_to_wiphy(priv);
 	struct orinoco_rx_data *rx_data, *temp;
 
+	wiphy_unregister(wiphy);
+
 	/* If the tasklet is scheduled when we call tasklet_kill it
 	 * will run one final time. However the tasklet will only
 	 * drain priv->rx_list if the hw is still available. */
@@ -2281,13 +2340,14 @@ void free_orinocodev(struct orinoco_private *priv)
 	orinoco_mic_free(priv);
 	orinoco_bss_data_free(priv);
 	free_netdev(dev);
+	wiphy_free(wiphy);
 }
 EXPORT_SYMBOL(free_orinocodev);
 
 static void orinoco_get_drvinfo(struct net_device *dev,
 				struct ethtool_drvinfo *info)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 
 	strncpy(info->driver, DRIVER_NAME, sizeof(info->driver) - 1);
 	strncpy(info->version, DRIVER_VERSION, sizeof(info->version) - 1);
diff --git a/drivers/net/wireless/orinoco/orinoco.h b/drivers/net/wireless/orinoco/orinoco.h
index 2e9d33f..608cc5e 100644
--- a/drivers/net/wireless/orinoco/orinoco.h
+++ b/drivers/net/wireless/orinoco/orinoco.h
@@ -14,6 +14,7 @@
 #include <linux/netdevice.h>
 #include <linux/wireless.h>
 #include <net/iw_handler.h>
+#include <net/cfg80211.h>
 
 #include "hermes.h"
 
@@ -67,6 +68,10 @@ struct orinoco_private {
 	int (*hard_reset)(struct orinoco_private *);
 	int (*stop_fw)(struct orinoco_private *, int);
 
+	struct ieee80211_supported_band band;
+	struct ieee80211_channel channels[14];
+	u32 cipher_suites[3];
+
 	/* Synchronisation stuff */
 	spinlock_t lock;
 	int hw_unavailable;
@@ -216,4 +221,10 @@ static inline void orinoco_unlock(struct orinoco_private *priv,
 	spin_unlock_irqrestore(&priv->lock, *flags);
 }
 
+/*** Navigate from net_device to orinoco_private ***/
+static inline struct orinoco_private *ndev_priv(struct net_device *dev)
+{
+	struct wireless_dev *wdev = netdev_priv(dev);
+	return wdev_priv(wdev);
+}
 #endif /* _ORINOCO_H */
diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c
index 74fdfce..74892e1 100644
--- a/drivers/net/wireless/orinoco/wext.c
+++ b/drivers/net/wireless/orinoco/wext.c
@@ -7,6 +7,7 @@
 #include <linux/wireless.h>
 #include <linux/ieee80211.h>
 #include <net/iw_handler.h>
+#include <net/cfg80211.h>
 
 #include "hermes.h"
 #include "hermes_rid.h"
@@ -23,7 +24,7 @@
 
 static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	hermes_t *hw = &priv->hw;
 	struct iw_statistics *wstats = &priv->wstats;
 	int err;
@@ -87,31 +88,12 @@ static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev)
 /* Wireless extensions                                              */
 /********************************************************************/
 
-static int orinoco_ioctl_getname(struct net_device *dev,
-				 struct iw_request_info *info,
-				 char *name,
-				 char *extra)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	int numrates;
-	int err;
-
-	err = orinoco_hw_get_bitratelist(priv, &numrates, NULL, 0);
-
-	if (!err && (numrates > 2))
-		strcpy(name, "IEEE 802.11b");
-	else
-		strcpy(name, "IEEE 802.11-DS");
-
-	return 0;
-}
-
 static int orinoco_ioctl_setwap(struct net_device *dev,
 				struct iw_request_info *info,
 				struct sockaddr *ap_addr,
 				char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	int err = -EINPROGRESS;		/* Call commit handler */
 	unsigned long flags;
 	static const u8 off_addr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
@@ -172,7 +154,7 @@ static int orinoco_ioctl_getwap(struct net_device *dev,
 				struct sockaddr *ap_addr,
 				char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 
 	hermes_t *hw = &priv->hw;
 	int err = 0;
@@ -195,7 +177,7 @@ static int orinoco_ioctl_setmode(struct net_device *dev,
 				 u32 *mode,
 				 char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	int err = -EINPROGRESS;		/* Call commit handler */
 	unsigned long flags;
 
@@ -243,7 +225,7 @@ static int orinoco_ioctl_getmode(struct net_device *dev,
 				 u32 *mode,
 				 char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 
 	*mode = priv->iw_mode;
 	return 0;
@@ -254,7 +236,7 @@ static int orinoco_ioctl_getiwrange(struct net_device *dev,
 				    struct iw_point *rrq,
 				    char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	int err = 0;
 	struct iw_range *range = (struct iw_range *) extra;
 	int numrates;
@@ -367,7 +349,7 @@ static int orinoco_ioctl_setiwencode(struct net_device *dev,
 				     struct iw_point *erq,
 				     char *keybuf)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	int index = (erq->flags & IW_ENCODE_INDEX) - 1;
 	int setindex = priv->tx_key;
 	int encode_alg = priv->encode_alg;
@@ -469,7 +451,7 @@ static int orinoco_ioctl_getiwencode(struct net_device *dev,
 				     struct iw_point *erq,
 				     char *keybuf)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	int index = (erq->flags & IW_ENCODE_INDEX) - 1;
 	u16 xlen = 0;
 	unsigned long flags;
@@ -508,7 +490,7 @@ static int orinoco_ioctl_setessid(struct net_device *dev,
 				  struct iw_point *erq,
 				  char *essidbuf)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	unsigned long flags;
 
 	/* Note : ESSID is ignored in Ad-Hoc demo mode, but we can set it
@@ -539,7 +521,7 @@ static int orinoco_ioctl_getessid(struct net_device *dev,
 				  struct iw_point *erq,
 				  char *essidbuf)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	int active;
 	int err = 0;
 	unsigned long flags;
@@ -567,7 +549,7 @@ static int orinoco_ioctl_setnick(struct net_device *dev,
 				 struct iw_point *nrq,
 				 char *nickbuf)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	unsigned long flags;
 
 	if (nrq->length > IW_ESSID_MAX_SIZE)
@@ -589,7 +571,7 @@ static int orinoco_ioctl_getnick(struct net_device *dev,
 				 struct iw_point *nrq,
 				 char *nickbuf)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	unsigned long flags;
 
 	if (orinoco_lock(priv, &flags) != 0)
@@ -608,7 +590,7 @@ static int orinoco_ioctl_setfreq(struct net_device *dev,
 				 struct iw_freq *frq,
 				 char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	int chan = -1;
 	unsigned long flags;
 	int err = -EINPROGRESS;		/* Call commit handler */
@@ -657,7 +639,7 @@ static int orinoco_ioctl_getfreq(struct net_device *dev,
 				 struct iw_freq *frq,
 				 char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	int tmp;
 
 	/* Locking done in there */
@@ -676,7 +658,7 @@ static int orinoco_ioctl_getsens(struct net_device *dev,
 				 struct iw_param *srq,
 				 char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	hermes_t *hw = &priv->hw;
 	u16 val;
 	int err;
@@ -705,7 +687,7 @@ static int orinoco_ioctl_setsens(struct net_device *dev,
 				 struct iw_param *srq,
 				 char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	int val = srq->value;
 	unsigned long flags;
 
@@ -728,7 +710,7 @@ static int orinoco_ioctl_setrts(struct net_device *dev,
 				struct iw_param *rrq,
 				char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	int val = rrq->value;
 	unsigned long flags;
 
@@ -752,7 +734,7 @@ static int orinoco_ioctl_getrts(struct net_device *dev,
 				struct iw_param *rrq,
 				char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 
 	rrq->value = priv->rts_thresh;
 	rrq->disabled = (rrq->value == 2347);
@@ -766,7 +748,7 @@ static int orinoco_ioctl_setfrag(struct net_device *dev,
 				 struct iw_param *frq,
 				 char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	int err = -EINPROGRESS;		/* Call commit handler */
 	unsigned long flags;
 
@@ -806,7 +788,7 @@ static int orinoco_ioctl_getfrag(struct net_device *dev,
 				 struct iw_param *frq,
 				 char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	hermes_t *hw = &priv->hw;
 	int err;
 	u16 val;
@@ -847,7 +829,7 @@ static int orinoco_ioctl_setrate(struct net_device *dev,
 				 struct iw_param *rrq,
 				 char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	int ratemode;
 	int bitrate; /* 100s of kilobits */
 	unsigned long flags;
@@ -881,7 +863,7 @@ static int orinoco_ioctl_getrate(struct net_device *dev,
 				 struct iw_param *rrq,
 				 char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	int err = 0;
 	int bitrate, automatic;
 	unsigned long flags;
@@ -910,7 +892,7 @@ static int orinoco_ioctl_setpower(struct net_device *dev,
 				  struct iw_param *prq,
 				  char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	int err = -EINPROGRESS;		/* Call commit handler */
 	unsigned long flags;
 
@@ -964,7 +946,7 @@ static int orinoco_ioctl_getpower(struct net_device *dev,
 				  struct iw_param *prq,
 				  char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	hermes_t *hw = &priv->hw;
 	int err = 0;
 	u16 enable, period, timeout, mcast;
@@ -1018,7 +1000,7 @@ static int orinoco_ioctl_set_encodeext(struct net_device *dev,
 				       union iwreq_data *wrqu,
 				       char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	struct iw_point *encoding = &wrqu->encoding;
 	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
 	int idx, alg = ext->alg, set_key = 1;
@@ -1119,7 +1101,7 @@ static int orinoco_ioctl_get_encodeext(struct net_device *dev,
 				       union iwreq_data *wrqu,
 				       char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	struct iw_point *encoding = &wrqu->encoding;
 	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
 	int idx, max_key_len;
@@ -1176,7 +1158,7 @@ static int orinoco_ioctl_set_auth(struct net_device *dev,
 				  struct iw_request_info *info,
 				  union iwreq_data *wrqu, char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	hermes_t *hw = &priv->hw;
 	struct iw_param *param = &wrqu->param;
 	unsigned long flags;
@@ -1254,7 +1236,7 @@ static int orinoco_ioctl_get_auth(struct net_device *dev,
 				  struct iw_request_info *info,
 				  union iwreq_data *wrqu, char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	struct iw_param *param = &wrqu->param;
 	unsigned long flags;
 	int ret = 0;
@@ -1294,7 +1276,7 @@ static int orinoco_ioctl_set_genie(struct net_device *dev,
 				   struct iw_request_info *info,
 				   union iwreq_data *wrqu, char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	u8 *buf;
 	unsigned long flags;
 
@@ -1337,7 +1319,7 @@ static int orinoco_ioctl_get_genie(struct net_device *dev,
 				   struct iw_request_info *info,
 				   union iwreq_data *wrqu, char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	unsigned long flags;
 	int err = 0;
 
@@ -1366,7 +1348,7 @@ static int orinoco_ioctl_set_mlme(struct net_device *dev,
 				  struct iw_request_info *info,
 				  union iwreq_data *wrqu, char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	hermes_t *hw = &priv->hw;
 	struct iw_mlme *mlme = (struct iw_mlme *)extra;
 	unsigned long flags;
@@ -1407,7 +1389,7 @@ static int orinoco_ioctl_getretry(struct net_device *dev,
 				  struct iw_param *rrq,
 				  char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	hermes_t *hw = &priv->hw;
 	int err = 0;
 	u16 short_limit, long_limit, lifetime;
@@ -1461,7 +1443,7 @@ static int orinoco_ioctl_reset(struct net_device *dev,
 			       void *wrqu,
 			       char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 
 	if (!capable(CAP_NET_ADMIN))
 		return -EPERM;
@@ -1486,7 +1468,7 @@ static int orinoco_ioctl_setibssport(struct net_device *dev,
 				     char *extra)
 
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	int val = *((int *) extra);
 	unsigned long flags;
 
@@ -1507,7 +1489,7 @@ static int orinoco_ioctl_getibssport(struct net_device *dev,
 				     void *wrqu,
 				     char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	int *val = (int *) extra;
 
 	*val = priv->ibss_port;
@@ -1519,7 +1501,7 @@ static int orinoco_ioctl_setport3(struct net_device *dev,
 				  void *wrqu,
 				  char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	int val = *((int *) extra);
 	int err = 0;
 	unsigned long flags;
@@ -1565,7 +1547,7 @@ static int orinoco_ioctl_getport3(struct net_device *dev,
 				  void *wrqu,
 				  char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	int *val = (int *) extra;
 
 	*val = priv->prefer_port3;
@@ -1577,7 +1559,7 @@ static int orinoco_ioctl_setpreamble(struct net_device *dev,
 				     void *wrqu,
 				     char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	unsigned long flags;
 	int val;
 
@@ -1609,7 +1591,7 @@ static int orinoco_ioctl_getpreamble(struct net_device *dev,
 				     void *wrqu,
 				     char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	int *val = (int *) extra;
 
 	if (!priv->has_preamble)
@@ -1629,7 +1611,7 @@ static int orinoco_ioctl_getrid(struct net_device *dev,
 				struct iw_point *data,
 				char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	hermes_t *hw = &priv->hw;
 	int rid = data->flags;
 	u16 length;
@@ -1666,7 +1648,7 @@ static int orinoco_ioctl_setscan(struct net_device *dev,
 				 struct iw_point *srq,
 				 char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	hermes_t *hw = &priv->hw;
 	struct iw_scan_req *si = (struct iw_scan_req *) extra;
 	int err = 0;
@@ -1791,7 +1773,7 @@ static inline char *orinoco_translate_scan(struct net_device *dev,
 					   union hermes_scan_info *bss,
 					   unsigned long last_scanned)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	u16			capabilities;
 	u16			channel;
 	struct iw_event		iwe;		/* Temporary buffer */
@@ -2102,7 +2084,7 @@ static int orinoco_ioctl_getscan(struct net_device *dev,
 				 struct iw_point *srq,
 				 char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	int err = 0;
 	unsigned long flags;
 	char *current_ev = extra;
@@ -2180,7 +2162,7 @@ static int orinoco_ioctl_commit(struct net_device *dev,
 				void *wrqu,
 				char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	struct hermes *hw = &priv->hw;
 	unsigned long flags;
 	int err = 0;
@@ -2257,7 +2239,7 @@ static const struct iw_priv_args orinoco_privtab[] = {
 	[IW_IOCTL_IDX(id)] = (iw_handler) func
 static const iw_handler	orinoco_handler[] = {
 	STD_IW_HANDLER(SIOCSIWCOMMIT,	orinoco_ioctl_commit),
-	STD_IW_HANDLER(SIOCGIWNAME,	orinoco_ioctl_getname),
+	STD_IW_HANDLER(SIOCGIWNAME,	cfg80211_wext_giwname),
 	STD_IW_HANDLER(SIOCSIWFREQ,	orinoco_ioctl_setfreq),
 	STD_IW_HANDLER(SIOCGIWFREQ,	orinoco_ioctl_getfreq),
 	STD_IW_HANDLER(SIOCSIWMODE,	orinoco_ioctl_setmode),
-- 
1.6.0.6


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

* [PATCH 15/23] orinoco: make firmware download less verbose
  2009-06-18 22:21 [PATCH 00/23] orinoco: initiate cfg80211 conversion David Kilroy
                   ` (13 preceding siblings ...)
  2009-06-18 22:21 ` [PATCH 14/23] orinoco: initiate cfg80211 conversion David Kilroy
@ 2009-06-18 22:21 ` David Kilroy
  2009-06-18 22:21 ` [PATCH 16/23] orinoco: move netdev interface creation to main driver David Kilroy
                   ` (8 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: David Kilroy @ 2009-06-18 22:21 UTC (permalink / raw)
  To: linux-wireless; +Cc: orinoco-devel, David Kilroy

The firmware download code has been in a couple of releases, without any
significant issues reported in this code.

Convert to use pr_debug, so the messages can be recoverred by defining
DEBUG.

Signed-off-by: David Kilroy <kilroyd@googlemail.com>
---
 drivers/net/wireless/orinoco/hermes_dld.c |   50 +++++++++++++---------------
 1 files changed, 23 insertions(+), 27 deletions(-)

diff --git a/drivers/net/wireless/orinoco/hermes_dld.c b/drivers/net/wireless/orinoco/hermes_dld.c
index a9ba195..a3eefe1 100644
--- a/drivers/net/wireless/orinoco/hermes_dld.c
+++ b/drivers/net/wireless/orinoco/hermes_dld.c
@@ -309,7 +309,7 @@ int hermes_read_pda(hermes_t *hw,
 
 	/* Open auxiliary port */
 	ret = hermes_aux_control(hw, 1);
-	printk(KERN_DEBUG PFX "AUX enable returned %d\n", ret);
+	pr_debug(PFX "AUX enable returned %d\n", ret);
 	if (ret)
 		return ret;
 
@@ -319,12 +319,12 @@ int hermes_read_pda(hermes_t *hw,
 
 	/* Close aux port */
 	ret = hermes_aux_control(hw, 0);
-	printk(KERN_DEBUG PFX "AUX disable returned %d\n", ret);
+	pr_debug(PFX "AUX disable returned %d\n", ret);
 
 	/* Check PDA length */
 	pda_size = le16_to_cpu(pda[0]);
-	printk(KERN_DEBUG PFX "Actual PDA length %d, Max allowed %d\n",
-	       pda_size, pda_len);
+	pr_debug(PFX "Actual PDA length %d, Max allowed %d\n",
+		 pda_size, pda_len);
 	if (pda_size > pda_len)
 		return -EINVAL;
 
@@ -422,20 +422,19 @@ int hermesi_program_init(hermes_t *hw, u32 offset)
 		return err;
 
 	err = hermes_aux_control(hw, 1);
-	printk(KERN_DEBUG PFX "AUX enable returned %d\n", err);
+	pr_debug(PFX "AUX enable returned %d\n", err);
 
 	if (err)
 		return err;
 
-	printk(KERN_DEBUG PFX "Enabling volatile, EP 0x%08x\n", offset);
+	pr_debug(KERN_DEBUG PFX "Enabling volatile, EP 0x%08x\n", offset);
 	err = hermes_doicmd_wait(hw,
 				 HERMES_PROGRAM_ENABLE_VOLATILE,
 				 offset & 0xFFFFu,
 				 offset >> 16,
 				 0,
 				 NULL);
-	printk(KERN_DEBUG PFX "PROGRAM_ENABLE returned %d\n",
-	       err);
+	pr_debug(PFX "PROGRAM_ENABLE returned %d\n", err);
 
 	return err;
 }
@@ -454,16 +453,16 @@ int hermesi_program_end(hermes_t *hw)
 
 	rc = hermes_docmd_wait(hw, HERMES_PROGRAM_DISABLE, 0, &resp);
 
-	printk(KERN_DEBUG PFX "PROGRAM_DISABLE returned %d, "
-	       "r0 0x%04x, r1 0x%04x, r2 0x%04x\n",
-	       rc, resp.resp0, resp.resp1, resp.resp2);
+	pr_debug(PFX "PROGRAM_DISABLE returned %d, "
+		 "r0 0x%04x, r1 0x%04x, r2 0x%04x\n",
+		 rc, resp.resp0, resp.resp1, resp.resp2);
 
 	if ((rc == 0) &&
 	    ((resp.status & HERMES_STATUS_CMDCODE) != HERMES_CMD_DOWNLD))
 		rc = -EIO;
 
 	err = hermes_aux_control(hw, 0);
-	printk(KERN_DEBUG PFX "AUX disable returned %d\n", err);
+	pr_debug(PFX "AUX disable returned %d\n", err);
 
 	/* Acknowledge any outstanding command */
 	hermes_write_regn(hw, EVACK, 0xFFFF);
@@ -496,9 +495,8 @@ int hermes_program(hermes_t *hw, const char *first_block, const void *end)
 
 	while ((blkaddr != BLOCK_END) &&
 	       (((void *) blk + blklen) <= end)) {
-		printk(KERN_DEBUG PFX
-		       "Programming block of length %d to address 0x%08x\n",
-		       blklen, blkaddr);
+		pr_debug(PFX "Programming block of length %d "
+			 "to address 0x%08x\n", blklen, blkaddr);
 
 #if !LIMIT_PROGRAM_SIZE
 		/* wl_lkm driver splits this into writes of 2000 bytes */
@@ -510,10 +508,9 @@ int hermes_program(hermes_t *hw, const char *first_block, const void *end)
 		addr = blkaddr;
 
 		while (addr < (blkaddr + blklen)) {
-			printk(KERN_DEBUG PFX
-			       "Programming subblock of length %d "
-			       "to address 0x%08x. Data @ %p\n",
-			       len, addr, &blk->data[addr - blkaddr]);
+			pr_debug(PFX "Programming subblock of length %d "
+				 "to address 0x%08x. Data @ %p\n",
+				 len, addr, &blk->data[addr - blkaddr]);
 
 			hermes_aux_setaddr(hw, addr);
 			hermes_write_bytes(hw, HERMES_AUXDATA,
@@ -643,8 +640,8 @@ int hermes_apply_pda_with_defaults(hermes_t *hw,
 
 		pdi = hermes_find_pdi(first_pdi, record_id, pda_end);
 		if (pdi)
-			printk(KERN_DEBUG PFX "Found record 0x%04x at %p\n",
-			       record_id, pdi);
+			pr_debug(PFX "Found record 0x%04x at %p\n",
+				 record_id, pdi);
 
 		switch (record_id) {
 		case 0x110: /* Modem REFDAC values */
@@ -654,9 +651,9 @@ int hermes_apply_pda_with_defaults(hermes_t *hw,
 			default_pdi = NULL;
 			if (outdoor_pdi) {
 				pdi = outdoor_pdi;
-				printk(KERN_DEBUG PFX
-				       "Using outdoor record 0x%04x at %p\n",
-				       record_id + 1, pdi);
+				pr_debug(PFX
+					 "Using outdoor record 0x%04x at %p\n",
+					 record_id + 1, pdi);
 			}
 			break;
 		case 0x5: /*  HWIF Compatiblity */
@@ -684,9 +681,8 @@ int hermes_apply_pda_with_defaults(hermes_t *hw,
 		if (!pdi && default_pdi) {
 			/* Use default */
 			pdi = default_pdi;
-			printk(KERN_DEBUG PFX
-			       "Using default record 0x%04x at %p\n",
-			       record_id, pdi);
+			pr_debug(PFX "Using default record 0x%04x at %p\n",
+				 record_id, pdi);
 		}
 
 		if (pdi) {
-- 
1.6.0.6


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

* [PATCH 16/23] orinoco: move netdev interface creation to main driver
  2009-06-18 22:21 [PATCH 00/23] orinoco: initiate cfg80211 conversion David Kilroy
                   ` (14 preceding siblings ...)
  2009-06-18 22:21 ` [PATCH 15/23] orinoco: make firmware download less verbose David Kilroy
@ 2009-06-18 22:21 ` David Kilroy
  2009-06-18 22:21 ` [PATCH 17/23] airport: store irq in card private structure David Kilroy
                   ` (7 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: David Kilroy @ 2009-06-18 22:21 UTC (permalink / raw)
  To: linux-wireless; +Cc: orinoco-devel, David Kilroy

With the move to cfg80211 it's nice to keep the hardware operations
distinct from the interface, even though we can only support a single
interface.

This also means the driver resembles other cfg80211 drivers.

Signed-off-by: David Kilroy <kilroyd@googlemail.com>
---
 drivers/net/wireless/orinoco/airport.c        |   23 ++---
 drivers/net/wireless/orinoco/main.c           |  111 +++++++++++++++++-------
 drivers/net/wireless/orinoco/orinoco.h        |    4 +
 drivers/net/wireless/orinoco/orinoco_cs.c     |   21 ++----
 drivers/net/wireless/orinoco/orinoco_nortel.c |   14 +--
 drivers/net/wireless/orinoco/orinoco_pci.c    |   14 +--
 drivers/net/wireless/orinoco/orinoco_plx.c    |   14 +--
 drivers/net/wireless/orinoco/orinoco_tmd.c    |   14 +--
 drivers/net/wireless/orinoco/spectrum_cs.c    |   22 ++----
 9 files changed, 119 insertions(+), 118 deletions(-)

diff --git a/drivers/net/wireless/orinoco/airport.c b/drivers/net/wireless/orinoco/airport.c
index 9f90337..e46e0d7 100644
--- a/drivers/net/wireless/orinoco/airport.c
+++ b/drivers/net/wireless/orinoco/airport.c
@@ -116,7 +116,7 @@ airport_detach(struct macio_dev *mdev)
 	struct airport *card = priv->card;
 
 	if (card->ndev_registered)
-		unregister_netdev(dev);
+		orinoco_if_del(priv);
 	card->ndev_registered = 0;
 
 	if (card->irq_requested)
@@ -174,9 +174,9 @@ static int
 airport_attach(struct macio_dev *mdev, const struct of_device_id *match)
 {
 	struct orinoco_private *priv;
-	struct net_device *dev;
 	struct airport *card;
 	unsigned long phys_addr;
+	unsigned int irq;
 	hermes_t *hw;
 
 	if (macio_resource_count(mdev) < 1 || macio_irq_count(mdev) < 1) {
@@ -191,27 +191,23 @@ airport_attach(struct macio_dev *mdev, const struct of_device_id *match)
 		printk(KERN_ERR PFX "Cannot allocate network device\n");
 		return -ENODEV;
 	}
-	dev = priv->ndev;
 	card = priv->card;
 
 	hw = &priv->hw;
 	card->mdev = mdev;
 
-	if (macio_request_resource(mdev, 0, "airport")) {
+	if (macio_request_resource(mdev, 0, DRIVER_NAME)) {
 		printk(KERN_ERR PFX "can't request IO resource !\n");
 		free_orinocodev(priv);
 		return -EBUSY;
 	}
 
-	SET_NETDEV_DEV(dev, &mdev->ofdev.dev);
-
 	macio_set_drvdata(mdev, priv);
 
 	/* Setup interrupts & base address */
-	dev->irq = macio_irq(mdev, 0);
+	irq = macio_irq(mdev, 0);
 	phys_addr = macio_resource_start(mdev, 0);  /* Physical address */
 	printk(KERN_DEBUG PFX "Physical address %lx\n", phys_addr);
-	dev->base_addr = phys_addr;
 	card->vaddr = ioremap(phys_addr, AIRPORT_IO_LEN);
 	if (!card->vaddr) {
 		printk(KERN_ERR PFX "ioremap() failed\n");
@@ -228,8 +224,8 @@ airport_attach(struct macio_dev *mdev, const struct of_device_id *match)
 	/* Reset it before we get the interrupt */
 	hermes_init(hw);
 
-	if (request_irq(dev->irq, orinoco_interrupt, 0, dev->name, priv)) {
-		printk(KERN_ERR PFX "Couldn't get IRQ %d\n", dev->irq);
+	if (request_irq(irq, orinoco_interrupt, 0, DRIVER_NAME, priv)) {
+		printk(KERN_ERR PFX "Couldn't get IRQ %d\n", irq);
 		goto failed;
 	}
 	card->irq_requested = 1;
@@ -240,12 +236,11 @@ airport_attach(struct macio_dev *mdev, const struct of_device_id *match)
 		goto failed;
 	}
 
-	/* Tell the stack we exist */
-	if (register_netdev(dev) != 0) {
-		printk(KERN_ERR PFX "register_netdev() failed\n");
+	/* Register an interface with the stack */
+	if (orinoco_if_add(priv, phys_addr, irq) != 0) {
+		printk(KERN_ERR PFX "orinoco_if_add() failed\n");
 		goto failed;
 	}
-	printk(KERN_DEBUG PFX "Card registered for interface %s\n", dev->name);
 	card->ndev_registered = 1;
 	return 0;
  failed:
diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c
index 5c1cf64..361cf09 100644
--- a/drivers/net/wireless/orinoco/main.c
+++ b/drivers/net/wireless/orinoco/main.c
@@ -1017,8 +1017,8 @@ static void orinoco_rx(struct net_device *dev,
 
 static void orinoco_rx_isr_tasklet(unsigned long data)
 {
-	struct net_device *dev = (struct net_device *) data;
-	struct orinoco_private *priv = ndev_priv(dev);
+	struct orinoco_private *priv = (struct orinoco_private *) data;
+	struct net_device *dev = priv->ndev;
 	struct orinoco_rx_data *rx_data, *temp;
 	struct hermes_rx_descriptor *desc;
 	struct sk_buff *skb;
@@ -2143,7 +2143,6 @@ int orinoco_init(struct orinoco_private *priv)
 	err = orinoco_hw_read_card_settings(priv, wiphy->perm_addr);
 	if (err)
 		goto out;
-	memcpy(priv->ndev->dev_addr, wiphy->perm_addr, ETH_ALEN);
 
 	err = orinoco_hw_allocate_fid(priv);
 	if (err) {
@@ -2226,9 +2225,7 @@ struct orinoco_private
 		  int (*hard_reset)(struct orinoco_private *),
 		  int (*stop_fw)(struct orinoco_private *, int))
 {
-	struct net_device *dev;
 	struct orinoco_private *priv;
-	struct wireless_dev *wdev;
 	struct wiphy *wiphy;
 
 	/* allocate wiphy
@@ -2240,43 +2237,20 @@ struct orinoco_private
 	if (!wiphy)
 		return NULL;
 
-	dev = alloc_etherdev(sizeof(struct wireless_dev));
-	if (!dev) {
-		wiphy_free(wiphy);
-		return NULL;
-	}
-
 	priv = wiphy_priv(wiphy);
-	priv->ndev = dev;
+	priv->dev = device;
 
 	if (sizeof_card)
 		priv->card = (void *)((unsigned long)priv
 				      + sizeof(struct orinoco_private));
 	else
 		priv->card = NULL;
-	priv->dev = device;
 
 	orinoco_wiphy_init(wiphy);
 
-	/* Initialise wireless_dev */
-	wdev = netdev_priv(dev);
-	wdev->wiphy = wiphy;
-	wdev->iftype = NL80211_IFTYPE_STATION;
-
-	/* Setup / override net_device fields */
-	dev->ieee80211_ptr = wdev;
-	dev->netdev_ops = &orinoco_netdev_ops;
-	dev->watchdog_timeo = HZ; /* 1 second timeout */
-	dev->ethtool_ops = &orinoco_ethtool_ops;
-	dev->wireless_handlers = &orinoco_handler_def;
 #ifdef WIRELESS_SPY
 	priv->wireless_data.spy_data = &priv->spy_data;
-	dev->wireless_data = &priv->wireless_data;
 #endif
-	/* we use the default eth_mac_addr for setting the MAC addr */
-
-	/* Reserve space in skb for the SNAP header */
-	dev->hard_header_len += ENCAPS_OVERHEAD;
 
 	/* Set up default callbacks */
 	priv->hard_reset = hard_reset;
@@ -2293,9 +2267,8 @@ struct orinoco_private
 
 	INIT_LIST_HEAD(&priv->rx_list);
 	tasklet_init(&priv->rx_tasklet, orinoco_rx_isr_tasklet,
-		     (unsigned long) dev);
+		     (unsigned long) priv);
 
-	netif_carrier_off(dev);
 	priv->last_linkstatus = 0xffff;
 
 #if defined(CONFIG_HERMES_CACHE_FW_ON_INIT) || defined(CONFIG_PM_SLEEP)
@@ -2310,9 +2283,82 @@ struct orinoco_private
 }
 EXPORT_SYMBOL(alloc_orinocodev);
 
-void free_orinocodev(struct orinoco_private *priv)
+/* We can only support a single interface. We provide a separate
+ * function to set it up to distinguish between hardware
+ * initialisation and interface setup.
+ *
+ * The base_addr and irq parameters are passed on to netdev for use
+ * with SIOCGIFMAP.
+ */
+int orinoco_if_add(struct orinoco_private *priv,
+		   unsigned long base_addr,
+		   unsigned int irq)
+{
+	struct wiphy *wiphy = priv_to_wiphy(priv);
+	struct wireless_dev *wdev;
+	struct net_device *dev;
+	int ret;
+
+	dev = alloc_etherdev(sizeof(struct wireless_dev));
+
+	if (!dev)
+		return -ENOMEM;
+
+	/* Initialise wireless_dev */
+	wdev = netdev_priv(dev);
+	wdev->wiphy = wiphy;
+	wdev->iftype = NL80211_IFTYPE_STATION;
+
+	/* Setup / override net_device fields */
+	dev->ieee80211_ptr = wdev;
+	dev->netdev_ops = &orinoco_netdev_ops;
+	dev->watchdog_timeo = HZ; /* 1 second timeout */
+	dev->ethtool_ops = &orinoco_ethtool_ops;
+	dev->wireless_handlers = &orinoco_handler_def;
+#ifdef WIRELESS_SPY
+	dev->wireless_data = &priv->wireless_data;
+#endif
+	/* we use the default eth_mac_addr for setting the MAC addr */
+
+	/* Reserve space in skb for the SNAP header */
+	dev->hard_header_len += ENCAPS_OVERHEAD;
+
+	netif_carrier_off(dev);
+
+	memcpy(dev->dev_addr, wiphy->perm_addr, ETH_ALEN);
+
+	dev->base_addr = base_addr;
+	dev->irq = irq;
+
+	SET_NETDEV_DEV(dev, priv->dev);
+	ret = register_netdev(dev);
+	if (ret)
+		goto fail;
+
+	priv->ndev = dev;
+
+	/* Report what we've done */
+	dev_dbg(priv->dev, "Registerred interface %s.\n", dev->name);
+
+	return 0;
+
+ fail:
+	free_netdev(dev);
+	return ret;
+}
+EXPORT_SYMBOL(orinoco_if_add);
+
+void orinoco_if_del(struct orinoco_private *priv)
 {
 	struct net_device *dev = priv->ndev;
+
+	unregister_netdev(dev);
+	free_netdev(dev);
+}
+EXPORT_SYMBOL(orinoco_if_del);
+
+void free_orinocodev(struct orinoco_private *priv)
+{
 	struct wiphy *wiphy = priv_to_wiphy(priv);
 	struct orinoco_rx_data *rx_data, *temp;
 
@@ -2339,7 +2385,6 @@ void free_orinocodev(struct orinoco_private *priv)
 	kfree(priv->wpa_ie);
 	orinoco_mic_free(priv);
 	orinoco_bss_data_free(priv);
-	free_netdev(dev);
 	wiphy_free(wiphy);
 }
 EXPORT_SYMBOL(free_orinocodev);
diff --git a/drivers/net/wireless/orinoco/orinoco.h b/drivers/net/wireless/orinoco/orinoco.h
index 608cc5e..45aa616 100644
--- a/drivers/net/wireless/orinoco/orinoco.h
+++ b/drivers/net/wireless/orinoco/orinoco.h
@@ -193,6 +193,10 @@ extern struct orinoco_private *alloc_orinocodev(
 	int (*stop_fw)(struct orinoco_private *, int));
 extern void free_orinocodev(struct orinoco_private *priv);
 extern int orinoco_init(struct orinoco_private *priv);
+extern int orinoco_if_add(struct orinoco_private *priv,
+			  unsigned long base_addr,
+			  unsigned int irq);
+extern void orinoco_if_del(struct orinoco_private *priv);
 extern int __orinoco_up(struct orinoco_private *priv);
 extern int __orinoco_down(struct orinoco_private *priv);
 extern int orinoco_reinit_firmware(struct orinoco_private *priv);
diff --git a/drivers/net/wireless/orinoco/orinoco_cs.c b/drivers/net/wireless/orinoco/orinoco_cs.c
index 20abf02..4c29d36 100644
--- a/drivers/net/wireless/orinoco/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco/orinoco_cs.c
@@ -147,7 +147,7 @@ static void orinoco_cs_detach(struct pcmcia_device *link)
 	struct orinoco_private *priv = link->priv;
 
 	if (link->dev_node)
-		unregister_netdev(priv->ndev);
+		orinoco_if_del(priv);
 
 	orinoco_cs_release(link);
 
@@ -239,7 +239,6 @@ orinoco_cs_config(struct pcmcia_device *link)
 {
 	struct orinoco_private *priv = link->priv;
 	struct orinoco_pccard *card = priv->card;
-	struct net_device *dev = priv->ndev;
 	hermes_t *hw = &priv->hw;
 	int last_fn, last_ret;
 	void __iomem *mem;
@@ -293,8 +292,6 @@ orinoco_cs_config(struct pcmcia_device *link)
 		 pcmcia_request_configuration(link, &link->conf));
 
 	/* Ok, we have the configuration, prepare to register the netdev */
-	dev->base_addr = link->io.BasePort1;
-	dev->irq = link->irq.AssignedIRQ;
 	card->node.major = card->node.minor = 0;
 
 	/* Initialise the main driver */
@@ -303,25 +300,19 @@ orinoco_cs_config(struct pcmcia_device *link)
 		goto failed;
 	}
 
-	SET_NETDEV_DEV(dev, &handle_to_dev(link));
-	/* Tell the stack we exist */
-	if (register_netdev(dev) != 0) {
-		printk(KERN_ERR PFX "register_netdev() failed\n");
+	/* Register an interface with the stack */
+	if (orinoco_if_add(priv, link->io.BasePort1,
+			   link->irq.AssignedIRQ) != 0) {
+		printk(KERN_ERR PFX "orinoco_if_add() failed\n");
 		goto failed;
 	}
 
 	/* At this point, the dev_node_t structure(s) needs to be
 	 * initialized and arranged in a linked list at link->dev_node. */
-	strcpy(card->node.dev_name, dev->name);
+	strcpy(card->node.dev_name, priv->ndev->name);
 	link->dev_node = &card->node; /* link->dev_node being non-NULL is also
 				       * used to indicate that the
 				       * net_device has been registered */
-
-	/* Finally, report what we've done */
-	printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s, irq %d, io "
-	       "0x%04x-0x%04x\n", dev->name, dev_name(dev->dev.parent),
-	       link->irq.AssignedIRQ, link->io.BasePort1,
-	       link->io.BasePort1 + link->io.NumPorts1 - 1);
 	return 0;
 
  cs_failed:
diff --git a/drivers/net/wireless/orinoco/orinoco_nortel.c b/drivers/net/wireless/orinoco/orinoco_nortel.c
index 45cef81..c13a4c3 100644
--- a/drivers/net/wireless/orinoco/orinoco_nortel.c
+++ b/drivers/net/wireless/orinoco/orinoco_nortel.c
@@ -144,7 +144,6 @@ static int orinoco_nortel_init_one(struct pci_dev *pdev,
 	int err;
 	struct orinoco_private *priv;
 	struct orinoco_pci_card *card;
-	struct net_device *dev;
 	void __iomem *hermes_io, *bridge_io, *attr_io;
 
 	err = pci_enable_device(pdev);
@@ -189,16 +188,14 @@ static int orinoco_nortel_init_one(struct pci_dev *pdev,
 		goto fail_alloc;
 	}
 
-	dev = priv->ndev;
 	card = priv->card;
 	card->bridge_io = bridge_io;
 	card->attr_io = attr_io;
-	SET_NETDEV_DEV(dev, &pdev->dev);
 
 	hermes_struct_init(&priv->hw, hermes_io, HERMES_16BIT_REGSPACING);
 
 	err = request_irq(pdev->irq, orinoco_interrupt, IRQF_SHARED,
-			  dev->name, priv);
+			  DRIVER_NAME, priv);
 	if (err) {
 		printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq);
 		err = -EBUSY;
@@ -223,15 +220,13 @@ static int orinoco_nortel_init_one(struct pci_dev *pdev,
 		goto fail;
 	}
 
-	err = register_netdev(dev);
+	err = orinoco_if_add(priv, 0, 0);
 	if (err) {
-		printk(KERN_ERR PFX "Cannot register network device\n");
+		printk(KERN_ERR PFX "orinoco_if_add() failed\n");
 		goto fail;
 	}
 
 	pci_set_drvdata(pdev, priv);
-	printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s\n", dev->name,
-	       pci_name(pdev));
 
 	return 0;
 
@@ -263,13 +258,12 @@ static int orinoco_nortel_init_one(struct pci_dev *pdev,
 static void __devexit orinoco_nortel_remove_one(struct pci_dev *pdev)
 {
 	struct orinoco_private *priv = pci_get_drvdata(pdev);
-	struct net_device *dev = priv->ndev;
 	struct orinoco_pci_card *card = priv->card;
 
 	/* Clear LEDs */
 	iowrite16(0, card->bridge_io + 10);
 
-	unregister_netdev(dev);
+	orinoco_if_del(priv);
 	free_irq(pdev->irq, priv);
 	pci_set_drvdata(pdev, NULL);
 	free_orinocodev(priv);
diff --git a/drivers/net/wireless/orinoco/orinoco_pci.c b/drivers/net/wireless/orinoco/orinoco_pci.c
index d0eb4ae..fea7781 100644
--- a/drivers/net/wireless/orinoco/orinoco_pci.c
+++ b/drivers/net/wireless/orinoco/orinoco_pci.c
@@ -116,7 +116,6 @@ static int orinoco_pci_init_one(struct pci_dev *pdev,
 	int err;
 	struct orinoco_private *priv;
 	struct orinoco_pci_card *card;
-	struct net_device *dev;
 	void __iomem *hermes_io;
 
 	err = pci_enable_device(pdev);
@@ -147,14 +146,12 @@ static int orinoco_pci_init_one(struct pci_dev *pdev,
 		goto fail_alloc;
 	}
 
-	dev = priv->ndev;
 	card = priv->card;
-	SET_NETDEV_DEV(dev, &pdev->dev);
 
 	hermes_struct_init(&priv->hw, hermes_io, HERMES_32BIT_REGSPACING);
 
 	err = request_irq(pdev->irq, orinoco_interrupt, IRQF_SHARED,
-			  dev->name, priv);
+			  DRIVER_NAME, priv);
 	if (err) {
 		printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq);
 		err = -EBUSY;
@@ -173,15 +170,13 @@ static int orinoco_pci_init_one(struct pci_dev *pdev,
 		goto fail;
 	}
 
-	err = register_netdev(dev);
+	err = orinoco_if_add(priv, 0, 0);
 	if (err) {
-		printk(KERN_ERR PFX "Cannot register network device\n");
+		printk(KERN_ERR PFX "orinoco_if_add() failed\n");
 		goto fail;
 	}
 
 	pci_set_drvdata(pdev, priv);
-	printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s\n", dev->name,
-	       pci_name(pdev));
 
 	return 0;
 
@@ -207,9 +202,8 @@ static int orinoco_pci_init_one(struct pci_dev *pdev,
 static void __devexit orinoco_pci_remove_one(struct pci_dev *pdev)
 {
 	struct orinoco_private *priv = pci_get_drvdata(pdev);
-	struct net_device *dev = priv->ndev;
 
-	unregister_netdev(dev);
+	orinoco_if_del(priv);
 	free_irq(pdev->irq, priv);
 	pci_set_drvdata(pdev, NULL);
 	free_orinocodev(priv);
diff --git a/drivers/net/wireless/orinoco/orinoco_plx.c b/drivers/net/wireless/orinoco/orinoco_plx.c
index 8f225d0..3f2942a 100644
--- a/drivers/net/wireless/orinoco/orinoco_plx.c
+++ b/drivers/net/wireless/orinoco/orinoco_plx.c
@@ -183,7 +183,6 @@ static int orinoco_plx_init_one(struct pci_dev *pdev,
 	int err;
 	struct orinoco_private *priv;
 	struct orinoco_pci_card *card;
-	struct net_device *dev;
 	void __iomem *hermes_io, *attr_io, *bridge_io;
 
 	err = pci_enable_device(pdev);
@@ -228,16 +227,14 @@ static int orinoco_plx_init_one(struct pci_dev *pdev,
 		goto fail_alloc;
 	}
 
-	dev = priv->ndev;
 	card = priv->card;
 	card->bridge_io = bridge_io;
 	card->attr_io = attr_io;
-	SET_NETDEV_DEV(dev, &pdev->dev);
 
 	hermes_struct_init(&priv->hw, hermes_io, HERMES_16BIT_REGSPACING);
 
 	err = request_irq(pdev->irq, orinoco_interrupt, IRQF_SHARED,
-			  dev->name, priv);
+			  DRIVER_NAME, priv);
 	if (err) {
 		printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq);
 		err = -EBUSY;
@@ -262,15 +259,13 @@ static int orinoco_plx_init_one(struct pci_dev *pdev,
 		goto fail;
 	}
 
-	err = register_netdev(dev);
+	err = orinoco_if_add(priv, 0, 0);
 	if (err) {
-		printk(KERN_ERR PFX "Cannot register network device\n");
+		printk(KERN_ERR PFX "orinoco_if_add() failed\n");
 		goto fail;
 	}
 
 	pci_set_drvdata(pdev, priv);
-	printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s\n", dev->name,
-	       pci_name(pdev));
 
 	return 0;
 
@@ -302,10 +297,9 @@ static int orinoco_plx_init_one(struct pci_dev *pdev,
 static void __devexit orinoco_plx_remove_one(struct pci_dev *pdev)
 {
 	struct orinoco_private *priv = pci_get_drvdata(pdev);
-	struct net_device *dev = priv->ndev;
 	struct orinoco_pci_card *card = priv->card;
 
-	unregister_netdev(dev);
+	orinoco_if_del(priv);
 	free_irq(pdev->irq, priv);
 	pci_set_drvdata(pdev, NULL);
 	free_orinocodev(priv);
diff --git a/drivers/net/wireless/orinoco/orinoco_tmd.c b/drivers/net/wireless/orinoco/orinoco_tmd.c
index 3c04fae..d345254 100644
--- a/drivers/net/wireless/orinoco/orinoco_tmd.c
+++ b/drivers/net/wireless/orinoco/orinoco_tmd.c
@@ -94,7 +94,6 @@ static int orinoco_tmd_init_one(struct pci_dev *pdev,
 	int err;
 	struct orinoco_private *priv;
 	struct orinoco_pci_card *card;
-	struct net_device *dev;
 	void __iomem *hermes_io, *bridge_io;
 
 	err = pci_enable_device(pdev);
@@ -132,15 +131,13 @@ static int orinoco_tmd_init_one(struct pci_dev *pdev,
 		goto fail_alloc;
 	}
 
-	dev = priv->ndev;
 	card = priv->card;
 	card->bridge_io = bridge_io;
-	SET_NETDEV_DEV(dev, &pdev->dev);
 
 	hermes_struct_init(&priv->hw, hermes_io, HERMES_16BIT_REGSPACING);
 
 	err = request_irq(pdev->irq, orinoco_interrupt, IRQF_SHARED,
-			  dev->name, priv);
+			  DRIVER_NAME, priv);
 	if (err) {
 		printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq);
 		err = -EBUSY;
@@ -159,15 +156,13 @@ static int orinoco_tmd_init_one(struct pci_dev *pdev,
 		goto fail;
 	}
 
-	err = register_netdev(dev);
+	err = orinoco_if_add(priv, 0, 0);
 	if (err) {
-		printk(KERN_ERR PFX "Cannot register network device\n");
+		printk(KERN_ERR PFX "orinoco_if_add() failed\n");
 		goto fail;
 	}
 
 	pci_set_drvdata(pdev, priv);
-	printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s\n", dev->name,
-	       pci_name(pdev));
 
 	return 0;
 
@@ -196,10 +191,9 @@ static int orinoco_tmd_init_one(struct pci_dev *pdev,
 static void __devexit orinoco_tmd_remove_one(struct pci_dev *pdev)
 {
 	struct orinoco_private *priv = pci_get_drvdata(pdev);
-	struct net_device *dev = priv->ndev;
 	struct orinoco_pci_card *card = priv->card;
 
-	unregister_netdev(dev);
+	orinoco_if_del(priv);
 	free_irq(pdev->irq, priv);
 	pci_set_drvdata(pdev, NULL);
 	free_orinocodev(priv);
diff --git a/drivers/net/wireless/orinoco/spectrum_cs.c b/drivers/net/wireless/orinoco/spectrum_cs.c
index 43e1aed..7b4a7e4 100644
--- a/drivers/net/wireless/orinoco/spectrum_cs.c
+++ b/drivers/net/wireless/orinoco/spectrum_cs.c
@@ -220,7 +220,7 @@ static void spectrum_cs_detach(struct pcmcia_device *link)
 	struct orinoco_private *priv = link->priv;
 
 	if (link->dev_node)
-		unregister_netdev(priv->ndev);
+		orinoco_if_del(priv);
 
 	spectrum_cs_release(link);
 
@@ -306,7 +306,6 @@ spectrum_cs_config(struct pcmcia_device *link)
 {
 	struct orinoco_private *priv = link->priv;
 	struct orinoco_pccard *card = priv->card;
-	struct net_device *dev = priv->ndev;
 	hermes_t *hw = &priv->hw;
 	int last_fn, last_ret;
 	void __iomem *mem;
@@ -360,8 +359,6 @@ spectrum_cs_config(struct pcmcia_device *link)
 		 pcmcia_request_configuration(link, &link->conf));
 
 	/* Ok, we have the configuration, prepare to register the netdev */
-	dev->base_addr = link->io.BasePort1;
-	dev->irq = link->irq.AssignedIRQ;
 	card->node.major = card->node.minor = 0;
 
 	/* Reset card */
@@ -374,26 +371,19 @@ spectrum_cs_config(struct pcmcia_device *link)
 		goto failed;
 	}
 
-	SET_NETDEV_DEV(dev, &handle_to_dev(link));
-	/* Tell the stack we exist */
-	if (register_netdev(dev) != 0) {
-		printk(KERN_ERR PFX "register_netdev() failed\n");
+	/* Register an interface with the stack */
+	if (orinoco_if_add(priv, link->io.BasePort1,
+			   link->irq.AssignedIRQ) != 0) {
+		printk(KERN_ERR PFX "orinoco_if_add() failed\n");
 		goto failed;
 	}
 
 	/* At this point, the dev_node_t structure(s) needs to be
 	 * initialized and arranged in a linked list at link->dev_node. */
-	strcpy(card->node.dev_name, dev->name);
+	strcpy(card->node.dev_name, priv->ndev->name);
 	link->dev_node = &card->node; /* link->dev_node being non-NULL is also
 				       * used to indicate that the
 				       * net_device has been registered */
-
-	/* Finally, report what we've done */
-	printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s, irq %d, io "
-	       "0x%04x-0x%04x\n", dev->name, dev_name(dev->dev.parent),
-	       link->irq.AssignedIRQ, link->io.BasePort1,
-	       link->io.BasePort1 + link->io.NumPorts1 - 1);
-
 	return 0;
 
  cs_failed:
-- 
1.6.0.6


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

* [PATCH 17/23] airport: store irq in card private structure
  2009-06-18 22:21 [PATCH 00/23] orinoco: initiate cfg80211 conversion David Kilroy
                   ` (15 preceding siblings ...)
  2009-06-18 22:21 ` [PATCH 16/23] orinoco: move netdev interface creation to main driver David Kilroy
@ 2009-06-18 22:21 ` David Kilroy
  2009-06-18 22:21 ` [PATCH 18/23] orinoco: Handle suspend/restore in core driver David Kilroy
                   ` (6 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: David Kilroy @ 2009-06-18 22:21 UTC (permalink / raw)
  To: linux-wireless; +Cc: orinoco-devel, David Kilroy

... instead of relying on the net_device fields.

Signed-off-by: David Kilroy <kilroyd@googlemail.com>
---
 drivers/net/wireless/orinoco/airport.c |   24 ++++++++++++------------
 1 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/orinoco/airport.c b/drivers/net/wireless/orinoco/airport.c
index e46e0d7..70f1331 100644
--- a/drivers/net/wireless/orinoco/airport.c
+++ b/drivers/net/wireless/orinoco/airport.c
@@ -27,6 +27,7 @@
 struct airport {
 	struct macio_dev *mdev;
 	void __iomem *vaddr;
+	unsigned int irq;
 	int irq_requested;
 	int ndev_registered;
 };
@@ -36,6 +37,7 @@ airport_suspend(struct macio_dev *mdev, pm_message_t state)
 {
 	struct orinoco_private *priv = dev_get_drvdata(&mdev->ofdev.dev);
 	struct net_device *dev = priv->ndev;
+	struct airport *card = priv->card;
 	unsigned long flags;
 	int err;
 
@@ -59,7 +61,7 @@ airport_suspend(struct macio_dev *mdev, pm_message_t state)
 
 	orinoco_unlock(priv, &flags);
 
-	disable_irq(dev->irq);
+	disable_irq(card->irq);
 	pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE,
 			  macio_get_of_node(mdev), 0, 0);
 
@@ -71,6 +73,7 @@ airport_resume(struct macio_dev *mdev)
 {
 	struct orinoco_private *priv = dev_get_drvdata(&mdev->ofdev.dev);
 	struct net_device *dev = priv->ndev;
+	struct airport *card = priv->card;
 	unsigned long flags;
 	int err;
 
@@ -80,7 +83,7 @@ airport_resume(struct macio_dev *mdev)
 			  macio_get_of_node(mdev), 0, 1);
 	msleep(200);
 
-	enable_irq(dev->irq);
+	enable_irq(card->irq);
 
 	err = orinoco_reinit_firmware(priv);
 	if (err) {
@@ -112,7 +115,6 @@ static int
 airport_detach(struct macio_dev *mdev)
 {
 	struct orinoco_private *priv = dev_get_drvdata(&mdev->ofdev.dev);
-	struct net_device *dev = priv->ndev;
 	struct airport *card = priv->card;
 
 	if (card->ndev_registered)
@@ -120,7 +122,7 @@ airport_detach(struct macio_dev *mdev)
 	card->ndev_registered = 0;
 
 	if (card->irq_requested)
-		free_irq(dev->irq, priv);
+		free_irq(card->irq, priv);
 	card->irq_requested = 0;
 
 	if (card->vaddr)
@@ -146,7 +148,6 @@ static int airport_hard_reset(struct orinoco_private *priv)
 	 * re-initialize properly, it falls in a screaming heap
 	 * shortly afterwards. */
 #if 0
-	struct net_device *dev = priv->ndev;
 	struct airport *card = priv->card;
 
 	/* Vitally important.  If we don't do this it seems we get an
@@ -154,7 +155,7 @@ static int airport_hard_reset(struct orinoco_private *priv)
 	 * hw_unavailable is already set it doesn't get ACKed, we get
 	 * into an interrupt loop and the PMU decides to turn us
 	 * off. */
-	disable_irq(dev->irq);
+	disable_irq(card->irq);
 
 	pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE,
 			  macio_get_of_node(card->mdev), 0, 0);
@@ -163,7 +164,7 @@ static int airport_hard_reset(struct orinoco_private *priv)
 			  macio_get_of_node(card->mdev), 0, 1);
 	ssleep(1);
 
-	enable_irq(dev->irq);
+	enable_irq(card->irq);
 	ssleep(1);
 #endif
 
@@ -176,7 +177,6 @@ airport_attach(struct macio_dev *mdev, const struct of_device_id *match)
 	struct orinoco_private *priv;
 	struct airport *card;
 	unsigned long phys_addr;
-	unsigned int irq;
 	hermes_t *hw;
 
 	if (macio_resource_count(mdev) < 1 || macio_irq_count(mdev) < 1) {
@@ -205,7 +205,7 @@ airport_attach(struct macio_dev *mdev, const struct of_device_id *match)
 	macio_set_drvdata(mdev, priv);
 
 	/* Setup interrupts & base address */
-	irq = macio_irq(mdev, 0);
+	card->irq = macio_irq(mdev, 0);
 	phys_addr = macio_resource_start(mdev, 0);  /* Physical address */
 	printk(KERN_DEBUG PFX "Physical address %lx\n", phys_addr);
 	card->vaddr = ioremap(phys_addr, AIRPORT_IO_LEN);
@@ -224,8 +224,8 @@ airport_attach(struct macio_dev *mdev, const struct of_device_id *match)
 	/* Reset it before we get the interrupt */
 	hermes_init(hw);
 
-	if (request_irq(irq, orinoco_interrupt, 0, DRIVER_NAME, priv)) {
-		printk(KERN_ERR PFX "Couldn't get IRQ %d\n", irq);
+	if (request_irq(card->irq, orinoco_interrupt, 0, DRIVER_NAME, priv)) {
+		printk(KERN_ERR PFX "Couldn't get IRQ %d\n", card->irq);
 		goto failed;
 	}
 	card->irq_requested = 1;
@@ -237,7 +237,7 @@ airport_attach(struct macio_dev *mdev, const struct of_device_id *match)
 	}
 
 	/* Register an interface with the stack */
-	if (orinoco_if_add(priv, phys_addr, irq) != 0) {
+	if (orinoco_if_add(priv, phys_addr, card->irq) != 0) {
 		printk(KERN_ERR PFX "orinoco_if_add() failed\n");
 		goto failed;
 	}
-- 
1.6.0.6


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

* [PATCH 18/23] orinoco: Handle suspend/restore in core driver
  2009-06-18 22:21 [PATCH 00/23] orinoco: initiate cfg80211 conversion David Kilroy
                   ` (16 preceding siblings ...)
  2009-06-18 22:21 ` [PATCH 17/23] airport: store irq in card private structure David Kilroy
@ 2009-06-18 22:21 ` David Kilroy
  2009-06-18 22:21 ` [PATCH 19/23] orinoco: provide generic commit function David Kilroy
                   ` (5 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: David Kilroy @ 2009-06-18 22:21 UTC (permalink / raw)
  To: linux-wireless; +Cc: orinoco-devel, David Kilroy

Each device does almost exactly the same things on suspend and resume
when upping and downing the interface. So move this logic into a common
routine.

Signed-off-by: David Kilroy <kilroyd@googlemail.com>
---
 drivers/net/wireless/orinoco/airport.c     |   33 +--------------
 drivers/net/wireless/orinoco/main.c        |   61 +++++++++++++++++++++++++---
 drivers/net/wireless/orinoco/orinoco.h     |    5 +-
 drivers/net/wireless/orinoco/orinoco_cs.c  |   44 ++------------------
 drivers/net/wireless/orinoco/orinoco_pci.h |   47 +--------------------
 drivers/net/wireless/orinoco/spectrum_cs.c |   41 +-----------------
 6 files changed, 70 insertions(+), 161 deletions(-)

diff --git a/drivers/net/wireless/orinoco/airport.c b/drivers/net/wireless/orinoco/airport.c
index 70f1331..c60df2c 100644
--- a/drivers/net/wireless/orinoco/airport.c
+++ b/drivers/net/wireless/orinoco/airport.c
@@ -50,15 +50,7 @@ airport_suspend(struct macio_dev *mdev, pm_message_t state)
 		return 0;
 	}
 
-	err = __orinoco_down(priv);
-	if (err)
-		printk(KERN_WARNING "%s: PBOOK_SLEEP_NOW: Error %d downing interface\n",
-		       dev->name, err);
-
-	netif_device_detach(dev);
-
-	priv->hw_unavailable++;
-
+	orinoco_down(priv);
 	orinoco_unlock(priv, &flags);
 
 	disable_irq(card->irq);
@@ -85,30 +77,11 @@ airport_resume(struct macio_dev *mdev)
 
 	enable_irq(card->irq);
 
-	err = orinoco_reinit_firmware(priv);
-	if (err) {
-		printk(KERN_ERR "%s: Error %d re-initializing firmware on PBOOK_WAKE\n",
-		       dev->name, err);
-		return 0;
-	}
-
 	spin_lock_irqsave(&priv->lock, flags);
-
-	netif_device_attach(dev);
-
-	priv->hw_unavailable--;
-
-	if (priv->open && (!priv->hw_unavailable)) {
-		err = __orinoco_up(priv);
-		if (err)
-			printk(KERN_ERR "%s: Error %d restarting card on PBOOK_WAKE\n",
-			       dev->name, err);
-	}
-
-
+	err = orinoco_up(priv);
 	spin_unlock_irqrestore(&priv->lock, flags);
 
-	return 0;
+	return err;
 }
 
 static int
diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c
index 361cf09..0727b41 100644
--- a/drivers/net/wireless/orinoco/main.c
+++ b/drivers/net/wireless/orinoco/main.c
@@ -211,6 +211,8 @@ struct orinoco_rx_data {
 /********************************************************************/
 
 static void __orinoco_set_multicast_list(struct net_device *dev);
+static int __orinoco_up(struct orinoco_private *priv);
+static int __orinoco_down(struct orinoco_private *priv);
 
 /********************************************************************/
 /* Internal helper functions                                        */
@@ -1514,7 +1516,7 @@ static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw)
 /* Internal hardware control routines                               */
 /********************************************************************/
 
-int __orinoco_up(struct orinoco_private *priv)
+static int __orinoco_up(struct orinoco_private *priv)
 {
 	struct net_device *dev = priv->ndev;
 	struct hermes *hw = &priv->hw;
@@ -1542,9 +1544,8 @@ int __orinoco_up(struct orinoco_private *priv)
 
 	return 0;
 }
-EXPORT_SYMBOL(__orinoco_up);
 
-int __orinoco_down(struct orinoco_private *priv)
+static int __orinoco_down(struct orinoco_private *priv)
 {
 	struct net_device *dev = priv->ndev;
 	struct hermes *hw = &priv->hw;
@@ -1574,9 +1575,8 @@ int __orinoco_down(struct orinoco_private *priv)
 
 	return 0;
 }
-EXPORT_SYMBOL(__orinoco_down);
 
-int orinoco_reinit_firmware(struct orinoco_private *priv)
+static int orinoco_reinit_firmware(struct orinoco_private *priv)
 {
 	struct hermes *hw = &priv->hw;
 	int err;
@@ -1592,7 +1592,6 @@ int orinoco_reinit_firmware(struct orinoco_private *priv)
 
 	return err;
 }
-EXPORT_SYMBOL(orinoco_reinit_firmware);
 
 int __orinoco_program_rids(struct net_device *dev)
 {
@@ -2389,6 +2388,56 @@ void free_orinocodev(struct orinoco_private *priv)
 }
 EXPORT_SYMBOL(free_orinocodev);
 
+int orinoco_up(struct orinoco_private *priv)
+{
+	struct net_device *dev = priv->ndev;
+	unsigned long flags;
+	int err;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	err = orinoco_reinit_firmware(priv);
+	if (err) {
+		printk(KERN_ERR "%s: Error %d re-initializing firmware\n",
+		       dev->name, err);
+		goto exit;
+	}
+
+	netif_device_attach(dev);
+	priv->hw_unavailable--;
+
+	if (priv->open && !priv->hw_unavailable) {
+		err = __orinoco_up(priv);
+		if (err)
+			printk(KERN_ERR "%s: Error %d restarting card\n",
+			       dev->name, err);
+	}
+
+exit:
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return 0;
+}
+EXPORT_SYMBOL(orinoco_up);
+
+void orinoco_down(struct orinoco_private *priv)
+{
+	struct net_device *dev = priv->ndev;
+	unsigned long flags;
+	int err;
+
+	spin_lock_irqsave(&priv->lock, flags);
+	err = __orinoco_down(priv);
+	if (err)
+		printk(KERN_WARNING "%s: Error %d downing interface\n",
+		       dev->name, err);
+
+	netif_device_detach(dev);
+	priv->hw_unavailable++;
+	spin_unlock_irqrestore(&priv->lock, flags);
+}
+EXPORT_SYMBOL(orinoco_down);
+
 static void orinoco_get_drvinfo(struct net_device *dev,
 				struct ethtool_drvinfo *info)
 {
diff --git a/drivers/net/wireless/orinoco/orinoco.h b/drivers/net/wireless/orinoco/orinoco.h
index 45aa616..4ee85f8 100644
--- a/drivers/net/wireless/orinoco/orinoco.h
+++ b/drivers/net/wireless/orinoco/orinoco.h
@@ -197,9 +197,8 @@ extern int orinoco_if_add(struct orinoco_private *priv,
 			  unsigned long base_addr,
 			  unsigned int irq);
 extern void orinoco_if_del(struct orinoco_private *priv);
-extern int __orinoco_up(struct orinoco_private *priv);
-extern int __orinoco_down(struct orinoco_private *priv);
-extern int orinoco_reinit_firmware(struct orinoco_private *priv);
+extern int orinoco_up(struct orinoco_private *priv);
+extern void orinoco_down(struct orinoco_private *priv);
 extern irqreturn_t orinoco_interrupt(int irq, void *dev_id);
 
 /********************************************************************/
diff --git a/drivers/net/wireless/orinoco/orinoco_cs.c b/drivers/net/wireless/orinoco/orinoco_cs.c
index 4c29d36..38c1c9d 100644
--- a/drivers/net/wireless/orinoco/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco/orinoco_cs.c
@@ -349,26 +349,12 @@ static int orinoco_cs_suspend(struct pcmcia_device *link)
 {
 	struct orinoco_private *priv = link->priv;
 	struct orinoco_pccard *card = priv->card;
-	struct net_device *dev = priv->ndev;
-	int err = 0;
-	unsigned long flags;
 
 	/* This is probably racy, but I can't think of
 	   a better way, short of rewriting the PCMCIA
 	   layer to not suck :-( */
-	if (!test_bit(0, &card->hard_reset_in_progress)) {
-		spin_lock_irqsave(&priv->lock, flags);
-
-		err = __orinoco_down(priv);
-		if (err)
-			printk(KERN_WARNING "%s: Error %d downing interface\n",
-			       dev->name, err);
-
-		netif_device_detach(dev);
-		priv->hw_unavailable++;
-
-		spin_unlock_irqrestore(&priv->lock, flags);
-	}
+	if (!test_bit(0, &card->hard_reset_in_progress))
+		orinoco_down(priv);
 
 	return 0;
 }
@@ -377,32 +363,10 @@ static int orinoco_cs_resume(struct pcmcia_device *link)
 {
 	struct orinoco_private *priv = link->priv;
 	struct orinoco_pccard *card = priv->card;
-	struct net_device *dev = priv->ndev;
 	int err = 0;
-	unsigned long flags;
 
-	if (!test_bit(0, &card->hard_reset_in_progress)) {
-		err = orinoco_reinit_firmware(priv);
-		if (err) {
-			printk(KERN_ERR "%s: Error %d re-initializing firmware\n",
-			       dev->name, err);
-			return -EIO;
-		}
-
-		spin_lock_irqsave(&priv->lock, flags);
-
-		netif_device_attach(dev);
-		priv->hw_unavailable--;
-
-		if (priv->open && !priv->hw_unavailable) {
-			err = __orinoco_up(priv);
-			if (err)
-				printk(KERN_ERR "%s: Error %d restarting card\n",
-				       dev->name, err);
-		}
-
-		spin_unlock_irqrestore(&priv->lock, flags);
-	}
+	if (!test_bit(0, &card->hard_reset_in_progress))
+		err = orinoco_up(priv);
 
 	return err;
 }
diff --git a/drivers/net/wireless/orinoco/orinoco_pci.h b/drivers/net/wireless/orinoco/orinoco_pci.h
index 22aa630..ea7231a 100644
--- a/drivers/net/wireless/orinoco/orinoco_pci.h
+++ b/drivers/net/wireless/orinoco/orinoco_pci.h
@@ -22,28 +22,8 @@ struct orinoco_pci_card {
 static int orinoco_pci_suspend(struct pci_dev *pdev, pm_message_t state)
 {
 	struct orinoco_private *priv = pci_get_drvdata(pdev);
-	struct net_device *dev = priv->ndev;
-	unsigned long flags;
-	int err;
-
-	err = orinoco_lock(priv, &flags);
-	if (err) {
-		printk(KERN_ERR "%s: cannot lock hardware for suspend\n",
-		       dev->name);
-		return err;
-	}
-
-	err = __orinoco_down(priv);
-	if (err)
-		printk(KERN_WARNING "%s: error %d bringing interface down "
-		       "for suspend\n", dev->name, err);
-
-	netif_device_detach(dev);
-
-	priv->hw_unavailable++;
-
-	orinoco_unlock(priv, &flags);
 
+	orinoco_down(priv);
 	free_irq(pdev->irq, priv);
 	pci_save_state(pdev);
 	pci_disable_device(pdev);
@@ -56,7 +36,6 @@ static int orinoco_pci_resume(struct pci_dev *pdev)
 {
 	struct orinoco_private *priv = pci_get_drvdata(pdev);
 	struct net_device *dev = priv->ndev;
-	unsigned long flags;
 	int err;
 
 	pci_set_power_state(pdev, 0);
@@ -77,29 +56,9 @@ static int orinoco_pci_resume(struct pci_dev *pdev)
 		return -EBUSY;
 	}
 
-	err = orinoco_reinit_firmware(priv);
-	if (err) {
-		printk(KERN_ERR "%s: error %d re-initializing firmware "
-		       "on resume\n", dev->name, err);
-		return err;
-	}
-
-	spin_lock_irqsave(&priv->lock, flags);
-
-	netif_device_attach(dev);
+	err = orinoco_up(priv);
 
-	priv->hw_unavailable--;
-
-	if (priv->open && (!priv->hw_unavailable)) {
-		err = __orinoco_up(priv);
-		if (err)
-			printk(KERN_ERR "%s: Error %d restarting card on resume\n",
-			       dev->name, err);
-	}
-
-	spin_unlock_irqrestore(&priv->lock, flags);
-
-	return 0;
+	return err;
 }
 #else
 #define orinoco_pci_suspend NULL
diff --git a/drivers/net/wireless/orinoco/spectrum_cs.c b/drivers/net/wireless/orinoco/spectrum_cs.c
index 7b4a7e4..c361310 100644
--- a/drivers/net/wireless/orinoco/spectrum_cs.c
+++ b/drivers/net/wireless/orinoco/spectrum_cs.c
@@ -421,22 +421,10 @@ static int
 spectrum_cs_suspend(struct pcmcia_device *link)
 {
 	struct orinoco_private *priv = link->priv;
-	struct net_device *dev = priv->ndev;
-	unsigned long flags;
 	int err = 0;
 
 	/* Mark the device as stopped, to block IO until later */
-	spin_lock_irqsave(&priv->lock, flags);
-
-	err = __orinoco_down(priv);
-	if (err)
-		printk(KERN_WARNING "%s: Error %d downing interface\n",
-		       dev->name, err);
-
-	netif_device_detach(dev);
-	priv->hw_unavailable++;
-
-	spin_unlock_irqrestore(&priv->lock, flags);
+	orinoco_down(priv);
 
 	return err;
 }
@@ -445,32 +433,9 @@ static int
 spectrum_cs_resume(struct pcmcia_device *link)
 {
 	struct orinoco_private *priv = link->priv;
-	struct net_device *dev = priv->ndev;
-	unsigned long flags;
-	int err;
-
-	err = orinoco_reinit_firmware(priv);
-	if (err) {
-		printk(KERN_ERR "%s: Error %d re-initializing firmware\n",
-		       dev->name, err);
-		return -EIO;
-	}
+	int err = orinoco_up(priv);
 
-	spin_lock_irqsave(&priv->lock, flags);
-
-	netif_device_attach(dev);
-	priv->hw_unavailable--;
-
-	if (priv->open && !priv->hw_unavailable) {
-		err = __orinoco_up(priv);
-		if (err)
-			printk(KERN_ERR "%s: Error %d restarting card\n",
-			       dev->name, err);
-	}
-
-	spin_unlock_irqrestore(&priv->lock, flags);
-
-	return 0;
+	return err;
 }
 
 
-- 
1.6.0.6


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

* [PATCH 19/23] orinoco: provide generic commit function
  2009-06-18 22:21 [PATCH 00/23] orinoco: initiate cfg80211 conversion David Kilroy
                   ` (17 preceding siblings ...)
  2009-06-18 22:21 ` [PATCH 18/23] orinoco: Handle suspend/restore in core driver David Kilroy
@ 2009-06-18 22:21 ` David Kilroy
  2009-06-18 22:21 ` [PATCH 20/23] orinoco: convert mode setting to cfg80211 David Kilroy
                   ` (4 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: David Kilroy @ 2009-06-18 22:21 UTC (permalink / raw)
  To: linux-wireless; +Cc: orinoco-devel, David Kilroy

This allows changes to be commited from cfg80211 functions.

Signed-off-by: David Kilroy <kilroyd@googlemail.com>
---
 drivers/net/wireless/orinoco/hw.c   |  227 ++++++++++++++++++++++++++
 drivers/net/wireless/orinoco/hw.h   |    1 +
 drivers/net/wireless/orinoco/main.c |  297 ++++++++---------------------------
 drivers/net/wireless/orinoco/main.h |    3 +-
 drivers/net/wireless/orinoco/wext.c |   35 +----
 5 files changed, 294 insertions(+), 269 deletions(-)

diff --git a/drivers/net/wireless/orinoco/hw.c b/drivers/net/wireless/orinoco/hw.c
index eaa89d3..56627d9 100644
--- a/drivers/net/wireless/orinoco/hw.c
+++ b/drivers/net/wireless/orinoco/hw.c
@@ -406,6 +406,233 @@ void orinoco_get_ratemode_cfg(int ratemode, int *bitrate, int *automatic)
 	*automatic = bitrate_table[ratemode].automatic;
 }
 
+int orinoco_hw_program_rids(struct orinoco_private *priv)
+{
+	struct net_device *dev = priv->ndev;
+	hermes_t *hw = &priv->hw;
+	int err;
+	struct hermes_idstring idbuf;
+
+	/* Set the MAC address */
+	err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
+			       HERMES_BYTES_TO_RECLEN(ETH_ALEN), dev->dev_addr);
+	if (err) {
+		printk(KERN_ERR "%s: Error %d setting MAC address\n",
+		       dev->name, err);
+		return err;
+	}
+
+	/* Set up the link mode */
+	err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFPORTTYPE,
+				   priv->port_type);
+	if (err) {
+		printk(KERN_ERR "%s: Error %d setting port type\n",
+		       dev->name, err);
+		return err;
+	}
+	/* Set the channel/frequency */
+	if (priv->channel != 0 && priv->iw_mode != IW_MODE_INFRA) {
+		err = hermes_write_wordrec(hw, USER_BAP,
+					   HERMES_RID_CNFOWNCHANNEL,
+					   priv->channel);
+		if (err) {
+			printk(KERN_ERR "%s: Error %d setting channel %d\n",
+			       dev->name, err, priv->channel);
+			return err;
+		}
+	}
+
+	if (priv->has_ibss) {
+		u16 createibss;
+
+		if ((strlen(priv->desired_essid) == 0) && (priv->createibss)) {
+			printk(KERN_WARNING "%s: This firmware requires an "
+			       "ESSID in IBSS-Ad-Hoc mode.\n", dev->name);
+			/* With wvlan_cs, in this case, we would crash.
+			 * hopefully, this driver will behave better...
+			 * Jean II */
+			createibss = 0;
+		} else {
+			createibss = priv->createibss;
+		}
+
+		err = hermes_write_wordrec(hw, USER_BAP,
+					   HERMES_RID_CNFCREATEIBSS,
+					   createibss);
+		if (err) {
+			printk(KERN_ERR "%s: Error %d setting CREATEIBSS\n",
+			       dev->name, err);
+			return err;
+		}
+	}
+
+	/* Set the desired BSSID */
+	err = __orinoco_hw_set_wap(priv);
+	if (err) {
+		printk(KERN_ERR "%s: Error %d setting AP address\n",
+		       dev->name, err);
+		return err;
+	}
+
+	/* Set the desired ESSID */
+	idbuf.len = cpu_to_le16(strlen(priv->desired_essid));
+	memcpy(&idbuf.val, priv->desired_essid, sizeof(idbuf.val));
+	/* WinXP wants partner to configure OWNSSID even in IBSS mode. (jimc) */
+	err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNSSID,
+			HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
+			&idbuf);
+	if (err) {
+		printk(KERN_ERR "%s: Error %d setting OWNSSID\n",
+		       dev->name, err);
+		return err;
+	}
+	err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFDESIREDSSID,
+			HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
+			&idbuf);
+	if (err) {
+		printk(KERN_ERR "%s: Error %d setting DESIREDSSID\n",
+		       dev->name, err);
+		return err;
+	}
+
+	/* Set the station name */
+	idbuf.len = cpu_to_le16(strlen(priv->nick));
+	memcpy(&idbuf.val, priv->nick, sizeof(idbuf.val));
+	err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
+			       HERMES_BYTES_TO_RECLEN(strlen(priv->nick)+2),
+			       &idbuf);
+	if (err) {
+		printk(KERN_ERR "%s: Error %d setting nickname\n",
+		       dev->name, err);
+		return err;
+	}
+
+	/* Set AP density */
+	if (priv->has_sensitivity) {
+		err = hermes_write_wordrec(hw, USER_BAP,
+					   HERMES_RID_CNFSYSTEMSCALE,
+					   priv->ap_density);
+		if (err) {
+			printk(KERN_WARNING "%s: Error %d setting SYSTEMSCALE. "
+			       "Disabling sensitivity control\n",
+			       dev->name, err);
+
+			priv->has_sensitivity = 0;
+		}
+	}
+
+	/* Set RTS threshold */
+	err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD,
+				   priv->rts_thresh);
+	if (err) {
+		printk(KERN_ERR "%s: Error %d setting RTS threshold\n",
+		       dev->name, err);
+		return err;
+	}
+
+	/* Set fragmentation threshold or MWO robustness */
+	if (priv->has_mwo)
+		err = hermes_write_wordrec(hw, USER_BAP,
+					   HERMES_RID_CNFMWOROBUST_AGERE,
+					   priv->mwo_robust);
+	else
+		err = hermes_write_wordrec(hw, USER_BAP,
+					   HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
+					   priv->frag_thresh);
+	if (err) {
+		printk(KERN_ERR "%s: Error %d setting fragmentation\n",
+		       dev->name, err);
+		return err;
+	}
+
+	/* Set bitrate */
+	err = __orinoco_hw_set_bitrate(priv);
+	if (err) {
+		printk(KERN_ERR "%s: Error %d setting bitrate\n",
+		       dev->name, err);
+		return err;
+	}
+
+	/* Set power management */
+	if (priv->has_pm) {
+		err = hermes_write_wordrec(hw, USER_BAP,
+					   HERMES_RID_CNFPMENABLED,
+					   priv->pm_on);
+		if (err) {
+			printk(KERN_ERR "%s: Error %d setting up PM\n",
+			       dev->name, err);
+			return err;
+		}
+
+		err = hermes_write_wordrec(hw, USER_BAP,
+					   HERMES_RID_CNFMULTICASTRECEIVE,
+					   priv->pm_mcast);
+		if (err) {
+			printk(KERN_ERR "%s: Error %d setting up PM\n",
+			       dev->name, err);
+			return err;
+		}
+		err = hermes_write_wordrec(hw, USER_BAP,
+					   HERMES_RID_CNFMAXSLEEPDURATION,
+					   priv->pm_period);
+		if (err) {
+			printk(KERN_ERR "%s: Error %d setting up PM\n",
+			       dev->name, err);
+			return err;
+		}
+		err = hermes_write_wordrec(hw, USER_BAP,
+					   HERMES_RID_CNFPMHOLDOVERDURATION,
+					   priv->pm_timeout);
+		if (err) {
+			printk(KERN_ERR "%s: Error %d setting up PM\n",
+			       dev->name, err);
+			return err;
+		}
+	}
+
+	/* Set preamble - only for Symbol so far... */
+	if (priv->has_preamble) {
+		err = hermes_write_wordrec(hw, USER_BAP,
+					   HERMES_RID_CNFPREAMBLE_SYMBOL,
+					   priv->preamble);
+		if (err) {
+			printk(KERN_ERR "%s: Error %d setting preamble\n",
+			       dev->name, err);
+			return err;
+		}
+	}
+
+	/* Set up encryption */
+	if (priv->has_wep || priv->has_wpa) {
+		err = __orinoco_hw_setup_enc(priv);
+		if (err) {
+			printk(KERN_ERR "%s: Error %d activating encryption\n",
+			       dev->name, err);
+			return err;
+		}
+	}
+
+	if (priv->iw_mode == IW_MODE_MONITOR) {
+		/* Enable monitor mode */
+		dev->type = ARPHRD_IEEE80211;
+		err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
+					    HERMES_TEST_MONITOR, 0, NULL);
+	} else {
+		/* Disable monitor mode */
+		dev->type = ARPHRD_ETHER;
+		err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
+					    HERMES_TEST_STOP, 0, NULL);
+	}
+	if (err)
+		return err;
+
+	/* Reset promiscuity / multicast*/
+	priv->promiscuous = 0;
+	priv->mc_count = 0;
+
+	return 0;
+}
+
 /* Get tsc from the firmware */
 int orinoco_hw_get_tkip_iv(struct orinoco_private *priv, int key, u8 *tsc)
 {
diff --git a/drivers/net/wireless/orinoco/hw.h b/drivers/net/wireless/orinoco/hw.h
index 84c108c..210c2b1 100644
--- a/drivers/net/wireless/orinoco/hw.h
+++ b/drivers/net/wireless/orinoco/hw.h
@@ -29,6 +29,7 @@ int orinoco_hw_allocate_fid(struct orinoco_private *priv);
 int orinoco_get_bitratemode(int bitrate, int automatic);
 void orinoco_get_ratemode_cfg(int ratemode, int *bitrate, int *automatic);
 
+int orinoco_hw_program_rids(struct orinoco_private *priv);
 int orinoco_hw_get_tkip_iv(struct orinoco_private *priv, int key, u8 *tsc);
 int __orinoco_hw_set_bitrate(struct orinoco_private *priv);
 int orinoco_hw_get_act_bitrate(struct orinoco_private *priv, int *bitrate);
diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c
index 0727b41..dab6649 100644
--- a/drivers/net/wireless/orinoco/main.c
+++ b/drivers/net/wireless/orinoco/main.c
@@ -210,9 +210,10 @@ struct orinoco_rx_data {
 /* Function prototypes                                              */
 /********************************************************************/
 
-static void __orinoco_set_multicast_list(struct net_device *dev);
+static int __orinoco_set_multicast_list(struct net_device *dev);
 static int __orinoco_up(struct orinoco_private *priv);
 static int __orinoco_down(struct orinoco_private *priv);
+static int __orinoco_commit(struct orinoco_private *priv);
 
 /********************************************************************/
 /* Internal helper functions                                        */
@@ -1524,7 +1525,7 @@ static int __orinoco_up(struct orinoco_private *priv)
 
 	netif_carrier_off(dev); /* just to make sure */
 
-	err = __orinoco_program_rids(dev);
+	err = __orinoco_commit(priv);
 	if (err) {
 		printk(KERN_ERR "%s: Error %d configuring card\n",
 		       dev->name, err);
@@ -1593,237 +1594,7 @@ static int orinoco_reinit_firmware(struct orinoco_private *priv)
 	return err;
 }
 
-int __orinoco_program_rids(struct net_device *dev)
-{
-	struct orinoco_private *priv = ndev_priv(dev);
-	hermes_t *hw = &priv->hw;
-	int err;
-	struct hermes_idstring idbuf;
-
-	/* Set the MAC address */
-	err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
-			       HERMES_BYTES_TO_RECLEN(ETH_ALEN), dev->dev_addr);
-	if (err) {
-		printk(KERN_ERR "%s: Error %d setting MAC address\n",
-		       dev->name, err);
-		return err;
-	}
-
-	/* Set up the link mode */
-	err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFPORTTYPE,
-				   priv->port_type);
-	if (err) {
-		printk(KERN_ERR "%s: Error %d setting port type\n",
-		       dev->name, err);
-		return err;
-	}
-	/* Set the channel/frequency */
-	if (priv->channel != 0 && priv->iw_mode != IW_MODE_INFRA) {
-		err = hermes_write_wordrec(hw, USER_BAP,
-					   HERMES_RID_CNFOWNCHANNEL,
-					   priv->channel);
-		if (err) {
-			printk(KERN_ERR "%s: Error %d setting channel %d\n",
-			       dev->name, err, priv->channel);
-			return err;
-		}
-	}
-
-	if (priv->has_ibss) {
-		u16 createibss;
-
-		if ((strlen(priv->desired_essid) == 0) && (priv->createibss)) {
-			printk(KERN_WARNING "%s: This firmware requires an "
-			       "ESSID in IBSS-Ad-Hoc mode.\n", dev->name);
-			/* With wvlan_cs, in this case, we would crash.
-			 * hopefully, this driver will behave better...
-			 * Jean II */
-			createibss = 0;
-		} else {
-			createibss = priv->createibss;
-		}
-
-		err = hermes_write_wordrec(hw, USER_BAP,
-					   HERMES_RID_CNFCREATEIBSS,
-					   createibss);
-		if (err) {
-			printk(KERN_ERR "%s: Error %d setting CREATEIBSS\n",
-			       dev->name, err);
-			return err;
-		}
-	}
-
-	/* Set the desired BSSID */
-	err = __orinoco_hw_set_wap(priv);
-	if (err) {
-		printk(KERN_ERR "%s: Error %d setting AP address\n",
-		       dev->name, err);
-		return err;
-	}
-	/* Set the desired ESSID */
-	idbuf.len = cpu_to_le16(strlen(priv->desired_essid));
-	memcpy(&idbuf.val, priv->desired_essid, sizeof(idbuf.val));
-	/* WinXP wants partner to configure OWNSSID even in IBSS mode. (jimc) */
-	err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNSSID,
-			HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
-			&idbuf);
-	if (err) {
-		printk(KERN_ERR "%s: Error %d setting OWNSSID\n",
-		       dev->name, err);
-		return err;
-	}
-	err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFDESIREDSSID,
-			HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
-			&idbuf);
-	if (err) {
-		printk(KERN_ERR "%s: Error %d setting DESIREDSSID\n",
-		       dev->name, err);
-		return err;
-	}
-
-	/* Set the station name */
-	idbuf.len = cpu_to_le16(strlen(priv->nick));
-	memcpy(&idbuf.val, priv->nick, sizeof(idbuf.val));
-	err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
-			       HERMES_BYTES_TO_RECLEN(strlen(priv->nick)+2),
-			       &idbuf);
-	if (err) {
-		printk(KERN_ERR "%s: Error %d setting nickname\n",
-		       dev->name, err);
-		return err;
-	}
-
-	/* Set AP density */
-	if (priv->has_sensitivity) {
-		err = hermes_write_wordrec(hw, USER_BAP,
-					   HERMES_RID_CNFSYSTEMSCALE,
-					   priv->ap_density);
-		if (err) {
-			printk(KERN_WARNING "%s: Error %d setting SYSTEMSCALE. "
-			       "Disabling sensitivity control\n",
-			       dev->name, err);
-
-			priv->has_sensitivity = 0;
-		}
-	}
-
-	/* Set RTS threshold */
-	err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD,
-				   priv->rts_thresh);
-	if (err) {
-		printk(KERN_ERR "%s: Error %d setting RTS threshold\n",
-		       dev->name, err);
-		return err;
-	}
-
-	/* Set fragmentation threshold or MWO robustness */
-	if (priv->has_mwo)
-		err = hermes_write_wordrec(hw, USER_BAP,
-					   HERMES_RID_CNFMWOROBUST_AGERE,
-					   priv->mwo_robust);
-	else
-		err = hermes_write_wordrec(hw, USER_BAP,
-					   HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
-					   priv->frag_thresh);
-	if (err) {
-		printk(KERN_ERR "%s: Error %d setting fragmentation\n",
-		       dev->name, err);
-		return err;
-	}
-
-	/* Set bitrate */
-	err = __orinoco_hw_set_bitrate(priv);
-	if (err) {
-		printk(KERN_ERR "%s: Error %d setting bitrate\n",
-		       dev->name, err);
-		return err;
-	}
-
-	/* Set power management */
-	if (priv->has_pm) {
-		err = hermes_write_wordrec(hw, USER_BAP,
-					   HERMES_RID_CNFPMENABLED,
-					   priv->pm_on);
-		if (err) {
-			printk(KERN_ERR "%s: Error %d setting up PM\n",
-			       dev->name, err);
-			return err;
-		}
-
-		err = hermes_write_wordrec(hw, USER_BAP,
-					   HERMES_RID_CNFMULTICASTRECEIVE,
-					   priv->pm_mcast);
-		if (err) {
-			printk(KERN_ERR "%s: Error %d setting up PM\n",
-			       dev->name, err);
-			return err;
-		}
-		err = hermes_write_wordrec(hw, USER_BAP,
-					   HERMES_RID_CNFMAXSLEEPDURATION,
-					   priv->pm_period);
-		if (err) {
-			printk(KERN_ERR "%s: Error %d setting up PM\n",
-			       dev->name, err);
-			return err;
-		}
-		err = hermes_write_wordrec(hw, USER_BAP,
-					   HERMES_RID_CNFPMHOLDOVERDURATION,
-					   priv->pm_timeout);
-		if (err) {
-			printk(KERN_ERR "%s: Error %d setting up PM\n",
-			       dev->name, err);
-			return err;
-		}
-	}
-
-	/* Set preamble - only for Symbol so far... */
-	if (priv->has_preamble) {
-		err = hermes_write_wordrec(hw, USER_BAP,
-					   HERMES_RID_CNFPREAMBLE_SYMBOL,
-					   priv->preamble);
-		if (err) {
-			printk(KERN_ERR "%s: Error %d setting preamble\n",
-			       dev->name, err);
-			return err;
-		}
-	}
-
-	/* Set up encryption */
-	if (priv->has_wep || priv->has_wpa) {
-		err = __orinoco_hw_setup_enc(priv);
-		if (err) {
-			printk(KERN_ERR "%s: Error %d activating encryption\n",
-			       dev->name, err);
-			return err;
-		}
-	}
-
-	if (priv->iw_mode == IW_MODE_MONITOR) {
-		/* Enable monitor mode */
-		dev->type = ARPHRD_IEEE80211;
-		err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
-					    HERMES_TEST_MONITOR, 0, NULL);
-	} else {
-		/* Disable monitor mode */
-		dev->type = ARPHRD_ETHER;
-		err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
-					    HERMES_TEST_STOP, 0, NULL);
-	}
-	if (err)
-		return err;
-
-	/* Set promiscuity / multicast*/
-	priv->promiscuous = 0;
-	priv->mc_count = 0;
-
-	/* FIXME: what about netif_tx_lock */
-	__orinoco_set_multicast_list(dev);
-
-	return 0;
-}
-
-/* FIXME: return int? */
-static void
+static int
 __orinoco_set_multicast_list(struct net_device *dev)
 {
 	struct orinoco_private *priv = ndev_priv(dev);
@@ -1843,6 +1614,8 @@ __orinoco_set_multicast_list(struct net_device *dev)
 
 	err = __orinoco_hw_set_multicast_list(priv, dev->mc_list, mc_count,
 					      promisc);
+
+	return err;
 }
 
 /* This must be called from user context, without locks held - use
@@ -1920,6 +1693,64 @@ void orinoco_reset(struct work_struct *work)
 	printk(KERN_ERR "%s: Device has been disabled!\n", dev->name);
 }
 
+static int __orinoco_commit(struct orinoco_private *priv)
+{
+	struct net_device *dev = priv->ndev;
+	int err = 0;
+
+	err = orinoco_hw_program_rids(priv);
+
+	/* FIXME: what about netif_tx_lock */
+	(void) __orinoco_set_multicast_list(dev);
+
+	return err;
+}
+
+/* Ensures configuration changes are applied. May result in a reset.
+ * The caller should hold priv->lock
+ */
+int orinoco_commit(struct orinoco_private *priv)
+{
+	struct net_device *dev = priv->ndev;
+	hermes_t *hw = &priv->hw;
+	int err;
+
+	if (priv->broken_disableport) {
+		schedule_work(&priv->reset_work);
+		return 0;
+	}
+
+	err = hermes_disable_port(hw, 0);
+	if (err) {
+		printk(KERN_WARNING "%s: Unable to disable port "
+		       "while reconfiguring card\n", dev->name);
+		priv->broken_disableport = 1;
+		goto out;
+	}
+
+	err = __orinoco_commit(priv);
+	if (err) {
+		printk(KERN_WARNING "%s: Unable to reconfigure card\n",
+		       dev->name);
+		goto out;
+	}
+
+	err = hermes_enable_port(hw, 0);
+	if (err) {
+		printk(KERN_WARNING "%s: Unable to enable port while reconfiguring card\n",
+		       dev->name);
+		goto out;
+	}
+
+ out:
+	if (err) {
+		printk(KERN_WARNING "%s: Resetting instead...\n", dev->name);
+		schedule_work(&priv->reset_work);
+		err = 0;
+	}
+	return err;
+}
+
 /********************************************************************/
 /* Interrupt handler                                                */
 /********************************************************************/
diff --git a/drivers/net/wireless/orinoco/main.h b/drivers/net/wireless/orinoco/main.h
index af2bae4..21ab36c 100644
--- a/drivers/net/wireless/orinoco/main.h
+++ b/drivers/net/wireless/orinoco/main.h
@@ -29,10 +29,9 @@ struct net_device;
 struct work_struct;
 
 void set_port_type(struct orinoco_private *priv);
-int __orinoco_program_rids(struct net_device *dev);
+int orinoco_commit(struct orinoco_private *priv);
 void orinoco_reset(struct work_struct *work);
 
-
 /* Information element helpers - find a home for these... */
 static inline u8 *orinoco_get_ie(u8 *data, size_t len,
 				 enum ieee80211_eid eid)
diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c
index 74892e1..4c20b1d 100644
--- a/drivers/net/wireless/orinoco/wext.c
+++ b/drivers/net/wireless/orinoco/wext.c
@@ -2163,49 +2163,16 @@ static int orinoco_ioctl_commit(struct net_device *dev,
 				char *extra)
 {
 	struct orinoco_private *priv = ndev_priv(dev);
-	struct hermes *hw = &priv->hw;
 	unsigned long flags;
 	int err = 0;
 
 	if (!priv->open)
 		return 0;
 
-	if (priv->broken_disableport) {
-		orinoco_reset(&priv->reset_work);
-		return 0;
-	}
-
 	if (orinoco_lock(priv, &flags) != 0)
 		return err;
 
-	err = hermes_disable_port(hw, 0);
-	if (err) {
-		printk(KERN_WARNING "%s: Unable to disable port "
-		       "while reconfiguring card\n", dev->name);
-		priv->broken_disableport = 1;
-		goto out;
-	}
-
-	err = __orinoco_program_rids(dev);
-	if (err) {
-		printk(KERN_WARNING "%s: Unable to reconfigure card\n",
-		       dev->name);
-		goto out;
-	}
-
-	err = hermes_enable_port(hw, 0);
-	if (err) {
-		printk(KERN_WARNING "%s: Unable to enable port while reconfiguring card\n",
-		       dev->name);
-		goto out;
-	}
-
- out:
-	if (err) {
-		printk(KERN_WARNING "%s: Resetting instead...\n", dev->name);
-		schedule_work(&priv->reset_work);
-		err = 0;
-	}
+	err = orinoco_commit(priv);
 
 	orinoco_unlock(priv, &flags);
 	return err;
-- 
1.6.0.6


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

* [PATCH 20/23] orinoco: convert mode setting to cfg80211
  2009-06-18 22:21 [PATCH 00/23] orinoco: initiate cfg80211 conversion David Kilroy
                   ` (18 preceding siblings ...)
  2009-06-18 22:21 ` [PATCH 19/23] orinoco: provide generic commit function David Kilroy
@ 2009-06-18 22:21 ` David Kilroy
  2009-06-18 22:21 ` [PATCH 21/23] orinoco: convert scanning " David Kilroy
                   ` (3 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: David Kilroy @ 2009-06-18 22:21 UTC (permalink / raw)
  To: linux-wireless; +Cc: orinoco-devel, David Kilroy

Signed-off-by: David Kilroy <kilroyd@googlemail.com>
---
 drivers/net/wireless/orinoco/cfg.c     |   46 +++++++++++++++++++-
 drivers/net/wireless/orinoco/hw.c      |   12 +++--
 drivers/net/wireless/orinoco/main.c    |   15 +++---
 drivers/net/wireless/orinoco/orinoco.h |    2 +-
 drivers/net/wireless/orinoco/wext.c    |   75 +++----------------------------
 5 files changed, 70 insertions(+), 80 deletions(-)

diff --git a/drivers/net/wireless/orinoco/cfg.c b/drivers/net/wireless/orinoco/cfg.c
index 9a616dd..9e59d90 100644
--- a/drivers/net/wireless/orinoco/cfg.c
+++ b/drivers/net/wireless/orinoco/cfg.c
@@ -93,6 +93,50 @@ int orinoco_wiphy_register(struct wiphy *wiphy)
 	return wiphy_register(wiphy);
 }
 
-const struct cfg80211_ops orinoco_cfg_ops = {
+static int orinoco_change_vif(struct wiphy *wiphy, struct net_device *dev,
+			      enum nl80211_iftype type, u32 *flags,
+			      struct vif_params *params)
+{
+	struct orinoco_private *priv = wiphy_priv(wiphy);
+	int err = 0;
+	unsigned long lock;
+
+	if (orinoco_lock(priv, &lock) != 0)
+		return -EBUSY;
+
+	switch (type) {
+	case NL80211_IFTYPE_ADHOC:
+		if (!priv->has_ibss && !priv->has_port3)
+			err = -EINVAL;
+		break;
+
+	case NL80211_IFTYPE_STATION:
+		break;
+
+	case NL80211_IFTYPE_MONITOR:
+		if (priv->broken_monitor && !force_monitor) {
+			printk(KERN_WARNING "%s: Monitor mode support is "
+			       "buggy in this firmware, not enabling\n",
+			       wiphy_name(wiphy));
+			err = -EINVAL;
+		}
+		break;
+
+	default:
+		err = -EINVAL;
+	}
 
+	if (!err) {
+		priv->iw_mode = type;
+		set_port_type(priv);
+		err = orinoco_commit(priv);
+	}
+
+	orinoco_unlock(priv, &lock);
+
+	return err;
+}
+
+const struct cfg80211_ops orinoco_cfg_ops = {
+	.change_virtual_intf = orinoco_change_vif,
 };
diff --git a/drivers/net/wireless/orinoco/hw.c b/drivers/net/wireless/orinoco/hw.c
index 56627d9..4600fe4 100644
--- a/drivers/net/wireless/orinoco/hw.c
+++ b/drivers/net/wireless/orinoco/hw.c
@@ -7,7 +7,7 @@
 #include <linux/if_arp.h>
 #include <linux/ieee80211.h>
 #include <linux/wireless.h>
-
+#include <net/cfg80211.h>
 #include "hermes.h"
 #include "hermes_rid.h"
 #include "orinoco.h"
@@ -409,6 +409,7 @@ void orinoco_get_ratemode_cfg(int ratemode, int *bitrate, int *automatic)
 int orinoco_hw_program_rids(struct orinoco_private *priv)
 {
 	struct net_device *dev = priv->ndev;
+	struct wireless_dev *wdev = netdev_priv(dev);
 	hermes_t *hw = &priv->hw;
 	int err;
 	struct hermes_idstring idbuf;
@@ -431,7 +432,7 @@ int orinoco_hw_program_rids(struct orinoco_private *priv)
 		return err;
 	}
 	/* Set the channel/frequency */
-	if (priv->channel != 0 && priv->iw_mode != IW_MODE_INFRA) {
+	if (priv->channel != 0 && priv->iw_mode != NL80211_IFTYPE_STATION) {
 		err = hermes_write_wordrec(hw, USER_BAP,
 					   HERMES_RID_CNFOWNCHANNEL,
 					   priv->channel);
@@ -612,7 +613,7 @@ int orinoco_hw_program_rids(struct orinoco_private *priv)
 		}
 	}
 
-	if (priv->iw_mode == IW_MODE_MONITOR) {
+	if (priv->iw_mode == NL80211_IFTYPE_MONITOR) {
 		/* Enable monitor mode */
 		dev->type = ARPHRD_IEEE80211;
 		err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
@@ -630,6 +631,9 @@ int orinoco_hw_program_rids(struct orinoco_private *priv)
 	priv->promiscuous = 0;
 	priv->mc_count = 0;
 
+	/* Record mode change */
+	wdev->iftype = priv->iw_mode;
+
 	return 0;
 }
 
@@ -884,7 +888,7 @@ int __orinoco_hw_setup_enc(struct orinoco_private *priv)
 		} else
 			master_wep_flag = 0;
 
-		if (priv->iw_mode == IW_MODE_MONITOR)
+		if (priv->iw_mode == NL80211_IFTYPE_MONITOR)
 			master_wep_flag |= HERMES_WEP_HOST_DECRYPT;
 
 		/* Master WEP setting : on/off */
diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c
index dab6649..ebf92ae 100644
--- a/drivers/net/wireless/orinoco/main.c
+++ b/drivers/net/wireless/orinoco/main.c
@@ -222,11 +222,11 @@ static int __orinoco_commit(struct orinoco_private *priv);
 void set_port_type(struct orinoco_private *priv)
 {
 	switch (priv->iw_mode) {
-	case IW_MODE_INFRA:
+	case NL80211_IFTYPE_STATION:
 		priv->port_type = 1;
 		priv->createibss = 0;
 		break;
-	case IW_MODE_ADHOC:
+	case NL80211_IFTYPE_ADHOC:
 		if (priv->prefer_port3) {
 			priv->port_type = 3;
 			priv->createibss = 0;
@@ -235,7 +235,7 @@ void set_port_type(struct orinoco_private *priv)
 			priv->createibss = 1;
 		}
 		break;
-	case IW_MODE_MONITOR:
+	case NL80211_IFTYPE_MONITOR:
 		priv->port_type = 3;
 		priv->createibss = 0;
 		break;
@@ -359,7 +359,8 @@ static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
 		return NETDEV_TX_BUSY;
 	}
 
-	if (!netif_carrier_ok(dev) || (priv->iw_mode == IW_MODE_MONITOR)) {
+	if (!netif_carrier_ok(dev) ||
+	    (priv->iw_mode == NL80211_IFTYPE_MONITOR)) {
 		/* Oops, the firmware hasn't established a connection,
 		   silently drop the packet (this seems to be the
 		   safest approach). */
@@ -820,7 +821,7 @@ static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw)
 	}
 
 	/* Handle frames in monitor mode */
-	if (priv->iw_mode == IW_MODE_MONITOR) {
+	if (priv->iw_mode == NL80211_IFTYPE_MONITOR) {
 		orinoco_rx_monitor(dev, rxfid, desc);
 		goto out;
 	}
@@ -1331,7 +1332,7 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
 		u16 newstatus;
 		int connected;
 
-		if (priv->iw_mode == IW_MODE_MONITOR)
+		if (priv->iw_mode == NL80211_IFTYPE_MONITOR)
 			break;
 
 		if (len != sizeof(linkstatus)) {
@@ -1981,7 +1982,7 @@ int orinoco_init(struct orinoco_private *priv)
 	}
 
 	/* Set up the default configuration */
-	priv->iw_mode = IW_MODE_INFRA;
+	priv->iw_mode = NL80211_IFTYPE_STATION;
 	/* By default use IEEE/IBSS ad-hoc mode if we have it */
 	priv->prefer_port3 = priv->has_port3 && (!priv->has_ibss);
 	set_port_type(priv);
diff --git a/drivers/net/wireless/orinoco/orinoco.h b/drivers/net/wireless/orinoco/orinoco.h
index 4ee85f8..0c89c28 100644
--- a/drivers/net/wireless/orinoco/orinoco.h
+++ b/drivers/net/wireless/orinoco/orinoco.h
@@ -121,7 +121,7 @@ struct orinoco_private {
 	unsigned int broken_monitor:1;
 
 	/* Configuration paramaters */
-	u32 iw_mode;
+	enum nl80211_iftype iw_mode;
 	int prefer_port3;
 	u16 encode_alg, wep_restrict, tx_key;
 	struct orinoco_key keys[ORINOCO_MAX_KEYS];
diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c
index 4c20b1d..9cd991a 100644
--- a/drivers/net/wireless/orinoco/wext.c
+++ b/drivers/net/wireless/orinoco/wext.c
@@ -52,7 +52,7 @@ static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev)
 	 * here so we're not safe to sleep here. */
 	hermes_inquire(hw, HERMES_INQ_TALLIES);
 
-	if (priv->iw_mode == IW_MODE_ADHOC) {
+	if (priv->iw_mode == NL80211_IFTYPE_ADHOC) {
 		memset(&wstats->qual, 0, sizeof(wstats->qual));
 		/* If a spy address is defined, we report stats of the
 		 * first spy address - Jean II */
@@ -124,7 +124,7 @@ static int orinoco_ioctl_setwap(struct net_device *dev,
 		goto out;
 	}
 
-	if (priv->iw_mode != IW_MODE_INFRA) {
+	if (priv->iw_mode != NL80211_IFTYPE_STATION) {
 		printk(KERN_WARNING "%s: Manual roaming supported only in "
 		       "managed mode\n", dev->name);
 		err = -EOPNOTSUPP;
@@ -172,65 +172,6 @@ static int orinoco_ioctl_getwap(struct net_device *dev,
 	return err;
 }
 
-static int orinoco_ioctl_setmode(struct net_device *dev,
-				 struct iw_request_info *info,
-				 u32 *mode,
-				 char *extra)
-{
-	struct orinoco_private *priv = ndev_priv(dev);
-	int err = -EINPROGRESS;		/* Call commit handler */
-	unsigned long flags;
-
-	if (priv->iw_mode == *mode)
-		return 0;
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-
-	switch (*mode) {
-	case IW_MODE_ADHOC:
-		if (!priv->has_ibss && !priv->has_port3)
-			err = -EOPNOTSUPP;
-		break;
-
-	case IW_MODE_INFRA:
-		break;
-
-	case IW_MODE_MONITOR:
-		if (priv->broken_monitor && !force_monitor) {
-			printk(KERN_WARNING "%s: Monitor mode support is "
-			       "buggy in this firmware, not enabling\n",
-			       dev->name);
-			err = -EOPNOTSUPP;
-		}
-		break;
-
-	default:
-		err = -EOPNOTSUPP;
-		break;
-	}
-
-	if (err == -EINPROGRESS) {
-		priv->iw_mode = *mode;
-		set_port_type(priv);
-	}
-
-	orinoco_unlock(priv, &flags);
-
-	return err;
-}
-
-static int orinoco_ioctl_getmode(struct net_device *dev,
-				 struct iw_request_info *info,
-				 u32 *mode,
-				 char *extra)
-{
-	struct orinoco_private *priv = ndev_priv(dev);
-
-	*mode = priv->iw_mode;
-	return 0;
-}
-
 static int orinoco_ioctl_getiwrange(struct net_device *dev,
 				    struct iw_request_info *info,
 				    struct iw_point *rrq,
@@ -280,7 +221,7 @@ static int orinoco_ioctl_getiwrange(struct net_device *dev,
 	if (priv->has_wpa)
 		range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_CIPHER_TKIP;
 
-	if ((priv->iw_mode == IW_MODE_ADHOC) && (!SPY_NUMBER(priv))) {
+	if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) && (!SPY_NUMBER(priv))) {
 		/* Quality stats meaningless in ad-hoc mode */
 	} else {
 		range->max_qual.qual = 0x8b - 0x2f;
@@ -596,7 +537,7 @@ static int orinoco_ioctl_setfreq(struct net_device *dev,
 	int err = -EINPROGRESS;		/* Call commit handler */
 
 	/* In infrastructure mode the AP sets the channel */
-	if (priv->iw_mode == IW_MODE_INFRA)
+	if (priv->iw_mode == NL80211_IFTYPE_STATION)
 		return -EBUSY;
 
 	if ((frq->e == 0) && (frq->m <= 1000)) {
@@ -622,7 +563,7 @@ static int orinoco_ioctl_setfreq(struct net_device *dev,
 		return -EBUSY;
 
 	priv->channel = chan;
-	if (priv->iw_mode == IW_MODE_MONITOR) {
+	if (priv->iw_mode == NL80211_IFTYPE_MONITOR) {
 		/* Fast channel change - no commit if successful */
 		hermes_t *hw = &priv->hw;
 		err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
@@ -1673,7 +1614,7 @@ static int orinoco_ioctl_setscan(struct net_device *dev,
 	/* In monitor mode, the scan results are always empty.
 	 * Probe responses are passed to the driver as received
 	 * frames and could be processed in software. */
-	if (priv->iw_mode == IW_MODE_MONITOR) {
+	if (priv->iw_mode == NL80211_IFTYPE_MONITOR) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
@@ -2209,8 +2150,8 @@ static const iw_handler	orinoco_handler[] = {
 	STD_IW_HANDLER(SIOCGIWNAME,	cfg80211_wext_giwname),
 	STD_IW_HANDLER(SIOCSIWFREQ,	orinoco_ioctl_setfreq),
 	STD_IW_HANDLER(SIOCGIWFREQ,	orinoco_ioctl_getfreq),
-	STD_IW_HANDLER(SIOCSIWMODE,	orinoco_ioctl_setmode),
-	STD_IW_HANDLER(SIOCGIWMODE,	orinoco_ioctl_getmode),
+	STD_IW_HANDLER(SIOCSIWMODE,	cfg80211_wext_siwmode),
+	STD_IW_HANDLER(SIOCGIWMODE,	cfg80211_wext_giwmode),
 	STD_IW_HANDLER(SIOCSIWSENS,	orinoco_ioctl_setsens),
 	STD_IW_HANDLER(SIOCGIWSENS,	orinoco_ioctl_getsens),
 	STD_IW_HANDLER(SIOCGIWRANGE,	orinoco_ioctl_getiwrange),
-- 
1.6.0.6


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

* [PATCH 21/23] orinoco: convert scanning to cfg80211
  2009-06-18 22:21 [PATCH 00/23] orinoco: initiate cfg80211 conversion David Kilroy
                   ` (19 preceding siblings ...)
  2009-06-18 22:21 ` [PATCH 20/23] orinoco: convert mode setting to cfg80211 David Kilroy
@ 2009-06-18 22:21 ` David Kilroy
  2009-06-19 17:35   ` John W. Linville
  2009-06-18 22:21 ` [PATCH 22/23] orinoco: convert giwrange " David Kilroy
                   ` (2 subsequent siblings)
  23 siblings, 1 reply; 32+ messages in thread
From: David Kilroy @ 2009-06-18 22:21 UTC (permalink / raw)
  To: linux-wireless; +Cc: orinoco-devel, David Kilroy

This removes the custom scan cache used by orinoco.

We also have to avoid calling cfg80211_scan_done from the hard
interrupt, so we offload the entirety of scan processing to a workqueue.

This may behave strangely if you start scanning just prior to
suspending...

Signed-off-by: David Kilroy <kilroyd@googlemail.com>
---
 drivers/net/wireless/orinoco/cfg.c     |   20 ++
 drivers/net/wireless/orinoco/hermes.h  |    2 +-
 drivers/net/wireless/orinoco/hw.c      |   85 ++++++
 drivers/net/wireless/orinoco/hw.h      |    3 +
 drivers/net/wireless/orinoco/main.c    |  167 +++++++----
 drivers/net/wireless/orinoco/orinoco.h |   22 +--
 drivers/net/wireless/orinoco/scan.c    |  285 +++++++++---------
 drivers/net/wireless/orinoco/scan.h    |   21 +-
 drivers/net/wireless/orinoco/wext.c    |  517 +-------------------------------
 9 files changed, 378 insertions(+), 744 deletions(-)

diff --git a/drivers/net/wireless/orinoco/cfg.c b/drivers/net/wireless/orinoco/cfg.c
index 9e59d90..1a87d3a 100644
--- a/drivers/net/wireless/orinoco/cfg.c
+++ b/drivers/net/wireless/orinoco/cfg.c
@@ -137,6 +137,26 @@ static int orinoco_change_vif(struct wiphy *wiphy, struct net_device *dev,
 	return err;
 }
 
+static int orinoco_scan(struct wiphy *wiphy, struct net_device *dev,
+			struct cfg80211_scan_request *request)
+{
+	struct orinoco_private *priv = wiphy_priv(wiphy);
+	int err;
+
+	if (!request)
+		return -EINVAL;
+
+	if (priv->scan_request && priv->scan_request != request)
+		return -EBUSY;
+
+	priv->scan_request = request;
+
+	err = orinoco_hw_trigger_scan(priv, request->ssids);
+
+	return err;
+}
+
 const struct cfg80211_ops orinoco_cfg_ops = {
 	.change_virtual_intf = orinoco_change_vif,
+	.scan = orinoco_scan,
 };
diff --git a/drivers/net/wireless/orinoco/hermes.h b/drivers/net/wireless/orinoco/hermes.h
index c78c442..2dddbb5 100644
--- a/drivers/net/wireless/orinoco/hermes.h
+++ b/drivers/net/wireless/orinoco/hermes.h
@@ -342,7 +342,7 @@ struct agere_ext_scan_info {
 	__le64	timestamp;
 	__le16	beacon_interval;
 	__le16	capabilities;
-	u8	data[316];
+	u8	data[0];
 } __attribute__ ((packed));
 
 #define HERMES_LINKSTATUS_NOT_CONNECTED   (0x0000)
diff --git a/drivers/net/wireless/orinoco/hw.c b/drivers/net/wireless/orinoco/hw.c
index 4600fe4..fa508af 100644
--- a/drivers/net/wireless/orinoco/hw.c
+++ b/drivers/net/wireless/orinoco/hw.c
@@ -1157,3 +1157,88 @@ int orinoco_hw_get_bitratelist(struct orinoco_private *priv,
 
 	return 0;
 }
+
+int orinoco_hw_trigger_scan(struct orinoco_private *priv,
+			    const struct cfg80211_ssid *ssid)
+{
+	struct net_device *dev = priv->ndev;
+	hermes_t *hw = &priv->hw;
+	unsigned long flags;
+	int err = 0;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
+
+	/* Scanning with port 0 disabled would fail */
+	if (!netif_running(dev)) {
+		err = -ENETDOWN;
+		goto out;
+	}
+
+	/* In monitor mode, the scan results are always empty.
+	 * Probe responses are passed to the driver as received
+	 * frames and could be processed in software. */
+	if (priv->iw_mode == NL80211_IFTYPE_MONITOR) {
+		err = -EOPNOTSUPP;
+		goto out;
+	}
+
+	if (priv->has_hostscan) {
+		switch (priv->firmware_type) {
+		case FIRMWARE_TYPE_SYMBOL:
+			err = hermes_write_wordrec(hw, USER_BAP,
+						HERMES_RID_CNFHOSTSCAN_SYMBOL,
+						HERMES_HOSTSCAN_SYMBOL_ONCE |
+						HERMES_HOSTSCAN_SYMBOL_BCAST);
+			break;
+		case FIRMWARE_TYPE_INTERSIL: {
+			__le16 req[3];
+
+			req[0] = cpu_to_le16(0x3fff);	/* All channels */
+			req[1] = cpu_to_le16(0x0001);	/* rate 1 Mbps */
+			req[2] = 0;			/* Any ESSID */
+			err = HERMES_WRITE_RECORD(hw, USER_BAP,
+						  HERMES_RID_CNFHOSTSCAN, &req);
+			break;
+		}
+		case FIRMWARE_TYPE_AGERE:
+			if (ssid->ssid_len > 0) {
+				struct hermes_idstring idbuf;
+				size_t len = ssid->ssid_len;
+
+				idbuf.len = cpu_to_le16(len);
+				memcpy(idbuf.val, ssid->ssid, len);
+
+				err = hermes_write_ltv(hw, USER_BAP,
+					       HERMES_RID_CNFSCANSSID_AGERE,
+					       HERMES_BYTES_TO_RECLEN(len + 2),
+					       &idbuf);
+			} else
+				err = hermes_write_wordrec(hw, USER_BAP,
+						   HERMES_RID_CNFSCANSSID_AGERE,
+						   0);	/* Any ESSID */
+			if (err)
+				break;
+
+			if (priv->has_ext_scan) {
+				err = hermes_write_wordrec(hw, USER_BAP,
+						HERMES_RID_CNFSCANCHANNELS2GHZ,
+						0x7FFF);
+				if (err)
+					goto out;
+
+				err = hermes_inquire(hw,
+						     HERMES_INQ_CHANNELINFO);
+			} else
+				err = hermes_inquire(hw, HERMES_INQ_SCAN);
+
+			break;
+		}
+	} else
+		err = hermes_inquire(hw, HERMES_INQ_SCAN);
+
+ out:
+	orinoco_unlock(priv, &flags);
+
+	return err;
+}
diff --git a/drivers/net/wireless/orinoco/hw.h b/drivers/net/wireless/orinoco/hw.h
index 210c2b1..27b4276 100644
--- a/drivers/net/wireless/orinoco/hw.h
+++ b/drivers/net/wireless/orinoco/hw.h
@@ -7,6 +7,7 @@
 
 #include <linux/types.h>
 #include <linux/wireless.h>
+#include <net/cfg80211.h>
 
 /* Hardware BAPs */
 #define USER_BAP 0
@@ -47,5 +48,7 @@ int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
 int orinoco_hw_get_freq(struct orinoco_private *priv);
 int orinoco_hw_get_bitratelist(struct orinoco_private *priv,
 			       int *numrates, s32 *rates, int max);
+int orinoco_hw_trigger_scan(struct orinoco_private *priv,
+			    const struct cfg80211_ssid *ssid);
 
 #endif /* _ORINOCO_HW_H_ */
diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c
index ebf92ae..90e2d32 100644
--- a/drivers/net/wireless/orinoco/main.c
+++ b/drivers/net/wireless/orinoco/main.c
@@ -206,6 +206,13 @@ struct orinoco_rx_data {
 	struct list_head list;
 };
 
+struct orinoco_scan_data {
+	void *buf;
+	size_t len;
+	int type;
+	struct list_head list;
+};
+
 /********************************************************************/
 /* Function prototypes                                              */
 /********************************************************************/
@@ -1265,6 +1272,78 @@ static void orinoco_send_wevents(struct work_struct *work)
 	orinoco_unlock(priv, &flags);
 }
 
+static void qbuf_scan(struct orinoco_private *priv, void *buf,
+		      int len, int type)
+{
+	struct orinoco_scan_data *sd;
+	unsigned long flags;
+
+	sd = kmalloc(sizeof(*sd), GFP_ATOMIC);
+	sd->buf = buf;
+	sd->len = len;
+	sd->type = type;
+
+	spin_lock_irqsave(priv->scan_lock, flags);
+	list_add_tail(&sd->list, &priv->scan_list);
+	spin_unlock_irqrestore(priv->scan_lock, flags);
+
+	schedule_work(&priv->process_scan);
+}
+
+static void qabort_scan(struct orinoco_private *priv)
+{
+	struct orinoco_scan_data *sd;
+	unsigned long flags;
+
+	sd = kmalloc(sizeof(*sd), GFP_ATOMIC);
+	sd->len = -1; /* Abort */
+
+	spin_lock_irqsave(priv->scan_lock, flags);
+	list_add_tail(&sd->list, &priv->scan_list);
+	spin_unlock_irqrestore(priv->scan_lock, flags);
+
+	schedule_work(&priv->process_scan);
+}
+
+static void orinoco_process_scan_results(struct work_struct *work)
+{
+	struct orinoco_private *priv =
+		container_of(work, struct orinoco_private, process_scan);
+	struct orinoco_scan_data *sd, *temp;
+	unsigned long flags;
+	void *buf;
+	int len;
+	int type;
+
+	spin_lock_irqsave(priv->scan_lock, flags);
+	list_for_each_entry_safe(sd, temp, &priv->scan_list, list) {
+		spin_unlock_irqrestore(priv->scan_lock, flags);
+
+		buf = sd->buf;
+		len = sd->len;
+		type = sd->type;
+
+		list_del(&sd->list);
+		kfree(sd);
+
+		if (len > 0) {
+			if (type == HERMES_INQ_CHANNELINFO)
+				orinoco_add_extscan_result(priv, buf, len);
+			else
+				orinoco_add_hostscan_results(priv, buf, len);
+
+			kfree(buf);
+		} else if (priv->scan_request) {
+			/* Either abort or complete the scan */
+			cfg80211_scan_done(priv->scan_request, (len < 0));
+			priv->scan_request = NULL;
+		}
+
+		spin_lock_irqsave(priv->scan_lock, flags);
+	}
+	spin_unlock_irqrestore(priv->scan_lock, flags);
+}
+
 static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
 {
 	struct orinoco_private *priv = ndev_priv(dev);
@@ -1351,7 +1430,7 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
 		 * the hostscan frame can be requested.  */
 		if (newstatus == HERMES_LINKSTATUS_AP_OUT_OF_RANGE &&
 		    priv->firmware_type == FIRMWARE_TYPE_SYMBOL &&
-		    priv->has_hostscan && priv->scan_inprogress) {
+		    priv->has_hostscan && priv->scan_request) {
 			hermes_inquire(hw, HERMES_INQ_HOSTSCAN_SYMBOL);
 			break;
 		}
@@ -1377,7 +1456,7 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
 	}
 	break;
 	case HERMES_INQ_SCAN:
-		if (!priv->scan_inprogress && priv->bssid_fixed &&
+		if (!priv->scan_request && priv->bssid_fixed &&
 		    priv->firmware_type == FIRMWARE_TYPE_INTERSIL) {
 			schedule_work(&priv->join_work);
 			break;
@@ -1387,30 +1466,30 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
 	case HERMES_INQ_HOSTSCAN_SYMBOL: {
 		/* Result of a scanning. Contains information about
 		 * cells in the vicinity - Jean II */
-		union iwreq_data	wrqu;
 		unsigned char *buf;
 
-		/* Scan is no longer in progress */
-		priv->scan_inprogress = 0;
-
 		/* Sanity check */
 		if (len > 4096) {
 			printk(KERN_WARNING "%s: Scan results too large (%d bytes)\n",
 			       dev->name, len);
+			qabort_scan(priv);
 			break;
 		}
 
 		/* Allocate buffer for results */
 		buf = kmalloc(len, GFP_ATOMIC);
-		if (buf == NULL)
+		if (buf == NULL) {
 			/* No memory, so can't printk()... */
+			qabort_scan(priv);
 			break;
+		}
 
 		/* Read scan data */
 		err = hermes_bap_pread(hw, IRQ_BAP, (void *) buf, len,
 				       infofid, sizeof(info));
 		if (err) {
 			kfree(buf);
+			qabort_scan(priv);
 			break;
 		}
 
@@ -1424,24 +1503,14 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
 		}
 #endif	/* ORINOCO_DEBUG */
 
-		if (orinoco_process_scan_results(priv, buf, len) == 0) {
-			/* Send an empty event to user space.
-			 * We don't send the received data on the event because
-			 * it would require us to do complex transcoding, and
-			 * we want to minimise the work done in the irq handler
-			 * Use a request to extract the data - Jean II */
-			wrqu.data.length = 0;
-			wrqu.data.flags = 0;
-			wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
-		}
-		kfree(buf);
+		qbuf_scan(priv, buf, len, type);
 	}
 	break;
 	case HERMES_INQ_CHANNELINFO:
 	{
 		struct agere_ext_scan_info *bss;
 
-		if (!priv->scan_inprogress) {
+		if (!priv->scan_request) {
 			printk(KERN_DEBUG "%s: Got chaninfo without scan, "
 			       "len=%d\n", dev->name, len);
 			break;
@@ -1449,25 +1518,12 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
 
 		/* An empty result indicates that the scan is complete */
 		if (len == 0) {
-			union iwreq_data	wrqu;
-
-			/* Scan is no longer in progress */
-			priv->scan_inprogress = 0;
-
-			wrqu.data.length = 0;
-			wrqu.data.flags = 0;
-			wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
+			qbuf_scan(priv, NULL, len, type);
 			break;
 		}
 
 		/* Sanity check */
-		else if (len > sizeof(*bss)) {
-			printk(KERN_WARNING
-			       "%s: Ext scan results too large (%d bytes). "
-			       "Truncating results to %zd bytes.\n",
-			       dev->name, len, sizeof(*bss));
-			len = sizeof(*bss);
-		} else if (len < (offsetof(struct agere_ext_scan_info,
+		else if (len < (offsetof(struct agere_ext_scan_info,
 					   data) + 2)) {
 			/* Drop this result now so we don't have to
 			 * keep checking later */
@@ -1477,21 +1533,18 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
 			break;
 		}
 
-		bss = kmalloc(sizeof(*bss), GFP_ATOMIC);
+		bss = kmalloc(len, GFP_ATOMIC);
 		if (bss == NULL)
 			break;
 
 		/* Read scan data */
 		err = hermes_bap_pread(hw, IRQ_BAP, (void *) bss, len,
 				       infofid, sizeof(info));
-		if (err) {
+		if (err)
 			kfree(bss);
-			break;
-		}
-
-		orinoco_add_ext_scan_result(priv, bss);
+		else
+			qbuf_scan(priv, bss, len, type);
 
-		kfree(bss);
 		break;
 	}
 	case HERMES_INQ_SEC_STAT_AGERE:
@@ -1506,6 +1559,8 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
 		/* We don't actually do anything about it */
 		break;
 	}
+
+	return;
 }
 
 static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw)
@@ -1649,9 +1704,11 @@ void orinoco_reset(struct work_struct *work)
 
 	orinoco_unlock(priv, &flags);
 
-	/* Scanning support: Cleanup of driver struct */
-	orinoco_clear_scan_results(priv, 0);
-	priv->scan_inprogress = 0;
+	/* Scanning support: Notify scan cancellation */
+	if (priv->scan_request) {
+		cfg80211_scan_done(priv->scan_request, 1);
+		priv->scan_request = NULL;
+	}
 
 	if (priv->hard_reset) {
 		err = (*priv->hard_reset)(priv);
@@ -1965,12 +2022,6 @@ int orinoco_init(struct orinoco_private *priv)
 		}
 	}
 
-	/* Now we have the firmware capabilities, allocate appropiate
-	 * sized scan buffers */
-	if (orinoco_bss_data_allocate(priv))
-		goto out;
-	orinoco_bss_data_init(priv);
-
 	err = orinoco_hw_read_card_settings(priv, wiphy->perm_addr);
 	if (err)
 		goto out;
@@ -2100,6 +2151,10 @@ struct orinoco_private
 	tasklet_init(&priv->rx_tasklet, orinoco_rx_isr_tasklet,
 		     (unsigned long) priv);
 
+	spin_lock_init(&priv->scan_lock);
+	INIT_LIST_HEAD(&priv->scan_list);
+	INIT_WORK(&priv->process_scan, orinoco_process_scan_results);
+
 	priv->last_linkstatus = 0xffff;
 
 #if defined(CONFIG_HERMES_CACHE_FW_ON_INIT) || defined(CONFIG_PM_SLEEP)
@@ -2192,6 +2247,7 @@ void free_orinocodev(struct orinoco_private *priv)
 {
 	struct wiphy *wiphy = priv_to_wiphy(priv);
 	struct orinoco_rx_data *rx_data, *temp;
+	struct orinoco_scan_data *sd, *sdtemp;
 
 	wiphy_unregister(wiphy);
 
@@ -2209,13 +2265,22 @@ void free_orinocodev(struct orinoco_private *priv)
 		kfree(rx_data);
 	}
 
+	cancel_work_sync(&priv->process_scan);
+	/* Explicitly drain priv->scan_list */
+	list_for_each_entry_safe(sd, sdtemp, &priv->scan_list, list) {
+		list_del(&sd->list);
+
+		if ((sd->len > 0) && sd->buf)
+			kfree(sd->buf);
+		kfree(sd);
+	}
+
 	orinoco_unregister_pm_notifier(priv);
 	orinoco_uncache_fw(priv);
 
 	priv->wpa_ie_len = 0;
 	kfree(priv->wpa_ie);
 	orinoco_mic_free(priv);
-	orinoco_bss_data_free(priv);
 	wiphy_free(wiphy);
 }
 EXPORT_SYMBOL(free_orinocodev);
diff --git a/drivers/net/wireless/orinoco/orinoco.h b/drivers/net/wireless/orinoco/orinoco.h
index 0c89c28..5f4f5c9 100644
--- a/drivers/net/wireless/orinoco/orinoco.h
+++ b/drivers/net/wireless/orinoco/orinoco.h
@@ -48,18 +48,6 @@ typedef enum {
 	FIRMWARE_TYPE_SYMBOL
 } fwtype_t;
 
-struct bss_element {
-	union hermes_scan_info bss;
-	unsigned long last_scanned;
-	struct list_head list;
-};
-
-struct xbss_element {
-	struct agere_ext_scan_info bss;
-	unsigned long last_scanned;
-	struct list_head list;
-};
-
 struct firmware;
 
 struct orinoco_private {
@@ -145,12 +133,10 @@ struct orinoco_private {
 	int promiscuous, mc_count;
 
 	/* Scanning support */
-	struct list_head bss_list;
-	struct list_head bss_free_list;
-	void *bss_xbss_data;
-
-	int	scan_inprogress;	/* Scan pending... */
-	u32	scan_mode;		/* Type of scan done */
+	struct cfg80211_scan_request *scan_request;
+	struct work_struct process_scan;
+	struct list_head scan_list;
+	spinlock_t scan_lock; /* protects the scan list */
 
 	/* WPA support */
 	u8 *wpa_ie;
diff --git a/drivers/net/wireless/orinoco/scan.c b/drivers/net/wireless/orinoco/scan.c
index 89d699d..522eb98 100644
--- a/drivers/net/wireless/orinoco/scan.c
+++ b/drivers/net/wireless/orinoco/scan.c
@@ -5,147 +5,166 @@
 
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/etherdevice.h>
+#include <linux/ieee80211.h>
+#include <net/cfg80211.h>
 
 #include "hermes.h"
 #include "orinoco.h"
+#include "main.h"
 
 #include "scan.h"
 
-#define ORINOCO_MAX_BSS_COUNT	64
+#define ZERO_DBM_OFFSET 0x95
+#define MAX_SIGNAL_LEVEL 0x8A
+#define MIN_SIGNAL_LEVEL 0x2F
 
-#define PRIV_BSS	((struct bss_element *)priv->bss_xbss_data)
-#define PRIV_XBSS	((struct xbss_element *)priv->bss_xbss_data)
+#define SIGNAL_TO_DBM(x)					\
+	(clamp_t(s32, (x), MIN_SIGNAL_LEVEL, MAX_SIGNAL_LEVEL)	\
+	 - ZERO_DBM_OFFSET)
+#define SIGNAL_TO_MBM(x) (SIGNAL_TO_DBM(x) * 100)
 
-int orinoco_bss_data_allocate(struct orinoco_private *priv)
+static int symbol_build_supp_rates(u8 *buf, const __le16 *rates)
 {
-	if (priv->bss_xbss_data)
-		return 0;
-
-	if (priv->has_ext_scan)
-		priv->bss_xbss_data = kzalloc(ORINOCO_MAX_BSS_COUNT *
-					      sizeof(struct xbss_element),
-					      GFP_KERNEL);
-	else
-		priv->bss_xbss_data = kzalloc(ORINOCO_MAX_BSS_COUNT *
-					      sizeof(struct bss_element),
-					      GFP_KERNEL);
-
-	if (!priv->bss_xbss_data) {
-		printk(KERN_WARNING "Out of memory allocating beacons");
-		return -ENOMEM;
+	int i;
+	u8 rate;
+
+	buf[0] = WLAN_EID_SUPP_RATES;
+	for (i = 0; i < 5; i++) {
+		rate = le16_to_cpu(rates[i]);
+		/* NULL terminated */
+		if (rate == 0x0)
+			break;
+		buf[i + 2] = rate;
 	}
-	return 0;
-}
+	buf[1] = i;
 
-void orinoco_bss_data_free(struct orinoco_private *priv)
-{
-	kfree(priv->bss_xbss_data);
-	priv->bss_xbss_data = NULL;
+	return i + 2;
 }
 
-void orinoco_bss_data_init(struct orinoco_private *priv)
+static int prism_build_supp_rates(u8 *buf, const u8 *rates)
 {
 	int i;
 
-	INIT_LIST_HEAD(&priv->bss_free_list);
-	INIT_LIST_HEAD(&priv->bss_list);
-	if (priv->has_ext_scan)
-		for (i = 0; i < ORINOCO_MAX_BSS_COUNT; i++)
-			list_add_tail(&(PRIV_XBSS[i].list),
-				      &priv->bss_free_list);
-	else
-		for (i = 0; i < ORINOCO_MAX_BSS_COUNT; i++)
-			list_add_tail(&(PRIV_BSS[i].list),
-				      &priv->bss_free_list);
-
-}
-
-void orinoco_clear_scan_results(struct orinoco_private *priv,
-				unsigned long scan_age)
-{
-	if (priv->has_ext_scan) {
-		struct xbss_element *bss;
-		struct xbss_element *tmp_bss;
-
-		/* Blow away current list of scan results */
-		list_for_each_entry_safe(bss, tmp_bss, &priv->bss_list, list) {
-			if (!scan_age ||
-			    time_after(jiffies, bss->last_scanned + scan_age)) {
-				list_move_tail(&bss->list,
-					       &priv->bss_free_list);
-				/* Don't blow away ->list, just BSS data */
-				memset(&bss->bss, 0, sizeof(bss->bss));
-				bss->last_scanned = 0;
-			}
-		}
-	} else {
-		struct bss_element *bss;
-		struct bss_element *tmp_bss;
-
-		/* Blow away current list of scan results */
-		list_for_each_entry_safe(bss, tmp_bss, &priv->bss_list, list) {
-			if (!scan_age ||
-			    time_after(jiffies, bss->last_scanned + scan_age)) {
-				list_move_tail(&bss->list,
-					       &priv->bss_free_list);
-				/* Don't blow away ->list, just BSS data */
-				memset(&bss->bss, 0, sizeof(bss->bss));
-				bss->last_scanned = 0;
-			}
+	buf[0] = WLAN_EID_SUPP_RATES;
+	for (i = 0; i < 8; i++) {
+		/* NULL terminated */
+		if (rates[i] == 0x0)
+			break;
+		buf[i + 2] = rates[i];
+	}
+	buf[1] = i;
+
+	/* We might still have another 2 rates, which need to go in
+	 * extended supported rates */
+	if (i == 8 && rates[i] > 0) {
+		buf[10] = WLAN_EID_EXT_SUPP_RATES;
+		for (; i < 10; i++) {
+			/* NULL terminated */
+			if (rates[i] == 0x0)
+				break;
+			buf[i + 2] = rates[i];
 		}
+		buf[11] = i - 8;
 	}
+
+	return (i < 8) ? i + 2 : i + 4;
 }
 
-void orinoco_add_ext_scan_result(struct orinoco_private *priv,
-				 struct agere_ext_scan_info *atom)
+static void orinoco_add_hostscan_result(struct orinoco_private *priv,
+					const union hermes_scan_info *bss)
 {
-	struct xbss_element *bss = NULL;
-	int found = 0;
-
-	/* Try to update an existing bss first */
-	list_for_each_entry(bss, &priv->bss_list, list) {
-		if (compare_ether_addr(bss->bss.bssid, atom->bssid))
-			continue;
-		/* ESSID lengths */
-		if (bss->bss.data[1] != atom->data[1])
-			continue;
-		if (memcmp(&bss->bss.data[2], &atom->data[2],
-			   atom->data[1]))
-			continue;
-		found = 1;
+	struct wiphy *wiphy = priv_to_wiphy(priv);
+	struct ieee80211_channel *channel;
+	u8 *ie;
+	u8 ie_buf[46];
+	u64 timestamp;
+	s32 signal;
+	u16 capability;
+	u16 beacon_interval;
+	int ie_len;
+	int freq;
+	int len;
+
+	len = le16_to_cpu(bss->a.essid_len);
+
+	/* Reconstruct SSID and bitrate IEs to pass up */
+	ie_buf[0] = WLAN_EID_SSID;
+	ie_buf[1] = len;
+	memcpy(&ie_buf[2], bss->a.essid, len);
+
+	ie = ie_buf + len + 2;
+	ie_len = ie_buf[1] + 2;
+	switch (priv->firmware_type) {
+	case FIRMWARE_TYPE_SYMBOL:
+		ie_len += symbol_build_supp_rates(ie, bss->s.rates);
 		break;
-	}
 
-	/* Grab a bss off the free list */
-	if (!found && !list_empty(&priv->bss_free_list)) {
-		bss = list_entry(priv->bss_free_list.next,
-				 struct xbss_element, list);
-		list_del(priv->bss_free_list.next);
+	case FIRMWARE_TYPE_INTERSIL:
+		ie_len += prism_build_supp_rates(ie, bss->p.rates);
+		break;
 
-		list_add_tail(&bss->list, &priv->bss_list);
+	case FIRMWARE_TYPE_AGERE:
+	default:
+		break;
 	}
 
-	if (bss) {
-		/* Always update the BSS to get latest beacon info */
-		memcpy(&bss->bss, atom, sizeof(bss->bss));
-		bss->last_scanned = jiffies;
-	}
+	freq = ieee80211_dsss_chan_to_freq(le16_to_cpu(bss->a.channel));
+	channel = ieee80211_get_channel(wiphy, freq);
+	timestamp = 0;
+	capability = le16_to_cpu(bss->a.capabilities);
+	beacon_interval = le16_to_cpu(bss->a.beacon_interv);
+	signal = SIGNAL_TO_MBM(le16_to_cpu(bss->a.level));
+
+	cfg80211_inform_bss(wiphy, channel, bss->a.bssid, timestamp,
+			    capability, beacon_interval, ie_buf, ie_len,
+			    signal, GFP_KERNEL);
 }
 
-int orinoco_process_scan_results(struct orinoco_private *priv,
-				 unsigned char *buf,
-				 int len)
+void orinoco_add_extscan_result(struct orinoco_private *priv,
+				struct agere_ext_scan_info *bss,
+				size_t len)
 {
-	int			offset;		/* In the scan data */
-	union hermes_scan_info *atom;
-	int			atom_len;
+	struct wiphy *wiphy = priv_to_wiphy(priv);
+	struct ieee80211_channel *channel;
+	u8 *ie;
+	u64 timestamp;
+	s32 signal;
+	u16 capability;
+	u16 beacon_interval;
+	size_t ie_len;
+	int chan, freq;
+
+	ie_len = len - sizeof(*bss);
+	ie = orinoco_get_ie(bss->data, ie_len, WLAN_EID_DS_PARAMS);
+	chan = ie ? ie[2] : 0;
+	freq = ieee80211_dsss_chan_to_freq(chan);
+	channel = ieee80211_get_channel(wiphy, freq);
+
+	timestamp = le64_to_cpu(bss->timestamp);
+	capability = le16_to_cpu(bss->capabilities);
+	beacon_interval = le16_to_cpu(bss->beacon_interval);
+	ie = bss->data;
+	signal = SIGNAL_TO_MBM(bss->level);
+
+	cfg80211_inform_bss(wiphy, channel, bss->bssid, timestamp,
+			    capability, beacon_interval, ie, ie_len,
+			    signal, GFP_KERNEL);
+}
+
+void orinoco_add_hostscan_results(struct orinoco_private *priv,
+				  unsigned char *buf,
+				  size_t len)
+{
+	int offset;		/* In the scan data */
+	size_t atom_len;
+	bool abort = false;
 
 	switch (priv->firmware_type) {
 	case FIRMWARE_TYPE_AGERE:
 		atom_len = sizeof(struct agere_scan_apinfo);
 		offset = 0;
 		break;
+
 	case FIRMWARE_TYPE_SYMBOL:
 		/* Lack of documentation necessitates this hack.
 		 * Different firmwares have 68 or 76 byte long atoms.
@@ -163,6 +182,7 @@ int orinoco_process_scan_results(struct orinoco_private *priv,
 			atom_len = 68;
 		offset = 0;
 		break;
+
 	case FIRMWARE_TYPE_INTERSIL:
 		offset = 4;
 		if (priv->has_hostscan) {
@@ -172,13 +192,16 @@ int orinoco_process_scan_results(struct orinoco_private *priv,
 				printk(KERN_ERR "%s: Invalid atom_len in scan "
 				       "data: %d\n", priv->ndev->name,
 				       atom_len);
-				return -EIO;
+				abort = true;
+				goto scan_abort;
 			}
 		} else
 			atom_len = offsetof(struct prism2_scan_apinfo, atim);
 		break;
+
 	default:
-		return -EOPNOTSUPP;
+		abort = true;
+		goto scan_abort;
 	}
 
 	/* Check that we got an whole number of atoms */
@@ -186,48 +209,22 @@ int orinoco_process_scan_results(struct orinoco_private *priv,
 		printk(KERN_ERR "%s: Unexpected scan data length %d, "
 		       "atom_len %d, offset %d\n", priv->ndev->name, len,
 		       atom_len, offset);
-		return -EIO;
+		abort = true;
+		goto scan_abort;
 	}
 
-	orinoco_clear_scan_results(priv, msecs_to_jiffies(15000));
-
-	/* Read the entries one by one */
+	/* Process the entries one by one */
 	for (; offset + atom_len <= len; offset += atom_len) {
-		int found = 0;
-		struct bss_element *bss = NULL;
+		union hermes_scan_info *atom;
 
-		/* Get next atom */
 		atom = (union hermes_scan_info *) (buf + offset);
 
-		/* Try to update an existing bss first */
-		list_for_each_entry(bss, &priv->bss_list, list) {
-			if (compare_ether_addr(bss->bss.a.bssid, atom->a.bssid))
-				continue;
-			if (le16_to_cpu(bss->bss.a.essid_len) !=
-			      le16_to_cpu(atom->a.essid_len))
-				continue;
-			if (memcmp(bss->bss.a.essid, atom->a.essid,
-			      le16_to_cpu(atom->a.essid_len)))
-				continue;
-			found = 1;
-			break;
-		}
-
-		/* Grab a bss off the free list */
-		if (!found && !list_empty(&priv->bss_free_list)) {
-			bss = list_entry(priv->bss_free_list.next,
-					 struct bss_element, list);
-			list_del(priv->bss_free_list.next);
-
-			list_add_tail(&bss->list, &priv->bss_list);
-		}
-
-		if (bss) {
-			/* Always update the BSS to get latest beacon info */
-			memcpy(&bss->bss, atom, sizeof(bss->bss));
-			bss->last_scanned = jiffies;
-		}
+		orinoco_add_hostscan_result(priv, atom);
 	}
 
-	return 0;
+ scan_abort:
+	if (priv->scan_request) {
+		cfg80211_scan_done(priv->scan_request, abort);
+		priv->scan_request = NULL;
+	}
 }
diff --git a/drivers/net/wireless/orinoco/scan.h b/drivers/net/wireless/orinoco/scan.h
index f319f74..2dc4e04 100644
--- a/drivers/net/wireless/orinoco/scan.h
+++ b/drivers/net/wireless/orinoco/scan.h
@@ -9,21 +9,12 @@
 struct orinoco_private;
 struct agere_ext_scan_info;
 
-/* Setup and free memory for scan results */
-int orinoco_bss_data_allocate(struct orinoco_private *priv);
-void orinoco_bss_data_free(struct orinoco_private *priv);
-void orinoco_bss_data_init(struct orinoco_private *priv);
-
 /* Add scan results */
-void orinoco_add_ext_scan_result(struct orinoco_private *priv,
-				 struct agere_ext_scan_info *atom);
-int orinoco_process_scan_results(struct orinoco_private *dev,
-				 unsigned char *buf,
-				 int len);
-
-/* Clear scan results */
-void orinoco_clear_scan_results(struct orinoco_private *priv,
-				unsigned long scan_age);
-
+void orinoco_add_extscan_result(struct orinoco_private *priv,
+				struct agere_ext_scan_info *atom,
+				size_t len);
+void orinoco_add_hostscan_results(struct orinoco_private *dev,
+				  unsigned char *buf,
+				  size_t len);
 
 #endif /* _ORINOCO_SCAN_H_ */
diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c
index 9cd991a..082ea0a 100644
--- a/drivers/net/wireless/orinoco/wext.c
+++ b/drivers/net/wireless/orinoco/wext.c
@@ -1583,519 +1583,6 @@ static int orinoco_ioctl_getrid(struct net_device *dev,
 	return err;
 }
 
-/* Trigger a scan (look for other cells in the vicinity) */
-static int orinoco_ioctl_setscan(struct net_device *dev,
-				 struct iw_request_info *info,
-				 struct iw_point *srq,
-				 char *extra)
-{
-	struct orinoco_private *priv = ndev_priv(dev);
-	hermes_t *hw = &priv->hw;
-	struct iw_scan_req *si = (struct iw_scan_req *) extra;
-	int err = 0;
-	unsigned long flags;
-
-	/* Note : you may have realised that, as this is a SET operation,
-	 * this is privileged and therefore a normal user can't
-	 * perform scanning.
-	 * This is not an error, while the device perform scanning,
-	 * traffic doesn't flow, so it's a perfect DoS...
-	 * Jean II */
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-
-	/* Scanning with port 0 disabled would fail */
-	if (!netif_running(dev)) {
-		err = -ENETDOWN;
-		goto out;
-	}
-
-	/* In monitor mode, the scan results are always empty.
-	 * Probe responses are passed to the driver as received
-	 * frames and could be processed in software. */
-	if (priv->iw_mode == NL80211_IFTYPE_MONITOR) {
-		err = -EOPNOTSUPP;
-		goto out;
-	}
-
-	/* Note : because we don't lock out the irq handler, the way
-	 * we access scan variables in priv is critical.
-	 *	o scan_inprogress : not touched by irq handler
-	 *	o scan_mode : not touched by irq handler
-	 * Before modifying anything on those variables, please think hard !
-	 * Jean II */
-
-	/* Save flags */
-	priv->scan_mode = srq->flags;
-
-	/* Always trigger scanning, even if it's in progress.
-	 * This way, if the info frame get lost, we will recover somewhat
-	 * gracefully  - Jean II */
-
-	if (priv->has_hostscan) {
-		switch (priv->firmware_type) {
-		case FIRMWARE_TYPE_SYMBOL:
-			err = hermes_write_wordrec(hw, USER_BAP,
-						HERMES_RID_CNFHOSTSCAN_SYMBOL,
-						HERMES_HOSTSCAN_SYMBOL_ONCE |
-						HERMES_HOSTSCAN_SYMBOL_BCAST);
-			break;
-		case FIRMWARE_TYPE_INTERSIL: {
-			__le16 req[3];
-
-			req[0] = cpu_to_le16(0x3fff);	/* All channels */
-			req[1] = cpu_to_le16(0x0001);	/* rate 1 Mbps */
-			req[2] = 0;			/* Any ESSID */
-			err = HERMES_WRITE_RECORD(hw, USER_BAP,
-						  HERMES_RID_CNFHOSTSCAN, &req);
-		}
-		break;
-		case FIRMWARE_TYPE_AGERE:
-			if (priv->scan_mode & IW_SCAN_THIS_ESSID) {
-				struct hermes_idstring idbuf;
-				size_t len = min(sizeof(idbuf.val),
-						 (size_t) si->essid_len);
-				idbuf.len = cpu_to_le16(len);
-				memcpy(idbuf.val, si->essid, len);
-
-				err = hermes_write_ltv(hw, USER_BAP,
-					       HERMES_RID_CNFSCANSSID_AGERE,
-					       HERMES_BYTES_TO_RECLEN(len + 2),
-					       &idbuf);
-			} else
-				err = hermes_write_wordrec(hw, USER_BAP,
-						   HERMES_RID_CNFSCANSSID_AGERE,
-						   0);	/* Any ESSID */
-			if (err)
-				break;
-
-			if (priv->has_ext_scan) {
-				/* Clear scan results at the start of
-				 * an extended scan */
-				orinoco_clear_scan_results(priv,
-						msecs_to_jiffies(15000));
-
-				/* TODO: Is this available on older firmware?
-				 *   Can we use it to scan specific channels
-				 *   for IW_SCAN_THIS_FREQ? */
-				err = hermes_write_wordrec(hw, USER_BAP,
-						HERMES_RID_CNFSCANCHANNELS2GHZ,
-						0x7FFF);
-				if (err)
-					goto out;
-
-				err = hermes_inquire(hw,
-						     HERMES_INQ_CHANNELINFO);
-			} else
-				err = hermes_inquire(hw, HERMES_INQ_SCAN);
-			break;
-		}
-	} else
-		err = hermes_inquire(hw, HERMES_INQ_SCAN);
-
-	/* One more client */
-	if (!err)
-		priv->scan_inprogress = 1;
-
- out:
-	orinoco_unlock(priv, &flags);
-	return err;
-}
-
-#define MAX_CUSTOM_LEN 64
-
-/* Translate scan data returned from the card to a card independant
- * format that the Wireless Tools will understand - Jean II */
-static inline char *orinoco_translate_scan(struct net_device *dev,
-					   struct iw_request_info *info,
-					   char *current_ev,
-					   char *end_buf,
-					   union hermes_scan_info *bss,
-					   unsigned long last_scanned)
-{
-	struct orinoco_private *priv = ndev_priv(dev);
-	u16			capabilities;
-	u16			channel;
-	struct iw_event		iwe;		/* Temporary buffer */
-	char custom[MAX_CUSTOM_LEN];
-
-	memset(&iwe, 0, sizeof(iwe));
-
-	/* First entry *MUST* be the AP MAC address */
-	iwe.cmd = SIOCGIWAP;
-	iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
-	memcpy(iwe.u.ap_addr.sa_data, bss->a.bssid, ETH_ALEN);
-	current_ev = iwe_stream_add_event(info, current_ev, end_buf,
-					  &iwe, IW_EV_ADDR_LEN);
-
-	/* Other entries will be displayed in the order we give them */
-
-	/* Add the ESSID */
-	iwe.u.data.length = le16_to_cpu(bss->a.essid_len);
-	if (iwe.u.data.length > 32)
-		iwe.u.data.length = 32;
-	iwe.cmd = SIOCGIWESSID;
-	iwe.u.data.flags = 1;
-	current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-					  &iwe, bss->a.essid);
-
-	/* Add mode */
-	iwe.cmd = SIOCGIWMODE;
-	capabilities = le16_to_cpu(bss->a.capabilities);
-	if (capabilities & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
-		if (capabilities & WLAN_CAPABILITY_ESS)
-			iwe.u.mode = IW_MODE_MASTER;
-		else
-			iwe.u.mode = IW_MODE_ADHOC;
-		current_ev = iwe_stream_add_event(info, current_ev, end_buf,
-						  &iwe, IW_EV_UINT_LEN);
-	}
-
-	channel = bss->s.channel;
-	if ((channel >= 1) && (channel <= NUM_CHANNELS)) {
-		/* Add channel and frequency */
-		iwe.cmd = SIOCGIWFREQ;
-		iwe.u.freq.m = channel;
-		iwe.u.freq.e = 0;
-		current_ev = iwe_stream_add_event(info, current_ev, end_buf,
-						  &iwe, IW_EV_FREQ_LEN);
-
-		iwe.u.freq.m = ieee80211_dsss_chan_to_freq(channel) * 100000;
-		iwe.u.freq.e = 1;
-		current_ev = iwe_stream_add_event(info, current_ev, end_buf,
-						  &iwe, IW_EV_FREQ_LEN);
-	}
-
-	/* Add quality statistics. level and noise in dB. No link quality */
-	iwe.cmd = IWEVQUAL;
-	iwe.u.qual.updated = IW_QUAL_DBM | IW_QUAL_QUAL_INVALID;
-	iwe.u.qual.level = (__u8) le16_to_cpu(bss->a.level) - 0x95;
-	iwe.u.qual.noise = (__u8) le16_to_cpu(bss->a.noise) - 0x95;
-	/* Wireless tools prior to 27.pre22 will show link quality
-	 * anyway, so we provide a reasonable value. */
-	if (iwe.u.qual.level > iwe.u.qual.noise)
-		iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise;
-	else
-		iwe.u.qual.qual = 0;
-	current_ev = iwe_stream_add_event(info, current_ev, end_buf,
-					  &iwe, IW_EV_QUAL_LEN);
-
-	/* Add encryption capability */
-	iwe.cmd = SIOCGIWENCODE;
-	if (capabilities & WLAN_CAPABILITY_PRIVACY)
-		iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
-	else
-		iwe.u.data.flags = IW_ENCODE_DISABLED;
-	iwe.u.data.length = 0;
-	current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-					  &iwe, NULL);
-
-	/* Bit rate is not available in Lucent/Agere firmwares */
-	if (priv->firmware_type != FIRMWARE_TYPE_AGERE) {
-		char *current_val = current_ev + iwe_stream_lcp_len(info);
-		int i;
-		int step;
-
-		if (priv->firmware_type == FIRMWARE_TYPE_SYMBOL)
-			step = 2;
-		else
-			step = 1;
-
-		iwe.cmd = SIOCGIWRATE;
-		/* Those two flags are ignored... */
-		iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
-		/* Max 10 values */
-		for (i = 0; i < 10; i += step) {
-			/* NULL terminated */
-			if (bss->p.rates[i] == 0x0)
-				break;
-			/* Bit rate given in 500 kb/s units (+ 0x80) */
-			iwe.u.bitrate.value =
-				((bss->p.rates[i] & 0x7f) * 500000);
-			current_val = iwe_stream_add_value(info, current_ev,
-							   current_val,
-							   end_buf, &iwe,
-							   IW_EV_PARAM_LEN);
-		}
-		/* Check if we added any event */
-		if ((current_val - current_ev) > iwe_stream_lcp_len(info))
-			current_ev = current_val;
-	}
-
-	/* Beacon interval */
-	iwe.cmd = IWEVCUSTOM;
-	iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
-				     "bcn_int=%d",
-				     le16_to_cpu(bss->a.beacon_interv));
-	if (iwe.u.data.length)
-		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-						  &iwe, custom);
-
-	/* Capabilites */
-	iwe.cmd = IWEVCUSTOM;
-	iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
-				     "capab=0x%04x",
-				     capabilities);
-	if (iwe.u.data.length)
-		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-						  &iwe, custom);
-
-	/* Add EXTRA: Age to display seconds since last beacon/probe response
-	 * for given network. */
-	iwe.cmd = IWEVCUSTOM;
-	iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
-				     " Last beacon: %dms ago",
-				     jiffies_to_msecs(jiffies - last_scanned));
-	if (iwe.u.data.length)
-		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-						  &iwe, custom);
-
-	return current_ev;
-}
-
-static inline char *orinoco_translate_ext_scan(struct net_device *dev,
-					       struct iw_request_info *info,
-					       char *current_ev,
-					       char *end_buf,
-					       struct agere_ext_scan_info *bss,
-					       unsigned long last_scanned)
-{
-	u16			capabilities;
-	u16			channel;
-	struct iw_event		iwe;		/* Temporary buffer */
-	char custom[MAX_CUSTOM_LEN];
-	u8 *ie;
-
-	memset(&iwe, 0, sizeof(iwe));
-
-	/* First entry *MUST* be the AP MAC address */
-	iwe.cmd = SIOCGIWAP;
-	iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
-	memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
-	current_ev = iwe_stream_add_event(info, current_ev, end_buf,
-					  &iwe, IW_EV_ADDR_LEN);
-
-	/* Other entries will be displayed in the order we give them */
-
-	/* Add the ESSID */
-	ie = bss->data;
-	iwe.u.data.length = ie[1];
-	if (iwe.u.data.length) {
-		if (iwe.u.data.length > 32)
-			iwe.u.data.length = 32;
-		iwe.cmd = SIOCGIWESSID;
-		iwe.u.data.flags = 1;
-		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-						  &iwe, &ie[2]);
-	}
-
-	/* Add mode */
-	capabilities = le16_to_cpu(bss->capabilities);
-	if (capabilities & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
-		iwe.cmd = SIOCGIWMODE;
-		if (capabilities & WLAN_CAPABILITY_ESS)
-			iwe.u.mode = IW_MODE_MASTER;
-		else
-			iwe.u.mode = IW_MODE_ADHOC;
-		current_ev = iwe_stream_add_event(info, current_ev, end_buf,
-						  &iwe, IW_EV_UINT_LEN);
-	}
-
-	ie = orinoco_get_ie(bss->data, sizeof(bss->data), WLAN_EID_DS_PARAMS);
-	channel = ie ? ie[2] : 0;
-	if ((channel >= 1) && (channel <= NUM_CHANNELS)) {
-		/* Add channel and frequency */
-		iwe.cmd = SIOCGIWFREQ;
-		iwe.u.freq.m = channel;
-		iwe.u.freq.e = 0;
-		current_ev = iwe_stream_add_event(info, current_ev, end_buf,
-						  &iwe, IW_EV_FREQ_LEN);
-
-		iwe.u.freq.m = ieee80211_dsss_chan_to_freq(channel) * 100000;
-		iwe.u.freq.e = 1;
-		current_ev = iwe_stream_add_event(info, current_ev, end_buf,
-						  &iwe, IW_EV_FREQ_LEN);
-	}
-
-	/* Add quality statistics. level and noise in dB. No link quality */
-	iwe.cmd = IWEVQUAL;
-	iwe.u.qual.updated = IW_QUAL_DBM | IW_QUAL_QUAL_INVALID;
-	iwe.u.qual.level = bss->level - 0x95;
-	iwe.u.qual.noise = bss->noise - 0x95;
-	/* Wireless tools prior to 27.pre22 will show link quality
-	 * anyway, so we provide a reasonable value. */
-	if (iwe.u.qual.level > iwe.u.qual.noise)
-		iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise;
-	else
-		iwe.u.qual.qual = 0;
-	current_ev = iwe_stream_add_event(info, current_ev, end_buf,
-					  &iwe, IW_EV_QUAL_LEN);
-
-	/* Add encryption capability */
-	iwe.cmd = SIOCGIWENCODE;
-	if (capabilities & WLAN_CAPABILITY_PRIVACY)
-		iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
-	else
-		iwe.u.data.flags = IW_ENCODE_DISABLED;
-	iwe.u.data.length = 0;
-	current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-					  &iwe, NULL);
-
-	/* WPA IE */
-	ie = orinoco_get_wpa_ie(bss->data, sizeof(bss->data));
-	if (ie) {
-		iwe.cmd = IWEVGENIE;
-		iwe.u.data.length = ie[1] + 2;
-		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-						  &iwe, ie);
-	}
-
-	/* RSN IE */
-	ie = orinoco_get_ie(bss->data, sizeof(bss->data), WLAN_EID_RSN);
-	if (ie) {
-		iwe.cmd = IWEVGENIE;
-		iwe.u.data.length = ie[1] + 2;
-		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-						  &iwe, ie);
-	}
-
-	ie = orinoco_get_ie(bss->data, sizeof(bss->data), WLAN_EID_SUPP_RATES);
-	if (ie) {
-		char *p = current_ev + iwe_stream_lcp_len(info);
-		int i;
-
-		iwe.cmd = SIOCGIWRATE;
-		/* Those two flags are ignored... */
-		iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
-
-		for (i = 2; i < (ie[1] + 2); i++) {
-			iwe.u.bitrate.value = ((ie[i] & 0x7F) * 500000);
-			p = iwe_stream_add_value(info, current_ev, p, end_buf,
-						 &iwe, IW_EV_PARAM_LEN);
-		}
-		/* Check if we added any event */
-		if (p > (current_ev + iwe_stream_lcp_len(info)))
-			current_ev = p;
-	}
-
-	/* Timestamp */
-	iwe.cmd = IWEVCUSTOM;
-	iwe.u.data.length =
-		snprintf(custom, MAX_CUSTOM_LEN, "tsf=%016llx",
-			 (unsigned long long) le64_to_cpu(bss->timestamp));
-	if (iwe.u.data.length)
-		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-						  &iwe, custom);
-
-	/* Beacon interval */
-	iwe.cmd = IWEVCUSTOM;
-	iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
-				     "bcn_int=%d",
-				     le16_to_cpu(bss->beacon_interval));
-	if (iwe.u.data.length)
-		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-						  &iwe, custom);
-
-	/* Capabilites */
-	iwe.cmd = IWEVCUSTOM;
-	iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
-				     "capab=0x%04x",
-				     capabilities);
-	if (iwe.u.data.length)
-		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-						  &iwe, custom);
-
-	/* Add EXTRA: Age to display seconds since last beacon/probe response
-	 * for given network. */
-	iwe.cmd = IWEVCUSTOM;
-	iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
-				     " Last beacon: %dms ago",
-				     jiffies_to_msecs(jiffies - last_scanned));
-	if (iwe.u.data.length)
-		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-						  &iwe, custom);
-
-	return current_ev;
-}
-
-/* Return results of a scan */
-static int orinoco_ioctl_getscan(struct net_device *dev,
-				 struct iw_request_info *info,
-				 struct iw_point *srq,
-				 char *extra)
-{
-	struct orinoco_private *priv = ndev_priv(dev);
-	int err = 0;
-	unsigned long flags;
-	char *current_ev = extra;
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-
-	if (priv->scan_inprogress) {
-		/* Important note : we don't want to block the caller
-		 * until results are ready for various reasons.
-		 * First, managing wait queues is complex and racy.
-		 * Second, we grab some rtnetlink lock before comming
-		 * here (in dev_ioctl()).
-		 * Third, we generate an Wireless Event, so the
-		 * caller can wait itself on that - Jean II */
-		err = -EAGAIN;
-		goto out;
-	}
-
-	if (priv->has_ext_scan) {
-		struct xbss_element *bss;
-
-		list_for_each_entry(bss, &priv->bss_list, list) {
-			/* Translate this entry to WE format */
-			current_ev =
-				orinoco_translate_ext_scan(dev, info,
-							   current_ev,
-							   extra + srq->length,
-							   &bss->bss,
-							   bss->last_scanned);
-
-			/* Check if there is space for one more entry */
-			if ((extra + srq->length - current_ev)
-			    <= IW_EV_ADDR_LEN) {
-				/* Ask user space to try again with a
-				 * bigger buffer */
-				err = -E2BIG;
-				goto out;
-			}
-		}
-
-	} else {
-		struct bss_element *bss;
-
-		list_for_each_entry(bss, &priv->bss_list, list) {
-			/* Translate this entry to WE format */
-			current_ev = orinoco_translate_scan(dev, info,
-							    current_ev,
-							    extra + srq->length,
-							    &bss->bss,
-							    bss->last_scanned);
-
-			/* Check if there is space for one more entry */
-			if ((extra + srq->length - current_ev)
-			    <= IW_EV_ADDR_LEN) {
-				/* Ask user space to try again with a
-				 * bigger buffer */
-				err = -E2BIG;
-				goto out;
-			}
-		}
-	}
-
-	srq->length = (current_ev - extra);
-	srq->flags = (__u16) priv->scan_mode;
-
-out:
-	orinoco_unlock(priv, &flags);
-	return err;
-}
 
 /* Commit handler, called after set operations */
 static int orinoco_ioctl_commit(struct net_device *dev,
@@ -2161,8 +1648,8 @@ static const iw_handler	orinoco_handler[] = {
 	STD_IW_HANDLER(SIOCGIWTHRSPY,	iw_handler_get_thrspy),
 	STD_IW_HANDLER(SIOCSIWAP,	orinoco_ioctl_setwap),
 	STD_IW_HANDLER(SIOCGIWAP,	orinoco_ioctl_getwap),
-	STD_IW_HANDLER(SIOCSIWSCAN,	orinoco_ioctl_setscan),
-	STD_IW_HANDLER(SIOCGIWSCAN,	orinoco_ioctl_getscan),
+	STD_IW_HANDLER(SIOCSIWSCAN,	cfg80211_wext_siwscan),
+	STD_IW_HANDLER(SIOCGIWSCAN,	cfg80211_wext_giwscan),
 	STD_IW_HANDLER(SIOCSIWESSID,	orinoco_ioctl_setessid),
 	STD_IW_HANDLER(SIOCGIWESSID,	orinoco_ioctl_getessid),
 	STD_IW_HANDLER(SIOCSIWNICKN,	orinoco_ioctl_setnick),
-- 
1.6.0.6


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

* [PATCH 22/23] orinoco: convert giwrange to cfg80211
  2009-06-18 22:21 [PATCH 00/23] orinoco: initiate cfg80211 conversion David Kilroy
                   ` (20 preceding siblings ...)
  2009-06-18 22:21 ` [PATCH 21/23] orinoco: convert scanning " David Kilroy
@ 2009-06-18 22:21 ` David Kilroy
  2009-06-18 22:21 ` [PATCH 23/23] orinoco: remove WE nickname support David Kilroy
  2009-06-18 22:52 ` [PATCH 00/23] orinoco: initiate cfg80211 conversion Johannes Berg
  23 siblings, 0 replies; 32+ messages in thread
From: David Kilroy @ 2009-06-18 22:21 UTC (permalink / raw)
  To: linux-wireless; +Cc: orinoco-devel, David Kilroy

Signed-off-by: David Kilroy <kilroyd@googlemail.com>
---
 drivers/net/wireless/orinoco/wext.c |  115 +----------------------------------
 1 files changed, 1 insertions(+), 114 deletions(-)

diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c
index 082ea0a..21db578 100644
--- a/drivers/net/wireless/orinoco/wext.c
+++ b/drivers/net/wireless/orinoco/wext.c
@@ -172,119 +172,6 @@ static int orinoco_ioctl_getwap(struct net_device *dev,
 	return err;
 }
 
-static int orinoco_ioctl_getiwrange(struct net_device *dev,
-				    struct iw_request_info *info,
-				    struct iw_point *rrq,
-				    char *extra)
-{
-	struct orinoco_private *priv = ndev_priv(dev);
-	int err = 0;
-	struct iw_range *range = (struct iw_range *) extra;
-	int numrates;
-	int i, k;
-
-	rrq->length = sizeof(struct iw_range);
-	memset(range, 0, sizeof(struct iw_range));
-
-	range->we_version_compiled = WIRELESS_EXT;
-	range->we_version_source = 22;
-
-	/* Set available channels/frequencies */
-	range->num_channels = NUM_CHANNELS;
-	k = 0;
-	for (i = 0; i < NUM_CHANNELS; i++) {
-		if (priv->channel_mask & (1 << i)) {
-			range->freq[k].i = i + 1;
-			range->freq[k].m = (ieee80211_dsss_chan_to_freq(i + 1) *
-					    100000);
-			range->freq[k].e = 1;
-			k++;
-		}
-
-		if (k >= IW_MAX_FREQUENCIES)
-			break;
-	}
-	range->num_frequency = k;
-	range->sensitivity = 3;
-
-	if (priv->has_wep) {
-		range->max_encoding_tokens = ORINOCO_MAX_KEYS;
-		range->encoding_size[0] = SMALL_KEY_SIZE;
-		range->num_encoding_sizes = 1;
-
-		if (priv->has_big_wep) {
-			range->encoding_size[1] = LARGE_KEY_SIZE;
-			range->num_encoding_sizes = 2;
-		}
-	}
-
-	if (priv->has_wpa)
-		range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_CIPHER_TKIP;
-
-	if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) && (!SPY_NUMBER(priv))) {
-		/* Quality stats meaningless in ad-hoc mode */
-	} else {
-		range->max_qual.qual = 0x8b - 0x2f;
-		range->max_qual.level = 0x2f - 0x95 - 1;
-		range->max_qual.noise = 0x2f - 0x95 - 1;
-		/* Need to get better values */
-		range->avg_qual.qual = 0x24;
-		range->avg_qual.level = 0xC2;
-		range->avg_qual.noise = 0x9E;
-	}
-
-	err = orinoco_hw_get_bitratelist(priv, &numrates,
-					 range->bitrate, IW_MAX_BITRATES);
-	if (err)
-		return err;
-	range->num_bitrates = numrates;
-
-	/* Set an indication of the max TCP throughput in bit/s that we can
-	 * expect using this interface. May be use for QoS stuff...
-	 * Jean II */
-	if (numrates > 2)
-		range->throughput = 5 * 1000 * 1000;	/* ~5 Mb/s */
-	else
-		range->throughput = 1.5 * 1000 * 1000;	/* ~1.5 Mb/s */
-
-	range->min_rts = 0;
-	range->max_rts = 2347;
-	range->min_frag = 256;
-	range->max_frag = 2346;
-
-	range->min_pmp = 0;
-	range->max_pmp = 65535000;
-	range->min_pmt = 0;
-	range->max_pmt = 65535 * 1000;	/* ??? */
-	range->pmp_flags = IW_POWER_PERIOD;
-	range->pmt_flags = IW_POWER_TIMEOUT;
-	range->pm_capa = (IW_POWER_PERIOD | IW_POWER_TIMEOUT |
-			  IW_POWER_UNICAST_R);
-
-	range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
-	range->retry_flags = IW_RETRY_LIMIT;
-	range->r_time_flags = IW_RETRY_LIFETIME;
-	range->min_retry = 0;
-	range->max_retry = 65535;	/* ??? */
-	range->min_r_time = 0;
-	range->max_r_time = 65535 * 1000;	/* ??? */
-
-	if (priv->firmware_type == FIRMWARE_TYPE_AGERE)
-		range->scan_capa = IW_SCAN_CAPA_ESSID;
-	else
-		range->scan_capa = IW_SCAN_CAPA_NONE;
-
-	/* Event capability (kernel) */
-	IW_EVENT_CAPA_SET_KERNEL(range->event_capa);
-	/* Event capability (driver) */
-	IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWTHRSPY);
-	IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
-	IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
-	IW_EVENT_CAPA_SET(range->event_capa, IWEVTXDROP);
-
-	return 0;
-}
-
 static int orinoco_ioctl_setiwencode(struct net_device *dev,
 				     struct iw_request_info *info,
 				     struct iw_point *erq,
@@ -1641,7 +1528,7 @@ static const iw_handler	orinoco_handler[] = {
 	STD_IW_HANDLER(SIOCGIWMODE,	cfg80211_wext_giwmode),
 	STD_IW_HANDLER(SIOCSIWSENS,	orinoco_ioctl_setsens),
 	STD_IW_HANDLER(SIOCGIWSENS,	orinoco_ioctl_getsens),
-	STD_IW_HANDLER(SIOCGIWRANGE,	orinoco_ioctl_getiwrange),
+	STD_IW_HANDLER(SIOCGIWRANGE,	cfg80211_wext_giwrange),
 	STD_IW_HANDLER(SIOCSIWSPY,	iw_handler_set_spy),
 	STD_IW_HANDLER(SIOCGIWSPY,	iw_handler_get_spy),
 	STD_IW_HANDLER(SIOCSIWTHRSPY,	iw_handler_set_thrspy),
-- 
1.6.0.6


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

* [PATCH 23/23] orinoco: remove WE nickname support
  2009-06-18 22:21 [PATCH 00/23] orinoco: initiate cfg80211 conversion David Kilroy
                   ` (21 preceding siblings ...)
  2009-06-18 22:21 ` [PATCH 22/23] orinoco: convert giwrange " David Kilroy
@ 2009-06-18 22:21 ` David Kilroy
  2009-06-18 22:52 ` [PATCH 00/23] orinoco: initiate cfg80211 conversion Johannes Berg
  23 siblings, 0 replies; 32+ messages in thread
From: David Kilroy @ 2009-06-18 22:21 UTC (permalink / raw)
  To: linux-wireless; +Cc: orinoco-devel, David Kilroy

Signed-off-by: David Kilroy <kilroyd@googlemail.com>
---
 drivers/net/wireless/orinoco/wext.c |   43 -----------------------------------
 1 files changed, 0 insertions(+), 43 deletions(-)

diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c
index 21db578..b6ff3db 100644
--- a/drivers/net/wireless/orinoco/wext.c
+++ b/drivers/net/wireless/orinoco/wext.c
@@ -372,47 +372,6 @@ static int orinoco_ioctl_getessid(struct net_device *dev,
 	return 0;
 }
 
-static int orinoco_ioctl_setnick(struct net_device *dev,
-				 struct iw_request_info *info,
-				 struct iw_point *nrq,
-				 char *nickbuf)
-{
-	struct orinoco_private *priv = ndev_priv(dev);
-	unsigned long flags;
-
-	if (nrq->length > IW_ESSID_MAX_SIZE)
-		return -E2BIG;
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-
-	memset(priv->nick, 0, sizeof(priv->nick));
-	memcpy(priv->nick, nickbuf, nrq->length);
-
-	orinoco_unlock(priv, &flags);
-
-	return -EINPROGRESS;		/* Call commit handler */
-}
-
-static int orinoco_ioctl_getnick(struct net_device *dev,
-				 struct iw_request_info *info,
-				 struct iw_point *nrq,
-				 char *nickbuf)
-{
-	struct orinoco_private *priv = ndev_priv(dev);
-	unsigned long flags;
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-
-	memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE);
-	orinoco_unlock(priv, &flags);
-
-	nrq->length = strlen(priv->nick);
-
-	return 0;
-}
-
 static int orinoco_ioctl_setfreq(struct net_device *dev,
 				 struct iw_request_info *info,
 				 struct iw_freq *frq,
@@ -1539,8 +1498,6 @@ static const iw_handler	orinoco_handler[] = {
 	STD_IW_HANDLER(SIOCGIWSCAN,	cfg80211_wext_giwscan),
 	STD_IW_HANDLER(SIOCSIWESSID,	orinoco_ioctl_setessid),
 	STD_IW_HANDLER(SIOCGIWESSID,	orinoco_ioctl_getessid),
-	STD_IW_HANDLER(SIOCSIWNICKN,	orinoco_ioctl_setnick),
-	STD_IW_HANDLER(SIOCGIWNICKN,	orinoco_ioctl_getnick),
 	STD_IW_HANDLER(SIOCSIWRATE,	orinoco_ioctl_setrate),
 	STD_IW_HANDLER(SIOCGIWRATE,	orinoco_ioctl_getrate),
 	STD_IW_HANDLER(SIOCSIWRTS,	orinoco_ioctl_setrts),
-- 
1.6.0.6


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

* Re: [PATCH 00/23] orinoco: initiate cfg80211 conversion
  2009-06-18 22:21 [PATCH 00/23] orinoco: initiate cfg80211 conversion David Kilroy
                   ` (22 preceding siblings ...)
  2009-06-18 22:21 ` [PATCH 23/23] orinoco: remove WE nickname support David Kilroy
@ 2009-06-18 22:52 ` Johannes Berg
  23 siblings, 0 replies; 32+ messages in thread
From: Johannes Berg @ 2009-06-18 22:52 UTC (permalink / raw)
  To: David Kilroy; +Cc: linux-wireless

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


>  drivers/net/wireless/orinoco/Kconfig          |    1 +
>  drivers/net/wireless/orinoco/Makefile         |    2 +-
>  drivers/net/wireless/orinoco/airport.c        |   98 +--
>  drivers/net/wireless/orinoco/cfg.c            |  162 ++++
>  drivers/net/wireless/orinoco/cfg.h            |   15 +
>  drivers/net/wireless/orinoco/fw.c             |   41 +-
>  drivers/net/wireless/orinoco/hermes.h         |    2 +-
>  drivers/net/wireless/orinoco/hermes_dld.c     |   50 +-
>  drivers/net/wireless/orinoco/hw.c             |  668 +++++++++++++++-
>  drivers/net/wireless/orinoco/hw.h             |   11 +-
>  drivers/net/wireless/orinoco/main.c           | 1133 +++++++++----------------
>  drivers/net/wireless/orinoco/main.h           |    3 +-
>  drivers/net/wireless/orinoco/orinoco.h        |   49 +-
>  drivers/net/wireless/orinoco/orinoco_cs.c     |   96 +--
>  drivers/net/wireless/orinoco/orinoco_nortel.c |   38 +-
>  drivers/net/wireless/orinoco/orinoco_pci.c    |   38 +-
>  drivers/net/wireless/orinoco/orinoco_pci.h    |   57 +--
>  drivers/net/wireless/orinoco/orinoco_plx.c    |   38 +-
>  drivers/net/wireless/orinoco/orinoco_tmd.c    |   38 +-
>  drivers/net/wireless/orinoco/scan.c           |  285 +++----
>  drivers/net/wireless/orinoco/scan.h           |   21 +-
>  drivers/net/wireless/orinoco/spectrum_cs.c    |   96 +--
>  drivers/net/wireless/orinoco/wext.c           |  878 ++------------------
>  include/net/cfg80211.h                        |   11 +
>  net/wireless/core.c                           |    3 -
>  net/wireless/wext-compat.c                    |   31 +-
>  26 files changed, 1748 insertions(+), 2117 deletions(-)
>  create mode 100644 drivers/net/wireless/orinoco/cfg.c
>  create mode 100644 drivers/net/wireless/orinoco/cfg.h

Amazing. Very cool!

johannes

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

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

* Re: [PATCH 02/23] cfg80211: Advertise ciphers via WE according to driver capability
  2009-06-18 22:21 ` [PATCH 02/23] cfg80211: Advertise ciphers via WE according to driver capability David Kilroy
@ 2009-06-18 23:38   ` Julian Calaby
  2009-06-19 17:20     ` Dave
  0 siblings, 1 reply; 32+ messages in thread
From: Julian Calaby @ 2009-06-18 23:38 UTC (permalink / raw)
  To: David Kilroy; +Cc: linux-wireless, orinoco-devel

On Fri, Jun 19, 2009 at 08:21, David Kilroy<kilroyd@googlemail.com> wrote:
> Signed-off-by: David Kilroy <kilroyd@googlemail.com>
> Acked-by: Johannes Berg <johannes@sipsolutions.net>
> ---
>  net/wireless/wext-compat.c |   15 +++++++++++++--
>  1 files changed, 13 insertions(+), 2 deletions(-)
>
> diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
> index 9e56f35..7dbe6c6 100644
> --- a/net/wireless/wext-compat.c
> +++ b/net/wireless/wext-compat.c
> @@ -204,8 +204,19 @@ int cfg80211_wext_giwrange(struct net_device *dev,
>        range->avg_qual.noise = range->max_qual.noise / 2;
>        range->avg_qual.updated = range->max_qual.updated;
>
> -       range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
> -                         IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
> +       range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2;

Should this should go into the for loop too, like how patch 5 works?

> +       for (c = 0; c < wdev->wiphy->n_cipher_suites; c++) {
> +               switch (wdev->wiphy->cipher_suites[c]) {
> +               case WLAN_CIPHER_SUITE_TKIP:
> +                       range->enc_capa |= IW_ENC_CAPA_CIPHER_TKIP;
> +                       break;
> +
> +               case WLAN_CIPHER_SUITE_CCMP:
> +                       range->enc_capa |= IW_ENC_CAPA_CIPHER_CCMP;
> +                       break;
> +               }
> +       }
>
>        for (band = 0; band < IEEE80211_NUM_BANDS; band ++) {
>                int i;

Thanks,

-- 

Julian Calaby

Email: julian.calaby@gmail.com
.Plan: http://sites.google.com/site/juliancalaby/

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

* Re: [PATCH 02/23] cfg80211: Advertise ciphers via WE according to driver capability
  2009-06-18 23:38   ` Julian Calaby
@ 2009-06-19 17:20     ` Dave
  2009-06-20  0:38       ` Julian Calaby
  0 siblings, 1 reply; 32+ messages in thread
From: Dave @ 2009-06-19 17:20 UTC (permalink / raw)
  To: Julian Calaby; +Cc: linux-wireless, orinoco-devel

Julian Calaby wrote:
> On Fri, Jun 19, 2009 at 08:21, David Kilroy<kilroyd@googlemail.com> wrote:
>> Signed-off-by: David Kilroy <kilroyd@googlemail.com>
>> Acked-by: Johannes Berg <johannes@sipsolutions.net>
>> ---
>>  net/wireless/wext-compat.c |   15 +++++++++++++--
>>  1 files changed, 13 insertions(+), 2 deletions(-)
>>
>> diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
>> index 9e56f35..7dbe6c6 100644
>> --- a/net/wireless/wext-compat.c
>> +++ b/net/wireless/wext-compat.c
>> @@ -204,8 +204,19 @@ int cfg80211_wext_giwrange(struct net_device *dev,
>>        range->avg_qual.noise = range->max_qual.noise / 2;
>>        range->avg_qual.updated = range->max_qual.updated;
>>
>> -       range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
>> -                         IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
>> +       range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2;
> 
> Should this should go into the for loop too, like how patch 5 works?

Err... patch 5 moves this line into the for loop. I moved these in
separate patches because:

* Indicating available ciphers based on cipher capability is obviously
correct.
* Indicating WPA/WPA2 based on cipher capability is not obviously
correct - and we might want the drivers to indicate this explicitly.
* The latter patch can be NACK'd without affecting the former, or the
rest of the series (well, apart from patch 22).

As it happens, no-one has objected (yet).

Apologies if I've completely misunderstood you.


Thanks,

Dave.

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

* Re: [PATCH 21/23] orinoco: convert scanning to cfg80211
  2009-06-18 22:21 ` [PATCH 21/23] orinoco: convert scanning " David Kilroy
@ 2009-06-19 17:35   ` John W. Linville
  2009-06-19 17:52     ` Dave
  0 siblings, 1 reply; 32+ messages in thread
From: John W. Linville @ 2009-06-19 17:35 UTC (permalink / raw)
  To: David Kilroy; +Cc: linux-wireless, orinoco-devel

On Thu, Jun 18, 2009 at 11:21:33PM +0100, David Kilroy wrote:
> This removes the custom scan cache used by orinoco.
> 
> We also have to avoid calling cfg80211_scan_done from the hard
> interrupt, so we offload the entirety of scan processing to a workqueue.
> 
> This may behave strangely if you start scanning just prior to
> suspending...
> 
> Signed-off-by: David Kilroy <kilroyd@googlemail.com>

Hmmm...please do try to compile test patches before posting! :-)

John

---

>From 81aab523c06da0e025a7c9b2669058fd16597d18 Mon Sep 17 00:00:00 2001
From: John W. Linville <linville@tuxdriver.com>
Date: Fri, 19 Jun 2009 13:33:50 -0400
Subject: [PATCH] fixups for "orinoco: convert scanning to cfg80211"

Signed-off-by: John W. Linville <linville@tuxdriver.com>
---
 drivers/net/wireless/orinoco/main.c |   16 ++++++++--------
 1 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c
index 90e2d32..cd1c04d 100644
--- a/drivers/net/wireless/orinoco/main.c
+++ b/drivers/net/wireless/orinoco/main.c
@@ -1283,9 +1283,9 @@ static void qbuf_scan(struct orinoco_private *priv, void *buf,
 	sd->len = len;
 	sd->type = type;
 
-	spin_lock_irqsave(priv->scan_lock, flags);
+	spin_lock_irqsave(&priv->scan_lock, flags);
 	list_add_tail(&sd->list, &priv->scan_list);
-	spin_unlock_irqrestore(priv->scan_lock, flags);
+	spin_unlock_irqrestore(&priv->scan_lock, flags);
 
 	schedule_work(&priv->process_scan);
 }
@@ -1298,9 +1298,9 @@ static void qabort_scan(struct orinoco_private *priv)
 	sd = kmalloc(sizeof(*sd), GFP_ATOMIC);
 	sd->len = -1; /* Abort */
 
-	spin_lock_irqsave(priv->scan_lock, flags);
+	spin_lock_irqsave(&priv->scan_lock, flags);
 	list_add_tail(&sd->list, &priv->scan_list);
-	spin_unlock_irqrestore(priv->scan_lock, flags);
+	spin_unlock_irqrestore(&priv->scan_lock, flags);
 
 	schedule_work(&priv->process_scan);
 }
@@ -1315,9 +1315,9 @@ static void orinoco_process_scan_results(struct work_struct *work)
 	int len;
 	int type;
 
-	spin_lock_irqsave(priv->scan_lock, flags);
+	spin_lock_irqsave(&priv->scan_lock, flags);
 	list_for_each_entry_safe(sd, temp, &priv->scan_list, list) {
-		spin_unlock_irqrestore(priv->scan_lock, flags);
+		spin_unlock_irqrestore(&priv->scan_lock, flags);
 
 		buf = sd->buf;
 		len = sd->len;
@@ -1339,9 +1339,9 @@ static void orinoco_process_scan_results(struct work_struct *work)
 			priv->scan_request = NULL;
 		}
 
-		spin_lock_irqsave(priv->scan_lock, flags);
+		spin_lock_irqsave(&priv->scan_lock, flags);
 	}
-	spin_unlock_irqrestore(priv->scan_lock, flags);
+	spin_unlock_irqrestore(&priv->scan_lock, flags);
 }
 
 static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
-- 
1.6.0.6

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

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

* Re: [PATCH 21/23] orinoco: convert scanning to cfg80211
  2009-06-19 17:35   ` John W. Linville
@ 2009-06-19 17:52     ` Dave
  2009-06-19 18:02       ` John W. Linville
  0 siblings, 1 reply; 32+ messages in thread
From: Dave @ 2009-06-19 17:52 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, orinoco-devel

John W. Linville wrote:
> On Thu, Jun 18, 2009 at 11:21:33PM +0100, David Kilroy wrote:
>> This removes the custom scan cache used by orinoco.
>>
>> We also have to avoid calling cfg80211_scan_done from the hard
>> interrupt, so we offload the entirety of scan processing to a workqueue.
>>
>> This may behave strangely if you start scanning just prior to
>> suspending...
>>
>> Signed-off-by: David Kilroy <kilroyd@googlemail.com>
> 
> Hmmm...please do try to compile test patches before posting! :-)
> 
> John

Compile? I'm running it! (and sparse didn't complain either)

I'll go have a look see what's special on my end. I'm guessing no SMP or
something.

Would you like the series/patch reposted including this fix?


Thanks,

Dave.

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

* Re: [PATCH 21/23] orinoco: convert scanning to cfg80211
  2009-06-19 17:52     ` Dave
@ 2009-06-19 18:02       ` John W. Linville
  2009-06-19 21:25         ` Dave
  0 siblings, 1 reply; 32+ messages in thread
From: John W. Linville @ 2009-06-19 18:02 UTC (permalink / raw)
  To: Dave; +Cc: linux-wireless, orinoco-devel

On Fri, Jun 19, 2009 at 06:52:45PM +0100, Dave wrote:
> John W. Linville wrote:
> > On Thu, Jun 18, 2009 at 11:21:33PM +0100, David Kilroy wrote:
> >> This removes the custom scan cache used by orinoco.
> >>
> >> We also have to avoid calling cfg80211_scan_done from the hard
> >> interrupt, so we offload the entirety of scan processing to a workqueue.
> >>
> >> This may behave strangely if you start scanning just prior to
> >> suspending...
> >>
> >> Signed-off-by: David Kilroy <kilroyd@googlemail.com>
> > 
> > Hmmm...please do try to compile test patches before posting! :-)
> > 
> > John
> 
> Compile? I'm running it! (and sparse didn't complain either)
> 
> I'll go have a look see what's special on my end. I'm guessing no SMP or
> something.

Haha...yeah, that's probably it...

> Would you like the series/patch reposted including this fix?

No, I've got it fixed.

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

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

* Re: [PATCH 21/23] orinoco: convert scanning to cfg80211
  2009-06-19 18:02       ` John W. Linville
@ 2009-06-19 21:25         ` Dave
  0 siblings, 0 replies; 32+ messages in thread
From: Dave @ 2009-06-19 21:25 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, orinoco-devel

John W. Linville wrote:
> On Fri, Jun 19, 2009 at 06:52:45PM +0100, Dave wrote:
>> John W. Linville wrote:
>>> Hmmm...please do try to compile test patches before posting! :-)

>> Compile? I'm running it! (and sparse didn't complain either)
>>
>> I'll go have a look see what's special on my end. I'm guessing no SMP or
>> something.
> 
> Haha...yeah, that's probably it...
> 
>> Would you like the series/patch reposted including this fix?
> 
> No, I've got it fixed.

Thanks.

It looks like I can enable DEBUG_SPINLOCKS to highlight this - but it's
expensive to keep turning that on and off.

Alternatively I could submit a patch to either add typechecks to
spinlock_api_up.h or convert the #defines to inlines.

Sounds a bit too controversial for me, so I'll just try to be vigilant
for now.


Regards,

Dave.

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

* Re: [PATCH 02/23] cfg80211: Advertise ciphers via WE according to driver capability
  2009-06-19 17:20     ` Dave
@ 2009-06-20  0:38       ` Julian Calaby
  0 siblings, 0 replies; 32+ messages in thread
From: Julian Calaby @ 2009-06-20  0:38 UTC (permalink / raw)
  To: Dave; +Cc: linux-wireless, orinoco-devel

On Sat, Jun 20, 2009 at 03:20, Dave<kilroyd@googlemail.com> wrote:
> Julian Calaby wrote:
>> On Fri, Jun 19, 2009 at 08:21, David Kilroy<kilroyd@googlemail.com> wrote:
>>> Signed-off-by: David Kilroy <kilroyd@googlemail.com>
>>> Acked-by: Johannes Berg <johannes@sipsolutions.net>
>>> ---
>>>  net/wireless/wext-compat.c |   15 +++++++++++++--
>>>  1 files changed, 13 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
>>> index 9e56f35..7dbe6c6 100644
>>> --- a/net/wireless/wext-compat.c
>>> +++ b/net/wireless/wext-compat.c
>>> @@ -204,8 +204,19 @@ int cfg80211_wext_giwrange(struct net_device *dev,
>>>        range->avg_qual.noise = range->max_qual.noise / 2;
>>>        range->avg_qual.updated = range->max_qual.updated;
>>>
>>> -       range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
>>> -                         IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
>>> +       range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2;
>>
>> Should this should go into the for loop too, like how patch 5 works?
>
> Err... patch 5 moves this line into the for loop. I moved these in
> separate patches because:

You know, it does. Argh! This is what you get for not reading the
patches properly.

> As it happens, no-one has objected (yet).

Hmm, yes.

> Apologies if I've completely misunderstood you.

No, you haven't.

Sorry for the noise.

Thanks,

-- 

Julian Calaby

Email: julian.calaby@gmail.com
.Plan: http://sites.google.com/site/juliancalaby/

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

end of thread, other threads:[~2009-06-20  0:45 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-06-18 22:21 [PATCH 00/23] orinoco: initiate cfg80211 conversion David Kilroy
2009-06-18 22:21 ` [PATCH 01/23] cfg80211: add wrapper function to get wiphy from priv pointer David Kilroy
2009-06-18 22:21 ` [PATCH 02/23] cfg80211: Advertise ciphers via WE according to driver capability David Kilroy
2009-06-18 23:38   ` Julian Calaby
2009-06-19 17:20     ` Dave
2009-06-20  0:38       ` Julian Calaby
2009-06-18 22:21 ` [PATCH 03/23] cfg80211: allow drivers that can't scan for specific ssids David Kilroy
2009-06-18 22:21 ` [PATCH 04/23] cfg80211: set WE encoding size based on available ciphers David Kilroy
2009-06-18 22:21 ` [PATCH 05/23] cfg80211: infer WPA and WPA2 support from TKIP and CCMP David Kilroy
2009-06-18 22:21 ` [PATCH 06/23] orinoco: Move firmware capability determination into hw.c David Kilroy
2009-06-18 22:21 ` [PATCH 07/23] orinoco: Move card reading code " David Kilroy
2009-06-18 22:21 ` [PATCH 08/23] orinoco: Move FID allocation to hw.c David Kilroy
2009-06-18 22:21 ` [PATCH 09/23] orinoco: use dev_err in early initialisation routines David Kilroy
2009-06-18 22:21 ` [PATCH 10/23] orinoco: firmware helpers should use dev_err and friends David Kilroy
2009-06-18 22:21 ` [PATCH 11/23] orinoco: Replace net_device with orinoco_private in driver interfaces David Kilroy
2009-06-18 22:21 ` [PATCH 12/23] orinoco: initialise independently of netdev David Kilroy
2009-06-18 22:21 ` [PATCH 13/23] orinoco: Change set_tkip to use orinoco_private instead of hermes_t David Kilroy
2009-06-18 22:21 ` [PATCH 14/23] orinoco: initiate cfg80211 conversion David Kilroy
2009-06-18 22:21 ` [PATCH 15/23] orinoco: make firmware download less verbose David Kilroy
2009-06-18 22:21 ` [PATCH 16/23] orinoco: move netdev interface creation to main driver David Kilroy
2009-06-18 22:21 ` [PATCH 17/23] airport: store irq in card private structure David Kilroy
2009-06-18 22:21 ` [PATCH 18/23] orinoco: Handle suspend/restore in core driver David Kilroy
2009-06-18 22:21 ` [PATCH 19/23] orinoco: provide generic commit function David Kilroy
2009-06-18 22:21 ` [PATCH 20/23] orinoco: convert mode setting to cfg80211 David Kilroy
2009-06-18 22:21 ` [PATCH 21/23] orinoco: convert scanning " David Kilroy
2009-06-19 17:35   ` John W. Linville
2009-06-19 17:52     ` Dave
2009-06-19 18:02       ` John W. Linville
2009-06-19 21:25         ` Dave
2009-06-18 22:21 ` [PATCH 22/23] orinoco: convert giwrange " David Kilroy
2009-06-18 22:21 ` [PATCH 23/23] orinoco: remove WE nickname support David Kilroy
2009-06-18 22:52 ` [PATCH 00/23] orinoco: initiate cfg80211 conversion Johannes Berg

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).