* [PATCH] ar9170: remove EXPERIMENTAL marker
From: Luis R. Rodriguez @ 2009-07-27 23:52 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Luis R. Rodriguez, Christian Lamparter
In-Reply-To: <1248738730-4003-1-git-send-email-lrodriguez@atheros.com>
Cc: Christian Lamparter <chunkeey@web.de>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
drivers/net/wireless/ath/ar9170/Kconfig | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/drivers/net/wireless/ath/ar9170/Kconfig b/drivers/net/wireless/ath/ar9170/Kconfig
index de4281f..05918f1 100644
--- a/drivers/net/wireless/ath/ar9170/Kconfig
+++ b/drivers/net/wireless/ath/ar9170/Kconfig
@@ -1,12 +1,13 @@
config AR9170_USB
tristate "Atheros AR9170 802.11n USB support"
- depends on USB && MAC80211 && WLAN_80211 && EXPERIMENTAL
+ depends on USB && MAC80211 && WLAN_80211
select FW_LOADER
help
This is a driver for the Atheros "otus" 802.11n USB devices.
These devices require additional firmware (2 files).
For now, these files can be downloaded from here:
+
http://wireless.kernel.org/en/users/Drivers/ar9170
If you choose to build a module, it'll be called ar9170usb.
--
1.6.0.4
^ permalink raw reply related
* [PATCH] ath5k: remove EXPERIMENTAL marker
From: Luis R. Rodriguez @ 2009-07-27 23:52 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Luis R. Rodriguez
In-Reply-To: <1248738730-4003-1-git-send-email-lrodriguez@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
drivers/net/wireless/ath/ath5k/Kconfig | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/wireless/ath/ath5k/Kconfig b/drivers/net/wireless/ath/ath5k/Kconfig
index 9b07eef..06d0066 100644
--- a/drivers/net/wireless/ath/ath5k/Kconfig
+++ b/drivers/net/wireless/ath/ath5k/Kconfig
@@ -1,6 +1,6 @@
config ATH5K
tristate "Atheros 5xxx wireless cards support"
- depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL
+ depends on PCI && MAC80211 && WLAN_80211
select MAC80211_LEDS
select LEDS_CLASS
select NEW_LEDS
--
1.6.0.4
^ permalink raw reply related
* [PATCH] ath: use menuconfig to put ath stuff in its own page
From: Luis R. Rodriguez @ 2009-07-27 23:52 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Luis R. Rodriguez
In-Reply-To: <1248738730-4003-1-git-send-email-lrodriguez@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
drivers/net/wireless/ath/Kconfig | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/wireless/ath/Kconfig b/drivers/net/wireless/ath/Kconfig
index f27f3a7..253b95a 100644
--- a/drivers/net/wireless/ath/Kconfig
+++ b/drivers/net/wireless/ath/Kconfig
@@ -1,4 +1,4 @@
-config ATH_COMMON
+menuconfig ATH_COMMON
tristate "Atheros Wireless Cards"
depends on WLAN_80211
depends on CFG80211
--
1.6.0.4
^ permalink raw reply related
* [PATCH] ath: simplify kconfig dependency and add documentation
From: Luis R. Rodriguez @ 2009-07-27 23:52 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Luis R. Rodriguez
In-Reply-To: <1248738730-4003-1-git-send-email-lrodriguez@atheros.com>
Make atheros wireless drivers visible when you select
"Atheros wirless drivers". Adds links to ath.ko page,
and Atheros drivers page on the wiki.
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
drivers/net/wireless/ath/Kconfig | 18 ++++++++++++++++--
drivers/net/wireless/ath/ar9170/Kconfig | 1 -
drivers/net/wireless/ath/ath5k/Kconfig | 1 -
drivers/net/wireless/ath/ath9k/Kconfig | 1 -
4 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/ath/Kconfig b/drivers/net/wireless/ath/Kconfig
index 6bed009..f27f3a7 100644
--- a/drivers/net/wireless/ath/Kconfig
+++ b/drivers/net/wireless/ath/Kconfig
@@ -2,9 +2,23 @@ config ATH_COMMON
tristate "Atheros Wireless Cards"
depends on WLAN_80211
depends on CFG80211
- depends on ATH5K || ATH9K || AR9170_USB
+ ---help---
+ This will enable the support for the Atheros wireless drivers.
+ ath5k, ath9k and ar9170 drivers share some common code, this option
+ enables the common ath.ko module which currently shares just common
+ regulatory EEPROM helpers but will likely be extended later to share
+ more between modules.
+ For more information and documentation on this module you can visit:
+
+ http://wireless.kernel.org/en/users/Drivers/ath
+
+ For information on all Atheros wireless drivers visit:
+
+ http://wireless.kernel.org/en/users/Drivers/Atheros
+
+if ATH_COMMON
source "drivers/net/wireless/ath/ath5k/Kconfig"
source "drivers/net/wireless/ath/ath9k/Kconfig"
source "drivers/net/wireless/ath/ar9170/Kconfig"
-
+endif
diff --git a/drivers/net/wireless/ath/ar9170/Kconfig b/drivers/net/wireless/ath/ar9170/Kconfig
index b99e326..de4281f 100644
--- a/drivers/net/wireless/ath/ar9170/Kconfig
+++ b/drivers/net/wireless/ath/ar9170/Kconfig
@@ -2,7 +2,6 @@ config AR9170_USB
tristate "Atheros AR9170 802.11n USB support"
depends on USB && MAC80211 && WLAN_80211 && EXPERIMENTAL
select FW_LOADER
- select ATH_COMMON
help
This is a driver for the Atheros "otus" 802.11n USB devices.
diff --git a/drivers/net/wireless/ath/ath5k/Kconfig b/drivers/net/wireless/ath/ath5k/Kconfig
index daf0c83..9b07eef 100644
--- a/drivers/net/wireless/ath/ath5k/Kconfig
+++ b/drivers/net/wireless/ath/ath5k/Kconfig
@@ -1,7 +1,6 @@
config ATH5K
tristate "Atheros 5xxx wireless cards support"
depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL
- select ATH_COMMON
select MAC80211_LEDS
select LEDS_CLASS
select NEW_LEDS
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig
index 0f4a6d8..2cb72f8 100644
--- a/drivers/net/wireless/ath/ath9k/Kconfig
+++ b/drivers/net/wireless/ath/ath9k/Kconfig
@@ -1,7 +1,6 @@
config ATH9K
tristate "Atheros 802.11n wireless cards support"
depends on PCI && MAC80211 && WLAN_80211
- select ATH_COMMON
select MAC80211_LEDS
select LEDS_CLASS
select NEW_LEDS
--
1.6.0.4
^ permalink raw reply related
* [PATCH] ath: depend on cfg80211
From: Luis R. Rodriguez @ 2009-07-27 23:52 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Luis R. Rodriguez
In-Reply-To: <1248738730-4003-1-git-send-email-lrodriguez@atheros.com>
The ath.ko module itself depends on cfg80211
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
drivers/net/wireless/ath/Kconfig | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/drivers/net/wireless/ath/Kconfig b/drivers/net/wireless/ath/Kconfig
index eb0337c..6bed009 100644
--- a/drivers/net/wireless/ath/Kconfig
+++ b/drivers/net/wireless/ath/Kconfig
@@ -1,6 +1,7 @@
config ATH_COMMON
tristate "Atheros Wireless Cards"
depends on WLAN_80211
+ depends on CFG80211
depends on ATH5K || ATH9K || AR9170_USB
source "drivers/net/wireless/ath/ath5k/Kconfig"
--
1.6.0.4
^ permalink raw reply related
* [PATCH] atheros: few kconfig cleanups
From: Luis R. Rodriguez @ 2009-07-27 23:52 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Luis R. Rodriguez
Just few kconfig cleanups.
Luis R. Rodriguez (5):
ath: depend on cfg80211
ath: simplify kconfig dependency and add documentation
ath: use menuconfig to put ath stuff in its own page
ath5k: remove EXPERIMENTAL marker
ar9170: remove EXPERIMENTAL marker
drivers/net/wireless/ath/Kconfig | 21 ++++++++++++++++++---
drivers/net/wireless/ath/ar9170/Kconfig | 4 ++--
drivers/net/wireless/ath/ath5k/Kconfig | 3 +--
drivers/net/wireless/ath/ath9k/Kconfig | 1 -
4 files changed, 21 insertions(+), 8 deletions(-)
^ permalink raw reply
* [PATCH] rt2x00: remove experimental on kconfig
From: Luis R. Rodriguez @ 2009-07-27 23:20 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Luis R. Rodriguez, Ivo van Doorn
These have been around for a while, if there are issues
they should be reported.
Cc: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
Ivo, is this fair to say? Was surprised to see rt2x00 marked
as experimental still.
drivers/net/wireless/rt2x00/Kconfig | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig
index f970aa2..379da5c 100644
--- a/drivers/net/wireless/rt2x00/Kconfig
+++ b/drivers/net/wireless/rt2x00/Kconfig
@@ -1,8 +1,8 @@
menuconfig RT2X00
tristate "Ralink driver support"
- depends on MAC80211 && WLAN_80211 && EXPERIMENTAL
+ depends on MAC80211 && WLAN_80211
---help---
- This will enable the experimental support for the Ralink drivers,
+ This will enable the support for the Ralink drivers,
developed in the rt2x00 project <http://rt2x00.serialmonkey.com>.
These drivers make use of the mac80211 stack.
--
1.6.3.3
^ permalink raw reply related
* [PATCH] wext: remove extra return on wireless_nlevent_init()
From: Luis R. Rodriguez @ 2009-07-27 23:10 UTC (permalink / raw)
To: linville; +Cc: johannes, linux-wireless, Luis R. Rodriguez
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
net/wireless/wext.c | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/net/wireless/wext.c b/net/wireless/wext.c
index 3fe3c2c..5b4a0ce 100644
--- a/net/wireless/wext.c
+++ b/net/wireless/wext.c
@@ -1291,7 +1291,6 @@ static struct pernet_operations wext_pernet_ops = {
static int __init wireless_nlevent_init(void)
{
return register_pernet_subsys(&wext_pernet_ops);
- return 0;
}
subsys_initcall(wireless_nlevent_init);
--
1.6.3.3
^ permalink raw reply related
* Re: [PATCH 04/14] iwlwifi: Thermal Throttling Management - part 2
From: reinette chatre @ 2009-07-27 22:46 UTC (permalink / raw)
To: Johannes Berg
Cc: linville@tuxdriver.com, linux-wireless@vger.kernel.org,
ipw3945-devel@lists.sourceforge.net, Guy, Wey-Yi W
In-Reply-To: <1248733760.7015.0.camel@johannes.local>
Hi Johannes,
On Mon, 2009-07-27 at 15:29 -0700, Johannes Berg wrote:
> On Fri, 2009-07-24 at 11:13 -0700, Reinette Chatre wrote:
>
> > /**
> > + * struct iwl_tt_restriction - Thermal Throttling restriction table used
> > + * by advance thermal throttling management
> > + * based on the current thermal throttling state, determine
> > + * number of tx/rx streams; and the status of HT operation
> > + * @tx_stream: number of tx stream allowed
> > + * @is_ht: ht enable/disable
> > + * @rx_stream: number of rx stream allowed
> > + */
>
> This kernel-doc, and some others, are really botched btw -- the bit
> after 'struct foo - ' really needs to be a single line only, you can put
> longer descriptions after the parameters.
Sorry for missing this. We are trying to be better with documentation
and need to do more work in this area. This patch is currently in
wireless-testing. I am not sure how to proceed here. If I send a cleanup
patch on top of current wireless-testing it will only make sense to
address other kernel-doc mishaps. As our driver has not been tested
(afaik) to provide meaningful documentation when kernel-doc is used I am
hesitant to take on this right now ... but it is something we have to
address at some point.
Reinette
^ permalink raw reply
* Re: [PATCH 04/14] iwlwifi: Thermal Throttling Management - part 2
From: Johannes Berg @ 2009-07-27 22:29 UTC (permalink / raw)
To: Reinette Chatre; +Cc: linville, linux-wireless, ipw3945-devel, Wey-Yi Guy
In-Reply-To: <1248459194-10239-5-git-send-email-reinette.chatre@intel.com>
[-- Attachment #1: Type: text/plain, Size: 659 bytes --]
On Fri, 2009-07-24 at 11:13 -0700, Reinette Chatre wrote:
> /**
> + * struct iwl_tt_restriction - Thermal Throttling restriction table used
> + * by advance thermal throttling management
> + * based on the current thermal throttling state, determine
> + * number of tx/rx streams; and the status of HT operation
> + * @tx_stream: number of tx stream allowed
> + * @is_ht: ht enable/disable
> + * @rx_stream: number of rx stream allowed
> + */
This kernel-doc, and some others, are really botched btw -- the bit
after 'struct foo - ' really needs to be a single line only, you can put
longer descriptions after the parameters.
johannes
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
^ permalink raw reply
* Re: Problem with exclusive interrupt in hostap_cs
From: Larry Finger @ 2009-07-27 22:28 UTC (permalink / raw)
To: Wolfram Sang; +Cc: linux-pcmcia, linux-wireless
In-Reply-To: <4A6DB08F.2060108@pengutronix.de>
Wolfram Sang wrote:
> Hi Larry,
>
> Larry Finger wrote:
>
>> I took a second look at the code and found that other drivers are
>> using the
>> routine prism2_interrupt() with shared interrupts, thus the patch
>> below should
>> be all that is needed.
>>
>> I trust that you will be able to build the patched driver.
>>
>> Larry
>>
>>
>> Index: wireless-testing/drivers/net/wireless/hostap/hostap_cs.c
>> ===================================================================
>> --- wireless-testing.orig/drivers/net/wireless/hostap/hostap_cs.c
>> +++ wireless-testing/drivers/net/wireless/hostap/hostap_cs.c
>> @@ -666,7 +666,8 @@ static int prism2_config(struct pcmcia_d
>> * irq structure is initialized.
>> */
>> if (link->conf.Attributes & CONF_ENABLE_IRQ) {
>> - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
>> + link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING |
>> + IRQ_HANDLE_PRESENT;
>> link->irq.IRQInfo1 = IRQ_LEVEL_ID;
>> link->irq.Handler = prism2_interrupt;
>> link->irq.Instance = dev;
>
> Do you think this could be queued up by now? Looks okay to me...
As Dominik was missing and there was no action on the linux-pcmcia
list, I took advantage of the fact that this is a wireless device and
submitted the patch to John Linville. It is commit
e4a01604b8e5656f3a059f52b3e8f2560740c057 in the wireless-testing tree
and was sent to DaveM on July 24 for linux-next. It will be in 2.6.32.
Larry
^ permalink raw reply
* [PATCH v3] mac80211: redefine usage of the mac80211 workqueue
From: Luis R. Rodriguez @ 2009-07-27 22:21 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Luis R. Rodriguez
The mac80211 workqueue exists to enable mac80211 and drivers
to queue their own work on a single threaded workqueue. mac80211
takes care to flush the workqueue during suspend but we never
really had requirements on drivers for how they should use
the workqueue in consideration for suspend.
We extend mac80211 to document how the mac80211 workqueue should
be used, how it should not be used and finally move raw access to
the workqueue to mac80211 only. Drivers and mac80211 use helpers
to queue work onto the mac80211 workqueue:
* ieee80211_queue_work()
* ieee80211_queue_delayed_work()
These helpers will now warn if mac80211 already completed its
suspend cycle and someone is trying to queue work. mac80211
flushes the mac80211 workqueue prior to suspend a few times,
but we haven't taken the care to ensure drivers won't add more
work after suspend. To help with this we add a warning when
someone tries to add work and mac80211 already completed the
suspend cycle.
Drivers should ensure they cancel any work or delayed work
in the mac80211 stop() callback.
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
Don't use EXPORT_SYMBOL_GPL compatible to allow crap drivers to use
this interface and expose them.
drivers/net/wireless/at76c50x-usb.c | 10 +++---
drivers/net/wireless/ath/ar9170/led.c | 11 ++++--
drivers/net/wireless/ath/ar9170/main.c | 26 ++++++++------
drivers/net/wireless/ath/ath9k/main.c | 15 ++++----
drivers/net/wireless/ath/ath9k/virtual.c | 17 +++++----
drivers/net/wireless/ath/ath9k/xmit.c | 2 +-
drivers/net/wireless/b43/main.c | 8 ++--
drivers/net/wireless/b43/phy_common.c | 2 +-
drivers/net/wireless/b43/pio.c | 2 +-
drivers/net/wireless/b43legacy/main.c | 8 ++--
drivers/net/wireless/p54/led.c | 5 +--
drivers/net/wireless/p54/main.c | 2 +-
drivers/net/wireless/p54/p54spi.c | 4 +-
drivers/net/wireless/p54/txrx.c | 2 +-
drivers/net/wireless/rt2x00/rt2x00dev.c | 2 +-
drivers/net/wireless/rt2x00/rt2x00link.c | 8 ++--
drivers/net/wireless/rt2x00/rt2x00mac.c | 2 +-
drivers/net/wireless/rtl818x/rtl8187_dev.c | 2 +-
drivers/net/wireless/rtl818x/rtl8187_leds.c | 10 +++---
include/net/mac80211.h | 50 ++++++++++++++++++++++----
net/mac80211/ibss.c | 6 ++--
net/mac80211/ieee80211_i.h | 6 +++
net/mac80211/iface.c | 4 +-
net/mac80211/main.c | 8 ++--
net/mac80211/mesh.c | 10 +++---
net/mac80211/mesh_hwmp.c | 4 +-
net/mac80211/mlme.c | 48 ++++++++++++--------------
net/mac80211/pm.c | 4 +-
net/mac80211/scan.c | 8 ++--
net/mac80211/tx.c | 2 +-
net/mac80211/util.c | 41 ++++++++++++++++++++++
31 files changed, 207 insertions(+), 122 deletions(-)
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c
index aff09a1..7218dba 100644
--- a/drivers/net/wireless/at76c50x-usb.c
+++ b/drivers/net/wireless/at76c50x-usb.c
@@ -1875,8 +1875,8 @@ static void at76_dwork_hw_scan(struct work_struct *work)
/* FIXME: add maximum time for scan to complete */
if (ret != CMD_STATUS_COMPLETE) {
- queue_delayed_work(priv->hw->workqueue, &priv->dwork_hw_scan,
- SCAN_POLL_INTERVAL);
+ ieee80211_queue_delayed_work(priv->hw, &priv->dwork_hw_scan,
+ SCAN_POLL_INTERVAL);
mutex_unlock(&priv->mtx);
return;
}
@@ -1937,8 +1937,8 @@ static int at76_hw_scan(struct ieee80211_hw *hw,
goto exit;
}
- queue_delayed_work(priv->hw->workqueue, &priv->dwork_hw_scan,
- SCAN_POLL_INTERVAL);
+ ieee80211_queue_delayed_work(priv->hw, &priv->dwork_hw_scan,
+ SCAN_POLL_INTERVAL);
exit:
mutex_unlock(&priv->mtx);
@@ -2027,7 +2027,7 @@ static void at76_configure_filter(struct ieee80211_hw *hw,
} else
return;
- queue_work(hw->workqueue, &priv->work_set_promisc);
+ ieee80211_queue_work(hw, &priv->work_set_promisc);
}
static int at76_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
diff --git a/drivers/net/wireless/ath/ar9170/led.c b/drivers/net/wireless/ath/ar9170/led.c
index 63fda6c..86c4e79 100644
--- a/drivers/net/wireless/ath/ar9170/led.c
+++ b/drivers/net/wireless/ath/ar9170/led.c
@@ -90,9 +90,12 @@ static void ar9170_update_leds(struct work_struct *work)
ar9170_set_leds_state(ar, led_val);
mutex_unlock(&ar->mutex);
- if (rerun)
- queue_delayed_work(ar->hw->workqueue, &ar->led_work,
- msecs_to_jiffies(blink_delay));
+ if (!rerun)
+ return;
+
+ ieee80211_queue_delayed_work(ar->hw,
+ &ar->led_work,
+ msecs_to_jiffies(blink_delay));
}
static void ar9170_led_brightness_set(struct led_classdev *led,
@@ -110,7 +113,7 @@ static void ar9170_led_brightness_set(struct led_classdev *led,
}
if (likely(IS_ACCEPTING_CMD(ar) && arl->toggled))
- queue_delayed_work(ar->hw->workqueue, &ar->led_work, HZ/10);
+ ieee80211_queue_delayed_work(ar->hw, &ar->led_work, HZ/10);
}
static int ar9170_register_led(struct ar9170 *ar, int i, char *name,
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c
index 099ed3c..4fc389a 100644
--- a/drivers/net/wireless/ath/ar9170/main.c
+++ b/drivers/net/wireless/ath/ar9170/main.c
@@ -595,10 +595,12 @@ static void ar9170_tx_janitor(struct work_struct *work)
ar9170_tx_fake_ampdu_status(ar);
- if (resched)
- queue_delayed_work(ar->hw->workqueue,
- &ar->tx_janitor,
- msecs_to_jiffies(AR9170_JANITOR_DELAY));
+ if (!resched)
+ return;
+
+ ieee80211_queue_delayed_work(ar->hw,
+ &ar->tx_janitor,
+ msecs_to_jiffies(AR9170_JANITOR_DELAY));
}
void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len)
@@ -648,7 +650,7 @@ void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len)
* pre-TBTT event
*/
if (ar->vif && ar->vif->type == NL80211_IFTYPE_AP)
- queue_work(ar->hw->workqueue, &ar->beacon_work);
+ ieee80211_queue_work(ar->hw, &ar->beacon_work);
break;
case 0xc2:
@@ -1825,10 +1827,12 @@ static void ar9170_tx(struct ar9170 *ar)
}
}
- if (schedule_garbagecollector)
- queue_delayed_work(ar->hw->workqueue,
- &ar->tx_janitor,
- msecs_to_jiffies(AR9170_JANITOR_DELAY));
+ if (!schedule_garbagecollector)
+ return;
+
+ ieee80211_queue_delayed_work(ar->hw,
+ &ar->tx_janitor,
+ msecs_to_jiffies(AR9170_JANITOR_DELAY));
}
static bool ar9170_tx_ampdu_queue(struct ar9170 *ar, struct sk_buff *skb)
@@ -2157,7 +2161,7 @@ static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
}
if (likely(IS_STARTED(ar)))
- queue_work(ar->hw->workqueue, &ar->filter_config_work);
+ ieee80211_queue_work(ar->hw, &ar->filter_config_work);
}
static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw,
@@ -2415,7 +2419,7 @@ static void ar9170_sta_notify(struct ieee80211_hw *hw,
}
if (IS_STARTED(ar) && ar->filter_changed)
- queue_work(ar->hw->workqueue, &ar->filter_config_work);
+ ieee80211_queue_work(ar->hw, &ar->filter_config_work);
}
static int ar9170_get_stats(struct ieee80211_hw *hw,
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index cf44623..292ac2b 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -973,10 +973,11 @@ static void ath_led_blink_work(struct work_struct *work)
ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN,
(sc->sc_flags & SC_OP_LED_ON) ? 1 : 0);
- queue_delayed_work(sc->hw->workqueue, &sc->ath_led_blink_work,
- (sc->sc_flags & SC_OP_LED_ON) ?
- msecs_to_jiffies(sc->led_off_duration) :
- msecs_to_jiffies(sc->led_on_duration));
+ ieee80211_queue_delayed_work(sc->hw,
+ &sc->ath_led_blink_work,
+ (sc->sc_flags & SC_OP_LED_ON) ?
+ msecs_to_jiffies(sc->led_off_duration) :
+ msecs_to_jiffies(sc->led_on_duration));
sc->led_on_duration = sc->led_on_cnt ?
max((ATH_LED_ON_DURATION_IDLE - sc->led_on_cnt), 25) :
@@ -1013,8 +1014,8 @@ static void ath_led_brightness(struct led_classdev *led_cdev,
case LED_FULL:
if (led->led_type == ATH_LED_ASSOC) {
sc->sc_flags |= SC_OP_LED_ASSOCIATED;
- queue_delayed_work(sc->hw->workqueue,
- &sc->ath_led_blink_work, 0);
+ ieee80211_queue_delayed_work(sc->hw,
+ &sc->ath_led_blink_work, 0);
} else if (led->led_type == ATH_LED_RADIO) {
ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 0);
sc->sc_flags |= SC_OP_LED_ON;
@@ -1972,7 +1973,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
ieee80211_wake_queues(hw);
- queue_delayed_work(sc->hw->workqueue, &sc->tx_complete_work, 0);
+ ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
mutex_unlock:
mutex_unlock(&sc->mutex);
diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c
index e1d419e..19b88f8 100644
--- a/drivers/net/wireless/ath/ath9k/virtual.c
+++ b/drivers/net/wireless/ath/ath9k/virtual.c
@@ -351,7 +351,7 @@ void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
* Drop from tasklet to work to allow mutex for channel
* change.
*/
- queue_work(aphy->sc->hw->workqueue,
+ ieee80211_queue_work(aphy->sc->hw,
&aphy->sc->chan_work);
}
}
@@ -367,7 +367,7 @@ static void ath9k_mark_paused(struct ath_wiphy *aphy)
struct ath_softc *sc = aphy->sc;
aphy->state = ATH_WIPHY_PAUSED;
if (!__ath9k_wiphy_pausing(sc))
- queue_work(sc->hw->workqueue, &sc->chan_work);
+ ieee80211_queue_work(sc->hw, &sc->chan_work);
}
static void ath9k_pause_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
@@ -521,7 +521,7 @@ int ath9k_wiphy_select(struct ath_wiphy *aphy)
spin_unlock_bh(&sc->wiphy_lock);
ath_radio_disable(sc);
ath_radio_enable(sc);
- queue_work(aphy->sc->hw->workqueue,
+ ieee80211_queue_work(aphy->sc->hw,
&aphy->sc->chan_work);
return -EBUSY; /* previous select still in progress */
}
@@ -541,7 +541,7 @@ int ath9k_wiphy_select(struct ath_wiphy *aphy)
if (now) {
/* Ready to request channel change immediately */
- queue_work(aphy->sc->hw->workqueue, &aphy->sc->chan_work);
+ ieee80211_queue_work(aphy->sc->hw, &aphy->sc->chan_work);
}
/*
@@ -648,8 +648,9 @@ try_again:
"change\n");
}
- queue_delayed_work(sc->hw->workqueue, &sc->wiphy_work,
- sc->wiphy_scheduler_int);
+ ieee80211_queue_delayed_work(sc->hw,
+ &sc->wiphy_work,
+ sc->wiphy_scheduler_int);
}
void ath9k_wiphy_set_scheduler(struct ath_softc *sc, unsigned int msec_int)
@@ -657,8 +658,8 @@ void ath9k_wiphy_set_scheduler(struct ath_softc *sc, unsigned int msec_int)
cancel_delayed_work_sync(&sc->wiphy_work);
sc->wiphy_scheduler_int = msecs_to_jiffies(msec_int);
if (sc->wiphy_scheduler_int)
- queue_delayed_work(sc->hw->workqueue, &sc->wiphy_work,
- sc->wiphy_scheduler_int);
+ ieee80211_queue_delayed_work(sc->hw, &sc->wiphy_work,
+ sc->wiphy_scheduler_int);
}
/* caller must hold wiphy_lock */
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index b7806e2..87762da 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -2063,7 +2063,7 @@ static void ath_tx_complete_poll_work(struct work_struct *work)
ath_reset(sc, false);
}
- queue_delayed_work(sc->hw->workqueue, &sc->tx_complete_work,
+ ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work,
msecs_to_jiffies(ATH_TX_COMPLETE_POLL_INT));
}
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 3f4360a..f985938 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -1654,7 +1654,7 @@ static void b43_update_templates(struct b43_wl *wl)
wl->current_beacon = beacon;
wl->beacon0_uploaded = 0;
wl->beacon1_uploaded = 0;
- queue_work(wl->hw->workqueue, &wl->beacon_update_trigger);
+ ieee80211_queue_work(wl->hw, &wl->beacon_update_trigger);
}
static void b43_set_beacon_int(struct b43_wldev *dev, u16 beacon_int)
@@ -2914,7 +2914,7 @@ out_requeue:
delay = msecs_to_jiffies(50);
else
delay = round_jiffies_relative(HZ * 15);
- queue_delayed_work(wl->hw->workqueue, &dev->periodic_work, delay);
+ ieee80211_queue_delayed_work(wl->hw, &dev->periodic_work, delay);
out:
mutex_unlock(&wl->mutex);
}
@@ -2925,7 +2925,7 @@ static void b43_periodic_tasks_setup(struct b43_wldev *dev)
dev->periodic_state = 0;
INIT_DELAYED_WORK(work, b43_periodic_work_handler);
- queue_delayed_work(dev->wl->hw->workqueue, work, 0);
+ ieee80211_queue_delayed_work(dev->wl->hw, work, 0);
}
/* Check if communication with the device works correctly. */
@@ -4871,7 +4871,7 @@ void b43_controller_restart(struct b43_wldev *dev, const char *reason)
if (b43_status(dev) < B43_STAT_INITIALIZED)
return;
b43info(dev->wl, "Controller RESET (%s) ...\n", reason);
- queue_work(dev->wl->hw->workqueue, &dev->restart_work);
+ ieee80211_queue_work(dev->wl->hw, &dev->restart_work);
}
#ifdef CONFIG_PM
diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c
index 6d24162..f537bfe 100644
--- a/drivers/net/wireless/b43/phy_common.c
+++ b/drivers/net/wireless/b43/phy_common.c
@@ -352,7 +352,7 @@ void b43_phy_txpower_check(struct b43_wldev *dev, unsigned int flags)
/* We must adjust the transmission power in hardware.
* Schedule b43_phy_txpower_adjust_work(). */
- queue_work(dev->wl->hw->workqueue, &dev->wl->txpower_adjust_work);
+ ieee80211_queue_work(dev->wl->hw, &dev->wl->txpower_adjust_work);
}
int b43_phy_shm_tssi_read(struct b43_wldev *dev, u16 shm_offset)
diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c
index 69138e8..73c047d 100644
--- a/drivers/net/wireless/b43/pio.c
+++ b/drivers/net/wireless/b43/pio.c
@@ -783,7 +783,7 @@ void b43_pio_rx(struct b43_pio_rxqueue *q)
{
/* Due to latency issues we must run the RX path in
* a workqueue to be able to schedule between packets. */
- queue_work(q->dev->wl->hw->workqueue, &q->rx_work);
+ ieee80211_queue_work(q->dev->wl->hw, &q->rx_work);
}
static void b43_pio_tx_suspend_queue(struct b43_pio_txqueue *q)
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index c4973c1..b143559 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -1252,7 +1252,7 @@ static void b43legacy_update_templates(struct b43legacy_wl *wl)
wl->current_beacon = beacon;
wl->beacon0_uploaded = 0;
wl->beacon1_uploaded = 0;
- queue_work(wl->hw->workqueue, &wl->beacon_update_trigger);
+ ieee80211_queue_work(wl->hw, &wl->beacon_update_trigger);
}
static void b43legacy_set_beacon_int(struct b43legacy_wldev *dev,
@@ -2300,7 +2300,7 @@ out_requeue:
delay = msecs_to_jiffies(50);
else
delay = round_jiffies_relative(HZ * 15);
- queue_delayed_work(wl->hw->workqueue, &dev->periodic_work, delay);
+ ieee80211_queue_delayed_work(wl->hw, &dev->periodic_work, delay);
out:
mutex_unlock(&wl->mutex);
}
@@ -2311,7 +2311,7 @@ static void b43legacy_periodic_tasks_setup(struct b43legacy_wldev *dev)
dev->periodic_state = 0;
INIT_DELAYED_WORK(work, b43legacy_periodic_work_handler);
- queue_delayed_work(dev->wl->hw->workqueue, work, 0);
+ ieee80211_queue_delayed_work(dev->wl->hw, work, 0);
}
/* Validate access to the chip (SHM) */
@@ -3885,7 +3885,7 @@ void b43legacy_controller_restart(struct b43legacy_wldev *dev,
if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED)
return;
b43legacyinfo(dev->wl, "Controller RESET (%s) ...\n", reason);
- queue_work(dev->wl->hw->workqueue, &dev->restart_work);
+ ieee80211_queue_work(dev->wl->hw, &dev->restart_work);
}
#ifdef CONFIG_PM
diff --git a/drivers/net/wireless/p54/led.c b/drivers/net/wireless/p54/led.c
index c00115b..9575ac0 100644
--- a/drivers/net/wireless/p54/led.c
+++ b/drivers/net/wireless/p54/led.c
@@ -61,7 +61,7 @@ static void p54_update_leds(struct work_struct *work)
wiphy_name(priv->hw->wiphy), err);
if (rerun)
- queue_delayed_work(priv->hw->workqueue, &priv->led_work,
+ ieee80211_queue_delayed_work(priv->hw, &priv->led_work,
msecs_to_jiffies(blink_delay));
}
@@ -78,8 +78,7 @@ static void p54_led_brightness_set(struct led_classdev *led_dev,
if ((brightness) && (led->registered)) {
led->toggled++;
- queue_delayed_work(priv->hw->workqueue, &priv->led_work,
- HZ/10);
+ ieee80211_queue_delayed_work(priv->hw, &priv->led_work, HZ/10);
}
}
diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c
index 955f6d7..a0d0e72 100644
--- a/drivers/net/wireless/p54/main.c
+++ b/drivers/net/wireless/p54/main.c
@@ -180,7 +180,7 @@ static int p54_start(struct ieee80211_hw *dev)
goto out;
}
- queue_delayed_work(dev->workqueue, &priv->work, 0);
+ ieee80211_queue_delayed_work(dev, &priv->work, 0);
priv->softled_state = 0;
err = p54_set_leds(priv);
diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c
index eef5329..05458d9 100644
--- a/drivers/net/wireless/p54/p54spi.c
+++ b/drivers/net/wireless/p54/p54spi.c
@@ -391,7 +391,7 @@ static irqreturn_t p54spi_interrupt(int irq, void *config)
struct spi_device *spi = config;
struct p54s_priv *priv = dev_get_drvdata(&spi->dev);
- queue_work(priv->hw->workqueue, &priv->work);
+ ieee80211_queue_work(priv->hw, &priv->work);
return IRQ_HANDLED;
}
@@ -479,7 +479,7 @@ static void p54spi_op_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
list_add_tail(&di->tx_list, &priv->tx_pending);
spin_unlock_irqrestore(&priv->tx_lock, flags);
- queue_work(priv->hw->workqueue, &priv->work);
+ ieee80211_queue_work(priv->hw, &priv->work);
}
static void p54spi_work(struct work_struct *work)
diff --git a/drivers/net/wireless/p54/txrx.c b/drivers/net/wireless/p54/txrx.c
index c32a0d2..704685f 100644
--- a/drivers/net/wireless/p54/txrx.c
+++ b/drivers/net/wireless/p54/txrx.c
@@ -380,7 +380,7 @@ static int p54_rx_data(struct p54_common *priv, struct sk_buff *skb)
ieee80211_rx_irqsafe(priv->hw, skb);
- queue_delayed_work(priv->hw->workqueue, &priv->work,
+ ieee80211_queue_delayed_work(priv->hw, &priv->work,
msecs_to_jiffies(P54_STATISTICS_UPDATE));
return -1;
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 658a63b..b717afb 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -215,7 +215,7 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev)
rt2x00lib_beacondone_iter,
rt2x00dev);
- queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->intf_work);
+ ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->intf_work);
}
EXPORT_SYMBOL_GPL(rt2x00lib_beacondone);
diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c
index 7991568..9178316 100644
--- a/drivers/net/wireless/rt2x00/rt2x00link.c
+++ b/drivers/net/wireless/rt2x00/rt2x00link.c
@@ -351,8 +351,8 @@ void rt2x00link_start_tuner(struct rt2x00_dev *rt2x00dev)
rt2x00link_reset_tuner(rt2x00dev, false);
- queue_delayed_work(rt2x00dev->hw->workqueue,
- &link->work, LINK_TUNE_INTERVAL);
+ ieee80211_queue_delayed_work(rt2x00dev->hw,
+ &link->work, LINK_TUNE_INTERVAL);
}
void rt2x00link_stop_tuner(struct rt2x00_dev *rt2x00dev)
@@ -461,8 +461,8 @@ static void rt2x00link_tuner(struct work_struct *work)
* Increase tuner counter, and reschedule the next link tuner run.
*/
link->count++;
- queue_delayed_work(rt2x00dev->hw->workqueue,
- &link->work, LINK_TUNE_INTERVAL);
+ ieee80211_queue_delayed_work(rt2x00dev->hw,
+ &link->work, LINK_TUNE_INTERVAL);
}
void rt2x00link_register(struct rt2x00_dev *rt2x00dev)
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 7de1a2c..36f8135 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -431,7 +431,7 @@ void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
if (!test_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags))
rt2x00dev->ops->lib->config_filter(rt2x00dev, *total_flags);
else
- queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->filter_work);
+ ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->filter_work);
}
EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter);
diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c
index c9b9dbe..53f57dc 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c
@@ -220,7 +220,7 @@ static void rtl8187_tx_cb(struct urb *urb)
* reading a register in the device. We are in interrupt mode
* here, thus queue the skb and finish on a work queue. */
skb_queue_tail(&priv->b_tx_status.queue, skb);
- queue_delayed_work(hw->workqueue, &priv->work, 0);
+ ieee80211_queue_delayed_work(hw, &priv->work, 0);
}
}
diff --git a/drivers/net/wireless/rtl818x/rtl8187_leds.c b/drivers/net/wireless/rtl818x/rtl8187_leds.c
index cf9f899..a6cfb7e 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_leds.c
+++ b/drivers/net/wireless/rtl818x/rtl8187_leds.c
@@ -108,11 +108,11 @@ static void rtl8187_led_brightness_set(struct led_classdev *led_dev,
struct rtl8187_priv *priv = hw->priv;
if (brightness == LED_OFF) {
- queue_delayed_work(hw->workqueue, &priv->led_off, 0);
+ ieee80211_queue_delayed_work(hw, &priv->led_off, 0);
/* The LED is off for 1/20 sec so that it just blinks. */
- queue_delayed_work(hw->workqueue, &priv->led_on, HZ / 20);
+ ieee80211_queue_delayed_work(hw, &priv->led_on, HZ / 20);
} else
- queue_delayed_work(hw->workqueue, &priv->led_on, 0);
+ ieee80211_queue_delayed_work(hw, &priv->led_on, 0);
}
static int rtl8187_register_led(struct ieee80211_hw *dev,
@@ -193,7 +193,7 @@ void rtl8187_leds_init(struct ieee80211_hw *dev, u16 custid)
err = rtl8187_register_led(dev, &priv->led_rx, name,
ieee80211_get_rx_led_name(dev), ledpin);
if (!err) {
- queue_delayed_work(dev->workqueue, &priv->led_on, 0);
+ ieee80211_queue_delayed_work(dev, &priv->led_on, 0);
return;
}
/* registration of RX LED failed - unregister TX */
@@ -209,7 +209,7 @@ void rtl8187_leds_exit(struct ieee80211_hw *dev)
struct rtl8187_priv *priv = dev->priv;
/* turn the LED off before exiting */
- queue_delayed_work(dev->workqueue, &priv->led_off, 0);
+ ieee80211_queue_delayed_work(dev, &priv->led_off, 0);
cancel_delayed_work_sync(&priv->led_off);
cancel_delayed_work_sync(&priv->led_on);
rtl8187_unregister_led(&priv->led_rx);
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index d4e09a0..5ed93f4 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -73,6 +73,21 @@
*/
/**
+ * DOC: mac80211 workqueue
+ *
+ * mac80211 provides its own workqueue for drivers and internal mac80211 use.
+ * The workqueue is a single threaded workqueue and can only be accessed by
+ * helpers for sanity checking. Drivers must ensure all work added onto the
+ * mac80211 workqueue should be cancelled on the driver stop() callback.
+ *
+ * mac80211 will flushed the workqueue upon interface removal and during
+ * suspend.
+ *
+ * All work performed on the mac80211 workqueue must not acquire the RTNL lock.
+ *
+ */
+
+/**
* enum ieee80211_max_queues - maximum number of queues
*
* @IEEE80211_MAX_QUEUES: Maximum number of regular device queues.
@@ -913,12 +928,6 @@ enum ieee80211_hw_flags {
*
* @conf: &struct ieee80211_conf, device configuration, don't use.
*
- * @workqueue: single threaded workqueue available for driver use,
- * allocated by mac80211 on registration and flushed when an
- * interface is removed.
- * NOTICE: All work performed on this workqueue must not
- * acquire the RTNL lock.
- *
* @priv: pointer to private area that was allocated for driver use
* along with this structure.
*
@@ -954,7 +963,6 @@ enum ieee80211_hw_flags {
struct ieee80211_hw {
struct ieee80211_conf conf;
struct wiphy *wiphy;
- struct workqueue_struct *workqueue;
const char *rate_control_algorithm;
void *priv;
u32 flags;
@@ -1301,7 +1309,8 @@ enum ieee80211_ampdu_mlme_action {
* is disabled. This should turn off the hardware (at least
* it must turn off frame reception.)
* May be called right after add_interface if that rejects
- * an interface.
+ * an interface. If you added any work onto the mac80211 workqueue
+ * you should ensure to cancel it on this callback.
* Must be implemented.
*
* @add_interface: Called when a netdevice attached to the hardware is
@@ -1928,6 +1937,31 @@ void ieee80211_iterate_active_interfaces_atomic(struct ieee80211_hw *hw,
void *data);
/**
+ * ieee80211_queue_work - add work onto the mac80211 workqueue
+ *
+ * Drivers and mac80211 use this to add work onto the mac80211 workqueue.
+ * This helper ensures drivers are not queueing work when they should not be.
+ *
+ * @hw: the hardware struct for the interface we are adding work for
+ * @work: the work we want to add onto the mac80211 workqueue
+ */
+void ieee80211_queue_work(struct ieee80211_hw *hw, struct work_struct *work);
+
+/**
+ * ieee80211_queue_delayed_work - add work onto the mac80211 workqueue
+ *
+ * Drivers and mac80211 use this to queue delayed work onto the mac80211
+ * workqueue.
+ *
+ * @hw: the hardware struct for the interface we are adding work for
+ * @dwork: delayable work to queue onto the mac80211 workqueue
+ * @delay: number of jiffies to wait before queueing
+ */
+void ieee80211_queue_delayed_work(struct ieee80211_hw *hw,
+ struct delayed_work *dwork,
+ unsigned long delay);
+
+/**
* ieee80211_start_tx_ba_session - Start a tx Block Ack session.
* @hw: pointer as obtained from ieee80211_alloc_hw().
* @ra: receiver address of the BA session recipient
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 6e3cca6..920ec87 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -781,7 +781,7 @@ static void ieee80211_ibss_timer(unsigned long data)
}
set_bit(IEEE80211_IBSS_REQ_RUN, &ifibss->request);
- queue_work(local->hw.workqueue, &ifibss->work);
+ ieee80211_queue_work(&local->hw, &ifibss->work);
}
#ifdef CONFIG_PM
@@ -853,7 +853,7 @@ ieee80211_ibss_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
case IEEE80211_STYPE_PROBE_REQ:
case IEEE80211_STYPE_AUTH:
skb_queue_tail(&sdata->u.ibss.skb_queue, skb);
- queue_work(local->hw.workqueue, &sdata->u.ibss.work);
+ ieee80211_queue_work(&local->hw, &sdata->u.ibss.work);
return RX_QUEUED;
}
@@ -912,7 +912,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
ieee80211_recalc_idle(sdata->local);
set_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request);
- queue_work(sdata->local->hw.workqueue, &sdata->u.ibss.work);
+ ieee80211_queue_work(&sdata->local->hw, &sdata->u.ibss.work);
return 0;
}
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index aec6853..316825b 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -614,6 +614,12 @@ struct ieee80211_local {
const struct ieee80211_ops *ops;
+ /*
+ * private workqueue to mac80211. mac80211 makes this accessible
+ * via ieee80211_queue_work()
+ */
+ struct workqueue_struct *workqueue;
+
unsigned long queue_stop_reasons[IEEE80211_MAX_QUEUES];
/* also used to protect ampdu_ac_queue and amdpu_ac_stop_refcnt */
spinlock_t queue_stop_reason_lock;
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 6c655b6..342edab 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -312,7 +312,7 @@ static int ieee80211_open(struct net_device *dev)
* to fix this.
*/
if (sdata->vif.type == NL80211_IFTYPE_STATION)
- queue_work(local->hw.workqueue, &sdata->u.mgd.work);
+ ieee80211_queue_work(&local->hw, &sdata->u.mgd.work);
netif_tx_start_all_queues(dev);
@@ -541,7 +541,7 @@ static int ieee80211_stop(struct net_device *dev)
ieee80211_led_radio(local, false);
- flush_workqueue(local->hw.workqueue);
+ flush_workqueue(local->workqueue);
tasklet_disable(&local->tx_pending_tasklet);
tasklet_disable(&local->tasklet);
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index c1a7991..2309074 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -794,9 +794,9 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
if (hw->queues > IEEE80211_MAX_QUEUES)
hw->queues = IEEE80211_MAX_QUEUES;
- local->hw.workqueue =
+ local->workqueue =
create_singlethread_workqueue(wiphy_name(local->hw.wiphy));
- if (!local->hw.workqueue) {
+ if (!local->workqueue) {
result = -ENOMEM;
goto fail_workqueue;
}
@@ -886,7 +886,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
sta_info_stop(local);
fail_sta_info:
debugfs_hw_del(local);
- destroy_workqueue(local->hw.workqueue);
+ destroy_workqueue(local->workqueue);
fail_workqueue:
wiphy_unregister(local->hw.wiphy);
fail_wiphy_register:
@@ -928,7 +928,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
skb_queue_purge(&local->skb_queue);
skb_queue_purge(&local->skb_queue_unreliable);
- destroy_workqueue(local->hw.workqueue);
+ destroy_workqueue(local->workqueue);
wiphy_unregister(local->hw.wiphy);
ieee80211_wep_free(local);
ieee80211_led_exit(local);
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 9a38269..2f4f518 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -54,7 +54,7 @@ static void ieee80211_mesh_housekeeping_timer(unsigned long data)
return;
}
- queue_work(local->hw.workqueue, &ifmsh->work);
+ ieee80211_queue_work(local->hw.workqueue, &ifmsh->work);
}
/**
@@ -357,7 +357,7 @@ static void ieee80211_mesh_path_timer(unsigned long data)
return;
}
- queue_work(local->hw.workqueue, &ifmsh->work);
+ ieee80211_queue_work(local->hw.workqueue, &ifmsh->work);
}
struct mesh_table *mesh_table_grow(struct mesh_table *tbl)
@@ -471,7 +471,7 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
struct ieee80211_local *local = sdata->local;
ifmsh->housekeeping = true;
- queue_work(local->hw.workqueue, &ifmsh->work);
+ ieee80211_queue_work(local->hw.workqueue, &ifmsh->work);
ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON |
BSS_CHANGED_BEACON_ENABLED);
}
@@ -619,7 +619,7 @@ void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local)
rcu_read_lock();
list_for_each_entry_rcu(sdata, &local->interfaces, list)
if (ieee80211_vif_is_mesh(&sdata->vif))
- queue_work(local->hw.workqueue, &sdata->u.mesh.work);
+ ieee80211_queue_work(local->hw.workqueue, &sdata->u.mesh.work);
rcu_read_unlock();
}
@@ -692,7 +692,7 @@ ieee80211_mesh_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
case IEEE80211_STYPE_PROBE_RESP:
case IEEE80211_STYPE_BEACON:
skb_queue_tail(&ifmsh->skb_queue, skb);
- queue_work(local->hw.workqueue, &ifmsh->work);
+ ieee80211_queue_work(local->hw.workqueue, &ifmsh->work);
return RX_QUEUED;
}
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index e93c37e..11ab71a 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -660,14 +660,14 @@ static void mesh_queue_preq(struct mesh_path *mpath, u8 flags)
spin_unlock(&ifmsh->mesh_preq_queue_lock);
if (time_after(jiffies, ifmsh->last_preq + min_preq_int_jiff(sdata)))
- queue_work(sdata->local->hw.workqueue, &ifmsh->work);
+ ieee80211_queue_work(sdata->local->hw.workqueue, &ifmsh->work);
else if (time_before(jiffies, ifmsh->last_preq)) {
/* avoid long wait if did not send preqs for a long time
* and jiffies wrapped around
*/
ifmsh->last_preq = jiffies - min_preq_int_jiff(sdata) - 1;
- queue_work(sdata->local->hw.workqueue, &ifmsh->work);
+ ieee80211_queue_work(sdata->local->hw.workqueue, &ifmsh->work);
} else
mod_timer(&ifmsh->mesh_path_timer, ifmsh->last_preq +
min_preq_int_jiff(sdata));
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index ee83125..0779ba1 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -565,7 +565,7 @@ static void ieee80211_chswitch_timer(unsigned long data)
return;
}
- queue_work(sdata->local->hw.workqueue, &ifmgd->chswitch_work);
+ ieee80211_queue_work(&sdata->local->hw, &ifmgd->chswitch_work);
}
void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
@@ -597,7 +597,7 @@ void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
sdata->local->csa_channel = new_ch;
if (sw_elem->count <= 1) {
- queue_work(sdata->local->hw.workqueue, &ifmgd->chswitch_work);
+ ieee80211_queue_work(&sdata->local->hw, &ifmgd->chswitch_work);
} else {
ieee80211_stop_queues_by_reason(&sdata->local->hw,
IEEE80211_QUEUE_STOP_REASON_CSA);
@@ -763,7 +763,7 @@ void ieee80211_dynamic_ps_timer(unsigned long data)
if (local->quiescing || local->suspended)
return;
- queue_work(local->hw.workqueue, &local->dynamic_ps_enable_work);
+ ieee80211_queue_work(&local->hw, &local->dynamic_ps_enable_work);
}
/* MLME */
@@ -950,7 +950,7 @@ ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata,
* due to work needing to be done. Hence, queue the STAs work
* again for that.
*/
- queue_work(local->hw.workqueue, &ifmgd->work);
+ ieee80211_queue_work(&local->hw, &ifmgd->work);
return RX_MGMT_CFG80211_AUTH_TO;
}
@@ -995,7 +995,7 @@ ieee80211_authenticate(struct ieee80211_sub_if_data *sdata,
* due to work needing to be done. Hence, queue the STAs work
* again for that.
*/
- queue_work(local->hw.workqueue, &ifmgd->work);
+ ieee80211_queue_work(&local->hw, &ifmgd->work);
return RX_MGMT_CFG80211_AUTH_TO;
}
@@ -1124,7 +1124,7 @@ ieee80211_associate(struct ieee80211_sub_if_data *sdata,
* due to work needing to be done. Hence, queue the STAs work
* again for that.
*/
- queue_work(local->hw.workqueue, &ifmgd->work);
+ ieee80211_queue_work(&local->hw, &ifmgd->work);
return RX_MGMT_CFG80211_ASSOC_TO;
}
@@ -1232,8 +1232,7 @@ void ieee80211_beacon_loss(struct ieee80211_vif *vif)
{
struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
- queue_work(sdata->local->hw.workqueue,
- &sdata->u.mgd.beacon_loss_work);
+ ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.beacon_loss_work);
}
EXPORT_SYMBOL(ieee80211_beacon_loss);
@@ -1888,7 +1887,7 @@ ieee80211_rx_result ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata,
case IEEE80211_STYPE_DISASSOC:
case IEEE80211_STYPE_ACTION:
skb_queue_tail(&sdata->u.mgd.skb_queue, skb);
- queue_work(local->hw.workqueue, &sdata->u.mgd.work);
+ ieee80211_queue_work(&local->hw, &sdata->u.mgd.work);
return RX_QUEUED;
}
@@ -2026,7 +2025,7 @@ static void ieee80211_sta_timer(unsigned long data)
return;
}
- queue_work(local->hw.workqueue, &ifmgd->work);
+ ieee80211_queue_work(&local->hw, &ifmgd->work);
}
static void ieee80211_sta_work(struct work_struct *work)
@@ -2051,13 +2050,11 @@ static void ieee80211_sta_work(struct work_struct *work)
return;
/*
- * Nothing should have been stuffed into the workqueue during
- * the suspend->resume cycle. If this WARN is seen then there
- * is a bug with either the driver suspend or something in
- * mac80211 stuffing into the workqueue which we haven't yet
- * cleared during mac80211's suspend cycle.
+ * ieee80211_queue_work() should have picked up most cases,
+ * here we'll pick the the rest.
*/
- if (WARN_ON(local->suspended))
+ if (WARN(local->suspended, "STA MLME work scheduled while "
+ "going to suspend\n"))
return;
ifmgd = &sdata->u.mgd;
@@ -2113,9 +2110,9 @@ static void ieee80211_sta_work(struct work_struct *work)
mutex_unlock(&ifmgd->mtx);
if (test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request))
- queue_delayed_work(local->hw.workqueue,
- &local->scan_work,
- round_jiffies_relative(0));
+ ieee80211_queue_delayed_work(&local->hw,
+ &local->scan_work,
+ round_jiffies_relative(0));
return;
}
@@ -2196,8 +2193,7 @@ static void ieee80211_sta_bcn_mon_timer(unsigned long data)
if (local->quiescing)
return;
- queue_work(sdata->local->hw.workqueue,
- &sdata->u.mgd.beacon_loss_work);
+ ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.beacon_loss_work);
}
static void ieee80211_sta_conn_mon_timer(unsigned long data)
@@ -2210,7 +2206,7 @@ static void ieee80211_sta_conn_mon_timer(unsigned long data)
if (local->quiescing)
return;
- queue_work(local->hw.workqueue, &ifmgd->monitor_work);
+ ieee80211_queue_work(&local->hw, &ifmgd->monitor_work);
}
static void ieee80211_sta_monitor_work(struct work_struct *work)
@@ -2229,10 +2225,10 @@ static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata)
IEEE80211_STA_CONNECTION_POLL);
/* let's probe the connection once */
- queue_work(sdata->local->hw.workqueue,
+ ieee80211_queue_work(&sdata->local->hw,
&sdata->u.mgd.monitor_work);
/* and do all the other regular work too */
- queue_work(sdata->local->hw.workqueue,
+ ieee80211_queue_work(&sdata->local->hw,
&sdata->u.mgd.work);
}
}
@@ -2393,7 +2389,7 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
list_add(&wk->list, &sdata->u.mgd.work_list);
mutex_unlock(&ifmgd->mtx);
- queue_work(sdata->local->hw.workqueue, &sdata->u.mgd.work);
+ ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.work);
return 0;
}
@@ -2467,7 +2463,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
else
ifmgd->flags &= ~IEEE80211_STA_CONTROL_PORT;
- queue_work(sdata->local->hw.workqueue, &sdata->u.mgd.work);
+ ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.work);
err = 0;
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
index 7a549f9..271db2c 100644
--- a/net/mac80211/pm.c
+++ b/net/mac80211/pm.c
@@ -26,7 +26,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw)
/* make quiescing visible to timers everywhere */
mb();
- flush_workqueue(local->hw.workqueue);
+ flush_workqueue(local->workqueue);
/* Don't try to run timers while suspended. */
del_timer_sync(&local->sta_cleanup);
@@ -56,7 +56,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw)
rcu_read_unlock();
/* flush again, in case driver queued work */
- flush_workqueue(local->hw.workqueue);
+ flush_workqueue(local->workqueue);
/* stop hardware - this must stop RX */
if (local->open_count) {
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 4573100..244f53f 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -385,8 +385,9 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local)
spin_unlock_bh(&local->filter_lock);
/* TODO: start scan as soon as all nullfunc frames are ACKed */
- queue_delayed_work(local->hw.workqueue, &local->scan_work,
- IEEE80211_CHANNEL_TIME);
+ ieee80211_queue_delayed_work(&local->hw,
+ &local->scan_work,
+ IEEE80211_CHANNEL_TIME);
return 0;
}
@@ -715,8 +716,7 @@ void ieee80211_scan_work(struct work_struct *work)
}
} while (next_delay == 0);
- queue_delayed_work(local->hw.workqueue, &local->scan_work,
- next_delay);
+ ieee80211_queue_delayed_work(&local->hw, &local->scan_work, next_delay);
}
int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 75604cd..95d24fd 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1400,7 +1400,7 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
if (local->hw.conf.flags & IEEE80211_CONF_PS) {
ieee80211_stop_queues_by_reason(&local->hw,
IEEE80211_QUEUE_STOP_REASON_PS);
- queue_work(local->hw.workqueue,
+ ieee80211_queue_work(&local->hw,
&local->dynamic_ps_disable_work);
}
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 8502936..e55d57f 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -511,6 +511,46 @@ void ieee80211_iterate_active_interfaces_atomic(
}
EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic);
+/*
+ * Nothing should have been stuffed into the workqueue during
+ * the suspend->resume cycle. If this WARN is seen then there
+ * is a bug with either the driver suspend or something in
+ * mac80211 stuffing into the workqueue which we haven't yet
+ * cleared during mac80211's suspend cycle.
+ */
+static bool ieee80211_can_queue_work(struct ieee80211_local *local)
+{
+ if (WARN(local->suspended, "queueing ieee80211 work while "
+ "going to suspend\n"))
+ return false;
+
+ return true;
+}
+
+void ieee80211_queue_work(struct ieee80211_hw *hw, struct work_struct *work)
+{
+ struct ieee80211_local *local = hw_to_local(hw);
+
+ if (!ieee80211_can_queue_work(local))
+ return;
+
+ queue_work(local->workqueue, work);
+}
+EXPORT_SYMBOL(ieee80211_queue_work);
+
+void ieee80211_queue_delayed_work(struct ieee80211_hw *hw,
+ struct delayed_work *dwork,
+ unsigned long delay)
+{
+ struct ieee80211_local *local = hw_to_local(hw);
+
+ if (!ieee80211_can_queue_work(local))
+ return;
+
+ queue_delayed_work(local->workqueue, dwork, delay);
+}
+EXPORT_SYMBOL(ieee80211_queue_delayed_work);
+
void ieee802_11_parse_elems(u8 *start, size_t len,
struct ieee802_11_elems *elems)
{
@@ -1114,3 +1154,4 @@ int ieee80211_reconfig(struct ieee80211_local *local)
#endif
return 0;
}
+
--
1.6.0.4
^ permalink raw reply related
* RE: [PATCH] iwlwifi: Read outside array bounds
From: reinette chatre @ 2009-07-27 22:12 UTC (permalink / raw)
To: Winkler, Tomas
Cc: Zhu, Yi, Roel Kluin, linux-wireless@vger.kernel.org,
ipw3945-devel@lists.sourceforge.net, Andrew Morton
In-Reply-To: <6F5C1D715B2DA5498A628E6B9C124F040141D0B0DC@hasmsx504.ger.corp.intel.com>
On Mon, 2009-07-27 at 01:28 -0700, Winkler, Tomas wrote:
>
> > -----Original Message-----
> > From: Zhu, Yi
> > Sent: Monday, July 27, 2009 4:42 AM
> > To: Roel Kluin; Winkler, Tomas; Chatre, Reinette
> > Cc: linux-wireless@vger.kernel.org; ipw3945-devel@lists.sourceforge.net;
> > Andrew Morton
> > Subject: Re: [PATCH] iwlwifi: Read outside array bounds
> >
> > On Sun, 2009-07-26 at 05:34 +0800, Roel Kluin wrote:
> > > tid is bounded (above) by the size of default_tid_to_tx_fifo (17
> > elements), but
> > > the size of priv->stations[].tid[] is MAX_TID_COUNT (9) elements.
> >
> > I think MAX_TID_COUNT should be defined as 16 or 17. Tomas?
> >
>
> In general it's 16. In practice we use only 8.
I think the above statement means that we are mostly using EDCA quality
of service which only uses 8 tids. We do not currently use HCCA (and
thus of course not the hybrid) which would cause more tids to be used.
A closer look at this flow to this function shows:
rs_tl_turn_on_agg
->rs_tl_turn_on_agg_for_tid
-->ieee80211_start_tx_ba_session
--->iwl_mac_ampdu_action
---->iwl_tx_agg_start
>From what I can tell the tid is not modified from rs_tl_turn_on_agg to
iwl_tx_agg_start and rs_tl_turn_on_agg will not call further with a
value of tid larger than 7 due to its checking.
I thus do not see that tid may be equal or larger than MAX_TID_COUNT at
this point of checking. Even so, having this check will not do harm and
will increase safety.
This patch is already merged and that is ok, I just wanted to add this
information to it.
Reinette
^ permalink raw reply
* Re: [PATCH v2] mac80211: redefine usage of the mac80211 workqueue
From: Luis R. Rodriguez @ 2009-07-27 22:02 UTC (permalink / raw)
To: Gábor Stefanik; +Cc: Johannes Berg, linville, linux-wireless
In-Reply-To: <69e28c910907271322x6c6ea95cr1cd1d310bf0ebe9b@mail.gmail.com>
2009/7/27 Gábor Stefanik <netrolller.3d@gmail.com>:
> On Mon, Jul 27, 2009 at 9:41 PM, Luis R.
> Rodriguez<lrodriguez@atheros.com> wrote:
>> On Mon, Jul 27, 2009 at 12:08 PM, Johannes
>> Berg<johannes@sipsolutions.net> wrote:
>>> On Mon, 2009-07-27 at 11:59 -0700, Luis R. Rodriguez wrote:
>>>
>>>> +EXPORT_SYMBOL_GPL(ieee80211_queue_work);
>>>
>>> Do we really want to allow these as _GPL only? Most things are not _GPL
>>> but usable by anyone, which of course isn't too useful since mac80211
>>> changes all the time :)
>>
>> Well I don't see why not.
>>
>> Luis
>
> Do we want to prevent non-GPL
You mean non-GPL-compatible.
> drivers from using mac80211?
This wouldn't prevent it -- this is just for stuffing work into the
mac80211 workqueue. The way I was seeing this is we want to ensure
suspend works properly, if we allow non-GPL-compatible drivers stuff
work into the mac80211 workqueue suspend issues may pop up and the
issues may be driver related, not mac80211 related. But I guess its
better to see if crap vendor drivers are not following the APIs
properly, I'll remove this.
> That's
> actually counter-productive, as it reduces the chance of a
> manufacturer ever releasing a useful, kernel-includable driver. (Most
> manufacturers initially develop non-GPL drivers, which hopefully end
> up getting released under the GPL after community persuasion.
In my experience so far vendors tend to not write mac80211 drivers at
all unless they are open, all known vendor drivers I know of use wext
crap.
> If we
> make mac80211 GPL-only, that prevents any internal driver based on
> mac80211 from getting written.)
I'll remove this GPL_COMPATIBLE_ONLY thingy.
Luis
^ permalink raw reply
* [PATCH] mac80211: do not use irq locks where not necessary
From: Johannes Berg @ 2009-07-27 21:46 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
Except for places where we take locks that we need in
functions exported to drivers (which might call them
in interrupt context) we don't need to ever disable
IRQs in mac80211, just softirqs.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
Nobody objected (or probably tested, for that matter...), and it's been
working fine for me, albeit only with USB hardware. However, things
really related to calls that drivers can make from interrupts should be
ok -- just not sure I really got all the lock dependencies right. Let's
put it into wireless-testing to see :)
Point is that by not disabling IRQs we can improve latency for IRQs, of
course.
net/mac80211/key.c | 33 +++++++++---------------
net/mac80211/pm.c | 5 +--
net/mac80211/rc80211_pid_debugfs.c | 15 ++++-------
net/mac80211/sta_info.c | 49 ++++++++++++++-----------------------
net/mac80211/sta_info.h | 27 +++++++-------------
net/mac80211/tx.c | 11 +++-----
net/mac80211/util.c | 9 +++---
7 files changed, 57 insertions(+), 92 deletions(-)
--- wireless-testing.orig/net/mac80211/key.c 2009-07-25 10:45:14.000000000 +0200
+++ wireless-testing/net/mac80211/key.c 2009-07-27 11:43:40.000000000 +0200
@@ -211,11 +211,9 @@ static void __ieee80211_set_default_key(
void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx)
{
- unsigned long flags;
-
- spin_lock_irqsave(&sdata->local->key_lock, flags);
+ spin_lock_bh(&sdata->local->key_lock);
__ieee80211_set_default_key(sdata, idx);
- spin_unlock_irqrestore(&sdata->local->key_lock, flags);
+ spin_unlock_bh(&sdata->local->key_lock);
}
static void
@@ -236,11 +234,9 @@ __ieee80211_set_default_mgmt_key(struct
void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata,
int idx)
{
- unsigned long flags;
-
- spin_lock_irqsave(&sdata->local->key_lock, flags);
+ spin_lock_bh(&sdata->local->key_lock);
__ieee80211_set_default_mgmt_key(sdata, idx);
- spin_unlock_irqrestore(&sdata->local->key_lock, flags);
+ spin_unlock_bh(&sdata->local->key_lock);
}
@@ -386,7 +382,6 @@ void ieee80211_key_link(struct ieee80211
struct sta_info *sta)
{
struct ieee80211_key *old_key;
- unsigned long flags;
int idx;
BUG_ON(!sdata);
@@ -430,7 +425,7 @@ void ieee80211_key_link(struct ieee80211
}
}
- spin_lock_irqsave(&sdata->local->key_lock, flags);
+ spin_lock_bh(&sdata->local->key_lock);
if (sta)
old_key = sta->key;
@@ -446,7 +441,7 @@ void ieee80211_key_link(struct ieee80211
if (netif_running(sdata->dev))
add_todo(key, KEY_FLAG_TODO_HWACCEL_ADD);
- spin_unlock_irqrestore(&sdata->local->key_lock, flags);
+ spin_unlock_bh(&sdata->local->key_lock);
}
static void __ieee80211_key_free(struct ieee80211_key *key)
@@ -463,8 +458,6 @@ static void __ieee80211_key_free(struct
void ieee80211_key_free(struct ieee80211_key *key)
{
- unsigned long flags;
-
if (!key)
return;
@@ -477,9 +470,9 @@ void ieee80211_key_free(struct ieee80211
return;
}
- spin_lock_irqsave(&key->sdata->local->key_lock, flags);
+ spin_lock_bh(&key->sdata->local->key_lock);
__ieee80211_key_free(key);
- spin_unlock_irqrestore(&key->sdata->local->key_lock, flags);
+ spin_unlock_bh(&key->sdata->local->key_lock);
}
/*
@@ -493,14 +486,13 @@ static void ieee80211_todo_for_each_key(
u32 todo_flags)
{
struct ieee80211_key *key;
- unsigned long flags;
might_sleep();
- spin_lock_irqsave(&sdata->local->key_lock, flags);
+ spin_lock_bh(&sdata->local->key_lock);
list_for_each_entry(key, &sdata->key_list, list)
add_todo(key, todo_flags);
- spin_unlock_irqrestore(&sdata->local->key_lock, flags);
+ spin_unlock_bh(&sdata->local->key_lock);
ieee80211_key_todo();
}
@@ -608,17 +600,16 @@ void ieee80211_key_todo(void)
void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_key *key, *tmp;
- unsigned long flags;
ieee80211_key_lock();
ieee80211_debugfs_key_remove_default(sdata);
ieee80211_debugfs_key_remove_mgmt_default(sdata);
- spin_lock_irqsave(&sdata->local->key_lock, flags);
+ spin_lock_bh(&sdata->local->key_lock);
list_for_each_entry_safe(key, tmp, &sdata->key_list, list)
__ieee80211_key_free(key);
- spin_unlock_irqrestore(&sdata->local->key_lock, flags);
+ spin_unlock_bh(&sdata->local->key_lock);
__ieee80211_key_todo();
--- wireless-testing.orig/net/mac80211/pm.c 2009-07-25 10:45:14.000000000 +0200
+++ wireless-testing/net/mac80211/pm.c 2009-07-27 11:43:40.000000000 +0200
@@ -12,7 +12,6 @@ int __ieee80211_suspend(struct ieee80211
struct ieee80211_sub_if_data *sdata;
struct ieee80211_if_init_conf conf;
struct sta_info *sta;
- unsigned long flags;
ieee80211_scan_cancel(local);
@@ -65,7 +64,7 @@ int __ieee80211_suspend(struct ieee80211
}
/* remove STAs */
- spin_lock_irqsave(&local->sta_lock, flags);
+ spin_lock_bh(&local->sta_lock);
list_for_each_entry(sta, &local->sta_list, list) {
if (local->ops->sta_notify) {
sdata = sta->sdata;
@@ -80,7 +79,7 @@ int __ieee80211_suspend(struct ieee80211
mesh_plink_quiesce(sta);
}
- spin_unlock_irqrestore(&local->sta_lock, flags);
+ spin_unlock_bh(&local->sta_lock);
/* remove all interfaces */
list_for_each_entry(sdata, &local->interfaces, list) {
--- wireless-testing.orig/net/mac80211/rc80211_pid_debugfs.c 2009-07-25 10:45:14.000000000 +0200
+++ wireless-testing/net/mac80211/rc80211_pid_debugfs.c 2009-07-27 11:43:40.000000000 +0200
@@ -22,9 +22,8 @@ static void rate_control_pid_event(struc
union rc_pid_event_data *data)
{
struct rc_pid_event *ev;
- unsigned long status;
- spin_lock_irqsave(&buf->lock, status);
+ spin_lock_bh(&buf->lock);
ev = &(buf->ring[buf->next_entry]);
buf->next_entry = (buf->next_entry + 1) % RC_PID_EVENT_RING_SIZE;
@@ -33,7 +32,7 @@ static void rate_control_pid_event(struc
ev->type = type;
ev->data = *data;
- spin_unlock_irqrestore(&buf->lock, status);
+ spin_unlock_bh(&buf->lock);
wake_up_all(&buf->waitqueue);
}
@@ -86,19 +85,18 @@ static int rate_control_pid_events_open(
struct rc_pid_sta_info *sinfo = inode->i_private;
struct rc_pid_event_buffer *events = &sinfo->events;
struct rc_pid_events_file_info *file_info;
- unsigned long status;
/* Allocate a state struct */
file_info = kmalloc(sizeof(*file_info), GFP_KERNEL);
if (file_info == NULL)
return -ENOMEM;
- spin_lock_irqsave(&events->lock, status);
+ spin_lock_bh(&events->lock);
file_info->next_entry = events->next_entry;
file_info->events = events;
- spin_unlock_irqrestore(&events->lock, status);
+ spin_unlock_bh(&events->lock);
file->private_data = file_info;
@@ -136,7 +134,6 @@ static ssize_t rate_control_pid_events_r
char pb[RC_PID_PRINT_BUF_SIZE];
int ret;
int p;
- unsigned long status;
/* Check if there is something to read. */
if (events->next_entry == file_info->next_entry) {
@@ -153,7 +150,7 @@ static ssize_t rate_control_pid_events_r
/* Write out one event per call. I don't care whether it's a little
* inefficient, this is debugging code anyway. */
- spin_lock_irqsave(&events->lock, status);
+ spin_lock_bh(&events->lock);
/* Get an event */
ev = &(events->ring[file_info->next_entry]);
@@ -188,7 +185,7 @@ static ssize_t rate_control_pid_events_r
}
p += snprintf(pb + p, length - p, "\n");
- spin_unlock_irqrestore(&events->lock, status);
+ spin_unlock_bh(&events->lock);
if (copy_to_user(buf, pb, p))
return -EFAULT;
--- wireless-testing.orig/net/mac80211/sta_info.c 2009-07-25 10:45:14.000000000 +0200
+++ wireless-testing/net/mac80211/sta_info.c 2009-07-27 11:43:40.000000000 +0200
@@ -322,7 +322,6 @@ int sta_info_insert(struct sta_info *sta
{
struct ieee80211_local *local = sta->local;
struct ieee80211_sub_if_data *sdata = sta->sdata;
- unsigned long flags;
int err = 0;
/*
@@ -341,10 +340,10 @@ int sta_info_insert(struct sta_info *sta
goto out_free;
}
- spin_lock_irqsave(&local->sta_lock, flags);
+ spin_lock_bh(&local->sta_lock);
/* check if STA exists already */
if (sta_info_get(local, sta->sta.addr)) {
- spin_unlock_irqrestore(&local->sta_lock, flags);
+ spin_unlock_bh(&local->sta_lock);
err = -EEXIST;
goto out_free;
}
@@ -367,7 +366,7 @@ int sta_info_insert(struct sta_info *sta
wiphy_name(local->hw.wiphy), sta->sta.addr);
#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
- spin_unlock_irqrestore(&local->sta_lock, flags);
+ spin_unlock_bh(&local->sta_lock);
#ifdef CONFIG_MAC80211_DEBUGFS
/*
@@ -424,13 +423,11 @@ static void __sta_info_set_tim_bit(struc
void sta_info_set_tim_bit(struct sta_info *sta)
{
- unsigned long flags;
-
BUG_ON(!sta->sdata->bss);
- spin_lock_irqsave(&sta->local->sta_lock, flags);
+ spin_lock_bh(&sta->local->sta_lock);
__sta_info_set_tim_bit(sta->sdata->bss, sta);
- spin_unlock_irqrestore(&sta->local->sta_lock, flags);
+ spin_unlock_bh(&sta->local->sta_lock);
}
static void __sta_info_clear_tim_bit(struct ieee80211_if_ap *bss,
@@ -449,13 +446,11 @@ static void __sta_info_clear_tim_bit(str
void sta_info_clear_tim_bit(struct sta_info *sta)
{
- unsigned long flags;
-
BUG_ON(!sta->sdata->bss);
- spin_lock_irqsave(&sta->local->sta_lock, flags);
+ spin_lock_bh(&sta->local->sta_lock);
__sta_info_clear_tim_bit(sta->sdata->bss, sta);
- spin_unlock_irqrestore(&sta->local->sta_lock, flags);
+ spin_unlock_bh(&sta->local->sta_lock);
}
static void __sta_info_unlink(struct sta_info **sta)
@@ -546,11 +541,10 @@ static void __sta_info_unlink(struct sta
void sta_info_unlink(struct sta_info **sta)
{
struct ieee80211_local *local = (*sta)->local;
- unsigned long flags;
- spin_lock_irqsave(&local->sta_lock, flags);
+ spin_lock_bh(&local->sta_lock);
__sta_info_unlink(sta);
- spin_unlock_irqrestore(&local->sta_lock, flags);
+ spin_unlock_bh(&local->sta_lock);
}
static int sta_info_buffer_expired(struct sta_info *sta,
@@ -577,7 +571,6 @@ static int sta_info_buffer_expired(struc
static void sta_info_cleanup_expire_buffered(struct ieee80211_local *local,
struct sta_info *sta)
{
- unsigned long flags;
struct sk_buff *skb;
struct ieee80211_sub_if_data *sdata;
@@ -585,13 +578,13 @@ static void sta_info_cleanup_expire_buff
return;
for (;;) {
- spin_lock_irqsave(&sta->ps_tx_buf.lock, flags);
+ spin_lock_bh(&sta->ps_tx_buf.lock);
skb = skb_peek(&sta->ps_tx_buf);
if (sta_info_buffer_expired(sta, skb))
skb = __skb_dequeue(&sta->ps_tx_buf);
else
skb = NULL;
- spin_unlock_irqrestore(&sta->ps_tx_buf.lock, flags);
+ spin_unlock_bh(&sta->ps_tx_buf.lock);
if (!skb)
break;
@@ -646,15 +639,14 @@ static void __sta_info_pin(struct sta_in
static struct sta_info *__sta_info_unpin(struct sta_info *sta)
{
struct sta_info *ret = NULL;
- unsigned long flags;
- spin_lock_irqsave(&sta->local->sta_lock, flags);
+ spin_lock_bh(&sta->local->sta_lock);
WARN_ON(sta->pin_status != STA_INFO_PIN_STAT_DESTROY &&
sta->pin_status != STA_INFO_PIN_STAT_PINNED);
if (sta->pin_status == STA_INFO_PIN_STAT_DESTROY)
ret = sta;
sta->pin_status = STA_INFO_PIN_STAT_NORMAL;
- spin_unlock_irqrestore(&sta->local->sta_lock, flags);
+ spin_unlock_bh(&sta->local->sta_lock);
return ret;
}
@@ -664,14 +656,13 @@ static void sta_info_debugfs_add_work(st
struct ieee80211_local *local =
container_of(work, struct ieee80211_local, sta_debugfs_add);
struct sta_info *sta, *tmp;
- unsigned long flags;
/* We need to keep the RTNL across the whole pinned status. */
rtnl_lock();
while (1) {
sta = NULL;
- spin_lock_irqsave(&local->sta_lock, flags);
+ spin_lock_bh(&local->sta_lock);
list_for_each_entry(tmp, &local->sta_list, list) {
/*
* debugfs.add_has_run will be set by
@@ -684,7 +675,7 @@ static void sta_info_debugfs_add_work(st
break;
}
}
- spin_unlock_irqrestore(&local->sta_lock, flags);
+ spin_unlock_bh(&local->sta_lock);
if (!sta)
break;
@@ -750,11 +741,10 @@ int sta_info_flush(struct ieee80211_loca
struct sta_info *sta, *tmp;
LIST_HEAD(tmp_list);
int ret = 0;
- unsigned long flags;
might_sleep();
- spin_lock_irqsave(&local->sta_lock, flags);
+ spin_lock_bh(&local->sta_lock);
list_for_each_entry_safe(sta, tmp, &local->sta_list, list) {
if (!sdata || sdata == sta->sdata) {
__sta_info_unlink(&sta);
@@ -764,7 +754,7 @@ int sta_info_flush(struct ieee80211_loca
}
}
}
- spin_unlock_irqrestore(&local->sta_lock, flags);
+ spin_unlock_bh(&local->sta_lock);
list_for_each_entry_safe(sta, tmp, &tmp_list, list)
sta_info_destroy(sta);
@@ -778,9 +768,8 @@ void ieee80211_sta_expire(struct ieee802
struct ieee80211_local *local = sdata->local;
struct sta_info *sta, *tmp;
LIST_HEAD(tmp_list);
- unsigned long flags;
- spin_lock_irqsave(&local->sta_lock, flags);
+ spin_lock_bh(&local->sta_lock);
list_for_each_entry_safe(sta, tmp, &local->sta_list, list)
if (time_after(jiffies, sta->last_rx + exp_time)) {
#ifdef CONFIG_MAC80211_IBSS_DEBUG
@@ -791,7 +780,7 @@ void ieee80211_sta_expire(struct ieee802
if (sta)
list_add(&sta->list, &tmp_list);
}
- spin_unlock_irqrestore(&local->sta_lock, flags);
+ spin_unlock_bh(&local->sta_lock);
list_for_each_entry_safe(sta, tmp, &tmp_list, list)
sta_info_destroy(sta);
--- wireless-testing.orig/net/mac80211/sta_info.h 2009-07-25 10:45:14.000000000 +0200
+++ wireless-testing/net/mac80211/sta_info.h 2009-07-27 11:43:40.000000000 +0200
@@ -341,30 +341,25 @@ static inline enum plink_state sta_plink
static inline void set_sta_flags(struct sta_info *sta, const u32 flags)
{
- unsigned long irqfl;
-
- spin_lock_irqsave(&sta->flaglock, irqfl);
+ spin_lock_bh(&sta->flaglock);
sta->flags |= flags;
- spin_unlock_irqrestore(&sta->flaglock, irqfl);
+ spin_unlock_bh(&sta->flaglock);
}
static inline void clear_sta_flags(struct sta_info *sta, const u32 flags)
{
- unsigned long irqfl;
-
- spin_lock_irqsave(&sta->flaglock, irqfl);
+ spin_lock_bh(&sta->flaglock);
sta->flags &= ~flags;
- spin_unlock_irqrestore(&sta->flaglock, irqfl);
+ spin_unlock_bh(&sta->flaglock);
}
static inline u32 test_sta_flags(struct sta_info *sta, const u32 flags)
{
u32 ret;
- unsigned long irqfl;
- spin_lock_irqsave(&sta->flaglock, irqfl);
+ spin_lock_bh(&sta->flaglock);
ret = sta->flags & flags;
- spin_unlock_irqrestore(&sta->flaglock, irqfl);
+ spin_unlock_bh(&sta->flaglock);
return ret;
}
@@ -373,12 +368,11 @@ static inline u32 test_and_clear_sta_fla
const u32 flags)
{
u32 ret;
- unsigned long irqfl;
- spin_lock_irqsave(&sta->flaglock, irqfl);
+ spin_lock_bh(&sta->flaglock);
ret = sta->flags & flags;
sta->flags &= ~flags;
- spin_unlock_irqrestore(&sta->flaglock, irqfl);
+ spin_unlock_bh(&sta->flaglock);
return ret;
}
@@ -386,11 +380,10 @@ static inline u32 test_and_clear_sta_fla
static inline u32 get_sta_flags(struct sta_info *sta)
{
u32 ret;
- unsigned long irqfl;
- spin_lock_irqsave(&sta->flaglock, irqfl);
+ spin_lock_bh(&sta->flaglock);
ret = sta->flags;
- spin_unlock_irqrestore(&sta->flaglock, irqfl);
+ spin_unlock_bh(&sta->flaglock);
return ret;
}
--- wireless-testing.orig/net/mac80211/tx.c 2009-07-27 11:42:03.000000000 +0200
+++ wireless-testing/net/mac80211/tx.c 2009-07-27 11:43:40.000000000 +0200
@@ -1049,13 +1049,12 @@ ieee80211_tx_prepare(struct ieee80211_su
if (tx->sta && ieee80211_is_data_qos(hdr->frame_control) &&
(local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION)) {
- unsigned long flags;
struct tid_ampdu_tx *tid_tx;
qc = ieee80211_get_qos_ctl(hdr);
tid = *qc & IEEE80211_QOS_CTL_TID_MASK;
- spin_lock_irqsave(&tx->sta->lock, flags);
+ spin_lock_bh(&tx->sta->lock);
/*
* XXX: This spinlock could be fairly expensive, but see the
* comment in agg-tx.c:ieee80211_agg_tx_operational().
@@ -1080,7 +1079,7 @@ ieee80211_tx_prepare(struct ieee80211_su
info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
__skb_queue_tail(&tid_tx->pending, skb);
}
- spin_unlock_irqrestore(&tx->sta->lock, flags);
+ spin_unlock_bh(&tx->sta->lock);
if (unlikely(queued))
return TX_QUEUED;
@@ -2024,11 +2023,9 @@ struct sk_buff *ieee80211_beacon_get(str
if (local->tim_in_locked_section) {
ieee80211_beacon_add_tim(ap, skb, beacon);
} else {
- unsigned long flags;
-
- spin_lock_irqsave(&local->sta_lock, flags);
+ spin_lock_bh(&local->sta_lock);
ieee80211_beacon_add_tim(ap, skb, beacon);
- spin_unlock_irqrestore(&local->sta_lock, flags);
+ spin_unlock_bh(&local->sta_lock);
}
if (beacon->tail)
--- wireless-testing.orig/net/mac80211/util.c 2009-07-27 11:42:03.000000000 +0200
+++ wireless-testing/net/mac80211/util.c 2009-07-27 11:43:40.000000000 +0200
@@ -973,7 +973,6 @@ int ieee80211_reconfig(struct ieee80211_
struct ieee80211_sub_if_data *sdata;
struct ieee80211_if_init_conf conf;
struct sta_info *sta;
- unsigned long flags;
int res;
bool from_suspend = local->suspended;
@@ -1004,7 +1003,7 @@ int ieee80211_reconfig(struct ieee80211_
/* add STAs back */
if (local->ops->sta_notify) {
- spin_lock_irqsave(&local->sta_lock, flags);
+ spin_lock_bh(&local->sta_lock);
list_for_each_entry(sta, &local->sta_list, list) {
sdata = sta->sdata;
if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
@@ -1015,7 +1014,7 @@ int ieee80211_reconfig(struct ieee80211_
drv_sta_notify(local, &sdata->vif, STA_NOTIFY_ADD,
&sta->sta);
}
- spin_unlock_irqrestore(&local->sta_lock, flags);
+ spin_unlock_bh(&local->sta_lock);
}
/* Clear Suspend state so that ADDBA requests can be processed */
@@ -1105,10 +1104,10 @@ int ieee80211_reconfig(struct ieee80211_
add_timer(&local->sta_cleanup);
- spin_lock_irqsave(&local->sta_lock, flags);
+ spin_lock_bh(&local->sta_lock);
list_for_each_entry(sta, &local->sta_list, list)
mesh_plink_restart(sta);
- spin_unlock_irqrestore(&local->sta_lock, flags);
+ spin_unlock_bh(&local->sta_lock);
#else
WARN_ON(1);
#endif
^ permalink raw reply
* [PATCH v3 12/14] iwlwifi: debugFs to enable/disable HT40 support
From: reinette chatre @ 2009-07-27 20:50 UTC (permalink / raw)
To: John W. Linville
Cc: Guy, Wey-Yi W, linux-wireless@vger.kernel.org,
ipw3945-devel@lists.sourceforge.net, Gábor Stefanik
In-Reply-To: <20090727184339.GA8823@tuxdriver.com>
From: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Add debugfs file to enable/disable HT40(40MHz) channel support.
By default, 40MHz is supported if AP can support the function.
By echo "1" to "disable_ht40" file, iwlwifi driver will disable the
40MHz support and only allow 20MHz channel.
Because the information exchange happen during association time,
so enable/disable ht40 channel only can be performed when it is not
associated with AP.
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
v2: name change "fat_mode" -> "ht40"
v3: formatting fixes
John,
This patch applies cleanly after reverting the original. Sorry for the problems.
Reinette
drivers/net/wireless/iwlwifi/iwl-core.c | 4 ++
drivers/net/wireless/iwlwifi/iwl-debug.h | 1 +
drivers/net/wireless/iwlwifi/iwl-debugfs.c | 46 ++++++++++++++++++++++++++++
drivers/net/wireless/iwlwifi/iwl-dev.h | 1 +
4 files changed, 52 insertions(+), 0 deletions(-)
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 85d6fef..b6528f5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -646,6 +646,10 @@ u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv,
if (!sta_ht_inf->ht_supported)
return 0;
}
+#ifdef CONFIG_IWLWIFI_DEBUG
+ if (priv->disable_ht40)
+ return 0;
+#endif
return iwl_is_channel_extension(priv, priv->band,
le16_to_cpu(priv->staging_rxon.channel),
iwl_ht_conf->extension_chan_offset);
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
index 609a681..fbe1776 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.h
@@ -88,6 +88,7 @@ struct iwl_debugfs {
#ifdef CONFIG_IWLWIFI_LEDS
struct dentry *file_led;
#endif
+ struct dentry *file_disable_ht40;
} dbgfs_data_files;
struct dir_rf_files {
struct dentry *file_disable_sensitivity;
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 748dc31..7707a26 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -653,6 +653,49 @@ static ssize_t iwl_dbgfs_thermal_throttling_read(struct file *file,
return ret;
}
+static ssize_t iwl_dbgfs_disable_ht40_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct iwl_priv *priv = file->private_data;
+ char buf[8];
+ int buf_size;
+ int ht40;
+
+ memset(buf, 0, sizeof(buf));
+ buf_size = min(count, sizeof(buf) - 1);
+ if (copy_from_user(buf, user_buf, buf_size))
+ return -EFAULT;
+ if (sscanf(buf, "%d", &ht40) != 1)
+ return -EFAULT;
+ if (!iwl_is_associated(priv))
+ priv->disable_ht40 = ht40 ? true : false;
+ else {
+ IWL_ERR(priv, "Sta associated with AP - "
+ "Change to 40MHz channel support is not allowed\n");
+ return -EINVAL;
+ }
+
+ return count;
+}
+
+static ssize_t iwl_dbgfs_disable_ht40_read(struct file *file,
+ char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+ char buf[100];
+ int pos = 0;
+ const size_t bufsz = sizeof(buf);
+ ssize_t ret;
+
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "11n 40MHz Mode: %s\n",
+ priv->disable_ht40 ? "Disabled" : "Enabled");
+ ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+ return ret;
+}
+
DEBUGFS_READ_WRITE_FILE_OPS(sram);
DEBUGFS_WRITE_FILE_OPS(log_event);
DEBUGFS_READ_FILE_OPS(nvm);
@@ -667,6 +710,7 @@ DEBUGFS_READ_FILE_OPS(qos);
DEBUGFS_READ_FILE_OPS(led);
#endif
DEBUGFS_READ_FILE_OPS(thermal_throttling);
+DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40);
/*
* Create the debugfs files and directories
@@ -708,6 +752,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
DEBUGFS_ADD_FILE(led, data);
#endif
DEBUGFS_ADD_FILE(thermal_throttling, data);
+ DEBUGFS_ADD_FILE(disable_ht40, data);
DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal);
DEBUGFS_ADD_BOOL(disable_chain_noise, rf,
&priv->disable_chain_noise_cal);
@@ -747,6 +792,7 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv)
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_led);
#endif
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_thermal_throttling);
+ DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_disable_ht40);
DEBUGFS_REMOVE(priv->dbgfs->dir_data);
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity);
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_chain_noise);
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index facbc3d..0ee3ad2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1164,6 +1164,7 @@ struct iwl_priv {
/* debugging info */
u32 framecnt_to_us;
atomic_t restrict_refcnt;
+ bool disable_ht40;
#ifdef CONFIG_IWLWIFI_DEBUGFS
/* debugfs */
struct iwl_debugfs *dbgfs;
--
1.5.6.3
^ permalink raw reply related
* [RESEND] [PATCHv2] b43 add harware tkip
From: gregor kowski @ 2009-07-27 20:49 UTC (permalink / raw)
To: bcm43xx-dev; +Cc: Michael Buesch, linux-wireless
Update : work with qos, implement dump key, fix an issue with setting
random value on tkip key clear.
PS : this depends on "b43 : remove old kidx API"
This add hardware tkip for b43.
It uncovered a bug in b43_write_probe_resp_template : it is writing at the
wrong shm offset, it is in the B43_SHM_SH_TKIPTSCTTAK zone. This patch
comments these writes.
Signed-off-by: Gregor Kowski <gregor.kowski@gmail.com>
Index: linux-2.6/drivers/net/wireless/b43/dma.c
===================================================================
--- linux-2.6.orig/drivers/net/wireless/b43/dma.c 2009-07-25
10:58:30.000000000 +0000
+++ linux-2.6/drivers/net/wireless/b43/dma.c 2009-07-27 20:46:05.000000000 +0000
@@ -1188,7 +1188,7 @@
header = &(ring->txhdr_cache[(slot / TX_SLOTS_PER_FRAME) * hdrsize]);
cookie = generate_cookie(ring, slot);
err = b43_generate_txhdr(ring->dev, header,
- skb->data, skb->len, info, cookie);
+ skb, info, cookie);
if (unlikely(err)) {
ring->current_slot = old_top_slot;
ring->used_slots = old_used_slots;
Index: linux-2.6/drivers/net/wireless/b43/main.c
===================================================================
--- linux-2.6.orig/drivers/net/wireless/b43/main.c 2009-07-27
20:40:14.000000000 +0000
+++ linux-2.6/drivers/net/wireless/b43/main.c 2009-07-27
20:46:05.000000000 +0000
@@ -836,6 +836,64 @@
}
}
+/* The ucode will use this with key to decrypt rx packets.
+ * It will first check if the iv32 match,
+ * - if they don't it returns the packet without decryption (and software
+ * decryption can be done). That's what happen when iv16 wrap.
+ * - if they do, the rc4 key is computed with tkip phase2, and
+ * the wep decryption is tried on the packet. Either it will
+ * success and B43_RX_MAC_DEC is returned, either it fails
+ * and B43_RX_MAC_DEC|B43_RX_MAC_DECERR is returned and the packet
+ * is not usable (wrong key used on it).
+ * So in order to never have B43_RX_MAC_DECERR, we should provide
+ * a iv32 and phase1key that match. Because we drop packets in case of
+ * B43_RX_MAC_DECERR, if we have a correct iv32 but a wrong phase1key, all
+ * packets will be lost without higher layer knowing (ie no resync possible
+ * until next wrap).
+ *
+ * NOTE : this should support 50 key like RCMTA because
+ * (B43_SHM_SH_KEYIDXBLOCK - B43_SHM_SH_TKIPTSCTTAK)/14 = 50
+ */
+static void rx_tkip_phase1_write(struct b43_wldev *dev, u8 index, u32 iv32,
+ u16 *phase1key)
+{
+ unsigned int i;
+ u32 offset;
+ const u8 per_sta_keys_start = 4;
+
+ B43_WARN_ON(index < per_sta_keys_start);
+ /* We have two default TX keys and possibly two default RX keys.
+ * Physical mac 0 is mapped to physical key 4 or 8, depending
+ * on the firmware version.
+ * So we must adjust the index here.
+ */
+ index -= per_sta_keys_start;
+
+ if (b43_debug(dev, B43_DBG_KEYS))
+ b43dbg(dev->wl, "rx_tkip_phase1_write : idx 0x%x, iv32 0x%x\n",
+ index, iv32);
+ /* Write the key to the RX tkip shared mem */
+ offset = B43_SHM_SH_TKIPTSCTTAK + index * (10 + 4);
+ for (i = 0; i < 10; i += 2) {
+ b43_shm_write16(dev, B43_SHM_SHARED, offset + i, phase1key[i/2]);
+ }
+ b43_shm_write16(dev, B43_SHM_SHARED, offset + i, iv32);
+ b43_shm_write16(dev, B43_SHM_SHARED, offset + i + 2, iv32>>16);
+}
+
+static void b43_mac_update_tkip_key(struct ieee80211_hw *hw,
+ struct ieee80211_key_conf *keyconf, const u8 *addr,
+ u32 iv32, u16 *phase1key)
+{
+ struct b43_wl *wl = hw_to_b43_wl(hw);
+ struct b43_wldev *dev = wl->current_dev;
+ int index = keyconf->hw_key_idx;
+ keymac_write(dev, index, NULL); /* First zero out mac to avoid race */
+
+ rx_tkip_phase1_write(dev, index, iv32, phase1key);
+ keymac_write(dev, index, addr);
+}
+
static void do_key_write(struct b43_wldev *dev,
u8 index, u8 algorithm,
const u8 *key, size_t key_len, const u8 *mac_addr)
@@ -848,6 +906,19 @@
if (index >= per_sta_keys_start)
keymac_write(dev, index, NULL); /* First zero out mac. */
+ if (algorithm == B43_SEC_ALGO_TKIP) {
+ /*
+ * We should provide an initial iv32, phase1key pair.
+ * We could start with iv32=0 and compute the corresponding
+ * phase1key, but this mean calling ieee80211_get_tkip_key
+ * with a fake skb (or export other tkip function).
+ * Because we are lazy we hope iv32 won't start with
+ * 0xffffffff and let's b43_mac_update_tkip_key provide a
+ * correct pair.
+ */
+ rx_tkip_phase1_write(dev, index, 0xffffffff, (u16*)buf);
+ } else if (index >= per_sta_keys_start) /* clear it */
+ rx_tkip_phase1_write(dev, index, 0, (u16*)buf);
if (key)
memcpy(buf, key, key_len);
key_write(dev, index, algorithm, buf);
@@ -865,6 +936,8 @@
{
int i;
+ if (algorithm == B43_SEC_ALGO_TKIP && key_len == 32)
+ key_len = 16;
if (key_len > B43_SEC_KEYSIZE)
return -EINVAL;
for (i = 0; i < dev->max_nr_keys; i++) {
@@ -946,6 +1019,14 @@
printk(" Algo: %04X/%02X", algo, key->algorithm);
if (index >= 4) {
+ if (key->algorithm == B43_SEC_ALGO_TKIP) {
+ printk(" TKIP: ");
+ offset = B43_SHM_SH_TKIPTSCTTAK + (index - 4) * (10 + 4);
+ for (i = 0; i < 14; i+=2) {
+ u16 tmp = b43_shm_read16(dev, B43_SHM_SHARED, offset + i);
+ printk("%02X%02X", (tmp & 0xFF), ((tmp >> 8) & 0xFF));
+ }
+ }
rcmta0 = b43_shm_read32(dev, B43_SHM_RCMTA,
((index - 4) * 2) + 0);
rcmta1 = b43_shm_read16(dev, B43_SHM_RCMTA,
@@ -1505,10 +1586,13 @@
/* Looks like PLCP headers plus packet timings are stored for
* all possible basic rates
*/
+ /* FIXME this is the wrong offset : it goes in tkip rx phase1 shm */
+#if 0
b43_write_probe_resp_plcp(dev, 0x31A, size, &b43_b_ratetable[0]);
b43_write_probe_resp_plcp(dev, 0x32C, size, &b43_b_ratetable[1]);
b43_write_probe_resp_plcp(dev, 0x33E, size, &b43_b_ratetable[2]);
b43_write_probe_resp_plcp(dev, 0x350, size, &b43_b_ratetable[3]);
+#endif
size = min((size_t) size, 0x200 - sizeof(struct b43_plcp_hdr6));
b43_write_template_common(dev, probe_resp_data,
@@ -3667,8 +3751,9 @@
switch (cmd) {
case SET_KEY:
- if (algorithm == B43_SEC_ALGO_TKIP) {
- /* FIXME: No TKIP hardware encryption for now. */
+ if (algorithm == B43_SEC_ALGO_TKIP &&
+ !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
+ /* We support only pairwise key */
err = -EOPNOTSUPP;
goto out_unlock;
}
@@ -3698,6 +3783,8 @@
b43_hf_read(dev) & ~B43_HF_USEDEFKEYS);
}
key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+ if (algorithm == B43_SEC_ALGO_TKIP)
+ key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
break;
case DISABLE_KEY: {
err = b43_key_clear(dev, key->hw_key_idx);
@@ -4425,6 +4512,7 @@
.bss_info_changed = b43_op_bss_info_changed,
.configure_filter = b43_op_configure_filter,
.set_key = b43_op_set_key,
+ .update_tkip_key = b43_mac_update_tkip_key,
.get_stats = b43_op_get_stats,
.get_tx_stats = b43_op_get_tx_stats,
.get_tsf = b43_op_get_tsf,
Index: linux-2.6/drivers/net/wireless/b43/pio.c
===================================================================
--- linux-2.6.orig/drivers/net/wireless/b43/pio.c 2009-07-25
10:58:30.000000000 +0000
+++ linux-2.6/drivers/net/wireless/b43/pio.c 2009-07-27 20:46:05.000000000 +0000
@@ -461,8 +461,8 @@
cookie = generate_cookie(q, pack);
hdrlen = b43_txhdr_size(q->dev);
- err = b43_generate_txhdr(q->dev, (u8 *)&txhdr, skb->data,
- skb->len, info, cookie);
+ err = b43_generate_txhdr(q->dev, (u8 *)&txhdr, skb,
+ info, cookie);
if (err)
return err;
Index: linux-2.6/drivers/net/wireless/b43/xmit.c
===================================================================
--- linux-2.6.orig/drivers/net/wireless/b43/xmit.c 2009-07-27
20:40:14.000000000 +0000
+++ linux-2.6/drivers/net/wireless/b43/xmit.c 2009-07-27
20:46:05.000000000 +0000
@@ -180,11 +180,12 @@
/* Generate a TX data header. */
int b43_generate_txhdr(struct b43_wldev *dev,
u8 *_txhdr,
- const unsigned char *fragment_data,
- unsigned int fragment_len,
+ struct sk_buff *skb_frag,
struct ieee80211_tx_info *info,
u16 cookie)
{
+ const unsigned char *fragment_data = skb_frag->data;
+ unsigned int fragment_len = skb_frag->len;
struct b43_txhdr *txhdr = (struct b43_txhdr *)_txhdr;
const struct b43_phy *phy = &dev->phy;
const struct ieee80211_hdr *wlhdr =
@@ -257,9 +258,25 @@
mac_ctl |= (key->algorithm << B43_TXH_MAC_KEYALG_SHIFT) &
B43_TXH_MAC_KEYALG;
wlhdr_len = ieee80211_hdrlen(fctl);
- iv_len = min((size_t) info->control.hw_key->iv_len,
- ARRAY_SIZE(txhdr->iv));
- memcpy(txhdr->iv, ((u8 *) wlhdr) + wlhdr_len, iv_len);
+ if (key->algorithm == B43_SEC_ALGO_TKIP) {
+ u16 phase1key[5];
+ int i;
+ /* we give the phase1key and iv16 here, the key is stored in
+ * shm. With that the hardware can do phase 2 and encryption.
+ */
+ ieee80211_get_tkip_key(info->control.hw_key, skb_frag,
IEEE80211_TKIP_P1_KEY, (u8*)phase1key);
+ /* phase1key is in host endian */
+ for (i = 0; i < 5; i++)
+ phase1key[i] = cpu_to_le16(phase1key[i]);
+
+ memcpy(txhdr->iv, phase1key, 10);
+ /* iv16 */
+ memcpy(txhdr->iv+10, ((u8 *) wlhdr) + wlhdr_len, 3);
+ } else {
+ iv_len = min((size_t) info->control.hw_key->iv_len,
+ ARRAY_SIZE(txhdr->iv));
+ memcpy(txhdr->iv, ((u8 *) wlhdr) + wlhdr_len, iv_len);
+ }
}
if (b43_is_old_txhdr_format(dev)) {
b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)(&txhdr->old_format.plcp),
Index: linux-2.6/drivers/net/wireless/b43/xmit.h
===================================================================
--- linux-2.6.orig/drivers/net/wireless/b43/xmit.h 2009-07-27
20:40:14.000000000 +0000
+++ linux-2.6/drivers/net/wireless/b43/xmit.h 2009-07-27
20:46:05.000000000 +0000
@@ -176,8 +176,7 @@
int b43_generate_txhdr(struct b43_wldev *dev,
u8 * txhdr,
- const unsigned char *fragment_data,
- unsigned int fragment_len,
+ struct sk_buff *skb_frag,
struct ieee80211_tx_info *txctl, u16 cookie);
/* Transmit Status */
^ permalink raw reply
* [RESEND] [PATCH] b43 : remove old kidx API
From: gregor kowski @ 2009-07-27 20:43 UTC (permalink / raw)
To: bcm43xx-dev; +Cc: Michael Buesch, linux-wireless
Remove old kidx API.
This simplify the code, and fix a potential key overflow.
Signed-off-by: Gregor Kowski <gregor.kowski@gmail.com>
Index: linux-2.6/drivers/net/wireless/b43/main.c
===================================================================
--- linux-2.6.orig/drivers/net/wireless/b43/main.c 2009-07-25
10:58:31.000000000 +0000
+++ linux-2.6/drivers/net/wireless/b43/main.c 2009-07-27
20:40:14.000000000 +0000
@@ -776,13 +776,11 @@
unsigned int i;
u32 offset;
u16 value;
- u16 kidx;
/* Key index/algo block */
- kidx = b43_kidx_to_fw(dev, index);
- value = ((kidx << 4) | algorithm);
+ value = ((index << 4) | algorithm);
b43_shm_write16(dev, B43_SHM_SHARED,
- B43_SHM_SH_KEYIDXBLOCK + (kidx * 2), value);
+ B43_SHM_SH_KEYIDXBLOCK + (index * 2), value);
/* Write the key to the Key Table Pointer offset */
offset = dev->ktp + (index * B43_SEC_KEYSIZE);
@@ -796,10 +794,7 @@
static void keymac_write(struct b43_wldev *dev, u8 index, const u8 *addr)
{
u32 addrtmp[2] = { 0, 0, };
- u8 per_sta_keys_start = 8;
-
- if (b43_new_kidx_api(dev))
- per_sta_keys_start = 4;
+ const u8 per_sta_keys_start = 4;
B43_WARN_ON(index < per_sta_keys_start);
/* We have two default TX keys and possibly two default RX keys.
@@ -846,10 +841,7 @@
const u8 *key, size_t key_len, const u8 *mac_addr)
{
u8 buf[B43_SEC_KEYSIZE] = { 0, };
- u8 per_sta_keys_start = 8;
-
- if (b43_new_kidx_api(dev))
- per_sta_keys_start = 4;
+ const u8 per_sta_keys_start = 4;
B43_WARN_ON(index >= dev->max_nr_keys);
B43_WARN_ON(key_len > B43_SEC_KEYSIZE);
@@ -872,7 +864,6 @@
struct ieee80211_key_conf *keyconf)
{
int i;
- int sta_keys_start;
if (key_len > B43_SEC_KEYSIZE)
return -EINVAL;
@@ -881,12 +872,9 @@
B43_WARN_ON(dev->key[i].keyconf == keyconf);
}
if (index < 0) {
+ const int per_sta_keys_start = 4;
/* Pairwise key. Get an empty slot for the key. */
- if (b43_new_kidx_api(dev))
- sta_keys_start = 4;
- else
- sta_keys_start = 8;
- for (i = sta_keys_start; i < dev->max_nr_keys; i++) {
+ for (i = per_sta_keys_start; i < dev->max_nr_keys; i++) {
if (!dev->key[i].keyconf) {
/* found empty */
index = i;
@@ -901,11 +889,6 @@
B43_WARN_ON(index > 3);
do_key_write(dev, index, algorithm, key, key_len, mac_addr);
- if ((index <= 3) && !b43_new_kidx_api(dev)) {
- /* Default RX key */
- B43_WARN_ON(mac_addr);
- do_key_write(dev, index + 4, algorithm, key, key_len, NULL);
- }
keyconf->hw_key_idx = index;
dev->key[index].keyconf = keyconf;
@@ -918,10 +901,6 @@
return -EINVAL;
do_key_write(dev, index, B43_SEC_ALGO_NONE,
NULL, B43_SEC_KEYSIZE, NULL);
- if ((index <= 3) && !b43_new_kidx_api(dev)) {
- do_key_write(dev, index + 4, B43_SEC_ALGO_NONE,
- NULL, B43_SEC_KEYSIZE, NULL);
- }
dev->key[index].keyconf = NULL;
return 0;
@@ -2972,7 +2951,8 @@
static void b43_security_init(struct b43_wldev *dev)
{
- dev->max_nr_keys = (dev->dev->id.revision >= 5) ? 58 : 20;
+ dev->max_nr_keys = (dev->dev->id.revision >= 5) ? 54 : 20;
+ B43_WARN_ON(dev->fw.rev < 351);
B43_WARN_ON(dev->max_nr_keys > ARRAY_SIZE(dev->key));
dev->ktp = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_KTP);
/* KTP is a word address, but we address SHM bytewise.
@@ -2981,7 +2961,7 @@
dev->ktp *= 2;
if (dev->dev->id.revision >= 5) {
/* Number of RCMTA address slots */
- b43_write16(dev, B43_MMIO_RCMTA_COUNT, dev->max_nr_keys - 8);
+ b43_write16(dev, B43_MMIO_RCMTA_COUNT, dev->max_nr_keys - 4);
}
b43_clear_keys(dev);
}
Index: linux-2.6/drivers/net/wireless/b43/xmit.c
===================================================================
--- linux-2.6.orig/drivers/net/wireless/b43/xmit.c 2009-07-25
10:58:31.000000000 +0000
+++ linux-2.6/drivers/net/wireless/b43/xmit.c 2009-07-27
20:40:14.000000000 +0000
@@ -252,7 +252,6 @@
/* Hardware appends ICV. */
plcp_fragment_len += info->control.hw_key->icv_len;
- key_idx = b43_kidx_to_fw(dev, key_idx);
mac_ctl |= (key_idx << B43_TXH_MAC_KEYIDX_SHIFT) &
B43_TXH_MAC_KEYIDX;
mac_ctl |= (key->algorithm << B43_TXH_MAC_KEYALG_SHIFT) &
@@ -577,7 +576,6 @@
/* We must adjust the key index here. We want the "physical"
* key index, but the ucode passed it slightly different.
*/
- keyidx = b43_kidx_to_raw(dev, keyidx);
B43_WARN_ON(keyidx >= dev->max_nr_keys);
if (dev->key[keyidx].algorithm != B43_SEC_ALGO_NONE) {
Index: linux-2.6/drivers/net/wireless/b43/xmit.h
===================================================================
--- linux-2.6.orig/drivers/net/wireless/b43/xmit.h 2009-07-25
10:58:30.000000000 +0000
+++ linux-2.6/drivers/net/wireless/b43/xmit.h 2009-07-27
20:40:14.000000000 +0000
@@ -301,36 +301,4 @@
void b43_tx_suspend(struct b43_wldev *dev);
void b43_tx_resume(struct b43_wldev *dev);
-
-/* Helper functions for converting the key-table index from "firmware-format"
- * to "raw-format" and back. The firmware API changed for this at
some revision.
- * We need to account for that here. */
-static inline int b43_new_kidx_api(struct b43_wldev *dev)
-{
- /* FIXME: Not sure the change was at rev 351 */
- return (dev->fw.rev >= 351);
-}
-static inline u8 b43_kidx_to_fw(struct b43_wldev *dev, u8 raw_kidx)
-{
- u8 firmware_kidx;
- if (b43_new_kidx_api(dev)) {
- firmware_kidx = raw_kidx;
- } else {
- if (raw_kidx >= 4) /* Is per STA key? */
- firmware_kidx = raw_kidx - 4;
- else
- firmware_kidx = raw_kidx; /* TX default key */
- }
- return firmware_kidx;
-}
-static inline u8 b43_kidx_to_raw(struct b43_wldev *dev, u8 firmware_kidx)
-{
- u8 raw_kidx;
- if (b43_new_kidx_api(dev))
- raw_kidx = firmware_kidx;
- else
- raw_kidx = firmware_kidx + 4; /* RX default keys or per STA keys */
- return raw_kidx;
-}
-
#endif /* B43_XMIT_H_ */
^ permalink raw reply
* Re: 2.6.31-rc2: Possible regression in rt61pci driver
From: Johannes Berg @ 2009-07-27 20:32 UTC (permalink / raw)
To: chris2553; +Cc: Pavel Roskin, linux-wireless, Ivo van Doorn
In-Reply-To: <200907272122.11290.chris2553@googlemail.com>
[-- Attachment #1: Type: text/plain, Size: 857 bytes --]
On Mon, 2009-07-27 at 21:22 +0100, Chris Clayton wrote:
> Yes, I remove the card once the laptop has frozen, because doing so "thaws" it again. The laptop is
> then usable until 2-5 minutes after I insert the card again, when it will freeze again. I can
> repeat this cycle over and over.
That really points to a hw (or hw programming) bug that causes the card
to lock up the bus. Had that many times in early b43 days.
> > It looks like a problem specific to the hardware, not anything in the
> > common wireless code. I suggest that you post your question to
> > users@rt2x00.serialmonkey.com. That's the mailing list for rt61pci and
> > other Ralink devices.
>
> I think I'll just configure MAC80211 power saving off or use the ath5k card that I also own.
You could also ask Ivo to disable power saving for rt61pci.
johannes
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
^ permalink raw reply
* Re: 2.6.31-rc2: Possible regression in rt61pci driver
From: Pavel Roskin @ 2009-07-27 20:30 UTC (permalink / raw)
To: chris2553; +Cc: linux-wireless
In-Reply-To: <200907272122.11290.chris2553@googlemail.com>
On Mon, 2009-07-27 at 21:22 +0100, Chris Clayton wrote:
> I think I'll just configure MAC80211 power saving off or use the ath5k
> card that I also own.
OK, it's unfortunate but understandable. I'll keep this in mind in case
I have a chance to do a extensive testing for rt61pci. I'm using a PCI
card that cannot be removed to easily.
--
Regards,
Pavel Roskin
^ permalink raw reply
* Re: 2.6.31-rc2: Possible regression in rt61pci driver
From: Chris Clayton @ 2009-07-27 20:22 UTC (permalink / raw)
To: Pavel Roskin; +Cc: linux-wireless
In-Reply-To: <1248725279.7440.8.camel@mj>
On Monday 27 July 2009, Pavel Roskin wrote:
> On Mon, 2009-07-27 at 20:35 +0100, Chris Clayton wrote:
> > On Monday 27 July 2009, Pavel Roskin wrote:
> > > But I think you may be getting something when the freeze happen. But
> > > to see it, you need to be on a text console. There are other ways to
> > > capture the kernel messages, which are described in the file
> > > Documentation/oops-tracing.txt in the Linux sources.
> >
> > I've taken some photos of the screen from the insertion of the card
> > through to ejecting it, and uploaded them to imageshack: They can be
> > viewed at:
> >
> > http://img145.imageshack.us/img145/8741/xdscn0647.jpg
> > http://img170.imageshack.us/img170/1954/xdscn0648.jpg
> > http://img195.imageshack.us/img195/807/xdscn0649.jpg
> > http://img195.imageshack.us/img195/9625/xdscn0650.jpg
> > http://img195.imageshack.us/img195/2717/xdscn0651.jpg
> > http://img170.imageshack.us/img170/6103/xdscn0652.jpg
> > http://img170.imageshack.us/img170/5844/xdscn0653.jpg
> >
> > Between them they should show all the output to the console, although
> > some do overlap a little.
> >
> > I hope they are helpful in tracking down this problem.
>
> Do you remove the card? It's like the card is disconnected at some
> point, either physically or logically.
Yes, I remove the card once the laptop has frozen, because doing so "thaws" it again. The laptop is
then usable until 2-5 minutes after I insert the card again, when it will freeze again. I can
repeat this cycle over and over.
>
> It looks like a problem specific to the hardware, not anything in the
> common wireless code. I suggest that you post your question to
> users@rt2x00.serialmonkey.com. That's the mailing list for rt61pci and
> other Ralink devices.
I think I'll just configure MAC80211 power saving off or use the ath5k card that I also own.
Thanks anyway.
Chris
--
No, Sir; there is nothing which has yet been contrived by man, by which
so much happiness is produced as by a good tavern or inn - Doctor Samuel
Johnson
^ permalink raw reply
* Re: [PATCH v2] mac80211: redefine usage of the mac80211 workqueue
From: Gábor Stefanik @ 2009-07-27 20:22 UTC (permalink / raw)
To: Luis R. Rodriguez; +Cc: Johannes Berg, linville, linux-wireless
In-Reply-To: <43e72e890907271241m7ccf386aj97097bb715e32658@mail.gmail.com>
On Mon, Jul 27, 2009 at 9:41 PM, Luis R.
Rodriguez<lrodriguez@atheros.com> wrote:
> On Mon, Jul 27, 2009 at 12:08 PM, Johannes
> Berg<johannes@sipsolutions.net> wrote:
>> On Mon, 2009-07-27 at 11:59 -0700, Luis R. Rodriguez wrote:
>>
>>> +EXPORT_SYMBOL_GPL(ieee80211_queue_work);
>>
>> Do we really want to allow these as _GPL only? Most things are not _GPL
>> but usable by anyone, which of course isn't too useful since mac80211
>> changes all the time :)
>
> Well I don't see why not.
>
> =A0Luis
Do we want to prevent non-GPL drivers from using mac80211? That's
actually counter-productive, as it reduces the chance of a
manufacturer ever releasing a useful, kernel-includable driver. (Most
manufacturers initially develop non-GPL drivers, which hopefully end
up getting released under the GPL after community persuasion. If we
make mac80211 GPL-only, that prevents any internal driver based on
mac80211 from getting written.)
--=20
Vista: [V]iruses, [I]ntruders, [S]pyware, [T]rojans and [A]dware. :-)
^ permalink raw reply
* Re: 2.6.31-rc2: Possible regression in rt61pci driver
From: Pavel Roskin @ 2009-07-27 20:07 UTC (permalink / raw)
To: chris2553; +Cc: linux-wireless
In-Reply-To: <200907272035.41193.chris2553@googlemail.com>
On Mon, 2009-07-27 at 20:35 +0100, Chris Clayton wrote:
> On Monday 27 July 2009, Pavel Roskin wrote:
> >
> > But I think you may be getting something when the freeze happen. But to
> > see it, you need to be on a text console. There are other ways to
> > capture the kernel messages, which are described in the file
> > Documentation/oops-tracing.txt in the Linux sources.
>
> I've taken some photos of the screen from the insertion of the card through to ejecting it, and
> uploaded them to imageshack: They can be viewed at:
>
> http://img145.imageshack.us/img145/8741/xdscn0647.jpg
> http://img170.imageshack.us/img170/1954/xdscn0648.jpg
> http://img195.imageshack.us/img195/807/xdscn0649.jpg
> http://img195.imageshack.us/img195/9625/xdscn0650.jpg
> http://img195.imageshack.us/img195/2717/xdscn0651.jpg
> http://img170.imageshack.us/img170/6103/xdscn0652.jpg
> http://img170.imageshack.us/img170/5844/xdscn0653.jpg
>
> Between them they should show all the output to the console, although some do overlap a little.
>
> I hope they are helpful in tracking down this problem.
Do you remove the card? It's like the card is disconnected at some
point, either physically or logically.
It looks like a problem specific to the hardware, not anything in the
common wireless code. I suggest that you post your question to
users@rt2x00.serialmonkey.com. That's the mailing list for rt61pci and
other Ralink devices.
--
Regards,
Pavel Roskin
^ permalink raw reply
* [PATCH v2] ar9170: remove unneeded flush_workqueue()
From: Luis R. Rodriguez @ 2009-07-27 19:51 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Luis R. Rodriguez, Christian Lamparter
cancel_delayed_work_sync() and cancel_work_sync() are already being
used therefore already waiting for all pending work by the driver
to have been completed, no need to flush the mac80211 workqueue.
Cc: Christian Lamparter <chunkeey@web.de>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
Rebased on to latest wireless-testing.
drivers/net/wireless/ath/ar9170/main.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c
index 85a1452..099ed3c 100644
--- a/drivers/net/wireless/ath/ar9170/main.c
+++ b/drivers/net/wireless/ath/ar9170/main.c
@@ -1290,14 +1290,13 @@ static void ar9170_op_stop(struct ieee80211_hw *hw)
if (IS_STARTED(ar))
ar->state = AR9170_IDLE;
- flush_workqueue(ar->hw->workqueue);
-
cancel_delayed_work_sync(&ar->tx_janitor);
#ifdef CONFIG_AR9170_LEDS
cancel_delayed_work_sync(&ar->led_work);
#endif
cancel_work_sync(&ar->filter_config_work);
cancel_work_sync(&ar->beacon_work);
+
mutex_lock(&ar->mutex);
if (IS_ACCEPTING_CMD(ar)) {
--
1.6.0.4
^ permalink raw reply related
* Re: [PATCH v2] mac80211: redefine usage of the mac80211 workqueue
From: Luis R. Rodriguez @ 2009-07-27 19:41 UTC (permalink / raw)
To: Johannes Berg; +Cc: linville, linux-wireless
In-Reply-To: <1248721724.32365.1.camel@johannes.local>
On Mon, Jul 27, 2009 at 12:08 PM, Johannes
Berg<johannes@sipsolutions.net> wrote:
> On Mon, 2009-07-27 at 11:59 -0700, Luis R. Rodriguez wrote:
>
>> +EXPORT_SYMBOL_GPL(ieee80211_queue_work);
>
> Do we really want to allow these as _GPL only? Most things are not _GPL
> but usable by anyone, which of course isn't too useful since mac80211
> changes all the time :)
Well I don't see why not.
Luis
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox