]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: rtw88: Enable data rate fallback for older chips
authorBitterblue Smith <rtl8821cerfe2@gmail.com>
Wed, 23 Oct 2024 14:10:32 +0000 (17:10 +0300)
committerPing-Ke Shih <pkshih@realtek.com>
Tue, 29 Oct 2024 03:58:11 +0000 (11:58 +0800)
RTL8811AU fails to perform the 4-way handshake when the AP is too far
because it transmits the EAPOL frames at MCS9 and when that doesn't
work it retries 48 times with the same rate, to no avail.

Retrying 48 times with the same rate seems pointless. Set the
appropriate field in the TX descriptor to allow it to use lower rates
when retrying.

Set it for RTL8723D and RTL8703B because they interpret this field the
same way as RTL8811A.

The newer RTL8822C, RTL8822B, RTL8821C seem to interpret this field in
the TX descriptor differently, so leave it alone for those chips.

Tested with RTL8811AU and RTL8723DU.

Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/2b3e3e6f-541b-4a3b-8ca3-65b267e6a95a@gmail.com
12 files changed:
drivers/net/wireless/realtek/rtw88/fw.c
drivers/net/wireless/realtek/rtw88/main.h
drivers/net/wireless/realtek/rtw88/pci.c
drivers/net/wireless/realtek/rtw88/rtw8703b.c
drivers/net/wireless/realtek/rtw88/rtw8723d.c
drivers/net/wireless/realtek/rtw88/rtw8821c.c
drivers/net/wireless/realtek/rtw88/rtw8822b.c
drivers/net/wireless/realtek/rtw88/rtw8822c.c
drivers/net/wireless/realtek/rtw88/sdio.c
drivers/net/wireless/realtek/rtw88/tx.c
drivers/net/wireless/realtek/rtw88/tx.h
drivers/net/wireless/realtek/rtw88/usb.c

index 168e19187ba7e7cf8f6c78183610ff23cbd10cb9..19de5ba555a9e0741e213792e6c280e332a6bd14 100644 (file)
@@ -1290,7 +1290,7 @@ static void rtw_fill_rsvd_page_desc(struct rtw_dev *rtwdev, struct sk_buff *skb,
        rtw_tx_rsvd_page_pkt_info_update(rtwdev, &pkt_info, skb, type);
        pkt_desc = skb_push(skb, chip->tx_pkt_desc_sz);
        memset(pkt_desc, 0, chip->tx_pkt_desc_sz);
-       rtw_tx_fill_tx_desc(&pkt_info, skb);
+       rtw_tx_fill_tx_desc(rtwdev, &pkt_info, skb);
 }
 
 static inline u8 rtw_len_to_page(unsigned int len, u8 page_size)
index af4876327837a3bf7d7c0a0a10dc642b0e3df88c..64bc43cdd2097786f54ee7b75db0eb57f9915521 100644 (file)
@@ -1204,6 +1204,7 @@ struct rtw_chip_info {
        u8 usb_tx_agg_desc_num;
        bool hw_feature_report;
        u8 c2h_ra_report_size;
+       bool old_datarate_fb_limit;
 
        u8 default_1ss_tx_path;
 
index f71e41d6f97cc067b0cd733f153146c0de57f573..0ecaefc4c83dde26b92601e816106a6f5bf7bc50 100644 (file)
@@ -824,7 +824,7 @@ static int rtw_pci_tx_write_data(struct rtw_dev *rtwdev,
        pkt_desc = skb_push(skb, chip->tx_pkt_desc_sz);
        memset(pkt_desc, 0, tx_pkt_desc_sz);
        pkt_info->qsel = rtw_pci_get_tx_qsel(skb, queue);
-       rtw_tx_fill_tx_desc(pkt_info, skb);
+       rtw_tx_fill_tx_desc(rtwdev, pkt_info, skb);
        dma = dma_map_single(&rtwpci->pdev->dev, skb->data, skb->len,
                             DMA_TO_DEVICE);
        if (dma_mapping_error(&rtwpci->pdev->dev, dma))
index 97dbc77f037a6ced6a0f99dc314a0bdb59738d1a..f6f6635b46e18e23be3fc01ac693f42f220b631c 100644 (file)
@@ -1964,6 +1964,7 @@ const struct rtw_chip_info rtw8703b_hw_spec = {
        .usb_tx_agg_desc_num = 1, /* Not sure if this chip has USB interface */
        .hw_feature_report = true,
        .c2h_ra_report_size = 7,
+       .old_datarate_fb_limit = true,
 
        .path_div_supported = false,
        .ht_supported = true,
index f6a08b06f8539ad050d8febe88b3d91e0b9b5fe1..a0bf37a5863237064620bbcfb1269e85f492c312 100644 (file)
@@ -2135,6 +2135,7 @@ const struct rtw_chip_info rtw8723d_hw_spec = {
        .usb_tx_agg_desc_num = 1,
        .hw_feature_report = true,
        .c2h_ra_report_size = 7,
+       .old_datarate_fb_limit = true,
        .ht_supported = true,
        .vht_supported = false,
        .lps_deep_mode_supported = 0,
index e17d0193ca6ff773a8c97ff4538f79d25e60721f..39dc8244f744a436206eb1ec482bfe923f33f559 100644 (file)
@@ -1972,6 +1972,7 @@ const struct rtw_chip_info rtw8821c_hw_spec = {
        .usb_tx_agg_desc_num = 3,
        .hw_feature_report = true,
        .c2h_ra_report_size = 7,
+       .old_datarate_fb_limit = false,
        .ht_supported = true,
        .vht_supported = true,
        .lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK),
index 7360ce0a193e1903f29d0e1ad93580acd5fd0540..419eb14c54670422481c062bb5be0141868e85dd 100644 (file)
@@ -2513,6 +2513,7 @@ const struct rtw_chip_info rtw8822b_hw_spec = {
        .usb_tx_agg_desc_num = 3,
        .hw_feature_report = true,
        .c2h_ra_report_size = 7,
+       .old_datarate_fb_limit = false,
        .ht_supported = true,
        .vht_supported = true,
        .lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK),
index 17d4d9bddd8367a92e4a4730d14ef147aee33570..56085f220fcd9d78a11ad1b2161f8b27e71bb1c0 100644 (file)
@@ -5333,6 +5333,7 @@ const struct rtw_chip_info rtw8822c_hw_spec = {
        .usb_tx_agg_desc_num = 3,
        .hw_feature_report = true,
        .c2h_ra_report_size = 7,
+       .old_datarate_fb_limit = false,
        .default_1ss_tx_path = BB_PATH_A,
        .path_div_supported = true,
        .ht_supported = true,
index f0b06ed8f76d44f330cd5794de2901ea2bd5e374..799230eb5f16ffb2455dd1729d5f28a29937168d 100644 (file)
@@ -864,7 +864,7 @@ static void rtw_sdio_tx_skb_prepare(struct rtw_dev *rtwdev,
 
        pkt_info->qsel = rtw_sdio_get_tx_qsel(rtwdev, skb, queue);
 
-       rtw_tx_fill_tx_desc(pkt_info, skb);
+       rtw_tx_fill_tx_desc(rtwdev, pkt_info, skb);
        rtw_tx_fill_txdesc_checksum(rtwdev, pkt_info, pkt_desc);
 }
 
index dae7ca14886507905c5aaca05b1bb13a981789dd..6ed470dd6f221ad58854017bac0701f2ce096a3e 100644 (file)
@@ -32,7 +32,8 @@ void rtw_tx_stats(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
        }
 }
 
-void rtw_tx_fill_tx_desc(struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb)
+void rtw_tx_fill_tx_desc(struct rtw_dev *rtwdev,
+                        struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb)
 {
        struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)skb->data;
        bool more_data = false;
@@ -67,6 +68,9 @@ void rtw_tx_fill_tx_desc(struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb)
 
        tx_desc->w4 = le32_encode_bits(pkt_info->rate, RTW_TX_DESC_W4_DATARATE);
 
+       if (rtwdev->chip->old_datarate_fb_limit)
+               tx_desc->w4 |= le32_encode_bits(0x1f, RTW_TX_DESC_W4_DATARATE_FB_LIMIT);
+
        tx_desc->w5 = le32_encode_bits(pkt_info->short_gi, RTW_TX_DESC_W5_DATA_SHORT) |
                      le32_encode_bits(pkt_info->bw, RTW_TX_DESC_W5_DATA_BW) |
                      le32_encode_bits(pkt_info->ldpc, RTW_TX_DESC_W5_DATA_LDPC) |
index 3d544fd7f60f517aa2067eaa5809c4a7becc306c..d34cdeca16f192f007484b1b2d4f44f4dbc10a79 100644 (file)
@@ -44,6 +44,7 @@ struct rtw_tx_desc {
 #define RTW_TX_DESC_W3_NAVUSEHDR BIT(15)
 #define RTW_TX_DESC_W3_MAX_AGG_NUM GENMASK(21, 17)
 #define RTW_TX_DESC_W4_DATARATE GENMASK(6, 0)
+#define RTW_TX_DESC_W4_DATARATE_FB_LIMIT GENMASK(12, 8)
 #define RTW_TX_DESC_W4_RTSRATE GENMASK(28, 24)
 #define RTW_TX_DESC_W5_DATA_SHORT BIT(4)
 #define RTW_TX_DESC_W5_DATA_BW GENMASK(6, 5)
@@ -94,7 +95,8 @@ void rtw_tx_pkt_info_update(struct rtw_dev *rtwdev,
                            struct rtw_tx_pkt_info *pkt_info,
                            struct ieee80211_sta *sta,
                            struct sk_buff *skb);
-void rtw_tx_fill_tx_desc(struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb);
+void rtw_tx_fill_tx_desc(struct rtw_dev *rtwdev,
+                        struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb);
 void rtw_tx_report_enqueue(struct rtw_dev *rtwdev, struct sk_buff *skb, u8 sn);
 void rtw_tx_report_handle(struct rtw_dev *rtwdev, struct sk_buff *skb, int src);
 void rtw_tx_rsvd_page_pkt_info_update(struct rtw_dev *rtwdev,
index ba314d90ab3ffed2fbdb04803db4a08a9262834c..a3d2b40ec67b9ab737f7b8a0d014787168d9f8ea 100644 (file)
@@ -458,7 +458,7 @@ static int rtw_usb_write_data(struct rtw_dev *rtwdev,
        skb_put_data(skb, buf, size);
        skb_push(skb, chip->tx_pkt_desc_sz);
        memset(skb->data, 0, chip->tx_pkt_desc_sz);
-       rtw_tx_fill_tx_desc(pkt_info, skb);
+       rtw_tx_fill_tx_desc(rtwdev, pkt_info, skb);
        rtw_tx_fill_txdesc_checksum(rtwdev, pkt_info, skb->data);
 
        ret = rtw_usb_write_port(rtwdev, qsel, skb,
@@ -525,7 +525,7 @@ static int rtw_usb_tx_write(struct rtw_dev *rtwdev,
        pkt_desc = skb_push(skb, chip->tx_pkt_desc_sz);
        memset(pkt_desc, 0, chip->tx_pkt_desc_sz);
        ep = qsel_to_ep(rtwusb, pkt_info->qsel);
-       rtw_tx_fill_tx_desc(pkt_info, skb);
+       rtw_tx_fill_tx_desc(rtwdev, pkt_info, skb);
        rtw_tx_fill_txdesc_checksum(rtwdev, pkt_info, skb->data);
        tx_data = rtw_usb_get_tx_data(skb);
        tx_data->sn = pkt_info->sn;