Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH 3/6] ath9k: add helper to un-init the hw properly
From: Luis R. Rodriguez @ 2009-10-07  1:19 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, vasanth, Luis R. Rodriguez
In-Reply-To: <1254878351-32433-1-git-send-email-lrodriguez@atheros.com>

This is used in several places, ensure we do it right in all
callers by using a helper.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/main.c |   23 ++++++++++++++---------
 1 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 0fe915a..e6842dd 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1325,6 +1325,17 @@ void ath_cleanup(struct ath_softc *sc)
 	ieee80211_free_hw(sc->hw);
 }
 
+static void ath9k_uninit_hw(struct ath_softc *sc)
+{
+	struct ath_hw *ah = sc->sc_ah;
+
+	BUG_ON(!ah);
+
+	ath9k_exit_debug(ah);
+	ath9k_hw_detach(ah);
+	sc->sc_ah = NULL;
+}
+
 void ath_detach(struct ath_softc *sc)
 {
 	struct ieee80211_hw *hw = sc->hw;
@@ -1365,9 +1376,7 @@ void ath_detach(struct ath_softc *sc)
 	    ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
 		ath_gen_timer_free(ah, sc->btcoex.no_stomp_timer);
 
-	ath9k_exit_debug(ah);
-	ath9k_hw_detach(ah);
-	sc->sc_ah = NULL;
+	ath9k_uninit_hw(sc);
 }
 
 static int ath9k_reg_notifier(struct wiphy *wiphy,
@@ -1850,10 +1859,8 @@ bad2:
 		if (ATH_TXQ_SETUP(sc, i))
 			ath_tx_cleanupq(sc, &sc->tx.txq[i]);
 
-	ath9k_exit_debug(ah);
 bad_free_hw:
-	ath9k_hw_detach(ah);
-	sc->sc_ah = NULL;
+	ath9k_uninit_hw(sc);
 	return r;
 }
 
@@ -1966,9 +1973,7 @@ error_attach:
 		if (ATH_TXQ_SETUP(sc, i))
 			ath_tx_cleanupq(sc, &sc->tx.txq[i]);
 
-	ath9k_exit_debug(ah);
-	ath9k_hw_detach(ah);
-	sc->sc_ah = NULL;
+	ath9k_uninit_hw(sc);
 
 	return error;
 }
-- 
1.6.0.4


^ permalink raw reply related

* [PATCH 1/6] ath9k: move common->debug_mask setting to ath_init_softc()
From: Luis R. Rodriguez @ 2009-10-07  1:19 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, vasanth, Luis R. Rodriguez
In-Reply-To: <1254878351-32433-1-git-send-email-lrodriguez@atheros.com>

What this means is we can enable now debug prints without
requiring CONFIG_ATH9K_DEBUG.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/debug.c |    5 -----
 drivers/net/wireless/ath/ath9k/main.c  |    5 +++++
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 25ae88e..84f4426 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -23,9 +23,6 @@
 #define REG_READ_D(_ah, _reg) \
 	ath9k_hw_common(_ah)->ops->read((_ah), (_reg))
 
-static unsigned int ath9k_debug = ATH_DBG_DEFAULT;
-module_param_named(debug, ath9k_debug, uint, 0);
-
 static struct dentry *ath9k_debugfs_root;
 
 static int ath9k_debugfs_open(struct inode *inode, struct file *file)
@@ -565,8 +562,6 @@ int ath9k_init_debug(struct ath_hw *ah)
 	struct ath_common *common = ath9k_hw_common(ah);
 	struct ath_softc *sc = (struct ath_softc *) common->priv;
 
-	common->debug_mask = ath9k_debug;
-
 	if (!ath9k_debugfs_root)
 		return -ENOENT;
 
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 86374ad..7f90cb8 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -29,6 +29,10 @@ static int modparam_nohwcrypt;
 module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444);
 MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
 
+static unsigned int ath9k_debug = ATH_DBG_DEFAULT;
+module_param_named(debug, ath9k_debug, uint, 0);
+MODULE_PARM_DESC(ath9k_debug, "Debugging mask");
+
 /* We use the hw_value as an index into our private channel structure */
 
 #define CHAN2G(_freq, _idx)  { \
@@ -1637,6 +1641,7 @@ static int ath_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
 	common->ah = ah;
 	common->hw = sc->hw;
 	common->priv = sc;
+	common->debug_mask = ath9k_debug;
 
 	/*
 	 * Cache line size is used to size and align various
-- 
1.6.0.4


^ permalink raw reply related

* [PATCH 5/6] ath9k: move ath_cleanup() below helpers to avoid forward declarations
From: Luis R. Rodriguez @ 2009-10-07  1:19 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, vasanth, Luis R. Rodriguez
In-Reply-To: <1254878351-32433-1-git-send-email-lrodriguez@atheros.com>

This should fix the oops which occurs during module unload
due to the dereferencig of ah upon debugfs exit.

IP: [<46412d6b>] 0x46412d6b
*pde = 00000000
Oops: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC
last sysfs file: /sys/class/power_supply/BAT0/energy_full
Modules linked in: ath9k(-) ath9k_hw mac80211 ath cfg80211 <bleh>

Pid: 3112, comm: rmmod Not tainted (2.6.32-rc2-wl #101) 9461DUU
EIP: 0060:[<46412d6b>] EFLAGS: 00010246 CPU: 0
EIP is at 0x46412d6b
EAX: f5870004 EBX: f6700d94 ECX: 00000000 EDX: c14313a7
ESI: f5870000 EDI: fb58ce70 EBP: f6661eb4 ESP: f6661ea8
DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
Process rmmod (pid: 3112, ti=f6660000 task=f6579380 task.ti=f6660000)
Stack:
fb57e5e5 f5ca5d50 fb58ce70 f6661ebc fb58629a f6661ec8 c11b715e f5ca5da8
<0> f6661ed8 c1223d98 f5ca5da8 f5ca5ddc f6661eec c1223e6f fb58ce70 fb58ce70
<0> c14958a0 f6661f00 c1222edb fb58ce70 fb58ce70 fb58cebc f6661f1c c12243c9
Call Trace:
[<fb57e5e5>] ? ath_cleanup+0x35/0x50 [ath9k]
[<fb58629a>] ? ath_pci_remove+0x1a/0x20 [ath9k]
[<c11b715e>] ? pci_device_remove+0x1e/0x40
[<c1223d98>] ? __device_release_driver+0x58/0xa0
[<c1223e6f>] ? driver_detach+0x8f/0xa0
[<c1222edb>] ? bus_remove_driver+0x7b/0xb0
[<c12243c9>] ? driver_unregister+0x49/0x80
[<c1158cf2>] ? sysfs_remove_file+0x12/0x20
[<c11b73b5>] ? pci_unregister_driver+0x35/0x90
[<fb586172>] ? ath_pci_exit+0x12/0x20 [ath9k]
[<fb5883ec>] ? ath9k_exit+0x10/0x3d [ath9k]
[<c131971d>] ? mutex_unlock+0xd/0x10
[<c1088c0f>] ? sys_delete_module+0x16f/0x220
[<c10e3d5d>] ? do_munmap+0x23d/0x290
[<c11a629c>] ? trace_hardirqs_off_thunk+0xc/0x10
[<c11a628c>] ? trace_hardirqs_on_thunk+0xc/0x10
[<c1003b41>] ? sysenter_exit+0xf/0x1a
[<c1003b08>] ? sysenter_do_call+0x12/0x3c
Code:  Bad EIP value.
EIP: [<46412d6b>] 0x46412d6b SS:ESP 0068:f6661ea8
CR2: 0000000046412d6b
---[ end trace 847f3b05ff3dcb19 ]---

Reported-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/main.c |   31 ++++++++++++++-----------------
 1 files changed, 14 insertions(+), 17 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 39b2780..c541516 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1313,23 +1313,6 @@ static void ath_start_rfkill_poll(struct ath_softc *sc)
 		wiphy_rfkill_start_polling(sc->hw->wiphy);
 }
 
-static void ath_clean_core(struct ath_softc *sc);
-static void ath9k_uninit_hw(struct ath_softc *sc);
-
-void ath_cleanup(struct ath_softc *sc)
-{
-	struct ath_hw *ah = sc->sc_ah;
-	struct ath_common *common = ath9k_hw_common(ah);
-
-	ath_clean_core(sc);
-	free_irq(sc->irq, sc);
-	ath_bus_cleanup(common);
-	kfree(sc->sec_wiphy);
-	ieee80211_free_hw(sc->hw);
-
-	ath9k_uninit_hw(sc);
-}
-
 static void ath9k_uninit_hw(struct ath_softc *sc)
 {
 	struct ath_hw *ah = sc->sc_ah;
@@ -1388,6 +1371,20 @@ void ath_detach(struct ath_softc *sc)
 	ath9k_uninit_hw(sc);
 }
 
+void ath_cleanup(struct ath_softc *sc)
+{
+	struct ath_hw *ah = sc->sc_ah;
+	struct ath_common *common = ath9k_hw_common(ah);
+
+	ath_clean_core(sc);
+	free_irq(sc->irq, sc);
+	ath_bus_cleanup(common);
+	kfree(sc->sec_wiphy);
+	ieee80211_free_hw(sc->hw);
+
+	ath9k_uninit_hw(sc);
+}
+
 static int ath9k_reg_notifier(struct wiphy *wiphy,
 			      struct regulatory_request *request)
 {
-- 
1.6.0.4


^ permalink raw reply related

* [PATCH 2/6] ath9k: initialize hw prior to debugfs
From: Luis R. Rodriguez @ 2009-10-07  1:19 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, vasanth, Luis R. Rodriguez
In-Reply-To: <1254878351-32433-1-git-send-email-lrodriguez@atheros.com>

debugfs uses the hardware for several debugfs files as such the
hardware must be initialized and available prior to its usage. The
same applies to when we free the hw structs -- free debufs file
entries prior to free'ing the hardware.

Reported-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath.h        |    6 ++++++
 drivers/net/wireless/ath/ath9k/hw.c   |   11 ++++++++++-
 drivers/net/wireless/ath/ath9k/main.c |   28 ++++++++++++++--------------
 3 files changed, 30 insertions(+), 15 deletions(-)

diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index b6cd752..5e19a73 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -23,6 +23,11 @@
 
 static const u8 ath_bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 
+enum ath_device_state {
+	ATH_HW_UNAVAILABLE,
+	ATH_HW_INITIALIZED,
+};
+
 struct reg_dmn_pair_mapping {
 	u16 regDmnEnum;
 	u16 reg_5ghz_ctl;
@@ -59,6 +64,7 @@ struct ath_common {
 	void *priv;
 	struct ieee80211_hw *hw;
 	int debug_mask;
+	enum ath_device_state state;
 
 	u16 cachelsz;
 	u16 curaid;
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 692fd1d..cab17c6 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -999,6 +999,8 @@ int ath9k_hw_init(struct ath_hw *ah)
 
 	ath9k_init_nfcal_hist_buffer(ah);
 
+	common->state = ATH_HW_INITIALIZED;
+
 	return 0;
 }
 
@@ -1239,11 +1241,18 @@ const char *ath9k_hw_probe(u16 vendorid, u16 devid)
 
 void ath9k_hw_detach(struct ath_hw *ah)
 {
+	struct ath_common *common = ath9k_hw_common(ah);
+
+	if (common->state <= ATH_HW_INITIALIZED)
+		goto free_hw;
+
 	if (!AR_SREV_9100(ah))
 		ath9k_hw_ani_disable(ah);
 
-	ath9k_hw_rf_free(ah);
 	ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
+
+free_hw:
+	ath9k_hw_rf_free(ah);
 	kfree(ah);
 	ah = NULL;
 }
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 7f90cb8..0fe915a 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1365,8 +1365,8 @@ void ath_detach(struct ath_softc *sc)
 	    ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
 		ath_gen_timer_free(ah, sc->btcoex.no_stomp_timer);
 
-	ath9k_hw_detach(ah);
 	ath9k_exit_debug(ah);
+	ath9k_hw_detach(ah);
 	sc->sc_ah = NULL;
 }
 
@@ -1626,10 +1626,8 @@ static int ath_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
 		     (unsigned long)sc);
 
 	ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL);
-	if (!ah) {
-		r = -ENOMEM;
-		goto bad_no_ah;
-	}
+	if (!ah)
+		return -ENOMEM;
 
 	ah->hw_version.devid = devid;
 	ah->hw_version.subsysid = subsysid;
@@ -1651,15 +1649,18 @@ static int ath_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
 	/* XXX assert csz is non-zero */
 	common->cachelsz = csz << 2;	/* convert to bytes */
 
-	if (ath9k_init_debug(ah) < 0)
-		dev_err(sc->dev, "Unable to create debugfs files\n");
-
 	r = ath9k_hw_init(ah);
 	if (r) {
 		ath_print(common, ATH_DBG_FATAL,
 			  "Unable to initialize hardware; "
 			  "initialization status: %d\n", r);
-		goto bad;
+		goto bad_free_hw;
+	}
+
+	if (ath9k_init_debug(ah) < 0) {
+		ath_print(common, ATH_DBG_FATAL,
+			  "Unable to create debugfs files\n");
+		goto bad_free_hw;
 	}
 
 	/* Get the hardware key cache size. */
@@ -1848,12 +1849,11 @@ bad2:
 	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
 		if (ATH_TXQ_SETUP(sc, i))
 			ath_tx_cleanupq(sc, &sc->tx.txq[i]);
-bad:
+
+	ath9k_exit_debug(ah);
+bad_free_hw:
 	ath9k_hw_detach(ah);
-bad_no_ah:
-	ath9k_exit_debug(sc->sc_ah);
 	sc->sc_ah = NULL;
-
 	return r;
 }
 
@@ -1966,8 +1966,8 @@ error_attach:
 		if (ATH_TXQ_SETUP(sc, i))
 			ath_tx_cleanupq(sc, &sc->tx.txq[i]);
 
-	ath9k_hw_detach(ah);
 	ath9k_exit_debug(ah);
+	ath9k_hw_detach(ah);
 	sc->sc_ah = NULL;
 
 	return error;
-- 
1.6.0.4


^ permalink raw reply related

* [PATCH 4/6] ath9k: add a helper to clean the core driver upon module unload
From: Luis R. Rodriguez @ 2009-10-07  1:19 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, vasanth, Luis R. Rodriguez
In-Reply-To: <1254878351-32433-1-git-send-email-lrodriguez@atheros.com>

The core driver needs to be stopped and then as a last step the
hardware needs to be stopped and its structure free'd. We do this
by moving the core driver cleanup to a new helper ath_clean_core()
and have ath_cleanup() call it. Only as a last step does
ath_cleanup() now free the hw.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/main.c |   13 +++++++++++--
 1 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index e6842dd..39b2780 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1313,16 +1313,21 @@ static void ath_start_rfkill_poll(struct ath_softc *sc)
 		wiphy_rfkill_start_polling(sc->hw->wiphy);
 }
 
+static void ath_clean_core(struct ath_softc *sc);
+static void ath9k_uninit_hw(struct ath_softc *sc);
+
 void ath_cleanup(struct ath_softc *sc)
 {
 	struct ath_hw *ah = sc->sc_ah;
 	struct ath_common *common = ath9k_hw_common(ah);
 
-	ath_detach(sc);
+	ath_clean_core(sc);
 	free_irq(sc->irq, sc);
 	ath_bus_cleanup(common);
 	kfree(sc->sec_wiphy);
 	ieee80211_free_hw(sc->hw);
+
+	ath9k_uninit_hw(sc);
 }
 
 static void ath9k_uninit_hw(struct ath_softc *sc)
@@ -1336,7 +1341,7 @@ static void ath9k_uninit_hw(struct ath_softc *sc)
 	sc->sc_ah = NULL;
 }
 
-void ath_detach(struct ath_softc *sc)
+static void ath_clean_core(struct ath_softc *sc)
 {
 	struct ieee80211_hw *hw = sc->hw;
 	struct ath_hw *ah = sc->sc_ah;
@@ -1375,7 +1380,11 @@ void ath_detach(struct ath_softc *sc)
 	if ((sc->btcoex.no_stomp_timer) &&
 	    ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
 		ath_gen_timer_free(ah, sc->btcoex.no_stomp_timer);
+}
 
+void ath_detach(struct ath_softc *sc)
+{
+	ath_clean_core(sc);
 	ath9k_uninit_hw(sc);
 }
 
-- 
1.6.0.4


^ permalink raw reply related

* [PATCH 6/6] ath9k: rename ath_beaconq_setup() to ath9k_hw_beaconq_setup()
From: Luis R. Rodriguez @ 2009-10-07  1:19 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, vasanth, Luis R. Rodriguez
In-Reply-To: <1254878351-32433-1-git-send-email-lrodriguez@atheros.com>

And move it to hw code on mac.c where it belongs.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/ath9k.h  |    1 -
 drivers/net/wireless/ath/ath9k/beacon.c |   12 ------------
 drivers/net/wireless/ath/ath9k/mac.c    |   13 +++++++++++++
 drivers/net/wireless/ath/ath9k/mac.h    |    1 +
 drivers/net/wireless/ath/ath9k/main.c   |    2 +-
 5 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 14ff38d..13dd020 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -421,7 +421,6 @@ struct ath_beacon {
 
 void ath_beacon_tasklet(unsigned long data);
 void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif);
-int ath_beaconq_setup(struct ath_hw *ah);
 int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif);
 void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp);
 
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index 54be876..b10c884 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -242,18 +242,6 @@ static void ath_beacon_start_adhoc(struct ath_softc *sc,
 		  sc->beacon.beaconq, ito64(bf->bf_daddr), bf->bf_desc);
 }
 
-int ath_beaconq_setup(struct ath_hw *ah)
-{
-	struct ath9k_tx_queue_info qi;
-
-	memset(&qi, 0, sizeof(qi));
-	qi.tqi_aifs = 1;
-	qi.tqi_cwmin = 0;
-	qi.tqi_cwmax = 0;
-	/* NB: don't enable any interrupts */
-	return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi);
-}
-
 int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
 {
 	struct ath_softc *sc = aphy->sc;
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index e2c1ba3..46466ff 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -1018,3 +1018,16 @@ bool ath9k_hw_stopdmarecv(struct ath_hw *ah)
 #undef AH_RX_STOP_DMA_TIMEOUT
 }
 EXPORT_SYMBOL(ath9k_hw_stopdmarecv);
+
+int ath9k_hw_beaconq_setup(struct ath_hw *ah)
+{
+	struct ath9k_tx_queue_info qi;
+
+	memset(&qi, 0, sizeof(qi));
+	qi.tqi_aifs = 1;
+	qi.tqi_cwmin = 0;
+	qi.tqi_cwmax = 0;
+	/* NB: don't enable any interrupts */
+	return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi);
+}
+EXPORT_SYMBOL(ath9k_hw_beaconq_setup);
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index 9ab3431..fefb65d 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -667,5 +667,6 @@ void ath9k_hw_rxena(struct ath_hw *ah);
 void ath9k_hw_startpcureceive(struct ath_hw *ah);
 void ath9k_hw_stoppcurecv(struct ath_hw *ah);
 bool ath9k_hw_stopdmarecv(struct ath_hw *ah);
+int ath9k_hw_beaconq_setup(struct ath_hw *ah);
 
 #endif /* MAC_H */
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index c541516..36af6f3 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1709,7 +1709,7 @@ static int ath_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
 	 * priority.  Note that the hal handles reseting
 	 * these queues at the needed time.
 	 */
-	sc->beacon.beaconq = ath_beaconq_setup(ah);
+	sc->beacon.beaconq = ath9k_hw_beaconq_setup(ah);
 	if (sc->beacon.beaconq == -1) {
 		ath_print(common, ATH_DBG_FATAL,
 			  "Unable to setup a beacon xmit queue\n");
-- 
1.6.0.4


^ permalink raw reply related

* [PATCH 0/6] ath9k: fix rmmod
From: Luis R. Rodriguez @ 2009-10-07  1:19 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, vasanth, Luis R. Rodriguez

This series fixes removing ath9k as a module as reported by
Vasanth. I've now tested these as I was finally able to boot
to 2.6.32-rc3.

Luis R. Rodriguez (6):
  ath9k: move common->debug_mask setting to ath_init_softc()
  ath9k: initialize hw prior to debugfs
  ath9k: add helper to un-init the hw properly
  ath9k: add a helper to clean the core driver upon module unload
  ath9k: move ath_cleanup() below helpers to avoid forward declarations
  ath9k: rename ath_beaconq_setup() to ath9k_hw_beaconq_setup()

 drivers/net/wireless/ath/ath.h          |    6 +++
 drivers/net/wireless/ath/ath9k/ath9k.h  |    1 -
 drivers/net/wireless/ath/ath9k/beacon.c |   12 -----
 drivers/net/wireless/ath/ath9k/debug.c  |    5 --
 drivers/net/wireless/ath/ath9k/hw.c     |   11 ++++-
 drivers/net/wireless/ath/ath9k/mac.c    |   13 ++++++
 drivers/net/wireless/ath/ath9k/mac.h    |    1 +
 drivers/net/wireless/ath/ath9k/main.c   |   72 +++++++++++++++++++------------
 8 files changed, 74 insertions(+), 47 deletions(-)


^ permalink raw reply

* Re: [PATCH] libertas: separate libertas' Kconfig in it's own file
From: Andrey Yurovsky @ 2009-10-07  1:15 UTC (permalink / raw)
  To: Dan Williams; +Cc: Holger Schurig, linux-wireless, John W Linville
In-Reply-To: <1254868789.8034.0.camel@localhost.localdomain>

On Tue, Oct 6, 2009 at 3:39 PM, Dan Williams <dcbw@redhat.com> wrote:
> On Tue, 2009-10-06 at 16:31 +0200, Holger Schurig wrote:
>> Also sorts all "source" lines in the wireless/Kconfig.
>>
>> Signed-off-by: Holger Schurig <hs4233@mail.mn-solutions.de>
>
> Yeah, we've got a lot more options now.
>
> Acked-by: Dan Williams <dcbw@redhat.com>

LIBERTAS_CS does a "select FW_LOADER" that's already selected by
LIBERTAS, so we should probably remove that line.  Probably worth a
separate (trivial) patch?

  -Andrey

>> Index: linux-wl/drivers/net/wireless/Kconfig
>> ===================================================================
>> --- linux-wl.orig/drivers/net/wireless/Kconfig        2009-10-06 07:55:26.000000000 +0200
>> +++ linux-wl/drivers/net/wireless/Kconfig     2009-10-06 07:58:05.000000000 +0200
>> @@ -139,47 +139,6 @@ config PCMCIA_RAYCS
>>         To compile this driver as a module, choose M here: the module will be
>>         called ray_cs.  If unsure, say N.
>>
>> -config LIBERTAS
>> -     tristate "Marvell 8xxx Libertas WLAN driver support"
>> -     depends on WLAN_80211
>> -     select WIRELESS_EXT
>> -     select WEXT_SPY
>> -     select LIB80211
>> -     select FW_LOADER
>> -     ---help---
>> -       A library for Marvell Libertas 8xxx devices.
>> -
>> -config LIBERTAS_USB
>> -     tristate "Marvell Libertas 8388 USB 802.11b/g cards"
>> -     depends on LIBERTAS && USB
>> -     ---help---
>> -       A driver for Marvell Libertas 8388 USB devices.
>> -
>> -config LIBERTAS_CS
>> -     tristate "Marvell Libertas 8385 CompactFlash 802.11b/g cards"
>> -     depends on LIBERTAS && PCMCIA
>> -     select FW_LOADER
>> -     ---help---
>> -       A driver for Marvell Libertas 8385 CompactFlash devices.
>> -
>> -config LIBERTAS_SDIO
>> -     tristate "Marvell Libertas 8385/8686/8688 SDIO 802.11b/g cards"
>> -     depends on LIBERTAS && MMC
>> -     ---help---
>> -       A driver for Marvell Libertas 8385/8686/8688 SDIO devices.
>> -
>> -config LIBERTAS_SPI
>> -     tristate "Marvell Libertas 8686 SPI 802.11b/g cards"
>> -     depends on LIBERTAS && SPI
>> -     ---help---
>> -       A driver for Marvell Libertas 8686 SPI devices.
>> -
>> -config LIBERTAS_DEBUG
>> -     bool "Enable full debugging output in the Libertas module."
>> -     depends on LIBERTAS
>> -     ---help---
>> -       Debugging support.
>> -
>>  config LIBERTAS_THINFIRM
>>       tristate "Marvell 8xxx Libertas WLAN driver support with thin firmware"
>>       depends on WLAN_80211 && MAC80211
>> @@ -491,17 +450,18 @@ config MWL8K
>>         To compile this driver as a module, choose M here: the module
>>         will be called mwl8k.  If unsure, say N.
>>
>> -source "drivers/net/wireless/p54/Kconfig"
>>  source "drivers/net/wireless/ath/Kconfig"
>> -source "drivers/net/wireless/ipw2x00/Kconfig"
>> -source "drivers/net/wireless/iwlwifi/Kconfig"
>> -source "drivers/net/wireless/hostap/Kconfig"
>>  source "drivers/net/wireless/b43/Kconfig"
>>  source "drivers/net/wireless/b43legacy/Kconfig"
>> -source "drivers/net/wireless/zd1211rw/Kconfig"
>> -source "drivers/net/wireless/rt2x00/Kconfig"
>> +source "drivers/net/wireless/hostap/Kconfig"
>> +source "drivers/net/wireless/ipw2x00/Kconfig"
>> +source "drivers/net/wireless/iwlwifi/Kconfig"
>> +source "drivers/net/wireless/iwmc3200wifi/Kconfig"
>> +source "drivers/net/wireless/libertas/Kconfig"
>>  source "drivers/net/wireless/orinoco/Kconfig"
>> +source "drivers/net/wireless/p54/Kconfig"
>> +source "drivers/net/wireless/rt2x00/Kconfig"
>>  source "drivers/net/wireless/wl12xx/Kconfig"
>> -source "drivers/net/wireless/iwmc3200wifi/Kconfig"
>> +source "drivers/net/wireless/zd1211rw/Kconfig"
>>
>>  endif # WLAN
>> Index: linux-wl/drivers/net/wireless/libertas/Makefile
>> ===================================================================
>> --- linux-wl.orig/drivers/net/wireless/libertas/Makefile      2009-10-06 07:55:26.000000000 +0200
>> +++ linux-wl/drivers/net/wireless/libertas/Makefile   2009-10-06 07:58:25.000000000 +0200
>> @@ -1,5 +1,15 @@
>> -libertas-objs := main.o wext.o rx.o tx.o cmd.o cmdresp.o scan.o 11d.o        \
>> -              debugfs.o persistcfg.o ethtool.o assoc.o
>> +libertas-y += 11d.o
>> +libertas-y += assoc.o
>> +libertas-y += cmd.o
>> +libertas-y += cmdresp.o
>> +libertas-y += debugfs.o
>> +libertas-y += ethtool.o
>> +libertas-y += main.o
>> +libertas-y += persistcfg.o
>> +libertas-y += rx.o
>> +libertas-y += scan.o
>> +libertas-y += tx.o
>> +libertas-y += wext.o
>>
>>  usb8xxx-objs += if_usb.o
>>  libertas_cs-objs += if_cs.o
>> Index: linux-wl/drivers/net/wireless/libertas/Kconfig
>> ===================================================================
>> --- /dev/null 1970-01-01 00:00:00.000000000 +0000
>> +++ linux-wl/drivers/net/wireless/libertas/Kconfig    2009-10-06 07:58:15.000000000 +0200
>> @@ -0,0 +1,40 @@
>> +config LIBERTAS
>> +     tristate "Marvell 8xxx Libertas WLAN driver support"
>> +     depends on WLAN_80211
>> +     select WIRELESS_EXT
>> +     select WEXT_SPY
>> +     select LIB80211
>> +     select FW_LOADER
>> +     ---help---
>> +       A library for Marvell Libertas 8xxx devices.
>> +
>> +config LIBERTAS_USB
>> +     tristate "Marvell Libertas 8388 USB 802.11b/g cards"
>> +     depends on LIBERTAS && USB
>> +     ---help---
>> +       A driver for Marvell Libertas 8388 USB devices.
>> +
>> +config LIBERTAS_CS
>> +     tristate "Marvell Libertas 8385 CompactFlash 802.11b/g cards"
>> +     depends on LIBERTAS && PCMCIA
>> +     select FW_LOADER
>> +     ---help---
>> +       A driver for Marvell Libertas 8385 CompactFlash devices.
>> +
>> +config LIBERTAS_SDIO
>> +     tristate "Marvell Libertas 8385/8686/8688 SDIO 802.11b/g cards"
>> +     depends on LIBERTAS && MMC
>> +     ---help---
>> +       A driver for Marvell Libertas 8385/8686/8688 SDIO devices.
>> +
>> +config LIBERTAS_SPI
>> +     tristate "Marvell Libertas 8686 SPI 802.11b/g cards"
>> +     depends on LIBERTAS && SPI
>> +     ---help---
>> +       A driver for Marvell Libertas 8686 SPI devices.
>> +
>> +config LIBERTAS_DEBUG
>> +     bool "Enable full debugging output in the Libertas module."
>> +     depends on LIBERTAS
>> +     ---help---
>> +       Debugging support.
>>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply

* RE: [PATCH] libertas: Use lbs_is_cmd_allowed() check in command handling routines.
From: Bing Zhao @ 2009-10-07  1:12 UTC (permalink / raw)
  To: Andrey Yurovsky
  Cc: libertas-dev@lists.infradead.org, Amitkumar Karwar,
	linux-wireless@vger.kernel.org
In-Reply-To: <45e8e6c40910061801u2b67abb5v4658a7bbf1e0726a@mail.gmail.com>

Hi Andrey,

> -----Original Message-----
> From: Andrey Yurovsky [mailto:andrey@cozybit.com]
> Sent: Tuesday, October 06, 2009 6:01 PM
> To: Bing Zhao
> Cc: libertas-dev@lists.infradead.org; Amitkumar Karwar; linux-wireless@vger.kernel.org
> Subject: Re: [PATCH] libertas: Use lbs_is_cmd_allowed() check in command handling routines.
> 
> Hi Bing,
> 
> On Tue, Oct 6, 2009 at 5:02 PM, Bing Zhao <bzhao@marvell.com> wrote:
> > From: Amitkumar Karwar <akarwar@marvell.com>
> > +static int lbs_is_cmd_allowed(struct lbs_private *priv)
> > +{
> > +       int         ret = 1;
> > +
> > +       lbs_deb_enter(LBS_DEB_CMD);
> > +
> > +       if (!priv->is_auto_deep_sleep_enabled) {
> > +               if (priv->is_deep_sleep) {
> > +                       lbs_deb_cmd("IOCTLS called when station"
> > +                                       " is in deep sleep\n");
> > +                       ret = 0;
> > +               }
> > +       }
> 
> Can this debug message be something like "command not allowed in deep
> sleep" instead of mentioning IOCTLS?

Thanks for your suggestion. Yes, it will be changed.

Regards,

Bing

> 
>   -Andrey

^ permalink raw reply

* Re: [PATCH] libertas: Use lbs_is_cmd_allowed() check in command handling routines.
From: Andrey Yurovsky @ 2009-10-07  1:01 UTC (permalink / raw)
  To: Bing Zhao; +Cc: libertas-dev, Amitkumar Karwar, linux-wireless
In-Reply-To: <1254873770-31241-1-git-send-email-bzhao@marvell.com>

Hi Bing,

On Tue, Oct 6, 2009 at 5:02 PM, Bing Zhao <bzhao@marvell.com> wrote:
> From: Amitkumar Karwar <akarwar@marvell.com>
> +static int lbs_is_cmd_allowed(struct lbs_private *priv)
> +{
> +       int         ret = 1;
> +
> +       lbs_deb_enter(LBS_DEB_CMD);
> +
> +       if (!priv->is_auto_deep_sleep_enabled) {
> +               if (priv->is_deep_sleep) {
> +                       lbs_deb_cmd("IOCTLS called when station"
> +                                       " is in deep sleep\n");
> +                       ret = 0;
> +               }
> +       }

Can this debug message be something like "command not allowed in deep
sleep" instead of mentioning IOCTLS?

  -Andrey

^ permalink raw reply

* [PATCH 2/7] ath5k: use ath_hw_setbssidmask() for bssid mask setting upon assoc
From: Luis R. Rodriguez @ 2009-10-07  0:44 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez
In-Reply-To: <1254876274-1145-1-git-send-email-lrodriguez@atheros.com>

This should avoid future typos.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath5k/pcu.c |    9 ++-------
 1 files changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c
index 0385e80..32fd5f8 100644
--- a/drivers/net/wireless/ath/ath5k/pcu.c
+++ b/drivers/net/wireless/ath/ath5k/pcu.c
@@ -288,13 +288,8 @@ void ath5k_hw_set_associd(struct ath5k_hw *ah, const u8 *bssid, u16 assoc_id)
 	/*
 	 * Set simple BSSID mask on 5212
 	 */
-	if (ah->ah_version == AR5K_AR5212) {
-		ath5k_hw_reg_write(ah, get_unaligned_le32(common->bssidmask),
-				   AR_BSSMSKL);
-		ath5k_hw_reg_write(ah,
-				   get_unaligned_le16(common->bssidmask + 4),
-				   AR_BSSMSKU);
-	}
+	if (ah->ah_version == AR5K_AR5212)
+		ath_hw_setbssidmask(common);
 
 	/*
 	 * Set BSSID which triggers the "SME Join" operation
-- 
1.6.0.4


^ permalink raw reply related

* [PATCH 5/7] ath5k: remove temporary low_id and high_id vars on ath5k_hw_set_associd()
From: Luis R. Rodriguez @ 2009-10-07  0:44 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez
In-Reply-To: <1254876274-1145-1-git-send-email-lrodriguez@atheros.com>

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath5k/pcu.c |   15 ++++++++-------
 1 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c
index 23e5e7e..2ab9c0e 100644
--- a/drivers/net/wireless/ath/ath5k/pcu.c
+++ b/drivers/net/wireless/ath/ath5k/pcu.c
@@ -282,7 +282,6 @@ int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac)
 void ath5k_hw_set_associd(struct ath5k_hw *ah)
 {
 	struct ath_common *common = ath5k_hw_common(ah);
-	u32 low_id, high_id;
 	u16 tim_offset = 0;
 
 	/*
@@ -294,11 +293,13 @@ void ath5k_hw_set_associd(struct ath5k_hw *ah)
 	/*
 	 * Set BSSID which triggers the "SME Join" operation
 	 */
-	low_id = get_unaligned_le32(common->curbssid);
-	high_id = get_unaligned_le16(common->curbssid + 4);
-	ath5k_hw_reg_write(ah, low_id, AR_BSSMSKL);
-	ath5k_hw_reg_write(ah, high_id | ((common->curaid & 0x3fff) <<
-				AR5K_BSS_ID1_AID_S), AR_BSSMSKU);
+	ath5k_hw_reg_write(ah,
+			   get_unaligned_le32(common->curbssid),
+			   AR_BSSMSKL);
+	ath5k_hw_reg_write(ah,
+			   get_unaligned_le16(common->curbssid + 4) |
+			   ((common->curaid & 0x3fff) << AR5K_BSS_ID1_AID_S),
+			   AR_BSSMSKU);
 
 	if (common->curaid == 0) {
 		ath5k_hw_disable_pspoll(ah);
@@ -306,7 +307,7 @@ void ath5k_hw_set_associd(struct ath5k_hw *ah)
 	}
 
 	AR5K_REG_WRITE_BITS(ah, AR5K_BEACON, AR5K_BEACON_TIM,
-			tim_offset ? tim_offset + 4 : 0);
+			    tim_offset ? tim_offset + 4 : 0);
 
 	ath5k_hw_enable_pspoll(ah, NULL, 0);
 }
-- 
1.6.0.4


^ permalink raw reply related

* [PATCH 0/7] ath5k: few fixes for regressions
From: Luis R. Rodriguez @ 2009-10-07  0:44 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez

I wasn't able to connect to some AP and it turned out the issue
was a few regressions introduced in my series. It was hard to note
as I was able to connect at work and at home, so I guess this would
only have been seen with some specific APs. This series fixed my
connection but since I introduced them I figured I'd throw in
an extra patch at the end for setting the association ID.

Luis R. Rodriguez (7):
  ath5k: fix regression on setting bssid mask on association
  ath5k: use ath_hw_setbssidmask() for bssid mask setting upon assoc
  ath5k: fix regression introduced upon the removal of AR5K_HIGH_ID()
  ath5k: simplify passed params to ath5k_hw_set_associd()
  ath5k: remove temporary low_id and high_id vars on
    ath5k_hw_set_associd()
  ath5k: fix regression which triggers an SME join upon assoc
  ath5k: enable Power-Save Polls by setting the association ID

 drivers/net/wireless/ath/ath5k/ath5k.h  |    2 +-
 drivers/net/wireless/ath/ath5k/attach.c |    2 +-
 drivers/net/wireless/ath/ath5k/base.c   |   13 ++++++++++---
 drivers/net/wireless/ath/ath5k/pcu.c    |   30 +++++++++++++-----------------
 drivers/net/wireless/ath/ath5k/reset.c  |    5 ++---
 5 files changed, 27 insertions(+), 25 deletions(-)


^ permalink raw reply

* [PATCH 3/7] ath5k: fix regression introduced upon the removal of AR5K_HIGH_ID()
From: Luis R. Rodriguez @ 2009-10-07  0:44 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez
In-Reply-To: <1254876274-1145-1-git-send-email-lrodriguez@atheros.com>

The trick was to add four bytes whenever this was used. There
are two places where this was missed.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath5k/pcu.c   |    2 +-
 drivers/net/wireless/ath/ath5k/reset.c |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c
index 32fd5f8..9e6e41b 100644
--- a/drivers/net/wireless/ath/ath5k/pcu.c
+++ b/drivers/net/wireless/ath/ath5k/pcu.c
@@ -295,7 +295,7 @@ void ath5k_hw_set_associd(struct ath5k_hw *ah, const u8 *bssid, u16 assoc_id)
 	 * Set BSSID which triggers the "SME Join" operation
 	 */
 	low_id = get_unaligned_le32(bssid);
-	high_id = get_unaligned_le16(bssid);
+	high_id = get_unaligned_le16(bssid + 4);
 	ath5k_hw_reg_write(ah, low_id, AR_BSSMSKL);
 	ath5k_hw_reg_write(ah, high_id | ((assoc_id & 0x3fff) <<
 				AR5K_BSS_ID1_AID_S), AR_BSSMSKU);
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index 51aff76..39346a2 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -1178,7 +1178,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
 			   get_unaligned_le32(common->macaddr),
 			   AR5K_STA_ID0);
 	ath5k_hw_reg_write(ah,
-			   staid1_flags | get_unaligned_le16(common->macaddr),
+			   staid1_flags | get_unaligned_le16(common->macaddr + 4),
 			   AR5K_STA_ID1);
 
 
-- 
1.6.0.4


^ permalink raw reply related

* [PATCH 4/7] ath5k: simplify passed params to ath5k_hw_set_associd()
From: Luis R. Rodriguez @ 2009-10-07  0:44 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez
In-Reply-To: <1254876274-1145-1-git-send-email-lrodriguez@atheros.com>

We have access to common->curbssid and common->curaid so just
use those. Note that common->curaid is always 0 so this keeps
our current behaviour of always using 0 for now. Once we fix
storing the association ID passed by mac80211 this will
require no changes here.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath5k/ath5k.h  |    2 +-
 drivers/net/wireless/ath/ath5k/attach.c |    2 +-
 drivers/net/wireless/ath/ath5k/base.c   |    2 +-
 drivers/net/wireless/ath/ath5k/pcu.c    |   10 +++++-----
 drivers/net/wireless/ath/ath5k/reset.c  |    2 +-
 5 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index 43585d5..647d826 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -1191,7 +1191,7 @@ extern bool ath5k_eeprom_is_hb63(struct ath5k_hw *ah);
 extern int ath5k_hw_set_opmode(struct ath5k_hw *ah);
 /* BSSID Functions */
 extern int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac);
-extern void ath5k_hw_set_associd(struct ath5k_hw *ah, const u8 *bssid, u16 assoc_id);
+extern void ath5k_hw_set_associd(struct ath5k_hw *ah);
 extern void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask);
 /* Receive start/stop functions */
 extern void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah);
diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c
index e230de8..92995ad 100644
--- a/drivers/net/wireless/ath/ath5k/attach.c
+++ b/drivers/net/wireless/ath/ath5k/attach.c
@@ -326,7 +326,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
 
 	/* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */
 	memcpy(common->curbssid, ath_bcast_mac, ETH_ALEN);
-	ath5k_hw_set_associd(ah, common->curbssid, 0);
+	ath5k_hw_set_associd(ah);
 	ath5k_hw_set_opmode(ah);
 
 	ath5k_hw_rfgain_opt_init(ah);
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 5aaa9bd..01da83d 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -3213,7 +3213,7 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
 		memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
 		/* XXX: assoc id is set to 0 for now, mac80211 doesn't have
 		 * a clean way of letting us retrieve this yet. */
-		ath5k_hw_set_associd(ah, common->curbssid, 0);
+		ath5k_hw_set_associd(ah);
 		mmiowb();
 	}
 
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c
index 9e6e41b..23e5e7e 100644
--- a/drivers/net/wireless/ath/ath5k/pcu.c
+++ b/drivers/net/wireless/ath/ath5k/pcu.c
@@ -279,7 +279,7 @@ int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac)
  *
  * Sets the BSSID which trigers the "SME Join" operation
  */
-void ath5k_hw_set_associd(struct ath5k_hw *ah, const u8 *bssid, u16 assoc_id)
+void ath5k_hw_set_associd(struct ath5k_hw *ah)
 {
 	struct ath_common *common = ath5k_hw_common(ah);
 	u32 low_id, high_id;
@@ -294,13 +294,13 @@ void ath5k_hw_set_associd(struct ath5k_hw *ah, const u8 *bssid, u16 assoc_id)
 	/*
 	 * Set BSSID which triggers the "SME Join" operation
 	 */
-	low_id = get_unaligned_le32(bssid);
-	high_id = get_unaligned_le16(bssid + 4);
+	low_id = get_unaligned_le32(common->curbssid);
+	high_id = get_unaligned_le16(common->curbssid + 4);
 	ath5k_hw_reg_write(ah, low_id, AR_BSSMSKL);
-	ath5k_hw_reg_write(ah, high_id | ((assoc_id & 0x3fff) <<
+	ath5k_hw_reg_write(ah, high_id | ((common->curaid & 0x3fff) <<
 				AR5K_BSS_ID1_AID_S), AR_BSSMSKU);
 
-	if (assoc_id == 0) {
+	if (common->curaid == 0) {
 		ath5k_hw_disable_pspoll(ah);
 		return;
 	}
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index 39346a2..fb89815 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -1188,7 +1188,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
 
 	/* Restore bssid and bssid mask */
 	/* XXX: add ah->aid once mac80211 gives this to us */
-	ath5k_hw_set_associd(ah, common->curbssid, 0);
+	ath5k_hw_set_associd(ah);
 
 	/* Set PCU config */
 	ath5k_hw_set_opmode(ah);
-- 
1.6.0.4


^ permalink raw reply related

* [PATCH 7/7] ath5k: enable Power-Save Polls by setting the association ID
From: Luis R. Rodriguez @ 2009-10-07  0:44 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez
In-Reply-To: <1254876274-1145-1-git-send-email-lrodriguez@atheros.com>

mac80211 has long provided us the association ID. This isn't useful except
for Power-Save polling which now gets enabled. We can now poll for our
pending frames on the AP during power save.

You can review the details of Power-Save on the wireless wiki:

http://wireless.kernel.org/en/developers/Documentation/ieee80211/power-savings

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath5k/base.c  |   11 +++++++++--
 drivers/net/wireless/ath/ath5k/reset.c |    1 -
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 01da83d..07c1e52 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -3211,8 +3211,7 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
 	if (changes & BSS_CHANGED_BSSID) {
 		/* Cache for later use during resets */
 		memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
-		/* XXX: assoc id is set to 0 for now, mac80211 doesn't have
-		 * a clean way of letting us retrieve this yet. */
+		common->curaid = 0;
 		ath5k_hw_set_associd(ah);
 		mmiowb();
 	}
@@ -3226,6 +3225,14 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
 			set_beacon_filter(hw, sc->assoc);
 		ath5k_hw_set_ledstate(sc->ah, sc->assoc ?
 			AR5K_LED_ASSOC : AR5K_LED_INIT);
+		if (bss_conf->assoc) {
+			ATH5K_DBG(sc, ATH5K_DEBUG_ANY,
+				  "Bss Info ASSOC %d, bssid: %pM\n",
+				  bss_conf->aid, common->curbssid);
+			common->curaid = bss_conf->aid;
+			ath5k_hw_set_associd(ah);
+			/* Once ANI is available you would start it here */
+		}
 	}
 
 	if (changes & BSS_CHANGED_BEACON) {
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index fb89815..3dab3d8 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -1187,7 +1187,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
 	 */
 
 	/* Restore bssid and bssid mask */
-	/* XXX: add ah->aid once mac80211 gives this to us */
 	ath5k_hw_set_associd(ah);
 
 	/* Set PCU config */
-- 
1.6.0.4


^ permalink raw reply related

* [PATCH 1/7] ath5k: fix regression on setting bssid mask on association
From: Luis R. Rodriguez @ 2009-10-07  0:44 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez
In-Reply-To: <1254876274-1145-1-git-send-email-lrodriguez@atheros.com>

There was a typo on the second bssid mask register.
This was caused by the patch titled:

"ath5k: use common curbssid, bssidmask and macaddr"

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath5k/pcu.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c
index 9ac7638..0385e80 100644
--- a/drivers/net/wireless/ath/ath5k/pcu.c
+++ b/drivers/net/wireless/ath/ath5k/pcu.c
@@ -292,7 +292,7 @@ void ath5k_hw_set_associd(struct ath5k_hw *ah, const u8 *bssid, u16 assoc_id)
 		ath5k_hw_reg_write(ah, get_unaligned_le32(common->bssidmask),
 				   AR_BSSMSKL);
 		ath5k_hw_reg_write(ah,
-				   get_unaligned_le16(common->curbssid + 4),
+				   get_unaligned_le16(common->bssidmask + 4),
 				   AR_BSSMSKU);
 	}
 
-- 
1.6.0.4


^ permalink raw reply related

* [PATCH 6/7] ath5k: fix regression which triggers an SME join upon assoc
From: Luis R. Rodriguez @ 2009-10-07  0:44 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Luis R. Rodriguez
In-Reply-To: <1254876274-1145-1-git-send-email-lrodriguez@atheros.com>

This fixes a regression introduced by patch titled:

"atheros: define shared bssidmask setting"

The register for the BSSID was exchanged for the bssid mask register.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath5k/pcu.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c
index 2ab9c0e..64fc1eb 100644
--- a/drivers/net/wireless/ath/ath5k/pcu.c
+++ b/drivers/net/wireless/ath/ath5k/pcu.c
@@ -295,11 +295,11 @@ void ath5k_hw_set_associd(struct ath5k_hw *ah)
 	 */
 	ath5k_hw_reg_write(ah,
 			   get_unaligned_le32(common->curbssid),
-			   AR_BSSMSKL);
+			   AR5K_BSS_ID0);
 	ath5k_hw_reg_write(ah,
 			   get_unaligned_le16(common->curbssid + 4) |
 			   ((common->curaid & 0x3fff) << AR5K_BSS_ID1_AID_S),
-			   AR_BSSMSKU);
+			   AR5K_BSS_ID1);
 
 	if (common->curaid == 0) {
 		ath5k_hw_disable_pspoll(ah);
-- 
1.6.0.4


^ permalink raw reply related

* Re: [ath5k-devel] Regarding changing channel widthlin
From: Luis R. Rodriguez @ 2009-10-07  0:21 UTC (permalink / raw)
  To: Nick Kossifidis; +Cc: Aditya, ath5k-devel, linux-wireless

On Tue, Oct 6, 2009 at 5:17 PM, Nick Kossifidis <mickflemm@gmail.com> wrote:
> Until we have a
> clean way to set this through cfg80211/nl80211 (which is an ongoing
> discussion) we wont support 5/10Mhz operation but you can try and let
> us know.

I believe the cfg80211/nl80211 changes is probably the bulk of the
work that does need to get done. Someone motivated just needs to do
it.

   Luis

^ permalink raw reply

* [PATCH] libertas: Use lbs_is_cmd_allowed() check in command handling routines.
From: Bing Zhao @ 2009-10-07  0:02 UTC (permalink / raw)
  To: libertas-dev; +Cc: linux-wireless, Bing Zhao, Amitkumar Karwar

From: Amitkumar Karwar <akarwar@marvell.com>

lbs_is_cmd_allowed() check is added in __lbs_cmd_async() and
lbs_prepare_and_send_command(). The check is removed from other places.

Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
---
 drivers/net/wireless/libertas/cmd.c     |   35 ++++++++
 drivers/net/wireless/libertas/debugfs.c |   46 -----------
 drivers/net/wireless/libertas/decl.h    |    1 -
 drivers/net/wireless/libertas/scan.c    |   11 ---
 drivers/net/wireless/libertas/wext.c    |  133 -------------------------------
 5 files changed, 35 insertions(+), 191 deletions(-)

diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index 3a3e894..c2d9e28 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -75,6 +75,31 @@ static u8 is_command_allowed_in_ps(u16 cmd)
 }
 
 /**
+ *  @brief This function checks if the command is allowed.
+ *
+ *  @param priv         A pointer to lbs_private structure
+ *  @return             allowed or not allowed.
+ */
+
+static int lbs_is_cmd_allowed(struct lbs_private *priv)
+{
+	int         ret = 1;
+
+	lbs_deb_enter(LBS_DEB_CMD);
+
+	if (!priv->is_auto_deep_sleep_enabled) {
+		if (priv->is_deep_sleep) {
+			lbs_deb_cmd("IOCTLS called when station"
+					" is in deep sleep\n");
+			ret = 0;
+		}
+	}
+
+	lbs_deb_leave(LBS_DEB_CMD);
+	return ret;
+}
+
+/**
  *  @brief Updates the hardware details like MAC address and regulatory region
  *
  *  @param priv    	A pointer to struct lbs_private structure
@@ -1452,6 +1477,11 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
 		goto done;
 	}
 
+	if (!lbs_is_cmd_allowed(priv)) {
+		ret = -EBUSY;
+		goto done;
+	}
+
 	cmdnode = lbs_get_cmd_ctrl_node(priv);
 
 	if (cmdnode == NULL) {
@@ -2104,6 +2134,11 @@ static struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv,
 		goto done;
 	}
 
+	if (!lbs_is_cmd_allowed(priv)) {
+		cmdnode = ERR_PTR(-EBUSY);
+		goto done;
+	}
+
 	cmdnode = lbs_get_cmd_ctrl_node(priv);
 	if (cmdnode == NULL) {
 		lbs_deb_host("PREP_CMD: cmdnode is NULL\n");
diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c
index 8a7e931..893a55c 100644
--- a/drivers/net/wireless/libertas/debugfs.c
+++ b/drivers/net/wireless/libertas/debugfs.c
@@ -117,11 +117,6 @@ static ssize_t lbs_sleepparams_write(struct file *file,
 	if (!buf)
 		return -ENOMEM;
 
-	if (!lbs_is_cmd_allowed(priv)) {
-		ret = -EBUSY;
-		goto out_unlock;
-	}
-
 	buf_size = min(count, len - 1);
 	if (copy_from_user(buf, user_buf, buf_size)) {
 		ret = -EFAULT;
@@ -162,11 +157,6 @@ static ssize_t lbs_sleepparams_read(struct file *file, char __user *userbuf,
 	if (!buf)
 		return -ENOMEM;
 
-	if (!lbs_is_cmd_allowed(priv)) {
-		ret = -EBUSY;
-		goto out_unlock;
-	}
-
 	ret = lbs_cmd_802_11_sleep_params(priv, CMD_ACT_GET, &sp);
 	if (ret)
 		goto out_unlock;
@@ -233,9 +223,6 @@ static ssize_t lbs_threshold_read(uint16_t tlv_type, uint16_t event_mask,
 	u8 freq;
 	int events = 0;
 
-	if (!lbs_is_cmd_allowed(priv))
-		return -EBUSY;
-
 	buf = (char *)get_zeroed_page(GFP_KERNEL);
 	if (!buf)
 		return -ENOMEM;
@@ -288,9 +275,6 @@ static ssize_t lbs_threshold_write(uint16_t tlv_type, uint16_t event_mask,
 	char *buf;
 	int ret;
 
-	if (!lbs_is_cmd_allowed(priv))
-		return -EBUSY;
-
 	buf = (char *)get_zeroed_page(GFP_KERNEL);
 	if (!buf)
 		return -ENOMEM;
@@ -460,11 +444,6 @@ static ssize_t lbs_rdmac_read(struct file *file, char __user *userbuf,
 	if (!buf)
 		return -ENOMEM;
 
-	if (!lbs_is_cmd_allowed(priv)) {
-		free_page(addr);
-		return -EBUSY;
-	}
-
 	offval.offset = priv->mac_offset;
 	offval.value = 0;
 
@@ -517,11 +496,6 @@ static ssize_t lbs_wrmac_write(struct file *file,
 	if (!buf)
 		return -ENOMEM;
 
-	if (!lbs_is_cmd_allowed(priv)) {
-		res = -EBUSY;
-		goto out_unlock;
-	}
-
 	buf_size = min(count, len - 1);
 	if (copy_from_user(buf, userbuf, buf_size)) {
 		res = -EFAULT;
@@ -558,11 +532,6 @@ static ssize_t lbs_rdbbp_read(struct file *file, char __user *userbuf,
 	if (!buf)
 		return -ENOMEM;
 
-	if (!lbs_is_cmd_allowed(priv)) {
-		free_page(addr);
-		return -EBUSY;
-	}
-
 	offval.offset = priv->bbp_offset;
 	offval.value = 0;
 
@@ -616,11 +585,6 @@ static ssize_t lbs_wrbbp_write(struct file *file,
 	if (!buf)
 		return -ENOMEM;
 
-	if (!lbs_is_cmd_allowed(priv)) {
-		res = -EBUSY;
-		goto out_unlock;
-	}
-
 	buf_size = min(count, len - 1);
 	if (copy_from_user(buf, userbuf, buf_size)) {
 		res = -EFAULT;
@@ -657,11 +621,6 @@ static ssize_t lbs_rdrf_read(struct file *file, char __user *userbuf,
 	if (!buf)
 		return -ENOMEM;
 
-	if (!lbs_is_cmd_allowed(priv)) {
-		free_page(addr);
-		return -EBUSY;
-	}
-
 	offval.offset = priv->rf_offset;
 	offval.value = 0;
 
@@ -715,11 +674,6 @@ static ssize_t lbs_wrrf_write(struct file *file,
 	if (!buf)
 		return -ENOMEM;
 
-	if (!lbs_is_cmd_allowed(priv)) {
-		res = -EBUSY;
-		goto out_unlock;
-	}
-
 	buf_size = min(count, len - 1);
 	if (copy_from_user(buf, userbuf, buf_size)) {
 		res = -EFAULT;
diff --git a/drivers/net/wireless/libertas/decl.h b/drivers/net/wireless/libertas/decl.h
index 34b475f..e47bf19 100644
--- a/drivers/net/wireless/libertas/decl.h
+++ b/drivers/net/wireless/libertas/decl.h
@@ -34,7 +34,6 @@ int lbs_process_event(struct lbs_private *priv, u32 event);
 void lbs_queue_event(struct lbs_private *priv, u32 event);
 void lbs_notify_command_response(struct lbs_private *priv, u8 resp_idx);
 int lbs_set_deep_sleep(struct lbs_private *priv, int deep_sleep);
-int lbs_is_cmd_allowed(struct lbs_private *priv);
 int lbs_enter_auto_deep_sleep(struct lbs_private *priv);
 int lbs_exit_auto_deep_sleep(struct lbs_private *priv);
 
diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c
index e468e15..6c95af3 100644
--- a/drivers/net/wireless/libertas/scan.c
+++ b/drivers/net/wireless/libertas/scan.c
@@ -950,11 +950,6 @@ int lbs_set_scan(struct net_device *dev, struct iw_request_info *info,
 
 	lbs_deb_enter(LBS_DEB_WEXT);
 
-	if (!lbs_is_cmd_allowed(priv)) {
-		ret = -EBUSY;
-		goto out;
-	}
-
 	if (!priv->radio_on) {
 		ret = -EINVAL;
 		goto out;
@@ -1022,12 +1017,6 @@ int lbs_get_scan(struct net_device *dev, struct iw_request_info *info,
 
 	lbs_deb_enter(LBS_DEB_WEXT);
 
-	if (!lbs_is_cmd_allowed(priv)) {
-		err = -EBUSY;
-		lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", err);
-		return err;
-	}
-
 	/* iwlist should wait until the current scan is finished */
 	if (priv->scan_channel)
 		return -EAGAIN;
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
index 38a451e..69dd19b 100644
--- a/drivers/net/wireless/libertas/wext.c
+++ b/drivers/net/wireless/libertas/wext.c
@@ -46,32 +46,6 @@ static inline void lbs_cancel_association_work(struct lbs_private *priv)
 }
 
 /**
- *  @brief This function checks if the command is allowed.
- *
- *  @param priv         A pointer to lbs_private structure
- *  @return             allowed or not allowed.
- */
-
-int lbs_is_cmd_allowed(struct lbs_private *priv)
-{
-	int         ret = 1;
-
-	lbs_deb_enter(LBS_DEB_WEXT);
-
-	if (!priv->is_auto_deep_sleep_enabled) {
-		if (priv->is_deep_sleep) {
-			lbs_deb_wext("IOCTLS called when station"
-					"is in deep sleep\n");
-			ret = 0;
-		}
-	}
-
-	lbs_deb_leave(LBS_DEB_WEXT);
-	return ret;
-}
-
-
-/**
  *  @brief Find the channel frequency power info with specific channel
  *
  *  @param priv 	A pointer to struct lbs_private structure
@@ -193,11 +167,6 @@ static int lbs_get_freq(struct net_device *dev, struct iw_request_info *info,
 
 	lbs_deb_enter(LBS_DEB_WEXT);
 
-	if (!lbs_is_cmd_allowed(priv)) {
-		lbs_deb_leave(LBS_DEB_WEXT);
-		return -EBUSY;
-	}
-
 	cfp = lbs_find_cfp_by_band_and_channel(priv, 0,
 					   priv->curbssparams.channel);
 
@@ -308,12 +277,6 @@ static int lbs_set_rts(struct net_device *dev, struct iw_request_info *info,
 
 	lbs_deb_enter(LBS_DEB_WEXT);
 
-	if (!lbs_is_cmd_allowed(priv)) {
-		ret = -EBUSY;
-		lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
-		return ret;
-	}
-
 	if (vwrq->disabled)
 		val = MRVDRV_RTS_MAX_VALUE;
 
@@ -335,11 +298,6 @@ static int lbs_get_rts(struct net_device *dev, struct iw_request_info *info,
 
 	lbs_deb_enter(LBS_DEB_WEXT);
 
-	if (!lbs_is_cmd_allowed(priv)) {
-		ret = -EBUSY;
-		goto out;
-	}
-
 	ret = lbs_get_snmp_mib(priv, SNMP_MIB_OID_RTS_THRESHOLD, &val);
 	if (ret)
 		goto out;
@@ -362,12 +320,6 @@ static int lbs_set_frag(struct net_device *dev, struct iw_request_info *info,
 
 	lbs_deb_enter(LBS_DEB_WEXT);
 
-	if (!lbs_is_cmd_allowed(priv)) {
-		ret = -EBUSY;
-		lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
-		return ret;
-	}
-
 	if (vwrq->disabled)
 		val = MRVDRV_FRAG_MAX_VALUE;
 
@@ -389,11 +341,6 @@ static int lbs_get_frag(struct net_device *dev, struct iw_request_info *info,
 
 	lbs_deb_enter(LBS_DEB_WEXT);
 
-	if (!lbs_is_cmd_allowed(priv)) {
-		ret = -EBUSY;
-		goto out;
-	}
-
 	ret = lbs_get_snmp_mib(priv, SNMP_MIB_OID_FRAG_THRESHOLD, &val);
 	if (ret)
 		goto out;
@@ -443,11 +390,6 @@ static int lbs_get_txpow(struct net_device *dev,
 
 	lbs_deb_enter(LBS_DEB_WEXT);
 
-	if (!lbs_is_cmd_allowed(priv)) {
-		ret = -EBUSY;
-		goto out;
-	}
-
 	if (!priv->radio_on) {
 		lbs_deb_wext("tx power off\n");
 		vwrq->value = 0;
@@ -481,11 +423,6 @@ static int lbs_set_retry(struct net_device *dev, struct iw_request_info *info,
 
 	lbs_deb_enter(LBS_DEB_WEXT);
 
-	if (!lbs_is_cmd_allowed(priv)) {
-		ret = -EBUSY;
-		goto out;
-	}
-
         if ((vwrq->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT)
                 return -EOPNOTSUPP;
 
@@ -534,11 +471,6 @@ static int lbs_get_retry(struct net_device *dev, struct iw_request_info *info,
 
 	lbs_deb_enter(LBS_DEB_WEXT);
 
-	if (!lbs_is_cmd_allowed(priv)) {
-		ret = -EBUSY;
-		goto out;
-	}
-
 	vwrq->disabled = 0;
 
 	if (vwrq->flags & IW_RETRY_LONG) {
@@ -907,9 +839,6 @@ static struct iw_statistics *lbs_get_wireless_stats(struct net_device *dev)
 
 	lbs_deb_enter(LBS_DEB_WEXT);
 
-	if (!lbs_is_cmd_allowed(priv))
-		return NULL;
-
 	priv->wstats.status = priv->mode;
 
 	/* If we're not associated, all quality values are meaningless */
@@ -1010,12 +939,6 @@ static int lbs_set_freq(struct net_device *dev, struct iw_request_info *info,
 
 	lbs_deb_enter(LBS_DEB_WEXT);
 
-	if (!lbs_is_cmd_allowed(priv)) {
-		ret = -EBUSY;
-		lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
-		return ret;
-	}
-
 	mutex_lock(&priv->lock);
 	assoc_req = lbs_get_association_request(priv);
 	if (!assoc_req) {
@@ -1125,11 +1048,6 @@ static int lbs_set_rate(struct net_device *dev, struct iw_request_info *info,
 
 	lbs_deb_enter(LBS_DEB_WEXT);
 
-	if (!lbs_is_cmd_allowed(priv)) {
-		ret = -EBUSY;
-		goto out;
-	}
-
 	lbs_deb_wext("vwrq->value %d\n", vwrq->value);
 	lbs_deb_wext("vwrq->fixed %d\n", vwrq->fixed);
 
@@ -1188,11 +1106,6 @@ static int lbs_get_rate(struct net_device *dev, struct iw_request_info *info,
 
 	lbs_deb_enter(LBS_DEB_WEXT);
 
-	if (!lbs_is_cmd_allowed(priv)) {
-		lbs_deb_leave(LBS_DEB_WEXT);
-		return -EBUSY;
-	}
-
 	if (priv->connect_status == LBS_CONNECTED) {
 		vwrq->value = priv->cur_rate * 500000;
 
@@ -1219,11 +1132,6 @@ static int lbs_set_mode(struct net_device *dev,
 
 	lbs_deb_enter(LBS_DEB_WEXT);
 
-	if (!lbs_is_cmd_allowed(priv)) {
-		ret = -EBUSY;
-		goto out;
-	}
-
 	if (   (*uwrq != IW_MODE_ADHOC)
 	    && (*uwrq != IW_MODE_INFRA)
 	    && (*uwrq != IW_MODE_AUTO)) {
@@ -1465,12 +1373,6 @@ static int lbs_set_encode(struct net_device *dev,
 
 	lbs_deb_enter(LBS_DEB_WEXT);
 
-	if (!lbs_is_cmd_allowed(priv)) {
-		ret = -EBUSY;
-		lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
-		return ret;
-	}
-
 	mutex_lock(&priv->lock);
 	assoc_req = lbs_get_association_request(priv);
 	if (!assoc_req) {
@@ -1654,12 +1556,6 @@ static int lbs_set_encodeext(struct net_device *dev,
 
 	lbs_deb_enter(LBS_DEB_WEXT);
 
-	if (!lbs_is_cmd_allowed(priv)) {
-		ret = -EBUSY;
-		lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
-		return ret;
-	}
-
 	mutex_lock(&priv->lock);
 	assoc_req = lbs_get_association_request(priv);
 	if (!assoc_req) {
@@ -1872,12 +1768,6 @@ static int lbs_set_auth(struct net_device *dev,
 
 	lbs_deb_enter(LBS_DEB_WEXT);
 
-	if (!lbs_is_cmd_allowed(priv)) {
-		ret = -EBUSY;
-		lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
-		return ret;
-	}
-
 	mutex_lock(&priv->lock);
 	assoc_req = lbs_get_association_request(priv);
 	if (!assoc_req) {
@@ -1980,12 +1870,6 @@ static int lbs_get_auth(struct net_device *dev,
 
 	lbs_deb_enter(LBS_DEB_WEXT);
 
-	if (!lbs_is_cmd_allowed(priv)) {
-		ret = -EBUSY;
-		lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
-		return ret;
-	}
-
 	switch (dwrq->flags & IW_AUTH_INDEX) {
 	case IW_AUTH_KEY_MGMT:
 		dwrq->value = priv->secinfo.key_mgmt;
@@ -2028,11 +1912,6 @@ static int lbs_set_txpow(struct net_device *dev, struct iw_request_info *info,
 
 	lbs_deb_enter(LBS_DEB_WEXT);
 
-	if (!lbs_is_cmd_allowed(priv)) {
-		ret = -EBUSY;
-		goto out;
-	}
-
 	if (vwrq->disabled) {
 		lbs_set_radio(priv, RADIO_PREAMBLE_AUTO, 0);
 		goto out;
@@ -2152,12 +2031,6 @@ static int lbs_set_essid(struct net_device *dev, struct iw_request_info *info,
 
 	lbs_deb_enter(LBS_DEB_WEXT);
 
-	if (!lbs_is_cmd_allowed(priv)) {
-		ret = -EBUSY;
-		lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
-		return ret;
-	}
-
 	if (!priv->radio_on) {
 		ret = -EINVAL;
 		goto out;
@@ -2285,12 +2158,6 @@ static int lbs_set_wap(struct net_device *dev, struct iw_request_info *info,
 
 	lbs_deb_enter(LBS_DEB_WEXT);
 
-	if (!lbs_is_cmd_allowed(priv)) {
-		ret = -EBUSY;
-		lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
-		return ret;
-	}
-
 	if (!priv->radio_on)
 		return -EINVAL;
 
-- 
1.5.4.3


^ permalink raw reply related

* Re: [WIP, RFC] libertas: allow scanning via "iw"
From: Dan Williams @ 2009-10-06 22:49 UTC (permalink / raw)
  To: Holger Schurig; +Cc: linux-wireless
In-Reply-To: <200910061633.08237.hs4233@mail.mn-solutions.de>

On Tue, 2009-10-06 at 16:33 +0200, Holger Schurig wrote:
> This adds support for "iw eth1 scan trigger" and "iw eth1 scan dump".
> 
> Do not apply!
> 
> ---
> 
> There are some open points, all marked as TODO
> 
> * signal isn't reported in dBm or mBm. The scan response from
>   the firmware tells me some "RSSI" value.

#define MRVDRV_NF_DEFAULT_SCAN_VALUE		(-96)
#define SCAN_RSSI(RSSI)			(0x100 - ((u8)(RSSI)))

	iwe.u.qual.level = SCAN_RSSI(bss->rssi);

	rssi = iwe.u.qual.level - MRVDRV_NF_DEFAULT_SCAN_VALUE;

so it's more or less dBm.

Dan

> * no real support for active/passive scanning yet
> * no integration into the current code, e.g. no usage of the
>   scan results in assoc.c and other places. priv->networks is
>   completely unrelated (and should ultimatively go away)
> * dummy lbs_scan_networks()
> * dummy lbs_send_specific_ssid_scan()
> * scan.c and scan.h are just disabled, not deleted
> 
> 
> Besides all of this, the following is possible:
> 
> # iw eth1 scan trigger freq 2412 passive; sleep 0.5; iw eth1 scan dump
> BSS 00:1b:d4:44:35:90 (on eth1)
>         TSF: 286400000 usec (0d, 00:04:46)
>         freq: 2412
>         beacon interval: 100
>         capability: ESS Privacy (0x0011)
>         signal: 57/100
>         SSID: MNWPA
>         Supported rates: 1.0* 2.0 5.5 11.0
>         DS Parameter set: channel 1
>         ERP: Use_Protection
>         WPA:     * Version: 1
>                  * Group cipher: TKIP
>                  * Pairwise ciphers: TKIP
>                  * Authentication suites: PSK
>                  * Capabilities: 4-PTKSA-RC 4-GTKSA-RC (0x0028)
>         WMM:    * Parameter version 1
>                 * u-APSD
>                 * BE: CW 31-1023, AIFSN 3
>                 * BK: CW 31-1023, AIFSN 7
>                 * VI: CW 15-31, AIFSN 2, TXOP 3008 usec
>                 * VO: CW 7-15, AIFSN 2, TXOP 1504 usec
> BSS 00:1b:53:11:dc:40 (on eth1)
>         TSF: 286410000 usec (0d, 00:04:46)
>         freq: 2412
>         beacon interval: 100
>         capability: ESS Privacy (0x0011)
>         signal: 64/100
>         SSID: MNWPA
>         Supported rates: 11.0*
>         DS Parameter set: channel 1
>         ERP: NonERP_Present Use_Protection Barker_Preamble_Mode
>         WMM:    * Parameter version 1
>                 * u-APSD
>                 * BE: CW 31-1023, AIFSN 3
>                 * BK: CW 31-1023, AIFSN 7
>                 * VI: CW 15-31, AIFSN 2, TXOP 3008 usec
>                 * VO: CW 7-15, AIFSN 2, TXOP 1504 usec
> 
> # iw eth1 scan trigger freq 2417 2462
> # iw eth1 scan ssid MNWPA
> 
> Index: linux-wl/drivers/net/wireless/libertas/cfg.c
> ===================================================================
> --- linux-wl.orig/drivers/net/wireless/libertas/cfg.c	2009-10-06 15:23:34.000000000 +0200
> +++ linux-wl/drivers/net/wireless/libertas/cfg.c	2009-10-06 15:23:48.000000000 +0200
> @@ -7,9 +7,34 @@
>   */
>  
>  #include <net/cfg80211.h>
> +#include <asm/unaligned.h>
>  
>  #include "cfg.h"
>  #include "cmd.h"
> +#include "host.h"
> +
> +/*
> + * When scanning, the firmware doesn't send a nul packet with the power-safe
> + * bit on to the AP. So we cannot stay away from our current channel too
> + * long, otherwise we loose data. So take a "nap" while scanning every other
> + * while.
> + */
> +#define LBS_SCAN_MAX_CHANNELS_BEFORE_NAP 4
> +
> +/* Memory needed to store a max sized channel List TLV for a firmware scan */
> +#define CHAN_TLV_MAX_SIZE  (sizeof(struct mrvl_ie_header)    \
> +	+ (MRVDRV_MAX_CHANNELS_PER_SCAN     \
> +	* sizeof(struct chanscanparamset)))
> +
> +/* Memory needed to store a max number/size SSID TLV for a firmware scan */
> +#define SSID_TLV_MAX_SIZE  (1 * sizeof(struct mrvl_ie_ssid_param_set))
> +
> +/* Maximum memory needed for a cmd_ds_802_11_scan with all TLVs at max */
> +#define MAX_SCAN_CFG_ALLOC (sizeof(struct cmd_ds_802_11_scan)	\
> +	+ CHAN_TLV_MAX_SIZE + SSID_TLV_MAX_SIZE)
> +
> +/* Scan time specified in the channel TLV for each channel for active scans */
> +#define MRVDRV_ACTIVE_SCAN_CHAN_TIME   100
>  
> 
>  #define CHAN2G(_channel, _freq, _flags) {        \
> @@ -77,6 +102,10 @@ static const u32 cipher_suites[] = {
>  
> 
> 
> +/***************************************************************************
> + * Set Channel
> + */
> +
>  static int lbs_cfg_set_channel(struct wiphy *wiphy,
>  	struct ieee80211_channel *chan,
>  	enum nl80211_channel_type channel_type)
> @@ -97,10 +126,374 @@ static int lbs_cfg_set_channel(struct wi
>  }
>  
> 
> +/***************************************************************************
> + * Scanning
> + */
> +
> +static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy,
> +	struct cmd_header *resp)
> +{
> +	struct cmd_ds_802_11_scan_rsp *scanresp = (void *)resp;
> +	int bsssize;
> +	u8 *pos;
> +	uint16_t nr_sets;
> +	u8 *tsfdesc;
> +	int tsfsize;
> +	int i;
> +	int ret = -EILSEQ;
> +
> +	bsssize = get_unaligned_le16(&scanresp->bssdescriptsize);
> +	nr_sets = le16_to_cpu(resp->size);
> +
> +	/* The general layout of the scan response is described in
> +	 * chapter 5.7.1. Basically we have common part, then
> +	 * one data section for each returned BSS, and then again
> +	 * one data section containing TSFs. Sample:
> +	 *
> +	 * cmd_ds_802_11_scan_rsp
> +	 *   cmd_header
> +	 *   pos_size
> +	 *   nr_sets
> +	 *   bssdesc 1
> +	 *     bssid
> +	 *     rssi
> +	 *     intvl
> +	 *     capa
> +	 *     IEs
> +	 *   bssdesc 2
> +	 *   bssdesc n
> +	 *   MrvlIEtypes_TsfFimestamp_t
> +	 *     TSF for BSS 1
> +	 *     TSF for BSS 2
> +	 *     TSF for BSS n
> +	 */
> +
> +	pos = scanresp->bssdesc_and_tlvbuffer;
> +
> +	tsfdesc = pos + bsssize;
> +	tsfsize = 4 + 8 * scanresp->nr_sets;
> +
> +	/* Validity check: we expect a Marvell-Local IE */
> +	i = get_unaligned_le16(tsfdesc);
> +	tsfdesc += 2;
> +	if (i != 0x0113)
> +		goto done;
> +	/* Validity check: the IE holds TSF values with 8 bytes each,
> +	 * so the size in the IE must match the nr_sets value */
> +	i = get_unaligned_le16(tsfdesc);
> +	tsfdesc += 2;
> +	if (i / 8 != scanresp->nr_sets)
> +		goto done;
> +
> +	for (i = 0; i < scanresp->nr_sets; i++) {
> +		u8 *bssid;
> +		u8 *ie;
> +		int left;
> +		int ielen;
> +		u8 rssi;
> +		uint16_t intvl;
> +		uint16_t capa;
> +		int chan_no = -1;
> +
> +		int len = get_unaligned_le16(pos);
> +		pos += 2;
> +
> +		/* BSSID */
> +		bssid = pos;
> +		pos += ETH_ALEN;
> +		/* RSSI */
> +		rssi = *pos++;
> +		/* Packet time stamp */
> +		pos += 8;
> +		/* Beacon interval */
> +		intvl = get_unaligned_le16(pos);
> +		pos += 2;
> +		/* Capabilities */
> +		capa = get_unaligned_le16(pos);
> +		pos += 2;
> +
> +		/* To find out the channel, we must parse the IEs */
> +		ie = pos;
> +		ielen = left = len - 6-1-8-2-2;
> +		while (left >= 2) {
> +			u8 id, elen;
> +			id = *pos++;
> +			elen = *pos++;
> +			left -= 2;
> +			if (elen > left || elen == 0)
> +				goto done;
> +			if (id == WLAN_EID_DS_PARAMS)
> +				chan_no = *pos;
> +			left -= elen;
> +			pos += elen;
> +		}
> +
> +		if (chan_no != -1) {
> +			struct wiphy *wiphy = priv->wdev->wiphy;
> +			int freq = ieee80211_channel_to_frequency(chan_no);
> +			struct ieee80211_channel *channel =
> +				ieee80211_get_channel(wiphy, freq);
> +			if (channel ||
> +			    !channel->flags & IEEE80211_CHAN_DISABLED)
> +				cfg80211_inform_bss(wiphy, channel,
> +					bssid, le64_to_cpu(*(__le64 *)tsfdesc),
> +					capa, intvl, ie, ielen, rssi,
> +					GFP_KERNEL);
> +		}
> +
> +		tsfdesc += 8;
> +	}
> +	ret = 0;
> +
> + done:
> +	lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret);
> +	return ret;
> +}
> +
> +
> +/*
> + * Add SSID TLV of the form:
> + *
> + * TLV-ID SSID     00 00
> + * length          06 00
> + * ssid            4d 4e 54 45 53 54
> + */
> +static int lbs_scan_add_ssid_tlv(struct lbs_private *priv, u8 *tlv)
> +{
> +	struct mrvl_ie_ssid_param_set *ssid_tlv = (void *)tlv;
> +
> +	ssid_tlv->header.type = cpu_to_le16(TLV_TYPE_SSID);
> +	ssid_tlv->header.len = cpu_to_le16(priv->scan_req->ssids[0].ssid_len);
> +	memcpy(ssid_tlv->ssid, priv->scan_req->ssids[0].ssid,
> +		priv->scan_req->ssids[0].ssid_len);
> +	return sizeof(ssid_tlv->header) + priv->scan_req->ssids[0].ssid_len;
> +}
> +
> +
> +/*
> + * Add CHANLIST TLV of the form:
> + *
> + * TLV-ID CHANLIST 01 01
> + * length          0e 00
> + * channel         00 01 00 00 00 64 00
> + *   radio type    00
> + *   channel          01
> + *   scan type           00
> + *   min scan time          00 00
> + *   max scan time                64 00
> + * channel 2       00 02 00 00 00 64 00
> + *
> + * It adds the channel from priv->scan_channel to the TLV. Actual channel
> + * data comes from priv->wiphy->channels.
> + */
> +static int lbs_scan_add_channel_tlv(struct lbs_private *priv, u8 *tlv,
> +	int last_channel)
> +{
> +	int chanscanparamsize = sizeof(struct chanscanparamset) *
> +			(last_channel - priv->scan_channel);
> +
> +	struct mrvl_ie_header *header = (void *) tlv;
> +
> +	header->type = cpu_to_le16(TLV_TYPE_CHANLIST);
> +	header->len  = cpu_to_le16(chanscanparamsize);
> +	tlv += sizeof(struct mrvl_ie_header);
> +
> +	lbs_deb_scan("scan from %d to %d, size %d\n", priv->scan_channel,
> +		last_channel, chanscanparamsize);
> +	memset(tlv, 0, chanscanparamsize);
> +
> +	while (priv->scan_channel < last_channel) {
> +		struct chanscanparamset *param = (void *) tlv;
> +
> +		param->radiotype = CMD_SCAN_RADIO_TYPE_BG;
> +		param->channumber =
> +			priv->scan_req->channels[priv->scan_channel]->hw_value;
> +		/* TODO param->.chanscanmode.passivescan = 1; */
> +		param->maxscantime = cpu_to_le16(MRVDRV_ACTIVE_SCAN_CHAN_TIME);
> +		tlv += sizeof(struct chanscanparamset);
> +		priv->scan_channel++;
> +	}
> +	return sizeof(struct mrvl_ie_header) + chanscanparamsize;
> +}
> +
> +
> +/*
> + * Add RATES TLV of the form
> + *
> + * TLV-ID RATES    01 00
> + * length          0e 00
> + * rates           82 84 8b 96 0c 12 18 24 30 48 60 6c
> + *
> + * The rates are in lbs_bg_rates[], but for the 802.11b
> + * rates the high bit is set. We add this TLV only because
> + * there's a firmware which otherwise doesn't report all
> + * APs in range.
> + */
> +static int lbs_scan_add_rates_tlv(u8 *tlv)
> +{
> +	int i;
> +	struct mrvl_ie_rates_param_set *rate_tlv = (void *)tlv;
> +
> +	rate_tlv->header.type = cpu_to_le16(TLV_TYPE_RATES);
> +	tlv += sizeof(rate_tlv->header);
> +	for (i = 0; i < ARRAY_SIZE(lbs_rates); i++) {
> +		*tlv = lbs_rates[i].hw_value;
> +		/* This code makes sure that the 802.11b rates (1 MBit/s, 2
> +		   MBit/s, 5.5 MBit/s and 11 MBit/s get's the high bit set.
> +		   Note that the values are MBit/s * 2, to mark them as
> +		   basic rates so that the firmware likes it better */
> +		if (*tlv == 0x02 || *tlv == 0x04 ||
> +		    *tlv == 0x0b || *tlv == 0x16)
> +			*tlv |= 0x80;
> +		tlv++;
> +	}
> +	rate_tlv->header.len = cpu_to_le16(i);
> +	return sizeof(rate_tlv->header) + i;
> +}
> +
> +/*
> + * Assumes priv->scan_req is initialized and valid
> + * Assumes priv->scan_channel is initialized
> + */
> +void lbs_cfg_scan_worker(struct work_struct *work)
> +{
> +	struct lbs_private *priv =
> +		container_of(work, struct lbs_private, scan_work.work);
> +	struct cmd_ds_802_11_scan *scan_cmd;
> +	u8 *tlv;	/* pointer into our current, growing TLV storage area */
> +	int last_channel;
> +
> +	lbs_deb_enter(LBS_DEB_SCAN);
> +
> +	/* create the fixed part for scan command */
> +	scan_cmd = kzalloc(MAX_SCAN_CFG_ALLOC, GFP_KERNEL);
> +	if (scan_cmd == NULL)
> +		goto out_no_scan_cmd;
> +	tlv = scan_cmd->tlvbuffer;
> +
> +	netif_stop_queue(priv->dev);
> +	netif_carrier_off(priv->dev);
> +	if (priv->mesh_dev) {
> +		netif_stop_queue(priv->mesh_dev);
> +		netif_carrier_off(priv->mesh_dev);
> +	}
> +
> +	scan_cmd->bsstype = CMD_BSS_TYPE_ANY;
> +
> +	/* add SSID TLV */
> +	if (priv->scan_req->n_ssids)
> +		tlv += lbs_scan_add_ssid_tlv(priv, tlv);
> +
> +	/* add channel TLVs */
> +	last_channel = priv->scan_channel + LBS_SCAN_MAX_CHANNELS_BEFORE_NAP;
> +	if (last_channel > priv->scan_req->n_channels)
> +		last_channel = priv->scan_req->n_channels;
> +	tlv += lbs_scan_add_channel_tlv(priv, tlv, last_channel);
> +
> +	/* add rates TLV */
> +	tlv += lbs_scan_add_rates_tlv(tlv);
> +
> +	if (priv->scan_channel < priv->scan_req->n_channels) {
> +		lbs_deb_scan("reschedule scan\n");
> +		cancel_delayed_work(&priv->scan_work);
> +		queue_delayed_work(priv->work_thread, &priv->scan_work,
> +			msecs_to_jiffies(300));
> +	}
> +
> +	/* This is the final data we are about to send */
> +	scan_cmd->hdr.size = cpu_to_le16(tlv - (u8 *)scan_cmd);
> +	lbs_deb_hex(LBS_DEB_SCAN, "SCAN_CMD", (void *)scan_cmd,
> +		    sizeof(*scan_cmd));
> +	lbs_deb_hex(LBS_DEB_SCAN, "SCAN_TLV", scan_cmd->tlvbuffer,
> +		    tlv - scan_cmd->tlvbuffer);
> +
> +	__lbs_cmd(priv, CMD_802_11_SCAN, &scan_cmd->hdr,
> +		le16_to_cpu(scan_cmd->hdr.size),
> +		lbs_ret_scan, 0);
> +
> +	if (priv->scan_channel >= priv->scan_req->n_channels) {
> +		/* Mark scan done */
> +		cfg80211_scan_done(priv->scan_req, false);
> +		priv->scan_req = NULL;
> +	}
> +
> +	if (priv->connect_status == LBS_CONNECTED) {
> +		netif_carrier_on(priv->dev);
> +		if (!priv->tx_pending_len)
> +			netif_wake_queue(priv->dev);
> +	}
> +	if (priv->mesh_dev && (priv->mesh_connect_status == LBS_CONNECTED)) {
> +		netif_carrier_on(priv->mesh_dev);
> +		if (!priv->tx_pending_len)
> +			netif_wake_queue(priv->mesh_dev);
> +	}
> +	kfree(scan_cmd);
> +
> + out_no_scan_cmd:
> +	lbs_deb_leave(LBS_DEB_CFG80211);
> +}
> +
> +
> +static int lbs_cfg_scan(struct wiphy *wiphy,
> +	struct net_device *dev,
> +	struct cfg80211_scan_request *request)
> +{
> +	struct lbs_private *priv = wiphy_priv(wiphy);
> +	int ret = 0;
> +
> +	lbs_deb_enter(LBS_DEB_CFG80211);
> +
> +	if (priv->scan_req || delayed_work_pending(&priv->scan_work)) {
> +		/* old scan request not yet processed */
> +		ret = -EAGAIN;
> +		goto out;
> +	}
> +
> +	lbs_deb_cfg80211("n_ssids %d, n_channels %d, ie_len %d\n",
> +		request->n_ssids, request->n_channels, request->ie_len);
> +
> +	priv->scan_channel = 0;
> +	queue_delayed_work(priv->work_thread, &priv->scan_work,
> +		msecs_to_jiffies(50));
> +
> +	if (priv->surpriseremoved)
> +		ret = -EIO;
> +
> +	priv->scan_req = request;
> +
> + out:
> +	lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
> +	return ret;
> +}
> +
> +
> +int lbs_send_specific_ssid_scan(struct lbs_private *priv, u8 *ssid,
> +	u8 ssid_len)
> +{
> +	lbs_deb_enter(LBS_DEB_SCAN);
> +
> +	/* TODO */
> +	return -ENOTSUPP;
> +}
> +
> +
> +int lbs_scan_networks(struct lbs_private *priv, int full_scan)
> +{
> +	lbs_deb_enter(LBS_DEB_SCAN);
> +
> +	/* TODO */
> +	return -ENOTSUPP;
> +
> +}
> +
>  
> +/***************************************************************************
> + * Initialization
> + */
>  
>  static struct cfg80211_ops lbs_cfg80211_ops = {
>  	.set_channel = lbs_cfg_set_channel,
> +	.scan = lbs_cfg_scan,
>  };
>  
> 
> @@ -153,7 +546,8 @@ int lbs_cfg_register(struct lbs_private 
>  	lbs_deb_enter(LBS_DEB_CFG80211);
>  
>  	wdev->wiphy->max_scan_ssids = 1;
> -	wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
> +	wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_UNSPEC;
> +	/* TODO: convert to CFG80211_SIGNAL_TYPE_MBM; */
>  
>  	/* TODO: BIT(NL80211_IFTYPE_ADHOC); */
>  	wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
> Index: linux-wl/drivers/net/wireless/libertas/dev.h
> ===================================================================
> --- linux-wl.orig/drivers/net/wireless/libertas/dev.h	2009-10-06 15:22:40.000000000 +0200
> +++ linux-wl/drivers/net/wireless/libertas/dev.h	2009-10-06 15:23:48.000000000 +0200
> @@ -10,6 +10,7 @@
>  #include <linux/wireless.h>
>  #include <linux/ethtool.h>
>  #include <linux/debugfs.h>
> +#include <net/cfg80211.h>
>  
>  #include "defs.h"
>  #include "hostcmd.h"
> @@ -101,6 +102,7 @@ struct lbs_mesh_stats {
>  /** Private structure for the MV device */
>  struct lbs_private {
>  	struct wireless_dev *wdev;
> +	struct cfg80211_scan_request *scan_req;
>  	int mesh_open;
>  	int mesh_fw_ver;
>  	int infra_open;
> Index: linux-wl/drivers/net/wireless/libertas/wext.c
> ===================================================================
> --- linux-wl.orig/drivers/net/wireless/libertas/wext.c	2009-10-06 15:22:40.000000000 +0200
> +++ linux-wl/drivers/net/wireless/libertas/wext.c	2009-10-06 15:23:48.000000000 +0200
> @@ -17,7 +17,6 @@
>  #include "defs.h"
>  #include "dev.h"
>  #include "wext.h"
> -#include "scan.h"
>  #include "assoc.h"
>  #include "cmd.h"
>  
> @@ -2346,8 +2345,8 @@ static const iw_handler lbs_handler[] = 
>  	(iw_handler) lbs_get_wap,	/* SIOCGIWAP */
>  	(iw_handler) NULL,	/* SIOCSIWMLME */
>  	(iw_handler) NULL,	/* SIOCGIWAPLIST - deprecated */
> -	(iw_handler) lbs_set_scan,	/* SIOCSIWSCAN */
> -	(iw_handler) lbs_get_scan,	/* SIOCGIWSCAN */
> +	(iw_handler) NULL, 	/* SIOCSIWSCAN */
> +	(iw_handler) NULL,	/* SIOCGIWSCAN */
>  	(iw_handler) lbs_set_essid,	/* SIOCSIWESSID */
>  	(iw_handler) lbs_get_essid,	/* SIOCGIWESSID */
>  	(iw_handler) lbs_set_nick,	/* SIOCSIWNICKN */
> @@ -2404,8 +2403,8 @@ static const iw_handler mesh_wlan_handle
>  	(iw_handler) NULL,	/* SIOCGIWAP */
>  	(iw_handler) NULL,	/* SIOCSIWMLME */
>  	(iw_handler) NULL,	/* SIOCGIWAPLIST - deprecated */
> -	(iw_handler) lbs_set_scan,	/* SIOCSIWSCAN */
> -	(iw_handler) lbs_get_scan,	/* SIOCGIWSCAN */
> +	(iw_handler) NULL,	/* SIOCSIWSCAN */
> +	(iw_handler) NULL,	/* SIOCGIWSCAN */
>  	(iw_handler) lbs_mesh_set_essid,/* SIOCSIWESSID */
>  	(iw_handler) lbs_mesh_get_essid,/* SIOCGIWESSID */
>  	(iw_handler) NULL,		/* SIOCSIWNICKN */
> Index: linux-wl/drivers/net/wireless/libertas/Makefile
> ===================================================================
> --- linux-wl.orig/drivers/net/wireless/libertas/Makefile	2009-10-06 15:22:40.000000000 +0200
> +++ linux-wl/drivers/net/wireless/libertas/Makefile	2009-10-06 15:23:48.000000000 +0200
> @@ -8,7 +8,8 @@ libertas-y += ethtool.o
>  libertas-y += main.o
>  libertas-y += persistcfg.o
>  libertas-y += rx.o
> -libertas-y += scan.o
> +# TODO
> +#libertas-y += scan.o
>  libertas-y += tx.o
>  libertas-y += wext.o
>  
> Index: linux-wl/drivers/net/wireless/libertas/assoc.c
> ===================================================================
> --- linux-wl.orig/drivers/net/wireless/libertas/assoc.c	2009-10-06 15:22:40.000000000 +0200
> +++ linux-wl/drivers/net/wireless/libertas/assoc.c	2009-10-06 15:23:48.000000000 +0200
> @@ -9,7 +9,7 @@
>  #include "assoc.h"
>  #include "decl.h"
>  #include "host.h"
> -#include "scan.h"
> +#include "cfg.h"
>  #include "cmd.h"
>  
>  static const u8 bssid_any[ETH_ALEN]  __attribute__ ((aligned (2))) =
> @@ -495,6 +495,23 @@ done:
>  }
>  
>  /**
> + *  @brief Compare two SSIDs
> + *
> + *  @param ssid1    A pointer to ssid to compare
> + *  @param ssid2    A pointer to ssid to compare
> + *
> + *  @return         0: ssid is same, otherwise is different
> + */
> +static int lbs_ssid_cmp(uint8_t *ssid1, uint8_t ssid1_len, uint8_t *ssid2,
> +		 uint8_t ssid2_len)
> +{
> +	if (ssid1_len != ssid2_len)
> +		return -1;
> +
> +	return memcmp(ssid1, ssid2, ssid1_len);
> +}
> +
> +/**
>   *  @brief Join an adhoc network found in a previous scan
>   *
>   *  @param priv         A pointer to struct lbs_private structure
> Index: linux-wl/drivers/net/wireless/libertas/main.c
> ===================================================================
> --- linux-wl.orig/drivers/net/wireless/libertas/main.c	2009-10-06 15:22:40.000000000 +0200
> +++ linux-wl/drivers/net/wireless/libertas/main.c	2009-10-06 15:23:48.000000000 +0200
> @@ -22,7 +22,7 @@
>  #include "wext.h"
>  #include "cfg.h"
>  #include "debugfs.h"
> -#include "scan.h"
> +#include "cfg.h"
>  #include "assoc.h"
>  #include "cmd.h"
>  
> @@ -1133,7 +1133,8 @@ static void lbs_sync_channel_worker(stru
>  	lbs_deb_leave(LBS_DEB_MAIN);
>  }
>  
> -
> +/* TODO */
> +#define MAX_NETWORK_COUNT 128
>  static int lbs_init_adapter(struct lbs_private *priv)
>  {
>  	size_t bufsize;
> @@ -1313,7 +1314,7 @@ struct lbs_private *lbs_add_card(void *c
>  
>  	priv->work_thread = create_singlethread_workqueue("lbs_worker");
>  	INIT_DELAYED_WORK(&priv->assoc_work, lbs_association_worker);
> -	INIT_DELAYED_WORK(&priv->scan_work, lbs_scan_worker);
> +	INIT_DELAYED_WORK(&priv->scan_work, lbs_cfg_scan_worker);
>  	INIT_WORK(&priv->mcast_work, lbs_set_mcast_worker);
>  	INIT_WORK(&priv->sync_channel, lbs_sync_channel_worker);
>  
> Index: linux-wl/drivers/net/wireless/libertas/persistcfg.c
> ===================================================================
> --- linux-wl.orig/drivers/net/wireless/libertas/persistcfg.c	2009-10-06 15:22:40.000000000 +0200
> +++ linux-wl/drivers/net/wireless/libertas/persistcfg.c	2009-10-06 15:23:48.000000000 +0200
> @@ -11,7 +11,6 @@
>  #include "dev.h"
>  #include "wext.h"
>  #include "debugfs.h"
> -#include "scan.h"
>  #include "assoc.h"
>  #include "cmd.h"
>  
> Index: linux-wl/drivers/net/wireless/libertas/scan.c
> ===================================================================
> --- linux-wl.orig/drivers/net/wireless/libertas/scan.c	2009-10-06 15:22:40.000000000 +0200
> +++ linux-wl/drivers/net/wireless/libertas/scan.c	2009-10-06 15:23:48.000000000 +0200
> @@ -3,6 +3,8 @@
>    *
>    * IOCTL handlers as well as command preperation and response routines
>    *  for sending scan commands to the firmware.
> +  *
> +  * TODO: remove this file
>    */
>  #include <linux/types.h>
>  #include <linux/kernel.h>
> @@ -90,23 +92,6 @@ static inline void clear_bss_descriptor(
>  	memset(bss, 0, offsetof(struct bss_descriptor, list));
>  }
>  
> -/**
> - *  @brief Compare two SSIDs
> - *
> - *  @param ssid1    A pointer to ssid to compare
> - *  @param ssid2    A pointer to ssid to compare
> - *
> - *  @return         0: ssid is same, otherwise is different
> - */
> -int lbs_ssid_cmp(uint8_t *ssid1, uint8_t ssid1_len, uint8_t *ssid2,
> -		 uint8_t ssid2_len)
> -{
> -	if (ssid1_len != ssid2_len)
> -		return -1;
> -
> -	return memcmp(ssid1, ssid2, ssid1_len);
> -}
> -
>  static inline int is_same_network(struct bss_descriptor *src,
>  				  struct bss_descriptor *dst)
>  {
> Index: linux-wl/drivers/net/wireless/libertas/scan.h
> ===================================================================
> --- linux-wl.orig/drivers/net/wireless/libertas/scan.h	2009-10-06 15:22:40.000000000 +0200
> +++ linux-wl/drivers/net/wireless/libertas/scan.h	2009-10-06 15:23:48.000000000 +0200
> @@ -1,3 +1,6 @@
> +#error don't include scan.h
> +/* TODO: remove this file */
> +
>  /**
>    * Interface for the wlan network scan routines
>    *
> 


^ permalink raw reply

* Re: [PATCH] libertas: separate libertas' Kconfig in it's own file
From: Dan Williams @ 2009-10-06 22:39 UTC (permalink / raw)
  To: Holger Schurig; +Cc: linux-wireless, John W Linville
In-Reply-To: <200910061631.20976.hs4233@mail.mn-solutions.de>

On Tue, 2009-10-06 at 16:31 +0200, Holger Schurig wrote:
> Also sorts all "source" lines in the wireless/Kconfig.
> 
> Signed-off-by: Holger Schurig <hs4233@mail.mn-solutions.de>

Yeah, we've got a lot more options now.

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

> 
> Index: linux-wl/drivers/net/wireless/Kconfig
> ===================================================================
> --- linux-wl.orig/drivers/net/wireless/Kconfig	2009-10-06 07:55:26.000000000 +0200
> +++ linux-wl/drivers/net/wireless/Kconfig	2009-10-06 07:58:05.000000000 +0200
> @@ -139,47 +139,6 @@ config PCMCIA_RAYCS
>  	  To compile this driver as a module, choose M here: the module will be
>  	  called ray_cs.  If unsure, say N.
>  
> -config LIBERTAS
> -	tristate "Marvell 8xxx Libertas WLAN driver support"
> -	depends on WLAN_80211
> -	select WIRELESS_EXT
> -	select WEXT_SPY
> -	select LIB80211
> -	select FW_LOADER
> -	---help---
> -	  A library for Marvell Libertas 8xxx devices.
> -
> -config LIBERTAS_USB
> -	tristate "Marvell Libertas 8388 USB 802.11b/g cards"
> -	depends on LIBERTAS && USB
> -	---help---
> -	  A driver for Marvell Libertas 8388 USB devices.
> -
> -config LIBERTAS_CS
> -	tristate "Marvell Libertas 8385 CompactFlash 802.11b/g cards"
> -	depends on LIBERTAS && PCMCIA
> -	select FW_LOADER
> -	---help---
> -	  A driver for Marvell Libertas 8385 CompactFlash devices.
> -
> -config LIBERTAS_SDIO
> -	tristate "Marvell Libertas 8385/8686/8688 SDIO 802.11b/g cards"
> -	depends on LIBERTAS && MMC
> -	---help---
> -	  A driver for Marvell Libertas 8385/8686/8688 SDIO devices.
> -
> -config LIBERTAS_SPI
> -	tristate "Marvell Libertas 8686 SPI 802.11b/g cards"
> -	depends on LIBERTAS && SPI
> -	---help---
> -	  A driver for Marvell Libertas 8686 SPI devices.
> -
> -config LIBERTAS_DEBUG
> -	bool "Enable full debugging output in the Libertas module."
> -	depends on LIBERTAS
> -	---help---
> -	  Debugging support.
> -
>  config LIBERTAS_THINFIRM
>  	tristate "Marvell 8xxx Libertas WLAN driver support with thin firmware"
>  	depends on WLAN_80211 && MAC80211
> @@ -491,17 +450,18 @@ config MWL8K
>  	  To compile this driver as a module, choose M here: the module
>  	  will be called mwl8k.  If unsure, say N.
>  
> -source "drivers/net/wireless/p54/Kconfig"
>  source "drivers/net/wireless/ath/Kconfig"
> -source "drivers/net/wireless/ipw2x00/Kconfig"
> -source "drivers/net/wireless/iwlwifi/Kconfig"
> -source "drivers/net/wireless/hostap/Kconfig"
>  source "drivers/net/wireless/b43/Kconfig"
>  source "drivers/net/wireless/b43legacy/Kconfig"
> -source "drivers/net/wireless/zd1211rw/Kconfig"
> -source "drivers/net/wireless/rt2x00/Kconfig"
> +source "drivers/net/wireless/hostap/Kconfig"
> +source "drivers/net/wireless/ipw2x00/Kconfig"
> +source "drivers/net/wireless/iwlwifi/Kconfig"
> +source "drivers/net/wireless/iwmc3200wifi/Kconfig"
> +source "drivers/net/wireless/libertas/Kconfig"
>  source "drivers/net/wireless/orinoco/Kconfig"
> +source "drivers/net/wireless/p54/Kconfig"
> +source "drivers/net/wireless/rt2x00/Kconfig"
>  source "drivers/net/wireless/wl12xx/Kconfig"
> -source "drivers/net/wireless/iwmc3200wifi/Kconfig"
> +source "drivers/net/wireless/zd1211rw/Kconfig"
>  
>  endif # WLAN
> Index: linux-wl/drivers/net/wireless/libertas/Makefile
> ===================================================================
> --- linux-wl.orig/drivers/net/wireless/libertas/Makefile	2009-10-06 07:55:26.000000000 +0200
> +++ linux-wl/drivers/net/wireless/libertas/Makefile	2009-10-06 07:58:25.000000000 +0200
> @@ -1,5 +1,15 @@
> -libertas-objs := main.o wext.o rx.o tx.o cmd.o cmdresp.o scan.o 11d.o	\
> -		 debugfs.o persistcfg.o ethtool.o assoc.o
> +libertas-y += 11d.o
> +libertas-y += assoc.o
> +libertas-y += cmd.o
> +libertas-y += cmdresp.o
> +libertas-y += debugfs.o
> +libertas-y += ethtool.o
> +libertas-y += main.o
> +libertas-y += persistcfg.o
> +libertas-y += rx.o
> +libertas-y += scan.o
> +libertas-y += tx.o
> +libertas-y += wext.o
>  
>  usb8xxx-objs += if_usb.o
>  libertas_cs-objs += if_cs.o
> Index: linux-wl/drivers/net/wireless/libertas/Kconfig
> ===================================================================
> --- /dev/null	1970-01-01 00:00:00.000000000 +0000
> +++ linux-wl/drivers/net/wireless/libertas/Kconfig	2009-10-06 07:58:15.000000000 +0200
> @@ -0,0 +1,40 @@
> +config LIBERTAS
> +	tristate "Marvell 8xxx Libertas WLAN driver support"
> +	depends on WLAN_80211
> +	select WIRELESS_EXT
> +	select WEXT_SPY
> +	select LIB80211
> +	select FW_LOADER
> +	---help---
> +	  A library for Marvell Libertas 8xxx devices.
> +
> +config LIBERTAS_USB
> +	tristate "Marvell Libertas 8388 USB 802.11b/g cards"
> +	depends on LIBERTAS && USB
> +	---help---
> +	  A driver for Marvell Libertas 8388 USB devices.
> +
> +config LIBERTAS_CS
> +	tristate "Marvell Libertas 8385 CompactFlash 802.11b/g cards"
> +	depends on LIBERTAS && PCMCIA
> +	select FW_LOADER
> +	---help---
> +	  A driver for Marvell Libertas 8385 CompactFlash devices.
> +
> +config LIBERTAS_SDIO
> +	tristate "Marvell Libertas 8385/8686/8688 SDIO 802.11b/g cards"
> +	depends on LIBERTAS && MMC
> +	---help---
> +	  A driver for Marvell Libertas 8385/8686/8688 SDIO devices.
> +
> +config LIBERTAS_SPI
> +	tristate "Marvell Libertas 8686 SPI 802.11b/g cards"
> +	depends on LIBERTAS && SPI
> +	---help---
> +	  A driver for Marvell Libertas 8686 SPI devices.
> +
> +config LIBERTAS_DEBUG
> +	bool "Enable full debugging output in the Libertas module."
> +	depends on LIBERTAS
> +	---help---
> +	  Debugging support.
> 


^ permalink raw reply

* [PATCH v2] b43: do not stack-allocate pio rx/tx header and tail buffers
From: Albert Herranz @ 2009-10-06 22:07 UTC (permalink / raw)
  To: bcm43xx-dev, mb; +Cc: linux-wireless, Albert Herranz
In-Reply-To: <200910062252.17565.mb@bu3sch.de>

The DMA-API debugging facility complains about b43 mapping memory from
stack for SDIO-based cards.

Indeed, b43 currently allocates the PIO RX/TX header and tail buffers
from stack. The solution here is to use heap-allocated buffers instead.

Signed-off-by: Albert Herranz <albert_herranz@yahoo.es>
---
v2
- embed buffers into struct b43_wl, and make them depend on CONFIG_B43_PIO
- take into account tail buffers for unaligned length transfers

 drivers/net/wireless/b43/b43.h  |  168 +++++++++++++++++++++------------------
 drivers/net/wireless/b43/pio.c  |   78 +++++++++---------
 drivers/net/wireless/b43/xmit.c |    2 +-
 3 files changed, 132 insertions(+), 116 deletions(-)

diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index fa1549a..6607162 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -607,82 +607,7 @@ struct b43_qos_params {
 	struct ieee80211_tx_queue_params p;
 };
 
-struct b43_wldev;
-
-/* Data structure for the WLAN parts (802.11 cores) of the b43 chip. */
-struct b43_wl {
-	/* Pointer to the active wireless device on this chip */
-	struct b43_wldev *current_dev;
-	/* Pointer to the ieee80211 hardware data structure */
-	struct ieee80211_hw *hw;
-
-	/* Global driver mutex. Every operation must run with this mutex locked. */
-	struct mutex mutex;
-	/* Hard-IRQ spinlock. This lock protects things used in the hard-IRQ
-	 * handler, only. This basically is just the IRQ mask register. */
-	spinlock_t hardirq_lock;
-
-	/* The number of queues that were registered with the mac80211 subsystem
-	 * initially. This is a backup copy of hw->queues in case hw->queues has
-	 * to be dynamically lowered at runtime (Firmware does not support QoS).
-	 * hw->queues has to be restored to the original value before unregistering
-	 * from the mac80211 subsystem. */
-	u16 mac80211_initially_registered_queues;
-
-	/* We can only have one operating interface (802.11 core)
-	 * at a time. General information about this interface follows.
-	 */
-
-	struct ieee80211_vif *vif;
-	/* The MAC address of the operating interface. */
-	u8 mac_addr[ETH_ALEN];
-	/* Current BSSID */
-	u8 bssid[ETH_ALEN];
-	/* Interface type. (NL80211_IFTYPE_XXX) */
-	int if_type;
-	/* Is the card operating in AP, STA or IBSS mode? */
-	bool operating;
-	/* filter flags */
-	unsigned int filter_flags;
-	/* Stats about the wireless interface */
-	struct ieee80211_low_level_stats ieee_stats;
-
-#ifdef CONFIG_B43_HWRNG
-	struct hwrng rng;
-	bool rng_initialized;
-	char rng_name[30 + 1];
-#endif /* CONFIG_B43_HWRNG */
-
-	/* List of all wireless devices on this chip */
-	struct list_head devlist;
-	u8 nr_devs;
-
-	bool radiotap_enabled;
-	bool radio_enabled;
-
-	/* The beacon we are currently using (AP or IBSS mode). */
-	struct sk_buff *current_beacon;
-	bool beacon0_uploaded;
-	bool beacon1_uploaded;
-	bool beacon_templates_virgin; /* Never wrote the templates? */
-	struct work_struct beacon_update_trigger;
-
-	/* The current QOS parameters for the 4 queues. */
-	struct b43_qos_params qos_params[4];
-
-	/* Work for adjustment of the transmission power.
-	 * This is scheduled when we determine that the actual TX output
-	 * power doesn't match what we want. */
-	struct work_struct txpower_adjust_work;
-
-	/* Packet transmit work */
-	struct work_struct tx_work;
-	/* Queue of packets to be transmitted. */
-	struct sk_buff_head tx_queue;
-
-	/* The device LEDs. */
-	struct b43_leds leds;
-};
+struct b43_wl;
 
 /* The type of the firmware file. */
 enum b43_firmware_file_type {
@@ -824,6 +749,97 @@ struct b43_wldev {
 #endif
 };
 
+/*
+ * Include goes here to avoid a dependency problem.
+ * A better fix would be to integrate xmit.h into b43.h.
+ */
+#include "xmit.h"
+
+/* Data structure for the WLAN parts (802.11 cores) of the b43 chip. */
+struct b43_wl {
+	/* Pointer to the active wireless device on this chip */
+	struct b43_wldev *current_dev;
+	/* Pointer to the ieee80211 hardware data structure */
+	struct ieee80211_hw *hw;
+
+	/* Global driver mutex. Every operation must run with this mutex locked. */
+	struct mutex mutex;
+	/* Hard-IRQ spinlock. This lock protects things used in the hard-IRQ
+	 * handler, only. This basically is just the IRQ mask register. */
+	spinlock_t hardirq_lock;
+
+	/* The number of queues that were registered with the mac80211 subsystem
+	 * initially. This is a backup copy of hw->queues in case hw->queues has
+	 * to be dynamically lowered at runtime (Firmware does not support QoS).
+	 * hw->queues has to be restored to the original value before unregistering
+	 * from the mac80211 subsystem. */
+	u16 mac80211_initially_registered_queues;
+
+	/* We can only have one operating interface (802.11 core)
+	 * at a time. General information about this interface follows.
+	 */
+
+	struct ieee80211_vif *vif;
+	/* The MAC address of the operating interface. */
+	u8 mac_addr[ETH_ALEN];
+	/* Current BSSID */
+	u8 bssid[ETH_ALEN];
+	/* Interface type. (NL80211_IFTYPE_XXX) */
+	int if_type;
+	/* Is the card operating in AP, STA or IBSS mode? */
+	bool operating;
+	/* filter flags */
+	unsigned int filter_flags;
+	/* Stats about the wireless interface */
+	struct ieee80211_low_level_stats ieee_stats;
+
+#ifdef CONFIG_B43_HWRNG
+	struct hwrng rng;
+	bool rng_initialized;
+	char rng_name[30 + 1];
+#endif /* CONFIG_B43_HWRNG */
+
+	/* List of all wireless devices on this chip */
+	struct list_head devlist;
+	u8 nr_devs;
+
+	bool radiotap_enabled;
+	bool radio_enabled;
+
+	/* The beacon we are currently using (AP or IBSS mode). */
+	struct sk_buff *current_beacon;
+	bool beacon0_uploaded;
+	bool beacon1_uploaded;
+	bool beacon_templates_virgin; /* Never wrote the templates? */
+	struct work_struct beacon_update_trigger;
+
+	/* The current QOS parameters for the 4 queues. */
+	struct b43_qos_params qos_params[4];
+
+	/* Work for adjustment of the transmission power.
+	 * This is scheduled when we determine that the actual TX output
+	 * power doesn't match what we want. */
+	struct work_struct txpower_adjust_work;
+
+	/* Packet transmit work */
+	struct work_struct tx_work;
+	/* Queue of packets to be transmitted. */
+	struct sk_buff_head tx_queue;
+
+	/* The device LEDs. */
+	struct b43_leds leds;
+
+#ifdef CONFIG_B43_PIO
+	/*
+	 * RX/TX header/tail buffers used by the frame transmit functions.
+	 */
+	struct b43_rxhdr_fw4 rxhdr;
+	struct b43_txhdr txhdr;
+	u8 rx_tail[4];
+	u8 tx_tail[4];
+#endif /* CONFIG_B43_PIO */
+};
+
 static inline struct b43_wl *hw_to_b43_wl(struct ieee80211_hw *hw)
 {
 	return hw->priv;
diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c
index 9c13979..dbbf0d1 100644
--- a/drivers/net/wireless/b43/pio.c
+++ b/drivers/net/wireless/b43/pio.c
@@ -331,6 +331,7 @@ static u16 tx_write_2byte_queue(struct b43_pio_txqueue *q,
 				unsigned int data_len)
 {
 	struct b43_wldev *dev = q->dev;
+	struct b43_wl *wl = dev->wl;
 	const u8 *data = _data;
 
 	ctl |= B43_PIO_TXCTL_WRITELO | B43_PIO_TXCTL_WRITEHI;
@@ -340,13 +341,12 @@ static u16 tx_write_2byte_queue(struct b43_pio_txqueue *q,
 			q->mmio_base + B43_PIO_TXDATA,
 			sizeof(u16));
 	if (data_len & 1) {
-		u8 tail[2] = { 0, };
-
 		/* Write the last byte. */
 		ctl &= ~B43_PIO_TXCTL_WRITEHI;
 		b43_piotx_write16(q, B43_PIO_TXCTL, ctl);
-		tail[0] = data[data_len - 1];
-		ssb_block_write(dev->dev, tail, 2,
+		wl->tx_tail[0] = data[data_len - 1];
+		wl->tx_tail[1] = 0;
+		ssb_block_write(dev->dev, wl->tx_tail, 2,
 				q->mmio_base + B43_PIO_TXDATA,
 				sizeof(u16));
 	}
@@ -381,6 +381,7 @@ static u32 tx_write_4byte_queue(struct b43_pio_txqueue *q,
 				unsigned int data_len)
 {
 	struct b43_wldev *dev = q->dev;
+	struct b43_wl *wl = dev->wl;
 	const u8 *data = _data;
 
 	ctl |= B43_PIO8_TXCTL_0_7 | B43_PIO8_TXCTL_8_15 |
@@ -391,29 +392,31 @@ static u32 tx_write_4byte_queue(struct b43_pio_txqueue *q,
 			q->mmio_base + B43_PIO8_TXDATA,
 			sizeof(u32));
 	if (data_len & 3) {
-		u8 tail[4] = { 0, };
-
+		wl->tx_tail[3] = 0;
 		/* Write the last few bytes. */
 		ctl &= ~(B43_PIO8_TXCTL_8_15 | B43_PIO8_TXCTL_16_23 |
 			 B43_PIO8_TXCTL_24_31);
 		switch (data_len & 3) {
 		case 3:
 			ctl |= B43_PIO8_TXCTL_16_23 | B43_PIO8_TXCTL_8_15;
-			tail[0] = data[data_len - 3];
-			tail[1] = data[data_len - 2];
-			tail[2] = data[data_len - 1];
+			wl->tx_tail[0] = data[data_len - 3];
+			wl->tx_tail[1] = data[data_len - 2];
+			wl->tx_tail[2] = data[data_len - 1];
 			break;
 		case 2:
 			ctl |= B43_PIO8_TXCTL_8_15;
-			tail[0] = data[data_len - 2];
-			tail[1] = data[data_len - 1];
+			wl->tx_tail[0] = data[data_len - 2];
+			wl->tx_tail[1] = data[data_len - 1];
+			wl->tx_tail[2] = 0;
 			break;
 		case 1:
-			tail[0] = data[data_len - 1];
+			wl->tx_tail[0] = data[data_len - 1];
+			wl->tx_tail[1] = 0;
+			wl->tx_tail[2] = 0;
 			break;
 		}
 		b43_piotx_write32(q, B43_PIO8_TXCTL, ctl);
-		ssb_block_write(dev->dev, tail, 4,
+		ssb_block_write(dev->dev, wl->tx_tail, 4,
 				q->mmio_base + B43_PIO8_TXDATA,
 				sizeof(u32));
 	}
@@ -445,8 +448,9 @@ static void pio_tx_frame_4byte_queue(struct b43_pio_txpacket *pack,
 static int pio_tx_frame(struct b43_pio_txqueue *q,
 			struct sk_buff *skb)
 {
+	struct b43_wldev *dev = q->dev;
+	struct b43_wl *wl = dev->wl;
 	struct b43_pio_txpacket *pack;
-	struct b43_txhdr txhdr;
 	u16 cookie;
 	int err;
 	unsigned int hdrlen;
@@ -457,8 +461,8 @@ static int pio_tx_frame(struct b43_pio_txqueue *q,
 			  struct b43_pio_txpacket, list);
 
 	cookie = generate_cookie(q, pack);
-	hdrlen = b43_txhdr_size(q->dev);
-	err = b43_generate_txhdr(q->dev, (u8 *)&txhdr, skb,
+	hdrlen = b43_txhdr_size(dev);
+	err = b43_generate_txhdr(dev, (u8 *)&wl->txhdr, skb,
 				 info, cookie);
 	if (err)
 		return err;
@@ -466,15 +470,15 @@ static int pio_tx_frame(struct b43_pio_txqueue *q,
 	if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) {
 		/* Tell the firmware about the cookie of the last
 		 * mcast frame, so it can clear the more-data bit in it. */
-		b43_shm_write16(q->dev, B43_SHM_SHARED,
+		b43_shm_write16(dev, B43_SHM_SHARED,
 				B43_SHM_SH_MCASTCOOKIE, cookie);
 	}
 
 	pack->skb = skb;
 	if (q->rev >= 8)
-		pio_tx_frame_4byte_queue(pack, (const u8 *)&txhdr, hdrlen);
+		pio_tx_frame_4byte_queue(pack, (const u8 *)&wl->txhdr, hdrlen);
 	else
-		pio_tx_frame_2byte_queue(pack, (const u8 *)&txhdr, hdrlen);
+		pio_tx_frame_2byte_queue(pack, (const u8 *)&wl->txhdr, hdrlen);
 
 	/* Remove it from the list of available packet slots.
 	 * It will be put back when we receive the status report. */
@@ -614,14 +618,14 @@ void b43_pio_get_tx_stats(struct b43_wldev *dev,
 static bool pio_rx_frame(struct b43_pio_rxqueue *q)
 {
 	struct b43_wldev *dev = q->dev;
-	struct b43_rxhdr_fw4 rxhdr;
+	struct b43_wl *wl = dev->wl;
 	u16 len;
 	u32 macstat;
 	unsigned int i, padding;
 	struct sk_buff *skb;
 	const char *err_msg = NULL;
 
-	memset(&rxhdr, 0, sizeof(rxhdr));
+	memset(&wl->rxhdr, 0, sizeof(wl->rxhdr));
 
 	/* Check if we have data and wait for it to get ready. */
 	if (q->rev >= 8) {
@@ -659,16 +663,16 @@ data_ready:
 
 	/* Get the preamble (RX header) */
 	if (q->rev >= 8) {
-		ssb_block_read(dev->dev, &rxhdr, sizeof(rxhdr),
+		ssb_block_read(dev->dev, &wl->rxhdr, sizeof(wl->rxhdr),
 			       q->mmio_base + B43_PIO8_RXDATA,
 			       sizeof(u32));
 	} else {
-		ssb_block_read(dev->dev, &rxhdr, sizeof(rxhdr),
+		ssb_block_read(dev->dev, &wl->rxhdr, sizeof(wl->rxhdr),
 			       q->mmio_base + B43_PIO_RXDATA,
 			       sizeof(u16));
 	}
 	/* Sanity checks. */
-	len = le16_to_cpu(rxhdr.frame_len);
+	len = le16_to_cpu(wl->rxhdr.frame_len);
 	if (unlikely(len > 0x700)) {
 		err_msg = "len > 0x700";
 		goto rx_error;
@@ -678,7 +682,7 @@ data_ready:
 		goto rx_error;
 	}
 
-	macstat = le32_to_cpu(rxhdr.mac_status);
+	macstat = le32_to_cpu(wl->rxhdr.mac_status);
 	if (macstat & B43_RX_MAC_FCSERR) {
 		if (!(q->dev->wl->filter_flags & FIF_FCSFAIL)) {
 			/* Drop frames with failed FCS. */
@@ -703,24 +707,22 @@ data_ready:
 			       q->mmio_base + B43_PIO8_RXDATA,
 			       sizeof(u32));
 		if (len & 3) {
-			u8 tail[4] = { 0, };
-
 			/* Read the last few bytes. */
-			ssb_block_read(dev->dev, tail, 4,
+			ssb_block_read(dev->dev, wl->rx_tail, 4,
 				       q->mmio_base + B43_PIO8_RXDATA,
 				       sizeof(u32));
 			switch (len & 3) {
 			case 3:
-				skb->data[len + padding - 3] = tail[0];
-				skb->data[len + padding - 2] = tail[1];
-				skb->data[len + padding - 1] = tail[2];
+				skb->data[len + padding - 3] = wl->rx_tail[0];
+				skb->data[len + padding - 2] = wl->rx_tail[1];
+				skb->data[len + padding - 1] = wl->rx_tail[2];
 				break;
 			case 2:
-				skb->data[len + padding - 2] = tail[0];
-				skb->data[len + padding - 1] = tail[1];
+				skb->data[len + padding - 2] = wl->rx_tail[0];
+				skb->data[len + padding - 1] = wl->rx_tail[1];
 				break;
 			case 1:
-				skb->data[len + padding - 1] = tail[0];
+				skb->data[len + padding - 1] = wl->rx_tail[0];
 				break;
 			}
 		}
@@ -729,17 +731,15 @@ data_ready:
 			       q->mmio_base + B43_PIO_RXDATA,
 			       sizeof(u16));
 		if (len & 1) {
-			u8 tail[2] = { 0, };
-
 			/* Read the last byte. */
-			ssb_block_read(dev->dev, tail, 2,
+			ssb_block_read(dev->dev, wl->rx_tail, 2,
 				       q->mmio_base + B43_PIO_RXDATA,
 				       sizeof(u16));
-			skb->data[len + padding - 1] = tail[0];
+			skb->data[len + padding - 1] = wl->rx_tail[0];
 		}
 	}
 
-	b43_rx(q->dev, skb, &rxhdr);
+	b43_rx(q->dev, skb, &wl->rxhdr);
 
 	return 1;
 
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index ac9f600..892573b 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -27,7 +27,7 @@
 
 */
 
-#include "xmit.h"
+#include "b43.h"
 #include "phy_common.h"
 #include "dma.h"
 #include "pio.h"
-- 
1.6.0.4


^ permalink raw reply related

* RE: [PATCH v2] libertas: Add auto deep sleep support for SD8385/SD8686/SD8688
From: Bing Zhao @ 2009-10-06 21:44 UTC (permalink / raw)
  To: Holger Schurig
  Cc: libertas-dev@lists.infradead.org, linux-wireless@vger.kernel.org,
	Amitkumar Karwar
In-Reply-To: <200910010942.59562.hs4233@mail.mn-solutions.de>

Hi Holger,

Sorry for the late response.

> -----Original Message-----
> From: Holger Schurig [mailto:hs4233@mail.mn-solutions.de]
> Sent: Thursday, October 01, 2009 12:43 AM
> To: Bing Zhao
> Cc: libertas-dev@lists.infradead.org; linux-wireless@vger.kernel.org; Amitkumar Karwar
> Subject: Re: [PATCH v2] libertas: Add auto deep sleep support for SD8385/SD8686/SD8688
> 
> > Tests have been done for USB/CS cards to make sure that the patch
> > won't break USB/CS code.
> 
> 
> Side question: which firmware are you using on CS cards?

firmware version for Marvell CF8385 card: 5.101.13p1

Regards,

Bing

> 
> --
> http://www.holgerschurig.de

^ permalink raw reply

* Re: b43: fix wldev use after free
From: Michael Buesch @ 2009-10-06 21:35 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Dave Young, linville, bcm43xx-dev, linux-wireless, linux-kernel
In-Reply-To: <20091006142822.55d5120c.akpm@linux-foundation.org>

On Tuesday 06 October 2009 23:28:22 Andrew Morton wrote:
> > fix it by call b43_leds_unregister before b43_one_core_detach
> > if it is the last one in wl->devlist
> > 
> 
> It appears that a different fix was added to linux-next yesterday:

Yes, this one is better, because it doesn't really change the code. It just removes
one unnecessary pointer usage.

-- 
Greetings, Michael.

^ permalink raw reply


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