wifi: rtw89: fw: update TX AMPDU parameter to CMAC table
authorPing-Ke Shih <pkshih@realtek.com>
Mon, 15 Jan 2024 03:37:38 +0000 (11:37 +0800)
committerKalle Valo <kvalo@kernel.org>
Thu, 18 Jan 2024 09:33:56 +0000 (11:33 +0200)
The CMAC table is used to define how hardware TX a certain packet, and
we can specify TX AMPDU size, so hardware can prepare proper retry window
buffer. Otherwise, it can't transmit with expected aggregation number.
Since each TID could have different aggregation number, the smallest number
is adopted to prevent over peer's receiving buffer.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://msgid.link/20240115033742.16372-5-pkshih@realtek.com
drivers/net/wireless/realtek/rtw89/core.h
drivers/net/wireless/realtek/rtw89/fw.c
drivers/net/wireless/realtek/rtw89/fw.h
drivers/net/wireless/realtek/rtw89/mac80211.c
drivers/net/wireless/realtek/rtw89/rtw8851b.c
drivers/net/wireless/realtek/rtw89/rtw8852a.c
drivers/net/wireless/realtek/rtw89/rtw8852b.c
drivers/net/wireless/realtek/rtw89/rtw8852c.c
drivers/net/wireless/realtek/rtw89/rtw8922a.c

index 433557e892968c47774193e6206dda35f6040ba1..b795a06d8d13af05c4800d2e8744a94a70ec1a0c 100644 (file)
@@ -2933,6 +2933,7 @@ struct rtw89_sta {
        struct ewma_evm evm_min[RF_PATH_MAX];
        struct ewma_evm evm_max[RF_PATH_MAX];
        struct rtw89_ampdu_params ampdu_params[IEEE80211_NUM_TIDS];
+       DECLARE_BITMAP(ampdu_map, IEEE80211_NUM_TIDS);
        struct ieee80211_rx_status rx_status;
        u16 rx_hw_rate;
        __le32 htc_template;
@@ -3200,6 +3201,9 @@ struct rtw89_chip_ops {
        int (*h2c_assoc_cmac_tbl)(struct rtw89_dev *rtwdev,
                                  struct ieee80211_vif *vif,
                                  struct ieee80211_sta *sta);
+       int (*h2c_ampdu_cmac_tbl)(struct rtw89_dev *rtwdev,
+                                 struct ieee80211_vif *vif,
+                                 struct ieee80211_sta *sta);
        int (*h2c_update_beacon)(struct rtw89_dev *rtwdev,
                                 struct rtw89_vif *rtwvif);
        int (*h2c_ba_cam)(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
index fc1295d5d8e83f3642655b59ffaf4056592ca32f..3181cde5ab93871d980b1943a0f3303d754dd300 100644 (file)
@@ -2404,6 +2404,72 @@ fail:
 }
 EXPORT_SYMBOL(rtw89_fw_h2c_assoc_cmac_tbl_g7);
 
+int rtw89_fw_h2c_ampdu_cmac_tbl_g7(struct rtw89_dev *rtwdev,
+                                  struct ieee80211_vif *vif,
+                                  struct ieee80211_sta *sta)
+{
+       struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
+       struct rtw89_h2c_cctlinfo_ud_g7 *h2c;
+       u32 len = sizeof(*h2c);
+       struct sk_buff *skb;
+       u16 agg_num = 0;
+       u8 ba_bmap = 0;
+       int ret;
+       u8 tid;
+
+       skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
+       if (!skb) {
+               rtw89_err(rtwdev, "failed to alloc skb for ampdu cmac g7\n");
+               return -ENOMEM;
+       }
+       skb_put(skb, len);
+       h2c = (struct rtw89_h2c_cctlinfo_ud_g7 *)skb->data;
+
+       for_each_set_bit(tid, rtwsta->ampdu_map, IEEE80211_NUM_TIDS) {
+               if (agg_num == 0)
+                       agg_num = rtwsta->ampdu_params[tid].agg_num;
+               else
+                       agg_num = min(agg_num, rtwsta->ampdu_params[tid].agg_num);
+       }
+
+       if (agg_num <= 0x20)
+               ba_bmap = 3;
+       else if (agg_num > 0x20 && agg_num <= 0x40)
+               ba_bmap = 0;
+       else if (agg_num > 0x40 && agg_num <= 0x80)
+               ba_bmap = 1;
+       else if (agg_num > 0x80 && agg_num <= 0x100)
+               ba_bmap = 2;
+       else if (agg_num > 0x100 && agg_num <= 0x200)
+               ba_bmap = 4;
+       else if (agg_num > 0x200 && agg_num <= 0x400)
+               ba_bmap = 5;
+
+       h2c->c0 = le32_encode_bits(rtwsta->mac_id, CCTLINFO_G7_C0_MACID) |
+                 le32_encode_bits(1, CCTLINFO_G7_C0_OP);
+
+       h2c->w3 = le32_encode_bits(ba_bmap, CCTLINFO_G7_W3_BA_BMAP);
+       h2c->m3 = cpu_to_le32(CCTLINFO_G7_W3_BA_BMAP);
+
+       rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
+                             H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
+                             H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 0,
+                             len);
+
+       ret = rtw89_h2c_tx(rtwdev, skb, false);
+       if (ret) {
+               rtw89_err(rtwdev, "failed to send h2c\n");
+               goto fail;
+       }
+
+       return 0;
+fail:
+       dev_kfree_skb_any(skb);
+
+       return ret;
+}
+EXPORT_SYMBOL(rtw89_fw_h2c_ampdu_cmac_tbl_g7);
+
 int rtw89_fw_h2c_txtime_cmac_tbl(struct rtw89_dev *rtwdev,
                                 struct rtw89_sta *rtwsta)
 {
index f1f119358b28e73e5f05aafe220648416b03d892..b9159278dd4b7b5e4fb9c0d68fb61e67e3bae1e6 100644 (file)
@@ -3946,6 +3946,9 @@ int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev,
 int rtw89_fw_h2c_assoc_cmac_tbl_g7(struct rtw89_dev *rtwdev,
                                   struct ieee80211_vif *vif,
                                   struct ieee80211_sta *sta);
+int rtw89_fw_h2c_ampdu_cmac_tbl_g7(struct rtw89_dev *rtwdev,
+                                  struct ieee80211_vif *vif,
+                                  struct ieee80211_sta *sta);
 int rtw89_fw_h2c_txtime_cmac_tbl(struct rtw89_dev *rtwdev,
                                 struct rtw89_sta *rtwsta);
 int rtw89_fw_h2c_txpath_cmac_tbl(struct rtw89_dev *rtwdev,
@@ -4103,6 +4106,18 @@ static inline int rtw89_chip_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev,
        return chip->ops->h2c_assoc_cmac_tbl(rtwdev, vif, sta);
 }
 
+static inline int rtw89_chip_h2c_ampdu_cmac_tbl(struct rtw89_dev *rtwdev,
+                                               struct ieee80211_vif *vif,
+                                               struct ieee80211_sta *sta)
+{
+       const struct rtw89_chip_info *chip = rtwdev->chip;
+
+       if (chip->ops->h2c_ampdu_cmac_tbl)
+               return chip->ops->h2c_ampdu_cmac_tbl(rtwdev, vif, sta);
+
+       return 0;
+}
+
 static inline
 int rtw89_chip_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
                          bool valid, struct ieee80211_ampdu_params *params)
index 71d5e6f7bb6494e7f4226964f789ac523584f2f8..21b42984fd8a46115d1b5e1bfc193d66df439cd3 100644 (file)
@@ -660,6 +660,8 @@ static int rtw89_ops_ampdu_action(struct ieee80211_hw *hw,
        case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
                mutex_lock(&rtwdev->mutex);
                clear_bit(RTW89_TXQ_F_AMPDU, &rtwtxq->flags);
+               clear_bit(tid, rtwsta->ampdu_map);
+               rtw89_chip_h2c_ampdu_cmac_tbl(rtwdev, vif, sta);
                mutex_unlock(&rtwdev->mutex);
                ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
                break;
@@ -668,7 +670,9 @@ static int rtw89_ops_ampdu_action(struct ieee80211_hw *hw,
                set_bit(RTW89_TXQ_F_AMPDU, &rtwtxq->flags);
                rtwsta->ampdu_params[tid].agg_num = params->buf_size;
                rtwsta->ampdu_params[tid].amsdu = params->amsdu;
+               set_bit(tid, rtwsta->ampdu_map);
                rtw89_leave_ps_mode(rtwdev);
+               rtw89_chip_h2c_ampdu_cmac_tbl(rtwdev, vif, sta);
                mutex_unlock(&rtwdev->mutex);
                break;
        case IEEE80211_AMPDU_RX_START:
index 0688b4c576f9492ca12b2047c111fbdbb74b0f37..63523ca3a0d74ebdc650a2f69e0e89a49c28b8a0 100644 (file)
@@ -2335,6 +2335,7 @@ static const struct rtw89_chip_ops rtw8851b_chip_ops = {
        .resume_sch_tx          = rtw89_mac_resume_sch_tx,
        .h2c_dctl_sec_cam       = NULL,
        .h2c_assoc_cmac_tbl     = rtw89_fw_h2c_assoc_cmac_tbl,
+       .h2c_ampdu_cmac_tbl     = NULL,
        .h2c_update_beacon      = rtw89_fw_h2c_update_beacon,
        .h2c_ba_cam             = rtw89_fw_h2c_ba_cam,
 
index e15751f48fa35af23e694854e9d1d6c702a2e702..3e8219974343a8632807138f7dc6c45326745e31 100644 (file)
@@ -2079,6 +2079,7 @@ static const struct rtw89_chip_ops rtw8852a_chip_ops = {
        .resume_sch_tx          = rtw89_mac_resume_sch_tx,
        .h2c_dctl_sec_cam       = NULL,
        .h2c_assoc_cmac_tbl     = rtw89_fw_h2c_assoc_cmac_tbl,
+       .h2c_ampdu_cmac_tbl     = NULL,
        .h2c_update_beacon      = rtw89_fw_h2c_update_beacon,
        .h2c_ba_cam             = rtw89_fw_h2c_ba_cam,
 
index 817ba15bba20b4e844b820f786527bd276387549..341adc067a965e1b4d2b1c8d89de39db3db1e1b6 100644 (file)
@@ -2504,6 +2504,7 @@ static const struct rtw89_chip_ops rtw8852b_chip_ops = {
        .resume_sch_tx          = rtw89_mac_resume_sch_tx,
        .h2c_dctl_sec_cam       = NULL,
        .h2c_assoc_cmac_tbl     = rtw89_fw_h2c_assoc_cmac_tbl,
+       .h2c_ampdu_cmac_tbl     = NULL,
        .h2c_update_beacon      = rtw89_fw_h2c_update_beacon,
        .h2c_ba_cam             = rtw89_fw_h2c_ba_cam,
 
index 892e3412a9e95c817598fa89c1c0ff5311b844c9..9c9800b2f299d7dc0caf62a930651cef174f5b3c 100644 (file)
@@ -2849,6 +2849,7 @@ static const struct rtw89_chip_ops rtw8852c_chip_ops = {
        .resume_sch_tx          = rtw89_mac_resume_sch_tx_v1,
        .h2c_dctl_sec_cam       = rtw89_fw_h2c_dctl_sec_cam_v1,
        .h2c_assoc_cmac_tbl     = rtw89_fw_h2c_assoc_cmac_tbl,
+       .h2c_ampdu_cmac_tbl     = NULL,
        .h2c_update_beacon      = rtw89_fw_h2c_update_beacon,
        .h2c_ba_cam             = rtw89_fw_h2c_ba_cam,
 
index d0b11848dc933666ec9c8f4b9831246e7ed1e2a0..acccd4be152890dcc4ba75f354951ec5c708ecb0 100644 (file)
@@ -824,6 +824,7 @@ static const struct rtw89_chip_ops rtw8922a_chip_ops = {
        .pwr_off_func           = rtw8922a_pwr_off_func,
        .h2c_dctl_sec_cam       = rtw89_fw_h2c_dctl_sec_cam_v2,
        .h2c_assoc_cmac_tbl     = rtw89_fw_h2c_assoc_cmac_tbl_g7,
+       .h2c_ampdu_cmac_tbl     = rtw89_fw_h2c_ampdu_cmac_tbl_g7,
        .h2c_update_beacon      = rtw89_fw_h2c_update_beacon_be,
        .h2c_ba_cam             = rtw89_fw_h2c_ba_cam_v1,
 };