提交 08aa8077 编写于 作者: P Ping-Ke Shih 提交者: Kalle Valo

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: NPing-Ke Shih <pkshih@realtek.com>
Signed-off-by: NKalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20220816013247.6243-4-pkshih@realtek.com
上级 8b1b4730
...@@ -2242,23 +2242,42 @@ int rtw89_core_acquire_sta_ba_entry(struct rtw89_dev *rtwdev, ...@@ -2242,23 +2242,42 @@ int rtw89_core_acquire_sta_ba_entry(struct rtw89_dev *rtwdev,
struct rtw89_sta *rtwsta, u8 tid, u8 *cam_idx) struct rtw89_sta *rtwsta, u8 tid, u8 *cam_idx)
{ {
const struct rtw89_chip_info *chip = rtwdev->chip; 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; 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) { 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 * one if BA CAM is full. Hardware will process the original tid
* automatically. * automatically.
*/ */
if (tid != 0) if (tid != 0 && tid != 5)
return -ENOSPC; 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; entry->tid = tid;
list_add_tail(&entry->list, &rtwsta->ba_cam_list);
*cam_idx = idx; *cam_idx = idx;
return 0; return 0;
...@@ -2267,20 +2286,21 @@ int rtw89_core_acquire_sta_ba_entry(struct rtw89_dev *rtwdev, ...@@ -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, int rtw89_core_release_sta_ba_entry(struct rtw89_dev *rtwdev,
struct rtw89_sta *rtwsta, u8 tid, u8 *cam_idx) struct rtw89_sta *rtwsta, u8 tid, u8 *cam_idx)
{ {
const struct rtw89_chip_info *chip = rtwdev->chip; struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
struct rtw89_ba_cam_entry *entry; struct rtw89_ba_cam_entry *entry = NULL, *tmp;
int i; u8 idx;
for (i = 0; i < chip->bacam_num; i++) { lockdep_assert_held(&rtwdev->mutex);
if (!test_bit(i, rtwsta->ba_cam_map))
continue;
entry = &rtwsta->ba_cam_entry[i]; list_for_each_entry_safe(entry, tmp, &rtwsta->ba_cam_list, list) {
if (entry->tid != tid) if (entry->tid != tid)
continue; continue;
rtw89_core_release_bit_map(rtwsta->ba_cam_map, i); idx = entry - cam_info->ba_cam_entry;
*cam_idx = i; list_del(&entry->list);
rtw89_core_release_bit_map(cam_info->ba_cam_map, idx);
*cam_idx = idx;
return 0; return 0;
} }
...@@ -2343,6 +2363,7 @@ int rtw89_core_sta_add(struct rtw89_dev *rtwdev, ...@@ -2343,6 +2363,7 @@ int rtw89_core_sta_add(struct rtw89_dev *rtwdev,
rtwsta->rtwvif = rtwvif; rtwsta->rtwvif = rtwvif;
rtwsta->prev_rssi = 0; rtwsta->prev_rssi = 0;
INIT_LIST_HEAD(&rtwsta->ba_cam_list);
for (i = 0; i < ARRAY_SIZE(sta->txq); i++) for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
rtw89_core_txq_init(rtwdev, sta->txq[i]); rtw89_core_txq_init(rtwdev, sta->txq[i]);
......
...@@ -2084,6 +2084,7 @@ struct rtw89_ra_report { ...@@ -2084,6 +2084,7 @@ struct rtw89_ra_report {
DECLARE_EWMA(rssi, 10, 16); DECLARE_EWMA(rssi, 10, 16);
struct rtw89_ba_cam_entry { struct rtw89_ba_cam_entry {
struct list_head list;
u8 tid; u8 tid;
}; };
...@@ -2146,6 +2147,7 @@ struct rtw89_sta { ...@@ -2146,6 +2147,7 @@ struct rtw89_sta {
__le32 htc_template; __le32 htc_template;
struct rtw89_addr_cam_entry addr_cam; /* AP mode or TDLS peer only */ struct rtw89_addr_cam_entry addr_cam; /* AP mode or TDLS peer only */
struct rtw89_bssid_cam_entry bssid_cam; /* TDLS peer only */ struct rtw89_bssid_cam_entry bssid_cam; /* TDLS peer only */
struct list_head ba_cam_list;
bool use_cfg_mask; bool use_cfg_mask;
struct cfg80211_bitrate_mask mask; struct cfg80211_bitrate_mask mask;
...@@ -2154,9 +2156,6 @@ struct rtw89_sta { ...@@ -2154,9 +2156,6 @@ struct rtw89_sta {
u32 ampdu_max_time:4; u32 ampdu_max_time:4;
bool cctl_tx_retry_limit; bool cctl_tx_retry_limit;
u32 data_tx_cnt_lmt:6; 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 { struct rtw89_efuse {
...@@ -2764,6 +2763,8 @@ struct rtw89_cam_info { ...@@ -2764,6 +2763,8 @@ struct rtw89_cam_info {
DECLARE_BITMAP(addr_cam_map, RTW89_MAX_ADDR_CAM_NUM); DECLARE_BITMAP(addr_cam_map, RTW89_MAX_ADDR_CAM_NUM);
DECLARE_BITMAP(bssid_cam_map, RTW89_MAX_BSSID_CAM_NUM); DECLARE_BITMAP(bssid_cam_map, RTW89_MAX_BSSID_CAM_NUM);
DECLARE_BITMAP(sec_cam_map, RTW89_MAX_SEC_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 { enum rtw89_sar_sources {
......
...@@ -2434,6 +2434,26 @@ void rtw89_vif_ids_get_iter(void *data, u8 *mac, struct ieee80211_vif *vif) ...@@ -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); 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) static void rtw89_sta_ids_get_iter(void *data, struct ieee80211_sta *sta)
{ {
struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; 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) ...@@ -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, seq_printf(m, "STA [%d] %pM %s\n", rtwsta->mac_id, sta->addr,
sta->tdls ? "(TDLS)" : ""); sta->tdls ? "(TDLS)" : "");
rtw89_dump_addr_cam(m, &rtwsta->addr_cam); 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) 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) ...@@ -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_dev *rtwdev = debugfs_priv->rtwdev;
struct rtw89_cam_info *cam_info = &rtwdev->cam_info; struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
mutex_lock(&rtwdev->mutex);
seq_puts(m, "map:\n"); seq_puts(m, "map:\n");
seq_printf(m, "\tmac_id: %*ph\n", (int)sizeof(rtwdev->mac_id_map), seq_printf(m, "\tmac_id: %*ph\n", (int)sizeof(rtwdev->mac_id_map),
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) ...@@ -2459,12 +2482,16 @@ static int rtw89_debug_priv_stations_get(struct seq_file *m, void *v)
cam_info->bssid_cam_map); cam_info->bssid_cam_map);
seq_printf(m, "\tsec_cam: %*ph\n", (int)sizeof(cam_info->sec_cam_map), seq_printf(m, "\tsec_cam: %*ph\n", (int)sizeof(cam_info->sec_cam_map),
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_iterate_active_interfaces_atomic(rtwdev->hw,
IEEE80211_IFACE_ITER_NORMAL, rtw89_vif_ids_get_iter, m); IEEE80211_IFACE_ITER_NORMAL, rtw89_vif_ids_get_iter, m);
ieee80211_iterate_stations_atomic(rtwdev->hw, rtw89_sta_ids_get_iter, m); ieee80211_iterate_stations_atomic(rtwdev->hw, rtw89_sta_ids_get_iter, m);
mutex_unlock(&rtwdev->mutex);
return 0; return 0;
} }
......
...@@ -302,7 +302,7 @@ static void ser_reset_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) ...@@ -302,7 +302,7 @@ static void ser_reset_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
rtwvif->trigger = false; 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_vif *rtwvif = (struct rtw89_vif *)data;
struct rtw89_dev *rtwdev = rtwvif->rtwdev; struct rtw89_dev *rtwdev = rtwvif->rtwdev;
...@@ -312,15 +312,19 @@ static void ser_sta_deinit_addr_cam_iter(void *data, struct ieee80211_sta *sta) ...@@ -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); rtw89_cam_deinit_addr_cam(rtwdev, &rtwsta->addr_cam);
if (sta->tdls) if (sta->tdls)
rtw89_cam_deinit_bssid_cam(rtwdev, &rtwsta->bssid_cam); 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) static void ser_deinit_cam(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
{ {
ieee80211_iterate_stations_atomic(rtwdev->hw, ieee80211_iterate_stations_atomic(rtwdev->hw,
ser_sta_deinit_addr_cam_iter, ser_sta_deinit_cam_iter,
rtwvif); rtwvif);
rtw89_cam_deinit(rtwdev, 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) static void ser_reset_mac_binding(struct rtw89_dev *rtwdev)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册