diff options
| author | Bjoern A. Zeeb <bz@FreeBSD.org> | 2026-04-18 20:35:37 +0000 |
|---|---|---|
| committer | Bjoern A. Zeeb <bz@FreeBSD.org> | 2026-04-22 20:57:11 +0000 |
| commit | f45e34316eb7871dc2cd649997fc5d63b1de2009 (patch) | |
| tree | eb85a56855d57352fb29558d9680954a41b024bc /sys/contrib/dev/iwlwifi/fw | |
| parent | 7410ff27b2b2288dc6ae9f94f12b16e2dad5c364 (diff) | |
iwlwifi: update Intel's mvm/mld drivers
This version is based on
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
028ef9c96e96197026887c0f092424679298aae8 ( tag: v7.0 ).
Sponsored by: The FreeBSD Foundation
(cherry picked from commit b2bd08185e4984c70179c195f712cef5a136d21b)
Diffstat (limited to 'sys/contrib/dev/iwlwifi/fw')
| -rw-r--r-- | sys/contrib/dev/iwlwifi/fw/acpi.c | 117 | ||||
| -rw-r--r-- | sys/contrib/dev/iwlwifi/fw/api/commands.h | 5 | ||||
| -rw-r--r-- | sys/contrib/dev/iwlwifi/fw/api/mac-cfg.h | 159 | ||||
| -rw-r--r-- | sys/contrib/dev/iwlwifi/fw/api/nvm-reg.h | 34 | ||||
| -rw-r--r-- | sys/contrib/dev/iwlwifi/fw/api/power.h | 2 | ||||
| -rw-r--r-- | sys/contrib/dev/iwlwifi/fw/api/rs.h | 41 | ||||
| -rw-r--r-- | sys/contrib/dev/iwlwifi/fw/api/rx.h | 95 | ||||
| -rw-r--r-- | sys/contrib/dev/iwlwifi/fw/api/scan.h | 10 | ||||
| -rw-r--r-- | sys/contrib/dev/iwlwifi/fw/dbg.c | 7 | ||||
| -rw-r--r-- | sys/contrib/dev/iwlwifi/fw/debugfs.c | 3 | ||||
| -rw-r--r-- | sys/contrib/dev/iwlwifi/fw/file.h | 2 | ||||
| -rw-r--r-- | sys/contrib/dev/iwlwifi/fw/pnvm.c | 4 | ||||
| -rw-r--r-- | sys/contrib/dev/iwlwifi/fw/regulatory.c | 206 | ||||
| -rw-r--r-- | sys/contrib/dev/iwlwifi/fw/regulatory.h | 9 | ||||
| -rw-r--r-- | sys/contrib/dev/iwlwifi/fw/runtime.h | 17 | ||||
| -rw-r--r-- | sys/contrib/dev/iwlwifi/fw/smem.c | 8 | ||||
| -rw-r--r-- | sys/contrib/dev/iwlwifi/fw/uefi.c | 72 | ||||
| -rw-r--r-- | sys/contrib/dev/iwlwifi/fw/uefi.h | 2 |
18 files changed, 496 insertions, 297 deletions
diff --git a/sys/contrib/dev/iwlwifi/fw/acpi.c b/sys/contrib/dev/iwlwifi/fw/acpi.c index 52edc19d8cdd..de9aef0d924c 100644 --- a/sys/contrib/dev/iwlwifi/fw/acpi.c +++ b/sys/contrib/dev/iwlwifi/fw/acpi.c @@ -28,6 +28,8 @@ static const size_t acpi_dsm_size[DSM_FUNC_NUM_FUNCS] = { [DSM_FUNC_ENERGY_DETECTION_THRESHOLD] = sizeof(u32), [DSM_FUNC_RFI_CONFIG] = sizeof(u32), [DSM_FUNC_ENABLE_11BE] = sizeof(u32), + [DSM_FUNC_ENABLE_UNII_9] = sizeof(u32), + [DSM_FUNC_ENABLE_11BN] = sizeof(u32), }; static int iwl_acpi_get_handle(struct device *dev, acpi_string method, @@ -156,61 +158,104 @@ out: } /* - * This function receives a DSM function number, calculates its expected size - * according to Intel BIOS spec, and fills in the value in a 32-bit field. + * This function loads all the DSM functions, it checks the size and populates + * the cache with the values in a 32-bit field. * In case the expected size is smaller than 32-bit, padding will be added. */ -int iwl_acpi_get_dsm(struct iwl_fw_runtime *fwrt, - enum iwl_dsm_funcs func, u32 *value) +static int iwl_acpi_load_dsm_values(struct iwl_fw_runtime *fwrt) { - size_t expected_size; - u64 tmp; + u64 query_func_val; int ret; BUILD_BUG_ON(ARRAY_SIZE(acpi_dsm_size) != DSM_FUNC_NUM_FUNCS); - if (WARN_ON(func >= ARRAY_SIZE(acpi_dsm_size) || !func)) - return -EINVAL; + ret = iwl_acpi_get_dsm_integer(fwrt->dev, ACPI_DSM_REV, + DSM_FUNC_QUERY, + &iwl_guid, &query_func_val, + acpi_dsm_size[DSM_FUNC_QUERY]); - expected_size = acpi_dsm_size[func]; + if (ret) { + IWL_DEBUG_RADIO(fwrt, "ACPI QUERY FUNC not valid: %d\n", ret); + return ret; + } - /* Currently all ACPI DSMs are either 8-bit or 32-bit */ - if (expected_size != sizeof(u8) && expected_size != sizeof(u32)) - return -EOPNOTSUPP; + fwrt->dsm_revision = ACPI_DSM_REV; + fwrt->dsm_source = BIOS_SOURCE_ACPI; - if (!fwrt->acpi_dsm_funcs_valid) { - ret = iwl_acpi_get_dsm_integer(fwrt->dev, ACPI_DSM_REV, - DSM_FUNC_QUERY, - &iwl_guid, &tmp, - acpi_dsm_size[DSM_FUNC_QUERY]); - if (ret) { - /* always indicate BIT(0) to avoid re-reading */ - fwrt->acpi_dsm_funcs_valid = BIT(0); - return ret; + IWL_DEBUG_RADIO(fwrt, "ACPI DSM validity bitmap 0x%x\n", + (u32)query_func_val); + + /* DSM_FUNC_QUERY is 0, start from 1 */ + for (int func = 1; func < ARRAY_SIZE(fwrt->dsm_values); func++) { + size_t expected_size = acpi_dsm_size[func]; + u64 tmp; + + if (!(query_func_val & BIT(func))) { + IWL_DEBUG_RADIO(fwrt, + "ACPI DSM %d not indicated as valid\n", + func); + continue; } - IWL_DEBUG_RADIO(fwrt, "ACPI DSM validity bitmap 0x%x\n", - (u32)tmp); - /* always indicate BIT(0) to avoid re-reading */ - fwrt->acpi_dsm_funcs_valid = tmp | BIT(0); + /* This is an invalid function (5 for example) */ + if (!expected_size) + continue; + + /* Currently all ACPI DSMs are either 8-bit or 32-bit */ + if (expected_size != sizeof(u8) && expected_size != sizeof(u32)) + continue; + + ret = iwl_acpi_get_dsm_integer(fwrt->dev, ACPI_DSM_REV, func, + &iwl_guid, &tmp, expected_size); + if (ret) + continue; + + if ((expected_size == sizeof(u8) && tmp != (u8)tmp) || + (expected_size == sizeof(u32) && tmp != (u32)tmp)) + IWL_DEBUG_RADIO(fwrt, + "DSM value overflows the expected size, truncating\n"); + fwrt->dsm_values[func] = (u32)tmp; + fwrt->dsm_funcs_valid |= BIT(func); + } + + return 0; +} + +/* + * This function receives a DSM function number, calculates its expected size + * according to Intel BIOS spec, and fills in the value in a 32-bit field. + * In case the expected size is smaller than 32-bit, padding will be added. + */ +int iwl_acpi_get_dsm(struct iwl_fw_runtime *fwrt, + enum iwl_dsm_funcs func, u32 *value) +{ + if (!fwrt->dsm_funcs_valid) { + int ret = iwl_acpi_load_dsm_values(fwrt); + + /* + * Always set the valid bit for DSM_FUNC_QUERY so that even if + * DSM_FUNC_QUERY returns 0 (no DSM function is valid), we will + * still consider the cache as valid. + */ + fwrt->dsm_funcs_valid |= BIT(DSM_FUNC_QUERY); + + if (ret) + return ret; } - if (!(fwrt->acpi_dsm_funcs_valid & BIT(func))) { + BUILD_BUG_ON(ARRAY_SIZE(fwrt->dsm_values) != DSM_FUNC_NUM_FUNCS); + BUILD_BUG_ON(BITS_PER_TYPE(fwrt->dsm_funcs_valid) < DSM_FUNC_NUM_FUNCS); + + if (WARN_ON(func >= ARRAY_SIZE(fwrt->dsm_values) || !func)) + return -EINVAL; + + if (!(fwrt->dsm_funcs_valid & BIT(func))) { IWL_DEBUG_RADIO(fwrt, "ACPI DSM %d not indicated as valid\n", func); return -ENODATA; } - ret = iwl_acpi_get_dsm_integer(fwrt->dev, ACPI_DSM_REV, func, - &iwl_guid, &tmp, expected_size); - if (ret) - return ret; - - if ((expected_size == sizeof(u8) && tmp != (u8)tmp) || - (expected_size == sizeof(u32) && tmp != (u32)tmp)) - IWL_DEBUG_RADIO(fwrt, - "DSM value overflows the expected size, truncating\n"); - *value = (u32)tmp; + *value = fwrt->dsm_values[func]; return 0; } diff --git a/sys/contrib/dev/iwlwifi/fw/api/commands.h b/sys/contrib/dev/iwlwifi/fw/api/commands.h index 8d64a271bb94..36159a769916 100644 --- a/sys/contrib/dev/iwlwifi/fw/api/commands.h +++ b/sys/contrib/dev/iwlwifi/fw/api/commands.h @@ -297,6 +297,11 @@ enum iwl_legacy_cmds { SCAN_OFFLOAD_UPDATE_PROFILES_CMD = 0x6E, /** + * @SCAN_START_NOTIFICATION_UMAC: uses &struct iwl_umac_scan_start + */ + SCAN_START_NOTIFICATION_UMAC = 0xb2, + + /** * @MATCH_FOUND_NOTIFICATION: scan match found */ MATCH_FOUND_NOTIFICATION = 0xd9, diff --git a/sys/contrib/dev/iwlwifi/fw/api/mac-cfg.h b/sys/contrib/dev/iwlwifi/fw/api/mac-cfg.h index f76cea6e9ec8..c7a833f8041a 100644 --- a/sys/contrib/dev/iwlwifi/fw/api/mac-cfg.h +++ b/sys/contrib/dev/iwlwifi/fw/api/mac-cfg.h @@ -66,6 +66,18 @@ enum iwl_mac_conf_subcmd_ids { */ TWT_OPERATION_CMD = 0x10, /** + * @NAN_CFG_CMD: &struct iwl_nan_config_cmd + */ + NAN_CFG_CMD = 0x12, + /** + * @NAN_DW_END_NOTIF: &struct iwl_nan_dw_end_notif + */ + NAN_DW_END_NOTIF = 0xf4, + /** + * @NAN_JOINED_CLUSTER_NOTIF: &struct iwl_nan_cluster_notif + */ + NAN_JOINED_CLUSTER_NOTIF = 0xf5, + /** * @MISSED_BEACONS_NOTIF: &struct iwl_missed_beacons_notif */ MISSED_BEACONS_NOTIF = 0xF6, @@ -492,22 +504,36 @@ enum iwl_link_modify_bandwidth { }; /** + * enum iwl_npca_flags - NPCA flags + * @IWL_NPCA_FLAG_MAC_HDR_BASED: MAC header based NPCA operation + * permitted in the BSS (MOPLEN) + */ +enum iwl_npca_flags { + IWL_NPCA_FLAG_MAC_HDR_BASED = BIT(0), +}; /* NPCA_FLAG_E */ + +/** * struct iwl_npca_params - NPCA parameters (non-primary channel access) * + * @dis_subch_bmap: disabled subchannel bitmap for NPCA * @switch_delay: after switch, delay TX according to destination AP * @switch_back_delay: switch back to control channel before OBSS frame end + * @initial_qsrc: Indicates the value that is used to initialize the + * EDCAF QSRC[AC] variables * @min_dur_threshold: minimum PPDU time to switch to the non-primary - * NPCA channel - * @flags: NPCA flags - bit 0: puncturing allowed, bit 1: new TX allowed + * NPCA channel (usec) + * @flags: NPCA flags, see &enum iwl_npca_flags * @reserved: reserved for alignment purposes */ struct iwl_npca_params { + __le16 dis_subch_bmap; u8 switch_delay; u8 switch_back_delay; - __le16 min_dur_threshold; - __le16 flags; - __le16 reserved; -} __packed; /* NPCA_PARAM_API_S_VER_1 */ + u8 initial_qsrc; + u8 min_dur_threshold; + u8 flags; + u8 reserved; +} __packed; /* NPCA_PARAM_API_S_VER_2 */ /** * struct iwl_link_config_cmd - command structure to configure the LINK context @@ -618,7 +644,8 @@ struct iwl_link_config_cmd { struct iwl_npca_params npca_params; /* since _VER_7 */ struct iwl_ac_qos prio_edca_params; /* since _VER_7 */ __le32 reserved3[4]; -} __packed; /* LINK_CONTEXT_CONFIG_CMD_API_S_VER_1, _VER_2, _VER_3, _VER_4, _VER_5, _VER_6, _VER_7 */ +} __packed; /* LINK_CONTEXT_CONFIG_CMD_API_S_VER_1, _VER_2, _VER_3, _VER_4, + * _VER_5, _VER_6, _VER_7, _VER_8 */ /* Currently FW supports link ids in the range 0-3 and can have * at most two active links for each vif. @@ -990,4 +1017,122 @@ struct iwl_twt_operation_cmd { u8 ul_tid_bitmap; } __packed; /* TWT_OPERATION_API_S_VER_1 */ +enum iwl_nan_band { + IWL_NAN_BAND_5GHZ = 0, + IWL_NAN_BAND_2GHZ = 1, + IWL_NUM_NAN_BANDS, +}; + +/** + * struct iwl_nan_band_config - NAN band configuration + * + * @rssi_close: RSSI threshold for close proximity in dBm + * @rssi_middle: RSSI threshold for middle proximity in dBm + * @dw_interval: Discovery Window (DW) interval for synchronization beacons and + * SDFs. Valid values of DW interval are: 1, 2, 3, 4 and 5 corresponding to + * 1, 2, 4, 8, and 16 DWs. + * @reserved: reserved + */ +struct iwl_nan_band_config { + u8 rssi_close; + u8 rssi_middle; + u8 dw_interval; + u8 reserved; +}; /* NAN_BAND_SPECIFIC_CONFIG_API_S_VER_1 */ + +/** + * enum iwl_nan_flags - flags for NAN configuration + * + * @IWL_NAN_FLAG_DW_END_NOTIF_ENABLED: indicates that the host wants to receive + * notifications when a DW ends. + */ +enum iwl_nan_flags { + IWL_NAN_FLAG_DW_END_NOTIF_ENABLED = BIT(0), +}; + +/** + * struct iwl_nan_config_cmd - NAN configuration command + * + * @action: action to perform, see &enum iwl_ctxt_action + * @nmi_addr: NAN Management Interface (NMI) address + * @reserved_for_nmi_addr: reserved + * @discovery_beacon_interval: discovery beacon interval in TUs + * @cluster_id: lower last two bytes of the cluster ID, in case the local + * device starts a cluster + * @sta_id: station ID of the NAN station + * @hb_channel: channel for 5 GHz if the device supports operation on 5 GHz. + * Valid values are 44 and 149, which correspond to the 5 GHz channel, and + * 0 which means that NAN operation on the 5 GHz band is disabled. + * @master_pref: master preference + * @dwell_time: dwell time on the discovery channel during scan (milliseconds). + * If set to 0, the dwell time is determined by the firmware. + * @scan_period: scan period in seconds. If set to 0, the scan period is + * determined by the firmware. + * @flags: flags for NAN configuration, see &enum iwl_nan_flags + * @band_config: band configuration for NAN, one for each band + * @nan_attr_len: length of the NAN attributes to be added to the beacon (bytes) + * @nan_vendor_elems_len: length of the NAN vendor elements to be added to the + * beacon (bytes) + * @beacon_data: variable length data that contains the NAN attributes + * (&nan_attr_len) followed by the NAN vendor elements + * (&nan_vendor_elems_len). + */ +struct iwl_nan_config_cmd { + __le32 action; + u8 nmi_addr[6]; + __le16 reserved_for_nmi_addr; + __le32 discovery_beacon_interval; + + u8 cluster_id[2]; + u8 sta_id; + u8 hb_channel; + + u8 master_pref; + u8 dwell_time; + u8 scan_period; + u8 flags; + + struct iwl_nan_band_config band_config[IWL_NUM_NAN_BANDS]; + + __le32 nan_attr_len; + __le32 nan_vendor_elems_len; + u8 beacon_data[]; +} __packed; /* NAN_CONFIG_CMD_API_S_VER_1 */ + +/** + * enum iwl_nan_cluster_notif_flags - flags for the cluster notification + * + * @IWL_NAN_CLUSTER_NOTIF_FLAG_NEW_CLUSTER: indicates that the device has + * started a new cluster. If not set, the device has joined an existing + * cluster. + */ +enum iwl_nan_cluster_notif_flags { + IWL_NAN_CLUSTER_NOTIF_FLAG_NEW_CLUSTER = BIT(0), +}; /* NAN_JOINED_CLUSTER_FLAG_E_VER_1 */ + +/** + * struct iwl_nan_cluster_notif - event sent when the device starts or joins a + * NAN cluster. + * + * @cluster_id: the last two bytes of the cluster ID + * @flags: combination of &enum iwl_nan_cluster_notif_flags + * @reserved: reserved + */ +struct iwl_nan_cluster_notif { + u8 cluster_id[2]; + u8 flags; + u8 reserved; +}; /* NAN_JOINED_CLUSTER_NTF_API_S_VER_1 */ + +/** + * struct iwl_nan_dw_end_notif - sent to notify the host the end of a DW. + * + * @band: band on which the DW ended. See &enum iwl_nan_band. + * @reserved: reserved + */ +struct iwl_nan_dw_end_notif { + u8 band; + u8 reserved[3]; +} __packed; /* NAN_DW_END_NTF_API_S_VER_1 */ + #endif /* __iwl_fw_api_mac_cfg_h__ */ diff --git a/sys/contrib/dev/iwlwifi/fw/api/nvm-reg.h b/sys/contrib/dev/iwlwifi/fw/api/nvm-reg.h index 4644fc1aa1ec..bd6bf931866f 100644 --- a/sys/contrib/dev/iwlwifi/fw/api/nvm-reg.h +++ b/sys/contrib/dev/iwlwifi/fw/api/nvm-reg.h @@ -503,18 +503,26 @@ enum bios_source { }; /** - * struct bios_value_u32 - BIOS configuration. + * struct iwl_bios_config_hdr - BIOS configuration header * @table_source: see &enum bios_source * @table_revision: table revision. * @reserved: reserved - * @value: value in bios. */ -struct bios_value_u32 { +struct iwl_bios_config_hdr { u8 table_source; u8 table_revision; u8 reserved[2]; +} __packed; /* BIOS_CONFIG_HDR_API_S_VER_1 */ + +/** + * struct bios_value_u32 - BIOS configuration. + * @hdr: bios config header + * @value: value in bios. + */ +struct bios_value_u32 { + struct iwl_bios_config_hdr hdr; __le32 value; -} __packed; /* BIOS_TABLE_SOURCE_U32_S_VER_1 */ +} __packed; /* BIOS_CONFIG_DATA_U32_API_S_VER_1 */ /** * struct iwl_tas_config_cmd - configures the TAS. @@ -650,6 +658,10 @@ struct iwl_lari_config_change_cmd_v8 { * bit0: enable 11be in China(CB/CN). * bit1: enable 11be in South Korea. * bit 2 - 31: reserved. + * @oem_11bn_allow_bitmap: Bitmap of 11bn allowed MCCs. The firmware expects to + * get the data from the BIOS. + * @oem_unii9_enable: UNII-9 enablement as read from the BIOS + * @bios_hdr: bios config header */ struct iwl_lari_config_change_cmd { __le32 config_bitmap; @@ -661,8 +673,16 @@ struct iwl_lari_config_change_cmd { __le32 edt_bitmap; __le32 oem_320mhz_allow_bitmap; __le32 oem_11be_allow_bitmap; + /* since version 13 */ + __le32 oem_11bn_allow_bitmap; + /* since version 13 */ + __le32 oem_unii9_enable; + /* since version 13 */ + struct iwl_bios_config_hdr bios_hdr; } __packed; -/* LARI_CHANGE_CONF_CMD_S_VER_12 */ +/* LARI_CHANGE_CONF_CMD_S_VER_12 + * LARI_CHANGE_CONF_CMD_S_VER_13 + */ /* Activate UNII-1 (5.2GHz) for World Wide */ #define ACTIVATE_5G2_IN_WW_MASK BIT(4) @@ -682,11 +702,11 @@ struct iwl_pnvm_init_complete_ntfy { /** * struct iwl_mcc_allowed_ap_type_cmd - struct for MCC_ALLOWED_AP_TYPE_CMD - * @offset_map: mapping a mcc to UHB AP type support (UATS) allowed + * @mcc_to_ap_type_map: mapping an MCC to 6 GHz AP type support (UATS) * @reserved: reserved */ struct iwl_mcc_allowed_ap_type_cmd { - u8 offset_map[UATS_TABLE_ROW_SIZE][UATS_TABLE_COL_SIZE]; + u8 mcc_to_ap_type_map[UATS_TABLE_ROW_SIZE][UATS_TABLE_COL_SIZE]; __le16 reserved; } __packed; /* MCC_ALLOWED_AP_TYPE_CMD_API_S_VER_1 */ diff --git a/sys/contrib/dev/iwlwifi/fw/api/power.h b/sys/contrib/dev/iwlwifi/fw/api/power.h index 535864e22626..0cd8a12e0f7c 100644 --- a/sys/contrib/dev/iwlwifi/fw/api/power.h +++ b/sys/contrib/dev/iwlwifi/fw/api/power.h @@ -766,7 +766,7 @@ enum iwl_6ghz_ap_type { * AP_TX_POWER_CONSTRAINTS_CMD * Used for VLP/LPI/AFC Access Point power constraints for 6GHz channels * @link_id: linkId - * @ap_type: see &enum iwl_ap_type + * @ap_type: see &enum iwl_6ghz_ap_type * @eirp_pwr: 8-bit 2s complement signed integer in the range * -64 dBm to 63 dBm with a 0.5 dB step * default &DEFAULT_TPE_TX_POWER (no maximum limit) diff --git a/sys/contrib/dev/iwlwifi/fw/api/rs.h b/sys/contrib/dev/iwlwifi/fw/api/rs.h index 9c464e7aba10..ae6be3ed32f8 100644 --- a/sys/contrib/dev/iwlwifi/fw/api/rs.h +++ b/sys/contrib/dev/iwlwifi/fw/api/rs.h @@ -73,6 +73,7 @@ enum iwl_tlc_mng_cfg_chains { * @IWL_TLC_MNG_MODE_VHT: enable VHT * @IWL_TLC_MNG_MODE_HE: enable HE * @IWL_TLC_MNG_MODE_EHT: enable EHT + * @IWL_TLC_MNG_MODE_UHR: enable UHR */ enum iwl_tlc_mng_cfg_mode { IWL_TLC_MNG_MODE_CCK = 0, @@ -82,6 +83,7 @@ enum iwl_tlc_mng_cfg_mode { IWL_TLC_MNG_MODE_VHT, IWL_TLC_MNG_MODE_HE, IWL_TLC_MNG_MODE_EHT, + IWL_TLC_MNG_MODE_UHR, }; /** @@ -205,7 +207,7 @@ struct iwl_tlc_config_cmd_v4 { } __packed; /* TLC_MNG_CONFIG_CMD_API_S_VER_4 */ /** - * struct iwl_tlc_config_cmd - TLC configuration + * struct iwl_tlc_config_cmd_v5 - TLC configuration * @sta_id: station id * @reserved1: reserved * @max_ch_width: max supported channel width from &enum iwl_tlc_mng_cfg_cw @@ -221,7 +223,7 @@ struct iwl_tlc_config_cmd_v4 { * @max_tx_op: max TXOP in uSecs for all AC (BK, BE, VO, VI), * set zero for no limit. */ -struct iwl_tlc_config_cmd { +struct iwl_tlc_config_cmd_v5 { u8 sta_id; u8 reserved1[3]; u8 max_ch_width; @@ -236,6 +238,38 @@ struct iwl_tlc_config_cmd { } __packed; /* TLC_MNG_CONFIG_CMD_API_S_VER_5 */ /** + * struct iwl_tlc_config_cmd - TLC configuration + * @sta_mask: station mask (in NAN we can have multiple logical stations of + * the same peer (with the same TLC configuration)). + * @phy_id: the phy id to used for this TLC configuration + * @max_ch_width: max supported channel width from &enum iwl_tlc_mng_cfg_cw + * @mode: &enum iwl_tlc_mng_cfg_mode + * @chains: bitmask of &enum iwl_tlc_mng_cfg_chains + * @sgi_ch_width_supp: bitmap of SGI support per channel width + * use BIT(&enum iwl_tlc_mng_cfg_cw) + * @flags: bitmask of &enum iwl_tlc_mng_cfg_flags + * @non_ht_rates: bitmap of supported legacy rates + * @ht_rates: bitmap of &enum iwl_tlc_mng_ht_rates, per <nss, channel-width> + * pair (0 - 80mhz width and below, 1 - 160mhz, 2 - 320mhz). + * @max_mpdu_len: max MPDU length, in bytes + * @max_tx_op: max TXOP in uSecs for all AC (BK, BE, VO, VI), + * set zero for no limit. + */ +struct iwl_tlc_config_cmd { + __le32 sta_mask; + __le32 phy_id; + u8 max_ch_width; + u8 mode; + u8 chains; + u8 sgi_ch_width_supp; + __le16 flags; + __le16 non_ht_rates; + __le32 ht_rates[IWL_TLC_NSS_MAX][IWL_TLC_MCS_PER_BW_NUM_V4]; + __le16 max_mpdu_len; + __le16 max_tx_op; +} __packed; /* TLC_MNG_CONFIG_CMD_API_S_VER_6 */ + +/** * enum iwl_tlc_update_flags - updated fields * @IWL_TLC_NOTIF_FLAG_RATE: last initial rate update * @IWL_TLC_NOTIF_FLAG_AMSDU: umsdu parameters update @@ -706,10 +740,11 @@ enum { #define RATE_MCS_HE_SU_4_LTF 3 #define RATE_MCS_HE_SU_4_LTF_08_GI 4 -/* Bit 24-23: HE type. (0) SU, (1) SU_EXT, (2) MU, (3) trigger based */ +/* Bit 24-23: HE type. (0) SU, (1) HE SU_EXT/UHR ELR, (2) MU, (3) trigger based */ #define RATE_MCS_HE_TYPE_POS 23 #define RATE_MCS_HE_TYPE_SU (0 << RATE_MCS_HE_TYPE_POS) #define RATE_MCS_HE_TYPE_EXT_SU (1 << RATE_MCS_HE_TYPE_POS) +#define RATE_MCS_HE_TYPE_UHR_ELR (1 << RATE_MCS_HE_TYPE_POS) #define RATE_MCS_HE_TYPE_MU (2 << RATE_MCS_HE_TYPE_POS) #define RATE_MCS_HE_TYPE_TRIG (3 << RATE_MCS_HE_TYPE_POS) #define RATE_MCS_HE_TYPE_MSK (3 << RATE_MCS_HE_TYPE_POS) diff --git a/sys/contrib/dev/iwlwifi/fw/api/rx.h b/sys/contrib/dev/iwlwifi/fw/api/rx.h index dbac7de00142..3ebf64bbc264 100644 --- a/sys/contrib/dev/iwlwifi/fw/api/rx.h +++ b/sys/contrib/dev/iwlwifi/fw/api/rx.h @@ -1077,13 +1077,37 @@ struct iwl_vht_sigs { #define OFDM_RX_FRAME_VHT_NUM_OF_DATA_SYM 0x000007ff #define OFDM_RX_FRAME_VHT_NUM_OF_DATA_SYM_VALID 0x80000000 __le32 a0; - __le32 a1, a2; +#define OFDM_RX_FRAME_VHT_BANDWIDTH 0x00000003 +#define OFDM_RX_FRAME_VHT_STBC 0x00000008 +#define OFDM_RX_FRAME_VHT_GRP_ID 0x000003f0 +#define OFDM_RX_FRAME_VHT_STS_USER0 0x00001c00 +#define OFDM_RX_FRAME_VHT_MU_STS_USER1 0x0000e000 +#define OFDM_RX_FRAME_VHT_MU_STS_USER2 0x00070000 +#define OFDM_RX_FRAME_VHT_MU_STS_USER3 0x00380000 +#define OFDM_RX_FRAME_VHT_PARTIAL_AID_OR_MU_STS 0x003fe000 +#define OFDM_RX_FRAME_VHT_MU_MIMO_USER_POSITION 0x03000000 +#define OFDM_RX_FRAME_VHT_NO_STREAMS 0x04000000 +#define OFDM_RX_FRAME_VHT_STS 0x38000000 + __le32 a1; +#define OFDM_RX_FRAME_VHT_SHORT_GI 0x00000001 +#define OFDM_RX_FRAME_VHT_SHORT_GI_AMBIG 0x00000002 +#define OFDM_RX_FRAME_VHT_CODING 0x00000004 +#define OFDM_RX_FRAME_VHT_CODING_EXTRA_SYM 0x00000008 +#define OFDM_RX_FRAME_VHT_MCS_OR_MU_CODING 0x000000f0 +#define OFDM_RX_FRAME_VHT_BF_OR_MU_RESERVED 0x00000100 +#define OFDM_RX_FRAME_VHT_CRC 0x0003fc00 +#define OFDM_RX_FRAME_VHT_CRC_OK_BIT 0x00040000 +#define OFDM_RX_FRAME_VHT_CUR_USER_CODING 0x00080000 +#define OFDM_RX_FRAME_VHT_CUR_USER_STS 0x00700000 + __le32 a2; }; struct iwl_he_sigs { #define OFDM_RX_FRAME_HE_BEAM_CHANGE 0x00000001 #define OFDM_RX_FRAME_HE_UL_FLAG 0x00000002 +/* SU/ER-SU: MCS, MU: SIG-B MCS */ #define OFDM_RX_FRAME_HE_MCS 0x0000003c +/* SU/ER-SU: DCM, MU: SIG-B DCM */ #define OFDM_RX_FRAME_HE_DCM 0x00000040 #define OFDM_RX_FRAME_HE_BSS_COLOR 0x00001f80 #define OFDM_RX_FRAME_HE_SPATIAL_REUSE 0x0001e000 @@ -1262,19 +1286,82 @@ struct iwl_eht_tb_sigs { }; struct iwl_uhr_sigs { - __le32 usig_a1, usig_a1_uhr, usig_a2_uhr, b1, b2; + /* same as EHT above */ + __le32 usig_a1; +#define OFDM_RX_FRAME_UHR_BSS_COLOR2 0x0000003f + __le32 usig_a1_uhr; +#define OFDM_RX_FRAME_UHR_PPDU_TYPE 0x00000003 +#define OFDM_RX_FRAME_UHR_COBF_CSR_DISABLE 0x00000004 +#define OFDM_RX_FRAME_UHR_PUNC_CHANNEL 0x000000f8 +#define OFDM_RX_FRAME_UHR_USIG2_VALIDATE_B8 0x00000100 +#define OFDM_RX_FRAME_UHR_SIG_MCS 0x00000600 +#define OFDM_RX_FRAME_UHR_SIG_SYM_NUM 0x0000f800 +#define OFDM_RX_FRAME_UHR_TRIG_SPATIAL_REUSE_1 0x000f0000 +#define OFDM_RX_FRAME_UHR_TRIG_SPATIAL_REUSE_2 0x00f00000 +#define OFDM_RX_FRAME_UHR_TRIG_USIG2_DISREGARD 0x1f000000 + __le32 usig_a2_uhr; +#define OFDM_RX_FRAME_UHR_SPATIAL_REUSE 0x0000000f +#define OFDM_RX_FRAME_UHR_GI_LTF_TYPE 0x00000030 +#define OFDM_RX_FRAME_UHR_NUM_OF_LTF_SYM 0x000001c0 +#define OFDM_RX_FRAME_UHR_CODING_EXTRA_SYM 0x00000200 +#define OFDM_RX_FRAME_UHR_PE_A_FACTOR 0x00000c00 +#define OFDM_RX_FRAME_UHR_PE_DISAMBIGUITY 0x00001000 +#define OFDM_RX_FRAME_UHR_IM_DISABLE 0x00002000 +#define OFDM_RX_FRAME_UHR_USIG_OVF_DISREGARD 0x0000c000 +#define OFDM_RX_FRAME_UHR_NUM_OF_USERS 0x00070000 +#define OFDM_RX_FRAME_UHR_NSTS 0x00f00000 +#define OFDM_RX_FRAME_UHR_BF 0x01000000 +#define OFDM_RX_FRAME_UHR_USIG_OVF_NDP_DISREGARD 0x06000000 +#define OFDM_RX_FRAME_UHR_COMM_CC1_CRC_OK 0x08000000 +#define OFDM_RX_FRAME_UHR_COMM_CC2_CRC_OK 0x10000000 +#define OFDM_RX_FRAME_UHR_NON_VALID_RU_ALLOC 0x20000000 + __le32 b1; +#define OFDM_RX_FRAME_UHR_MCS 0x000001f0 +#define OFDM_RX_FRAME_UHR_CODING 0x00000200 +#define OFDM_RX_FRAME_UHR_SPATIAL_CONFIG 0x00003c00 +#define OFDM_RX_FRAME_UHR_STA_RU 0x003fc000 +#define OFDM_RX_FRAME_UHR_STA_RU_PS160 0x00400000 +#define OFDM_RX_FRAME_UHR_UEQM 0x00800000 +#define OFDM_RX_FRAME_UHR_2XLDPC 0x01000000 +#define OFDM_RX_FRAME_UHR_UEQM_PATTERN 0x06000000 +#define OFDM_RX_FRAME_UHR_IS_MU_MIMO_USER_FIELD 0x08000000 +#define OFDM_RX_FRAME_UHR_USER_FIELD_CRC_OK 0x40000000 + __le32 b2; +#define OFDM_RX_UHR_NUM_OF_DATA_SYM 0x000007ff +#define OFDM_RX_UHR_PE_DURATION 0x00003800 __le32 sig2; + /* same as EHT above: OFDM_RX_FRAME_EHT_RU_ALLOC_* */ __le32 cmn[6]; +#define OFDM_RX_FRAME_UHR_USER_FIELD_ID 0x000007ff __le32 user_id; }; struct iwl_uhr_tb_sigs { - __le32 usig_a1, usig_a2_uhr, tb_rx0, tb_rx1; + /* same as UHR above */ + __le32 usig_a1, usig_a2_uhr; + /* same as HE above */ + __le32 tb_rx0, tb_rx1; }; struct iwl_uhr_elr_sigs { + /* same as UHR above */ __le32 usig_a1, usig_a2_uhr; - __le32 uhr_sig_elr1, uhr_sig_elr2; +#define OFDM_RX_VECTOR_UHR_ELR_VER_ID 0x00000007 +#define OFDM_RX_VECTOR_UHR_ELR_UPLINK_FLAG 0x00000008 +#define OFDM_RX_VECTOR_UHR_ELR_MCS 0x00000010 +#define OFDM_RX_VECTOR_UHR_ELR_CODING 0x00000020 +#define OFDM_RX_VECTOR_UHR_ELR_LENGTH_IN_SYM 0x00007fc0 +#define OFDM_RX_VECTOR_UHR_ELR_CODING_EXTRA_SYM 0x00008000 +#define OFDM_RX_VECTOR_UHR_ELR_SIG1_CRC_OK 0x00010000 +#define OFDM_RX_VECTOR_UHR_ELR_STA_ID 0x0ffe0000 +#define OFDM_RX_VECTOR_UHR_ELR_DISREGARD 0x70000000 + __le32 uhr_sig_elr1; +#define OFDM_RX_VECTOR_UHR_ELR_MARK_BSS_COLOR 0x0000003f +#define OFDM_RX_VECTOR_UHR_ELR_SIG_ID_INDX 0x00000e00 +#define OFDM_RX_VECTOR_UHR_ELR_STA_RU 0x000ff000 +#define OFDM_RX_VECTOR_UHR_ELR_STA_RU_PS160 0x00100000 +#define OFDM_RX_VECTOR_UHR_ELR_SIG2_CRC_OK 0x00200000 + __le32 uhr_sig_elr2; }; union iwl_sigs { diff --git a/sys/contrib/dev/iwlwifi/fw/api/scan.h b/sys/contrib/dev/iwlwifi/fw/api/scan.h index 60f0a4924ddf..46fcc32608e3 100644 --- a/sys/contrib/dev/iwlwifi/fw/api/scan.h +++ b/sys/contrib/dev/iwlwifi/fw/api/scan.h @@ -1157,6 +1157,16 @@ enum iwl_umac_scan_abort_status { }; /** + * struct iwl_umac_scan_start - scan start notification + * @uid: scan id, &enum iwl_umac_scan_uid_offsets + * @reserved: for future use + */ +struct iwl_umac_scan_start { + __le32 uid; + __le32 reserved; +} __packed; /* SCAN_START_UMAC_API_S_VER_1 */ + +/** * struct iwl_umac_scan_complete - scan complete notification * @uid: scan id, &enum iwl_umac_scan_uid_offsets * @last_schedule: last scheduling line diff --git a/sys/contrib/dev/iwlwifi/fw/dbg.c b/sys/contrib/dev/iwlwifi/fw/dbg.c index 86ed11bfdff3..4d97c0626547 100644 --- a/sys/contrib/dev/iwlwifi/fw/dbg.c +++ b/sys/contrib/dev/iwlwifi/fw/dbg.c @@ -598,7 +598,7 @@ static struct scatterlist *alloc_sgtable(ssize_t size) nents -= n_fill; } - new = kcalloc(n_alloc, sizeof(*new), GFP_KERNEL); + new = kzalloc_objs(*new, n_alloc); if (!new) { if (result) _devcd_free_sgtable(result); @@ -2981,8 +2981,7 @@ int iwl_fw_dbg_error_collect(struct iwl_fw_runtime *fwrt, struct iwl_fw_dump_desc *iwl_dump_error_desc; int ret; - iwl_dump_error_desc = - kmalloc(sizeof(*iwl_dump_error_desc), GFP_KERNEL); + iwl_dump_error_desc = kmalloc_obj(*iwl_dump_error_desc); if (!iwl_dump_error_desc) return -ENOMEM; @@ -3034,7 +3033,7 @@ int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt, delay = le32_to_cpu(trigger->stop_delay) * USEC_PER_MSEC; } - desc = kzalloc(struct_size(desc, trig_desc.data, len), GFP_ATOMIC); + desc = kzalloc_flex(*desc, trig_desc.data, len, GFP_ATOMIC); if (!desc) return -ENOMEM; diff --git a/sys/contrib/dev/iwlwifi/fw/debugfs.c b/sys/contrib/dev/iwlwifi/fw/debugfs.c index 3b0e8c43ba4a..ddee7c2deb36 100644 --- a/sys/contrib/dev/iwlwifi/fw/debugfs.c +++ b/sys/contrib/dev/iwlwifi/fw/debugfs.c @@ -7,6 +7,7 @@ #include "api/commands.h" #include "debugfs.h" #include "dbg.h" +#include <linux/hex.h> #include <linux/seq_file.h> #define FWRT_DEBUGFS_OPEN_WRAPPER(name, buflen, argtype) \ @@ -359,7 +360,7 @@ static void *iwl_dbgfs_fw_info_seq_start(struct seq_file *seq, loff_t *pos) if (*pos >= fw->ucode_capa.n_cmd_versions) return NULL; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) return NULL; state->pos = *pos; diff --git a/sys/contrib/dev/iwlwifi/fw/file.h b/sys/contrib/dev/iwlwifi/fw/file.h index b9e0b69c6680..378788de1d74 100644 --- a/sys/contrib/dev/iwlwifi/fw/file.h +++ b/sys/contrib/dev/iwlwifi/fw/file.h @@ -447,6 +447,7 @@ typedef unsigned int __bitwise iwl_ucode_tlv_capa_t; * during assert handling even if the dump isn't split * @IWL_UCODE_TLV_CAPA_FW_ACCEPTS_RAW_DSM_TABLE: Firmware has capability of * handling raw DSM table data. + * @IWL_UCODE_TLV_CAPA_NAN_SYNC_SUPPORT: Supports NAN synchronization * * @NUM_IWL_UCODE_TLV_CAPA: number of bits used */ @@ -550,6 +551,7 @@ enum iwl_ucode_tlv_capa { IWL_UCODE_TLV_CAPA_RESET_DURING_ASSERT = (__force iwl_ucode_tlv_capa_t)(4 * 32 + 0), IWL_UCODE_TLV_CAPA_FW_ACCEPTS_RAW_DSM_TABLE = (__force iwl_ucode_tlv_capa_t)(4 * 32 + 1), + IWL_UCODE_TLV_CAPA_NAN_SYNC_SUPPORT = (__force iwl_ucode_tlv_capa_t)(4 * 32 + 2), NUM_IWL_UCODE_TLV_CAPA /* * This construction make both sparse (which cannot increment the previous diff --git a/sys/contrib/dev/iwlwifi/fw/pnvm.c b/sys/contrib/dev/iwlwifi/fw/pnvm.c index f297e82d63d2..afff8d51ca95 100644 --- a/sys/contrib/dev/iwlwifi/fw/pnvm.c +++ b/sys/contrib/dev/iwlwifi/fw/pnvm.c @@ -379,7 +379,7 @@ iwl_pnvm_load_pnvm_to_trans(struct iwl_trans *trans, return; } - pnvm_data = kzalloc(sizeof(*pnvm_data), GFP_KERNEL); + pnvm_data = kzalloc_obj(*pnvm_data); if (!pnvm_data) goto free; @@ -425,7 +425,7 @@ iwl_pnvm_load_reduce_power_to_trans(struct iwl_trans *trans, return; } - pnvm_data = kzalloc(sizeof(*pnvm_data), GFP_KERNEL); + pnvm_data = kzalloc_obj(*pnvm_data); if (!pnvm_data) goto free; diff --git a/sys/contrib/dev/iwlwifi/fw/regulatory.c b/sys/contrib/dev/iwlwifi/fw/regulatory.c index 476b930a5bcd..b40cfada866c 100644 --- a/sys/contrib/dev/iwlwifi/fw/regulatory.c +++ b/sys/contrib/dev/iwlwifi/fw/regulatory.c @@ -379,8 +379,10 @@ int iwl_fill_ppag_table(struct iwl_fw_runtime *fwrt, num_sub_bands = IWL_NUM_SUB_BANDS_V2; gain = cmd->v7.gain[0]; *cmd_size = sizeof(cmd->v7); - cmd->v7.ppag_config_info.table_source = fwrt->ppag_bios_source; - cmd->v7.ppag_config_info.table_revision = fwrt->ppag_bios_rev; + cmd->v7.ppag_config_info.hdr.table_source = + fwrt->ppag_bios_source; + cmd->v7.ppag_config_info.hdr.table_revision = + fwrt->ppag_bios_rev; cmd->v7.ppag_config_info.value = cpu_to_le32(fwrt->ppag_flags); } else { IWL_DEBUG_RADIO(fwrt, "Unsupported PPAG command version\n"); @@ -491,206 +493,6 @@ bool iwl_add_mcc_to_tas_block_list(u16 *list, u8 *size, u16 mcc) } IWL_EXPORT_SYMBOL(iwl_add_mcc_to_tas_block_list); -__le32 iwl_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt) -{ - int ret; - u32 val; - __le32 config_bitmap = 0; - - switch (CSR_HW_RFID_TYPE(fwrt->trans->info.hw_rf_id)) { - case IWL_CFG_RF_TYPE_HR1: - case IWL_CFG_RF_TYPE_HR2: - case IWL_CFG_RF_TYPE_JF1: - case IWL_CFG_RF_TYPE_JF2: - ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ENABLE_INDONESIA_5G2, - &val); - - if (!ret && val == DSM_VALUE_INDONESIA_ENABLE) - config_bitmap |= - cpu_to_le32(LARI_CONFIG_ENABLE_5G2_IN_INDONESIA_MSK); - break; - default: - break; - } - - ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_DISABLE_SRD, &val); - if (!ret) { - if (val == DSM_VALUE_SRD_PASSIVE) - config_bitmap |= - cpu_to_le32(LARI_CONFIG_CHANGE_ETSI_TO_PASSIVE_MSK); - else if (val == DSM_VALUE_SRD_DISABLE) - config_bitmap |= - cpu_to_le32(LARI_CONFIG_CHANGE_ETSI_TO_DISABLED_MSK); - } - - if (fw_has_capa(&fwrt->fw->ucode_capa, - IWL_UCODE_TLV_CAPA_CHINA_22_REG_SUPPORT)) { - ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_REGULATORY_CONFIG, - &val); - /* - * China 2022 enable if the BIOS object does not exist or - * if it is enabled in BIOS. - */ - if (ret < 0 || val & DSM_MASK_CHINA_22_REG) - config_bitmap |= - cpu_to_le32(LARI_CONFIG_ENABLE_CHINA_22_REG_SUPPORT_MSK); - } - - return config_bitmap; -} -IWL_EXPORT_SYMBOL(iwl_get_lari_config_bitmap); - -static size_t iwl_get_lari_config_cmd_size(u8 cmd_ver) -{ - size_t cmd_size; - - switch (cmd_ver) { - case 12: - cmd_size = sizeof(struct iwl_lari_config_change_cmd); - break; - case 8: - cmd_size = sizeof(struct iwl_lari_config_change_cmd_v8); - break; - case 6: - cmd_size = sizeof(struct iwl_lari_config_change_cmd_v6); - break; - default: - cmd_size = sizeof(struct iwl_lari_config_change_cmd_v1); - break; - } - return cmd_size; -} - -int iwl_fill_lari_config(struct iwl_fw_runtime *fwrt, - struct iwl_lari_config_change_cmd *cmd, - size_t *cmd_size) -{ - int ret; - u32 value; - bool has_raw_dsm_capa = fw_has_capa(&fwrt->fw->ucode_capa, - IWL_UCODE_TLV_CAPA_FW_ACCEPTS_RAW_DSM_TABLE); - u8 cmd_ver = iwl_fw_lookup_cmd_ver(fwrt->fw, - WIDE_ID(REGULATORY_AND_NVM_GROUP, - LARI_CONFIG_CHANGE), 1); - - if (WARN_ONCE(cmd_ver > 12, - "Don't add newer versions to this function\n")) - return -EINVAL; - - memset(cmd, 0, sizeof(*cmd)); - *cmd_size = iwl_get_lari_config_cmd_size(cmd_ver); - - cmd->config_bitmap = iwl_get_lari_config_bitmap(fwrt); - - ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_11AX_ENABLEMENT, &value); - if (!ret) { - if (!has_raw_dsm_capa) - value &= DSM_11AX_ALLOW_BITMAP; - cmd->oem_11ax_allow_bitmap = cpu_to_le32(value); - } - - ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ENABLE_UNII4_CHAN, &value); - if (!ret) { - if (!has_raw_dsm_capa) - value &= DSM_UNII4_ALLOW_BITMAP; - - /* Since version 12, bits 4 and 5 are supported - * regardless of this capability, By pass this masking - * if firmware has capability of accepting raw DSM table. - */ - if (!has_raw_dsm_capa && cmd_ver < 12 && - !fw_has_capa(&fwrt->fw->ucode_capa, - IWL_UCODE_TLV_CAPA_BIOS_OVERRIDE_5G9_FOR_CA)) - value &= ~(DSM_VALUE_UNII4_CANADA_OVERRIDE_MSK | - DSM_VALUE_UNII4_CANADA_EN_MSK); - - cmd->oem_unii4_allow_bitmap = cpu_to_le32(value); - } - - ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ACTIVATE_CHANNEL, &value); - if (!ret) { - if (!has_raw_dsm_capa) - value &= CHAN_STATE_ACTIVE_BITMAP_CMD_V12; - - if (!has_raw_dsm_capa && cmd_ver < 8) - value &= ~ACTIVATE_5G2_IN_WW_MASK; - - /* Since version 12, bits 5 and 6 are supported - * regardless of this capability, By pass this masking - * if firmware has capability of accepting raw DSM table. - */ - if (!has_raw_dsm_capa && cmd_ver < 12 && - !fw_has_capa(&fwrt->fw->ucode_capa, - IWL_UCODE_TLV_CAPA_BIOS_OVERRIDE_UNII4_US_CA)) - value &= CHAN_STATE_ACTIVE_BITMAP_CMD_V8; - - cmd->chan_state_active_bitmap = cpu_to_le32(value); - } - - ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ENABLE_6E, &value); - if (!ret) - cmd->oem_uhb_allow_bitmap = cpu_to_le32(value); - - ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_FORCE_DISABLE_CHANNELS, &value); - if (!ret) { - if (!has_raw_dsm_capa) - value &= DSM_FORCE_DISABLE_CHANNELS_ALLOWED_BITMAP; - cmd->force_disable_channels_bitmap = cpu_to_le32(value); - } - - ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ENERGY_DETECTION_THRESHOLD, - &value); - if (!ret) { - if (!has_raw_dsm_capa) - value &= DSM_EDT_ALLOWED_BITMAP; - cmd->edt_bitmap = cpu_to_le32(value); - } - - ret = iwl_bios_get_wbem(fwrt, &value); - if (!ret) - cmd->oem_320mhz_allow_bitmap = cpu_to_le32(value); - - ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ENABLE_11BE, &value); - if (!ret) - cmd->oem_11be_allow_bitmap = cpu_to_le32(value); - - if (cmd->config_bitmap || - cmd->oem_uhb_allow_bitmap || - cmd->oem_11ax_allow_bitmap || - cmd->oem_unii4_allow_bitmap || - cmd->chan_state_active_bitmap || - cmd->force_disable_channels_bitmap || - cmd->edt_bitmap || - cmd->oem_320mhz_allow_bitmap || - cmd->oem_11be_allow_bitmap) { - IWL_DEBUG_RADIO(fwrt, - "sending LARI_CONFIG_CHANGE, config_bitmap=0x%x, oem_11ax_allow_bitmap=0x%x\n", - le32_to_cpu(cmd->config_bitmap), - le32_to_cpu(cmd->oem_11ax_allow_bitmap)); - IWL_DEBUG_RADIO(fwrt, - "sending LARI_CONFIG_CHANGE, oem_unii4_allow_bitmap=0x%x, chan_state_active_bitmap=0x%x, cmd_ver=%d\n", - le32_to_cpu(cmd->oem_unii4_allow_bitmap), - le32_to_cpu(cmd->chan_state_active_bitmap), - cmd_ver); - IWL_DEBUG_RADIO(fwrt, - "sending LARI_CONFIG_CHANGE, oem_uhb_allow_bitmap=0x%x, force_disable_channels_bitmap=0x%x\n", - le32_to_cpu(cmd->oem_uhb_allow_bitmap), - le32_to_cpu(cmd->force_disable_channels_bitmap)); - IWL_DEBUG_RADIO(fwrt, - "sending LARI_CONFIG_CHANGE, edt_bitmap=0x%x, oem_320mhz_allow_bitmap=0x%x\n", - le32_to_cpu(cmd->edt_bitmap), - le32_to_cpu(cmd->oem_320mhz_allow_bitmap)); - IWL_DEBUG_RADIO(fwrt, - "sending LARI_CONFIG_CHANGE, oem_11be_allow_bitmap=0x%x\n", - le32_to_cpu(cmd->oem_11be_allow_bitmap)); - } else { - return 1; - } - - return 0; -} -IWL_EXPORT_SYMBOL(iwl_fill_lari_config); - int iwl_bios_get_dsm(struct iwl_fw_runtime *fwrt, enum iwl_dsm_funcs func, u32 *value) { diff --git a/sys/contrib/dev/iwlwifi/fw/regulatory.h b/sys/contrib/dev/iwlwifi/fw/regulatory.h index 735482e7adf5..1489031687b7 100644 --- a/sys/contrib/dev/iwlwifi/fw/regulatory.h +++ b/sys/contrib/dev/iwlwifi/fw/regulatory.h @@ -125,7 +125,9 @@ enum iwl_dsm_funcs { DSM_FUNC_ENERGY_DETECTION_THRESHOLD = 10, DSM_FUNC_RFI_CONFIG = 11, DSM_FUNC_ENABLE_11BE = 12, - DSM_FUNC_NUM_FUNCS = 13, + DSM_FUNC_ENABLE_11BN = 13, + DSM_FUNC_ENABLE_UNII_9 = 14, + DSM_FUNC_NUM_FUNCS, }; enum iwl_dsm_values_srd { @@ -218,11 +220,6 @@ int iwl_bios_get_mcc(struct iwl_fw_runtime *fwrt, char *mcc); int iwl_bios_get_eckv(struct iwl_fw_runtime *fwrt, u32 *ext_clk); int iwl_bios_get_wbem(struct iwl_fw_runtime *fwrt, u32 *value); -__le32 iwl_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt); -int iwl_fill_lari_config(struct iwl_fw_runtime *fwrt, - struct iwl_lari_config_change_cmd *cmd, - size_t *cmd_size); - int iwl_bios_get_dsm(struct iwl_fw_runtime *fwrt, enum iwl_dsm_funcs func, u32 *value); diff --git a/sys/contrib/dev/iwlwifi/fw/runtime.h b/sys/contrib/dev/iwlwifi/fw/runtime.h index 57570ff15622..ff186fb2e0da 100644 --- a/sys/contrib/dev/iwlwifi/fw/runtime.h +++ b/sys/contrib/dev/iwlwifi/fw/runtime.h @@ -116,10 +116,14 @@ struct iwl_txf_iter_data { * @phy_filters: specific phy filters as read from WPFC BIOS table * @ppag_bios_rev: PPAG BIOS revision * @ppag_bios_source: see &enum bios_source - * @acpi_dsm_funcs_valid: bitmap indicating which DSM values are valid, + * @dsm_funcs_valid: bitmap indicating which DSM values are valid, * zero (default initialization) means it hasn't been read yet, * and BIT(0) is set when it has since function 0 also has this - * bitmap and is always supported + * bitmap and is always supported. + * If the bit is set for a specific function, then the corresponding + * entry in &dsm_values is valid. + * @dsm_values: cache of the DSM values. The validity of each entry is + * determined by &dsm_funcs_valid. * @geo_enabled: WGDS table is present * @geo_num_profiles: number of geo profiles * @geo_rev: geo profiles table revision @@ -137,6 +141,8 @@ struct iwl_txf_iter_data { * @timestamp.seq: timestamp marking sequence * @timestamp.delay: timestamp marking worker delay * @tpc_enabled: TPC enabled + * @dsm_source: one of &enum bios_source. UEFI, ACPI or NONE + * @dsm_revision: the revision of the DSM table */ struct iwl_fw_runtime { struct iwl_trans *trans; @@ -211,9 +217,12 @@ struct iwl_fw_runtime { bool uats_valid; u8 uefi_tables_lock_status; struct iwl_phy_specific_cfg phy_filters; + enum bios_source dsm_source; + u8 dsm_revision; -#ifdef CONFIG_ACPI - u32 acpi_dsm_funcs_valid; +#if defined(CONFIG_ACPI) || defined(CONFIG_EFI) + u32 dsm_funcs_valid; + u32 dsm_values[DSM_FUNC_NUM_FUNCS]; #endif }; diff --git a/sys/contrib/dev/iwlwifi/fw/smem.c b/sys/contrib/dev/iwlwifi/fw/smem.c index 90fd69b4860c..344ddde85b18 100644 --- a/sys/contrib/dev/iwlwifi/fw/smem.c +++ b/sys/contrib/dev/iwlwifi/fw/smem.c @@ -6,6 +6,7 @@ */ #include "iwl-drv.h" #include "runtime.h" +#include "dbg.h" #include "fw/api/commands.h" static void iwl_parse_shared_mem_22000(struct iwl_fw_runtime *fwrt, @@ -17,7 +18,9 @@ static void iwl_parse_shared_mem_22000(struct iwl_fw_runtime *fwrt, u8 api_ver = iwl_fw_lookup_notif_ver(fwrt->fw, SYSTEM_GROUP, SHARED_MEM_CFG_CMD, 0); - if (WARN_ON(lmac_num > ARRAY_SIZE(mem_cfg->lmac_smem))) + /* Note: notification has 3 entries, but we only expect 2 */ + if (IWL_FW_CHECK(fwrt, lmac_num > ARRAY_SIZE(fwrt->smem_cfg.lmac), + "FW advertises %d LMACs\n", lmac_num)) return; fwrt->smem_cfg.num_lmacs = lmac_num; @@ -26,7 +29,8 @@ static void iwl_parse_shared_mem_22000(struct iwl_fw_runtime *fwrt, fwrt->smem_cfg.rxfifo2_size = le32_to_cpu(mem_cfg->rxfifo2_size); if (api_ver >= 4 && - !WARN_ON_ONCE(iwl_rx_packet_payload_len(pkt) < sizeof(*mem_cfg))) { + !IWL_FW_CHECK(fwrt, iwl_rx_packet_payload_len(pkt) < sizeof(*mem_cfg), + "bad shared mem notification size\n")) { fwrt->smem_cfg.rxfifo2_control_size = le32_to_cpu(mem_cfg->rxfifo2_control_size); } diff --git a/sys/contrib/dev/iwlwifi/fw/uefi.c b/sys/contrib/dev/iwlwifi/fw/uefi.c index 4ae4d215e633..a7ba86e06c09 100644 --- a/sys/contrib/dev/iwlwifi/fw/uefi.c +++ b/sys/contrib/dev/iwlwifi/fw/uefi.c @@ -402,8 +402,9 @@ static int iwl_uefi_uats_parse(struct uefi_cnv_wlan_uats_data *uats_data, if (uats_data->revision != 1) return -EINVAL; - memcpy(fwrt->uats_table.offset_map, uats_data->offset_map, - sizeof(fwrt->uats_table.offset_map)); + memcpy(fwrt->uats_table.mcc_to_ap_type_map, + uats_data->mcc_to_ap_type_map, + sizeof(fwrt->uats_table.mcc_to_ap_type_map)); fwrt->uats_valid = true; @@ -721,17 +722,12 @@ out: return ret; } -int iwl_uefi_get_dsm(struct iwl_fw_runtime *fwrt, enum iwl_dsm_funcs func, - u32 *value) +static int iwl_uefi_load_dsm_values(struct iwl_fw_runtime *fwrt) { struct uefi_cnv_var_general_cfg *data; int ret = -EINVAL; - BUILD_BUG_ON(ARRAY_SIZE(data->functions) < DSM_FUNC_NUM_FUNCS); - - /* Not supported function index */ - if (func >= DSM_FUNC_NUM_FUNCS || func == 5) - return -EOPNOTSUPP; + BUILD_BUG_ON(ARRAY_SIZE(data->functions) < ARRAY_SIZE(fwrt->dsm_values)); data = iwl_uefi_get_verified_variable(fwrt->trans, IWL_UEFI_DSM_NAME, "DSM", sizeof(*data), NULL); @@ -743,24 +739,66 @@ int iwl_uefi_get_dsm(struct iwl_fw_runtime *fwrt, enum iwl_dsm_funcs func, data->revision); goto out; } + fwrt->dsm_revision = data->revision; + fwrt->dsm_source = BIOS_SOURCE_UEFI; - if (!(data->functions[DSM_FUNC_QUERY] & BIT(func))) { - IWL_DEBUG_RADIO(fwrt, "DSM func %d not in 0x%x\n", - func, data->functions[DSM_FUNC_QUERY]); - goto out; - } + fwrt->dsm_funcs_valid = data->functions[DSM_FUNC_QUERY]; - *value = data->functions[func]; + /* + * Make sure we don't load the DSM values twice. Set this only after we + * validated the DSM table so that if the table in UEFI is not valid, + * we will fallback to ACPI. + */ + fwrt->dsm_funcs_valid |= BIT(DSM_FUNC_QUERY); - IWL_DEBUG_RADIO(fwrt, - "UEFI: DSM func=%d: value=%d\n", func, *value); + for (int func = 1; func < ARRAY_SIZE(fwrt->dsm_values); func++) { + if (!(fwrt->dsm_funcs_valid & BIT(func))) { + IWL_DEBUG_RADIO(fwrt, "DSM func %d not in 0x%x\n", + func, fwrt->dsm_funcs_valid); + continue; + } + fwrt->dsm_values[func] = data->functions[func]; + + IWL_DEBUG_RADIO(fwrt, + "UEFI: DSM func=%d: value=%d\n", func, + fwrt->dsm_values[func]); + } ret = 0; + out: kfree(data); return ret; } +int iwl_uefi_get_dsm(struct iwl_fw_runtime *fwrt, enum iwl_dsm_funcs func, + u32 *value) +{ + /* Not supported function index */ + if (func >= DSM_FUNC_NUM_FUNCS || func == 5) + return -EOPNOTSUPP; + + if (!fwrt->dsm_funcs_valid) { + int ret = iwl_uefi_load_dsm_values(fwrt); + + if (ret) + return ret; + } + + if (!(fwrt->dsm_funcs_valid & BIT(func))) { + IWL_DEBUG_RADIO(fwrt, "DSM func %d not in 0x%x\n", + func, fwrt->dsm_funcs_valid); + return -EINVAL; + } + + *value = fwrt->dsm_values[func]; + + IWL_DEBUG_RADIO(fwrt, + "UEFI: DSM func=%d: value=%d\n", func, *value); + + return 0; +} + int iwl_uefi_get_puncturing(struct iwl_fw_runtime *fwrt) { struct uefi_cnv_var_puncturing_data *data; diff --git a/sys/contrib/dev/iwlwifi/fw/uefi.h b/sys/contrib/dev/iwlwifi/fw/uefi.h index da9d242d85b6..d350141ad9bb 100644 --- a/sys/contrib/dev/iwlwifi/fw/uefi.h +++ b/sys/contrib/dev/iwlwifi/fw/uefi.h @@ -60,7 +60,7 @@ struct uefi_cnv_wlan_sgom_data { struct uefi_cnv_wlan_uats_data { u8 revision; - u8 offset_map[IWL_UATS_MAP_SIZE - 1]; + u8 mcc_to_ap_type_map[IWL_UATS_MAP_SIZE - 1]; } __packed; struct uefi_cnv_common_step_data { |
