wifi: rtw89: chan: move handling from add/remove to assign/unassign for MLO
authorZong-Zhe Yang <kevin_yang@realtek.com>
Tue, 6 Feb 2024 03:06:23 +0000 (11:06 +0800)
committerKalle Valo <kvalo@kernel.org>
Mon, 12 Feb 2024 15:37:09 +0000 (17:37 +0200)
After MLO, we will need to consider not only active chanctx but also active
interfaces (roles) to decide entity things. So in advance, we move handling
from chanctx_ops::add/remove to chanctx_ops::assign_vif/unassign_vif. Then,
we can recalculate and aware active interfaces' changes.

For now, behavior should not be really different, since active chanctx and
active interface are one-to-one mapping before MLO.

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://msgid.link/20240206030624.23382-6-pkshih@realtek.com
drivers/net/wireless/realtek/rtw89/chan.c
drivers/net/wireless/realtek/rtw89/core.c
drivers/net/wireless/realtek/rtw89/core.h

index 57fabc05dab9dec968ec3d084419d08874657302..71fe0d3ab3b0cf5f5d66d1761233f34c9a837851 100644 (file)
@@ -1979,7 +1979,6 @@ int rtw89_chanctx_ops_add(struct rtw89_dev *rtwdev,
                return -ENOENT;
 
        rtw89_config_entity_chandef(rtwdev, idx, &ctx->def);
-       rtw89_set_channel(rtwdev);
        cfg->idx = idx;
        hal->sub[idx].cfg = cfg;
        return 0;
@@ -1990,37 +1989,8 @@ void rtw89_chanctx_ops_remove(struct rtw89_dev *rtwdev,
 {
        struct rtw89_hal *hal = &rtwdev->hal;
        struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv;
-       enum rtw89_entity_mode mode;
-       u8 drop, roll;
-
-       drop = cfg->idx;
-       if (drop != RTW89_SUB_ENTITY_0)
-               goto out;
-
-       roll = find_next_bit(hal->entity_map, NUM_OF_RTW89_SUB_ENTITY, drop + 1);
-
-       /* Follow rtw89_config_default_chandef() when rtw89_entity_recalc(). */
-       if (roll == NUM_OF_RTW89_SUB_ENTITY)
-               goto out;
-
-       /* RTW89_SUB_ENTITY_0 is going to release, and another exists.
-        * Make another roll down to RTW89_SUB_ENTITY_0 to replace.
-        */
-       rtw89_swap_sub_entity(rtwdev, RTW89_SUB_ENTITY_0, roll);
-       drop = roll;
 
-out:
-       mode = rtw89_get_entity_mode(rtwdev);
-       switch (mode) {
-       case RTW89_ENTITY_MODE_MCC:
-               rtw89_mcc_stop(rtwdev);
-               break;
-       default:
-               break;
-       }
-
-       clear_bit(drop, hal->entity_map);
-       rtw89_set_channel(rtwdev);
+       clear_bit(cfg->idx, hal->entity_map);
 }
 
 void rtw89_chanctx_ops_change(struct rtw89_dev *rtwdev,
@@ -2045,7 +2015,8 @@ int rtw89_chanctx_ops_assign_vif(struct rtw89_dev *rtwdev,
        rtwvif->sub_entity_idx = cfg->idx;
        rtwvif->chanctx_assigned = true;
        cfg->ref_count++;
-       return 0;
+
+       return rtw89_set_channel(rtwdev);
 }
 
 void rtw89_chanctx_ops_unassign_vif(struct rtw89_dev *rtwdev,
@@ -2053,8 +2024,48 @@ void rtw89_chanctx_ops_unassign_vif(struct rtw89_dev *rtwdev,
                                    struct ieee80211_chanctx_conf *ctx)
 {
        struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv;
+       struct rtw89_hal *hal = &rtwdev->hal;
+       struct rtw89_entity_weight w = {};
+       enum rtw89_sub_entity_idx roll;
+       enum rtw89_entity_mode cur;
 
        rtwvif->sub_entity_idx = RTW89_SUB_ENTITY_0;
        rtwvif->chanctx_assigned = false;
        cfg->ref_count--;
+
+       if (cfg->ref_count != 0)
+               goto out;
+
+       if (cfg->idx != RTW89_SUB_ENTITY_0)
+               goto out;
+
+       roll = find_next_bit(hal->entity_map, NUM_OF_RTW89_SUB_ENTITY,
+                            cfg->idx + 1);
+       /* Follow rtw89_config_default_chandef() when rtw89_entity_recalc(). */
+       if (roll == NUM_OF_RTW89_SUB_ENTITY)
+               goto out;
+
+       /* RTW89_SUB_ENTITY_0 is going to release, and another exists.
+        * Make another roll down to RTW89_SUB_ENTITY_0 to replace.
+        */
+       rtw89_swap_sub_entity(rtwdev, cfg->idx, roll);
+
+out:
+       rtw89_entity_calculate_weight(rtwdev, &w);
+
+       cur = rtw89_get_entity_mode(rtwdev);
+       switch (cur) {
+       case RTW89_ENTITY_MODE_MCC:
+               /* If still multi-roles, re-plan MCC for chanctx changes.
+                * Otherwise, just stop MCC.
+                */
+               rtw89_mcc_stop(rtwdev);
+               if (w.active_roles == NUM_OF_RTW89_MCC_ROLES)
+                       rtw89_mcc_start(rtwdev);
+               break;
+       default:
+               break;
+       }
+
+       rtw89_set_channel(rtwdev);
 }
index 95ace26a8f66d3d17116f4a2f1169966345eb32f..6441d99cd6c0fa5e34c149c7f6c082c016773dcc 100644 (file)
@@ -372,7 +372,7 @@ void rtw89_core_set_chip_txpwr(struct rtw89_dev *rtwdev)
        chip->ops->set_txpwr(rtwdev, chan, phy_idx);
 }
 
-void rtw89_set_channel(struct rtw89_dev *rtwdev)
+int rtw89_set_channel(struct rtw89_dev *rtwdev)
 {
        struct rtw89_hal *hal = &rtwdev->hal;
        const struct rtw89_chip_info *chip = rtwdev->chip;
@@ -399,7 +399,7 @@ void rtw89_set_channel(struct rtw89_dev *rtwdev)
                break;
        default:
                WARN(1, "Invalid ent mode: %d\n", mode);
-               return;
+               return -EINVAL;
        }
 
        roc_idx = atomic_read(&hal->roc_entity_idx);
@@ -426,6 +426,7 @@ void rtw89_set_channel(struct rtw89_dev *rtwdev)
        }
 
        rtw89_set_entity_state(rtwdev, true);
+       return 0;
 }
 
 void rtw89_get_channel(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
index d98dcf12bef77b39a2140adef76f44d561fa6c19..462c4b03c76ba1fac4f609849efd6d37c6fe7f9e 100644 (file)
@@ -6045,7 +6045,7 @@ void rtw89_core_set_chip_txpwr(struct rtw89_dev *rtwdev);
 void rtw89_get_default_chandef(struct cfg80211_chan_def *chandef);
 void rtw89_get_channel_params(const struct cfg80211_chan_def *chandef,
                              struct rtw89_chan *chan);
-void rtw89_set_channel(struct rtw89_dev *rtwdev);
+int rtw89_set_channel(struct rtw89_dev *rtwdev);
 void rtw89_get_channel(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
                       struct rtw89_chan *chan);
 u8 rtw89_core_acquire_bit_map(unsigned long *addr, unsigned long size);