]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
wifi: ath12k: Add support for reading variant from ACPI to download board data file
authorLingbo Kong <quic_lingbok@quicinc.com>
Mon, 13 Jan 2025 07:48:10 +0000 (15:48 +0800)
committerJeff Johnson <jeff.johnson@oss.qualcomm.com>
Mon, 3 Feb 2025 22:43:29 +0000 (14:43 -0800)
Currently, ath12k does not support reading variant from ACPI board data
filename extension for downloading board data file.

To address this issue, obtain the string of the ACPI data filename
extension and use it as part of the string to search for the board data
file from board-2.bin.

This patch will not affect QCN9274, because only WCN7850 supports ACPI.

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>
Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
Link: https://patch.msgid.link/20250113074810.29729-5-quic_lingbok@quicinc.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
drivers/net/wireless/ath/ath12k/acpi.c
drivers/net/wireless/ath/ath12k/acpi.h
drivers/net/wireless/ath/ath12k/core.h
drivers/net/wireless/ath/ath12k/qmi.c

index 231b4eb92a5df683061814f67c20941d5c43dbe8..d81367ce6929433897db7dd5c963c27329ccbb1c 100644 (file)
@@ -37,6 +37,24 @@ static int ath12k_acpi_dsm_get_data(struct ath12k_base *ab, int func)
                        ab->acpi.bit_flag = obj->integer.value;
                        break;
                }
+       } else if (obj->type == ACPI_TYPE_STRING) {
+               switch (func) {
+               case ATH12K_ACPI_DSM_FUNC_BDF_EXT:
+                       if (obj->string.length <= ATH12K_ACPI_BDF_ANCHOR_STRING_LEN ||
+                           obj->string.length > ATH12K_ACPI_BDF_MAX_LEN ||
+                           memcmp(obj->string.pointer, ATH12K_ACPI_BDF_ANCHOR_STRING,
+                                  ATH12K_ACPI_BDF_ANCHOR_STRING_LEN)) {
+                               ath12k_warn(ab, "invalid ACPI DSM BDF size: %d\n",
+                                           obj->string.length);
+                               ret = -EINVAL;
+                               goto out;
+                       }
+
+                       memcpy(ab->acpi.bdf_string, obj->string.pointer,
+                              obj->buffer.length);
+
+                       break;
+               }
        } else if (obj->type == ACPI_TYPE_BUFFER) {
                switch (func) {
                case ATH12K_ACPI_DSM_FUNC_SUPPORT_FUNCS:
@@ -341,6 +359,8 @@ int ath12k_acpi_start(struct ath12k_base *ab)
        ab->acpi.acpi_bios_sar_enable = false;
        ab->acpi.acpi_cca_enable = false;
        ab->acpi.acpi_band_edge_enable = false;
+       ab->acpi.acpi_enable_bdf = false;
+       ab->acpi.bdf_string[0] = '\0';
 
        if (!ab->hw_params->acpi_guid)
                /* not supported with this hardware */
@@ -368,6 +388,16 @@ int ath12k_acpi_start(struct ath12k_base *ab)
                        ab->acpi.acpi_disable_rfkill = true;
        }
 
+       if (ATH12K_ACPI_FUNC_BIT_VALID(ab->acpi, ATH12K_ACPI_FUNC_BIT_BDF_EXT)) {
+               ret = ath12k_acpi_dsm_get_data(ab, ATH12K_ACPI_DSM_FUNC_BDF_EXT);
+               if (ret || ab->acpi.bdf_string[0] == '\0') {
+                       ath12k_warn(ab, "failed to get ACPI BDF EXT: %d\n", ret);
+                       return ret;
+               }
+
+               ab->acpi.acpi_enable_bdf = true;
+       }
+
        if (ATH12K_ACPI_FUNC_BIT_VALID(ab->acpi, ATH12K_ACPI_FUNC_BIT_TAS_CFG)) {
                ret = ath12k_acpi_dsm_get_data(ab, ATH12K_ACPI_DSM_FUNC_TAS_CFG);
                if (ret) {
@@ -452,6 +482,21 @@ int ath12k_acpi_start(struct ath12k_base *ab)
        return 0;
 }
 
+int ath12k_acpi_check_bdf_variant_name(struct ath12k_base *ab)
+{
+       size_t max_len = sizeof(ab->qmi.target.bdf_ext);
+
+       if (!ab->acpi.acpi_enable_bdf)
+               return -ENODATA;
+
+       if (strscpy(ab->qmi.target.bdf_ext, ab->acpi.bdf_string + 4, max_len) < 0)
+               ath12k_dbg(ab, ATH12K_DBG_BOOT,
+                          "acpi bdf variant longer than the buffer (variant: %s)\n",
+                          ab->acpi.bdf_string);
+
+       return 0;
+}
+
 void ath12k_acpi_stop(struct ath12k_base *ab)
 {
        if (!ab->acpi.started)
index 19a1a1118e82bd733262c4718ac868dd55204a19..3a26fea6af1a9f999feac536bbf9fbab4f24d1f9 100644 (file)
@@ -10,6 +10,7 @@
 
 #define ATH12K_ACPI_DSM_FUNC_SUPPORT_FUNCS     0
 #define ATH12K_ACPI_DSM_FUNC_DISABLE_FLAG      2
+#define ATH12K_ACPI_DSM_FUNC_BDF_EXT           3
 #define ATH12K_ACPI_DSM_FUNC_BIOS_SAR          4
 #define ATH12K_ACPI_DSM_FUNC_GEO_OFFSET                5
 #define ATH12K_ACPI_DSM_FUNC_INDEX_CCA         6
@@ -18,6 +19,7 @@
 #define ATH12K_ACPI_DSM_FUNC_INDEX_BAND_EDGE           10
 
 #define ATH12K_ACPI_FUNC_BIT_DISABLE_FLAG              BIT(1)
+#define ATH12K_ACPI_FUNC_BIT_BDF_EXT                   BIT(2)
 #define ATH12K_ACPI_FUNC_BIT_BIOS_SAR                  BIT(3)
 #define ATH12K_ACPI_FUNC_BIT_GEO_OFFSET                        BIT(4)
 #define ATH12K_ACPI_FUNC_BIT_CCA                       BIT(5)
 #define ATH12K_ACPI_DSM_DISABLE_11BE_BIT       BIT(0)
 #define ATH12K_ACPI_DSM_DISABLE_RFKILL_BIT     BIT(2)
 
+#define ATH12K_ACPI_BDF_ANCHOR_STRING_LEN      3
+#define ATH12K_ACPI_BDF_ANCHOR_STRING          "BDF"
+#define ATH12K_ACPI_BDF_MAX_LEN                        100
+
 #define ATH12K_ACPI_DSM_GEO_OFFSET_DATA_SIZE (ATH12K_ACPI_GEO_OFFSET_DATA_OFFSET + \
                                              ATH12K_ACPI_BIOS_SAR_GEO_OFFSET_LEN)
 #define ATH12K_ACPI_DSM_BIOS_SAR_DATA_SIZE (ATH12K_ACPI_POWER_LIMIT_DATA_OFFSET + \
@@ -71,6 +77,7 @@ void ath12k_acpi_stop(struct ath12k_base *ab);
 bool ath12k_acpi_get_disable_rfkill(struct ath12k_base *ab);
 bool ath12k_acpi_get_disable_11be(struct ath12k_base *ab);
 void ath12k_acpi_set_dsm_func(struct ath12k_base *ab);
+int ath12k_acpi_check_bdf_variant_name(struct ath12k_base *ab);
 
 #else
 
@@ -97,6 +104,11 @@ static inline void ath12k_acpi_set_dsm_func(struct ath12k_base *ab)
 {
 }
 
+static inline int ath12k_acpi_check_bdf_variant_name(struct ath12k_base *ab)
+{
+       return 0;
+}
+
 #endif /* CONFIG_ACPI */
 
 #endif /* ATH12K_ACPI_H */
index 79ffaa62bd2fd2b1736b081b460dbe0b53bbb0b2..c34a144048650ff27235c2c681f0c9af4c0464be 100644 (file)
@@ -1062,7 +1062,9 @@ struct ath12k_base {
                bool acpi_disable_rfkill;
                bool acpi_cca_enable;
                bool acpi_band_edge_enable;
+               bool acpi_enable_bdf;
                u32 bit_flag;
+               char bdf_string[ATH12K_ACPI_BDF_MAX_LEN];
                u8 tas_cfg[ATH12K_ACPI_DSM_TAS_CFG_SIZE];
                u8 tas_sar_power_table[ATH12K_ACPI_DSM_TAS_DATA_SIZE];
                u8 bios_sar_data[ATH12K_ACPI_DSM_BIOS_SAR_DATA_SIZE];
index c43f773c66ba465b0f1d4e880f83d539facf2529..ef537c6bf0daae4e78102cbc0e84e84806d6d165 100644 (file)
@@ -2745,6 +2745,10 @@ int ath12k_qmi_request_target_cap(struct ath12k_base *ab)
                /* ACPI is optional so continue in case of an error */
                ath12k_dbg(ab, ATH12K_DBG_BOOT, "acpi failed: %d\n", r);
 
+       r = ath12k_acpi_check_bdf_variant_name(ab);
+       if (r)
+               ath12k_dbg(ab, ATH12K_DBG_BOOT, "ACPI bdf variant name not set.\n");
+
 out:
        return ret;
 }