wifi: rtw89: correct BA CAM allocation

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>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20220816013247.6243-4-pkshih@realtek.com
This commit is contained in:
Ping-Ke Shih 2022-08-16 09:32:47 +08:00 committed by Kalle Valo
parent 8b1b4730b0
commit 08aa80777b
4 changed files with 73 additions and 20 deletions

View file

@ -2242,23 +2242,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;
idx = rtw89_core_acquire_bit_map(rtwsta->ba_cam_map, chip->bacam_num);
lockdep_assert_held(&rtwdev->mutex);
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;
@ -2267,20 +2286,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;
}
@ -2343,6 +2363,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]);

View file

@ -2084,6 +2084,7 @@ struct rtw89_ra_report {
DECLARE_EWMA(rssi, 10, 16);
struct rtw89_ba_cam_entry {
struct list_head list;
u8 tid;
};
@ -2146,6 +2147,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;
@ -2154,9 +2156,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 {
@ -2764,6 +2763,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 {

View file

@ -2434,6 +2434,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]=%d", entry->tid,
(int)(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;
@ -2442,6 +2462,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)
@ -2450,6 +2471,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);
@ -2459,12 +2482,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;
}

View file

@ -302,7 +302,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;
@ -312,15 +312,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)