summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/intel/iwlwifi/fw
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/fw')
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/acpi.c38
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/binding.h6
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/commands.h23
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/context.h13
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/d3.h2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/datapath.h6
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/location.h16
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h65
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/mac.h24
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h11
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/offload.h3
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/phy-ctxt.h6
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/phy.h10
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/power.h2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/rx.h4
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/time-event.h7
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/dbg.c12
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/file.h5
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/pnvm.c234
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/pnvm.h5
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/uefi.c272
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/uefi.h47
22 files changed, 492 insertions, 319 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c
index cb9181f05501..018d820ae231 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c
@@ -41,6 +41,34 @@ static const struct dmi_system_id dmi_ppag_approved_list[] = {
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"),
+ },
+ },
{}
};
@@ -1149,7 +1177,15 @@ int iwl_read_ppag_table(struct iwl_fw_runtime *fwrt, union iwl_ppag_table_cmd *c
IWL_DEBUG_RADIO(fwrt,
"PPAG table rev is %d but FW supports v1, sending truncated table\n",
fwrt->ppag_ver);
- cmd->v1.flags &= cpu_to_le32(IWL_PPAG_ETSI_MASK);
+ if (!fw_has_capa(&fwrt->fw->ucode_capa,
+ IWL_UCODE_TLV_CAPA_PPAG_CHINA_BIOS_SUPPORT)) {
+ cmd->v1.flags &= cpu_to_le32(IWL_PPAG_ETSI_MASK);
+ IWL_DEBUG_RADIO(fwrt,
+ "FW doesn't support ppag China bit\n");
+ } else {
+ IWL_DEBUG_RADIO(fwrt,
+ "FW supports ppag China bit\n");
+ }
}
} else if (cmd_ver >= 2 && cmd_ver <= 4) {
num_sub_bands = IWL_NUM_SUB_BANDS_V2;
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/binding.h b/drivers/net/wireless/intel/iwlwifi/fw/api/binding.h
index 29e2816e7052..b6b5959cb259 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/binding.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/binding.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
- * Copyright (C) 2012-2014, 2020 Intel Corporation
+ * Copyright (C) 2012-2014, 2020, 2022 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2016-2017 Intel Deutschland GmbH
*/
@@ -18,7 +18,7 @@
* ( BINDING_CONTEXT_CMD = 0x2b )
* @id_and_color: ID and color of the relevant Binding,
* &enum iwl_ctxt_id_and_color
- * @action: action to perform, one of FW_CTXT_ACTION_*
+ * @action: action to perform, see &enum iwl_ctxt_action
* @macs: array of MAC id and colors which belong to the binding,
* &enum iwl_ctxt_id_and_color
* @phy: PHY id and color which belongs to the binding,
@@ -38,7 +38,7 @@ struct iwl_binding_cmd_v1 {
* ( BINDING_CONTEXT_CMD = 0x2b )
* @id_and_color: ID and color of the relevant Binding,
* &enum iwl_ctxt_id_and_color
- * @action: action to perform, one of FW_CTXT_ACTION_*
+ * @action: action to perform, see &enum iwl_ctxt_action
* @macs: array of MAC id and colors which belong to the binding
* &enum iwl_ctxt_id_and_color
* @phy: PHY id and color which belongs to the binding
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h b/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h
index 111d96cbde6f..13cb0d53a1a3 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h
@@ -139,11 +139,6 @@ enum iwl_legacy_cmds {
REMOVE_STA = 0x19,
/**
- * @FW_GET_ITEM_CMD: uses &struct iwl_fw_get_item_cmd
- */
- FW_GET_ITEM_CMD = 0x1a,
-
- /**
* @TX_CMD: uses &struct iwl_tx_cmd or &struct iwl_tx_cmd_gen2 or
* &struct iwl_tx_cmd_gen3,
* response in &struct iwl_mvm_tx_resp or
@@ -534,12 +529,6 @@ enum iwl_legacy_cmds {
PROT_OFFLOAD_CONFIG_CMD = 0xd4,
/**
- * @OFFLOADS_QUERY_CMD:
- * No data in command, response in &struct iwl_wowlan_status
- */
- OFFLOADS_QUERY_CMD = 0xd5,
-
- /**
* @D0I3_END_CMD: End D0i3/D3 state, no command data
*/
D0I3_END_CMD = 0xed,
@@ -566,18 +555,22 @@ enum iwl_legacy_cmds {
WOWLAN_TKIP_PARAM = 0xe3,
/**
- * @WOWLAN_KEK_KCK_MATERIAL: &struct iwl_wowlan_kek_kck_material_cmd
+ * @WOWLAN_KEK_KCK_MATERIAL: &struct iwl_wowlan_kek_kck_material_cmd_v2,
+ * &struct iwl_wowlan_kek_kck_material_cmd_v3 or
+ * &struct iwl_wowlan_kek_kck_material_cmd_v4
*/
WOWLAN_KEK_KCK_MATERIAL = 0xe4,
/**
- * @WOWLAN_GET_STATUSES: response in &struct iwl_wowlan_status
+ * @WOWLAN_GET_STATUSES: response in &struct iwl_wowlan_status_v6,
+ * &struct iwl_wowlan_status_v7, &struct iwl_wowlan_status_v9 or
+ * &struct iwl_wowlan_status_v12
*/
WOWLAN_GET_STATUSES = 0xe5,
/**
- * @SCAN_OFFLOAD_PROFILES_QUERY_CMD:
- * No command data, response is &struct iwl_scan_offload_profiles_query
+ * @SCAN_OFFLOAD_PROFILES_QUERY_CMD: No command data, response is
+ * &struct iwl_scan_offload_profiles_query_v1
*/
SCAN_OFFLOAD_PROFILES_QUERY_CMD = 0x56,
};
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/context.h b/drivers/net/wireless/intel/iwlwifi/fw/api/context.h
index 105ba7170c3f..1fa5678c1cd6 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/context.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/context.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
- * Copyright (C) 2012-2014 Intel Corporation
+ * Copyright (C) 2012-2014, 2022 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2016-2017 Intel Deutschland GmbH
*/
@@ -26,13 +26,18 @@ enum iwl_ctxt_id_and_color {
#define FW_CMD_ID_AND_COLOR(_id, _color) (((_id) << FW_CTXT_ID_POS) |\
((_color) << FW_CTXT_COLOR_POS))
-/* Possible actions on PHYs, MACs and Bindings */
+/**
+ * enum iwl_ctxt_action - Posssible actions on PHYs, MACs, Bindings and other
+ * @FW_CTXT_ACTION_INVALID: unused, invalid action
+ * @FW_CTXT_ACTION_ADD: add the context
+ * @FW_CTXT_ACTION_MODIFY: modify the context
+ * @FW_CTXT_ACTION_REMOVE: remove the context
+ */
enum iwl_ctxt_action {
- FW_CTXT_ACTION_STUB = 0,
+ FW_CTXT_ACTION_INVALID = 0,
FW_CTXT_ACTION_ADD,
FW_CTXT_ACTION_MODIFY,
FW_CTXT_ACTION_REMOVE,
- FW_CTXT_ACTION_NUM
}; /* COMMON_CONTEXT_ACTION_API_E_VER_1 */
#endif /* __iwl_fw_api_context_h__ */
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h b/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h
index 8a613e150a02..37ac2364e714 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h
@@ -47,12 +47,14 @@ struct iwl_d3_manager_config {
* @IWL_D3_PROTO_OFFLOAD_NS: NS (Neighbor Solicitation) is enabled
* @IWL_D3_PROTO_IPV4_VALID: IPv4 data is valid
* @IWL_D3_PROTO_IPV6_VALID: IPv6 data is valid
+ * @IWL_D3_PROTO_REJECT_BTM: reject BTM request
*/
enum iwl_proto_offloads {
IWL_D3_PROTO_OFFLOAD_ARP = BIT(0),
IWL_D3_PROTO_OFFLOAD_NS = BIT(1),
IWL_D3_PROTO_IPV4_VALID = BIT(2),
IWL_D3_PROTO_IPV6_VALID = BIT(3),
+ IWL_D3_PROTO_REJECT_BTM = BIT(4),
};
#define IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V1 2
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/datapath.h b/drivers/net/wireless/intel/iwlwifi/fw/api/datapath.h
index 6f59381b9f9a..751b596ea1a5 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/datapath.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/datapath.h
@@ -38,7 +38,9 @@ enum iwl_data_path_subcmd_ids {
WNM_80211V_TIMING_MEASUREMENT_CONFIG_CMD = 0x4,
/**
- * @STA_HE_CTXT_CMD: &struct iwl_he_sta_context_cmd
+ * @STA_HE_CTXT_CMD: &struct iwl_he_sta_context_cmd_v1,
+ * &struct iwl_he_sta_context_cmd_v2 or
+ * &struct iwl_he_sta_context_cmd_v3
*/
STA_HE_CTXT_CMD = 0x7,
@@ -447,7 +449,7 @@ struct iwl_sad_properties {
* @phy_id: PHY index
* @rlc: RLC properties, &struct iwl_rlc_properties
* @sad: SAD (single antenna diversity) options, &struct iwl_sad_properties
- * @flags: flags, &enum iwl_rlc_flags
+ * @flags: flags (unused)
* @reserved: reserved
*/
struct iwl_rlc_config_cmd {
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/location.h b/drivers/net/wireless/intel/iwlwifi/fw/api/location.h
index 12af94e166ed..b044990c7b87 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/location.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/location.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
* Copyright (C) 2015-2017 Intel Deutschland GmbH
- * Copyright (C) 2018-2021 Intel Corporation
+ * Copyright (C) 2018-2022 Intel Corporation
*/
#ifndef __iwl_fw_api_location_h__
#define __iwl_fw_api_location_h__
@@ -35,8 +35,11 @@ enum iwl_location_subcmd_ids {
*/
TOF_RANGE_REQ_EXT_CMD = 0x3,
/**
- * @TOF_RESPONDER_CONFIG_CMD: FTM responder configuration,
- * uses &struct iwl_tof_responder_config_cmd
+ * @TOF_RESPONDER_CONFIG_CMD: FTM responder configuration, one of
+ * &struct iwl_tof_responder_config_cmd_v6,
+ * &struct iwl_tof_responder_config_cmd_v7,
+ * &struct iwl_tof_responder_config_cmd_v8 or
+ * &struct iwl_tof_responder_config_cmd_v9
*/
TOF_RESPONDER_CONFIG_CMD = 0x4,
/**
@@ -69,8 +72,11 @@ enum iwl_location_subcmd_ids {
*/
TOF_MCSI_DEBUG_NOTIF = 0xFE,
/**
- * @TOF_RANGE_RESPONSE_NOTIF: ranging response, using
- * &struct iwl_tof_range_rsp_ntfy
+ * @TOF_RANGE_RESPONSE_NOTIF: ranging response, using one of
+ * &struct iwl_tof_range_rsp_ntfy_v5,
+ * &struct iwl_tof_range_rsp_ntfy_v6,
+ * &struct iwl_tof_range_rsp_ntfy_v7 or
+ * &struct iwl_tof_range_rsp_ntfy_v8
*/
TOF_RANGE_RESPONSE_NOTIF = 0xFF,
};
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h b/drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h
index 74f2efbad34e..a4cb24934a01 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h
@@ -140,40 +140,60 @@ struct iwl_missed_vap_notif {
*
* @id_and_color: ID and color of the MAC
*/
-struct iwl_channel_switch_start_notif {
+struct iwl_channel_switch_start_notif_v1 {
__le32 id_and_color;
} __packed; /* CHANNEL_SWITCH_START_NTFY_API_S_VER_1 */
+/**
+ * struct iwl_channel_switch_start_notif - Channel switch start notification
+ *
+ * @link_id: FW link id
+ */
+struct iwl_channel_switch_start_notif {
+ __le32 link_id;
+} __packed; /* CHANNEL_SWITCH_START_NTFY_API_S_VER_3 */
+
#define CS_ERR_COUNT_ERROR BIT(0)
#define CS_ERR_LONG_DELAY_AFTER_CS BIT(1)
#define CS_ERR_LONG_TX_BLOCK BIT(2)
#define CS_ERR_TX_BLOCK_TIMER_EXPIRED BIT(3)
/**
- * struct iwl_channel_switch_error_notif - Channel switch error notification
+ * struct iwl_channel_switch_error_notif_v1 - Channel switch error notification
*
* @mac_id: the mac for which the ucode sends the notification for
* @csa_err_mask: mask of channel switch error that can occur
*/
-struct iwl_channel_switch_error_notif {
+struct iwl_channel_switch_error_notif_v1 {
__le32 mac_id;
__le32 csa_err_mask;
} __packed; /* CHANNEL_SWITCH_ERROR_NTFY_API_S_VER_1 */
/**
+ * struct iwl_channel_switch_error_notif - Channel switch error notification
+ *
+ * @link_id: FW link id
+ * @csa_err_mask: mask of channel switch error that can occur
+ */
+struct iwl_channel_switch_error_notif {
+ __le32 link_id;
+ __le32 csa_err_mask;
+} __packed; /* CHANNEL_SWITCH_ERROR_NTFY_API_S_VER_2 */
+
+/**
* struct iwl_cancel_channel_switch_cmd - Cancel Channel Switch command
*
- * @mac_id: the mac that should cancel the channel switch
+ * @id: the id of the link or mac that should cancel the channel switch
*/
struct iwl_cancel_channel_switch_cmd {
- __le32 mac_id;
+ __le32 id;
} __packed; /* MAC_CANCEL_CHANNEL_SWITCH_S_VER_1 */
/**
* struct iwl_chan_switch_te_cmd - Channel Switch Time Event command
*
* @mac_id: MAC ID for channel switch
- * @action: action to perform, one of FW_CTXT_ACTION_*
+ * @action: action to perform, see &enum iwl_ctxt_action
* @tsf: beacon tsf
* @cs_count: channel switch count from CSA/eCSA IE
* @cs_delayed_bcn_count: if set to N (!= 0) GO/AP can delay N beacon intervals
@@ -211,17 +231,30 @@ struct iwl_mac_low_latency_cmd {
* struct iwl_mac_client_data - configuration data for client MAC context
*
* @is_assoc: 1 for associated state, 0 otherwise
+ * @esr_transition_timeout: the timeout required by the AP for the
+ * eSR transition.
+ * Available only from version 2 of the command.
+ * This values comes from the EMLSR transition delay in the EML
+ * Capabilities subfield.
+ * @reserved: alignment
* @assoc_id: unique ID assigned by the AP during association
+ * @reserved1: alignment
* @data_policy: see &enum iwl_mac_data_policy
+ * @reserved2: alignment
* @ctwin: client traffic window in TU (period after TBTT when GO is present).
* 0 indicates that there is no CT window.
*/
struct iwl_mac_client_data {
- __le32 is_assoc;
- __le32 assoc_id;
- __le32 data_policy;
+ u8 is_assoc;
+ u8 esr_transition_timeout;
+ __le16 reserved;
+
+ __le16 assoc_id;
+ __le16 reserved1;
+ __le16 data_policy;
+ __le16 reserved2;
__le32 ctwin;
-} __packed; /* MAC_CONTEXT_CONFIG_CLIENT_DATA_API_S_VER_1 */
+} __packed; /* MAC_CONTEXT_CONFIG_CLIENT_DATA_API_S_VER_2 */
/**
* struct iwl_mac_p2p_dev_data - configuration data for P2P device MAC context
@@ -263,7 +296,7 @@ enum iwl_mac_config_filter_flags {
* ( MAC_CONTEXT_CONFIG_CMD = 0x8 )
*
* @id_and_color: ID and color of the MAC
- * @action: action to perform, one of FW_CTXT_ACTION_*
+ * @action: action to perform, see &enum iwl_ctxt_action
* @mac_type: one of &enum iwl_mac_types
* @local_mld_addr: mld address
* @reserved_for_local_mld_addr: reserved
@@ -292,12 +325,12 @@ struct iwl_mac_config_cmd {
__le16 he_ap_support;
__le32 eht_support;
__le32 nic_not_ack_enabled;
- /* MAC_CONTEXT_CONFIG_SPECIFIC_DATA_API_U_VER_1 */
+ /* MAC_CONTEXT_CONFIG_SPECIFIC_DATA_API_U_VER_2 */
union {
struct iwl_mac_client_data client;
struct iwl_mac_p2p_dev_data p2p_dev;
};
-} __packed; /* MAC_CONTEXT_CONFIG_CMD_API_S_VER_1 */
+} __packed; /* MAC_CONTEXT_CONFIG_CMD_API_S_VER_2 */
/**
* enum iwl_link_ctx_modify_flags - indicate to the fw what fields are being
@@ -390,7 +423,7 @@ enum iwl_link_ctx_flags {
* in MLD API
* ( LINK_CONFIG_CMD =0x9 )
*
- * @action: action to perform, one of FW_CTXT_ACTION_*
+ * @action: action to perform, see &enum iwl_ctxt_action
* @link_id: the id of the link that this cmd configures
* @mac_id: interface ID. Relevant only if action is FW_CTXT_ACTION_ADD
* @phy_id: PHY index. Can be changed only if the link was inactive
@@ -430,6 +463,7 @@ enum iwl_link_ctx_flags {
* @reserved_for_ref_bssid_addr: reserved
* @bssid_index: index of the associated VAP
* @bss_color: 11ax AP ID that is used in the HE SIG-A to mark inter BSS frame
+ * @spec_link_id: link_id as the AP knows it
* @reserved: alignment
* @ibss_bssid_addr: bssid for ibss
* @reserved_for_ibss_bssid_addr: reserved
@@ -469,7 +503,8 @@ struct iwl_link_config_cmd {
__le16 reserved_for_ref_bssid_addr;
u8 bssid_index;
u8 bss_color;
- u8 reserved[2];
+ u8 spec_link_id;
+ u8 reserved;
u8 ibss_bssid_addr[6];
__le16 reserved_for_ibss_bssid_addr;
__le32 reserved1[8];
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/mac.h b/drivers/net/wireless/intel/iwlwifi/fw/api/mac.h
index e3eda251c728..55882190251c 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/mac.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/mac.h
@@ -295,7 +295,7 @@ struct iwl_ac_qos {
* struct iwl_mac_ctx_cmd - command structure to configure MAC contexts
* ( MAC_CONTEXT_CMD = 0x28 )
* @id_and_color: ID and color of the MAC
- * @action: action to perform, one of FW_CTXT_ACTION_*
+ * @action: action to perform, see &enum iwl_ctxt_action
* @mac_type: one of &enum iwl_mac_types
* @tsf_id: TSF HW timer, one of &enum iwl_tsf_id
* @node_addr: MAC address
@@ -353,7 +353,7 @@ struct iwl_nonqos_seq_query_cmd {
} __packed; /* NON_QOS_TX_COUNTER_GET_SET_API_S_VER_1 */
/**
- * struct iwl_missed_beacons_notif - information on missed beacons
+ * struct iwl_missed_beacons_notif_ver_3 - information on missed beacons
* ( MISSED_BEACONS_NOTIFICATION = 0xa2 )
* @mac_id: interface ID
* @consec_missed_beacons_since_last_rx: number of consecutive missed
@@ -362,7 +362,7 @@ struct iwl_nonqos_seq_query_cmd {
* @num_expected_beacons: number of expected beacons
* @num_recvd_beacons: number of received beacons
*/
-struct iwl_missed_beacons_notif {
+struct iwl_missed_beacons_notif_ver_3 {
__le32 mac_id;
__le32 consec_missed_beacons_since_last_rx;
__le32 consec_missed_beacons;
@@ -371,6 +371,24 @@ struct iwl_missed_beacons_notif {
} __packed; /* MISSED_BEACON_NTFY_API_S_VER_3 */
/**
+ * struct iwl_missed_beacons_notif - information on missed beacons
+ * ( MISSED_BEACONS_NOTIFICATION = 0xa2 )
+ * @link_id: fw link ID
+ * @consec_missed_beacons_since_last_rx: number of consecutive missed
+ * beacons since last RX.
+ * @consec_missed_beacons: number of consecutive missed beacons
+ * @num_expected_beacons: number of expected beacons
+ * @num_recvd_beacons: number of received beacons
+ */
+struct iwl_missed_beacons_notif {
+ __le32 link_id;
+ __le32 consec_missed_beacons_since_last_rx;
+ __le32 consec_missed_beacons;
+ __le32 num_expected_beacons;
+ __le32 num_recvd_beacons;
+} __packed; /* MISSED_BEACON_NTFY_API_S_VER_4 */
+
+/**
* struct iwl_he_backoff_conf - used for backoff configuration
* Per each trigger-based AC, (set by MU EDCA Parameter set info-element)
* used for backoff configuration of TXF5..TXF8 trigger based.
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h b/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h
index 91bfde6d5367..71cce6dfeaf9 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h
@@ -17,7 +17,12 @@ enum iwl_regulatory_and_nvm_subcmd_ids {
NVM_ACCESS_COMPLETE = 0x0,
/**
- * @LARI_CONFIG_CHANGE: &struct iwl_lari_config_change_cmd
+ * @LARI_CONFIG_CHANGE: &struct iwl_lari_config_change_cmd_v1,
+ * &struct iwl_lari_config_change_cmd_v2,
+ * &struct iwl_lari_config_change_cmd_v3,
+ * &struct iwl_lari_config_change_cmd_v4,
+ * &struct iwl_lari_config_change_cmd_v5 or
+ * &struct iwl_lari_config_change_cmd_v6
*/
LARI_CONFIG_CHANGE = 0x1,
@@ -29,12 +34,12 @@ enum iwl_regulatory_and_nvm_subcmd_ids {
NVM_GET_INFO = 0x2,
/**
- * @TAS_CONFIG: &struct iwl_tas_config_cmd
+ * @TAS_CONFIG: &union iwl_tas_config_cmd
*/
TAS_CONFIG = 0x3,
/**
- * @SAR_OFFSET_MAPPING_TABLE_CMD: &iwl_sar_offset_mapping_cmd
+ * @SAR_OFFSET_MAPPING_TABLE_CMD: &struct iwl_sar_offset_mapping_cmd
*/
SAR_OFFSET_MAPPING_TABLE_CMD = 0x4,
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/offload.h b/drivers/net/wireless/intel/iwlwifi/fw/api/offload.h
index a0123f81f5d8..898bf351f6e4 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/offload.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/offload.h
@@ -28,7 +28,8 @@ enum iwl_prot_offload_subcmd_ids {
D3_END_NOTIFICATION = 0xFE,
/**
- * @STORED_BEACON_NTF: &struct iwl_stored_beacon_notif
+ * @STORED_BEACON_NTF: &struct iwl_stored_beacon_notif_v2 or
+ * &struct iwl_stored_beacon_notif_v3
*/
STORED_BEACON_NTF = 0xFF,
};
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/phy-ctxt.h b/drivers/net/wireless/intel/iwlwifi/fw/api/phy-ctxt.h
index 2f7d8558becd..8fe42cff1102 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/phy-ctxt.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/phy-ctxt.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
- * Copyright (C) 2012-2014, 2018, 2020-2021 Intel Corporation
+ * Copyright (C) 2012-2014, 2018, 2020-2022 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2016-2017 Intel Deutschland GmbH
*/
@@ -116,7 +116,7 @@ struct iwl_phy_context_cmd_tail {
* struct iwl_phy_context_cmd - config of the PHY context
* ( PHY_CONTEXT_CMD = 0x8 )
* @id_and_color: ID and color of the relevant Binding
- * @action: action to perform, one of FW_CTXT_ACTION_*
+ * @action: action to perform, see &enum iwl_ctxt_action
* @apply_time: 0 means immediate apply and context switch.
* other value means apply new params after X usecs
* @tx_param_color: ???
@@ -138,7 +138,7 @@ struct iwl_phy_context_cmd_v1 {
* struct iwl_phy_context_cmd - config of the PHY context
* ( PHY_CONTEXT_CMD = 0x8 )
* @id_and_color: ID and color of the relevant Binding
- * @action: action to perform, one of FW_CTXT_ACTION_*
+ * @action: action to perform, see &enum iwl_ctxt_action
* @lmac_id: the lmac id the phy context belongs to
* @ci: channel info
* @rxchain_info: ???
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/phy.h b/drivers/net/wireless/intel/iwlwifi/fw/api/phy.h
index b1b9c29859c1..5a3f30e5e06d 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/phy.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/phy.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
- * Copyright (C) 2012-2014, 2019-2021 Intel Corporation
+ * Copyright (C) 2012-2014, 2019-2022 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2016-2017 Intel Deutschland GmbH
*/
@@ -29,12 +29,16 @@ enum iwl_phy_ops_subcmd_ids {
TEMP_REPORTING_THRESHOLDS_CMD = 0x04,
/**
- * @PER_CHAIN_LIMIT_OFFSET_CMD: &struct iwl_geo_tx_power_profiles_cmd
+ * @PER_CHAIN_LIMIT_OFFSET_CMD: &struct iwl_geo_tx_power_profiles_cmd_v1,
+ * &struct iwl_geo_tx_power_profiles_cmd_v2,
+ * &struct iwl_geo_tx_power_profiles_cmd_v3,
+ * &struct iwl_geo_tx_power_profiles_cmd_v4 or
+ * &struct iwl_geo_tx_power_profiles_cmd_v5
*/
PER_CHAIN_LIMIT_OFFSET_CMD = 0x05,
/**
- * @PER_PLATFORM_ANT_GAIN_CMD: &struct iwl_ppag_table_cmd
+ * @PER_PLATFORM_ANT_GAIN_CMD: &union iwl_ppag_table_cmd
*/
PER_PLATFORM_ANT_GAIN_CMD = 0x07,
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/power.h b/drivers/net/wireless/intel/iwlwifi/fw/api/power.h
index f92cac1da764..85d89f559f6c 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/power.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/power.h
@@ -537,7 +537,7 @@ union iwl_ppag_table_cmd {
struct iwl_sar_offset_mapping_cmd {
u8 offset_map[MCC_TO_SAR_OFFSET_TABLE_ROW_SIZE]
[MCC_TO_SAR_OFFSET_TABLE_COL_SIZE];
- u16 reserved;
+ __le16 reserved;
} __packed; /*SAR_OFFSET_MAPPING_TABLE_CMD_API_S*/
/**
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h b/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h
index fdd8b01f09e4..67af922fd3ba 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h
@@ -367,8 +367,8 @@ enum iwl_rx_phy_eht_data1 {
/* number of EHT-LTF symbols 0 - 1 EHT-LTF, 1 - 2 EHT-LTFs, 2 - 4 EHT-LTFs,
* 3 - 6 EHT-LTFs, 4 - 8 EHT-LTFs */
IWL_RX_PHY_DATA1_EHT_SIG_LTF_NUM = 0x000000e0,
- IWL_RX_PHY_DATA1_EHT_B0 = 0x00000100,
- IWL_RX_PHY_DATA1_EHT_RU_B1_B7_ALLOC = 0x0000fe00,
+ IWL_RX_PHY_DATA1_EHT_RU_ALLOC_B0 = 0x00000100,
+ IWL_RX_PHY_DATA1_EHT_RU_ALLOC_B1_B7 = 0x0000fe00,
};
/* goes into Metadata DW 7 */
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/time-event.h b/drivers/net/wireless/intel/iwlwifi/fw/api/time-event.h
index 904cd78a9fa0..7cc706731d70 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/time-event.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/time-event.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
- * Copyright (C) 2012-2014, 2018-2020 Intel Corporation
+ * Copyright (C) 2012-2014, 2018-2020, 2022 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2016-2017 Intel Deutschland GmbH
*/
@@ -292,7 +292,7 @@ struct iwl_hs20_roc_req_tail {
* ( HOT_SPOT_CMD 0x53 )
*
* @id_and_color: ID and color of the MAC
- * @action: action to perform, one of FW_CTXT_ACTION_*
+ * @action: action to perform, see &enum iwl_ctxt_action
* @event_unique_id: If the action FW_CTXT_ACTION_REMOVE then the
* event_unique_id should be the id of the time event assigned by ucode.
* Otherwise ignore the event_unique_id.
@@ -377,7 +377,8 @@ enum iwl_mvm_session_prot_conf_id {
* struct iwl_mvm_session_prot_cmd - configure a session protection
* @id_and_color: the id and color of the mac for which this session protection
* is sent
- * @action: can be either FW_CTXT_ACTION_ADD or FW_CTXT_ACTION_REMOVE
+ * @action: can be either FW_CTXT_ACTION_ADD or FW_CTXT_ACTION_REMOVE,
+ * see &enum iwl_ctxt_action
* @conf_id: see &enum iwl_mvm_session_prot_conf_id
* @duration_tu: the duration of the whole protection in TUs.
* @repetition_count: not used
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
index 55219974b92b..3c5a43a619c6 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
@@ -2034,7 +2034,6 @@ static u32
iwl_dump_ini_imr_get_size(struct iwl_fw_runtime *fwrt,
struct iwl_dump_ini_region_data *reg_data)
{
- u32 size = 0;
u32 ranges = 0;
u32 imr_enable = fwrt->trans->dbg.imr_data.imr_enable;
u32 imr_size = fwrt->trans->dbg.imr_data.imr_size;
@@ -2044,17 +2043,16 @@ iwl_dump_ini_imr_get_size(struct iwl_fw_runtime *fwrt,
IWL_DEBUG_INFO(fwrt,
"WRT: Invalid imr data enable: %d, imr_size: %d, sram_size: %d\n",
imr_enable, imr_size, sram_size);
- return size;
+ return 0;
}
- size = imr_size;
ranges = iwl_dump_ini_imr_ranges(fwrt, reg_data);
- if (!size && !ranges) {
- IWL_ERR(fwrt, "WRT: imr_size :=%d, ranges :=%d\n", size, ranges);
+ if (!ranges) {
+ IWL_ERR(fwrt, "WRT: ranges :=%d\n", ranges);
return 0;
}
- size += sizeof(struct iwl_fw_ini_error_dump) +
+ imr_size += sizeof(struct iwl_fw_ini_error_dump) +
ranges * sizeof(struct iwl_fw_ini_error_dump_range);
- return size;
+ return imr_size;
}
/**
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h
index cddf09d6be1c..a78b68c2ae3d 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/file.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h
@@ -323,6 +323,7 @@ typedef unsigned int __bitwise iwl_ucode_tlv_capa_t;
* is supported.
* @IWL_UCODE_TLV_CAPA_BT_COEX_RRC: supports BT Coex RRC
* @IWL_UCODE_TLV_CAPA_GSCAN_SUPPORT: supports gscan (no longer used)
+ * @IWL_UCODE_TLV_CAPA_FRAGMENTED_PNVM_IMG: supports fragmented PNVM image
* @IWL_UCODE_TLV_CAPA_SOC_LATENCY_SUPPORT: the firmware supports setting
* stabilization latency for SoCs.
* @IWL_UCODE_TLV_CAPA_STA_PM_NOTIF: firmware will send STA PM notification
@@ -398,6 +399,7 @@ enum iwl_ucode_tlv_capa {
IWL_UCODE_TLV_CAPA_GSCAN_SUPPORT = (__force iwl_ucode_tlv_capa_t)31,
/* set 1 */
+ IWL_UCODE_TLV_CAPA_FRAGMENTED_PNVM_IMG = (__force iwl_ucode_tlv_capa_t)32,
IWL_UCODE_TLV_CAPA_SOC_LATENCY_SUPPORT = (__force iwl_ucode_tlv_capa_t)37,
IWL_UCODE_TLV_CAPA_STA_PM_NOTIF = (__force iwl_ucode_tlv_capa_t)38,
IWL_UCODE_TLV_CAPA_BINDING_CDB_SUPPORT = (__force iwl_ucode_tlv_capa_t)39,
@@ -462,6 +464,9 @@ enum iwl_ucode_tlv_capa {
IWL_UCODE_TLV_CAPA_BIGTK_TX_SUPPORT = (__force iwl_ucode_tlv_capa_t)109,
IWL_UCODE_TLV_CAPA_MLD_API_SUPPORT = (__force iwl_ucode_tlv_capa_t)110,
IWL_UCODE_TLV_CAPA_SCAN_DONT_TOGGLE_ANT = (__force iwl_ucode_tlv_capa_t)111,
+ IWL_UCODE_TLV_CAPA_PPAG_CHINA_BIOS_SUPPORT = (__force iwl_ucode_tlv_capa_t)112,
+ IWL_UCODE_TLV_CAPA_OFFLOAD_REJ_BTM_SUPPORT = (__force iwl_ucode_tlv_capa_t)113,
+ IWL_UCODE_TLV_CAPA_STA_EXP_MFP_SUPPORT = (__force iwl_ucode_tlv_capa_t)114,
#ifdef __CHECKER__
/* sparse says it cannot increment the previous enum member */
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c
index c6f2672fdc73..650e4bde9c17 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
- * Copyright(c) 2020-2022 Intel Corporation
+ * Copyright(c) 2020-2023 Intel Corporation
*/
#include "iwl-drv.h"
@@ -31,18 +31,18 @@ static bool iwl_pnvm_complete_fn(struct iwl_notif_wait_data *notif_wait,
}
static int iwl_pnvm_handle_section(struct iwl_trans *trans, const u8 *data,
- size_t len)
+ size_t len,
+ struct iwl_pnvm_image *pnvm_data)
{
const struct iwl_ucode_tlv *tlv;
u32 sha1 = 0;
u16 mac_type = 0, rf_id = 0;
- u8 *pnvm_data = NULL, *tmp;
bool hw_match = false;
- u32 size = 0;
- int ret;
IWL_DEBUG_FW(trans, "Handling PNVM section\n");
+ memset(pnvm_data, 0, sizeof(*pnvm_data));
+
while (len >= sizeof(*tlv)) {
u32 tlv_len, tlv_type;
@@ -55,8 +55,7 @@ static int iwl_pnvm_handle_section(struct iwl_trans *trans, const u8 *data,
if (len < tlv_len) {
IWL_ERR(trans, "invalid TLV len: %zd/%u\n",
len, tlv_len);
- ret = -EINVAL;
- goto out;
+ return -EINVAL;
}
data += sizeof(*tlv);
@@ -75,6 +74,7 @@ static int iwl_pnvm_handle_section(struct iwl_trans *trans, const u8 *data,
IWL_DEBUG_FW(trans,
"Got IWL_UCODE_TLV_PNVM_VERSION %0x\n",
sha1);
+ pnvm_data->version = sha1;
break;
case IWL_UCODE_TLV_HW_TYPE:
if (tlv_len < 2 * sizeof(__le16)) {
@@ -112,26 +112,26 @@ static int iwl_pnvm_handle_section(struct iwl_trans *trans, const u8 *data,
break;
}
- IWL_DEBUG_FW(trans, "Adding data (size %d)\n",
- data_len);
-
- tmp = krealloc(pnvm_data, size + data_len, GFP_KERNEL);
- if (!tmp) {
+ if (pnvm_data->n_chunks == IPC_DRAM_MAP_ENTRY_NUM_MAX) {
IWL_DEBUG_FW(trans,
- "Couldn't allocate (more) pnvm_data\n");
-
- ret = -ENOMEM;
- goto out;
+ "too many payloads to allocate in DRAM.\n");
+ return -EINVAL;
}
- pnvm_data = tmp;
-
- memcpy(pnvm_data + size, section->data, data_len);
+ IWL_DEBUG_FW(trans, "Adding data (size %d)\n",
+ data_len);
- size += data_len;
+ pnvm_data->chunks[pnvm_data->n_chunks].data = section->data;
+ pnvm_data->chunks[pnvm_data->n_chunks].len = data_len;
+ pnvm_data->n_chunks++;
break;
}
+ case IWL_UCODE_TLV_MEM_DESC:
+ if (iwl_uefi_handle_tlv_mem_desc(trans, data, tlv_len,
+ pnvm_data))
+ return -EINVAL;
+ break;
case IWL_UCODE_TLV_PNVM_SKU:
IWL_DEBUG_FW(trans,
"New PNVM section started, stop parsing.\n");
@@ -152,26 +152,20 @@ done:
"HW mismatch, skipping PNVM section (need mac_type 0x%x rf_id 0x%x)\n",
CSR_HW_REV_TYPE(trans->hw_rev),
CSR_HW_RFID_TYPE(trans->hw_rf_id));
- ret = -ENOENT;
- goto out;
+ return -ENOENT;
}
- if (!size) {
+ if (!pnvm_data->n_chunks) {
IWL_DEBUG_FW(trans, "Empty PNVM, skipping.\n");
- ret = -ENOENT;
- goto out;
+ return -ENOENT;
}
- IWL_INFO(trans, "loaded PNVM version %08x\n", sha1);
-
- ret = iwl_trans_set_pnvm(trans, pnvm_data, size);
-out:
- kfree(pnvm_data);
- return ret;
+ return 0;
}
static int iwl_pnvm_parse(struct iwl_trans *trans, const u8 *data,
- size_t len)
+ size_t len,
+ struct iwl_pnvm_image *pnvm_data)
{
const struct iwl_ucode_tlv *tlv;
@@ -212,7 +206,8 @@ static int iwl_pnvm_parse(struct iwl_trans *trans, const u8 *data,
trans->sku_id[2] == le32_to_cpu(sku_id->data[2])) {
int ret;
- ret = iwl_pnvm_handle_section(trans, data, len);
+ ret = iwl_pnvm_handle_section(trans, data, len,
+ pnvm_data);
if (!ret)
return 0;
} else {
@@ -255,89 +250,136 @@ static int iwl_pnvm_get_from_fs(struct iwl_trans *trans, u8 **data, size_t *len)
return 0;
}
-int iwl_pnvm_load(struct iwl_trans *trans,
- struct iwl_notif_wait_data *notif_wait)
+static u8 *iwl_get_pnvm_image(struct iwl_trans *trans_p, size_t *len)
{
- u8 *data;
- size_t len;
struct pnvm_sku_package *package;
- struct iwl_notification_wait pnvm_wait;
- static const u16 ntf_cmds[] = { WIDE_ID(REGULATORY_AND_NVM_GROUP,
- PNVM_INIT_COMPLETE_NTFY) };
- int ret;
-
- /* if the SKU_ID is empty, there's nothing to do */
- if (!trans->sku_id[0] && !trans->sku_id[1] && !trans->sku_id[2])
- return 0;
-
- /*
- * If we already loaded (or tried to load) it before, we just
- * need to set it again.
- */
- if (trans->pnvm_loaded) {
- ret = iwl_trans_set_pnvm(trans, NULL, 0);
- if (ret)
- return ret;
- goto skip_parse;
- }
+ u8 *image = NULL;
/* First attempt to get the PNVM from BIOS */
- package = iwl_uefi_get_pnvm(trans, &len);
+ package = iwl_uefi_get_pnvm(trans_p, len);
if (!IS_ERR_OR_NULL(package)) {
- if (len >= sizeof(*package)) {
+ if (*len >= sizeof(*package)) {
/* we need only the data */
- len -= sizeof(*package);
- data = kmemdup(package->data, len, GFP_KERNEL);
- } else {
- data = NULL;
+ *len -= sizeof(*package);
+ image = kmemdup(package->data, *len, GFP_KERNEL);
}
-
/* free package regardless of whether kmemdup succeeded */
kfree(package);
-
- if (data)
- goto parse;
+ if (image)
+ return image;
}
/* If it's not available, try from the filesystem */
- ret = iwl_pnvm_get_from_fs(trans, &data, &len);
+ if (iwl_pnvm_get_from_fs(trans_p, &image, len))
+ return NULL;
+ return image;
+}
+
+static void iwl_pnvm_load_pnvm_to_trans(struct iwl_trans *trans,
+ const struct iwl_ucode_capabilities *capa)
+{
+ struct iwl_pnvm_image *pnvm_data = NULL;
+ u8 *data = NULL;
+ size_t length;
+ int ret;
+
+ /* failed to get/parse the image in the past, no use trying again */
+ if (trans->fail_to_parse_pnvm_image)
+ return;
+
+ if (trans->pnvm_loaded)
+ goto set;
+
+ data = iwl_get_pnvm_image(trans, &length);
+ if (!data) {
+ trans->fail_to_parse_pnvm_image = true;
+ return;
+ }
+
+ pnvm_data = kzalloc(sizeof(*pnvm_data), GFP_KERNEL);
+ if (!pnvm_data)
+ goto free;
+
+ ret = iwl_pnvm_parse(trans, data, length, pnvm_data);
if (ret) {
- /*
- * Pretend we've loaded it - at least we've tried and
- * couldn't load it at all, so there's no point in
- * trying again over and over.
- */
- trans->pnvm_loaded = true;
-
- goto skip_parse;
+ trans->fail_to_parse_pnvm_image = true;
+ goto free;
}
-parse:
- iwl_pnvm_parse(trans, data, len);
+ ret = iwl_trans_load_pnvm(trans, pnvm_data, capa);
+ if (ret)
+ goto free;
+ IWL_INFO(trans, "loaded PNVM version %08x\n", pnvm_data->version);
+set:
+ iwl_trans_set_pnvm(trans, capa);
+free:
kfree(data);
+ kfree(pnvm_data);
+}
-skip_parse:
- /* now try to get the reduce power table, if not loaded yet */
- if (!trans->reduce_power_loaded) {
- data = iwl_uefi_get_reduced_power(trans, &len);
- if (IS_ERR_OR_NULL(data)) {
- /*
- * Pretend we've loaded it - at least we've tried and
- * couldn't load it at all, so there's no point in
- * trying again over and over.
- */
- trans->reduce_power_loaded = true;
- } else {
- ret = iwl_trans_set_reduce_power(trans, data, len);
- if (ret)
- IWL_DEBUG_FW(trans,
- "Failed to set reduce power table %d\n",
- ret);
- kfree(data);
- }
+static void
+iwl_pnvm_load_reduce_power_to_trans(struct iwl_trans *trans,
+ const struct iwl_ucode_capabilities *capa)
+{
+ struct iwl_pnvm_image *pnvm_data = NULL;
+ u8 *data = NULL;
+ size_t length;
+ int ret;
+
+ if (trans->failed_to_load_reduce_power_image)
+ return;
+
+ if (trans->reduce_power_loaded)
+ goto set;
+
+ data = iwl_uefi_get_reduced_power(trans, &length);
+ if (IS_ERR(data)) {
+ trans->failed_to_load_reduce_power_image = true;
+ return;
}
+ pnvm_data = kzalloc(sizeof(*pnvm_data), GFP_KERNEL);
+ if (!pnvm_data)
+ goto free;
+
+ ret = iwl_uefi_reduce_power_parse(trans, data, length, pnvm_data);
+ if (ret) {
+ trans->failed_to_load_reduce_power_image = true;
+ goto free;
+ }
+
+ ret = iwl_trans_load_reduce_power(trans, pnvm_data, capa);
+ if (ret) {
+ IWL_DEBUG_FW(trans,
+ "Failed to load reduce power table %d\n",
+ ret);
+ trans->failed_to_load_reduce_power_image = true;
+ goto free;
+ }
+
+set:
+ iwl_trans_set_reduce_power(trans, capa);
+free:
+ kfree(data);
+ kfree(pnvm_data);
+}
+
+int iwl_pnvm_load(struct iwl_trans *trans,
+ struct iwl_notif_wait_data *notif_wait,
+ const struct iwl_ucode_capabilities *capa)
+{
+ struct iwl_notification_wait pnvm_wait;
+ static const u16 ntf_cmds[] = { WIDE_ID(REGULATORY_AND_NVM_GROUP,
+ PNVM_INIT_COMPLETE_NTFY) };
+
+ /* if the SKU_ID is empty, there's nothing to do */
+ if (!trans->sku_id[0] && !trans->sku_id[1] && !trans->sku_id[2])
+ return 0;
+
+ iwl_pnvm_load_pnvm_to_trans(trans, capa);
+ iwl_pnvm_load_reduce_power_to_trans(trans, capa);
+
iwl_init_notification_wait(notif_wait, &pnvm_wait,
ntf_cmds, ARRAY_SIZE(ntf_cmds),
iwl_pnvm_complete_fn, trans);
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.h b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.h
index 203c367dd4de..4e10baa01738 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/******************************************************************************
*
- * Copyright(c) 2020-2021 Intel Corporation
+ * Copyright(c) 2020-2022 Intel Corporation
*
*****************************************************************************/
@@ -15,7 +15,8 @@
#define MAX_PNVM_NAME 64
int iwl_pnvm_load(struct iwl_trans *trans,
- struct iwl_notif_wait_data *notif_wait);
+ struct iwl_notif_wait_data *notif_wait,
+ const struct iwl_ucode_capabilities *capa);
static inline
void iwl_pnvm_get_fs_name(struct iwl_trans *trans,
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/uefi.c b/drivers/net/wireless/intel/iwlwifi/fw/uefi.c
index 01afea33c38c..9877988db0d2 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/uefi.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/uefi.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
- * Copyright(c) 2021-2022 Intel Corporation
+ * Copyright(c) 2021-2023 Intel Corporation
*/
#include "iwl-drv.h"
@@ -17,52 +17,109 @@
0xb2, 0xec, 0xf5, 0xa3, \
0x59, 0x4f, 0x4a, 0xea)
-void *iwl_uefi_get_pnvm(struct iwl_trans *trans, size_t *len)
+struct iwl_uefi_pnvm_mem_desc {
+ __le32 addr;
+ __le32 size;
+ const u8 data[];
+} __packed;
+
+static void *iwl_uefi_get_variable(efi_char16_t *name, efi_guid_t *guid,
+ unsigned long *data_size)
{
- void *data;
- unsigned long package_size;
efi_status_t status;
+ void *data;
- *len = 0;
+ if (!data_size)
+ return ERR_PTR(-EINVAL);
if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE))
return ERR_PTR(-ENODEV);
- /*
- * TODO: we hardcode a maximum length here, because reading
- * from the UEFI is not working. To implement this properly,
- * we have to call efivar_entry_size().
- */
- package_size = IWL_HARDCODED_PNVM_SIZE;
+ /* first call with NULL data to get the exact entry size */
+ *data_size = 0;
+ status = efi.get_variable(name, guid, NULL, data_size, NULL);
+ if (status != EFI_BUFFER_TOO_SMALL || !*data_size)
+ return ERR_PTR(-EIO);
- data = kmalloc(package_size, GFP_KERNEL);
+ data = kmalloc(*data_size, GFP_KERNEL);
if (!data)
return ERR_PTR(-ENOMEM);
- status = efi.get_variable(IWL_UEFI_OEM_PNVM_NAME, &IWL_EFI_VAR_GUID,
- NULL, &package_size, data);
+ status = efi.get_variable(name, guid, NULL, data_size, data);
if (status != EFI_SUCCESS) {
- IWL_DEBUG_FW(trans,
- "PNVM UEFI variable not found 0x%lx (len %lu)\n",
- status, package_size);
kfree(data);
return ERR_PTR(-ENOENT);
}
+ return data;
+}
+
+void *iwl_uefi_get_pnvm(struct iwl_trans *trans, size_t *len)
+{
+ unsigned long package_size;
+ void *data;
+
+ *len = 0;
+
+ data = iwl_uefi_get_variable(IWL_UEFI_OEM_PNVM_NAME, &IWL_EFI_VAR_GUID,
+ &package_size);
+ if (IS_ERR(data)) {
+ IWL_DEBUG_FW(trans,
+ "PNVM UEFI variable not found 0x%lx (len %lu)\n",
+ PTR_ERR(data), package_size);
+ return data;
+ }
+
IWL_DEBUG_FW(trans, "Read PNVM from UEFI with size %lu\n", package_size);
*len = package_size;
return data;
}
-static void *iwl_uefi_reduce_power_section(struct iwl_trans *trans,
- const u8 *data, size_t len)
+int iwl_uefi_handle_tlv_mem_desc(struct iwl_trans *trans, const u8 *data,
+ u32 tlv_len, struct iwl_pnvm_image *pnvm_data)
+{
+ const struct iwl_uefi_pnvm_mem_desc *desc = (const void *)data;
+ u32 data_len;
+
+ if (tlv_len < sizeof(*desc)) {
+ IWL_DEBUG_FW(trans, "TLV len (%d) is too small\n", tlv_len);
+ return -EINVAL;
+ }
+
+ data_len = tlv_len - sizeof(*desc);
+
+ IWL_DEBUG_FW(trans,
+ "Handle IWL_UCODE_TLV_MEM_DESC, len %d data_len %d\n",
+ tlv_len, data_len);
+
+ if (le32_to_cpu(desc->size) != data_len) {
+ IWL_DEBUG_FW(trans, "invalid mem desc size %d\n", desc->size);
+ return -EINVAL;
+ }
+
+ if (pnvm_data->n_chunks == IPC_DRAM_MAP_ENTRY_NUM_MAX) {
+ IWL_DEBUG_FW(trans, "too many payloads to allocate in DRAM.\n");
+ return -EINVAL;
+ }
+
+ IWL_DEBUG_FW(trans, "Adding data (size %d)\n", data_len);
+
+ pnvm_data->chunks[pnvm_data->n_chunks].data = desc->data;
+ pnvm_data->chunks[pnvm_data->n_chunks].len = data_len;
+ pnvm_data->n_chunks++;
+
+ return 0;
+}
+
+static int iwl_uefi_reduce_power_section(struct iwl_trans *trans,
+ const u8 *data, size_t len,
+ struct iwl_pnvm_image *pnvm_data)
{
const struct iwl_ucode_tlv *tlv;
- u8 *reduce_power_data = NULL, *tmp;
- u32 size = 0;
IWL_DEBUG_FW(trans, "Handling REDUCE_POWER section\n");
+ memset(pnvm_data, 0, sizeof(*pnvm_data));
while (len >= sizeof(*tlv)) {
u32 tlv_len, tlv_type;
@@ -76,39 +133,17 @@ static void *iwl_uefi_reduce_power_section(struct iwl_trans *trans,
if (len < tlv_len) {
IWL_ERR(trans, "invalid TLV len: %zd/%u\n",
len, tlv_len);
- kfree(reduce_power_data);
- reduce_power_data = ERR_PTR(-EINVAL);
- goto out;
+ return -EINVAL;
}
data += sizeof(*tlv);
switch (tlv_type) {
- case IWL_UCODE_TLV_MEM_DESC: {
- IWL_DEBUG_FW(trans,
- "Got IWL_UCODE_TLV_MEM_DESC len %d\n",
- tlv_len);
-
- IWL_DEBUG_FW(trans, "Adding data (size %d)\n", tlv_len);
-
- tmp = krealloc(reduce_power_data, size + tlv_len, GFP_KERNEL);
- if (!tmp) {
- IWL_DEBUG_FW(trans,
- "Couldn't allocate (more) reduce_power_data\n");
-
- kfree(reduce_power_data);
- reduce_power_data = ERR_PTR(-ENOMEM);
- goto out;
- }
-
- reduce_power_data = tmp;
-
- memcpy(reduce_power_data + size, data, tlv_len);
-
- size += tlv_len;
-
+ case IWL_UCODE_TLV_MEM_DESC:
+ if (iwl_uefi_handle_tlv_mem_desc(trans, data, tlv_len,
+ pnvm_data))
+ return -EINVAL;
break;
- }
case IWL_UCODE_TLV_PNVM_SKU:
IWL_DEBUG_FW(trans,
"New REDUCE_POWER section started, stop parsing.\n");
@@ -124,27 +159,18 @@ static void *iwl_uefi_reduce_power_section(struct iwl_trans *trans,
}
done:
- if (!size) {
+ if (!pnvm_data->n_chunks) {
IWL_DEBUG_FW(trans, "Empty REDUCE_POWER, skipping.\n");
- /* Better safe than sorry, but 'reduce_power_data' should
- * always be NULL if !size.
- */
- kfree(reduce_power_data);
- reduce_power_data = ERR_PTR(-ENOENT);
- goto out;
+ return -ENOENT;
}
-
- IWL_INFO(trans, "loaded REDUCE_POWER\n");
-
-out:
- return reduce_power_data;
+ return 0;
}
-static void *iwl_uefi_reduce_power_parse(struct iwl_trans *trans,
- const u8 *data, size_t len)
+int iwl_uefi_reduce_power_parse(struct iwl_trans *trans,
+ const u8 *data, size_t len,
+ struct iwl_pnvm_image *pnvm_data)
{
const struct iwl_ucode_tlv *tlv;
- void *sec_data;
IWL_DEBUG_FW(trans, "Parsing REDUCE_POWER data\n");
@@ -160,7 +186,7 @@ static void *iwl_uefi_reduce_power_parse(struct iwl_trans *trans,
if (len < tlv_len) {
IWL_ERR(trans, "invalid TLV len: %zd/%u\n",
len, tlv_len);
- return ERR_PTR(-EINVAL);
+ return -EINVAL;
}
if (tlv_type == IWL_UCODE_TLV_PNVM_SKU) {
@@ -181,11 +207,11 @@ static void *iwl_uefi_reduce_power_parse(struct iwl_trans *trans,
if (trans->sku_id[0] == le32_to_cpu(sku_id->data[0]) &&
trans->sku_id[1] == le32_to_cpu(sku_id->data[1]) &&
trans->sku_id[2] == le32_to_cpu(sku_id->data[2])) {
- sec_data = iwl_uefi_reduce_power_section(trans,
- data,
- len);
- if (!IS_ERR(sec_data))
- return sec_data;
+ int ret = iwl_uefi_reduce_power_section(trans,
+ data, len,
+ pnvm_data);
+ if (!ret)
+ return 0;
} else {
IWL_DEBUG_FW(trans, "SKU ID didn't match!\n");
}
@@ -195,51 +221,45 @@ static void *iwl_uefi_reduce_power_parse(struct iwl_trans *trans,
}
}
- return ERR_PTR(-ENOENT);
+ return -ENOENT;
}
-void *iwl_uefi_get_reduced_power(struct iwl_trans *trans, size_t *len)
+u8 *iwl_uefi_get_reduced_power(struct iwl_trans *trans, size_t *len)
{
struct pnvm_sku_package *package;
- void *data = NULL;
unsigned long package_size;
- efi_status_t status;
+ u8 *data;
- *len = 0;
+ package = iwl_uefi_get_variable(IWL_UEFI_REDUCED_POWER_NAME,
+ &IWL_EFI_VAR_GUID, &package_size);
- if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE))
- return ERR_PTR(-ENODEV);
-
- /*
- * TODO: we hardcode a maximum length here, because reading
- * from the UEFI is not working. To implement this properly,
- * we have to call efivar_entry_size().
- */
- package_size = IWL_HARDCODED_REDUCE_POWER_SIZE;
-
- package = kmalloc(package_size, GFP_KERNEL);
- if (!package)
- return ERR_PTR(-ENOMEM);
-
- status = efi.get_variable(IWL_UEFI_REDUCED_POWER_NAME, &IWL_EFI_VAR_GUID,
- NULL, &package_size, package);
- if (status != EFI_SUCCESS) {
+ if (IS_ERR(package)) {
IWL_DEBUG_FW(trans,
"Reduced Power UEFI variable not found 0x%lx (len %lu)\n",
- status, package_size);
+ PTR_ERR(package), package_size);
+ return ERR_CAST(package);
+ }
+
+ if (package_size < sizeof(*package)) {
+ IWL_DEBUG_FW(trans,
+ "Invalid Reduced Power UEFI variable len (%lu)\n",
+ package_size);
kfree(package);
- return ERR_PTR(-ENOENT);
+ return ERR_PTR(-EINVAL);
}
IWL_DEBUG_FW(trans, "Read reduced power from UEFI with size %lu\n",
package_size);
- *len = package_size;
IWL_DEBUG_FW(trans, "rev %d, total_size %d, n_skus %d\n",
package->rev, package->total_size, package->n_skus);
- data = iwl_uefi_reduce_power_parse(trans, package->data,
- *len - sizeof(*package));
+ *len = package_size - sizeof(*package);
+ data = kmemdup(package->data, *len, GFP_KERNEL);
+ if (!data) {
+ kfree(package);
+ return ERR_PTR(-ENOMEM);
+ }
kfree(package);
@@ -264,31 +284,27 @@ void iwl_uefi_get_step_table(struct iwl_trans *trans)
{
struct uefi_cnv_common_step_data *data;
unsigned long package_size;
- efi_status_t status;
int ret;
if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210)
return;
- if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE))
- return;
+ data = iwl_uefi_get_variable(IWL_UEFI_STEP_NAME, &IWL_EFI_VAR_GUID,
+ &package_size);
- /* TODO: we hardcode a maximum length here, because reading
- * from the UEFI is not working. To implement this properly,
- * we have to call efivar_entry_size().
- */
- package_size = IWL_HARDCODED_STEP_SIZE;
-
- data = kmalloc(package_size, GFP_KERNEL);
- if (!data)
+ if (IS_ERR(data)) {
+ IWL_DEBUG_FW(trans,
+ "STEP UEFI variable not found 0x%lx\n",
+ PTR_ERR(data));
return;
+ }
- status = efi.get_variable(IWL_UEFI_STEP_NAME, &IWL_EFI_VAR_GUID,
- NULL, &package_size, data);
- if (status != EFI_SUCCESS) {
+ if (package_size < sizeof(*data)) {
IWL_DEBUG_FW(trans,
- "STEP UEFI variable not found 0x%lx\n", status);
- goto out_free;
+ "Invalid STEP table UEFI variable len (%lu)\n",
+ package_size);
+ kfree(data);
+ return;
}
IWL_DEBUG_FW(trans, "Read STEP from UEFI with size %lu\n",
@@ -298,7 +314,6 @@ void iwl_uefi_get_step_table(struct iwl_trans *trans)
if (ret < 0)
IWL_DEBUG_FW(trans, "Cannot read STEP tables. rev is invalid\n");
-out_free:
kfree(data);
}
IWL_EXPORT_SYMBOL(iwl_uefi_get_step_table);
@@ -341,29 +356,26 @@ void iwl_uefi_get_sgom_table(struct iwl_trans *trans,
{
struct uefi_cnv_wlan_sgom_data *data;
unsigned long package_size;
- efi_status_t status;
int ret;
- if (!fwrt->geo_enabled ||
- !efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE))
+ if (!fwrt->geo_enabled)
return;
- /* TODO: we hardcode a maximum length here, because reading
- * from the UEFI is not working. To implement this properly,
- * we have to call efivar_entry_size().
- */
- package_size = IWL_HARDCODED_SGOM_SIZE;
-
- data = kmalloc(package_size, GFP_KERNEL);
- if (!data)
+ data = iwl_uefi_get_variable(IWL_UEFI_SGOM_NAME, &IWL_EFI_VAR_GUID,
+ &package_size);
+ if (IS_ERR(data)) {
+ IWL_DEBUG_FW(trans,
+ "SGOM UEFI variable not found 0x%lx\n",
+ PTR_ERR(data));
return;
+ }
- status = efi.get_variable(IWL_UEFI_SGOM_NAME, &IWL_EFI_VAR_GUID,
- NULL, &package_size, data);
- if (status != EFI_SUCCESS) {
+ if (package_size < sizeof(*data)) {
IWL_DEBUG_FW(trans,
- "SGOM UEFI variable not found 0x%lx\n", status);
- goto out_free;
+ "Invalid SGOM table UEFI variable len (%lu)\n",
+ package_size);
+ kfree(data);
+ return;
}
IWL_DEBUG_FW(trans, "Read SGOM from UEFI with size %lu\n",
@@ -373,9 +385,7 @@ void iwl_uefi_get_sgom_table(struct iwl_trans *trans,
if (ret < 0)
IWL_DEBUG_FW(trans, "Cannot read SGOM tables. rev is invalid\n");
-out_free:
kfree(data);
-
}
IWL_EXPORT_SYMBOL(iwl_uefi_get_sgom_table);
#endif /* CONFIG_ACPI */
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/uefi.h b/drivers/net/wireless/intel/iwlwifi/fw/uefi.h
index 17089bc74cf9..1369cc4855c3 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/uefi.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/uefi.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
- * Copyright(c) 2021-2022 Intel Corporation
+ * Copyright(c) 2021-2023 Intel Corporation
*/
#ifndef __iwl_fw_uefi__
#define __iwl_fw_uefi__
@@ -10,16 +10,7 @@
#define IWL_UEFI_SGOM_NAME L"UefiCnvWlanSarGeoOffsetMapping"
#define IWL_UEFI_STEP_NAME L"UefiCnvCommonSTEP"
-/*
- * TODO: we have these hardcoded values that the caller must pass,
- * because reading from the UEFI is not working. To implement this
- * properly, we have to change iwl_pnvm_get_from_uefi() to call
- * efivar_entry_size() and return the value to the caller instead.
- */
-#define IWL_HARDCODED_PNVM_SIZE 4096
-#define IWL_HARDCODED_REDUCE_POWER_SIZE 32768
-#define IWL_HARDCODED_SGOM_SIZE 339
-#define IWL_HARDCODED_STEP_SIZE 6
+#define IWL_SGOM_MAP_SIZE 339
struct pnvm_sku_package {
u8 rev;
@@ -31,7 +22,7 @@ struct pnvm_sku_package {
struct uefi_cnv_wlan_sgom_data {
u8 revision;
- u8 offset_map[IWL_HARDCODED_SGOM_SIZE - 1];
+ u8 offset_map[IWL_SGOM_MAP_SIZE - 1];
} __packed;
struct uefi_cnv_common_step_data {
@@ -50,24 +41,42 @@ struct uefi_cnv_common_step_data {
*/
#ifdef CONFIG_EFI
void *iwl_uefi_get_pnvm(struct iwl_trans *trans, size_t *len);
-void *iwl_uefi_get_reduced_power(struct iwl_trans *trans, size_t *len);
+u8 *iwl_uefi_get_reduced_power(struct iwl_trans *trans, size_t *len);
+int iwl_uefi_reduce_power_parse(struct iwl_trans *trans,
+ const u8 *data, size_t len,
+ struct iwl_pnvm_image *pnvm_data);
void iwl_uefi_get_step_table(struct iwl_trans *trans);
+int iwl_uefi_handle_tlv_mem_desc(struct iwl_trans *trans, const u8 *data,
+ u32 tlv_len, struct iwl_pnvm_image *pnvm_data);
#else /* CONFIG_EFI */
-static inline
-void *iwl_uefi_get_pnvm(struct iwl_trans *trans, size_t *len)
+static inline void *iwl_uefi_get_pnvm(struct iwl_trans *trans, size_t *len)
{
return ERR_PTR(-EOPNOTSUPP);
}
-static inline
-void *iwl_uefi_get_reduced_power(struct iwl_trans *trans, size_t *len)
+static inline int
+iwl_uefi_reduce_power_parse(struct iwl_trans *trans,
+ const u8 *data, size_t len,
+ struct iwl_pnvm_image *pnvm_data)
+{
+ return -EOPNOTSUPP;
+}
+
+static inline u8 *
+iwl_uefi_get_reduced_power(struct iwl_trans *trans, size_t *len)
{
return ERR_PTR(-EOPNOTSUPP);
}
-static inline
-void iwl_uefi_get_step_table(struct iwl_trans *trans)
+static inline void iwl_uefi_get_step_table(struct iwl_trans *trans)
+{
+}
+
+static inline int
+iwl_uefi_handle_tlv_mem_desc(struct iwl_trans *trans, const u8 *data,
+ u32 tlv_len, struct iwl_pnvm_image *pnvm_data)
{
+ return 0;
}
#endif /* CONFIG_EFI */