ath9k-htc: speedup disconnect handling
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
@@ -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
@@ -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
@@ -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
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
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
Quoted 4 lines · Ming Lei
If
ATH_DBG_RESETis 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
@@ -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
@@ -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
@@ -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 ;
2010/4/20 Sujith <[email protected]>:
Quoted 11 lines
Quoted 4 lines · Ming Lei
If
ATH_DBG_RESETis 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_WMIin 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