diff options
Diffstat (limited to 'drivers/net/wireless/ath/ar9170')
-rw-r--r-- | drivers/net/wireless/ath/ar9170/ar9170.h | 12 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ar9170/hw.h | 15 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ar9170/main.c | 532 |
3 files changed, 421 insertions, 138 deletions
diff --git a/drivers/net/wireless/ath/ar9170/ar9170.h b/drivers/net/wireless/ath/ar9170/ar9170.h index b6a1bff67ca..17bd3eaf3e0 100644 --- a/drivers/net/wireless/ath/ar9170/ar9170.h +++ b/drivers/net/wireless/ath/ar9170/ar9170.h | |||
@@ -104,10 +104,16 @@ enum ar9170_device_state { | |||
104 | AR9170_ASSOCIATED, | 104 | AR9170_ASSOCIATED, |
105 | }; | 105 | }; |
106 | 106 | ||
107 | struct ar9170_rxstream_mpdu_merge { | ||
108 | struct ar9170_rx_head plcp; | ||
109 | bool has_plcp; | ||
110 | }; | ||
111 | |||
107 | struct ar9170 { | 112 | struct ar9170 { |
108 | struct ieee80211_hw *hw; | 113 | struct ieee80211_hw *hw; |
109 | struct mutex mutex; | 114 | struct mutex mutex; |
110 | enum ar9170_device_state state; | 115 | enum ar9170_device_state state; |
116 | unsigned long bad_hw_nagger; | ||
111 | 117 | ||
112 | int (*open)(struct ar9170 *); | 118 | int (*open)(struct ar9170 *); |
113 | void (*stop)(struct ar9170 *); | 119 | void (*stop)(struct ar9170 *); |
@@ -135,6 +141,7 @@ struct ar9170 { | |||
135 | u64 cur_mc_hash, want_mc_hash; | 141 | u64 cur_mc_hash, want_mc_hash; |
136 | u32 cur_filter, want_filter; | 142 | u32 cur_filter, want_filter; |
137 | unsigned int filter_changed; | 143 | unsigned int filter_changed; |
144 | unsigned int filter_state; | ||
138 | bool sniffer_enabled; | 145 | bool sniffer_enabled; |
139 | 146 | ||
140 | /* PHY */ | 147 | /* PHY */ |
@@ -174,6 +181,11 @@ struct ar9170 { | |||
174 | struct sk_buff_head global_tx_status; | 181 | struct sk_buff_head global_tx_status; |
175 | struct sk_buff_head global_tx_status_waste; | 182 | struct sk_buff_head global_tx_status_waste; |
176 | struct delayed_work tx_status_janitor; | 183 | struct delayed_work tx_status_janitor; |
184 | |||
185 | /* rxstream mpdu merge */ | ||
186 | struct ar9170_rxstream_mpdu_merge rx_mpdu; | ||
187 | struct sk_buff *rx_failover; | ||
188 | int rx_failover_missing; | ||
177 | }; | 189 | }; |
178 | 190 | ||
179 | struct ar9170_sta_info { | 191 | struct ar9170_sta_info { |
diff --git a/drivers/net/wireless/ath/ar9170/hw.h b/drivers/net/wireless/ath/ar9170/hw.h index 53e250a4278..95bf812d6fc 100644 --- a/drivers/net/wireless/ath/ar9170/hw.h +++ b/drivers/net/wireless/ath/ar9170/hw.h | |||
@@ -312,7 +312,7 @@ struct ar9170_rx_head { | |||
312 | u8 plcp[12]; | 312 | u8 plcp[12]; |
313 | } __packed; | 313 | } __packed; |
314 | 314 | ||
315 | struct ar9170_rx_tail { | 315 | struct ar9170_rx_phystatus { |
316 | union { | 316 | union { |
317 | struct { | 317 | struct { |
318 | u8 rssi_ant0, rssi_ant1, rssi_ant2, | 318 | u8 rssi_ant0, rssi_ant1, rssi_ant2, |
@@ -324,6 +324,9 @@ struct ar9170_rx_tail { | |||
324 | 324 | ||
325 | u8 evm_stream0[6], evm_stream1[6]; | 325 | u8 evm_stream0[6], evm_stream1[6]; |
326 | u8 phy_err; | 326 | u8 phy_err; |
327 | } __packed; | ||
328 | |||
329 | struct ar9170_rx_macstatus { | ||
327 | u8 SAidx, DAidx; | 330 | u8 SAidx, DAidx; |
328 | u8 error; | 331 | u8 error; |
329 | u8 status; | 332 | u8 status; |
@@ -339,7 +342,7 @@ struct ar9170_rx_tail { | |||
339 | 342 | ||
340 | #define AR9170_RX_ENC_SOFTWARE 0x8 | 343 | #define AR9170_RX_ENC_SOFTWARE 0x8 |
341 | 344 | ||
342 | static inline u8 ar9170_get_decrypt_type(struct ar9170_rx_tail *t) | 345 | static inline u8 ar9170_get_decrypt_type(struct ar9170_rx_macstatus *t) |
343 | { | 346 | { |
344 | return (t->SAidx & 0xc0) >> 4 | | 347 | return (t->SAidx & 0xc0) >> 4 | |
345 | (t->DAidx & 0xc0) >> 6; | 348 | (t->DAidx & 0xc0) >> 6; |
@@ -357,10 +360,9 @@ static inline u8 ar9170_get_decrypt_type(struct ar9170_rx_tail *t) | |||
357 | 360 | ||
358 | #define AR9170_RX_STATUS_MPDU_MASK 0x30 | 361 | #define AR9170_RX_STATUS_MPDU_MASK 0x30 |
359 | #define AR9170_RX_STATUS_MPDU_SINGLE 0x00 | 362 | #define AR9170_RX_STATUS_MPDU_SINGLE 0x00 |
360 | #define AR9170_RX_STATUS_MPDU_FIRST 0x10 | 363 | #define AR9170_RX_STATUS_MPDU_FIRST 0x20 |
361 | #define AR9170_RX_STATUS_MPDU_MIDDLE 0x20 | 364 | #define AR9170_RX_STATUS_MPDU_MIDDLE 0x30 |
362 | #define AR9170_RX_STATUS_MPDU_LAST 0x30 | 365 | #define AR9170_RX_STATUS_MPDU_LAST 0x10 |
363 | |||
364 | 366 | ||
365 | #define AR9170_RX_ERROR_RXTO 0x01 | 367 | #define AR9170_RX_ERROR_RXTO 0x01 |
366 | #define AR9170_RX_ERROR_OVERRUN 0x02 | 368 | #define AR9170_RX_ERROR_OVERRUN 0x02 |
@@ -369,6 +371,7 @@ static inline u8 ar9170_get_decrypt_type(struct ar9170_rx_tail *t) | |||
369 | #define AR9170_RX_ERROR_WRONG_RA 0x10 | 371 | #define AR9170_RX_ERROR_WRONG_RA 0x10 |
370 | #define AR9170_RX_ERROR_PLCP 0x20 | 372 | #define AR9170_RX_ERROR_PLCP 0x20 |
371 | #define AR9170_RX_ERROR_MMIC 0x40 | 373 | #define AR9170_RX_ERROR_MMIC 0x40 |
374 | #define AR9170_RX_ERROR_FATAL 0x80 | ||
372 | 375 | ||
373 | struct ar9170_cmd_tx_status { | 376 | struct ar9170_cmd_tx_status { |
374 | __le16 unkn; | 377 | __le16 unkn; |
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c index 4682fe2f3f3..1b60906b80c 100644 --- a/drivers/net/wireless/ath/ar9170/main.c +++ b/drivers/net/wireless/ath/ar9170/main.c | |||
@@ -454,214 +454,430 @@ static void ar9170_handle_command_response(struct ar9170 *ar, | |||
454 | } | 454 | } |
455 | } | 455 | } |
456 | 456 | ||
457 | /* | 457 | static void ar9170_rx_reset_rx_mpdu(struct ar9170 *ar) |
458 | * If the frame alignment is right (or the kernel has | ||
459 | * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS), and there | ||
460 | * is only a single MPDU in the USB frame, then we can | ||
461 | * submit to mac80211 the SKB directly. However, since | ||
462 | * there may be multiple packets in one SKB in stream | ||
463 | * mode, and we need to observe the proper ordering, | ||
464 | * this is non-trivial. | ||
465 | */ | ||
466 | static void ar9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len) | ||
467 | { | 458 | { |
468 | struct sk_buff *skb; | 459 | memset(&ar->rx_mpdu.plcp, 0, sizeof(struct ar9170_rx_head)); |
469 | struct ar9170_rx_head *head = (void *)buf; | 460 | ar->rx_mpdu.has_plcp = false; |
470 | struct ar9170_rx_tail *tail; | 461 | } |
471 | struct ieee80211_rx_status status; | ||
472 | int mpdu_len, i; | ||
473 | u8 error, antennas = 0, decrypt; | ||
474 | __le16 fc; | ||
475 | int reserved; | ||
476 | 462 | ||
477 | if (unlikely(!IS_STARTED(ar))) | 463 | static int ar9170_nag_limiter(struct ar9170 *ar) |
478 | return ; | 464 | { |
465 | bool print_message; | ||
466 | |||
467 | /* | ||
468 | * we expect all sorts of errors in promiscuous mode. | ||
469 | * don't bother with it, it's OK! | ||
470 | */ | ||
471 | if (ar->sniffer_enabled) | ||
472 | return false; | ||
473 | |||
474 | /* | ||
475 | * only go for frequent errors! The hardware tends to | ||
476 | * do some stupid thing once in a while under load, in | ||
477 | * noisy environments or just for fun! | ||
478 | */ | ||
479 | if (time_before(jiffies, ar->bad_hw_nagger) && net_ratelimit()) | ||
480 | print_message = true; | ||
481 | else | ||
482 | print_message = false; | ||
483 | |||
484 | /* reset threshold for "once in a while" */ | ||
485 | ar->bad_hw_nagger = jiffies + HZ / 4; | ||
486 | return print_message; | ||
487 | } | ||
488 | |||
489 | static int ar9170_rx_mac_status(struct ar9170 *ar, | ||
490 | struct ar9170_rx_head *head, | ||
491 | struct ar9170_rx_macstatus *mac, | ||
492 | struct ieee80211_rx_status *status) | ||
493 | { | ||
494 | u8 error, decrypt; | ||
479 | 495 | ||
480 | /* Received MPDU */ | ||
481 | mpdu_len = len; | ||
482 | mpdu_len -= sizeof(struct ar9170_rx_head); | ||
483 | mpdu_len -= sizeof(struct ar9170_rx_tail); | ||
484 | BUILD_BUG_ON(sizeof(struct ar9170_rx_head) != 12); | 496 | BUILD_BUG_ON(sizeof(struct ar9170_rx_head) != 12); |
485 | BUILD_BUG_ON(sizeof(struct ar9170_rx_tail) != 24); | 497 | BUILD_BUG_ON(sizeof(struct ar9170_rx_macstatus) != 4); |
486 | 498 | ||
487 | if (mpdu_len <= FCS_LEN) | 499 | error = mac->error; |
488 | return; | 500 | if (error & AR9170_RX_ERROR_MMIC) { |
501 | status->flag |= RX_FLAG_MMIC_ERROR; | ||
502 | error &= ~AR9170_RX_ERROR_MMIC; | ||
503 | } | ||
489 | 504 | ||
490 | tail = (void *)(buf + sizeof(struct ar9170_rx_head) + mpdu_len); | 505 | if (error & AR9170_RX_ERROR_PLCP) { |
506 | status->flag |= RX_FLAG_FAILED_PLCP_CRC; | ||
507 | error &= ~AR9170_RX_ERROR_PLCP; | ||
491 | 508 | ||
492 | for (i = 0; i < 3; i++) | 509 | if (!(ar->filter_state & FIF_PLCPFAIL)) |
493 | if (tail->rssi[i] != 0x80) | 510 | return -EINVAL; |
494 | antennas |= BIT(i); | 511 | } |
495 | 512 | ||
496 | /* post-process RSSI */ | 513 | if (error & AR9170_RX_ERROR_FCS) { |
497 | for (i = 0; i < 7; i++) | 514 | status->flag |= RX_FLAG_FAILED_FCS_CRC; |
498 | if (tail->rssi[i] & 0x80) | 515 | error &= ~AR9170_RX_ERROR_FCS; |
499 | tail->rssi[i] = ((tail->rssi[i] & 0x7f) + 1) & 0x7f; | ||
500 | 516 | ||
501 | memset(&status, 0, sizeof(status)); | 517 | if (!(ar->filter_state & FIF_FCSFAIL)) |
518 | return -EINVAL; | ||
519 | } | ||
520 | |||
521 | decrypt = ar9170_get_decrypt_type(mac); | ||
522 | if (!(decrypt & AR9170_RX_ENC_SOFTWARE) && | ||
523 | decrypt != AR9170_ENC_ALG_NONE) | ||
524 | status->flag |= RX_FLAG_DECRYPTED; | ||
502 | 525 | ||
503 | status.band = ar->channel->band; | 526 | /* ignore wrong RA errors */ |
504 | status.freq = ar->channel->center_freq; | 527 | error &= ~AR9170_RX_ERROR_WRONG_RA; |
505 | status.signal = ar->noise[0] + tail->rssi_combined; | ||
506 | status.noise = ar->noise[0]; | ||
507 | status.antenna = antennas; | ||
508 | 528 | ||
509 | switch (tail->status & AR9170_RX_STATUS_MODULATION_MASK) { | 529 | if (error & AR9170_RX_ERROR_DECRYPT) { |
530 | error &= ~AR9170_RX_ERROR_DECRYPT; | ||
531 | /* | ||
532 | * Rx decryption is done in place, | ||
533 | * the original data is lost anyway. | ||
534 | */ | ||
535 | |||
536 | return -EINVAL; | ||
537 | } | ||
538 | |||
539 | /* drop any other error frames */ | ||
540 | if (unlikely(error)) { | ||
541 | /* TODO: update netdevice's RX dropped/errors statistics */ | ||
542 | |||
543 | if (ar9170_nag_limiter(ar)) | ||
544 | printk(KERN_DEBUG "%s: received frame with " | ||
545 | "suspicious error code (%#x).\n", | ||
546 | wiphy_name(ar->hw->wiphy), error); | ||
547 | |||
548 | return -EINVAL; | ||
549 | } | ||
550 | |||
551 | status->band = ar->channel->band; | ||
552 | status->freq = ar->channel->center_freq; | ||
553 | |||
554 | switch (mac->status & AR9170_RX_STATUS_MODULATION_MASK) { | ||
510 | case AR9170_RX_STATUS_MODULATION_CCK: | 555 | case AR9170_RX_STATUS_MODULATION_CCK: |
511 | if (tail->status & AR9170_RX_STATUS_SHORT_PREAMBLE) | 556 | if (mac->status & AR9170_RX_STATUS_SHORT_PREAMBLE) |
512 | status.flag |= RX_FLAG_SHORTPRE; | 557 | status->flag |= RX_FLAG_SHORTPRE; |
513 | switch (head->plcp[0]) { | 558 | switch (head->plcp[0]) { |
514 | case 0x0a: | 559 | case 0x0a: |
515 | status.rate_idx = 0; | 560 | status->rate_idx = 0; |
516 | break; | 561 | break; |
517 | case 0x14: | 562 | case 0x14: |
518 | status.rate_idx = 1; | 563 | status->rate_idx = 1; |
519 | break; | 564 | break; |
520 | case 0x37: | 565 | case 0x37: |
521 | status.rate_idx = 2; | 566 | status->rate_idx = 2; |
522 | break; | 567 | break; |
523 | case 0x6e: | 568 | case 0x6e: |
524 | status.rate_idx = 3; | 569 | status->rate_idx = 3; |
525 | break; | 570 | break; |
526 | default: | 571 | default: |
527 | if ((!ar->sniffer_enabled) && (net_ratelimit())) | 572 | if (ar9170_nag_limiter(ar)) |
528 | printk(KERN_ERR "%s: invalid plcp cck rate " | 573 | printk(KERN_ERR "%s: invalid plcp cck rate " |
529 | "(%x).\n", wiphy_name(ar->hw->wiphy), | 574 | "(%x).\n", wiphy_name(ar->hw->wiphy), |
530 | head->plcp[0]); | 575 | head->plcp[0]); |
531 | return; | 576 | return -EINVAL; |
532 | } | 577 | } |
533 | break; | 578 | break; |
579 | |||
534 | case AR9170_RX_STATUS_MODULATION_OFDM: | 580 | case AR9170_RX_STATUS_MODULATION_OFDM: |
535 | switch (head->plcp[0] & 0xF) { | 581 | switch (head->plcp[0] & 0xf) { |
536 | case 0xB: | 582 | case 0xb: |
537 | status.rate_idx = 0; | 583 | status->rate_idx = 0; |
538 | break; | 584 | break; |
539 | case 0xF: | 585 | case 0xf: |
540 | status.rate_idx = 1; | 586 | status->rate_idx = 1; |
541 | break; | 587 | break; |
542 | case 0xA: | 588 | case 0xa: |
543 | status.rate_idx = 2; | 589 | status->rate_idx = 2; |
544 | break; | 590 | break; |
545 | case 0xE: | 591 | case 0xe: |
546 | status.rate_idx = 3; | 592 | status->rate_idx = 3; |
547 | break; | 593 | break; |
548 | case 0x9: | 594 | case 0x9: |
549 | status.rate_idx = 4; | 595 | status->rate_idx = 4; |
550 | break; | 596 | break; |
551 | case 0xD: | 597 | case 0xd: |
552 | status.rate_idx = 5; | 598 | status->rate_idx = 5; |
553 | break; | 599 | break; |
554 | case 0x8: | 600 | case 0x8: |
555 | status.rate_idx = 6; | 601 | status->rate_idx = 6; |
556 | break; | 602 | break; |
557 | case 0xC: | 603 | case 0xc: |
558 | status.rate_idx = 7; | 604 | status->rate_idx = 7; |
559 | break; | 605 | break; |
560 | default: | 606 | default: |
561 | if ((!ar->sniffer_enabled) && (net_ratelimit())) | 607 | if (ar9170_nag_limiter(ar)) |
562 | printk(KERN_ERR "%s: invalid plcp ofdm rate " | 608 | printk(KERN_ERR "%s: invalid plcp ofdm rate " |
563 | "(%x).\n", wiphy_name(ar->hw->wiphy), | 609 | "(%x).\n", wiphy_name(ar->hw->wiphy), |
564 | head->plcp[0]); | 610 | head->plcp[0]); |
565 | return; | 611 | return -EINVAL; |
566 | } | 612 | } |
567 | if (status.band == IEEE80211_BAND_2GHZ) | 613 | if (status->band == IEEE80211_BAND_2GHZ) |
568 | status.rate_idx += 4; | 614 | status->rate_idx += 4; |
569 | break; | 615 | break; |
616 | |||
570 | case AR9170_RX_STATUS_MODULATION_HT: | 617 | case AR9170_RX_STATUS_MODULATION_HT: |
618 | if (head->plcp[3] & 0x80) | ||
619 | status->flag |= RX_FLAG_40MHZ; | ||
620 | if (head->plcp[6] & 0x80) | ||
621 | status->flag |= RX_FLAG_SHORT_GI; | ||
622 | |||
623 | status->rate_idx = clamp(0, 75, head->plcp[6] & 0x7f); | ||
624 | status->flag |= RX_FLAG_HT; | ||
625 | break; | ||
626 | |||
571 | case AR9170_RX_STATUS_MODULATION_DUPOFDM: | 627 | case AR9170_RX_STATUS_MODULATION_DUPOFDM: |
572 | /* XXX */ | 628 | /* XXX */ |
573 | 629 | if (ar9170_nag_limiter(ar)) | |
574 | if (net_ratelimit()) | ||
575 | printk(KERN_ERR "%s: invalid modulation\n", | 630 | printk(KERN_ERR "%s: invalid modulation\n", |
576 | wiphy_name(ar->hw->wiphy)); | 631 | wiphy_name(ar->hw->wiphy)); |
577 | return; | 632 | return -EINVAL; |
578 | } | 633 | } |
579 | 634 | ||
580 | error = tail->error; | 635 | return 0; |
636 | } | ||
581 | 637 | ||
582 | if (error & AR9170_RX_ERROR_MMIC) { | 638 | static void ar9170_rx_phy_status(struct ar9170 *ar, |
583 | status.flag |= RX_FLAG_MMIC_ERROR; | 639 | struct ar9170_rx_phystatus *phy, |
584 | error &= ~AR9170_RX_ERROR_MMIC; | 640 | struct ieee80211_rx_status *status) |
585 | } | 641 | { |
642 | int i; | ||
586 | 643 | ||
587 | if (error & AR9170_RX_ERROR_PLCP) { | 644 | BUILD_BUG_ON(sizeof(struct ar9170_rx_phystatus) != 20); |
588 | status.flag |= RX_FLAG_FAILED_PLCP_CRC; | 645 | |
589 | error &= ~AR9170_RX_ERROR_PLCP; | 646 | for (i = 0; i < 3; i++) |
647 | if (phy->rssi[i] != 0x80) | ||
648 | status->antenna |= BIT(i); | ||
649 | |||
650 | /* post-process RSSI */ | ||
651 | for (i = 0; i < 7; i++) | ||
652 | if (phy->rssi[i] & 0x80) | ||
653 | phy->rssi[i] = ((phy->rssi[i] & 0x7f) + 1) & 0x7f; | ||
654 | |||
655 | /* TODO: we could do something with phy_errors */ | ||
656 | status->signal = ar->noise[0] + phy->rssi_combined; | ||
657 | status->noise = ar->noise[0]; | ||
658 | } | ||
659 | |||
660 | static struct sk_buff *ar9170_rx_copy_data(u8 *buf, int len) | ||
661 | { | ||
662 | struct sk_buff *skb; | ||
663 | int reserved = 0; | ||
664 | struct ieee80211_hdr *hdr = (void *) buf; | ||
665 | |||
666 | if (ieee80211_is_data_qos(hdr->frame_control)) { | ||
667 | u8 *qc = ieee80211_get_qos_ctl(hdr); | ||
668 | reserved += NET_IP_ALIGN; | ||
669 | |||
670 | if (*qc & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT) | ||
671 | reserved += NET_IP_ALIGN; | ||
590 | } | 672 | } |
591 | 673 | ||
592 | if (error & AR9170_RX_ERROR_FCS) { | 674 | if (ieee80211_has_a4(hdr->frame_control)) |
593 | status.flag |= RX_FLAG_FAILED_FCS_CRC; | 675 | reserved += NET_IP_ALIGN; |
594 | error &= ~AR9170_RX_ERROR_FCS; | 676 | |
677 | reserved = 32 + (reserved & NET_IP_ALIGN); | ||
678 | |||
679 | skb = dev_alloc_skb(len + reserved); | ||
680 | if (likely(skb)) { | ||
681 | skb_reserve(skb, reserved); | ||
682 | memcpy(skb_put(skb, len), buf, len); | ||
595 | } | 683 | } |
596 | 684 | ||
597 | decrypt = ar9170_get_decrypt_type(tail); | 685 | return skb; |
598 | if (!(decrypt & AR9170_RX_ENC_SOFTWARE) && | 686 | } |
599 | decrypt != AR9170_ENC_ALG_NONE) | ||
600 | status.flag |= RX_FLAG_DECRYPTED; | ||
601 | 687 | ||
602 | /* ignore wrong RA errors */ | 688 | /* |
603 | error &= ~AR9170_RX_ERROR_WRONG_RA; | 689 | * If the frame alignment is right (or the kernel has |
690 | * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS), and there | ||
691 | * is only a single MPDU in the USB frame, then we could | ||
692 | * submit to mac80211 the SKB directly. However, since | ||
693 | * there may be multiple packets in one SKB in stream | ||
694 | * mode, and we need to observe the proper ordering, | ||
695 | * this is non-trivial. | ||
696 | */ | ||
604 | 697 | ||
605 | if (error & AR9170_RX_ERROR_DECRYPT) { | 698 | static void ar9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len) |
606 | error &= ~AR9170_RX_ERROR_DECRYPT; | 699 | { |
700 | struct ar9170_rx_head *head; | ||
701 | struct ar9170_rx_macstatus *mac; | ||
702 | struct ar9170_rx_phystatus *phy = NULL; | ||
703 | struct ieee80211_rx_status status; | ||
704 | struct sk_buff *skb; | ||
705 | int mpdu_len; | ||
706 | |||
707 | if (unlikely(!IS_STARTED(ar) || len < (sizeof(*mac)))) | ||
708 | return ; | ||
709 | |||
710 | /* Received MPDU */ | ||
711 | mpdu_len = len - sizeof(*mac); | ||
712 | |||
713 | mac = (void *)(buf + mpdu_len); | ||
714 | if (unlikely(mac->error & AR9170_RX_ERROR_FATAL)) { | ||
715 | /* this frame is too damaged and can't be used - drop it */ | ||
607 | 716 | ||
608 | /* | ||
609 | * Rx decryption is done in place, | ||
610 | * the original data is lost anyway. | ||
611 | */ | ||
612 | return ; | 717 | return ; |
613 | } | 718 | } |
614 | 719 | ||
615 | /* drop any other error frames */ | 720 | switch (mac->status & AR9170_RX_STATUS_MPDU_MASK) { |
616 | if ((error) && (net_ratelimit())) { | 721 | case AR9170_RX_STATUS_MPDU_FIRST: |
617 | printk(KERN_DEBUG "%s: errors: %#x\n", | 722 | /* first mpdu packet has the plcp header */ |
618 | wiphy_name(ar->hw->wiphy), error); | 723 | if (likely(mpdu_len >= sizeof(struct ar9170_rx_head))) { |
619 | return; | 724 | head = (void *) buf; |
725 | memcpy(&ar->rx_mpdu.plcp, (void *) buf, | ||
726 | sizeof(struct ar9170_rx_head)); | ||
727 | |||
728 | mpdu_len -= sizeof(struct ar9170_rx_head); | ||
729 | buf += sizeof(struct ar9170_rx_head); | ||
730 | ar->rx_mpdu.has_plcp = true; | ||
731 | } else { | ||
732 | if (ar9170_nag_limiter(ar)) | ||
733 | printk(KERN_ERR "%s: plcp info is clipped.\n", | ||
734 | wiphy_name(ar->hw->wiphy)); | ||
735 | return ; | ||
736 | } | ||
737 | break; | ||
738 | |||
739 | case AR9170_RX_STATUS_MPDU_LAST: | ||
740 | /* last mpdu has a extra tail with phy status information */ | ||
741 | |||
742 | if (likely(mpdu_len >= sizeof(struct ar9170_rx_phystatus))) { | ||
743 | mpdu_len -= sizeof(struct ar9170_rx_phystatus); | ||
744 | phy = (void *)(buf + mpdu_len); | ||
745 | } else { | ||
746 | if (ar9170_nag_limiter(ar)) | ||
747 | printk(KERN_ERR "%s: frame tail is clipped.\n", | ||
748 | wiphy_name(ar->hw->wiphy)); | ||
749 | return ; | ||
750 | } | ||
751 | |||
752 | case AR9170_RX_STATUS_MPDU_MIDDLE: | ||
753 | /* middle mpdus are just data */ | ||
754 | if (unlikely(!ar->rx_mpdu.has_plcp)) { | ||
755 | if (!ar9170_nag_limiter(ar)) | ||
756 | return ; | ||
757 | |||
758 | printk(KERN_ERR "%s: rx stream did not start " | ||
759 | "with a first_mpdu frame tag.\n", | ||
760 | wiphy_name(ar->hw->wiphy)); | ||
761 | |||
762 | return ; | ||
763 | } | ||
764 | |||
765 | head = &ar->rx_mpdu.plcp; | ||
766 | break; | ||
767 | |||
768 | case AR9170_RX_STATUS_MPDU_SINGLE: | ||
769 | /* single mpdu - has plcp (head) and phy status (tail) */ | ||
770 | head = (void *) buf; | ||
771 | |||
772 | mpdu_len -= sizeof(struct ar9170_rx_head); | ||
773 | mpdu_len -= sizeof(struct ar9170_rx_phystatus); | ||
774 | |||
775 | buf += sizeof(struct ar9170_rx_head); | ||
776 | phy = (void *)(buf + mpdu_len); | ||
777 | break; | ||
778 | |||
779 | default: | ||
780 | BUG_ON(1); | ||
781 | break; | ||
620 | } | 782 | } |
621 | 783 | ||
622 | buf += sizeof(struct ar9170_rx_head); | 784 | if (unlikely(mpdu_len < FCS_LEN)) |
623 | fc = *(__le16 *)buf; | 785 | return ; |
624 | 786 | ||
625 | if (ieee80211_is_data_qos(fc) ^ ieee80211_has_a4(fc)) | 787 | memset(&status, 0, sizeof(status)); |
626 | reserved = 32 + 2; | 788 | if (unlikely(ar9170_rx_mac_status(ar, head, mac, &status))) |
627 | else | 789 | return ; |
628 | reserved = 32; | ||
629 | 790 | ||
630 | skb = dev_alloc_skb(mpdu_len + reserved); | 791 | if (phy) |
631 | if (!skb) | 792 | ar9170_rx_phy_status(ar, phy, &status); |
632 | return; | ||
633 | 793 | ||
634 | skb_reserve(skb, reserved); | 794 | skb = ar9170_rx_copy_data(buf, mpdu_len); |
635 | memcpy(skb_put(skb, mpdu_len), buf, mpdu_len); | 795 | if (likely(skb)) |
636 | ieee80211_rx_irqsafe(ar->hw, skb, &status); | 796 | ieee80211_rx_irqsafe(ar->hw, skb, &status); |
637 | } | 797 | } |
638 | 798 | ||
639 | void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb) | 799 | void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb) |
640 | { | 800 | { |
641 | unsigned int i, tlen, resplen; | 801 | unsigned int i, tlen, resplen, wlen = 0, clen = 0; |
642 | u8 *tbuf, *respbuf; | 802 | u8 *tbuf, *respbuf; |
643 | 803 | ||
644 | tbuf = skb->data; | 804 | tbuf = skb->data; |
645 | tlen = skb->len; | 805 | tlen = skb->len; |
646 | 806 | ||
647 | while (tlen >= 4) { | 807 | while (tlen >= 4) { |
648 | int clen = tbuf[1] << 8 | tbuf[0]; | 808 | clen = tbuf[1] << 8 | tbuf[0]; |
649 | int wlen = (clen + 3) & ~3; | 809 | wlen = ALIGN(clen, 4); |
650 | 810 | ||
651 | /* | 811 | /* check if this is stream has a valid tag.*/ |
652 | * parse stream (if any) | ||
653 | */ | ||
654 | if (tbuf[2] != 0 || tbuf[3] != 0x4e) { | 812 | if (tbuf[2] != 0 || tbuf[3] != 0x4e) { |
655 | printk(KERN_ERR "%s: missing tag!\n", | 813 | /* |
656 | wiphy_name(ar->hw->wiphy)); | 814 | * TODO: handle the highly unlikely event that the |
815 | * corrupted stream has the TAG at the right position. | ||
816 | */ | ||
817 | |||
818 | /* check if the frame can be repaired. */ | ||
819 | if (!ar->rx_failover_missing) { | ||
820 | /* this is no "short read". */ | ||
821 | if (ar9170_nag_limiter(ar)) { | ||
822 | printk(KERN_ERR "%s: missing tag!\n", | ||
823 | wiphy_name(ar->hw->wiphy)); | ||
824 | goto err_telluser; | ||
825 | } else | ||
826 | goto err_silent; | ||
827 | } | ||
828 | |||
829 | if (ar->rx_failover_missing > tlen) { | ||
830 | if (ar9170_nag_limiter(ar)) { | ||
831 | printk(KERN_ERR "%s: possible multi " | ||
832 | "stream corruption!\n", | ||
833 | wiphy_name(ar->hw->wiphy)); | ||
834 | goto err_telluser; | ||
835 | } else | ||
836 | goto err_silent; | ||
837 | } | ||
838 | |||
839 | memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen); | ||
840 | ar->rx_failover_missing -= tlen; | ||
841 | |||
842 | if (ar->rx_failover_missing <= 0) { | ||
843 | /* | ||
844 | * nested ar9170_rx call! | ||
845 | * termination is guranteed, even when the | ||
846 | * combined frame also have a element with | ||
847 | * a bad tag. | ||
848 | */ | ||
849 | |||
850 | ar->rx_failover_missing = 0; | ||
851 | ar9170_rx(ar, ar->rx_failover); | ||
852 | |||
853 | skb_reset_tail_pointer(ar->rx_failover); | ||
854 | skb_trim(ar->rx_failover, 0); | ||
855 | } | ||
856 | |||
657 | return ; | 857 | return ; |
658 | } | 858 | } |
859 | |||
860 | /* check if stream is clipped */ | ||
659 | if (wlen > tlen - 4) { | 861 | if (wlen > tlen - 4) { |
660 | printk(KERN_ERR "%s: invalid RX (%d, %d, %d)\n", | 862 | if (ar->rx_failover_missing) { |
661 | wiphy_name(ar->hw->wiphy), clen, wlen, tlen); | 863 | /* TODO: handle double stream corruption. */ |
662 | print_hex_dump(KERN_DEBUG, "data: ", | 864 | if (ar9170_nag_limiter(ar)) { |
663 | DUMP_PREFIX_OFFSET, | 865 | printk(KERN_ERR "%s: double rx stream " |
664 | 16, 1, tbuf, tlen, true); | 866 | "corruption!\n", |
867 | wiphy_name(ar->hw->wiphy)); | ||
868 | goto err_telluser; | ||
869 | } else | ||
870 | goto err_silent; | ||
871 | } | ||
872 | |||
873 | /* | ||
874 | * save incomplete data set. | ||
875 | * the firmware will resend the missing bits when | ||
876 | * the rx - descriptor comes round again. | ||
877 | */ | ||
878 | |||
879 | memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen); | ||
880 | ar->rx_failover_missing = clen - tlen; | ||
665 | return ; | 881 | return ; |
666 | } | 882 | } |
667 | resplen = clen; | 883 | resplen = clen; |
@@ -686,12 +902,44 @@ void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb) | |||
686 | if (i == 12) | 902 | if (i == 12) |
687 | ar9170_handle_command_response(ar, respbuf, resplen); | 903 | ar9170_handle_command_response(ar, respbuf, resplen); |
688 | else | 904 | else |
689 | ar9170_handle_mpdu(ar, respbuf, resplen); | 905 | ar9170_handle_mpdu(ar, respbuf, clen); |
690 | } | 906 | } |
691 | 907 | ||
692 | if (tlen) | 908 | if (tlen) { |
693 | printk(KERN_ERR "%s: buffer remains!\n", | 909 | if (net_ratelimit()) |
694 | wiphy_name(ar->hw->wiphy)); | 910 | printk(KERN_ERR "%s: %d bytes of unprocessed " |
911 | "data left in rx stream!\n", | ||
912 | wiphy_name(ar->hw->wiphy), tlen); | ||
913 | |||
914 | goto err_telluser; | ||
915 | } | ||
916 | |||
917 | return ; | ||
918 | |||
919 | err_telluser: | ||
920 | printk(KERN_ERR "%s: damaged RX stream data [want:%d, " | ||
921 | "data:%d, rx:%d, pending:%d ]\n", | ||
922 | wiphy_name(ar->hw->wiphy), clen, wlen, tlen, | ||
923 | ar->rx_failover_missing); | ||
924 | |||
925 | if (ar->rx_failover_missing) | ||
926 | print_hex_dump_bytes("rxbuf:", DUMP_PREFIX_OFFSET, | ||
927 | ar->rx_failover->data, | ||
928 | ar->rx_failover->len); | ||
929 | |||
930 | print_hex_dump_bytes("stream:", DUMP_PREFIX_OFFSET, | ||
931 | skb->data, skb->len); | ||
932 | |||
933 | printk(KERN_ERR "%s: please check your hardware and cables, if " | ||
934 | "you see this message frequently.\n", | ||
935 | wiphy_name(ar->hw->wiphy)); | ||
936 | |||
937 | err_silent: | ||
938 | if (ar->rx_failover_missing) { | ||
939 | skb_reset_tail_pointer(ar->rx_failover); | ||
940 | skb_trim(ar->rx_failover, 0); | ||
941 | ar->rx_failover_missing = 0; | ||
942 | } | ||
695 | } | 943 | } |
696 | 944 | ||
697 | #define AR9170_FILL_QUEUE(queue, ai_fs, cwmin, cwmax, _txop) \ | 945 | #define AR9170_FILL_QUEUE(queue, ai_fs, cwmin, cwmax, _txop) \ |
@@ -721,6 +969,8 @@ static int ar9170_op_start(struct ieee80211_hw *hw) | |||
721 | AR9170_FILL_QUEUE(ar->edcf[3], 2, 3, 7, 47); /* VOICE */ | 969 | AR9170_FILL_QUEUE(ar->edcf[3], 2, 3, 7, 47); /* VOICE */ |
722 | AR9170_FILL_QUEUE(ar->edcf[4], 2, 3, 7, 0); /* SPECIAL */ | 970 | AR9170_FILL_QUEUE(ar->edcf[4], 2, 3, 7, 0); /* SPECIAL */ |
723 | 971 | ||
972 | ar->bad_hw_nagger = jiffies; | ||
973 | |||
724 | err = ar->open(ar); | 974 | err = ar->open(ar); |
725 | if (err) | 975 | if (err) |
726 | goto out; | 976 | goto out; |
@@ -1175,8 +1425,8 @@ static void ar9170_op_configure_filter(struct ieee80211_hw *hw, | |||
1175 | 1425 | ||
1176 | /* mask supported flags */ | 1426 | /* mask supported flags */ |
1177 | *new_flags &= FIF_ALLMULTI | FIF_CONTROL | FIF_BCN_PRBRESP_PROMISC | | 1427 | *new_flags &= FIF_ALLMULTI | FIF_CONTROL | FIF_BCN_PRBRESP_PROMISC | |
1178 | FIF_PROMISC_IN_BSS; | 1428 | FIF_PROMISC_IN_BSS | FIF_FCSFAIL | FIF_PLCPFAIL; |
1179 | 1429 | ar->filter_state = *new_flags; | |
1180 | /* | 1430 | /* |
1181 | * We can support more by setting the sniffer bit and | 1431 | * We can support more by setting the sniffer bit and |
1182 | * then checking the error flags, later. | 1432 | * then checking the error flags, later. |
@@ -1559,20 +1809,33 @@ void *ar9170_alloc(size_t priv_size) | |||
1559 | { | 1809 | { |
1560 | struct ieee80211_hw *hw; | 1810 | struct ieee80211_hw *hw; |
1561 | struct ar9170 *ar; | 1811 | struct ar9170 *ar; |
1812 | struct sk_buff *skb; | ||
1562 | int i; | 1813 | int i; |
1563 | 1814 | ||
1815 | /* | ||
1816 | * this buffer is used for rx stream reconstruction. | ||
1817 | * Under heavy load this device (or the transport layer?) | ||
1818 | * tends to split the streams into seperate rx descriptors. | ||
1819 | */ | ||
1820 | |||
1821 | skb = __dev_alloc_skb(AR9170_MAX_RX_BUFFER_SIZE, GFP_KERNEL); | ||
1822 | if (!skb) | ||
1823 | goto err_nomem; | ||
1824 | |||
1564 | hw = ieee80211_alloc_hw(priv_size, &ar9170_ops); | 1825 | hw = ieee80211_alloc_hw(priv_size, &ar9170_ops); |
1565 | if (!hw) | 1826 | if (!hw) |
1566 | return ERR_PTR(-ENOMEM); | 1827 | goto err_nomem; |
1567 | 1828 | ||
1568 | ar = hw->priv; | 1829 | ar = hw->priv; |
1569 | ar->hw = hw; | 1830 | ar->hw = hw; |
1831 | ar->rx_failover = skb; | ||
1570 | 1832 | ||
1571 | mutex_init(&ar->mutex); | 1833 | mutex_init(&ar->mutex); |
1572 | spin_lock_init(&ar->cmdlock); | 1834 | spin_lock_init(&ar->cmdlock); |
1573 | spin_lock_init(&ar->tx_stats_lock); | 1835 | spin_lock_init(&ar->tx_stats_lock); |
1574 | skb_queue_head_init(&ar->global_tx_status); | 1836 | skb_queue_head_init(&ar->global_tx_status); |
1575 | skb_queue_head_init(&ar->global_tx_status_waste); | 1837 | skb_queue_head_init(&ar->global_tx_status_waste); |
1838 | ar9170_rx_reset_rx_mpdu(ar); | ||
1576 | INIT_WORK(&ar->filter_config_work, ar9170_set_filters); | 1839 | INIT_WORK(&ar->filter_config_work, ar9170_set_filters); |
1577 | INIT_WORK(&ar->beacon_work, ar9170_new_beacon); | 1840 | INIT_WORK(&ar->beacon_work, ar9170_new_beacon); |
1578 | INIT_DELAYED_WORK(&ar->tx_status_janitor, ar9170_tx_status_janitor); | 1841 | INIT_DELAYED_WORK(&ar->tx_status_janitor, ar9170_tx_status_janitor); |
@@ -1600,6 +1863,10 @@ void *ar9170_alloc(size_t priv_size) | |||
1600 | ar->noise[i] = -95; /* ATH_DEFAULT_NOISE_FLOOR */ | 1863 | ar->noise[i] = -95; /* ATH_DEFAULT_NOISE_FLOOR */ |
1601 | 1864 | ||
1602 | return ar; | 1865 | return ar; |
1866 | |||
1867 | err_nomem: | ||
1868 | kfree_skb(skb); | ||
1869 | return ERR_PTR(-ENOMEM); | ||
1603 | } | 1870 | } |
1604 | 1871 | ||
1605 | static int ar9170_read_eeprom(struct ar9170 *ar) | 1872 | static int ar9170_read_eeprom(struct ar9170 *ar) |
@@ -1725,6 +1992,7 @@ void ar9170_unregister(struct ar9170 *ar) | |||
1725 | ar9170_unregister_leds(ar); | 1992 | ar9170_unregister_leds(ar); |
1726 | #endif /* CONFIG_AR9170_LEDS */ | 1993 | #endif /* CONFIG_AR9170_LEDS */ |
1727 | 1994 | ||
1995 | kfree_skb(ar->rx_failover); | ||
1728 | ieee80211_unregister_hw(ar->hw); | 1996 | ieee80211_unregister_hw(ar->hw); |
1729 | mutex_destroy(&ar->mutex); | 1997 | mutex_destroy(&ar->mutex); |
1730 | } | 1998 | } |