Linux wireless drivers development
 help / color / mirror / Atom feed
* Re: wireless-testing regression: iwl3945 scan fails
From: Kalle Valo @ 2009-07-25  5:55 UTC (permalink / raw)
  To: reinette chatre; +Cc: linux-wireless@vger.kernel.org, Johannes Berg
In-Reply-To: <874ot2sa51.fsf@litku.valot.fi>

Kalle Valo <kalle.valo@iki.fi> writes:

> reinette chatre <reinette.chatre@intel.com> writes:
>
>> Are you saying that this problem occurs always with wpa_supplicant and
>> sometimes with iw?
>
> I did some more testing and I can now reproduce this with iw as well. I
> just need to reboot my laptop to reproduce it. I'll debug this more on a
> rainy day.

This is getting very odd, I cannot reproduce the problem anymore with
rc4-wl. Just to be safe, I rebooted back to rc3-wl and I was immediately
able to reproduce it. To summarise, rc2-wl and rc4-wl were ok and only
rc3-wl is broken. So something fixed this, I just don't know what.

-- 
Kalle Valo

^ permalink raw reply

* [PATCH] mac80211: fix oops in ieee80211_scan_state_set_channel()
From: Pavel Roskin @ 2009-07-25  5:18 UTC (permalink / raw)
  To: Johannes Berg, linux-wireless, John Linville, Larry Finger

Move check for the final value of local->scan_channel_idx from
ieee80211_scan_state_decision() to ieee80211_scan_state_set_channel().

Stop the state machine in ieee80211_scan_work() by checking
local->scanning.  Don't return a value from
ieee80211_scan_state_decision().

Signed-off-by: Pavel Roskin <proski@gnu.org>
---
 net/mac80211/scan.c |   22 +++++++++++-----------
 1 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index b376775..8b5a4a3 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -470,18 +470,12 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
 	return rc;
 }
 
-static int ieee80211_scan_state_decision(struct ieee80211_local *local,
-					 unsigned long *next_delay)
+static void ieee80211_scan_state_decision(struct ieee80211_local *local,
+					  unsigned long *next_delay)
 {
 	bool associated = false;
 	struct ieee80211_sub_if_data *sdata;
 
-	/* if no more bands/channels left, complete scan and advance to the idle state */
-	if (local->scan_channel_idx >= local->scan_req->n_channels) {
-		ieee80211_scan_completed(&local->hw, false);
-		return 1;
-	}
-
 	/* check if at least one STA interface is associated */
 	mutex_lock(&local->iflist_mtx);
 	list_for_each_entry(sdata, &local->interfaces, list) {
@@ -517,7 +511,6 @@ static int ieee80211_scan_state_decision(struct ieee80211_local *local,
 	}
 
 	*next_delay = 0;
-	return 0;
 }
 
 static void ieee80211_scan_state_leave_oper_channel(struct ieee80211_local *local,
@@ -587,6 +580,12 @@ static void ieee80211_scan_state_set_channel(struct ieee80211_local *local,
 	struct ieee80211_channel *chan;
 	struct ieee80211_sub_if_data *sdata = local->scan_sdata;
 
+	/* if no more bands/channels left, complete scan and advance to the idle state */
+	if (local->scan_channel_idx >= local->scan_req->n_channels) {
+		ieee80211_scan_completed(&local->hw, false);
+		return;
+	}
+
 	skip = 0;
 	chan = local->scan_req->channels[local->scan_channel_idx];
 
@@ -695,8 +694,7 @@ void ieee80211_scan_work(struct work_struct *work)
 	do {
 		switch (local->next_scan_state) {
 		case SCAN_DECISION:
-			if (ieee80211_scan_state_decision(local, &next_delay))
-				return;
+			ieee80211_scan_state_decision(local, &next_delay);
 			break;
 		case SCAN_SET_CHANNEL:
 			ieee80211_scan_state_set_channel(local, &next_delay);
@@ -711,6 +709,8 @@ void ieee80211_scan_work(struct work_struct *work)
 			ieee80211_scan_state_enter_oper_channel(local, &next_delay);
 			break;
 		}
+		if (!local->scanning)
+			return;
 	} while (next_delay == 0);
 
 	queue_delayed_work(local->hw.workqueue, &local->scan_work,

^ permalink raw reply related

* Re: BUG in latest wireless-testing pull - 2.6.31-rc4
From: Pavel Roskin @ 2009-07-25  4:21 UTC (permalink / raw)
  To: Larry Finger; +Cc: Johannes Berg, John Linville, wireless
In-Reply-To: <4A6A7D95.1080103@lwfinger.net>

On Fri, 2009-07-24 at 22:35 -0500, Larry Finger wrote:
> I pulled from the wireless-testing (git describe yields
> v2.6.31-rc4-29133-g1addf37) and get the following BUG:
> 
> BUG: unable to handle kernel NULL pointer dereference at 000000000000000c
> IP: [<ffffffffa0267fc1>] ieee80211_scan_work+0x18a/0x426 [mac80211]

I got it too :-(

> chan = local->scan_req->channels[local->scan_channel_idx];
> 
> in ieee80211_scan_state_set_channel().

The same thing here.

The oops happens when local->scan_channel_idx reaches 14, which is
local->scan_req->n_channels.

I tried this patch:

--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -588,6 +588,10 @@ static void ieee80211_scan_state_set_channel(struct ieee80211_local *local,
 	struct ieee80211_sub_if_data *sdata = local->scan_sdata;
 
 	skip = 0;
+
+	if (local->scan_channel_idx >= local->scan_req->n_channels)
+		return;
+
 	chan = local->scan_req->channels[local->scan_channel_idx];
 
 	if (chan->flags & IEEE80211_CHAN_DISABLED ||


It prevents the oops, but now udev hangs on startup.   Perhaps
ieee80211_scan_state_set_channel() shouldn't set local->scan_channel_idx
to an invalid value in the first place.  Or maybe if it happens,
something else should be done to stop the scan.

-- 
Regards,
Pavel Roskin

^ permalink raw reply

* BUG in latest wireless-testing pull - 2.6.31-rc4
From: Larry Finger @ 2009-07-25  3:35 UTC (permalink / raw)
  To: Johannes Berg, John Linville; +Cc: wireless

I pulled from the wireless-testing (git describe yields
v2.6.31-rc4-29133-g1addf37) and get the following BUG:

BUG: unable to handle kernel NULL pointer dereference at 000000000000000c
IP: [<ffffffffa0267fc1>] ieee80211_scan_work+0x18a/0x426 [mac80211]
PGD 0
Oops: 0000 [#1] SMP
last sysfs file:
/sys/devices/pci0000:00/0000:00:0d.0/0000:04:00.0/ssb0:0/uevent
CPU 0
Modules linked in: af_packet snd_pcm_oss snd_mixer_oss snd_seq
snd_seq_device nfs lockd nfs_acl auth_rpcgss sunrpc vboxnetadp
vboxnetflt vboxdrv cpufreq_conservative cpufreq_userspace
cpufreq_powersave powernow_k8 fuse ext4 jbd2 crc16 loop dm_mod arc4
ecb ide_cd_mod cdrom b43 rng_core snd_hda_codec_conexant
ide_pci_generic mac80211 cfg80211 rfkill snd_hda_intel snd_hda_codec
snd_pcm led_class snd_timer snd battery ssb i2c_nforce2 amd74xx ac
k8temp serio_raw button sg soundcore hwmon ide_core i2c_core joydev
forcedeth snd_page_alloc sd_mod ohci_hcd ehci_hcd usbcore edd ahci
libata scsi_mod ext3 mbcache jbd fan thermal processor
Pid: 2059, comm: phy0 Not tainted 2.6.31-rc4-wl #184 HP Pavilion
dv2700 Notebook PC
RIP: 0010:[<ffffffffa0267fc1>]  [<ffffffffa0267fc1>]
ieee80211_scan_work+0x18a/0x426 [mac80211]
RSP: 0018:ffff8800b852fdb0  EFLAGS: 00010293
RAX: ffff880037b26969 RBX: 0000000000000000 RCX: ffff8800b88e46c0
RDX: 000000000000000e RSI: 0000000000000001 RDI: ffffffff8127bc96
RBP: ffff8800b852fdf0 R08: 0000000000000002 R09: 0000000000000000
R10: ffff880002193fd0 R11: ffff8800b852fb70 R12: ffff880037b411d0
R13: ffff880037b404c0 R14: ffff880037b412e8 R15: ffff8800b859acd0
FS:  00007f987563e6f0(0000) GS:ffff880002187000(0000)
knlGS:0000000000000000
CS:  0010 DS: 0018 ES: 0018 CR0: 000000008005003b
CR2: 000000000000000c CR3: 0000000001001000 CR4: 00000000000006f0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Process phy0 (pid: 2059, threadinfo ffff8800b852e000, task
ffff8800b859acd0)
Stack:
 ffff8800021a0840 ffff880037b41118 ffff880037b41128 ffff8800b852fed8
<0> ffff8800021a0840 ffff880037b412f0 ffff880037b412e8 ffff8800b859acd0
<0> ffff8800b852fec0 ffffffff81050704 ffffffff810506ad 0000000000000046
Call Trace:
 [<ffffffff81050704>] worker_thread+0x1fa/0x30a
 [<ffffffff810506ad>] ? worker_thread+0x1a3/0x30a
 [<ffffffffa0267e37>] ? ieee80211_scan_work+0x0/0x426 [mac80211]
 [<ffffffff81054f7c>] ? autoremove_wake_function+0x0/0x38
 [<ffffffff81063973>] ? trace_hardirqs_on+0xd/0xf
 [<ffffffff8105050a>] ? worker_thread+0x0/0x30a
 [<ffffffff81054c1a>] kthread+0x88/0x90
 [<ffffffff8100cb7a>] child_rip+0xa/0x20
 [<ffffffff8100c53c>] ? restore_args+0x0/0x30
 [<ffffffff81054b92>] ? kthread+0x0/0x90
 [<ffffffff8100cb70>] ? child_rip+0x0/0x20
Code: 85 24 0e 00 00 03 00 00 00 e9 43 ff ff ff 49 8b 85 00 0e 00 00
49 63 95 1c 0e 00 00 49 8b 8d c8 0e 00 00 48 8b 40 10 48 8b 1c d0 <8b>
43 0c a8 01 75 27 83 b9 90 08 00 00 01 75 04 a8 04 75 1a 49
RIP  [<ffffffffa0267fc1>] ieee80211_scan_work+0x18a/0x426 [mac80211]
 RSP <ffff8800b852fdb0>
CR2: 000000000000000c
---[ end trace 07b5d563305d3f01 ]---

The trace translates back to the statement

chan = local->scan_req->channels[local->scan_channel_idx];

in ieee80211_scan_state_set_channel().

Larry



^ permalink raw reply

* Re: lockdep complaint , now upgraded on wireless-testing
From: John W. Linville @ 2009-07-25  1:01 UTC (permalink / raw)
  To: Luis R. Rodriguez; +Cc: Johannes Berg, linux-wireless
In-Reply-To: <43e72e890907241743l7eb68cd9h5796e1dc70823c86@mail.gmail.com>

On Fri, Jul 24, 2009 at 05:43:59PM -0700, Luis R. Rodriguez wrote:
> Pretty sure this is the same one I saw the other day when I applied
> the old netns patches from Johannes. Johannes then fixed them, but not
> sure if the new shiny patch was posted.
> 
> John, I think its best we just revert your current netns patches and
> apply Johannes' new ones. That would mean not needing my ath9k oops
> fix nor a secondary patch to fix this separately.

Where are the "Johannes' new ones"?

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

^ permalink raw reply

* Re: [PATCH] mac80211/drivers: add new mac80211 workqueue API
From: Luis R. Rodriguez @ 2009-07-25  0:50 UTC (permalink / raw)
  To: linville, johannes; +Cc: linux-wireless, ath9k-devel, Luis R. Rodriguez
In-Reply-To: <1248482853-17032-1-git-send-email-lrodriguez@atheros.com>

Forgot to specify the order. The order is:

1/3 mac80211: redefine usage of the mac80211 workqueue
2/3 mac80211: do not queue work after suspend in the dynamic ps timer
3/3 ath9k: cancel xmit poll work at stop() callback

  Luis

^ permalink raw reply

* [PATCH] mac80211: redefine usage of the mac80211 workqueue
From: Luis R. Rodriguez @ 2009-07-25  0:47 UTC (permalink / raw)
  To: linville, johannes
  Cc: linux-wireless, ath9k-devel, Luis R. Rodriguez, Reinette Chatre,
	Dan Williams, Lennert Buytenhek, Daniel Drake
In-Reply-To: <1248482853-17032-1-git-send-email-lrodriguez@atheros.com>

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 and flush the mac80211 workqueue:

  * ieee80211_queue_work()
  * ieee80211_queue_delayed_work()
  * ieee80211_flush_workqueue()

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. Drivers not using the mac80211
workqueue will need to review proper sanity checking themselves.
mac80211 drivers that *do not* use the mac80211 workqueue and
invented their own (and that this patch does not touch) and
could be changed to do so:

  * iwlwifi/*
  * libertas_tf
  * mwl8k
  * zd1211rw

Cc: Reinette Chatre <reinette.chatre@intel.com>
Cc: Dan Williams <dcbw@redhat.com>
Cc: Lennert Buytenhek <buytenh@marvell.com>
Cc: Daniel Drake <ddrake@brontes3d.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/at76c50x-usb.c         |   12 +++---
 drivers/net/wireless/ath/ar9170/led.c       |   11 +++--
 drivers/net/wireless/ath/ar9170/main.c      |   28 +++++++-----
 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                      |   61 +++++++++++++++++++++++----
 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                         |   49 +++++++++++++++++++++
 31 files changed, 228 insertions(+), 124 deletions(-)

diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c
index 13303fa..d540423 100644
--- a/drivers/net/wireless/at76c50x-usb.c
+++ b/drivers/net/wireless/at76c50x-usb.c
@@ -1872,8 +1872,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;
 	}
@@ -1934,8 +1934,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);
@@ -2024,7 +2024,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,
@@ -2297,7 +2297,7 @@ static void at76_delete_device(struct at76_priv *priv)
 
 	if (priv->mac80211_registered) {
 		cancel_delayed_work(&priv->dwork_hw_scan);
-		flush_workqueue(priv->hw->workqueue);
+		ieee80211_flush_workqueue(priv->hw);
 		ieee80211_unregister_hw(priv->hw);
 	}
 
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 c7287a8..e4d4cf3 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:
@@ -1290,7 +1292,7 @@ static void ar9170_op_stop(struct ieee80211_hw *hw)
 	if (IS_STARTED(ar))
 		ar->state = AR9170_IDLE;
 
-	flush_workqueue(ar->hw->workqueue);
+	ieee80211_flush_workqueue(ar->hw);
 
 	cancel_delayed_work_sync(&ar->tx_janitor);
 	cancel_delayed_work_sync(&ar->led_work);
@@ -1824,10 +1826,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)
@@ -2156,7 +2160,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,
@@ -2414,7 +2418,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 1c648db..3eb3032 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -976,10 +976,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) :
@@ -1016,8 +1017,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;
@@ -1978,7 +1979,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 6eb2927..9fd4709 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -2055,7 +2055,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..a99a1e3 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,42 @@ 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_flush_workqueue - flush the mac80211 workqueue
+ *
+ * Drivers and mac80211 use this to flush the mac80211 workqueue
+ * when needed. Note that mac80211 will flush the workqueue for you
+ * during interface removal and during suspend.
+ *
+ * @hw: the hardware struct for the interface requesting a flush
+ */
+void ieee80211_flush_workqueue(struct ieee80211_hw *hw);
+
+/**
  * 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 c6b25cb..74d1672 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -615,6 +615,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 d79a211..96a9e0a 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);
+		ieee80211_flush_workqueue(&local->hw);
 
 		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 76c03da..a9d717e 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)
 		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;
 	}
 
@@ -2023,7 +2022,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)
@@ -2048,13 +2047,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;
@@ -2110,9 +2107,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;
 	}
 
@@ -2193,8 +2190,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)
@@ -2207,7 +2203,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)
@@ -2226,10 +2222,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);
 	}
 }
@@ -2390,7 +2386,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;
 }
 
@@ -2464,7 +2460,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..1800e8e 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);
+	ieee80211_flush_workqueue(hw);
 
 	/* 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);
+	ieee80211_flush_workqueue(hw);
 
 	/* stop hardware - this must stop RX */
 	if (local->open_count) {
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index b376775..00ed919 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -386,8 +386,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;
 }
@@ -713,8 +714,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 ec450d7..2cf9ff7 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 7fc5584..9f11490 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -498,6 +498,54 @@ 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_GPL(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_GPL(ieee80211_queue_delayed_work);
+
+void ieee80211_flush_workqueue(struct ieee80211_hw *hw)
+{
+	struct ieee80211_local *local = hw_to_local(hw);
+
+	flush_workqueue(local->workqueue);
+}
+EXPORT_SYMBOL_GPL(ieee80211_flush_workqueue);
+
 void ieee802_11_parse_elems(u8 *start, size_t len,
 			    struct ieee802_11_elems *elems)
 {
@@ -1101,3 +1149,4 @@ int ieee80211_reconfig(struct ieee80211_local *local)
 #endif
 	return 0;
 }
+
-- 
1.6.0.4


^ permalink raw reply related

* [PATCH] mac80211/drivers: add new mac80211 workqueue API
From: Luis R. Rodriguez @ 2009-07-25  0:47 UTC (permalink / raw)
  To: linville, johannes; +Cc: linux-wireless, ath9k-devel, Luis R. Rodriguez

This set move the mac80211 workqueue struct privately into mac80211
and exposes it only through helpers. We do this to aid proper suspend
support, these could eventually be extended for further sanity
checkings or considerations.

We also fix two initial warnings we hit with this, one on mac80211, the
other on ath9k.

Luis R. Rodriguez (3):
  mac80211: redefine usage of the mac80211 workqueue
  mac80211: do not queue work after suspend in the dynamic ps timer
  ath9k: cancel xmit poll work at stop() callback

 drivers/net/wireless/at76c50x-usb.c         |   12 +++---
 drivers/net/wireless/ath/ar9170/led.c       |   11 +++--
 drivers/net/wireless/ath/ar9170/main.c      |   28 +++++++-----
 drivers/net/wireless/ath/ath9k/main.c       |   17 ++++---
 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                      |   61 +++++++++++++++++++++++----
 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                         |   50 ++++++++++------------
 net/mac80211/pm.c                           |    4 +-
 net/mac80211/scan.c                         |    8 ++--
 net/mac80211/tx.c                           |    2 +-
 net/mac80211/util.c                         |   49 +++++++++++++++++++++
 31 files changed, 231 insertions(+), 125 deletions(-)


^ permalink raw reply

* [PATCH] mac80211: do not queue work after suspend in the dynamic ps timer
From: Luis R. Rodriguez @ 2009-07-25  0:47 UTC (permalink / raw)
  To: linville, johannes; +Cc: linux-wireless, ath9k-devel, Luis R. Rodriguez
In-Reply-To: <1248482853-17032-1-git-send-email-lrodriguez@atheros.com>

This fixes this warning during suspend <--> resume:

WARNING: at net/mac80211/util.c:511 ieee80211_queue_work+0x3a/0x40 [mac80211]()
Hardware name: 6460DWU
queueing ieee80211 work while going to suspend
Modules linked in: <--snip-->
Pid: 0, comm: swapper Not tainted 2.6.31-rc3-wl #4
Call Trace:
 <IRQ>  [<ffffffffa0139d0a>] ? ieee80211_queue_work+0x3a/0x40 [mac80211]
 [<ffffffff810552b8>] warn_slowpath_common+0x78/0xd0
 [<ffffffffa012a580>] ? ieee80211_dynamic_ps_timer+0x0/0x30 [mac80211]
 [<ffffffff81055394>] warn_slowpath_fmt+0x64/0x70
 [<ffffffff810188a9>] ? sched_clock+0x9/0x10
 [<ffffffff8107800c>] ? getnstimeofday+0x5c/0xf0
 [<ffffffff810188a9>] ? sched_clock+0x9/0x10
 [<ffffffff81074625>] ? sched_clock_cpu+0x75/0x240
 [<ffffffffa0139d0a>] ieee80211_queue_work+0x3a/0x40 [mac80211]
 [<ffffffffa012a59c>] ieee80211_dynamic_ps_timer+0x1c/0x30 [mac80211]
 ... etc

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

diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index a9d717e..98df70d 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -760,7 +760,7 @@ void ieee80211_dynamic_ps_timer(unsigned long data)
 {
 	struct ieee80211_local *local = (void *) data;
 
-	if (local->quiescing)
+	if (local->quiescing || local->suspended)
 		return;
 
 	ieee80211_queue_work(&local->hw, &local->dynamic_ps_enable_work);
-- 
1.6.0.4


^ permalink raw reply related

* [PATCH] ath9k: cancel xmit poll work at stop() callback
From: Luis R. Rodriguez @ 2009-07-25  0:47 UTC (permalink / raw)
  To: linville, johannes; +Cc: linux-wireless, ath9k-devel, Luis R. Rodriguez
In-Reply-To: <1248482853-17032-1-git-send-email-lrodriguez@atheros.com>

We forgot to cancel this work at the stop() callback.

------------[ cut here ]------------
WARNING: at net/mac80211/util.c:511 ieee80211_queue_delayed_work+0x3a/0x40 [mac80211]()
Hardware name: 6460DWU
queueing ieee80211 work while going to suspend
Modules linked in: <-- snip -->
Pid: 5124, comm: phy0 Tainted: G        W  2.6.31-rc3-wl #4
Call Trace:
 [<ffffffffa03adcda>] ? ieee80211_queue_delayed_work+0x3a/0x40 [mac80211]
 [<ffffffff810552b8>] warn_slowpath_common+0x78/0xd0
 [<ffffffff81055394>] warn_slowpath_fmt+0x64/0x70
 [<ffffffff814ed2c9>] ? thread_return+0x3e/0x635
 [<ffffffffa03adcda>] ieee80211_queue_delayed_work+0x3a/0x40 [mac80211]
 [<ffffffffa0297690>] ath_tx_complete_poll_work+0xc0/0x100 [ath9k]
 [<ffffffffa02975d0>] ? ath_tx_complete_poll_work+0x0/0x100 [ath9k]
 [<ffffffff81069b68>] worker_thread+0x178/0x260
 [<ffffffff8106ecc0>] ? autoremove_wake_function+0x0/0x40
 [<ffffffff810699f0>] ? worker_thread+0x0/0x260
 [<ffffffff8106e89e>] kthread+0x9e/0xb0
 [<ffffffff8101302a>] child_rip+0xa/0x20
 [<ffffffff8106e800>] ? kthread+0x0/0xb0
 [<ffffffff81013020>] ? child_rip+0x0/0x20

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

diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 3eb3032..fff89cc 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -2100,6 +2100,8 @@ static void ath9k_stop(struct ieee80211_hw *hw)
 
 	mutex_lock(&sc->mutex);
 
+	cancel_delayed_work_sync(&sc->tx_complete_work);
+
 	if (ath9k_wiphy_started(sc)) {
 		mutex_unlock(&sc->mutex);
 		return; /* another wiphy still in use */
-- 
1.6.0.4


^ permalink raw reply related

* lockdep complaint , now upgraded on wireless-testing
From: Luis R. Rodriguez @ 2009-07-25  0:43 UTC (permalink / raw)
  To: John W. Linville, Johannes Berg; +Cc: linux-wireless

Pretty sure this is the same one I saw the other day when I applied
the old netns patches from Johannes. Johannes then fixed them, but not
sure if the new shiny patch was posted.

John, I think its best we just revert your current netns patches and
apply Johannes' new ones. That would mean not needing my ath9k oops
fix nor a secondary patch to fix this separately.

  Luis

[   69.138284] =======================================================
[   69.138468] [ INFO: possible circular locking dependency detected ]
[   69.138564] 2.6.31-rc4-wl #6
[   69.138654] -------------------------------------------------------
[   69.138741] wpa_supplicant/3799 is trying to acquire lock:
[   69.138835]  (cfg80211_mutex){+.+.+.}, at: [<ffffffffa009246a>]
cfg80211_get_dev_from_ifindex+0x1a/0x90 [cfg80211]
[   69.139204]
[   69.139205] but task is already holding lock:
[   69.139380]  (rtnl_mutex){+.+.+.}, at: [<ffffffff81400ff2>]
rtnl_lock+0x12/0x20
[   69.139728]
[   69.139729] which lock already depends on the new lock.
[   69.139730]
 69.140017] the existing dependency chain (in reverse order) is:
[   69.140215]
[   69.140215] -> #1 (rtnl_mutex){+.+.+.}:
[   69.140666]        [<ffffffff810857b6>] __lock_acquire+0xd76/0x12b0
[   69.140857]        [<ffffffff81085dd3>] lock_acquire+0xe3/0x120
[   69.141047]        [<ffffffff814ee7a4>] mutex_lock_nested+0x44/0x350
[   69.141241]        [<ffffffff81400ff2>] rtnl_lock+0x12/0x20
[   69.141432]        [<ffffffffa009f6a5>]
nl80211_send_reg_change_event+0x1f5/0x2a0 [cfg80211]
[   69.141642]        [<ffffffffa009529e>] set_regdom+0x28e/0x4c0 [cfg80211]
[   69.141666]        [<ffffffffa0099d7a>] nl80211_set_reg+0x11a/0x2c0
[cfg80211]
[   69.141666]        [<ffffffff81416ad6>] genl_rcv_msg+0x1b6/0x1f0
[   69.141666]        [<ffffffff81415b69>] netlink_rcv_skb+0x89/0xb0
[   69.141666]        [<ffffffff81416909>] genl_rcv+0x29/0x40
[   69.141666]        [<ffffffff8141584d>] netlink_unicast+0x29d/0x2b0
[   69.141666]        [<ffffffff81416444>] netlink_sendmsg+0x214/0x300
[   69.141666]        [<ffffffff813e4407>] sock_sendmsg+0x107/0x130
[   69.141666]        [<ffffffff813e45b9>] sys_sendmsg+0x189/0x320
[   69.141666]        [<ffffffff81011f82>] system_call_fastpath+0x16/0x1b
[   69.141666]        [<ffffffffffffffff>] 0xffffffffffffffff
[   69.141666]
[   69.141666] -> #0 (cfg80211_mutex){+.+.+.}:
[   69.141666]        [<ffffffff8108587b>] __lock_acquire+0xe3b/0x12b0
[   69.141666]        [<ffffffff81085dd3>] lock_acquire+0xe3/0x120
[   69.141666]        [<ffffffff814ee7a4>] mutex_lock_nested+0x44/0x350
[   69.141666]        [<ffffffffa009246a>]
cfg80211_get_dev_from_ifindex+0x1a/0x90 [cfg80211]
[   69.141666]        [<ffffffffa009813f>]
get_rdev_dev_by_info_ifindex+0x6f/0xa0 [cfg80211]
[   69.141666]        [<ffffffffa009b12b>]
nl80211_set_interface+0x3b/0x260 [cfg80211]

^ permalink raw reply

* Re: [PATCH] mac80211: add helper to add to the mac80211 workqueue
From: Luis R. Rodriguez @ 2009-07-25  0:06 UTC (permalink / raw)
  To: Johannes Berg
  Cc: linville, linux-wireless, ath9k-devel, Reinette Chatre,
	Dan Williams, Lennert Buytenhek, Daniel Drake
In-Reply-To: <1248459325.32151.32.camel@johannes.local>

On Fri, Jul 24, 2009 at 11:15 AM, Johannes
Berg<johannes@sipsolutions.net> wrote:
> On Fri, 2009-07-24 at 14:08 -0400, Luis R. Rodriguez wrote:
>> We add a mac80211 helper for adding work onto the mac80211
>> workqueue. We then add a warning if we are suspended. At that
>> point drivers nor mac80211 should have queued work, drivers
>> and mac80211 should ensure the workqueue will remain clair
>> until resume.
>>
>> We make use of the helper now in mac80211 and on all mac80211
>> drivers. If you see a warning because of this patch during
>> the suspend <--> resume cycle it means suspend is busted for
>> your driver or mac80211 and it needs to be fixed.
>
> Looks good to me.

Except I forgot about delayed queing, flushing. I will repost and
consider all the other things.

  Luis

^ permalink raw reply

* Re: ath9k panic (ath_tx_rc_status)
From: Luis R. Rodriguez @ 2009-07-24 23:58 UTC (permalink / raw)
  To: Davide Pesavento; +Cc: linux-wireless
In-Reply-To: <2da21fe50907241631o3bf02d35md09c341133f503d2@mail.gmail.com>

On Sat, Jul 25, 2009 at 01:31:24AM +0200, Davide Pesavento wrote:
> Hi,
> 
> after the latest pull from wireless-testing
> (2.6.31-rc4-wl-29133-g1addf37) I always get a kernel panic with the
> ath9k driver. The panic happens as soon as I start wpa_supplicant
> (with -Dnl80211) or NetworkManager. I think that the kernel spits out
> some warnings (lockdep?) before crashing, but I haven't been able to
> capture them.
> This is a regression since my previous pull (2.6.31-rc3-wl... + something).

Yup, wrong patch applied/sent/fuckup. Try the patch posted.

  Luis

^ permalink raw reply

* [PATCH] mac80211: fix oops due to missing private data
From: Luis R. Rodriguez @ 2009-07-24 23:57 UTC (permalink / raw)
  To: linville, johannes
  Cc: linux-wireless, ath9k-devel, davidepesa, Luis R. Rodriguez

This was caused by patch:

"mac80211: cooperate more with network namespaces"

The version of the patch applied doesn't match Johannes' latest:

http://johannes.sipsolutions.net/patches/kernel/all/LATEST/NNN-mac80211-netns.patch

The skb->cb virtual interface data wasn't being reset for
reuse so ath9k pooped out when trying to dereference the
private rate control info from the skb.

BUG: unable to handle kernel NULL pointer dereference
RIP: 0010:[<ffffffffa0258173>] ath_tx_rc_status+0x33/0x150 [ath9k]
<-- snip etc -->

Reported-by: Davide Pesavento <davidepesa@gmail.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 net/mac80211/tx.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 1b9e081..2cf9ff7 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1170,13 +1170,15 @@ static int __ieee80211_tx(struct ieee80211_local *local,
 		}
 
 		ret = drv_tx(local, skb);
-		info->control.vif = &sdata->vif;
 		if (WARN_ON(ret != NETDEV_TX_OK && skb->len != len)) {
 			dev_kfree_skb(skb);
 			ret = NETDEV_TX_OK;
 		}
-		if (ret != NETDEV_TX_OK)
+		if (ret != NETDEV_TX_OK) {
+			info->control.vif = &sdata->vif;
 			return IEEE80211_TX_AGAIN;
+		}
+
 		*skbp = skb = next;
 		ieee80211_led_tx(local, 1);
 		fragm = true;
-- 
1.6.0.4


^ permalink raw reply related

* ath9k panic (ath_tx_rc_status)
From: Davide Pesavento @ 2009-07-24 23:31 UTC (permalink / raw)
  To: linux-wireless

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

Hi,

after the latest pull from wireless-testing
(2.6.31-rc4-wl-29133-g1addf37) I always get a kernel panic with the
ath9k driver. The panic happens as soon as I start wpa_supplicant
(with -Dnl80211) or NetworkManager. I think that the kernel spits out
some warnings (lockdep?) before crashing, but I haven't been able to
capture them.
This is a regression since my previous pull (2.6.31-rc3-wl... + something).

Regards,
Davide

[-- Attachment #2: 25072009.jpg --]
[-- Type: image/jpeg, Size: 503895 bytes --]

^ permalink raw reply

* Re: [PATCH 12/14] iwlwifi: debugFs to enable/disable 40MHz channel support
From: Gábor Stefanik @ 2009-07-24 21:40 UTC (permalink / raw)
  To: Reinette Chatre; +Cc: linville, linux-wireless, ipw3945-devel, Wey-Yi Guy
In-Reply-To: <1248459194-10239-13-git-send-email-reinette.chatre@intel.com>

On Fri, Jul 24, 2009 at 8:13 PM, Reinette
Chatre<reinette.chatre@intel.com> wrote:
> From: Wey-Yi Guy <wey-yi.w.guy@intel.com>
>
> Add debugfs file to enable/disable Fat(40MHz) channel support.
> By default, 40MHz is supported if AP can support the function.
>
> By echo "1" to "disable_fat_mode" file, iwlwifi driver will disable the 40MHz
> support and only allow 20MHz channel.

Please make that disable_ht40. The term "fat channel" is deprecated in
favor of "HT40".

>
> Because the information exchange happen during association time,
> so enable/disable fat 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>
> ---
>  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 710dd41..edfdbe8 100644
> --- a/drivers/net/wireless/iwlwifi/iwl-core.c
> +++ b/drivers/net/wireless/iwlwifi/iwl-core.c
> @@ -632,6 +632,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_fat)
> +               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..2e10da3 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_fat_mode;
>        } 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..03486d5 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_fat_mode_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 fat_mode;
> +
> +       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", &fat_mode) != 1)
> +               return -EFAULT;
> +       if (!iwl_is_associated(priv))
> +               priv->disable_fat = fat_mode ? true : false;
> +       else {
> +               IWL_ERR(priv, "Sta associated with AP - "
> +                       "Change fat mode is not allowed\n");
> +               return -EINVAL;
> +       }
> +
> +       return count;
> +}
> +
> +static ssize_t iwl_dbgfs_disable_fat_mode_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_fat ? "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_fat_mode);
>
>  /*
>  * 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_fat_mode, 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_fat_mode);
>        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..6101d12 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_fat;
>  #ifdef CONFIG_IWLWIFI_DEBUGFS
>        /* debugfs */
>        struct iwl_debugfs *dbgfs;
> --
> 1.5.6.3
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>



-- 
Vista: [V]iruses, [I]ntruders, [S]pyware, [T]rojans and [A]dware. :-)

^ permalink raw reply

* Oopses with wireless-testing from today
From: Marcel Holtmann @ 2009-07-24 20:26 UTC (permalink / raw)
  To: linux-wireless

Hi Johannes,

so here are some oopses I have seen while running the latest
wireless-testing tree from today.

Regards

Marcel


[ 2140.094603] ------------[ cut here ]------------
[ 2140.094644] WARNING: at net/mac80211/mlme.c:2007 ieee80211_sta_work+0x4f7/0xe34 [mac80211]()
[ 2140.094651] Hardware name: 7454CTO
[ 2140.094654] unexpected: 3
[ 2140.094658] Modules linked in: iwlagn iwlcore fuse rfcomm bnep sco l2cap cdc_ether usbnet mii cdc_wdm cdc_acm binfmt_misc uinput snd_hda_codec_conexant snd_hda_intel snd_hda_codec uvcvideo snd_pcm videodev snd_timer mac80211 btusb v4l1_compat snd v4l2_compat_ioctl32 bluetooth soundcore cfg80211 snd_page_alloc uhci_hcd ehci_hcd [last unloaded: iwlcore]
[ 2140.094719] Pid: 28084, comm: phy4 Not tainted 2.6.31-rc4-wl #41
[ 2140.094724] Call Trace:
[ 2140.094738]  [<ffffffff8103ad05>] warn_slowpath_common+0x77/0x8f
[ 2140.094747]  [<ffffffff8103ad6a>] warn_slowpath_fmt+0x3c/0x3e
[ 2140.094779]  [<ffffffffa009f9b0>] ? ieee80211_rx_mgmt_deauth+0xa3/0xb0 [mac80211]
[ 2140.094810]  [<ffffffffa00a1f63>] ieee80211_sta_work+0x4f7/0xe34 [mac80211]
[ 2140.094842]  [<ffffffffa00a1a6c>] ? ieee80211_sta_work+0x0/0xe34 [mac80211]
[ 2140.094852]  [<ffffffff81049dc1>] worker_thread+0x147/0x1eb
[ 2140.094860]  [<ffffffff8104d8b9>] ? autoremove_wake_function+0x0/0x34
[ 2140.094869]  [<ffffffff81049c7a>] ? worker_thread+0x0/0x1eb
[ 2140.094876]  [<ffffffff8104d5bb>] kthread+0x85/0x8d
[ 2140.094885]  [<ffffffff8100beca>] child_rip+0xa/0x20
[ 2140.094892]  [<ffffffff8104d536>] ? kthread+0x0/0x8d
[ 2140.094899]  [<ffffffff8100bec0>] ? child_rip+0x0/0x20
[ 2140.094905] ---[ end trace d5f74de670daf4e3 ]---


[ 2332.961400] ------------[ cut here ]------------
[ 2332.961442] WARNING: at net/mac80211/mlme.c:2502 ieee80211_mgd_deauth+0xc7/0x105 [mac80211]()
[ 2332.961448] Hardware name: 7454CTO
[ 2332.961451] Modules linked in: iwlagn iwlcore fuse rfcomm bnep sco l2cap cdc_ether usbnet mii cdc_wdm cdc_acm binfmt_misc uinput snd_hda_codec_conexant snd_hda_intel snd_hda_codec uvcvideo snd_pcm videodev snd_timer mac80211 btusb v4l1_compat snd v4l2_compat_ioctl32 bluetooth soundcore cfg80211 snd_page_alloc uhci_hcd ehci_hcd [last unloaded: iwlcore]
[ 2332.961512] Pid: 28271, comm: wpa_supplicant Tainted: G        W  2.6.31-rc4-wl #41
[ 2332.961518] Call Trace:
[ 2332.961532]  [<ffffffff8103ad05>] warn_slowpath_common+0x77/0x8f
[ 2332.961540]  [<ffffffff8103ad2c>] warn_slowpath_null+0xf/0x11
[ 2332.961571]  [<ffffffffa009fa84>] ieee80211_mgd_deauth+0xc7/0x105 [mac80211]
[ 2332.961603]  [<ffffffffa00a5344>] ieee80211_deauth+0x19/0x1b [mac80211]
[ 2332.961633]  [<ffffffffa0038a70>] __cfg80211_mlme_deauth+0x12b/0x13a [cfg80211]
[ 2332.961660]  [<ffffffffa003b936>] __cfg80211_disconnect+0xd9/0x145 [cfg80211]
[ 2332.961685]  [<ffffffffa003dce6>] cfg80211_mgd_wext_siwap+0x129/0x1ce [cfg80211]
[ 2332.961714]  [<ffffffffa009927a>] ieee80211_ioctl_siwap+0x23/0x37 [mac80211]
[ 2332.961724]  [<ffffffff8133a6f1>] ioctl_standard_call+0x53/0xa7
[ 2332.961735]  [<ffffffff812ac302>] ? __dev_get_by_name+0x85/0x9c
[ 2332.961743]  [<ffffffff8133a69e>] ? ioctl_standard_call+0x0/0xa7
[ 2332.961751]  [<ffffffff81339be3>] ? ioctl_private_call+0x0/0x77
[ 2332.961758]  [<ffffffff81339d41>] wext_ioctl_dispatch+0xdc/0x154
[ 2332.961766]  [<ffffffff81339e9f>] wext_handle_ioctl+0x39/0x70
[ 2332.961775]  [<ffffffff812b05b5>] dev_ioctl+0x614/0x63d
[ 2332.961785]  [<ffffffff81120df7>] ? avc_has_perm+0x57/0x6c
[ 2332.961795]  [<ffffffff8107ecd3>] ? unlock_page+0x22/0x26
[ 2332.961804]  [<ffffffff8129f878>] sock_ioctl+0x204/0x20f
[ 2332.961813]  [<ffffffff810b1b8d>] vfs_ioctl+0x1d/0x82
[ 2332.961822]  [<ffffffff811b74a3>] ? tty_ldisc_deref+0x6f/0x74
[ 2332.961830]  [<ffffffff81121b65>] ? file_has_perm+0x7e/0x89
[ 2332.961838]  [<ffffffff810b20a1>] do_vfs_ioctl+0x438/0x47e
[ 2332.961846]  [<ffffffff810b2138>] sys_ioctl+0x51/0x74
[ 2332.961855]  [<ffffffff8100ae6b>] system_call_fastpath+0x16/0x1b
[ 2332.961861] ---[ end trace d5f74de670daf4e4 ]---


[ 2332.961986] ------------[ cut here ]------------
[ 2332.962020] WARNING: at net/mac80211/mlme.c:2502 ieee80211_mgd_deauth+0xc7/0x105 [mac80211]()
[ 2332.962026] Hardware name: 7454CTO
[ 2332.962029] Modules linked in: iwlagn iwlcore fuse rfcomm bnep sco l2cap cdc_ether usbnet mii cdc_wdm cdc_acm binfmt_misc uinput snd_hda_codec_conexant snd_hda_intel snd_hda_codec uvcvideo snd_pcm videodev snd_timer mac80211 btusb v4l1_compat snd v4l2_compat_ioctl32 bluetooth soundcore cfg80211 snd_page_alloc uhci_hcd ehci_hcd [last unloaded: iwlcore]
[ 2332.962087] Pid: 28271, comm: wpa_supplicant Tainted: G        W  2.6.31-rc4-wl #41
[ 2332.962092] Call Trace:
[ 2332.962101]  [<ffffffff8103ad05>] warn_slowpath_common+0x77/0x8f
[ 2332.962109]  [<ffffffff8103ad2c>] warn_slowpath_null+0xf/0x11
[ 2332.962139]  [<ffffffffa009fa84>] ieee80211_mgd_deauth+0xc7/0x105 [mac80211]
[ 2332.962171]  [<ffffffffa00a5344>] ieee80211_deauth+0x19/0x1b [mac80211]
[ 2332.962198]  [<ffffffffa0038a70>] __cfg80211_mlme_deauth+0x12b/0x13a [cfg80211]
[ 2332.962224]  [<ffffffffa003b936>] __cfg80211_disconnect+0xd9/0x145 [cfg80211]
[ 2332.962249]  [<ffffffffa003de70>] cfg80211_mgd_wext_siwessid+0xe5/0x17c [cfg80211]
[ 2332.962278]  [<ffffffffa009921e>] ieee80211_ioctl_siwessid+0x28/0x2a [mac80211]
[ 2332.962287]  [<ffffffff8133a60b>] ioctl_standard_iw_point+0x18b/0x21e
[ 2332.962315]  [<ffffffffa00991f6>] ? ieee80211_ioctl_siwessid+0x0/0x2a [mac80211]
[ 2332.962324]  [<ffffffff8133a72b>] ioctl_standard_call+0x8d/0xa7
[ 2332.962333]  [<ffffffff812ac302>] ? __dev_get_by_name+0x85/0x9c
[ 2332.962341]  [<ffffffff8133a69e>] ? ioctl_standard_call+0x0/0xa7
[ 2332.962348]  [<ffffffff81339be3>] ? ioctl_private_call+0x0/0x77
[ 2332.962356]  [<ffffffff81339d41>] wext_ioctl_dispatch+0xdc/0x154
[ 2332.962364]  [<ffffffff81339e9f>] wext_handle_ioctl+0x39/0x70
[ 2332.962372]  [<ffffffff812b05b5>] dev_ioctl+0x614/0x63d
[ 2332.962381]  [<ffffffff81120df7>] ? avc_has_perm+0x57/0x6c
[ 2332.962390]  [<ffffffff8129f878>] sock_ioctl+0x204/0x20f
[ 2332.962399]  [<ffffffff8114e029>] ? cpumask_any_but+0x29/0x36
[ 2332.962407]  [<ffffffff810b1b8d>] vfs_ioctl+0x1d/0x82
[ 2332.962415]  [<ffffffff81121b65>] ? file_has_perm+0x7e/0x89
[ 2332.962423]  [<ffffffff810b20a1>] do_vfs_ioctl+0x438/0x47e
[ 2332.962431]  [<ffffffff810b2138>] sys_ioctl+0x51/0x74
[ 2332.962440]  [<ffffffff81050c0c>] ? up_write+0x9/0xb
[ 2332.962448]  [<ffffffff8100ae6b>] system_call_fastpath+0x16/0x1b
[ 2332.962454] ---[ end trace d5f74de670daf4e5 ]---


[ 2332.962599] ------------[ cut here ]------------
[ 2332.962633] WARNING: at net/mac80211/mlme.c:2502 ieee80211_mgd_deauth+0xc7/0x105 [mac80211]()
[ 2332.962638] Hardware name: 7454CTO
[ 2332.962642] Modules linked in: iwlagn iwlcore fuse rfcomm bnep sco l2cap cdc_ether usbnet mii cdc_wdm cdc_acm binfmt_misc uinput snd_hda_codec_conexant snd_hda_intel snd_hda_codec uvcvideo snd_pcm videodev snd_timer mac80211 btusb v4l1_compat snd v4l2_compat_ioctl32 bluetooth soundcore cfg80211 snd_page_alloc uhci_hcd ehci_hcd [last unloaded: iwlcore]
[ 2332.962700] Pid: 28271, comm: wpa_supplicant Tainted: G        W  2.6.31-rc4-wl #41
[ 2332.962705] Call Trace:
[ 2332.962716]  [<ffffffff8103ad05>] warn_slowpath_common+0x77/0x8f
[ 2332.962723]  [<ffffffff8103ad2c>] warn_slowpath_null+0xf/0x11
[ 2332.962753]  [<ffffffffa009fa84>] ieee80211_mgd_deauth+0xc7/0x105 [mac80211]
[ 2332.962785]  [<ffffffffa00a5344>] ieee80211_deauth+0x19/0x1b [mac80211]
[ 2332.962813]  [<ffffffffa0038a70>] __cfg80211_mlme_deauth+0x12b/0x13a [cfg80211]
[ 2332.962839]  [<ffffffffa003b936>] __cfg80211_disconnect+0xd9/0x145 [cfg80211]
[ 2332.962861]  [<ffffffffa002b2f6>] cfg80211_netdev_notifier_call+0x1f2/0x2fc [cfg80211]
[ 2332.962873]  [<ffffffff810512c2>] notifier_call_chain+0x32/0x5e
[ 2332.962882]  [<ffffffff8105135e>] raw_notifier_call_chain+0xf/0x11
[ 2332.962891]  [<ffffffff812ae9de>] call_netdevice_notifiers+0x16/0x18
[ 2332.962899]  [<ffffffff812af32f>] dev_close+0x4d/0x84
[ 2332.962907]  [<ffffffff812aed35>] dev_change_flags+0xa8/0x168
[ 2332.962918]  [<ffffffff812ea669>] devinet_ioctl+0x265/0x58b
[ 2332.962927]  [<ffffffff812eb9e8>] inet_ioctl+0x92/0xaa
[ 2332.962934]  [<ffffffff8129f860>] sock_ioctl+0x1ec/0x20f
[ 2332.962942]  [<ffffffff812a0ff1>] ? sys_sendto+0xdb/0x103
[ 2332.962950]  [<ffffffff810b1b8d>] vfs_ioctl+0x1d/0x82
[ 2332.962959]  [<ffffffff811b74a3>] ? tty_ldisc_deref+0x6f/0x74
[ 2332.962968]  [<ffffffff81121b65>] ? file_has_perm+0x7e/0x89
[ 2332.962975]  [<ffffffff810b20a1>] do_vfs_ioctl+0x438/0x47e
[ 2332.962984]  [<ffffffff810b2138>] sys_ioctl+0x51/0x74
[ 2332.962991]  [<ffffffff8100ae6b>] system_call_fastpath+0x16/0x1b
[ 2332.962997] ---[ end trace d5f74de670daf4e6 ]---


[ 2332.963008] ------------[ cut here ]------------
[ 2332.963037] WARNING: at net/mac80211/mlme.c:2502 ieee80211_mgd_deauth+0xc7/0x105 [mac80211]()
[ 2332.963043] Hardware name: 7454CTO
[ 2332.963046] Modules linked in: iwlagn iwlcore fuse rfcomm bnep sco l2cap cdc_ether usbnet mii cdc_wdm cdc_acm binfmt_misc uinput snd_hda_codec_conexant snd_hda_intel snd_hda_codec uvcvideo snd_pcm videodev snd_timer mac80211 btusb v4l1_compat snd v4l2_compat_ioctl32 bluetooth soundcore cfg80211 snd_page_alloc uhci_hcd ehci_hcd [last unloaded: iwlcore]
[ 2332.963102] Pid: 28271, comm: wpa_supplicant Tainted: G        W  2.6.31-rc4-wl #41
[ 2332.963106] Call Trace:
[ 2332.963114]  [<ffffffff8103ad05>] warn_slowpath_common+0x77/0x8f
[ 2332.963122]  [<ffffffff8103ad2c>] warn_slowpath_null+0xf/0x11
[ 2332.963152]  [<ffffffffa009fa84>] ieee80211_mgd_deauth+0xc7/0x105 [mac80211]
[ 2332.963184]  [<ffffffffa00a5344>] ieee80211_deauth+0x19/0x1b [mac80211]
[ 2332.963210]  [<ffffffffa0038875>] cfg80211_mlme_down+0x10d/0x1dd [cfg80211]
[ 2332.963232]  [<ffffffffa002b301>] cfg80211_netdev_notifier_call+0x1fd/0x2fc [cfg80211]
[ 2332.963242]  [<ffffffff810512c2>] notifier_call_chain+0x32/0x5e
[ 2332.963251]  [<ffffffff8105135e>] raw_notifier_call_chain+0xf/0x11
[ 2332.963260]  [<ffffffff812ae9de>] call_netdevice_notifiers+0x16/0x18
[ 2332.963268]  [<ffffffff812af32f>] dev_close+0x4d/0x84
[ 2332.963275]  [<ffffffff812aed35>] dev_change_flags+0xa8/0x168
[ 2332.963284]  [<ffffffff812ea669>] devinet_ioctl+0x265/0x58b
[ 2332.963293]  [<ffffffff812eb9e8>] inet_ioctl+0x92/0xaa
[ 2332.963300]  [<ffffffff8129f860>] sock_ioctl+0x1ec/0x20f
[ 2332.963308]  [<ffffffff812a0ff1>] ? sys_sendto+0xdb/0x103
[ 2332.963315]  [<ffffffff810b1b8d>] vfs_ioctl+0x1d/0x82
[ 2332.963323]  [<ffffffff811b74a3>] ? tty_ldisc_deref+0x6f/0x74
[ 2332.963332]  [<ffffffff81121b65>] ? file_has_perm+0x7e/0x89
[ 2332.963340]  [<ffffffff810b20a1>] do_vfs_ioctl+0x438/0x47e
[ 2332.963348]  [<ffffffff810b2138>] sys_ioctl+0x51/0x74
[ 2332.963355]  [<ffffffff8100ae6b>] system_call_fastpath+0x16/0x1b
[ 2332.963361] ---[ end trace d5f74de670daf4e7 ]---



^ permalink raw reply

* pull request: wireless-next-2.6 2009-07-24
From: John W. Linville @ 2009-07-24 19:36 UTC (permalink / raw)
  To: davem; +Cc: linux-wireless, netdev

Dave,

Here is the latest huge round of wireless patches intended for 2.6.32.
It hits all the usual areas (i.e. drivers, mac80211, and cfg80211) with
patches from all the usual suspects.  This includes the reworking of
mac80211 to eliminate the confusing "master netdev".

FWIW, my laptop has been happy with it.  Most of the bits here have been
in -next for at least a few days.

Please let me know if there are problems!

Thanks,

John

---

Individual patches are available here:

	http://www.kernel.org/pub/linux/kernel/people/linville/wireless-next-2.6/

---

The following changes since commit 74d154189d597b91da4322996dbf4f5c3d1544ab:
  David S. Miller (1):
        Merge branch 'master' of master.kernel.org:/.../davem/net-2.6

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6.git master

Christian Lamparter (8):
      p54: re-enable power save feature
      p54: generate channel list dynamically
      ar9170: implement transmit aggregation
      p54: remove useless code
      p54: fix beaconing related firmware crash
      p54: fix a fw crash caused by statistic feedback
      mac80211: do not monitor the connection while scanning
      mac80211: fix spare warnings in driver-trace.h

Gabor Juhos (5):
      ath9k: serialize ath9k_hw_setpower calls
      ath9k: uninline ath9k_ps_{wakeup,restore} functions
      ath9k: serialize ath9k_ps_{wakeup,restore} calls
      ath9k: wake up the chip for TSF reset
      ath9k: make use ath9k_hw_wait int ath9k_hw_reset_tsf

Gábor Stefanik (1):
      cfg80211: fix disabling WPA via wext (SIOCSIWAUTH)

Helmut Schaa (1):
      cfg80211: update misleading comment

Hin-Tak Leung (2):
      zd1211rw: adding Accton Technology Corp (083a:e501) as a ZD1211B device
      rtl8187: updating Kconfig with info of branded devices

Ivo van Doorn (1):
      rt2x00: Remove DEVICE_STATE_DISABLED_RADIO_HW

Javier Cardona (2):
      mac80211: Assign next hop address to pending mesh frames
      mac80211: Fix regression in mesh forwarding path.

Jay Sternberg (2):
      iwlwifi: Handle new firmware file with ucode build number in header
      iwlwifi: update 1000 series API version to match firmware

Jiri Slaby (1):
      wireless: wl12xx, fix lock imbalance

Joe Perches (1):
      MAINTAINERS: Update rtl8180 patterns

Johannes Berg (25):
      mac80211: fix sparse warning
      mac80211: driver operation debugging
      cfg80211: fix race in giwrate
      cfg80211: fix two buglets
      nl80211: introduce new key attributes
      cfg80211: rework key operation
      mac80211: fix multi-use timer
      mac80211: monitor the connection
      cfg80211: fix a locking bug
      mac80211: mesh: fix two small problems
      cfg80211: fix wext stats
      mac80211_hwsim: report fixed signal strength
      cfg80211: don't look at wdev->ssid for giwessid
      cfg80211: fix wext setting SSID
      nl80211: report BSS status
      cfg80211: fix more bugs in mlme handling
      mac80211: cancel the connection monitor timers/work
      cfg80211: fix unregistration
      iwlwifi: make some logging functions static/unexport
      wireless: remove print_mac uses
      cfg80211: don't optimise wext calls too much
      net: export __dev_addr_sync/__dev_addr_unsync
      mac80211: remove master netdev
      net: remove unused skb->do_not_encrypt
      mac80211: fix ieee80211_xmit call context

Julia Lawall (1):
      drivers/net: Drop unnecessary NULL test

Kalle Valo (3):
      wl1251: remove accidentally added wl1251_netlink.c
      wl1251: remove wl1251_plt_start/stop()
      MAINTAINERS: add wl1251 wireless driver

Larry Finger (2):
      hostap_cs: Enable shared interrupts
      p54: Eliminate unnecessary initialization

Luis Correia (1):
      rt2x00: Comment spellchecking

Luis R. Rodriguez (21):
      mac80211: drop frames for sta with no valid rate
      ath9k: downgrade assert in rc.c for invalid rate
      iwlwifi: remove rs_get_rate workaround
      ath9k: cleanup try count for MRR in rate control
      ath9k: remove unused min rate calculation code
      ath9k: remove unused stepdown when looking for the next rate
      ath9k: remove pointless wrapper ath_rc_rate_getidx()
      ath9k: rename ath_rc_get_nextlowervalid_txrate()
      ath9k: remove unused ath_rc_isvalid_txmask()
      ath9k: remove ATH9K_MODE_11B
      ath9k: remap ATH9K_MODE_*
      ath9k: rename ath_rc_ratefind_ht() to ath_rc_get_highest_rix()
      ath9k: remove unnecessary IEEE80211_TX_CTL_NO_ACK checks
      mac80211: make minstrel/pid RC use ieee80211_is_data(fc)
      iwlwifi: use ieee80211_is_data(fc)
      mac80211: add helper for management / no-ack frame rate decision
      ath9k: remove rate control wraper
      ath9k: disable radio when all devices are marked idle
      cfg80211: treat ieee80211_regdom hints as user hints
      ath9k: do not stop the queues in driver stop
      adm8211: remove uneeded code during suspend/resume

Marcin Slusarz (1):
      wireless: fix supported cards for rtl8187

Pavel Roskin (1):
      ath5k: fix values for bus error bits in ISR2

Reinette Chatre (7):
      iwlwifi: fix permissions on debugfs files
      iwl3945: cleanup number of queues settings
      iwlagn: fix minimum number of queues setting
      iwlagn: do not send key clear commands when rfkill enabled
      iwlwifi: make debug level more user friendly
      iwlwifi: clarify hardware error message
      iwlwifi: inform user about rfkill state changes

Roel Kluin (1):
      arlan: inverted logic?

Samuel Ortiz (1):
      iwmc3200wifi: cfg80211 managed mode port

Senthil Balasubramanian (3):
      ath9k: Manipulate and report the correct RSSI
      ath9k: RX stucks during heavy traffic in HT40 mode.
      ath9k: Fix TX hang issue with Atheros chipsets

Stefan Steuerwald (1):
      rt2x00: Implement set_tim callback for all drivers

Stefan Weil (1):
      wl12xx: fix spelling

Vasanthakumar Thiagarajan (7):
      ath9k: Remove dead code in rate control
      ath9k: Remove unused members from rate control structure
      ath9k: Use probe interval instead of rssi reduce interval
      ath9k: Nuke struct ath_tx_ratectrl_state
      ath9k: Remove bogus assert in ath_clone_txbuf()
      ath9k: Handle tx desc shortage more appropriately
      ath9k: Remove pointless ath9k_ps_restore() in ath_detach()

Vivek Natarajan (1):
      ath9k: Add AR9287 based chipsets' register information.

Wey-Yi Guy (9):
      iwlwifi: move show_qos to debugfs
      iwlagn: modify digital SVR for 1000
      iwlwifi: fix rx signal quality reporting in dmesg
      iwlwifi: make led functions generic
      iwlwifi: add led debugfs function
      iwlwifi: Led blinking counting both tx and rx
      iwlwifi: checking unknown HW type
      iwlwifi: uCode Alive notification with timeout
      iwlwifi: change iwl_enable/disable_interrupts to "inline"

Zhu Yi (15):
      cfg80211: fix NULL dereference in IBSS SIOCGIWAP
      iwmc3200wifi: fix UMAC INIT_COMPLETE notification handling
      iwmc3200wifi: hardware does not support IP checksum
      iwmc3200wifi: set cipher_suites before registering wiphy
      iwmc3200wifi: use correct debug level
      iwmc3200wifi: remove setting WEP keys before setting essid support
      iwmc3200wifi: make iwm_send_wifi_if_cmd return 0 on success
      iwmc3200wifi: remove key caches in driver
      cfg80211: remove WARN_ON in __cfg80211_sme_scan_done
      cfg80211: set_default_key only for WEP
      cfg80211: fix typo of IWEVASSOCRESPIE
      iwmc3200wifi: use cfg80211_connect_result to send req/resp IE
      iwmc3200wifi: fix cfg80211_connect_result is called in IBSS
      iwmc3200wifi: fix a use-after-free bug
      cfg80211: avoid setting default_key if add_key fails

 MAINTAINERS                                  |   11 +-
 drivers/net/wireless/Kconfig                 |    6 +-
 drivers/net/wireless/adm8211.c               |   17 -
 drivers/net/wireless/arlan-main.c            |    2 +-
 drivers/net/wireless/ath/ar9170/ar9170.h     |   52 ++
 drivers/net/wireless/ath/ar9170/main.c       |  609 ++++++++++++++++++++++-
 drivers/net/wireless/ath/ath5k/reg.h         |   12 +-
 drivers/net/wireless/ath/ath9k/ath9k.h       |   48 +-
 drivers/net/wireless/ath/ath9k/calib.c       |   13 +-
 drivers/net/wireless/ath/ath9k/calib.h       |    4 +-
 drivers/net/wireless/ath/ath9k/eeprom.c      |   20 +-
 drivers/net/wireless/ath/ath9k/hw.c          |   70 +++-
 drivers/net/wireless/ath/ath9k/hw.h          |   18 +-
 drivers/net/wireless/ath/ath9k/initvals.h    |   47 +-
 drivers/net/wireless/ath/ath9k/mac.c         |   30 +-
 drivers/net/wireless/ath/ath9k/main.c        |   35 ++-
 drivers/net/wireless/ath/ath9k/rc.c          |  609 ++++++++----------------
 drivers/net/wireless/ath/ath9k/rc.h          |   29 +-
 drivers/net/wireless/ath/ath9k/recv.c        |   25 +-
 drivers/net/wireless/ath/ath9k/reg.h         |   93 ++++
 drivers/net/wireless/ath/ath9k/virtual.c     |   17 +
 drivers/net/wireless/ath/ath9k/xmit.c        |   76 +++-
 drivers/net/wireless/b43/main.c              |    4 +-
 drivers/net/wireless/hostap/hostap_cs.c      |    3 +-
 drivers/net/wireless/ipw2x00/ipw2200.c       |    3 -
 drivers/net/wireless/iwlwifi/iwl-1000.c      |    2 +-
 drivers/net/wireless/iwlwifi/iwl-3945-hw.h   |    7 +-
 drivers/net/wireless/iwlwifi/iwl-3945-rs.c   |   24 +-
 drivers/net/wireless/iwlwifi/iwl-3945.c      |   52 ++-
 drivers/net/wireless/iwlwifi/iwl-3945.h      |    3 -
 drivers/net/wireless/iwlwifi/iwl-4965.c      |   67 +++-
 drivers/net/wireless/iwlwifi/iwl-5000.c      |   60 +++-
 drivers/net/wireless/iwlwifi/iwl-6000.c      |    5 +-
 drivers/net/wireless/iwlwifi/iwl-agn-rs.c    |   16 +-
 drivers/net/wireless/iwlwifi/iwl-agn.c       |  165 ++++---
 drivers/net/wireless/iwlwifi/iwl-core.c      |  424 ++++++++--------
 drivers/net/wireless/iwlwifi/iwl-core.h      |   18 +-
 drivers/net/wireless/iwlwifi/iwl-debug.h     |   16 +-
 drivers/net/wireless/iwlwifi/iwl-debugfs.c   |   69 +++-
 drivers/net/wireless/iwlwifi/iwl-dev.h       |   40 ++-
 drivers/net/wireless/iwlwifi/iwl-eeprom.c    |    6 +-
 drivers/net/wireless/iwlwifi/iwl-helpers.h   |   21 +
 drivers/net/wireless/iwlwifi/iwl-led.c       |   34 +-
 drivers/net/wireless/iwlwifi/iwl-prph.h      |    5 +-
 drivers/net/wireless/iwlwifi/iwl-rx.c        |    8 +-
 drivers/net/wireless/iwlwifi/iwl-sta.c       |   19 +-
 drivers/net/wireless/iwlwifi/iwl-tx.c        |    6 +-
 drivers/net/wireless/iwlwifi/iwl3945-base.c  |   89 ++--
 drivers/net/wireless/iwmc3200wifi/cfg80211.c |  270 ++++++++---
 drivers/net/wireless/iwmc3200wifi/commands.c |   52 +--
 drivers/net/wireless/iwmc3200wifi/hal.c      |   16 +-
 drivers/net/wireless/iwmc3200wifi/iwm.h      |    5 +
 drivers/net/wireless/iwmc3200wifi/main.c     |    7 +
 drivers/net/wireless/iwmc3200wifi/rx.c       |   96 +++--
 drivers/net/wireless/iwmc3200wifi/umac.h     |    6 +
 drivers/net/wireless/iwmc3200wifi/wext.c     |  320 ++-----------
 drivers/net/wireless/libertas/assoc.c        |   10 +-
 drivers/net/wireless/mac80211_hwsim.c        |    8 +-
 drivers/net/wireless/mwl8k.c                 |    6 +-
 drivers/net/wireless/p54/eeprom.c            |  327 ++++++++++---
 drivers/net/wireless/p54/fwio.c              |   23 +-
 drivers/net/wireless/p54/lmac.h              |    7 +
 drivers/net/wireless/p54/main.c              |  112 +++--
 drivers/net/wireless/p54/p54.h               |    3 +
 drivers/net/wireless/p54/txrx.c              |   80 +++-
 drivers/net/wireless/rt2x00/rt2400pci.c      |    1 +
 drivers/net/wireless/rt2x00/rt2400pci.h      |    2 +-
 drivers/net/wireless/rt2x00/rt2500pci.c      |    1 +
 drivers/net/wireless/rt2x00/rt2500pci.h      |    2 +-
 drivers/net/wireless/rt2x00/rt2500usb.c      |    1 +
 drivers/net/wireless/rt2x00/rt2500usb.h      |    2 +-
 drivers/net/wireless/rt2x00/rt2800usb.c      |    9 +-
 drivers/net/wireless/rt2x00/rt2800usb.h      |    2 +-
 drivers/net/wireless/rt2x00/rt2x00.h         |    7 +-
 drivers/net/wireless/rt2x00/rt2x00config.c   |    2 +-
 drivers/net/wireless/rt2x00/rt2x00crypto.c   |    2 +-
 drivers/net/wireless/rt2x00/rt2x00dev.c      |    3 +-
 drivers/net/wireless/rt2x00/rt2x00link.c     |    2 +-
 drivers/net/wireless/rt2x00/rt2x00mac.c      |   14 +-
 drivers/net/wireless/rt2x00/rt2x00queue.h    |   10 +-
 drivers/net/wireless/rt2x00/rt2x00reg.h      |    4 +-
 drivers/net/wireless/rt2x00/rt61pci.c        |    3 +-
 drivers/net/wireless/rt2x00/rt61pci.h        |    2 +-
 drivers/net/wireless/rt2x00/rt73usb.c        |    1 +
 drivers/net/wireless/rt2x00/rt73usb.h        |    4 +-
 drivers/net/wireless/wl12xx/wl1251_acx.c     |    4 +-
 drivers/net/wireless/wl12xx/wl1251_main.c    |   61 +---
 drivers/net/wireless/wl12xx/wl1251_netlink.c |  679 --------------------------
 drivers/net/wireless/wl12xx/wl1251_ops.c     |    4 +-
 drivers/net/wireless/wl12xx/wl1251_rx.h      |    2 +-
 drivers/net/wireless/zd1211rw/zd_usb.c       |    1 +
 include/linux/nl80211.h                      |   52 ++
 include/linux/skbuff.h                       |    6 +-
 include/net/cfg80211.h                       |   20 +-
 include/net/mac80211.h                       |   37 ++
 net/core/dev.c                               |    2 +
 net/core/skbuff.c                            |    3 -
 net/mac80211/Kconfig                         |   12 +
 net/mac80211/Makefile                        |    3 +
 net/mac80211/agg-tx.c                        |    3 -
 net/mac80211/cfg.c                           |    2 +-
 net/mac80211/debugfs.c                       |    2 +-
 net/mac80211/driver-ops.h                    |   85 +++-
 net/mac80211/driver-trace.c                  |    6 +
 net/mac80211/driver-trace.h                  |  648 ++++++++++++++++++++++++
 net/mac80211/ibss.c                          |    9 +-
 net/mac80211/ieee80211_i.h                   |   47 +-
 net/mac80211/iface.c                         |   51 +-
 net/mac80211/main.c                          |  120 +-----
 net/mac80211/mesh.c                          |    5 +-
 net/mac80211/mesh_hwmp.c                     |    9 +-
 net/mac80211/mesh_pathtbl.c                  |   26 +-
 net/mac80211/mlme.c                          |  308 ++++++++++---
 net/mac80211/rate.c                          |   31 ++-
 net/mac80211/rc80211_minstrel.c              |   23 +-
 net/mac80211/rc80211_pid_algo.c              |   12 +-
 net/mac80211/rx.c                            |   55 ++-
 net/mac80211/scan.c                          |   19 +-
 net/mac80211/tx.c                            |  323 ++++++-------
 net/mac80211/util.c                          |   68 +--
 net/mac80211/wep.c                           |    6 +-
 net/mac80211/wep.h                           |    3 +
 net/mac80211/wme.c                           |    6 +-
 net/mac80211/wme.h                           |    3 +-
 net/wireless/core.c                          |   21 +-
 net/wireless/core.h                          |   32 +-
 net/wireless/ibss.c                          |   84 +++-
 net/wireless/mlme.c                          |   24 +-
 net/wireless/nl80211.c                       |  428 +++++++++++++---
 net/wireless/reg.c                           |   25 +-
 net/wireless/sme.c                           |  112 +++--
 net/wireless/util.c                          |   45 ++-
 net/wireless/wext-compat.c                   |  202 +++++---
 net/wireless/wext-sme.c                      |   76 ++--
 134 files changed, 4999 insertions(+), 3237 deletions(-)
 delete mode 100644 drivers/net/wireless/wl12xx/wl1251_netlink.c
 create mode 100644 net/mac80211/driver-trace.c
 create mode 100644 net/mac80211/driver-trace.h

Omnibus patch available here:

	http://www.kernel.org/pub/linux/kernel/people/linville/wireless-next-2.6-2009-07-24.patch.bz2

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

^ permalink raw reply

* Re: [PATCH 3/6] ath9k: Add debug counters for TX
From: John W. Linville @ 2009-07-24 18:35 UTC (permalink / raw)
  To: Sujith; +Cc: linux-wireless
In-Reply-To: <19048.13623.675052.94639@localhost.localdomain>

On Thu, Jul 23, 2009 at 03:32:31PM +0530, Sujith wrote:
> Location: ath9k/phy#/xmit
> 
> Signed-off-by: Sujith <Sujith.Manoharan@atheros.com>

Eeek!

  CC [M]  drivers/net/wireless/ath/ath9k/hw.o
In file included from drivers/net/wireless/ath/ath9k/ath9k.h:28,
                 from drivers/net/wireless/ath/ath9k/hw.c:21:
drivers/net/wireless/ath/ath9k/debug.h:201: warning: ‘struct ath_buf’ declared inside parameter list
drivers/net/wireless/ath/ath9k/debug.h:201: warning: its scope is only this definition or declaration, which is probably not what you want
drivers/net/wireless/ath/ath9k/debug.h:201: warning: ‘struct ath_txq’ declared inside parameter list
  CC [M]  drivers/net/wireless/ath/ath9k/eeprom.o
In file included from drivers/net/wireless/ath/ath9k/ath9k.h:28,
                 from drivers/net/wireless/ath/ath9k/eeprom.c:18:
drivers/net/wireless/ath/ath9k/debug.h:201: warning: ‘struct ath_buf’ declared inside parameter list
drivers/net/wireless/ath/ath9k/debug.h:201: warning: its scope is only this definition or declaration, which is probably not what you want
drivers/net/wireless/ath/ath9k/debug.h:201: warning: ‘struct ath_txq’ declared inside parameter list
  CC [M]  drivers/net/wireless/ath/ath9k/mac.o
In file included from drivers/net/wireless/ath/ath9k/ath9k.h:28,
                 from drivers/net/wireless/ath/ath9k/mac.c:18:
drivers/net/wireless/ath/ath9k/debug.h:201: warning: ‘struct ath_buf’ declared inside parameter list
drivers/net/wireless/ath/ath9k/debug.h:201: warning: its scope is only this definition or declaration, which is probably not what you want
drivers/net/wireless/ath/ath9k/debug.h:201: warning: ‘struct ath_txq’ declared inside parameter list
  CC [M]  drivers/net/wireless/ath/ath9k/calib.o
In file included from drivers/net/wireless/ath/ath9k/ath9k.h:28,
                 from drivers/net/wireless/ath/ath9k/calib.c:18:
drivers/net/wireless/ath/ath9k/debug.h:201: warning: ‘struct ath_buf’ declared inside parameter list
drivers/net/wireless/ath/ath9k/debug.h:201: warning: its scope is only this definition or declaration, which is probably not what you want
drivers/net/wireless/ath/ath9k/debug.h:201: warning: ‘struct ath_txq’ declared inside parameter list
  CC [M]  drivers/net/wireless/ath/ath9k/ani.o
In file included from drivers/net/wireless/ath/ath9k/ath9k.h:28,
                 from drivers/net/wireless/ath/ath9k/ani.c:18:
drivers/net/wireless/ath/ath9k/debug.h:201: warning: ‘struct ath_buf’ declared inside parameter list
drivers/net/wireless/ath/ath9k/debug.h:201: warning: its scope is only this definition or declaration, which is probably not what you want
drivers/net/wireless/ath/ath9k/debug.h:201: warning: ‘struct ath_txq’ declared inside parameter list
  CC [M]  drivers/net/wireless/ath/ath9k/phy.o
In file included from drivers/net/wireless/ath/ath9k/ath9k.h:28,
                 from drivers/net/wireless/ath/ath9k/phy.c:18:
drivers/net/wireless/ath/ath9k/debug.h:201: warning: ‘struct ath_buf’ declared inside parameter list
drivers/net/wireless/ath/ath9k/debug.h:201: warning: its scope is only this definition or declaration, which is probably not what you want
drivers/net/wireless/ath/ath9k/debug.h:201: warning: ‘struct ath_txq’ declared inside parameter list
  CC [M]  drivers/net/wireless/ath/ath9k/beacon.o
In file included from drivers/net/wireless/ath/ath9k/ath9k.h:28,
                 from drivers/net/wireless/ath/ath9k/beacon.c:18:
drivers/net/wireless/ath/ath9k/debug.h:201: warning: ‘struct ath_buf’ declared inside parameter list
drivers/net/wireless/ath/ath9k/debug.h:201: warning: its scope is only this definition or declaration, which is probably not what you want
drivers/net/wireless/ath/ath9k/debug.h:201: warning: ‘struct ath_txq’ declared inside parameter list
  CC [M]  drivers/net/wireless/ath/ath9k/main.o
In file included from drivers/net/wireless/ath/ath9k/ath9k.h:28,
                 from drivers/net/wireless/ath/ath9k/main.c:19:
drivers/net/wireless/ath/ath9k/debug.h:201: warning: ‘struct ath_buf’ declared inside parameter list
drivers/net/wireless/ath/ath9k/debug.h:201: warning: its scope is only this definition or declaration, which is probably not what you want
drivers/net/wireless/ath/ath9k/debug.h:201: warning: ‘struct ath_txq’ declared inside parameter list
  CC [M]  drivers/net/wireless/ath/ath9k/recv.o
In file included from drivers/net/wireless/ath/ath9k/ath9k.h:28,
                 from drivers/net/wireless/ath/ath9k/recv.c:18:
drivers/net/wireless/ath/ath9k/debug.h:201: warning: ‘struct ath_buf’ declared inside parameter list
drivers/net/wireless/ath/ath9k/debug.h:201: warning: its scope is only this definition or declaration, which is probably not what you want
drivers/net/wireless/ath/ath9k/debug.h:201: warning: ‘struct ath_txq’ declared inside parameter list
  CC [M]  drivers/net/wireless/ath/ath9k/xmit.o
In file included from drivers/net/wireless/ath/ath9k/ath9k.h:28,
                 from drivers/net/wireless/ath/ath9k/xmit.c:18:
drivers/net/wireless/ath/ath9k/debug.h:201: warning: ‘struct ath_buf’ declared inside parameter list
drivers/net/wireless/ath/ath9k/debug.h:201: warning: its scope is only this definition or declaration, which is probably not what you want
drivers/net/wireless/ath/ath9k/debug.h:201: warning: ‘struct ath_txq’ declared inside parameter list
drivers/net/wireless/ath/ath9k/xmit.c: In function ‘ath_tx_complete_buf’:
drivers/net/wireless/ath/ath9k/xmit.c:1838: warning: passing argument 2 of ‘ath_debug_stat_tx’ from incompatible pointer type
drivers/net/wireless/ath/ath9k/debug.h:199: note: expected ‘struct ath_txq *’ but argument is of type ‘struct ath_txq *’
drivers/net/wireless/ath/ath9k/xmit.c:1838: warning: passing argument 3 of ‘ath_debug_stat_tx’ from incompatible pointer type
drivers/net/wireless/ath/ath9k/debug.h:199: note: expected ‘struct ath_buf *’ but argument is of type ‘struct ath_buf *’
  CC [M]  drivers/net/wireless/ath/ath9k/virtual.o
In file included from drivers/net/wireless/ath/ath9k/ath9k.h:28,
                 from drivers/net/wireless/ath/ath9k/virtual.c:18:
drivers/net/wireless/ath/ath9k/debug.h:201: warning: ‘struct ath_buf’ declared inside parameter list
drivers/net/wireless/ath/ath9k/debug.h:201: warning: its scope is only this definition or declaration, which is probably not what you want
drivers/net/wireless/ath/ath9k/debug.h:201: warning: ‘struct ath_txq’ declared inside parameter list
  CC [M]  drivers/net/wireless/ath/ath9k/rc.o
In file included from drivers/net/wireless/ath/ath9k/ath9k.h:28,
                 from drivers/net/wireless/ath/ath9k/rc.c:19:
drivers/net/wireless/ath/ath9k/debug.h:201: warning: ‘struct ath_buf’ declared inside parameter list
drivers/net/wireless/ath/ath9k/debug.h:201: warning: its scope is only this definition or declaration, which is probably not what you want
drivers/net/wireless/ath/ath9k/debug.h:201: warning: ‘struct ath_txq’ declared inside parameter list
  CC [M]  drivers/net/wireless/ath/ath9k/pci.o
In file included from drivers/net/wireless/ath/ath9k/ath9k.h:28,
                 from drivers/net/wireless/ath/ath9k/pci.c:20:
drivers/net/wireless/ath/ath9k/debug.h:201: warning: ‘struct ath_buf’ declared inside parameter list
drivers/net/wireless/ath/ath9k/debug.h:201: warning: its scope is only this definition or declaration, which is probably not what you want
drivers/net/wireless/ath/ath9k/debug.h:201: warning: ‘struct ath_txq’ declared inside parameter list

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

^ permalink raw reply

* new lockdep warning in 2.6.31-rc3-wl
From: reinette chatre @ 2009-07-24 18:45 UTC (permalink / raw)
  To: linux-wireless; +Cc: Luis R. Rodriguez

I saw this right after association. This is with the latest
wireless-testing.

[   65.053475] =======================================================
[   65.053562] [ INFO: possible circular locking dependency detected ]
[   65.053608] 2.6.31-rc3-wl #13
[   65.053649] -------------------------------------------------------
[   65.053694] phy0/3223 is trying to acquire lock:
[   65.053738]  (cfg80211_mutex){+.+.+.}, at: [<ffffffffa01c9a72>] regulatory_hint_11d+0x32/0x430 [cfg80211]
[   65.053887] 
[   65.053888] but task is already holding lock:
[   65.053968]  (&ifmgd->mtx){+.+.+.}, at: [<ffffffffa0220f78>] ieee80211_sta_work+0x118/0x11c0 [mac80211]
[   65.054120] 
[   65.054120] which lock already depends on the new lock.
[   65.054121] 
[   65.054239] 
[   65.054240] the existing dependency chain (in reverse order) is:
[   65.054322] 
[   65.054323] -> #3 (&ifmgd->mtx){+.+.+.}:
[   65.054483]        [<ffffffff8106f994>] __lock_acquire+0x1164/0x1b50
[   65.054558]        [<ffffffff81070453>] lock_acquire+0xd3/0x100
[   65.054630]        [<ffffffff81323e65>] mutex_lock_nested+0x45/0x320
[   65.054705]        [<ffffffffa021ed35>] ieee80211_mgd_auth+0xf5/0x1f0 [mac80211]
[   65.054798]        [<ffffffffa0225623>] ieee80211_auth+0x13/0x20 [mac80211]
[   65.054880]        [<ffffffffa01d5ac1>] __cfg80211_mlme_auth+0x1b1/0x290 [cfg80211]
[   65.054971]        [<ffffffffa01d7d6b>] cfg80211_conn_do_work+0xdb/0x1b0 [cfg80211]
[   65.055061]        [<ffffffffa01d8217>] __cfg80211_connect+0x3d7/0x4c0 [cfg80211]
[   65.055150]        [<ffffffffa01db9ed>] cfg80211_mgd_wext_connect+0xcd/0x180 [cfg80211]
[   65.055240]        [<ffffffffa01dbc2f>] cfg80211_mgd_wext_siwap+0x18f/0x210 [cfg80211]
[   65.055329]        [<ffffffffa021698c>] ieee80211_ioctl_siwap+0x1c/0x70 [mac80211]
[   65.055421]        [<ffffffff8130ebc3>] ioctl_standard_call+0x63/0x460
[   65.055495]        [<ffffffff8130e7bb>] wext_handle_ioctl+0x16b/0x240
[   65.055568]        [<ffffffff8128cd02>] dev_ioctl+0x3f2/0x5f0
[   65.055642]        [<ffffffff81277059>] sock_ioctl+0x89/0x290
[   65.055715]        [<ffffffff810fe201>] vfs_ioctl+0x31/0xa0
[   65.055787]        [<ffffffff810fe38a>] do_vfs_ioctl+0x8a/0x5c0
[   65.055859]        [<ffffffff810fe959>] sys_ioctl+0x99/0xa0
[   65.055931]        [<ffffffff8100bd6b>] system_call_fastpath+0x16/0x1b
[   65.056006]        [<ffffffffffffffff>] 0xffffffffffffffff
[   65.056080] 
[   65.056080] -> #2 (&wdev->mtx){+.+.+.}:
[   65.056240]        [<ffffffff8106f994>] __lock_acquire+0x1164/0x1b50
[   65.056314]        [<ffffffff81070453>] lock_acquire+0xd3/0x100
[   65.056386]        [<ffffffff81323e65>] mutex_lock_nested+0x45/0x320
[   65.056459]        [<ffffffffa01c5224>] cfg80211_netdev_notifier_call+0x1a4/0x380 [cfg80211]
[   65.056550]        [<ffffffff81328855>] notifier_call_chain+0x65/0xa0
[   65.056623]        [<ffffffff810605f1>] raw_notifier_call_chain+0x11/0x20
[   65.056697]        [<ffffffff8128bbea>] dev_open+0x10a/0x120
[   65.056769]        [<ffffffff8128af4d>] dev_change_flags+0x9d/0x1e0
[   65.056842]        [<ffffffff81294bb3>] do_setlink+0x2b3/0x450
[   65.056844]        [<ffffffff81294f25>] rtnl_setlink+0x115/0x160
[   65.056844]        [<ffffffff8129605e>] rtnetlink_rcv_msg+0x18e/0x240
[   65.056844]        [<ffffffff812a8379>] netlink_rcv_skb+0x89/0xb0
[   65.056844]        [<ffffffff81295eb9>] rtnetlink_rcv+0x29/0x40
[   65.056844]        [<ffffffff812a7d12>] netlink_unicast+0x2e2/0x2f0
[   65.056844]        [<ffffffff812a7f41>] netlink_sendmsg+0x221/0x330
[   65.056844]        [<ffffffff81277f07>] sock_sendmsg+0x127/0x140
[   65.056844]        [<ffffffff81278065>] sys_sendmsg+0x145/0x280
[   65.056844]        [<ffffffff8100bd6b>] system_call_fastpath+0x16/0x1b
[   65.056844]        [<ffffffffffffffff>] 0xffffffffffffffff
[   65.056844] 
[   65.056844] -> #1 (&rdev->mtx){+.+.+.}:
[   65.056844]        [<ffffffff8106f994>] __lock_acquire+0x1164/0x1b50
[   65.056844]        [<ffffffff81070453>] lock_acquire+0xd3/0x100
[   65.056844]        [<ffffffff81323e65>] mutex_lock_nested+0x45/0x320
[   65.056844]        [<ffffffffa01c6421>] cfg80211_get_dev_from_ifindex+0x61/0xa0 [cfg80211]
[   65.056844]        [<ffffffffa01ca3c0>] cfg80211_wext_giwscan+0x50/0x1210 [cfg80211]
[   65.056844]        [<ffffffff8130ed54>] ioctl_standard_call+0x1f4/0x460
[   65.056844]        [<ffffffff8130e7bb>] wext_handle_ioctl+0x16b/0x240
[   65.056844]        [<ffffffff8128cd02>] dev_ioctl+0x3f2/0x5f0
[   65.056844]        [<ffffffff81277059>] sock_ioctl+0x89/0x290
[   65.056844]        [<ffffffff810fe201>] vfs_ioctl+0x31/0xa0
[   65.056844]        [<ffffffff810fe38a>] do_vfs_ioctl+0x8a/0x5c0
[   65.056844]        [<ffffffff810fe959>] sys_ioctl+0x99/0xa0
[   65.056844]        [<ffffffff8100bd6b>] system_call_fastpath+0x16/0x1b
[   65.056844]        [<ffffffffffffffff>] 0xffffffffffffffff
[   65.056844] 
[   65.056844] -> #0 (cfg80211_mutex){+.+.+.}:
[   65.056844]        [<ffffffff8106fae3>] __lock_acquire+0x12b3/0x1b50
[   65.056844]        [<ffffffff81070453>] lock_acquire+0xd3/0x100
[   65.056844]        [<ffffffff81323e65>] mutex_lock_nested+0x45/0x320
[   65.056844]        [<ffffffffa01c9a72>] regulatory_hint_11d+0x32/0x430 [cfg80211]
[   65.056844]        [<ffffffffa0220a8d>] ieee80211_rx_mgmt_beacon+0x2cd/0x4d0 [mac80211]
[   65.056844]        [<ffffffffa0221049>] ieee80211_sta_work+0x1e9/0x11c0 [mac80211]
[   65.056844]        [<ffffffff81055f80>] worker_thread+0x1f0/0x340
[   65.056844]        [<ffffffff8105b28e>] kthread+0x9e/0xb0
[   65.056844]        [<ffffffff8100ce7a>] child_rip+0xa/0x20
[   65.056844]        [<ffffffffffffffff>] 0xffffffffffffffff
[   65.056844] 
[   65.056844] other info that might help us debug this:
[   65.056844] 
[   65.056844] 3 locks held by phy0/3223:
[   65.056844]  #0:  ((wiphy_name(local->hw.wiphy))){+.+.+.}, at: [<ffffffff81055f2d>] worker_thread+0x19d/0x340
[   65.056844]  #1:  (&ifmgd->work){+.+.+.}, at: [<ffffffff81055f2d>] worker_thread+0x19d/0x340
[   65.056844]  #2:  (&ifmgd->mtx){+.+.+.}, at: [<ffffffffa0220f78>] ieee80211_sta_work+0x118/0x11c0 [mac80211]
[   65.056844] 
[   65.056844] stack backtrace:
[   65.056844] Pid: 3223, comm: phy0 Not tainted 2.6.31-rc3-wl #13
[   65.056844] Call Trace:
[   65.056844]  [<ffffffff8106e28c>] print_circular_bug_tail+0xdc/0xe0
[   65.056844]  [<ffffffff8106fae3>] __lock_acquire+0x12b3/0x1b50
[   65.056844]  [<ffffffff8106d5ed>] ? mark_held_locks+0x6d/0x90
[   65.056844]  [<ffffffff81070453>] lock_acquire+0xd3/0x100
[   65.056844]  [<ffffffffa01c9a72>] ? regulatory_hint_11d+0x32/0x430 [cfg80211]
[   65.056844]  [<ffffffff81323e65>] mutex_lock_nested+0x45/0x320
[   65.056844]  [<ffffffffa01c9a72>] ? regulatory_hint_11d+0x32/0x430 [cfg80211]
[   65.056844]  [<ffffffffa01cc03c>] ? cfg80211_inform_bss_frame+0x19c/0x1a0 [cfg80211]
[   65.056844]  [<ffffffffa01c9a72>] regulatory_hint_11d+0x32/0x430 [cfg80211]
[   65.056844]  [<ffffffffa021a35c>] ? ieee80211_rx_bss_put+0xc/0x10 [mac80211]
[   65.056844]  [<ffffffffa0220753>] ? ieee80211_rx_bss_info+0xb3/0x120 [mac80211]
[   65.056844]  [<ffffffffa0220a8d>] ieee80211_rx_mgmt_beacon+0x2cd/0x4d0 [mac80211]
[   65.056844]  [<ffffffffa0221049>] ieee80211_sta_work+0x1e9/0x11c0 [mac80211]
[   65.056844]  [<ffffffff810adb60>] ? probe_workqueue_execution+0x40/0xa0
[   65.056844]  [<ffffffffa0220e60>] ? ieee80211_sta_work+0x0/0x11c0 [mac80211]
[   65.056844]  [<ffffffff81055f80>] worker_thread+0x1f0/0x340
[   65.056844]  [<ffffffff81055f2d>] ? worker_thread+0x19d/0x340
[   65.056844]  [<ffffffff8105b680>] ? autoremove_wake_function+0x0/0x40
[   65.056844]  [<ffffffff8106d94d>] ? trace_hardirqs_on+0xd/0x10
[   65.056844]  [<ffffffff81055d90>] ? worker_thread+0x0/0x340
[   65.056844]  [<ffffffff8105b28e>] kthread+0x9e/0xb0
[   65.056844]  [<ffffffff8100ce7a>] child_rip+0xa/0x20
[   65.056844]  [<ffffffff8100c83c>] ? restore_args+0x0/0x30
[   65.056844]  [<ffffffff8105b1f0>] ? kthread+0x0/0xb0
[   65.056844]  [<ffffffff8100ce70>] ? child_rip+0x0/0x20




^ permalink raw reply

* Re: [PATCH] mac80211: add helper to add to the mac80211 workqueue
From: Johannes Berg @ 2009-07-24 18:15 UTC (permalink / raw)
  To: Luis R. Rodriguez
  Cc: linville, linux-wireless, ath9k-devel, Reinette Chatre,
	Dan Williams, Lennert Buytenhek, Daniel Drake
In-Reply-To: <1248458909-15338-1-git-send-email-lrodriguez@atheros.com>

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

On Fri, 2009-07-24 at 14:08 -0400, Luis R. Rodriguez wrote:
> We add a mac80211 helper for adding work onto the mac80211
> workqueue. We then add a warning if we are suspended. At that
> point drivers nor mac80211 should have queued work, drivers
> and mac80211 should ensure the workqueue will remain clair
> until resume.
> 
> We make use of the helper now in mac80211 and on all mac80211
> drivers. If you see a warning because of this patch during
> the suspend <--> resume cycle it means suspend is busted for
> your driver or mac80211 and it needs to be fixed.

Looks good to me.

johannes

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

^ permalink raw reply

* [PATCH v2.6.31] iwlwifi: fix TX queue race
From: Reinette Chatre @ 2009-07-24 18:13 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Johannes Berg, Reinette Chatre
In-Reply-To: <1248459194-10239-1-git-send-email-reinette.chatre@intel.com>

From: Johannes Berg <johannes@sipsolutions.net>

I had a problem on 4965 hardware (well, probably other hardware too,
but others don't survive my stress testing right now, unfortunately)
where the driver was sending invalid commands to the device, but no
such thing could be seen from the driver's point of view. I could
reproduce this fairly easily by sending multiple TCP streams with
iperf on different TIDs, though sometimes a single iperf stream was
sufficient. It even happened with a single core, but I have forced
preemption turned on.

The culprit was a queue overrun, where we advanced the queue's write
pointer over the read pointer. After careful analysis I've come to
the conclusion that the cause is a race condition between iwlwifi
and mac80211.

mac80211, of course, checks whether the queue is stopped, before
transmitting a frame. This effectively looks like this:

        lock(queues)
        if (stopped(queue)) {
                unlock(queues)
                return busy;
	}
        unlock(queues)
        ...             <-- this place will be important
			    there is some more code here
        drv_tx(frame)

The driver, on the other hand, can stop and start queues, which does

        lock(queues)
        mark_running/stopped(queue)
        unlock(queues)

	[if marked running: wake up tasklet to send pending frames]

Now, however, once the driver starts the queue, mac80211 can see that
and end up at the marked place above, at which point for some reason the
driver seems to stop the queue again (I don't understand that) and then
we end up transmitting while the queue is actually full.

Now, this shouldn't actually matter much, but for some reason I've seen
it happen multiple times in a row and the queue actually overflows, at
which point the queue bites itself in the tail and things go completely
wrong.

This patch fixes this by just dropping the packet should this have
happened, and making the lock in iwlwifi cover everything so iwlwifi
can't race against itself (dropping the lock there might make it more
likely, but it did seem to happen without that too).

Since we can't hold the lock across drv_tx() above, I see no way to fix
this in mac80211, but I also don't understand why I haven't seen this
before -- maybe I just never stress tested it this badly.

With this patch, the device has survived many minutes of simultanously
sending two iperf streams on different TIDs with combined throughput
of about 60 Mbps.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-tx.c |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 85ae7a6..82a5f62 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -720,8 +720,6 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
 		goto drop_unlock;
 	}
 
-	spin_unlock_irqrestore(&priv->lock, flags);
-
 	hdr_len = ieee80211_hdrlen(fc);
 
 	/* Find (or create) index into station table for destination station */
@@ -729,7 +727,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
 	if (sta_id == IWL_INVALID_STATION) {
 		IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
 			       hdr->addr1);
-		goto drop;
+		goto drop_unlock;
 	}
 
 	IWL_DEBUG_TX(priv, "station Id %d\n", sta_id);
@@ -750,14 +748,17 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
 			txq_id = priv->stations[sta_id].tid[tid].agg.txq_id;
 			swq_id = iwl_virtual_agg_queue_num(swq_id, txq_id);
 		}
-		priv->stations[sta_id].tid[tid].tfds_in_queue++;
 	}
 
 	txq = &priv->txq[txq_id];
 	q = &txq->q;
 	txq->swq_id = swq_id;
 
-	spin_lock_irqsave(&priv->lock, flags);
+	if (unlikely(iwl_queue_space(q) < q->high_mark))
+		goto drop_unlock;
+
+	if (ieee80211_is_data_qos(fc))
+		priv->stations[sta_id].tid[tid].tfds_in_queue++;
 
 	/* Set up driver data for this TFD */
 	memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info));
@@ -901,7 +902,6 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
 
 drop_unlock:
 	spin_unlock_irqrestore(&priv->lock, flags);
-drop:
 	return -1;
 }
 EXPORT_SYMBOL(iwl_tx_skb);
-- 
1.5.6.3


^ permalink raw reply related

* [PATCH 11/14] iwlwifi: fix LED config option
From: Reinette Chatre @ 2009-07-24 18:13 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Pavel Machek, Reinette Chatre
In-Reply-To: <1248459194-10239-1-git-send-email-reinette.chatre@intel.com>

From: Pavel Machek <pavel@ucw.cz>

IWLWIFI_LEDS option should certainly have help comment, and should
default to y.

Signed-off-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
 drivers/net/wireless/iwlwifi/Kconfig |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index e092af0..99310c0 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -9,6 +9,9 @@ config IWLWIFI
 config IWLWIFI_LEDS
 	bool "Enable LED support in iwlagn and iwl3945 drivers"
 	depends on IWLWIFI
+	default y
+	---help---
+	  Select this if you want LED support.
 
 config IWLWIFI_SPECTRUM_MEASUREMENT
 	bool "Enable Spectrum Measurement in iwlagn driver"
-- 
1.5.6.3


^ permalink raw reply related

* [PATCH 14/14] iwlagn: fix sparse warning when compiling without debug
From: Reinette Chatre @ 2009-07-24 18:13 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Reinette Chatre
In-Reply-To: <1248459194-10239-1-git-send-email-reinette.chatre@intel.com>

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1167 bytes --]

From: Reinette Chatre <reinette.chatre@intel.com>

C [M]  drivers/net/wireless/iwlwifi/iwl-core.o
drivers/net/wireless/iwlwifi/iwl-core.c:1341: warning:
‘iwl_dump_nic_error_log’ defined but not used

Reported-by: Luis R. Rodriguez <lrodriguez@atheros.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-core.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index edfdbe8..b6db955 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -1295,7 +1295,6 @@ static void iwl_print_rx_config_cmd(struct iwl_priv *priv)
 	IWL_DEBUG_RADIO(priv, "u8[6] bssid_addr: %pM\n", rxon->bssid_addr);
 	IWL_DEBUG_RADIO(priv, "u16 assoc_id: 0x%x\n", le16_to_cpu(rxon->assoc_id));
 }
-#endif
 
 static const char *desc_lookup_text[] = {
 	"OK",
@@ -1500,6 +1499,7 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv)
 	iwl_print_event_log(priv, 0, next_entry, mode);
 
 }
+#endif
 /**
  * iwl_irq_handle_error - called for HW or SW error interrupt from card
  */
-- 
1.5.6.3


^ permalink raw reply related

* [PATCH 10/14] iwlwifi: Name fix for MPDU density for TX aggregation
From: Reinette Chatre @ 2009-07-24 18:13 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Wey-Yi Guy, Reinette Chatre
In-Reply-To: <1248459194-10239-1-git-send-email-reinette.chatre@intel.com>

From: Wey-Yi Guy <wey-yi.w.guy@intel.com>

Fix incorrect name for HT MPDU Density.
default set to 4 uSec

Reported-by: Sujith <Sujith.Manoharan@atheros.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-dev.h |   12 ++++++++++--
 1 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 3ca188a..facbc3d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -491,8 +491,16 @@ union iwl_ht_rate_supp {
 };
 
 #define CFG_HT_RX_AMPDU_FACTOR_DEF  (0x3)
-#define CFG_HT_MPDU_DENSITY_2USEC   (0x5)
-#define CFG_HT_MPDU_DENSITY_DEF CFG_HT_MPDU_DENSITY_2USEC
+
+/*
+ * Maximal MPDU density for TX aggregation
+ * 4 - 2us density
+ * 5 - 4us density
+ * 6 - 8us density
+ * 7 - 16us density
+ */
+#define CFG_HT_MPDU_DENSITY_4USEC   (0x5)
+#define CFG_HT_MPDU_DENSITY_DEF CFG_HT_MPDU_DENSITY_4USEC
 
 struct iwl_ht_info {
 	/* self configuration data */
-- 
1.5.6.3


^ permalink raw reply related


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