aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c66
1 files changed, 40 insertions, 26 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index aec6440d364a..4c5ae3d45625 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -208,8 +208,7 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
208 struct queue_entry *entry = (struct queue_entry *)urb->context; 208 struct queue_entry *entry = (struct queue_entry *)urb->context;
209 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 209 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
210 210
211 if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags) || 211 if (!__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
212 !__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
213 return; 212 return;
214 213
215 /* 214 /*
@@ -227,7 +226,9 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
227 * Schedule the delayed work for reading the TX status 226 * Schedule the delayed work for reading the TX status
228 * from the device. 227 * from the device.
229 */ 228 */
230 ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->txdone_work); 229 if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) &&
230 test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
231 ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->txdone_work);
231} 232}
232 233
233static void rt2x00usb_kick_tx_entry(struct queue_entry *entry) 234static void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
@@ -279,6 +280,14 @@ static void rt2x00usb_kill_tx_entry(struct queue_entry *entry)
279 if ((entry->queue->qid == QID_BEACON) && 280 if ((entry->queue->qid == QID_BEACON) &&
280 (test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags))) 281 (test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags)))
281 usb_kill_urb(bcn_priv->guardian_urb); 282 usb_kill_urb(bcn_priv->guardian_urb);
283
284 /*
285 * We need a short delay here to wait for
286 * the URB to be canceled
287 */
288 do {
289 udelay(100);
290 } while (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags));
282} 291}
283 292
284void rt2x00usb_kill_tx_queue(struct data_queue *queue) 293void rt2x00usb_kill_tx_queue(struct data_queue *queue)
@@ -290,8 +299,7 @@ EXPORT_SYMBOL_GPL(rt2x00usb_kill_tx_queue);
290 299
291static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue) 300static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue)
292{ 301{
293 struct queue_entry *entry; 302 struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
294 struct queue_entry_priv_usb *entry_priv;
295 unsigned short threshold = queue->threshold; 303 unsigned short threshold = queue->threshold;
296 304
297 WARNING(queue->rt2x00dev, "TX queue %d DMA timed out," 305 WARNING(queue->rt2x00dev, "TX queue %d DMA timed out,"
@@ -305,28 +313,33 @@ static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue)
305 * queue from being enabled during the txdone handler. 313 * queue from being enabled during the txdone handler.
306 */ 314 */
307 queue->threshold = queue->limit; 315 queue->threshold = queue->limit;
308 ieee80211_stop_queue(queue->rt2x00dev->hw, queue->qid); 316 ieee80211_stop_queue(rt2x00dev->hw, queue->qid);
309 317
310 /* 318 /*
311 * Reset all currently uploaded TX frames. 319 * Kill all entries in the queue, afterwards we need to
320 * wait a bit for all URBs to be cancelled.
312 */ 321 */
313 while (!rt2x00queue_empty(queue)) { 322 rt2x00usb_kill_tx_queue(queue);
314 entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
315 entry_priv = entry->priv_data;
316 usb_kill_urb(entry_priv->urb);
317 323
318 /* 324 /*
319 * We need a short delay here to wait for 325 * In case that a driver has overriden the txdone_work
320 * the URB to be canceled 326 * function, we invoke the TX done through there.
321 */ 327 */
322 do { 328 rt2x00dev->txdone_work.func(&rt2x00dev->txdone_work);
323 udelay(100);
324 } while (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags));
325 329
326 /* 330 /*
327 * Invoke the TX done handler 331 * Security measure: if the driver did override the
328 */ 332 * txdone_work function, and the hardware did arrive
329 rt2x00usb_work_txdone_entry(entry); 333 * in a state which causes it to malfunction, it is
334 * possible that the driver couldn't handle the txdone
335 * event correctly. So after giving the driver the
336 * chance to cleanup, we now force a cleanup of any
337 * leftovers.
338 */
339 if (!rt2x00queue_empty(queue)) {
340 WARNING(queue->rt2x00dev, "TX queue %d DMA timed out,"
341 " status handling failed, invoke hard reset", queue->qid);
342 rt2x00usb_work_txdone(&rt2x00dev->txdone_work);
330 } 343 }
331 344
332 /* 345 /*
@@ -334,7 +347,7 @@ static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue)
334 * queue again. 347 * queue again.
335 */ 348 */
336 queue->threshold = threshold; 349 queue->threshold = threshold;
337 ieee80211_wake_queue(queue->rt2x00dev->hw, queue->qid); 350 ieee80211_wake_queue(rt2x00dev->hw, queue->qid);
338} 351}
339 352
340static void rt2x00usb_watchdog_tx_status(struct data_queue *queue) 353static void rt2x00usb_watchdog_tx_status(struct data_queue *queue)
@@ -394,8 +407,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
394 struct queue_entry *entry = (struct queue_entry *)urb->context; 407 struct queue_entry *entry = (struct queue_entry *)urb->context;
395 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 408 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
396 409
397 if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags) || 410 if (!__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
398 !__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
399 return; 411 return;
400 412
401 /* 413 /*
@@ -415,7 +427,9 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
415 * Schedule the delayed work for reading the RX status 427 * Schedule the delayed work for reading the RX status
416 * from the device. 428 * from the device.
417 */ 429 */
418 ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->rxdone_work); 430 if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) &&
431 test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
432 ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->rxdone_work);
419} 433}
420 434
421/* 435/*