]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
wifi: ath12k: Enable MLO setup ready and teardown commands for single split-phy device
authorAaradhana Sahu <quic_aarasahu@quicinc.com>
Fri, 7 Feb 2025 05:03:25 +0000 (10:33 +0530)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 29 May 2025 09:13:30 +0000 (11:13 +0200)
[ Upstream commit 5cec2d86c7f4242fb30a696d8e6fd48109bf3e8f ]

When multi-link operation(MLO) is enabled through follow-up patches in
the single split-phy device, the firmware expects hardware links
(hw_links) information from the driver.

If driver does not send WMI multi-link setup and ready command to the
firmware during MLO setup for single split-phy device, the firmware will
be unaware of the hw_links component of the multi-link operation. This may
lead to firmware assert during multi-link association.

Therefore, enable WMI setup, ready and teardown commands for single
split-phy PCI device.

Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3

Signed-off-by: Aaradhana Sahu <quic_aarasahu@quicinc.com>
Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
Link: https://patch.msgid.link/20250207050327.360987-2-quic_aarasahu@quicinc.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/wireless/ath/ath12k/core.c
drivers/net/wireless/ath/ath12k/core.h
drivers/net/wireless/ath/ath12k/mac.c

index 212cd935e60a054fa58f472ff8e87414a8e3118f..ffd173ff7b08c495084bb22361aa7ff26c22a256 100644 (file)
@@ -887,10 +887,41 @@ static void ath12k_core_hw_group_stop(struct ath12k_hw_group *ag)
        ath12k_mac_destroy(ag);
 }
 
+u8 ath12k_get_num_partner_link(struct ath12k *ar)
+{
+       struct ath12k_base *partner_ab, *ab = ar->ab;
+       struct ath12k_hw_group *ag = ab->ag;
+       struct ath12k_pdev *pdev;
+       u8 num_link = 0;
+       int i, j;
+
+       lockdep_assert_held(&ag->mutex);
+
+       for (i = 0; i < ag->num_devices; i++) {
+               partner_ab = ag->ab[i];
+
+               for (j = 0; j < partner_ab->num_radios; j++) {
+                       pdev = &partner_ab->pdevs[j];
+
+                       /* Avoid the self link */
+                       if (ar == pdev->ar)
+                               continue;
+
+                       num_link++;
+               }
+       }
+
+       return num_link;
+}
+
 static int __ath12k_mac_mlo_ready(struct ath12k *ar)
 {
+       u8 num_link = ath12k_get_num_partner_link(ar);
        int ret;
 
+       if (num_link == 0)
+               return 0;
+
        ret = ath12k_wmi_mlo_ready(ar);
        if (ret) {
                ath12k_err(ar->ab, "MLO ready failed for pdev %d: %d\n",
@@ -932,7 +963,7 @@ static int ath12k_core_mlo_setup(struct ath12k_hw_group *ag)
 {
        int ret, i;
 
-       if (!ag->mlo_capable || ag->num_devices == 1)
+       if (!ag->mlo_capable)
                return 0;
 
        ret = ath12k_mac_mlo_setup(ag);
index ee595794a7aee83a7695fb57d6b8e2e74eabf3aa..6325ac493f82c2d31c55775c52753b1abb279e1d 100644 (file)
@@ -1084,6 +1084,7 @@ int ath12k_core_resume(struct ath12k_base *ab);
 int ath12k_core_suspend(struct ath12k_base *ab);
 int ath12k_core_suspend_late(struct ath12k_base *ab);
 void ath12k_core_hw_group_unassign(struct ath12k_base *ab);
+u8 ath12k_get_num_partner_link(struct ath12k *ar);
 
 const struct firmware *ath12k_core_firmware_request(struct ath12k_base *ab,
                                                    const char *filename);
index 9c3e66dbe0c3be7e2d428af297a3b26c4383ea02..9123ffab55b52170ffb4a6f1b8b45325436a9fc2 100644 (file)
@@ -11140,6 +11140,9 @@ static int __ath12k_mac_mlo_setup(struct ath12k *ar)
                }
        }
 
+       if (num_link == 0)
+               return 0;
+
        mlo.group_id = cpu_to_le32(ag->id);
        mlo.partner_link_id = partner_link_id;
        mlo.num_partner_links = num_link;
@@ -11169,10 +11172,16 @@ static int __ath12k_mac_mlo_teardown(struct ath12k *ar)
 {
        struct ath12k_base *ab = ar->ab;
        int ret;
+       u8 num_link;
 
        if (test_bit(ATH12K_FLAG_RECOVERY, &ab->dev_flags))
                return 0;
 
+       num_link = ath12k_get_num_partner_link(ar);
+
+       if (num_link == 0)
+               return 0;
+
        ret = ath12k_wmi_mlo_teardown(ar);
        if (ret) {
                ath12k_warn(ab, "failed to send MLO teardown WMI command for pdev %d: %d\n",