Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH 2/3] carl9170: reduce channel change delay
From: Christian Lamparter @ 2010-12-26 17:22 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville, Felix

By removing two "safety" msleeps (and an echo nop), the
channel change delay is effectively halved. Previously,
the delay could be as long as 260 ms and the device
could not go off-channel without risking to miss the
next DTIM beacon [interval ~307 ms].

Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
---
Hi Felix,

It seems that removing the msleeps doesn't have ANY negative effect
on the operation. Furthermore ath9k doesn't need the 20ms+ msleeps
in the phy codepaths either. So, I wonder if this is just some old
"safety" buffers which survived otus and ar9170usb development
phases, or is there some merit to them?

Regards,
	Chr
---
 drivers/net/wireless/ath/carl9170/phy.c |    8 --------
 1 files changed, 0 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/ath/carl9170/phy.c b/drivers/net/wireless/ath/carl9170/phy.c
index 122e75e..b6b0de6 100644
--- a/drivers/net/wireless/ath/carl9170/phy.c
+++ b/drivers/net/wireless/ath/carl9170/phy.c
@@ -1029,8 +1029,6 @@ static int carl9170_init_rf_bank4_pwr(struct ar9170 *ar, bool band5ghz,
 	if (err)
 		return err;
 
-	msleep(20);
-
 	return 0;
 }
 
@@ -1660,12 +1658,6 @@ int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
 			return err;
 
 		cmd = CARL9170_CMD_RF_INIT;
-
-		msleep(100);
-
-		err = carl9170_echo_test(ar, 0xaabbccdd);
-		if (err)
-			return err;
 	} else {
 		cmd = CARL9170_CMD_FREQUENCY;
 	}
-- 
1.7.2.3


^ permalink raw reply related

* [PATCH 1/3] carl9170: add missing return-value check
From: Christian Lamparter @ 2010-12-26 17:21 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville

This patch adds a forgotten bail-out path.

Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
---
 drivers/net/wireless/ath/carl9170/phy.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/carl9170/phy.c b/drivers/net/wireless/ath/carl9170/phy.c
index 82bc81c..122e75e 100644
--- a/drivers/net/wireless/ath/carl9170/phy.c
+++ b/drivers/net/wireless/ath/carl9170/phy.c
@@ -1676,6 +1676,8 @@ int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
 
 	err = carl9170_write_reg(ar, AR9170_PHY_REG_HEAVY_CLIP_ENABLE,
 				 0x200);
+	if (err)
+		return err;
 
 	err = carl9170_init_rf_bank4_pwr(ar,
 		channel->band == IEEE80211_BAND_5GHZ,
-- 
1.7.2.3


^ permalink raw reply related

* [RFC] mac80211: ignore PSM bit of reordered frames
From: Christian Lamparter @ 2010-12-26 19:56 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg

This patch tackles one of the problems of my
reorder release timer patch from August.

<http://www.spinics.net/lists/linux-wireless/msg57214.html>
=>
What if the reorder release triggers and ap_sta_ps_end
(called by ieee80211_rx_h_sta_process) accidentally clears
the WLAN_STA_PS_STA flag, because 100ms ago - when the STA
was still active - frames were put into the reorder buffer.

Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
---
Alternatively, we could flush the per-tid STA reorder buffer
content in ap_sta_ps_start, so the buffer is empty.

---
 net/mac80211/ieee80211_i.h |    2 ++
 net/mac80211/rx.c          |    4 ++++
 2 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index a0cf5ab..bb71fe3 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -168,6 +168,7 @@ typedef unsigned __bitwise__ ieee80211_rx_result;
  * @IEEE80211_RX_FRAGMENTED: fragmented frame
  * @IEEE80211_RX_AMSDU: a-MSDU packet
  * @IEEE80211_RX_MALFORMED_ACTION_FRM: action frame is malformed
+ * @IEEE80211_RX_DEFERED_RELEASE: frame was subjected to receive reordering
  *
  * These are per-frame flags that are attached to a frame in the
  * @rx_flags field of &struct ieee80211_rx_status.
@@ -178,6 +179,7 @@ enum ieee80211_packet_rx_flags {
 	IEEE80211_RX_FRAGMENTED			= BIT(2),
 	IEEE80211_RX_AMSDU			= BIT(3),
 	IEEE80211_RX_MALFORMED_ACTION_FRM	= BIT(4),
+	IEEE80211_RX_DEFERED_RELEASE		= BIT(5),
 };
 
 /**
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index b6c2a30..e612805 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -537,6 +537,7 @@ static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw,
 					    struct sk_buff_head *frames)
 {
 	struct sk_buff *skb = tid_agg_rx->reorder_buf[index];
+	struct ieee80211_rx_status *status;
 
 	lockdep_assert_held(&tid_agg_rx->reorder_lock);
 
@@ -546,6 +547,8 @@ static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw,
 	/* release the frame from the reorder ring buffer */
 	tid_agg_rx->stored_mpdu_num--;
 	tid_agg_rx->reorder_buf[index] = NULL;
+	status = IEEE80211_SKB_RXCB(skb);
+	status->rx_flags |= IEEE80211_RX_DEFERED_RELEASE;
 	__skb_queue_tail(frames, skb);
 
 no_frame:
@@ -1185,6 +1188,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
 	 * exchange sequence.
 	 */
 	if (!ieee80211_has_morefrags(hdr->frame_control) &&
+	    !(status->rx_flags & IEEE80211_RX_DEFERED_RELEASE) &&
 	    (rx->sdata->vif.type == NL80211_IFTYPE_AP ||
 	     rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) {
 		if (test_sta_flags(sta, WLAN_STA_PS_STA)) {
-- 
1.7.2.3


^ permalink raw reply related

* [PATCH 3/3] carl9170: fix usb pm suspend->resume woes
From: Christian Lamparter @ 2010-12-26 17:22 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville, angus_rt

This patch revamps some common code-paths which are
shared between (re-)initialization and suspend/resume
subroutines. It also adds some helpful comments
about quirks and associated difficulties.

It's quite big, but it should fix #25382:
<https://bugzilla.kernel.org/show_bug.cgi?id=25382>

And hopefully the code is robust enough to deal with
all possible suspend/resume scenarios without requiring
the user to do any sort of manual and possibly
dangerous work.

Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
---
 drivers/net/wireless/ath/carl9170/usb.c |   53 +++++++++++++++++++++---------
 1 files changed, 37 insertions(+), 16 deletions(-)

diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c
index 2d947a3..537732e 100644
--- a/drivers/net/wireless/ath/carl9170/usb.c
+++ b/drivers/net/wireless/ath/carl9170/usb.c
@@ -834,7 +834,7 @@ static int carl9170_usb_load_firmware(struct ar9170 *ar)
 	if (err)
 		goto err_out;
 
-	/* firmware restarts cmd counter */
+	/* now, start the command response counter */
 	ar->cmd_seq = -1;
 
 	return 0;
@@ -851,7 +851,12 @@ int carl9170_usb_restart(struct ar9170 *ar)
 	if (ar->intf->condition != USB_INTERFACE_BOUND)
 		return 0;
 
-	/* Disable command response sequence counter. */
+	/*
+	 * Disable the command response sequence counter check.
+	 * We already know that the device/firmware is in a bad state.
+	 * So, no extra points are awarded to anyone who reminds the
+	 * driver about that.
+	 */
 	ar->cmd_seq = -2;
 
 	err = carl9170_reboot(ar);
@@ -903,6 +908,15 @@ static int carl9170_usb_init_device(struct ar9170 *ar)
 {
 	int err;
 
+	/*
+	 * The carl9170 firmware let's the driver know when it's
+	 * ready for action. But we have to be prepared to gracefully
+	 * handle all spurious [flushed] messages after each (re-)boot.
+	 * Thus the command response counter remains disabled until it
+	 * can be safely synchronized.
+	 */
+	ar->cmd_seq = -2;
+
 	err = carl9170_usb_send_rx_irq_urb(ar);
 	if (err)
 		goto err_out;
@@ -911,14 +925,21 @@ static int carl9170_usb_init_device(struct ar9170 *ar)
 	if (err)
 		goto err_unrx;
 
+	err = carl9170_usb_open(ar);
+	if (err)
+		goto err_unrx;
+
 	mutex_lock(&ar->mutex);
 	err = carl9170_usb_load_firmware(ar);
 	mutex_unlock(&ar->mutex);
 	if (err)
-		goto err_unrx;
+		goto err_stop;
 
 	return 0;
 
+err_stop:
+	carl9170_usb_stop(ar);
+
 err_unrx:
 	carl9170_usb_cancel_urbs(ar);
 
@@ -964,10 +985,6 @@ static void carl9170_usb_firmware_finish(struct ar9170 *ar)
 	if (err)
 		goto err_freefw;
 
-	err = carl9170_usb_open(ar);
-	if (err)
-		goto err_unrx;
-
 	err = carl9170_register(ar);
 
 	carl9170_usb_stop(ar);
@@ -1043,7 +1060,6 @@ static int carl9170_usb_probe(struct usb_interface *intf,
 	atomic_set(&ar->rx_work_urbs, 0);
 	atomic_set(&ar->rx_anch_urbs, 0);
 	atomic_set(&ar->rx_pool_urbs, 0);
-	ar->cmd_seq = -2;
 
 	usb_get_dev(ar->udev);
 
@@ -1090,10 +1106,6 @@ static int carl9170_usb_suspend(struct usb_interface *intf,
 
 	carl9170_usb_cancel_urbs(ar);
 
-	/*
-	 * firmware automatically reboots for usb suspend.
-	 */
-
 	return 0;
 }
 
@@ -1106,12 +1118,20 @@ static int carl9170_usb_resume(struct usb_interface *intf)
 		return -ENODEV;
 
 	usb_unpoison_anchored_urbs(&ar->rx_anch);
+	carl9170_set_state(ar, CARL9170_STOPPED);
 
-	err = carl9170_usb_init_device(ar);
-	if (err)
-		goto err_unrx;
+	/*
+	 * The USB documentation demands that [for suspend] all traffic
+	 * to and from the device has to stop. This would be fine, but
+	 * there's a catch: the device[usb phy] does not come back.
+	 *
+	 * Upon resume the firmware will "kill" itself and the
+	 * boot-code sorts out the magic voodoo.
+	 * Not very nice, but there's not much what could go wrong.
+	 */
+	msleep(1100);
 
-	err = carl9170_usb_open(ar);
+	err = carl9170_usb_init_device(ar);
 	if (err)
 		goto err_unrx;
 
@@ -1133,6 +1153,7 @@ static struct usb_driver carl9170_driver = {
 #ifdef CONFIG_PM
 	.suspend = carl9170_usb_suspend,
 	.resume = carl9170_usb_resume,
+	.reset_resume = carl9170_usb_resume,
 #endif /* CONFIG_PM */
 };
 
-- 
1.7.2.3


^ permalink raw reply related

* Re: [linux-pm] subtle pm_runtime_put_sync race and sdio functions
From: Rafael J. Wysocki @ 2010-12-26 18:37 UTC (permalink / raw)
  To: Ohad Ben-Cohen
  Cc: Alan Stern, linux-pm, Johannes Berg, linux-wireless, linux-mmc,
	Ido Yariv, Kevin Hilman
In-Reply-To: <AANLkTinvBD6NhHY7PMw9NSJNBW77-Gah8Vcow6t1aiCT@mail.gmail.com>

On Sunday, December 26, 2010, Ohad Ben-Cohen wrote:
> On Sun, Dec 26, 2010 at 1:45 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> > (It still is not a race, though.)
> 
> Thread 1
> =======
> 
> suspend_handler_of_a_random_device()
> {
>     return failure;
> }
> 
> Thread 2
> =======
> 
> suspend_handler_of_our_mmc_host_controller()
> {
>     invoke our sdio suspend handler and power down the card (directly);
>     return success;
> }
> 
> If thread 2 wins => everything is cool
> If thread 1 wins => our driver will not be able to resume
> 
> The race begins after mac80211 invokes our driver's power off handler,
> which is using pm_runtime_put_sync().

So, it only happens during asynchronous suspend?  In other words, if suspend
is synchronous, everything should be fine, right?

Rafael

^ permalink raw reply

* Re: [linux-pm] subtle pm_runtime_put_sync race and sdio functions
From: Rafael J. Wysocki @ 2010-12-26 18:35 UTC (permalink / raw)
  To: Ohad Ben-Cohen
  Cc: Alan Stern, linux-pm, Johannes Berg, linux-wireless, linux-mmc,
	Ido Yariv, Kevin Hilman
In-Reply-To: <AANLkTimzNXyirnV9wGXf6R454bwEDf=poBZzevAWXEUd@mail.gmail.com>

On Sunday, December 26, 2010, Ohad Ben-Cohen wrote:
> On Sun, Dec 26, 2010 at 1:45 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> > Why does the driver need the device to be reset even though it hasn't
> > been suspeneded yet?
> 
> Because it is asked to stop the hardware by mac80211.

So I guess the mac80211 layer should ask it to start it again.

Thanks,
Rafael

^ permalink raw reply

* [PATCH 3/3] iwlwifi: remove reference to Gen2
From: Wey-Yi Guy @ 2010-12-26 18:17 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Wey-Yi Guy
In-Reply-To: <1293387478-3297-1-git-send-email-wey-yi.w.guy@intel.com>

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

The correct name should be used for the newer devices, remove
reference to Gen2

Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-agn.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index b54d74d..5f11dc2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -4412,7 +4412,7 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
 	{IWL_PCI_DEVICE(0x4239, 0x1311, iwl6000i_2agn_cfg)},
 	{IWL_PCI_DEVICE(0x4239, 0x1316, iwl6000i_2abg_cfg)},
 
-/* 6x00 Series Gen2a */
+/* 6x05 Series */
 	{IWL_PCI_DEVICE(0x0082, 0x1301, iwl6005_2agn_cfg)},
 	{IWL_PCI_DEVICE(0x0082, 0x1306, iwl6005_2abg_cfg)},
 	{IWL_PCI_DEVICE(0x0082, 0x1307, iwl6005_2bg_cfg)},
@@ -4421,7 +4421,7 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
 	{IWL_PCI_DEVICE(0x0085, 0x1311, iwl6005_2agn_cfg)},
 	{IWL_PCI_DEVICE(0x0085, 0x1316, iwl6005_2abg_cfg)},
 
-/* 6x00 Series Gen2b */
+/* 6x30 Series */
 	{IWL_PCI_DEVICE(0x008A, 0x5305, iwl1030_bgn_cfg)},
 	{IWL_PCI_DEVICE(0x008A, 0x5307, iwl1030_bg_cfg)},
 	{IWL_PCI_DEVICE(0x008A, 0x5325, iwl1030_bgn_cfg)},
@@ -4447,7 +4447,7 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
 	{IWL_PCI_DEVICE(0x0089, 0x1311, iwl6050_2agn_cfg)},
 	{IWL_PCI_DEVICE(0x0089, 0x1316, iwl6050_2abg_cfg)},
 
-/* 6x50 WiFi/WiMax Series Gen2 */
+/* 6150 WiFi/WiMax Series */
 	{IWL_PCI_DEVICE(0x0885, 0x1305, iwl6150_bgn_cfg)},
 	{IWL_PCI_DEVICE(0x0885, 0x1306, iwl6150_bgn_cfg)},
 	{IWL_PCI_DEVICE(0x0885, 0x1325, iwl6150_bgn_cfg)},
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 1/3] iwlwifi: remove extra string
From: Wey-Yi Guy @ 2010-12-26 18:17 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Wey-Yi Guy
In-Reply-To: <1293387478-3297-1-git-send-email-wey-yi.w.guy@intel.com>

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

For "led_mode" module parameters, string "led_mode" is duplicated twice,
remove one.

Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-led.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c
index 516e557..46ccdf4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-led.c
@@ -45,7 +45,7 @@
 /* default: IWL_LED_BLINK(0) using blinking index table */
 static int led_mode;
 module_param(led_mode, int, S_IRUGO);
-MODULE_PARM_DESC(led_mode, "led mode: 0=system default, "
+MODULE_PARM_DESC(led_mode, "0=system default, "
 		"1=On(RF On)/Off(RF Off), 2=blinking");
 
 static const struct {
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 2/3] iwlagn: fix FH error
From: Wey-Yi Guy @ 2010-12-26 18:17 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Johannes Berg, Wey-Yi Guy
In-Reply-To: <1293387478-3297-1-git-send-email-wey-yi.w.guy@intel.com>

From: Johannes Berg <johannes.berg@intel.com>

# iw wlan0 interface add moni0 type monitor flags control
# ip link set moni0 up

causes a continuous spew of FH_ERROR from the
device. Fix this by not setting the CTL2HOST
filter by itself -- CTL + promisc works fine.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-agn.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index d407547..b54d74d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -3634,7 +3634,8 @@ void iwlagn_configure_filter(struct ieee80211_hw *hw,
 			changed_flags, *total_flags);
 
 	CHK(FIF_OTHER_BSS | FIF_PROMISC_IN_BSS, RXON_FILTER_PROMISC_MSK);
-	CHK(FIF_CONTROL, RXON_FILTER_CTL2HOST_MSK);
+	/* Setting _just_ RXON_FILTER_CTL2HOST_MSK causes FH errors */
+	CHK(FIF_CONTROL, RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_PROMISC_MSK);
 	CHK(FIF_BCN_PRBRESP_PROMISC, RXON_FILTER_BCON_AWARE_MSK);
 
 #undef CHK
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 0/3] update for 2.6.38
From: Wey-Yi Guy @ 2010-12-26 18:17 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Wey-Yi Guy

We fix a FH error bug in monitor mode
We also make some minor chages for better coding

Johannes Berg (1):
  iwlagn: fix FH error

Wey-Yi Guy (2):
  iwlwifi: remove extra string
  iwlwifi: remove reference to Gen2

these patches are also available from wireless-next-2.6 branch on
 git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-2.6.git

 drivers/net/wireless/iwlwifi/iwl-agn.c |    9 +++++----
 drivers/net/wireless/iwlwifi/iwl-led.c |    2 +-
 2 files changed, 6 insertions(+), 5 deletions(-)


^ permalink raw reply

* [PATCH] ath5k: fix cycle counter inconsistent locking
From: Bob Copeland @ 2010-12-26 17:10 UTC (permalink / raw)
  To: linville, jirislaby, mickflemm, lrodriguez, br1
  Cc: linux-wireless, ath5k-devel, Bob Copeland

ath5k_reset is called from process context and takes the cc_lock
with plain spin_lock(), but cc_lock can also be taken from tasklets
in softirq context.  Thus we need to at least use spin_lock_bh.

This fixes the following lockdep warning:

[   19.967874] sky2 0000:01:00.0: eth0: enabling interface
[   19.982761] ieee80211 phy0: device now idle
[   20.904809] NET: Registered protocol family 17
[   21.243857] ieee80211 phy0: device no longer idle - scanning
[   21.404343]
[   21.404346] =================================
[   21.404450] [ INFO: inconsistent lock state ]
[   21.404518] 2.6.37-rc7-wl+ #242
[   21.404582] ---------------------------------
[   21.404650] inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} usage.
[   21.404721] kworker/u:4/982 [HC0[0]:SC1[3]:HE1:SE0] takes:
[   21.404792]  (&(&common->cc_lock)->rlock){+.?...}, at: [<f8115780>] ath5k_ani_calibration+0x29/0x5d9 [ath5k]
[   21.405011] {SOFTIRQ-ON-W} state was registered at:
[   21.405011]   [<c105cadd>] __lock_acquire+0x62f/0x13c1
[   21.405011]   [<c105d944>] lock_acquire+0xd5/0xf1
[   21.405011]   [<c12c978d>] _raw_spin_lock+0x45/0x72
[   21.405011]   [<f8111533>] ath5k_reset+0x2c0/0x349 [ath5k]
[   21.405011]   [<f8111a7a>] ath5k_start+0xb8/0x139 [ath5k]
[   21.405011]   [<f849c714>] ieee80211_do_open+0x13f/0x819 [mac80211]
[   21.405011]   [<f849ce51>] ieee80211_open+0x63/0x66 [mac80211]
[   21.405011]   [<c1258b2e>] __dev_open+0x8d/0xb6
[   21.405011]   [<c1255c64>] __dev_change_flags+0x9d/0x114
[   21.405011]   [<c1258a75>] dev_change_flags+0x18/0x44
[   21.405011]   [<c1262990>] do_setlink+0x23f/0x521
[   21.405011]   [<c1262d58>] rtnl_setlink+0xe6/0xea
[   21.405011]   [<c126347c>] rtnetlink_rcv_msg+0x18a/0x1a0
[   21.405011]   [<c126d5f0>] netlink_rcv_skb+0x35/0x7b
[   21.405011]   [<c12632eb>] rtnetlink_rcv+0x20/0x27
[   21.405011]   [<c126d370>] netlink_unicast+0x1bb/0x21e
[   21.405011]   [<c126db21>] netlink_sendmsg+0x23b/0x288
[   21.405011]   [<c124823c>] sock_sendmsg+0xac/0xc4
[   21.405011]   [<c1248680>] sys_sendmsg+0x152/0x1a2
[   21.405011]   [<c1249b0d>] sys_socketcall+0x214/0x275
[   21.405011]   [<c10029d0>] sysenter_do_call+0x12/0x36
[   21.405011] irq event stamp: 138032
[   21.405011] hardirqs last  enabled at (138032): [<c12ca252>] _raw_spin_unlock_irqrestore+0x3b/0x5e
[   21.405011] hardirqs last disabled at (138031): [<c12c98cc>] _raw_spin_lock_irqsave+0x18/0x7e
[   21.405011] softirqs last  enabled at (138024): [<f84a570e>] ieee80211_tx_skb+0x47/0x49 [mac80211]
[   21.405011] softirqs last disabled at (138027): [<c100452b>] do_softirq+0x63/0xb4
[   21.405011]
[   21.405011] other info that might help us debug this:
[   21.405011] 3 locks held by kworker/u:4/982:
[   21.405011]  #0:  (name){+.+.+.}, at: [<c1046158>] process_one_work+0x1b8/0x41b
[   21.405011]  #1:  ((&(&local->scan_work)->work)){+.+.+.}, at: [<c1046158>] process_one_work+0x1b8/0x41b
[   21.405011]  #2:  (&local->mtx){+.+.+.}, at: [<f84920fb>] ieee80211_scan_work+0x32/0x4a4 [mac80211]
[   21.405011]
[   21.405011] stack backtrace:
[   21.405011] Pid: 982, comm: kworker/u:4 Not tainted 2.6.37-rc7-wl+ #242
[   21.405011] Call Trace:
[   21.405011]  [<c12c6e68>] ? printk+0x1d/0x25
[   21.405011]  [<c105a742>] print_usage_bug+0x181/0x18b
[   21.405011]  [<c105b196>] ? check_usage_forwards+0x0/0xb6
[   21.405011]  [<c105a9ec>] mark_lock+0x2a0/0x4aa
[   21.405011]  [<c1059f6d>] ? trace_hardirqs_off+0xb/0xd
[   21.405011]  [<c105ca68>] __lock_acquire+0x5ba/0x13c1
[   21.405011]  [<c1059eed>] ? trace_hardirqs_off_caller+0x18/0x8d
[   21.405011]  [<c1059f6d>] ? trace_hardirqs_off+0xb/0xd
[   21.405011]  [<c1050411>] ? local_clock+0x2c/0x4f
[   21.405011]  [<c1059e00>] ? save_trace+0x2/0xa0
[   21.405011]  [<c105ac39>] ? mark_held_locks+0x43/0x5b
[   21.405011]  [<c12ca252>] ? _raw_spin_unlock_irqrestore+0x3b/0x5e
[   21.405011]  [<f8115780>] ? ath5k_ani_calibration+0x29/0x5d9 [ath5k]
[   21.405011]  [<c105d944>] lock_acquire+0xd5/0xf1
[   21.405011]  [<f8115780>] ? ath5k_ani_calibration+0x29/0x5d9 [ath5k]
[   21.405011]  [<c12c9b1a>] _raw_spin_lock_bh+0x4a/0x77
[   21.405011]  [<f8115780>] ? ath5k_ani_calibration+0x29/0x5d9 [ath5k]
[   21.405011]  [<f8115780>] ath5k_ani_calibration+0x29/0x5d9 [ath5k]
[   21.405011]  [<c105ac39>] ? mark_held_locks+0x43/0x5b
[   21.405011]  [<f8113496>] ath5k_tasklet_ani+0x1d/0x27 [ath5k]
[   21.405011]  [<c1037304>] tasklet_action+0x96/0x137
[   21.405011]  [<c10379b5>] __do_softirq+0xde/0x1c3
[   21.405011]  [<c10b0cef>] ? arch_get_unmapped_area_topdown+0x3b/0x127
[   21.405011]  [<c10378d7>] ? __do_softirq+0x0/0x1c3
[   21.405011]  <IRQ>  [<c1036dee>] ? irq_exit+0x3d/0x49
[   21.405011]  [<c1003b4f>] ? do_IRQ+0x98/0xac
[   21.405011]  [<c1002eee>] ? common_interrupt+0x2e/0x34
[   21.405011]  [<c103007b>] ? sys_unshare+0x57/0x226
[   21.405011]  [<c1047fee>] ? queue_delayed_work+0x1/0x27
[   21.405011]  [<f84a83a0>] ? ieee80211_queue_delayed_work+0x2e/0x33 [mac80211]
[   21.405011]  [<f8492528>] ? ieee80211_scan_work+0x45f/0x4a4 [mac80211]
[   21.405011]  [<c104620e>] ? process_one_work+0x26e/0x41b
[   21.405011]  [<c1046158>] ? process_one_work+0x1b8/0x41b
[   21.405011]  [<f84920c9>] ? ieee80211_scan_work+0x0/0x4a4 [mac80211]
[   21.405011]  [<c10466b6>] ? worker_thread+0x18a/0x2a5
[   21.405011]  [<c12ca25e>] ? _raw_spin_unlock_irqrestore+0x47/0x5e
[   21.405011]  [<c104652c>] ? worker_thread+0x0/0x2a5
[   21.405011]  [<c104abe7>] ? kthread+0x67/0x6c
[   21.405011]  [<c104ab80>] ? kthread+0x0/0x6c
[   21.405011]  [<c1002efa>] ? kernel_thread_helper+0x6/0x10

Signed-off-by: Bob Copeland <me@bobcopeland.com>
---
 drivers/net/wireless/ath/ath5k/base.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index e4ec40c..63ef7ff 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -2703,11 +2703,11 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan,
 
 	/* clear survey data and cycle counters */
 	memset(&sc->survey, 0, sizeof(sc->survey));
-	spin_lock(&common->cc_lock);
+	spin_lock_bh(&common->cc_lock);
 	ath_hw_cycle_counters_update(common);
 	memset(&common->cc_survey, 0, sizeof(common->cc_survey));
 	memset(&common->cc_ani, 0, sizeof(common->cc_ani));
-	spin_unlock(&common->cc_lock);
+	spin_unlock_bh(&common->cc_lock);
 
 	/*
 	 * Change channels and update the h/w rate map if we're switching;
-- 
1.7.1.1



^ permalink raw reply related

* Re: [linux-pm] subtle pm_runtime_put_sync race and sdio functions
From: Alan Stern @ 2010-12-26 17:00 UTC (permalink / raw)
  To: Ohad Ben-Cohen
  Cc: Rafael J. Wysocki, linux-pm, Johannes Berg, linux-wireless,
	linux-mmc, Ido Yariv, Kevin Hilman
In-Reply-To: <AANLkTinyKfwcZLD5D4rdF6OpQqr79F==GRjAMBjjbupW@mail.gmail.com>

On Sun, 26 Dec 2010, Ohad Ben-Cohen wrote:

> On Sun, Dec 26, 2010 at 4:48 AM, Alan Stern <stern@rowland.harvard.edu> wrote:
> > Is there a separate handler responsible for powering the device back
> > on?  What are the names of these handlers?
> 
> wl1271_sdio_power_on() and wl1271_sdio_power_off().
> 
> If you're taking a look, please do so using the latest code as seen on mmc-next:
> 
> git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc.git mmc-next

Hmm.  It's a little difficult to untangle the web of dev_pm_ops
pointers and other stuff.  There's wl1271_suspend() and wl1271_resume()
(which don't do anything) plus wl1271_sdio_set_power(), which calls
either wl1271_sdio_power_on() or wl1271_sdio_power_off(), and these
routines in turn call pm_runtime_get_sync() and pm_runtime_put_sync().

Under what circumstances does the MMC/SDIO core call 
wl1271_sdio_set_power(), and where are those function calls?

> > That's not a race
> 
> It is.
> 
> If system suspend will continue uninterruptedly, and the driver will
> be suspended (by the SDIO subsystem), then the device will be powered
> down, and everything will work.
> 
> But if something will interrupt the suspend transition _before_ our
> driver is suspended (e.g. some other suspend() handler will fail),
> then we have a problem, because the device will not be reset as the
> driver needs it to be.

The normal case is that system suspend succeeds.  Then there is no 
race.  If system suspend fails then the failure may occur either before 
or after the wl1271 device is powered down; _that_ is the race 
(assuming you are using asynchronous PM).  But normally it doesn't 
occur.

> > What is the name of the driver's runtime_suspend routine?
> 
> The driver itself doesn't have one; power is being controlled by the
> MMC/SDIO subsystem, so the actual runtime_suspend handler is
> mmc_runtime_suspend().

You mean, the wl1271 device has no PM methods of its own; its power is 
managed entirely by the parent MMC/SDIO controller?  If that's right 
then you should call pm_runtime_no_callbacks() for the wl1271 device.

Is it possible for there to be more than one device connected to the 
same MMC/SDIO controller?  If it is, how do you reset one without 
resetting all the others?

> > And while we're at it, what is the name of the routine that _actually_ changes the
> > device's power level?
> 
> mmc_power_save_host(), which is called by mmc_runtime_suspend().
> 
> (well, more accurately it is actually fixed_voltage_disable(), but
> that's a few levels deeper than I think you'll be interested in)

That's for runtime PM.  What about system sleep?  It looks like
sdio_bus_type has no callbacks for suspend or resume, so the driver's
callbacks get used instead -- that would be wl1271_suspend() and
wl1271_resume().  But they don't do anything, so there's no power
change until the parent MMC/SDIO controller is suspended.  That would
be in mmc_sdio_suspend() and mmc_sdio_resume()?  But I can't tell what
pmops->suspend and pmops->resume methods they end up calling.  Are
these the entries in wl1271_sdio_pm_ops?  Does that mean
wl1271_suspend() and wl1271_resume() get called twice?

I think I already understand how the runtime suspend/resume paths work:
There are no runtime PM methods for the wl1271 device, so the PM core
simply propagates changes up to the parent MMC/SDIO device and ends up
calling mmc_runtime_suspend() or mmc_runtime_resume().  Right?

What is the pathway for reset (or other similar activities that 
require the device to be powered-down while it is in use)?  
wl1271_sdio_reset() doesn't do anything.

Alan Stern


^ permalink raw reply

* Re: [linux-pm] subtle pm_runtime_put_sync race and sdio functions
From: Ohad Ben-Cohen @ 2010-12-26 14:53 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Alan Stern, linux-pm, Johannes Berg, linux-wireless, linux-mmc,
	Ido Yariv, Kevin Hilman
In-Reply-To: <201012261245.29680.rjw@sisk.pl>

On Sun, Dec 26, 2010 at 1:45 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> (It still is not a race, though.)

Thread 1
=======

suspend_handler_of_a_random_device()
{
    return failure;
}

Thread 2
=======

suspend_handler_of_our_mmc_host_controller()
{
    invoke our sdio suspend handler and power down the card (directly);
    return success;
}

If thread 2 wins => everything is cool
If thread 1 wins => our driver will not be able to resume

The race begins after mac80211 invokes our driver's power off handler,
which is using pm_runtime_put_sync().

^ permalink raw reply

* Re: [RFC PATCH 0/6] zd1211rw: add support for AP mode
From: Jussi Kivilinna @ 2010-12-26 14:53 UTC (permalink / raw)
  To: Rafał Miłecki
  Cc: Johannes Berg, linux-wireless, Daniel Drake, zd1211-devs,
	Ulrich Kunitz
In-Reply-To: <AANLkTim_G3Q8tkNepERTWT-0j118ZxTbN==Z9ufCUWRa@mail.gmail.com>

Quoting Rafał Miłecki <zajec5@gmail.com>:

> 2010/12/26 Johannes Berg <johannes@sipsolutions.net>:
>> On Sun, 2010-12-26 at 13:24 +0200, Jussi Kivilinna wrote:
>>
>>>  1. I have not been able to trigger bc/mc buffering. I have tested with
>>>     b43 and rndis_wlan stations.
>>
>> Put the stations into powersave mode. I guess neither of those actually
>> support that, though you might easily pretend to support powersave in
>> b43 -- even if it won't save power it'll have the AP trigger this.
>>
>> However, bc/mc buffering is a very important feature of AP mode, so you
>> shouldn't try to support AP mode w/o it.
>
> What do bc and mc stand for?

Broadcast/multicast.

-Jussi


^ permalink raw reply

* Re: [RFC PATCH 5/6] zd1211rw: implement beacon fetching and handling ieee80211_get_buffered_bc()
From: Jussi Kivilinna @ 2010-12-26 14:51 UTC (permalink / raw)
  To: Rafał Miłecki
  Cc: linux-wireless, Daniel Drake, zd1211-devs, Ulrich Kunitz
In-Reply-To: <AANLkTi=yN485OSM+TSPoZrG=h3M0vhAAmVgmndxp-BrG@mail.gmail.com>

Quoting Rafał Miłecki <zajec5@gmail.com>:

> 2010/12/26 Jussi Kivilinna <jussi.kivilinna@mbnet.fi>:
>> +       if (mac->vif || mac->vif->type == NL80211_IFTYPE_UNSPECIFIED)
>> +               return;
>
> That's smelly. I think you meant negation in first part of condition.

Heh.. well that fixed broadcast/multicast buffering. Thanks.

>
>
>> -       if (int_status & INT_CFG_NEXT_BCN)
>> +       if (int_status & INT_CFG_NEXT_BCN) {
>>                dev_dbg_f_limit(zd_mac_dev(mac), "INT_CFG_NEXT_BCN\n");
>> -       else
>> +               zd_beacon_done(mac);
>> +       } else
>>                dev_dbg_f(zd_mac_dev(mac), "Unsupported interrupt\n");
>
> Minor thing, check http://www.kernel.org/doc/Documentation/CodingStyle
>
>> This does not apply if one branch of a conditional statement is a single
>> statement. Use braces in both branches.
>
> Use brackets for "else" as well please.
>

Ok.

-Jussi


^ permalink raw reply

* Re: [RFC PATCH 3/6] zd1211rw: let zd_set_beacon_interval() set dtim_period and add AP-beacon flag
From: Jussi Kivilinna @ 2010-12-26 14:50 UTC (permalink / raw)
  To: Rafał Miłecki
  Cc: linux-wireless, Daniel Drake, zd1211-devs, Ulrich Kunitz
In-Reply-To: <AANLkTikFrH0P+A-tZU1hULNja4yvWkwqb22csHtrKO76@mail.gmail.com>

Quoting Rafał Miłecki <zajec5@gmail.com>:

> 2010/12/26 Jussi Kivilinna <jussi.kivilinna@mbnet.fi>:
>> -static int set_beacon_interval(struct zd_chip *chip, u32 interval)
>> +static int set_beacon_interval(struct zd_chip *chip, u32 interval,
>> +                              u16 dtim_period)
>
> That gets messy. We have interval in interval, flags in interval and
> period in dtim_period :|
>
> Do you have idea what is maximum value for dtim_period? It sounds like
> it should be 0xff.
>
> Could we maybe try sth like:
> u16 interval, u8 dtim_period, u8 flags? Then we would have
> flags << 24 | dtim_period << 16 | interval
>
> Or maybe to avoid problems with shifting flags (re-defining defines?),
> we could use a little more messy
> flags | dtim_period << 16 | interval
>
> Or do you have better idea? Proposed one doesn't seem really clear for me.
>
Vendor driver uses u16 interval, u8 dtim_p, u8 mode and selects right  
flags based on interval. I'll something like change to that, I think  
caller shouldn't be setting hw flags here anyway.

-Jussi


^ permalink raw reply

* Re: [linux-pm] subtle pm_runtime_put_sync race and sdio functions
From: Ohad Ben-Cohen @ 2010-12-26 12:43 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Alan Stern, linux-pm, Johannes Berg, linux-wireless, linux-mmc,
	Ido Yariv, Kevin Hilman
In-Reply-To: <201012261245.29680.rjw@sisk.pl>

On Sun, Dec 26, 2010 at 1:45 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> Why does the driver need the device to be reset even though it hasn't
> been suspeneded yet?

Because it is asked to stop the hardware by mac80211.

^ permalink raw reply

* Re: [RFC PATCH 0/6] zd1211rw: add support for AP mode
From: Rafał Miłecki @ 2010-12-26 12:37 UTC (permalink / raw)
  To: Johannes Berg
  Cc: Jussi Kivilinna, linux-wireless, Daniel Drake, zd1211-devs,
	Ulrich Kunitz
In-Reply-To: <1293366263.3537.1.camel@jlt3.sipsolutions.net>

2010/12/26 Johannes Berg <johannes@sipsolutions.net>:
> On Sun, 2010-12-26 at 13:24 +0200, Jussi Kivilinna wrote:
>
>>  1. I have not been able to trigger bc/mc buffering. I have tested with
>>     b43 and rndis_wlan stations.
>
> Put the stations into powersave mode. I guess neither of those actually
> support that, though you might easily pretend to support powersave in
> b43 -- even if it won't save power it'll have the AP trigger this.
>
> However, bc/mc buffering is a very important feature of AP mode, so you
> shouldn't try to support AP mode w/o it.

What do bc and mc stand for?

-- 
Rafał

^ permalink raw reply

* Re: [RFC PATCH 0/6] zd1211rw: add support for AP mode
From: Johannes Berg @ 2010-12-26 12:24 UTC (permalink / raw)
  To: Jussi Kivilinna; +Cc: linux-wireless, Daniel Drake, zd1211-devs, Ulrich Kunitz
In-Reply-To: <20101226112404.31775.77854.stgit@fate.lan>

On Sun, 2010-12-26 at 13:24 +0200, Jussi Kivilinna wrote:

>  1. I have not been able to trigger bc/mc buffering. I have tested with
>     b43 and rndis_wlan stations.

Put the stations into powersave mode. I guess neither of those actually
support that, though you might easily pretend to support powersave in
b43 -- even if it won't save power it'll have the AP trigger this.

However, bc/mc buffering is a very important feature of AP mode, so you
shouldn't try to support AP mode w/o it.

johannes


^ permalink raw reply

* Re: [RFC PATCH 5/6] zd1211rw: implement beacon fetching and handling ieee80211_get_buffered_bc()
From: Rafał Miłecki @ 2010-12-26 12:22 UTC (permalink / raw)
  To: Jussi Kivilinna; +Cc: linux-wireless, Daniel Drake, zd1211-devs, Ulrich Kunitz
In-Reply-To: <20101226112452.31775.12810.stgit@fate.lan>

2010/12/26 Jussi Kivilinna <jussi.kivilinna@mbnet.fi>:
> +       if (mac->vif || mac->vif->type == NL80211_IFTYPE_UNSPECIFIED)
> +               return;

That's smelly. I think you meant negation in first part of condition.


> -       if (int_status & INT_CFG_NEXT_BCN)
> +       if (int_status & INT_CFG_NEXT_BCN) {
>                dev_dbg_f_limit(zd_mac_dev(mac), "INT_CFG_NEXT_BCN\n");
> -       else
> +               zd_beacon_done(mac);
> +       } else
>                dev_dbg_f(zd_mac_dev(mac), "Unsupported interrupt\n");

Minor thing, check http://www.kernel.org/doc/Documentation/CodingStyle

> This does not apply if one branch of a conditional statement is a single
> statement. Use braces in both branches.

Use brackets for "else" as well please.

-- 
Rafał

^ permalink raw reply

* Re: [RFC PATCH 3/6] zd1211rw: let zd_set_beacon_interval() set dtim_period and add AP-beacon flag
From: Rafał Miłecki @ 2010-12-26 12:14 UTC (permalink / raw)
  To: Jussi Kivilinna; +Cc: linux-wireless, Daniel Drake, zd1211-devs, Ulrich Kunitz
In-Reply-To: <20101226112433.31775.89617.stgit@fate.lan>

2010/12/26 Jussi Kivilinna <jussi.kivilinna@mbnet.fi>:
> -static int set_beacon_interval(struct zd_chip *chip, u32 interval)
> +static int set_beacon_interval(struct zd_chip *chip, u32 interval,
> +                              u16 dtim_period)

That gets messy. We have interval in interval, flags in interval and
period in dtim_period :|

Do you have idea what is maximum value for dtim_period? It sounds like
it should be 0xff.

Could we maybe try sth like:
u16 interval, u8 dtim_period, u8 flags? Then we would have
flags << 24 | dtim_period << 16 | interval

Or maybe to avoid problems with shifting flags (re-defining defines?),
we could use a little more messy
flags | dtim_period << 16 | interval

Or do you have better idea? Proposed one doesn't seem really clear for me.

-- 
Rafał

^ permalink raw reply

* Re: [RFC PATCH 1/6] zd1211rw: fix beacon interval setup
From: Rafał Miłecki @ 2010-12-26 11:56 UTC (permalink / raw)
  To: Jussi Kivilinna; +Cc: linux-wireless, Daniel Drake, zd1211-devs, Ulrich Kunitz
In-Reply-To: <20101226112414.31775.62053.stgit@fate.lan>

2010/12/26 Jussi Kivilinna <jussi.kivilinna@mbnet.fi>:
> Vendor driver uses CR_BNC_INTERVAL at various places, one is HW_EnableBeacon()
> that combinies beacon interval with BSS-type flag and DTIM value in upper
> 16bit of u32. The other one is HW_UpdateBcnInterval() that set_aw_pt_bi()
> appears to be based on. HW_UpdateBcnInterval() takes interval argument as u16
> and uses that for calculations, set_aw_pt_bi() uses u32 value that has flags
> and dtim in upper part. This clearly seems wrong. Also HW_UpdateBcnInterval()
> updates only lower 16bit part of CR_BNC_INTERVAL.
>
> So make set_aw_pt_bi() do calculations on only lower u16 part of
> s->beacon_interval.

It seems correct, we have for example:
#define BCN_MODE_IBSS			0x2000000
which can be set in beacon_interval.

AFAICS pre_tbtt should contain only interval, without additional flags.

Do I get it right?


>        if (s->pre_tbtt < 4 || s->pre_tbtt >= s->beacon_interval)
> -               s->pre_tbtt = s->beacon_interval - 1;
> +               s->pre_tbtt = (s->beacon_interval & 0xffff) - 1;

So if I am right, in condition here you should extract interval from
beacon_interval and compare it with pre_tbtt. Extracting from pre_tbtt
should not be needed, as it's plain interval.

Maybe use some local variable like
b_interval = s->beacon_interval & 0xffff
?

-- 
Rafał

^ permalink raw reply

* Re: [linux-pm] subtle pm_runtime_put_sync race and sdio functions
From: Rafael J. Wysocki @ 2010-12-26 11:45 UTC (permalink / raw)
  To: Ohad Ben-Cohen
  Cc: Alan Stern, linux-pm, Johannes Berg, linux-wireless, linux-mmc,
	Ido Yariv, Kevin Hilman
In-Reply-To: <AANLkTinyKfwcZLD5D4rdF6OpQqr79F==GRjAMBjjbupW@mail.gmail.com>

On Sunday, December 26, 2010, Ohad Ben-Cohen wrote:
> On Sun, Dec 26, 2010 at 4:48 AM, Alan Stern <stern@rowland.harvard.edu> wrote:
> > Is there a separate handler responsible for powering the device back
> > on?  What are the names of these handlers?
> 
> wl1271_sdio_power_on() and wl1271_sdio_power_off().
> 
> If you're taking a look, please do so using the latest code as seen on mmc-next:
> 
> git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc.git mmc-next
> 
> > That's not a race
> 
> It is.
> 
> If system suspend will continue uninterruptedly, and the driver will
> be suspended (by the SDIO subsystem), then the device will be powered
> down, and everything will work.
> 
> But if something will interrupt the suspend transition _before_ our
> driver is suspended (e.g. some other suspend() handler will fail),
> then we have a problem, because the device will not be reset as the
> driver needs it to be.

Now, that's interesting.  (It still is not a race, though.)
Why does the driver need the device to be reset even though it hasn't
been suspeneded yet?

Rafael

^ permalink raw reply

* [RFC PATCH 6/6] zd1211rw: enable NL80211_IFTYPE_AP
From: Jussi Kivilinna @ 2010-12-26 11:25 UTC (permalink / raw)
  To: linux-wireless; +Cc: Daniel Drake, zd1211-devs, Ulrich Kunitz
In-Reply-To: <20101226112404.31775.77854.stgit@fate.lan>

Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
---
 drivers/net/wireless/zd1211rw/zd_mac.c |    7 +++++--
 1 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index 2489c97..031dbfe 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -922,6 +922,7 @@ static int zd_op_add_interface(struct ieee80211_hw *hw,
 	case NL80211_IFTYPE_MESH_POINT:
 	case NL80211_IFTYPE_STATION:
 	case NL80211_IFTYPE_ADHOC:
+	case NL80211_IFTYPE_AP:
 		mac->type = vif->type;
 		break;
 	default:
@@ -1120,7 +1121,8 @@ static void zd_op_bss_info_changed(struct ieee80211_hw *hw,
 	dev_dbg_f(zd_mac_dev(mac), "changes: %x\n", changes);
 
 	if (mac->type == NL80211_IFTYPE_MESH_POINT ||
-	    mac->type == NL80211_IFTYPE_ADHOC) {
+	    mac->type == NL80211_IFTYPE_ADHOC ||
+	    mac->type == NL80211_IFTYPE_AP) {
 		associated = true;
 		if (changes & BSS_CHANGED_BEACON) {
 			struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
@@ -1223,7 +1225,8 @@ struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf)
 	hw->wiphy->interface_modes =
 		BIT(NL80211_IFTYPE_MESH_POINT) |
 		BIT(NL80211_IFTYPE_STATION) |
-		BIT(NL80211_IFTYPE_ADHOC);
+		BIT(NL80211_IFTYPE_ADHOC) |
+		BIT(NL80211_IFTYPE_AP);
 
 	hw->max_signal = 100;
 	hw->queues = 1;


^ permalink raw reply related

* [RFC PATCH 5/6] zd1211rw: implement beacon fetching and handling ieee80211_get_buffered_bc()
From: Jussi Kivilinna @ 2010-12-26 11:24 UTC (permalink / raw)
  To: linux-wireless; +Cc: Daniel Drake, zd1211-devs, Ulrich Kunitz
In-Reply-To: <20101226112404.31775.77854.stgit@fate.lan>

Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
---
 drivers/net/wireless/zd1211rw/zd_mac.c |   38 +++++++++++++++++++++++++++++---
 1 files changed, 35 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index 9f755fc..2489c97 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -951,15 +951,46 @@ static int zd_op_config(struct ieee80211_hw *hw, u32 changed)
 	return zd_chip_set_channel(&mac->chip, conf->channel->hw_value);
 }
 
+static void zd_beacon_done(struct zd_mac *mac)
+{
+	struct sk_buff *skb, *beacon;
+
+	if (mac->vif || mac->vif->type == NL80211_IFTYPE_UNSPECIFIED)
+		return;
+
+	/*
+	 * Send out buffered broad- and multicast frames.
+	 */
+	if (mac->vif->type == NL80211_IFTYPE_AP) {
+		dev_dbg_f_limit(zd_mac_dev(mac), "buffered_bc tx\n");
+		skb = ieee80211_get_buffered_bc(mac->hw, mac->vif);
+		while (skb) {
+			zd_op_tx(mac->hw, skb);
+			skb = ieee80211_get_buffered_bc(mac->hw, mac->vif);
+		}
+	}
+
+	/*
+	 * Fetch next beacon so that tim_count is updated.
+	 */
+	beacon = ieee80211_beacon_get(mac->hw, mac->vif);
+	if (!beacon)
+		return;
+
+	zd_mac_config_beacon(mac->hw, beacon);
+	kfree_skb(beacon);
+}
+
 static void zd_process_intr(struct work_struct *work)
 {
 	u16 int_status;
 	struct zd_mac *mac = container_of(work, struct zd_mac, process_intr);
 
 	int_status = le16_to_cpu(*(__le16 *)(mac->intr_buffer+4));
-	if (int_status & INT_CFG_NEXT_BCN)
+	if (int_status & INT_CFG_NEXT_BCN) {
 		dev_dbg_f_limit(zd_mac_dev(mac), "INT_CFG_NEXT_BCN\n");
-	else
+		zd_beacon_done(mac);
+	} else
 		dev_dbg_f(zd_mac_dev(mac), "Unsupported interrupt\n");
 
 	zd_chip_enable_hwint(&mac->chip);
@@ -1186,7 +1217,8 @@ struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf)
 	hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &mac->band;
 
 	hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
-		    IEEE80211_HW_SIGNAL_UNSPEC;
+		    IEEE80211_HW_SIGNAL_UNSPEC |
+		    IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING;
 
 	hw->wiphy->interface_modes =
 		BIT(NL80211_IFTYPE_MESH_POINT) |


^ 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