mirror of
https://github.com/torvalds/linux.git
synced 2024-12-21 02:21:36 +00:00
carl9170: fix spurious restart due to high latency
RX Stress tests of unidirectional bulk traffic with bitrates of up to 220Mbit/s have revealed that the fatal-event recovery logic [which was solely triggered by an out-of-rx-buffer situation] is too aggressive. The new method now "pings" the device and then decides - based on the response - whenever a restart is needed or not. Signed-off-by: Christian Lamparter <chunkeey@googlemail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
e27769059c
commit
e4a668c590
@ -215,7 +215,7 @@ enum carl9170_restart_reasons {
|
||||
CARL9170_RR_TOO_MANY_FIRMWARE_ERRORS,
|
||||
CARL9170_RR_WATCHDOG,
|
||||
CARL9170_RR_STUCK_TX,
|
||||
CARL9170_RR_SLOW_SYSTEM,
|
||||
CARL9170_RR_UNRESPONSIVE_DEVICE,
|
||||
CARL9170_RR_COMMAND_TIMEOUT,
|
||||
CARL9170_RR_TOO_MANY_PHY_ERRORS,
|
||||
CARL9170_RR_LOST_RSP,
|
||||
@ -287,6 +287,7 @@ struct ar9170 {
|
||||
|
||||
/* reset / stuck frames/queue detection */
|
||||
struct work_struct restart_work;
|
||||
struct work_struct ping_work;
|
||||
unsigned int restart_counter;
|
||||
unsigned long queue_stop_timeout[__AR9170_NUM_TXQ];
|
||||
unsigned long max_queue_stop_timeout[__AR9170_NUM_TXQ];
|
||||
|
@ -428,6 +428,7 @@ static void carl9170_cancel_worker(struct ar9170 *ar)
|
||||
cancel_delayed_work_sync(&ar->led_work);
|
||||
#endif /* CONFIG_CARL9170_LEDS */
|
||||
cancel_work_sync(&ar->ps_work);
|
||||
cancel_work_sync(&ar->ping_work);
|
||||
cancel_work_sync(&ar->ampdu_work);
|
||||
}
|
||||
|
||||
@ -533,6 +534,21 @@ void carl9170_restart(struct ar9170 *ar, const enum carl9170_restart_reasons r)
|
||||
*/
|
||||
}
|
||||
|
||||
static void carl9170_ping_work(struct work_struct *work)
|
||||
{
|
||||
struct ar9170 *ar = container_of(work, struct ar9170, ping_work);
|
||||
int err;
|
||||
|
||||
if (!IS_STARTED(ar))
|
||||
return;
|
||||
|
||||
mutex_lock(&ar->mutex);
|
||||
err = carl9170_echo_test(ar, 0xdeadbeef);
|
||||
if (err)
|
||||
carl9170_restart(ar, CARL9170_RR_UNRESPONSIVE_DEVICE);
|
||||
mutex_unlock(&ar->mutex);
|
||||
}
|
||||
|
||||
static int carl9170_init_interface(struct ar9170 *ar,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
@ -1614,6 +1630,7 @@ void *carl9170_alloc(size_t priv_size)
|
||||
skb_queue_head_init(&ar->tx_pending[i]);
|
||||
}
|
||||
INIT_WORK(&ar->ps_work, carl9170_ps_work);
|
||||
INIT_WORK(&ar->ping_work, carl9170_ping_work);
|
||||
INIT_WORK(&ar->restart_work, carl9170_restart_work);
|
||||
INIT_WORK(&ar->ampdu_work, carl9170_ampdu_work);
|
||||
INIT_DELAYED_WORK(&ar->tx_janitor, carl9170_tx_janitor);
|
||||
|
@ -431,7 +431,7 @@ static void carl9170_usb_rx_complete(struct urb *urb)
|
||||
* device.
|
||||
*/
|
||||
|
||||
carl9170_restart(ar, CARL9170_RR_SLOW_SYSTEM);
|
||||
ieee80211_queue_work(ar->hw, &ar->ping_work);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user