diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/hif_usb.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/hif_usb.c | 334 |
1 files changed, 236 insertions, 98 deletions
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 2d10239ce82..2e3a33a5340 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c | |||
@@ -17,11 +17,9 @@ | |||
17 | #include "htc.h" | 17 | #include "htc.h" |
18 | 18 | ||
19 | /* identify firmware images */ | 19 | /* identify firmware images */ |
20 | #define FIRMWARE_AR7010 "ar7010.fw" | 20 | #define FIRMWARE_AR7010_1_1 "htc_7010.fw" |
21 | #define FIRMWARE_AR7010_1_1 "ar7010_1_1.fw" | 21 | #define FIRMWARE_AR9271 "htc_9271.fw" |
22 | #define FIRMWARE_AR9271 "ar9271.fw" | ||
23 | 22 | ||
24 | MODULE_FIRMWARE(FIRMWARE_AR7010); | ||
25 | MODULE_FIRMWARE(FIRMWARE_AR7010_1_1); | 23 | MODULE_FIRMWARE(FIRMWARE_AR7010_1_1); |
26 | MODULE_FIRMWARE(FIRMWARE_AR9271); | 24 | MODULE_FIRMWARE(FIRMWARE_AR9271); |
27 | 25 | ||
@@ -80,7 +78,7 @@ static void hif_usb_regout_cb(struct urb *urb) | |||
80 | 78 | ||
81 | if (cmd) { | 79 | if (cmd) { |
82 | ath9k_htc_txcompletion_cb(cmd->hif_dev->htc_handle, | 80 | ath9k_htc_txcompletion_cb(cmd->hif_dev->htc_handle, |
83 | cmd->skb, 1); | 81 | cmd->skb, true); |
84 | kfree(cmd); | 82 | kfree(cmd); |
85 | } | 83 | } |
86 | 84 | ||
@@ -126,6 +124,90 @@ static int hif_usb_send_regout(struct hif_device_usb *hif_dev, | |||
126 | return ret; | 124 | return ret; |
127 | } | 125 | } |
128 | 126 | ||
127 | static void hif_usb_mgmt_cb(struct urb *urb) | ||
128 | { | ||
129 | struct cmd_buf *cmd = (struct cmd_buf *)urb->context; | ||
130 | struct hif_device_usb *hif_dev = cmd->hif_dev; | ||
131 | bool txok = true; | ||
132 | |||
133 | if (!cmd || !cmd->skb || !cmd->hif_dev) | ||
134 | return; | ||
135 | |||
136 | switch (urb->status) { | ||
137 | case 0: | ||
138 | break; | ||
139 | case -ENOENT: | ||
140 | case -ECONNRESET: | ||
141 | case -ENODEV: | ||
142 | case -ESHUTDOWN: | ||
143 | txok = false; | ||
144 | |||
145 | /* | ||
146 | * If the URBs are being flushed, no need to complete | ||
147 | * this packet. | ||
148 | */ | ||
149 | spin_lock(&hif_dev->tx.tx_lock); | ||
150 | if (hif_dev->tx.flags & HIF_USB_TX_FLUSH) { | ||
151 | spin_unlock(&hif_dev->tx.tx_lock); | ||
152 | dev_kfree_skb_any(cmd->skb); | ||
153 | kfree(cmd); | ||
154 | return; | ||
155 | } | ||
156 | spin_unlock(&hif_dev->tx.tx_lock); | ||
157 | |||
158 | break; | ||
159 | default: | ||
160 | txok = false; | ||
161 | break; | ||
162 | } | ||
163 | |||
164 | skb_pull(cmd->skb, 4); | ||
165 | ath9k_htc_txcompletion_cb(cmd->hif_dev->htc_handle, | ||
166 | cmd->skb, txok); | ||
167 | kfree(cmd); | ||
168 | } | ||
169 | |||
170 | static int hif_usb_send_mgmt(struct hif_device_usb *hif_dev, | ||
171 | struct sk_buff *skb) | ||
172 | { | ||
173 | struct urb *urb; | ||
174 | struct cmd_buf *cmd; | ||
175 | int ret = 0; | ||
176 | __le16 *hdr; | ||
177 | |||
178 | urb = usb_alloc_urb(0, GFP_ATOMIC); | ||
179 | if (urb == NULL) | ||
180 | return -ENOMEM; | ||
181 | |||
182 | cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC); | ||
183 | if (cmd == NULL) { | ||
184 | usb_free_urb(urb); | ||
185 | return -ENOMEM; | ||
186 | } | ||
187 | |||
188 | cmd->skb = skb; | ||
189 | cmd->hif_dev = hif_dev; | ||
190 | |||
191 | hdr = (__le16 *) skb_push(skb, 4); | ||
192 | *hdr++ = cpu_to_le16(skb->len - 4); | ||
193 | *hdr++ = cpu_to_le16(ATH_USB_TX_STREAM_MODE_TAG); | ||
194 | |||
195 | usb_fill_bulk_urb(urb, hif_dev->udev, | ||
196 | usb_sndbulkpipe(hif_dev->udev, USB_WLAN_TX_PIPE), | ||
197 | skb->data, skb->len, | ||
198 | hif_usb_mgmt_cb, cmd); | ||
199 | |||
200 | usb_anchor_urb(urb, &hif_dev->mgmt_submitted); | ||
201 | ret = usb_submit_urb(urb, GFP_ATOMIC); | ||
202 | if (ret) { | ||
203 | usb_unanchor_urb(urb); | ||
204 | kfree(cmd); | ||
205 | } | ||
206 | usb_free_urb(urb); | ||
207 | |||
208 | return ret; | ||
209 | } | ||
210 | |||
129 | static inline void ath9k_skb_queue_purge(struct hif_device_usb *hif_dev, | 211 | static inline void ath9k_skb_queue_purge(struct hif_device_usb *hif_dev, |
130 | struct sk_buff_head *list) | 212 | struct sk_buff_head *list) |
131 | { | 213 | { |
@@ -133,7 +215,22 @@ static inline void ath9k_skb_queue_purge(struct hif_device_usb *hif_dev, | |||
133 | 215 | ||
134 | while ((skb = __skb_dequeue(list)) != NULL) { | 216 | while ((skb = __skb_dequeue(list)) != NULL) { |
135 | dev_kfree_skb_any(skb); | 217 | dev_kfree_skb_any(skb); |
136 | TX_STAT_INC(skb_dropped); | 218 | } |
219 | } | ||
220 | |||
221 | static inline void ath9k_skb_queue_complete(struct hif_device_usb *hif_dev, | ||
222 | struct sk_buff_head *queue, | ||
223 | bool txok) | ||
224 | { | ||
225 | struct sk_buff *skb; | ||
226 | |||
227 | while ((skb = __skb_dequeue(queue)) != NULL) { | ||
228 | ath9k_htc_txcompletion_cb(hif_dev->htc_handle, | ||
229 | skb, txok); | ||
230 | if (txok) | ||
231 | TX_STAT_INC(skb_success); | ||
232 | else | ||
233 | TX_STAT_INC(skb_failed); | ||
137 | } | 234 | } |
138 | } | 235 | } |
139 | 236 | ||
@@ -141,7 +238,7 @@ static void hif_usb_tx_cb(struct urb *urb) | |||
141 | { | 238 | { |
142 | struct tx_buf *tx_buf = (struct tx_buf *) urb->context; | 239 | struct tx_buf *tx_buf = (struct tx_buf *) urb->context; |
143 | struct hif_device_usb *hif_dev; | 240 | struct hif_device_usb *hif_dev; |
144 | struct sk_buff *skb; | 241 | bool txok = true; |
145 | 242 | ||
146 | if (!tx_buf || !tx_buf->hif_dev) | 243 | if (!tx_buf || !tx_buf->hif_dev) |
147 | return; | 244 | return; |
@@ -155,10 +252,7 @@ static void hif_usb_tx_cb(struct urb *urb) | |||
155 | case -ECONNRESET: | 252 | case -ECONNRESET: |
156 | case -ENODEV: | 253 | case -ENODEV: |
157 | case -ESHUTDOWN: | 254 | case -ESHUTDOWN: |
158 | /* | 255 | txok = false; |
159 | * The URB has been killed, free the SKBs. | ||
160 | */ | ||
161 | ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue); | ||
162 | 256 | ||
163 | /* | 257 | /* |
164 | * If the URBs are being flushed, no need to add this | 258 | * If the URBs are being flushed, no need to add this |
@@ -167,41 +261,19 @@ static void hif_usb_tx_cb(struct urb *urb) | |||
167 | spin_lock(&hif_dev->tx.tx_lock); | 261 | spin_lock(&hif_dev->tx.tx_lock); |
168 | if (hif_dev->tx.flags & HIF_USB_TX_FLUSH) { | 262 | if (hif_dev->tx.flags & HIF_USB_TX_FLUSH) { |
169 | spin_unlock(&hif_dev->tx.tx_lock); | 263 | spin_unlock(&hif_dev->tx.tx_lock); |
264 | ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue); | ||
170 | return; | 265 | return; |
171 | } | 266 | } |
172 | spin_unlock(&hif_dev->tx.tx_lock); | 267 | spin_unlock(&hif_dev->tx.tx_lock); |
173 | 268 | ||
174 | /* | 269 | break; |
175 | * In the stop() case, this URB has to be added to | ||
176 | * the free list. | ||
177 | */ | ||
178 | goto add_free; | ||
179 | default: | 270 | default: |
271 | txok = false; | ||
180 | break; | 272 | break; |
181 | } | 273 | } |
182 | 274 | ||
183 | /* | 275 | ath9k_skb_queue_complete(hif_dev, &tx_buf->skb_queue, txok); |
184 | * Check if TX has been stopped, this is needed because | ||
185 | * this CB could have been invoked just after the TX lock | ||
186 | * was released in hif_stop() and kill_urb() hasn't been | ||
187 | * called yet. | ||
188 | */ | ||
189 | spin_lock(&hif_dev->tx.tx_lock); | ||
190 | if (hif_dev->tx.flags & HIF_USB_TX_STOP) { | ||
191 | spin_unlock(&hif_dev->tx.tx_lock); | ||
192 | ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue); | ||
193 | goto add_free; | ||
194 | } | ||
195 | spin_unlock(&hif_dev->tx.tx_lock); | ||
196 | |||
197 | /* Complete the queued SKBs. */ | ||
198 | while ((skb = __skb_dequeue(&tx_buf->skb_queue)) != NULL) { | ||
199 | ath9k_htc_txcompletion_cb(hif_dev->htc_handle, | ||
200 | skb, 1); | ||
201 | TX_STAT_INC(skb_completed); | ||
202 | } | ||
203 | 276 | ||
204 | add_free: | ||
205 | /* Re-initialize the SKB queue */ | 277 | /* Re-initialize the SKB queue */ |
206 | tx_buf->len = tx_buf->offset = 0; | 278 | tx_buf->len = tx_buf->offset = 0; |
207 | __skb_queue_head_init(&tx_buf->skb_queue); | 279 | __skb_queue_head_init(&tx_buf->skb_queue); |
@@ -274,7 +346,7 @@ static int __hif_usb_tx(struct hif_device_usb *hif_dev) | |||
274 | ret = usb_submit_urb(tx_buf->urb, GFP_ATOMIC); | 346 | ret = usb_submit_urb(tx_buf->urb, GFP_ATOMIC); |
275 | if (ret) { | 347 | if (ret) { |
276 | tx_buf->len = tx_buf->offset = 0; | 348 | tx_buf->len = tx_buf->offset = 0; |
277 | ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue); | 349 | ath9k_skb_queue_complete(hif_dev, &tx_buf->skb_queue, false); |
278 | __skb_queue_head_init(&tx_buf->skb_queue); | 350 | __skb_queue_head_init(&tx_buf->skb_queue); |
279 | list_move_tail(&tx_buf->list, &hif_dev->tx.tx_buf); | 351 | list_move_tail(&tx_buf->list, &hif_dev->tx.tx_buf); |
280 | hif_dev->tx.tx_buf_cnt++; | 352 | hif_dev->tx.tx_buf_cnt++; |
@@ -286,10 +358,11 @@ static int __hif_usb_tx(struct hif_device_usb *hif_dev) | |||
286 | return ret; | 358 | return ret; |
287 | } | 359 | } |
288 | 360 | ||
289 | static int hif_usb_send_tx(struct hif_device_usb *hif_dev, struct sk_buff *skb, | 361 | static int hif_usb_send_tx(struct hif_device_usb *hif_dev, struct sk_buff *skb) |
290 | struct ath9k_htc_tx_ctl *tx_ctl) | ||
291 | { | 362 | { |
363 | struct ath9k_htc_tx_ctl *tx_ctl; | ||
292 | unsigned long flags; | 364 | unsigned long flags; |
365 | int ret = 0; | ||
293 | 366 | ||
294 | spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); | 367 | spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); |
295 | 368 | ||
@@ -304,26 +377,36 @@ static int hif_usb_send_tx(struct hif_device_usb *hif_dev, struct sk_buff *skb, | |||
304 | return -ENOMEM; | 377 | return -ENOMEM; |
305 | } | 378 | } |
306 | 379 | ||
307 | __skb_queue_tail(&hif_dev->tx.tx_skb_queue, skb); | 380 | spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); |
308 | hif_dev->tx.tx_skb_cnt++; | ||
309 | 381 | ||
310 | /* Send normal frames immediately */ | 382 | tx_ctl = HTC_SKB_CB(skb); |
311 | if (!tx_ctl || (tx_ctl && (tx_ctl->type == ATH9K_HTC_NORMAL))) | 383 | |
312 | __hif_usb_tx(hif_dev); | 384 | /* Mgmt/Beacon frames don't use the TX buffer pool */ |
385 | if ((tx_ctl->type == ATH9K_HTC_MGMT) || | ||
386 | (tx_ctl->type == ATH9K_HTC_BEACON)) { | ||
387 | ret = hif_usb_send_mgmt(hif_dev, skb); | ||
388 | } | ||
389 | |||
390 | spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); | ||
391 | |||
392 | if ((tx_ctl->type == ATH9K_HTC_NORMAL) || | ||
393 | (tx_ctl->type == ATH9K_HTC_AMPDU)) { | ||
394 | __skb_queue_tail(&hif_dev->tx.tx_skb_queue, skb); | ||
395 | hif_dev->tx.tx_skb_cnt++; | ||
396 | } | ||
313 | 397 | ||
314 | /* Check if AMPDUs have to be sent immediately */ | 398 | /* Check if AMPDUs have to be sent immediately */ |
315 | if (tx_ctl && (tx_ctl->type == ATH9K_HTC_AMPDU) && | 399 | if ((hif_dev->tx.tx_buf_cnt == MAX_TX_URB_NUM) && |
316 | (hif_dev->tx.tx_buf_cnt == MAX_TX_URB_NUM) && | ||
317 | (hif_dev->tx.tx_skb_cnt < 2)) { | 400 | (hif_dev->tx.tx_skb_cnt < 2)) { |
318 | __hif_usb_tx(hif_dev); | 401 | __hif_usb_tx(hif_dev); |
319 | } | 402 | } |
320 | 403 | ||
321 | spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); | 404 | spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); |
322 | 405 | ||
323 | return 0; | 406 | return ret; |
324 | } | 407 | } |
325 | 408 | ||
326 | static void hif_usb_start(void *hif_handle, u8 pipe_id) | 409 | static void hif_usb_start(void *hif_handle) |
327 | { | 410 | { |
328 | struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle; | 411 | struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle; |
329 | unsigned long flags; | 412 | unsigned long flags; |
@@ -335,14 +418,14 @@ static void hif_usb_start(void *hif_handle, u8 pipe_id) | |||
335 | spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); | 418 | spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); |
336 | } | 419 | } |
337 | 420 | ||
338 | static void hif_usb_stop(void *hif_handle, u8 pipe_id) | 421 | static void hif_usb_stop(void *hif_handle) |
339 | { | 422 | { |
340 | struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle; | 423 | struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle; |
341 | struct tx_buf *tx_buf = NULL, *tx_buf_tmp = NULL; | 424 | struct tx_buf *tx_buf = NULL, *tx_buf_tmp = NULL; |
342 | unsigned long flags; | 425 | unsigned long flags; |
343 | 426 | ||
344 | spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); | 427 | spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); |
345 | ath9k_skb_queue_purge(hif_dev, &hif_dev->tx.tx_skb_queue); | 428 | ath9k_skb_queue_complete(hif_dev, &hif_dev->tx.tx_skb_queue, false); |
346 | hif_dev->tx.tx_skb_cnt = 0; | 429 | hif_dev->tx.tx_skb_cnt = 0; |
347 | hif_dev->tx.flags |= HIF_USB_TX_STOP; | 430 | hif_dev->tx.flags |= HIF_USB_TX_STOP; |
348 | spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); | 431 | spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); |
@@ -352,17 +435,18 @@ static void hif_usb_stop(void *hif_handle, u8 pipe_id) | |||
352 | &hif_dev->tx.tx_pending, list) { | 435 | &hif_dev->tx.tx_pending, list) { |
353 | usb_kill_urb(tx_buf->urb); | 436 | usb_kill_urb(tx_buf->urb); |
354 | } | 437 | } |
438 | |||
439 | usb_kill_anchored_urbs(&hif_dev->mgmt_submitted); | ||
355 | } | 440 | } |
356 | 441 | ||
357 | static int hif_usb_send(void *hif_handle, u8 pipe_id, struct sk_buff *skb, | 442 | static int hif_usb_send(void *hif_handle, u8 pipe_id, struct sk_buff *skb) |
358 | struct ath9k_htc_tx_ctl *tx_ctl) | ||
359 | { | 443 | { |
360 | struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle; | 444 | struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle; |
361 | int ret = 0; | 445 | int ret = 0; |
362 | 446 | ||
363 | switch (pipe_id) { | 447 | switch (pipe_id) { |
364 | case USB_WLAN_TX_PIPE: | 448 | case USB_WLAN_TX_PIPE: |
365 | ret = hif_usb_send_tx(hif_dev, skb, tx_ctl); | 449 | ret = hif_usb_send_tx(hif_dev, skb); |
366 | break; | 450 | break; |
367 | case USB_REG_OUT_PIPE: | 451 | case USB_REG_OUT_PIPE: |
368 | ret = hif_usb_send_regout(hif_dev, skb); | 452 | ret = hif_usb_send_regout(hif_dev, skb); |
@@ -377,6 +461,40 @@ static int hif_usb_send(void *hif_handle, u8 pipe_id, struct sk_buff *skb, | |||
377 | return ret; | 461 | return ret; |
378 | } | 462 | } |
379 | 463 | ||
464 | static inline bool check_index(struct sk_buff *skb, u8 idx) | ||
465 | { | ||
466 | struct ath9k_htc_tx_ctl *tx_ctl; | ||
467 | |||
468 | tx_ctl = HTC_SKB_CB(skb); | ||
469 | |||
470 | if ((tx_ctl->type == ATH9K_HTC_AMPDU) && | ||
471 | (tx_ctl->sta_idx == idx)) | ||
472 | return true; | ||
473 | |||
474 | return false; | ||
475 | } | ||
476 | |||
477 | static void hif_usb_sta_drain(void *hif_handle, u8 idx) | ||
478 | { | ||
479 | struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle; | ||
480 | struct sk_buff *skb, *tmp; | ||
481 | unsigned long flags; | ||
482 | |||
483 | spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); | ||
484 | |||
485 | skb_queue_walk_safe(&hif_dev->tx.tx_skb_queue, skb, tmp) { | ||
486 | if (check_index(skb, idx)) { | ||
487 | __skb_unlink(skb, &hif_dev->tx.tx_skb_queue); | ||
488 | ath9k_htc_txcompletion_cb(hif_dev->htc_handle, | ||
489 | skb, false); | ||
490 | hif_dev->tx.tx_skb_cnt--; | ||
491 | TX_STAT_INC(skb_failed); | ||
492 | } | ||
493 | } | ||
494 | |||
495 | spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); | ||
496 | } | ||
497 | |||
380 | static struct ath9k_htc_hif hif_usb = { | 498 | static struct ath9k_htc_hif hif_usb = { |
381 | .transport = ATH9K_HIF_USB, | 499 | .transport = ATH9K_HIF_USB, |
382 | .name = "ath9k_hif_usb", | 500 | .name = "ath9k_hif_usb", |
@@ -386,6 +504,7 @@ static struct ath9k_htc_hif hif_usb = { | |||
386 | 504 | ||
387 | .start = hif_usb_start, | 505 | .start = hif_usb_start, |
388 | .stop = hif_usb_stop, | 506 | .stop = hif_usb_stop, |
507 | .sta_drain = hif_usb_sta_drain, | ||
389 | .send = hif_usb_send, | 508 | .send = hif_usb_send, |
390 | }; | 509 | }; |
391 | 510 | ||
@@ -567,6 +686,9 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb) | |||
567 | case -ESHUTDOWN: | 686 | case -ESHUTDOWN: |
568 | goto free; | 687 | goto free; |
569 | default: | 688 | default: |
689 | skb_reset_tail_pointer(skb); | ||
690 | skb_trim(skb, 0); | ||
691 | |||
570 | goto resubmit; | 692 | goto resubmit; |
571 | } | 693 | } |
572 | 694 | ||
@@ -591,23 +713,15 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb) | |||
591 | USB_REG_IN_PIPE), | 713 | USB_REG_IN_PIPE), |
592 | nskb->data, MAX_REG_IN_BUF_SIZE, | 714 | nskb->data, MAX_REG_IN_BUF_SIZE, |
593 | ath9k_hif_usb_reg_in_cb, nskb); | 715 | ath9k_hif_usb_reg_in_cb, nskb); |
594 | |||
595 | ret = usb_submit_urb(urb, GFP_ATOMIC); | ||
596 | if (ret) { | ||
597 | kfree_skb(nskb); | ||
598 | urb->context = NULL; | ||
599 | } | ||
600 | |||
601 | return; | ||
602 | } | 716 | } |
603 | 717 | ||
604 | resubmit: | 718 | resubmit: |
605 | skb_reset_tail_pointer(skb); | 719 | usb_anchor_urb(urb, &hif_dev->reg_in_submitted); |
606 | skb_trim(skb, 0); | ||
607 | |||
608 | ret = usb_submit_urb(urb, GFP_ATOMIC); | 720 | ret = usb_submit_urb(urb, GFP_ATOMIC); |
609 | if (ret) | 721 | if (ret) { |
722 | usb_unanchor_urb(urb); | ||
610 | goto free; | 723 | goto free; |
724 | } | ||
611 | 725 | ||
612 | return; | 726 | return; |
613 | free: | 727 | free: |
@@ -641,6 +755,8 @@ static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb *hif_dev) | |||
641 | kfree(tx_buf->buf); | 755 | kfree(tx_buf->buf); |
642 | kfree(tx_buf); | 756 | kfree(tx_buf); |
643 | } | 757 | } |
758 | |||
759 | usb_kill_anchored_urbs(&hif_dev->mgmt_submitted); | ||
644 | } | 760 | } |
645 | 761 | ||
646 | static int ath9k_hif_usb_alloc_tx_urbs(struct hif_device_usb *hif_dev) | 762 | static int ath9k_hif_usb_alloc_tx_urbs(struct hif_device_usb *hif_dev) |
@@ -652,6 +768,7 @@ static int ath9k_hif_usb_alloc_tx_urbs(struct hif_device_usb *hif_dev) | |||
652 | INIT_LIST_HEAD(&hif_dev->tx.tx_pending); | 768 | INIT_LIST_HEAD(&hif_dev->tx.tx_pending); |
653 | spin_lock_init(&hif_dev->tx.tx_lock); | 769 | spin_lock_init(&hif_dev->tx.tx_lock); |
654 | __skb_queue_head_init(&hif_dev->tx.tx_skb_queue); | 770 | __skb_queue_head_init(&hif_dev->tx.tx_skb_queue); |
771 | init_usb_anchor(&hif_dev->mgmt_submitted); | ||
655 | 772 | ||
656 | for (i = 0; i < MAX_TX_URB_NUM; i++) { | 773 | for (i = 0; i < MAX_TX_URB_NUM; i++) { |
657 | tx_buf = kzalloc(sizeof(struct tx_buf), GFP_KERNEL); | 774 | tx_buf = kzalloc(sizeof(struct tx_buf), GFP_KERNEL); |
@@ -748,43 +865,67 @@ err_urb: | |||
748 | return ret; | 865 | return ret; |
749 | } | 866 | } |
750 | 867 | ||
751 | static void ath9k_hif_usb_dealloc_reg_in_urb(struct hif_device_usb *hif_dev) | 868 | static void ath9k_hif_usb_dealloc_reg_in_urbs(struct hif_device_usb *hif_dev) |
752 | { | 869 | { |
753 | if (hif_dev->reg_in_urb) { | 870 | usb_kill_anchored_urbs(&hif_dev->reg_in_submitted); |
754 | usb_kill_urb(hif_dev->reg_in_urb); | ||
755 | if (hif_dev->reg_in_urb->context) | ||
756 | kfree_skb((void *)hif_dev->reg_in_urb->context); | ||
757 | usb_free_urb(hif_dev->reg_in_urb); | ||
758 | hif_dev->reg_in_urb = NULL; | ||
759 | } | ||
760 | } | 871 | } |
761 | 872 | ||
762 | static int ath9k_hif_usb_alloc_reg_in_urb(struct hif_device_usb *hif_dev) | 873 | static int ath9k_hif_usb_alloc_reg_in_urbs(struct hif_device_usb *hif_dev) |
763 | { | 874 | { |
764 | struct sk_buff *skb; | 875 | struct urb *urb = NULL; |
876 | struct sk_buff *skb = NULL; | ||
877 | int i, ret; | ||
765 | 878 | ||
766 | hif_dev->reg_in_urb = usb_alloc_urb(0, GFP_KERNEL); | 879 | init_usb_anchor(&hif_dev->reg_in_submitted); |
767 | if (hif_dev->reg_in_urb == NULL) | ||
768 | return -ENOMEM; | ||
769 | 880 | ||
770 | skb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_KERNEL); | 881 | for (i = 0; i < MAX_REG_IN_URB_NUM; i++) { |
771 | if (!skb) | ||
772 | goto err; | ||
773 | 882 | ||
774 | usb_fill_bulk_urb(hif_dev->reg_in_urb, hif_dev->udev, | 883 | /* Allocate URB */ |
775 | usb_rcvbulkpipe(hif_dev->udev, | 884 | urb = usb_alloc_urb(0, GFP_KERNEL); |
776 | USB_REG_IN_PIPE), | 885 | if (urb == NULL) { |
777 | skb->data, MAX_REG_IN_BUF_SIZE, | 886 | ret = -ENOMEM; |
778 | ath9k_hif_usb_reg_in_cb, skb); | 887 | goto err_urb; |
888 | } | ||
779 | 889 | ||
780 | if (usb_submit_urb(hif_dev->reg_in_urb, GFP_KERNEL) != 0) | 890 | /* Allocate buffer */ |
781 | goto err; | 891 | skb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_KERNEL); |
892 | if (!skb) { | ||
893 | ret = -ENOMEM; | ||
894 | goto err_skb; | ||
895 | } | ||
896 | |||
897 | usb_fill_bulk_urb(urb, hif_dev->udev, | ||
898 | usb_rcvbulkpipe(hif_dev->udev, | ||
899 | USB_REG_IN_PIPE), | ||
900 | skb->data, MAX_REG_IN_BUF_SIZE, | ||
901 | ath9k_hif_usb_reg_in_cb, skb); | ||
902 | |||
903 | /* Anchor URB */ | ||
904 | usb_anchor_urb(urb, &hif_dev->reg_in_submitted); | ||
905 | |||
906 | /* Submit URB */ | ||
907 | ret = usb_submit_urb(urb, GFP_KERNEL); | ||
908 | if (ret) { | ||
909 | usb_unanchor_urb(urb); | ||
910 | goto err_submit; | ||
911 | } | ||
912 | |||
913 | /* | ||
914 | * Drop reference count. | ||
915 | * This ensures that the URB is freed when killing them. | ||
916 | */ | ||
917 | usb_free_urb(urb); | ||
918 | } | ||
782 | 919 | ||
783 | return 0; | 920 | return 0; |
784 | 921 | ||
785 | err: | 922 | err_submit: |
786 | ath9k_hif_usb_dealloc_reg_in_urb(hif_dev); | 923 | kfree_skb(skb); |
787 | return -ENOMEM; | 924 | err_skb: |
925 | usb_free_urb(urb); | ||
926 | err_urb: | ||
927 | ath9k_hif_usb_dealloc_reg_in_urbs(hif_dev); | ||
928 | return ret; | ||
788 | } | 929 | } |
789 | 930 | ||
790 | static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev) | 931 | static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev) |
@@ -801,7 +942,7 @@ static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev) | |||
801 | goto err_rx; | 942 | goto err_rx; |
802 | 943 | ||
803 | /* Register Read */ | 944 | /* Register Read */ |
804 | if (ath9k_hif_usb_alloc_reg_in_urb(hif_dev) < 0) | 945 | if (ath9k_hif_usb_alloc_reg_in_urbs(hif_dev) < 0) |
805 | goto err_reg; | 946 | goto err_reg; |
806 | 947 | ||
807 | return 0; | 948 | return 0; |
@@ -816,7 +957,7 @@ err: | |||
816 | static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev) | 957 | static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev) |
817 | { | 958 | { |
818 | usb_kill_anchored_urbs(&hif_dev->regout_submitted); | 959 | usb_kill_anchored_urbs(&hif_dev->regout_submitted); |
819 | ath9k_hif_usb_dealloc_reg_in_urb(hif_dev); | 960 | ath9k_hif_usb_dealloc_reg_in_urbs(hif_dev); |
820 | ath9k_hif_usb_dealloc_tx_urbs(hif_dev); | 961 | ath9k_hif_usb_dealloc_tx_urbs(hif_dev); |
821 | ath9k_hif_usb_dealloc_rx_urbs(hif_dev); | 962 | ath9k_hif_usb_dealloc_rx_urbs(hif_dev); |
822 | } | 963 | } |
@@ -1026,10 +1167,7 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface, | |||
1026 | /* Find out which firmware to load */ | 1167 | /* Find out which firmware to load */ |
1027 | 1168 | ||
1028 | if (IS_AR7010_DEVICE(id->driver_info)) | 1169 | if (IS_AR7010_DEVICE(id->driver_info)) |
1029 | if (le16_to_cpu(udev->descriptor.bcdDevice) == 0x0202) | 1170 | hif_dev->fw_name = FIRMWARE_AR7010_1_1; |
1030 | hif_dev->fw_name = FIRMWARE_AR7010_1_1; | ||
1031 | else | ||
1032 | hif_dev->fw_name = FIRMWARE_AR7010; | ||
1033 | else | 1171 | else |
1034 | hif_dev->fw_name = FIRMWARE_AR9271; | 1172 | hif_dev->fw_name = FIRMWARE_AR9271; |
1035 | 1173 | ||