diff options
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_chip.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_chip.h | 18 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_mac.c | 202 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_mac.h | 25 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_usb.c | 4 |
5 files changed, 227 insertions, 26 deletions
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c index 4e79a9800134..dfa1b9bc22c8 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.c +++ b/drivers/net/wireless/zd1211rw/zd_chip.c | |||
@@ -755,7 +755,7 @@ static int hw_reset_phy(struct zd_chip *chip) | |||
755 | static int zd1211_hw_init_hmac(struct zd_chip *chip) | 755 | static int zd1211_hw_init_hmac(struct zd_chip *chip) |
756 | { | 756 | { |
757 | static const struct zd_ioreq32 ioreqs[] = { | 757 | static const struct zd_ioreq32 ioreqs[] = { |
758 | { CR_ZD1211_RETRY_MAX, 0x2 }, | 758 | { CR_ZD1211_RETRY_MAX, ZD1211_RETRY_COUNT }, |
759 | { CR_RX_THRESHOLD, 0x000c0640 }, | 759 | { CR_RX_THRESHOLD, 0x000c0640 }, |
760 | }; | 760 | }; |
761 | 761 | ||
@@ -767,7 +767,7 @@ static int zd1211_hw_init_hmac(struct zd_chip *chip) | |||
767 | static int zd1211b_hw_init_hmac(struct zd_chip *chip) | 767 | static int zd1211b_hw_init_hmac(struct zd_chip *chip) |
768 | { | 768 | { |
769 | static const struct zd_ioreq32 ioreqs[] = { | 769 | static const struct zd_ioreq32 ioreqs[] = { |
770 | { CR_ZD1211B_RETRY_MAX, 0x02020202 }, | 770 | { CR_ZD1211B_RETRY_MAX, ZD1211B_RETRY_COUNT }, |
771 | { CR_ZD1211B_CWIN_MAX_MIN_AC0, 0x007f003f }, | 771 | { CR_ZD1211B_CWIN_MAX_MIN_AC0, 0x007f003f }, |
772 | { CR_ZD1211B_CWIN_MAX_MIN_AC1, 0x007f003f }, | 772 | { CR_ZD1211B_CWIN_MAX_MIN_AC1, 0x007f003f }, |
773 | { CR_ZD1211B_CWIN_MAX_MIN_AC2, 0x003f001f }, | 773 | { CR_ZD1211B_CWIN_MAX_MIN_AC2, 0x003f001f }, |
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.h b/drivers/net/wireless/zd1211rw/zd_chip.h index 678c139a840c..9fd8f3508d66 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.h +++ b/drivers/net/wireless/zd1211rw/zd_chip.h | |||
@@ -642,13 +642,29 @@ enum { | |||
642 | #define CR_ZD1211B_TXOP CTL_REG(0x0b20) | 642 | #define CR_ZD1211B_TXOP CTL_REG(0x0b20) |
643 | #define CR_ZD1211B_RETRY_MAX CTL_REG(0x0b28) | 643 | #define CR_ZD1211B_RETRY_MAX CTL_REG(0x0b28) |
644 | 644 | ||
645 | /* Value for CR_ZD1211_RETRY_MAX & CR_ZD1211B_RETRY_MAX. Vendor driver uses 2, | ||
646 | * we use 0. The first rate is tried (count+2), then all next rates are tried | ||
647 | * twice, until 1 Mbits is tried. */ | ||
648 | #define ZD1211_RETRY_COUNT 0 | ||
649 | #define ZD1211B_RETRY_COUNT \ | ||
650 | (ZD1211_RETRY_COUNT << 0)| \ | ||
651 | (ZD1211_RETRY_COUNT << 8)| \ | ||
652 | (ZD1211_RETRY_COUNT << 16)| \ | ||
653 | (ZD1211_RETRY_COUNT << 24) | ||
654 | |||
645 | /* Used to detect PLL lock */ | 655 | /* Used to detect PLL lock */ |
646 | #define UW2453_INTR_REG ((zd_addr_t)0x85c1) | 656 | #define UW2453_INTR_REG ((zd_addr_t)0x85c1) |
647 | 657 | ||
648 | #define CWIN_SIZE 0x007f043f | 658 | #define CWIN_SIZE 0x007f043f |
649 | 659 | ||
650 | 660 | ||
651 | #define HWINT_ENABLED 0x004f0000 | 661 | #define HWINT_ENABLED \ |
662 | (INT_TX_COMPLETE_EN| \ | ||
663 | INT_RX_COMPLETE_EN| \ | ||
664 | INT_RETRY_FAIL_EN| \ | ||
665 | INT_WAKEUP_EN| \ | ||
666 | INT_CFG_NEXT_BCN_EN) | ||
667 | |||
652 | #define HWINT_DISABLED 0 | 668 | #define HWINT_DISABLED 0 |
653 | 669 | ||
654 | #define E2P_PWR_INT_GUARD 8 | 670 | #define E2P_PWR_INT_GUARD 8 |
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 6d666359a42f..8a243732c519 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c | |||
@@ -88,6 +88,34 @@ static const struct ieee80211_rate zd_rates[] = { | |||
88 | .flags = 0 }, | 88 | .flags = 0 }, |
89 | }; | 89 | }; |
90 | 90 | ||
91 | /* | ||
92 | * Zydas retry rates table. Each line is listed in the same order as | ||
93 | * in zd_rates[] and contains all the rate used when a packet is sent | ||
94 | * starting with a given rates. Let's consider an example : | ||
95 | * | ||
96 | * "11 Mbits : 4, 3, 2, 1, 0" means : | ||
97 | * - packet is sent using 4 different rates | ||
98 | * - 1st rate is index 3 (ie 11 Mbits) | ||
99 | * - 2nd rate is index 2 (ie 5.5 Mbits) | ||
100 | * - 3rd rate is index 1 (ie 2 Mbits) | ||
101 | * - 4th rate is index 0 (ie 1 Mbits) | ||
102 | */ | ||
103 | |||
104 | static const struct tx_retry_rate zd_retry_rates[] = { | ||
105 | { /* 1 Mbits */ 1, { 0 }}, | ||
106 | { /* 2 Mbits */ 2, { 1, 0 }}, | ||
107 | { /* 5.5 Mbits */ 3, { 2, 1, 0 }}, | ||
108 | { /* 11 Mbits */ 4, { 3, 2, 1, 0 }}, | ||
109 | { /* 6 Mbits */ 5, { 4, 3, 2, 1, 0 }}, | ||
110 | { /* 9 Mbits */ 6, { 5, 4, 3, 2, 1, 0}}, | ||
111 | { /* 12 Mbits */ 5, { 6, 3, 2, 1, 0 }}, | ||
112 | { /* 18 Mbits */ 6, { 7, 6, 3, 2, 1, 0 }}, | ||
113 | { /* 24 Mbits */ 6, { 8, 6, 3, 2, 1, 0 }}, | ||
114 | { /* 36 Mbits */ 7, { 9, 8, 6, 3, 2, 1, 0 }}, | ||
115 | { /* 48 Mbits */ 8, {10, 9, 8, 6, 3, 2, 1, 0 }}, | ||
116 | { /* 54 Mbits */ 9, {11, 10, 9, 8, 6, 3, 2, 1, 0 }} | ||
117 | }; | ||
118 | |||
91 | static const struct ieee80211_channel zd_channels[] = { | 119 | static const struct ieee80211_channel zd_channels[] = { |
92 | { .center_freq = 2412, .hw_value = 1 }, | 120 | { .center_freq = 2412, .hw_value = 1 }, |
93 | { .center_freq = 2417, .hw_value = 2 }, | 121 | { .center_freq = 2417, .hw_value = 2 }, |
@@ -282,7 +310,7 @@ static void zd_op_stop(struct ieee80211_hw *hw) | |||
282 | } | 310 | } |
283 | 311 | ||
284 | /** | 312 | /** |
285 | * tx_status - reports tx status of a packet if required | 313 | * zd_mac_tx_status - reports tx status of a packet if required |
286 | * @hw - a &struct ieee80211_hw pointer | 314 | * @hw - a &struct ieee80211_hw pointer |
287 | * @skb - a sk-buffer | 315 | * @skb - a sk-buffer |
288 | * @flags: extra flags to set in the TX status info | 316 | * @flags: extra flags to set in the TX status info |
@@ -295,15 +323,49 @@ static void zd_op_stop(struct ieee80211_hw *hw) | |||
295 | * | 323 | * |
296 | * If no status information has been requested, the skb is freed. | 324 | * If no status information has been requested, the skb is freed. |
297 | */ | 325 | */ |
298 | static void tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | 326 | static void zd_mac_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, |
299 | int ackssi, bool success) | 327 | int ackssi, struct tx_status *tx_status) |
300 | { | 328 | { |
301 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 329 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
330 | int i; | ||
331 | int success = 1, retry = 1; | ||
332 | int first_idx; | ||
333 | const struct tx_retry_rate *retries; | ||
302 | 334 | ||
303 | ieee80211_tx_info_clear_status(info); | 335 | ieee80211_tx_info_clear_status(info); |
304 | 336 | ||
305 | if (success) | 337 | if (tx_status) { |
338 | success = !tx_status->failure; | ||
339 | retry = tx_status->retry + success; | ||
340 | } | ||
341 | |||
342 | if (success) { | ||
343 | /* success */ | ||
306 | info->flags |= IEEE80211_TX_STAT_ACK; | 344 | info->flags |= IEEE80211_TX_STAT_ACK; |
345 | } else { | ||
346 | /* failure */ | ||
347 | info->flags &= ~IEEE80211_TX_STAT_ACK; | ||
348 | } | ||
349 | |||
350 | first_idx = info->status.rates[0].idx; | ||
351 | ZD_ASSERT(0<=first_idx && first_idx<ARRAY_SIZE(zd_retry_rates)); | ||
352 | retries = &zd_retry_rates[first_idx]; | ||
353 | ZD_ASSERT(0<=retry && retry<=retries->count); | ||
354 | |||
355 | info->status.rates[0].idx = retries->rate[0]; | ||
356 | info->status.rates[0].count = 1; // (retry > 1 ? 2 : 1); | ||
357 | |||
358 | for (i=1; i<IEEE80211_TX_MAX_RATES-1 && i<retry; i++) { | ||
359 | info->status.rates[i].idx = retries->rate[i]; | ||
360 | info->status.rates[i].count = 1; // ((i==retry-1) && success ? 1:2); | ||
361 | } | ||
362 | for (; i<IEEE80211_TX_MAX_RATES && i<retry; i++) { | ||
363 | info->status.rates[i].idx = retries->rate[retry-1]; | ||
364 | info->status.rates[i].count = 1; // (success ? 1:2); | ||
365 | } | ||
366 | if (i<IEEE80211_TX_MAX_RATES) | ||
367 | info->status.rates[i].idx = -1; /* terminate */ | ||
368 | |||
307 | info->status.ack_signal = ackssi; | 369 | info->status.ack_signal = ackssi; |
308 | ieee80211_tx_status_irqsafe(hw, skb); | 370 | ieee80211_tx_status_irqsafe(hw, skb); |
309 | } | 371 | } |
@@ -316,16 +378,79 @@ static void tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
316 | * transferred. The first frame from the tx queue, will be selected and | 378 | * transferred. The first frame from the tx queue, will be selected and |
317 | * reported as error to the upper layers. | 379 | * reported as error to the upper layers. |
318 | */ | 380 | */ |
319 | void zd_mac_tx_failed(struct ieee80211_hw *hw) | 381 | void zd_mac_tx_failed(struct urb *urb) |
320 | { | 382 | { |
321 | struct sk_buff_head *q = &zd_hw_mac(hw)->ack_wait_queue; | 383 | struct ieee80211_hw * hw = zd_usb_to_hw(urb->context); |
384 | struct zd_mac *mac = zd_hw_mac(hw); | ||
385 | struct sk_buff_head *q = &mac->ack_wait_queue; | ||
322 | struct sk_buff *skb; | 386 | struct sk_buff *skb; |
387 | struct tx_status *tx_status = (struct tx_status *)urb->transfer_buffer; | ||
388 | unsigned long flags; | ||
389 | int success = !tx_status->failure; | ||
390 | int retry = tx_status->retry + success; | ||
391 | int found = 0; | ||
392 | int i, position = 0; | ||
323 | 393 | ||
324 | skb = skb_dequeue(q); | 394 | q = &mac->ack_wait_queue; |
325 | if (skb == NULL) | 395 | spin_lock_irqsave(&q->lock, flags); |
326 | return; | 396 | |
397 | skb_queue_walk(q, skb) { | ||
398 | struct ieee80211_hdr *tx_hdr; | ||
399 | struct ieee80211_tx_info *info; | ||
400 | int first_idx, final_idx; | ||
401 | const struct tx_retry_rate *retries; | ||
402 | u8 final_rate; | ||
403 | |||
404 | position ++; | ||
405 | |||
406 | /* if the hardware reports a failure and we had a 802.11 ACK | ||
407 | * pending, then we skip the first skb when searching for a | ||
408 | * matching frame */ | ||
409 | if (tx_status->failure && mac->ack_pending && | ||
410 | skb_queue_is_first(q, skb)) { | ||
411 | continue; | ||
412 | } | ||
413 | |||
414 | tx_hdr = (struct ieee80211_hdr *)skb->data; | ||
415 | |||
416 | /* we skip all frames not matching the reported destination */ | ||
417 | if (unlikely(memcmp(tx_hdr->addr1, tx_status->mac, ETH_ALEN))) { | ||
418 | continue; | ||
419 | } | ||
420 | |||
421 | /* we skip all frames not matching the reported final rate */ | ||
327 | 422 | ||
328 | tx_status(hw, skb, 0, 0); | 423 | info = IEEE80211_SKB_CB(skb); |
424 | first_idx = info->status.rates[0].idx; | ||
425 | ZD_ASSERT(0<=first_idx && first_idx<ARRAY_SIZE(zd_retry_rates)); | ||
426 | retries = &zd_retry_rates[first_idx]; | ||
427 | if (retry < 0 || retry > retries->count) { | ||
428 | continue; | ||
429 | } | ||
430 | |||
431 | ZD_ASSERT(0<=retry && retry<=retries->count); | ||
432 | final_idx = retries->rate[retry-1]; | ||
433 | final_rate = zd_rates[final_idx].hw_value; | ||
434 | |||
435 | if (final_rate != tx_status->rate) { | ||
436 | continue; | ||
437 | } | ||
438 | |||
439 | found = 1; | ||
440 | break; | ||
441 | } | ||
442 | |||
443 | if (found) { | ||
444 | for (i=1; i<=position; i++) { | ||
445 | skb = __skb_dequeue(q); | ||
446 | zd_mac_tx_status(hw, skb, | ||
447 | mac->ack_pending ? mac->ack_signal : 0, | ||
448 | i == position ? tx_status : NULL); | ||
449 | mac->ack_pending = 0; | ||
450 | } | ||
451 | } | ||
452 | |||
453 | spin_unlock_irqrestore(&q->lock, flags); | ||
329 | } | 454 | } |
330 | 455 | ||
331 | /** | 456 | /** |
@@ -342,18 +467,27 @@ void zd_mac_tx_to_dev(struct sk_buff *skb, int error) | |||
342 | { | 467 | { |
343 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 468 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
344 | struct ieee80211_hw *hw = info->rate_driver_data[0]; | 469 | struct ieee80211_hw *hw = info->rate_driver_data[0]; |
470 | struct zd_mac *mac = zd_hw_mac(hw); | ||
471 | |||
472 | ieee80211_tx_info_clear_status(info); | ||
345 | 473 | ||
346 | skb_pull(skb, sizeof(struct zd_ctrlset)); | 474 | skb_pull(skb, sizeof(struct zd_ctrlset)); |
347 | if (unlikely(error || | 475 | if (unlikely(error || |
348 | (info->flags & IEEE80211_TX_CTL_NO_ACK))) { | 476 | (info->flags & IEEE80211_TX_CTL_NO_ACK))) { |
349 | tx_status(hw, skb, 0, !error); | 477 | /* |
478 | * FIXME : do we need to fill in anything ? | ||
479 | */ | ||
480 | ieee80211_tx_status_irqsafe(hw, skb); | ||
350 | } else { | 481 | } else { |
351 | struct sk_buff_head *q = | 482 | struct sk_buff_head *q = &mac->ack_wait_queue; |
352 | &zd_hw_mac(hw)->ack_wait_queue; | ||
353 | 483 | ||
354 | skb_queue_tail(q, skb); | 484 | skb_queue_tail(q, skb); |
355 | while (skb_queue_len(q) > ZD_MAC_MAX_ACK_WAITERS) | 485 | while (skb_queue_len(q) > ZD_MAC_MAX_ACK_WAITERS) { |
356 | zd_mac_tx_failed(hw); | 486 | zd_mac_tx_status(hw, skb_dequeue(q), |
487 | mac->ack_pending ? mac->ack_signal : 0, | ||
488 | NULL); | ||
489 | mac->ack_pending = 0; | ||
490 | } | ||
357 | } | 491 | } |
358 | } | 492 | } |
359 | 493 | ||
@@ -606,27 +740,47 @@ fail: | |||
606 | static int filter_ack(struct ieee80211_hw *hw, struct ieee80211_hdr *rx_hdr, | 740 | static int filter_ack(struct ieee80211_hw *hw, struct ieee80211_hdr *rx_hdr, |
607 | struct ieee80211_rx_status *stats) | 741 | struct ieee80211_rx_status *stats) |
608 | { | 742 | { |
743 | struct zd_mac *mac = zd_hw_mac(hw); | ||
609 | struct sk_buff *skb; | 744 | struct sk_buff *skb; |
610 | struct sk_buff_head *q; | 745 | struct sk_buff_head *q; |
611 | unsigned long flags; | 746 | unsigned long flags; |
747 | int found = 0; | ||
748 | int i, position = 0; | ||
612 | 749 | ||
613 | if (!ieee80211_is_ack(rx_hdr->frame_control)) | 750 | if (!ieee80211_is_ack(rx_hdr->frame_control)) |
614 | return 0; | 751 | return 0; |
615 | 752 | ||
616 | q = &zd_hw_mac(hw)->ack_wait_queue; | 753 | q = &mac->ack_wait_queue; |
617 | spin_lock_irqsave(&q->lock, flags); | 754 | spin_lock_irqsave(&q->lock, flags); |
618 | skb_queue_walk(q, skb) { | 755 | skb_queue_walk(q, skb) { |
619 | struct ieee80211_hdr *tx_hdr; | 756 | struct ieee80211_hdr *tx_hdr; |
620 | 757 | ||
758 | position ++; | ||
759 | |||
760 | if (mac->ack_pending && skb_queue_is_first(q, skb)) | ||
761 | continue; | ||
762 | |||
621 | tx_hdr = (struct ieee80211_hdr *)skb->data; | 763 | tx_hdr = (struct ieee80211_hdr *)skb->data; |
622 | if (likely(!memcmp(tx_hdr->addr2, rx_hdr->addr1, ETH_ALEN))) | 764 | if (likely(!memcmp(tx_hdr->addr2, rx_hdr->addr1, ETH_ALEN))) |
623 | { | 765 | { |
624 | __skb_unlink(skb, q); | 766 | found = 1; |
625 | tx_status(hw, skb, stats->signal, 1); | 767 | break; |
626 | goto out; | ||
627 | } | 768 | } |
628 | } | 769 | } |
629 | out: | 770 | |
771 | if (found) { | ||
772 | for (i=1; i<position; i++) { | ||
773 | skb = __skb_dequeue(q); | ||
774 | zd_mac_tx_status(hw, skb, | ||
775 | mac->ack_pending ? mac->ack_signal : 0, | ||
776 | NULL); | ||
777 | mac->ack_pending = 0; | ||
778 | } | ||
779 | |||
780 | mac->ack_pending = 1; | ||
781 | mac->ack_signal = stats->signal; | ||
782 | } | ||
783 | |||
630 | spin_unlock_irqrestore(&q->lock, flags); | 784 | spin_unlock_irqrestore(&q->lock, flags); |
631 | return 1; | 785 | return 1; |
632 | } | 786 | } |
@@ -709,6 +863,7 @@ int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length) | |||
709 | skb_reserve(skb, 2); | 863 | skb_reserve(skb, 2); |
710 | } | 864 | } |
711 | 865 | ||
866 | /* FIXME : could we avoid this big memcpy ? */ | ||
712 | memcpy(skb_put(skb, length), buffer, length); | 867 | memcpy(skb_put(skb, length), buffer, length); |
713 | 868 | ||
714 | memcpy(IEEE80211_SKB_RXCB(skb), &stats, sizeof(stats)); | 869 | memcpy(IEEE80211_SKB_RXCB(skb), &stats, sizeof(stats)); |
@@ -999,7 +1154,14 @@ struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf) | |||
999 | hw->queues = 1; | 1154 | hw->queues = 1; |
1000 | hw->extra_tx_headroom = sizeof(struct zd_ctrlset); | 1155 | hw->extra_tx_headroom = sizeof(struct zd_ctrlset); |
1001 | 1156 | ||
1157 | /* | ||
1158 | * Tell mac80211 that we support multi rate retries | ||
1159 | */ | ||
1160 | hw->max_rates = IEEE80211_TX_MAX_RATES; | ||
1161 | hw->max_rate_tries = 18; /* 9 rates * 2 retries/rate */ | ||
1162 | |||
1002 | skb_queue_head_init(&mac->ack_wait_queue); | 1163 | skb_queue_head_init(&mac->ack_wait_queue); |
1164 | mac->ack_pending = 0; | ||
1003 | 1165 | ||
1004 | zd_chip_init(&mac->chip, hw, intf); | 1166 | zd_chip_init(&mac->chip, hw, intf); |
1005 | housekeeping_init(mac); | 1167 | housekeeping_init(mac); |
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.h b/drivers/net/wireless/zd1211rw/zd_mac.h index 7c2759118d13..630c298a730e 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.h +++ b/drivers/net/wireless/zd1211rw/zd_mac.h | |||
@@ -140,6 +140,21 @@ struct rx_status { | |||
140 | #define ZD_RX_CRC16_ERROR 0x40 | 140 | #define ZD_RX_CRC16_ERROR 0x40 |
141 | #define ZD_RX_ERROR 0x80 | 141 | #define ZD_RX_ERROR 0x80 |
142 | 142 | ||
143 | struct tx_retry_rate { | ||
144 | int count; /* number of valid element in rate[] array */ | ||
145 | int rate[10]; /* retry rates, described by an index in zd_rates[] */ | ||
146 | }; | ||
147 | |||
148 | struct tx_status { | ||
149 | u8 type; /* must always be 0x01 : USB_INT_TYPE */ | ||
150 | u8 id; /* must always be 0xa0 : USB_INT_ID_RETRY_FAILED */ | ||
151 | u8 rate; | ||
152 | u8 pad; | ||
153 | u8 mac[ETH_ALEN]; | ||
154 | u8 retry; | ||
155 | u8 failure; | ||
156 | } __attribute__((packed)); | ||
157 | |||
143 | enum mac_flags { | 158 | enum mac_flags { |
144 | MAC_FIXED_CHANNEL = 0x01, | 159 | MAC_FIXED_CHANNEL = 0x01, |
145 | }; | 160 | }; |
@@ -150,7 +165,7 @@ struct housekeeping { | |||
150 | 165 | ||
151 | #define ZD_MAC_STATS_BUFFER_SIZE 16 | 166 | #define ZD_MAC_STATS_BUFFER_SIZE 16 |
152 | 167 | ||
153 | #define ZD_MAC_MAX_ACK_WAITERS 10 | 168 | #define ZD_MAC_MAX_ACK_WAITERS 50 |
154 | 169 | ||
155 | struct zd_mac { | 170 | struct zd_mac { |
156 | struct zd_chip chip; | 171 | struct zd_chip chip; |
@@ -184,6 +199,12 @@ struct zd_mac { | |||
184 | 199 | ||
185 | /* whether to pass control frames to stack */ | 200 | /* whether to pass control frames to stack */ |
186 | unsigned int pass_ctrl:1; | 201 | unsigned int pass_ctrl:1; |
202 | |||
203 | /* whether we have received a 802.11 ACK that is pending */ | ||
204 | unsigned int ack_pending:1; | ||
205 | |||
206 | /* signal strength of the last 802.11 ACK received */ | ||
207 | int ack_signal; | ||
187 | }; | 208 | }; |
188 | 209 | ||
189 | #define ZD_REGDOMAIN_FCC 0x10 | 210 | #define ZD_REGDOMAIN_FCC 0x10 |
@@ -279,7 +300,7 @@ int zd_mac_preinit_hw(struct ieee80211_hw *hw); | |||
279 | int zd_mac_init_hw(struct ieee80211_hw *hw); | 300 | int zd_mac_init_hw(struct ieee80211_hw *hw); |
280 | 301 | ||
281 | int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length); | 302 | int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length); |
282 | void zd_mac_tx_failed(struct ieee80211_hw *hw); | 303 | void zd_mac_tx_failed(struct urb *urb); |
283 | void zd_mac_tx_to_dev(struct sk_buff *skb, int error); | 304 | void zd_mac_tx_to_dev(struct sk_buff *skb, int error); |
284 | 305 | ||
285 | #ifdef DEBUG | 306 | #ifdef DEBUG |
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index 23a6a6d4863b..d46f20a57b7d 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c | |||
@@ -419,7 +419,7 @@ static void int_urb_complete(struct urb *urb) | |||
419 | handle_regs_int(urb); | 419 | handle_regs_int(urb); |
420 | break; | 420 | break; |
421 | case USB_INT_ID_RETRY_FAILED: | 421 | case USB_INT_ID_RETRY_FAILED: |
422 | zd_mac_tx_failed(zd_usb_to_hw(urb->context)); | 422 | zd_mac_tx_failed(urb); |
423 | break; | 423 | break; |
424 | default: | 424 | default: |
425 | dev_dbg_f(urb_dev(urb), "error: urb %p unknown id %x\n", urb, | 425 | dev_dbg_f(urb_dev(urb), "error: urb %p unknown id %x\n", urb, |
@@ -553,6 +553,8 @@ static void handle_rx_packet(struct zd_usb *usb, const u8 *buffer, | |||
553 | 553 | ||
554 | if (length < sizeof(struct rx_length_info)) { | 554 | if (length < sizeof(struct rx_length_info)) { |
555 | /* It's not a complete packet anyhow. */ | 555 | /* It's not a complete packet anyhow. */ |
556 | printk("%s: invalid, small RX packet : %d\n", | ||
557 | __func__, length); | ||
556 | return; | 558 | return; |
557 | } | 559 | } |
558 | length_info = (struct rx_length_info *) | 560 | length_info = (struct rx_length_info *) |