]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: rtw89: chan: re-calculate MLO DBCC mode during setting channel
authorZong-Zhe Yang <kevin_yang@realtek.com>
Mon, 5 May 2025 07:24:33 +0000 (15:24 +0800)
committerPing-Ke Shih <pkshih@realtek.com>
Sat, 10 May 2025 00:53:51 +0000 (08:53 +0800)
Wi-Fi 7 chips have dual HW bands. After impending MLO support, they
can work with HW-[0] / HW-[1] / HW-[0,1] according to active links.
So, during setting channel, also re-calculate the MLO DBCC mode flag.
Then, leaf chip functions of setting channel can configure with HWs
based on current case.

Besides, tweak the initial and idle MLO DBCC mode of Wi-Fi 7 chips to
MLO_1_PLUS_1_1RF to work with dual HW bands. And, after disconnecting,
due to no active links, MLO DBCC mode will re-calculate to idle case,
i.e. MLO_1_PLUS_1_1RF.

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

index 4fec61ed3454c1bcf14f666b8dc969dfe1091f4f..871befa63889eaaeaa3e3b749afd615182e2bf1e 100644 (file)
@@ -359,12 +359,41 @@ dflt:
 }
 EXPORT_SYMBOL(__rtw89_mgnt_chan_get);
 
+static enum rtw89_mlo_dbcc_mode
+rtw89_entity_sel_mlo_dbcc_mode(struct rtw89_dev *rtwdev, u8 active_hws)
+{
+       if (rtwdev->chip->chip_gen != RTW89_CHIP_BE)
+               return MLO_DBCC_NOT_SUPPORT;
+
+       switch (active_hws) {
+       case BIT(0):
+               return MLO_2_PLUS_0_1RF;
+       case BIT(1):
+               return MLO_0_PLUS_2_1RF;
+       case BIT(0) | BIT(1):
+       default:
+               return MLO_1_PLUS_1_1RF;
+       }
+}
+
+static
+void rtw89_entity_recalc_mlo_dbcc_mode(struct rtw89_dev *rtwdev, u8 active_hws)
+{
+       enum rtw89_mlo_dbcc_mode mode;
+
+       mode = rtw89_entity_sel_mlo_dbcc_mode(rtwdev, active_hws);
+       rtwdev->mlo_dbcc_mode = mode;
+
+       rtw89_debug(rtwdev, RTW89_DBG_STATE, "recalc mlo dbcc mode to %d\n", mode);
+}
+
 static void rtw89_entity_recalc_mgnt_roles(struct rtw89_dev *rtwdev)
 {
        struct rtw89_hal *hal = &rtwdev->hal;
        struct rtw89_entity_mgnt *mgnt = &hal->entity_mgnt;
        struct rtw89_vif_link *link;
        struct rtw89_vif *role;
+       u8 active_hws = 0;
        u8 pos = 0;
        int i, j;
 
@@ -413,10 +442,13 @@ fill:
                                continue;
 
                        mgnt->chanctx_tbl[pos][i] = link->chanctx_idx;
+                       active_hws |= BIT(i);
                }
 
                mgnt->active_roles[pos++] = role;
        }
+
+       rtw89_entity_recalc_mlo_dbcc_mode(rtwdev, active_hws);
 }
 
 enum rtw89_entity_mode rtw89_entity_recalc(struct rtw89_dev *rtwdev)
index c5bb3452946e12074e29867a39a7f218c0b8341d..1546e3d8e2e076cb0d55f5d92e633b6c09026166 100644 (file)
@@ -4966,7 +4966,7 @@ int rtw89_core_init(struct rtw89_dev *rtwdev)
        if (rtwdev->chip->chip_gen == RTW89_CHIP_BE) {
                rtwdev->dbcc_en = true;
                rtwdev->mac.qta_mode = RTW89_QTA_DBCC;
-               rtwdev->mlo_dbcc_mode = MLO_2_PLUS_0_1RF;
+               rtwdev->mlo_dbcc_mode = MLO_1_PLUS_1_1RF;
        }
 
        rtwdev->bbs[RTW89_PHY_0].phy_idx = RTW89_PHY_0;