wifi: rtw89: mcc: update role bitmap when changed
authorZong-Zhe Yang <kevin_yang@realtek.com>
Fri, 8 Sep 2023 03:11:41 +0000 (11:11 +0800)
committerKalle Valo <kvalo@kernel.org>
Mon, 18 Sep 2023 14:28:45 +0000 (17:28 +0300)
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: Zong-Zhe Yang <kevin_yang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20230908031145.20931-5-pkshih@realtek.com
drivers/net/wireless/realtek/rtw89/chan.c
drivers/net/wireless/realtek/rtw89/chan.h
drivers/net/wireless/realtek/rtw89/core.c
drivers/net/wireless/realtek/rtw89/core.h

index 5f30c6d304b8c7213488a60e928a4863b5d77c6f..5ac6d60dfd73b872d663a8592bc3fcf90ad362e4 100644 (file)
@@ -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)
 {
index 9bdf3d1637bb41ce133a0356482a73350196c077..2fca703c99f0d4de780026f24c935f4e0f833427 100644 (file)
@@ -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,
index cb2f4e59187ba322a4c546067048470a54c5533b..68ffd753f4a0466a44d78c0e0ff0950e57a47fc2 100644 (file)
@@ -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;
index 43a81acdaacfee899888f93db334bfe8d76128d0..eb185b3ffa3cf6c3b52675a2bb1646122ff605f8 100644 (file)
@@ -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;