Skip to content

Commit aa3cb24

Browse files
nbd168Kalle Valo
authored andcommitted
mt76: mt7603: fix sequence number assignment
If the MT_TXD3_SN_VALID flag is not set in the tx descriptor, the hardware assigns the sequence number. However, the rest of the code assumes that the sequence number specified in the 802.11 header gets transmitted. This was causing issues with the aggregation setup, which worked for the initial one (where the sequence numbers were still close), but not for further teardown/re-establishing of sessions. Additionally, the overwrite of the TID sequence number in WTBL2 was resetting the hardware assigned sequence numbers, causing them to drift further apart. Fix this by using the software assigned sequence numbers Signed-off-by: Felix Fietkau <[email protected]> Signed-off-by: Kalle Valo <[email protected]>
1 parent 2170e21 commit aa3cb24

File tree

3 files changed

+18
-43
lines changed

3 files changed

+18
-43
lines changed

drivers/net/wireless/mediatek/mt76/mt7603/mac.c

Lines changed: 14 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ void mt7603_mac_rx_ba_reset(struct mt7603_dev *dev, void *addr, u8 tid)
343343
MT_BA_CONTROL_1_RESET));
344344
}
345345

346-
void mt7603_mac_tx_ba_reset(struct mt7603_dev *dev, int wcid, int tid, int ssn,
346+
void mt7603_mac_tx_ba_reset(struct mt7603_dev *dev, int wcid, int tid,
347347
int ba_size)
348348
{
349349
u32 addr = mt7603_wtbl2_addr(wcid);
@@ -358,43 +358,6 @@ void mt7603_mac_tx_ba_reset(struct mt7603_dev *dev, int wcid, int tid, int ssn,
358358
mt76_clear(dev, addr + (15 * 4), tid_mask);
359359
return;
360360
}
361-
mt76_poll(dev, MT_WTBL_UPDATE, MT_WTBL_UPDATE_BUSY, 0, 5000);
362-
363-
mt7603_mac_stop(dev);
364-
switch (tid) {
365-
case 0:
366-
mt76_rmw_field(dev, addr + (2 * 4), MT_WTBL2_W2_TID0_SN, ssn);
367-
break;
368-
case 1:
369-
mt76_rmw_field(dev, addr + (2 * 4), MT_WTBL2_W2_TID1_SN, ssn);
370-
break;
371-
case 2:
372-
mt76_rmw_field(dev, addr + (2 * 4), MT_WTBL2_W2_TID2_SN_LO,
373-
ssn);
374-
mt76_rmw_field(dev, addr + (3 * 4), MT_WTBL2_W3_TID2_SN_HI,
375-
ssn >> 8);
376-
break;
377-
case 3:
378-
mt76_rmw_field(dev, addr + (3 * 4), MT_WTBL2_W3_TID3_SN, ssn);
379-
break;
380-
case 4:
381-
mt76_rmw_field(dev, addr + (3 * 4), MT_WTBL2_W3_TID4_SN, ssn);
382-
break;
383-
case 5:
384-
mt76_rmw_field(dev, addr + (3 * 4), MT_WTBL2_W3_TID5_SN_LO,
385-
ssn);
386-
mt76_rmw_field(dev, addr + (4 * 4), MT_WTBL2_W4_TID5_SN_HI,
387-
ssn >> 4);
388-
break;
389-
case 6:
390-
mt76_rmw_field(dev, addr + (4 * 4), MT_WTBL2_W4_TID6_SN, ssn);
391-
break;
392-
case 7:
393-
mt76_rmw_field(dev, addr + (4 * 4), MT_WTBL2_W4_TID7_SN, ssn);
394-
break;
395-
}
396-
mt7603_wtbl_update(dev, wcid, MT_WTBL_UPDATE_WTBL2);
397-
mt7603_mac_start(dev);
398361

399362
for (i = 7; i > 0; i--) {
400363
if (ba_size >= MT_AGG_SIZE_LIMIT(i))
@@ -827,13 +790,15 @@ mt7603_mac_write_txwi(struct mt7603_dev *dev, __le32 *txwi,
827790
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
828791
struct ieee80211_tx_rate *rate = &info->control.rates[0];
829792
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
793+
struct ieee80211_bar *bar = (struct ieee80211_bar *)skb->data;
830794
struct ieee80211_vif *vif = info->control.vif;
831795
struct mt7603_vif *mvif;
832796
int wlan_idx;
833797
int hdr_len = ieee80211_get_hdrlen_from_skb(skb);
834798
int tx_count = 8;
835799
u8 frame_type, frame_subtype;
836800
u16 fc = le16_to_cpu(hdr->frame_control);
801+
u16 seqno = 0;
837802
u8 vif_idx = 0;
838803
u32 val;
839804
u8 bw;
@@ -919,7 +884,17 @@ mt7603_mac_write_txwi(struct mt7603_dev *dev, __le32 *txwi,
919884
tx_count = 0x1f;
920885

921886
val = FIELD_PREP(MT_TXD3_REM_TX_COUNT, tx_count) |
922-
FIELD_PREP(MT_TXD3_SEQ, le16_to_cpu(hdr->seq_ctrl));
887+
MT_TXD3_SN_VALID;
888+
889+
if (ieee80211_is_data_qos(hdr->frame_control))
890+
seqno = le16_to_cpu(hdr->seq_ctrl);
891+
else if (ieee80211_is_back_req(hdr->frame_control))
892+
seqno = le16_to_cpu(bar->start_seq_num);
893+
else
894+
val &= ~MT_TXD3_SN_VALID;
895+
896+
val |= FIELD_PREP(MT_TXD3_SEQ, seqno >> 4);
897+
923898
txwi[3] = cpu_to_le32(val);
924899

925900
if (key) {

drivers/net/wireless/mediatek/mt76/mt7603/main.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -584,21 +584,21 @@ mt7603_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
584584
case IEEE80211_AMPDU_TX_OPERATIONAL:
585585
mtxq->aggr = true;
586586
mtxq->send_bar = false;
587-
mt7603_mac_tx_ba_reset(dev, msta->wcid.idx, tid, *ssn, ba_size);
587+
mt7603_mac_tx_ba_reset(dev, msta->wcid.idx, tid, ba_size);
588588
break;
589589
case IEEE80211_AMPDU_TX_STOP_FLUSH:
590590
case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
591591
mtxq->aggr = false;
592592
ieee80211_send_bar(vif, sta->addr, tid, mtxq->agg_ssn);
593-
mt7603_mac_tx_ba_reset(dev, msta->wcid.idx, tid, *ssn, -1);
593+
mt7603_mac_tx_ba_reset(dev, msta->wcid.idx, tid, -1);
594594
break;
595595
case IEEE80211_AMPDU_TX_START:
596596
mtxq->agg_ssn = *ssn << 4;
597597
ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
598598
break;
599599
case IEEE80211_AMPDU_TX_STOP_CONT:
600600
mtxq->aggr = false;
601-
mt7603_mac_tx_ba_reset(dev, msta->wcid.idx, tid, *ssn, -1);
601+
mt7603_mac_tx_ba_reset(dev, msta->wcid.idx, tid, -1);
602602
ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
603603
break;
604604
}

drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ void mt7603_beacon_set_timer(struct mt7603_dev *dev, int idx, int intval);
200200
int mt7603_mac_fill_rx(struct mt7603_dev *dev, struct sk_buff *skb);
201201
void mt7603_mac_add_txs(struct mt7603_dev *dev, void *data);
202202
void mt7603_mac_rx_ba_reset(struct mt7603_dev *dev, void *addr, u8 tid);
203-
void mt7603_mac_tx_ba_reset(struct mt7603_dev *dev, int wcid, int tid, int ssn,
203+
void mt7603_mac_tx_ba_reset(struct mt7603_dev *dev, int wcid, int tid,
204204
int ba_size);
205205

206206
void mt7603_pse_client_reset(struct mt7603_dev *dev);

0 commit comments

Comments
 (0)