wifi: iwlwifi: prepare for reading PPAG table from UEFI
authorMiri Korenblit <miriam.rachel.korenblit@intel.com>
Wed, 31 Jan 2024 08:24:41 +0000 (10:24 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Fri, 2 Feb 2024 13:15:15 +0000 (14:15 +0100)
As PPAG table is going to be read from UEFI, there are some
cleanups required:
Move functions/definitions that are common to both UEFI and ACPI to
regulatory.h/c.
In addition, rename the functions/macros names so it will be clear which
one is ACPI specific, and which is common for ACPI and UEFI.

Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Reviewed-by: Gregory Greenman <gregory.greenman@intel.com>
Link: https://msgid.link/20240131091413.25623670b422.I8132af7517e4faf0ea8cbeb2efe9651edd319b98@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/intel/iwlwifi/fw/acpi.c
drivers/net/wireless/intel/iwlwifi/fw/acpi.h
drivers/net/wireless/intel/iwlwifi/fw/regulatory.c
drivers/net/wireless/intel/iwlwifi/fw/regulatory.h
drivers/net/wireless/intel/iwlwifi/mvm/fw.c

index d2689d93da0c9fefc2dc7d511e071f35544ab03f..9b0ecfc087ab43b26d3578c786bf67b887c887f2 100644 (file)
@@ -4,7 +4,6 @@
  * Copyright (C) 2019-2023 Intel Corporation
  */
 #include <linux/uuid.h>
-#include <linux/dmi.h>
 #include "iwl-drv.h"
 #include "iwl-debug.h"
 #include "acpi.h"
@@ -20,63 +19,6 @@ const guid_t iwl_rfi_guid = GUID_INIT(0x7266172C, 0x220B, 0x4B29,
                                      0xDD, 0x26, 0xB5, 0xFD);
 IWL_EXPORT_SYMBOL(iwl_rfi_guid);
 
-static const struct dmi_system_id dmi_ppag_approved_list[] = {
-       { .ident = "HP",
-         .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "HP"),
-               },
-       },
-       { .ident = "SAMSUNG",
-         .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD"),
-               },
-       },
-       { .ident = "MSFT",
-         .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
-               },
-       },
-       { .ident = "ASUS",
-         .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-               },
-       },
-       { .ident = "GOOGLE-HP",
-         .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Google"),
-                       DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
-               },
-       },
-       { .ident = "GOOGLE-ASUS",
-         .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Google"),
-                       DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTek COMPUTER INC."),
-               },
-       },
-       { .ident = "GOOGLE-SAMSUNG",
-         .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Google"),
-                       DMI_MATCH(DMI_BOARD_VENDOR, "SAMSUNG ELECTRONICS CO., LTD"),
-               },
-       },
-       { .ident = "DELL",
-         .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-               },
-       },
-       { .ident = "DELL",
-         .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
-               },
-       },
-       { .ident = "RAZER",
-         .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Razer"),
-               },
-       },
-       {}
-};
-
 static int iwl_acpi_get_handle(struct device *dev, acpi_string method,
                               acpi_handle *ret_handle)
 {
@@ -1002,7 +944,7 @@ read_table:
                goto out_free;
        }
 
-       fwrt->ppag_flags = flags->integer.value & ACPI_PPAG_MASK;
+       fwrt->ppag_flags = flags->integer.value & IWL_PPAG_ETSI_CHINA_MASK;
        cmd_ver = iwl_fw_lookup_cmd_ver(fwrt->fw,
                                        WIDE_ID(PHY_OPS_GROUP,
                                                PER_PLATFORM_ANT_GAIN_CMD),
@@ -1036,11 +978,11 @@ read_table:
                        if (cmd_ver >= 4)
                                continue;
                        if ((j == 0 &&
-                               (fwrt->ppag_chains[i].subbands[j] > ACPI_PPAG_MAX_LB ||
-                                fwrt->ppag_chains[i].subbands[j] < ACPI_PPAG_MIN_LB)) ||
+                               (fwrt->ppag_chains[i].subbands[j] > IWL_PPAG_MAX_LB ||
+                                fwrt->ppag_chains[i].subbands[j] < IWL_PPAG_MIN_LB)) ||
                                (j != 0 &&
-                               (fwrt->ppag_chains[i].subbands[j] > ACPI_PPAG_MAX_HB ||
-                               fwrt->ppag_chains[i].subbands[j] < ACPI_PPAG_MIN_HB))) {
+                               (fwrt->ppag_chains[i].subbands[j] > IWL_PPAG_MAX_HB ||
+                               fwrt->ppag_chains[i].subbands[j] < IWL_PPAG_MIN_HB))) {
                                        ret = -EINVAL;
                                        goto out_free;
                                }
@@ -1056,110 +998,6 @@ out_free:
 }
 IWL_EXPORT_SYMBOL(iwl_acpi_get_ppag_table);
 
-int iwl_fill_ppag_table(struct iwl_fw_runtime *fwrt,
-                       union iwl_ppag_table_cmd *cmd,
-                       int *cmd_size)
-{
-        u8 cmd_ver;
-        int i, j, num_sub_bands;
-        s8 *gain;
-
-       /* many firmware images for JF lie about this */
-       if (CSR_HW_RFID_TYPE(fwrt->trans->hw_rf_id) ==
-           CSR_HW_RFID_TYPE(CSR_HW_RF_ID_TYPE_JF))
-               return -EOPNOTSUPP;
-
-        if (!fw_has_capa(&fwrt->fw->ucode_capa, IWL_UCODE_TLV_CAPA_SET_PPAG)) {
-                IWL_DEBUG_RADIO(fwrt,
-                                "PPAG capability not supported by FW, command not sent.\n");
-                return -EINVAL;
-       }
-
-       cmd_ver = iwl_fw_lookup_cmd_ver(fwrt->fw,
-                                       WIDE_ID(PHY_OPS_GROUP,
-                                               PER_PLATFORM_ANT_GAIN_CMD),
-                                       IWL_FW_CMD_VER_UNKNOWN);
-       if (!fwrt->ppag_table_valid || (cmd_ver <= 3 && !fwrt->ppag_flags)) {
-               IWL_DEBUG_RADIO(fwrt, "PPAG not enabled, command not sent.\n");
-               return -EINVAL;
-       }
-
-        /* The 'flags' field is the same in v1 and in v2 so we can just
-         * use v1 to access it.
-         */
-        cmd->v1.flags = cpu_to_le32(fwrt->ppag_flags);
-
-       IWL_DEBUG_RADIO(fwrt, "PPAG cmd ver is %d\n", cmd_ver);
-       if (cmd_ver == 1) {
-                num_sub_bands = IWL_NUM_SUB_BANDS_V1;
-                gain = cmd->v1.gain[0];
-                *cmd_size = sizeof(cmd->v1);
-                if (fwrt->ppag_ver == 1 || fwrt->ppag_ver == 2) {
-                       /* in this case FW supports revision 0 */
-                        IWL_DEBUG_RADIO(fwrt,
-                                       "PPAG table rev is %d, send truncated table\n",
-                                        fwrt->ppag_ver);
-               }
-       } else if (cmd_ver >= 2 && cmd_ver <= 4) {
-                num_sub_bands = IWL_NUM_SUB_BANDS_V2;
-                gain = cmd->v2.gain[0];
-                *cmd_size = sizeof(cmd->v2);
-                if (fwrt->ppag_ver == 0) {
-                       /* in this case FW supports revisions 1 or 2 */
-                        IWL_DEBUG_RADIO(fwrt,
-                                       "PPAG table rev is 0, send padded table\n");
-                }
-        } else {
-                IWL_DEBUG_RADIO(fwrt, "Unsupported PPAG command version\n");
-                return -EINVAL;
-        }
-
-       /* ppag mode */
-       IWL_DEBUG_RADIO(fwrt,
-                       "PPAG MODE bits were read from bios: %d\n",
-                       cmd->v1.flags);
-       if ((cmd_ver == 1 && !fw_has_capa(&fwrt->fw->ucode_capa,
-                                         IWL_UCODE_TLV_CAPA_PPAG_CHINA_BIOS_SUPPORT)) ||
-           (cmd_ver == 2 && fwrt->ppag_ver == 2)) {
-               cmd->v1.flags &= cpu_to_le32(IWL_PPAG_ETSI_MASK);
-               IWL_DEBUG_RADIO(fwrt, "masking ppag China bit\n");
-       } else {
-               IWL_DEBUG_RADIO(fwrt, "isn't masking ppag China bit\n");
-       }
-
-       IWL_DEBUG_RADIO(fwrt,
-                       "PPAG MODE bits going to be sent: %d\n",
-                       cmd->v1.flags);
-
-       for (i = 0; i < IWL_NUM_CHAIN_LIMITS; i++) {
-                for (j = 0; j < num_sub_bands; j++) {
-                        gain[i * num_sub_bands + j] =
-                                fwrt->ppag_chains[i].subbands[j];
-                        IWL_DEBUG_RADIO(fwrt,
-                                        "PPAG table: chain[%d] band[%d]: gain = %d\n",
-                                        i, j, gain[i * num_sub_bands + j]);
-                }
-        }
-
-       return 0;
-}
-IWL_EXPORT_SYMBOL(iwl_fill_ppag_table);
-
-bool iwl_acpi_is_ppag_approved(struct iwl_fw_runtime *fwrt)
-{
-
-       if (!dmi_check_system(dmi_ppag_approved_list)) {
-               IWL_DEBUG_RADIO(fwrt,
-                       "System vendor '%s' is not in the approved list, disabling PPAG.\n",
-                       dmi_get_system_info(DMI_SYS_VENDOR));
-                       fwrt->ppag_flags = 0;
-                       return false;
-       }
-
-       return true;
-}
-IWL_EXPORT_SYMBOL(iwl_acpi_is_ppag_approved);
-
 void iwl_acpi_get_phy_filters(struct iwl_fw_runtime *fwrt,
                              struct iwl_phy_specific_cfg *filters)
 {
index ef927d74bc7cb3222a52985e27ed5aaa93b257d3..ca3587e9f85636cc4e203e743679acd698235eda 100644 (file)
 #define ACPI_PPAG_WIFI_DATA_SIZE_V2    ((IWL_NUM_CHAIN_LIMITS * \
                                          IWL_NUM_SUB_BANDS_V2) + 2)
 
-/* PPAG gain value bounds in 1/8 dBm */
-#define ACPI_PPAG_MIN_LB -16
-#define ACPI_PPAG_MAX_LB 24
-#define ACPI_PPAG_MIN_HB -16
-#define ACPI_PPAG_MAX_HB 40
-#define ACPI_PPAG_MASK 3
-#define IWL_PPAG_ETSI_MASK BIT(0)
-
 #define IWL_SAR_ENABLE_MSK             BIT(0)
 #define IWL_REDUCE_POWER_FLAGS_POS     1
 
 /* The Inidcator whether UEFI WIFI GUID tables are locked is read from ACPI */
 #define UEFI_WIFI_GUID_UNLOCKED                0
 
-/*
- * The profile for revision 2 is a superset of revision 1, which is in
- * turn a superset of revision 0.  So we can store all revisions
- * inside revision 2, which is what we represent here.
- */
-struct iwl_ppag_chain {
-       s8 subbands[ACPI_SAR_NUM_SUB_BANDS_REV2];
-};
-
 enum iwl_dsm_funcs_rev_0 {
        DSM_FUNC_QUERY = 0,
        DSM_FUNC_DISABLE_SRD = 1,
@@ -207,12 +190,6 @@ __le32 iwl_acpi_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt);
 
 int iwl_acpi_get_ppag_table(struct iwl_fw_runtime *fwrt);
 
-int iwl_fill_ppag_table(struct iwl_fw_runtime *fwrt,
-                       union iwl_ppag_table_cmd *cmd,
-                       int *cmd_size);
-
-bool iwl_acpi_is_ppag_approved(struct iwl_fw_runtime *fwrt);
-
 void iwl_acpi_get_phy_filters(struct iwl_fw_runtime *fwrt,
                              struct iwl_phy_specific_cfg *filters);
 
@@ -284,18 +261,6 @@ static inline int iwl_acpi_get_ppag_table(struct iwl_fw_runtime *fwrt)
        return -ENOENT;
 }
 
-static inline int iwl_fill_ppag_table(struct iwl_fw_runtime *fwrt,
-                                     union iwl_ppag_table_cmd *cmd,
-                                     int *cmd_size)
-{
-       return -ENOENT;
-}
-
-static inline bool iwl_acpi_is_ppag_approved(struct iwl_fw_runtime *fwrt)
-{
-       return false;
-}
-
 static inline void iwl_acpi_get_phy_filters(struct iwl_fw_runtime *fwrt,
                                            struct iwl_phy_specific_cfg *filters)
 {
index 862d8b8b0fc9b0829fac268f75482627aa161de5..2393c8a8e2886233cee039a333bf49c17af8932e 100644 (file)
@@ -2,6 +2,7 @@
 /*
  * Copyright (C) 2023 Intel Corporation
  */
+#include <linux/dmi.h>
 #include "iwl-drv.h"
 #include "iwl-debug.h"
 #include "regulatory.h"
@@ -24,6 +25,63 @@ IWL_BIOS_TABLE_LOADER(wrds);
 IWL_BIOS_TABLE_LOADER(ewrd);
 IWL_BIOS_TABLE_LOADER(wgds);
 
+static const struct dmi_system_id dmi_ppag_approved_list[] = {
+       { .ident = "HP",
+         .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "HP"),
+               },
+       },
+       { .ident = "SAMSUNG",
+         .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD"),
+               },
+       },
+       { .ident = "MSFT",
+         .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
+               },
+       },
+       { .ident = "ASUS",
+         .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+               },
+       },
+       { .ident = "GOOGLE-HP",
+         .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Google"),
+                       DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
+               },
+       },
+       { .ident = "GOOGLE-ASUS",
+         .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Google"),
+                       DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTek COMPUTER INC."),
+               },
+       },
+       { .ident = "GOOGLE-SAMSUNG",
+         .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Google"),
+                       DMI_MATCH(DMI_BOARD_VENDOR, "SAMSUNG ELECTRONICS CO., LTD"),
+               },
+       },
+       { .ident = "DELL",
+         .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+               },
+       },
+       { .ident = "DELL",
+         .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
+               },
+       },
+       { .ident = "RAZER",
+         .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Razer"),
+               },
+       },
+       {}
+};
+
 bool iwl_sar_geo_support(struct iwl_fw_runtime *fwrt)
 {
        /*
@@ -147,3 +205,106 @@ int iwl_sar_fill_profile(struct iwl_fw_runtime *fwrt,
        return ret;
 }
 IWL_EXPORT_SYMBOL(iwl_sar_fill_profile);
+
+int iwl_fill_ppag_table(struct iwl_fw_runtime *fwrt,
+                       union iwl_ppag_table_cmd *cmd, int *cmd_size)
+{
+       u8 cmd_ver;
+       int i, j, num_sub_bands;
+       s8 *gain;
+
+       /* many firmware images for JF lie about this */
+       if (CSR_HW_RFID_TYPE(fwrt->trans->hw_rf_id) ==
+           CSR_HW_RFID_TYPE(CSR_HW_RF_ID_TYPE_JF))
+               return -EOPNOTSUPP;
+
+       if (!fw_has_capa(&fwrt->fw->ucode_capa, IWL_UCODE_TLV_CAPA_SET_PPAG)) {
+               IWL_DEBUG_RADIO(fwrt,
+                               "PPAG capability not supported by FW, command not sent.\n");
+               return -EINVAL;
+       }
+
+       cmd_ver = iwl_fw_lookup_cmd_ver(fwrt->fw,
+                                       WIDE_ID(PHY_OPS_GROUP,
+                                               PER_PLATFORM_ANT_GAIN_CMD),
+                                       IWL_FW_CMD_VER_UNKNOWN);
+       if (!fwrt->ppag_table_valid || (cmd_ver <= 3 && !fwrt->ppag_flags)) {
+               IWL_DEBUG_RADIO(fwrt, "PPAG not enabled, command not sent.\n");
+               return -EINVAL;
+       }
+
+       /* The 'flags' field is the same in v1 and in v2 so we can just
+        * use v1 to access it.
+        */
+       cmd->v1.flags = cpu_to_le32(fwrt->ppag_flags);
+
+       IWL_DEBUG_RADIO(fwrt, "PPAG cmd ver is %d\n", cmd_ver);
+       if (cmd_ver == 1) {
+               num_sub_bands = IWL_NUM_SUB_BANDS_V1;
+               gain = cmd->v1.gain[0];
+               *cmd_size = sizeof(cmd->v1);
+               if (fwrt->ppag_ver == 1 || fwrt->ppag_ver == 2) {
+                       /* in this case FW supports revision 0 */
+                       IWL_DEBUG_RADIO(fwrt,
+                                       "PPAG table rev is %d, send truncated table\n",
+                                       fwrt->ppag_ver);
+               }
+       } else if (cmd_ver >= 2 && cmd_ver <= 4) {
+               num_sub_bands = IWL_NUM_SUB_BANDS_V2;
+               gain = cmd->v2.gain[0];
+               *cmd_size = sizeof(cmd->v2);
+               if (fwrt->ppag_ver == 0) {
+                       /* in this case FW supports revisions 1 or 2 */
+                       IWL_DEBUG_RADIO(fwrt,
+                                       "PPAG table rev is 0, send padded table\n");
+               }
+       } else {
+               IWL_DEBUG_RADIO(fwrt, "Unsupported PPAG command version\n");
+               return -EINVAL;
+       }
+
+       /* ppag mode */
+       IWL_DEBUG_RADIO(fwrt,
+                       "PPAG MODE bits were read from bios: %d\n",
+                       cmd->v1.flags);
+       if ((cmd_ver == 1 &&
+            !fw_has_capa(&fwrt->fw->ucode_capa,
+                         IWL_UCODE_TLV_CAPA_PPAG_CHINA_BIOS_SUPPORT)) ||
+           (cmd_ver == 2 && fwrt->ppag_ver == 2)) {
+               cmd->v1.flags &= cpu_to_le32(IWL_PPAG_ETSI_MASK);
+               IWL_DEBUG_RADIO(fwrt, "masking ppag China bit\n");
+       } else {
+               IWL_DEBUG_RADIO(fwrt, "isn't masking ppag China bit\n");
+       }
+
+       IWL_DEBUG_RADIO(fwrt,
+                       "PPAG MODE bits going to be sent: %d\n",
+                       cmd->v1.flags);
+
+       for (i = 0; i < IWL_NUM_CHAIN_LIMITS; i++) {
+               for (j = 0; j < num_sub_bands; j++) {
+                       gain[i * num_sub_bands + j] =
+                               fwrt->ppag_chains[i].subbands[j];
+                       IWL_DEBUG_RADIO(fwrt,
+                                       "PPAG table: chain[%d] band[%d]: gain = %d\n",
+                                       i, j, gain[i * num_sub_bands + j]);
+               }
+       }
+
+       return 0;
+}
+IWL_EXPORT_SYMBOL(iwl_fill_ppag_table);
+
+bool iwl_is_ppag_approved(struct iwl_fw_runtime *fwrt)
+{
+       if (!dmi_check_system(dmi_ppag_approved_list)) {
+               IWL_DEBUG_RADIO(fwrt,
+                               "System vendor '%s' is not in the approved list, disabling PPAG.\n",
+                               dmi_get_system_info(DMI_SYS_VENDOR));
+                               fwrt->ppag_flags = 0;
+                               return false;
+       }
+
+       return true;
+}
+IWL_EXPORT_SYMBOL(iwl_is_ppag_approved);
index 73c6122e76267bc9b542b213640935ce96d2c03e..63f650cb6517361671e9d19d65bd75c97330b963 100644 (file)
 
 #define IWL_SAR_ENABLE_MSK             BIT(0)
 
+/* PPAG gain value bounds in 1/8 dBm */
+#define IWL_PPAG_MIN_LB        -16
+#define IWL_PPAG_MAX_LB 24
+#define IWL_PPAG_MIN_HB -16
+#define IWL_PPAG_MAX_HB 40
+
+#define IWL_PPAG_ETSI_CHINA_MASK       3
+#define IWL_PPAG_ETSI_MASK             BIT(0)
+
 /*
  * The profile for revision 2 is a superset of revision 1, which is in
  * turn a superset of revision 0.  So we can store all revisions
@@ -75,6 +84,11 @@ struct iwl_geo_profile {
        struct iwl_geo_profile_band bands[BIOS_GEO_MAX_NUM_BANDS];
 };
 
+/* Same thing as with SAR, all revisions fit in revision 2 */
+struct iwl_ppag_chain {
+       s8 subbands[BIOS_SAR_MAX_SUB_BANDS_NUM];
+};
+
 struct iwl_fw_runtime;
 
 bool iwl_sar_geo_support(struct iwl_fw_runtime *fwrt);
@@ -87,6 +101,12 @@ int iwl_sar_fill_profile(struct iwl_fw_runtime *fwrt,
                         __le16 *per_chain, u32 n_tables, u32 n_subbands,
                         int prof_a, int prof_b);
 
+int iwl_fill_ppag_table(struct iwl_fw_runtime *fwrt,
+                       union iwl_ppag_table_cmd *cmd,
+                       int *cmd_size);
+
+bool iwl_is_ppag_approved(struct iwl_fw_runtime *fwrt);
+
 int iwl_bios_get_wrds_table(struct iwl_fw_runtime *fwrt);
 
 int iwl_bios_get_ewrd_table(struct iwl_fw_runtime *fwrt);
index d52fc3119972dbb6fc526b6d4139a6b3ed17ad72..1d759fe7d12db6be03d5f787d04f6ce9e291f01f 100644 (file)
@@ -1104,7 +1104,7 @@ int iwl_mvm_ppag_send_cmd(struct iwl_mvm *mvm)
 static int iwl_mvm_ppag_init(struct iwl_mvm *mvm)
 {
        /* no need to read the table, done in INIT stage */
-       if (!(iwl_acpi_is_ppag_approved(&mvm->fwrt)))
+       if (!(iwl_is_ppag_approved(&mvm->fwrt)))
                return 0;
 
        return iwl_mvm_ppag_send_cmd(mvm);