diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2500usb.c | 7 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800.h | 61 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800lib.c | 264 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800lib.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800pci.c | 165 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00.h | 18 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00config.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00dev.c | 38 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00ht.c | 21 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00mac.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt61pci.c | 5 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt73usb.c | 8 |
12 files changed, 496 insertions, 97 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 6e94356265b3..93e44c7f3a74 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
@@ -1674,10 +1674,15 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1674 | 1674 | ||
1675 | /* | 1675 | /* |
1676 | * Initialize all hw fields. | 1676 | * Initialize all hw fields. |
1677 | * | ||
1678 | * Don't set IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING unless we are | ||
1679 | * capable of sending the buffered frames out after the DTIM | ||
1680 | * transmission using rt2x00lib_beacondone. This will send out | ||
1681 | * multicast and broadcast traffic immediately instead of buffering it | ||
1682 | * infinitly and thus dropping it after some time. | ||
1677 | */ | 1683 | */ |
1678 | rt2x00dev->hw->flags = | 1684 | rt2x00dev->hw->flags = |
1679 | IEEE80211_HW_RX_INCLUDES_FCS | | 1685 | IEEE80211_HW_RX_INCLUDES_FCS | |
1680 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | ||
1681 | IEEE80211_HW_SIGNAL_DBM | | 1686 | IEEE80211_HW_SIGNAL_DBM | |
1682 | IEEE80211_HW_SUPPORTS_PS | | 1687 | IEEE80211_HW_SUPPORTS_PS | |
1683 | IEEE80211_HW_PS_NULLFUNC_STACK; | 1688 | IEEE80211_HW_PS_NULLFUNC_STACK; |
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index 2edc7742a7e9..eb8b6cab9925 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> | 2 | Copyright (C) 2004 - 2010 Ivo van Doorn <IvDoorn@gmail.com> |
3 | Copyright (C) 2010 Willow Garage <http://www.willowgarage.com> | ||
3 | Copyright (C) 2009 Alban Browaeys <prahal@yahoo.com> | 4 | Copyright (C) 2009 Alban Browaeys <prahal@yahoo.com> |
4 | Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org> | 5 | Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org> |
5 | Copyright (C) 2009 Luis Correia <luis.f.correia@gmail.com> | 6 | Copyright (C) 2009 Luis Correia <luis.f.correia@gmail.com> |
@@ -710,8 +711,14 @@ | |||
710 | 711 | ||
711 | /* | 712 | /* |
712 | * TBTT_SYNC_CFG: | 713 | * TBTT_SYNC_CFG: |
714 | * BCN_AIFSN: Beacon AIFSN after TBTT interrupt in slots | ||
715 | * BCN_CWMIN: Beacon CWMin after TBTT interrupt in slots | ||
713 | */ | 716 | */ |
714 | #define TBTT_SYNC_CFG 0x1118 | 717 | #define TBTT_SYNC_CFG 0x1118 |
718 | #define TBTT_SYNC_CFG_TBTT_ADJUST FIELD32(0x000000ff) | ||
719 | #define TBTT_SYNC_CFG_BCN_EXP_WIN FIELD32(0x0000ff00) | ||
720 | #define TBTT_SYNC_CFG_BCN_AIFSN FIELD32(0x000f0000) | ||
721 | #define TBTT_SYNC_CFG_BCN_CWMIN FIELD32(0x00f00000) | ||
715 | 722 | ||
716 | /* | 723 | /* |
717 | * TSF_TIMER_DW0: Local lsb TSF timer, read-only | 724 | * TSF_TIMER_DW0: Local lsb TSF timer, read-only |
@@ -747,16 +754,21 @@ | |||
747 | #define INT_TIMER_EN_GP_TIMER FIELD32(0x00000002) | 754 | #define INT_TIMER_EN_GP_TIMER FIELD32(0x00000002) |
748 | 755 | ||
749 | /* | 756 | /* |
750 | * CH_IDLE_STA: channel idle time | 757 | * CH_IDLE_STA: channel idle time (in us) |
751 | */ | 758 | */ |
752 | #define CH_IDLE_STA 0x1130 | 759 | #define CH_IDLE_STA 0x1130 |
753 | 760 | ||
754 | /* | 761 | /* |
755 | * CH_BUSY_STA: channel busy time | 762 | * CH_BUSY_STA: channel busy time on primary channel (in us) |
756 | */ | 763 | */ |
757 | #define CH_BUSY_STA 0x1134 | 764 | #define CH_BUSY_STA 0x1134 |
758 | 765 | ||
759 | /* | 766 | /* |
767 | * CH_BUSY_STA_SEC: channel busy time on secondary channel in HT40 mode (in us) | ||
768 | */ | ||
769 | #define CH_BUSY_STA_SEC 0x1138 | ||
770 | |||
771 | /* | ||
760 | * MAC_STATUS_CFG: | 772 | * MAC_STATUS_CFG: |
761 | * BBP_RF_BUSY: When set to 0, BBP and RF are stable. | 773 | * BBP_RF_BUSY: When set to 0, BBP and RF are stable. |
762 | * if 1 or higher one of the 2 registers is busy. | 774 | * if 1 or higher one of the 2 registers is busy. |
@@ -1342,6 +1354,9 @@ | |||
1342 | * PID_TYPE: The PID latched from the PID field in the TXWI, can be used | 1354 | * PID_TYPE: The PID latched from the PID field in the TXWI, can be used |
1343 | * to match a frame with its tx result (even though the PID is | 1355 | * to match a frame with its tx result (even though the PID is |
1344 | * only 4 bits wide). | 1356 | * only 4 bits wide). |
1357 | * PID_QUEUE: Part of PID_TYPE, this is the queue index number (0-3) | ||
1358 | * PID_ENTRY: Part of PID_TYPE, this is the queue entry index number (1-3) | ||
1359 | * This identification number is calculated by ((idx % 3) + 1). | ||
1345 | * TX_SUCCESS: Indicates tx success (1) or failure (0) | 1360 | * TX_SUCCESS: Indicates tx success (1) or failure (0) |
1346 | * TX_AGGRE: Indicates if the frame was part of an aggregate (1) or not (0) | 1361 | * TX_AGGRE: Indicates if the frame was part of an aggregate (1) or not (0) |
1347 | * TX_ACK_REQUIRED: Indicates if the frame needed to get ack'ed (1) or not (0) | 1362 | * TX_ACK_REQUIRED: Indicates if the frame needed to get ack'ed (1) or not (0) |
@@ -1353,6 +1368,8 @@ | |||
1353 | #define TX_STA_FIFO 0x1718 | 1368 | #define TX_STA_FIFO 0x1718 |
1354 | #define TX_STA_FIFO_VALID FIELD32(0x00000001) | 1369 | #define TX_STA_FIFO_VALID FIELD32(0x00000001) |
1355 | #define TX_STA_FIFO_PID_TYPE FIELD32(0x0000001e) | 1370 | #define TX_STA_FIFO_PID_TYPE FIELD32(0x0000001e) |
1371 | #define TX_STA_FIFO_PID_QUEUE FIELD32(0x00000006) | ||
1372 | #define TX_STA_FIFO_PID_ENTRY FIELD32(0x00000018) | ||
1356 | #define TX_STA_FIFO_TX_SUCCESS FIELD32(0x00000020) | 1373 | #define TX_STA_FIFO_TX_SUCCESS FIELD32(0x00000020) |
1357 | #define TX_STA_FIFO_TX_AGGRE FIELD32(0x00000040) | 1374 | #define TX_STA_FIFO_TX_AGGRE FIELD32(0x00000040) |
1358 | #define TX_STA_FIFO_TX_ACK_REQUIRED FIELD32(0x00000080) | 1375 | #define TX_STA_FIFO_TX_ACK_REQUIRED FIELD32(0x00000080) |
@@ -1435,6 +1452,24 @@ | |||
1435 | 1452 | ||
1436 | /* | 1453 | /* |
1437 | * Security key table memory. | 1454 | * Security key table memory. |
1455 | * | ||
1456 | * The pairwise key table shares some memory with the beacon frame | ||
1457 | * buffers 6 and 7. That basically means that when beacon 6 & 7 | ||
1458 | * are used we should only use the reduced pairwise key table which | ||
1459 | * has a maximum of 222 entries. | ||
1460 | * | ||
1461 | * --------------------------------------------- | ||
1462 | * |0x4000 | Pairwise Key | Reduced Pairwise | | ||
1463 | * | | Table | Key Table | | ||
1464 | * | | Size: 256 * 32 | Size: 222 * 32 | | ||
1465 | * |0x5BC0 | |------------------- | ||
1466 | * | | | Beacon 6 | | ||
1467 | * |0x5DC0 | |------------------- | ||
1468 | * | | | Beacon 7 | | ||
1469 | * |0x5FC0 | |------------------- | ||
1470 | * |0x5FFF | | | ||
1471 | * -------------------------- | ||
1472 | * | ||
1438 | * MAC_WCID_BASE: 8-bytes (use only 6 bytes) * 256 entry | 1473 | * MAC_WCID_BASE: 8-bytes (use only 6 bytes) * 256 entry |
1439 | * PAIRWISE_KEY_TABLE_BASE: 32-byte * 256 entry | 1474 | * PAIRWISE_KEY_TABLE_BASE: 32-byte * 256 entry |
1440 | * MAC_IVEIV_TABLE_BASE: 8-byte * 256-entry | 1475 | * MAC_IVEIV_TABLE_BASE: 8-byte * 256-entry |
@@ -1584,7 +1619,8 @@ struct mac_iveiv_entry { | |||
1584 | * 2. Extract memory from FCE table for BCN 4~5 | 1619 | * 2. Extract memory from FCE table for BCN 4~5 |
1585 | * 3. Extract memory from Pair-wise key table for BCN 6~7 | 1620 | * 3. Extract memory from Pair-wise key table for BCN 6~7 |
1586 | * It occupied those memory of wcid 238~253 for BCN 6 | 1621 | * It occupied those memory of wcid 238~253 for BCN 6 |
1587 | * and wcid 222~237 for BCN 7 | 1622 | * and wcid 222~237 for BCN 7 (see Security key table memory |
1623 | * for more info). | ||
1588 | * | 1624 | * |
1589 | * IMPORTANT NOTE: Not sure why legacy driver does this, | 1625 | * IMPORTANT NOTE: Not sure why legacy driver does this, |
1590 | * but HW_BEACON_BASE7 is 0x0200 bytes below HW_BEACON_BASE6. | 1626 | * but HW_BEACON_BASE7 is 0x0200 bytes below HW_BEACON_BASE6. |
@@ -1963,10 +1999,17 @@ struct mac_iveiv_entry { | |||
1963 | * FRAG: 1 To inform TKIP engine this is a fragment. | 1999 | * FRAG: 1 To inform TKIP engine this is a fragment. |
1964 | * MIMO_PS: The remote peer is in dynamic MIMO-PS mode | 2000 | * MIMO_PS: The remote peer is in dynamic MIMO-PS mode |
1965 | * TX_OP: 0:HT TXOP rule , 1:PIFS TX ,2:Backoff, 3:sifs | 2001 | * TX_OP: 0:HT TXOP rule , 1:PIFS TX ,2:Backoff, 3:sifs |
1966 | * BW: Channel bandwidth 20MHz or 40 MHz | 2002 | * BW: Channel bandwidth 0:20MHz, 1:40 MHz (for legacy rates this will |
2003 | * duplicate the frame to both channels). | ||
1967 | * STBC: 1: STBC support MCS =0-7, 2,3 : RESERVED | 2004 | * STBC: 1: STBC support MCS =0-7, 2,3 : RESERVED |
1968 | * AMPDU: 1: this frame is eligible for AMPDU aggregation, the hw will | 2005 | * AMPDU: 1: this frame is eligible for AMPDU aggregation, the hw will |
1969 | * aggregate consecutive frames with the same RA and QoS TID. | 2006 | * aggregate consecutive frames with the same RA and QoS TID. If |
2007 | * a frame A with the same RA and QoS TID but AMPDU=0 is queued | ||
2008 | * directly after a frame B with AMPDU=1, frame A might still | ||
2009 | * get aggregated into the AMPDU started by frame B. So, setting | ||
2010 | * AMPDU to 0 does _not_ necessarily mean the frame is sent as | ||
2011 | * MPDU, it can still end up in an AMPDU if the previous frame | ||
2012 | * was tagged as AMPDU. | ||
1970 | */ | 2013 | */ |
1971 | #define TXWI_W0_FRAG FIELD32(0x00000001) | 2014 | #define TXWI_W0_FRAG FIELD32(0x00000001) |
1972 | #define TXWI_W0_MIMO_PS FIELD32(0x00000002) | 2015 | #define TXWI_W0_MIMO_PS FIELD32(0x00000002) |
@@ -1993,6 +2036,10 @@ struct mac_iveiv_entry { | |||
1993 | * frame was processed. If multiple frames are aggregated together | 2036 | * frame was processed. If multiple frames are aggregated together |
1994 | * (AMPDU==1) the reported tx status will always contain the packet | 2037 | * (AMPDU==1) the reported tx status will always contain the packet |
1995 | * id of the first frame. 0: Don't report tx status for this frame. | 2038 | * id of the first frame. 0: Don't report tx status for this frame. |
2039 | * PACKETID_QUEUE: Part of PACKETID, This is the queue index (0-3) | ||
2040 | * PACKETID_ENTRY: Part of PACKETID, THis is the queue entry index (1-3) | ||
2041 | * This identification number is calculated by ((idx % 3) + 1). | ||
2042 | * The (+1) is required to prevent PACKETID to become 0. | ||
1996 | */ | 2043 | */ |
1997 | #define TXWI_W1_ACK FIELD32(0x00000001) | 2044 | #define TXWI_W1_ACK FIELD32(0x00000001) |
1998 | #define TXWI_W1_NSEQ FIELD32(0x00000002) | 2045 | #define TXWI_W1_NSEQ FIELD32(0x00000002) |
@@ -2000,6 +2047,8 @@ struct mac_iveiv_entry { | |||
2000 | #define TXWI_W1_WIRELESS_CLI_ID FIELD32(0x0000ff00) | 2047 | #define TXWI_W1_WIRELESS_CLI_ID FIELD32(0x0000ff00) |
2001 | #define TXWI_W1_MPDU_TOTAL_BYTE_COUNT FIELD32(0x0fff0000) | 2048 | #define TXWI_W1_MPDU_TOTAL_BYTE_COUNT FIELD32(0x0fff0000) |
2002 | #define TXWI_W1_PACKETID FIELD32(0xf0000000) | 2049 | #define TXWI_W1_PACKETID FIELD32(0xf0000000) |
2050 | #define TXWI_W1_PACKETID_QUEUE FIELD32(0x30000000) | ||
2051 | #define TXWI_W1_PACKETID_ENTRY FIELD32(0xc0000000) | ||
2003 | 2052 | ||
2004 | /* | 2053 | /* |
2005 | * Word2 | 2054 | * Word2 |
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 3bb67492d754..10aefc4fb0cc 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
@@ -483,7 +483,8 @@ void rt2800_write_tx_data(struct queue_entry *entry, | |||
483 | txdesc->key_idx : 0xff); | 483 | txdesc->key_idx : 0xff); |
484 | rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT, | 484 | rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT, |
485 | txdesc->length); | 485 | txdesc->length); |
486 | rt2x00_set_field32(&word, TXWI_W1_PACKETID, txdesc->qid + 1); | 486 | rt2x00_set_field32(&word, TXWI_W1_PACKETID_QUEUE, txdesc->qid); |
487 | rt2x00_set_field32(&word, TXWI_W1_PACKETID_ENTRY, (entry->entry_idx % 3) + 1); | ||
487 | rt2x00_desc_write(txwi, 1, word); | 488 | rt2x00_desc_write(txwi, 1, word); |
488 | 489 | ||
489 | /* | 490 | /* |
@@ -630,15 +631,90 @@ static bool rt2800_txdone_entry_check(struct queue_entry *entry, u32 reg) | |||
630 | return true; | 631 | return true; |
631 | } | 632 | } |
632 | 633 | ||
634 | void rt2800_txdone_entry(struct queue_entry *entry, u32 status) | ||
635 | { | ||
636 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | ||
637 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | ||
638 | struct txdone_entry_desc txdesc; | ||
639 | u32 word; | ||
640 | u16 mcs, real_mcs; | ||
641 | int aggr, ampdu; | ||
642 | __le32 *txwi; | ||
643 | |||
644 | /* | ||
645 | * Obtain the status about this packet. | ||
646 | */ | ||
647 | txdesc.flags = 0; | ||
648 | txwi = rt2800_drv_get_txwi(entry); | ||
649 | rt2x00_desc_read(txwi, 0, &word); | ||
650 | |||
651 | mcs = rt2x00_get_field32(word, TXWI_W0_MCS); | ||
652 | ampdu = rt2x00_get_field32(word, TXWI_W0_AMPDU); | ||
653 | |||
654 | real_mcs = rt2x00_get_field32(status, TX_STA_FIFO_MCS); | ||
655 | aggr = rt2x00_get_field32(status, TX_STA_FIFO_TX_AGGRE); | ||
656 | |||
657 | /* | ||
658 | * If a frame was meant to be sent as a single non-aggregated MPDU | ||
659 | * but ended up in an aggregate the used tx rate doesn't correlate | ||
660 | * with the one specified in the TXWI as the whole aggregate is sent | ||
661 | * with the same rate. | ||
662 | * | ||
663 | * For example: two frames are sent to rt2x00, the first one sets | ||
664 | * AMPDU=1 and requests MCS7 whereas the second frame sets AMDPU=0 | ||
665 | * and requests MCS15. If the hw aggregates both frames into one | ||
666 | * AMDPU the tx status for both frames will contain MCS7 although | ||
667 | * the frame was sent successfully. | ||
668 | * | ||
669 | * Hence, replace the requested rate with the real tx rate to not | ||
670 | * confuse the rate control algortihm by providing clearly wrong | ||
671 | * data. | ||
672 | */ | ||
673 | if (aggr == 1 && ampdu == 0 && real_mcs != mcs) { | ||
674 | skbdesc->tx_rate_idx = real_mcs; | ||
675 | mcs = real_mcs; | ||
676 | } | ||
677 | |||
678 | /* | ||
679 | * Ralink has a retry mechanism using a global fallback | ||
680 | * table. We setup this fallback table to try the immediate | ||
681 | * lower rate for all rates. In the TX_STA_FIFO, the MCS field | ||
682 | * always contains the MCS used for the last transmission, be | ||
683 | * it successful or not. | ||
684 | */ | ||
685 | if (rt2x00_get_field32(status, TX_STA_FIFO_TX_SUCCESS)) { | ||
686 | /* | ||
687 | * Transmission succeeded. The number of retries is | ||
688 | * mcs - real_mcs | ||
689 | */ | ||
690 | __set_bit(TXDONE_SUCCESS, &txdesc.flags); | ||
691 | txdesc.retry = ((mcs > real_mcs) ? mcs - real_mcs : 0); | ||
692 | } else { | ||
693 | /* | ||
694 | * Transmission failed. The number of retries is | ||
695 | * always 7 in this case (for a total number of 8 | ||
696 | * frames sent). | ||
697 | */ | ||
698 | __set_bit(TXDONE_FAILURE, &txdesc.flags); | ||
699 | txdesc.retry = rt2x00dev->long_retry; | ||
700 | } | ||
701 | |||
702 | /* | ||
703 | * the frame was retried at least once | ||
704 | * -> hw used fallback rates | ||
705 | */ | ||
706 | if (txdesc.retry) | ||
707 | __set_bit(TXDONE_FALLBACK, &txdesc.flags); | ||
708 | |||
709 | rt2x00lib_txdone(entry, &txdesc); | ||
710 | } | ||
711 | EXPORT_SYMBOL_GPL(rt2800_txdone_entry); | ||
712 | |||
633 | void rt2800_txdone(struct rt2x00_dev *rt2x00dev) | 713 | void rt2800_txdone(struct rt2x00_dev *rt2x00dev) |
634 | { | 714 | { |
635 | struct data_queue *queue; | 715 | struct data_queue *queue; |
636 | struct queue_entry *entry; | 716 | struct queue_entry *entry; |
637 | __le32 *txwi; | ||
638 | struct txdone_entry_desc txdesc; | ||
639 | u32 word; | ||
640 | u32 reg; | 717 | u32 reg; |
641 | u16 mcs, real_mcs; | ||
642 | u8 pid; | 718 | u8 pid; |
643 | int i; | 719 | int i; |
644 | 720 | ||
@@ -660,7 +736,7 @@ void rt2800_txdone(struct rt2x00_dev *rt2x00dev) | |||
660 | * Skip this entry when it contains an invalid | 736 | * Skip this entry when it contains an invalid |
661 | * queue identication number. | 737 | * queue identication number. |
662 | */ | 738 | */ |
663 | pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE) - 1; | 739 | pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE); |
664 | if (pid >= QID_RX) | 740 | if (pid >= QID_RX) |
665 | continue; | 741 | continue; |
666 | 742 | ||
@@ -673,7 +749,6 @@ void rt2800_txdone(struct rt2x00_dev *rt2x00dev) | |||
673 | * order. We first check that the queue is not empty. | 749 | * order. We first check that the queue is not empty. |
674 | */ | 750 | */ |
675 | entry = NULL; | 751 | entry = NULL; |
676 | txwi = NULL; | ||
677 | while (!rt2x00queue_empty(queue)) { | 752 | while (!rt2x00queue_empty(queue)) { |
678 | entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); | 753 | entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); |
679 | if (rt2800_txdone_entry_check(entry, reg)) | 754 | if (rt2800_txdone_entry_check(entry, reg)) |
@@ -683,48 +758,7 @@ void rt2800_txdone(struct rt2x00_dev *rt2x00dev) | |||
683 | if (!entry || rt2x00queue_empty(queue)) | 758 | if (!entry || rt2x00queue_empty(queue)) |
684 | break; | 759 | break; |
685 | 760 | ||
686 | 761 | rt2800_txdone_entry(entry, reg); | |
687 | /* | ||
688 | * Obtain the status about this packet. | ||
689 | */ | ||
690 | txdesc.flags = 0; | ||
691 | txwi = rt2800_drv_get_txwi(entry); | ||
692 | rt2x00_desc_read(txwi, 0, &word); | ||
693 | mcs = rt2x00_get_field32(word, TXWI_W0_MCS); | ||
694 | real_mcs = rt2x00_get_field32(reg, TX_STA_FIFO_MCS); | ||
695 | |||
696 | /* | ||
697 | * Ralink has a retry mechanism using a global fallback | ||
698 | * table. We setup this fallback table to try the immediate | ||
699 | * lower rate for all rates. In the TX_STA_FIFO, the MCS field | ||
700 | * always contains the MCS used for the last transmission, be | ||
701 | * it successful or not. | ||
702 | */ | ||
703 | if (rt2x00_get_field32(reg, TX_STA_FIFO_TX_SUCCESS)) { | ||
704 | /* | ||
705 | * Transmission succeeded. The number of retries is | ||
706 | * mcs - real_mcs | ||
707 | */ | ||
708 | __set_bit(TXDONE_SUCCESS, &txdesc.flags); | ||
709 | txdesc.retry = ((mcs > real_mcs) ? mcs - real_mcs : 0); | ||
710 | } else { | ||
711 | /* | ||
712 | * Transmission failed. The number of retries is | ||
713 | * always 7 in this case (for a total number of 8 | ||
714 | * frames sent). | ||
715 | */ | ||
716 | __set_bit(TXDONE_FAILURE, &txdesc.flags); | ||
717 | txdesc.retry = rt2x00dev->long_retry; | ||
718 | } | ||
719 | |||
720 | /* | ||
721 | * the frame was retried at least once | ||
722 | * -> hw used fallback rates | ||
723 | */ | ||
724 | if (txdesc.retry) | ||
725 | __set_bit(TXDONE_FALLBACK, &txdesc.flags); | ||
726 | |||
727 | rt2x00lib_txdone(entry, &txdesc); | ||
728 | } | 762 | } |
729 | } | 763 | } |
730 | EXPORT_SYMBOL_GPL(rt2800_txdone); | 764 | EXPORT_SYMBOL_GPL(rt2800_txdone); |
@@ -1031,8 +1065,12 @@ int rt2800_config_pairwise_key(struct rt2x00_dev *rt2x00dev, | |||
1031 | * 1 pairwise key is possible per AID, this means that the AID | 1065 | * 1 pairwise key is possible per AID, this means that the AID |
1032 | * equals our hw_key_idx. Make sure the WCID starts _after_ the | 1066 | * equals our hw_key_idx. Make sure the WCID starts _after_ the |
1033 | * last possible shared key entry. | 1067 | * last possible shared key entry. |
1068 | * | ||
1069 | * Since parts of the pairwise key table might be shared with | ||
1070 | * the beacon frame buffers 6 & 7 we should only write into the | ||
1071 | * first 222 entries. | ||
1034 | */ | 1072 | */ |
1035 | if (crypto->aid > (256 - 32)) | 1073 | if (crypto->aid > (222 - 32)) |
1036 | return -ENOSPC; | 1074 | return -ENOSPC; |
1037 | 1075 | ||
1038 | key->hw_key_idx = 32 + crypto->aid; | 1076 | key->hw_key_idx = 32 + crypto->aid; |
@@ -1159,6 +1197,102 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf, | |||
1159 | } | 1197 | } |
1160 | EXPORT_SYMBOL_GPL(rt2800_config_intf); | 1198 | EXPORT_SYMBOL_GPL(rt2800_config_intf); |
1161 | 1199 | ||
1200 | static void rt2800_config_ht_opmode(struct rt2x00_dev *rt2x00dev, | ||
1201 | struct rt2x00lib_erp *erp) | ||
1202 | { | ||
1203 | bool any_sta_nongf = !!(erp->ht_opmode & | ||
1204 | IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); | ||
1205 | u8 protection = erp->ht_opmode & IEEE80211_HT_OP_MODE_PROTECTION; | ||
1206 | u8 mm20_mode, mm40_mode, gf20_mode, gf40_mode; | ||
1207 | u16 mm20_rate, mm40_rate, gf20_rate, gf40_rate; | ||
1208 | u32 reg; | ||
1209 | |||
1210 | /* default protection rate for HT20: OFDM 24M */ | ||
1211 | mm20_rate = gf20_rate = 0x4004; | ||
1212 | |||
1213 | /* default protection rate for HT40: duplicate OFDM 24M */ | ||
1214 | mm40_rate = gf40_rate = 0x4084; | ||
1215 | |||
1216 | switch (protection) { | ||
1217 | case IEEE80211_HT_OP_MODE_PROTECTION_NONE: | ||
1218 | /* | ||
1219 | * All STAs in this BSS are HT20/40 but there might be | ||
1220 | * STAs not supporting greenfield mode. | ||
1221 | * => Disable protection for HT transmissions. | ||
1222 | */ | ||
1223 | mm20_mode = mm40_mode = gf20_mode = gf40_mode = 0; | ||
1224 | |||
1225 | break; | ||
1226 | case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ: | ||
1227 | /* | ||
1228 | * All STAs in this BSS are HT20 or HT20/40 but there | ||
1229 | * might be STAs not supporting greenfield mode. | ||
1230 | * => Protect all HT40 transmissions. | ||
1231 | */ | ||
1232 | mm20_mode = gf20_mode = 0; | ||
1233 | mm40_mode = gf40_mode = 2; | ||
1234 | |||
1235 | break; | ||
1236 | case IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER: | ||
1237 | /* | ||
1238 | * Nonmember protection: | ||
1239 | * According to 802.11n we _should_ protect all | ||
1240 | * HT transmissions (but we don't have to). | ||
1241 | * | ||
1242 | * But if cts_protection is enabled we _shall_ protect | ||
1243 | * all HT transmissions using a CCK rate. | ||
1244 | * | ||
1245 | * And if any station is non GF we _shall_ protect | ||
1246 | * GF transmissions. | ||
1247 | * | ||
1248 | * We decide to protect everything | ||
1249 | * -> fall through to mixed mode. | ||
1250 | */ | ||
1251 | case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED: | ||
1252 | /* | ||
1253 | * Legacy STAs are present | ||
1254 | * => Protect all HT transmissions. | ||
1255 | */ | ||
1256 | mm20_mode = mm40_mode = gf20_mode = gf40_mode = 2; | ||
1257 | |||
1258 | /* | ||
1259 | * If erp protection is needed we have to protect HT | ||
1260 | * transmissions with CCK 11M long preamble. | ||
1261 | */ | ||
1262 | if (erp->cts_protection) { | ||
1263 | /* don't duplicate RTS/CTS in CCK mode */ | ||
1264 | mm20_rate = mm40_rate = 0x0003; | ||
1265 | gf20_rate = gf40_rate = 0x0003; | ||
1266 | } | ||
1267 | break; | ||
1268 | }; | ||
1269 | |||
1270 | /* check for STAs not supporting greenfield mode */ | ||
1271 | if (any_sta_nongf) | ||
1272 | gf20_mode = gf40_mode = 2; | ||
1273 | |||
1274 | /* Update HT protection config */ | ||
1275 | rt2800_register_read(rt2x00dev, MM20_PROT_CFG, ®); | ||
1276 | rt2x00_set_field32(®, MM20_PROT_CFG_PROTECT_RATE, mm20_rate); | ||
1277 | rt2x00_set_field32(®, MM20_PROT_CFG_PROTECT_CTRL, mm20_mode); | ||
1278 | rt2800_register_write(rt2x00dev, MM20_PROT_CFG, reg); | ||
1279 | |||
1280 | rt2800_register_read(rt2x00dev, MM40_PROT_CFG, ®); | ||
1281 | rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_RATE, mm40_rate); | ||
1282 | rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_CTRL, mm40_mode); | ||
1283 | rt2800_register_write(rt2x00dev, MM40_PROT_CFG, reg); | ||
1284 | |||
1285 | rt2800_register_read(rt2x00dev, GF20_PROT_CFG, ®); | ||
1286 | rt2x00_set_field32(®, GF20_PROT_CFG_PROTECT_RATE, gf20_rate); | ||
1287 | rt2x00_set_field32(®, GF20_PROT_CFG_PROTECT_CTRL, gf20_mode); | ||
1288 | rt2800_register_write(rt2x00dev, GF20_PROT_CFG, reg); | ||
1289 | |||
1290 | rt2800_register_read(rt2x00dev, GF40_PROT_CFG, ®); | ||
1291 | rt2x00_set_field32(®, GF40_PROT_CFG_PROTECT_RATE, gf40_rate); | ||
1292 | rt2x00_set_field32(®, GF40_PROT_CFG_PROTECT_CTRL, gf40_mode); | ||
1293 | rt2800_register_write(rt2x00dev, GF40_PROT_CFG, reg); | ||
1294 | } | ||
1295 | |||
1162 | void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp, | 1296 | void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp, |
1163 | u32 changed) | 1297 | u32 changed) |
1164 | { | 1298 | { |
@@ -1203,6 +1337,9 @@ void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp, | |||
1203 | erp->beacon_int * 16); | 1337 | erp->beacon_int * 16); |
1204 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); | 1338 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); |
1205 | } | 1339 | } |
1340 | |||
1341 | if (changed & BSS_CHANGED_HT) | ||
1342 | rt2800_config_ht_opmode(rt2x00dev, erp); | ||
1206 | } | 1343 | } |
1207 | EXPORT_SYMBOL_GPL(rt2800_config_erp); | 1344 | EXPORT_SYMBOL_GPL(rt2800_config_erp); |
1208 | 1345 | ||
@@ -1907,8 +2044,7 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1907 | 2044 | ||
1908 | rt2800_register_read(rt2x00dev, MM40_PROT_CFG, ®); | 2045 | rt2800_register_read(rt2x00dev, MM40_PROT_CFG, ®); |
1909 | rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_RATE, 0x4084); | 2046 | rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_RATE, 0x4084); |
1910 | rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_CTRL, | 2047 | rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_CTRL, 0); |
1911 | !rt2x00_is_usb(rt2x00dev)); | ||
1912 | rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_NAV, 1); | 2048 | rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_NAV, 1); |
1913 | rt2x00_set_field32(®, MM40_PROT_CFG_TX_OP_ALLOW_CCK, 1); | 2049 | rt2x00_set_field32(®, MM40_PROT_CFG_TX_OP_ALLOW_CCK, 1); |
1914 | rt2x00_set_field32(®, MM40_PROT_CFG_TX_OP_ALLOW_OFDM, 1); | 2050 | rt2x00_set_field32(®, MM40_PROT_CFG_TX_OP_ALLOW_OFDM, 1); |
@@ -3056,11 +3192,20 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
3056 | * Initialize all hw fields. | 3192 | * Initialize all hw fields. |
3057 | */ | 3193 | */ |
3058 | rt2x00dev->hw->flags = | 3194 | rt2x00dev->hw->flags = |
3059 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | ||
3060 | IEEE80211_HW_SIGNAL_DBM | | 3195 | IEEE80211_HW_SIGNAL_DBM | |
3061 | IEEE80211_HW_SUPPORTS_PS | | 3196 | IEEE80211_HW_SUPPORTS_PS | |
3062 | IEEE80211_HW_PS_NULLFUNC_STACK | | 3197 | IEEE80211_HW_PS_NULLFUNC_STACK | |
3063 | IEEE80211_HW_AMPDU_AGGREGATION; | 3198 | IEEE80211_HW_AMPDU_AGGREGATION; |
3199 | /* | ||
3200 | * Don't set IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING for USB devices | ||
3201 | * unless we are capable of sending the buffered frames out after the | ||
3202 | * DTIM transmission using rt2x00lib_beacondone. This will send out | ||
3203 | * multicast and broadcast traffic immediately instead of buffering it | ||
3204 | * infinitly and thus dropping it after some time. | ||
3205 | */ | ||
3206 | if (!rt2x00_is_usb(rt2x00dev)) | ||
3207 | rt2x00dev->hw->flags |= | ||
3208 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING; | ||
3064 | 3209 | ||
3065 | SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); | 3210 | SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); |
3066 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, | 3211 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, |
@@ -3071,12 +3216,13 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
3071 | * As rt2800 has a global fallback table we cannot specify | 3216 | * As rt2800 has a global fallback table we cannot specify |
3072 | * more then one tx rate per frame but since the hw will | 3217 | * more then one tx rate per frame but since the hw will |
3073 | * try several rates (based on the fallback table) we should | 3218 | * try several rates (based on the fallback table) we should |
3074 | * still initialize max_rates to the maximum number of rates | 3219 | * initialize max_report_rates to the maximum number of rates |
3075 | * we are going to try. Otherwise mac80211 will truncate our | 3220 | * we are going to try. Otherwise mac80211 will truncate our |
3076 | * reported tx rates and the rc algortihm will end up with | 3221 | * reported tx rates and the rc algortihm will end up with |
3077 | * incorrect data. | 3222 | * incorrect data. |
3078 | */ | 3223 | */ |
3079 | rt2x00dev->hw->max_rates = 7; | 3224 | rt2x00dev->hw->max_rates = 1; |
3225 | rt2x00dev->hw->max_report_rates = 7; | ||
3080 | rt2x00dev->hw->max_rate_tries = 1; | 3226 | rt2x00dev->hw->max_rate_tries = 1; |
3081 | 3227 | ||
3082 | rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom); | 3228 | rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom); |
@@ -3333,8 +3479,12 @@ int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
3333 | switch (action) { | 3479 | switch (action) { |
3334 | case IEEE80211_AMPDU_RX_START: | 3480 | case IEEE80211_AMPDU_RX_START: |
3335 | case IEEE80211_AMPDU_RX_STOP: | 3481 | case IEEE80211_AMPDU_RX_STOP: |
3336 | /* we don't support RX aggregation yet */ | 3482 | /* |
3337 | ret = -ENOTSUPP; | 3483 | * The hw itself takes care of setting up BlockAck mechanisms. |
3484 | * So, we only have to allow mac80211 to nagotiate a BlockAck | ||
3485 | * agreement. Once that is done, the hw will BlockAck incoming | ||
3486 | * AMPDUs without further setup. | ||
3487 | */ | ||
3338 | break; | 3488 | break; |
3339 | case IEEE80211_AMPDU_TX_START: | 3489 | case IEEE80211_AMPDU_TX_START: |
3340 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); | 3490 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h index 600c5eb25c41..81cbc92e7857 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.h +++ b/drivers/net/wireless/rt2x00/rt2800lib.h | |||
@@ -153,6 +153,7 @@ void rt2800_write_tx_data(struct queue_entry *entry, | |||
153 | void rt2800_process_rxwi(struct queue_entry *entry, struct rxdone_entry_desc *txdesc); | 153 | void rt2800_process_rxwi(struct queue_entry *entry, struct rxdone_entry_desc *txdesc); |
154 | 154 | ||
155 | void rt2800_txdone(struct rt2x00_dev *rt2x00dev); | 155 | void rt2800_txdone(struct rt2x00_dev *rt2x00dev); |
156 | void rt2800_txdone_entry(struct queue_entry *entry, u32 status); | ||
156 | 157 | ||
157 | void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc); | 158 | void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc); |
158 | 159 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 005ee153e0cc..85a134cd62bf 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c | |||
@@ -241,6 +241,7 @@ static void rt2800pci_clear_entry(struct queue_entry *entry) | |||
241 | { | 241 | { |
242 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; | 242 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; |
243 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | 243 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
244 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | ||
244 | u32 word; | 245 | u32 word; |
245 | 246 | ||
246 | if (entry->queue->qid == QID_RX) { | 247 | if (entry->queue->qid == QID_RX) { |
@@ -251,6 +252,13 @@ static void rt2800pci_clear_entry(struct queue_entry *entry) | |||
251 | rt2x00_desc_read(entry_priv->desc, 1, &word); | 252 | rt2x00_desc_read(entry_priv->desc, 1, &word); |
252 | rt2x00_set_field32(&word, RXD_W1_DMA_DONE, 0); | 253 | rt2x00_set_field32(&word, RXD_W1_DMA_DONE, 0); |
253 | rt2x00_desc_write(entry_priv->desc, 1, word); | 254 | rt2x00_desc_write(entry_priv->desc, 1, word); |
255 | |||
256 | /* | ||
257 | * Set RX IDX in register to inform hardware that we have | ||
258 | * handled this entry and it is available for reuse again. | ||
259 | */ | ||
260 | rt2800_register_write(rt2x00dev, RX_CRX_IDX, | ||
261 | entry->entry_idx); | ||
254 | } else { | 262 | } else { |
255 | rt2x00_desc_read(entry_priv->desc, 1, &word); | 263 | rt2x00_desc_read(entry_priv->desc, 1, &word); |
256 | rt2x00_set_field32(&word, TXD_W1_DMA_DONE, 1); | 264 | rt2x00_set_field32(&word, TXD_W1_DMA_DONE, 1); |
@@ -599,7 +607,6 @@ static void rt2800pci_kill_tx_queue(struct data_queue *queue) | |||
599 | static void rt2800pci_fill_rxdone(struct queue_entry *entry, | 607 | static void rt2800pci_fill_rxdone(struct queue_entry *entry, |
600 | struct rxdone_entry_desc *rxdesc) | 608 | struct rxdone_entry_desc *rxdesc) |
601 | { | 609 | { |
602 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | ||
603 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; | 610 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; |
604 | __le32 *rxd = entry_priv->desc; | 611 | __le32 *rxd = entry_priv->desc; |
605 | u32 word; | 612 | u32 word; |
@@ -641,12 +648,6 @@ static void rt2800pci_fill_rxdone(struct queue_entry *entry, | |||
641 | * Process the RXWI structure that is at the start of the buffer. | 648 | * Process the RXWI structure that is at the start of the buffer. |
642 | */ | 649 | */ |
643 | rt2800_process_rxwi(entry, rxdesc); | 650 | rt2800_process_rxwi(entry, rxdesc); |
644 | |||
645 | /* | ||
646 | * Set RX IDX in register to inform hardware that we have handled | ||
647 | * this entry and it is available for reuse again. | ||
648 | */ | ||
649 | rt2800_register_write(rt2x00dev, RX_CRX_IDX, entry->entry_idx); | ||
650 | } | 651 | } |
651 | 652 | ||
652 | /* | 653 | /* |
@@ -660,6 +661,63 @@ static void rt2800pci_wakeup(struct rt2x00_dev *rt2x00dev) | |||
660 | rt2800_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS); | 661 | rt2800_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS); |
661 | } | 662 | } |
662 | 663 | ||
664 | static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) | ||
665 | { | ||
666 | struct data_queue *queue; | ||
667 | struct queue_entry *entry; | ||
668 | u32 status; | ||
669 | u8 qid; | ||
670 | |||
671 | while (!kfifo_is_empty(&rt2x00dev->txstatus_fifo)) { | ||
672 | /* Now remove the tx status from the FIFO */ | ||
673 | if (kfifo_out(&rt2x00dev->txstatus_fifo, &status, | ||
674 | sizeof(status)) != sizeof(status)) { | ||
675 | WARN_ON(1); | ||
676 | break; | ||
677 | } | ||
678 | |||
679 | qid = rt2x00_get_field32(status, TX_STA_FIFO_PID_TYPE) - 1; | ||
680 | if (qid >= QID_RX) { | ||
681 | /* | ||
682 | * Unknown queue, this shouldn't happen. Just drop | ||
683 | * this tx status. | ||
684 | */ | ||
685 | WARNING(rt2x00dev, "Got TX status report with " | ||
686 | "unexpected pid %u, dropping", qid); | ||
687 | break; | ||
688 | } | ||
689 | |||
690 | queue = rt2x00queue_get_queue(rt2x00dev, qid); | ||
691 | if (unlikely(queue == NULL)) { | ||
692 | /* | ||
693 | * The queue is NULL, this shouldn't happen. Stop | ||
694 | * processing here and drop the tx status | ||
695 | */ | ||
696 | WARNING(rt2x00dev, "Got TX status for an unavailable " | ||
697 | "queue %u, dropping", qid); | ||
698 | break; | ||
699 | } | ||
700 | |||
701 | if (rt2x00queue_empty(queue)) { | ||
702 | /* | ||
703 | * The queue is empty. Stop processing here | ||
704 | * and drop the tx status. | ||
705 | */ | ||
706 | WARNING(rt2x00dev, "Got TX status for an empty " | ||
707 | "queue %u, dropping", qid); | ||
708 | break; | ||
709 | } | ||
710 | |||
711 | entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); | ||
712 | rt2800_txdone_entry(entry, status); | ||
713 | } | ||
714 | } | ||
715 | |||
716 | static void rt2800pci_txstatus_tasklet(unsigned long data) | ||
717 | { | ||
718 | rt2800pci_txdone((struct rt2x00_dev *)data); | ||
719 | } | ||
720 | |||
663 | static irqreturn_t rt2800pci_interrupt_thread(int irq, void *dev_instance) | 721 | static irqreturn_t rt2800pci_interrupt_thread(int irq, void *dev_instance) |
664 | { | 722 | { |
665 | struct rt2x00_dev *rt2x00dev = dev_instance; | 723 | struct rt2x00_dev *rt2x00dev = dev_instance; |
@@ -684,13 +742,7 @@ static irqreturn_t rt2800pci_interrupt_thread(int irq, void *dev_instance) | |||
684 | rt2x00pci_rxdone(rt2x00dev); | 742 | rt2x00pci_rxdone(rt2x00dev); |
685 | 743 | ||
686 | /* | 744 | /* |
687 | * 4 - Tx done interrupt. | 745 | * 4 - Auto wakeup interrupt. |
688 | */ | ||
689 | if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) | ||
690 | rt2800_txdone(rt2x00dev); | ||
691 | |||
692 | /* | ||
693 | * 5 - Auto wakeup interrupt. | ||
694 | */ | 746 | */ |
695 | if (rt2x00_get_field32(reg, INT_SOURCE_CSR_AUTO_WAKEUP)) | 747 | if (rt2x00_get_field32(reg, INT_SOURCE_CSR_AUTO_WAKEUP)) |
696 | rt2800pci_wakeup(rt2x00dev); | 748 | rt2800pci_wakeup(rt2x00dev); |
@@ -702,10 +754,58 @@ static irqreturn_t rt2800pci_interrupt_thread(int irq, void *dev_instance) | |||
702 | return IRQ_HANDLED; | 754 | return IRQ_HANDLED; |
703 | } | 755 | } |
704 | 756 | ||
757 | static void rt2800pci_txstatus_interrupt(struct rt2x00_dev *rt2x00dev) | ||
758 | { | ||
759 | u32 status; | ||
760 | int i; | ||
761 | |||
762 | /* | ||
763 | * The TX_FIFO_STATUS interrupt needs special care. We should | ||
764 | * read TX_STA_FIFO but we should do it immediately as otherwise | ||
765 | * the register can overflow and we would lose status reports. | ||
766 | * | ||
767 | * Hence, read the TX_STA_FIFO register and copy all tx status | ||
768 | * reports into a kernel FIFO which is handled in the txstatus | ||
769 | * tasklet. We use a tasklet to process the tx status reports | ||
770 | * because we can schedule the tasklet multiple times (when the | ||
771 | * interrupt fires again during tx status processing). | ||
772 | * | ||
773 | * Furthermore we don't disable the TX_FIFO_STATUS | ||
774 | * interrupt here but leave it enabled so that the TX_STA_FIFO | ||
775 | * can also be read while the interrupt thread gets executed. | ||
776 | * | ||
777 | * Since we have only one producer and one consumer we don't | ||
778 | * need to lock the kfifo. | ||
779 | */ | ||
780 | for (i = 0; i < TX_ENTRIES; i++) { | ||
781 | rt2800_register_read(rt2x00dev, TX_STA_FIFO, &status); | ||
782 | |||
783 | if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID)) | ||
784 | break; | ||
785 | |||
786 | if (kfifo_is_full(&rt2x00dev->txstatus_fifo)) { | ||
787 | WARNING(rt2x00dev, "TX status FIFO overrun," | ||
788 | " drop tx status report.\n"); | ||
789 | break; | ||
790 | } | ||
791 | |||
792 | if (kfifo_in(&rt2x00dev->txstatus_fifo, &status, | ||
793 | sizeof(status)) != sizeof(status)) { | ||
794 | WARNING(rt2x00dev, "TX status FIFO overrun," | ||
795 | "drop tx status report.\n"); | ||
796 | break; | ||
797 | } | ||
798 | } | ||
799 | |||
800 | /* Schedule the tasklet for processing the tx status. */ | ||
801 | tasklet_schedule(&rt2x00dev->txstatus_tasklet); | ||
802 | } | ||
803 | |||
705 | static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance) | 804 | static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance) |
706 | { | 805 | { |
707 | struct rt2x00_dev *rt2x00dev = dev_instance; | 806 | struct rt2x00_dev *rt2x00dev = dev_instance; |
708 | u32 reg; | 807 | u32 reg; |
808 | irqreturn_t ret = IRQ_HANDLED; | ||
709 | 809 | ||
710 | /* Read status and ACK all interrupts */ | 810 | /* Read status and ACK all interrupts */ |
711 | rt2800_register_read(rt2x00dev, INT_SOURCE_CSR, ®); | 811 | rt2800_register_read(rt2x00dev, INT_SOURCE_CSR, ®); |
@@ -717,15 +817,38 @@ static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance) | |||
717 | if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) | 817 | if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) |
718 | return IRQ_HANDLED; | 818 | return IRQ_HANDLED; |
719 | 819 | ||
720 | /* Store irqvalue for use in the interrupt thread. */ | 820 | if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) |
721 | rt2x00dev->irqvalue[0] = reg; | 821 | rt2800pci_txstatus_interrupt(rt2x00dev); |
722 | 822 | ||
723 | /* Disable interrupts, will be enabled again in the interrupt thread. */ | 823 | if (rt2x00_get_field32(reg, INT_SOURCE_CSR_PRE_TBTT) || |
724 | rt2x00dev->ops->lib->set_device_state(rt2x00dev, | 824 | rt2x00_get_field32(reg, INT_SOURCE_CSR_TBTT) || |
725 | STATE_RADIO_IRQ_OFF_ISR); | 825 | rt2x00_get_field32(reg, INT_SOURCE_CSR_RX_DONE) || |
826 | rt2x00_get_field32(reg, INT_SOURCE_CSR_AUTO_WAKEUP)) { | ||
827 | /* | ||
828 | * All other interrupts are handled in the interrupt thread. | ||
829 | * Store irqvalue for use in the interrupt thread. | ||
830 | */ | ||
831 | rt2x00dev->irqvalue[0] = reg; | ||
832 | |||
833 | /* | ||
834 | * Disable interrupts, will be enabled again in the | ||
835 | * interrupt thread. | ||
836 | */ | ||
837 | rt2x00dev->ops->lib->set_device_state(rt2x00dev, | ||
838 | STATE_RADIO_IRQ_OFF_ISR); | ||
839 | |||
840 | /* | ||
841 | * Leave the TX_FIFO_STATUS interrupt enabled to not lose any | ||
842 | * tx status reports. | ||
843 | */ | ||
844 | rt2800_register_read(rt2x00dev, INT_MASK_CSR, ®); | ||
845 | rt2x00_set_field32(®, INT_MASK_CSR_TX_FIFO_STATUS, 1); | ||
846 | rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg); | ||
726 | 847 | ||
848 | ret = IRQ_WAKE_THREAD; | ||
849 | } | ||
727 | 850 | ||
728 | return IRQ_WAKE_THREAD; | 851 | return ret; |
729 | } | 852 | } |
730 | 853 | ||
731 | /* | 854 | /* |
@@ -788,6 +911,7 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
788 | __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); | 911 | __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); |
789 | __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags); | 912 | __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags); |
790 | __set_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags); | 913 | __set_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags); |
914 | __set_bit(DRIVER_REQUIRE_TXSTATUS_FIFO, &rt2x00dev->flags); | ||
791 | if (!modparam_nohwcrypt) | 915 | if (!modparam_nohwcrypt) |
792 | __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); | 916 | __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); |
793 | __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags); | 917 | __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags); |
@@ -837,6 +961,7 @@ static const struct rt2800_ops rt2800pci_rt2800_ops = { | |||
837 | static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { | 961 | static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { |
838 | .irq_handler = rt2800pci_interrupt, | 962 | .irq_handler = rt2800pci_interrupt, |
839 | .irq_handler_thread = rt2800pci_interrupt_thread, | 963 | .irq_handler_thread = rt2800pci_interrupt_thread, |
964 | .txstatus_tasklet = rt2800pci_txstatus_tasklet, | ||
840 | .probe_hw = rt2800pci_probe_hw, | 965 | .probe_hw = rt2800pci_probe_hw, |
841 | .get_firmware_name = rt2800pci_get_firmware_name, | 966 | .get_firmware_name = rt2800pci_get_firmware_name, |
842 | .check_firmware = rt2800_check_firmware, | 967 | .check_firmware = rt2800_check_firmware, |
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 7832a5996a8c..75ac6624bf9e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/mutex.h> | 36 | #include <linux/mutex.h> |
37 | #include <linux/etherdevice.h> | 37 | #include <linux/etherdevice.h> |
38 | #include <linux/input-polldev.h> | 38 | #include <linux/input-polldev.h> |
39 | #include <linux/kfifo.h> | ||
39 | 40 | ||
40 | #include <net/mac80211.h> | 41 | #include <net/mac80211.h> |
41 | 42 | ||
@@ -457,6 +458,7 @@ struct rt2x00lib_erp { | |||
457 | short eifs; | 458 | short eifs; |
458 | 459 | ||
459 | u16 beacon_int; | 460 | u16 beacon_int; |
461 | u16 ht_opmode; | ||
460 | }; | 462 | }; |
461 | 463 | ||
462 | /* | 464 | /* |
@@ -522,6 +524,11 @@ struct rt2x00lib_ops { | |||
522 | irq_handler_t irq_handler_thread; | 524 | irq_handler_t irq_handler_thread; |
523 | 525 | ||
524 | /* | 526 | /* |
527 | * TX status tasklet handler. | ||
528 | */ | ||
529 | void (*txstatus_tasklet) (unsigned long data); | ||
530 | |||
531 | /* | ||
525 | * Device init handlers. | 532 | * Device init handlers. |
526 | */ | 533 | */ |
527 | int (*probe_hw) (struct rt2x00_dev *rt2x00dev); | 534 | int (*probe_hw) (struct rt2x00_dev *rt2x00dev); |
@@ -651,6 +658,7 @@ enum rt2x00_flags { | |||
651 | DRIVER_REQUIRE_DMA, | 658 | DRIVER_REQUIRE_DMA, |
652 | DRIVER_REQUIRE_COPY_IV, | 659 | DRIVER_REQUIRE_COPY_IV, |
653 | DRIVER_REQUIRE_L2PAD, | 660 | DRIVER_REQUIRE_L2PAD, |
661 | DRIVER_REQUIRE_TXSTATUS_FIFO, | ||
654 | 662 | ||
655 | /* | 663 | /* |
656 | * Driver features | 664 | * Driver features |
@@ -884,6 +892,16 @@ struct rt2x00_dev { | |||
884 | * and interrupt thread routine. | 892 | * and interrupt thread routine. |
885 | */ | 893 | */ |
886 | u32 irqvalue[2]; | 894 | u32 irqvalue[2]; |
895 | |||
896 | /* | ||
897 | * FIFO for storing tx status reports between isr and tasklet. | ||
898 | */ | ||
899 | struct kfifo txstatus_fifo; | ||
900 | |||
901 | /* | ||
902 | * Tasklet for processing tx status reports (rt2800pci). | ||
903 | */ | ||
904 | struct tasklet_struct txstatus_tasklet; | ||
887 | }; | 905 | }; |
888 | 906 | ||
889 | /* | 907 | /* |
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index 4c7ff765a8bf..54ffb5aeb34e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c | |||
@@ -103,6 +103,9 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev, | |||
103 | /* Update global beacon interval time, this is needed for PS support */ | 103 | /* Update global beacon interval time, this is needed for PS support */ |
104 | rt2x00dev->beacon_int = bss_conf->beacon_int; | 104 | rt2x00dev->beacon_int = bss_conf->beacon_int; |
105 | 105 | ||
106 | if (changed & BSS_CHANGED_HT) | ||
107 | erp.ht_opmode = bss_conf->ht_operation_mode; | ||
108 | |||
106 | rt2x00dev->ops->lib->config_erp(rt2x00dev, &erp, changed); | 109 | rt2x00dev->ops->lib->config_erp(rt2x00dev, &erp, changed); |
107 | } | 110 | } |
108 | 111 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 053fdd3bd720..6f442b02b83e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -813,6 +813,30 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
813 | rt2x00dev->hw->extra_tx_headroom += RT2X00_ALIGN_SIZE; | 813 | rt2x00dev->hw->extra_tx_headroom += RT2X00_ALIGN_SIZE; |
814 | 814 | ||
815 | /* | 815 | /* |
816 | * Allocate tx status FIFO for driver use. | ||
817 | */ | ||
818 | if (test_bit(DRIVER_REQUIRE_TXSTATUS_FIFO, &rt2x00dev->flags) && | ||
819 | rt2x00dev->ops->lib->txstatus_tasklet) { | ||
820 | /* | ||
821 | * Allocate txstatus fifo and tasklet, we use a size of 512 | ||
822 | * for the kfifo which is big enough to store 512/4=128 tx | ||
823 | * status reports. In the worst case (tx status for all tx | ||
824 | * queues gets reported before we've got a chance to handle | ||
825 | * them) 24*4=384 tx status reports need to be cached. | ||
826 | */ | ||
827 | status = kfifo_alloc(&rt2x00dev->txstatus_fifo, 512, | ||
828 | GFP_KERNEL); | ||
829 | if (status) | ||
830 | return status; | ||
831 | |||
832 | /* tasklet for processing the tx status reports. */ | ||
833 | tasklet_init(&rt2x00dev->txstatus_tasklet, | ||
834 | rt2x00dev->ops->lib->txstatus_tasklet, | ||
835 | (unsigned long)rt2x00dev); | ||
836 | |||
837 | } | ||
838 | |||
839 | /* | ||
816 | * Register HW. | 840 | * Register HW. |
817 | */ | 841 | */ |
818 | status = ieee80211_register_hw(rt2x00dev->hw); | 842 | status = ieee80211_register_hw(rt2x00dev->hw); |
@@ -909,10 +933,8 @@ int rt2x00lib_start(struct rt2x00_dev *rt2x00dev) | |||
909 | 933 | ||
910 | /* Enable the radio */ | 934 | /* Enable the radio */ |
911 | retval = rt2x00lib_enable_radio(rt2x00dev); | 935 | retval = rt2x00lib_enable_radio(rt2x00dev); |
912 | if (retval) { | 936 | if (retval) |
913 | rt2x00queue_uninitialize(rt2x00dev); | ||
914 | return retval; | 937 | return retval; |
915 | } | ||
916 | 938 | ||
917 | set_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags); | 939 | set_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags); |
918 | 940 | ||
@@ -1028,6 +1050,16 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) | |||
1028 | cancel_work_sync(&rt2x00dev->txdone_work); | 1050 | cancel_work_sync(&rt2x00dev->txdone_work); |
1029 | 1051 | ||
1030 | /* | 1052 | /* |
1053 | * Free the tx status fifo. | ||
1054 | */ | ||
1055 | kfifo_free(&rt2x00dev->txstatus_fifo); | ||
1056 | |||
1057 | /* | ||
1058 | * Kill the tx status tasklet. | ||
1059 | */ | ||
1060 | tasklet_kill(&rt2x00dev->txstatus_tasklet); | ||
1061 | |||
1062 | /* | ||
1031 | * Uninitialize device. | 1063 | * Uninitialize device. |
1032 | */ | 1064 | */ |
1033 | rt2x00lib_uninitialize(rt2x00dev); | 1065 | rt2x00lib_uninitialize(rt2x00dev); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00ht.c b/drivers/net/wireless/rt2x00/rt2x00ht.c index ad3c7ff4837b..c637bcaec5f8 100644 --- a/drivers/net/wireless/rt2x00/rt2x00ht.c +++ b/drivers/net/wireless/rt2x00/rt2x00ht.c | |||
@@ -60,9 +60,10 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry, | |||
60 | * when using more then one tx stream (>MCS7). | 60 | * when using more then one tx stream (>MCS7). |
61 | */ | 61 | */ |
62 | if (tx_info->control.sta && txdesc->mcs > 7 && | 62 | if (tx_info->control.sta && txdesc->mcs > 7 && |
63 | (tx_info->control.sta->ht_cap.cap & | 63 | ((tx_info->control.sta->ht_cap.cap & |
64 | (WLAN_HT_CAP_SM_PS_DYNAMIC << | 64 | IEEE80211_HT_CAP_SM_PS) >> |
65 | IEEE80211_HT_CAP_SM_PS_SHIFT))) | 65 | IEEE80211_HT_CAP_SM_PS_SHIFT) == |
66 | WLAN_HT_CAP_SM_PS_DYNAMIC) | ||
66 | __set_bit(ENTRY_TXD_HT_MIMO_PS, &txdesc->flags); | 67 | __set_bit(ENTRY_TXD_HT_MIMO_PS, &txdesc->flags); |
67 | } else { | 68 | } else { |
68 | txdesc->mcs = rt2x00_get_rate_mcs(hwrate->mcs); | 69 | txdesc->mcs = rt2x00_get_rate_mcs(hwrate->mcs); |
@@ -72,9 +73,11 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry, | |||
72 | 73 | ||
73 | 74 | ||
74 | /* | 75 | /* |
75 | * Convert flags | 76 | * This frame is eligible for an AMPDU, however, don't aggregate |
77 | * frames that are intended to probe a specific tx rate. | ||
76 | */ | 78 | */ |
77 | if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) | 79 | if (tx_info->flags & IEEE80211_TX_CTL_AMPDU && |
80 | !(tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE)) | ||
78 | __set_bit(ENTRY_TXD_HT_AMPDU, &txdesc->flags); | 81 | __set_bit(ENTRY_TXD_HT_AMPDU, &txdesc->flags); |
79 | 82 | ||
80 | /* | 83 | /* |
@@ -84,7 +87,13 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry, | |||
84 | txdesc->rate_mode = RATE_MODE_HT_MIX; | 87 | txdesc->rate_mode = RATE_MODE_HT_MIX; |
85 | if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD) | 88 | if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD) |
86 | txdesc->rate_mode = RATE_MODE_HT_GREENFIELD; | 89 | txdesc->rate_mode = RATE_MODE_HT_GREENFIELD; |
87 | if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) | 90 | |
91 | /* | ||
92 | * Set 40Mhz mode if necessary (for legacy rates this will | ||
93 | * duplicate the frame to both channels). | ||
94 | */ | ||
95 | if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH || | ||
96 | txrate->flags & IEEE80211_TX_RC_DUP_DATA) | ||
88 | __set_bit(ENTRY_TXD_HT_BW_40, &txdesc->flags); | 97 | __set_bit(ENTRY_TXD_HT_BW_40, &txdesc->flags); |
89 | if (txrate->flags & IEEE80211_TX_RC_SHORT_GI) | 98 | if (txrate->flags & IEEE80211_TX_RC_SHORT_GI) |
90 | __set_bit(ENTRY_TXD_HT_SHORT_GI, &txdesc->flags); | 99 | __set_bit(ENTRY_TXD_HT_SHORT_GI, &txdesc->flags); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 7862a840984a..c3c206a97d54 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c | |||
@@ -671,7 +671,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw, | |||
671 | */ | 671 | */ |
672 | if (changes & (BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_ERP_PREAMBLE | | 672 | if (changes & (BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_ERP_PREAMBLE | |
673 | BSS_CHANGED_ERP_SLOT | BSS_CHANGED_BASIC_RATES | | 673 | BSS_CHANGED_ERP_SLOT | BSS_CHANGED_BASIC_RATES | |
674 | BSS_CHANGED_BEACON_INT)) | 674 | BSS_CHANGED_BEACON_INT | BSS_CHANGED_HT)) |
675 | rt2x00lib_config_erp(rt2x00dev, intf, bss_conf, changes); | 675 | rt2x00lib_config_erp(rt2x00dev, intf, bss_conf, changes); |
676 | } | 676 | } |
677 | EXPORT_SYMBOL_GPL(rt2x00mac_bss_info_changed); | 677 | EXPORT_SYMBOL_GPL(rt2x00mac_bss_info_changed); |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 97b3935f615b..af548c87f108 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
@@ -2630,12 +2630,13 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2630 | * As rt61 has a global fallback table we cannot specify | 2630 | * As rt61 has a global fallback table we cannot specify |
2631 | * more then one tx rate per frame but since the hw will | 2631 | * more then one tx rate per frame but since the hw will |
2632 | * try several rates (based on the fallback table) we should | 2632 | * try several rates (based on the fallback table) we should |
2633 | * still initialize max_rates to the maximum number of rates | 2633 | * initialize max_report_rates to the maximum number of rates |
2634 | * we are going to try. Otherwise mac80211 will truncate our | 2634 | * we are going to try. Otherwise mac80211 will truncate our |
2635 | * reported tx rates and the rc algortihm will end up with | 2635 | * reported tx rates and the rc algortihm will end up with |
2636 | * incorrect data. | 2636 | * incorrect data. |
2637 | */ | 2637 | */ |
2638 | rt2x00dev->hw->max_rates = 7; | 2638 | rt2x00dev->hw->max_rates = 1; |
2639 | rt2x00dev->hw->max_report_rates = 7; | ||
2639 | rt2x00dev->hw->max_rate_tries = 1; | 2640 | rt2x00dev->hw->max_rate_tries = 1; |
2640 | 2641 | ||
2641 | /* | 2642 | /* |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index e22f01c1818e..9be8089317e4 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -2063,9 +2063,14 @@ static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2063 | 2063 | ||
2064 | /* | 2064 | /* |
2065 | * Initialize all hw fields. | 2065 | * Initialize all hw fields. |
2066 | * | ||
2067 | * Don't set IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING unless we are | ||
2068 | * capable of sending the buffered frames out after the DTIM | ||
2069 | * transmission using rt2x00lib_beacondone. This will send out | ||
2070 | * multicast and broadcast traffic immediately instead of buffering it | ||
2071 | * infinitly and thus dropping it after some time. | ||
2066 | */ | 2072 | */ |
2067 | rt2x00dev->hw->flags = | 2073 | rt2x00dev->hw->flags = |
2068 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | ||
2069 | IEEE80211_HW_SIGNAL_DBM | | 2074 | IEEE80211_HW_SIGNAL_DBM | |
2070 | IEEE80211_HW_SUPPORTS_PS | | 2075 | IEEE80211_HW_SUPPORTS_PS | |
2071 | IEEE80211_HW_PS_NULLFUNC_STACK; | 2076 | IEEE80211_HW_PS_NULLFUNC_STACK; |
@@ -2365,6 +2370,7 @@ static struct usb_device_id rt73usb_device_table[] = { | |||
2365 | { USB_DEVICE(0x0411, 0x00f4), USB_DEVICE_DATA(&rt73usb_ops) }, | 2370 | { USB_DEVICE(0x0411, 0x00f4), USB_DEVICE_DATA(&rt73usb_ops) }, |
2366 | { USB_DEVICE(0x0411, 0x0116), USB_DEVICE_DATA(&rt73usb_ops) }, | 2371 | { USB_DEVICE(0x0411, 0x0116), USB_DEVICE_DATA(&rt73usb_ops) }, |
2367 | { USB_DEVICE(0x0411, 0x0119), USB_DEVICE_DATA(&rt73usb_ops) }, | 2372 | { USB_DEVICE(0x0411, 0x0119), USB_DEVICE_DATA(&rt73usb_ops) }, |
2373 | { USB_DEVICE(0x0411, 0x0137), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
2368 | /* CEIVA */ | 2374 | /* CEIVA */ |
2369 | { USB_DEVICE(0x178d, 0x02be), USB_DEVICE_DATA(&rt73usb_ops) }, | 2375 | { USB_DEVICE(0x178d, 0x02be), USB_DEVICE_DATA(&rt73usb_ops) }, |
2370 | /* CNet */ | 2376 | /* CNet */ |