]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
wifi: rtw89: chan: refine MCC re-plan flow when unassign chanctx
authorZong-Zhe Yang <kevin_yang@realtek.com>
Sat, 27 Jul 2024 08:06:44 +0000 (16:06 +0800)
committerPing-Ke Shih <pkshih@realtek.com>
Fri, 2 Aug 2024 01:33:14 +0000 (09:33 +0800)
Originally during unassign-chanctx, MCC (multi-channel concurrency) is
re-planed before set-channel if need. But, we might calculate MCC stuffs
based on old channel info. And, the following set-channel might be racing
with FW MCC state mechanism. So, we refine this flow. Now, if MCC re-plan
is needed here, it will be done after set-channel.

Besides, to be more rigorous, we now ensure entity isn't paused before we
deal with MCC things here.

Signed-off-by: Zong-Zhe Yang <kevin_yang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20240727080650.12195-2-pkshih@realtek.com
drivers/net/wireless/realtek/rtw89/chan.c

index 7f90d93dcdc0c0d69b098e05496ff60c5353706c..3789c98de36af319c74e3aecccb2b67864cbbe43 100644 (file)
@@ -2443,9 +2443,10 @@ void rtw89_chanctx_ops_unassign_vif(struct rtw89_dev *rtwdev,
 {
        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;
+       enum rtw89_entity_mode new;
+       int ret;
 
        rtwvif->sub_entity_idx = RTW89_SUB_ENTITY_0;
        rtwvif->chanctx_assigned = false;
@@ -2469,21 +2470,33 @@ void rtw89_chanctx_ops_unassign_vif(struct rtw89_dev *rtwdev,
        rtw89_swap_sub_entity(rtwdev, cfg->idx, roll);
 
 out:
-       rtw89_entity_calculate_weight(rtwdev, &w);
+       if (!hal->entity_pause) {
+               cur = rtw89_get_entity_mode(rtwdev);
+               switch (cur) {
+               case RTW89_ENTITY_MODE_MCC:
+                       rtw89_mcc_stop(rtwdev);
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       ret = rtw89_set_channel(rtwdev);
+       if (ret)
+               return;
 
-       cur = rtw89_get_entity_mode(rtwdev);
-       switch (cur) {
+       if (hal->entity_pause)
+               return;
+
+       new = rtw89_get_entity_mode(rtwdev);
+       switch (new) {
        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);
+               /* re-plan MCC for chanctx changes. */
+               ret = rtw89_mcc_start(rtwdev);
+               if (ret)
+                       rtw89_warn(rtwdev, "failed to start MCC: %d\n", ret);
                break;
        default:
                break;
        }
-
-       rtw89_set_channel(rtwdev);
 }