Skip to contentSkip to conversation

ath9k-htc: speedup disconnect handling

PATCH New [email protected] 2 participants 5 messages Apr 19, 2010 – Apr 20, 2010 Qualcomm Atheros ATH9K wireless driver

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 ath9k-htc: speedup disconnect handling

From: Ming Lei <[email protected]>

This patch detects the disconnect in wmi register write path, then speedup the disconnect handling.

---
 drivers/net/wireless/ath/ath9k/hw.c  |    2 ++
 drivers/net/wireless/ath/ath9k/hw.h  |    1 +
 drivers/net/wireless/ath/ath9k/wmi.c |    8 ++++++++
 3 files changed, 11 insertions(+), 0 deletions(-)
drivers/net/wireless/ath/ath9k/hw.c +2 -0
index 9aa40df..bcc48ff 100644
@@ -111,6 +111,8 @@ bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout)
 	BUG_ON(timeout < AH_TIME_QUANTUM);
 
 	for (i = 0; i < (timeout / AH_TIME_QUANTUM); i++) {
+		if (AR_SREV_9271(ah) && ah->htc_disconnected)
+			break;
 		if ((REG_READ(ah, reg) & mask) == val)
 			return true;
 
drivers/net/wireless/ath/ath9k/hw.h +1 -0
index 8158e8e..6b22158 100644
@@ -635,6 +635,7 @@ struct ath_hw {
 	u32 ah_flags;
 
 	bool htc_reset_init;
+	bool htc_disconnected;
 
 	enum nl80211_iftype opmode;
 	enum ath9k_power_mode power_mode;
drivers/net/wireless/ath/ath9k/wmi.c +8 -0
index dc6c6fc..fbd44c7 100644
@@ -279,6 +279,9 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
 	if (!wmi)
 		return -EINVAL;
 
+	if (ah->htc_disconnected)
+		return -ENODEV;
+
 	skb = alloc_skb(headroom + cmd_len, GFP_ATOMIC);
 	if (!skb)
 		return -ENOMEM;
@@ -324,6 +327,11 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
 	return 0;
 
 out:
+	if (ret == -ENODEV) {
+		ah->htc_disconnected = 1;
+		ath_print(common, ATH_DBG_WMI,"HTC disconnected!\n");
+	}
+
 	ath_print(common, ATH_DBG_WMI,
 		  "WMI failure for: %s\n", wmi_cmd_to_name(cmd_id));
 	mutex_unlock(&wmi->op_mutex);
Signature · 1 line
1.6.2.5
#1 lore raw

PATCH 1/1 ath9k-htc: speedup disconnect handling

Quoted 2 lines · [email protected] wrote:

This patch detects the disconnect in wmi register write path, then speedup the disconnect handling.

What bug does this fix ? Submission of URBs in the REGOUT pipe should not really fail, and if it does, it is indicative of a deeper problem and recovery mechanisms are needed.

If you do get WMI failures, can you post the relevant sections from the kernel log ?

Sujith

author
#2 lore raw

2010/4/20 Sujith <[email protected]>:

Quoted 7 lines
Quoted 2 lines · [email protected] wrote:

This patch detects the disconnect in wmi register write path, then speedup the disconnect handling.

What bug does this fix ? Submission of URBs in the REGOUT pipe should not really fail, and if it does, it is indicative of a deeper problem and recovery mechanisms are needed.

After the 9271 device is unplugged, you will find your machine hung for several hundreds of milliseconds.

Quoted 3 lines

If you do get WMI failures, can you post the relevant sections from the kernel log ?

If ATH_DBG_RESET is enabled, you will find the debug messages below[1] during disconnecting. From the messages, the short hang should be caused by the 'RTC stuck in MAC reset'. Once the patch is applied, no such issue will happen.

[1], debug messages during 9287 disconnecting

[12873.291066] usb 2-1.3: USB disconnect, address 15
[12873.291800] device: 'ep_01': device_unregister
[12873.291809] PM: Removing info for No Bus:ep_01
[12873.292465] device: 'ep_82': device_unregister
[12873.292472] PM: Removing info for No Bus:ep_82
[12873.292654] device: 'ep_83': device_unregister
[12873.292661] PM: Removing info for No Bus:ep_83
[12873.292828] device: 'ep_04': device_unregister
[12873.292834] PM: Removing info for No Bus:ep_04
[12873.292999] device: 'ep_05': device_unregister
[12873.293431] PM: Removing info for No Bus:ep_05
[12873.293612] device: 'ep_06': device_unregister
[12873.293689] PM: Removing info for No Bus:ep_06
[12873.293868] PM: Removing info for usb:2-1.3:1.0
[12873.294338] bus: 'usb': remove device 2-1.3:1.0
[12873.294373] usb 2-1.3: __pm_runtime_resume()!
[12873.294380] usb 2-1.3: __pm_runtime_resume() returns 1!
[12873.294392] device: 'ath9k-phy12::assoc': device_unregister
[12873.294399] PM: Removing info for No Bus:ath9k-phy12::assoc
[12873.294732] device: 'ath9k-phy12::assoc': device_create_release
[12873.294771] device: 'ath9k-phy12::tx': device_unregister
[12873.294778] PM: Removing info for No Bus:ath9k-phy12::tx
[12873.295676] device: 'ath9k-phy12::tx': device_create_release
[12873.295718] device: 'ath9k-phy12::rx': device_unregister
[12873.295725] PM: Removing info for No Bus:ath9k-phy12::rx
[12873.296316] device: 'ath9k-phy12::rx': device_create_release
[12873.296351] device: 'ath9k-phy12::radio': device_unregister
[12873.296358] PM: Removing info for No Bus:ath9k-phy12::radio
[12873.296701] device: 'ath9k-phy12::radio': device_create_release
[12874.349767] ath: timeout (100000 us) on reg 0x7000: 0xfffffffb &
0x00000003 != 0x00000000
[12874.349774] ath: RTC stuck in MAC reset
[12874.349777] ath: Chip reset failed
[12874.349779] ath: Unable to reset channel (2437 Mhz) reset status -22
[12874.349784] ath: Unable to set channel
[12874.349939] ath: ah->misc_mode 0x4
[12874.350750] ath: Unable to remove station entry for: 00:03:7f:13:02:d3
[12874.352092] phy12: Removed STA 00:03:7f:13:02:d3
[12874.352224] phy12: Destroyed STA 00:03:7f:13:02:d3
[12874.352232] wlan14: deauthenticating from 00:03:7f:13:02:d3 by
local choice (reason=3)
[12874.352494] phy12: device now idle
[12875.177375] ath: timeout (100000 us) on reg 0x7000: 0xfffffffb &
0x00000003 != 0x00000000
[12875.177382] ath: RTC stuck in MAC reset
[12875.988627] ath: timeout (100000 us) on reg 0x7000: 0xfffffffb &
0x00000003 != 0x00000000
[12875.988633] ath: RTC stuck in MAC reset
[12875.988638] ath: AWAKE -> FULL-SLEEP
[12876.000157] PM: Removing info for No Bus:wlan14
[12876.005146] cfg80211: All devices are disconnected, going to
restore regulatory settings
[12876.005157] cfg80211: Restoring regulatory settings
[12876.005175] cfg80211: Calling CRDA to update world regulatory domain
[12876.006494] PM: Removing info for No Bus:rfkill13
[12876.013231] PM: Removing info for No Bus:phy12
[12876.026482] usb 2-1.3: ath9k_htc: USB layer deinitialized
[12876.027680] device: 'ep_00': device_unregister
[12876.027684] PM: Removing info for No Bus:ep_00
[12876.027781] PM: Removing info for usb:2-1.3
[12876.029678] bus: 'usb': remove device 2-1.3
[12876.045047] cfg80211: World regulatory domain updated:
[12876.045051]     (start_freq - end_freq @ bandwidth),
(max_antenna_gain, max_eirp)
[12876.045054]     (2402000 KHz - 2472000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
[12876.045057]     (2457000 KHz - 2482000 KHz @ 20000 KHz), (300 mBi, 2000 mBm)
[12876.045060]     (2474000 KHz - 2494000 KHz @ 20000 KHz), (300 mBi, 2000 mBm)
[12876.045062]     (5170000 KHz - 5250000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
[12876.045065]     (5735000 KHz - 5835000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
[12876.144805] hub 2-1:1.0: __pm_runtime_suspend()!
[12876.144832] hub 2-1:1.0: __pm_runtime_suspend() returns 0!
[12878.705219] usb 2-1: __pm_runtime_suspend() from workqueue!
[12878.716694] usb 2-1: __pm_runtime_suspend() returns 0!
[12881.705105] usb usb2: __pm_runtime_suspend() from workqueue!
[12881.705175] usb usb2: __pm_runtime_suspend() returns 0!
Signature · 1 line
Lei Ming
#3 lore raw
Quoted 4 lines · Ming Lei

If ATH_DBG_RESET is enabled, you will find the debug messages below[1] during disconnecting. From the messages, the short hang should be caused by the 'RTC stuck in MAC reset'. Once the patch is applied, no such issue will happen.

I take it that you didn't have ATH_DBG_WMI in your debug mask. A simpler way to fix this issue is to deny all WMI commands once the target has been unplugged - something like the attached patch.

Can you check if it fixes your issue ?

drivers/net/wireless/ath/ath9k/htc.h +1 -0
index c765ff4..b771e20 100644
@@ -329,6 +329,7 @@ struct htc_beacon_config {
 #define OP_ASSOCIATED     BIT(8)
 #define OP_ENABLE_BEACON  BIT(9)
 #define OP_LED_DEINIT     BIT(10)
+#define OP_UNPLUGGED      BIT(11)
 
 struct ath9k_htc_priv {
 	struct device *dev;
drivers/net/wireless/ath/ath9k/htc_drv_init.c +8 -0
index a861896..701f2ef 100644
@@ -744,6 +744,9 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
 	if (ret)
 		goto err_init;
 
+	/* The device may have been unplugged earlier. */
+	priv->op_flags &= ~OP_UNPLUGGED;
+
 	ret = ath9k_init_device(priv, devid);
 	if (ret)
 		goto err_init;
@@ -760,6 +763,11 @@ err_free:
 void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug)
 {
 	if (htc_handle->drv_priv) {
+
+		/* Check if the device has been yanked out. */
+		if (hotunplug)
+			htc_handle->drv_priv->op_flags |= OP_UNPLUGGED;
+
 		ath9k_deinit_device(htc_handle->drv_priv);
 		ath9k_deinit_wmi(htc_handle->drv_priv);
 		ieee80211_free_hw(htc_handle->drv_priv->hw);
drivers/net/wireless/ath/ath9k/wmi.c +3 -0
index dc6c6fc..c688545 100644
@@ -276,6 +276,9 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
 	int time_left, ret = 0;
 	unsigned long flags;
 
+	if (wmi->drv_priv->op_flags & OP_UNPLUGGED)
+		return 0;
+
 	if (!wmi)
 		return -EINVAL;
 
author
#4 lore raw

2010/4/20 Sujith <[email protected]>:

Quoted 11 lines
Quoted 4 lines · Ming Lei

If ATH_DBG_RESET is enabled, you will find the debug messages below[1] during disconnecting.  From the messages, the short hang should be caused by the 'RTC stuck in MAC reset'. Once the patch is applied, no such issue will happen.

I take it that you didn't have ATH_DBG_WMI in your debug mask. A simpler way to fix this issue is to deny all WMI commands once the target has been unplugged - something like the attached patch.

Can you check if it fixes your issue ?

Yes, the patch does fix the issue.

Thanks,

Signature · 1 line
Lei Ming