mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-05 18:39:59 +00:00
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:
parent
8b1b4730b0
commit
08aa80777b
4 changed files with 73 additions and 20 deletions
|
@ -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]);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue