mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-28 11:18:45 +07:00
First batch of patches intended for v5.2
* Send NO_DATA events so they can be captured in radiotap; * Some channel-switch changes; * Support for multiple BSSID; * Continued work and bugfixes for the new debugging infra; * Support for some new FW API versions; * Some work to support new hardware; * General bugfixes; * Other cleanups; -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEF3LNfgb2BPWm68smoUecoho8xfoFAlyU0OwACgkQoUecoho8 xfpOOQ/6A+gMe6x7+Mz1Cu6ipjc9ODmGKvDr/CpKUeG1XBedgEJpX9/iR5gFHJVw ho8ScEiN54pvktFJptjHIqY+6fPndygvnuYTKWoxN6GnQmairav7l83Vp7cI8P0s MHF42EVGvlBc+BwEFC747lgy29B3BFewq50nWFgycGYj+JaV18DxYFXV4+VPXXZ0 CshNC1WbdX0jI+Qzbbm3oeYA/YrjlU7iIzrri8zD3DVPKwWeYMm/kJ6OkA7RyGcW LYSl28BXSZzEl5rtQ763vIoZMGtUmnhtLSLgrxNbzT5u40NGLipU51iApOY4NV9T nZUY3XjcBbWbWKhuMuv35wx0HzV6/346D0NPBDPCNmikJHXJFF0zhnZ3WY58ho8C 8iKZXm8gQIaEl4oqucOIFeMHXjablvtabePinifMluXv8E4kHbjYpNzpFsnSDZyN 2HNkyW4H7yn9R0GL0XxBt6d+NI5XYB/NkvgywzxGtouyLuav/M5X5lOaxJVDWe79 8hdAPIlesu85cPTfoOPjtRSaHBpXpcyjnUq11XkznCbbO2PLgEc85cd3sQnhYF3t wmUxLgfUTy/PjmemEOau2bGpCYRAfjkfQE9aJFjqn2fsn5R65ADLyxgQ1fbUlLrq GvYN/WARDCeRudM5i2CMQwXGIcXKay3MKVCups0U2/xUb+DZWsM= =wFO2 -----END PGP SIGNATURE----- Merge tag 'iwlwifi-next-for-kalle-2019-03-22' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next First batch of patches intended for v5.2 * Send NO_DATA events so they can be captured in radiotap; * Some channel-switch changes; * Support for multiple BSSID; * Continued work and bugfixes for the new debugging infra; * Support for some new FW API versions; * Some work to support new hardware; * General bugfixes; * Other cleanups;
This commit is contained in:
commit
8db32fa400
@ -88,6 +88,7 @@
|
||||
#define IWL_22000_SO_A_HR_B_FW_PRE "iwlwifi-so-a0-hr-b0-"
|
||||
#define IWL_22000_SO_A_GF_A_FW_PRE "iwlwifi-so-a0-gf-a0-"
|
||||
#define IWL_22000_TY_A_GF_A_FW_PRE "iwlwifi-ty-a0-gf-a0-"
|
||||
#define IWL_22000_SO_A_GF4_A_FW_PRE "iwlwifi-so-a0-gf4-a0-"
|
||||
|
||||
#define IWL_22000_HR_MODULE_FIRMWARE(api) \
|
||||
IWL_22000_HR_FW_PRE __stringify(api) ".ucode"
|
||||
@ -427,12 +428,20 @@ const struct iwl_cfg iwlax210_2ax_cfg_so_hr_a0 = {
|
||||
const struct iwl_cfg iwlax210_2ax_cfg_so_gf_a0 = {
|
||||
.name = "Intel(R) Wi-Fi 7 AX211 160MHz",
|
||||
.fw_name_pre = IWL_22000_SO_A_GF_A_FW_PRE,
|
||||
.uhb_supported = true,
|
||||
IWL_DEVICE_AX210,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwlax210_2ax_cfg_ty_gf_a0 = {
|
||||
.name = "Intel(R) Wi-Fi 7 AX210 160MHz",
|
||||
.fw_name_pre = IWL_22000_TY_A_GF_A_FW_PRE,
|
||||
.uhb_supported = true,
|
||||
IWL_DEVICE_AX210,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwlax210_2ax_cfg_so_gf4_a0 = {
|
||||
.name = "Intel(R) Wi-Fi 7 AX210 160MHz",
|
||||
.fw_name_pre = IWL_22000_SO_A_GF4_A_FW_PRE,
|
||||
IWL_DEVICE_AX210,
|
||||
};
|
||||
|
||||
|
@ -60,12 +60,13 @@
|
||||
|
||||
#include <linux/bitops.h>
|
||||
|
||||
/*
|
||||
/**
|
||||
* struct iwl_fw_ini_header: Common Header for all debug group TLV's structures
|
||||
*
|
||||
* @tlv_version: version info
|
||||
* @apply_point: &enum iwl_fw_ini_apply_point
|
||||
* @data: TLV data followed
|
||||
**/
|
||||
*/
|
||||
struct iwl_fw_ini_header {
|
||||
__le32 tlv_version;
|
||||
__le32 apply_point;
|
||||
@ -73,7 +74,7 @@ struct iwl_fw_ini_header {
|
||||
} __packed; /* FW_DEBUG_TLV_HEADER_S */
|
||||
|
||||
/**
|
||||
* struct iwl_fw_ini_allocation_tlv - (IWL_FW_INI_TLV_TYPE_BUFFER_ALLOCATION)
|
||||
* struct iwl_fw_ini_allocation_tlv - (IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION)
|
||||
* buffer allocation TLV - for debug
|
||||
*
|
||||
* @iwl_fw_ini_header: header
|
||||
@ -84,7 +85,7 @@ struct iwl_fw_ini_header {
|
||||
* @max_fragments: the maximum allowed fragmentation in the desired memory
|
||||
* allocation above
|
||||
* @min_frag_size: the minimum allowed fragmentation size in bytes
|
||||
*/
|
||||
*/
|
||||
struct iwl_fw_ini_allocation_tlv {
|
||||
struct iwl_fw_ini_header header;
|
||||
__le32 allocation_id;
|
||||
@ -95,33 +96,52 @@ struct iwl_fw_ini_allocation_tlv {
|
||||
} __packed; /* FW_DEBUG_TLV_BUFFER_ALLOCATION_TLV_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_fw_ini_hcmd (IWL_FW_INI_TLV_TYPE_HCMD)
|
||||
* Generic Host command pass through TLV
|
||||
* enum iwl_fw_ini_dbg_domain - debug domains
|
||||
* allows to send host cmd or collect memory region if a given domain is enabled
|
||||
*
|
||||
* @IWL_FW_INI_DBG_DOMAIN_ALWAYS_ON: the default domain, always on
|
||||
* @IWL_FW_INI_DBG_DOMAIN_REPORT_PS: power save domain
|
||||
*/
|
||||
enum iwl_fw_ini_dbg_domain {
|
||||
IWL_FW_INI_DBG_DOMAIN_ALWAYS_ON = 0,
|
||||
IWL_FW_INI_DBG_DOMAIN_REPORT_PS,
|
||||
}; /* FW_DEBUG_TLV_DOMAIN_API_E_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_fw_ini_hcmd
|
||||
*
|
||||
* @id: the debug configuration command type for instance: 0xf6 / 0xf5 / DHC
|
||||
* @group: the desired cmd group
|
||||
* @padding: all zeros for dword alignment
|
||||
* @data: all of the relevant command (0xf6/0xf5) to be sent
|
||||
*/
|
||||
* @reserved: to align to FW struct
|
||||
* @data: all of the relevant command data to be sent
|
||||
*/
|
||||
struct iwl_fw_ini_hcmd {
|
||||
u8 id;
|
||||
u8 group;
|
||||
__le16 padding;
|
||||
__le16 reserved;
|
||||
u8 data[0];
|
||||
} __packed; /* FW_DEBUG_TLV_HCMD_DATA_S */
|
||||
} __packed; /* FW_DEBUG_TLV_HCMD_DATA_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_fw_ini_hcmd_tlv
|
||||
* struct iwl_fw_ini_hcmd_tlv - (IWL_UCODE_TLV_TYPE_HCMD)
|
||||
* Generic Host command pass through TLV
|
||||
*
|
||||
* @header: header
|
||||
* @domain: send command only if the specific domain is enabled
|
||||
* &enum iwl_fw_ini_dbg_domain
|
||||
* @period_msec: period in which the hcmd will be sent to FW. Measured in msec
|
||||
* (0 = one time command).
|
||||
* @hcmd: a variable length host-command to be sent to apply the configuration.
|
||||
*/
|
||||
struct iwl_fw_ini_hcmd_tlv {
|
||||
struct iwl_fw_ini_header header;
|
||||
__le32 domain;
|
||||
__le32 period_msec;
|
||||
struct iwl_fw_ini_hcmd hcmd;
|
||||
} __packed; /* FW_DEBUG_TLV_HCMD_S_VER_1 */
|
||||
} __packed; /* FW_DEBUG_TLV_HCMD_API_S_VER_1 */
|
||||
|
||||
/*
|
||||
* struct iwl_fw_ini_debug_flow_tlv (IWL_FW_INI_TLV_TYPE_DEBUG_FLOW)
|
||||
/**
|
||||
* struct iwl_fw_ini_debug_flow_tlv - (IWL_UCODE_TLV_TYPE_DEBUG_FLOW)
|
||||
*
|
||||
* @header: header
|
||||
* @debug_flow_cfg: &enum iwl_fw_ini_debug_flow
|
||||
@ -134,8 +154,20 @@ struct iwl_fw_ini_debug_flow_tlv {
|
||||
#define IWL_FW_INI_MAX_REGION_ID 64
|
||||
#define IWL_FW_INI_MAX_NAME 32
|
||||
|
||||
/**
|
||||
* struct iwl_fw_ini_region_cfg_dhc - defines dhc response to dump.
|
||||
*
|
||||
* @id_and_grp: id and group of dhc response.
|
||||
* @desc: dhc response descriptor.
|
||||
*/
|
||||
struct iwl_fw_ini_region_cfg_dhc {
|
||||
__le32 id_and_grp;
|
||||
__le32 desc;
|
||||
} __packed; /* FW_DEBUG_TLV_REGION_DHC_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_fw_ini_region_cfg_internal - meta data of internal memory region
|
||||
*
|
||||
* @num_of_range: the amount of ranges in the region
|
||||
* @range_data_size: size of the data to read per range, in bytes.
|
||||
*/
|
||||
@ -146,6 +178,7 @@ struct iwl_fw_ini_region_cfg_internal {
|
||||
|
||||
/**
|
||||
* struct iwl_fw_ini_region_cfg_fifos - meta data of fifos region
|
||||
*
|
||||
* @fid1: fifo id 1 - bitmap of lmac tx/rx fifos to include in the region
|
||||
* @fid2: fifo id 2 - bitmap of umac rx fifos to include in the region.
|
||||
* It is unused for tx.
|
||||
@ -163,34 +196,43 @@ struct iwl_fw_ini_region_cfg_fifos {
|
||||
|
||||
/**
|
||||
* struct iwl_fw_ini_region_cfg
|
||||
*
|
||||
* @region_id: ID of this dump configuration
|
||||
* @region_type: &enum iwl_fw_ini_region_type
|
||||
* @num_regions: amount of regions in the address array.
|
||||
* @domain: dump this region only if the specific domain is enabled
|
||||
* &enum iwl_fw_ini_dbg_domain
|
||||
* @name_len: name length
|
||||
* @name: file name to use for this region
|
||||
* @internal: used in case the region uses internal memory.
|
||||
* @allocation_id: For DRAM type field substitutes for allocation_id
|
||||
* @fifos: used in case of fifos region.
|
||||
* @dhc_desc: dhc response descriptor.
|
||||
* @notif_id_and_grp: dump this region only if the specific notification
|
||||
* occurred.
|
||||
* @offset: offset to use for each memory base address
|
||||
* @start_addr: array of addresses.
|
||||
*/
|
||||
struct iwl_fw_ini_region_cfg {
|
||||
__le32 region_id;
|
||||
__le32 region_type;
|
||||
__le32 domain;
|
||||
__le32 name_len;
|
||||
u8 name[IWL_FW_INI_MAX_NAME];
|
||||
union {
|
||||
struct iwl_fw_ini_region_cfg_internal internal;
|
||||
__le32 allocation_id;
|
||||
struct iwl_fw_ini_region_cfg_fifos fifos;
|
||||
};
|
||||
struct iwl_fw_ini_region_cfg_dhc dhc_desc;
|
||||
__le32 notif_id_and_grp;
|
||||
}; /* FW_DEBUG_TLV_REGION_EXT_INT_PARAMS_API_U_VER_1 */
|
||||
__le32 offset;
|
||||
__le32 start_addr[];
|
||||
} __packed; /* FW_DEBUG_TLV_REGION_CONFIG_S */
|
||||
} __packed; /* FW_DEBUG_TLV_REGION_CONFIG_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_fw_ini_region_tlv - (IWL_FW_INI_TLV_TYPE_REGION_CFG)
|
||||
* DUMP sections define IDs and triggers that use those IDs TLV
|
||||
* struct iwl_fw_ini_region_tlv - (IWL_UCODE_TLV_TYPE_REGIONS)
|
||||
* defines memory regions to dump
|
||||
*
|
||||
* @header: header
|
||||
* @num_regions: how many different region section and IDs are coming next
|
||||
* @region_config: list of dump configurations
|
||||
@ -199,13 +241,12 @@ struct iwl_fw_ini_region_tlv {
|
||||
struct iwl_fw_ini_header header;
|
||||
__le32 num_regions;
|
||||
struct iwl_fw_ini_region_cfg region_config[];
|
||||
} __packed; /* FW_DEBUG_TLV_REGIONS_S_VER_1 */
|
||||
} __packed; /* FW_DEBUG_TLV_REGIONS_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_fw_ini_trigger - (IWL_FW_INI_TLV_TYPE_DUMP_CFG)
|
||||
* Region sections define IDs and triggers that use those IDs TLV
|
||||
* struct iwl_fw_ini_trigger
|
||||
*
|
||||
* @trigger_id: enum &iwl_fw_ini_tigger_id
|
||||
* @trigger_id: &enum iwl_fw_ini_trigger_id
|
||||
* @override_trig: determines how apply trigger in case a trigger with the
|
||||
* same id is already in use. Using the first 2 bytes:
|
||||
* Byte 0: if 0, override trigger configuration, otherwise use the
|
||||
@ -214,6 +255,7 @@ struct iwl_fw_ini_region_tlv {
|
||||
* existing trigger.
|
||||
* @dump_delay: delay from trigger fire to dump, in usec
|
||||
* @occurrences: max amount of times to be fired
|
||||
* @reserved: to align to FW struct
|
||||
* @ignore_consec: ignore consecutive triggers, in usec
|
||||
* @force_restart: force FW restart
|
||||
* @multi_dut: initiate debug dump data on several DUTs
|
||||
@ -226,17 +268,18 @@ struct iwl_fw_ini_trigger {
|
||||
__le32 override_trig;
|
||||
__le32 dump_delay;
|
||||
__le32 occurrences;
|
||||
__le32 reserved;
|
||||
__le32 ignore_consec;
|
||||
__le32 force_restart;
|
||||
__le32 multi_dut;
|
||||
__le32 trigger_data;
|
||||
__le32 num_regions;
|
||||
__le32 data[];
|
||||
} __packed; /* FW_TLV_DEBUG_TRIGGER_CONFIG_S */
|
||||
} __packed; /* FW_TLV_DEBUG_TRIGGER_CONFIG_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_fw_ini_trigger_tlv - (IWL_FW_INI_TLV_TYPE_TRIGGERS_CFG)
|
||||
* DUMP sections define IDs and triggers that use those IDs TLV
|
||||
* struct iwl_fw_ini_trigger_tlv - (IWL_UCODE_TLV_TYPE_TRIGGERS)
|
||||
* Triggers that hold memory regions to dump in case a trigger fires
|
||||
*
|
||||
* @header: header
|
||||
* @num_triggers: how many different triggers section and IDs are coming next
|
||||
@ -246,16 +289,18 @@ struct iwl_fw_ini_trigger_tlv {
|
||||
struct iwl_fw_ini_header header;
|
||||
__le32 num_triggers;
|
||||
struct iwl_fw_ini_trigger trigger_config[];
|
||||
} __packed; /* FW_TLV_DEBUG_TRIGGERS_S_VER_1 */
|
||||
} __packed; /* FW_TLV_DEBUG_TRIGGERS_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* enum iwl_fw_ini_trigger_id
|
||||
*
|
||||
* @IWL_FW_TRIGGER_ID_FW_ASSERT: FW assert
|
||||
* @IWL_FW_TRIGGER_ID_FW_HW_ERROR: HW assert
|
||||
* @IWL_FW_TRIGGER_ID_FW_TFD_Q_HANG: TFD queue hang
|
||||
* @IWL_FW_TRIGGER_ID_FW_DEBUG_HOST_TRIGGER: FW debug notification
|
||||
* @IWL_FW_TRIGGER_ID_FW_GENERIC_NOTIFOCATION: FW generic notification
|
||||
* @IWL_FW_TRIGGER_ID_FW_GENERIC_NOTIFICATION: FW generic notification
|
||||
* @IWL_FW_TRIGGER_ID_USER_TRIGGER: User trigger
|
||||
* @IWL_FW_TRIGGER_ID_PERIODIC_TRIGGER: triggers periodically
|
||||
* @IWL_FW_TRIGGER_ID_HOST_PEER_CLIENT_INACTIVITY: peer inactivity
|
||||
* @IWL_FW_TRIGGER_ID_HOST_TX_LATENCY_THRESHOLD_CROSSED: TX latency
|
||||
* threshold was crossed
|
||||
@ -299,47 +344,51 @@ enum iwl_fw_ini_trigger_id {
|
||||
|
||||
/* FW triggers */
|
||||
IWL_FW_TRIGGER_ID_FW_DEBUG_HOST_TRIGGER = 4,
|
||||
IWL_FW_TRIGGER_ID_FW_GENERIC_NOTIFOCATION = 5,
|
||||
IWL_FW_TRIGGER_ID_FW_GENERIC_NOTIFICATION = 5,
|
||||
|
||||
/* User trigger */
|
||||
IWL_FW_TRIGGER_ID_USER_TRIGGER = 6,
|
||||
|
||||
/* periodic uses the data field for the interval time */
|
||||
IWL_FW_TRIGGER_ID_PERIODIC_TRIGGER = 7,
|
||||
|
||||
/* Host triggers */
|
||||
IWL_FW_TRIGGER_ID_HOST_PEER_CLIENT_INACTIVITY = 7,
|
||||
IWL_FW_TRIGGER_ID_HOST_TX_LATENCY_THRESHOLD_CROSSED = 8,
|
||||
IWL_FW_TRIGGER_ID_HOST_TX_RESPONSE_STATUS_FAILED = 9,
|
||||
IWL_FW_TRIGGER_ID_HOST_OS_REQ_DEAUTH_PEER = 10,
|
||||
IWL_FW_TRIGGER_ID_HOST_STOP_GO_REQUEST = 11,
|
||||
IWL_FW_TRIGGER_ID_HOST_START_GO_REQUEST = 12,
|
||||
IWL_FW_TRIGGER_ID_HOST_JOIN_GROUP_REQUEST = 13,
|
||||
IWL_FW_TRIGGER_ID_HOST_SCAN_START = 14,
|
||||
IWL_FW_TRIGGER_ID_HOST_SCAN_SUBMITTED = 15,
|
||||
IWL_FW_TRIGGER_ID_HOST_SCAN_PARAMS = 16,
|
||||
IWL_FW_TRIGGER_ID_HOST_CHECK_FOR_HANG = 17,
|
||||
IWL_FW_TRIGGER_ID_HOST_BAR_RECEIVED = 18,
|
||||
IWL_FW_TRIGGER_ID_HOST_AGG_TX_RESPONSE_STATUS_FAILED = 19,
|
||||
IWL_FW_TRIGGER_ID_HOST_EAPOL_TX_RESPONSE_FAILED = 20,
|
||||
IWL_FW_TRIGGER_ID_HOST_FAKE_TX_RESPONSE_SUSPECTED = 21,
|
||||
IWL_FW_TRIGGER_ID_HOST_AUTH_REQ_FROM_ASSOC_CLIENT = 22,
|
||||
IWL_FW_TRIGGER_ID_HOST_ROAM_COMPLETE = 23,
|
||||
IWL_FW_TRIGGER_ID_HOST_AUTH_ASSOC_FAST_FAILED = 24,
|
||||
IWL_FW_TRIGGER_ID_HOST_D3_START = 25,
|
||||
IWL_FW_TRIGGER_ID_HOST_D3_END = 26,
|
||||
IWL_FW_TRIGGER_ID_HOST_BSS_MISSED_BEACONS = 27,
|
||||
IWL_FW_TRIGGER_ID_HOST_P2P_CLIENT_MISSED_BEACONS = 28,
|
||||
IWL_FW_TRIGGER_ID_HOST_PEER_CLIENT_TX_FAILURES = 29,
|
||||
IWL_FW_TRIGGER_ID_HOST_TX_WFD_ACTION_FRAME_FAILED = 30,
|
||||
IWL_FW_TRIGGER_ID_HOST_AUTH_ASSOC_FAILED = 31,
|
||||
IWL_FW_TRIGGER_ID_HOST_SCAN_COMPLETE = 32,
|
||||
IWL_FW_TRIGGER_ID_HOST_SCAN_ABORT = 33,
|
||||
IWL_FW_TRIGGER_ID_HOST_NIC_ALIVE = 34,
|
||||
IWL_FW_TRIGGER_ID_HOST_CHANNEL_SWITCH_COMPLETE = 35,
|
||||
IWL_FW_TRIGGER_ID_HOST_PEER_CLIENT_INACTIVITY = 8,
|
||||
IWL_FW_TRIGGER_ID_HOST_TX_LATENCY_THRESHOLD_CROSSED = 9,
|
||||
IWL_FW_TRIGGER_ID_HOST_TX_RESPONSE_STATUS_FAILED = 10,
|
||||
IWL_FW_TRIGGER_ID_HOST_OS_REQ_DEAUTH_PEER = 11,
|
||||
IWL_FW_TRIGGER_ID_HOST_STOP_GO_REQUEST = 12,
|
||||
IWL_FW_TRIGGER_ID_HOST_START_GO_REQUEST = 13,
|
||||
IWL_FW_TRIGGER_ID_HOST_JOIN_GROUP_REQUEST = 14,
|
||||
IWL_FW_TRIGGER_ID_HOST_SCAN_START = 15,
|
||||
IWL_FW_TRIGGER_ID_HOST_SCAN_SUBMITTED = 16,
|
||||
IWL_FW_TRIGGER_ID_HOST_SCAN_PARAMS = 17,
|
||||
IWL_FW_TRIGGER_ID_HOST_CHECK_FOR_HANG = 18,
|
||||
IWL_FW_TRIGGER_ID_HOST_BAR_RECEIVED = 19,
|
||||
IWL_FW_TRIGGER_ID_HOST_AGG_TX_RESPONSE_STATUS_FAILED = 20,
|
||||
IWL_FW_TRIGGER_ID_HOST_EAPOL_TX_RESPONSE_FAILED = 21,
|
||||
IWL_FW_TRIGGER_ID_HOST_FAKE_TX_RESPONSE_SUSPECTED = 22,
|
||||
IWL_FW_TRIGGER_ID_HOST_AUTH_REQ_FROM_ASSOC_CLIENT = 23,
|
||||
IWL_FW_TRIGGER_ID_HOST_ROAM_COMPLETE = 24,
|
||||
IWL_FW_TRIGGER_ID_HOST_AUTH_ASSOC_FAST_FAILED = 25,
|
||||
IWL_FW_TRIGGER_ID_HOST_D3_START = 26,
|
||||
IWL_FW_TRIGGER_ID_HOST_D3_END = 27,
|
||||
IWL_FW_TRIGGER_ID_HOST_BSS_MISSED_BEACONS = 28,
|
||||
IWL_FW_TRIGGER_ID_HOST_P2P_CLIENT_MISSED_BEACONS = 29,
|
||||
IWL_FW_TRIGGER_ID_HOST_PEER_CLIENT_TX_FAILURES = 30,
|
||||
IWL_FW_TRIGGER_ID_HOST_TX_WFD_ACTION_FRAME_FAILED = 31,
|
||||
IWL_FW_TRIGGER_ID_HOST_AUTH_ASSOC_FAILED = 32,
|
||||
IWL_FW_TRIGGER_ID_HOST_SCAN_COMPLETE = 33,
|
||||
IWL_FW_TRIGGER_ID_HOST_SCAN_ABORT = 34,
|
||||
IWL_FW_TRIGGER_ID_HOST_NIC_ALIVE = 35,
|
||||
IWL_FW_TRIGGER_ID_HOST_CHANNEL_SWITCH_COMPLETE = 36,
|
||||
|
||||
IWL_FW_TRIGGER_ID_NUM,
|
||||
}; /* FW_DEBUG_TLV_TRIGGER_ID_E_VER_1 */
|
||||
|
||||
/**
|
||||
* enum iwl_fw_ini_apply_point
|
||||
*
|
||||
* @IWL_FW_INI_APPLY_INVALID: invalid
|
||||
* @IWL_FW_INI_APPLY_EARLY: pre loading FW
|
||||
* @IWL_FW_INI_APPLY_AFTER_ALIVE: first cmd from host after alive
|
||||
@ -360,6 +409,7 @@ enum iwl_fw_ini_apply_point {
|
||||
|
||||
/**
|
||||
* enum iwl_fw_ini_allocation_id
|
||||
*
|
||||
* @IWL_FW_INI_ALLOCATION_INVALID: invalid
|
||||
* @IWL_FW_INI_ALLOCATION_ID_DBGC1: allocation meant for DBGC1 configuration
|
||||
* @IWL_FW_INI_ALLOCATION_ID_DBGC2: allocation meant for DBGC2 configuration
|
||||
@ -380,18 +430,22 @@ enum iwl_fw_ini_allocation_id {
|
||||
|
||||
/**
|
||||
* enum iwl_fw_ini_buffer_location
|
||||
*
|
||||
* @IWL_FW_INI_LOCATION_INVALID: invalid
|
||||
* @IWL_FW_INI_LOCATION_SRAM_PATH: SRAM location
|
||||
* @IWL_FW_INI_LOCATION_DRAM_PATH: DRAM location
|
||||
* @IWL_FW_INI_LOCATION_NPK_PATH: NPK location
|
||||
*/
|
||||
enum iwl_fw_ini_buffer_location {
|
||||
IWL_FW_INI_LOCATION_INVALID,
|
||||
IWL_FW_INI_LOCATION_SRAM_PATH,
|
||||
IWL_FW_INI_LOCATION_DRAM_PATH,
|
||||
IWL_FW_INI_LOCATION_NPK_PATH,
|
||||
}; /* FW_DEBUG_TLV_BUFFER_LOCATION_E_VER_1 */
|
||||
|
||||
/**
|
||||
* enum iwl_fw_ini_debug_flow
|
||||
*
|
||||
* @IWL_FW_INI_DEBUG_INVALID: invalid
|
||||
* @IWL_FW_INI_DEBUG_DBTR_FLOW: undefined
|
||||
* @IWL_FW_INI_DEBUG_TB2DTF_FLOW: undefined
|
||||
@ -404,6 +458,7 @@ enum iwl_fw_ini_debug_flow {
|
||||
|
||||
/**
|
||||
* enum iwl_fw_ini_region_type
|
||||
*
|
||||
* @IWL_FW_INI_REGION_INVALID: invalid
|
||||
* @IWL_FW_INI_REGION_DEVICE_MEMORY: device internal memory
|
||||
* @IWL_FW_INI_REGION_PERIPHERY_MAC: periphery registers of MAC
|
||||
@ -416,6 +471,8 @@ enum iwl_fw_ini_debug_flow {
|
||||
* @IWL_FW_INI_REGION_RXF: RX fifo
|
||||
* @IWL_FW_INI_REGION_PAGING: paging memory
|
||||
* @IWL_FW_INI_REGION_CSR: CSR registers
|
||||
* @IWL_FW_INI_REGION_NOTIFICATION: FW notification data
|
||||
* @IWL_FW_INI_REGION_DHC: dhc response to dump
|
||||
* @IWL_FW_INI_REGION_NUM: number of region types
|
||||
*/
|
||||
enum iwl_fw_ini_region_type {
|
||||
@ -431,6 +488,8 @@ enum iwl_fw_ini_region_type {
|
||||
IWL_FW_INI_REGION_RXF,
|
||||
IWL_FW_INI_REGION_PAGING,
|
||||
IWL_FW_INI_REGION_CSR,
|
||||
IWL_FW_INI_REGION_NOTIFICATION,
|
||||
IWL_FW_INI_REGION_DHC,
|
||||
IWL_FW_INI_REGION_NUM
|
||||
}; /* FW_DEBUG_TLV_REGION_TYPE_E_VER_1 */
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
|
||||
* Copyright (C) 2018 Intel Corporation
|
||||
* Copyright(C) 2018 - 2019 Intel Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@ -31,7 +31,7 @@
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
|
||||
* Copyright (C) 2018 Intel Corporation
|
||||
* Copyright(C) 2018 - 2019 Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -233,7 +233,8 @@ struct iwl_nvm_get_info_phy {
|
||||
__le32 rx_chains;
|
||||
} __packed; /* REGULATORY_NVM_GET_INFO_PHY_SKU_SECTION_S_VER_1 */
|
||||
|
||||
#define IWL_NUM_CHANNELS (51)
|
||||
#define IWL_NUM_CHANNELS_V1 51
|
||||
#define IWL_NUM_CHANNELS 110
|
||||
|
||||
/**
|
||||
* struct iwl_nvm_get_info_regulatory - regulatory information
|
||||
@ -241,12 +242,38 @@ struct iwl_nvm_get_info_phy {
|
||||
* @channel_profile: regulatory data of this channel
|
||||
* @reserved: reserved
|
||||
*/
|
||||
struct iwl_nvm_get_info_regulatory {
|
||||
struct iwl_nvm_get_info_regulatory_v1 {
|
||||
__le32 lar_enabled;
|
||||
__le16 channel_profile[IWL_NUM_CHANNELS];
|
||||
__le16 channel_profile[IWL_NUM_CHANNELS_V1];
|
||||
__le16 reserved;
|
||||
} __packed; /* REGULATORY_NVM_GET_INFO_REGULATORY_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_nvm_get_info_regulatory - regulatory information
|
||||
* @lar_enabled: is LAR enabled
|
||||
* @n_channels: number of valid channels in the array
|
||||
* @channel_profile: regulatory data of this channel
|
||||
*/
|
||||
struct iwl_nvm_get_info_regulatory {
|
||||
__le32 lar_enabled;
|
||||
__le32 n_channels;
|
||||
__le32 channel_profile[IWL_NUM_CHANNELS];
|
||||
} __packed; /* REGULATORY_NVM_GET_INFO_REGULATORY_S_VER_2 */
|
||||
|
||||
/**
|
||||
* struct iwl_nvm_get_info_rsp_v3 - response to get NVM data
|
||||
* @general: general NVM data
|
||||
* @mac_sku: data relating to MAC sku
|
||||
* @phy_sku: data relating to PHY sku
|
||||
* @regulatory: regulatory data
|
||||
*/
|
||||
struct iwl_nvm_get_info_rsp_v3 {
|
||||
struct iwl_nvm_get_info_general general;
|
||||
struct iwl_nvm_get_info_sku mac_sku;
|
||||
struct iwl_nvm_get_info_phy phy_sku;
|
||||
struct iwl_nvm_get_info_regulatory_v1 regulatory;
|
||||
} __packed; /* REGULATORY_NVM_GET_INFO_RSP_API_S_VER_3 */
|
||||
|
||||
/**
|
||||
* struct iwl_nvm_get_info_rsp - response to get NVM data
|
||||
* @general: general NVM data
|
||||
@ -259,7 +286,7 @@ struct iwl_nvm_get_info_rsp {
|
||||
struct iwl_nvm_get_info_sku mac_sku;
|
||||
struct iwl_nvm_get_info_phy phy_sku;
|
||||
struct iwl_nvm_get_info_regulatory regulatory;
|
||||
} __packed; /* REGULATORY_NVM_GET_INFO_RSP_API_S_VER_3 */
|
||||
} __packed; /* REGULATORY_NVM_GET_INFO_RSP_API_S_VER_4 */
|
||||
|
||||
/**
|
||||
* struct iwl_nvm_access_complete_cmd - NVM_ACCESS commands are completed
|
||||
|
@ -8,7 +8,7 @@
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2015 - 2017 Intel Deutschland GmbH
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@ -31,7 +31,7 @@
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2015 - 2017 Intel Deutschland GmbH
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -688,13 +688,6 @@ struct iwl_rx_mpdu_desc {
|
||||
|
||||
#define IWL_RX_DESC_SIZE_V1 offsetofend(struct iwl_rx_mpdu_desc, v1)
|
||||
|
||||
#define IWL_CD_STTS_OPTIMIZED_POS 0
|
||||
#define IWL_CD_STTS_OPTIMIZED_MSK 0x01
|
||||
#define IWL_CD_STTS_TRANSFER_STATUS_POS 1
|
||||
#define IWL_CD_STTS_TRANSFER_STATUS_MSK 0x0E
|
||||
#define IWL_CD_STTS_WIFI_STATUS_POS 4
|
||||
#define IWL_CD_STTS_WIFI_STATUS_MSK 0xF0
|
||||
|
||||
#define RX_NO_DATA_CHAIN_A_POS 0
|
||||
#define RX_NO_DATA_CHAIN_A_MSK (0xff << RX_NO_DATA_CHAIN_A_POS)
|
||||
#define RX_NO_DATA_CHAIN_B_POS 8
|
||||
@ -747,62 +740,6 @@ struct iwl_rx_no_data {
|
||||
__le32 rx_vec[2];
|
||||
} __packed; /* RX_NO_DATA_NTFY_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* enum iwl_completion_desc_transfer_status - transfer status (bits 1-3)
|
||||
* @IWL_CD_STTS_UNUSED: unused
|
||||
* @IWL_CD_STTS_UNUSED_2: unused
|
||||
* @IWL_CD_STTS_END_TRANSFER: successful transfer complete.
|
||||
* In sniffer mode, when split is used, set in last CD completion. (RX)
|
||||
* @IWL_CD_STTS_OVERFLOW: In sniffer mode, when using split - used for
|
||||
* all CD completion. (RX)
|
||||
* @IWL_CD_STTS_ABORTED: CR abort / close flow. (RX)
|
||||
* @IWL_CD_STTS_ERROR: general error (RX)
|
||||
*/
|
||||
enum iwl_completion_desc_transfer_status {
|
||||
IWL_CD_STTS_UNUSED,
|
||||
IWL_CD_STTS_UNUSED_2,
|
||||
IWL_CD_STTS_END_TRANSFER,
|
||||
IWL_CD_STTS_OVERFLOW,
|
||||
IWL_CD_STTS_ABORTED,
|
||||
IWL_CD_STTS_ERROR,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum iwl_completion_desc_wifi_status - wifi status (bits 4-7)
|
||||
* @IWL_CD_STTS_VALID: the packet is valid (RX)
|
||||
* @IWL_CD_STTS_FCS_ERR: frame check sequence error (RX)
|
||||
* @IWL_CD_STTS_SEC_KEY_ERR: error handling the security key of rx (RX)
|
||||
* @IWL_CD_STTS_DECRYPTION_ERR: error decrypting the frame (RX)
|
||||
* @IWL_CD_STTS_DUP: duplicate packet (RX)
|
||||
* @IWL_CD_STTS_ICV_MIC_ERR: MIC error (RX)
|
||||
* @IWL_CD_STTS_INTERNAL_SNAP_ERR: problems removing the snap (RX)
|
||||
* @IWL_CD_STTS_SEC_PORT_FAIL: security port fail (RX)
|
||||
* @IWL_CD_STTS_BA_OLD_SN: block ack received old SN (RX)
|
||||
* @IWL_CD_STTS_QOS_NULL: QoS null packet (RX)
|
||||
* @IWL_CD_STTS_MAC_HDR_ERR: MAC header conversion error (RX)
|
||||
* @IWL_CD_STTS_MAX_RETRANS: reached max number of retransmissions (TX)
|
||||
* @IWL_CD_STTS_EX_LIFETIME: exceeded lifetime (TX)
|
||||
* @IWL_CD_STTS_NOT_USED: completed but not used (RX)
|
||||
* @IWL_CD_STTS_REPLAY_ERR: pn check failed, replay error (RX)
|
||||
*/
|
||||
enum iwl_completion_desc_wifi_status {
|
||||
IWL_CD_STTS_VALID,
|
||||
IWL_CD_STTS_FCS_ERR,
|
||||
IWL_CD_STTS_SEC_KEY_ERR,
|
||||
IWL_CD_STTS_DECRYPTION_ERR,
|
||||
IWL_CD_STTS_DUP,
|
||||
IWL_CD_STTS_ICV_MIC_ERR,
|
||||
IWL_CD_STTS_INTERNAL_SNAP_ERR,
|
||||
IWL_CD_STTS_SEC_PORT_FAIL,
|
||||
IWL_CD_STTS_BA_OLD_SN,
|
||||
IWL_CD_STTS_QOS_NULL,
|
||||
IWL_CD_STTS_MAC_HDR_ERR,
|
||||
IWL_CD_STTS_MAX_RETRANS,
|
||||
IWL_CD_STTS_EX_LIFETIME,
|
||||
IWL_CD_STTS_NOT_USED,
|
||||
IWL_CD_STTS_REPLAY_ERR,
|
||||
};
|
||||
|
||||
struct iwl_frame_release {
|
||||
u8 baid;
|
||||
u8 reserved;
|
||||
|
@ -788,7 +788,53 @@ struct iwl_umac_scan_complete {
|
||||
__le32 reserved;
|
||||
} __packed; /* SCAN_COMPLETE_NTF_UMAC_API_S_VER_1 */
|
||||
|
||||
#define SCAN_OFFLOAD_MATCHING_CHANNELS_LEN 5
|
||||
#define SCAN_OFFLOAD_MATCHING_CHANNELS_LEN_V1 5
|
||||
#define SCAN_OFFLOAD_MATCHING_CHANNELS_LEN 7
|
||||
|
||||
/**
|
||||
* struct iwl_scan_offload_profile_match_v1 - match information
|
||||
* @bssid: matched bssid
|
||||
* @reserved: reserved
|
||||
* @channel: channel where the match occurred
|
||||
* @energy: energy
|
||||
* @matching_feature: feature matches
|
||||
* @matching_channels: bitmap of channels that matched, referencing
|
||||
* the channels passed in the scan offload request.
|
||||
*/
|
||||
struct iwl_scan_offload_profile_match_v1 {
|
||||
u8 bssid[ETH_ALEN];
|
||||
__le16 reserved;
|
||||
u8 channel;
|
||||
u8 energy;
|
||||
u8 matching_feature;
|
||||
u8 matching_channels[SCAN_OFFLOAD_MATCHING_CHANNELS_LEN_V1];
|
||||
} __packed; /* SCAN_OFFLOAD_PROFILE_MATCH_RESULTS_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_scan_offload_profiles_query_v1 - match results query response
|
||||
* @matched_profiles: bitmap of matched profiles, referencing the
|
||||
* matches passed in the scan offload request
|
||||
* @last_scan_age: age of the last offloaded scan
|
||||
* @n_scans_done: number of offloaded scans done
|
||||
* @gp2_d0u: GP2 when D0U occurred
|
||||
* @gp2_invoked: GP2 when scan offload was invoked
|
||||
* @resume_while_scanning: not used
|
||||
* @self_recovery: obsolete
|
||||
* @reserved: reserved
|
||||
* @matches: array of match information, one for each match
|
||||
*/
|
||||
struct iwl_scan_offload_profiles_query_v1 {
|
||||
__le32 matched_profiles;
|
||||
__le32 last_scan_age;
|
||||
__le32 n_scans_done;
|
||||
__le32 gp2_d0u;
|
||||
__le32 gp2_invoked;
|
||||
u8 resume_while_scanning;
|
||||
u8 self_recovery;
|
||||
__le16 reserved;
|
||||
struct iwl_scan_offload_profile_match_v1 matches[IWL_SCAN_MAX_PROFILES];
|
||||
} __packed; /* SCAN_OFFLOAD_PROFILES_QUERY_RSP_S_VER_2 */
|
||||
|
||||
/**
|
||||
* struct iwl_scan_offload_profile_match - match information
|
||||
* @bssid: matched bssid
|
||||
@ -797,7 +843,7 @@ struct iwl_umac_scan_complete {
|
||||
* @energy: energy
|
||||
* @matching_feature: feature matches
|
||||
* @matching_channels: bitmap of channels that matched, referencing
|
||||
* the channels passed in tue scan offload request
|
||||
* the channels passed in the scan offload request.
|
||||
*/
|
||||
struct iwl_scan_offload_profile_match {
|
||||
u8 bssid[ETH_ALEN];
|
||||
@ -806,7 +852,7 @@ struct iwl_scan_offload_profile_match {
|
||||
u8 energy;
|
||||
u8 matching_feature;
|
||||
u8 matching_channels[SCAN_OFFLOAD_MATCHING_CHANNELS_LEN];
|
||||
} __packed; /* SCAN_OFFLOAD_PROFILE_MATCH_RESULTS_S_VER_1 */
|
||||
} __packed; /* SCAN_OFFLOAD_PROFILE_MATCH_RESULTS_S_VER_2 */
|
||||
|
||||
/**
|
||||
* struct iwl_scan_offload_profiles_query - match results query response
|
||||
@ -831,7 +877,7 @@ struct iwl_scan_offload_profiles_query {
|
||||
u8 self_recovery;
|
||||
__le16 reserved;
|
||||
struct iwl_scan_offload_profile_match matches[IWL_SCAN_MAX_PROFILES];
|
||||
} __packed; /* SCAN_OFFLOAD_PROFILES_QUERY_RSP_S_VER_2 */
|
||||
} __packed; /* SCAN_OFFLOAD_PROFILES_QUERY_RSP_S_VER_3 */
|
||||
|
||||
/**
|
||||
* struct iwl_umac_scan_iter_complete_notif - notifies end of scanning iteration
|
||||
|
@ -804,8 +804,8 @@ static void iwl_dump_paging(struct iwl_fw_runtime *fwrt,
|
||||
}
|
||||
|
||||
static struct iwl_fw_error_dump_file *
|
||||
_iwl_fw_error_dump(struct iwl_fw_runtime *fwrt,
|
||||
struct iwl_fw_dump_ptrs *fw_error_dump)
|
||||
iwl_fw_error_dump_file(struct iwl_fw_runtime *fwrt,
|
||||
struct iwl_fw_dump_ptrs *fw_error_dump)
|
||||
{
|
||||
struct iwl_fw_error_dump_file *dump_file;
|
||||
struct iwl_fw_error_dump_data *dump_data;
|
||||
@ -1791,16 +1791,13 @@ static void iwl_fw_ini_dump_trigger(struct iwl_fw_runtime *fwrt,
|
||||
}
|
||||
|
||||
static struct iwl_fw_error_dump_file *
|
||||
_iwl_fw_error_ini_dump(struct iwl_fw_runtime *fwrt,
|
||||
struct iwl_fw_dump_ptrs *fw_error_dump)
|
||||
iwl_fw_error_ini_dump_file(struct iwl_fw_runtime *fwrt)
|
||||
{
|
||||
int size, id = le32_to_cpu(fwrt->dump.desc->trig_desc.type);
|
||||
int size;
|
||||
struct iwl_fw_error_dump_data *dump_data;
|
||||
struct iwl_fw_error_dump_file *dump_file;
|
||||
struct iwl_fw_ini_trigger *trigger;
|
||||
|
||||
if (id == FW_DBG_TRIGGER_FW_ASSERT)
|
||||
id = IWL_FW_TRIGGER_ID_FW_ASSERT;
|
||||
enum iwl_fw_ini_trigger_id id = fwrt->dump.ini_trig_id;
|
||||
|
||||
if (!iwl_fw_ini_trigger_on(fwrt, id))
|
||||
return NULL;
|
||||
@ -1817,8 +1814,6 @@ _iwl_fw_error_ini_dump(struct iwl_fw_runtime *fwrt,
|
||||
if (!dump_file)
|
||||
return NULL;
|
||||
|
||||
fw_error_dump->fwrt_ptr = dump_file;
|
||||
|
||||
dump_file->barker = cpu_to_le32(IWL_FW_ERROR_DUMP_BARKER);
|
||||
dump_data = (void *)dump_file->data;
|
||||
dump_file->file_len = cpu_to_le32(size);
|
||||
@ -1828,47 +1823,27 @@ _iwl_fw_error_ini_dump(struct iwl_fw_runtime *fwrt,
|
||||
return dump_file;
|
||||
}
|
||||
|
||||
void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt)
|
||||
static void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt)
|
||||
{
|
||||
struct iwl_fw_dump_ptrs *fw_error_dump;
|
||||
struct iwl_fw_dump_ptrs fw_error_dump = {};
|
||||
struct iwl_fw_error_dump_file *dump_file;
|
||||
struct scatterlist *sg_dump_data;
|
||||
u32 file_len;
|
||||
u32 dump_mask = fwrt->fw->dbg.dump_mask;
|
||||
|
||||
IWL_DEBUG_INFO(fwrt, "WRT dump start\n");
|
||||
|
||||
/* there's no point in fw dump if the bus is dead */
|
||||
if (test_bit(STATUS_TRANS_DEAD, &fwrt->trans->status)) {
|
||||
IWL_ERR(fwrt, "Skip fw error dump since bus is dead\n");
|
||||
dump_file = iwl_fw_error_dump_file(fwrt, &fw_error_dump);
|
||||
if (!dump_file)
|
||||
goto out;
|
||||
}
|
||||
|
||||
fw_error_dump = kzalloc(sizeof(*fw_error_dump), GFP_KERNEL);
|
||||
if (!fw_error_dump)
|
||||
goto out;
|
||||
|
||||
if (fwrt->trans->ini_valid)
|
||||
dump_file = _iwl_fw_error_ini_dump(fwrt, fw_error_dump);
|
||||
else
|
||||
dump_file = _iwl_fw_error_dump(fwrt, fw_error_dump);
|
||||
|
||||
if (!dump_file) {
|
||||
kfree(fw_error_dump);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!fwrt->trans->ini_valid && fwrt->dump.monitor_only)
|
||||
dump_mask &= IWL_FW_ERROR_DUMP_FW_MONITOR;
|
||||
|
||||
if (!fwrt->trans->ini_valid)
|
||||
fw_error_dump->trans_ptr =
|
||||
iwl_trans_dump_data(fwrt->trans, dump_mask);
|
||||
|
||||
fw_error_dump.trans_ptr = iwl_trans_dump_data(fwrt->trans, dump_mask);
|
||||
file_len = le32_to_cpu(dump_file->file_len);
|
||||
fw_error_dump->fwrt_len = file_len;
|
||||
if (fw_error_dump->trans_ptr) {
|
||||
file_len += fw_error_dump->trans_ptr->len;
|
||||
fw_error_dump.fwrt_len = file_len;
|
||||
|
||||
if (fw_error_dump.trans_ptr) {
|
||||
file_len += fw_error_dump.trans_ptr->len;
|
||||
dump_file->file_len = cpu_to_le32(file_len);
|
||||
}
|
||||
|
||||
@ -1876,27 +1851,49 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt)
|
||||
if (sg_dump_data) {
|
||||
sg_pcopy_from_buffer(sg_dump_data,
|
||||
sg_nents(sg_dump_data),
|
||||
fw_error_dump->fwrt_ptr,
|
||||
fw_error_dump->fwrt_len, 0);
|
||||
if (fw_error_dump->trans_ptr)
|
||||
fw_error_dump.fwrt_ptr,
|
||||
fw_error_dump.fwrt_len, 0);
|
||||
if (fw_error_dump.trans_ptr)
|
||||
sg_pcopy_from_buffer(sg_dump_data,
|
||||
sg_nents(sg_dump_data),
|
||||
fw_error_dump->trans_ptr->data,
|
||||
fw_error_dump->trans_ptr->len,
|
||||
fw_error_dump->fwrt_len);
|
||||
fw_error_dump.trans_ptr->data,
|
||||
fw_error_dump.trans_ptr->len,
|
||||
fw_error_dump.fwrt_len);
|
||||
dev_coredumpsg(fwrt->trans->dev, sg_dump_data, file_len,
|
||||
GFP_KERNEL);
|
||||
}
|
||||
vfree(fw_error_dump->fwrt_ptr);
|
||||
vfree(fw_error_dump->trans_ptr);
|
||||
kfree(fw_error_dump);
|
||||
vfree(fw_error_dump.fwrt_ptr);
|
||||
vfree(fw_error_dump.trans_ptr);
|
||||
|
||||
out:
|
||||
iwl_fw_free_dump_desc(fwrt);
|
||||
clear_bit(IWL_FWRT_STATUS_DUMPING, &fwrt->status);
|
||||
IWL_DEBUG_INFO(fwrt, "WRT dump done\n");
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_fw_error_dump);
|
||||
|
||||
static void iwl_fw_error_ini_dump(struct iwl_fw_runtime *fwrt)
|
||||
{
|
||||
struct iwl_fw_error_dump_file *dump_file;
|
||||
struct scatterlist *sg_dump_data;
|
||||
u32 file_len;
|
||||
|
||||
dump_file = iwl_fw_error_ini_dump_file(fwrt);
|
||||
if (!dump_file)
|
||||
goto out;
|
||||
|
||||
file_len = le32_to_cpu(dump_file->file_len);
|
||||
|
||||
sg_dump_data = alloc_sgtable(file_len);
|
||||
if (sg_dump_data) {
|
||||
sg_pcopy_from_buffer(sg_dump_data, sg_nents(sg_dump_data),
|
||||
dump_file, file_len, 0);
|
||||
dev_coredumpsg(fwrt->trans->dev, sg_dump_data, file_len,
|
||||
GFP_KERNEL);
|
||||
}
|
||||
vfree(dump_file);
|
||||
out:
|
||||
fwrt->dump.ini_trig_id = IWL_FW_TRIGGER_ID_INVALID;
|
||||
clear_bit(IWL_FWRT_STATUS_DUMPING, &fwrt->status);
|
||||
}
|
||||
|
||||
const struct iwl_fw_dump_desc iwl_dump_desc_assert = {
|
||||
.trig_desc = {
|
||||
@ -1910,6 +1907,17 @@ int iwl_fw_dbg_collect_desc(struct iwl_fw_runtime *fwrt,
|
||||
bool monitor_only,
|
||||
unsigned int delay)
|
||||
{
|
||||
u32 trig_type = le32_to_cpu(desc->trig_desc.type);
|
||||
int ret;
|
||||
|
||||
if (fwrt->trans->ini_valid) {
|
||||
ret = iwl_fw_dbg_ini_collect(fwrt, trig_type);
|
||||
if (!ret)
|
||||
iwl_fw_free_dump_desc(fwrt);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (test_and_set_bit(IWL_FWRT_STATUS_DUMPING, &fwrt->status))
|
||||
return -EBUSY;
|
||||
|
||||
@ -1955,10 +1963,10 @@ int iwl_fw_dbg_error_collect(struct iwl_fw_runtime *fwrt,
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_fw_dbg_error_collect);
|
||||
|
||||
int _iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
|
||||
enum iwl_fw_dbg_trigger trig,
|
||||
const char *str, size_t len,
|
||||
struct iwl_fw_dbg_trigger_tlv *trigger)
|
||||
int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
|
||||
enum iwl_fw_dbg_trigger trig,
|
||||
const char *str, size_t len,
|
||||
struct iwl_fw_dbg_trigger_tlv *trigger)
|
||||
{
|
||||
struct iwl_fw_dump_desc *desc;
|
||||
unsigned int delay = 0;
|
||||
@ -1995,50 +2003,64 @@ int _iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
|
||||
|
||||
return iwl_fw_dbg_collect_desc(fwrt, desc, monitor_only, delay);
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(_iwl_fw_dbg_collect);
|
||||
IWL_EXPORT_SYMBOL(iwl_fw_dbg_collect);
|
||||
|
||||
int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
|
||||
u32 id, const char *str, size_t len)
|
||||
int _iwl_fw_dbg_ini_collect(struct iwl_fw_runtime *fwrt,
|
||||
enum iwl_fw_ini_trigger_id id)
|
||||
{
|
||||
struct iwl_fw_dump_desc *desc;
|
||||
struct iwl_fw_ini_active_triggers *active;
|
||||
u32 occur, delay;
|
||||
|
||||
if (!fwrt->trans->ini_valid)
|
||||
return _iwl_fw_dbg_collect(fwrt, id, str, len, NULL);
|
||||
|
||||
if (id == FW_DBG_TRIGGER_USER)
|
||||
id = IWL_FW_TRIGGER_ID_USER_TRIGGER;
|
||||
|
||||
active = &fwrt->dump.active_trigs[id];
|
||||
|
||||
if (WARN_ON(!active->active))
|
||||
if (WARN_ON(!iwl_fw_ini_trigger_on(fwrt, id)))
|
||||
return -EINVAL;
|
||||
|
||||
if (test_and_set_bit(IWL_FWRT_STATUS_DUMPING, &fwrt->status))
|
||||
return -EBUSY;
|
||||
|
||||
active = &fwrt->dump.active_trigs[id];
|
||||
delay = le32_to_cpu(active->trig->dump_delay);
|
||||
occur = le32_to_cpu(active->trig->occurrences);
|
||||
if (!occur)
|
||||
return 0;
|
||||
|
||||
active->trig->occurrences = cpu_to_le32(--occur);
|
||||
|
||||
if (le32_to_cpu(active->trig->force_restart)) {
|
||||
IWL_WARN(fwrt, "Force restart: trigger %d fired.\n", id);
|
||||
iwl_force_nmi(fwrt->trans);
|
||||
return 0;
|
||||
}
|
||||
|
||||
desc = kzalloc(sizeof(*desc) + len, GFP_ATOMIC);
|
||||
if (!desc)
|
||||
return -ENOMEM;
|
||||
fwrt->dump.ini_trig_id = id;
|
||||
|
||||
active->trig->occurrences = cpu_to_le32(--occur);
|
||||
IWL_WARN(fwrt, "Collecting data: ini trigger %d fired.\n", id);
|
||||
|
||||
desc->len = len;
|
||||
desc->trig_desc.type = cpu_to_le32(id);
|
||||
memcpy(desc->trig_desc.data, str, len);
|
||||
schedule_delayed_work(&fwrt->dump.wk, usecs_to_jiffies(delay));
|
||||
|
||||
return iwl_fw_dbg_collect_desc(fwrt, desc, true, delay);
|
||||
return 0;
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_fw_dbg_collect);
|
||||
IWL_EXPORT_SYMBOL(_iwl_fw_dbg_ini_collect);
|
||||
|
||||
int iwl_fw_dbg_ini_collect(struct iwl_fw_runtime *fwrt, u32 legacy_trigger_id)
|
||||
{
|
||||
int id;
|
||||
|
||||
switch (legacy_trigger_id) {
|
||||
case FW_DBG_TRIGGER_FW_ASSERT:
|
||||
case FW_DBG_TRIGGER_ALIVE_TIMEOUT:
|
||||
case FW_DBG_TRIGGER_DRIVER:
|
||||
id = IWL_FW_TRIGGER_ID_FW_ASSERT;
|
||||
break;
|
||||
case FW_DBG_TRIGGER_USER:
|
||||
id = IWL_FW_TRIGGER_ID_USER_TRIGGER;
|
||||
break;
|
||||
default:
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return _iwl_fw_dbg_ini_collect(fwrt, id);
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_fw_dbg_ini_collect);
|
||||
|
||||
int iwl_fw_dbg_collect_trig(struct iwl_fw_runtime *fwrt,
|
||||
struct iwl_fw_dbg_trigger_tlv *trigger,
|
||||
@ -2066,8 +2088,8 @@ int iwl_fw_dbg_collect_trig(struct iwl_fw_runtime *fwrt,
|
||||
len = strlen(buf) + 1;
|
||||
}
|
||||
|
||||
ret = _iwl_fw_dbg_collect(fwrt, le32_to_cpu(trigger->id), buf, len,
|
||||
trigger);
|
||||
ret = iwl_fw_dbg_collect(fwrt, le32_to_cpu(trigger->id), buf, len,
|
||||
trigger);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -2141,9 +2163,20 @@ void iwl_fw_dbg_collect_sync(struct iwl_fw_runtime *fwrt)
|
||||
return;
|
||||
}
|
||||
|
||||
/* there's no point in fw dump if the bus is dead */
|
||||
if (test_bit(STATUS_TRANS_DEAD, &fwrt->trans->status)) {
|
||||
IWL_ERR(fwrt, "Skip fw error dump since bus is dead\n");
|
||||
return;
|
||||
}
|
||||
|
||||
iwl_fw_dbg_stop_recording(fwrt, ¶ms);
|
||||
|
||||
iwl_fw_error_dump(fwrt);
|
||||
IWL_DEBUG_INFO(fwrt, "WRT dump start\n");
|
||||
if (fwrt->trans->ini_valid)
|
||||
iwl_fw_error_ini_dump(fwrt);
|
||||
else
|
||||
iwl_fw_error_dump(fwrt);
|
||||
IWL_DEBUG_INFO(fwrt, "WRT dump done\n");
|
||||
|
||||
/* start recording again if the firmware is not crashed */
|
||||
if (!test_bit(STATUS_FW_ERROR, &fwrt->trans->status) &&
|
||||
|
@ -108,18 +108,17 @@ static inline void iwl_fw_free_dump_desc(struct iwl_fw_runtime *fwrt)
|
||||
fwrt->dump.umac_err_id = 0;
|
||||
}
|
||||
|
||||
void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt);
|
||||
int iwl_fw_dbg_collect_desc(struct iwl_fw_runtime *fwrt,
|
||||
const struct iwl_fw_dump_desc *desc,
|
||||
bool monitor_only, unsigned int delay);
|
||||
int iwl_fw_dbg_error_collect(struct iwl_fw_runtime *fwrt,
|
||||
enum iwl_fw_dbg_trigger trig_type);
|
||||
int _iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
|
||||
enum iwl_fw_dbg_trigger trig,
|
||||
const char *str, size_t len,
|
||||
struct iwl_fw_dbg_trigger_tlv *trigger);
|
||||
int _iwl_fw_dbg_ini_collect(struct iwl_fw_runtime *fwrt,
|
||||
enum iwl_fw_ini_trigger_id id);
|
||||
int iwl_fw_dbg_ini_collect(struct iwl_fw_runtime *fwrt, u32 legacy_trigger_id);
|
||||
int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
|
||||
u32 id, const char *str, size_t len);
|
||||
enum iwl_fw_dbg_trigger trig, const char *str,
|
||||
size_t len, struct iwl_fw_dbg_trigger_tlv *trigger);
|
||||
int iwl_fw_dbg_collect_trig(struct iwl_fw_runtime *fwrt,
|
||||
struct iwl_fw_dbg_trigger_tlv *trigger,
|
||||
const char *fmt, ...) __printf(3, 4);
|
||||
@ -229,10 +228,8 @@ iwl_fw_ini_trigger_on(struct iwl_fw_runtime *fwrt,
|
||||
struct iwl_fw_ini_trigger *trig;
|
||||
u32 usec;
|
||||
|
||||
|
||||
|
||||
if (!fwrt->trans->ini_valid || id >= IWL_FW_TRIGGER_ID_NUM ||
|
||||
!fwrt->dump.active_trigs[id].active)
|
||||
if (!fwrt->trans->ini_valid || id == IWL_FW_TRIGGER_ID_INVALID ||
|
||||
id >= IWL_FW_TRIGGER_ID_NUM || !fwrt->dump.active_trigs[id].active)
|
||||
return false;
|
||||
|
||||
trig = fwrt->dump.active_trigs[id].trig;
|
||||
|
@ -211,6 +211,9 @@ struct iwl_fw_error_dump_info {
|
||||
* @fw_mon_wr_ptr: the position of the write pointer in the cyclic buffer
|
||||
* @fw_mon_base_ptr: base pointer of the data
|
||||
* @fw_mon_cycle_cnt: number of wraparounds
|
||||
* @fw_mon_base_high_ptr: used in AX210 devices, the base adderss is 64 bit
|
||||
* so fw_mon_base_ptr holds LSB 32 bits and fw_mon_base_high_ptr hold
|
||||
* MSB 32 bits
|
||||
* @reserved: for future use
|
||||
* @data: captured data
|
||||
*/
|
||||
@ -218,7 +221,8 @@ struct iwl_fw_error_dump_fw_mon {
|
||||
__le32 fw_mon_wr_ptr;
|
||||
__le32 fw_mon_base_ptr;
|
||||
__le32 fw_mon_cycle_cnt;
|
||||
__le32 reserved[3];
|
||||
__le32 fw_mon_base_high_ptr;
|
||||
__le32 reserved[2];
|
||||
u8 data[];
|
||||
} __packed;
|
||||
|
||||
|
@ -272,8 +272,13 @@ typedef unsigned int __bitwise iwl_ucode_tlv_api_t;
|
||||
* version of the beacon notification.
|
||||
* @IWL_UCODE_TLV_API_BEACON_FILTER_V4: This ucode supports v4 of
|
||||
* BEACON_FILTER_CONFIG_API_S_VER_4.
|
||||
* @IWL_UCODE_TLV_API_REGULATORY_NVM_INFO: This ucode supports v4 of
|
||||
* REGULATORY_NVM_GET_INFO_RSP_API_S.
|
||||
* @IWL_UCODE_TLV_API_FTM_NEW_RANGE_REQ: This ucode supports v7 of
|
||||
* LOCATION_RANGE_REQ_CMD_API_S and v6 of LOCATION_RANGE_RESP_NTFY_API_S.
|
||||
* @IWL_UCODE_TLV_API_SCAN_OFFLOAD_CHANS: This ucode supports v2 of
|
||||
* SCAN_OFFLOAD_PROFILE_MATCH_RESULTS_S and v3 of
|
||||
* SCAN_OFFLOAD_PROFILES_QUERY_RSP_S.
|
||||
*
|
||||
* @NUM_IWL_UCODE_TLV_API: number of bits used
|
||||
*/
|
||||
@ -300,7 +305,9 @@ enum iwl_ucode_tlv_api {
|
||||
IWL_UCODE_TLV_API_REDUCE_TX_POWER = (__force iwl_ucode_tlv_api_t)45,
|
||||
IWL_UCODE_TLV_API_SHORT_BEACON_NOTIF = (__force iwl_ucode_tlv_api_t)46,
|
||||
IWL_UCODE_TLV_API_BEACON_FILTER_V4 = (__force iwl_ucode_tlv_api_t)47,
|
||||
IWL_UCODE_TLV_API_REGULATORY_NVM_INFO = (__force iwl_ucode_tlv_api_t)48,
|
||||
IWL_UCODE_TLV_API_FTM_NEW_RANGE_REQ = (__force iwl_ucode_tlv_api_t)49,
|
||||
IWL_UCODE_TLV_API_SCAN_OFFLOAD_CHANS = (__force iwl_ucode_tlv_api_t)50,
|
||||
|
||||
NUM_IWL_UCODE_TLV_API
|
||||
#ifdef __CHECKER__
|
||||
@ -350,6 +357,7 @@ typedef unsigned int __bitwise iwl_ucode_tlv_capa_t;
|
||||
* IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD: firmware supports CSA command
|
||||
* @IWL_UCODE_TLV_CAPA_ULTRA_HB_CHANNELS: firmware supports ultra high band
|
||||
* (6 GHz).
|
||||
* @IWL_UCODE_TLV_CAPA_CS_MODIFY: firmware supports modify action CSA command
|
||||
* @IWL_UCODE_TLV_CAPA_EXTENDED_DTS_MEASURE: extended DTS measurement
|
||||
* @IWL_UCODE_TLV_CAPA_SHORT_PM_TIMEOUTS: supports short PM timeouts
|
||||
* @IWL_UCODE_TLV_CAPA_BT_MPLUT_SUPPORT: supports bt-coex Multi-priority LUT
|
||||
@ -420,6 +428,7 @@ enum iwl_ucode_tlv_capa {
|
||||
IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD = (__force iwl_ucode_tlv_capa_t)46,
|
||||
IWL_UCODE_TLV_CAPA_ULTRA_HB_CHANNELS = (__force iwl_ucode_tlv_capa_t)48,
|
||||
IWL_UCODE_TLV_CAPA_FTM_CALIBRATED = (__force iwl_ucode_tlv_capa_t)47,
|
||||
IWL_UCODE_TLV_CAPA_CS_MODIFY = (__force iwl_ucode_tlv_capa_t)49,
|
||||
|
||||
/* set 2 */
|
||||
IWL_UCODE_TLV_CAPA_EXTENDED_DTS_MEASURE = (__force iwl_ucode_tlv_capa_t)64,
|
||||
|
@ -145,6 +145,7 @@ struct iwl_fw_runtime {
|
||||
u32 lmac_err_id[MAX_NUM_LMAC];
|
||||
u32 umac_err_id;
|
||||
void *fifo_iter;
|
||||
enum iwl_fw_ini_trigger_id ini_trig_id;
|
||||
} dump;
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
struct {
|
||||
|
@ -383,6 +383,7 @@ struct iwl_csr_params {
|
||||
* @bisr_workaround: BISR hardware workaround (for 22260 series devices)
|
||||
* @min_txq_size: minimum number of slots required in a TX queue
|
||||
* @umac_prph_offset: offset to add to UMAC periphery address
|
||||
* @uhb_supported: ultra high band channels supported
|
||||
*
|
||||
* We enable the driver to be backward compatible wrt. hardware features.
|
||||
* API differences in uCode shouldn't be handled here but through TLVs
|
||||
@ -433,7 +434,8 @@ struct iwl_cfg {
|
||||
gen2:1,
|
||||
cdb:1,
|
||||
dbgc_supported:1,
|
||||
bisr_workaround:1;
|
||||
bisr_workaround:1,
|
||||
uhb_supported:1;
|
||||
u8 valid_tx_ant;
|
||||
u8 valid_rx_ant;
|
||||
u8 non_shared_ant;
|
||||
@ -572,6 +574,7 @@ extern const struct iwl_cfg iwlax210_2ax_cfg_so_jf_a0;
|
||||
extern const struct iwl_cfg iwlax210_2ax_cfg_so_hr_a0;
|
||||
extern const struct iwl_cfg iwlax210_2ax_cfg_so_gf_a0;
|
||||
extern const struct iwl_cfg iwlax210_2ax_cfg_ty_gf_a0;
|
||||
extern const struct iwl_cfg iwlax210_2ax_cfg_so_gf4_a0;
|
||||
#endif /* CPTCFG_IWLMVM || CPTCFG_IWLFMAC */
|
||||
|
||||
#endif /* __IWL_CONFIG_H__ */
|
||||
|
@ -8,7 +8,7 @@
|
||||
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 Intel Deutschland GmbH
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@ -30,7 +30,7 @@
|
||||
*
|
||||
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -336,6 +336,7 @@ enum {
|
||||
#define CSR_HW_RF_ID_TYPE_HR (0x0010A000)
|
||||
#define CSR_HW_RF_ID_TYPE_HRCDB (0x00109F00)
|
||||
#define CSR_HW_RF_ID_TYPE_GF (0x0010D000)
|
||||
#define CSR_HW_RF_ID_TYPE_GF4 (0x0010E000)
|
||||
|
||||
/* HW_RF CHIP ID */
|
||||
#define CSR_HW_RF_ID_TYPE_CHIP_ID(_val) (((_val) >> 12) & 0xFFF)
|
||||
|
@ -5,7 +5,7 @@
|
||||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright (C) 2018 Intel Corporation
|
||||
* Copyright (C) 2018 - 2019 Intel Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@ -28,7 +28,7 @@
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright (C) 2018 Intel Corporation
|
||||
* Copyright (C) 2018 - 2019 Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -73,6 +73,9 @@ void iwl_fw_dbg_copy_tlv(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv,
|
||||
int copy_size = le32_to_cpu(tlv->length) + sizeof(*tlv);
|
||||
int offset_size = copy_size;
|
||||
|
||||
if (le32_to_cpu(header->tlv_version) != 1)
|
||||
return;
|
||||
|
||||
if (WARN_ONCE(apply_point >= IWL_FW_INI_APPLY_NUM,
|
||||
"Invalid apply point id %d\n", apply_point))
|
||||
return;
|
||||
@ -132,6 +135,9 @@ void iwl_alloc_dbg_tlv(struct iwl_trans *trans, size_t len, const u8 *data,
|
||||
hdr = (void *)&tlv->data[0];
|
||||
apply = le32_to_cpu(hdr->apply_point);
|
||||
|
||||
if (le32_to_cpu(hdr->tlv_version) != 1)
|
||||
continue;
|
||||
|
||||
IWL_DEBUG_FW(trans, "Read TLV %x, apply point %d\n",
|
||||
le32_to_cpu(tlv->type), apply);
|
||||
|
||||
|
@ -130,7 +130,7 @@ enum nvm_sku_bits {
|
||||
/*
|
||||
* These are the channel numbers in the order that they are stored in the NVM
|
||||
*/
|
||||
static const u8 iwl_nvm_channels[] = {
|
||||
static const u16 iwl_nvm_channels[] = {
|
||||
/* 2.4 GHz */
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
/* 5 GHz */
|
||||
@ -139,7 +139,7 @@ static const u8 iwl_nvm_channels[] = {
|
||||
149, 153, 157, 161, 165
|
||||
};
|
||||
|
||||
static const u8 iwl_ext_nvm_channels[] = {
|
||||
static const u16 iwl_ext_nvm_channels[] = {
|
||||
/* 2.4 GHz */
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
/* 5 GHz */
|
||||
@ -148,14 +148,27 @@ static const u8 iwl_ext_nvm_channels[] = {
|
||||
149, 153, 157, 161, 165, 169, 173, 177, 181
|
||||
};
|
||||
|
||||
static const u16 iwl_uhb_nvm_channels[] = {
|
||||
/* 2.4 GHz */
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
/* 5 GHz */
|
||||
36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92,
|
||||
96, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144,
|
||||
149, 153, 157, 161, 165, 169, 173, 177, 181,
|
||||
/* 6-7 GHz */
|
||||
189, 193, 197, 201, 205, 209, 213, 217, 221, 225, 229, 233, 237, 241,
|
||||
245, 249, 253, 257, 261, 265, 269, 273, 277, 281, 285, 289, 293, 297,
|
||||
301, 305, 309, 313, 317, 321, 325, 329, 333, 337, 341, 345, 349, 353,
|
||||
357, 361, 365, 369, 373, 377, 381, 385, 389, 393, 397, 401, 405, 409,
|
||||
413, 417, 421
|
||||
};
|
||||
|
||||
#define IWL_NVM_NUM_CHANNELS ARRAY_SIZE(iwl_nvm_channels)
|
||||
#define IWL_NVM_NUM_CHANNELS_EXT ARRAY_SIZE(iwl_ext_nvm_channels)
|
||||
#define IWL_NVM_NUM_CHANNELS_UHB ARRAY_SIZE(iwl_uhb_nvm_channels)
|
||||
#define NUM_2GHZ_CHANNELS 14
|
||||
#define NUM_2GHZ_CHANNELS_EXT 14
|
||||
#define FIRST_2GHZ_HT_MINUS 5
|
||||
#define LAST_2GHZ_HT_PLUS 9
|
||||
#define LAST_5GHZ_HT 165
|
||||
#define LAST_5GHZ_HT_FAMILY_8000 181
|
||||
#define N_HW_ADDR_MASK 0xF
|
||||
|
||||
/* rate data (static) */
|
||||
@ -213,7 +226,7 @@ enum iwl_nvm_channel_flags {
|
||||
};
|
||||
|
||||
static inline void iwl_nvm_print_channel_flags(struct device *dev, u32 level,
|
||||
int chan, u16 flags)
|
||||
int chan, u32 flags)
|
||||
{
|
||||
#define CHECK_AND_PRINT_I(x) \
|
||||
((flags & NVM_CHANNEL_##x) ? " " #x : "")
|
||||
@ -244,20 +257,16 @@ static inline void iwl_nvm_print_channel_flags(struct device *dev, u32 level,
|
||||
}
|
||||
|
||||
static u32 iwl_get_channel_flags(u8 ch_num, int ch_idx, bool is_5ghz,
|
||||
u16 nvm_flags, const struct iwl_cfg *cfg)
|
||||
u32 nvm_flags, const struct iwl_cfg *cfg)
|
||||
{
|
||||
u32 flags = IEEE80211_CHAN_NO_HT40;
|
||||
u32 last_5ghz_ht = LAST_5GHZ_HT;
|
||||
|
||||
if (cfg->nvm_type == IWL_NVM_EXT)
|
||||
last_5ghz_ht = LAST_5GHZ_HT_FAMILY_8000;
|
||||
|
||||
if (!is_5ghz && (nvm_flags & NVM_CHANNEL_40MHZ)) {
|
||||
if (ch_num <= LAST_2GHZ_HT_PLUS)
|
||||
flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
|
||||
if (ch_num >= FIRST_2GHZ_HT_MINUS)
|
||||
flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
|
||||
} else if (ch_num <= last_5ghz_ht && (nvm_flags & NVM_CHANNEL_40MHZ)) {
|
||||
} else if (nvm_flags & NVM_CHANNEL_40MHZ) {
|
||||
if ((ch_idx - NUM_2GHZ_CHANNELS) % 2 == 0)
|
||||
flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
|
||||
else
|
||||
@ -292,30 +301,36 @@ static u32 iwl_get_channel_flags(u8 ch_num, int ch_idx, bool is_5ghz,
|
||||
|
||||
static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
|
||||
struct iwl_nvm_data *data,
|
||||
const __le16 * const nvm_ch_flags,
|
||||
u32 sbands_flags)
|
||||
const void * const nvm_ch_flags,
|
||||
u32 sbands_flags, bool v4)
|
||||
{
|
||||
int ch_idx;
|
||||
int n_channels = 0;
|
||||
struct ieee80211_channel *channel;
|
||||
u16 ch_flags;
|
||||
int num_of_ch, num_2ghz_channels;
|
||||
const u8 *nvm_chan;
|
||||
u32 ch_flags;
|
||||
int num_of_ch, num_2ghz_channels = NUM_2GHZ_CHANNELS;
|
||||
const u16 *nvm_chan;
|
||||
|
||||
if (cfg->nvm_type != IWL_NVM_EXT) {
|
||||
num_of_ch = IWL_NVM_NUM_CHANNELS;
|
||||
nvm_chan = &iwl_nvm_channels[0];
|
||||
num_2ghz_channels = NUM_2GHZ_CHANNELS;
|
||||
} else {
|
||||
if (cfg->uhb_supported) {
|
||||
num_of_ch = IWL_NVM_NUM_CHANNELS_UHB;
|
||||
nvm_chan = iwl_uhb_nvm_channels;
|
||||
} else if (cfg->nvm_type == IWL_NVM_EXT) {
|
||||
num_of_ch = IWL_NVM_NUM_CHANNELS_EXT;
|
||||
nvm_chan = &iwl_ext_nvm_channels[0];
|
||||
num_2ghz_channels = NUM_2GHZ_CHANNELS_EXT;
|
||||
nvm_chan = iwl_ext_nvm_channels;
|
||||
} else {
|
||||
num_of_ch = IWL_NVM_NUM_CHANNELS;
|
||||
nvm_chan = iwl_nvm_channels;
|
||||
}
|
||||
|
||||
for (ch_idx = 0; ch_idx < num_of_ch; ch_idx++) {
|
||||
bool is_5ghz = (ch_idx >= num_2ghz_channels);
|
||||
|
||||
ch_flags = __le16_to_cpup(nvm_ch_flags + ch_idx);
|
||||
if (v4)
|
||||
ch_flags =
|
||||
__le32_to_cpup((__le32 *)nvm_ch_flags + ch_idx);
|
||||
else
|
||||
ch_flags =
|
||||
__le16_to_cpup((__le16 *)nvm_ch_flags + ch_idx);
|
||||
|
||||
if (is_5ghz && !data->sku_cap_band_52ghz_enable)
|
||||
continue;
|
||||
@ -661,15 +676,15 @@ static void iwl_init_he_hw_capab(struct ieee80211_supported_band *sband,
|
||||
|
||||
static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
|
||||
struct iwl_nvm_data *data,
|
||||
const __le16 *nvm_ch_flags, u8 tx_chains,
|
||||
u8 rx_chains, u32 sbands_flags)
|
||||
const void *nvm_ch_flags, u8 tx_chains,
|
||||
u8 rx_chains, u32 sbands_flags, bool v4)
|
||||
{
|
||||
int n_channels;
|
||||
int n_used = 0;
|
||||
struct ieee80211_supported_band *sband;
|
||||
|
||||
n_channels = iwl_init_channel_map(dev, cfg, data, nvm_ch_flags,
|
||||
sbands_flags);
|
||||
sbands_flags, v4);
|
||||
sband = &data->bands[NL80211_BAND_2GHZ];
|
||||
sband->band = NL80211_BAND_2GHZ;
|
||||
sband->bitrates = &iwl_cfg80211_rates[RATES_24_OFFS];
|
||||
@ -1006,22 +1021,18 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
|
||||
sbands_flags |= IWL_NVM_SBANDS_FLAGS_NO_WIDE_IN_5GHZ;
|
||||
|
||||
iwl_init_sbands(dev, cfg, data, ch_section, tx_chains, rx_chains,
|
||||
sbands_flags);
|
||||
sbands_flags, false);
|
||||
data->calib_version = 255;
|
||||
|
||||
return data;
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_parse_nvm_data);
|
||||
|
||||
static u32 iwl_nvm_get_regdom_bw_flags(const u8 *nvm_chan,
|
||||
static u32 iwl_nvm_get_regdom_bw_flags(const u16 *nvm_chan,
|
||||
int ch_idx, u16 nvm_flags,
|
||||
const struct iwl_cfg *cfg)
|
||||
{
|
||||
u32 flags = NL80211_RRF_NO_HT40;
|
||||
u32 last_5ghz_ht = LAST_5GHZ_HT;
|
||||
|
||||
if (cfg->nvm_type == IWL_NVM_EXT)
|
||||
last_5ghz_ht = LAST_5GHZ_HT_FAMILY_8000;
|
||||
|
||||
if (ch_idx < NUM_2GHZ_CHANNELS &&
|
||||
(nvm_flags & NVM_CHANNEL_40MHZ)) {
|
||||
@ -1029,8 +1040,7 @@ static u32 iwl_nvm_get_regdom_bw_flags(const u8 *nvm_chan,
|
||||
flags &= ~NL80211_RRF_NO_HT40PLUS;
|
||||
if (nvm_chan[ch_idx] >= FIRST_2GHZ_HT_MINUS)
|
||||
flags &= ~NL80211_RRF_NO_HT40MINUS;
|
||||
} else if (nvm_chan[ch_idx] <= last_5ghz_ht &&
|
||||
(nvm_flags & NVM_CHANNEL_40MHZ)) {
|
||||
} else if (nvm_flags & NVM_CHANNEL_40MHZ) {
|
||||
if ((ch_idx - NUM_2GHZ_CHANNELS) % 2 == 0)
|
||||
flags &= ~NL80211_RRF_NO_HT40PLUS;
|
||||
else
|
||||
@ -1074,18 +1084,26 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
|
||||
int ch_idx;
|
||||
u16 ch_flags;
|
||||
u32 reg_rule_flags, prev_reg_rule_flags = 0;
|
||||
const u8 *nvm_chan = cfg->nvm_type == IWL_NVM_EXT ?
|
||||
iwl_ext_nvm_channels : iwl_nvm_channels;
|
||||
const u16 *nvm_chan;
|
||||
struct ieee80211_regdomain *regd, *copy_rd;
|
||||
int size_of_regd, regd_to_copy;
|
||||
struct ieee80211_reg_rule *rule;
|
||||
struct regdb_ptrs *regdb_ptrs;
|
||||
enum nl80211_band band;
|
||||
int center_freq, prev_center_freq = 0;
|
||||
int valid_rules = 0;
|
||||
bool new_rule;
|
||||
int max_num_ch = cfg->nvm_type == IWL_NVM_EXT ?
|
||||
IWL_NVM_NUM_CHANNELS_EXT : IWL_NVM_NUM_CHANNELS;
|
||||
int max_num_ch;
|
||||
|
||||
if (cfg->uhb_supported) {
|
||||
max_num_ch = IWL_NVM_NUM_CHANNELS_UHB;
|
||||
nvm_chan = iwl_uhb_nvm_channels;
|
||||
} else if (cfg->nvm_type == IWL_NVM_EXT) {
|
||||
max_num_ch = IWL_NVM_NUM_CHANNELS_EXT;
|
||||
nvm_chan = iwl_ext_nvm_channels;
|
||||
} else {
|
||||
max_num_ch = IWL_NVM_NUM_CHANNELS;
|
||||
nvm_chan = iwl_nvm_channels;
|
||||
}
|
||||
|
||||
if (WARN_ON(num_of_ch > max_num_ch))
|
||||
num_of_ch = max_num_ch;
|
||||
@ -1097,11 +1115,7 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
|
||||
num_of_ch);
|
||||
|
||||
/* build a regdomain rule for every valid channel */
|
||||
size_of_regd =
|
||||
sizeof(struct ieee80211_regdomain) +
|
||||
num_of_ch * sizeof(struct ieee80211_reg_rule);
|
||||
|
||||
regd = kzalloc(size_of_regd, GFP_KERNEL);
|
||||
regd = kzalloc(struct_size(regd, reg_rules, num_of_ch), GFP_KERNEL);
|
||||
if (!regd)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
@ -1177,14 +1191,10 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
|
||||
* Narrow down regdom for unused regulatory rules to prevent hole
|
||||
* between reg rules to wmm rules.
|
||||
*/
|
||||
regd_to_copy = sizeof(struct ieee80211_regdomain) +
|
||||
valid_rules * sizeof(struct ieee80211_reg_rule);
|
||||
|
||||
copy_rd = kmemdup(regd, regd_to_copy, GFP_KERNEL);
|
||||
if (!copy_rd) {
|
||||
copy_rd = kmemdup(regd, struct_size(regd, reg_rules, valid_rules),
|
||||
GFP_KERNEL);
|
||||
if (!copy_rd)
|
||||
copy_rd = ERR_PTR(-ENOMEM);
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
kfree(regdb_ptrs);
|
||||
@ -1393,7 +1403,6 @@ struct iwl_nvm_data *iwl_get_nvm(struct iwl_trans *trans,
|
||||
const struct iwl_fw *fw)
|
||||
{
|
||||
struct iwl_nvm_get_info cmd = {};
|
||||
struct iwl_nvm_get_info_rsp *rsp;
|
||||
struct iwl_nvm_data *nvm;
|
||||
struct iwl_host_cmd hcmd = {
|
||||
.flags = CMD_WANT_SKB | CMD_SEND_IN_RFKILL,
|
||||
@ -1408,12 +1417,24 @@ struct iwl_nvm_data *iwl_get_nvm(struct iwl_trans *trans,
|
||||
bool empty_otp;
|
||||
u32 mac_flags;
|
||||
u32 sbands_flags = 0;
|
||||
/*
|
||||
* All the values in iwl_nvm_get_info_rsp v4 are the same as
|
||||
* in v3, except for the channel profile part of the
|
||||
* regulatory. So we can just access the new struct, with the
|
||||
* exception of the latter.
|
||||
*/
|
||||
struct iwl_nvm_get_info_rsp *rsp;
|
||||
struct iwl_nvm_get_info_rsp_v3 *rsp_v3;
|
||||
bool v4 = fw_has_api(&fw->ucode_capa,
|
||||
IWL_UCODE_TLV_API_REGULATORY_NVM_INFO);
|
||||
size_t rsp_size = v4 ? sizeof(*rsp) : sizeof(*rsp_v3);
|
||||
void *channel_profile;
|
||||
|
||||
ret = iwl_trans_send_cmd(trans, &hcmd);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
if (WARN(iwl_rx_packet_payload_len(hcmd.resp_pkt) != sizeof(*rsp),
|
||||
if (WARN(iwl_rx_packet_payload_len(hcmd.resp_pkt) != rsp_size,
|
||||
"Invalid payload len in NVM response from FW %d",
|
||||
iwl_rx_packet_payload_len(hcmd.resp_pkt))) {
|
||||
ret = -EINVAL;
|
||||
@ -1475,11 +1496,15 @@ struct iwl_nvm_data *iwl_get_nvm(struct iwl_trans *trans,
|
||||
sbands_flags |= IWL_NVM_SBANDS_FLAGS_LAR;
|
||||
}
|
||||
|
||||
rsp_v3 = (void *)rsp;
|
||||
channel_profile = v4 ? (void *)rsp->regulatory.channel_profile :
|
||||
(void *)rsp_v3->regulatory.channel_profile;
|
||||
|
||||
iwl_init_sbands(trans->dev, trans->cfg, nvm,
|
||||
rsp->regulatory.channel_profile,
|
||||
nvm->valid_tx_ant & fw->valid_tx_ant,
|
||||
nvm->valid_rx_ant & fw->valid_rx_ant,
|
||||
sbands_flags);
|
||||
sbands_flags, v4);
|
||||
|
||||
iwl_free_resp(&hcmd);
|
||||
return nvm;
|
||||
|
@ -368,6 +368,12 @@
|
||||
#define MON_BUFF_WRPTR_VER2 (0xa03c24)
|
||||
#define MON_BUFF_CYCLE_CNT_VER2 (0xa03c28)
|
||||
#define MON_BUFF_SHIFT_VER2 (0x8)
|
||||
/* FW monitor familiy AX210 and on */
|
||||
#define DBGC_CUR_DBGBUF_BASE_ADDR_LSB (0xd03c20)
|
||||
#define DBGC_CUR_DBGBUF_BASE_ADDR_MSB (0xd03c24)
|
||||
#define DBGC_CUR_DBGBUF_STATUS (0xd03c1c)
|
||||
#define DBGC_DBGBUF_WRAP_AROUND (0xd03c2c)
|
||||
#define DBGC_CUR_DBGBUF_STATUS_OFFSET_MSK (0x00ffffff)
|
||||
|
||||
#define MON_DMARB_RD_CTL_ADDR (0xa03c60)
|
||||
#define MON_DMARB_RD_DATA_ADDR (0xa03c5c)
|
||||
|
@ -274,7 +274,6 @@ struct iwl_rx_cmd_buffer {
|
||||
bool _page_stolen;
|
||||
u32 _rx_page_order;
|
||||
unsigned int truesize;
|
||||
u8 status;
|
||||
};
|
||||
|
||||
static inline void *rxb_addr(struct iwl_rx_cmd_buffer *r)
|
||||
|
@ -8,7 +8,7 @@
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@ -31,7 +31,7 @@
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -1728,9 +1728,12 @@ void iwl_mvm_d0i3_update_keys(struct iwl_mvm *mvm,
|
||||
iwl_mvm_iter_d0i3_ap_keys(mvm, vif, iwl_mvm_d3_update_keys, >kdata);
|
||||
}
|
||||
|
||||
#define ND_QUERY_BUF_LEN (sizeof(struct iwl_scan_offload_profile_match) * \
|
||||
IWL_SCAN_MAX_PROFILES)
|
||||
|
||||
struct iwl_mvm_nd_query_results {
|
||||
u32 matched_profiles;
|
||||
struct iwl_scan_offload_profile_match matches[IWL_SCAN_MAX_PROFILES];
|
||||
u8 matches[ND_QUERY_BUF_LEN];
|
||||
};
|
||||
|
||||
static int
|
||||
@ -1743,6 +1746,7 @@ iwl_mvm_netdetect_query_results(struct iwl_mvm *mvm,
|
||||
.flags = CMD_WANT_SKB,
|
||||
};
|
||||
int ret, len;
|
||||
size_t query_len, matches_len;
|
||||
|
||||
ret = iwl_mvm_send_cmd(mvm, &cmd);
|
||||
if (ret) {
|
||||
@ -1750,8 +1754,19 @@ iwl_mvm_netdetect_query_results(struct iwl_mvm *mvm,
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (fw_has_api(&mvm->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_API_SCAN_OFFLOAD_CHANS)) {
|
||||
query_len = sizeof(struct iwl_scan_offload_profiles_query);
|
||||
matches_len = sizeof(struct iwl_scan_offload_profile_match) *
|
||||
IWL_SCAN_MAX_PROFILES;
|
||||
} else {
|
||||
query_len = sizeof(struct iwl_scan_offload_profiles_query_v1);
|
||||
matches_len = sizeof(struct iwl_scan_offload_profile_match_v1) *
|
||||
IWL_SCAN_MAX_PROFILES;
|
||||
}
|
||||
|
||||
len = iwl_rx_packet_payload_len(cmd.resp_pkt);
|
||||
if (len < sizeof(*query)) {
|
||||
if (len < query_len) {
|
||||
IWL_ERR(mvm, "Invalid scan offload profiles query response!\n");
|
||||
ret = -EIO;
|
||||
goto out_free_resp;
|
||||
@ -1760,7 +1775,7 @@ iwl_mvm_netdetect_query_results(struct iwl_mvm *mvm,
|
||||
query = (void *)cmd.resp_pkt->data;
|
||||
|
||||
results->matched_profiles = le32_to_cpu(query->matched_profiles);
|
||||
memcpy(results->matches, query->matches, sizeof(results->matches));
|
||||
memcpy(results->matches, query->matches, matches_len);
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
mvm->last_netdetect_scans = le32_to_cpu(query->n_scans_done);
|
||||
@ -1771,6 +1786,57 @@ iwl_mvm_netdetect_query_results(struct iwl_mvm *mvm,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int iwl_mvm_query_num_match_chans(struct iwl_mvm *mvm,
|
||||
struct iwl_mvm_nd_query_results *query,
|
||||
int idx)
|
||||
{
|
||||
int n_chans = 0, i;
|
||||
|
||||
if (fw_has_api(&mvm->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_API_SCAN_OFFLOAD_CHANS)) {
|
||||
struct iwl_scan_offload_profile_match *matches =
|
||||
(struct iwl_scan_offload_profile_match *)query->matches;
|
||||
|
||||
for (i = 0; i < SCAN_OFFLOAD_MATCHING_CHANNELS_LEN; i++)
|
||||
n_chans += hweight8(matches[idx].matching_channels[i]);
|
||||
} else {
|
||||
struct iwl_scan_offload_profile_match_v1 *matches =
|
||||
(struct iwl_scan_offload_profile_match_v1 *)query->matches;
|
||||
|
||||
for (i = 0; i < SCAN_OFFLOAD_MATCHING_CHANNELS_LEN_V1; i++)
|
||||
n_chans += hweight8(matches[idx].matching_channels[i]);
|
||||
}
|
||||
|
||||
return n_chans;
|
||||
}
|
||||
|
||||
static void iwl_mvm_query_set_freqs(struct iwl_mvm *mvm,
|
||||
struct iwl_mvm_nd_query_results *query,
|
||||
struct cfg80211_wowlan_nd_match *match,
|
||||
int idx)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (fw_has_api(&mvm->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_API_SCAN_OFFLOAD_CHANS)) {
|
||||
struct iwl_scan_offload_profile_match *matches =
|
||||
(struct iwl_scan_offload_profile_match *)query->matches;
|
||||
|
||||
for (i = 0; i < SCAN_OFFLOAD_MATCHING_CHANNELS_LEN * 8; i++)
|
||||
if (matches[idx].matching_channels[i / 8] & (BIT(i % 8)))
|
||||
match->channels[match->n_channels++] =
|
||||
mvm->nd_channels[i]->center_freq;
|
||||
} else {
|
||||
struct iwl_scan_offload_profile_match_v1 *matches =
|
||||
(struct iwl_scan_offload_profile_match_v1 *)query->matches;
|
||||
|
||||
for (i = 0; i < SCAN_OFFLOAD_MATCHING_CHANNELS_LEN_V1 * 8; i++)
|
||||
if (matches[idx].matching_channels[i / 8] & (BIT(i % 8)))
|
||||
match->channels[match->n_channels++] =
|
||||
mvm->nd_channels[i]->center_freq;
|
||||
}
|
||||
}
|
||||
|
||||
static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
@ -1783,7 +1849,7 @@ static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm,
|
||||
struct iwl_wowlan_status *fw_status;
|
||||
unsigned long matched_profiles;
|
||||
u32 reasons = 0;
|
||||
int i, j, n_matches, ret;
|
||||
int i, n_matches, ret;
|
||||
|
||||
fw_status = iwl_mvm_get_wakeup_status(mvm);
|
||||
if (!IS_ERR_OR_NULL(fw_status)) {
|
||||
@ -1817,14 +1883,10 @@ static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm,
|
||||
goto out_report_nd;
|
||||
|
||||
for_each_set_bit(i, &matched_profiles, mvm->n_nd_match_sets) {
|
||||
struct iwl_scan_offload_profile_match *fw_match;
|
||||
struct cfg80211_wowlan_nd_match *match;
|
||||
int idx, n_channels = 0;
|
||||
|
||||
fw_match = &query.matches[i];
|
||||
|
||||
for (j = 0; j < SCAN_OFFLOAD_MATCHING_CHANNELS_LEN; j++)
|
||||
n_channels += hweight8(fw_match->matching_channels[j]);
|
||||
n_channels = iwl_mvm_query_num_match_chans(mvm, &query, i);
|
||||
|
||||
match = kzalloc(struct_size(match, channels, n_channels),
|
||||
GFP_KERNEL);
|
||||
@ -1844,10 +1906,7 @@ static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm,
|
||||
if (mvm->n_nd_channels < n_channels)
|
||||
continue;
|
||||
|
||||
for (j = 0; j < SCAN_OFFLOAD_MATCHING_CHANNELS_LEN * 8; j++)
|
||||
if (fw_match->matching_channels[j / 8] & (BIT(j % 8)))
|
||||
match->channels[match->n_channels++] =
|
||||
mvm->nd_channels[j]->center_freq;
|
||||
iwl_mvm_query_set_freqs(mvm, &query, match, i);
|
||||
}
|
||||
|
||||
out_report_nd:
|
||||
@ -2030,7 +2089,6 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
|
||||
* 2. We are using a unified image but had an error while exiting D3
|
||||
*/
|
||||
set_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status);
|
||||
set_bit(IWL_MVM_STATUS_D3_RECONFIG, &mvm->status);
|
||||
/*
|
||||
* When switching images we return 1, which causes mac80211
|
||||
* to do a reconfig with IEEE80211_RECONFIG_TYPE_RESTART.
|
||||
|
@ -1349,7 +1349,7 @@ static ssize_t iwl_dbgfs_fw_dbg_collect_write(struct iwl_mvm *mvm,
|
||||
return 0;
|
||||
|
||||
iwl_fw_dbg_collect(&mvm->fwrt, FW_DBG_TRIGGER_USER, buf,
|
||||
(count - 1));
|
||||
(count - 1), NULL);
|
||||
|
||||
iwl_mvm_unref(mvm, IWL_MVM_REF_PRPH_WRITE);
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2015 - 2017 Intel Deutschland GmbH
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@ -31,7 +31,7 @@
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2015 - 2017 Intel Deutschland GmbH
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -1573,6 +1573,7 @@ void iwl_mvm_channel_switch_noa_notif(struct iwl_mvm *mvm,
|
||||
|
||||
rcu_read_lock();
|
||||
vif = rcu_dereference(mvm->vif_id_to_mac[mac_id]);
|
||||
mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
|
||||
switch (vif->type) {
|
||||
case NL80211_IFTYPE_AP:
|
||||
@ -1581,7 +1582,6 @@ void iwl_mvm_channel_switch_noa_notif(struct iwl_mvm *mvm,
|
||||
csa_vif != vif))
|
||||
goto out_unlock;
|
||||
|
||||
mvmvif = iwl_mvm_vif_from_mac80211(csa_vif);
|
||||
csa_id = FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color);
|
||||
if (WARN(csa_id != id_n_color,
|
||||
"channel switch noa notification on unexpected vif (csa_vif=%d, notif=%d)",
|
||||
@ -1602,6 +1602,7 @@ void iwl_mvm_channel_switch_noa_notif(struct iwl_mvm *mvm,
|
||||
return;
|
||||
case NL80211_IFTYPE_STATION:
|
||||
iwl_mvm_csa_client_absent(mvm, vif);
|
||||
cancel_delayed_work_sync(&mvmvif->csa_work);
|
||||
ieee80211_chswitch_done(vif, true);
|
||||
break;
|
||||
default:
|
||||
|
@ -8,7 +8,7 @@
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@ -31,7 +31,7 @@
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -420,6 +420,7 @@ int iwl_mvm_init_fw_regd(struct iwl_mvm *mvm)
|
||||
|
||||
const static u8 he_if_types_ext_capa_sta[] = {
|
||||
[0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING,
|
||||
[2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT,
|
||||
[7] = WLAN_EXT_CAPA8_OPMODE_NOTIF,
|
||||
[9] = WLAN_EXT_CAPA10_TWT_REQUESTER_SUPPORT,
|
||||
};
|
||||
@ -597,6 +598,9 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
|
||||
BIT(NL80211_IFTYPE_ADHOC);
|
||||
|
||||
hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
|
||||
wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
|
||||
hw->wiphy->features |= NL80211_FEATURE_HT_IBSS;
|
||||
|
||||
hw->wiphy->regulatory_flags |= REGULATORY_ENABLE_RELAX_NO_IR;
|
||||
if (iwl_mvm_is_lar_supported(mvm))
|
||||
hw->wiphy->regulatory_flags |= REGULATORY_WIPHY_SELF_MANAGED;
|
||||
@ -732,6 +736,9 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
|
||||
hw->wiphy->iftype_ext_capab = he_iftypes_ext_capa;
|
||||
hw->wiphy->num_iftype_ext_capab =
|
||||
ARRAY_SIZE(he_iftypes_ext_capa);
|
||||
|
||||
ieee80211_hw_set(hw, SUPPORTS_MULTI_BSSID);
|
||||
ieee80211_hw_set(hw, SUPPORTS_ONLY_HE_MULTI_BSSID);
|
||||
}
|
||||
|
||||
mvm->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
|
||||
@ -1191,15 +1198,6 @@ static void iwl_mvm_cleanup_iterator(void *data, u8 *mac,
|
||||
|
||||
static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
|
||||
{
|
||||
/* clear the D3 reconfig, we only need it to avoid dumping a
|
||||
* firmware coredump on reconfiguration, we shouldn't do that
|
||||
* on D3->D0 transition
|
||||
*/
|
||||
if (!test_and_clear_bit(IWL_MVM_STATUS_D3_RECONFIG, &mvm->status)) {
|
||||
mvm->fwrt.dump.desc = &iwl_dump_desc_assert;
|
||||
iwl_fw_error_dump(&mvm->fwrt);
|
||||
}
|
||||
|
||||
/* cleanup all stale references (scan, roc), but keep the
|
||||
* ucode_down ref until reconfig is complete
|
||||
*/
|
||||
@ -1500,6 +1498,91 @@ static int iwl_mvm_set_tx_power(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
return iwl_mvm_send_cmd_pdu(mvm, REDUCE_TX_POWER_CMD, 0, len, &cmd);
|
||||
}
|
||||
|
||||
static int iwl_mvm_post_channel_switch(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
|
||||
int ret;
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
|
||||
if (mvmvif->csa_failed) {
|
||||
mvmvif->csa_failed = false;
|
||||
ret = -EIO;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
if (vif->type == NL80211_IFTYPE_STATION) {
|
||||
struct iwl_mvm_sta *mvmsta;
|
||||
|
||||
mvmvif->csa_bcn_pending = false;
|
||||
mvmsta = iwl_mvm_sta_from_staid_protected(mvm,
|
||||
mvmvif->ap_sta_id);
|
||||
|
||||
if (WARN_ON(!mvmsta)) {
|
||||
ret = -EIO;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
iwl_mvm_sta_modify_disable_tx(mvm, mvmsta, false);
|
||||
|
||||
iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
|
||||
|
||||
ret = iwl_mvm_enable_beacon_filter(mvm, vif, 0);
|
||||
if (ret)
|
||||
goto out_unlock;
|
||||
|
||||
iwl_mvm_stop_session_protection(mvm, vif);
|
||||
}
|
||||
|
||||
mvmvif->ps_disabled = false;
|
||||
|
||||
ret = iwl_mvm_power_update_ps(mvm);
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&mvm->mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void iwl_mvm_abort_channel_switch(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
struct iwl_chan_switch_te_cmd cmd = {
|
||||
.mac_id = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
|
||||
mvmvif->color)),
|
||||
.action = cpu_to_le32(FW_CTXT_ACTION_REMOVE),
|
||||
};
|
||||
|
||||
IWL_DEBUG_MAC80211(mvm, "Abort CSA on mac %d\n", mvmvif->id);
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
WARN_ON(iwl_mvm_send_cmd_pdu(mvm,
|
||||
WIDE_ID(MAC_CONF_GROUP,
|
||||
CHANNEL_SWITCH_TIME_EVENT_CMD),
|
||||
0, sizeof(cmd), &cmd));
|
||||
mutex_unlock(&mvm->mutex);
|
||||
|
||||
WARN_ON(iwl_mvm_post_channel_switch(hw, vif));
|
||||
}
|
||||
|
||||
static void iwl_mvm_channel_switch_disconnect_wk(struct work_struct *wk)
|
||||
{
|
||||
struct iwl_mvm *mvm;
|
||||
struct iwl_mvm_vif *mvmvif;
|
||||
struct ieee80211_vif *vif;
|
||||
|
||||
mvmvif = container_of(wk, struct iwl_mvm_vif, csa_work.work);
|
||||
vif = container_of((void *)mvmvif, struct ieee80211_vif, drv_priv);
|
||||
mvm = mvmvif->mvm;
|
||||
|
||||
iwl_mvm_abort_channel_switch(mvm->hw, vif);
|
||||
ieee80211_chswitch_done(vif, false);
|
||||
}
|
||||
|
||||
static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
@ -1626,6 +1709,8 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
|
||||
}
|
||||
|
||||
iwl_mvm_tcm_add_vif(mvm, vif);
|
||||
INIT_DELAYED_WORK(&mvmvif->csa_work,
|
||||
iwl_mvm_channel_switch_disconnect_wk);
|
||||
|
||||
if (vif->type == NL80211_IFTYPE_MONITOR)
|
||||
mvm->monitor_on = true;
|
||||
@ -2308,7 +2393,11 @@ static void iwl_mvm_cfg_he_sta(struct iwl_mvm *mvm,
|
||||
(vif->bss_conf.uora_ocw_range >> 3) & 0x7;
|
||||
}
|
||||
|
||||
/* TODO: support Multi BSSID IE */
|
||||
if (vif->bss_conf.nontransmitted) {
|
||||
flags |= STA_CTXT_HE_REF_BSSID_VALID;
|
||||
ether_addr_copy(sta_ctxt_cmd.ref_bssid_addr,
|
||||
vif->bss_conf.transmitter_bssid);
|
||||
}
|
||||
|
||||
sta_ctxt_cmd.flags = cpu_to_le32(flags);
|
||||
|
||||
@ -4469,16 +4558,22 @@ static int iwl_mvm_schedule_client_csa(struct iwl_mvm *mvm,
|
||||
.action = cpu_to_le32(FW_CTXT_ACTION_ADD),
|
||||
.tsf = cpu_to_le32(chsw->timestamp),
|
||||
.cs_count = chsw->count,
|
||||
.cs_mode = chsw->block_tx,
|
||||
};
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
if (chsw->delay)
|
||||
cmd.cs_delayed_bcn_count =
|
||||
DIV_ROUND_UP(chsw->delay, vif->bss_conf.beacon_int);
|
||||
|
||||
return iwl_mvm_send_cmd_pdu(mvm,
|
||||
WIDE_ID(MAC_CONF_GROUP,
|
||||
CHANNEL_SWITCH_TIME_EVENT_CMD),
|
||||
0, sizeof(cmd), &cmd);
|
||||
}
|
||||
|
||||
#define IWL_MAX_CSA_BLOCK_TX 1500
|
||||
static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_channel_switch *chsw)
|
||||
@ -4543,8 +4638,18 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw,
|
||||
((vif->bss_conf.beacon_int * (chsw->count - 1) -
|
||||
IWL_MVM_CHANNEL_SWITCH_TIME_CLIENT) * 1024);
|
||||
|
||||
if (chsw->block_tx)
|
||||
if (chsw->block_tx) {
|
||||
iwl_mvm_csa_client_absent(mvm, vif);
|
||||
/*
|
||||
* In case of undetermined / long time with immediate
|
||||
* quiet monitor status to gracefully disconnect
|
||||
*/
|
||||
if (!chsw->count ||
|
||||
chsw->count * vif->bss_conf.beacon_int >
|
||||
IWL_MAX_CSA_BLOCK_TX)
|
||||
schedule_delayed_work(&mvmvif->csa_work,
|
||||
msecs_to_jiffies(IWL_MAX_CSA_BLOCK_TX));
|
||||
}
|
||||
|
||||
if (mvmvif->bf_data.bf_enabled) {
|
||||
ret = iwl_mvm_disable_beacon_filter(mvm, vif, 0);
|
||||
@ -4559,6 +4664,9 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw,
|
||||
iwl_mvm_schedule_csa_period(mvm, vif,
|
||||
vif->bss_conf.beacon_int,
|
||||
apply_time);
|
||||
|
||||
mvmvif->csa_count = chsw->count;
|
||||
mvmvif->csa_misbehave = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -4579,52 +4687,42 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int iwl_mvm_post_channel_switch(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif)
|
||||
static void iwl_mvm_channel_switch_rx_beacon(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_channel_switch *chsw)
|
||||
{
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
|
||||
int ret;
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
struct iwl_chan_switch_te_cmd cmd = {
|
||||
.mac_id = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
|
||||
mvmvif->color)),
|
||||
.action = cpu_to_le32(FW_CTXT_ACTION_MODIFY),
|
||||
.tsf = cpu_to_le32(chsw->timestamp),
|
||||
.cs_count = chsw->count,
|
||||
.cs_mode = chsw->block_tx,
|
||||
};
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_CS_MODIFY))
|
||||
return;
|
||||
|
||||
if (mvmvif->csa_failed) {
|
||||
mvmvif->csa_failed = false;
|
||||
ret = -EIO;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
if (vif->type == NL80211_IFTYPE_STATION) {
|
||||
struct iwl_mvm_sta *mvmsta;
|
||||
|
||||
mvmvif->csa_bcn_pending = false;
|
||||
mvmsta = iwl_mvm_sta_from_staid_protected(mvm,
|
||||
mvmvif->ap_sta_id);
|
||||
|
||||
if (WARN_ON(!mvmsta)) {
|
||||
ret = -EIO;
|
||||
goto out_unlock;
|
||||
if (chsw->count >= mvmvif->csa_count && chsw->block_tx) {
|
||||
if (mvmvif->csa_misbehave) {
|
||||
/* Second time, give up on this AP*/
|
||||
iwl_mvm_abort_channel_switch(hw, vif);
|
||||
ieee80211_chswitch_done(vif, false);
|
||||
mvmvif->csa_misbehave = false;
|
||||
return;
|
||||
}
|
||||
|
||||
iwl_mvm_sta_modify_disable_tx(mvm, mvmsta, false);
|
||||
|
||||
iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
|
||||
|
||||
ret = iwl_mvm_enable_beacon_filter(mvm, vif, 0);
|
||||
if (ret)
|
||||
goto out_unlock;
|
||||
|
||||
iwl_mvm_stop_session_protection(mvm, vif);
|
||||
mvmvif->csa_misbehave = true;
|
||||
}
|
||||
mvmvif->csa_count = chsw->count;
|
||||
|
||||
mvmvif->ps_disabled = false;
|
||||
IWL_DEBUG_MAC80211(mvm, "Modify CSA on mac %d\n", mvmvif->id);
|
||||
|
||||
ret = iwl_mvm_power_update_ps(mvm);
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&mvm->mutex);
|
||||
|
||||
return ret;
|
||||
WARN_ON(iwl_mvm_send_cmd_pdu(mvm,
|
||||
WIDE_ID(MAC_CONF_GROUP,
|
||||
CHANNEL_SWITCH_TIME_EVENT_CMD),
|
||||
CMD_ASYNC, sizeof(cmd), &cmd));
|
||||
}
|
||||
|
||||
static void iwl_mvm_flush_no_vif(struct iwl_mvm *mvm, u32 queues, bool drop)
|
||||
@ -5083,6 +5181,8 @@ const struct ieee80211_ops iwl_mvm_hw_ops = {
|
||||
.channel_switch = iwl_mvm_channel_switch,
|
||||
.pre_channel_switch = iwl_mvm_pre_channel_switch,
|
||||
.post_channel_switch = iwl_mvm_post_channel_switch,
|
||||
.abort_channel_switch = iwl_mvm_abort_channel_switch,
|
||||
.channel_switch_rx_beacon = iwl_mvm_channel_switch_rx_beacon,
|
||||
|
||||
.tdls_channel_switch = iwl_mvm_tdls_channel_switch,
|
||||
.tdls_cancel_channel_switch = iwl_mvm_tdls_cancel_channel_switch,
|
||||
|
@ -8,7 +8,7 @@
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@ -31,7 +31,7 @@
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -490,6 +490,9 @@ struct iwl_mvm_vif {
|
||||
bool csa_countdown;
|
||||
bool csa_failed;
|
||||
u16 csa_target_freq;
|
||||
u16 csa_count;
|
||||
u16 csa_misbehave;
|
||||
struct delayed_work csa_work;
|
||||
|
||||
/* Indicates that we are waiting for a beacon on a new channel */
|
||||
bool csa_bcn_pending;
|
||||
@ -1200,7 +1203,6 @@ struct iwl_mvm {
|
||||
* @IWL_MVM_STATUS_IN_HW_RESTART: HW restart is active
|
||||
* @IWL_MVM_STATUS_IN_D0I3: NIC is in D0i3
|
||||
* @IWL_MVM_STATUS_ROC_AUX_RUNNING: AUX remain-on-channel is running
|
||||
* @IWL_MVM_STATUS_D3_RECONFIG: D3 reconfiguration is being done
|
||||
* @IWL_MVM_STATUS_FIRMWARE_RUNNING: firmware is running
|
||||
* @IWL_MVM_STATUS_NEED_FLUSH_P2P: need to flush P2P bcast STA
|
||||
*/
|
||||
@ -1212,7 +1214,6 @@ enum iwl_mvm_status {
|
||||
IWL_MVM_STATUS_IN_HW_RESTART,
|
||||
IWL_MVM_STATUS_IN_D0I3,
|
||||
IWL_MVM_STATUS_ROC_AUX_RUNNING,
|
||||
IWL_MVM_STATUS_D3_RECONFIG,
|
||||
IWL_MVM_STATUS_FIRMWARE_RUNNING,
|
||||
IWL_MVM_STATUS_NEED_FLUSH_P2P,
|
||||
};
|
||||
@ -1650,8 +1651,8 @@ void iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct napi_struct *napi,
|
||||
struct iwl_rx_cmd_buffer *rxb);
|
||||
void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
|
||||
struct iwl_rx_cmd_buffer *rxb, int queue);
|
||||
void iwl_mvm_rx_monitor_ndp(struct iwl_mvm *mvm, struct napi_struct *napi,
|
||||
struct iwl_rx_cmd_buffer *rxb, int queue);
|
||||
void iwl_mvm_rx_monitor_no_data(struct iwl_mvm *mvm, struct napi_struct *napi,
|
||||
struct iwl_rx_cmd_buffer *rxb, int queue);
|
||||
void iwl_mvm_rx_frame_release(struct iwl_mvm *mvm, struct napi_struct *napi,
|
||||
struct iwl_rx_cmd_buffer *rxb, int queue);
|
||||
int iwl_mvm_notify_rx_queue(struct iwl_mvm *mvm, u32 rxq_mask,
|
||||
@ -2024,17 +2025,6 @@ static inline u32 iwl_mvm_flushable_queues(struct iwl_mvm *mvm)
|
||||
static inline void iwl_mvm_stop_device(struct iwl_mvm *mvm)
|
||||
{
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
/* If IWL_MVM_STATUS_HW_RESTART_REQUESTED bit is set then we received
|
||||
* an assert. Since we failed to bring the interface up, mac80211
|
||||
* will not attempt to reconfig the device,
|
||||
* which handles the dump collection in assert flow,
|
||||
* so trigger dump collection here.
|
||||
*/
|
||||
if (test_and_clear_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED,
|
||||
&mvm->status))
|
||||
iwl_fw_dbg_collect_desc(&mvm->fwrt, &iwl_dump_desc_assert,
|
||||
false, 0);
|
||||
|
||||
iwl_fw_cancel_timestamp(&mvm->fwrt);
|
||||
clear_bit(IWL_MVM_STATUS_FIRMWARE_RUNNING, &mvm->status);
|
||||
iwl_fwrt_stop_device(&mvm->fwrt);
|
||||
|
@ -8,7 +8,7 @@
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@ -31,7 +31,7 @@
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -1105,7 +1105,7 @@ static void iwl_mvm_rx_mq(struct iwl_op_mode *op_mode,
|
||||
else if (cmd == WIDE_ID(LEGACY_GROUP, FRAME_RELEASE))
|
||||
iwl_mvm_rx_frame_release(mvm, napi, rxb, 0);
|
||||
else if (cmd == WIDE_ID(DATA_PATH_GROUP, RX_NO_DATA_NOTIF))
|
||||
iwl_mvm_rx_monitor_ndp(mvm, napi, rxb, 0);
|
||||
iwl_mvm_rx_monitor_no_data(mvm, napi, rxb, 0);
|
||||
else
|
||||
iwl_mvm_rx_common(mvm, rxb, pkt);
|
||||
}
|
||||
@ -1340,6 +1340,8 @@ void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error)
|
||||
}
|
||||
}
|
||||
|
||||
iwl_fw_dbg_collect_desc(&mvm->fwrt, &iwl_dump_desc_assert,
|
||||
false, 0);
|
||||
if (fw_error && mvm->fw_restart > 0)
|
||||
mvm->fw_restart--;
|
||||
set_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status);
|
||||
|
@ -6,7 +6,7 @@
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2017 Intel Deutschland GmbH
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@ -27,7 +27,7 @@
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2017 Intel Deutschland GmbH
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -345,6 +345,37 @@ void iwl_mvm_tlc_update_notif(struct iwl_mvm *mvm,
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
static u16 rs_fw_get_max_amsdu_len(struct ieee80211_sta *sta)
|
||||
{
|
||||
const struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
|
||||
const struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
|
||||
|
||||
if (vht_cap && vht_cap->vht_supported) {
|
||||
switch (vht_cap->cap & IEEE80211_VHT_CAP_MAX_MPDU_MASK) {
|
||||
case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454:
|
||||
return IEEE80211_MAX_MPDU_LEN_VHT_11454;
|
||||
case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991:
|
||||
return IEEE80211_MAX_MPDU_LEN_VHT_7991;
|
||||
default:
|
||||
return IEEE80211_MAX_MPDU_LEN_VHT_3895;
|
||||
}
|
||||
|
||||
} else if (ht_cap && ht_cap->ht_supported) {
|
||||
if (ht_cap->cap & IEEE80211_HT_CAP_MAX_AMSDU)
|
||||
/*
|
||||
* agg is offloaded so we need to assume that agg
|
||||
* are enabled and max mpdu in ampdu is 4095
|
||||
* (spec 802.11-2016 9.3.2.1)
|
||||
*/
|
||||
return IEEE80211_MAX_MPDU_LEN_HT_BA;
|
||||
else
|
||||
return IEEE80211_MAX_MPDU_LEN_HT_3839;
|
||||
}
|
||||
|
||||
/* in legacy mode no amsdu is enabled so return zero */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rs_fw_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||
enum nl80211_band band, bool update)
|
||||
{
|
||||
@ -353,14 +384,15 @@ void rs_fw_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||
struct iwl_lq_sta_rs_fw *lq_sta = &mvmsta->lq_sta.rs_fw;
|
||||
u32 cmd_id = iwl_cmd_id(TLC_MNG_CONFIG_CMD, DATA_PATH_GROUP, 0);
|
||||
struct ieee80211_supported_band *sband;
|
||||
u16 max_amsdu_len = rs_fw_get_max_amsdu_len(sta);
|
||||
struct iwl_tlc_config_cmd cfg_cmd = {
|
||||
.sta_id = mvmsta->sta_id,
|
||||
.max_ch_width = update ?
|
||||
rs_fw_bw_from_sta_bw(sta) : RATE_MCS_CHAN_WIDTH_20,
|
||||
.flags = cpu_to_le16(rs_fw_set_config_flags(mvm, sta)),
|
||||
.chains = rs_fw_set_active_chains(iwl_mvm_get_valid_tx_ant(mvm)),
|
||||
.max_mpdu_len = cpu_to_le16(sta->max_amsdu_len),
|
||||
.sgi_ch_width_supp = rs_fw_sgi_cw_support(sta),
|
||||
.max_mpdu_len = cpu_to_le16(max_amsdu_len),
|
||||
.amsdu = iwl_mvm_is_csum_supported(mvm),
|
||||
};
|
||||
int ret;
|
||||
@ -373,6 +405,12 @@ void rs_fw_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||
sband = hw->wiphy->bands[band];
|
||||
rs_fw_set_supp_rates(sta, sband, &cfg_cmd);
|
||||
|
||||
/*
|
||||
* since TLC offload works with one mode we can assume
|
||||
* that only vht/ht is used and also set it as station max amsdu
|
||||
*/
|
||||
sta->max_amsdu_len = max_amsdu_len;
|
||||
|
||||
ret = iwl_mvm_send_cmd_pdu(mvm, cmd_id, 0, sizeof(cfg_cmd), &cfg_cmd);
|
||||
if (ret)
|
||||
IWL_ERR(mvm, "Failed to send rate scale config (%d)\n", ret);
|
||||
|
@ -8,7 +8,7 @@
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2015 - 2017 Intel Deutschland GmbH
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@ -31,7 +31,7 @@
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2015 - 2017 Intel Deutschland GmbH
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -1679,8 +1679,8 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
void iwl_mvm_rx_monitor_ndp(struct iwl_mvm *mvm, struct napi_struct *napi,
|
||||
struct iwl_rx_cmd_buffer *rxb, int queue)
|
||||
void iwl_mvm_rx_monitor_no_data(struct iwl_mvm *mvm, struct napi_struct *napi,
|
||||
struct iwl_rx_cmd_buffer *rxb, int queue)
|
||||
{
|
||||
struct ieee80211_rx_status *rx_status;
|
||||
struct iwl_rx_packet *pkt = rxb_addr(rxb);
|
||||
@ -1701,10 +1701,6 @@ void iwl_mvm_rx_monitor_ndp(struct iwl_mvm *mvm, struct napi_struct *napi,
|
||||
if (unlikely(test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)))
|
||||
return;
|
||||
|
||||
/* Currently only NDP type is supported */
|
||||
if (info_type != RX_NO_DATA_INFO_TYPE_NDP)
|
||||
return;
|
||||
|
||||
energy_a = (rssi & RX_NO_DATA_CHAIN_A_MSK) >> RX_NO_DATA_CHAIN_A_POS;
|
||||
energy_b = (rssi & RX_NO_DATA_CHAIN_B_MSK) >> RX_NO_DATA_CHAIN_B_POS;
|
||||
channel = (rssi & RX_NO_DATA_CHANNEL_MSK) >> RX_NO_DATA_CHANNEL_POS;
|
||||
@ -1726,9 +1722,22 @@ void iwl_mvm_rx_monitor_ndp(struct iwl_mvm *mvm, struct napi_struct *napi,
|
||||
|
||||
/* 0-length PSDU */
|
||||
rx_status->flag |= RX_FLAG_NO_PSDU;
|
||||
/* currently this is the only type for which we get this notif */
|
||||
rx_status->zero_length_psdu_type =
|
||||
IEEE80211_RADIOTAP_ZERO_LEN_PSDU_SOUNDING;
|
||||
|
||||
switch (info_type) {
|
||||
case RX_NO_DATA_INFO_TYPE_NDP:
|
||||
rx_status->zero_length_psdu_type =
|
||||
IEEE80211_RADIOTAP_ZERO_LEN_PSDU_SOUNDING;
|
||||
break;
|
||||
case RX_NO_DATA_INFO_TYPE_MU_UNMATCHED:
|
||||
case RX_NO_DATA_INFO_TYPE_HE_TB_UNMATCHED:
|
||||
rx_status->zero_length_psdu_type =
|
||||
IEEE80211_RADIOTAP_ZERO_LEN_PSDU_NOT_CAPTURED;
|
||||
break;
|
||||
default:
|
||||
rx_status->zero_length_psdu_type =
|
||||
IEEE80211_RADIOTAP_ZERO_LEN_PSDU_VENDOR;
|
||||
break;
|
||||
}
|
||||
|
||||
/* This may be overridden by iwl_mvm_rx_he() to HE_RU */
|
||||
switch (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK) {
|
||||
|
@ -1082,21 +1082,23 @@ static void iwl_mvm_fill_scan_dwell(struct iwl_mvm *mvm,
|
||||
dwell->extended = IWL_SCAN_DWELL_EXTENDED;
|
||||
}
|
||||
|
||||
static void iwl_mvm_fill_channels(struct iwl_mvm *mvm, u8 *channels)
|
||||
static void iwl_mvm_fill_channels(struct iwl_mvm *mvm, u8 *channels,
|
||||
u32 max_channels)
|
||||
{
|
||||
struct ieee80211_supported_band *band;
|
||||
int i, j = 0;
|
||||
|
||||
band = &mvm->nvm_data->bands[NL80211_BAND_2GHZ];
|
||||
for (i = 0; i < band->n_channels; i++, j++)
|
||||
for (i = 0; i < band->n_channels && j < max_channels; i++, j++)
|
||||
channels[j] = band->channels[i].hw_value;
|
||||
band = &mvm->nvm_data->bands[NL80211_BAND_5GHZ];
|
||||
for (i = 0; i < band->n_channels; i++, j++)
|
||||
for (i = 0; i < band->n_channels && j < max_channels; i++, j++)
|
||||
channels[j] = band->channels[i].hw_value;
|
||||
}
|
||||
|
||||
static void iwl_mvm_fill_scan_config_v1(struct iwl_mvm *mvm, void *config,
|
||||
u32 flags, u8 channel_flags)
|
||||
u32 flags, u8 channel_flags,
|
||||
u32 max_channels)
|
||||
{
|
||||
enum iwl_mvm_scan_type type = iwl_mvm_get_scan_type(mvm, NULL);
|
||||
struct iwl_scan_config_v1 *cfg = config;
|
||||
@ -1115,11 +1117,12 @@ static void iwl_mvm_fill_scan_config_v1(struct iwl_mvm *mvm, void *config,
|
||||
cfg->bcast_sta_id = mvm->aux_sta.sta_id;
|
||||
cfg->channel_flags = channel_flags;
|
||||
|
||||
iwl_mvm_fill_channels(mvm, cfg->channel_array);
|
||||
iwl_mvm_fill_channels(mvm, cfg->channel_array, max_channels);
|
||||
}
|
||||
|
||||
static void iwl_mvm_fill_scan_config(struct iwl_mvm *mvm, void *config,
|
||||
u32 flags, u8 channel_flags)
|
||||
u32 flags, u8 channel_flags,
|
||||
u32 max_channels)
|
||||
{
|
||||
struct iwl_scan_config *cfg = config;
|
||||
|
||||
@ -1162,7 +1165,7 @@ static void iwl_mvm_fill_scan_config(struct iwl_mvm *mvm, void *config,
|
||||
cfg->bcast_sta_id = mvm->aux_sta.sta_id;
|
||||
cfg->channel_flags = channel_flags;
|
||||
|
||||
iwl_mvm_fill_channels(mvm, cfg->channel_array);
|
||||
iwl_mvm_fill_channels(mvm, cfg->channel_array, max_channels);
|
||||
}
|
||||
|
||||
int iwl_mvm_config_scan(struct iwl_mvm *mvm)
|
||||
@ -1181,7 +1184,7 @@ int iwl_mvm_config_scan(struct iwl_mvm *mvm)
|
||||
u8 channel_flags;
|
||||
|
||||
if (WARN_ON(num_channels > mvm->fw->ucode_capa.n_scan_channels))
|
||||
return -ENOBUFS;
|
||||
num_channels = mvm->fw->ucode_capa.n_scan_channels;
|
||||
|
||||
if (iwl_mvm_is_cdb_supported(mvm)) {
|
||||
type = iwl_mvm_get_scan_type_band(mvm, NULL,
|
||||
@ -1234,9 +1237,11 @@ int iwl_mvm_config_scan(struct iwl_mvm *mvm)
|
||||
flags |= (iwl_mvm_is_scan_fragmented(hb_type)) ?
|
||||
SCAN_CONFIG_FLAG_SET_LMAC2_FRAGMENTED :
|
||||
SCAN_CONFIG_FLAG_CLEAR_LMAC2_FRAGMENTED;
|
||||
iwl_mvm_fill_scan_config(mvm, cfg, flags, channel_flags);
|
||||
iwl_mvm_fill_scan_config(mvm, cfg, flags, channel_flags,
|
||||
num_channels);
|
||||
} else {
|
||||
iwl_mvm_fill_scan_config_v1(mvm, cfg, flags, channel_flags);
|
||||
iwl_mvm_fill_scan_config_v1(mvm, cfg, flags, channel_flags,
|
||||
num_channels);
|
||||
}
|
||||
|
||||
cmd.data[0] = cfg;
|
||||
|
@ -8,7 +8,7 @@
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2017 Intel Deutschland GmbH
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@ -31,7 +31,7 @@
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2017 Intel Deutschland GmbH
|
||||
* Copyright(c) 2018 Intel Corporation
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -234,6 +234,7 @@ iwl_mvm_te_handle_notify_csa(struct iwl_mvm *mvm,
|
||||
break;
|
||||
}
|
||||
iwl_mvm_csa_client_absent(mvm, te_data->vif);
|
||||
cancel_delayed_work_sync(&mvmvif->csa_work);
|
||||
ieee80211_chswitch_done(te_data->vif, true);
|
||||
break;
|
||||
default:
|
||||
|
@ -106,7 +106,6 @@ struct iwl_host_cmd;
|
||||
* @page: driver's pointer to the rxb page
|
||||
* @invalid: rxb is in driver ownership - not owned by HW
|
||||
* @vid: index of this rxb in the global table
|
||||
* @size: size used from the buffer
|
||||
*/
|
||||
struct iwl_rx_mem_buffer {
|
||||
dma_addr_t page_dma;
|
||||
@ -114,7 +113,6 @@ struct iwl_rx_mem_buffer {
|
||||
u16 vid;
|
||||
bool invalid;
|
||||
struct list_head list;
|
||||
u32 size;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -135,46 +133,32 @@ struct isr_statistics {
|
||||
u32 unhandled;
|
||||
};
|
||||
|
||||
#define IWL_RX_TD_TYPE_MSK 0xff000000
|
||||
#define IWL_RX_TD_SIZE_MSK 0x00ffffff
|
||||
#define IWL_RX_TD_SIZE_2K BIT(11)
|
||||
#define IWL_RX_TD_TYPE 0
|
||||
|
||||
/**
|
||||
* struct iwl_rx_transfer_desc - transfer descriptor
|
||||
* @type_n_size: buffer type (bit 0: external buff valid,
|
||||
* bit 1: optional footer valid, bit 2-7: reserved)
|
||||
* and buffer size
|
||||
* @addr: ptr to free buffer start address
|
||||
* @rbid: unique tag of the buffer
|
||||
* @reserved: reserved
|
||||
*/
|
||||
struct iwl_rx_transfer_desc {
|
||||
__le32 type_n_size;
|
||||
__le64 addr;
|
||||
__le16 rbid;
|
||||
__le16 reserved;
|
||||
__le16 reserved[3];
|
||||
__le64 addr;
|
||||
} __packed;
|
||||
|
||||
#define IWL_RX_CD_SIZE 0xffffff00
|
||||
#define IWL_RX_CD_FLAGS_FRAGMENTED BIT(0)
|
||||
|
||||
/**
|
||||
* struct iwl_rx_completion_desc - completion descriptor
|
||||
* @type: buffer type (bit 0: external buff valid,
|
||||
* bit 1: optional footer valid, bit 2-7: reserved)
|
||||
* @status: status of the completion
|
||||
* @reserved1: reserved
|
||||
* @rbid: unique tag of the received buffer
|
||||
* @size: buffer size, masked by IWL_RX_CD_SIZE
|
||||
* @flags: flags (0: fragmented, all others: reserved)
|
||||
* @reserved2: reserved
|
||||
*/
|
||||
struct iwl_rx_completion_desc {
|
||||
u8 type;
|
||||
u8 status;
|
||||
__le16 reserved1;
|
||||
__le32 reserved1;
|
||||
__le16 rbid;
|
||||
__le32 size;
|
||||
u8 reserved2[22];
|
||||
u8 flags;
|
||||
u8 reserved2[25];
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
|
@ -282,9 +282,8 @@ static void iwl_pcie_restock_bd(struct iwl_trans *trans,
|
||||
if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) {
|
||||
struct iwl_rx_transfer_desc *bd = rxq->bd;
|
||||
|
||||
bd[rxq->write].type_n_size =
|
||||
cpu_to_le32((IWL_RX_TD_TYPE & IWL_RX_TD_TYPE_MSK) |
|
||||
((IWL_RX_TD_SIZE_2K >> 8) & IWL_RX_TD_SIZE_MSK));
|
||||
BUILD_BUG_ON(sizeof(*bd) != 2 * sizeof(u64));
|
||||
|
||||
bd[rxq->write].addr = cpu_to_le64(rxb->page_dma);
|
||||
bd[rxq->write].rbid = cpu_to_le16(rxb->vid);
|
||||
} else {
|
||||
@ -1265,9 +1264,6 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans,
|
||||
.truesize = max_len,
|
||||
};
|
||||
|
||||
if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560)
|
||||
rxcb.status = rxq->cd[i].status;
|
||||
|
||||
pkt = rxb_addr(&rxcb);
|
||||
|
||||
if (pkt->len_n_flags == cpu_to_le32(FH_RSCSR_FRAME_INVALID)) {
|
||||
@ -1394,6 +1390,8 @@ static struct iwl_rx_mem_buffer *iwl_pcie_get_rxb(struct iwl_trans *trans,
|
||||
struct iwl_rx_mem_buffer *rxb;
|
||||
u16 vid;
|
||||
|
||||
BUILD_BUG_ON(sizeof(struct iwl_rx_completion_desc) != 32);
|
||||
|
||||
if (!trans->cfg->mq_rx_supported) {
|
||||
rxb = rxq->queue[i];
|
||||
rxq->queue[i] = NULL;
|
||||
@ -1415,9 +1413,6 @@ static struct iwl_rx_mem_buffer *iwl_pcie_get_rxb(struct iwl_trans *trans,
|
||||
|
||||
IWL_DEBUG_RX(trans, "Got virtual RB ID %u\n", (u32)rxb->vid);
|
||||
|
||||
if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560)
|
||||
rxb->size = le32_to_cpu(rxq->cd[i].size) & IWL_RX_CD_SIZE;
|
||||
|
||||
rxb->invalid = true;
|
||||
|
||||
return rxb;
|
||||
|
@ -3012,10 +3012,14 @@ static void
|
||||
iwl_trans_pcie_dump_pointers(struct iwl_trans *trans,
|
||||
struct iwl_fw_error_dump_fw_mon *fw_mon_data)
|
||||
{
|
||||
u32 base, write_ptr, wrap_cnt;
|
||||
u32 base, base_high, write_ptr, write_ptr_val, wrap_cnt;
|
||||
|
||||
/* If there was a dest TLV - use the values from there */
|
||||
if (trans->ini_valid) {
|
||||
if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_AX210) {
|
||||
base = DBGC_CUR_DBGBUF_BASE_ADDR_LSB;
|
||||
base_high = DBGC_CUR_DBGBUF_BASE_ADDR_MSB;
|
||||
write_ptr = DBGC_CUR_DBGBUF_STATUS;
|
||||
wrap_cnt = DBGC_DBGBUF_WRAP_AROUND;
|
||||
} else if (trans->ini_valid) {
|
||||
base = iwl_umac_prph(trans, MON_BUFF_BASE_ADDR_VER2);
|
||||
write_ptr = iwl_umac_prph(trans, MON_BUFF_WRPTR_VER2);
|
||||
wrap_cnt = iwl_umac_prph(trans, MON_BUFF_CYCLE_CNT_VER2);
|
||||
@ -3028,12 +3032,18 @@ iwl_trans_pcie_dump_pointers(struct iwl_trans *trans,
|
||||
write_ptr = MON_BUFF_WRPTR;
|
||||
wrap_cnt = MON_BUFF_CYCLE_CNT;
|
||||
}
|
||||
fw_mon_data->fw_mon_wr_ptr =
|
||||
cpu_to_le32(iwl_read_prph(trans, write_ptr));
|
||||
|
||||
write_ptr_val = iwl_read_prph(trans, write_ptr);
|
||||
fw_mon_data->fw_mon_cycle_cnt =
|
||||
cpu_to_le32(iwl_read_prph(trans, wrap_cnt));
|
||||
fw_mon_data->fw_mon_base_ptr =
|
||||
cpu_to_le32(iwl_read_prph(trans, base));
|
||||
if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_AX210) {
|
||||
fw_mon_data->fw_mon_base_high_ptr =
|
||||
cpu_to_le32(iwl_read_prph(trans, base_high));
|
||||
write_ptr_val &= DBGC_CUR_DBGBUF_STATUS_OFFSET_MSK;
|
||||
}
|
||||
fw_mon_data->fw_mon_wr_ptr = cpu_to_le32(write_ptr_val);
|
||||
}
|
||||
|
||||
static u32
|
||||
@ -3044,9 +3054,10 @@ iwl_trans_pcie_dump_monitor(struct iwl_trans *trans,
|
||||
u32 len = 0;
|
||||
|
||||
if ((trans->num_blocks &&
|
||||
trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) ||
|
||||
(trans->dbg_dest_tlv && !trans->ini_valid) ||
|
||||
(trans->ini_valid && trans->num_blocks)) {
|
||||
(trans->cfg->device_family == IWL_DEVICE_FAMILY_7000 ||
|
||||
trans->cfg->device_family >= IWL_DEVICE_FAMILY_AX210 ||
|
||||
trans->ini_valid)) ||
|
||||
(trans->dbg_dest_tlv && !trans->ini_valid)) {
|
||||
struct iwl_fw_error_dump_fw_mon *fw_mon_data;
|
||||
|
||||
(*data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_FW_MONITOR);
|
||||
@ -3165,8 +3176,10 @@ static struct iwl_trans_dump_data
|
||||
len = sizeof(*dump_data);
|
||||
|
||||
/* host commands */
|
||||
len += sizeof(*data) +
|
||||
cmdq->n_window * (sizeof(*txcmd) + TFD_MAX_PAYLOAD_SIZE);
|
||||
if (dump_mask & BIT(IWL_FW_ERROR_DUMP_TXCMD))
|
||||
len += sizeof(*data) +
|
||||
cmdq->n_window * (sizeof(*txcmd) +
|
||||
TFD_MAX_PAYLOAD_SIZE);
|
||||
|
||||
/* FW monitor */
|
||||
if (dump_mask & BIT(IWL_FW_ERROR_DUMP_FW_MONITOR))
|
||||
@ -3539,6 +3552,9 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
|
||||
} else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
|
||||
CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_GF)) {
|
||||
trans->cfg = &iwlax210_2ax_cfg_so_gf_a0;
|
||||
} else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
|
||||
CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_GF4)) {
|
||||
trans->cfg = &iwlax210_2ax_cfg_so_gf4_a0;
|
||||
}
|
||||
} else if (cfg == &iwl_ax101_cfg_qu_hr) {
|
||||
if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
|
||||
|
Loading…
Reference in New Issue
Block a user