wifi: iwlwifi: Add support for PPAG cmd v5 and PPAG revision 3
authorAnjaneyulu <pagadala.yesu.anjaneyulu@intel.com>
Sun, 4 Feb 2024 22:06:06 +0000 (00:06 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Thu, 8 Feb 2024 14:00:45 +0000 (15:00 +0100)
Add support for
- PPAG revision 3 in BIOS to enable PPAG in UHB
- PPAG command version 5, this command allows OEM to control
  enablement of PPAG for LPI for UHB mode in USA and ETSI countries.

Signed-off-by: Anjaneyulu <pagadala.yesu.anjaneyulu@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://msgid.link/20240204235836.d17425824b11.If2c1b29e3c579f4135383681af2d625cfe2cffcd@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/intel/iwlwifi/fw/acpi.c
drivers/net/wireless/intel/iwlwifi/fw/api/power.h
drivers/net/wireless/intel/iwlwifi/fw/regulatory.c
drivers/net/wireless/intel/iwlwifi/fw/regulatory.h
drivers/net/wireless/intel/iwlwifi/fw/runtime.h
drivers/net/wireless/intel/iwlwifi/fw/uefi.c
drivers/net/wireless/intel/iwlwifi/fw/uefi.h

index 9afb1b1..82ecea0 100644 (file)
@@ -817,15 +817,15 @@ int iwl_acpi_get_ppag_table(struct iwl_fw_runtime *fwrt)
        if (IS_ERR(data))
                return PTR_ERR(data);
 
-       /* try to read ppag table rev 2 or 1 (both have the same data size) */
+       /* try to read ppag table rev 3, 2 or 1 (all have the same data size) */
        wifi_pkg = iwl_acpi_get_wifi_pkg(fwrt->dev, data,
                                ACPI_PPAG_WIFI_DATA_SIZE_V2, &tbl_rev);
 
        if (!IS_ERR(wifi_pkg)) {
-               if (tbl_rev == 1 || tbl_rev == 2) {
+               if (tbl_rev >= 1 && tbl_rev <= 3) {
                        num_sub_bands = IWL_NUM_SUB_BANDS_V2;
                        IWL_DEBUG_RADIO(fwrt,
-                                       "Reading PPAG table v2 (tbl_rev=%d)\n",
+                                       "Reading PPAG table (tbl_rev=%d)\n",
                                        tbl_rev);
                        goto read_table;
                } else {
@@ -857,7 +857,8 @@ read_table:
                goto out_free;
        }
 
-       fwrt->ppag_flags = flags->integer.value & IWL_PPAG_ETSI_CHINA_MASK;
+       fwrt->ppag_flags = iwl_bios_get_ppag_flags(flags->integer.value,
+                                                  fwrt->ppag_ver);
 
        /*
         * read, verify gain values and save them into the PPAG table.
index 040d83f..0bf3824 100644 (file)
@@ -505,14 +505,41 @@ struct iwl_geo_tx_power_profiles_resp {
        __le32 profile_idx;
 } __packed; /* PER_CHAIN_LIMIT_OFFSET_RSP */
 
+/**
+ * enum iwl_ppag_flags - PPAG enable masks
+ * @IWL_PPAG_ETSI_MASK: enable PPAG in ETSI
+ * @IWL_PPAG_CHINA_MASK: enable PPAG in China
+ * @IWL_PPAG_ETSI_LPI_UHB_MASK: enable LPI in ETSI for UHB
+ * @IWL_PPAG_ETSI_VLP_UHB_MASK: enable VLP in ETSI for UHB
+ * @IWL_PPAG_ETSI_SP_UHB_MASK: enable SP in ETSI for UHB
+ * @IWL_PPAG_USA_LPI_UHB_MASK: enable LPI in USA for UHB
+ * @IWL_PPAG_USA_VLP_UHB_MASK: enable VLP in USA for UHB
+ * @IWL_PPAG_USA_SP_UHB_MASK: enable SP in USA for UHB
+ * @IWL_PPAG_CANADA_LPI_UHB_MASK: enable LPI in CANADA for UHB
+ * @IWL_PPAG_CANADA_VLP_UHB_MASK: enable VLP in CANADA for UHB
+ * @IWL_PPAG_CANADA_SP_UHB_MASK: enable SP in CANADA for UHB
+ */
+enum iwl_ppag_flags {
+       IWL_PPAG_ETSI_MASK = BIT(0),
+       IWL_PPAG_CHINA_MASK = BIT(1),
+       IWL_PPAG_ETSI_LPI_UHB_MASK = BIT(2),
+       IWL_PPAG_ETSI_VLP_UHB_MASK = BIT(3),
+       IWL_PPAG_ETSI_SP_UHB_MASK = BIT(4),
+       IWL_PPAG_USA_LPI_UHB_MASK = BIT(5),
+       IWL_PPAG_USA_VLP_UHB_MASK = BIT(6),
+       IWL_PPAG_USA_SP_UHB_MASK = BIT(7),
+       IWL_PPAG_CANADA_LPI_UHB_MASK = BIT(8),
+       IWL_PPAG_CANADA_VLP_UHB_MASK = BIT(9),
+       IWL_PPAG_CANADA_SP_UHB_MASK = BIT(10),
+};
+
 /**
  * union iwl_ppag_table_cmd - union for all versions of PPAG command
  * @v1: version 1
  * @v2: version 2
- *
- * @flags: bit 0 - indicates enablement of PPAG for ETSI
- *         bit 1 - indicates enablement of PPAG for CHINA BIOS
- *         bit 1 can be used only in v3 (identical to v2)
+ * version 3, 4 and 5 are the same structure as v2,
+ *     but has a different format of the flags bitmap
+ * @flags: values from &enum iwl_ppag_flags
  * @gain: table of antenna gain values per chain and sub-band
  * @reserved: reserved
  */
@@ -529,6 +556,11 @@ union iwl_ppag_table_cmd {
        } v2;
 } __packed;
 
+#define IWL_PPAG_CMD_V4_MASK (IWL_PPAG_ETSI_MASK | IWL_PPAG_CHINA_MASK)
+#define IWL_PPAG_CMD_V5_MASK (IWL_PPAG_CMD_V4_MASK | \
+                             IWL_PPAG_ETSI_LPI_UHB_MASK | \
+                             IWL_PPAG_USA_LPI_UHB_MASK)
+
 #define MCC_TO_SAR_OFFSET_TABLE_ROW_SIZE       26
 #define MCC_TO_SAR_OFFSET_TABLE_COL_SIZE       13
 
index 597735a..36d5064 100644 (file)
@@ -320,7 +320,7 @@ int iwl_fill_ppag_table(struct iwl_fw_runtime *fwrt,
                                        WIDE_ID(PHY_OPS_GROUP,
                                                PER_PLATFORM_ANT_GAIN_CMD), 1);
        /*
-        * Starting from ver 4, driver needs to send the PPAG CMD regradless
+        * Starting from ver 4, driver needs to send the PPAG CMD regardless
         * if PPAG is enabled/disabled or valid/invalid.
         */
        send_ppag_always = cmd_ver > 3;
@@ -341,18 +341,18 @@ int iwl_fill_ppag_table(struct iwl_fw_runtime *fwrt,
                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) {
+               if (fwrt->ppag_ver >= 1) {
                        /* 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) {
+       } else if (cmd_ver >= 2 && cmd_ver <= 5) {
                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 */
+                       /* in this case FW supports revisions 1,2 or 3 */
                        IWL_DEBUG_RADIO(fwrt,
                                        "PPAG table rev is 0, send padded table\n");
                }
@@ -364,11 +364,17 @@ int iwl_fill_ppag_table(struct iwl_fw_runtime *fwrt,
        /* ppag mode */
        IWL_DEBUG_RADIO(fwrt,
                        "PPAG MODE bits were read from bios: %d\n",
-                       cmd->v1.flags);
+                       le32_to_cpu(cmd->v1.flags));
+
+       if (cmd_ver == 5)
+               cmd->v1.flags &= cpu_to_le32(IWL_PPAG_CMD_V5_MASK);
+       else if (cmd_ver < 5)
+               cmd->v1.flags &= cpu_to_le32(IWL_PPAG_CMD_V4_MASK);
+
        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_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 {
@@ -377,7 +383,7 @@ int iwl_fill_ppag_table(struct iwl_fw_runtime *fwrt,
 
        IWL_DEBUG_RADIO(fwrt,
                        "PPAG MODE bits going to be sent: %d\n",
-                       cmd->v1.flags);
+                       le32_to_cpu(cmd->v1.flags));
 
        for (i = 0; i < IWL_NUM_CHAIN_LIMITS; i++) {
                for (j = 0; j < num_sub_bands; j++) {
index 52389f8..28e7747 100644 (file)
@@ -37,7 +37,7 @@
 #define IWL_PPAG_MAX_HB 40
 
 #define IWL_PPAG_ETSI_CHINA_MASK       3
-#define IWL_PPAG_ETSI_MASK             BIT(0)
+#define IWL_PPAG_REV3_MASK             0x7FF
 
 #define IWL_WTAS_BLACK_LIST_MAX        16
 #define IWL_WTAS_ENABLED_MSK           0x1
@@ -189,4 +189,11 @@ __le32 iwl_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt);
 
 int iwl_bios_get_dsm(struct iwl_fw_runtime *fwrt, enum iwl_dsm_funcs func,
                     u32 *value);
+
+static inline u32 iwl_bios_get_ppag_flags(const u32 ppag_modes,
+                                         const u8 ppag_ver)
+{
+       return ppag_modes & (ppag_ver < 3 ? IWL_PPAG_ETSI_CHINA_MASK :
+                                           IWL_PPAG_REV3_MASK);
+}
 #endif /* __fw_regulatory_h__ */
index 16d9ea6..bd0c9b2 100644 (file)
@@ -174,7 +174,7 @@ struct iwl_fw_runtime {
        bool geo_enabled;
        struct iwl_ppag_chain ppag_chains[IWL_NUM_CHAIN_LIMITS];
        u32 ppag_flags;
-       u32 ppag_ver;
+       u8 ppag_ver;
 #ifdef CONFIG_ACPI
        struct iwl_sar_offset_mapping_cmd sgom_table;
        bool sgom_enabled;
index 3c4c99e..5148e80 100644 (file)
@@ -541,7 +541,8 @@ int iwl_uefi_get_ppag_table(struct iwl_fw_runtime *fwrt)
        }
 
        fwrt->ppag_ver = data->revision;
-       fwrt->ppag_flags = data->ppag_modes & IWL_PPAG_ETSI_CHINA_MASK;
+       fwrt->ppag_flags = iwl_bios_get_ppag_flags(data->ppag_modes,
+                                                  fwrt->ppag_ver);
 
        BUILD_BUG_ON(sizeof(fwrt->ppag_chains) != sizeof(data->ppag_chains));
        memcpy(&fwrt->ppag_chains, &data->ppag_chains,
index 1f7c3f4..3905329 100644 (file)
@@ -116,8 +116,7 @@ struct uefi_cnv_var_wgds {
 /*
  * struct uefi_cnv_var_ppag - PPAG table as defined in UEFI
  * @revision: the revision of the table
- * @ppag_modes: bit 0 - PPAG is enabled/disabled in ETSI,
- *     bit 1 - PPAG is enabled/disabled in China
+ * @ppag_modes: values from &enum iwl_ppag_flags
  * @ppag_chains: the PPAG values per chain and band
  */
 struct uefi_cnv_var_ppag {