diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00usb.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00usb.c | 520 |
1 files changed, 342 insertions, 178 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index ff3a36622d1b..8f90f6268077 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> | 2 | Copyright (C) 2010 Willow Garage <http://www.willowgarage.com> |
3 | Copyright (C) 2004 - 2010 Ivo van Doorn <IvDoorn@gmail.com> | ||
3 | <http://rt2x00.serialmonkey.com> | 4 | <http://rt2x00.serialmonkey.com> |
4 | 5 | ||
5 | This program is free software; you can redistribute it and/or modify | 6 | This program is free software; you can redistribute it and/or modify |
@@ -164,221 +165,399 @@ int rt2x00usb_regbusy_read(struct rt2x00_dev *rt2x00dev, | |||
164 | } | 165 | } |
165 | EXPORT_SYMBOL_GPL(rt2x00usb_regbusy_read); | 166 | EXPORT_SYMBOL_GPL(rt2x00usb_regbusy_read); |
166 | 167 | ||
167 | /* | 168 | |
168 | * TX data handlers. | 169 | struct rt2x00_async_read_data { |
169 | */ | 170 | __le32 reg; |
170 | static void rt2x00usb_interrupt_txdone(struct urb *urb) | 171 | struct usb_ctrlrequest cr; |
172 | struct rt2x00_dev *rt2x00dev; | ||
173 | bool (*callback)(struct rt2x00_dev *, int, u32); | ||
174 | }; | ||
175 | |||
176 | static void rt2x00usb_register_read_async_cb(struct urb *urb) | ||
171 | { | 177 | { |
172 | struct queue_entry *entry = (struct queue_entry *)urb->context; | 178 | struct rt2x00_async_read_data *rd = urb->context; |
173 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 179 | if (rd->callback(rd->rt2x00dev, urb->status, le32_to_cpu(rd->reg))) { |
174 | struct txdone_entry_desc txdesc; | 180 | if (usb_submit_urb(urb, GFP_ATOMIC) < 0) |
181 | kfree(rd); | ||
182 | } else | ||
183 | kfree(rd); | ||
184 | } | ||
185 | |||
186 | void rt2x00usb_register_read_async(struct rt2x00_dev *rt2x00dev, | ||
187 | const unsigned int offset, | ||
188 | bool (*callback)(struct rt2x00_dev*, int, u32)) | ||
189 | { | ||
190 | struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); | ||
191 | struct urb *urb; | ||
192 | struct rt2x00_async_read_data *rd; | ||
193 | |||
194 | rd = kmalloc(sizeof(*rd), GFP_ATOMIC); | ||
195 | if (!rd) | ||
196 | return; | ||
175 | 197 | ||
176 | if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags) || | 198 | urb = usb_alloc_urb(0, GFP_ATOMIC); |
177 | !test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) | 199 | if (!urb) { |
200 | kfree(rd); | ||
178 | return; | 201 | return; |
202 | } | ||
179 | 203 | ||
204 | rd->rt2x00dev = rt2x00dev; | ||
205 | rd->callback = callback; | ||
206 | rd->cr.bRequestType = USB_VENDOR_REQUEST_IN; | ||
207 | rd->cr.bRequest = USB_MULTI_READ; | ||
208 | rd->cr.wValue = 0; | ||
209 | rd->cr.wIndex = cpu_to_le16(offset); | ||
210 | rd->cr.wLength = cpu_to_le16(sizeof(u32)); | ||
211 | |||
212 | usb_fill_control_urb(urb, usb_dev, usb_rcvctrlpipe(usb_dev, 0), | ||
213 | (unsigned char *)(&rd->cr), &rd->reg, sizeof(rd->reg), | ||
214 | rt2x00usb_register_read_async_cb, rd); | ||
215 | if (usb_submit_urb(urb, GFP_ATOMIC) < 0) | ||
216 | kfree(rd); | ||
217 | usb_free_urb(urb); | ||
218 | } | ||
219 | EXPORT_SYMBOL_GPL(rt2x00usb_register_read_async); | ||
220 | |||
221 | /* | ||
222 | * TX data handlers. | ||
223 | */ | ||
224 | static void rt2x00usb_work_txdone_entry(struct queue_entry *entry) | ||
225 | { | ||
180 | /* | 226 | /* |
181 | * Obtain the status about this packet. | 227 | * If the transfer to hardware succeeded, it does not mean the |
182 | * Note that when the status is 0 it does not mean the | ||
183 | * frame was send out correctly. It only means the frame | 228 | * frame was send out correctly. It only means the frame |
184 | * was succesfully pushed to the hardware, we have no | 229 | * was successfully pushed to the hardware, we have no |
185 | * way to determine the transmission status right now. | 230 | * way to determine the transmission status right now. |
186 | * (Only indirectly by looking at the failed TX counters | 231 | * (Only indirectly by looking at the failed TX counters |
187 | * in the register). | 232 | * in the register). |
188 | */ | 233 | */ |
189 | txdesc.flags = 0; | 234 | if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) |
190 | if (!urb->status) | 235 | rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE); |
191 | __set_bit(TXDONE_UNKNOWN, &txdesc.flags); | ||
192 | else | 236 | else |
193 | __set_bit(TXDONE_FAILURE, &txdesc.flags); | 237 | rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN); |
194 | txdesc.retry = 0; | ||
195 | |||
196 | rt2x00lib_txdone(entry, &txdesc); | ||
197 | } | 238 | } |
198 | 239 | ||
199 | static inline void rt2x00usb_kick_tx_entry(struct queue_entry *entry) | 240 | static void rt2x00usb_work_txdone(struct work_struct *work) |
200 | { | 241 | { |
201 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 242 | struct rt2x00_dev *rt2x00dev = |
202 | struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); | 243 | container_of(work, struct rt2x00_dev, txdone_work); |
203 | struct queue_entry_priv_usb *entry_priv = entry->priv_data; | 244 | struct data_queue *queue; |
204 | u32 length; | 245 | struct queue_entry *entry; |
205 | 246 | ||
206 | if (test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags)) { | 247 | tx_queue_for_each(rt2x00dev, queue) { |
207 | /* | 248 | while (!rt2x00queue_empty(queue)) { |
208 | * USB devices cannot blindly pass the skb->len as the | 249 | entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); |
209 | * length of the data to usb_fill_bulk_urb. Pass the skb | ||
210 | * to the driver to determine what the length should be. | ||
211 | */ | ||
212 | length = rt2x00dev->ops->lib->get_tx_data_len(entry); | ||
213 | 250 | ||
214 | usb_fill_bulk_urb(entry_priv->urb, usb_dev, | 251 | if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || |
215 | usb_sndbulkpipe(usb_dev, entry->queue->usb_endpoint), | 252 | !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) |
216 | entry->skb->data, length, | 253 | break; |
217 | rt2x00usb_interrupt_txdone, entry); | ||
218 | 254 | ||
219 | usb_submit_urb(entry_priv->urb, GFP_ATOMIC); | 255 | rt2x00usb_work_txdone_entry(entry); |
256 | } | ||
220 | } | 257 | } |
221 | } | 258 | } |
222 | 259 | ||
223 | void rt2x00usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 260 | static void rt2x00usb_interrupt_txdone(struct urb *urb) |
224 | const enum data_queue_qid qid) | ||
225 | { | 261 | { |
226 | struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, qid); | 262 | struct queue_entry *entry = (struct queue_entry *)urb->context; |
227 | unsigned long irqflags; | 263 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
228 | unsigned int index; | 264 | |
229 | unsigned int index_done; | 265 | if (!test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) |
230 | unsigned int i; | 266 | return; |
267 | |||
268 | if (rt2x00dev->ops->lib->tx_dma_done) | ||
269 | rt2x00dev->ops->lib->tx_dma_done(entry); | ||
231 | 270 | ||
232 | /* | 271 | /* |
233 | * Only protect the range we are going to loop over, | 272 | * Report the frame as DMA done |
234 | * if during our loop a extra entry is set to pending | ||
235 | * it should not be kicked during this run, since it | ||
236 | * is part of another TX operation. | ||
237 | */ | 273 | */ |
238 | spin_lock_irqsave(&queue->lock, irqflags); | 274 | rt2x00lib_dmadone(entry); |
239 | index = queue->index[Q_INDEX]; | ||
240 | index_done = queue->index[Q_INDEX_DONE]; | ||
241 | spin_unlock_irqrestore(&queue->lock, irqflags); | ||
242 | 275 | ||
243 | /* | 276 | /* |
244 | * Start from the TX done pointer, this guarentees that we will | 277 | * Check if the frame was correctly uploaded |
245 | * send out all frames in the correct order. | ||
246 | */ | 278 | */ |
247 | if (index_done < index) { | 279 | if (urb->status) |
248 | for (i = index_done; i < index; i++) | 280 | set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); |
249 | rt2x00usb_kick_tx_entry(&queue->entries[i]); | ||
250 | } else { | ||
251 | for (i = index_done; i < queue->limit; i++) | ||
252 | rt2x00usb_kick_tx_entry(&queue->entries[i]); | ||
253 | 281 | ||
254 | for (i = 0; i < index; i++) | 282 | /* |
255 | rt2x00usb_kick_tx_entry(&queue->entries[i]); | 283 | * Schedule the delayed work for reading the TX status |
256 | } | 284 | * from the device. |
285 | */ | ||
286 | if (!test_bit(REQUIRE_TXSTATUS_FIFO, &rt2x00dev->cap_flags) || | ||
287 | !kfifo_is_empty(&rt2x00dev->txstatus_fifo)) | ||
288 | queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); | ||
257 | } | 289 | } |
258 | EXPORT_SYMBOL_GPL(rt2x00usb_kick_tx_queue); | ||
259 | 290 | ||
260 | void rt2x00usb_kill_tx_queue(struct rt2x00_dev *rt2x00dev, | 291 | static bool rt2x00usb_kick_tx_entry(struct queue_entry *entry, void* data) |
261 | const enum data_queue_qid qid) | ||
262 | { | 292 | { |
263 | struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, qid); | 293 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
264 | struct queue_entry_priv_usb *entry_priv; | 294 | struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); |
265 | struct queue_entry_priv_usb_bcn *bcn_priv; | 295 | struct queue_entry_priv_usb *entry_priv = entry->priv_data; |
266 | unsigned int i; | 296 | u32 length; |
267 | bool kill_guard; | 297 | int status; |
268 | 298 | ||
269 | /* | 299 | if (!test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags) || |
270 | * When killing the beacon queue, we must also kill | 300 | test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) |
271 | * the beacon guard byte. | 301 | return false; |
272 | */ | ||
273 | kill_guard = | ||
274 | (qid == QID_BEACON) && | ||
275 | (test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags)); | ||
276 | 302 | ||
277 | /* | 303 | /* |
278 | * Cancel all entries. | 304 | * USB devices cannot blindly pass the skb->len as the |
305 | * length of the data to usb_fill_bulk_urb. Pass the skb | ||
306 | * to the driver to determine what the length should be. | ||
279 | */ | 307 | */ |
280 | for (i = 0; i < queue->limit; i++) { | 308 | length = rt2x00dev->ops->lib->get_tx_data_len(entry); |
281 | entry_priv = queue->entries[i].priv_data; | 309 | |
282 | usb_kill_urb(entry_priv->urb); | 310 | usb_fill_bulk_urb(entry_priv->urb, usb_dev, |
311 | usb_sndbulkpipe(usb_dev, entry->queue->usb_endpoint), | ||
312 | entry->skb->data, length, | ||
313 | rt2x00usb_interrupt_txdone, entry); | ||
314 | |||
315 | status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC); | ||
316 | if (status) { | ||
317 | if (status == -ENODEV) | ||
318 | clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags); | ||
319 | set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); | ||
320 | rt2x00lib_dmadone(entry); | ||
321 | } | ||
322 | |||
323 | return false; | ||
324 | } | ||
325 | |||
326 | /* | ||
327 | * RX data handlers. | ||
328 | */ | ||
329 | static void rt2x00usb_work_rxdone(struct work_struct *work) | ||
330 | { | ||
331 | struct rt2x00_dev *rt2x00dev = | ||
332 | container_of(work, struct rt2x00_dev, rxdone_work); | ||
333 | struct queue_entry *entry; | ||
334 | struct skb_frame_desc *skbdesc; | ||
335 | u8 rxd[32]; | ||
336 | |||
337 | while (!rt2x00queue_empty(rt2x00dev->rx)) { | ||
338 | entry = rt2x00queue_get_entry(rt2x00dev->rx, Q_INDEX_DONE); | ||
339 | |||
340 | if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || | ||
341 | !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) | ||
342 | break; | ||
283 | 343 | ||
284 | /* | 344 | /* |
285 | * Kill guardian urb (if required by driver). | 345 | * Fill in desc fields of the skb descriptor |
286 | */ | 346 | */ |
287 | if (kill_guard) { | 347 | skbdesc = get_skb_frame_desc(entry->skb); |
288 | bcn_priv = queue->entries[i].priv_data; | 348 | skbdesc->desc = rxd; |
289 | usb_kill_urb(bcn_priv->guardian_urb); | 349 | skbdesc->desc_len = entry->queue->desc_size; |
290 | } | 350 | |
351 | /* | ||
352 | * Send the frame to rt2x00lib for further processing. | ||
353 | */ | ||
354 | rt2x00lib_rxdone(entry); | ||
291 | } | 355 | } |
292 | } | 356 | } |
293 | EXPORT_SYMBOL_GPL(rt2x00usb_kill_tx_queue); | ||
294 | 357 | ||
295 | static void rt2x00usb_watchdog_reset_tx(struct data_queue *queue) | 358 | static void rt2x00usb_interrupt_rxdone(struct urb *urb) |
296 | { | 359 | { |
297 | struct queue_entry_priv_usb *entry_priv; | 360 | struct queue_entry *entry = (struct queue_entry *)urb->context; |
298 | unsigned short threshold = queue->threshold; | 361 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
299 | 362 | ||
300 | WARNING(queue->rt2x00dev, "TX queue %d timed out, invoke reset", queue->qid); | 363 | if (!test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) |
364 | return; | ||
301 | 365 | ||
302 | /* | 366 | /* |
303 | * Temporarily disable the TX queue, this will force mac80211 | 367 | * Report the frame as DMA done |
304 | * to use the other queues until this queue has been restored. | ||
305 | * | ||
306 | * Set the queue threshold to the queue limit. This prevents the | ||
307 | * queue from being enabled during the txdone handler. | ||
308 | */ | 368 | */ |
309 | queue->threshold = queue->limit; | 369 | rt2x00lib_dmadone(entry); |
310 | ieee80211_stop_queue(queue->rt2x00dev->hw, queue->qid); | ||
311 | 370 | ||
312 | /* | 371 | /* |
313 | * Reset all currently uploaded TX frames. | 372 | * Check if the received data is simply too small |
373 | * to be actually valid, or if the urb is signaling | ||
374 | * a problem. | ||
314 | */ | 375 | */ |
315 | while (!rt2x00queue_empty(queue)) { | 376 | if (urb->actual_length < entry->queue->desc_size || urb->status) |
316 | entry_priv = rt2x00queue_get_entry(queue, Q_INDEX_DONE)->priv_data; | 377 | set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); |
317 | usb_kill_urb(entry_priv->urb); | ||
318 | |||
319 | /* | ||
320 | * We need a short delay here to wait for | ||
321 | * the URB to be canceled and invoked the tx_done handler. | ||
322 | */ | ||
323 | udelay(200); | ||
324 | } | ||
325 | 378 | ||
326 | /* | 379 | /* |
327 | * The queue has been reset, and mac80211 is allowed to use the | 380 | * Schedule the delayed work for reading the RX status |
328 | * queue again. | 381 | * from the device. |
329 | */ | 382 | */ |
330 | queue->threshold = threshold; | 383 | queue_work(rt2x00dev->workqueue, &rt2x00dev->rxdone_work); |
331 | ieee80211_wake_queue(queue->rt2x00dev->hw, queue->qid); | ||
332 | } | 384 | } |
333 | 385 | ||
334 | void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev) | 386 | static bool rt2x00usb_kick_rx_entry(struct queue_entry *entry, void* data) |
335 | { | 387 | { |
336 | struct data_queue *queue; | 388 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
389 | struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); | ||
390 | struct queue_entry_priv_usb *entry_priv = entry->priv_data; | ||
391 | int status; | ||
337 | 392 | ||
338 | tx_queue_for_each(rt2x00dev, queue) { | 393 | if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || |
339 | if (rt2x00queue_timeout(queue)) | 394 | test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) |
340 | rt2x00usb_watchdog_reset_tx(queue); | 395 | return false; |
396 | |||
397 | rt2x00lib_dmastart(entry); | ||
398 | |||
399 | usb_fill_bulk_urb(entry_priv->urb, usb_dev, | ||
400 | usb_rcvbulkpipe(usb_dev, entry->queue->usb_endpoint), | ||
401 | entry->skb->data, entry->skb->len, | ||
402 | rt2x00usb_interrupt_rxdone, entry); | ||
403 | |||
404 | status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC); | ||
405 | if (status) { | ||
406 | if (status == -ENODEV) | ||
407 | clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags); | ||
408 | set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); | ||
409 | rt2x00lib_dmadone(entry); | ||
341 | } | 410 | } |
411 | |||
412 | return false; | ||
342 | } | 413 | } |
343 | EXPORT_SYMBOL_GPL(rt2x00usb_watchdog); | ||
344 | 414 | ||
345 | /* | 415 | void rt2x00usb_kick_queue(struct data_queue *queue) |
346 | * RX data handlers. | 416 | { |
347 | */ | 417 | switch (queue->qid) { |
348 | static void rt2x00usb_interrupt_rxdone(struct urb *urb) | 418 | case QID_AC_VO: |
419 | case QID_AC_VI: | ||
420 | case QID_AC_BE: | ||
421 | case QID_AC_BK: | ||
422 | if (!rt2x00queue_empty(queue)) | ||
423 | rt2x00queue_for_each_entry(queue, | ||
424 | Q_INDEX_DONE, | ||
425 | Q_INDEX, | ||
426 | NULL, | ||
427 | rt2x00usb_kick_tx_entry); | ||
428 | break; | ||
429 | case QID_RX: | ||
430 | if (!rt2x00queue_full(queue)) | ||
431 | rt2x00queue_for_each_entry(queue, | ||
432 | Q_INDEX_DONE, | ||
433 | Q_INDEX, | ||
434 | NULL, | ||
435 | rt2x00usb_kick_rx_entry); | ||
436 | break; | ||
437 | default: | ||
438 | break; | ||
439 | } | ||
440 | } | ||
441 | EXPORT_SYMBOL_GPL(rt2x00usb_kick_queue); | ||
442 | |||
443 | static bool rt2x00usb_flush_entry(struct queue_entry *entry, void* data) | ||
349 | { | 444 | { |
350 | struct queue_entry *entry = (struct queue_entry *)urb->context; | ||
351 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 445 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
352 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | 446 | struct queue_entry_priv_usb *entry_priv = entry->priv_data; |
353 | u8 rxd[32]; | 447 | struct queue_entry_priv_usb_bcn *bcn_priv = entry->priv_data; |
354 | 448 | ||
355 | if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags) || | 449 | if (!test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) |
356 | !test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) | 450 | return false; |
357 | return; | ||
358 | 451 | ||
359 | /* | 452 | usb_kill_urb(entry_priv->urb); |
360 | * Check if the received data is simply too small | ||
361 | * to be actually valid, or if the urb is signaling | ||
362 | * a problem. | ||
363 | */ | ||
364 | if (urb->actual_length < entry->queue->desc_size || urb->status) { | ||
365 | set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); | ||
366 | usb_submit_urb(urb, GFP_ATOMIC); | ||
367 | return; | ||
368 | } | ||
369 | 453 | ||
370 | /* | 454 | /* |
371 | * Fill in desc fields of the skb descriptor | 455 | * Kill guardian urb (if required by driver). |
372 | */ | 456 | */ |
373 | skbdesc->desc = rxd; | 457 | if ((entry->queue->qid == QID_BEACON) && |
374 | skbdesc->desc_len = entry->queue->desc_size; | 458 | (test_bit(REQUIRE_BEACON_GUARD, &rt2x00dev->cap_flags))) |
459 | usb_kill_urb(bcn_priv->guardian_urb); | ||
460 | |||
461 | return false; | ||
462 | } | ||
463 | |||
464 | void rt2x00usb_flush_queue(struct data_queue *queue, bool drop) | ||
465 | { | ||
466 | struct work_struct *completion; | ||
467 | unsigned int i; | ||
468 | |||
469 | if (drop) | ||
470 | rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, NULL, | ||
471 | rt2x00usb_flush_entry); | ||
375 | 472 | ||
376 | /* | 473 | /* |
377 | * Send the frame to rt2x00lib for further processing. | 474 | * Obtain the queue completion handler |
378 | */ | 475 | */ |
379 | rt2x00lib_rxdone(rt2x00dev, entry); | 476 | switch (queue->qid) { |
477 | case QID_AC_VO: | ||
478 | case QID_AC_VI: | ||
479 | case QID_AC_BE: | ||
480 | case QID_AC_BK: | ||
481 | completion = &queue->rt2x00dev->txdone_work; | ||
482 | break; | ||
483 | case QID_RX: | ||
484 | completion = &queue->rt2x00dev->rxdone_work; | ||
485 | break; | ||
486 | default: | ||
487 | return; | ||
488 | } | ||
489 | |||
490 | for (i = 0; i < 10; i++) { | ||
491 | /* | ||
492 | * Check if the driver is already done, otherwise we | ||
493 | * have to sleep a little while to give the driver/hw | ||
494 | * the oppurtunity to complete interrupt process itself. | ||
495 | */ | ||
496 | if (rt2x00queue_empty(queue)) | ||
497 | break; | ||
498 | |||
499 | /* | ||
500 | * Schedule the completion handler manually, when this | ||
501 | * worker function runs, it should cleanup the queue. | ||
502 | */ | ||
503 | queue_work(queue->rt2x00dev->workqueue, completion); | ||
504 | |||
505 | /* | ||
506 | * Wait for a little while to give the driver | ||
507 | * the oppurtunity to recover itself. | ||
508 | */ | ||
509 | msleep(10); | ||
510 | } | ||
511 | } | ||
512 | EXPORT_SYMBOL_GPL(rt2x00usb_flush_queue); | ||
513 | |||
514 | static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue) | ||
515 | { | ||
516 | WARNING(queue->rt2x00dev, "TX queue %d DMA timed out," | ||
517 | " invoke forced forced reset\n", queue->qid); | ||
518 | |||
519 | rt2x00queue_flush_queue(queue, true); | ||
520 | } | ||
521 | |||
522 | static void rt2x00usb_watchdog_tx_status(struct data_queue *queue) | ||
523 | { | ||
524 | WARNING(queue->rt2x00dev, "TX queue %d status timed out," | ||
525 | " invoke forced tx handler\n", queue->qid); | ||
526 | |||
527 | queue_work(queue->rt2x00dev->workqueue, &queue->rt2x00dev->txdone_work); | ||
380 | } | 528 | } |
381 | 529 | ||
530 | static int rt2x00usb_status_timeout(struct data_queue *queue) | ||
531 | { | ||
532 | struct queue_entry *entry; | ||
533 | |||
534 | entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); | ||
535 | return rt2x00queue_status_timeout(entry); | ||
536 | } | ||
537 | |||
538 | static int rt2x00usb_dma_timeout(struct data_queue *queue) | ||
539 | { | ||
540 | struct queue_entry *entry; | ||
541 | |||
542 | entry = rt2x00queue_get_entry(queue, Q_INDEX_DMA_DONE); | ||
543 | return rt2x00queue_dma_timeout(entry); | ||
544 | } | ||
545 | |||
546 | void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev) | ||
547 | { | ||
548 | struct data_queue *queue; | ||
549 | |||
550 | tx_queue_for_each(rt2x00dev, queue) { | ||
551 | if (!rt2x00queue_empty(queue)) { | ||
552 | if (rt2x00usb_dma_timeout(queue)) | ||
553 | rt2x00usb_watchdog_tx_dma(queue); | ||
554 | if (rt2x00usb_status_timeout(queue)) | ||
555 | rt2x00usb_watchdog_tx_status(queue); | ||
556 | } | ||
557 | } | ||
558 | } | ||
559 | EXPORT_SYMBOL_GPL(rt2x00usb_watchdog); | ||
560 | |||
382 | /* | 561 | /* |
383 | * Radio handlers | 562 | * Radio handlers |
384 | */ | 563 | */ |
@@ -386,12 +565,6 @@ void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
386 | { | 565 | { |
387 | rt2x00usb_vendor_request_sw(rt2x00dev, USB_RX_CONTROL, 0, 0, | 566 | rt2x00usb_vendor_request_sw(rt2x00dev, USB_RX_CONTROL, 0, 0, |
388 | REGISTER_TIMEOUT); | 567 | REGISTER_TIMEOUT); |
389 | |||
390 | /* | ||
391 | * The USB version of kill_tx_queue also works | ||
392 | * on the RX queue. | ||
393 | */ | ||
394 | rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev, QID_RX); | ||
395 | } | 568 | } |
396 | EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio); | 569 | EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio); |
397 | 570 | ||
@@ -400,22 +573,10 @@ EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio); | |||
400 | */ | 573 | */ |
401 | void rt2x00usb_clear_entry(struct queue_entry *entry) | 574 | void rt2x00usb_clear_entry(struct queue_entry *entry) |
402 | { | 575 | { |
403 | struct usb_device *usb_dev = | 576 | entry->flags = 0; |
404 | to_usb_device_intf(entry->queue->rt2x00dev->dev); | ||
405 | struct queue_entry_priv_usb *entry_priv = entry->priv_data; | ||
406 | int pipe; | ||
407 | |||
408 | if (entry->queue->qid == QID_RX) { | ||
409 | pipe = usb_rcvbulkpipe(usb_dev, entry->queue->usb_endpoint); | ||
410 | usb_fill_bulk_urb(entry_priv->urb, usb_dev, pipe, | ||
411 | entry->skb->data, entry->skb->len, | ||
412 | rt2x00usb_interrupt_rxdone, entry); | ||
413 | 577 | ||
414 | set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); | 578 | if (entry->queue->qid == QID_RX) |
415 | usb_submit_urb(entry_priv->urb, GFP_ATOMIC); | 579 | rt2x00usb_kick_rx_entry(entry, NULL); |
416 | } else { | ||
417 | entry->flags = 0; | ||
418 | } | ||
419 | } | 580 | } |
420 | EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry); | 581 | EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry); |
421 | 582 | ||
@@ -489,9 +650,9 @@ static int rt2x00usb_find_endpoints(struct rt2x00_dev *rt2x00dev) | |||
489 | return 0; | 650 | return 0; |
490 | } | 651 | } |
491 | 652 | ||
492 | static int rt2x00usb_alloc_urb(struct rt2x00_dev *rt2x00dev, | 653 | static int rt2x00usb_alloc_entries(struct data_queue *queue) |
493 | struct data_queue *queue) | ||
494 | { | 654 | { |
655 | struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; | ||
495 | struct queue_entry_priv_usb *entry_priv; | 656 | struct queue_entry_priv_usb *entry_priv; |
496 | struct queue_entry_priv_usb_bcn *bcn_priv; | 657 | struct queue_entry_priv_usb_bcn *bcn_priv; |
497 | unsigned int i; | 658 | unsigned int i; |
@@ -508,8 +669,8 @@ static int rt2x00usb_alloc_urb(struct rt2x00_dev *rt2x00dev, | |||
508 | * no guardian byte was required for the beacon, | 669 | * no guardian byte was required for the beacon, |
509 | * then we are done. | 670 | * then we are done. |
510 | */ | 671 | */ |
511 | if (rt2x00dev->bcn != queue || | 672 | if (queue->qid != QID_BEACON || |
512 | !test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags)) | 673 | !test_bit(REQUIRE_BEACON_GUARD, &rt2x00dev->cap_flags)) |
513 | return 0; | 674 | return 0; |
514 | 675 | ||
515 | for (i = 0; i < queue->limit; i++) { | 676 | for (i = 0; i < queue->limit; i++) { |
@@ -522,9 +683,9 @@ static int rt2x00usb_alloc_urb(struct rt2x00_dev *rt2x00dev, | |||
522 | return 0; | 683 | return 0; |
523 | } | 684 | } |
524 | 685 | ||
525 | static void rt2x00usb_free_urb(struct rt2x00_dev *rt2x00dev, | 686 | static void rt2x00usb_free_entries(struct data_queue *queue) |
526 | struct data_queue *queue) | ||
527 | { | 687 | { |
688 | struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; | ||
528 | struct queue_entry_priv_usb *entry_priv; | 689 | struct queue_entry_priv_usb *entry_priv; |
529 | struct queue_entry_priv_usb_bcn *bcn_priv; | 690 | struct queue_entry_priv_usb_bcn *bcn_priv; |
530 | unsigned int i; | 691 | unsigned int i; |
@@ -543,8 +704,8 @@ static void rt2x00usb_free_urb(struct rt2x00_dev *rt2x00dev, | |||
543 | * no guardian byte was required for the beacon, | 704 | * no guardian byte was required for the beacon, |
544 | * then we are done. | 705 | * then we are done. |
545 | */ | 706 | */ |
546 | if (rt2x00dev->bcn != queue || | 707 | if (queue->qid != QID_BEACON || |
547 | !test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags)) | 708 | !test_bit(REQUIRE_BEACON_GUARD, &rt2x00dev->cap_flags)) |
548 | return; | 709 | return; |
549 | 710 | ||
550 | for (i = 0; i < queue->limit; i++) { | 711 | for (i = 0; i < queue->limit; i++) { |
@@ -570,7 +731,7 @@ int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev) | |||
570 | * Allocate DMA | 731 | * Allocate DMA |
571 | */ | 732 | */ |
572 | queue_for_each(rt2x00dev, queue) { | 733 | queue_for_each(rt2x00dev, queue) { |
573 | status = rt2x00usb_alloc_urb(rt2x00dev, queue); | 734 | status = rt2x00usb_alloc_entries(queue); |
574 | if (status) | 735 | if (status) |
575 | goto exit; | 736 | goto exit; |
576 | } | 737 | } |
@@ -589,7 +750,7 @@ void rt2x00usb_uninitialize(struct rt2x00_dev *rt2x00dev) | |||
589 | struct data_queue *queue; | 750 | struct data_queue *queue; |
590 | 751 | ||
591 | queue_for_each(rt2x00dev, queue) | 752 | queue_for_each(rt2x00dev, queue) |
592 | rt2x00usb_free_urb(rt2x00dev, queue); | 753 | rt2x00usb_free_entries(queue); |
593 | } | 754 | } |
594 | EXPORT_SYMBOL_GPL(rt2x00usb_uninitialize); | 755 | EXPORT_SYMBOL_GPL(rt2x00usb_uninitialize); |
595 | 756 | ||
@@ -633,10 +794,9 @@ exit: | |||
633 | } | 794 | } |
634 | 795 | ||
635 | int rt2x00usb_probe(struct usb_interface *usb_intf, | 796 | int rt2x00usb_probe(struct usb_interface *usb_intf, |
636 | const struct usb_device_id *id) | 797 | const struct rt2x00_ops *ops) |
637 | { | 798 | { |
638 | struct usb_device *usb_dev = interface_to_usbdev(usb_intf); | 799 | struct usb_device *usb_dev = interface_to_usbdev(usb_intf); |
639 | struct rt2x00_ops *ops = (struct rt2x00_ops *)id->driver_info; | ||
640 | struct ieee80211_hw *hw; | 800 | struct ieee80211_hw *hw; |
641 | struct rt2x00_dev *rt2x00dev; | 801 | struct rt2x00_dev *rt2x00dev; |
642 | int retval; | 802 | int retval; |
@@ -659,6 +819,10 @@ int rt2x00usb_probe(struct usb_interface *usb_intf, | |||
659 | 819 | ||
660 | rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_USB); | 820 | rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_USB); |
661 | 821 | ||
822 | INIT_WORK(&rt2x00dev->rxdone_work, rt2x00usb_work_rxdone); | ||
823 | INIT_WORK(&rt2x00dev->txdone_work, rt2x00usb_work_txdone); | ||
824 | init_timer(&rt2x00dev->txstatus_timer); | ||
825 | |||
662 | retval = rt2x00usb_alloc_reg(rt2x00dev); | 826 | retval = rt2x00usb_alloc_reg(rt2x00dev); |
663 | if (retval) | 827 | if (retval) |
664 | goto exit_free_device; | 828 | goto exit_free_device; |