Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH 0/3] wifi: rtw89: correct BA CAM allocation
@ 2022-08-15  7:07 Ping-Ke Shih
  2022-08-15  7:07 ` [PATCH 1/3] wifi: rtw89: 8852c: declare correct BA CAM number Ping-Ke Shih
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Ping-Ke Shih @ 2022-08-15  7:07 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

BA CAM is a global hardware resource, but we incorrectly see it as a
per-station resource. In station mode, it works well, but it will be wrong
if AP mode or multiple vif(s) in the future.

Therefore, move bitmap of BA_CAM to struct rtw89_dev::rtw89_cam_info.

Pine-Ke Shih (3):
  wifi: rtw89: 8852c: declare correct BA CAM number
  wifi: rtw89: 8852c: initialize and correct BA CAM content
  wifi: rtw89: correct BA CAM allocation

 drivers/net/wireless/realtek/rtw89/core.c     | 60 ++++++++++++-----
 drivers/net/wireless/realtek/rtw89/core.h     | 19 ++++--
 drivers/net/wireless/realtek/rtw89/debug.c    | 27 ++++++++
 drivers/net/wireless/realtek/rtw89/fw.c       | 66 ++++++++++++++++++-
 drivers/net/wireless/realtek/rtw89/fw.h       |  9 +++
 drivers/net/wireless/realtek/rtw89/rtw8852a.c |  3 +
 drivers/net/wireless/realtek/rtw89/rtw8852c.c |  3 +
 drivers/net/wireless/realtek/rtw89/ser.c      |  8 ++-
 8 files changed, 166 insertions(+), 29 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/3] wifi: rtw89: 8852c: declare correct BA CAM number
  2022-08-15  7:07 [PATCH 0/3] wifi: rtw89: correct BA CAM allocation Ping-Ke Shih
@ 2022-08-15  7:07 ` Ping-Ke Shih
  2022-08-15  7:07 ` [PATCH 2/3] wifi: rtw89: 8852c: initialize and correct BA CAM content Ping-Ke Shih
  2022-08-15  7:07 ` [PATCH 3/3] wifi: rtw89: correct BA CAM allocation Ping-Ke Shih
  2 siblings, 0 replies; 5+ messages in thread
From: Ping-Ke Shih @ 2022-08-15  7:07 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

8852A has 2 BA CAM entries, but 8852C has 8 entries. Add a field to
discriminate their differences.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw89/core.c     | 14 +++++++++-----
 drivers/net/wireless/realtek/rtw89/core.h     | 14 ++++++++------
 drivers/net/wireless/realtek/rtw89/fw.c       |  4 ++--
 drivers/net/wireless/realtek/rtw89/rtw8852a.c |  1 +
 drivers/net/wireless/realtek/rtw89/rtw8852c.c |  1 +
 5 files changed, 21 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index a5880a54812e7..07aa722164203 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -2266,13 +2266,15 @@ void rtw89_core_release_all_bits_map(unsigned long *addr, unsigned int nbits)
 	bitmap_zero(addr, nbits);
 }
 
-int rtw89_core_acquire_sta_ba_entry(struct rtw89_sta *rtwsta, u8 tid, u8 *cam_idx)
+int rtw89_core_acquire_sta_ba_entry(struct rtw89_dev *rtwdev,
+				    struct rtw89_sta *rtwsta, u8 tid, u8 *cam_idx)
 {
+	const struct rtw89_chip_info *chip = rtwdev->chip;
 	struct rtw89_ba_cam_entry *entry;
 	u8 idx;
 
-	idx = rtw89_core_acquire_bit_map(rtwsta->ba_cam_map, RTW89_BA_CAM_NUM);
-	if (idx == RTW89_BA_CAM_NUM) {
+	idx = rtw89_core_acquire_bit_map(rtwsta->ba_cam_map, chip->bacam_num);
+	if (idx == chip->bacam_num) {
 		/* allocate a static BA CAM to tid=0, so replace the existing
 		 * one if BA CAM is full. Hardware will process the original tid
 		 * automatically.
@@ -2290,12 +2292,14 @@ int rtw89_core_acquire_sta_ba_entry(struct rtw89_sta *rtwsta, u8 tid, u8 *cam_id
 	return 0;
 }
 
-int rtw89_core_release_sta_ba_entry(struct rtw89_sta *rtwsta, u8 tid, u8 *cam_idx)
+int rtw89_core_release_sta_ba_entry(struct rtw89_dev *rtwdev,
+				    struct rtw89_sta *rtwsta, u8 tid, u8 *cam_idx)
 {
+	const struct rtw89_chip_info *chip = rtwdev->chip;
 	struct rtw89_ba_cam_entry *entry;
 	int i;
 
-	for (i = 0; i < RTW89_BA_CAM_NUM; i++) {
+	for (i = 0; i < chip->bacam_num; i++) {
 		if (!test_bit(i, rtwsta->ba_cam_map))
 			continue;
 
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 7a9d6f5d8a513..38228dbe2a7dd 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -1915,8 +1915,6 @@ struct rtw89_ra_report {
 
 DECLARE_EWMA(rssi, 10, 16);
 
-#define RTW89_BA_CAM_NUM 2
-
 struct rtw89_ba_cam_entry {
 	u8 tid;
 };
@@ -1924,6 +1922,7 @@ struct rtw89_ba_cam_entry {
 #define RTW89_MAX_ADDR_CAM_NUM		128
 #define RTW89_MAX_BSSID_CAM_NUM		20
 #define RTW89_MAX_SEC_CAM_NUM		128
+#define RTW89_MAX_BA_CAM_NUM		8
 #define RTW89_SEC_CAM_IN_ADDR_CAM	7
 
 struct rtw89_addr_cam_entry {
@@ -1988,8 +1987,8 @@ struct rtw89_sta {
 	bool cctl_tx_retry_limit;
 	u32 data_tx_cnt_lmt:6;
 
-	DECLARE_BITMAP(ba_cam_map, RTW89_BA_CAM_NUM);
-	struct rtw89_ba_cam_entry ba_cam_entry[RTW89_BA_CAM_NUM];
+	DECLARE_BITMAP(ba_cam_map, RTW89_MAX_BA_CAM_NUM);
+	struct rtw89_ba_cam_entry ba_cam_entry[RTW89_MAX_BA_CAM_NUM];
 };
 
 struct rtw89_efuse {
@@ -2393,6 +2392,7 @@ struct rtw89_chip_info {
 	u8 acam_num;
 	u8 bcam_num;
 	u8 scam_num;
+	u8 bacam_num;
 
 	u8 sec_ctrl_efuse_size;
 	u32 physical_efuse_size;
@@ -3910,8 +3910,10 @@ void rtw89_set_channel(struct rtw89_dev *rtwdev);
 u8 rtw89_core_acquire_bit_map(unsigned long *addr, unsigned long size);
 void rtw89_core_release_bit_map(unsigned long *addr, u8 bit);
 void rtw89_core_release_all_bits_map(unsigned long *addr, unsigned int nbits);
-int rtw89_core_acquire_sta_ba_entry(struct rtw89_sta *rtwsta, u8 tid, u8 *cam_idx);
-int rtw89_core_release_sta_ba_entry(struct rtw89_sta *rtwsta, u8 tid, u8 *cam_idx);
+int rtw89_core_acquire_sta_ba_entry(struct rtw89_dev *rtwdev,
+				    struct rtw89_sta *rtwsta, u8 tid, u8 *cam_idx);
+int rtw89_core_release_sta_ba_entry(struct rtw89_dev *rtwdev,
+				    struct rtw89_sta *rtwsta, u8 tid, u8 *cam_idx);
 void rtw89_vif_type_mapping(struct ieee80211_vif *vif, bool assoc);
 int rtw89_chip_info_setup(struct rtw89_dev *rtwdev);
 bool rtw89_ra_report_to_bitrate(struct rtw89_dev *rtwdev, u8 rpt_rate, u16 *bitrate);
diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index 6473015a6b2a1..4d39cf9185378 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -644,8 +644,8 @@ int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
 	int ret;
 
 	ret = valid ?
-	      rtw89_core_acquire_sta_ba_entry(rtwsta, params->tid, &entry_idx) :
-	      rtw89_core_release_sta_ba_entry(rtwsta, params->tid, &entry_idx);
+	      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.
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c
index 81bd0c4fe21bc..4a1f7b5e83f6c 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c
@@ -2125,6 +2125,7 @@ const struct rtw89_chip_info rtw8852a_chip_info = {
 	.acam_num		= 128,
 	.bcam_num		= 10,
 	.scam_num		= 128,
+	.bacam_num		= 2,
 	.sec_ctrl_efuse_size	= 4,
 	.physical_efuse_size	= 1216,
 	.logical_efuse_size	= 1536,
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c
index b697aef2faf2d..a74b4c550ec1a 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c
@@ -2972,6 +2972,7 @@ const struct rtw89_chip_info rtw8852c_chip_info = {
 	.acam_num		= 128,
 	.bcam_num		= 20,
 	.scam_num		= 128,
+	.bacam_num		= 8,
 	.sec_ctrl_efuse_size	= 4,
 	.physical_efuse_size	= 1216,
 	.logical_efuse_size	= 2048,
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/3] wifi: rtw89: 8852c: initialize and correct BA CAM content
  2022-08-15  7:07 [PATCH 0/3] wifi: rtw89: correct BA CAM allocation Ping-Ke Shih
  2022-08-15  7:07 ` [PATCH 1/3] wifi: rtw89: 8852c: declare correct BA CAM number Ping-Ke Shih
@ 2022-08-15  7:07 ` Ping-Ke Shih
  2022-08-15  7:07 ` [PATCH 3/3] wifi: rtw89: correct BA CAM allocation Ping-Ke Shih
  2 siblings, 0 replies; 5+ messages in thread
From: Ping-Ke Shih @ 2022-08-15  7:07 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

The bacam_v1 must do additional initialization, and H2C content of BA CAM
is also different. So, correct them accordingly.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw89/core.c     |  1 +
 drivers/net/wireless/realtek/rtw89/core.h     |  2 +
 drivers/net/wireless/realtek/rtw89/fw.c       | 62 ++++++++++++++++++-
 drivers/net/wireless/realtek/rtw89/fw.h       |  9 +++
 drivers/net/wireless/realtek/rtw89/rtw8852a.c |  2 +
 drivers/net/wireless/realtek/rtw89/rtw8852c.c |  2 +
 6 files changed, 77 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index 07aa722164203..2ec4cc11b29e1 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -2898,6 +2898,7 @@ int rtw89_core_start(struct rtw89_dev *rtwdev)
 
 	rtw89_btc_ntfy_radio_state(rtwdev, BTC_RFCTRL_WL_ON);
 	rtw89_fw_h2c_fw_log(rtwdev, rtwdev->fw.fw_log_enable);
+	rtw89_fw_h2c_init_ba_cam(rtwdev);
 
 	return 0;
 }
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 38228dbe2a7dd..d06cfb8025318 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -2393,6 +2393,8 @@ struct rtw89_chip_info {
 	u8 bcam_num;
 	u8 scam_num;
 	u8 bacam_num;
+	u8 bacam_dynamic_num;
+	bool bacam_v1;
 
 	u8 sec_ctrl_efuse_size;
 	u32 physical_efuse_size;
diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index 4d39cf9185378..957c70ee9e135 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -638,6 +638,8 @@ EXPORT_SYMBOL(rtw89_fw_h2c_dctl_sec_cam_v1);
 int rtw89_fw_h2c_ba_cam(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;
 	u8 macid = rtwsta->mac_id;
 	struct sk_buff *skb;
 	u8 entry_idx;
@@ -663,7 +665,10 @@ int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
 	}
 	skb_put(skb, H2C_BA_CAM_LEN);
 	SET_BA_CAM_MACID(skb->data, macid);
-	SET_BA_CAM_ENTRY_IDX(skb->data, entry_idx);
+	if (chip->bacam_v1)
+		SET_BA_CAM_ENTRY_IDX_V1(skb->data, entry_idx);
+	else
+		SET_BA_CAM_ENTRY_IDX(skb->data, entry_idx);
 	if (!valid)
 		goto end;
 	SET_BA_CAM_VALID(skb->data, valid);
@@ -676,6 +681,11 @@ int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
 	SET_BA_CAM_INIT_REQ(skb->data, 1);
 	SET_BA_CAM_SSN(skb->data, params->ssn);
 
+	if (chip->bacam_v1) {
+		SET_BA_CAM_STD_EN(skb->data, 1);
+		SET_BA_CAM_BAND(skb->data, rtwvif->mac_idx);
+	}
+
 end:
 	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
 			      H2C_CAT_MAC,
@@ -695,6 +705,56 @@ int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
 	return -EBUSY;
 }
 
+static int rtw89_fw_h2c_init_dynamic_ba_cam_v1(struct rtw89_dev *rtwdev,
+					       u8 entry_idx, u8 uid)
+{
+	struct sk_buff *skb;
+
+	skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_BA_CAM_LEN);
+	if (!skb) {
+		rtw89_err(rtwdev, "failed to alloc skb for dynamic h2c ba cam\n");
+		return -ENOMEM;
+	}
+	skb_put(skb, H2C_BA_CAM_LEN);
+
+	SET_BA_CAM_VALID(skb->data, 1);
+	SET_BA_CAM_ENTRY_IDX_V1(skb->data, entry_idx);
+	SET_BA_CAM_UID(skb->data, uid);
+	SET_BA_CAM_BAND(skb->data, 0);
+	SET_BA_CAM_STD_EN(skb->data, 0);
+
+	rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
+			      H2C_CAT_MAC,
+			      H2C_CL_BA_CAM,
+			      H2C_FUNC_MAC_BA_CAM, 0, 1,
+			      H2C_BA_CAM_LEN);
+
+	if (rtw89_h2c_tx(rtwdev, skb, false)) {
+		rtw89_err(rtwdev, "failed to send h2c\n");
+		goto fail;
+	}
+
+	return 0;
+fail:
+	dev_kfree_skb_any(skb);
+
+	return -EBUSY;
+}
+
+void rtw89_fw_h2c_init_ba_cam_v1(struct rtw89_dev *rtwdev)
+{
+	const struct rtw89_chip_info *chip = rtwdev->chip;
+	u8 entry_idx = chip->bacam_num;
+	u8 uid = 0;
+	int i;
+
+	for (i = 0; i < chip->bacam_dynamic_num; i++) {
+		rtw89_fw_h2c_init_dynamic_ba_cam_v1(rtwdev, entry_idx, uid);
+		entry_idx++;
+		uid++;
+	}
+}
+
 #define H2C_LOG_CFG_LEN 12
 int rtw89_fw_h2c_fw_log(struct rtw89_dev *rtwdev, bool enable)
 {
diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h
index e75ad22aa85df..a9508986b5623 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.h
+++ b/drivers/net/wireless/realtek/rtw89/fw.h
@@ -2623,6 +2623,7 @@ void rtw89_fw_free_all_early_h2c(struct rtw89_dev *rtwdev);
 int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, u8 macid);
 int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
 			bool valid, struct ieee80211_ampdu_params *params);
+void rtw89_fw_h2c_init_ba_cam_v1(struct rtw89_dev *rtwdev);
 
 int rtw89_fw_h2c_lps_parm(struct rtw89_dev *rtwdev,
 			  struct rtw89_lps_parm *lps_param);
@@ -2643,4 +2644,12 @@ int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
 void rtw89_hw_scan_abort(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif);
 int rtw89_fw_h2c_trigger_cpu_exception(struct rtw89_dev *rtwdev);
 
+static inline void rtw89_fw_h2c_init_ba_cam(struct rtw89_dev *rtwdev)
+{
+	const struct rtw89_chip_info *chip = rtwdev->chip;
+
+	if (chip->bacam_v1)
+		rtw89_fw_h2c_init_ba_cam_v1(rtwdev);
+}
+
 #endif
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c
index 4a1f7b5e83f6c..41ca679685e07 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c
@@ -2126,6 +2126,8 @@ const struct rtw89_chip_info rtw8852a_chip_info = {
 	.bcam_num		= 10,
 	.scam_num		= 128,
 	.bacam_num		= 2,
+	.bacam_dynamic_num	= 4,
+	.bacam_v1		= false,
 	.sec_ctrl_efuse_size	= 4,
 	.physical_efuse_size	= 1216,
 	.logical_efuse_size	= 1536,
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c
index a74b4c550ec1a..f97349fa550fe 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c
@@ -2973,6 +2973,8 @@ const struct rtw89_chip_info rtw8852c_chip_info = {
 	.bcam_num		= 20,
 	.scam_num		= 128,
 	.bacam_num		= 8,
+	.bacam_dynamic_num	= 8,
+	.bacam_v1		= true,
 	.sec_ctrl_efuse_size	= 4,
 	.physical_efuse_size	= 1216,
 	.logical_efuse_size	= 2048,
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 3/3] wifi: rtw89: correct BA CAM allocation
  2022-08-15  7:07 [PATCH 0/3] wifi: rtw89: correct BA CAM allocation Ping-Ke Shih
  2022-08-15  7:07 ` [PATCH 1/3] wifi: rtw89: 8852c: declare correct BA CAM number Ping-Ke Shih
  2022-08-15  7:07 ` [PATCH 2/3] wifi: rtw89: 8852c: initialize and correct BA CAM content Ping-Ke Shih
@ 2022-08-15  7:07 ` Ping-Ke Shih
  2022-08-15 12:20   ` kernel test robot
  2 siblings, 1 reply; 5+ messages in thread
From: Ping-Ke Shih @ 2022-08-15  7:07 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless

BA CAM entries are global resource of hardware, so move the bitmap and
instances to rtw89_cam_info, and then use link list from rtw89_sta to
these instances.

To check the allocation, add ba_cam to debugfs:

  map:
  	mac_id:    01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  	addr_cam:  01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  	bssid_cam: 01 00 00 00 00 00 00 00
  	sec_cam:   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  	ba_cam:    03 00 00 00 00 00 00 00
  VIF [0] 94:08:53:8e:ef:21
  	bssid_cam_idx=0
  	addr_cam_idx=0
  	-> bssid_cam_idx=0
  	sec_cam_bitmap=00 00 00 00 00 00 00 00
  STA [0] 38:78:62:8b:cb:c6
  	addr_cam_idx=0
  	-> bssid_cam_idx=0
  	sec_cam_bitmap=00 00 00 00 00 00 00 00
  	ba_cam tid[6]=0, tid[1]=1

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw89/core.c  | 51 +++++++++++++++-------
 drivers/net/wireless/realtek/rtw89/core.h  |  7 +--
 drivers/net/wireless/realtek/rtw89/debug.c | 27 ++++++++++++
 drivers/net/wireless/realtek/rtw89/ser.c   |  8 +++-
 4 files changed, 73 insertions(+), 20 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index 2ec4cc11b29e1..608896dd0d158 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -2270,23 +2270,42 @@ int rtw89_core_acquire_sta_ba_entry(struct rtw89_dev *rtwdev,
 				    struct rtw89_sta *rtwsta, u8 tid, u8 *cam_idx)
 {
 	const struct rtw89_chip_info *chip = rtwdev->chip;
-	struct rtw89_ba_cam_entry *entry;
+	struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
+	struct rtw89_ba_cam_entry *entry = NULL, *tmp;
 	u8 idx;
+	int i;
+
+	lockdep_assert_held(&rtwdev->mutex);
 
-	idx = rtw89_core_acquire_bit_map(rtwsta->ba_cam_map, chip->bacam_num);
+	idx = rtw89_core_acquire_bit_map(cam_info->ba_cam_map, chip->bacam_num);
 	if (idx == chip->bacam_num) {
-		/* allocate a static BA CAM to tid=0, so replace the existing
+		/* allocate a static BA CAM to tid=0/5, so replace the existing
 		 * one if BA CAM is full. Hardware will process the original tid
 		 * automatically.
 		 */
-		if (tid != 0)
+		if (tid != 0 && tid != 5)
 			return -ENOSPC;
 
-		idx = 0;
+		for_each_set_bit(i, cam_info->ba_cam_map, chip->bacam_num) {
+			tmp = &cam_info->ba_cam_entry[i];
+			if (tmp->tid == 0 || tmp->tid == 5)
+				continue;
+
+			idx = i;
+			entry = tmp;
+			list_del(&entry->list);
+			break;
+		}
+
+		if (!entry)
+			return -ENOSPC;
+	} else {
+		entry = &cam_info->ba_cam_entry[idx];
 	}
 
-	entry = &rtwsta->ba_cam_entry[idx];
 	entry->tid = tid;
+	list_add_tail(&entry->list, &rtwsta->ba_cam_list);
+
 	*cam_idx = idx;
 
 	return 0;
@@ -2295,20 +2314,21 @@ int rtw89_core_acquire_sta_ba_entry(struct rtw89_dev *rtwdev,
 int rtw89_core_release_sta_ba_entry(struct rtw89_dev *rtwdev,
 				    struct rtw89_sta *rtwsta, u8 tid, u8 *cam_idx)
 {
-	const struct rtw89_chip_info *chip = rtwdev->chip;
-	struct rtw89_ba_cam_entry *entry;
-	int i;
+	struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
+	struct rtw89_ba_cam_entry *entry = NULL, *tmp;
+	u8 idx;
 
-	for (i = 0; i < chip->bacam_num; i++) {
-		if (!test_bit(i, rtwsta->ba_cam_map))
-			continue;
+	lockdep_assert_held(&rtwdev->mutex);
 
-		entry = &rtwsta->ba_cam_entry[i];
+	list_for_each_entry_safe(entry, tmp, &rtwsta->ba_cam_list, list) {
 		if (entry->tid != tid)
 			continue;
 
-		rtw89_core_release_bit_map(rtwsta->ba_cam_map, i);
-		*cam_idx = i;
+		idx = entry - cam_info->ba_cam_entry;
+		list_del(&entry->list);
+
+		rtw89_core_release_bit_map(cam_info->ba_cam_map, idx);
+		*cam_idx = idx;
 		return 0;
 	}
 
@@ -2371,6 +2391,7 @@ int rtw89_core_sta_add(struct rtw89_dev *rtwdev,
 
 	rtwsta->rtwvif = rtwvif;
 	rtwsta->prev_rssi = 0;
+	INIT_LIST_HEAD(&rtwsta->ba_cam_list);
 
 	for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
 		rtw89_core_txq_init(rtwdev, sta->txq[i]);
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index d06cfb8025318..6fd129f03b89d 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -1916,6 +1916,7 @@ struct rtw89_ra_report {
 DECLARE_EWMA(rssi, 10, 16);
 
 struct rtw89_ba_cam_entry {
+	struct list_head list;
 	u8 tid;
 };
 
@@ -1978,6 +1979,7 @@ struct rtw89_sta {
 	__le32 htc_template;
 	struct rtw89_addr_cam_entry addr_cam; /* AP mode or TDLS peer only */
 	struct rtw89_bssid_cam_entry bssid_cam; /* TDLS peer only */
+	struct list_head ba_cam_list;
 
 	bool use_cfg_mask;
 	struct cfg80211_bitrate_mask mask;
@@ -1986,9 +1988,6 @@ struct rtw89_sta {
 	u32 ampdu_max_time:4;
 	bool cctl_tx_retry_limit;
 	u32 data_tx_cnt_lmt:6;
-
-	DECLARE_BITMAP(ba_cam_map, RTW89_MAX_BA_CAM_NUM);
-	struct rtw89_ba_cam_entry ba_cam_entry[RTW89_MAX_BA_CAM_NUM];
 };
 
 struct rtw89_efuse {
@@ -2560,6 +2559,8 @@ struct rtw89_cam_info {
 	DECLARE_BITMAP(addr_cam_map, RTW89_MAX_ADDR_CAM_NUM);
 	DECLARE_BITMAP(bssid_cam_map, RTW89_MAX_BSSID_CAM_NUM);
 	DECLARE_BITMAP(sec_cam_map, RTW89_MAX_SEC_CAM_NUM);
+	DECLARE_BITMAP(ba_cam_map, RTW89_MAX_BA_CAM_NUM);
+	struct rtw89_ba_cam_entry ba_cam_entry[RTW89_MAX_BA_CAM_NUM];
 };
 
 enum rtw89_sar_sources {
diff --git a/drivers/net/wireless/realtek/rtw89/debug.c b/drivers/net/wireless/realtek/rtw89/debug.c
index 829c61da99bb9..1a7ba12229cc8 100644
--- a/drivers/net/wireless/realtek/rtw89/debug.c
+++ b/drivers/net/wireless/realtek/rtw89/debug.c
@@ -2433,6 +2433,26 @@ void rtw89_vif_ids_get_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
 	rtw89_dump_addr_cam(m, &rtwvif->addr_cam);
 }
 
+static void rtw89_dump_ba_cam(struct seq_file *m, struct rtw89_sta *rtwsta)
+{
+	struct rtw89_vif *rtwvif = rtwsta->rtwvif;
+	struct rtw89_dev *rtwdev = rtwvif->rtwdev;
+	struct rtw89_ba_cam_entry *entry;
+	bool first = true;
+
+	list_for_each_entry(entry, &rtwsta->ba_cam_list, list) {
+		if (first) {
+			seq_puts(m, "\tba_cam ");
+			first = false;
+		} else {
+			seq_puts(m, ", ");
+		}
+		seq_printf(m, "tid[%u]=%ld", entry->tid,
+			   entry - rtwdev->cam_info.ba_cam_entry);
+	}
+	seq_puts(m, "\n");
+}
+
 static void rtw89_sta_ids_get_iter(void *data, struct ieee80211_sta *sta)
 {
 	struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
@@ -2441,6 +2461,7 @@ static void rtw89_sta_ids_get_iter(void *data, struct ieee80211_sta *sta)
 	seq_printf(m, "STA [%d] %pM %s\n", rtwsta->mac_id, sta->addr,
 		   sta->tdls ? "(TDLS)" : "");
 	rtw89_dump_addr_cam(m, &rtwsta->addr_cam);
+	rtw89_dump_ba_cam(m, rtwsta);
 }
 
 static int rtw89_debug_priv_stations_get(struct seq_file *m, void *v)
@@ -2449,6 +2470,8 @@ static int rtw89_debug_priv_stations_get(struct seq_file *m, void *v)
 	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
 	struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
 
+	mutex_lock(&rtwdev->mutex);
+
 	seq_puts(m, "map:\n");
 	seq_printf(m, "\tmac_id:    %*ph\n", (int)sizeof(rtwdev->mac_id_map),
 		   rtwdev->mac_id_map);
@@ -2458,12 +2481,16 @@ static int rtw89_debug_priv_stations_get(struct seq_file *m, void *v)
 		   cam_info->bssid_cam_map);
 	seq_printf(m, "\tsec_cam:   %*ph\n", (int)sizeof(cam_info->sec_cam_map),
 		   cam_info->sec_cam_map);
+	seq_printf(m, "\tba_cam:    %*ph\n", (int)sizeof(cam_info->ba_cam_map),
+		   cam_info->ba_cam_map);
 
 	ieee80211_iterate_active_interfaces_atomic(rtwdev->hw,
 		IEEE80211_IFACE_ITER_NORMAL, rtw89_vif_ids_get_iter, m);
 
 	ieee80211_iterate_stations_atomic(rtwdev->hw, rtw89_sta_ids_get_iter, m);
 
+	mutex_unlock(&rtwdev->mutex);
+
 	return 0;
 }
 
diff --git a/drivers/net/wireless/realtek/rtw89/ser.c b/drivers/net/wireless/realtek/rtw89/ser.c
index 726223f25dc69..33aaa4dd05ef0 100644
--- a/drivers/net/wireless/realtek/rtw89/ser.c
+++ b/drivers/net/wireless/realtek/rtw89/ser.c
@@ -298,7 +298,7 @@ static void ser_reset_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
 	rtwvif->trigger = false;
 }
 
-static void ser_sta_deinit_addr_cam_iter(void *data, struct ieee80211_sta *sta)
+static void ser_sta_deinit_cam_iter(void *data, struct ieee80211_sta *sta)
 {
 	struct rtw89_vif *rtwvif = (struct rtw89_vif *)data;
 	struct rtw89_dev *rtwdev = rtwvif->rtwdev;
@@ -308,15 +308,19 @@ static void ser_sta_deinit_addr_cam_iter(void *data, struct ieee80211_sta *sta)
 		rtw89_cam_deinit_addr_cam(rtwdev, &rtwsta->addr_cam);
 	if (sta->tdls)
 		rtw89_cam_deinit_bssid_cam(rtwdev, &rtwsta->bssid_cam);
+
+	INIT_LIST_HEAD(&rtwsta->ba_cam_list);
 }
 
 static void ser_deinit_cam(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
 {
 	ieee80211_iterate_stations_atomic(rtwdev->hw,
-					  ser_sta_deinit_addr_cam_iter,
+					  ser_sta_deinit_cam_iter,
 					  rtwvif);
 
 	rtw89_cam_deinit(rtwdev, rtwvif);
+
+	bitmap_zero(rtwdev->cam_info.ba_cam_map, RTW89_MAX_BA_CAM_NUM);
 }
 
 static void ser_reset_mac_binding(struct rtw89_dev *rtwdev)
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 3/3] wifi: rtw89: correct BA CAM allocation
  2022-08-15  7:07 ` [PATCH 3/3] wifi: rtw89: correct BA CAM allocation Ping-Ke Shih
@ 2022-08-15 12:20   ` kernel test robot
  0 siblings, 0 replies; 5+ messages in thread
From: kernel test robot @ 2022-08-15 12:20 UTC (permalink / raw)
  To: Ping-Ke Shih, kvalo; +Cc: kbuild-all, linux-wireless

Hi Ping-Ke,

I love your patch! Perhaps something to improve:

[auto build test WARNING on wireless-next/main]
[also build test WARNING on wireless/main linus/master v6.0-rc1 next-20220815]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Ping-Ke-Shih/wifi-rtw89-correct-BA-CAM-allocation/20220815-151009
base:   https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next.git main
config: parisc-allyesconfig (https://download.01.org/0day-ci/archive/20220815/202208152030.442QsT2L-lkp@intel.com/config)
compiler: hppa-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/336a217f279e1188ec626d83a9f6edc636e68aa5
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Ping-Ke-Shih/wifi-rtw89-correct-BA-CAM-allocation/20220815-151009
        git checkout 336a217f279e1188ec626d83a9f6edc636e68aa5
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=parisc SHELL=/bin/bash drivers/net/

If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   drivers/net/wireless/realtek/rtw89/debug.c: In function 'rtw89_dump_ba_cam':
>> drivers/net/wireless/realtek/rtw89/debug.c:2450:42: warning: format '%ld' expects argument of type 'long int', but argument 4 has type 'int' [-Wformat=]
    2450 |                 seq_printf(m, "tid[%u]=%ld", entry->tid,
         |                                        ~~^
         |                                          |
         |                                          long int
         |                                        %d
    2451 |                            entry - rtwdev->cam_info.ba_cam_entry);
         |                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         |                                  |
         |                                  int


vim +2450 drivers/net/wireless/realtek/rtw89/debug.c

  2435	
  2436	static void rtw89_dump_ba_cam(struct seq_file *m, struct rtw89_sta *rtwsta)
  2437	{
  2438		struct rtw89_vif *rtwvif = rtwsta->rtwvif;
  2439		struct rtw89_dev *rtwdev = rtwvif->rtwdev;
  2440		struct rtw89_ba_cam_entry *entry;
  2441		bool first = true;
  2442	
  2443		list_for_each_entry(entry, &rtwsta->ba_cam_list, list) {
  2444			if (first) {
  2445				seq_puts(m, "\tba_cam ");
  2446				first = false;
  2447			} else {
  2448				seq_puts(m, ", ");
  2449			}
> 2450			seq_printf(m, "tid[%u]=%ld", entry->tid,
  2451				   entry - rtwdev->cam_info.ba_cam_entry);
  2452		}
  2453		seq_puts(m, "\n");
  2454	}
  2455	

-- 
0-DAY CI Kernel Test Service
https://01.org/lkp

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2022-08-15 12:20 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-08-15  7:07 [PATCH 0/3] wifi: rtw89: correct BA CAM allocation Ping-Ke Shih
2022-08-15  7:07 ` [PATCH 1/3] wifi: rtw89: 8852c: declare correct BA CAM number Ping-Ke Shih
2022-08-15  7:07 ` [PATCH 2/3] wifi: rtw89: 8852c: initialize and correct BA CAM content Ping-Ke Shih
2022-08-15  7:07 ` [PATCH 3/3] wifi: rtw89: correct BA CAM allocation Ping-Ke Shih
2022-08-15 12:20   ` kernel test robot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox