wifi: rtw89: add firmware H2C command of BA CAM V1
authorPing-Ke Shih <pkshih@realtek.com>
Mon, 8 Jan 2024 09:11:25 +0000 (17:11 +0800)
committerKalle Valo <kvalo@kernel.org>
Fri, 12 Jan 2024 17:10:51 +0000 (19:10 +0200)
BA CAM is used to generate BA frame for received AMPDU packets. To support
WiFi 7, change format from V0 to have more fields and enlarge entry number
for new need.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://msgid.link/20240108091134.67007-2-pkshih@realtek.com
drivers/net/wireless/realtek/rtw89/fw.c
drivers/net/wireless/realtek/rtw89/fw.h

index 09684cea9731c3ecfe2e01837133a7fc51bbfc4d..4cda96f15eccf534dec2940c0da348fad2fc9f9b 100644 (file)
@@ -1609,6 +1609,80 @@ void rtw89_fw_h2c_init_dynamic_ba_cam_v0_ext(struct rtw89_dev *rtwdev)
        }
 }
 
+int rtw89_fw_h2c_ba_cam_v1(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
+                          bool valid, struct ieee80211_ampdu_params *params)
+{
+       const struct rtw89_chip_info *chip = rtwdev->chip;
+       struct rtw89_vif *rtwvif = rtwsta->rtwvif;
+       struct rtw89_h2c_ba_cam_v1 *h2c;
+       u8 macid = rtwsta->mac_id;
+       u32 len = sizeof(*h2c);
+       struct sk_buff *skb;
+       u8 entry_idx;
+       u8 bmap_size;
+       int ret;
+
+       ret = valid ?
+             rtw89_core_acquire_sta_ba_entry(rtwdev, rtwsta, params->tid, &entry_idx) :
+             rtw89_core_release_sta_ba_entry(rtwdev, rtwsta, params->tid, &entry_idx);
+       if (ret) {
+               /* it still works even if we don't have static BA CAM, because
+                * hardware can create dynamic BA CAM automatically.
+                */
+               rtw89_debug(rtwdev, RTW89_DBG_TXRX,
+                           "failed to %s entry tid=%d for h2c ba cam\n",
+                           valid ? "alloc" : "free", params->tid);
+               return 0;
+       }
+
+       skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
+       if (!skb) {
+               rtw89_err(rtwdev, "failed to alloc skb for h2c ba cam\n");
+               return -ENOMEM;
+       }
+       skb_put(skb, len);
+       h2c = (struct rtw89_h2c_ba_cam_v1 *)skb->data;
+
+       if (params->buf_size > 512)
+               bmap_size = 10;
+       else if (params->buf_size > 256)
+               bmap_size = 8;
+       else if (params->buf_size > 64)
+               bmap_size = 4;
+       else
+               bmap_size = 0;
+
+       h2c->w0 = le32_encode_bits(valid, RTW89_H2C_BA_CAM_V1_W0_VALID) |
+                 le32_encode_bits(1, RTW89_H2C_BA_CAM_V1_W0_INIT_REQ) |
+                 le32_encode_bits(macid, RTW89_H2C_BA_CAM_V1_W0_MACID_MASK) |
+                 le32_encode_bits(params->tid, RTW89_H2C_BA_CAM_V1_W0_TID_MASK) |
+                 le32_encode_bits(bmap_size, RTW89_H2C_BA_CAM_V1_W0_BMAP_SIZE_MASK) |
+                 le32_encode_bits(params->ssn, RTW89_H2C_BA_CAM_V1_W0_SSN_MASK);
+
+       entry_idx += chip->bacam_dynamic_num; /* std entry right after dynamic ones */
+       h2c->w1 = le32_encode_bits(entry_idx, RTW89_H2C_BA_CAM_V1_W1_ENTRY_IDX_MASK) |
+                 le32_encode_bits(1, RTW89_H2C_BA_CAM_V1_W1_STD_ENTRY_EN) |
+                 le32_encode_bits(!!rtwvif->mac_idx, RTW89_H2C_BA_CAM_V1_W1_BAND_SEL);
+
+       rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
+                             H2C_CAT_MAC,
+                             H2C_CL_BA_CAM,
+                             H2C_FUNC_MAC_BA_CAM_V1, 0, 1,
+                             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;
+}
+
 #define H2C_LOG_CFG_LEN 12
 int rtw89_fw_h2c_fw_log(struct rtw89_dev *rtwdev, bool enable)
 {
index 01016588b1fcb45bcb947919ad51471833f8ca56..b7f564d30378af43617d1c510f7129d436071367 100644 (file)
@@ -1796,6 +1796,23 @@ static inline void SET_BA_CAM_ENTRY_IDX_V1(void *h2c, u32 val)
        le32p_replace_bits((__le32 *)h2c + 1, val, GENMASK(31, 28));
 }
 
+struct rtw89_h2c_ba_cam_v1 {
+       __le32 w0;
+       __le32 w1;
+} __packed;
+
+#define RTW89_H2C_BA_CAM_V1_W0_VALID BIT(0)
+#define RTW89_H2C_BA_CAM_V1_W0_INIT_REQ BIT(1)
+#define RTW89_H2C_BA_CAM_V1_W0_TID_MASK GENMASK(7, 4)
+#define RTW89_H2C_BA_CAM_V1_W0_MACID_MASK GENMASK(15, 8)
+#define RTW89_H2C_BA_CAM_V1_W0_BMAP_SIZE_MASK GENMASK(19, 16)
+#define RTW89_H2C_BA_CAM_V1_W0_SSN_MASK GENMASK(31, 20)
+#define RTW89_H2C_BA_CAM_V1_W1_UID_VALUE_MASK GENMASK(7, 0)
+#define RTW89_H2C_BA_CAM_V1_W1_STD_ENTRY_EN BIT(8)
+#define RTW89_H2C_BA_CAM_V1_W1_BAND_SEL BIT(9)
+#define RTW89_H2C_BA_CAM_V1_W1_MLD_EN BIT(10)
+#define RTW89_H2C_BA_CAM_V1_W1_ENTRY_IDX_MASK GENMASK(31, 24)
+
 static inline void SET_LPS_PARM_MACID(void *h2c, u32 val)
 {
        le32p_replace_bits((__le32 *)h2c, val, GENMASK(7, 0));
@@ -3690,6 +3707,7 @@ enum rtw89_fw_ofld_h2c_func {
 /* CLASS 12 - BA CAM */
 #define H2C_CL_BA_CAM                  0xc
 #define H2C_FUNC_MAC_BA_CAM            0x0
+#define H2C_FUNC_MAC_BA_CAM_V1         0x1
 
 /* CLASS 14 - MCC */
 #define H2C_CL_MCC                     0xe
@@ -3898,6 +3916,8 @@ void rtw89_fw_release_general_pkt_list_vif(struct rtw89_dev *rtwdev,
 void rtw89_fw_release_general_pkt_list(struct rtw89_dev *rtwdev, bool notify_fw);
 int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
                        bool valid, struct ieee80211_ampdu_params *params);
+int rtw89_fw_h2c_ba_cam_v1(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
+                          bool valid, struct ieee80211_ampdu_params *params);
 void rtw89_fw_h2c_init_dynamic_ba_cam_v0_ext(struct rtw89_dev *rtwdev);
 
 int rtw89_fw_h2c_lps_parm(struct rtw89_dev *rtwdev,