diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2800lib.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800lib.c | 264 |
1 files changed, 207 insertions, 57 deletions
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); |