Commit 31e415e3 authored by Zong-Zhe Yang's avatar Zong-Zhe Yang Committed by Kalle Valo

wifi: rtw89: mcc: update role bitmap when changed

Each MCC (multi-channel concurrency) role maintains a bitmap of mac IDs.
The bitmap is supposed to contain the two points below.
* mac ID of itself
* mac ID(s) of STA(s) connecting to it
Under STA+GC mode, the bitmaps of both roles should not change. However,
under STA+GO mode, the bitmap of GO may change due to P2P clients which
connect/disconnect to/from it.

FW controls (TDMA-based) MCC things via mac IDs in bitmap of each role.
For example, mac IDs are required by FW when it wants to pause role1's
TX in role0 slot.

So, to sync between driver and FW, we update the new mac ID bitmap of GO
to FW once it's changed.
Signed-off-by: default avatarZong-Zhe Yang <kevin_yang@realtek.com>
Signed-off-by: default avatarPing-Ke Shih <pkshih@realtek.com>
Signed-off-by: default avatarKalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20230908031145.20931-5-pkshih@realtek.com
parent 6e9d6f82
......@@ -191,6 +191,7 @@ void rtw89_entity_init(struct rtw89_dev *rtwdev)
struct rtw89_hal *hal = &rtwdev->hal;
bitmap_zero(hal->entity_map, NUM_OF_RTW89_SUB_ENTITY);
bitmap_zero(hal->changes, NUM_OF_RTW89_CHANCTX_CHANGES);
atomic_set(&hal->roc_entity_idx, RTW89_SUB_ENTITY_IDLE);
rtw89_config_default_chandef(rtwdev);
}
......@@ -1436,15 +1437,66 @@ static void rtw89_mcc_stop(struct rtw89_dev *rtwdev)
rtw89_chanctx_notify(rtwdev, RTW89_CHANCTX_STATE_MCC_STOP);
}
static int rtw89_mcc_upd_map_iterator(struct rtw89_dev *rtwdev,
struct rtw89_mcc_role *mcc_role,
unsigned int ordered_idx,
void *data)
{
struct rtw89_mcc_info *mcc = &rtwdev->mcc;
struct rtw89_mcc_role upd = {
.rtwvif = mcc_role->rtwvif,
};
int ret;
if (!mcc_role->is_go)
return 0;
rtw89_mcc_fill_role_macid_bitmap(rtwdev, &upd);
if (memcmp(mcc_role->macid_bitmap, upd.macid_bitmap,
sizeof(mcc_role->macid_bitmap)) == 0)
return 0;
ret = rtw89_fw_h2c_mcc_macid_bitmap(rtwdev, mcc->group,
upd.rtwvif->mac_id,
upd.macid_bitmap);
if (ret) {
rtw89_debug(rtwdev, RTW89_DBG_CHAN,
"MCC h2c failed to update macid bitmap: %d\n", ret);
return ret;
}
memcpy(mcc_role->macid_bitmap, upd.macid_bitmap,
sizeof(mcc_role->macid_bitmap));
return 0;
}
static void rtw89_mcc_update_macid_bitmap(struct rtw89_dev *rtwdev)
{
struct rtw89_mcc_info *mcc = &rtwdev->mcc;
if (mcc->mode != RTW89_MCC_MODE_GO_STA)
return;
rtw89_iterate_mcc_roles(rtwdev, rtw89_mcc_upd_map_iterator, NULL);
}
void rtw89_chanctx_work(struct work_struct *work)
{
struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev,
chanctx_work.work);
struct rtw89_hal *hal = &rtwdev->hal;
enum rtw89_entity_mode mode;
u32 changed = 0;
int ret;
int i;
mutex_lock(&rtwdev->mutex);
for (i = 0; i < NUM_OF_RTW89_CHANCTX_CHANGES; i++) {
if (test_and_clear_bit(i, hal->changes))
changed |= BIT(i);
}
mode = rtw89_get_entity_mode(rtwdev);
switch (mode) {
case RTW89_ENTITY_MODE_MCC_PREPARE:
......@@ -1455,6 +1507,10 @@ void rtw89_chanctx_work(struct work_struct *work)
if (ret)
rtw89_warn(rtwdev, "failed to start MCC: %d\n", ret);
break;
case RTW89_ENTITY_MODE_MCC:
if (changed & BIT(RTW89_CHANCTX_REMOTE_STA_CHANGE))
rtw89_mcc_update_macid_bitmap(rtwdev);
break;
default:
break;
}
......@@ -1462,8 +1518,10 @@ void rtw89_chanctx_work(struct work_struct *work)
mutex_unlock(&rtwdev->mutex);
}
void rtw89_queue_chanctx_work(struct rtw89_dev *rtwdev)
void rtw89_queue_chanctx_change(struct rtw89_dev *rtwdev,
enum rtw89_chanctx_changes change)
{
struct rtw89_hal *hal = &rtwdev->hal;
enum rtw89_entity_mode mode;
u32 delay;
......@@ -1474,6 +1532,15 @@ void rtw89_queue_chanctx_work(struct rtw89_dev *rtwdev)
case RTW89_ENTITY_MODE_MCC_PREPARE:
delay = ieee80211_tu_to_usec(RTW89_CHANCTX_TIME_MCC_PREPARE);
break;
case RTW89_ENTITY_MODE_MCC:
delay = ieee80211_tu_to_usec(RTW89_CHANCTX_TIME_MCC);
break;
}
if (change != RTW89_CHANCTX_CHANGE_DFLT) {
rtw89_debug(rtwdev, RTW89_DBG_CHAN, "set chanctx change %d\n",
change);
set_bit(change, hal->changes);
}
rtw89_debug(rtwdev, RTW89_DBG_CHAN,
......@@ -1483,6 +1550,11 @@ void rtw89_queue_chanctx_work(struct rtw89_dev *rtwdev)
usecs_to_jiffies(delay));
}
void rtw89_queue_chanctx_work(struct rtw89_dev *rtwdev)
{
rtw89_queue_chanctx_change(rtwdev, RTW89_CHANCTX_CHANGE_DFLT);
}
int rtw89_chanctx_ops_add(struct rtw89_dev *rtwdev,
struct ieee80211_chanctx_conf *ctx)
{
......
......@@ -9,6 +9,7 @@
/* The dwell time in TU before doing rtw89_chanctx_work(). */
#define RTW89_CHANCTX_TIME_MCC_PREPARE 100
#define RTW89_CHANCTX_TIME_MCC 100
/* various MCC setting time in TU */
#define RTW89_MCC_LONG_TRIGGER_TIME 300
......@@ -75,6 +76,8 @@ void rtw89_entity_init(struct rtw89_dev *rtwdev);
enum rtw89_entity_mode rtw89_entity_recalc(struct rtw89_dev *rtwdev);
void rtw89_chanctx_work(struct work_struct *work);
void rtw89_queue_chanctx_work(struct rtw89_dev *rtwdev);
void rtw89_queue_chanctx_change(struct rtw89_dev *rtwdev,
enum rtw89_chanctx_changes change);
int rtw89_chanctx_ops_add(struct rtw89_dev *rtwdev,
struct ieee80211_chanctx_conf *ctx);
void rtw89_chanctx_ops_remove(struct rtw89_dev *rtwdev,
......
......@@ -2934,6 +2934,8 @@ int rtw89_core_sta_add(struct rtw89_dev *rtwdev,
rtw89_warn(rtwdev, "failed to send h2c role info\n");
return ret;
}
rtw89_queue_chanctx_change(rtwdev, RTW89_CHANCTX_REMOTE_STA_CHANGE);
}
return 0;
......@@ -3099,6 +3101,8 @@ int rtw89_core_sta_remove(struct rtw89_dev *rtwdev,
rtw89_warn(rtwdev, "failed to send h2c role info\n");
return ret;
}
rtw89_queue_chanctx_change(rtwdev, RTW89_CHANCTX_REMOTE_STA_CHANGE);
}
return 0;
......
......@@ -3787,6 +3787,13 @@ struct rtw89_chanctx_cfg {
enum rtw89_sub_entity_idx idx;
};
enum rtw89_chanctx_changes {
RTW89_CHANCTX_REMOTE_STA_CHANGE,
NUM_OF_RTW89_CHANCTX_CHANGES,
RTW89_CHANCTX_CHANGE_DFLT = NUM_OF_RTW89_CHANCTX_CHANGES,
};
enum rtw89_entity_mode {
RTW89_ENTITY_MODE_SCC,
RTW89_ENTITY_MODE_MCC_PREPARE,
......@@ -3818,6 +3825,7 @@ struct rtw89_hal {
bool support_igi;
atomic_t roc_entity_idx;
DECLARE_BITMAP(changes, NUM_OF_RTW89_CHANCTX_CHANGES);
DECLARE_BITMAP(entity_map, NUM_OF_RTW89_SUB_ENTITY);
struct rtw89_sub_entity sub[NUM_OF_RTW89_SUB_ENTITY];
struct cfg80211_chan_def roc_chandef;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment