mirror of
https://github.com/torvalds/linux.git
synced 2026-05-28 17:13:52 +02:00
iwlwifi features, notably:
- unused API cleanups - transport layer cleanups - new APIs support -----BEGIN PGP SIGNATURE----- iHUEABYIAB0WIQQM3A3Pv7vbm9vtjWbacY7uyt+OfQUCaL/vOQAKCRDacY7uyt+O fToEAPwM+ZkLWMCIJnTRSpll8F9fCnlQRfce/QIGDMGWfXS2iQEA0yPfjqMbQXmI aVniE9m6xoOHHcF5V4M1J9mxO+QXQgA= =Cr9C -----END PGP SIGNATURE----- Merge tag 'iwlwifi-next-2025-09-09' of https://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next Miri Korenblit says: ==================== iwlwifi features, notably: - unused API cleanups - transport layer cleanups - new APIs support ==================== Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
commit
6f4f8abad4
|
|
@ -766,7 +766,7 @@ static int iwl_init_otp_access(struct iwl_trans *trans)
|
|||
{
|
||||
int ret;
|
||||
|
||||
ret = iwl_finish_nic_init(trans);
|
||||
ret = iwl_trans_activate_nic(trans);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -368,7 +368,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
|
|||
/* initialize to default */
|
||||
void iwl_power_initialize(struct iwl_priv *priv)
|
||||
{
|
||||
priv->power_data.bus_pm = priv->trans->pm_support;
|
||||
priv->power_data.bus_pm = iwl_trans_is_pm_supported(priv->trans);
|
||||
|
||||
priv->power_data.debug_sleep_level_override = -1;
|
||||
|
||||
|
|
|
|||
|
|
@ -632,9 +632,64 @@ struct iwl_wowlan_gtk_status_v3 {
|
|||
struct iwl_wowlan_all_rsc_tsc_v5 sc;
|
||||
} __packed; /* WOWLAN_GTK_MATERIAL_VER_3 */
|
||||
|
||||
/**
|
||||
* enum iwl_wowlan_key_status - Status of security keys in WoWLAN notifications
|
||||
* @IWL_WOWLAN_NOTIF_NO_KEY: No key is present; this entry should be ignored.
|
||||
* @IWL_WOWLAN_STATUS_OLD_KEY: old key exists; no rekey occurred, and only
|
||||
* metadata is available.
|
||||
* @IWL_WOWLAN_STATUS_NEW_KEY: A new key was created after a rekey; new key
|
||||
* material is available.
|
||||
*/
|
||||
enum iwl_wowlan_key_status {
|
||||
IWL_WOWLAN_NOTIF_NO_KEY = 0,
|
||||
IWL_WOWLAN_STATUS_OLD_KEY = 1,
|
||||
IWL_WOWLAN_STATUS_NEW_KEY = 2
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_wowlan_gtk_status - GTK status
|
||||
* @key: GTK material
|
||||
* @key_len: GTK length, if set to 0, the key is not available
|
||||
* @key_flags: information about the key:
|
||||
* bits[0:1]: key index assigned by the AP
|
||||
* bits[2:6]: GTK index of the key in the internal DB
|
||||
* bit[7]: Set iff this is the currently used GTK
|
||||
* @key_status: key status, see &enum iwl_wowlan_key_status
|
||||
* @reserved: padding
|
||||
* @tkip_mic_key: TKIP RX MIC key
|
||||
* @sc: RSC/TSC counters
|
||||
*/
|
||||
struct iwl_wowlan_gtk_status {
|
||||
u8 key[WOWLAN_KEY_MAX_SIZE];
|
||||
u8 key_len;
|
||||
u8 key_flags;
|
||||
u8 key_status;
|
||||
u8 reserved;
|
||||
u8 tkip_mic_key[IWL_MIC_KEY_SIZE];
|
||||
struct iwl_wowlan_all_rsc_tsc_v5 sc;
|
||||
} __packed; /* WOWLAN_GTK_MATERIAL_VER_4 */
|
||||
|
||||
#define IWL_WOWLAN_GTK_IDX_MASK (BIT(0) | BIT(1))
|
||||
#define IWL_WOWLAN_IGTK_BIGTK_IDX_MASK (BIT(0))
|
||||
|
||||
/**
|
||||
* struct iwl_wowlan_igtk_status_v1 - IGTK status
|
||||
* @key: IGTK material
|
||||
* @ipn: the IGTK packet number (replay counter)
|
||||
* @key_len: IGTK length, if set to 0, the key is not available
|
||||
* @key_flags: information about the key:
|
||||
* bits[0]: key index assigned by the AP (0: index 4, 1: index 5)
|
||||
* (0: index 6, 1: index 7 with bigtk)
|
||||
* bits[1:5]: IGTK index of the key in the internal DB
|
||||
* bit[6]: Set iff this is the currently used IGTK
|
||||
*/
|
||||
struct iwl_wowlan_igtk_status_v1 {
|
||||
u8 key[WOWLAN_KEY_MAX_SIZE];
|
||||
u8 ipn[6];
|
||||
u8 key_len;
|
||||
u8 key_flags;
|
||||
} __packed; /* WOWLAN_IGTK_MATERIAL_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_wowlan_igtk_status - IGTK status
|
||||
* @key: IGTK material
|
||||
|
|
@ -645,13 +700,17 @@ struct iwl_wowlan_gtk_status_v3 {
|
|||
* (0: index 6, 1: index 7 with bigtk)
|
||||
* bits[1:5]: IGTK index of the key in the internal DB
|
||||
* bit[6]: Set iff this is the currently used IGTK
|
||||
* @key_status: key status, see &enum iwl_wowlan_key_status
|
||||
* @reserved: padding
|
||||
*/
|
||||
struct iwl_wowlan_igtk_status {
|
||||
u8 key[WOWLAN_KEY_MAX_SIZE];
|
||||
u8 ipn[6];
|
||||
u8 key_len;
|
||||
u8 key_flags;
|
||||
} __packed; /* WOWLAN_IGTK_MATERIAL_VER_1 */
|
||||
u8 key_status;
|
||||
u8 reserved[3];
|
||||
} __packed; /* WOWLAN_IGTK_MATERIAL_VER_2 */
|
||||
|
||||
/**
|
||||
* struct iwl_wowlan_status_v6 - WoWLAN status
|
||||
|
|
@ -701,7 +760,7 @@ struct iwl_wowlan_status_v6 {
|
|||
*/
|
||||
struct iwl_wowlan_status_v7 {
|
||||
struct iwl_wowlan_gtk_status_v2 gtk[WOWLAN_GTK_KEYS_NUM];
|
||||
struct iwl_wowlan_igtk_status igtk[WOWLAN_IGTK_KEYS_NUM];
|
||||
struct iwl_wowlan_igtk_status_v1 igtk[WOWLAN_IGTK_KEYS_NUM];
|
||||
__le64 replay_ctr;
|
||||
__le16 pattern_number;
|
||||
__le16 non_qos_seq_ctr;
|
||||
|
|
@ -736,7 +795,7 @@ struct iwl_wowlan_status_v7 {
|
|||
*/
|
||||
struct iwl_wowlan_info_notif_v1 {
|
||||
struct iwl_wowlan_gtk_status_v3 gtk[WOWLAN_GTK_KEYS_NUM];
|
||||
struct iwl_wowlan_igtk_status igtk[WOWLAN_IGTK_KEYS_NUM];
|
||||
struct iwl_wowlan_igtk_status_v1 igtk[WOWLAN_IGTK_KEYS_NUM];
|
||||
__le64 replay_ctr;
|
||||
__le16 pattern_number;
|
||||
__le16 reserved1;
|
||||
|
|
@ -818,8 +877,8 @@ struct iwl_wowlan_mlo_gtk {
|
|||
*/
|
||||
struct iwl_wowlan_info_notif_v3 {
|
||||
struct iwl_wowlan_gtk_status_v3 gtk[WOWLAN_GTK_KEYS_NUM];
|
||||
struct iwl_wowlan_igtk_status igtk[WOWLAN_IGTK_KEYS_NUM];
|
||||
struct iwl_wowlan_igtk_status bigtk[WOWLAN_BIGTK_KEYS_NUM];
|
||||
struct iwl_wowlan_igtk_status_v1 igtk[WOWLAN_IGTK_KEYS_NUM];
|
||||
struct iwl_wowlan_igtk_status_v1 bigtk[WOWLAN_BIGTK_KEYS_NUM];
|
||||
__le64 replay_ctr;
|
||||
__le16 pattern_number;
|
||||
__le16 reserved1;
|
||||
|
|
@ -833,6 +892,45 @@ struct iwl_wowlan_info_notif_v3 {
|
|||
u8 reserved2[2];
|
||||
} __packed; /* WOWLAN_INFO_NTFY_API_S_VER_3 */
|
||||
|
||||
/**
|
||||
* struct iwl_wowlan_info_notif_v5 - WoWLAN information notification
|
||||
* @gtk: GTK data
|
||||
* @igtk: IGTK data
|
||||
* @bigtk: BIGTK data
|
||||
* @replay_ctr: GTK rekey replay counter
|
||||
* @pattern_number: number of the matched patterns
|
||||
* @qos_seq_ctr: QoS sequence counters to use next
|
||||
* @wakeup_reasons: wakeup reasons, see &enum iwl_wowlan_wakeup_reason
|
||||
* @num_of_gtk_rekeys: number of GTK rekeys
|
||||
* @transmitted_ndps: number of transmitted neighbor discovery packets
|
||||
* @received_beacons: number of received beacons
|
||||
* @tid_tear_down: bit mask of tids whose BA sessions were closed
|
||||
* in suspend state
|
||||
* @station_id: station id
|
||||
* @num_mlo_link_keys: number of &struct iwl_wowlan_mlo_gtk structs
|
||||
* following this notif
|
||||
* @tid_offloaded_tx: tid used by the firmware to transmit data packets
|
||||
* while in wowlan
|
||||
* @mlo_gtks: array of GTKs of size num_mlo_link_keys
|
||||
*/
|
||||
struct iwl_wowlan_info_notif_v5 {
|
||||
struct iwl_wowlan_gtk_status_v3 gtk[WOWLAN_GTK_KEYS_NUM];
|
||||
struct iwl_wowlan_igtk_status_v1 igtk[WOWLAN_IGTK_KEYS_NUM];
|
||||
struct iwl_wowlan_igtk_status_v1 bigtk[WOWLAN_BIGTK_KEYS_NUM];
|
||||
__le64 replay_ctr;
|
||||
__le16 pattern_number;
|
||||
__le16 qos_seq_ctr;
|
||||
__le32 wakeup_reasons;
|
||||
__le32 num_of_gtk_rekeys;
|
||||
__le32 transmitted_ndps;
|
||||
__le32 received_beacons;
|
||||
u8 tid_tear_down;
|
||||
u8 station_id;
|
||||
u8 num_mlo_link_keys;
|
||||
u8 tid_offloaded_tx;
|
||||
struct iwl_wowlan_mlo_gtk mlo_gtks[];
|
||||
} __packed; /* WOWLAN_INFO_NTFY_API_S_VER_5 */
|
||||
|
||||
/**
|
||||
* struct iwl_wowlan_info_notif - WoWLAN information notification
|
||||
* @gtk: GTK data
|
||||
|
|
@ -855,7 +953,7 @@ struct iwl_wowlan_info_notif_v3 {
|
|||
* @mlo_gtks: array of GTKs of size num_mlo_link_keys
|
||||
*/
|
||||
struct iwl_wowlan_info_notif {
|
||||
struct iwl_wowlan_gtk_status_v3 gtk[WOWLAN_GTK_KEYS_NUM];
|
||||
struct iwl_wowlan_gtk_status gtk[WOWLAN_GTK_KEYS_NUM];
|
||||
struct iwl_wowlan_igtk_status igtk[WOWLAN_IGTK_KEYS_NUM];
|
||||
struct iwl_wowlan_igtk_status bigtk[WOWLAN_BIGTK_KEYS_NUM];
|
||||
__le64 replay_ctr;
|
||||
|
|
@ -870,7 +968,7 @@ struct iwl_wowlan_info_notif {
|
|||
u8 num_mlo_link_keys;
|
||||
u8 tid_offloaded_tx;
|
||||
struct iwl_wowlan_mlo_gtk mlo_gtks[];
|
||||
} __packed; /* WOWLAN_INFO_NTFY_API_S_VER_5 */
|
||||
} __packed; /* WOWLAN_INFO_NTFY_API_S_VER_6 */
|
||||
|
||||
/**
|
||||
* struct iwl_wowlan_wake_pkt_notif - WoWLAN wake packet notification
|
||||
|
|
|
|||
|
|
@ -420,6 +420,8 @@ struct iwl_mac_config_cmd {
|
|||
* eht_support set to true. No longer used since _VER_3 of this command.
|
||||
* @LINK_CONTEXT_MODIFY_BANDWIDTH: Covers iwl_link_ctx_cfg_cmd::modify_bandwidth.
|
||||
* Request RX OMI to the AP to modify bandwidth of this link.
|
||||
* @LINK_CONTEXT_MODIFY_UHR_PARAMS: covers iwl_link_ctx_cfg_cmd::npca_params and
|
||||
* iwl_link_ctx_cfg_cmd::prio_edca_params. Since _VER_7.
|
||||
* @LINK_CONTEXT_MODIFY_ALL: set all above flags
|
||||
*/
|
||||
enum iwl_link_ctx_modify_flags {
|
||||
|
|
@ -432,6 +434,7 @@ enum iwl_link_ctx_modify_flags {
|
|||
LINK_CONTEXT_MODIFY_BSS_COLOR_DISABLE = BIT(6),
|
||||
LINK_CONTEXT_MODIFY_EHT_PARAMS = BIT(7),
|
||||
LINK_CONTEXT_MODIFY_BANDWIDTH = BIT(8),
|
||||
LINK_CONTEXT_MODIFY_UHR_PARAMS = BIT(9),
|
||||
LINK_CONTEXT_MODIFY_ALL = 0xff,
|
||||
}; /* LINK_CONTEXT_MODIFY_MASK_E_VER_1 */
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ enum iwl_prot_offload_subcmd_ids {
|
|||
/**
|
||||
* @WOWLAN_INFO_NOTIFICATION: Notification in
|
||||
* &struct iwl_wowlan_info_notif_v1, iwl_wowlan_info_notif_v3,
|
||||
* or &struct iwl_wowlan_info_notif
|
||||
* &struct iwl_wowlan_info_notif_v5 or &struct iwl_wowlan_info_notif
|
||||
*/
|
||||
WOWLAN_INFO_NOTIFICATION = 0xFD,
|
||||
|
||||
|
|
|
|||
|
|
@ -830,7 +830,7 @@ iwl_fw_error_dump_file(struct iwl_fw_runtime *fwrt,
|
|||
}
|
||||
|
||||
/* reading RXF/TXF sizes */
|
||||
if (test_bit(STATUS_FW_ERROR, &fwrt->trans->status)) {
|
||||
if (iwl_trans_is_fw_error(fwrt->trans)) {
|
||||
fifo_len = iwl_fw_rxf_len(fwrt, mem_cfg);
|
||||
fifo_len += iwl_fw_txf_len(fwrt, mem_cfg);
|
||||
|
||||
|
|
@ -3116,7 +3116,7 @@ static void iwl_send_dbg_dump_complete_cmd(struct iwl_fw_runtime *fwrt,
|
|||
.len[0] = sizeof(hcmd_data),
|
||||
};
|
||||
|
||||
if (test_bit(STATUS_FW_ERROR, &fwrt->trans->status))
|
||||
if (iwl_trans_is_fw_error(fwrt->trans))
|
||||
return;
|
||||
|
||||
if (fw_has_capa(&fwrt->fw->ucode_capa,
|
||||
|
|
|
|||
|
|
@ -178,7 +178,7 @@ static void iwl_fwrt_dump_lmac_error_log(struct iwl_fw_runtime *fwrt, u8 lmac_nu
|
|||
if (err)
|
||||
return;
|
||||
|
||||
err = iwl_finish_nic_init(trans);
|
||||
err = iwl_trans_activate_nic(trans);
|
||||
if (err)
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,11 +59,16 @@ static const struct dmi_system_id dmi_ppag_approved_list[] = {
|
|||
DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
|
||||
},
|
||||
},
|
||||
{ .ident = "ASUS",
|
||||
{ .ident = "ASUSTEK",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
},
|
||||
},
|
||||
{ .ident = "ASUS",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUS"),
|
||||
},
|
||||
},
|
||||
{ .ident = "GOOGLE-HP",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Google"),
|
||||
|
|
@ -141,11 +146,16 @@ static const struct dmi_system_id dmi_tas_approved_list[] = {
|
|||
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
|
||||
},
|
||||
},
|
||||
{ .ident = "ASUS",
|
||||
{ .ident = "ASUSTEK",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
},
|
||||
},
|
||||
{ .ident = "ASUS",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUS"),
|
||||
},
|
||||
},
|
||||
{ .ident = "GOOGLE-HP",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Google"),
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@
|
|||
#include "fw/api/phy.h"
|
||||
#include "fw/api/config.h"
|
||||
#include "fw/api/nvm-reg.h"
|
||||
#include "fw/img.h"
|
||||
#include "iwl-trans.h"
|
||||
|
||||
#define BIOS_SAR_MAX_PROFILE_NUM 4
|
||||
|
|
|
|||
|
|
@ -396,11 +396,11 @@ int iwl_dump_fh(struct iwl_trans *trans, char **buf)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int iwl_finish_nic_init(struct iwl_trans *trans)
|
||||
int iwl_trans_activate_nic(struct iwl_trans *trans)
|
||||
{
|
||||
return iwl_pcie_gen1_2_finish_nic_init(trans);
|
||||
return iwl_pcie_gen1_2_activate_nic(trans);
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_finish_nic_init);
|
||||
IWL_EXPORT_SYMBOL(iwl_trans_activate_nic);
|
||||
|
||||
void iwl_trans_sync_nmi_with_addr(struct iwl_trans *trans, u32 inta_addr,
|
||||
u32 sw_err_bit)
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs,
|
|||
void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask);
|
||||
void iwl_force_nmi(struct iwl_trans *trans);
|
||||
|
||||
int iwl_finish_nic_init(struct iwl_trans *trans);
|
||||
int iwl_trans_activate_nic(struct iwl_trans *trans);
|
||||
|
||||
/* Error handling */
|
||||
int iwl_dump_fh(struct iwl_trans *trans, char **buf);
|
||||
|
|
|
|||
|
|
@ -139,50 +139,6 @@ static struct ieee80211_rate iwl_cfg80211_rates[] = {
|
|||
#define RATES_52_OFFS 4
|
||||
#define N_RATES_52 (N_RATES_24 - RATES_52_OFFS)
|
||||
|
||||
/**
|
||||
* enum iwl_nvm_channel_flags - channel flags in NVM
|
||||
* @NVM_CHANNEL_VALID: channel is usable for this SKU/geo
|
||||
* @NVM_CHANNEL_IBSS: usable as an IBSS channel and deprecated
|
||||
* when %IWL_NVM_SBANDS_FLAGS_LAR enabled.
|
||||
* @NVM_CHANNEL_ALLOW_20MHZ_ACTIVITY: active scanning allowed and
|
||||
* AP allowed only in 20 MHz. Valid only
|
||||
* when %IWL_NVM_SBANDS_FLAGS_LAR enabled.
|
||||
* @NVM_CHANNEL_ACTIVE: active scanning allowed and allows IBSS
|
||||
* when %IWL_NVM_SBANDS_FLAGS_LAR enabled.
|
||||
* @NVM_CHANNEL_RADAR: radar detection required
|
||||
* @NVM_CHANNEL_INDOOR_ONLY: only indoor use is allowed
|
||||
* @NVM_CHANNEL_GO_CONCURRENT: GO operation is allowed when connected to BSS
|
||||
* on same channel on 2.4 or same UNII band on 5.2
|
||||
* @NVM_CHANNEL_UNIFORM: uniform spreading required
|
||||
* @NVM_CHANNEL_20MHZ: 20 MHz channel okay
|
||||
* @NVM_CHANNEL_40MHZ: 40 MHz channel okay
|
||||
* @NVM_CHANNEL_80MHZ: 80 MHz channel okay
|
||||
* @NVM_CHANNEL_160MHZ: 160 MHz channel okay
|
||||
* @NVM_CHANNEL_DC_HIGH: DC HIGH required/allowed (?)
|
||||
* @NVM_CHANNEL_VLP: client support connection to UHB VLP AP
|
||||
* @NVM_CHANNEL_AFC: client support connection to UHB AFC AP
|
||||
* @NVM_CHANNEL_VLP_AP_NOT_ALLOWED: UHB VLP AP not allowed,
|
||||
* Valid only when %NVM_CHANNEL_VLP is enabled.
|
||||
*/
|
||||
enum iwl_nvm_channel_flags {
|
||||
NVM_CHANNEL_VALID = BIT(0),
|
||||
NVM_CHANNEL_IBSS = BIT(1),
|
||||
NVM_CHANNEL_ALLOW_20MHZ_ACTIVITY = BIT(2),
|
||||
NVM_CHANNEL_ACTIVE = BIT(3),
|
||||
NVM_CHANNEL_RADAR = BIT(4),
|
||||
NVM_CHANNEL_INDOOR_ONLY = BIT(5),
|
||||
NVM_CHANNEL_GO_CONCURRENT = BIT(6),
|
||||
NVM_CHANNEL_UNIFORM = BIT(7),
|
||||
NVM_CHANNEL_20MHZ = BIT(8),
|
||||
NVM_CHANNEL_40MHZ = BIT(9),
|
||||
NVM_CHANNEL_80MHZ = BIT(10),
|
||||
NVM_CHANNEL_160MHZ = BIT(11),
|
||||
NVM_CHANNEL_DC_HIGH = BIT(12),
|
||||
NVM_CHANNEL_VLP = BIT(13),
|
||||
NVM_CHANNEL_AFC = BIT(14),
|
||||
NVM_CHANNEL_VLP_AP_NOT_ALLOWED = BIT(15),
|
||||
};
|
||||
|
||||
/**
|
||||
* enum iwl_reg_capa_flags_v1 - global flags applied for the whole regulatory
|
||||
* domain.
|
||||
|
|
@ -282,30 +238,6 @@ enum iwl_reg_capa_flags_v4 {
|
|||
*/
|
||||
#define REG_CAPA_V4_RESP_VER 8
|
||||
|
||||
/**
|
||||
* struct iwl_reg_capa - struct for global regulatory capabilities, Used for
|
||||
* handling the different APIs of reg_capa_flags.
|
||||
*
|
||||
* @allow_40mhz: 11n channel with a width of 40Mhz is allowed
|
||||
* for this regulatory domain.
|
||||
* @allow_80mhz: 11ac channel with a width of 80Mhz is allowed
|
||||
* for this regulatory domain (valid only in 5 and 6 Ghz).
|
||||
* @allow_160mhz: 11ac channel with a width of 160Mhz is allowed
|
||||
* for this regulatory domain (valid only in 5 and 6 Ghz).
|
||||
* @allow_320mhz: 11be channel with a width of 320Mhz is allowed
|
||||
* for this regulatory domain (valid only in 6 Ghz).
|
||||
* @disable_11ax: 11ax is forbidden for this regulatory domain.
|
||||
* @disable_11be: 11be is forbidden for this regulatory domain.
|
||||
*/
|
||||
struct iwl_reg_capa {
|
||||
bool allow_40mhz;
|
||||
bool allow_80mhz;
|
||||
bool allow_160mhz;
|
||||
bool allow_320mhz;
|
||||
bool disable_11ax;
|
||||
bool disable_11be;
|
||||
};
|
||||
|
||||
static inline void iwl_nvm_print_channel_flags(struct device *dev, u32 level,
|
||||
int chan, u32 flags)
|
||||
{
|
||||
|
|
@ -1596,9 +1528,10 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_rf_cfg *cfg,
|
|||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_parse_nvm_data);
|
||||
|
||||
static u32 iwl_nvm_get_regdom_bw_flags(const u16 *nvm_chan,
|
||||
int ch_idx, u16 nvm_flags,
|
||||
struct iwl_reg_capa reg_capa)
|
||||
VISIBLE_IF_IWLWIFI_KUNIT
|
||||
u32 iwl_nvm_get_regdom_bw_flags(const u16 *nvm_chan,
|
||||
int ch_idx, u16 nvm_flags,
|
||||
struct iwl_reg_capa reg_capa)
|
||||
{
|
||||
u32 flags = NL80211_RRF_NO_HT40;
|
||||
|
||||
|
|
@ -1688,6 +1621,7 @@ static u32 iwl_nvm_get_regdom_bw_flags(const u16 *nvm_chan,
|
|||
|
||||
return flags;
|
||||
}
|
||||
EXPORT_SYMBOL_IF_IWLWIFI_KUNIT(iwl_nvm_get_regdom_bw_flags);
|
||||
|
||||
static struct iwl_reg_capa iwl_get_reg_capa(u32 flags, u8 resp_ver)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -21,6 +21,80 @@ enum iwl_nvm_sbands_flags {
|
|||
IWL_NVM_SBANDS_FLAGS_NO_WIDE_IN_5GHZ = BIT(1),
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_reg_capa - struct for global regulatory capabilities, Used for
|
||||
* handling the different APIs of reg_capa_flags.
|
||||
*
|
||||
* @allow_40mhz: 11n channel with a width of 40Mhz is allowed
|
||||
* for this regulatory domain.
|
||||
* @allow_80mhz: 11ac channel with a width of 80Mhz is allowed
|
||||
* for this regulatory domain (valid only in 5 and 6 Ghz).
|
||||
* @allow_160mhz: 11ac channel with a width of 160Mhz is allowed
|
||||
* for this regulatory domain (valid only in 5 and 6 Ghz).
|
||||
* @allow_320mhz: 11be channel with a width of 320Mhz is allowed
|
||||
* for this regulatory domain (valid only in 6 Ghz).
|
||||
* @disable_11ax: 11ax is forbidden for this regulatory domain.
|
||||
* @disable_11be: 11be is forbidden for this regulatory domain.
|
||||
*/
|
||||
struct iwl_reg_capa {
|
||||
bool allow_40mhz;
|
||||
bool allow_80mhz;
|
||||
bool allow_160mhz;
|
||||
bool allow_320mhz;
|
||||
bool disable_11ax;
|
||||
bool disable_11be;
|
||||
};
|
||||
|
||||
/**
|
||||
* enum iwl_nvm_channel_flags - channel flags in NVM
|
||||
* @NVM_CHANNEL_VALID: channel is usable for this SKU/geo
|
||||
* @NVM_CHANNEL_IBSS: usable as an IBSS channel and deprecated
|
||||
* when %IWL_NVM_SBANDS_FLAGS_LAR enabled.
|
||||
* @NVM_CHANNEL_ALLOW_20MHZ_ACTIVITY: active scanning allowed and
|
||||
* AP allowed only in 20 MHz. Valid only
|
||||
* when %IWL_NVM_SBANDS_FLAGS_LAR enabled.
|
||||
* @NVM_CHANNEL_ACTIVE: active scanning allowed and allows IBSS
|
||||
* when %IWL_NVM_SBANDS_FLAGS_LAR enabled.
|
||||
* @NVM_CHANNEL_RADAR: radar detection required
|
||||
* @NVM_CHANNEL_INDOOR_ONLY: only indoor use is allowed
|
||||
* @NVM_CHANNEL_GO_CONCURRENT: GO operation is allowed when connected to BSS
|
||||
* on same channel on 2.4 or same UNII band on 5.2
|
||||
* @NVM_CHANNEL_UNIFORM: uniform spreading required
|
||||
* @NVM_CHANNEL_20MHZ: 20 MHz channel okay
|
||||
* @NVM_CHANNEL_40MHZ: 40 MHz channel okay
|
||||
* @NVM_CHANNEL_80MHZ: 80 MHz channel okay
|
||||
* @NVM_CHANNEL_160MHZ: 160 MHz channel okay
|
||||
* @NVM_CHANNEL_DC_HIGH: DC HIGH required/allowed (?)
|
||||
* @NVM_CHANNEL_VLP: client support connection to UHB VLP AP
|
||||
* @NVM_CHANNEL_AFC: client support connection to UHB AFC AP
|
||||
* @NVM_CHANNEL_VLP_AP_NOT_ALLOWED: UHB VLP AP not allowed,
|
||||
* Valid only when %NVM_CHANNEL_VLP is enabled.
|
||||
*/
|
||||
enum iwl_nvm_channel_flags {
|
||||
NVM_CHANNEL_VALID = BIT(0),
|
||||
NVM_CHANNEL_IBSS = BIT(1),
|
||||
NVM_CHANNEL_ALLOW_20MHZ_ACTIVITY = BIT(2),
|
||||
NVM_CHANNEL_ACTIVE = BIT(3),
|
||||
NVM_CHANNEL_RADAR = BIT(4),
|
||||
NVM_CHANNEL_INDOOR_ONLY = BIT(5),
|
||||
NVM_CHANNEL_GO_CONCURRENT = BIT(6),
|
||||
NVM_CHANNEL_UNIFORM = BIT(7),
|
||||
NVM_CHANNEL_20MHZ = BIT(8),
|
||||
NVM_CHANNEL_40MHZ = BIT(9),
|
||||
NVM_CHANNEL_80MHZ = BIT(10),
|
||||
NVM_CHANNEL_160MHZ = BIT(11),
|
||||
NVM_CHANNEL_DC_HIGH = BIT(12),
|
||||
NVM_CHANNEL_VLP = BIT(13),
|
||||
NVM_CHANNEL_AFC = BIT(14),
|
||||
NVM_CHANNEL_VLP_AP_NOT_ALLOWED = BIT(15),
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_IWLWIFI_KUNIT_TESTS)
|
||||
u32 iwl_nvm_get_regdom_bw_flags(const u16 *nvm_chan,
|
||||
int ch_idx, u16 nvm_flags,
|
||||
struct iwl_reg_capa reg_capa);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* iwl_parse_nvm_data - parse NVM data and return values
|
||||
*
|
||||
|
|
|
|||
|
|
@ -807,3 +807,18 @@ void iwl_trans_set_reduce_power(struct iwl_trans *trans,
|
|||
{
|
||||
iwl_trans_pcie_ctx_info_v2_set_reduce_power(trans, capa);
|
||||
}
|
||||
|
||||
bool iwl_trans_is_pm_supported(struct iwl_trans *trans)
|
||||
{
|
||||
if (WARN_ON(trans->mac_cfg->gen2))
|
||||
return false;
|
||||
|
||||
return iwl_pcie_gen1_is_pm_supported(trans);
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_trans_is_pm_supported);
|
||||
|
||||
bool iwl_trans_is_ltr_enabled(struct iwl_trans *trans)
|
||||
{
|
||||
return iwl_pcie_gen1_2_is_ltr_enabled(trans);
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_trans_is_ltr_enabled);
|
||||
|
|
|
|||
|
|
@ -284,8 +284,6 @@ static inline void iwl_free_rxb(struct iwl_rx_cmd_buffer *r)
|
|||
* @STATUS_RFKILL_OPMODE: RF-kill state reported to opmode
|
||||
* @STATUS_FW_ERROR: the fw is in error state
|
||||
* @STATUS_TRANS_DEAD: trans is dead - avoid any read/write operation
|
||||
* @STATUS_SUPPRESS_CMD_ERROR_ONCE: suppress "FW error in SYNC CMD" once,
|
||||
* e.g. for testing
|
||||
* @STATUS_IN_SW_RESET: device is undergoing reset, cleared by opmode
|
||||
* via iwl_trans_finish_sw_reset()
|
||||
* @STATUS_RESET_PENDING: reset worker was scheduled, but didn't dump
|
||||
|
|
@ -302,7 +300,6 @@ enum iwl_trans_status {
|
|||
STATUS_RFKILL_OPMODE,
|
||||
STATUS_FW_ERROR,
|
||||
STATUS_TRANS_DEAD,
|
||||
STATUS_SUPPRESS_CMD_ERROR_ONCE,
|
||||
STATUS_IN_SW_RESET,
|
||||
STATUS_RESET_PENDING,
|
||||
STATUS_TRANS_RESET_IN_PROGRESS,
|
||||
|
|
@ -847,8 +844,8 @@ struct iwl_trans_info {
|
|||
* @dev: pointer to struct device * that represents the device
|
||||
* @info: device information for use by other layers
|
||||
* @pnvm_loaded: indicates PNVM was loaded
|
||||
* @pm_support: set to true in start_hw if link pm is supported
|
||||
* @ltr_enabled: set to true if the LTR is enabled
|
||||
* @suppress_cmd_error_once: suppress "FW error in SYNC CMD" once,
|
||||
* e.g. for testing
|
||||
* @fail_to_parse_pnvm_image: set to true if pnvm parsing failed
|
||||
* @reduce_power_loaded: indicates reduced power section was loaded
|
||||
* @failed_to_load_reduce_power_image: set to true if pnvm loading failed
|
||||
|
|
@ -883,9 +880,8 @@ struct iwl_trans {
|
|||
const struct iwl_trans_info info;
|
||||
bool reduced_cap_sku;
|
||||
bool step_urm;
|
||||
bool suppress_cmd_error_once;
|
||||
|
||||
bool pm_support;
|
||||
bool ltr_enabled;
|
||||
u8 pnvm_loaded:1;
|
||||
u8 fail_to_parse_pnvm_image:1;
|
||||
u8 reduce_power_loaded:1;
|
||||
|
|
@ -1194,11 +1190,6 @@ static inline u16 iwl_trans_get_num_rbds(struct iwl_trans *trans)
|
|||
return result;
|
||||
}
|
||||
|
||||
static inline void iwl_trans_suppress_cmd_error_once(struct iwl_trans *trans)
|
||||
{
|
||||
set_bit(STATUS_SUPPRESS_CMD_ERROR_ONCE, &trans->status);
|
||||
}
|
||||
|
||||
static inline bool iwl_trans_device_enabled(struct iwl_trans *trans)
|
||||
{
|
||||
return test_bit(STATUS_DEVICE_ENABLED, &trans->status);
|
||||
|
|
@ -1209,6 +1200,20 @@ static inline bool iwl_trans_is_dead(struct iwl_trans *trans)
|
|||
return test_bit(STATUS_TRANS_DEAD, &trans->status);
|
||||
}
|
||||
|
||||
static inline bool iwl_trans_is_fw_error(struct iwl_trans *trans)
|
||||
{
|
||||
return test_bit(STATUS_FW_ERROR, &trans->status);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function notifies the transport layer of firmware error, the recovery
|
||||
* will be handled by the op mode
|
||||
*/
|
||||
static inline void iwl_trans_notify_fw_error(struct iwl_trans *trans)
|
||||
{
|
||||
trans->state = IWL_TRANS_NO_FW;
|
||||
set_bit(STATUS_FW_ERROR, &trans->status);
|
||||
}
|
||||
/*****************************************************
|
||||
* PCIe handling
|
||||
*****************************************************/
|
||||
|
|
@ -1253,4 +1258,8 @@ static inline u16 iwl_trans_get_device_id(struct iwl_trans *trans)
|
|||
return u32_get_bits(trans->info.hw_id, GENMASK(31, 16));
|
||||
}
|
||||
|
||||
bool iwl_trans_is_pm_supported(struct iwl_trans *trans);
|
||||
|
||||
bool iwl_trans_is_ltr_enabled(struct iwl_trans *trans);
|
||||
|
||||
#endif /* __iwl_trans_h__ */
|
||||
|
|
|
|||
|
|
@ -300,13 +300,11 @@ enum iwl_sap_msg {
|
|||
* @type: See &enum iwl_sap_msg.
|
||||
* @len: The length of the message (header not included).
|
||||
* @seq_num: For debug.
|
||||
* @payload: The payload of the message.
|
||||
*/
|
||||
struct iwl_sap_hdr {
|
||||
__le16 type;
|
||||
__le16 len;
|
||||
__le32 seq_num;
|
||||
u8 payload[];
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -281,7 +281,7 @@ iwl_mld_convert_gtk_resume_seq(struct iwl_mld_mcast_key_data *gtk_data,
|
|||
static void
|
||||
iwl_mld_convert_gtk_resume_data(struct iwl_mld *mld,
|
||||
struct iwl_mld_wowlan_status *wowlan_status,
|
||||
const struct iwl_wowlan_gtk_status_v3 *gtk_data,
|
||||
const struct iwl_wowlan_gtk_status *gtk_data,
|
||||
const struct iwl_wowlan_all_rsc_tsc_v5 *sc)
|
||||
{
|
||||
int status_idx = 0;
|
||||
|
|
@ -293,8 +293,9 @@ iwl_mld_convert_gtk_resume_data(struct iwl_mld *mld,
|
|||
for (int notif_idx = 0; notif_idx < ARRAY_SIZE(wowlan_status->gtk);
|
||||
notif_idx++) {
|
||||
int rsc_idx;
|
||||
u8 key_status = gtk_data[notif_idx].key_status;
|
||||
|
||||
if (!(gtk_data[notif_idx].key_len))
|
||||
if (!key_status)
|
||||
continue;
|
||||
|
||||
wowlan_status->gtk[status_idx].len =
|
||||
|
|
@ -304,10 +305,6 @@ iwl_mld_convert_gtk_resume_data(struct iwl_mld *mld,
|
|||
wowlan_status->gtk[status_idx].id =
|
||||
wowlan_status->gtk[status_idx].flags &
|
||||
IWL_WOWLAN_GTK_IDX_MASK;
|
||||
memcpy(wowlan_status->gtk[status_idx].key,
|
||||
gtk_data[notif_idx].key,
|
||||
sizeof(gtk_data[notif_idx].key));
|
||||
|
||||
/* The rsc for both gtk keys are stored in gtk[0]->sc->mcast_rsc
|
||||
* The gtk ids can be any two numbers between 0 and 3,
|
||||
* the id_map maps between the key id and the index in sc->mcast
|
||||
|
|
@ -317,13 +314,27 @@ iwl_mld_convert_gtk_resume_data(struct iwl_mld *mld,
|
|||
iwl_mld_convert_gtk_resume_seq(&wowlan_status->gtk[status_idx],
|
||||
sc, rsc_idx);
|
||||
|
||||
/* if it's as long as the TKIP encryption key, copy MIC key */
|
||||
if (wowlan_status->gtk[status_idx].len ==
|
||||
NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY)
|
||||
memcpy(wowlan_status->gtk[status_idx].key +
|
||||
NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY,
|
||||
gtk_data[notif_idx].tkip_mic_key,
|
||||
sizeof(gtk_data[notif_idx].tkip_mic_key));
|
||||
if (key_status == IWL_WOWLAN_STATUS_NEW_KEY) {
|
||||
memcpy(wowlan_status->gtk[status_idx].key,
|
||||
gtk_data[notif_idx].key,
|
||||
sizeof(gtk_data[notif_idx].key));
|
||||
|
||||
/* if it's as long as the TKIP encryption key,
|
||||
* copy MIC key
|
||||
*/
|
||||
if (wowlan_status->gtk[status_idx].len ==
|
||||
NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY)
|
||||
memcpy(wowlan_status->gtk[status_idx].key +
|
||||
NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY,
|
||||
gtk_data[notif_idx].tkip_mic_key,
|
||||
sizeof(gtk_data[notif_idx].tkip_mic_key));
|
||||
} else {
|
||||
/* If the key status is WOWLAN_STATUS_OLD_KEY, it
|
||||
* indicates that no key material is present, Set the
|
||||
* key length to 0 as an indication
|
||||
*/
|
||||
wowlan_status->gtk[status_idx].len = 0;
|
||||
}
|
||||
status_idx++;
|
||||
}
|
||||
}
|
||||
|
|
@ -370,11 +381,11 @@ static void
|
|||
iwl_mld_convert_igtk_resume_data(struct iwl_mld_wowlan_status *wowlan_status,
|
||||
const struct iwl_wowlan_igtk_status *igtk)
|
||||
{
|
||||
BUILD_BUG_ON(sizeof(wowlan_status->igtk.key) < sizeof(igtk->key));
|
||||
|
||||
if (!igtk->key_len)
|
||||
if (!igtk->key_status)
|
||||
return;
|
||||
|
||||
BUILD_BUG_ON(sizeof(wowlan_status->igtk.key) < sizeof(igtk->key));
|
||||
|
||||
wowlan_status->igtk.len = igtk->key_len;
|
||||
wowlan_status->igtk.flags = igtk->key_flags;
|
||||
wowlan_status->igtk.id =
|
||||
|
|
@ -382,7 +393,15 @@ iwl_mld_convert_igtk_resume_data(struct iwl_mld_wowlan_status *wowlan_status,
|
|||
IWL_WOWLAN_IGTK_BIGTK_IDX_MASK) +
|
||||
WOWLAN_IGTK_MIN_INDEX;
|
||||
|
||||
memcpy(wowlan_status->igtk.key, igtk->key, sizeof(igtk->key));
|
||||
if (igtk->key_status == IWL_WOWLAN_STATUS_NEW_KEY)
|
||||
memcpy(wowlan_status->igtk.key, igtk->key, sizeof(igtk->key));
|
||||
else
|
||||
/* If the key status is WOWLAN_STATUS_OLD_KEY, it indicates
|
||||
* that no key material is present. Set the key length to 0
|
||||
* as an indication.
|
||||
*/
|
||||
wowlan_status->igtk.len = 0;
|
||||
|
||||
iwl_mld_convert_mcast_ipn(&wowlan_status->igtk, igtk);
|
||||
}
|
||||
|
||||
|
|
@ -396,7 +415,7 @@ iwl_mld_convert_bigtk_resume_data(struct iwl_mld_wowlan_status *wowlan_status,
|
|||
|
||||
for (int notif_idx = 0; notif_idx < WOWLAN_BIGTK_KEYS_NUM;
|
||||
notif_idx++) {
|
||||
if (!bigtk[notif_idx].key_len)
|
||||
if (!bigtk[notif_idx].key_status)
|
||||
continue;
|
||||
|
||||
wowlan_status->bigtk[status_idx].len = bigtk[notif_idx].key_len;
|
||||
|
|
@ -409,8 +428,17 @@ iwl_mld_convert_bigtk_resume_data(struct iwl_mld_wowlan_status *wowlan_status,
|
|||
|
||||
BUILD_BUG_ON(sizeof(wowlan_status->bigtk[status_idx].key) <
|
||||
sizeof(bigtk[notif_idx].key));
|
||||
memcpy(wowlan_status->bigtk[status_idx].key,
|
||||
bigtk[notif_idx].key, sizeof(bigtk[notif_idx].key));
|
||||
if (bigtk[notif_idx].key_status == IWL_WOWLAN_STATUS_NEW_KEY)
|
||||
memcpy(wowlan_status->bigtk[status_idx].key,
|
||||
bigtk[notif_idx].key,
|
||||
sizeof(bigtk[notif_idx].key));
|
||||
else
|
||||
/* If the key status is WOWLAN_STATUS_OLD_KEY, it
|
||||
* indicates that no key material is present. Set the
|
||||
* key length to 0 as an indication.
|
||||
*/
|
||||
wowlan_status->bigtk[status_idx].len = 0;
|
||||
|
||||
iwl_mld_convert_mcast_ipn(&wowlan_status->bigtk[status_idx],
|
||||
&bigtk[notif_idx]);
|
||||
status_idx++;
|
||||
|
|
@ -453,34 +481,165 @@ iwl_mld_convert_mlo_keys(struct iwl_mld *mld,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
iwl_mld_convert_wowlan_notif_v5(const struct iwl_wowlan_info_notif_v5 *notif_v5,
|
||||
struct iwl_wowlan_info_notif *notif)
|
||||
{
|
||||
/* Convert GTK from v3 to the new format */
|
||||
BUILD_BUG_ON(ARRAY_SIZE(notif->gtk) != ARRAY_SIZE(notif_v5->gtk));
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(notif_v5->gtk); i++) {
|
||||
const struct iwl_wowlan_gtk_status_v3 *gtk_v3 = ¬if_v5->gtk[i];
|
||||
struct iwl_wowlan_gtk_status *gtk = ¬if->gtk[i];
|
||||
|
||||
/* Copy key material and metadata */
|
||||
BUILD_BUG_ON(sizeof(gtk->key) != sizeof(gtk_v3->key));
|
||||
BUILD_BUG_ON(sizeof(gtk->tkip_mic_key) != sizeof(gtk_v3->tkip_mic_key));
|
||||
|
||||
memcpy(gtk->key, gtk_v3->key, sizeof(gtk_v3->key));
|
||||
|
||||
gtk->key_len = gtk_v3->key_len;
|
||||
gtk->key_flags = gtk_v3->key_flags;
|
||||
|
||||
memcpy(gtk->tkip_mic_key, gtk_v3->tkip_mic_key,
|
||||
sizeof(gtk_v3->tkip_mic_key));
|
||||
gtk->sc = gtk_v3->sc;
|
||||
|
||||
/* Set key_status based on whether key material is present.
|
||||
* in v5, a key is either invalid (should be skipped) or has
|
||||
* both meta data and the key itself.
|
||||
*/
|
||||
if (gtk_v3->key_len)
|
||||
gtk->key_status = IWL_WOWLAN_STATUS_NEW_KEY;
|
||||
}
|
||||
|
||||
/* Convert IGTK from v1 to the new format, only one IGTK is passed by FW */
|
||||
BUILD_BUG_ON(offsetof(struct iwl_wowlan_igtk_status, key_status) !=
|
||||
sizeof(struct iwl_wowlan_igtk_status_v1));
|
||||
|
||||
memcpy(¬if->igtk[0], ¬if_v5->igtk[0],
|
||||
offsetof(struct iwl_wowlan_igtk_status, key_status));
|
||||
|
||||
/* Set key_status based on whether key material is present.
|
||||
* in v5, a key is either invalid (should be skipped) or has
|
||||
* both meta data and the key itself.
|
||||
*/
|
||||
if (notif_v5->igtk[0].key_len)
|
||||
notif->igtk[0].key_status = IWL_WOWLAN_STATUS_NEW_KEY;
|
||||
|
||||
/* Convert BIGTK from v1 to the new format */
|
||||
BUILD_BUG_ON(ARRAY_SIZE(notif->bigtk) != ARRAY_SIZE(notif_v5->bigtk));
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(notif_v5->bigtk); i++) {
|
||||
/* Copy everything until key_status */
|
||||
memcpy(¬if->bigtk[i], ¬if_v5->bigtk[i],
|
||||
offsetof(struct iwl_wowlan_igtk_status, key_status));
|
||||
|
||||
/* Set key_status based on whether key material is present.
|
||||
* in v5, a key is either invalid (should be skipped) or has
|
||||
* both meta data and the key itself.
|
||||
*/
|
||||
if (notif_v5->bigtk[i].key_len)
|
||||
notif->bigtk[i].key_status = IWL_WOWLAN_STATUS_NEW_KEY;
|
||||
}
|
||||
|
||||
notif->replay_ctr = notif_v5->replay_ctr;
|
||||
notif->pattern_number = notif_v5->pattern_number;
|
||||
notif->qos_seq_ctr = notif_v5->qos_seq_ctr;
|
||||
notif->wakeup_reasons = notif_v5->wakeup_reasons;
|
||||
notif->num_of_gtk_rekeys = notif_v5->num_of_gtk_rekeys;
|
||||
notif->transmitted_ndps = notif_v5->transmitted_ndps;
|
||||
notif->received_beacons = notif_v5->received_beacons;
|
||||
notif->tid_tear_down = notif_v5->tid_tear_down;
|
||||
notif->station_id = notif_v5->station_id;
|
||||
notif->num_mlo_link_keys = notif_v5->num_mlo_link_keys;
|
||||
notif->tid_offloaded_tx = notif_v5->tid_offloaded_tx;
|
||||
|
||||
/* Copy MLO GTK keys */
|
||||
if (notif_v5->num_mlo_link_keys) {
|
||||
memcpy(notif->mlo_gtks, notif_v5->mlo_gtks,
|
||||
notif_v5->num_mlo_link_keys * sizeof(struct iwl_wowlan_mlo_gtk));
|
||||
}
|
||||
}
|
||||
|
||||
static bool iwl_mld_validate_wowlan_notif_size(struct iwl_mld *mld,
|
||||
u32 len,
|
||||
u32 expected_len,
|
||||
u8 num_mlo_keys,
|
||||
int version)
|
||||
{
|
||||
u32 len_with_mlo_keys;
|
||||
|
||||
if (IWL_FW_CHECK(mld, len < expected_len,
|
||||
"Invalid wowlan_info_notif v%d (expected=%u got=%u)\n",
|
||||
version, expected_len, len))
|
||||
return false;
|
||||
|
||||
len_with_mlo_keys = expected_len +
|
||||
(num_mlo_keys * sizeof(struct iwl_wowlan_mlo_gtk));
|
||||
|
||||
if (IWL_FW_CHECK(mld, len < len_with_mlo_keys,
|
||||
"Invalid wowlan_info_notif v%d with MLO keys (expected=%u got=%u)\n",
|
||||
version, len_with_mlo_keys, len))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
iwl_mld_handle_wowlan_info_notif(struct iwl_mld *mld,
|
||||
struct iwl_mld_wowlan_status *wowlan_status,
|
||||
struct iwl_rx_packet *pkt)
|
||||
{
|
||||
const struct iwl_wowlan_info_notif *notif = (void *)pkt->data;
|
||||
const struct iwl_wowlan_info_notif *notif;
|
||||
struct iwl_wowlan_info_notif *converted_notif __free(kfree) = NULL;
|
||||
u32 len = iwl_rx_packet_payload_len(pkt);
|
||||
u32 len_with_mlo_keys;
|
||||
int wowlan_info_ver = iwl_fw_lookup_notif_ver(mld->fw,
|
||||
PROT_OFFLOAD_GROUP,
|
||||
WOWLAN_INFO_NOTIFICATION,
|
||||
IWL_FW_CMD_VER_UNKNOWN);
|
||||
|
||||
if (IWL_FW_CHECK(mld, len < sizeof(*notif),
|
||||
"Invalid wowlan_info_notif (expected=%zu got=%u)\n",
|
||||
sizeof(*notif), len))
|
||||
return true;
|
||||
|
||||
/* Now that we know that we have at least sizeof(notif),
|
||||
* check also the variable length part
|
||||
*/
|
||||
len_with_mlo_keys = sizeof(*notif) +
|
||||
notif->num_mlo_link_keys * sizeof(notif->mlo_gtks[0]);
|
||||
|
||||
if (IWL_FW_CHECK(mld, len < len_with_mlo_keys,
|
||||
"Invalid wowlan_info_notif (expected=%ud got=%u)\n",
|
||||
len_with_mlo_keys, len))
|
||||
if (wowlan_info_ver == 5) {
|
||||
/* v5 format - validate before conversion */
|
||||
const struct iwl_wowlan_info_notif_v5 *notif_v5 = (void *)pkt->data;
|
||||
|
||||
if (!iwl_mld_validate_wowlan_notif_size(mld, len,
|
||||
sizeof(*notif_v5),
|
||||
notif_v5->num_mlo_link_keys,
|
||||
5))
|
||||
return true;
|
||||
|
||||
converted_notif = kzalloc(struct_size(converted_notif,
|
||||
mlo_gtks,
|
||||
notif_v5->num_mlo_link_keys),
|
||||
GFP_ATOMIC);
|
||||
if (!converted_notif) {
|
||||
IWL_ERR(mld,
|
||||
"Failed to allocate memory for converted wowlan_info_notif\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
iwl_mld_convert_wowlan_notif_v5(notif_v5,
|
||||
converted_notif);
|
||||
notif = converted_notif;
|
||||
} else if (wowlan_info_ver == 6) {
|
||||
notif = (void *)pkt->data;
|
||||
if (!iwl_mld_validate_wowlan_notif_size(mld, len,
|
||||
sizeof(*notif),
|
||||
notif->num_mlo_link_keys,
|
||||
6))
|
||||
return true;
|
||||
} else {
|
||||
/* smaller versions are not supported */
|
||||
IWL_WARN(mld,
|
||||
"Unsupported wowlan_info_notif version %d\n",
|
||||
wowlan_info_ver);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (IWL_FW_CHECK(mld, notif->tid_offloaded_tx != IWL_WOWLAN_OFFLOAD_TID,
|
||||
"Invalid tid_offloaded_tx %d\n",
|
||||
wowlan_status->tid_offloaded_tx))
|
||||
notif->tid_offloaded_tx))
|
||||
return true;
|
||||
|
||||
iwl_mld_convert_gtk_resume_data(mld, wowlan_status, notif->gtk,
|
||||
|
|
@ -1213,8 +1372,7 @@ static int iwl_mld_wait_d3_notif(struct iwl_mld *mld,
|
|||
ret = iwl_trans_d3_resume(mld->trans, false);
|
||||
if (ret) {
|
||||
/* Avoid sending commands if the FW is dead */
|
||||
mld->trans->state = IWL_TRANS_NO_FW;
|
||||
set_bit(STATUS_FW_ERROR, &mld->trans->status);
|
||||
iwl_trans_notify_fw_error(mld->trans);
|
||||
iwl_remove_notification(&mld->notif_wait, &wait_d3_notif);
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -1267,8 +1425,7 @@ int iwl_mld_no_wowlan_suspend(struct iwl_mld *mld)
|
|||
if (ret) {
|
||||
IWL_ERR(mld, "d3 suspend: trans_d3_suspend failed %d\n", ret);
|
||||
/* We are going to stop the FW. Avoid sending commands in that flow */
|
||||
mld->trans->state = IWL_TRANS_NO_FW;
|
||||
set_bit(STATUS_FW_ERROR, &mld->trans->status);
|
||||
iwl_trans_notify_fw_error(mld->trans);
|
||||
} else {
|
||||
/* Async notification might send hcmds, which is not allowed in suspend */
|
||||
iwl_mld_cancel_async_notifications(mld);
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ static ssize_t iwl_dbgfs_fw_restart_write(struct iwl_mld *mld, char *buf,
|
|||
|
||||
if (count == 6 && !strcmp(buf, "nolog\n")) {
|
||||
mld->fw_status.do_not_dump_once = true;
|
||||
iwl_trans_suppress_cmd_error_once(mld->trans);
|
||||
mld->trans->suppress_cmd_error_once = true;
|
||||
}
|
||||
|
||||
/* take the return value to make compiler happy - it will
|
||||
|
|
@ -1001,8 +1001,12 @@ void iwl_mld_add_link_debugfs(struct ieee80211_hw *hw,
|
|||
* If not, this is a per-link dir of a MLO vif, add in it the iwlmld
|
||||
* dir.
|
||||
*/
|
||||
if (!mld_link_dir)
|
||||
if (!mld_link_dir) {
|
||||
mld_link_dir = debugfs_create_dir("iwlmld", dir);
|
||||
} else {
|
||||
/* Release the reference from debugfs_lookup */
|
||||
dput(mld_link_dir);
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t _iwl_dbgfs_fixed_rate_write(struct iwl_mld *mld, char *buf,
|
||||
|
|
|
|||
|
|
@ -115,20 +115,12 @@ static bool iwl_mld_is_nic_ack_enabled(struct iwl_mld *mld,
|
|||
|
||||
static void iwl_mld_set_he_support(struct iwl_mld *mld,
|
||||
struct ieee80211_vif *vif,
|
||||
struct iwl_mac_config_cmd *cmd,
|
||||
int cmd_ver)
|
||||
struct iwl_mac_config_cmd *cmd)
|
||||
{
|
||||
if (vif->type == NL80211_IFTYPE_AP) {
|
||||
if (cmd_ver == 2)
|
||||
cmd->wifi_gen_v2.he_ap_support = cpu_to_le16(1);
|
||||
else
|
||||
cmd->wifi_gen.he_ap_support = 1;
|
||||
} else {
|
||||
if (cmd_ver == 2)
|
||||
cmd->wifi_gen_v2.he_support = cpu_to_le16(1);
|
||||
else
|
||||
cmd->wifi_gen.he_support = 1;
|
||||
}
|
||||
if (vif->type == NL80211_IFTYPE_AP)
|
||||
cmd->wifi_gen.he_ap_support = 1;
|
||||
else
|
||||
cmd->wifi_gen.he_support = 1;
|
||||
}
|
||||
|
||||
/* fill the common part for all interface types */
|
||||
|
|
@ -140,9 +132,6 @@ static void iwl_mld_mac_cmd_fill_common(struct iwl_mld *mld,
|
|||
struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif);
|
||||
struct ieee80211_bss_conf *link_conf;
|
||||
unsigned int link_id;
|
||||
int cmd_ver = iwl_fw_lookup_cmd_ver(mld->fw,
|
||||
WIDE_ID(MAC_CONF_GROUP,
|
||||
MAC_CONFIG_CMD), 0);
|
||||
|
||||
lockdep_assert_wiphy(mld->wiphy);
|
||||
|
||||
|
|
@ -169,11 +158,8 @@ static void iwl_mld_mac_cmd_fill_common(struct iwl_mld *mld,
|
|||
* and enable both when we have MLO.
|
||||
*/
|
||||
if (ieee80211_vif_is_mld(vif)) {
|
||||
iwl_mld_set_he_support(mld, vif, cmd, cmd_ver);
|
||||
if (cmd_ver == 2)
|
||||
cmd->wifi_gen_v2.eht_support = cpu_to_le32(1);
|
||||
else
|
||||
cmd->wifi_gen.eht_support = 1;
|
||||
iwl_mld_set_he_support(mld, vif, cmd);
|
||||
cmd->wifi_gen.eht_support = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -181,7 +167,7 @@ static void iwl_mld_mac_cmd_fill_common(struct iwl_mld *mld,
|
|||
if (!link_conf->he_support)
|
||||
continue;
|
||||
|
||||
iwl_mld_set_he_support(mld, vif, cmd, cmd_ver);
|
||||
iwl_mld_set_he_support(mld, vif, cmd);
|
||||
|
||||
/* EHT, if supported, was already set above */
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -626,7 +626,7 @@ int iwl_mld_mac80211_add_interface(struct ieee80211_hw *hw,
|
|||
IEEE80211_VIF_SUPPORTS_CQM_RSSI;
|
||||
}
|
||||
|
||||
if (vif->p2p || iwl_fw_lookup_cmd_ver(mld->fw, PHY_CONTEXT_CMD, 0) < 5)
|
||||
if (vif->p2p)
|
||||
vif->driver_flags |= IEEE80211_VIF_IGNORE_OFDMA_WIDER_BW;
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -357,38 +357,26 @@ iwl_mld_vif_iter_emlsr_mode_notif(void *data, u8 *mac,
|
|||
struct ieee80211_vif *vif)
|
||||
{
|
||||
const struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif);
|
||||
enum iwl_mvm_fw_esr_recommendation action;
|
||||
const struct iwl_esr_mode_notif *notif = NULL;
|
||||
|
||||
if (iwl_fw_lookup_notif_ver(mld_vif->mld->fw, DATA_PATH_GROUP,
|
||||
ESR_MODE_NOTIF, 0) > 1) {
|
||||
notif = (void *)data;
|
||||
action = le32_to_cpu(notif->action);
|
||||
} else {
|
||||
const struct iwl_esr_mode_notif_v1 *notif_v1 = (void *)data;
|
||||
|
||||
action = le32_to_cpu(notif_v1->action);
|
||||
}
|
||||
const struct iwl_esr_mode_notif *notif = (void *)data;
|
||||
enum iwl_mvm_fw_esr_recommendation action = le32_to_cpu(notif->action);
|
||||
|
||||
if (!iwl_mld_vif_has_emlsr_cap(vif))
|
||||
return;
|
||||
|
||||
switch (action) {
|
||||
case ESR_RECOMMEND_LEAVE:
|
||||
if (notif)
|
||||
IWL_DEBUG_INFO(mld_vif->mld,
|
||||
"FW recommend leave reason = 0x%x\n",
|
||||
le32_to_cpu(notif->leave_reason_mask));
|
||||
IWL_DEBUG_INFO(mld_vif->mld,
|
||||
"FW recommend leave reason = 0x%x\n",
|
||||
le32_to_cpu(notif->leave_reason_mask));
|
||||
|
||||
iwl_mld_exit_emlsr(mld_vif->mld, vif,
|
||||
IWL_MLD_EMLSR_EXIT_FW_REQUEST,
|
||||
iwl_mld_get_primary_link(vif));
|
||||
break;
|
||||
case ESR_FORCE_LEAVE:
|
||||
if (notif)
|
||||
IWL_DEBUG_INFO(mld_vif->mld,
|
||||
"FW force leave reason = 0x%x\n",
|
||||
le32_to_cpu(notif->leave_reason_mask));
|
||||
IWL_DEBUG_INFO(mld_vif->mld,
|
||||
"FW force leave reason = 0x%x\n",
|
||||
le32_to_cpu(notif->leave_reason_mask));
|
||||
fallthrough;
|
||||
case ESR_RECOMMEND_ENTER:
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -333,7 +333,6 @@ CMD_VERSIONS(bt_coex_notif,
|
|||
CMD_VERSIONS(beacon_notification,
|
||||
CMD_VER_ENTRY(6, iwl_extended_beacon_notif))
|
||||
CMD_VERSIONS(emlsr_mode_notif,
|
||||
CMD_VER_ENTRY(1, iwl_esr_mode_notif_v1)
|
||||
CMD_VER_ENTRY(2, iwl_esr_mode_notif))
|
||||
CMD_VERSIONS(emlsr_trans_fail_notif,
|
||||
CMD_VER_ENTRY(1, iwl_esr_trans_fail_notif))
|
||||
|
|
|
|||
|
|
@ -82,9 +82,6 @@ int iwl_mld_start_roc(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|||
struct iwl_roc_req cmd = {
|
||||
.action = cpu_to_le32(FW_CTXT_ACTION_ADD),
|
||||
};
|
||||
u8 ver = iwl_fw_lookup_cmd_ver(mld->fw,
|
||||
WIDE_ID(MAC_CONF_GROUP, ROC_CMD), 0);
|
||||
u16 cmd_len = ver < 6 ? sizeof(struct iwl_roc_req_v5) : sizeof(cmd);
|
||||
enum iwl_roc_activity activity;
|
||||
int ret = 0;
|
||||
|
||||
|
|
@ -140,7 +137,7 @@ int iwl_mld_start_roc(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|||
memcpy(cmd.node_addr, vif->addr, ETH_ALEN);
|
||||
|
||||
ret = iwl_mld_send_cmd_pdu(mld, WIDE_ID(MAC_CONF_GROUP, ROC_CMD),
|
||||
&cmd, cmd_len);
|
||||
&cmd);
|
||||
if (ret) {
|
||||
IWL_ERR(mld, "Couldn't send the ROC_CMD\n");
|
||||
return ret;
|
||||
|
|
@ -190,9 +187,6 @@ int iwl_mld_cancel_roc(struct ieee80211_hw *hw,
|
|||
struct iwl_roc_req cmd = {
|
||||
.action = cpu_to_le32(FW_CTXT_ACTION_REMOVE),
|
||||
};
|
||||
u8 ver = iwl_fw_lookup_cmd_ver(mld->fw,
|
||||
WIDE_ID(MAC_CONF_GROUP, ROC_CMD), 0);
|
||||
u16 cmd_len = ver < 6 ? sizeof(struct iwl_roc_req_v5) : sizeof(cmd);
|
||||
int ret;
|
||||
|
||||
lockdep_assert_wiphy(mld->wiphy);
|
||||
|
|
@ -208,7 +202,7 @@ int iwl_mld_cancel_roc(struct ieee80211_hw *hw,
|
|||
cmd.activity = cpu_to_le32(mld_vif->roc_activity);
|
||||
|
||||
ret = iwl_mld_send_cmd_pdu(mld, WIDE_ID(MAC_CONF_GROUP, ROC_CMD),
|
||||
&cmd, cmd_len);
|
||||
&cmd);
|
||||
if (ret)
|
||||
IWL_ERR(mld, "Couldn't send the command to cancel the ROC\n");
|
||||
|
||||
|
|
|
|||
|
|
@ -504,9 +504,7 @@ iwl_mld_scan_get_cmd_gen_flags2(struct iwl_mld *mld,
|
|||
*/
|
||||
if (scan_status == IWL_MLD_SCAN_REGULAR &&
|
||||
ieee80211_vif_type_p2p(vif) == NL80211_IFTYPE_AP &&
|
||||
gen_flags & IWL_UMAC_SCAN_GEN_FLAGS_V2_FORCE_PASSIVE &&
|
||||
iwl_fw_lookup_notif_ver(mld->fw, SCAN_GROUP,
|
||||
CHANNEL_SURVEY_NOTIF, 0) >= 1)
|
||||
gen_flags & IWL_UMAC_SCAN_GEN_FLAGS_V2_FORCE_PASSIVE)
|
||||
flags |= IWL_UMAC_SCAN_GEN_FLAGS2_COLLECT_CHANNEL_STATS;
|
||||
|
||||
return flags;
|
||||
|
|
|
|||
|
|
@ -401,11 +401,9 @@ static u32 iwl_mld_get_htc_flags(struct ieee80211_link_sta *link_sta)
|
|||
static int iwl_mld_send_sta_cmd(struct iwl_mld *mld,
|
||||
const struct iwl_sta_cfg_cmd *cmd)
|
||||
{
|
||||
u32 cmd_id = WIDE_ID(MAC_CONF_GROUP, STA_CONFIG_CMD);
|
||||
int cmd_len = iwl_fw_lookup_cmd_ver(mld->fw, cmd_id, 0) > 1 ?
|
||||
sizeof(*cmd) :
|
||||
sizeof(struct iwl_sta_cfg_cmd_v1);
|
||||
int ret = iwl_mld_send_cmd_pdu(mld, cmd_id, cmd, cmd_len);
|
||||
int ret = iwl_mld_send_cmd_pdu(mld,
|
||||
WIDE_ID(MAC_CONF_GROUP, STA_CONFIG_CMD),
|
||||
cmd);
|
||||
if (ret)
|
||||
IWL_ERR(mld, "STA_CONFIG_CMD send failed, ret=0x%x\n", ret);
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -2082,7 +2082,7 @@ static void iwl_mvm_convert_gtk_v3(struct iwl_wowlan_status_data *status,
|
|||
}
|
||||
|
||||
static void iwl_mvm_convert_igtk(struct iwl_wowlan_status_data *status,
|
||||
struct iwl_wowlan_igtk_status *data)
|
||||
struct iwl_wowlan_igtk_status_v1 *data)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
|
@ -2106,7 +2106,7 @@ static void iwl_mvm_convert_igtk(struct iwl_wowlan_status_data *status,
|
|||
}
|
||||
|
||||
static void iwl_mvm_convert_bigtk(struct iwl_wowlan_status_data *status,
|
||||
const struct iwl_wowlan_igtk_status *data)
|
||||
const struct iwl_wowlan_igtk_status_v1 *data)
|
||||
{
|
||||
int data_idx, status_idx = 0;
|
||||
|
||||
|
|
@ -2137,7 +2137,7 @@ static void iwl_mvm_convert_bigtk(struct iwl_wowlan_status_data *status,
|
|||
}
|
||||
|
||||
static void iwl_mvm_parse_wowlan_info_notif(struct iwl_mvm *mvm,
|
||||
struct iwl_wowlan_info_notif *data,
|
||||
struct iwl_wowlan_info_notif_v5 *data,
|
||||
struct iwl_wowlan_status_data *status,
|
||||
u32 len)
|
||||
{
|
||||
|
|
@ -2907,7 +2907,7 @@ static bool iwl_mvm_wait_d3_notif(struct iwl_notif_wait_data *notif_wait,
|
|||
iwl_mvm_parse_wowlan_info_notif_v3(mvm, notif,
|
||||
d3_data->status, len);
|
||||
} else if (wowlan_info_ver == 5) {
|
||||
struct iwl_wowlan_info_notif *notif =
|
||||
struct iwl_wowlan_info_notif_v5 *notif =
|
||||
(void *)pkt->data;
|
||||
|
||||
iwl_mvm_parse_wowlan_info_notif(mvm, notif,
|
||||
|
|
@ -3102,7 +3102,7 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm)
|
|||
|
||||
rt_status = iwl_mvm_check_rt_status(mvm, vif);
|
||||
if (rt_status != FW_ALIVE) {
|
||||
set_bit(STATUS_FW_ERROR, &mvm->trans->status);
|
||||
iwl_trans_notify_fw_error(mvm->trans);
|
||||
if (rt_status == FW_ERROR) {
|
||||
IWL_ERR(mvm, "FW Error occurred during suspend. Restarting.\n");
|
||||
iwl_mvm_dump_nic_error_log(mvm);
|
||||
|
|
@ -3272,7 +3272,7 @@ int iwl_mvm_fast_resume(struct iwl_mvm *mvm)
|
|||
|
||||
rt_status = iwl_mvm_check_rt_status(mvm, NULL);
|
||||
if (rt_status != FW_ALIVE) {
|
||||
set_bit(STATUS_FW_ERROR, &mvm->trans->status);
|
||||
iwl_trans_notify_fw_error(mvm->trans);
|
||||
if (rt_status == FW_ERROR) {
|
||||
IWL_ERR(mvm,
|
||||
"iwl_mvm_check_rt_status failed, device is gone during suspend\n");
|
||||
|
|
@ -3284,7 +3284,6 @@ int iwl_mvm_fast_resume(struct iwl_mvm *mvm)
|
|||
&iwl_dump_desc_assert,
|
||||
false, 0);
|
||||
}
|
||||
mvm->trans->state = IWL_TRANS_NO_FW;
|
||||
ret = -ENODEV;
|
||||
|
||||
goto out;
|
||||
|
|
|
|||
|
|
@ -1134,7 +1134,7 @@ static ssize_t iwl_dbgfs_fw_restart_write(struct iwl_mvm *mvm, char *buf,
|
|||
|
||||
if (count == 6 && !strcmp(buf, "nolog\n")) {
|
||||
set_bit(IWL_MVM_STATUS_SUPPRESS_ERROR_LOG_ONCE, &mvm->status);
|
||||
iwl_trans_suppress_cmd_error_once(mvm->trans);
|
||||
mvm->trans->suppress_cmd_error_once = true;
|
||||
}
|
||||
|
||||
/* take the return value to make compiler happy - it will fail anyway */
|
||||
|
|
|
|||
|
|
@ -837,7 +837,7 @@ static int iwl_mvm_config_ltr(struct iwl_mvm *mvm)
|
|||
.flags = cpu_to_le32(LTR_CFG_FLAG_FEATURE_ENABLE),
|
||||
};
|
||||
|
||||
if (!mvm->trans->ltr_enabled)
|
||||
if (!iwl_trans_is_ltr_enabled(mvm->trans))
|
||||
return 0;
|
||||
|
||||
return iwl_mvm_send_cmd_pdu(mvm, LTR_CONFIG, 0,
|
||||
|
|
|
|||
|
|
@ -1243,7 +1243,7 @@ static int _iwl_pci_resume(struct device *device, bool restore)
|
|||
* won't really know how to recover.
|
||||
*/
|
||||
iwl_pcie_prepare_card_hw(trans);
|
||||
iwl_finish_nic_init(trans);
|
||||
iwl_trans_activate_nic(trans);
|
||||
iwl_op_mode_device_powered_off(trans->op_mode);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -403,6 +403,8 @@ struct iwl_pcie_txqs {
|
|||
* @dev_cmd_pool: pool for Tx cmd allocation - for internal use only.
|
||||
* The user should use iwl_trans_{alloc,free}_tx_cmd.
|
||||
* @dev_cmd_pool_name: name for the TX command allocation pool
|
||||
* @pm_support: set to true in start_hw if link pm is supported
|
||||
* @ltr_enabled: set to true if the LTR is enabled
|
||||
*/
|
||||
struct iwl_trans_pcie {
|
||||
struct iwl_rxq *rxq;
|
||||
|
|
@ -512,6 +514,9 @@ struct iwl_trans_pcie {
|
|||
|
||||
struct kmem_cache *dev_cmd_pool;
|
||||
char dev_cmd_pool_name[50];
|
||||
|
||||
bool pm_support;
|
||||
bool ltr_enabled;
|
||||
};
|
||||
|
||||
static inline struct iwl_trans_pcie *
|
||||
|
|
@ -1131,7 +1136,7 @@ int iwl_pcie_alloc_dma_ptr(struct iwl_trans *trans,
|
|||
struct iwl_dma_ptr *ptr, size_t size);
|
||||
void iwl_pcie_free_dma_ptr(struct iwl_trans *trans, struct iwl_dma_ptr *ptr);
|
||||
void iwl_pcie_apply_destination(struct iwl_trans *trans);
|
||||
int iwl_pcie_gen1_2_finish_nic_init(struct iwl_trans *trans);
|
||||
int iwl_pcie_gen1_2_activate_nic(struct iwl_trans *trans);
|
||||
|
||||
/* transport gen 2 exported functions */
|
||||
int iwl_trans_pcie_gen2_start_fw(struct iwl_trans *trans,
|
||||
|
|
@ -1151,4 +1156,17 @@ int iwl_trans_pcie_copy_imr(struct iwl_trans *trans,
|
|||
int iwl_trans_pcie_rxq_dma_data(struct iwl_trans *trans, int queue,
|
||||
struct iwl_trans_rxq_dma_data *data);
|
||||
|
||||
static inline bool iwl_pcie_gen1_is_pm_supported(struct iwl_trans *trans)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
|
||||
return trans_pcie->pm_support;
|
||||
}
|
||||
|
||||
static inline bool iwl_pcie_gen1_2_is_ltr_enabled(struct iwl_trans *trans)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
|
||||
return trans_pcie->ltr_enabled;
|
||||
}
|
||||
#endif /* __iwl_trans_int_pcie_h__ */
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ int iwl_pcie_gen2_apm_init(struct iwl_trans *trans)
|
|||
|
||||
iwl_pcie_apm_config(trans);
|
||||
|
||||
ret = iwl_finish_nic_init(trans);
|
||||
ret = iwl_trans_activate_nic(trans);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@
|
|||
#include "fw/dbg.h"
|
||||
#include "fw/api/tx.h"
|
||||
#include "fw/acpi.h"
|
||||
#include "fw/api/tx.h"
|
||||
#include "mei/iwl-mei.h"
|
||||
#include "internal.h"
|
||||
#include "iwl-fh.h"
|
||||
|
|
@ -215,13 +214,13 @@ void iwl_pcie_apm_config(struct iwl_trans *trans)
|
|||
iwl_set_bit(trans, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_DISABLED);
|
||||
|
||||
pcie_capability_read_word(trans_pcie->pci_dev, PCI_EXP_LNKCTL, &lctl);
|
||||
trans->pm_support = !(lctl & PCI_EXP_LNKCTL_ASPM_L0S);
|
||||
trans_pcie->pm_support = !(lctl & PCI_EXP_LNKCTL_ASPM_L0S);
|
||||
|
||||
pcie_capability_read_word(trans_pcie->pci_dev, PCI_EXP_DEVCTL2, &cap);
|
||||
trans->ltr_enabled = cap & PCI_EXP_DEVCTL2_LTR_EN;
|
||||
trans_pcie->ltr_enabled = cap & PCI_EXP_DEVCTL2_LTR_EN;
|
||||
IWL_DEBUG_POWER(trans, "L1 %sabled - LTR %sabled\n",
|
||||
(lctl & PCI_EXP_LNKCTL_ASPM_L1) ? "En" : "Dis",
|
||||
trans->ltr_enabled ? "En" : "Dis");
|
||||
trans_pcie->ltr_enabled ? "En" : "Dis");
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -268,7 +267,7 @@ static int iwl_pcie_apm_init(struct iwl_trans *trans)
|
|||
if (trans->mac_cfg->base->pll_cfg)
|
||||
iwl_set_bit(trans, CSR_ANA_PLL_CFG, CSR50_ANA_PLL_CFG_VAL);
|
||||
|
||||
ret = iwl_finish_nic_init(trans);
|
||||
ret = iwl_trans_activate_nic(trans);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -341,7 +340,7 @@ static void iwl_pcie_apm_lp_xtal_enable(struct iwl_trans *trans)
|
|||
ret = iwl_trans_pcie_sw_reset(trans, true);
|
||||
|
||||
if (!ret)
|
||||
ret = iwl_finish_nic_init(trans);
|
||||
ret = iwl_trans_activate_nic(trans);
|
||||
|
||||
if (WARN_ON(ret)) {
|
||||
/* Release XTAL ON request */
|
||||
|
|
@ -1543,7 +1542,7 @@ int iwl_trans_pcie_d3_resume(struct iwl_trans *trans,
|
|||
iwl_set_bit(trans, CSR_GP_CNTRL,
|
||||
CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
|
||||
|
||||
ret = iwl_finish_nic_init(trans);
|
||||
ret = iwl_trans_activate_nic(trans);
|
||||
if (ret) {
|
||||
IWL_ERR(trans, "Failed to init nic upon resume. err = %d\n",
|
||||
ret);
|
||||
|
|
@ -1767,7 +1766,7 @@ static int iwl_pcie_gen2_force_power_gating(struct iwl_trans *trans)
|
|||
{
|
||||
int ret;
|
||||
|
||||
ret = iwl_finish_nic_init(trans);
|
||||
ret = iwl_trans_activate_nic(trans);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
|
@ -3540,7 +3539,7 @@ iwl_trans_pcie_dump_data(struct iwl_trans *trans, u32 dump_mask,
|
|||
struct iwl_trans_dump_data *dump_data;
|
||||
u32 len, num_rbs = 0, monitor_len = 0;
|
||||
int i, ptr;
|
||||
bool dump_rbs = test_bit(STATUS_FW_ERROR, &trans->status) &&
|
||||
bool dump_rbs = iwl_trans_is_fw_error(trans) &&
|
||||
!trans->mac_cfg->mq_rx_supported &&
|
||||
dump_mask & BIT(IWL_FW_ERROR_DUMP_RB);
|
||||
|
||||
|
|
@ -4189,7 +4188,7 @@ int iwl_pci_gen1_2_probe(struct pci_dev *pdev,
|
|||
*/
|
||||
ret = iwl_pcie_prepare_card_hw(iwl_trans);
|
||||
if (!ret) {
|
||||
ret = iwl_finish_nic_init(iwl_trans);
|
||||
ret = iwl_trans_activate_nic(iwl_trans);
|
||||
if (ret)
|
||||
goto out_free_trans;
|
||||
if (iwl_trans_grab_nic_access(iwl_trans)) {
|
||||
|
|
@ -4309,7 +4308,7 @@ void iwl_pcie_gen1_2_remove(struct iwl_trans *trans)
|
|||
iwl_trans_pcie_free(trans);
|
||||
}
|
||||
|
||||
int iwl_pcie_gen1_2_finish_nic_init(struct iwl_trans *trans)
|
||||
int iwl_pcie_gen1_2_activate_nic(struct iwl_trans *trans)
|
||||
{
|
||||
const struct iwl_mac_cfg *mac_cfg = trans->mac_cfg;
|
||||
u32 poll_ready;
|
||||
|
|
|
|||
|
|
@ -2601,8 +2601,9 @@ static int iwl_trans_pcie_send_hcmd_sync(struct iwl_trans *trans,
|
|||
}
|
||||
|
||||
if (test_bit(STATUS_FW_ERROR, &trans->status)) {
|
||||
if (!test_and_clear_bit(STATUS_SUPPRESS_CMD_ERROR_ONCE,
|
||||
&trans->status)) {
|
||||
if (trans->suppress_cmd_error_once) {
|
||||
trans->suppress_cmd_error_once = false;
|
||||
} else {
|
||||
IWL_ERR(trans, "FW error in SYNC CMD %s\n", cmd_str);
|
||||
dump_stack();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
|
||||
iwlwifi-tests-y += module.o devinfo.o utils.o
|
||||
iwlwifi-tests-y += module.o devinfo.o utils.o nvm_parse.o
|
||||
|
||||
ccflags-y += -I$(src)/../
|
||||
|
||||
|
|
|
|||
72
drivers/net/wireless/intel/iwlwifi/tests/nvm_parse.c
Normal file
72
drivers/net/wireless/intel/iwlwifi/tests/nvm_parse.c
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* KUnit tests for NVM parse
|
||||
*
|
||||
* Copyright (C) 2025 Intel Corporation
|
||||
*/
|
||||
#include <kunit/static_stub.h>
|
||||
#include <kunit/test.h>
|
||||
#include <iwl-nvm-parse.h>
|
||||
|
||||
MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING");
|
||||
|
||||
static const struct nvm_flag_case {
|
||||
const char *desc;
|
||||
u16 nvm_flags;
|
||||
u32 reg_rule_flags;
|
||||
u32 set_reg_rule_flags;
|
||||
u32 clear_reg_rule_flags;
|
||||
} nvm_flag_cases[] = {
|
||||
{
|
||||
.desc = "Restricting VLP client and AP access",
|
||||
.nvm_flags = 0,
|
||||
.set_reg_rule_flags = NL80211_RRF_NO_6GHZ_VLP_CLIENT,
|
||||
.clear_reg_rule_flags = NL80211_RRF_ALLOW_6GHZ_VLP_AP,
|
||||
},
|
||||
{
|
||||
.desc = "Allow VLP client and AP access",
|
||||
.nvm_flags = NVM_CHANNEL_VLP,
|
||||
.set_reg_rule_flags = NL80211_RRF_ALLOW_6GHZ_VLP_AP,
|
||||
.clear_reg_rule_flags = NL80211_RRF_NO_6GHZ_VLP_CLIENT,
|
||||
},
|
||||
{
|
||||
.desc = "Allow VLP client access, while restricting AP access",
|
||||
.nvm_flags = NVM_CHANNEL_VLP | NVM_CHANNEL_VLP_AP_NOT_ALLOWED,
|
||||
.set_reg_rule_flags = 0,
|
||||
.clear_reg_rule_flags = NL80211_RRF_ALLOW_6GHZ_VLP_AP |
|
||||
NL80211_RRF_NO_6GHZ_VLP_CLIENT,
|
||||
},
|
||||
};
|
||||
|
||||
KUNIT_ARRAY_PARAM_DESC(nvm_flag, nvm_flag_cases, desc)
|
||||
|
||||
static void test_nvm_flags(struct kunit *test)
|
||||
{
|
||||
const struct nvm_flag_case *params = test->param_value;
|
||||
struct iwl_reg_capa reg_capa = {};
|
||||
u32 flags = 0;
|
||||
|
||||
flags = iwl_nvm_get_regdom_bw_flags(NULL, 0, params->nvm_flags,
|
||||
reg_capa);
|
||||
|
||||
if ((params->set_reg_rule_flags & flags) != params->set_reg_rule_flags)
|
||||
KUNIT_FAIL(test, "Expected set bits:0x%08x flags:0x%08x\n",
|
||||
params->set_reg_rule_flags, flags);
|
||||
|
||||
if (params->clear_reg_rule_flags & flags)
|
||||
KUNIT_FAIL(test, "Expected clear bits:0x%08x flags:0x%08x\n",
|
||||
params->clear_reg_rule_flags, flags);
|
||||
}
|
||||
|
||||
static struct kunit_case nvm_flags_test_cases[] = {
|
||||
KUNIT_CASE_PARAM(test_nvm_flags,
|
||||
nvm_flag_gen_params),
|
||||
{},
|
||||
};
|
||||
|
||||
static struct kunit_suite nvm_flags_suite = {
|
||||
.name = "iwlwifi-nvm_flags",
|
||||
.test_cases = nvm_flags_test_cases,
|
||||
};
|
||||
|
||||
kunit_test_suite(nvm_flags_suite);
|
||||
Loading…
Reference in New Issue
Block a user