]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: ath12k: Fix pdev id sent to firmware for single phy devices
authorLingbo Kong <quic_lingbok@quicinc.com>
Fri, 21 Jun 2024 10:28:09 +0000 (15:58 +0530)
committerKalle Valo <quic_kvalo@quicinc.com>
Wed, 26 Jun 2024 15:40:55 +0000 (18:40 +0300)
Pdev id from mac phy capabilities will be sent as a part of
HTT/WMI command to firmware. This causes issue with single pdev
devices where firmware does not respond to the WMI/HTT request
sent from host.

For single pdev devices firmware expects pdev id as 1 for 5 GHz/6 GHz
phy and 2 for 2 GHz band. Add wrapper ath12k_mac_get_target_pdev_id()
to help fetch right pdev for single pdev devices.

Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-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: Lingbo Kong <quic_lingbok@quicinc.com>
Signed-off-by: Ramya Gnanasekar <quic_rgnanase@quicinc.com>
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
Link: https://patch.msgid.link/20240621102809.3984004-1-quic_rgnanase@quicinc.com
drivers/net/wireless/ath/ath12k/mac.c
drivers/net/wireless/ath/ath12k/mac.h

index 43801ff5bfd8488746299e460eb30aaeb44d0e39..7475dddca8c5289762bded10569778d80737a348 100644 (file)
@@ -673,6 +673,82 @@ static struct ath12k *ath12k_get_ar_by_vif(struct ieee80211_hw *hw,
        return NULL;
 }
 
+static struct ath12k_vif *ath12k_mac_get_vif_up(struct ath12k *ar)
+{
+       struct ath12k_vif *arvif;
+
+       lockdep_assert_held(&ar->conf_mutex);
+       list_for_each_entry(arvif, &ar->arvifs, list) {
+               if (arvif->is_up)
+                       return arvif;
+       }
+
+       return NULL;
+}
+
+static bool ath12k_mac_band_match(enum nl80211_band band1, enum WMI_HOST_WLAN_BAND band2)
+{
+       switch (band1) {
+       case NL80211_BAND_2GHZ:
+               if (band2 & WMI_HOST_WLAN_2G_CAP)
+                       return true;
+               break;
+       case NL80211_BAND_5GHZ:
+       case NL80211_BAND_6GHZ:
+               if (band2 & WMI_HOST_WLAN_5G_CAP)
+                       return true;
+               break;
+       default:
+               return false;
+       }
+
+       return false;
+}
+
+static u8 ath12k_mac_get_target_pdev_id_from_vif(struct ath12k_vif *arvif)
+{
+       struct ath12k *ar = arvif->ar;
+       struct ath12k_base *ab = ar->ab;
+       struct ieee80211_vif *vif = arvif->vif;
+       struct cfg80211_chan_def def;
+       enum nl80211_band band;
+       u8 pdev_id = ab->fw_pdev[0].pdev_id;
+       int i;
+
+       if (WARN_ON(ath12k_mac_vif_chan(vif, &def)))
+               return pdev_id;
+
+       band = def.chan->band;
+
+       for (i = 0; i < ab->fw_pdev_count; i++) {
+               if (ath12k_mac_band_match(band, ab->fw_pdev[i].supported_bands))
+                       return ab->fw_pdev[i].pdev_id;
+       }
+
+       return pdev_id;
+}
+
+u8 ath12k_mac_get_target_pdev_id(struct ath12k *ar)
+{
+       struct ath12k_vif *arvif;
+       struct ath12k_base *ab = ar->ab;
+
+       if (!ab->hw_params->single_pdev_only)
+               return ar->pdev->pdev_id;
+
+       arvif = ath12k_mac_get_vif_up(ar);
+
+       /* fw_pdev array has pdev ids derived from phy capability
+        * service ready event (pdev_and_hw_link_ids).
+        * If no vif is active, return default first index.
+        */
+       if (!arvif)
+               return ar->ab->fw_pdev[0].pdev_id;
+
+       /* If active vif is found, return the pdev id matching chandef band */
+       return ath12k_mac_get_target_pdev_id_from_vif(arvif);
+}
+
 static void ath12k_pdev_caps_update(struct ath12k *ar)
 {
        struct ath12k_base *ab = ar->ab;
index 2c6cb144827af91b86934870c11c5b4ad114dec6..5efbb6822628f7c957e2e01663ebf93d6dafc62a 100644 (file)
@@ -85,5 +85,6 @@ void ath12k_mac_handle_beacon_miss(struct ath12k *ar, u32 vdev_id);
 int ath12k_mac_vif_set_keepalive(struct ath12k_vif *arvif,
                                 enum wmi_sta_keepalive_method method,
                                 u32 interval);
+u8 ath12k_mac_get_target_pdev_id(struct ath12k *ar);
 
 #endif