]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: rtw89: phy: limit AMPDU number for RA try rate
authorPing-Ke Shih <pkshih@realtek.com>
Tue, 10 Mar 2026 08:01:37 +0000 (16:01 +0800)
committerPing-Ke Shih <pkshih@realtek.com>
Mon, 16 Mar 2026 06:13:26 +0000 (14:13 +0800)
When RA (Rate Adaptive) does try higher rate, a TRY bit is flagged, and
hardware will reference registers configured by this patch as maximum
number of AMPDU. To prevent aggregate too many MPDU over peer's capability
causing loss in peer side, set the minimum values across all stations and
TID since there is single one register per hardware band. Consider MLD
case, a BA session can run across two hardware bands, so set the same
value as well.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20260310080146.31113-5-pkshih@realtek.com
drivers/net/wireless/realtek/rtw89/mac.c
drivers/net/wireless/realtek/rtw89/mac.h
drivers/net/wireless/realtek/rtw89/mac80211.c
drivers/net/wireless/realtek/rtw89/mac_be.c
drivers/net/wireless/realtek/rtw89/phy.c
drivers/net/wireless/realtek/rtw89/phy.h

index 234928613ef47dec10e1030340b2627445f0b09d..a292a14394b25f77c86a18cc6df58dd9beb77535 100644 (file)
@@ -7319,6 +7319,8 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_ax = {
        },
        .wow_ctrl = {.addr = R_AX_WOW_CTRL, .mask = B_AX_WOW_WOWEN,},
        .agg_limit = {.addr = R_AX_AMPDU_AGG_LIMIT, .mask = B_AX_AMPDU_MAX_TIME_MASK,},
+       .ra_agg_limit = {.addr = R_AX_AMPDU_AGG_LIMIT,
+                        .mask = B_AX_RA_TRY_RATE_AGG_LMT_MASK,},
        .txcnt_limit = {.addr = R_AX_TXCNT, .mask = B_AX_L_TXCNT_LMT_MASK,},
 
        .check_mac_en = rtw89_mac_check_mac_en_ax,
index e6b715b954092af3c3881b3fbb52ad83a04e384b..9c77bfaa34ee79791dc528777bf313ea725fce6b 100644 (file)
@@ -1037,6 +1037,7 @@ struct rtw89_mac_gen_def {
        struct rtw89_reg_def narrow_bw_ru_dis;
        struct rtw89_reg_def wow_ctrl;
        struct rtw89_reg_def agg_limit;
+       struct rtw89_reg_def ra_agg_limit;
        struct rtw89_reg_def txcnt_limit;
 
        int (*check_mac_en)(struct rtw89_dev *rtwdev, u8 band,
index 1ef73bfc40d1708111bbf8f64f3dfd436adea375..cd8e2c8de8888e4e82af21e0ebd4dbc8c4244f27 100644 (file)
@@ -1005,6 +1005,8 @@ static int rtw89_ops_ampdu_action(struct ieee80211_hw *hw,
                clear_bit(tid, rtwsta->ampdu_map);
                rtw89_chip_h2c_ampdu_cmac_tbl(rtwdev, rtwvif, rtwsta);
                ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+               rtw89_leave_ps_mode(rtwdev);
+               rtw89_phy_ra_recalc_agg_limit(rtwdev);
                break;
        case IEEE80211_AMPDU_TX_OPERATIONAL:
                set_bit(RTW89_TXQ_F_AMPDU, &rtwtxq->flags);
@@ -1013,6 +1015,7 @@ static int rtw89_ops_ampdu_action(struct ieee80211_hw *hw,
                set_bit(tid, rtwsta->ampdu_map);
                rtw89_leave_ps_mode(rtwdev);
                rtw89_chip_h2c_ampdu_cmac_tbl(rtwdev, rtwvif, rtwsta);
+               rtw89_phy_ra_recalc_agg_limit(rtwdev);
                break;
        case IEEE80211_AMPDU_RX_START:
                rtw89_chip_h2c_ba_cam(rtwdev, rtwsta, true, params);
index dc66b1ee851ac5d24fff3ca9452cd9e88e27189e..39a28fd27412bd462981f268b5014cfa0b445da3 100644 (file)
@@ -3193,6 +3193,8 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_be = {
        },
        .wow_ctrl = {.addr = R_BE_WOW_CTRL, .mask = B_BE_WOW_WOWEN,},
        .agg_limit = {.addr = R_BE_AMPDU_AGG_LIMIT, .mask = B_BE_AMPDU_MAX_TIME_MASK,},
+       .ra_agg_limit = {.addr = R_BE_AMPDU_AGG_LIMIT,
+                        .mask = B_BE_RA_TRY_RATE_AGG_LMT_MASK,},
        .txcnt_limit = {.addr = R_BE_TXCNT, .mask = B_BE_L_TXCNT_LMT_MASK,},
 
        .check_mac_en = rtw89_mac_check_mac_en_be,
index 74f5d5562848594ada6d34602e85abdbe4f53d74..0fa4d8d791f16bb4081faab670a2e422e02fcf73 100644 (file)
@@ -775,6 +775,33 @@ void rtw89_phy_ra_assoc(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_
        rtw89_fw_h2c_ra(rtwdev, ra, csi);
 }
 
+void rtw89_phy_ra_recalc_agg_limit(struct rtw89_dev *rtwdev)
+{
+       const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
+       const struct rtw89_reg_def *ra_limit = &mac->ra_agg_limit;
+       struct ieee80211_sta *sta;
+       struct rtw89_sta *rtwsta;
+       u16 agg_num = U16_MAX;
+       u8 tid;
+
+       for_each_station(sta, rtwdev->hw) {
+               rtwsta = sta_to_rtwsta(sta);
+
+               for_each_set_bit(tid, rtwsta->ampdu_map, IEEE80211_NUM_TIDS)
+                       agg_num = min(agg_num, rtwsta->ampdu_params[tid].agg_num);
+       }
+
+       if (agg_num == U16_MAX)
+               agg_num = 0x3F;
+       else
+               agg_num = clamp(agg_num, 1, 256) - 1;
+
+       rtw89_write32_idx(rtwdev, ra_limit->addr, ra_limit->mask, agg_num, RTW89_MAC_0);
+       if (!rtwdev->dbcc_en)
+               return;
+       rtw89_write32_idx(rtwdev, ra_limit->addr, ra_limit->mask, agg_num, RTW89_MAC_1);
+}
+
 u8 rtw89_phy_get_txsc(struct rtw89_dev *rtwdev,
                      const struct rtw89_chan *chan,
                      enum rtw89_bandwidth dbw)
index 094c7e45f2541507fbbc41d3fc6d81a6cf7686bf..bde419edf7447b1e4b8159f6cd984944c8c007dc 100644 (file)
@@ -1006,6 +1006,7 @@ void rtw89_phy_ra_update_sta(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta
 void rtw89_phy_ra_update_sta_link(struct rtw89_dev *rtwdev,
                                  struct rtw89_sta_link *rtwsta_link,
                                  u32 changed);
+void rtw89_phy_ra_recalc_agg_limit(struct rtw89_dev *rtwdev);
 void rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev,
                                struct ieee80211_vif *vif,
                                const struct cfg80211_bitrate_mask *mask);