From 7fe90e0e3d603844657e8361aa4686c6ee4a8c9d Mon Sep 17 00:00:00 2001 From: Haim Dreyfuss Date: Thu, 30 Mar 2017 11:16:17 +0300 Subject: [PATCH 01/46] iwlwifi: mvm: refactor geo init We are going to add debugfs entry to retrieve the current geographic profile being used in the FW. Currently the driver reads those tables from the BIOS and passes them to the FW. To prepare for this retrieving we want to store those tables in the driver. Signed-off-by: Haim Dreyfuss Signed-off-by: Luca Coelho --- .../wireless/intel/iwlwifi/mvm/fw-api-power.h | 9 +++ drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 64 ++++++++++++++----- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 12 +++- 3 files changed, 67 insertions(+), 18 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-power.h b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-power.h index 9d87fddd29b6..7da57ef2454e 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-power.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-power.h @@ -363,6 +363,7 @@ struct iwl_dev_tx_power_cmd { } __packed; /* TX_REDUCED_POWER_API_S_VER_4 */ #define IWL_NUM_GEO_PROFILES 3 +#define IWL_GEO_PER_CHAIN_SIZE 3 /** * enum iwl_geo_per_chain_offset_operation - type of operation @@ -401,6 +402,14 @@ struct iwl_geo_tx_power_profiles_cmd { struct iwl_per_chain_offset_group table[IWL_NUM_GEO_PROFILES]; } __packed; /* GEO_TX_POWER_LIMIT */ +/** + * struct iwl_geo_tx_power_profiles_resp - response to GEO_TX_POWER_LIMIT cmd + * @profile_idx: current geo profile in use + */ +struct iwl_geo_tx_power_profiles_resp { + __le32 profile_idx; +} __packed; /* GEO_TX_POWER_LIMIT_RESP */ + /** * struct iwl_beacon_filter_cmd * REPLY_BEACON_FILTERING_CMD = 0xd2 (command) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index 24cc406d87ef..273e19460016 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -1243,15 +1243,15 @@ static int iwl_mvm_sar_get_ewrd_table(struct iwl_mvm *mvm) return ret; } -static int iwl_mvm_sar_get_wgds_table(struct iwl_mvm *mvm, - struct iwl_mvm_geo_table *geo_table) +static int iwl_mvm_sar_get_wgds_table(struct iwl_mvm *mvm) { union acpi_object *wifi_pkg; acpi_handle root_handle; acpi_handle handle; struct acpi_buffer wgds = {ACPI_ALLOCATE_BUFFER, NULL}; acpi_status status; - int i, ret; + int i, j, ret; + int idx = 1; root_handle = ACPI_HANDLE(mvm->dev); if (!root_handle) { @@ -1282,15 +1282,17 @@ static int iwl_mvm_sar_get_wgds_table(struct iwl_mvm *mvm, goto out_free; } - for (i = 0; i < ACPI_WGDS_WIFI_DATA_SIZE; i++) { - union acpi_object *entry; + for (i = 0; i < IWL_NUM_GEO_PROFILES; i++) { + for (j = 0; j < IWL_MVM_GEO_TABLE_SIZE; j++) { + union acpi_object *entry; - entry = &wifi_pkg->package.elements[i + 1]; - if ((entry->type != ACPI_TYPE_INTEGER) || - (entry->integer.value > U8_MAX)) - return -EINVAL; + entry = &wifi_pkg->package.elements[idx++]; + if ((entry->type != ACPI_TYPE_INTEGER) || + (entry->integer.value > U8_MAX)) + return -EINVAL; - geo_table->values[i] = entry->integer.value; + mvm->geo_profiles[i].values[j] = entry->integer.value; + } } ret = 0; out_free: @@ -1351,16 +1353,47 @@ int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b) return iwl_mvm_send_cmd_pdu(mvm, REDUCE_TX_POWER_CMD, 0, len, &cmd); } +int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm) +{ + struct iwl_geo_tx_power_profiles_resp *resp; + int ret; + + struct iwl_geo_tx_power_profiles_cmd geo_cmd = { + .ops = cpu_to_le32(IWL_PER_CHAIN_OFFSET_GET_CURRENT_TABLE), + }; + struct iwl_host_cmd cmd = { + .id = WIDE_ID(PHY_OPS_GROUP, GEO_TX_POWER_LIMIT), + .len = { sizeof(geo_cmd), }, + .flags = CMD_WANT_SKB, + .data = { &geo_cmd }, + }; + + ret = iwl_mvm_send_cmd(mvm, &cmd); + if (ret) { + IWL_ERR(mvm, "Failed to get geographic profile info %d\n", ret); + return ret; + } + + resp = (void *)cmd.resp_pkt->data; + ret = le32_to_cpu(resp->profile_idx); + if (WARN_ON(ret > IWL_NUM_GEO_PROFILES)) { + ret = -EIO; + IWL_WARN(mvm, "Invalid geographic profile idx (%d)\n", ret); + } + + iwl_free_resp(&cmd); + return ret; +} + static int iwl_mvm_sar_geo_init(struct iwl_mvm *mvm) { - struct iwl_mvm_geo_table geo_table; struct iwl_geo_tx_power_profiles_cmd cmd = { .ops = cpu_to_le32(IWL_PER_CHAIN_OFFSET_SET_TABLES), }; - int ret, i, j, idx; + int ret, i, j; u16 cmd_wide_id = WIDE_ID(PHY_OPS_GROUP, GEO_TX_POWER_LIMIT); - ret = iwl_mvm_sar_get_wgds_table(mvm, &geo_table); + ret = iwl_mvm_sar_get_wgds_table(mvm); if (ret < 0) { IWL_DEBUG_RADIO(mvm, "Geo SAR BIOS table invalid or unavailable. (%d)\n", @@ -1381,9 +1414,8 @@ static int iwl_mvm_sar_geo_init(struct iwl_mvm *mvm) for (j = 0; j < ACPI_WGDS_NUM_BANDS; j++) { u8 *value; - idx = i * ACPI_WGDS_NUM_BANDS * ACPI_WGDS_TABLE_SIZE + - j * ACPI_WGDS_TABLE_SIZE; - value = &geo_table.values[idx]; + value = &mvm->geo_profiles[i].values[j * + IWL_GEO_PER_CHAIN_SIZE]; chain[j].max_tx_power = cpu_to_le16(value[0]); chain[j].chain_a = value[1]; chain[j].chain_b = value[2]; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 3b1f15873034..9b777b847e22 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -724,14 +724,14 @@ enum iwl_mvm_queue_status { #ifdef CONFIG_ACPI #define IWL_MVM_SAR_TABLE_SIZE 10 #define IWL_MVM_SAR_PROFILE_NUM 4 -#define IWL_MVM_GEO_TABLE_SIZE 18 +#define IWL_MVM_GEO_TABLE_SIZE 6 struct iwl_mvm_sar_profile { bool enabled; u8 table[IWL_MVM_SAR_TABLE_SIZE]; }; -struct iwl_mvm_geo_table { +struct iwl_mvm_geo_profile { u8 values[IWL_MVM_GEO_TABLE_SIZE]; }; #endif @@ -1071,6 +1071,7 @@ struct iwl_mvm { struct delayed_work cs_tx_unblock_dwork; #ifdef CONFIG_ACPI struct iwl_mvm_sar_profile sar_profiles[IWL_MVM_SAR_PROFILE_NUM]; + struct iwl_mvm_geo_profile geo_profiles[IWL_NUM_GEO_PROFILES]; #endif }; @@ -1889,12 +1890,19 @@ bool iwl_mvm_lqm_active(struct iwl_mvm *mvm); #ifdef CONFIG_ACPI int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b); +int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm); #else static inline int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b) { return -ENOENT; } + +static inline +int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm) +{ + return -ENOENT; +} #endif /* CONFIG_ACPI */ #endif /* __IWL_MVM_H__ */ From e6ee06575bb71ae96d936b2279fc827b82f98353 Mon Sep 17 00:00:00 2001 From: Haim Dreyfuss Date: Mon, 15 May 2017 14:27:21 +0300 Subject: [PATCH 02/46] iwlwifi: mvm: Add debugfs entry to retrieve SAR geographic profile Add a debugfs entry to get a verbose description of the power settings used in each band with the currently selected SAR geographic profile. Signed-off-by: Haim Dreyfuss Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/mvm/debugfs.c | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c index c2a1aeef74ec..c3ab13ee4097 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c @@ -336,6 +336,49 @@ static ssize_t iwl_dbgfs_nic_temp_read(struct file *file, return simple_read_from_buffer(user_buf, count, ppos, buf, pos); } +#ifdef CONFIG_ACPI +static ssize_t iwl_dbgfs_sar_geo_profile_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_mvm *mvm = file->private_data; + char buf[256]; + int pos = 0; + int bufsz = sizeof(buf); + int tbl_idx; + u8 *value; + + if (!iwl_mvm_firmware_running(mvm)) + return -EIO; + + mutex_lock(&mvm->mutex); + tbl_idx = iwl_mvm_get_sar_geo_profile(mvm); + if (tbl_idx < 0) { + mutex_unlock(&mvm->mutex); + return tbl_idx; + } + + if (!tbl_idx) { + pos = scnprintf(buf, bufsz, + "SAR geographic profile disabled\n"); + } else { + value = &mvm->geo_profiles[tbl_idx - 1].values[0]; + + pos += scnprintf(buf + pos, bufsz - pos, + "Use geographic profile %d\n", tbl_idx); + pos += scnprintf(buf + pos, bufsz - pos, + "2.4GHz:\n\tChain A offset: %hhd dBm\n\tChain B offset: %hhd dBm\n\tmax tx power: %hhd dBm\n", + value[1], value[2], value[0]); + pos += scnprintf(buf + pos, bufsz - pos, + "5.2GHz:\n\tChain A offset: %hhd dBm\n\tChain B offset: %hhd dBm\n\tmax tx power: %hhd dBm\n", + value[4], value[5], value[3]); + } + mutex_unlock(&mvm->mutex); + + return simple_read_from_buffer(user_buf, count, ppos, buf, pos); +} +#endif + static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { @@ -1572,6 +1615,9 @@ MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters_macs, 256); #ifdef CONFIG_PM_SLEEP MVM_DEBUGFS_READ_WRITE_FILE_OPS(d3_sram, 8); #endif +#ifdef CONFIG_ACPI +MVM_DEBUGFS_READ_FILE_OPS(sar_geo_profile); +#endif static ssize_t iwl_dbgfs_mem_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) @@ -1744,6 +1790,10 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) MVM_DEBUGFS_ADD_FILE(cont_recording, mvm->debugfs_dir, S_IWUSR); MVM_DEBUGFS_ADD_FILE(indirection_tbl, mvm->debugfs_dir, S_IWUSR); MVM_DEBUGFS_ADD_FILE(inject_packet, mvm->debugfs_dir, S_IWUSR); +#ifdef CONFIG_ACPI + MVM_DEBUGFS_ADD_FILE(sar_geo_profile, dbgfs_dir, S_IRUSR); +#endif + if (!debugfs_create_bool("enable_scan_iteration_notif", S_IRUSR | S_IWUSR, mvm->debugfs_dir, From 1644be9189c962cfd064d6b21af16f26f219a146 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 16 May 2017 13:21:52 +0200 Subject: [PATCH 03/46] iwlwifi: mvm: remove some CamelCase from firmware API Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/fw-api-d3.h | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-d3.h b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-d3.h index edde49202786..3463d1c577e8 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-d3.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-d3.h @@ -164,7 +164,7 @@ struct iwl_proto_offload_cmd_v2 { u8 solicited_node_ipv6_addr[16]; u8 target_ipv6_addr[IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V2][16]; u8 ndp_mac_addr[ETH_ALEN]; - u8 numValidIPv6Addresses; + u8 num_valid_ipv6_addrs; u8 reserved2[3]; } __packed; /* PROT_OFFLOAD_CONFIG_CMD_DB_S_VER_2 */ diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h index b84e8ddbbbc9..7588b93f835a 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h @@ -1748,8 +1748,8 @@ enum iwl_mvm_marker_id { * @metadata: additional meta data that will be written to the unsiffer log */ struct iwl_mvm_marker { - u8 dwLen; - u8 markerId; + u8 dw_len; + u8 marker_id; __le16 reserved; __le64 timestamp; __le32 metadata[0]; From 83b0319abc5c8bfb16c5fe3063a04de1402f9b21 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 16 May 2017 13:28:53 +0200 Subject: [PATCH 04/46] iwlwifi: mvm: fix various "Excess ... description" kernel-doc warnings Fix various "Excess struct/union/enum/typedef member '...' description in '...'" warnings from kernel-doc, mostly caused by typos. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/fw-api-d3.h | 4 ++-- drivers/net/wireless/intel/iwlwifi/mvm/fw-api-mac.h | 3 +-- drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rx.h | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/fw-api-scan.h | 8 ++++---- drivers/net/wireless/intel/iwlwifi/mvm/fw-api-tx.h | 1 - drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h | 5 ++--- 6 files changed, 10 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-d3.h b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-d3.h index 3463d1c577e8..2bfe4de6ac5a 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-d3.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-d3.h @@ -183,7 +183,7 @@ struct iwl_targ_addr { /** * struct iwl_proto_offload_cmd_v3_small - ARP/NS offload configuration * @common: common/IPv4 configuration - * @target_ipv6_addr: target IPv6 addresses + * @targ_addrs: target IPv6 addresses * @ns_config: NS offload configurations */ struct iwl_proto_offload_cmd_v3_small { @@ -196,7 +196,7 @@ struct iwl_proto_offload_cmd_v3_small { /** * struct iwl_proto_offload_cmd_v3_large - ARP/NS offload configuration * @common: common/IPv4 configuration - * @target_ipv6_addr: target IPv6 addresses + * @targ_addrs: target IPv6 addresses * @ns_config: NS offload configurations */ struct iwl_proto_offload_cmd_v3_large { diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-mac.h b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-mac.h index 1d970bf0d735..932adaf575eb 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-mac.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-mac.h @@ -331,7 +331,7 @@ struct iwl_ac_qos { * @id_and_color: ID and color of the MAC * @action: action to perform, one of FW_CTXT_ACTION_* * @mac_type: one of &enum iwl_mac_types - * @tsd_id: TSF HW timer, one of &enum iwl_tsf_id + * @tsf_id: TSF HW timer, one of &enum iwl_tsf_id * @node_addr: MAC address * @bssid_addr: BSSID * @cck_rates: basic rates available for CCK @@ -342,7 +342,6 @@ struct iwl_ac_qos { * @filter_flags: combination of &enum iwl_mac_filter_flags * @qos_flags: from &enum iwl_mac_qos_flags * @ac: one iwl_mac_qos configuration for each AC - * @mac_specific: one of struct iwl_mac_data_*, according to mac_type */ struct iwl_mac_ctx_cmd { /* COMMON_INDEX_HDR_API_S_VER_1 */ diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rx.h b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rx.h index ad7ab6dd86cb..02c321738e1e 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rx.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rx.h @@ -96,7 +96,7 @@ enum iwl_mac_context_info { * @beacon_time_stamp: beacon at on-air rise * @phy_flags: general phy flags: band, modulation, ... * @channel: channel number - * @non_cfg_phy_buf: for various implementations of non_cfg_phy + * @non_cfg_phy: for various implementations of non_cfg_phy * @rate_n_flags: RATE_MCS_* * @byte_count: frame's byte-count * @frame_time: frame's time on the air, based on byte count and frame rate diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-scan.h index f8e92026bdc6..e752359841b8 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-scan.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-scan.h @@ -137,7 +137,7 @@ enum iwl_scan_offload_band_selection { * struct iwl_scan_offload_profile - SCAN_OFFLOAD_PROFILE_S * @ssid_index: index to ssid list in fixed part * @unicast_cipher: encryption algorithm to match - bitmap - * @aut_alg: authentication algorithm to match - bitmap + * @auth_alg: authentication algorithm to match - bitmap * @network_type: enum iwl_scan_offload_network_type * @band_selection: enum iwl_scan_offload_band_selection * @client_bitmap: clients waiting for match - enum scan_framework_client @@ -221,7 +221,7 @@ enum iwl_scan_channel_flags_lmac { * struct iwl_scan_channel_cfg_lmac - SCAN_CHANNEL_CFG_S_VER2 * @flags: bits 1-20: directed scan to i'th ssid * other bits &enum iwl_scan_channel_flags_lmac - * @channel_number: channel number 1-13 etc + * @channel_num: channel number 1-13 etc * @iter_count: scan iteration on this channel * @iter_interval: interval in seconds between iterations on one channel */ @@ -320,13 +320,13 @@ enum iwl_scan_priority_ext { /** * struct iwl_scan_req_lmac - SCAN_REQUEST_CMD_API_S_VER_1 * @reserved1: for alignment and future use - * @channel_num: num of channels to scan + * @n_channels: num of channels to scan * @active-dwell: dwell time for active channels * @passive-dwell: dwell time for passive channels * @fragmented-dwell: dwell time for fragmented passive scan * @extended_dwell: dwell time for channels 1, 6 and 11 (in certain cases) * @reserved2: for alignment and future use - * @rx_chain_selct: PHY_RX_CHAIN_* flags + * @rx_chain_select: PHY_RX_CHAIN_* flags * @scan_flags: &enum iwl_mvm_lmac_scan_flags * @max_out_time: max time (in TU) to be out of associated channel * @suspend_time: pause scan this long (TUs) when returning to service channel diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-tx.h b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-tx.h index a37c584b0b48..4a6b919f13de 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-tx.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-tx.h @@ -537,7 +537,6 @@ struct agg_tx_status { * @tlc_info: TLC rate info * @ra_tid: bits [3:0] = ra, bits [7:4] = tid * @frame_ctrl: frame control - * @tx_queue: TX queue for this response * @status: for non-agg: frame status TX_STATUS_* * for agg: status of 1st frame, AGG_TX_STATE_*; other frame status fields * follow this one, up to frame_count. Length in @frame_count. diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h index 7588b93f835a..612546334545 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h @@ -2184,7 +2184,7 @@ enum iwl_tdls_channel_switch_type { * 200TU and the TDLS peer is to be given 25% of the time, the value * given will be 50TU, or 50 * 1024 if translated into microseconds. * @switch_time: switch time the peer sent in its channel switch timing IE - * @switch_timout: switch timeout the peer sent in its channel switch timing IE + * @switch_timeout: switch timeout the peer sent in its channel switch timing IE */ struct iwl_tdls_channel_switch_timing { __le32 frame_timestamp; /* GP2 time of peer packet Rx */ @@ -2456,7 +2456,7 @@ enum iwl_lqm_status { /** * struct iwl_link_qual_msrmnt_cmd - Link Quality Measurement command - * @cmd_operatrion: command operation to be performed (start or stop) + * @cmd_operation: command operation to be performed (start or stop) * as defined above. * @mac_id: MAC ID the measurement applies to. * @measurement_time: time of the total measurement to be performed, in uSec. @@ -2633,7 +2633,6 @@ struct iwl_nvm_get_info_phy { * struct iwl_nvm_get_info_regulatory - regulatory information * @lar_enabled: is LAR enabled * @channel_profile: regulatory data of this channel - * @regulatory: regulatory data, see &enum iwl_nvm_channel_flags for data */ struct iwl_nvm_get_info_regulatory { __le32 lar_enabled; From 40e07545d1bb9be2c37140a4d40df1339a4ed51d Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 16 May 2017 14:33:41 +0200 Subject: [PATCH 05/46] iwlwifi: mvm: remove various unused command IDs/structs Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/mvm/fw-api.h | 28 ------------------- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 11 -------- 2 files changed, 39 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h index 612546334545..60f86997f8cf 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h @@ -295,7 +295,6 @@ enum iwl_legacy_cmds { HOT_SPOT_CMD = 0x53, SCAN_OFFLOAD_COMPLETE = 0x6D, SCAN_OFFLOAD_UPDATE_PROFILES_CMD = 0x6E, - SCAN_OFFLOAD_CONFIG_CMD = 0x6f, MATCH_FOUND_NOTIFICATION = 0xd9, SCAN_ITERATION_COMPLETE = 0xe7, @@ -329,8 +328,6 @@ enum iwl_legacy_cmds { */ NVM_ACCESS_CMD = 0x88, - SET_CALIB_DEFAULT_CMD = 0x8e, - BEACON_NOTIFICATION = 0x90, /** * @BEACON_TEMPLATE_CMD: @@ -364,8 +361,6 @@ enum iwl_legacy_cmds { */ REDUCE_TX_POWER_CMD = 0x9f, - /* RF-KILL commands and notifications */ - CARD_STATE_CMD = 0xa0, CARD_STATE_NOTIFICATION = 0xa1, MISSED_BEACONS_NOTIFICATION = 0xa2, @@ -411,9 +406,6 @@ enum iwl_legacy_cmds { MARKER_CMD = 0xcb, - /* BT Coex */ - BT_COEX_PRIO_TABLE = 0xcc, - BT_COEX_PROT_ENV = 0xcd, /** * @BT_PROFILE_NOTIFICATION: &struct iwl_bt_coex_profile_notif */ @@ -422,7 +414,6 @@ enum iwl_legacy_cmds { * @BT_CONFIG: &struct iwl_bt_coex_cmd */ BT_CONFIG = 0x9b, - BT_COEX_UPDATE_SW_BOOST = 0x5a, BT_COEX_UPDATE_CORUN_LUT = 0x5b, BT_COEX_UPDATE_REDUCED_TXP = 0x5c, /** @@ -439,11 +430,8 @@ enum iwl_legacy_cmds { */ REPLY_BEACON_FILTERING_CMD = 0xd2, - /* DTS measurements */ - CMD_DTS_MEASUREMENT_TRIGGER = 0xdc, DTS_MEASUREMENT_NOTIFICATION = 0xdd, - REPLY_DEBUG_CMD = 0xf0, LDBG_CONFIG_CMD = 0xf6, DEBUG_LOG_MSG = 0xf7, @@ -484,12 +472,9 @@ enum iwl_legacy_cmds { * @WOWLAN_GET_STATUSES: response in &struct iwl_wowlan_status */ WOWLAN_GET_STATUSES = 0xe5, - WOWLAN_TX_POWER_PER_DB = 0xe6, /* and for NetDetect */ SCAN_OFFLOAD_PROFILES_QUERY_CMD = 0x56, - SCAN_OFFLOAD_HOTSPOTS_CONFIG_CMD = 0x58, - SCAN_OFFLOAD_HOTSPOTS_QUERY_CMD = 0x59, }; /* Please keep this enum *SORTED* by hex value. @@ -1580,19 +1565,6 @@ struct iwl_mfu_assert_dump_notif { __le32 data[0]; } __packed; /*MFU_DUMP_ASSERT_API_S_VER_1*/ -/** - * struct iwl_set_calib_default_cmd - set default value for calibration. - * ( SET_CALIB_DEFAULT_CMD = 0x8e ) - * @calib_index: the calibration to set value for - * @length: of data - * @data: the value to set for the calibration result - */ -struct iwl_set_calib_default_cmd { - __le16 calib_index; - __le16 length; - u8 data[0]; -} __packed; /* PHY_CALIB_OVERRIDE_VALUES_S */ - #define MAX_PORT_ID_NUM 2 #define MAX_MCAST_FILTERING_ADDRESSES 256 diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 2e4bfe9f07ec..695d1aead89f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -357,9 +357,6 @@ static const struct iwl_hcmd_names iwl_mvm_legacy_names[] = { HCMD_NAME(SCAN_OFFLOAD_ABORT_CMD), HCMD_NAME(HOT_SPOT_CMD), HCMD_NAME(SCAN_OFFLOAD_PROFILES_QUERY_CMD), - HCMD_NAME(SCAN_OFFLOAD_HOTSPOTS_CONFIG_CMD), - HCMD_NAME(SCAN_OFFLOAD_HOTSPOTS_QUERY_CMD), - HCMD_NAME(BT_COEX_UPDATE_SW_BOOST), HCMD_NAME(BT_COEX_UPDATE_CORUN_LUT), HCMD_NAME(BT_COEX_UPDATE_REDUCED_TXP), HCMD_NAME(BT_COEX_CI), @@ -368,13 +365,11 @@ static const struct iwl_hcmd_names iwl_mvm_legacy_names[] = { HCMD_NAME(PHY_DB_CMD), HCMD_NAME(SCAN_OFFLOAD_COMPLETE), HCMD_NAME(SCAN_OFFLOAD_UPDATE_PROFILES_CMD), - HCMD_NAME(SCAN_OFFLOAD_CONFIG_CMD), HCMD_NAME(POWER_TABLE_CMD), HCMD_NAME(PSM_UAPSD_AP_MISBEHAVING_NOTIFICATION), HCMD_NAME(REPLY_THERMAL_MNG_BACKOFF), HCMD_NAME(DC2DC_CONFIG_CMD), HCMD_NAME(NVM_ACCESS_CMD), - HCMD_NAME(SET_CALIB_DEFAULT_CMD), HCMD_NAME(BEACON_NOTIFICATION), HCMD_NAME(BEACON_TEMPLATE_CMD), HCMD_NAME(TX_ANT_CONFIGURATION_CMD), @@ -383,7 +378,6 @@ static const struct iwl_hcmd_names iwl_mvm_legacy_names[] = { HCMD_NAME(STATISTICS_NOTIFICATION), HCMD_NAME(EOSP_NOTIFICATION), HCMD_NAME(REDUCE_TX_POWER_CMD), - HCMD_NAME(CARD_STATE_CMD), HCMD_NAME(CARD_STATE_NOTIFICATION), HCMD_NAME(MISSED_BEACONS_NOTIFICATION), HCMD_NAME(TDLS_CONFIG_CMD), @@ -398,8 +392,6 @@ static const struct iwl_hcmd_names iwl_mvm_legacy_names[] = { HCMD_NAME(MCC_UPDATE_CMD), HCMD_NAME(MCC_CHUB_UPDATE_CMD), HCMD_NAME(MARKER_CMD), - HCMD_NAME(BT_COEX_PRIO_TABLE), - HCMD_NAME(BT_COEX_PROT_ENV), HCMD_NAME(BT_PROFILE_NOTIFICATION), HCMD_NAME(BCAST_FILTER_CMD), HCMD_NAME(MCAST_FILTER_CMD), @@ -410,7 +402,6 @@ static const struct iwl_hcmd_names iwl_mvm_legacy_names[] = { HCMD_NAME(OFFLOADS_QUERY_CMD), HCMD_NAME(REMOTE_WAKE_CONFIG_CMD), HCMD_NAME(MATCH_FOUND_NOTIFICATION), - HCMD_NAME(CMD_DTS_MEASUREMENT_TRIGGER), HCMD_NAME(DTS_MEASUREMENT_NOTIFICATION), HCMD_NAME(WOWLAN_PATTERNS), HCMD_NAME(WOWLAN_CONFIGURATION), @@ -418,11 +409,9 @@ static const struct iwl_hcmd_names iwl_mvm_legacy_names[] = { HCMD_NAME(WOWLAN_TKIP_PARAM), HCMD_NAME(WOWLAN_KEK_KCK_MATERIAL), HCMD_NAME(WOWLAN_GET_STATUSES), - HCMD_NAME(WOWLAN_TX_POWER_PER_DB), HCMD_NAME(SCAN_ITERATION_COMPLETE), HCMD_NAME(D0I3_END_CMD), HCMD_NAME(LTR_CONFIG), - HCMD_NAME(REPLY_DEBUG_CMD), }; /* Please keep this array *SORTED* by hex value. From cecb43c7b5e68924a57e09bba9290907defc2308 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 16 May 2017 15:12:14 +0200 Subject: [PATCH 06/46] iwlwifi: mvm: use __le16 even for reserved fields Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rx.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rx.h b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rx.h index 02c321738e1e..39b6f592a004 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rx.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rx.h @@ -569,7 +569,7 @@ struct iwl_mvm_pm_state_notification { u8 sta_id; u8 type; /* private: */ - u16 reserved; + __le16 reserved; } __packed; /* PEER_PM_NTFY_API_S_VER_1 */ #endif /* __fw_api_rx_h__ */ From 358631bf444547d476476cb90c8fc78962a81884 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 16 May 2017 15:14:19 +0200 Subject: [PATCH 07/46] iwlwifi: mvm: add documentation for all command IDs Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/iwl-fw-api.h | 24 ++ .../net/wireless/intel/iwlwifi/iwl-phy-db.c | 18 -- .../wireless/intel/iwlwifi/mvm/fw-api-tx.h | 1 + .../net/wireless/intel/iwlwifi/mvm/fw-api.h | 276 +++++++++++++++++- 4 files changed, 292 insertions(+), 27 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-fw-api.h b/drivers/net/wireless/intel/iwlwifi/iwl-fw-api.h index a004409fa984..0e107f916ce3 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-fw-api.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-fw-api.h @@ -202,4 +202,28 @@ struct iwl_tx_queue_cfg_rsp { __le16 reserved; } __packed; /* TX_QUEUE_CFG_RSP_API_S_VER_2 */ +/** + * struct iwl_calib_res_notif_phy_db - Receive phy db chunk after calibrations + * @type: type of the result - mostly ignored + * @length: length of the data + * @data: data, length in @length + */ +struct iwl_calib_res_notif_phy_db { + __le16 type; + __le16 length; + u8 data[]; +} __packed; + +/** + * struct iwl_phy_db_cmd - configure operational ucode + * @type: type of the data + * @length: length of the data + * @data: data, length in @length + */ +struct iwl_phy_db_cmd { + __le16 type; + __le16 length; + u8 data[]; +} __packed; + #endif /* __iwl_fw_api_h__*/ diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-phy-db.c b/drivers/net/wireless/intel/iwlwifi/iwl-phy-db.c index 2893826d7d2b..b7cd813ba70f 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-phy-db.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-phy-db.c @@ -112,30 +112,12 @@ enum iwl_phy_db_section_type { #define PHY_DB_CMD 0x6c -/* - * phy db - configure operational ucode - */ -struct iwl_phy_db_cmd { - __le16 type; - __le16 length; - u8 data[]; -} __packed; - /* for parsing of tx power channel group data that comes from the firmware*/ struct iwl_phy_db_chg_txp { __le32 space; __le16 max_channel_idx; } __packed; -/* - * phy db - Receive phy db chunk after calibrations - */ -struct iwl_calib_res_notif_phy_db { - __le16 type; - __le16 length; - u8 data[]; -} __packed; - struct iwl_phy_db *iwl_phy_db_init(struct iwl_trans *trans) { struct iwl_phy_db *phy_db = kzalloc(sizeof(struct iwl_phy_db), diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-tx.h b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-tx.h index 4a6b919f13de..9d2a991221cf 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-tx.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-tx.h @@ -595,6 +595,7 @@ struct iwl_mvm_tx_resp_v3 { * @ra_tid: bits [3:0] = ra, bits [7:4] = tid * @frame_ctrl: frame control * @tx_queue: TX queue for this response + * @reserved2: reserved for padding/alignment * @status: for non-agg: frame status TX_STATUS_* * For version 6 TX response isn't received for aggregation at all. * diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h index 60f86997f8cf..89e5ba3f4e42 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h @@ -185,7 +185,15 @@ enum iwl_legacy_cmds { * uses &struct iwl_scan_config_v1 or &struct iwl_scan_config */ SCAN_CFG_CMD = 0xc, + + /** + * @SCAN_REQ_UMAC: uses &struct iwl_scan_req_umac + */ SCAN_REQ_UMAC = 0xd, + + /** + * @SCAN_ABORT_UMAC: uses &struct iwl_umac_scan_abort + */ SCAN_ABORT_UMAC = 0xe, /** @@ -193,6 +201,10 @@ enum iwl_legacy_cmds { */ SCAN_COMPLETE_UMAC = 0xf, + /** + * @BA_WINDOW_STATUS_NOTIFICATION_ID: + * uses &struct iwl_ba_window_status_notif + */ BA_WINDOW_STATUS_NOTIFICATION_ID = 0x13, /** @@ -207,12 +219,15 @@ enum iwl_legacy_cmds { * &struct iwl_mvm_add_sta_cmd or &struct iwl_mvm_add_sta_cmd_v7. */ ADD_STA = 0x18, + /** * @REMOVE_STA: &struct iwl_mvm_rm_sta_cmd */ REMOVE_STA = 0x19, - /* paging get item */ + /** + * @FW_GET_ITEM_CMD: uses &struct iwl_fw_get_item_cmd + */ FW_GET_ITEM_CMD = 0x1a, /** @@ -242,15 +257,33 @@ enum iwl_legacy_cmds { */ SCD_QUEUE_CFG = 0x1d, - /* global key */ + /** + * @WEP_KEY: uses &struct iwl_mvm_wep_key_cmd + */ WEP_KEY = 0x20, - /* Memory */ + /** + * @SHARED_MEM_CFG: + * retrieve shared memory configuration - response in + * &struct iwl_shared_mem_cfg + */ SHARED_MEM_CFG = 0x25, - /* TDLS */ + /** + * @TDLS_CHANNEL_SWITCH_CMD: uses &struct iwl_tdls_channel_switch_cmd + */ TDLS_CHANNEL_SWITCH_CMD = 0x27, + + /** + * @TDLS_CHANNEL_SWITCH_NOTIFICATION: + * uses &struct iwl_tdls_channel_switch_notif + */ TDLS_CHANNEL_SWITCH_NOTIFICATION = 0xaa, + + /** + * @TDLS_CONFIG_CMD: + * &struct iwl_tdls_config_cmd, response in &struct iwl_tdls_config_res + */ TDLS_CONFIG_CMD = 0xa7, /** @@ -263,19 +296,27 @@ enum iwl_legacy_cmds { * &struct iwl_time_event_cmd, response in &struct iwl_time_event_resp */ TIME_EVENT_CMD = 0x29, /* both CMD and response */ + /** * @TIME_EVENT_NOTIFICATION: &struct iwl_time_event_notif */ TIME_EVENT_NOTIFICATION = 0x2a, + /** * @BINDING_CONTEXT_CMD: * &struct iwl_binding_cmd or &struct iwl_binding_cmd_v1 */ BINDING_CONTEXT_CMD = 0x2b, + /** * @TIME_QUOTA_CMD: &struct iwl_time_quota_cmd */ TIME_QUOTA_CMD = 0x2c, + + /** + * @NON_QOS_TX_COUNTER_CMD: + * command is &struct iwl_nonqos_seq_query_cmd + */ NON_QOS_TX_COUNTER_CMD = 0x2d, /** @@ -289,13 +330,42 @@ enum iwl_legacy_cmds { */ FW_PAGING_BLOCK_CMD = 0x4f, - /* Scan offload */ + /** + * @SCAN_OFFLOAD_REQUEST_CMD: uses &struct iwl_scan_req_lmac + */ SCAN_OFFLOAD_REQUEST_CMD = 0x51, + + /** + * @SCAN_OFFLOAD_ABORT_CMD: abort the scan - no further contents + */ SCAN_OFFLOAD_ABORT_CMD = 0x52, + + /** + * @HOT_SPOT_CMD: uses &struct iwl_hs20_roc_req + */ HOT_SPOT_CMD = 0x53, + + /** + * @SCAN_OFFLOAD_COMPLETE: + * notification, &struct iwl_periodic_scan_complete + */ SCAN_OFFLOAD_COMPLETE = 0x6D, + + /** + * @SCAN_OFFLOAD_UPDATE_PROFILES_CMD: + * update scan offload (scheduled scan) profiles/blacklist/etc. + */ SCAN_OFFLOAD_UPDATE_PROFILES_CMD = 0x6E, + + /** + * @MATCH_FOUND_NOTIFICATION: scan match found + */ MATCH_FOUND_NOTIFICATION = 0xd9, + + /** + * @SCAN_ITERATION_COMPLETE: + * uses &struct iwl_lmac_scan_complete_notif + */ SCAN_ITERATION_COMPLETE = 0xe7, /* Phy */ @@ -303,24 +373,55 @@ enum iwl_legacy_cmds { * @PHY_CONFIGURATION_CMD: &struct iwl_phy_cfg_cmd */ PHY_CONFIGURATION_CMD = 0x6a, + + /** + * @CALIB_RES_NOTIF_PHY_DB: &struct iwl_calib_res_notif_phy_db + */ CALIB_RES_NOTIF_PHY_DB = 0x6b, + + /** + * @PHY_DB_CMD: &struct iwl_phy_db_cmd + */ PHY_DB_CMD = 0x6c, - /* ToF - 802.11mc FTM */ + /** + * @TOF_CMD: &struct iwl_tof_config_cmd + */ TOF_CMD = 0x10, + + /** + * @TOF_NOTIFICATION: &struct iwl_tof_gen_resp_cmd + */ TOF_NOTIFICATION = 0x11, /** * @POWER_TABLE_CMD: &struct iwl_device_power_cmd */ POWER_TABLE_CMD = 0x77, + + /** + * @PSM_UAPSD_AP_MISBEHAVING_NOTIFICATION: + * &struct iwl_uapsd_misbehaving_ap_notif + */ PSM_UAPSD_AP_MISBEHAVING_NOTIFICATION = 0x78, + + /** + * @LTR_CONFIG: &struct iwl_ltr_config_cmd + */ LTR_CONFIG = 0xee, - /* Thermal Throttling*/ + /** + * @REPLY_THERMAL_MNG_BACKOFF: + * Thermal throttling command + */ REPLY_THERMAL_MNG_BACKOFF = 0x7e, - /* Set/Get DC2DC frequency tune */ + /** + * @DC2DC_CONFIG_CMD: + * Set/Get DC2DC frequency tune + * Command is &struct iwl_dc2dc_config_cmd, + * response is &struct iwl_dc2dc_config_resp + */ DC2DC_CONFIG_CMD = 0x83, /** @@ -328,7 +429,11 @@ enum iwl_legacy_cmds { */ NVM_ACCESS_CMD = 0x88, + /** + * @BEACON_NOTIFICATION: &struct iwl_extended_beacon_notif + */ BEACON_NOTIFICATION = 0x90, + /** * @BEACON_TEMPLATE_CMD: * Uses one of &struct iwl_mac_beacon_cmd_v6, @@ -353,6 +458,12 @@ enum iwl_legacy_cmds { * &struct iwl_notif_statistics_cdb */ STATISTICS_NOTIFICATION = 0x9d, + + /** + * @EOSP_NOTIFICATION: + * Notify that a service period ended, + * &struct iwl_mvm_eosp_notification + */ EOSP_NOTIFICATION = 0x9e, /** @@ -361,8 +472,16 @@ enum iwl_legacy_cmds { */ REDUCE_TX_POWER_CMD = 0x9f, + /** + * @CARD_STATE_NOTIFICATION: + * Card state (RF/CT kill) notification, + * uses &struct iwl_card_state_notif + */ CARD_STATE_NOTIFICATION = 0xa1, + /** + * @MISSED_BEACONS_NOTIFICATION: &struct iwl_missed_beacons_notif + */ MISSED_BEACONS_NOTIFICATION = 0xa2, /** @@ -390,7 +509,19 @@ enum iwl_legacy_cmds { * &struct iwl_rx_mpdu_res_start or &struct iwl_rx_mpdu_desc */ REPLY_RX_MPDU_CMD = 0xc1, + + /** + * @FRAME_RELEASE: + * Frame release (reorder helper) notification, uses + * &struct iwl_frame_release + */ FRAME_RELEASE = 0xc3, + + /** + * @BA_NOTIF: + * BlockAck notification, uses &struct iwl_mvm_compressed_ba_notif + * or &struct iwl_mvm_ba_notif depending on the HW + */ BA_NOTIF = 0xc5, /* Location Aware Regulatory */ @@ -404,18 +535,33 @@ enum iwl_legacy_cmds { */ MCC_CHUB_UPDATE_CMD = 0xc9, + /** + * @MARKER_CMD: trace marker command, uses &struct iwl_mvm_marker + */ MARKER_CMD = 0xcb, /** * @BT_PROFILE_NOTIFICATION: &struct iwl_bt_coex_profile_notif */ BT_PROFILE_NOTIFICATION = 0xce, + /** * @BT_CONFIG: &struct iwl_bt_coex_cmd */ BT_CONFIG = 0x9b, + + /** + * @BT_COEX_UPDATE_CORUN_LUT: + * &struct iwl_bt_coex_corun_lut_update_cmd + */ BT_COEX_UPDATE_CORUN_LUT = 0x5b, + + /** + * @BT_COEX_UPDATE_REDUCED_TXP: + * &struct iwl_bt_coex_reduced_txp_update_cmd + */ BT_COEX_UPDATE_REDUCED_TXP = 0x5c, + /** * @BT_COEX_CI: &struct iwl_bt_coex_ci_cmd */ @@ -430,21 +576,60 @@ enum iwl_legacy_cmds { */ REPLY_BEACON_FILTERING_CMD = 0xd2, + /** + * @DTS_MEASUREMENT_NOTIFICATION: + * &struct iwl_dts_measurement_notif_v1 or + * &struct iwl_dts_measurement_notif_v2 + */ DTS_MEASUREMENT_NOTIFICATION = 0xdd, + /** + * @LDBG_CONFIG_CMD: configure continuous trace recording + */ LDBG_CONFIG_CMD = 0xf6, + + /** + * @DEBUG_LOG_MSG: Debugging log data from firmware + */ DEBUG_LOG_MSG = 0xf7, + /** + * @BCAST_FILTER_CMD: &struct iwl_bcast_filter_cmd + */ BCAST_FILTER_CMD = 0xcf, + + /** + * @MCAST_FILTER_CMD: &struct iwl_mcast_filter_cmd + */ MCAST_FILTER_CMD = 0xd0, /** * @D3_CONFIG_CMD: &struct iwl_d3_manager_config */ D3_CONFIG_CMD = 0xd3, + + /** + * @PROT_OFFLOAD_CONFIG_CMD: Depending on firmware, uses one of + * &struct iwl_proto_offload_cmd_v1, &struct iwl_proto_offload_cmd_v2, + * &struct iwl_proto_offload_cmd_v3_small, + * &struct iwl_proto_offload_cmd_v3_large + */ PROT_OFFLOAD_CONFIG_CMD = 0xd4, + + /** + * @OFFLOADS_QUERY_CMD: + * No data in command, response in &struct iwl_wowlan_status + */ OFFLOADS_QUERY_CMD = 0xd5, + + /** + * @REMOTE_WAKE_CONFIG_CMD: &struct iwl_wowlan_remote_wake_config + */ REMOTE_WAKE_CONFIG_CMD = 0xd6, + + /** + * @D0I3_END_CMD: End D0i3/D3 state, no command data + */ D0I3_END_CMD = 0xed, /** @@ -456,24 +641,31 @@ enum iwl_legacy_cmds { * @WOWLAN_CONFIGURATION: &struct iwl_wowlan_config_cmd */ WOWLAN_CONFIGURATION = 0xe1, + /** * @WOWLAN_TSC_RSC_PARAM: &struct iwl_wowlan_rsc_tsc_params_cmd */ WOWLAN_TSC_RSC_PARAM = 0xe2, + /** * @WOWLAN_TKIP_PARAM: &struct iwl_wowlan_tkip_params_cmd */ WOWLAN_TKIP_PARAM = 0xe3, + /** * @WOWLAN_KEK_KCK_MATERIAL: &struct iwl_wowlan_kek_kck_material_cmd */ WOWLAN_KEK_KCK_MATERIAL = 0xe4, + /** * @WOWLAN_GET_STATUSES: response in &struct iwl_wowlan_status */ WOWLAN_GET_STATUSES = 0xe5, - /* and for NetDetect */ + /** + * @SCAN_OFFLOAD_PROFILES_QUERY_CMD: + * No command data, response is &struct iwl_scan_offload_profiles_query + */ SCAN_OFFLOAD_PROFILES_QUERY_CMD = 0x56, }; @@ -490,15 +682,38 @@ enum iwl_mac_conf_subcmd_ids { * enum iwl_phy_ops_subcmd_ids - PHY group commands */ enum iwl_phy_ops_subcmd_ids { + /** + * @CMD_DTS_MEASUREMENT_TRIGGER_WIDE: + * Uses either &struct iwl_dts_measurement_cmd or + * &struct iwl_ext_dts_measurement_cmd + */ CMD_DTS_MEASUREMENT_TRIGGER_WIDE = 0x0, + + /** + * @CTDP_CONFIG_CMD: &struct iwl_mvm_ctdp_cmd + */ CTDP_CONFIG_CMD = 0x03, /** * @TEMP_REPORTING_THRESHOLDS_CMD: &struct temp_report_ths_cmd */ TEMP_REPORTING_THRESHOLDS_CMD = 0x04, + + /** + * @GEO_TX_POWER_LIMIT: &struct iwl_geo_tx_power_profiles_cmd + */ GEO_TX_POWER_LIMIT = 0x05, + + /** + * @CT_KILL_NOTIFICATION: &struct ct_kill_notif + */ CT_KILL_NOTIFICATION = 0xFE, + + /** + * @DTS_MEASUREMENT_NOTIF_WIDE: + * &struct iwl_dts_measurement_notif_v1 or + * &struct iwl_dts_measurement_notif_v2 + */ DTS_MEASUREMENT_NOTIF_WIDE = 0xFF, }; @@ -512,6 +727,10 @@ enum iwl_system_subcmd_ids { * &struct iwl_shared_mem_cfg_v1 */ SHARED_MEM_CFG_CMD = 0x0, + + /** + * @INIT_EXTENDED_CFG_CMD: &struct iwl_init_extended_cfg_cmd + */ INIT_EXTENDED_CFG_CMD = 0x03, }; @@ -523,19 +742,57 @@ enum iwl_data_path_subcmd_ids { * @DQA_ENABLE_CMD: &struct iwl_dqa_enable_cmd */ DQA_ENABLE_CMD = 0x0, + + /** + * @UPDATE_MU_GROUPS_CMD: &struct iwl_mu_group_mgmt_cmd + */ UPDATE_MU_GROUPS_CMD = 0x1, + + /** + * @TRIGGER_RX_QUEUES_NOTIF_CMD: &struct iwl_rxq_sync_cmd + */ TRIGGER_RX_QUEUES_NOTIF_CMD = 0x2, + + /** + * @STA_PM_NOTIF: &struct iwl_mvm_pm_state_notification + */ STA_PM_NOTIF = 0xFD, + + /** + * @MU_GROUP_MGMT_NOTIF: &struct iwl_mu_group_mgmt_notif + */ MU_GROUP_MGMT_NOTIF = 0xFE, + + /** + * @RX_QUEUES_NOTIFICATION: &struct iwl_rxq_sync_notification + */ RX_QUEUES_NOTIFICATION = 0xFF, }; +/** + * enum iwl_prot_offload_subcmd_ids - protocol offload commands + */ enum iwl_prot_offload_subcmd_ids { + /** + * @STORED_BEACON_NTF: &struct iwl_stored_beacon_notif + */ STORED_BEACON_NTF = 0xFF, }; +/** + * enum iwl_regulatory_and_nvm_subcmd_ids - regulatory/NVM commands + */ enum iwl_regulatory_and_nvm_subcmd_ids { + /** + * @NVM_ACCESS_COMPLETE: &struct iwl_nvm_access_complete_cmd + */ NVM_ACCESS_COMPLETE = 0x0, + + /** + * @NVM_GET_INFO: + * Command is &struct iwl_nvm_get_info, + * response is &struct iwl_nvm_get_info_rsp + */ NVM_GET_INFO = 0x2, }; @@ -2605,6 +2862,7 @@ struct iwl_nvm_get_info_phy { * struct iwl_nvm_get_info_regulatory - regulatory information * @lar_enabled: is LAR enabled * @channel_profile: regulatory data of this channel + * @reserved: reserved */ struct iwl_nvm_get_info_regulatory { __le32 lar_enabled; From acf91dda3f64bedb4abc46d87b35d41c36a4a28d Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 16 May 2017 16:15:42 +0200 Subject: [PATCH 08/46] iwlwifi: mvm: fix a bunch of kernel-doc warnings Fix the kernel-doc, and remove some fields even the firmware doesn't use in ToF, RX, scan, station and generic FW APIS. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- .../wireless/intel/iwlwifi/mvm/fw-api-coex.h | 11 ++-- .../wireless/intel/iwlwifi/mvm/fw-api-d3.h | 5 ++ .../wireless/intel/iwlwifi/mvm/fw-api-mac.h | 2 + .../wireless/intel/iwlwifi/mvm/fw-api-rs.h | 3 + .../wireless/intel/iwlwifi/mvm/fw-api-rx.h | 33 +++++----- .../wireless/intel/iwlwifi/mvm/fw-api-scan.h | 28 ++++++--- .../wireless/intel/iwlwifi/mvm/fw-api-sta.h | 63 ++++++++++++++----- .../wireless/intel/iwlwifi/mvm/fw-api-tof.h | 14 ++++- .../net/wireless/intel/iwlwifi/mvm/fw-api.h | 26 +++++--- 9 files changed, 127 insertions(+), 58 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-coex.h b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-coex.h index c432fdb98630..8cd06aaa1f54 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-coex.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-coex.h @@ -7,6 +7,7 @@ * * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH + * Copyright(c) 2017 Intel Deutschland GmbH * * 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 @@ -33,6 +34,7 @@ * * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH + * Copyright(c) 2017 Intel Deutschland GmbH * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -132,10 +134,10 @@ struct iwl_bt_coex_reduced_txp_update_cmd { /** * struct iwl_bt_coex_ci_cmd - bt coex channel inhibition command - * @bt_primary_ci: - * @primary_ch_phy_id: - * @bt_secondary_ci: - * @secondary_ch_phy_id: + * @bt_primary_ci: primary channel inhibition bitmap + * @primary_ch_phy_id: primary channel PHY ID + * @bt_secondary_ci: secondary channel inhibition bitmap + * @secondary_ch_phy_id: secondary channel PHY ID * * Used for BT_COEX_CI command */ @@ -238,6 +240,7 @@ enum iwl_bt_ci_compliance { * @secondary_ch_lut: LUT used for secondary channel &enum iwl_bt_coex_lut_type * @bt_activity_grading: the activity of BT &enum iwl_bt_activity_grading * @ttc_rrc_status: is TTC or RRC enabled - one bit per PHY + * @reserved: reserved */ struct iwl_bt_coex_profile_notif { __le32 mbox_msg[4]; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-d3.h b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-d3.h index 2bfe4de6ac5a..d4a4c28b7192 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-d3.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-d3.h @@ -139,6 +139,7 @@ struct iwl_proto_offload_cmd_common { * for each target address * @target_ipv6_addr: our target addresses * @ndp_mac_addr: neighbor solicitation response MAC address + * @reserved2: reserved */ struct iwl_proto_offload_cmd_v1 { struct iwl_proto_offload_cmd_common common; @@ -157,6 +158,8 @@ struct iwl_proto_offload_cmd_v1 { * for each target address * @target_ipv6_addr: our target addresses * @ndp_mac_addr: neighbor solicitation response MAC address + * @num_valid_ipv6_addrs: number of valid IPv6 addresses + * @reserved2: reserved */ struct iwl_proto_offload_cmd_v2 { struct iwl_proto_offload_cmd_common common; @@ -183,6 +186,7 @@ struct iwl_targ_addr { /** * struct iwl_proto_offload_cmd_v3_small - ARP/NS offload configuration * @common: common/IPv4 configuration + * @num_valid_ipv6_addrs: number of valid IPv6 addresses * @targ_addrs: target IPv6 addresses * @ns_config: NS offload configurations */ @@ -196,6 +200,7 @@ struct iwl_proto_offload_cmd_v3_small { /** * struct iwl_proto_offload_cmd_v3_large - ARP/NS offload configuration * @common: common/IPv4 configuration + * @num_valid_ipv6_addrs: number of valid IPv6 addresses * @targ_addrs: target IPv6 addresses * @ns_config: NS offload configurations */ diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-mac.h b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-mac.h index 932adaf575eb..0c3350ad2f2f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-mac.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-mac.h @@ -333,7 +333,9 @@ struct iwl_ac_qos { * @mac_type: one of &enum iwl_mac_types * @tsf_id: TSF HW timer, one of &enum iwl_tsf_id * @node_addr: MAC address + * @reserved_for_node_addr: reserved * @bssid_addr: BSSID + * @reserved_for_bssid_addr: reserved * @cck_rates: basic rates available for CCK * @ofdm_rates: basic rates available for OFDM * @protection_flags: combination of &enum iwl_mac_protection_flags diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rs.h b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rs.h index 1e34e41f52bc..bdf1228d050b 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rs.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rs.h @@ -368,6 +368,7 @@ enum { /** * struct iwl_lq_cmd - link quality command * @sta_id: station to update + * @reduced_tpc: reduced transmit power control value * @control: not used * @flags: combination of LQ_FLAG_* * @mimo_delim: the first SISO index in rs_table, which separates MIMO @@ -385,6 +386,7 @@ enum { * 0: no limit * 1: no aggregation (one frame per aggregation) * 2 - 0x3f: maximal number of frames (up to 3f == 63) + * @reserved2: reserved * @rs_table: array of rates for each TX try, each is rate_n_flags, * meaning it is a combination of RATE_MCS_* and IWL_RATE_*_PLCP * @ss_params: single stream features. declare whether STBC or BFER are allowed. @@ -407,4 +409,5 @@ struct iwl_lq_cmd { __le32 rs_table[LQ_MAX_RETRY_NUM]; __le32 ss_params; }; /* LINK_QUALITY_CMD_API_S_VER_1 */ + #endif /* __fw_api_rs_h__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rx.h b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rx.h index 39b6f592a004..59038ade08d8 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rx.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rx.h @@ -90,7 +90,7 @@ enum iwl_mac_context_info { * @non_cfg_phy_cnt: non configurable DSP phy data byte count * @cfg_phy_cnt: configurable DSP phy data byte count * @stat_id: configurable DSP phy data set ID - * @reserved1: + * @reserved1: reserved * @system_timestamp: GP2 at on air rise * @timestamp: TSF at on air rise * @beacon_time_stamp: beacon at on-air rise @@ -158,10 +158,11 @@ struct iwl_rx_mpdu_res_start { /** * enum iwl_rx_phy_flags - to parse %iwl_rx_phy_info phy_flags * @RX_RES_PHY_FLAGS_BAND_24: true if the packet was received on 2.4 band - * @RX_RES_PHY_FLAGS_MOD_CCK: + * @RX_RES_PHY_FLAGS_MOD_CCK: modulation is CCK * @RX_RES_PHY_FLAGS_SHORT_PREAMBLE: true if packet's preamble was short - * @RX_RES_PHY_FLAGS_NARROW_BAND: + * @RX_RES_PHY_FLAGS_NARROW_BAND: narrow band (<20 MHz) receive * @RX_RES_PHY_FLAGS_ANTENNA: antenna on which the packet was received + * @RX_RES_PHY_FLAGS_ANTENNA_POS: antenna bit position * @RX_RES_PHY_FLAGS_AGG: set if the packet was part of an A-MPDU * @RX_RES_PHY_FLAGS_OFDM_HT: The frame was an HT frame * @RX_RES_PHY_FLAGS_OFDM_GF: The frame used GF preamble @@ -184,9 +185,9 @@ enum iwl_rx_phy_flags { * enum iwl_mvm_rx_status - written by fw for each Rx packet * @RX_MPDU_RES_STATUS_CRC_OK: CRC is fine * @RX_MPDU_RES_STATUS_OVERRUN_OK: there was no RXE overflow - * @RX_MPDU_RES_STATUS_SRC_STA_FOUND: - * @RX_MPDU_RES_STATUS_KEY_VALID: - * @RX_MPDU_RES_STATUS_KEY_PARAM_OK: + * @RX_MPDU_RES_STATUS_SRC_STA_FOUND: station was found + * @RX_MPDU_RES_STATUS_KEY_VALID: key was valid + * @RX_MPDU_RES_STATUS_KEY_PARAM_OK: key parameters were usable * @RX_MPDU_RES_STATUS_ICV_OK: ICV is fine, if not, the packet is destroyed * @RX_MPDU_RES_STATUS_MIC_OK: used for CCM alg only. TKIP MIC is checked * in the driver. @@ -198,21 +199,21 @@ enum iwl_rx_phy_flags { * @RX_MPDU_RES_STATUS_SEC_WEP_ENC: this frame is encrypted using WEP * @RX_MPDU_RES_STATUS_SEC_CCM_ENC: this frame is encrypted using CCM * @RX_MPDU_RES_STATUS_SEC_TKIP_ENC: this frame is encrypted using TKIP + * @RX_MPDU_RES_STATUS_SEC_EXT_ENC: this frame is encrypted using extension + * algorithm * @RX_MPDU_RES_STATUS_SEC_CCM_CMAC_ENC: this frame is encrypted using CCM_CMAC * @RX_MPDU_RES_STATUS_SEC_ENC_ERR: this frame couldn't be decrypted * @RX_MPDU_RES_STATUS_SEC_ENC_MSK: bitmask of the encryption algorithm * @RX_MPDU_RES_STATUS_DEC_DONE: this frame has been successfully decrypted - * @RX_MPDU_RES_STATUS_PROTECT_FRAME_BIT_CMP: - * @RX_MPDU_RES_STATUS_EXT_IV_BIT_CMP: - * @RX_MPDU_RES_STATUS_KEY_ID_CMP_BIT: + * @RX_MPDU_RES_STATUS_EXT_IV_BIT_CMP: extended IV (set with TKIP) + * @RX_MPDU_RES_STATUS_KEY_ID_CMP_BIT: key ID comparison done * @RX_MPDU_RES_STATUS_ROBUST_MNG_FRAME: this frame is an 11w management frame * @RX_MPDU_RES_STATUS_CSUM_DONE: checksum was done by the hw * @RX_MPDU_RES_STATUS_CSUM_OK: checksum found no errors - * @RX_MPDU_RES_STATUS_HASH_INDEX_MSK: - * @RX_MPDU_RES_STATUS_STA_ID_MSK: - * @RX_MPDU_RES_STATUS_RRF_KILL: - * @RX_MPDU_RES_STATUS_FILTERING_MSK: - * @RX_MPDU_RES_STATUS2_FILTERING_MSK: + * @RX_MPDU_RES_STATUS_STA_ID_MSK: station ID mask + * @RX_MDPU_RES_STATUS_STA_ID_SHIFT: station ID bit shift + * @RX_MPDU_RES_STATUS_FILTERING_MSK: filter status + * @RX_MPDU_RES_STATUS2_FILTERING_MSK: filter status 2 */ enum iwl_mvm_rx_status { RX_MPDU_RES_STATUS_CRC_OK = BIT(0), @@ -233,16 +234,13 @@ enum iwl_mvm_rx_status { RX_MPDU_RES_STATUS_SEC_ENC_ERR = (7 << 8), RX_MPDU_RES_STATUS_SEC_ENC_MSK = (7 << 8), RX_MPDU_RES_STATUS_DEC_DONE = BIT(11), - RX_MPDU_RES_STATUS_PROTECT_FRAME_BIT_CMP = BIT(12), RX_MPDU_RES_STATUS_EXT_IV_BIT_CMP = BIT(13), RX_MPDU_RES_STATUS_KEY_ID_CMP_BIT = BIT(14), RX_MPDU_RES_STATUS_ROBUST_MNG_FRAME = BIT(15), RX_MPDU_RES_STATUS_CSUM_DONE = BIT(16), RX_MPDU_RES_STATUS_CSUM_OK = BIT(17), - RX_MPDU_RES_STATUS_HASH_INDEX_MSK = (0x3F0000), RX_MDPU_RES_STATUS_STA_ID_SHIFT = 24, RX_MPDU_RES_STATUS_STA_ID_MSK = 0x1f << RX_MDPU_RES_STATUS_STA_ID_SHIFT, - RX_MPDU_RES_STATUS_RRF_KILL = BIT(29), RX_MPDU_RES_STATUS_FILTERING_MSK = (0xc00000), RX_MPDU_RES_STATUS2_FILTERING_MSK = (0xc0000000), }; @@ -476,6 +474,7 @@ enum iwl_rss_hash_func_en { * * @flags: 1 - enable, 0 - disable * @hash_mask: Type of RSS to use. Values are from %iwl_rss_hash_func_en + * @reserved: reserved * @secret_key: 320 bit input of random key configuration from driver * @indirection_table: indirection table */ diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-scan.h index e752359841b8..1cd7cc087936 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-scan.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-scan.h @@ -80,6 +80,10 @@ * selected by "type" bit field in struct iwl_scan_channel; * each channel may select different ssids from among the 20 entries. * SSID IEs get transmitted in reverse order of entry. + * + * @id: element ID + * @len: element length + * @ssid: element (SSID) data */ struct iwl_ssid_ie { u8 id; @@ -141,6 +145,7 @@ enum iwl_scan_offload_band_selection { * @network_type: enum iwl_scan_offload_network_type * @band_selection: enum iwl_scan_offload_band_selection * @client_bitmap: clients waiting for match - enum scan_framework_client + * @reserved: reserved */ struct iwl_scan_offload_profile { u8 ssid_index; @@ -161,6 +166,7 @@ struct iwl_scan_offload_profile { * @pass_match: clients waiting for the results * @active_clients: active clients bitmap - enum scan_framework_client * @any_beacon_notify: clients waiting for match notification without match + * @reserved: reserved */ struct iwl_scan_offload_profile_cfg { struct iwl_scan_offload_profile profiles[IWL_SCAN_MAX_PROFILES]; @@ -280,7 +286,7 @@ struct iwl_scan_channel_opt { * @IWL_MVM_LMAC_SCAN_FLAG_PASSIVE: force passive scan on all channels * @IWL_MVM_LMAC_SCAN_FLAG_PRE_CONNECTION: single channel scan * @IWL_MVM_LMAC_SCAN_FLAG_ITER_COMPLETE: send iteration complete notification - * @IWL_MVM_LMAC_SCAN_FLAG_MULTIPLE_SSIDS multiple SSID matching + * @IWL_MVM_LMAC_SCAN_FLAG_MULTIPLE_SSIDS: multiple SSID matching * @IWL_MVM_LMAC_SCAN_FLAG_FRAGMENTED: all passive scans will be fragmented * @IWL_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED: insert WFA vendor-specific TPC report * and DS parameter set IEs into probe requests. @@ -321,9 +327,9 @@ enum iwl_scan_priority_ext { * struct iwl_scan_req_lmac - SCAN_REQUEST_CMD_API_S_VER_1 * @reserved1: for alignment and future use * @n_channels: num of channels to scan - * @active-dwell: dwell time for active channels - * @passive-dwell: dwell time for passive channels - * @fragmented-dwell: dwell time for fragmented passive scan + * @active_dwell: dwell time for active channels + * @passive_dwell: dwell time for passive channels + * @fragmented_dwell: dwell time for fragmented passive scan * @extended_dwell: dwell time for channels 1, 6 and 11 (in certain cases) * @reserved2: for alignment and future use * @rx_chain_select: PHY_RX_CHAIN_* flags @@ -411,9 +417,10 @@ struct iwl_lmac_scan_complete_notif { * struct iwl_scan_offload_complete - PERIODIC_SCAN_COMPLETE_NTF_API_S_VER_2 * @last_schedule_line: last schedule line executed (fast or regular) * @last_schedule_iteration: last scan iteration executed before scan abort - * @status: enum iwl_scan_offload_complete_status + * @status: &enum iwl_scan_offload_complete_status * @ebs_status: EBS success status &enum iwl_scan_ebs_status - * @time_after_last_iter; time in seconds elapsed after last iteration + * @time_after_last_iter: time in seconds elapsed after last iteration + * @reserved: reserved */ struct iwl_periodic_scan_complete { u8 last_schedule_line; @@ -699,8 +706,8 @@ struct iwl_umac_scan_abort { * struct iwl_umac_scan_complete * @uid: scan id, &enum iwl_umac_scan_uid_offsets * @last_schedule: last scheduling line - * @last_iter: last scan iteration number - * @scan status: &enum iwl_scan_offload_complete_status + * @last_iter: last scan iteration number + * @status: &enum iwl_scan_offload_complete_status * @ebs_status: &enum iwl_scan_ebs_status * @time_from_last_iter: time elapsed from last iteration * @reserved: for future use @@ -719,9 +726,10 @@ struct iwl_umac_scan_complete { /** * struct iwl_scan_offload_profile_match - match information * @bssid: matched bssid + * @reserved: reserved * @channel: channel where the match occurred - * @energy: - * @matching_feature: + * @energy: energy + * @matching_feature: feature matches * @matching_channels: bitmap of channels that matched, referencing * the channels passed in tue scan offload request */ diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-sta.h b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-sta.h index c14ebd7ff77d..81f0a3463bac 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-sta.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-sta.h @@ -69,8 +69,8 @@ /** * enum iwl_sta_flags - flags for the ADD_STA host command - * @STA_FLG_REDUCED_TX_PWR_CTRL: - * @STA_FLG_REDUCED_TX_PWR_DATA: + * @STA_FLG_REDUCED_TX_PWR_CTRL: reduced TX power (control frames) + * @STA_FLG_REDUCED_TX_PWR_DATA: reduced TX power (data frames) * @STA_FLG_DISABLE_TX: set if TX should be disabled * @STA_FLG_PS: set if STA is in Power Save * @STA_FLG_INVALID: set if STA is invalid @@ -78,18 +78,40 @@ * @STA_FLG_SET_ALL_KEYS: the current key applies to all key IDs * @STA_FLG_DRAIN_FLOW: drain flow * @STA_FLG_PAN: STA is for PAN interface - * @STA_FLG_CLASS_AUTH: - * @STA_FLG_CLASS_ASSOC: - * @STA_FLG_CLASS_MIMO_PROT: - * @STA_FLG_MAX_AGG_SIZE_MSK: maximal size for A-MPDU + * @STA_FLG_CLASS_AUTH: station is authenticated + * @STA_FLG_CLASS_ASSOC: station is associated + * @STA_FLG_RTS_MIMO_PROT: station requires RTS MIMO protection (dynamic SMPS) + * @STA_FLG_MAX_AGG_SIZE_MSK: maximal size for A-MPDU (mask) + * @STA_FLG_MAX_AGG_SIZE_SHIFT: maximal size for A-MPDU (bit shift) + * @STA_FLG_MAX_AGG_SIZE_8K: maximal size for A-MPDU (8k supported) + * @STA_FLG_MAX_AGG_SIZE_16K: maximal size for A-MPDU (16k supported) + * @STA_FLG_MAX_AGG_SIZE_32K: maximal size for A-MPDU (32k supported) + * @STA_FLG_MAX_AGG_SIZE_64K: maximal size for A-MPDU (64k supported) + * @STA_FLG_MAX_AGG_SIZE_128K: maximal size for A-MPDU (128k supported) + * @STA_FLG_MAX_AGG_SIZE_256K: maximal size for A-MPDU (256k supported) + * @STA_FLG_MAX_AGG_SIZE_512K: maximal size for A-MPDU (512k supported) + * @STA_FLG_MAX_AGG_SIZE_1024K: maximal size for A-MPDU (1024k supported) * @STA_FLG_AGG_MPDU_DENS_MSK: maximal MPDU density for Tx aggregation * @STA_FLG_FAT_EN_MSK: support for channel width (for Tx). This flag is * initialised by driver and can be updated by fw upon reception of * action frames that can change the channel width. When cleared the fw * will send all the frames in 20MHz even when FAT channel is requested. + * @STA_FLG_FAT_EN_20MHZ: no wide channels are supported, only 20 MHz + * @STA_FLG_FAT_EN_40MHZ: wide channels up to 40 MHz supported + * @STA_FLG_FAT_EN_80MHZ: wide channels up to 80 MHz supported + * @STA_FLG_FAT_EN_160MHZ: wide channels up to 160 MHz supported * @STA_FLG_MIMO_EN_MSK: support for MIMO. This flag is initialised by the * driver and can be updated by fw upon reception of action frames. + * @STA_FLG_MIMO_EN_SISO: no support for MIMO + * @STA_FLG_MIMO_EN_MIMO2: 2 streams supported + * @STA_FLG_MIMO_EN_MIMO3: 3 streams supported * @STA_FLG_MFP_EN: Management Frame Protection + * @STA_FLG_AGG_MPDU_DENS_MSK: A-MPDU density (mask) + * @STA_FLG_AGG_MPDU_DENS_SHIFT: A-MPDU density (bit shift) + * @STA_FLG_AGG_MPDU_DENS_2US: A-MPDU density (2 usec gap) + * @STA_FLG_AGG_MPDU_DENS_4US: A-MPDU density (4 usec gap) + * @STA_FLG_AGG_MPDU_DENS_8US: A-MPDU density (8 usec gap) + * @STA_FLG_AGG_MPDU_DENS_16US: A-MPDU density (16 usec gap) */ enum iwl_sta_flags { STA_FLG_REDUCED_TX_PWR_CTRL = BIT(3), @@ -148,9 +170,10 @@ enum iwl_sta_flags { * @STA_KEY_FLG_WEP_KEY_MAP: wep is either a group key (0 - legacy WEP) or from * station info array (1 - n 1X mode) * @STA_KEY_FLG_KEYID_MSK: the index of the key + * @STA_KEY_FLG_KEYID_POS: key index bit position * @STA_KEY_NOT_VALID: key is invalid * @STA_KEY_FLG_WEP_13BYTES: set for 13 bytes WEP key - * @STA_KEY_FLG_KEY_32BYTES for non-wep key set for 32 bytes key + * @STA_KEY_FLG_KEY_32BYTES: for non-wep key set for 32 bytes key * @STA_KEY_MULTICAST: set for multical key * @STA_KEY_MFP: key is used for Management Frame Protection */ @@ -183,7 +206,7 @@ enum iwl_sta_key_flag { * @STA_MODIFY_ADD_BA_TID: this command modifies %add_immediate_ba_tid * @STA_MODIFY_REMOVE_BA_TID: this command modifies %remove_immediate_ba_tid * @STA_MODIFY_SLEEPING_STA_TX_COUNT: this command modifies %sleep_tx_count - * @STA_MODIFY_PROT_TH: + * @STA_MODIFY_PROT_TH: modify RTS threshold * @STA_MODIFY_QUEUES: modify the queues used by this station */ enum iwl_sta_modify_flag { @@ -209,9 +232,9 @@ enum iwl_sta_mode { /** * enum iwl_sta_sleep_flag - type of sleep of the station - * @STA_SLEEP_STATE_AWAKE: - * @STA_SLEEP_STATE_PS_POLL: - * @STA_SLEEP_STATE_UAPSD: + * @STA_SLEEP_STATE_AWAKE: station is awake + * @STA_SLEEP_STATE_PS_POLL: station is PS-polling + * @STA_SLEEP_STATE_UAPSD: station uses U-APSD * @STA_SLEEP_STATE_MOREDATA: set more-data bit on * (last) released frame */ @@ -233,8 +256,10 @@ enum iwl_sta_sleep_flag { * struct iwl_mvm_keyinfo - key information * @key_flags: type &enum iwl_sta_key_flag * @tkip_rx_tsc_byte2: TSC[2] for key mix ph1 detection + * @reserved1: reserved * @tkip_rx_ttak: 10-byte unicast TKIP TTAK for Rx * @key_offset: key offset in the fw's key table + * @reserved2: reserved * @key: 16-byte unicast decryption key * @tx_secur_seq_cnt: initial RSC / PN needed for replay check * @hw_tkip_mic_rx_key: byte: MIC Rx Key - used for TKIP only @@ -262,15 +287,17 @@ struct iwl_mvm_keyinfo { * struct iwl_mvm_add_sta_cmd_v7 - Add/modify a station in the fw's sta table. * ( REPLY_ADD_STA = 0x18 ) * @add_modify: see &enum iwl_sta_mode - * @awake_acs: + * @awake_acs: ACs to transmit data on while station is sleeping (for U-APSD) * @tid_disable_tx: is tid BIT(tid) enabled for Tx. Clear BIT(x) to enable * AMPDU for tid x. Set %STA_MODIFY_TID_DISABLE_TX to change this field. * @mac_id_n_color: the Mac context this station belongs to, * see &enum iwl_mvm_id_and_color * @addr: station's MAC address + * @reserved2: reserved * @sta_id: index of station in uCode's station table * @modify_mask: STA_MODIFY_*, selects which parameters to modify vs. leave * alone. 1 - modify, 0 - don't change. + * @reserved3: reserved * @station_flags: look at &enum iwl_sta_flags * @station_flags_msk: what of %station_flags have changed, * also &enum iwl_sta_flags @@ -341,15 +368,17 @@ enum iwl_sta_type { * struct iwl_mvm_add_sta_cmd - Add/modify a station in the fw's sta table. * ( REPLY_ADD_STA = 0x18 ) * @add_modify: see &enum iwl_sta_mode - * @awake_acs: + * @awake_acs: ACs to transmit data on while station is sleeping (for U-APSD) * @tid_disable_tx: is tid BIT(tid) enabled for Tx. Clear BIT(x) to enable * AMPDU for tid x. Set %STA_MODIFY_TID_DISABLE_TX to change this field. * @mac_id_n_color: the Mac context this station belongs to, * see &enum iwl_mvm_id_and_color * @addr: station's MAC address + * @reserved2: reserved * @sta_id: index of station in uCode's station table * @modify_mask: STA_MODIFY_*, selects which parameters to modify vs. leave * alone. 1 - modify, 0 - don't change. + * @reserved3: reserved * @station_flags: look at &enum iwl_sta_flags * @station_flags_msk: what of %station_flags have changed, * also &enum iwl_sta_flags @@ -429,6 +458,7 @@ struct iwl_mvm_add_sta_key_common { * struct iwl_mvm_add_sta_key_cmd_v1 - add/modify sta key * @common: see &struct iwl_mvm_add_sta_key_common * @tkip_rx_tsc_byte2: TSC[2] for key mix ph1 detection + * @reserved: reserved * @tkip_rx_ttak: 10-byte unicast TKIP TTAK for Rx */ struct iwl_mvm_add_sta_key_cmd_v1 { @@ -471,6 +501,7 @@ enum iwl_mvm_add_sta_rsp_status { * struct iwl_mvm_rm_sta_cmd - Add / modify a station in the fw's station table * ( REMOVE_STA = 0x19 ) * @sta_id: the station id of the station to be removed + * @reserved: reserved */ struct iwl_mvm_rm_sta_cmd { u8 sta_id; @@ -481,11 +512,11 @@ struct iwl_mvm_rm_sta_cmd { * struct iwl_mvm_mgmt_mcast_key_cmd_v1 * ( MGMT_MCAST_KEY = 0x1f ) * @ctrl_flags: &enum iwl_sta_key_flag - * @igtk: + * @igtk: IGTK key material * @k1: unused * @k2: unused * @sta_id: station ID that support IGTK - * @key_id: + * @key_id: key ID * @receive_seq_cnt: initial RSC/PN needed for replay check */ struct iwl_mvm_mgmt_mcast_key_cmd_v1 { @@ -504,7 +535,7 @@ struct iwl_mvm_mgmt_mcast_key_cmd_v1 { * @ctrl_flags: &enum iwl_sta_key_flag * @igtk: IGTK master key * @sta_id: station ID that support IGTK - * @key_id: + * @key_id: key ID * @receive_seq_cnt: initial RSC/PN needed for replay check */ struct iwl_mvm_mgmt_mcast_key_cmd { diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-tof.h b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-tof.h index e2acf39f784d..8658a983c463 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-tof.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-tof.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2015 Intel Deutschland GmbH + * Copyright(c) 2015 - 2017 Intel Deutschland GmbH * * 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 @@ * * BSD LICENSE * - * Copyright(c) 2015 Intel Deutschland GmbH + * Copyright(c) 2015 - 2017 Intel Deutschland GmbH * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -163,6 +163,7 @@ struct iwl_tof_responder_config_cmd { /** * struct iwl_tof_range_request_ext_cmd - extended range req for WLS * @tsf_timer_offset_msec: the recommended time offset (mSec) from the AP's TSF + * @reserved: reserved * @min_delta_ftm: Minimal time between two consecutive measurements, * in units of 100us. 0 means no preference by station * @ftm_format_and_bw20M: FTM Channel Spacing/Format for 20MHz: recommended @@ -272,6 +273,7 @@ enum iwl_tof_response_mode { * '1' Use MAC Address randomization according to the below * @macaddr_mask: Bits set to 0 shall be copied from the MAC address template. * Bits set to 1 shall be randomized by the UMAC + * @ap: per-AP request data */ struct iwl_tof_range_req_cmd { __le32 sub_grp_cmd_id; @@ -298,7 +300,9 @@ struct iwl_tof_gen_resp_cmd { /** * struct iwl_tof_range_rsp_ap_entry_ntfy - AP parameters (response) - * @measure_status: current APs measurement status + * @bssid: BSSID of the AP + * @measure_status: current APs measurement status, one of + * &enum iwl_tof_entry_status. * @measure_bw: Current AP Bandwidth: 0 20MHz, 1 40MHz, 2 80MHz * @rtt: The Round Trip Time that took for the last measurement for * current AP [nSec] @@ -308,6 +312,7 @@ struct iwl_tof_gen_resp_cmd { * @rssi: RSSI as uploaded in the Channel Estimation notification * @rssi_spread: The Difference between the maximum and the minimum RSSI values * measured for current AP in the current session + * @reserved: reserved * @range: Measured range [cm] * @range_variance: Measured range variance [cm] * @timestamp: The GP2 Clock [usec] where Channel Estimation notification was @@ -334,6 +339,7 @@ struct iwl_tof_range_rsp_ap_entry_ntfy { * @request_status: status of current measurement session * @last_in_batch: reprot policy (when not all responses are uploaded at once) * @num_of_aps: Number of APs to measure (error if > IWL_MVM_TOF_MAX_APS) + * @ap: per-AP data */ struct iwl_tof_range_rsp_ntfy { u8 request_id; @@ -348,6 +354,7 @@ struct iwl_tof_range_rsp_ntfy { * struct iwl_tof_mcsi_notif - used for debug * @token: token ID for the current session * @role: '0' - initiator, '1' - responder + * @reserved: reserved * @initiator_bssid: initiator machine * @responder_bssid: responder machine * @mcsi_buffer: debug data @@ -380,6 +387,7 @@ struct iwl_tof_neighbor_report { /** * struct iwl_tof_range_abort_cmd * @request_id: corresponds to a range request + * @reserved: reserved */ struct iwl_tof_range_abort_cmd { __le32 sub_grp_cmd_id; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h index 89e5ba3f4e42..17475e269ef5 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h @@ -1187,6 +1187,7 @@ enum { * ( REPLY_ERROR = 0x2 ) * @error_type: one of FW_ERR_* * @cmd_id: the command ID for which the error occured + * @reserved1: reserved * @bad_cmd_seq_num: sequence number of the erroneous command * @error_service: which service created the error, applicable only if * error_type = 2, otherwise 0 @@ -1649,7 +1650,7 @@ struct iwl_fw_channel_info { * @apply_time: 0 means immediate apply and context switch. * other value means apply new params after X usecs * @tx_param_color: ??? - * @channel_info: + * @ci: channel info * @txchain_info: ??? * @rxchain_info: ??? * @acquisition_data: ??? @@ -1738,9 +1739,9 @@ struct iwl_hs20_roc_res { /** * struct iwl_radio_version_notif - information on the radio version * ( RADIO_VERSION_NOTIFICATION = 0x68 ) - * @radio_flavor: - * @radio_step: - * @radio_dash: + * @radio_flavor: radio flavor + * @radio_step: radio version step + * @radio_dash: radio version dash */ struct iwl_radio_version_notif { __le32 radio_flavor; @@ -1774,8 +1775,8 @@ struct iwl_card_state_notif { * @consec_missed_beacons_since_last_rx: number of consecutive missed * beacons since last RX. * @consec_missed_beacons: number of consecutive missed beacons - * @num_expected_beacons: - * @num_recvd_beacons: + * @num_expected_beacons: number of expected beacons + * @num_recvd_beacons: number of received beacons */ struct iwl_missed_beacons_notif { __le32 mac_id; @@ -1835,6 +1836,7 @@ struct iwl_mfu_assert_dump_notif { * @count: Number of MAC addresses in the array * @pass_all: Set 1 to pass all multicast packets. * @bssid: current association BSSID. + * @reserved: reserved * @addr_list: Place holder for array of MAC addresses. * IMPORTANT: add padding if necessary to ensure DWORD alignment. */ @@ -1866,7 +1868,8 @@ enum iwl_mvm_bcast_filter_attr_offset { * struct iwl_fw_bcast_filter_attr - broadcast filter attribute * @offset_type: &enum iwl_mvm_bcast_filter_attr_offset. * @offset: starting offset of this pattern. - * @val: value to match - big endian (MSB is the first + * @reserved1: reserved + * @val: value to match - big endian (MSB is the first * byte to match from offset pos). * @mask: mask to match (big endian). */ @@ -1892,6 +1895,7 @@ enum iwl_mvm_bcast_filter_frame_type { * struct iwl_fw_bcast_filter - broadcast filter * @discard: discard frame (1) or let it pass (0). * @frame_type: &enum iwl_mvm_bcast_filter_frame_type. + * @reserved1: reserved * @num_attrs: number of valid attributes in this filter. * @attrs: attributes of this filter. a filter is considered matched * only when all its attributes are matched (i.e. AND relationship) @@ -1927,6 +1931,7 @@ struct iwl_ba_window_status_notif { /** * struct iwl_fw_bcast_mac - per-mac broadcast filtering configuration. * @default_discard: default action for this mac (discard (1) / pass (0)). + * @reserved1: reserved * @attached_filters: bitmap of relevant filters for this mac. */ struct iwl_fw_bcast_mac { @@ -1940,6 +1945,7 @@ struct iwl_fw_bcast_mac { * @disable: enable (0) / disable (1) * @max_bcast_filters: max number of filters (MAX_BCAST_FILTERS) * @max_macs: max number of macs (NUM_MAC_INDEX_DRIVER) + * @reserved1: reserved * @filters: broadcast filters * @macs: broadcast filtering configuration per-mac */ @@ -2282,7 +2288,7 @@ enum iwl_dts_control_measurement_mode { * @DTS_USE_CHAIN_A: chain A * @DTS_USE_CHAIN_B: chain B * @DTS_USE_CHAIN_C: chain C -* @XTAL_TEMPERATURE - read temperature from xtal +* @XTAL_TEMPERATURE: read temperature from xtal */ enum iwl_dts_used { DTS_USE_TOP = 0, @@ -2624,6 +2630,7 @@ struct iwl_shared_mem_cfg { /** * struct iwl_mu_group_mgmt_cmd - VHT MU-MIMO group configuration * + * @reserved: reserved * @membership_status: a bitmap of MU groups * @user_position:the position of station in a group. If the station is in the * group then bits (group * 2) is the position -1 @@ -2658,6 +2665,7 @@ struct iwl_mu_group_mgmt_notif { * @channel: channel this beacon was received on * @rates: rate in ucode internal format * @byte_count: frame's byte count + * @data: beacon data, length in @byte_count */ struct iwl_stored_beacon_notif { __le32 system_time; @@ -2781,6 +2789,7 @@ struct iwl_dbg_mem_access_rsp { /** * struct iwl_nvm_access_complete_cmd - NVM_ACCESS commands are completed + * @reserved: reserved */ struct iwl_nvm_access_complete_cmd { __le32 reserved; @@ -2820,6 +2829,7 @@ struct iwl_nvm_get_info { * @flags: 1 - empty, 0 - valid * @nvm_version: nvm version * @board_type: board type + * @reserved: reserved */ struct iwl_nvm_get_info_general { __le32 flags; From 779e0513c76e21b62e2ef907f8cfc48f9f41f734 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 17 May 2017 13:45:29 +0200 Subject: [PATCH 09/46] iwlwifi: dvm: use macros for format strings Some static checkers (e.g. smatch) complain if a non-constant format string is used, even if that's a static const variable. Since there's no impact on code generation, just change those format strings to be macros. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c index 376c79337a0e..937be04c6c71 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c @@ -681,11 +681,10 @@ DEBUGFS_READ_FILE_OPS(temperature); DEBUGFS_READ_WRITE_FILE_OPS(sleep_level_override); DEBUGFS_READ_FILE_OPS(current_sleep_command); -static const char *fmt_value = " %-30s %10u\n"; -static const char *fmt_hex = " %-30s 0x%02X\n"; -static const char *fmt_table = " %-30s %10u %10u %10u %10u\n"; -static const char *fmt_header = - "%-32s current cumulative delta max\n"; +#define fmt_value " %-30s %10u\n" +#define fmt_hex " %-30s 0x%02X\n" +#define fmt_table " %-30s %10u %10u %10u %10u\n" +#define fmt_header "%-32s current cumulative delta max\n" static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz) { From 565291c60a3592bd1b6683d2c848dd165a6a3e76 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 10 May 2017 11:31:06 +0200 Subject: [PATCH 10/46] iwlwifi: pcie: only apply retention workaround on 9000-series A-step Due to a hardware issue, certain power saving had to be disabled. However, this issue was fixed in B-step, so the workaround only needs to apply to A-step. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c index a5c0f69423d2..cd109740632d 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c @@ -761,6 +761,15 @@ static void iwl_pcie_rx_hw_init(struct iwl_trans *trans, struct iwl_rxq *rxq) void iwl_pcie_enable_rx_wake(struct iwl_trans *trans, bool enable) { + if (trans->cfg->device_family != IWL_DEVICE_FAMILY_9000) + return; + + if (CSR_HW_REV_STEP(trans->hw_rev) != SILICON_A_STEP) + return; + + if (!trans->cfg->integrated) + return; + /* * Turn on the chicken-bits that cause MAC wakeup for RX-related * values. @@ -768,12 +777,10 @@ void iwl_pcie_enable_rx_wake(struct iwl_trans *trans, bool enable) * bug where shadow registers are not in the retention list and their * value is lost when NIC powers down */ - if (trans->cfg->integrated) { - iwl_set_bit(trans, CSR_MAC_SHADOW_REG_CTRL, - CSR_MAC_SHADOW_REG_CTRL_RX_WAKE); - iwl_set_bit(trans, CSR_MAC_SHADOW_REG_CTL2, - CSR_MAC_SHADOW_REG_CTL2_RX_WAKE); - } + iwl_set_bit(trans, CSR_MAC_SHADOW_REG_CTRL, + CSR_MAC_SHADOW_REG_CTRL_RX_WAKE); + iwl_set_bit(trans, CSR_MAC_SHADOW_REG_CTL2, + CSR_MAC_SHADOW_REG_CTL2_RX_WAKE); } static void iwl_pcie_rx_mq_hw_init(struct iwl_trans *trans) From ae5bb2a62d96e52b138628e0cda4ebb377cbc456 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 18 May 2017 17:02:05 +0200 Subject: [PATCH 11/46] iwlwifi: pcie: fix 9000-series RF-kill interrupt propagation A hardware issue on 9000 series devices sometimes causes RF-kill interrupts to not be propagated to the host properly if ASPM is enabled. Work around this by setting the right hardware bit to allow it to interrupt the host for this reason (rfkill). Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/iwl-csr.h | 2 +- drivers/net/wireless/intel/iwlwifi/pcie/internal.h | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h index e239b1d92cf9..c6c1876c1ad4 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h @@ -312,7 +312,7 @@ #define CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN (0x00000001) #define CSR_GP_CNTRL_REG_MSK_POWER_SAVE_TYPE (0x07000000) -#define CSR_GP_CNTRL_REG_FLAG_MAC_POWER_SAVE (0x04000000) +#define CSR_GP_CNTRL_REG_FLAG_RFKILL_WAKE_L1A_EN (0x04000000) #define CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW (0x08000000) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h index 1f4bc933f0f2..7ec2d96ccceb 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h @@ -674,6 +674,16 @@ static inline void iwl_enable_rfkill_int(struct iwl_trans *trans) iwl_enable_hw_int_msk_msix(trans, MSIX_HW_INT_CAUSES_REG_RF_KILL); } + + if (trans->cfg->device_family == IWL_DEVICE_FAMILY_9000) { + /* + * On 9000-series devices this bit isn't enabled by default, so + * when we power down the device we need set the bit to allow it + * to wake up the PCI-E bus for RF-kill interrupts. + */ + iwl_set_bit(trans, CSR_GP_CNTRL, + CSR_GP_CNTRL_REG_FLAG_RFKILL_WAKE_L1A_EN); + } } void iwl_pcie_handle_rfkill_irq(struct iwl_trans *trans); From 806911da64404a6a6348c4840a47218c3bb64a3c Mon Sep 17 00:00:00 2001 From: Sharon Dvir Date: Sun, 21 May 2017 12:09:49 +0300 Subject: [PATCH 12/46] iwlwifi: mvm: change sta_id to u8 The sta_id variable is used as an index in an array, should be unsigned. Found by Klocwork. Fixes: 9f9af3d7d303 ("iwlwifi: mvm: re-aggregate shared queue after unsharing") Signed-off-by: Sharon Dvir Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c index 02f35a929606..9ec427966533 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c @@ -398,7 +398,7 @@ static int iwl_mvm_get_queue_agg_tids(struct iwl_mvm *mvm, int queue) struct iwl_mvm_sta *mvmsta; unsigned long tid_bitmap; unsigned long agg_tids = 0; - s8 sta_id; + u8 sta_id; int tid; lockdep_assert_held(&mvm->mutex); @@ -989,7 +989,7 @@ static void iwl_mvm_unshare_queue(struct iwl_mvm *mvm, int queue) { struct ieee80211_sta *sta; struct iwl_mvm_sta *mvmsta; - s8 sta_id; + u8 sta_id; int tid = -1; unsigned long tid_bitmap; unsigned int wdg_timeout; From 4c324a51b62079a43a4aa5024785ba542ff83ce3 Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Fri, 19 May 2017 15:06:29 +0300 Subject: [PATCH 13/46] iwlwifi: mvm: simplify CHECK_MLME_TRIGGER macro There's no reason to pass mvm and trig as parameters to the macro, since it will be expanded inside the function itself. Also remove the bogus buf parameter which doesn't exist and is not used. Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 24 +++++++------------ 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index d04a88c6c593..b98978d6cb21 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -4151,11 +4151,11 @@ static void iwl_mvm_event_mlme_callback(struct iwl_mvm *mvm, struct ieee80211_vif *vif, const struct ieee80211_event *event) { -#define CHECK_MLME_TRIGGER(_mvm, _trig, _buf, _cnt, _fmt...) \ +#define CHECK_MLME_TRIGGER(_cnt, _fmt...) \ do { \ - if ((_cnt) && --(_cnt)) \ + if ((trig_mlme->_cnt) && --(trig_mlme->_cnt)) \ break; \ - iwl_mvm_fw_dbg_collect_trig(_mvm, _trig, _fmt);\ + iwl_mvm_fw_dbg_collect_trig(mvm, trig, _fmt); \ } while (0) struct iwl_fw_dbg_trigger_tlv *trig; @@ -4171,31 +4171,25 @@ static void iwl_mvm_event_mlme_callback(struct iwl_mvm *mvm, if (event->u.mlme.data == ASSOC_EVENT) { if (event->u.mlme.status == MLME_DENIED) - CHECK_MLME_TRIGGER(mvm, trig, buf, - trig_mlme->stop_assoc_denied, + CHECK_MLME_TRIGGER(stop_assoc_denied, "DENIED ASSOC: reason %d", event->u.mlme.reason); else if (event->u.mlme.status == MLME_TIMEOUT) - CHECK_MLME_TRIGGER(mvm, trig, buf, - trig_mlme->stop_assoc_timeout, + CHECK_MLME_TRIGGER(stop_assoc_timeout, "ASSOC TIMEOUT"); } else if (event->u.mlme.data == AUTH_EVENT) { if (event->u.mlme.status == MLME_DENIED) - CHECK_MLME_TRIGGER(mvm, trig, buf, - trig_mlme->stop_auth_denied, + CHECK_MLME_TRIGGER(stop_auth_denied, "DENIED AUTH: reason %d", event->u.mlme.reason); else if (event->u.mlme.status == MLME_TIMEOUT) - CHECK_MLME_TRIGGER(mvm, trig, buf, - trig_mlme->stop_auth_timeout, + CHECK_MLME_TRIGGER(stop_auth_timeout, "AUTH TIMEOUT"); } else if (event->u.mlme.data == DEAUTH_RX_EVENT) { - CHECK_MLME_TRIGGER(mvm, trig, buf, - trig_mlme->stop_rx_deauth, + CHECK_MLME_TRIGGER(stop_rx_deauth, "DEAUTH RX %d", event->u.mlme.reason); } else if (event->u.mlme.data == DEAUTH_TX_EVENT) { - CHECK_MLME_TRIGGER(mvm, trig, buf, - trig_mlme->stop_tx_deauth, + CHECK_MLME_TRIGGER(stop_tx_deauth, "DEAUTH TX %d", event->u.mlme.reason); } #undef CHECK_MLME_TRIGGER From 175b87c692532ece6c4622628c8c9df726773236 Mon Sep 17 00:00:00 2001 From: Tzipi Peres Date: Mon, 22 May 2017 12:36:28 +0300 Subject: [PATCH 14/46] iwlwifi: add the new a000_2ax series Add a new config struct for the new a000 2ax series and add the five PCI ID for it. Signed-off-by: Tzipi Peres Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/iwl-a000.c | 10 ++++++++++ drivers/net/wireless/intel/iwlwifi/iwl-config.h | 1 + drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 5 +++++ 3 files changed, 16 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-a000.c b/drivers/net/wireless/intel/iwlwifi/iwl-a000.c index 4634c46d1eb4..2940c0a6c3d6 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-a000.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-a000.c @@ -158,5 +158,15 @@ const struct iwl_cfg iwla000_2ac_cfg_jf = { .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, }; +const struct iwl_cfg iwla000_2ax_cfg_hr = { + .name = "Intel(R) Dual Band Wireless AX a000", + .fw_name_pre = IWL_A000_HR_FW_PRE, + IWL_DEVICE_A000, + .ht_params = &iwl_a000_ht_params, + .nvm_ver = IWL_A000_NVM_VERSION, + .nvm_calib_ver = IWL_A000_TX_POWER_VERSION, + .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, +}; + MODULE_FIRMWARE(IWL_A000_HR_MODULE_FIRMWARE(IWL_A000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_A000_JF_MODULE_FIRMWARE(IWL_A000_UCODE_API_MAX)); diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h index 127017efdd87..c52623cb7c2a 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h @@ -462,6 +462,7 @@ extern const struct iwl_cfg iwl9560_2ac_cfg; extern const struct iwl_cfg iwla000_2ac_cfg_hr; extern const struct iwl_cfg iwla000_2ac_cfg_hr_cdb; extern const struct iwl_cfg iwla000_2ac_cfg_jf; +extern const struct iwl_cfg iwla000_2ax_cfg_hr; #endif /* CONFIG_IWLMVM */ #endif /* __IWL_CONFIG_H__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index a8fb77483313..e995b055be4e 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -539,6 +539,11 @@ static const struct pci_device_id iwl_hw_card_ids[] = { /* a000 Series */ {IWL_PCI_DEVICE(0x2720, 0x0A10, iwla000_2ac_cfg_hr_cdb)}, {IWL_PCI_DEVICE(0x34F0, 0x0310, iwla000_2ac_cfg_jf)}, + {IWL_PCI_DEVICE(0x2720, 0x0000, iwla000_2ax_cfg_hr)}, + {IWL_PCI_DEVICE(0x34F0, 0x0070, iwla000_2ax_cfg_hr)}, + {IWL_PCI_DEVICE(0x2720, 0x0078, iwla000_2ax_cfg_hr)}, + {IWL_PCI_DEVICE(0x2720, 0x0070, iwla000_2ax_cfg_hr)}, + {IWL_PCI_DEVICE(0x2720, 0x1080, iwla000_2ax_cfg_hr)}, #endif /* CONFIG_IWLMVM */ {0} From 4e37b063ad9f902052903c579b6f291ba329104e Mon Sep 17 00:00:00 2001 From: Tzipi Peres Date: Mon, 22 May 2017 16:16:52 +0300 Subject: [PATCH 15/46] iwlwifi: add twelve new 9560 series PCI IDs Add twelve new PCI IDs for the 9560 series. Signed-off-by: Tzipi Peres Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index e995b055be4e..7bf765ba5235 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -7,7 +7,7 @@ * * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH - * Copyright(c) 2016 Intel Deutschland GmbH + * Copyright(c) 2016-2017 Intel Deutschland GmbH * * 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 @@ -35,6 +35,7 @@ * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * All rights reserved. + * Copyright(c) 2017 Intel Deutschland GmbH * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -535,6 +536,18 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x31DC, 0x0030, iwl9560_2ac_cfg)}, {IWL_PCI_DEVICE(0x2526, 0x1030, iwl9560_2ac_cfg)}, {IWL_PCI_DEVICE(0xA370, 0x1030, iwl9560_2ac_cfg)}, + {IWL_PCI_DEVICE(0x9DF0, 0x0034, iwl9560_2ac_cfg)}, + {IWL_PCI_DEVICE(0xA370, 0x0034, iwl9560_2ac_cfg)}, + {IWL_PCI_DEVICE(0x31DC, 0x0034, iwl9560_2ac_cfg)}, + {IWL_PCI_DEVICE(0x2526, 0x0038, iwl9560_2ac_cfg)}, + {IWL_PCI_DEVICE(0x2526, 0x003C, iwl9560_2ac_cfg)}, + {IWL_PCI_DEVICE(0x9DF0, 0x0038, iwl9560_2ac_cfg)}, + {IWL_PCI_DEVICE(0xA370, 0x0038, iwl9560_2ac_cfg)}, + {IWL_PCI_DEVICE(0x31DC, 0x0038, iwl9560_2ac_cfg)}, + {IWL_PCI_DEVICE(0x9DF0, 0x003C, iwl9560_2ac_cfg)}, + {IWL_PCI_DEVICE(0xA370, 0x003C, iwl9560_2ac_cfg)}, + {IWL_PCI_DEVICE(0x31DC, 0x003C, iwl9560_2ac_cfg)}, + {IWL_PCI_DEVICE(0x2526, 0x0034, iwl9560_2ac_cfg)}, /* a000 Series */ {IWL_PCI_DEVICE(0x2720, 0x0A10, iwla000_2ac_cfg_hr_cdb)}, From 91109f42d0ad0c0c282d1fa1257a1548977aa895 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 26 May 2017 13:11:44 +0200 Subject: [PATCH 16/46] iwlwifi: mvm: use proper CDB check in PHY context modify When the firmware supports CDB, PHY contexts cannot be modified to change their band, but need to be added/remove instead. Instead of relying on iwl_mvm_has_new_tx_api(), check the right FW capa flag IWL_UCODE_TLV_CAPA_BINDING_CDB_SUPPORT and remove the comment. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c index d59efe804356..fb9eaf003ea5 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c @@ -255,8 +255,8 @@ int iwl_mvm_phy_ctxt_changed(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt, lockdep_assert_held(&mvm->mutex); - /* In CDB mode we cannot modify PHY context between bands so... */ - if (iwl_mvm_has_new_tx_api(mvm) && + if (fw_has_capa(&mvm->fw->ucode_capa, + IWL_UCODE_TLV_CAPA_BINDING_CDB_SUPPORT) && ctxt->channel->band != chandef->chan->band) { int ret; From a395058eb61c888ac5624cccb40eaedf77c01472 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 26 May 2017 11:16:39 +0200 Subject: [PATCH 17/46] iwlwifi: pcie: improve "invalid queue" warning Print out both queue IDs to be able to see what went wrong. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c index cd109740632d..6544facc2e0c 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c @@ -1129,8 +1129,12 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans, if (pkt->len_n_flags == cpu_to_le32(FH_RSCSR_FRAME_INVALID)) break; - WARN_ON((le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_RXQ_MASK) >> - FH_RSCSR_RXQ_POS != rxq->id); + WARN((le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_RXQ_MASK) >> + FH_RSCSR_RXQ_POS != rxq->id, + "frame on invalid queue - is on %d and indicates %d\n", + rxq->id, + (le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_RXQ_MASK) >> + FH_RSCSR_RXQ_POS); IWL_DEBUG_RX(trans, "cmd at offset %d: %s (%.2x.%2x, seq 0x%x)\n", From a58bb46855a019a204858cefd3e7d56f87f842f4 Mon Sep 17 00:00:00 2001 From: Liad Kaufman Date: Sun, 28 May 2017 14:20:04 +0300 Subject: [PATCH 18/46] iwlwifi: mvm: support aggs of 64 frames in A000 family A SCD bug was fixed in the A000 family, allowing to support aggregations of 64 frames (rather than 63). Signed-off-by: Liad Kaufman Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/rs.c | 6 +++++- drivers/net/wireless/intel/iwlwifi/mvm/rs.h | 2 ++ drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 11 +++++++++-- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c index a02dda8d9ea3..65beca3a457a 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c @@ -3233,7 +3233,11 @@ static void rs_build_rates_table_from_fixed(struct iwl_mvm *mvm, if (num_of_ant(ant) == 1) lq_cmd->single_stream_ant_msk = ant; - lq_cmd->agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF; + if (!mvm->trans->cfg->gen2) + lq_cmd->agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF; + else + lq_cmd->agg_frame_cnt_limit = + LINK_QUAL_AGG_FRAME_LIMIT_GEN2_DEF; } #endif /* CONFIG_MAC80211_DEBUGFS */ diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.h b/drivers/net/wireless/intel/iwlwifi/mvm/rs.h index 3abde1cb0303..32b4d66debea 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.h @@ -145,6 +145,8 @@ enum { #define LINK_QUAL_AGG_FRAME_LIMIT_DEF (63) #define LINK_QUAL_AGG_FRAME_LIMIT_MAX (63) +#define LINK_QUAL_AGG_FRAME_LIMIT_GEN2_DEF (64) +#define LINK_QUAL_AGG_FRAME_LIMIT_GEN2_MAX (64) #define LINK_QUAL_AGG_FRAME_LIMIT_MIN (0) #define LQ_SIZE 2 /* 2 mode tables: "Active" and "Search" */ diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c index 9ec427966533..ee7c978fe5ab 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c @@ -1354,7 +1354,10 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm, mvm_sta->mac_id_n_color = FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color); mvm_sta->vif = vif; - mvm_sta->max_agg_bufsize = LINK_QUAL_AGG_FRAME_LIMIT_DEF; + if (!mvm->trans->cfg->gen2) + mvm_sta->max_agg_bufsize = LINK_QUAL_AGG_FRAME_LIMIT_DEF; + else + mvm_sta->max_agg_bufsize = LINK_QUAL_AGG_FRAME_LIMIT_GEN2_DEF; mvm_sta->tx_protection = 0; mvm_sta->tt_tx_protection = false; mvm_sta->sta_type = sta->tdls ? IWL_STA_TDLS_LINK : IWL_STA_LINK; @@ -2677,7 +2680,11 @@ int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif, BUILD_BUG_ON((sizeof(mvmsta->agg_tids) * BITS_PER_BYTE) != IWL_MAX_TID_COUNT); - buf_size = min_t(int, buf_size, LINK_QUAL_AGG_FRAME_LIMIT_DEF); + if (!mvm->trans->cfg->gen2) + buf_size = min_t(int, buf_size, LINK_QUAL_AGG_FRAME_LIMIT_DEF); + else + buf_size = min_t(int, buf_size, + LINK_QUAL_AGG_FRAME_LIMIT_GEN2_DEF); spin_lock_bh(&mvmsta->lock); ssn = tid_data->ssn; From 3bfdee768c09bac3ee3e4b3a6d3b75cdc19e489c Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 29 May 2017 12:15:45 +0200 Subject: [PATCH 19/46] iwlwifi: pcie: improve debug in iwl_pcie_rx_handle_rb() Print the queue for the existing debug message and add a new debug message indicating where the RB ended. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c index 6544facc2e0c..1618a59a8a2f 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c @@ -1126,8 +1126,12 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans, pkt = rxb_addr(&rxcb); - if (pkt->len_n_flags == cpu_to_le32(FH_RSCSR_FRAME_INVALID)) + if (pkt->len_n_flags == cpu_to_le32(FH_RSCSR_FRAME_INVALID)) { + IWL_DEBUG_RX(trans, + "Q %d: RB end marker at offset %d\n", + rxq->id, offset); break; + } WARN((le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_RXQ_MASK) >> FH_RSCSR_RXQ_POS != rxq->id, @@ -1137,8 +1141,8 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans, FH_RSCSR_RXQ_POS); IWL_DEBUG_RX(trans, - "cmd at offset %d: %s (%.2x.%2x, seq 0x%x)\n", - rxcb._offset, + "Q %d: cmd at offset %d: %s (%.2x.%2x, seq 0x%x)\n", + rxq->id, offset, iwl_get_cmd_string(trans, iwl_cmd_id(pkt->hdr.cmd, pkt->hdr.group_id, From b3de3ef48aa3fe066150243f07d1cc4e6fac2c80 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Mon, 29 May 2017 14:01:06 +0300 Subject: [PATCH 20/46] iwlwifi: mvm: change when the BT_COEX is sent The BT_COEX command should not be sent to the INIT firmware image starting from 8000 family. The firmware team also requested to send the BT_COEX command after the PHY_DB_CMD and the PHY_CFG_CMD. While at it: s/iwl_send_bt_init_conf/iwl_mvm_send_bt_init_conf/ Signed-off-by: Emmanuel Grumbach Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/coex.c | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 16 +++++++++------- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 2 +- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/coex.c b/drivers/net/wireless/intel/iwlwifi/mvm/coex.c index fe7f1e424f55..34dd5c40ce77 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/coex.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/coex.c @@ -406,7 +406,7 @@ iwl_get_coex_type(struct iwl_mvm *mvm, const struct ieee80211_vif *vif) return ret; } -int iwl_send_bt_init_conf(struct iwl_mvm *mvm) +int iwl_mvm_send_bt_init_conf(struct iwl_mvm *mvm) { struct iwl_bt_coex_cmd bt_cmd = {}; u32 mode; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c index c3ab13ee4097..f87a43dad086 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c @@ -644,7 +644,7 @@ iwl_dbgfs_bt_force_ant_write(struct iwl_mvm *mvm, char *buf, modes_str[mvm->bt_force_ant_mode]); if (iwl_mvm_firmware_running(mvm)) - ret = iwl_send_bt_init_conf(mvm); + ret = iwl_mvm_send_bt_init_conf(mvm); else ret = 0; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index 273e19460016..07308912486a 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -836,9 +836,11 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) goto error; } - ret = iwl_send_bt_init_conf(mvm); - if (ret) - goto error; + if (mvm->cfg->device_family < IWL_DEVICE_FAMILY_8000) { + ret = iwl_mvm_send_bt_init_conf(mvm); + if (ret) + goto error; + } /* Read the NVM only at driver load time, no need to do this twice */ if (read_nvm) { @@ -1545,10 +1547,6 @@ int iwl_mvm_up(struct iwl_mvm *mvm) if (ret) goto error; - ret = iwl_send_bt_init_conf(mvm); - if (ret) - goto error; - /* Send phy db control command and then phy db calibration*/ if (!iwl_mvm_has_new_tx_api(mvm)) { ret = iwl_send_phy_db_data(mvm->phy_db); @@ -1560,6 +1558,10 @@ int iwl_mvm_up(struct iwl_mvm *mvm) goto error; } + ret = iwl_mvm_send_bt_init_conf(mvm); + if (ret) + goto error; + /* Init RSS configuration */ /* TODO - remove a000 disablement when we have RXQ config API */ if (iwl_mvm_has_new_rx_api(mvm) && !iwl_mvm_has_new_tx_api(mvm)) { diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 9b777b847e22..f2f1e04f471d 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -1680,7 +1680,7 @@ int iwl_mvm_exit_d0i3(struct iwl_op_mode *op_mode); int _iwl_mvm_exit_d0i3(struct iwl_mvm *mvm); /* BT Coex */ -int iwl_send_bt_init_conf(struct iwl_mvm *mvm); +int iwl_mvm_send_bt_init_conf(struct iwl_mvm *mvm); void iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb); void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif, From cba46988c0813cd9e74d6625af32f7043780dac3 Mon Sep 17 00:00:00 2001 From: Liad Kaufman Date: Thu, 13 Apr 2017 17:10:33 +0300 Subject: [PATCH 21/46] iwlwifi: mvm: support multi tid ba notif When receiving a BA_NOTIF on new TX API, it can contain BAs for several TIDs. Go over them and reclaim TX for every TID. Note that although the small API change, the API version still isn't bumped forward, as this NIC isn't still officially released. Signed-off-by: Liad Kaufman Signed-off-by: Luca Coelho --- .../wireless/intel/iwlwifi/mvm/fw-api-tx.h | 4 ++- drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 28 ++++++++----------- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-tx.h b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-tx.h index 9d2a991221cf..97d7eed32622 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-tx.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-tx.h @@ -668,13 +668,15 @@ struct iwl_mvm_ba_notif { * @q_num: TFD queue number * @tfd_index: Index of first un-acked frame in the TFD queue * @scd_queue: For debug only - the physical queue the TFD queue is bound to + * @tid: TID of the queue (0-7) * @reserved: reserved for alignment */ struct iwl_mvm_compressed_ba_tfd { __le16 q_num; __le16 tfd_index; u8 scd_queue; - u8 reserved[3]; + u8 tid; + u8 reserved[2]; } __packed; /* COMPRESSED_BA_TFD_API_S_VER_1 */ /** diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index c89bb453c496..627befb0d8d1 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c @@ -1813,6 +1813,7 @@ void iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb) if (iwl_mvm_has_new_tx_api(mvm)) { struct iwl_mvm_compressed_ba_notif *ba_res = (void *)pkt->data; + int i; sta_id = ba_res->sta_id; ba_info.status.ampdu_ack_len = (u8)le16_to_cpu(ba_res->done); @@ -1825,22 +1826,17 @@ void iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb) if (!le16_to_cpu(ba_res->tfd_cnt)) goto out; - /* - * TODO: - * When supporting multi TID aggregations - we need to move - * next_reclaimed to be per TXQ and not per TID or handle it - * in a different way. - * This will go together with SN and AddBA offload and cannot - * be handled properly for now. - */ - WARN_ON(le16_to_cpu(ba_res->ra_tid_cnt) != 1); - tid = ba_res->ra_tid[0].tid; - if (tid == IWL_MGMT_TID) - tid = IWL_MAX_TID_COUNT; - iwl_mvm_tx_reclaim(mvm, sta_id, tid, - (int)(le16_to_cpu(ba_res->tfd[0].q_num)), - le16_to_cpu(ba_res->tfd[0].tfd_index), - &ba_info, le32_to_cpu(ba_res->tx_rate)); + /* Free per TID */ + for (i = 0; i < le16_to_cpu(ba_res->tfd_cnt); i++) { + struct iwl_mvm_compressed_ba_tfd *ba_tfd = + &ba_res->tfd[i]; + + iwl_mvm_tx_reclaim(mvm, sta_id, ba_tfd->tid, + (int)(le16_to_cpu(ba_tfd->q_num)), + le16_to_cpu(ba_tfd->tfd_index), + &ba_info, + le32_to_cpu(ba_res->tx_rate)); + } out: IWL_DEBUG_TX_REPLY(mvm, From 3b37f4c99c93abf2cdde751a536190bde5a1283a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 30 May 2017 16:45:31 +0200 Subject: [PATCH 22/46] iwlwifi: unify external & internal modparam names Where possible (all except for "11n_disable", which isn't valid in C) rename the internal names for module parameters to be the same as the externally visible names, to aid finding their use etc. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c | 6 +++--- drivers/net/wireless/intel/iwlwifi/dvm/lib.c | 2 +- .../net/wireless/intel/iwlwifi/dvm/mac80211.c | 8 ++++---- drivers/net/wireless/intel/iwlwifi/dvm/main.c | 4 ++-- drivers/net/wireless/intel/iwlwifi/dvm/rx.c | 2 +- drivers/net/wireless/intel/iwlwifi/dvm/rxon.c | 2 +- drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 12 ++++++------ .../net/wireless/intel/iwlwifi/iwl-modparams.h | 16 ++++++++-------- drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 8 ++++---- drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c | 4 ++-- .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 6 +++--- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 8 ++++---- drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 4 ++-- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 2 +- 15 files changed, 43 insertions(+), 43 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c index 937be04c6c71..482ac8fdc67b 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c @@ -2308,10 +2308,10 @@ static ssize_t iwl_dbgfs_fw_restart_write(struct file *file, size_t count, loff_t *ppos) { struct iwl_priv *priv = file->private_data; - bool restart_fw = iwlwifi_mod_params.restart_fw; + bool fw_restart = iwlwifi_mod_params.fw_restart; int __maybe_unused ret; - iwlwifi_mod_params.restart_fw = true; + iwlwifi_mod_params.fw_restart = true; mutex_lock(&priv->mutex); @@ -2320,7 +2320,7 @@ static ssize_t iwl_dbgfs_fw_restart_write(struct file *file, mutex_unlock(&priv->mutex); - iwlwifi_mod_params.restart_fw = restart_fw; + iwlwifi_mod_params.fw_restart = fw_restart; return count; } diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/lib.c b/drivers/net/wireless/intel/iwlwifi/dvm/lib.c index 74e52f7c5aa1..2b6ffbc46fa5 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/lib.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/lib.c @@ -1157,7 +1157,7 @@ int iwlagn_suspend(struct iwl_priv *priv, struct cfg80211_wowlan *wowlan) if (ret) goto out; - if (!iwlwifi_mod_params.sw_crypto) { + if (!iwlwifi_mod_params.swcrypto) { /* mark all keys clear */ priv->ucode_key_table = 0; ctx->key_mapping_keys = 0; diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c index 444c74371929..82caae02dd09 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c @@ -138,7 +138,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, * packets, so enabling it with software crypto isn't safe) */ if (priv->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_MFP && - !iwlwifi_mod_params.sw_crypto) + !iwlwifi_mod_params.swcrypto) ieee80211_hw_set(hw, MFP_CAPABLE); hw->sta_data_size = sizeof(struct iwl_station_priv); @@ -171,7 +171,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, WIPHY_WOWLAN_DISCONNECT | WIPHY_WOWLAN_EAP_IDENTITY_REQ | WIPHY_WOWLAN_RFKILL_RELEASE; - if (!iwlwifi_mod_params.sw_crypto) + if (!iwlwifi_mod_params.swcrypto) priv->wowlan_support.flags |= WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | WIPHY_WOWLAN_GTK_REKEY_FAILURE; @@ -348,7 +348,7 @@ static void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw, { struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); - if (iwlwifi_mod_params.sw_crypto) + if (iwlwifi_mod_params.swcrypto) return; IWL_DEBUG_MAC80211(priv, "enter\n"); @@ -624,7 +624,7 @@ static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, IWL_DEBUG_MAC80211(priv, "enter\n"); - if (iwlwifi_mod_params.sw_crypto) { + if (iwlwifi_mod_params.swcrypto) { IWL_DEBUG_MAC80211(priv, "leave - hwcrypto disabled\n"); return -EOPNOTSUPP; } diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/main.c b/drivers/net/wireless/intel/iwlwifi/dvm/main.c index 4c8f9f1a5532..2acd94da9efe 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/main.c @@ -1371,7 +1371,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, /* is antenna coupling more than 35dB ? */ priv->bt_ant_couple_ok = - (iwlwifi_mod_params.ant_coupling > + (iwlwifi_mod_params.antenna_coupling > IWL_BT_ANTENNA_COUPLING_THRESHOLD) ? true : false; @@ -1958,7 +1958,7 @@ static void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) } if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) { - if (iwlwifi_mod_params.restart_fw) { + if (iwlwifi_mod_params.fw_restart) { IWL_DEBUG_FW_ERRORS(priv, "Restarting adapter due to uCode error.\n"); queue_work(priv->workqueue, &priv->restart); diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/rx.c b/drivers/net/wireless/intel/iwlwifi/dvm/rx.c index eaad7389b67c..c942830af2b5 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/rx.c @@ -639,7 +639,7 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv, } /* In case of HW accelerated crypto and bad decryption, drop */ - if (!iwlwifi_mod_params.sw_crypto && + if (!iwlwifi_mod_params.swcrypto && iwlagn_set_decrypted_flag(priv, hdr, ampdu_status, stats)) return; diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/rxon.c b/drivers/net/wireless/intel/iwlwifi/dvm/rxon.c index 087e579854ab..8f3e5586eda9 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/rxon.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/rxon.c @@ -1120,7 +1120,7 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) return 0; } - iwl_set_rxon_hwcrypto(priv, ctx, !iwlwifi_mod_params.sw_crypto); + iwl_set_rxon_hwcrypto(priv, ctx, !iwlwifi_mod_params.swcrypto); IWL_DEBUG_INFO(priv, "Going to commit RXON\n" diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c index c8d451474b64..b5ebd0fcfbf6 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c @@ -1615,11 +1615,11 @@ void iwl_drv_stop(struct iwl_drv *drv) /* shared module parameters */ struct iwl_mod_params iwlwifi_mod_params = { - .restart_fw = true, + .fw_restart = true, .bt_coex_active = true, .power_level = IWL_POWER_INDEX_1, .d0i3_disable = true, - .d0i3_entry_delay = 1000, + .d0i3_timeout = 1000, .uapsd_disable = IWL_DISABLE_UAPSD_BSS | IWL_DISABLE_UAPSD_P2P_CLIENT, /* the rest are 0 by default */ }; @@ -1711,7 +1711,7 @@ module_param_named(debug, iwlwifi_mod_params.debug_level, uint, MODULE_PARM_DESC(debug, "debug output mask"); #endif -module_param_named(swcrypto, iwlwifi_mod_params.sw_crypto, int, S_IRUGO); +module_param_named(swcrypto, iwlwifi_mod_params.swcrypto, int, S_IRUGO); MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])"); module_param_named(11n_disable, iwlwifi_mod_params.disable_11n, uint, S_IRUGO); MODULE_PARM_DESC(11n_disable, @@ -1720,10 +1720,10 @@ module_param_named(amsdu_size, iwlwifi_mod_params.amsdu_size, int, S_IRUGO); MODULE_PARM_DESC(amsdu_size, "amsdu size 0: 12K for multi Rx queue devices, 4K for other devices 1:4K 2:8K 3:12K (default 0)"); -module_param_named(fw_restart, iwlwifi_mod_params.restart_fw, bool, S_IRUGO); +module_param_named(fw_restart, iwlwifi_mod_params.fw_restart, bool, S_IRUGO); MODULE_PARM_DESC(fw_restart, "restart firmware in case of error (default true)"); -module_param_named(antenna_coupling, iwlwifi_mod_params.ant_coupling, +module_param_named(antenna_coupling, iwlwifi_mod_params.antenna_coupling, int, S_IRUGO); MODULE_PARM_DESC(antenna_coupling, "specify antenna coupling in dB (default: 0 dB)"); @@ -1782,7 +1782,7 @@ module_param_named(fw_monitor, iwlwifi_mod_params.fw_monitor, bool, S_IRUGO); MODULE_PARM_DESC(fw_monitor, "firmware monitor - to debug FW (default: false - needs lots of memory)"); -module_param_named(d0i3_timeout, iwlwifi_mod_params.d0i3_entry_delay, +module_param_named(d0i3_timeout, iwlwifi_mod_params.d0i3_timeout, uint, S_IRUGO); MODULE_PARM_DESC(d0i3_timeout, "Timeout to D0i3 entry when idle (ms)"); diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-modparams.h b/drivers/net/wireless/intel/iwlwifi/iwl-modparams.h index 0bd85e58cc2c..a41c46e63eb1 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-modparams.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-modparams.h @@ -102,32 +102,32 @@ enum iwl_uapsd_disable { * * Holds the module parameters * - * @sw_crypto: using hardware encryption, default = 0 + * @swcrypto: using hardware encryption, default = 0 * @disable_11n: disable 11n capabilities, default = 0, * use IWL_[DIS,EN]ABLE_HT_* constants * @amsdu_size: See &enum iwl_amsdu_size. - * @restart_fw: restart firmware, default = 1 + * @fw_restart: restart firmware, default = 1 * @bt_coex_active: enable bt coex, default = true * @led_mode: system default, default = 0 * @power_save: enable power save, default = false * @power_level: power level, default = 1 * @debug_level: levels are IWL_DL_* - * @ant_coupling: antenna coupling in dB, default = 0 + * @antenna_coupling: antenna coupling in dB, default = 0 * @nvm_file: specifies a external NVM file * @uapsd_disable: disable U-APSD, see &enum iwl_uapsd_disable, default = * IWL_DISABLE_UAPSD_BSS | IWL_DISABLE_UAPSD_P2P_CLIENT * @d0i3_disable: disable d0i3, default = 1, - * @d0i3_entry_delay: time to wait after no refs are taken before + * @d0i3_timeout: time to wait after no refs are taken before * entering D0i3 (in msecs) * @lar_disable: disable LAR (regulatory), default = 0 * @fw_monitor: allow to use firmware monitor * @disable_11ac: disable VHT capabilities, default = false. */ struct iwl_mod_params { - int sw_crypto; + int swcrypto; unsigned int disable_11n; int amsdu_size; - bool restart_fw; + bool fw_restart; bool bt_coex_active; int led_mode; bool power_save; @@ -135,11 +135,11 @@ struct iwl_mod_params { #ifdef CONFIG_IWLWIFI_DEBUG u32 debug_level; #endif - int ant_coupling; + int antenna_coupling; char *nvm_file; u32 uapsd_disable; bool d0i3_disable; - unsigned int d0i3_entry_delay; + unsigned int d0i3_timeout; bool lar_disable; bool fw_monitor; bool disable_11ac; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index ca2d11f4984e..5de19ea10575 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -83,7 +83,7 @@ void iwl_mvm_set_rekey_data(struct ieee80211_hw *hw, struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); - if (iwlwifi_mod_params.sw_crypto) + if (iwlwifi_mod_params.swcrypto) return; mutex_lock(&mvm->mutex); @@ -1054,7 +1054,7 @@ iwl_mvm_wowlan_config(struct iwl_mvm *mvm, return ret; } - if (!iwlwifi_mod_params.sw_crypto) { + if (!iwlwifi_mod_params.swcrypto) { /* * This needs to be unlocked due to lock ordering * constraints. Since we're in the suspend path @@ -1280,8 +1280,8 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, if (!unified_image) { iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN); - if (mvm->restart_fw > 0) { - mvm->restart_fw--; + if (mvm->fw_restart > 0) { + mvm->fw_restart--; ieee80211_restart_hw(mvm->hw); } } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c index f87a43dad086..78dde0a8d358 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c @@ -869,8 +869,8 @@ static ssize_t iwl_dbgfs_fw_restart_write(struct iwl_mvm *mvm, char *buf, mutex_lock(&mvm->mutex); /* allow one more restart that we're provoking here */ - if (mvm->restart_fw >= 0) - mvm->restart_fw++; + if (mvm->fw_restart >= 0) + mvm->fw_restart++; /* take the return value to make compiler happy - it will fail anyway */ ret = iwl_mvm_send_cmd_pdu(mvm, REPLY_ERROR, 0, 0, NULL); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index b98978d6cb21..1cfb4c72199a 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -493,7 +493,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) * firmware will interpret some mgmt packets, so enabling it * with software crypto isn't safe). */ - if (!iwlwifi_mod_params.sw_crypto) { + if (!iwlwifi_mod_params.swcrypto) { ieee80211_hw_set(hw, MFP_CAPABLE); mvm->ciphers[hw->wiphy->n_cipher_suites] = WLAN_CIPHER_SUITE_AES_CMAC; @@ -687,7 +687,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) WIPHY_WOWLAN_EAP_IDENTITY_REQ | WIPHY_WOWLAN_RFKILL_RELEASE | WIPHY_WOWLAN_NET_DETECT; - if (!iwlwifi_mod_params.sw_crypto) + if (!iwlwifi_mod_params.swcrypto) mvm->wowlan.flags |= WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | WIPHY_WOWLAN_GTK_REKEY_FAILURE | WIPHY_WOWLAN_4WAY_HANDSHAKE; @@ -2888,7 +2888,7 @@ static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw, int ret; u8 key_offset; - if (iwlwifi_mod_params.sw_crypto) { + if (iwlwifi_mod_params.swcrypto) { IWL_DEBUG_MAC80211(mvm, "leave - hwcrypto disabled\n"); return -EOPNOTSUPP; } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index f2f1e04f471d..e1f7d273d0bd 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -921,7 +921,7 @@ struct iwl_mvm { u8 vif_count; /* -1 for always, 0 for never, >0 for that many times */ - s8 restart_fw; + s8 fw_restart; u8 fw_dbg_conf; struct delayed_work fw_dump_wk; const struct iwl_mvm_dump_desc *fw_dump_desc; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 695d1aead89f..a0907762b0bf 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -594,7 +594,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, goto out_free; } - mvm->restart_fw = iwlwifi_mod_params.restart_fw ? -1 : 0; + mvm->fw_restart = iwlwifi_mod_params.fw_restart ? -1 : 0; if (!iwl_mvm_is_dqa_supported(mvm)) { mvm->last_agg_queue = mvm->cfg->base_params->num_of_queues - 1; @@ -1225,7 +1225,7 @@ void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error) * If WoWLAN fw asserted, don't restart either, mac80211 * can't recover this since we're already half suspended. */ - if (!mvm->restart_fw && fw_error) { + if (!mvm->fw_restart && fw_error) { iwl_mvm_fw_dbg_collect_desc(mvm, &iwl_mvm_dump_desc_assert, NULL); } else if (test_and_set_bit(IWL_MVM_STATUS_IN_HW_RESTART, @@ -1258,8 +1258,8 @@ void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error) /* don't let the transport/FW power down */ iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN); - if (fw_error && mvm->restart_fw > 0) - mvm->restart_fw--; + if (fw_error && mvm->fw_restart > 0) + mvm->fw_restart--; ieee80211_restart_hw(mvm->hw); } } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c index d48c2ecc0893..35e813bdfbe5 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c @@ -1695,7 +1695,7 @@ void iwl_mvm_report_scan_aborted(struct iwl_mvm *mvm) mvm->scan_uid_status[uid] = 0; } uid = iwl_mvm_scan_uid_by_status(mvm, IWL_MVM_SCAN_SCHED); - if (uid >= 0 && !mvm->restart_fw) { + if (uid >= 0 && !mvm->fw_restart) { ieee80211_sched_scan_stopped(mvm->hw); mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED; mvm->scan_uid_status[uid] = 0; @@ -1725,7 +1725,7 @@ void iwl_mvm_report_scan_aborted(struct iwl_mvm *mvm) * restarted. */ if ((mvm->scan_status & IWL_MVM_SCAN_SCHED) && - !mvm->restart_fw) { + !mvm->fw_restart) { ieee80211_sched_scan_stopped(mvm->hw); mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED; } diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index 7bf765ba5235..3ca0f374c081 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -723,7 +723,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pm_runtime_set_active(&pdev->dev); pm_runtime_set_autosuspend_delay(&pdev->dev, - iwlwifi_mod_params.d0i3_entry_delay); + iwlwifi_mod_params.d0i3_timeout); pm_runtime_use_autosuspend(&pdev->dev); /* We are not supposed to call pm_runtime_allow() by From 87fc030231b11a190f16d7162a141e2f162eae36 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 31 May 2017 13:15:18 +0200 Subject: [PATCH 23/46] iwlwifi: pcie: make ctxt-info free idempotent By setting the pointers to NULL at the end, these functions are made idempotent. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c index b1f43397bb59..00d1a5f048b3 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c @@ -103,6 +103,7 @@ static void iwl_pcie_ctxt_info_free_fw_img(struct iwl_trans *trans) kfree(dram->fw); dram->fw_cnt = 0; + dram->fw = NULL; } void iwl_pcie_ctxt_info_free_paging(struct iwl_trans *trans) @@ -124,6 +125,7 @@ void iwl_pcie_ctxt_info_free_paging(struct iwl_trans *trans) kfree(dram->paging); dram->paging_cnt = 0; + dram->paging = NULL; } static int iwl_pcie_ctxt_info_init_fw_sec(struct iwl_trans *trans, From f0fea2b728af737ec45d96a0279087a558ad9774 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 31 May 2017 13:19:10 +0200 Subject: [PATCH 24/46] iwlwifi: pcie: warn if paging is already initialized during init This appears to happen in some cases, like when iwlmvm is unloaded and loaded again without also unloading iwlwifi. Warn in this case and free the paging data to be able to continue without causing corruption and kernel crashes due to it (otherwise, paging data is overwritten, but dram->paging_cnt gets to be twice as big as it should be, and then an eventual free will crash.) Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c index 00d1a5f048b3..eddaca76d514 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c @@ -137,6 +137,11 @@ static int iwl_pcie_ctxt_info_init_fw_sec(struct iwl_trans *trans, struct iwl_context_info_dram *ctxt_dram = &ctxt_info->dram; int i, ret, lmac_cnt, umac_cnt, paging_cnt; + if (WARN(dram->paging, + "paging shouldn't already be initialized (%d pages)\n", + dram->paging_cnt)) + iwl_pcie_ctxt_info_free_paging(trans); + lmac_cnt = iwl_pcie_get_num_sections(fw, 0); /* add 1 due to separator */ umac_cnt = iwl_pcie_get_num_sections(fw, lmac_cnt + 1); From b092c9f25d45972cf401ad8bcfee2429bf189e2b Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 31 May 2017 14:14:51 +0200 Subject: [PATCH 25/46] iwlwifi: mvm: unconditionally stop device after init In commit b93b1fe3b532 ("iwlwifi: mvm: fix init_dbg flow to work as expected"), the code was changed to make the stop conditional on not having failed (and on not having init_dbg), which doesn't make sense - we should stop the device regardless of failures. Failure to do so is leading to the device being enabled when it shouldn't be, and - if it gets re-enabled later - the new context info code gets confused as paging data wasn't freed. Remove the invalid error condition again. Fixes: b93b1fe3b532 ("iwlwifi: mvm: fix init_dbg flow to work as expected") Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index a0907762b0bf..c1ce92f5306d 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -741,7 +741,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, mutex_lock(&mvm->mutex); iwl_mvm_ref(mvm, IWL_MVM_REF_INIT_UCODE); err = iwl_run_init_mvm_ucode(mvm, true); - if (!err || !iwlmvm_mod_params.init_dbg) + if (!iwlmvm_mod_params.init_dbg) iwl_mvm_stop_device(mvm); iwl_mvm_unref(mvm, IWL_MVM_REF_INIT_UCODE); mutex_unlock(&mvm->mutex); From 92c4dca6f5fd3d29d8c1daf02e210dd48dc756ac Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 7 Jun 2017 10:35:54 +0200 Subject: [PATCH 26/46] iwlwifi: mvm: fix deduplication start logic If the first frame on a given TID is received with seqno 0 and needed to be retransmitted, we erroneously drop it because the deduplication data is initialized to zero, and then comparing if (unlikely(ieee80211_has_retry(hdr->frame_control) && dup_data->last_seq[tid] == hdr->seq_ctrl && dup_data->last_sub_frame[tid] >= sub_frame_idx)) return true; will return in iwl_mvm_is_dup() since last_sub_frame is also set to zero, and sub_frame_idx is usually zero since this only covers the relatively rare case of A-MSDU. Fix this by initializing the last_seq array to 0xffff, which is an impossible value for hdr->seq_ctrl to have here because the lower four bits are the fragment number, and fragments aren't handled in this code but go to mac80211 instead. Fixes: a571f5f635ef ("iwlwifi: mvm: add duplicate packet detection per rx queue") Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c index ee7c978fe5ab..4df5f13fcdae 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c @@ -1402,11 +1402,24 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm, if (iwl_mvm_has_new_rx_api(mvm) && !test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) { + int q; + dup_data = kcalloc(mvm->trans->num_rx_queues, - sizeof(*dup_data), - GFP_KERNEL); + sizeof(*dup_data), GFP_KERNEL); if (!dup_data) return -ENOMEM; + /* + * Initialize all the last_seq values to 0xffff which can never + * compare equal to the frame's seq_ctrl in the check in + * iwl_mvm_is_dup() since the lower 4 bits are the fragment + * number and fragmented packets don't reach that function. + * + * This thus allows receiving a packet with seqno 0 and the + * retry bit set as the very first packet on a new TID. + */ + for (q = 0; q < mvm->trans->num_rx_queues; q++) + memset(dup_data[q].last_seq, 0xff, + sizeof(dup_data[q].last_seq)); mvm_sta->dup_data = dup_data; } From b4f489857aba0e066847dfd01b980578bbf921c9 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 1 Jun 2017 09:06:11 +0200 Subject: [PATCH 27/46] iwlwifi: mvm: rename iwl_shared_mem_cfg_v1 to the correct _v2 This structure represents V2, V1 has the three last fields missing. Rename it to be more accurate. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h | 6 +++--- drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h index 17475e269ef5..f3ca61ff9f58 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h @@ -724,7 +724,7 @@ enum iwl_system_subcmd_ids { /** * @SHARED_MEM_CFG_CMD: * response in &struct iwl_shared_mem_cfg or - * &struct iwl_shared_mem_cfg_v1 + * &struct iwl_shared_mem_cfg_v2 */ SHARED_MEM_CFG_CMD = 0x0, @@ -2546,7 +2546,7 @@ struct iwl_tdls_config_res { #define TX_FIFO_INTERNAL_MAX_NUM 6 /** - * struct iwl_shared_mem_cfg_v1 - Shared memory configuration information + * struct iwl_shared_mem_cfg_v2 - Shared memory configuration information * * @shared_mem_addr: shared memory addr (pre 8000 HW set to 0x0 as MARBH is not * accessible) @@ -2568,7 +2568,7 @@ struct iwl_tdls_config_res { * NOTE: on firmware that don't have IWL_UCODE_TLV_CAPA_EXTEND_SHARED_MEM_CFG * set, the last 3 members don't exist. */ -struct iwl_shared_mem_cfg_v1 { +struct iwl_shared_mem_cfg_v2 { __le32 shared_mem_addr; __le32 shared_mem_size; __le32 sample_buff_addr; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index 07308912486a..c5445be36701 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -955,7 +955,7 @@ static void iwl_mvm_parse_shared_mem_a000(struct iwl_mvm *mvm, static void iwl_mvm_parse_shared_mem(struct iwl_mvm *mvm, struct iwl_rx_packet *pkt) { - struct iwl_shared_mem_cfg_v1 *mem_cfg = (void *)pkt->data; + struct iwl_shared_mem_cfg_v2 *mem_cfg = (void *)pkt->data; int i; mvm->smem_cfg.num_lmacs = 1; From d962f9b1013b3209813b7b8038c2b9123a9626c4 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 1 Jun 2017 10:22:09 +0200 Subject: [PATCH 28/46] iwlwifi: create new subdirectory for FW interaction There's a lot of mvm code that really should be more generic and part of the iwlwifi module. Start by making a place to keep such code - in the new "fw" subdirectory - and already move the firmware related header files there. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/dvm/dev.h | 2 +- .../wireless/intel/iwlwifi/{iwl-fw-api.h => fw/api.h} | 0 .../iwlwifi/{iwl-fw-error-dump.h => fw/error-dump.h} | 0 .../intel/iwlwifi/{iwl-fw-file.h => fw/file.h} | 0 .../net/wireless/intel/iwlwifi/{iwl-fw.h => fw/img.h} | 10 +++++----- drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 2 +- drivers/net/wireless/intel/iwlwifi/iwl-trans.h | 4 ++-- drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.h | 4 ++-- drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 2 +- drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 2 +- 14 files changed, 17 insertions(+), 17 deletions(-) rename drivers/net/wireless/intel/iwlwifi/{iwl-fw-api.h => fw/api.h} (100%) rename drivers/net/wireless/intel/iwlwifi/{iwl-fw-error-dump.h => fw/error-dump.h} (100%) rename drivers/net/wireless/intel/iwlwifi/{iwl-fw-file.h => fw/file.h} (100%) rename drivers/net/wireless/intel/iwlwifi/{iwl-fw.h => fw/img.h} (98%) diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/dev.h b/drivers/net/wireless/intel/iwlwifi/dvm/dev.h index 8148df61a916..025db135b63c 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/dev.h +++ b/drivers/net/wireless/intel/iwlwifi/dvm/dev.h @@ -38,7 +38,7 @@ #include #include -#include "iwl-fw.h" +#include "fw/img.h" #include "iwl-eeprom-parse.h" #include "iwl-csr.h" #include "iwl-debug.h" diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-fw-api.h b/drivers/net/wireless/intel/iwlwifi/fw/api.h similarity index 100% rename from drivers/net/wireless/intel/iwlwifi/iwl-fw-api.h rename to drivers/net/wireless/intel/iwlwifi/fw/api.h diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-fw-error-dump.h b/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h similarity index 100% rename from drivers/net/wireless/intel/iwlwifi/iwl-fw-error-dump.h rename to drivers/net/wireless/intel/iwlwifi/fw/error-dump.h diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h similarity index 100% rename from drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h rename to drivers/net/wireless/intel/iwlwifi/fw/file.h diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-fw.h b/drivers/net/wireless/intel/iwlwifi/fw/img.h similarity index 98% rename from drivers/net/wireless/intel/iwlwifi/iwl-fw.h rename to drivers/net/wireless/intel/iwlwifi/fw/img.h index d323b70b510a..e6bc9cb60700 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-fw.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/img.h @@ -64,12 +64,12 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ -#ifndef __iwl_fw_h__ -#define __iwl_fw_h__ +#ifndef __iwl_fw_img_h__ +#define __iwl_fw_img_h__ #include -#include "iwl-fw-file.h" -#include "iwl-fw-error-dump.h" +#include "file.h" +#include "error-dump.h" /** * enum iwl_ucode_type @@ -339,4 +339,4 @@ iwl_get_ucode_image(const struct iwl_fw *fw, enum iwl_ucode_type ucode_type) return &fw->img[ucode_type]; } -#endif /* __iwl_fw_h__ */ +#endif /* __iwl_fw_img_h__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c index b5ebd0fcfbf6..6fdb5921e17f 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c @@ -76,7 +76,7 @@ #include "iwl-trans.h" #include "iwl-op-mode.h" #include "iwl-agn-hw.h" -#include "iwl-fw.h" +#include "fw/img.h" #include "iwl-config.h" #include "iwl-modparams.h" diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h index 57db6250a329..eb6842abb4c7 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h @@ -74,9 +74,9 @@ #include "iwl-debug.h" #include "iwl-config.h" -#include "iwl-fw.h" +#include "fw/img.h" #include "iwl-op-mode.h" -#include "iwl-fw-api.h" +#include "fw/api.h" /** * DOC: Transport layer - what is it ? diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c index 78dde0a8d358..61a5e34140db 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c @@ -73,7 +73,7 @@ #include "sta.h" #include "iwl-io.h" #include "debugfs.h" -#include "iwl-fw-error-dump.h" +#include "fw/error-dump.h" static ssize_t iwl_dbgfs_ctdp_budget_read(struct file *file, char __user *user_buf, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.h b/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.h index e9f1be9da7d4..4a5287a0c617 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.h @@ -65,8 +65,8 @@ #ifndef __mvm_fw_dbg_h__ #define __mvm_fw_dbg_h__ -#include "iwl-fw-file.h" -#include "iwl-fw-error-dump.h" +#include "fw/file.h" +#include "fw/error-dump.h" #include "mvm.h" void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index c5445be36701..80c42ef981c0 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -70,7 +70,7 @@ #include "iwl-trans.h" #include "iwl-op-mode.h" -#include "iwl-fw.h" +#include "fw/img.h" #include "iwl-debug.h" #include "iwl-csr.h" /* for iwl_mvm_rx_card_state_notif */ #include "iwl-io.h" /* for iwl_mvm_rx_card_state_notif */ diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 1cfb4c72199a..bcde1ba0f1c8 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -84,7 +84,7 @@ #include "iwl-eeprom-parse.h" #include "iwl-phy-db.h" #include "testmode.h" -#include "iwl-fw-error-dump.h" +#include "fw/error-dump.h" #include "iwl-prph.h" #include "iwl-nvm-parse.h" #include "fw-dbg.h" diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index e1f7d273d0bd..33979b48ac0a 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -81,7 +81,7 @@ #include "iwl-trans.h" #include "iwl-notif-wait.h" #include "iwl-eeprom-parse.h" -#include "iwl-fw-file.h" +#include "fw/file.h" #include "iwl-config.h" #include "sta.h" #include "fw-api.h" diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index c1ce92f5306d..d93f1fcdf879 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -71,7 +71,7 @@ #include "iwl-notif-wait.h" #include "iwl-trans.h" #include "iwl-op-mode.h" -#include "iwl-fw.h" +#include "fw/img.h" #include "iwl-debug.h" #include "iwl-drv.h" #include "iwl-modparams.h" diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index 5778ba2278d1..a7d0b5c5e4a0 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -80,7 +80,7 @@ #include "iwl-prph.h" #include "iwl-scd.h" #include "iwl-agn-hw.h" -#include "iwl-fw-error-dump.h" +#include "fw/error-dump.h" #include "internal.h" #include "iwl-fh.h" From 9fca9d5c9745a18f65a380dfc61cd07ee874c7e0 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 1 Jun 2017 10:32:17 +0200 Subject: [PATCH 29/46] iwlwifi: move notification wait into fw/ Move the notification wait code into the new fw interaction directory. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/Makefile | 2 +- drivers/net/wireless/intel/iwlwifi/dvm/dev.h | 2 +- .../intel/iwlwifi/{iwl-notif-wait.c => fw/notif-wait.c} | 2 +- .../intel/iwlwifi/{iwl-notif-wait.h => fw/notif-wait.h} | 0 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/time-event.c | 2 +- 7 files changed, 6 insertions(+), 6 deletions(-) rename drivers/net/wireless/intel/iwlwifi/{iwl-notif-wait.c => fw/notif-wait.c} (99%) rename drivers/net/wireless/intel/iwlwifi/{iwl-notif-wait.h => fw/notif-wait.h} (100%) diff --git a/drivers/net/wireless/intel/iwlwifi/Makefile b/drivers/net/wireless/intel/iwlwifi/Makefile index 411cb91c102f..7733fc41ce98 100644 --- a/drivers/net/wireless/intel/iwlwifi/Makefile +++ b/drivers/net/wireless/intel/iwlwifi/Makefile @@ -3,7 +3,6 @@ obj-$(CONFIG_IWLWIFI) += iwlwifi.o iwlwifi-objs += iwl-io.o iwlwifi-objs += iwl-drv.o iwlwifi-objs += iwl-debug.o -iwlwifi-objs += iwl-notif-wait.o iwlwifi-objs += iwl-eeprom-read.o iwl-eeprom-parse.o iwlwifi-objs += iwl-phy-db.o iwl-nvm-parse.o iwlwifi-objs += pcie/drv.o pcie/rx.o pcie/tx.o pcie/trans.o @@ -11,6 +10,7 @@ iwlwifi-objs += pcie/ctxt-info.o pcie/trans-gen2.o pcie/tx-gen2.o iwlwifi-$(CONFIG_IWLDVM) += iwl-1000.o iwl-2000.o iwl-5000.o iwl-6000.o iwlwifi-$(CONFIG_IWLMVM) += iwl-7000.o iwl-8000.o iwl-9000.o iwl-a000.o iwlwifi-objs += iwl-trans.o +iwlwifi-objs += fw/notif-wait.o iwlwifi-objs += $(iwlwifi-m) diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/dev.h b/drivers/net/wireless/intel/iwlwifi/dvm/dev.h index 025db135b63c..cceb4cd8e501 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/dev.h +++ b/drivers/net/wireless/intel/iwlwifi/dvm/dev.h @@ -44,7 +44,7 @@ #include "iwl-debug.h" #include "iwl-agn-hw.h" #include "iwl-op-mode.h" -#include "iwl-notif-wait.h" +#include "fw/notif-wait.h" #include "iwl-trans.h" #include "led.h" diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-notif-wait.c b/drivers/net/wireless/intel/iwlwifi/fw/notif-wait.c similarity index 99% rename from drivers/net/wireless/intel/iwlwifi/iwl-notif-wait.c rename to drivers/net/wireless/intel/iwlwifi/fw/notif-wait.c index 68412ff2112e..29bb92e3df59 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-notif-wait.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/notif-wait.c @@ -65,7 +65,7 @@ #include #include "iwl-drv.h" -#include "iwl-notif-wait.h" +#include "notif-wait.h" void iwl_notification_wait_init(struct iwl_notif_wait_data *notif_wait) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-notif-wait.h b/drivers/net/wireless/intel/iwlwifi/fw/notif-wait.h similarity index 100% rename from drivers/net/wireless/intel/iwlwifi/iwl-notif-wait.h rename to drivers/net/wireless/intel/iwlwifi/fw/notif-wait.h diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 33979b48ac0a..0f0cd6c9ce8b 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -79,7 +79,7 @@ #include "iwl-op-mode.h" #include "iwl-trans.h" -#include "iwl-notif-wait.h" +#include "fw/notif-wait.h" #include "iwl-eeprom-parse.h" #include "fw/file.h" #include "iwl-config.h" diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index d93f1fcdf879..32233cba6786 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -68,7 +68,7 @@ #include #include -#include "iwl-notif-wait.h" +#include "fw/notif-wait.h" #include "iwl-trans.h" #include "iwl-op-mode.h" #include "fw/img.h" diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c index 3e4fa853b44d..5a682722adce 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c @@ -66,7 +66,7 @@ #include #include -#include "iwl-notif-wait.h" +#include "fw/notif-wait.h" #include "iwl-trans.h" #include "fw-api.h" #include "time-event.h" From 650aaed3b30158f74c1f051a653da4f6eb3db205 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 1 Jun 2017 10:38:04 +0200 Subject: [PATCH 30/46] iwlwifi: move configuration into sub-directory Since we now support 8 device families, move their configuration files into a new subdirectory "cfg". Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/Makefile | 4 ++-- drivers/net/wireless/intel/iwlwifi/{iwl-1000.c => cfg/1000.c} | 0 drivers/net/wireless/intel/iwlwifi/{iwl-2000.c => cfg/2000.c} | 0 drivers/net/wireless/intel/iwlwifi/{iwl-5000.c => cfg/5000.c} | 0 drivers/net/wireless/intel/iwlwifi/{iwl-6000.c => cfg/6000.c} | 0 drivers/net/wireless/intel/iwlwifi/{iwl-7000.c => cfg/7000.c} | 0 drivers/net/wireless/intel/iwlwifi/{iwl-8000.c => cfg/8000.c} | 0 drivers/net/wireless/intel/iwlwifi/{iwl-9000.c => cfg/9000.c} | 0 drivers/net/wireless/intel/iwlwifi/{iwl-a000.c => cfg/a000.c} | 0 9 files changed, 2 insertions(+), 2 deletions(-) rename drivers/net/wireless/intel/iwlwifi/{iwl-1000.c => cfg/1000.c} (100%) rename drivers/net/wireless/intel/iwlwifi/{iwl-2000.c => cfg/2000.c} (100%) rename drivers/net/wireless/intel/iwlwifi/{iwl-5000.c => cfg/5000.c} (100%) rename drivers/net/wireless/intel/iwlwifi/{iwl-6000.c => cfg/6000.c} (100%) rename drivers/net/wireless/intel/iwlwifi/{iwl-7000.c => cfg/7000.c} (100%) rename drivers/net/wireless/intel/iwlwifi/{iwl-8000.c => cfg/8000.c} (100%) rename drivers/net/wireless/intel/iwlwifi/{iwl-9000.c => cfg/9000.c} (100%) rename drivers/net/wireless/intel/iwlwifi/{iwl-a000.c => cfg/a000.c} (100%) diff --git a/drivers/net/wireless/intel/iwlwifi/Makefile b/drivers/net/wireless/intel/iwlwifi/Makefile index 7733fc41ce98..20bd261223af 100644 --- a/drivers/net/wireless/intel/iwlwifi/Makefile +++ b/drivers/net/wireless/intel/iwlwifi/Makefile @@ -7,8 +7,8 @@ iwlwifi-objs += iwl-eeprom-read.o iwl-eeprom-parse.o iwlwifi-objs += iwl-phy-db.o iwl-nvm-parse.o iwlwifi-objs += pcie/drv.o pcie/rx.o pcie/tx.o pcie/trans.o iwlwifi-objs += pcie/ctxt-info.o pcie/trans-gen2.o pcie/tx-gen2.o -iwlwifi-$(CONFIG_IWLDVM) += iwl-1000.o iwl-2000.o iwl-5000.o iwl-6000.o -iwlwifi-$(CONFIG_IWLMVM) += iwl-7000.o iwl-8000.o iwl-9000.o iwl-a000.o +iwlwifi-$(CONFIG_IWLDVM) += cfg/1000.o cfg/2000.o cfg/5000.o cfg/6000.o +iwlwifi-$(CONFIG_IWLMVM) += cfg/7000.o cfg/8000.o cfg/9000.o cfg/a000.o iwlwifi-objs += iwl-trans.o iwlwifi-objs += fw/notif-wait.o diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-1000.c b/drivers/net/wireless/intel/iwlwifi/cfg/1000.c similarity index 100% rename from drivers/net/wireless/intel/iwlwifi/iwl-1000.c rename to drivers/net/wireless/intel/iwlwifi/cfg/1000.c diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-2000.c b/drivers/net/wireless/intel/iwlwifi/cfg/2000.c similarity index 100% rename from drivers/net/wireless/intel/iwlwifi/iwl-2000.c rename to drivers/net/wireless/intel/iwlwifi/cfg/2000.c diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-5000.c b/drivers/net/wireless/intel/iwlwifi/cfg/5000.c similarity index 100% rename from drivers/net/wireless/intel/iwlwifi/iwl-5000.c rename to drivers/net/wireless/intel/iwlwifi/cfg/5000.c diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-6000.c b/drivers/net/wireless/intel/iwlwifi/cfg/6000.c similarity index 100% rename from drivers/net/wireless/intel/iwlwifi/iwl-6000.c rename to drivers/net/wireless/intel/iwlwifi/cfg/6000.c diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-7000.c b/drivers/net/wireless/intel/iwlwifi/cfg/7000.c similarity index 100% rename from drivers/net/wireless/intel/iwlwifi/iwl-7000.c rename to drivers/net/wireless/intel/iwlwifi/cfg/7000.c diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-8000.c b/drivers/net/wireless/intel/iwlwifi/cfg/8000.c similarity index 100% rename from drivers/net/wireless/intel/iwlwifi/iwl-8000.c rename to drivers/net/wireless/intel/iwlwifi/cfg/8000.c diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-9000.c b/drivers/net/wireless/intel/iwlwifi/cfg/9000.c similarity index 100% rename from drivers/net/wireless/intel/iwlwifi/iwl-9000.c rename to drivers/net/wireless/intel/iwlwifi/cfg/9000.c diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-a000.c b/drivers/net/wireless/intel/iwlwifi/cfg/a000.c similarity index 100% rename from drivers/net/wireless/intel/iwlwifi/iwl-a000.c rename to drivers/net/wireless/intel/iwlwifi/cfg/a000.c From 4f2210ee8498faa3499a927f0a40027ff972ec3a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 1 Jun 2017 11:37:25 +0200 Subject: [PATCH 31/46] iwlwifi: mvm: remove version 2 of paging command Only a000-series devices were going to use this, but actually initialize using the context info, which includes paging, so this code is never invoked; remove it. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/mvm/fw-api.h | 25 ++---------- drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 39 ++++++------------- 2 files changed, 15 insertions(+), 49 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h index f3ca61ff9f58..3e297c95e8ff 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h @@ -326,7 +326,7 @@ enum iwl_legacy_cmds { /** * @FW_PAGING_BLOCK_CMD: - * &struct iwl_fw_paging_cmd or &struct iwl_fw_paging_cmd_v1 + * &struct iwl_fw_paging_cmd */ FW_PAGING_BLOCK_CMD = 0x4f, @@ -998,25 +998,6 @@ struct iwl_nvm_access_cmd { #define NUM_OF_FW_PAGING_BLOCKS 33 /* 32 for data and 1 block for CSS */ -/** - * struct iwl_fw_paging_cmd_v1 - paging layout - * - * (FW_PAGING_BLOCK_CMD = 0x4f) - * - * Send to FW the paging layout in the driver. - * - * @flags: various flags for the command - * @block_size: the block size in powers of 2 - * @block_num: number of blocks specified in the command. - * @device_phy_addr: virtual addresses from device side - */ -struct iwl_fw_paging_cmd_v1 { - __le32 flags; - __le32 block_size; - __le32 block_num; - __le32 device_phy_addr[NUM_OF_FW_PAGING_BLOCKS]; -} __packed; /* FW_PAGING_BLOCK_CMD_API_S_VER_1 */ - /** * struct iwl_fw_paging_cmd - paging layout * @@ -1033,8 +1014,8 @@ struct iwl_fw_paging_cmd { __le32 flags; __le32 block_size; __le32 block_num; - __le64 device_phy_addr[NUM_OF_FW_PAGING_BLOCKS]; -} __packed; /* FW_PAGING_BLOCK_CMD_API_S_VER_2 */ + __le32 device_phy_addr[NUM_OF_FW_PAGING_BLOCKS]; +} __packed; /* FW_PAGING_BLOCK_CMD_API_S_VER_1 */ /* * Fw items ID's diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index 80c42ef981c0..79e7a7a285dc 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -384,44 +384,29 @@ static int iwl_save_fw_paging(struct iwl_mvm *mvm, /* send paging cmd to FW in case CPU2 has paging image */ static int iwl_send_paging_cmd(struct iwl_mvm *mvm, const struct fw_img *fw) { - union { - struct iwl_fw_paging_cmd v2; - struct iwl_fw_paging_cmd_v1 v1; - } paging_cmd = { - .v2.flags = - cpu_to_le32(PAGING_CMD_IS_SECURED | - PAGING_CMD_IS_ENABLED | - (mvm->num_of_pages_in_last_blk << - PAGING_CMD_NUM_OF_PAGES_IN_LAST_GRP_POS)), - .v2.block_size = cpu_to_le32(BLOCK_2_EXP_SIZE), - .v2.block_num = cpu_to_le32(mvm->num_of_paging_blk), + struct iwl_fw_paging_cmd paging_cmd = { + .flags = cpu_to_le32(PAGING_CMD_IS_SECURED | + PAGING_CMD_IS_ENABLED | + (mvm->num_of_pages_in_last_blk << + PAGING_CMD_NUM_OF_PAGES_IN_LAST_GRP_POS)), + .block_size = cpu_to_le32(BLOCK_2_EXP_SIZE), + .block_num = cpu_to_le32(mvm->num_of_paging_blk), }; - int blk_idx, size = sizeof(paging_cmd.v2); - - /* A bit hard coded - but this is the old API and will be deprecated */ - if (!iwl_mvm_has_new_tx_api(mvm)) - size = sizeof(paging_cmd.v1); + int blk_idx; /* loop for for all paging blocks + CSS block */ for (blk_idx = 0; blk_idx < mvm->num_of_paging_blk + 1; blk_idx++) { dma_addr_t addr = mvm->fw_paging_db[blk_idx].fw_paging_phys; + __le32 phy_addr; addr = addr >> PAGE_2_EXP_SIZE; - - if (iwl_mvm_has_new_tx_api(mvm)) { - __le64 phy_addr = cpu_to_le64(addr); - - paging_cmd.v2.device_phy_addr[blk_idx] = phy_addr; - } else { - __le32 phy_addr = cpu_to_le32(addr); - - paging_cmd.v1.device_phy_addr[blk_idx] = phy_addr; - } + phy_addr = cpu_to_le32(addr); + paging_cmd.device_phy_addr[blk_idx] = phy_addr; } return iwl_mvm_send_cmd_pdu(mvm, iwl_cmd_id(FW_PAGING_BLOCK_CMD, IWL_ALWAYS_LONG_GROUP, 0), - 0, size, &paging_cmd); + 0, sizeof(paging_cmd), &paging_cmd); } /* From e6835942a7414ef4fd07b59851ad1fca7560dec1 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 12 Jun 2017 11:24:06 +0200 Subject: [PATCH 32/46] iwlwifi: mvm: quietly accept non-sta assoc response frames When hostapd adds a station, it does so before sending the association response frame, so that it can indicate the correct status code in the response. However, when this then fails, or the association response already is a reject for some other reason, then there's no station entry and thus no per-station management queue to send the response on and it must be sent on the probe response queue. The code should therefore not warn. In theory, we could check and warn if the status code is success, but that seems excessive, so just relax the check to allow any association response frames. Fixes: 3ee0f0e23e4f ("iwlwifi: mvm: fix DQA AP mode station assumption") Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index 627befb0d8d1..214829e5a860 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c @@ -554,12 +554,15 @@ static int iwl_mvm_get_ctrl_vif_queue(struct iwl_mvm *mvm, case NL80211_IFTYPE_AP: case NL80211_IFTYPE_ADHOC: /* - * Handle legacy hostapd as well, where station may be added - * only after assoc. Take care of the case where we send a - * deauth to a station that we don't have. + * Handle legacy hostapd as well, where station will be added + * only just before sending the association response. + * Also take care of the case where we send a deauth to a + * station that we don't have, or similarly an association + * response (with non-success status) for a station we can't + * accept. */ if (ieee80211_is_probe_resp(fc) || ieee80211_is_auth(fc) || - ieee80211_is_deauth(fc)) + ieee80211_is_deauth(fc) || ieee80211_is_assoc_resp(fc)) return mvm->probe_queue; if (info->hw_queue == info->control.vif->cab_queue) return info->hw_queue; From c42ff65da8167fa486bfcb7ea290cbdee8350aa7 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 13 Jun 2017 21:19:47 +0200 Subject: [PATCH 33/46] iwlwifi: pcie: add MSI-X interrupt tracing We have tracing for both pre-ICT and ICT interrupts, including all the data read there. Extend the tracing to MSI-X interrupts. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- .../wireless/intel/iwlwifi/iwl-devtrace-io.h | 26 ++++++++++++++++++- drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 4 +++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-io.h b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-io.h index 1dccae6532cf..4164dc1745ed 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-io.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-io.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved. - * Copyright(c) 2016 Intel Deutschland GmbH + * Copyright(c) 2016-2017 Intel Deutschland GmbH * * 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 @@ -29,6 +29,7 @@ #define __IWLWIFI_DEVICE_TRACE_IO #include +#include #undef TRACE_SYSTEM #define TRACE_SYSTEM iwlwifi_io @@ -165,6 +166,29 @@ TRACE_EVENT(iwlwifi_dev_irq, TP_printk("%d", 0) ); +TRACE_EVENT(iwlwifi_dev_irq_msix, + TP_PROTO(const struct device *dev, struct msix_entry *msix_entry, + bool defirq, u32 inta_fh, u32 inta_hw), + TP_ARGS(dev, msix_entry, defirq, inta_fh, inta_hw), + TP_STRUCT__entry( + DEV_ENTRY + __field(u32, entry) + __field(u8, defirq) + __field(u32, inta_fh) + __field(u32, inta_hw) + ), + TP_fast_assign( + DEV_ASSIGN; + __entry->entry = msix_entry->entry; + __entry->defirq = defirq; + __entry->inta_fh = inta_fh; + __entry->inta_hw = inta_hw; + ), + TP_printk("entry:%d defirq:%d fh:0x%x, hw:0x%x", + __entry->entry, __entry->defirq, + __entry->inta_fh, __entry->inta_hw) +); + TRACE_EVENT(iwlwifi_dev_ict_read, TP_PROTO(const struct device *dev, u32 index, u32 value), TP_ARGS(dev, index, value), diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c index 1618a59a8a2f..351c4423125a 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c @@ -1391,6 +1391,8 @@ irqreturn_t iwl_pcie_irq_rx_msix_handler(int irq, void *dev_id) struct iwl_trans_pcie *trans_pcie = iwl_pcie_get_trans_pcie(entry); struct iwl_trans *trans = trans_pcie->trans; + trace_iwlwifi_dev_irq_msix(trans->dev, entry, false, 0, 0); + if (WARN_ON(entry->entry >= trans->num_rx_queues)) return IRQ_NONE; @@ -1932,6 +1934,8 @@ irqreturn_t iwl_pcie_irq_msix_handler(int irq, void *dev_id) iwl_write32(trans, CSR_MSIX_HW_INT_CAUSES_AD, inta_hw); spin_unlock(&trans_pcie->irq_lock); + trace_iwlwifi_dev_irq_msix(trans->dev, entry, true, inta_fh, inta_hw); + if (unlikely(!(inta_fh | inta_hw))) { IWL_DEBUG_ISR(trans, "Ignore interrupt, inta == 0\n"); lock_map_release(&trans->sync_cmd_lockdep_map); From 275896ab5fbffcbe9d148ec054efe1af3fb4a29d Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 19 Jun 2017 13:24:49 +0200 Subject: [PATCH 34/46] iwlwifi: mvm: properly enable IP header checksumming The code was intended to enable IP header checksumming on AMSDUs, but failed to really do so because the A-MSDU bit was set after all the checksumming bits, and thus checking for A-MSDU could never be true. Fix this by setting the A-MSDU bit before the offload bits. Fixes: 5e6a98dc4863 ("iwlwifi: mvm: enable TCP/UDP checksum support for 9000 family") Reported-by: Emmanuel Grumbach Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index 214829e5a860..419d0351e0ef 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c @@ -105,9 +105,9 @@ iwl_mvm_bar_check_trigger(struct iwl_mvm *mvm, const u8 *addr, static u16 iwl_mvm_tx_csum(struct iwl_mvm *mvm, struct sk_buff *skb, struct ieee80211_hdr *hdr, - struct ieee80211_tx_info *info) + struct ieee80211_tx_info *info, + u16 offload_assist) { - u16 offload_assist = 0; #if IS_ENABLED(CONFIG_INET) u16 mh_len = ieee80211_hdrlen(hdr->frame_control); u8 protocol = 0; @@ -207,6 +207,7 @@ void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb, __le16 fc = hdr->frame_control; u32 tx_flags = le32_to_cpu(tx_cmd->tx_flags); u32 len = skb->len + FCS_LEN; + u16 offload_assist = 0; u8 ac; if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) @@ -225,8 +226,7 @@ void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb, tx_cmd->tid_tspec = qc[0] & 0xf; tx_flags &= ~TX_CMD_FLG_SEQ_CTL; if (*qc & IEEE80211_QOS_CTL_A_MSDU_PRESENT) - tx_cmd->offload_assist |= - cpu_to_le16(BIT(TX_CMD_OFFLD_AMSDU)); + offload_assist |= BIT(TX_CMD_OFFLD_AMSDU); } else if (ieee80211_is_back_req(fc)) { struct ieee80211_bar *bar = (void *)skb->data; u16 control = le16_to_cpu(bar->control); @@ -291,11 +291,12 @@ void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb, /* padding is inserted later in transport */ if (ieee80211_hdrlen(fc) % 4 && - !(tx_cmd->offload_assist & cpu_to_le16(BIT(TX_CMD_OFFLD_AMSDU)))) - tx_cmd->offload_assist |= cpu_to_le16(BIT(TX_CMD_OFFLD_PAD)); + !(offload_assist & BIT(TX_CMD_OFFLD_AMSDU))) + offload_assist |= BIT(TX_CMD_OFFLD_PAD); tx_cmd->offload_assist |= - cpu_to_le16(iwl_mvm_tx_csum(mvm, skb, hdr, info)); + cpu_to_le16(iwl_mvm_tx_csum(mvm, skb, hdr, info, + offload_assist)); } static u32 iwl_mvm_get_tx_rate(struct iwl_mvm *mvm, @@ -481,7 +482,7 @@ iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb, if (iwl_mvm_has_new_tx_api(mvm)) { struct iwl_tx_cmd_gen2 *cmd = (void *)dev_cmd->payload; - u16 offload_assist = iwl_mvm_tx_csum(mvm, skb, hdr, info); + u16 offload_assist = 0; if (ieee80211_is_data_qos(hdr->frame_control)) { u8 *qc = ieee80211_get_qos_ctl(hdr); @@ -490,6 +491,9 @@ iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb, offload_assist |= BIT(TX_CMD_OFFLD_AMSDU); } + offload_assist = iwl_mvm_tx_csum(mvm, skb, hdr, info, + offload_assist); + /* padding is inserted later in transport */ if (ieee80211_hdrlen(hdr->frame_control) % 4 && !(offload_assist & BIT(TX_CMD_OFFLD_AMSDU))) From 37e474acc9b6f645d92d8dc35014ff1baed3b1bc Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 19 Jun 2017 22:31:56 +0200 Subject: [PATCH 35/46] iwlwifi: mvm: fix mac80211 queue tracking In the driver, we track which hardware queue is associated with which mac80211 "hw_queue", in order to be able to stop and wake it. When moving these bitmaps out of the queue_info structures, the type of the bitmap was erroneously changed from u32 to u8, presumably in order to save memory. Turns out that u32 isn't needed, because the highest queue we can ever tell mac80211 is always < 16, but a u16 definitely is needed, queues >=8 do happen. While at it, throw a BUILD_BUG_ON() into the place where we set the limit (mvm->first_agg_queue) and a warning when it actually gets put into the bitmap. The consequence of this bug is that full HW queues associated with such a too-high mac80211 number never stop higher layer queues when full, and thus would simply drop all packets that couldn't be enqueued to the hardware queue. Fixes: 34e10860ae8d ("iwlwifi: mvm: remove references to queue_info in new TX path") Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 4 ++++ drivers/net/wireless/intel/iwlwifi/mvm/utils.c | 8 +++++++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 0f0cd6c9ce8b..6b8f7817391d 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -789,7 +789,7 @@ struct iwl_mvm { u64 on_time_scan; } radio_stats, accu_radio_stats; - u8 hw_queue_to_mac80211[IWL_MAX_TVQM_QUEUES]; + u16 hw_queue_to_mac80211[IWL_MAX_TVQM_QUEUES]; struct { u8 hw_queue_refcount; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 32233cba6786..1799a3d367f9 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -602,9 +602,13 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, if (mvm->cfg->base_params->num_of_queues == 16) { mvm->aux_queue = 11; mvm->first_agg_queue = 12; + BUILD_BUG_ON(BITS_PER_BYTE * + sizeof(mvm->hw_queue_to_mac80211[0]) < 12); } else { mvm->aux_queue = 15; mvm->first_agg_queue = 16; + BUILD_BUG_ON(BITS_PER_BYTE * + sizeof(mvm->hw_queue_to_mac80211[0]) < 16); } } else { mvm->aux_queue = IWL_MVM_DQA_AUX_QUEUE; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c index 0093e78dd571..bd2596fdafda 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c @@ -698,7 +698,13 @@ static bool iwl_mvm_update_txq_mapping(struct iwl_mvm *mvm, int queue, if (mvm->queue_info[queue].hw_queue_refcount > 0) enable_queue = false; - mvm->hw_queue_to_mac80211[queue] |= BIT(mac80211_queue); + if (mac80211_queue != IEEE80211_INVAL_HW_QUEUE) { + WARN(mac80211_queue >= + BITS_PER_BYTE * sizeof(mvm->hw_queue_to_mac80211[0]), + "cannot track mac80211 queue %d (queue %d, sta %d, tid %d)\n", + mac80211_queue, queue, sta_id, tid); + mvm->hw_queue_to_mac80211[queue] |= BIT(mac80211_queue); + } mvm->queue_info[queue].hw_queue_refcount++; mvm->queue_info[queue].tid_bitmap |= BIT(tid); From b0129db4f0669eb5d7c79031ac54e746f470e45a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 19 Jun 2017 22:48:32 +0200 Subject: [PATCH 36/46] iwlwifi: mvm: map cab_queue to real one earlier There may be a difference between the mac80211 vif->cab_queue and mvmvif->cab_queue, particularly with TVQM. Make the code map this earlier, instead of first returning the mac80211 one again from iwl_mvm_get_ctrl_vif_queue(). Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index 419d0351e0ef..12a35af66918 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c @@ -551,9 +551,13 @@ static void iwl_mvm_skb_prepare_status(struct sk_buff *skb, static int iwl_mvm_get_ctrl_vif_queue(struct iwl_mvm *mvm, struct ieee80211_tx_info *info, __le16 fc) { + struct iwl_mvm_vif *mvmvif; + if (!iwl_mvm_is_dqa_supported(mvm)) return info->hw_queue; + mvmvif = iwl_mvm_vif_from_mac80211(info->control.vif); + switch (info->control.vif->type) { case NL80211_IFTYPE_AP: case NL80211_IFTYPE_ADHOC: @@ -569,7 +573,7 @@ static int iwl_mvm_get_ctrl_vif_queue(struct iwl_mvm *mvm, ieee80211_is_deauth(fc) || ieee80211_is_assoc_resp(fc)) return mvm->probe_queue; if (info->hw_queue == info->control.vif->cab_queue) - return info->hw_queue; + return mvmvif->cab_queue; WARN_ONCE(info->control.vif->type != NL80211_IFTYPE_ADHOC, "fc=0x%02x", le16_to_cpu(fc)); @@ -578,7 +582,7 @@ static int iwl_mvm_get_ctrl_vif_queue(struct iwl_mvm *mvm, if (ieee80211_is_mgmt(fc)) return mvm->p2p_dev_queue; if (info->hw_queue == info->control.vif->cab_queue) - return info->hw_queue; + return mvmvif->cab_queue; WARN_ON_ONCE(1); return mvm->p2p_dev_queue; @@ -645,9 +649,6 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb) hdr->frame_control); if (queue < 0) return -1; - - if (queue == info.control.vif->cab_queue) - queue = mvmvif->cab_queue; } else if (info.control.vif->type == NL80211_IFTYPE_STATION && is_multicast_ether_addr(hdr->addr1)) { u8 ap_sta_id = ACCESS_ONCE(mvmvif->ap_sta_id); From 32026e8f709ff29bd00cce58036da8381eaa7592 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 19 Jun 2017 23:26:55 +0200 Subject: [PATCH 37/46] iwlwifi: mvm: fix mac80211's hw_queue in DQA mode When in non-DQA mode, mac80211 actually gets a pretty much perfect idea (in vif->hw_queue/cab_queue) of which queues we're using. But in DQA mode, this isn't true - nonetheless, we were adding all the queues, even the ones stations are using, to the queue allocation bitmap. Fix this, we should only add the queues we really are using in DQA mode: * IWL_MVM_OFFCHANNEL_QUEUE, as we use this in both modes * mvm->aux_queue, as we use this in both modes - mac80211 never really knows about it but we use it as a cookie internally, so can't reuse it * possibly the GCAST queue (cab_queue) * all the "queues" we told mac80211 about we were using on each interface (vif->hw_queue), these are entirely virtual in this mode Also add back the failure now when we can't allocate any more of these - now virtual - queues; this was skipped in DQA mode and would lead to having multiple ACs or even interfaces use the same queue number in mac80211 (10, since that's the limit), which would stop far too many queues if stopped. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/mvm/mac-ctxt.c | 32 +++++++++++++++---- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c index 71f23ac608eb..dc631b23e189 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c @@ -257,7 +257,7 @@ unsigned long iwl_mvm_get_used_hw_queues(struct iwl_mvm *mvm, }; if (iwl_mvm_is_dqa_supported(mvm)) - data.used_hw_queues |= BIT(IWL_MVM_DQA_CMD_QUEUE); + data.used_hw_queues |= BIT(IWL_MVM_DQA_GCAST_QUEUE); else data.used_hw_queues |= BIT(IWL_MVM_CMD_QUEUE); @@ -268,6 +268,14 @@ unsigned long iwl_mvm_get_used_hw_queues(struct iwl_mvm *mvm, mvm->hw, IEEE80211_IFACE_ITER_RESUME_ALL, iwl_mvm_iface_hw_queues_iter, &data); + /* + * for DQA, the hw_queue in mac80211 is never really used for + * real traffic (only the few queue IDs covered above), so + * we can reuse the real HW queue IDs the stations use + */ + if (iwl_mvm_is_dqa_supported(mvm)) + return data.used_hw_queues; + /* don't assign the same hw queues as TDLS stations */ ieee80211_iterate_stations_atomic(mvm->hw, iwl_mvm_mac_sta_hw_queues_iter, @@ -344,7 +352,7 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm, .found_vif = false, }; u32 ac; - int ret, i; + int ret, i, queue_limit; unsigned long used_hw_queues; /* @@ -430,17 +438,29 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm, return 0; } + if (iwl_mvm_is_dqa_supported(mvm)) { + /* + * queues in mac80211 almost entirely independent of + * the ones here - no real limit + */ + queue_limit = IEEE80211_MAX_QUEUES; + BUILD_BUG_ON(IEEE80211_MAX_QUEUES > + BITS_PER_BYTE * + sizeof(mvm->hw_queue_to_mac80211[0])); + } else { + /* need to not use too many in this case */ + queue_limit = mvm->first_agg_queue; + } + /* * Find available queues, and allocate them to the ACs. When in * DQA-mode they aren't really used, and this is done only so the * mac80211 ieee80211_check_queues() function won't fail */ for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { - u8 queue = find_first_zero_bit(&used_hw_queues, - mvm->first_agg_queue); + u8 queue = find_first_zero_bit(&used_hw_queues, queue_limit); - if (!iwl_mvm_is_dqa_supported(mvm) && - queue >= mvm->first_agg_queue) { + if (queue >= queue_limit) { IWL_ERR(mvm, "Failed to allocate queue\n"); ret = -EIO; goto exit_fail; From 4f555e602b42826b3d79081c9ef8b8e8fe29fc49 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 20 Jun 2017 16:05:30 +0300 Subject: [PATCH 38/46] iwlwifi: mvm: don't send fetch the TID from a non-QoS packet in TSO Getting the TID of a packet before we know it is a QoS data packet isn't a good idea. Delay the TID retrieval until we know the packet is a QoS data packet. Fixes: bb81bb68f472 ("iwlwifi: mvm: add Tx A-MSDU inside A-MPDU") Signed-off-by: Emmanuel Grumbach Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index 12a35af66918..172f0aa8d019 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c @@ -715,11 +715,6 @@ static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb, snap_ip_tcp = 8 + skb_transport_header(skb) - skb_network_header(skb) + tcp_hdrlen(skb); - qc = ieee80211_get_qos_ctl(hdr); - tid = *qc & IEEE80211_QOS_CTL_TID_MASK; - if (WARN_ON_ONCE(tid >= IWL_MAX_TID_COUNT)) - return -EINVAL; - dbg_max_amsdu_len = ACCESS_ONCE(mvm->max_amsdu_len); if (!sta->max_amsdu_len || @@ -730,6 +725,11 @@ static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb, goto segment; } + qc = ieee80211_get_qos_ctl(hdr); + tid = *qc & IEEE80211_QOS_CTL_TID_MASK; + if (WARN_ON_ONCE(tid >= IWL_MAX_TID_COUNT)) + return -EINVAL; + /* * Do not build AMSDU for IPv6 with extension headers. * ask stack to segment and checkum the generated MPDUs for us. From 52848a79b9d2d6773160221e7ea1e1500954de84 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 20 Jun 2017 12:51:30 +0200 Subject: [PATCH 39/46] iwlwifi: pcie: reconfigure MSI-X HW on resume When going into suspend, the HW configuration for MSI-X will likely be lost. As a consequence, after waking up, all IRQ causes will be mapped to interrupt 0, and as a consequence we don't notice the interrupt because in most cases this is an interrupt for a queue, and getting it doesn't read the other cause registers. Fixes: 2e5d4a8f61dc ("iwlwifi: pcie: Add new configuration to enable MSIX") Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index 3ca0f374c081..f16c1bb9bf94 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -799,6 +799,9 @@ static int iwl_pci_resume(struct device *device) if (!trans->op_mode) return 0; + /* reconfigure the MSI-X mapping to get the correct IRQ for rfkill */ + iwl_pcie_conf_msix_hw(trans_pcie); + /* * Enable rfkill interrupt (in order to keep track of the rfkill * status). Must be locked to avoid processing a possible rfkill From 6344436e9d3f4fb4878c12169477d4beb5b825ea Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Wed, 21 Jun 2017 09:40:15 +0300 Subject: [PATCH 40/46] iwlwifi: mvm: don't mess the SNAP header in TSO for non-QoS packets When we get large sends on non-QoS association, we had a bug that mangled the SNAP header. Fix that. Fixes: a6d5e32f247c ("iwlwifi: mvm: send large SKBs to the transport") Signed-off-by: Emmanuel Grumbach Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index 172f0aa8d019..584ddc39d5f7 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c @@ -849,11 +849,13 @@ static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb, if (tcp_payload_len > mss) { skb_shinfo(tmp)->gso_size = mss; } else { - qc = ieee80211_get_qos_ctl((void *)tmp->data); + if (ieee80211_is_data_qos(hdr->frame_control)) { + qc = ieee80211_get_qos_ctl((void *)tmp->data); - if (ipv4) - ip_send_check(ip_hdr(tmp)); - *qc &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT; + if (ipv4) + ip_send_check(ip_hdr(tmp)); + *qc &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT; + } skb_shinfo(tmp)->gso_size = 0; } From 6e46496302df7e63158fa1476cf9a30d5ee59dee Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 22 Jun 2017 13:06:21 +0200 Subject: [PATCH 41/46] iwlwifi: mvm: remove DQA non-STA client mode special case When we get a non-STA frame to transmit in client mode, we try to use the IWL_MVM_DQA_BSS_CLIENT_QUEUE queue (queue #4). However, at this point, the queue might not be allocated at all, causing warnings. The scenario on which this happened was a race condition between mac80211 and our queue allocation work: * mac80211 sends auth * we stop mac80211 queues to allocate a hw queue * authentication is aborted * we allocate HW queue and start mac80211 queues * mac80211 removes station * mac80211 hands us the auth frame from the pending queue At this point, since mac80211 has already removed the station, we try to transmit the frame through this special non-station case on queue 4 anyway. In order to really use it properly, we'd have to again go through the hw queue allocation work, and attach it to a station, etc. In this case that isn't possible (there's no station anymore), but if this special case were needed, then we'd have to do it this way. However, the special case is documented to exist for TDLS, but can't trigger there because the TDLS setup frames etc. are normal to-DS frames going to the peer through the AP. Testing also confirms that this code path isn't triggered in TDLS. Therefore, remove the code path to avoid using an unused queue. The erroneous frame described above will still be transmitted on the AUX queue, but arguably that's a mac80211 problem, which will eventually be fixed by moving everything there to TXQs. Fixes: e3118ad74d7e ("iwlwifi: mvm: support tdls in dqa mode") Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index 584ddc39d5f7..73967790f7e4 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c @@ -631,10 +631,6 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb) * (this is not possible for unicast packets as a TLDS discovery * response are sent without a station entry); otherwise use the * AUX station. - * In DQA mode, if vif is of type STATION and frames are not multicast - * or offchannel, they should be sent from the BSS queue. - * For example, TDLS setup frames should be sent on this queue, - * as they go through the AP. */ sta_id = mvm->aux_sta.sta_id; if (info.control.vif) { @@ -655,10 +651,6 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb) if (ap_sta_id != IWL_MVM_INVALID_STA) sta_id = ap_sta_id; - } else if (iwl_mvm_is_dqa_supported(mvm) && - info.control.vif->type == NL80211_IFTYPE_STATION && - queue != mvm->aux_queue) { - queue = IWL_MVM_DQA_BSS_CLIENT_QUEUE; } else if (iwl_mvm_is_dqa_supported(mvm) && info.control.vif->type == NL80211_IFTYPE_MONITOR) { queue = mvm->aux_queue; From 678d9b6dddea3869e78996a94ade8dc6d1b5fe68 Mon Sep 17 00:00:00 2001 From: Liad Kaufman Date: Thu, 18 May 2017 18:00:49 +0300 Subject: [PATCH 42/46] iwlwifi: mvm: update rx statistics cmd api The API has changed - update the code. Signed-off-by: Liad Kaufman Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/file.h | 4 + .../net/wireless/intel/iwlwifi/mvm/debugfs.c | 235 +++++++++++------- .../wireless/intel/iwlwifi/mvm/fw-api-stats.h | 167 +++++++++++-- .../net/wireless/intel/iwlwifi/mvm/fw-api.h | 6 +- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 11 +- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 6 +- drivers/net/wireless/intel/iwlwifi/mvm/rx.c | 83 ++++--- 7 files changed, 371 insertions(+), 141 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h index a216657b3c60..0fa8c473f1e2 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/file.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h @@ -245,10 +245,12 @@ typedef unsigned int __bitwise iwl_ucode_tlv_api_t; * ADD_MODIFY_STA_KEY_API_S_VER_2. * @IWL_UCODE_TLV_API_STA_TYPE: This ucode supports station type assignement. * @IWL_UCODE_TLV_API_NAN2_VER2: This ucode supports NAN API version 2 + * @IWL_UCODE_TLV_API_NEW_RX_STATS: should new RX STATISTICS API be used * * @NUM_IWL_UCODE_TLV_API: number of bits used */ enum iwl_ucode_tlv_api { + /* API Set 0 */ IWL_UCODE_TLV_API_FRAGMENTED_SCAN = (__force iwl_ucode_tlv_api_t)8, IWL_UCODE_TLV_API_WIFI_MCC_UPDATE = (__force iwl_ucode_tlv_api_t)9, IWL_UCODE_TLV_API_LQ_SS_PARAMS = (__force iwl_ucode_tlv_api_t)18, @@ -257,6 +259,8 @@ enum iwl_ucode_tlv_api { IWL_UCODE_TLV_API_TKIP_MIC_KEYS = (__force iwl_ucode_tlv_api_t)29, IWL_UCODE_TLV_API_STA_TYPE = (__force iwl_ucode_tlv_api_t)30, IWL_UCODE_TLV_API_NAN2_VER2 = (__force iwl_ucode_tlv_api_t)31, + /* API Set 1 */ + IWL_UCODE_TLV_API_NEW_RX_STATS = (__force iwl_ucode_tlv_api_t)35, NUM_IWL_UCODE_TLV_API #ifdef __CHECKER__ diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c index 61a5e34140db..c1c9c489edc9 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c @@ -668,15 +668,15 @@ static ssize_t iwl_dbgfs_fw_rx_stats_read(struct file *file, int pos = 0; char *buf; int ret; - /* 43 is the size of each data line, 33 is the size of each header */ - size_t bufsz = - ((sizeof(struct mvm_statistics_rx) / sizeof(__le32)) * 43) + - (4 * 33) + 1; + size_t bufsz; - struct mvm_statistics_rx_phy *ofdm; - struct mvm_statistics_rx_phy *cck; - struct mvm_statistics_rx_non_phy *general; - struct mvm_statistics_rx_ht_phy *ht; + if (iwl_mvm_has_new_rx_stats_api(mvm)) + bufsz = ((sizeof(struct mvm_statistics_rx) / + sizeof(__le32)) * 43) + (4 * 33) + 1; + else + /* 43 = size of each data line; 33 = size of each header */ + bufsz = ((sizeof(struct mvm_statistics_rx_v3) / + sizeof(__le32)) * 43) + (4 * 33) + 1; buf = kzalloc(bufsz, GFP_KERNEL); if (!buf) @@ -684,96 +684,157 @@ static ssize_t iwl_dbgfs_fw_rx_stats_read(struct file *file, mutex_lock(&mvm->mutex); - ofdm = &mvm->rx_stats.ofdm; - cck = &mvm->rx_stats.cck; - general = &mvm->rx_stats.general; - ht = &mvm->rx_stats.ofdm_ht; - pos += scnprintf(buf + pos, bufsz - pos, fmt_header, "Statistics_Rx - OFDM"); - PRINT_STATS_LE32(ofdm, ina_cnt); - PRINT_STATS_LE32(ofdm, fina_cnt); - PRINT_STATS_LE32(ofdm, plcp_err); - PRINT_STATS_LE32(ofdm, crc32_err); - PRINT_STATS_LE32(ofdm, overrun_err); - PRINT_STATS_LE32(ofdm, early_overrun_err); - PRINT_STATS_LE32(ofdm, crc32_good); - PRINT_STATS_LE32(ofdm, false_alarm_cnt); - PRINT_STATS_LE32(ofdm, fina_sync_err_cnt); - PRINT_STATS_LE32(ofdm, sfd_timeout); - PRINT_STATS_LE32(ofdm, fina_timeout); - PRINT_STATS_LE32(ofdm, unresponded_rts); - PRINT_STATS_LE32(ofdm, rxe_frame_lmt_overrun); - PRINT_STATS_LE32(ofdm, sent_ack_cnt); - PRINT_STATS_LE32(ofdm, sent_cts_cnt); - PRINT_STATS_LE32(ofdm, sent_ba_rsp_cnt); - PRINT_STATS_LE32(ofdm, dsp_self_kill); - PRINT_STATS_LE32(ofdm, mh_format_err); - PRINT_STATS_LE32(ofdm, re_acq_main_rssi_sum); - PRINT_STATS_LE32(ofdm, reserved); + if (!iwl_mvm_has_new_rx_stats_api(mvm)) { + struct mvm_statistics_rx_phy_v2 *ofdm = &mvm->rx_stats_v3.ofdm; + + PRINT_STATS_LE32(ofdm, ina_cnt); + PRINT_STATS_LE32(ofdm, fina_cnt); + PRINT_STATS_LE32(ofdm, plcp_err); + PRINT_STATS_LE32(ofdm, crc32_err); + PRINT_STATS_LE32(ofdm, overrun_err); + PRINT_STATS_LE32(ofdm, early_overrun_err); + PRINT_STATS_LE32(ofdm, crc32_good); + PRINT_STATS_LE32(ofdm, false_alarm_cnt); + PRINT_STATS_LE32(ofdm, fina_sync_err_cnt); + PRINT_STATS_LE32(ofdm, sfd_timeout); + PRINT_STATS_LE32(ofdm, fina_timeout); + PRINT_STATS_LE32(ofdm, unresponded_rts); + PRINT_STATS_LE32(ofdm, rxe_frame_lmt_overrun); + PRINT_STATS_LE32(ofdm, sent_ack_cnt); + PRINT_STATS_LE32(ofdm, sent_cts_cnt); + PRINT_STATS_LE32(ofdm, sent_ba_rsp_cnt); + PRINT_STATS_LE32(ofdm, dsp_self_kill); + PRINT_STATS_LE32(ofdm, mh_format_err); + PRINT_STATS_LE32(ofdm, re_acq_main_rssi_sum); + PRINT_STATS_LE32(ofdm, reserved); + } else { + struct mvm_statistics_rx_phy *ofdm = &mvm->rx_stats.ofdm; + + PRINT_STATS_LE32(ofdm, unresponded_rts); + PRINT_STATS_LE32(ofdm, rxe_frame_lmt_overrun); + PRINT_STATS_LE32(ofdm, sent_ba_rsp_cnt); + PRINT_STATS_LE32(ofdm, dsp_self_kill); + PRINT_STATS_LE32(ofdm, reserved); + } pos += scnprintf(buf + pos, bufsz - pos, fmt_header, "Statistics_Rx - CCK"); - PRINT_STATS_LE32(cck, ina_cnt); - PRINT_STATS_LE32(cck, fina_cnt); - PRINT_STATS_LE32(cck, plcp_err); - PRINT_STATS_LE32(cck, crc32_err); - PRINT_STATS_LE32(cck, overrun_err); - PRINT_STATS_LE32(cck, early_overrun_err); - PRINT_STATS_LE32(cck, crc32_good); - PRINT_STATS_LE32(cck, false_alarm_cnt); - PRINT_STATS_LE32(cck, fina_sync_err_cnt); - PRINT_STATS_LE32(cck, sfd_timeout); - PRINT_STATS_LE32(cck, fina_timeout); - PRINT_STATS_LE32(cck, unresponded_rts); - PRINT_STATS_LE32(cck, rxe_frame_lmt_overrun); - PRINT_STATS_LE32(cck, sent_ack_cnt); - PRINT_STATS_LE32(cck, sent_cts_cnt); - PRINT_STATS_LE32(cck, sent_ba_rsp_cnt); - PRINT_STATS_LE32(cck, dsp_self_kill); - PRINT_STATS_LE32(cck, mh_format_err); - PRINT_STATS_LE32(cck, re_acq_main_rssi_sum); - PRINT_STATS_LE32(cck, reserved); + if (!iwl_mvm_has_new_rx_stats_api(mvm)) { + struct mvm_statistics_rx_phy_v2 *cck = &mvm->rx_stats_v3.cck; + + PRINT_STATS_LE32(cck, ina_cnt); + PRINT_STATS_LE32(cck, fina_cnt); + PRINT_STATS_LE32(cck, plcp_err); + PRINT_STATS_LE32(cck, crc32_err); + PRINT_STATS_LE32(cck, overrun_err); + PRINT_STATS_LE32(cck, early_overrun_err); + PRINT_STATS_LE32(cck, crc32_good); + PRINT_STATS_LE32(cck, false_alarm_cnt); + PRINT_STATS_LE32(cck, fina_sync_err_cnt); + PRINT_STATS_LE32(cck, sfd_timeout); + PRINT_STATS_LE32(cck, fina_timeout); + PRINT_STATS_LE32(cck, unresponded_rts); + PRINT_STATS_LE32(cck, rxe_frame_lmt_overrun); + PRINT_STATS_LE32(cck, sent_ack_cnt); + PRINT_STATS_LE32(cck, sent_cts_cnt); + PRINT_STATS_LE32(cck, sent_ba_rsp_cnt); + PRINT_STATS_LE32(cck, dsp_self_kill); + PRINT_STATS_LE32(cck, mh_format_err); + PRINT_STATS_LE32(cck, re_acq_main_rssi_sum); + PRINT_STATS_LE32(cck, reserved); + } else { + struct mvm_statistics_rx_phy *cck = &mvm->rx_stats.cck; + + PRINT_STATS_LE32(cck, unresponded_rts); + PRINT_STATS_LE32(cck, rxe_frame_lmt_overrun); + PRINT_STATS_LE32(cck, sent_ba_rsp_cnt); + PRINT_STATS_LE32(cck, dsp_self_kill); + PRINT_STATS_LE32(cck, reserved); + } pos += scnprintf(buf + pos, bufsz - pos, fmt_header, "Statistics_Rx - GENERAL"); - PRINT_STATS_LE32(general, bogus_cts); - PRINT_STATS_LE32(general, bogus_ack); - PRINT_STATS_LE32(general, non_bssid_frames); - PRINT_STATS_LE32(general, filtered_frames); - PRINT_STATS_LE32(general, non_channel_beacons); - PRINT_STATS_LE32(general, channel_beacons); - PRINT_STATS_LE32(general, num_missed_bcon); - PRINT_STATS_LE32(general, adc_rx_saturation_time); - PRINT_STATS_LE32(general, ina_detection_search_time); - PRINT_STATS_LE32(general, beacon_silence_rssi_a); - PRINT_STATS_LE32(general, beacon_silence_rssi_b); - PRINT_STATS_LE32(general, beacon_silence_rssi_c); - PRINT_STATS_LE32(general, interference_data_flag); - PRINT_STATS_LE32(general, channel_load); - PRINT_STATS_LE32(general, dsp_false_alarms); - PRINT_STATS_LE32(general, beacon_rssi_a); - PRINT_STATS_LE32(general, beacon_rssi_b); - PRINT_STATS_LE32(general, beacon_rssi_c); - PRINT_STATS_LE32(general, beacon_energy_a); - PRINT_STATS_LE32(general, beacon_energy_b); - PRINT_STATS_LE32(general, beacon_energy_c); - PRINT_STATS_LE32(general, num_bt_kills); - PRINT_STATS_LE32(general, mac_id); - PRINT_STATS_LE32(general, directed_data_mpdu); + if (!iwl_mvm_has_new_rx_stats_api(mvm)) { + struct mvm_statistics_rx_non_phy_v3 *general = + &mvm->rx_stats_v3.general; + + PRINT_STATS_LE32(general, bogus_cts); + PRINT_STATS_LE32(general, bogus_ack); + PRINT_STATS_LE32(general, non_bssid_frames); + PRINT_STATS_LE32(general, filtered_frames); + PRINT_STATS_LE32(general, non_channel_beacons); + PRINT_STATS_LE32(general, channel_beacons); + PRINT_STATS_LE32(general, num_missed_bcon); + PRINT_STATS_LE32(general, adc_rx_saturation_time); + PRINT_STATS_LE32(general, ina_detection_search_time); + PRINT_STATS_LE32(general, beacon_silence_rssi_a); + PRINT_STATS_LE32(general, beacon_silence_rssi_b); + PRINT_STATS_LE32(general, beacon_silence_rssi_c); + PRINT_STATS_LE32(general, interference_data_flag); + PRINT_STATS_LE32(general, channel_load); + PRINT_STATS_LE32(general, dsp_false_alarms); + PRINT_STATS_LE32(general, beacon_rssi_a); + PRINT_STATS_LE32(general, beacon_rssi_b); + PRINT_STATS_LE32(general, beacon_rssi_c); + PRINT_STATS_LE32(general, beacon_energy_a); + PRINT_STATS_LE32(general, beacon_energy_b); + PRINT_STATS_LE32(general, beacon_energy_c); + PRINT_STATS_LE32(general, num_bt_kills); + PRINT_STATS_LE32(general, mac_id); + PRINT_STATS_LE32(general, directed_data_mpdu); + } else { + struct mvm_statistics_rx_non_phy *general = + &mvm->rx_stats.general; + + PRINT_STATS_LE32(general, bogus_cts); + PRINT_STATS_LE32(general, bogus_ack); + PRINT_STATS_LE32(general, non_channel_beacons); + PRINT_STATS_LE32(general, channel_beacons); + PRINT_STATS_LE32(general, num_missed_bcon); + PRINT_STATS_LE32(general, adc_rx_saturation_time); + PRINT_STATS_LE32(general, ina_detection_search_time); + PRINT_STATS_LE32(general, beacon_silence_rssi_a); + PRINT_STATS_LE32(general, beacon_silence_rssi_b); + PRINT_STATS_LE32(general, beacon_silence_rssi_c); + PRINT_STATS_LE32(general, interference_data_flag); + PRINT_STATS_LE32(general, channel_load); + PRINT_STATS_LE32(general, beacon_rssi_a); + PRINT_STATS_LE32(general, beacon_rssi_b); + PRINT_STATS_LE32(general, beacon_rssi_c); + PRINT_STATS_LE32(general, beacon_energy_a); + PRINT_STATS_LE32(general, beacon_energy_b); + PRINT_STATS_LE32(general, beacon_energy_c); + PRINT_STATS_LE32(general, num_bt_kills); + PRINT_STATS_LE32(general, mac_id); + } pos += scnprintf(buf + pos, bufsz - pos, fmt_header, "Statistics_Rx - HT"); - PRINT_STATS_LE32(ht, plcp_err); - PRINT_STATS_LE32(ht, overrun_err); - PRINT_STATS_LE32(ht, early_overrun_err); - PRINT_STATS_LE32(ht, crc32_good); - PRINT_STATS_LE32(ht, crc32_err); - PRINT_STATS_LE32(ht, mh_format_err); - PRINT_STATS_LE32(ht, agg_crc32_good); - PRINT_STATS_LE32(ht, agg_mpdu_cnt); - PRINT_STATS_LE32(ht, agg_cnt); - PRINT_STATS_LE32(ht, unsupport_mcs); + if (!iwl_mvm_has_new_rx_stats_api(mvm)) { + struct mvm_statistics_rx_ht_phy_v1 *ht = + &mvm->rx_stats_v3.ofdm_ht; + + PRINT_STATS_LE32(ht, plcp_err); + PRINT_STATS_LE32(ht, overrun_err); + PRINT_STATS_LE32(ht, early_overrun_err); + PRINT_STATS_LE32(ht, crc32_good); + PRINT_STATS_LE32(ht, crc32_err); + PRINT_STATS_LE32(ht, mh_format_err); + PRINT_STATS_LE32(ht, agg_crc32_good); + PRINT_STATS_LE32(ht, agg_mpdu_cnt); + PRINT_STATS_LE32(ht, agg_cnt); + PRINT_STATS_LE32(ht, unsupport_mcs); + } else { + struct mvm_statistics_rx_ht_phy *ht = + &mvm->rx_stats.ofdm_ht; + + PRINT_STATS_LE32(ht, mh_format_err); + PRINT_STATS_LE32(ht, agg_mpdu_cnt); + PRINT_STATS_LE32(ht, agg_cnt); + PRINT_STATS_LE32(ht, unsupport_mcs); + } mutex_unlock(&mvm->mutex); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-stats.h b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-stats.h index 4286222f54f7..c7531da508fd 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-stats.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-stats.h @@ -84,7 +84,55 @@ struct mvm_statistics_div { __le32 reserved2; } __packed; /* STATISTICS_SLOW_DIV_API_S_VER_2 */ +/** + * struct mvm_statistics_rx_non_phy + * @bogus_cts: CTS received when not expecting CTS + * @bogus_ack: ACK received when not expecting ACK + * @non_channel_beacons: beacons with our bss id but not on our serving channel + * @channel_beacons: beacons with our bss id and in our serving channel + * @num_missed_bcon: number of missed beacons + * @adc_rx_saturation_time: count in 0.8us units the time the ADC was in + * saturation + * @ina_detection_search_time: total time (in 0.8us) searched for INA + * @beacon_silence_rssi_a: RSSI silence after beacon frame + * @beacon_silence_rssi_b: RSSI silence after beacon frame + * @beacon_silence_rssi_c: RSSI silence after beacon frame + * @interference_data_flag: flag for interference data availability. 1 when data + * is available. + * @channel_load: counts RX Enable time in uSec + * @beacon_rssi_a: beacon RSSI on anntena A + * @beacon_rssi_b: beacon RSSI on antenna B + * @beacon_rssi_c: beacon RSSI on antenna C + * @beacon_energy_a: beacon energy on antenna A + * @beacon_energy_b: beacon energy on antenna B + * @beacon_energy_c: beacon energy on antenna C + * @num_bt_kills: number of BT "kills" (frame TX aborts) + * @mac_id: mac ID + */ struct mvm_statistics_rx_non_phy { + __le32 bogus_cts; + __le32 bogus_ack; + __le32 non_channel_beacons; + __le32 channel_beacons; + __le32 num_missed_bcon; + __le32 adc_rx_saturation_time; + __le32 ina_detection_search_time; + __le32 beacon_silence_rssi_a; + __le32 beacon_silence_rssi_b; + __le32 beacon_silence_rssi_c; + __le32 interference_data_flag; + __le32 channel_load; + __le32 beacon_rssi_a; + __le32 beacon_rssi_b; + __le32 beacon_rssi_c; + __le32 beacon_energy_a; + __le32 beacon_energy_b; + __le32 beacon_energy_c; + __le32 num_bt_kills; + __le32 mac_id; +} __packed; /* STATISTICS_RX_NON_PHY_API_S_VER_4 */ + +struct mvm_statistics_rx_non_phy_v3 { __le32 bogus_cts; /* CTS received when not expecting CTS */ __le32 bogus_ack; /* ACK received when not expecting ACK */ __le32 non_bssid_frames; /* number of frames with BSSID that @@ -121,6 +169,14 @@ struct mvm_statistics_rx_non_phy { } __packed; /* STATISTICS_RX_NON_PHY_API_S_VER_3 */ struct mvm_statistics_rx_phy { + __le32 unresponded_rts; + __le32 rxe_frame_lmt_overrun; + __le32 sent_ba_rsp_cnt; + __le32 dsp_self_kill; + __le32 reserved; +} __packed; /* STATISTICS_RX_PHY_API_S_VER_3 */ + +struct mvm_statistics_rx_phy_v2 { __le32 ina_cnt; __le32 fina_cnt; __le32 plcp_err; @@ -143,7 +199,7 @@ struct mvm_statistics_rx_phy { __le32 reserved; } __packed; /* STATISTICS_RX_PHY_API_S_VER_2 */ -struct mvm_statistics_rx_ht_phy { +struct mvm_statistics_rx_ht_phy_v1 { __le32 plcp_err; __le32 overrun_err; __le32 early_overrun_err; @@ -156,7 +212,14 @@ struct mvm_statistics_rx_ht_phy { __le32 unsupport_mcs; } __packed; /* STATISTICS_HT_RX_PHY_API_S_VER_1 */ -struct mvm_statistics_tx_non_phy { +struct mvm_statistics_rx_ht_phy { + __le32 mh_format_err; + __le32 agg_mpdu_cnt; + __le32 agg_cnt; + __le32 unsupport_mcs; +} __packed; /* STATISTICS_HT_RX_PHY_API_S_VER_2 */ + +struct mvm_statistics_tx_non_phy_v3 { __le32 preamble_cnt; __le32 rx_detected_cnt; __le32 bt_prio_defer_cnt; @@ -173,6 +236,19 @@ struct mvm_statistics_tx_non_phy { __le32 ack_or_ba_timeout_collision; } __packed; /* STATISTICS_TX_NON_PHY_API_S_VER_3 */ +struct mvm_statistics_tx_non_phy { + __le32 bt_prio_defer_cnt; + __le32 bt_prio_kill_cnt; + __le32 few_bytes_cnt; + __le32 cts_timeout; + __le32 ack_timeout; + __le32 dump_msdu_cnt; + __le32 burst_abort_next_frame_mismatch_cnt; + __le32 burst_abort_missing_next_frame_cnt; + __le32 cts_timeout_collision; + __le32 ack_or_ba_timeout_collision; +} __packed; /* STATISTICS_TX_NON_PHY_API_S_VER_4 */ + #define MAX_CHAINS 3 struct mvm_statistics_tx_non_phy_agg { @@ -202,11 +278,17 @@ struct mvm_statistics_tx_channel_width { __le32 fail_per_ch_width[4]; }; /* STATISTICS_TX_CHANNEL_WIDTH_API_S_VER_1 */ +struct mvm_statistics_tx_v4 { + struct mvm_statistics_tx_non_phy_v3 general; + struct mvm_statistics_tx_non_phy_agg agg; + struct mvm_statistics_tx_channel_width channel_width; +} __packed; /* STATISTICS_TX_API_S_VER_4 */ + struct mvm_statistics_tx { struct mvm_statistics_tx_non_phy general; struct mvm_statistics_tx_non_phy_agg agg; struct mvm_statistics_tx_channel_width channel_width; -} __packed; /* STATISTICS_TX_API_S_VER_4 */ +} __packed; /* STATISTICS_TX_API_S_VER_5 */ struct mvm_statistics_bt_activity { @@ -220,7 +302,7 @@ struct mvm_statistics_bt_activity { __le32 lo_priority_rx_denied_cnt; } __packed; /* STATISTICS_BT_ACTIVITY_API_S_VER_1 */ -struct mvm_statistics_general_common { +struct mvm_statistics_general_common_v19 { __le32 radio_temperature; __le32 radio_voltage; struct mvm_statistics_dbg dbg; @@ -250,20 +332,56 @@ struct mvm_statistics_general_common { __le64 tx_time; } __packed; +struct mvm_statistics_general_common { + __le32 radio_temperature; + struct mvm_statistics_dbg dbg; + __le32 sleep_time; + __le32 slots_out; + __le32 slots_idle; + __le32 ttl_timestamp; + struct mvm_statistics_div slow_div; + __le32 rx_enable_counter; + /* + * num_of_sos_states: + * count the number of times we have to re-tune + * in order to get out of bad PHY status + */ + __le32 num_of_sos_states; + __le32 beacon_filtered; + __le32 missed_beacons; + u8 beacon_filter_average_energy; + u8 beacon_filter_reason; + u8 beacon_filter_current_energy; + u8 beacon_filter_reserved; + __le32 beacon_filter_delta_time; + struct mvm_statistics_bt_activity bt_activity; + __le64 rx_time; + __le64 on_time_rf; + __le64 on_time_scan; + __le64 tx_time; +} __packed; /* STATISTICS_GENERAL_API_S_VER_10 */ + struct mvm_statistics_general_v8 { - struct mvm_statistics_general_common common; + struct mvm_statistics_general_common_v19 common; __le32 beacon_counter[NUM_MAC_INDEX]; u8 beacon_average_energy[NUM_MAC_INDEX]; u8 reserved[4 - (NUM_MAC_INDEX % 4)]; } __packed; /* STATISTICS_GENERAL_API_S_VER_8 */ -struct mvm_statistics_general_cdb { - struct mvm_statistics_general_common common; +struct mvm_statistics_general_cdb_v9 { + struct mvm_statistics_general_common_v19 common; __le32 beacon_counter[NUM_MAC_INDEX_CDB]; u8 beacon_average_energy[NUM_MAC_INDEX_CDB]; u8 reserved[4 - (NUM_MAC_INDEX_CDB % 4)]; } __packed; /* STATISTICS_GENERAL_API_S_VER_9 */ +struct mvm_statistics_general_cdb { + struct mvm_statistics_general_common common; + __le32 beacon_counter[MAC_INDEX_AUX]; + u8 beacon_average_energy[MAC_INDEX_AUX]; + u8 reserved[8 - MAC_INDEX_AUX]; +} __packed; /* STATISTICS_GENERAL_API_S_VER_10 */ + /** * struct mvm_statistics_load - RX statistics for multi-queue devices * @air_time: accumulated air time, per mac @@ -272,24 +390,31 @@ struct mvm_statistics_general_cdb { * @avg_energy: average RSSI, per station */ struct mvm_statistics_load { + __le32 air_time[MAC_INDEX_AUX]; + __le32 byte_count[MAC_INDEX_AUX]; + __le32 pkt_count[MAC_INDEX_AUX]; + u8 avg_energy[IWL_MVM_STATION_COUNT]; +} __packed; /* STATISTICS_RX_MAC_STATION_S_VER_3 */ + +struct mvm_statistics_load_v1 { __le32 air_time[NUM_MAC_INDEX]; __le32 byte_count[NUM_MAC_INDEX]; __le32 pkt_count[NUM_MAC_INDEX]; u8 avg_energy[IWL_MVM_STATION_COUNT]; } __packed; /* STATISTICS_RX_MAC_STATION_S_VER_1 */ -struct mvm_statistics_load_cdb { - __le32 air_time[NUM_MAC_INDEX_CDB]; - __le32 byte_count[NUM_MAC_INDEX_CDB]; - __le32 pkt_count[NUM_MAC_INDEX_CDB]; - u8 avg_energy[IWL_MVM_STATION_COUNT]; -} __packed; /* STATISTICS_RX_MAC_STATION_S_VER_2 */ - struct mvm_statistics_rx { struct mvm_statistics_rx_phy ofdm; struct mvm_statistics_rx_phy cck; struct mvm_statistics_rx_non_phy general; struct mvm_statistics_rx_ht_phy ofdm_ht; +} __packed; /* STATISTICS_RX_API_S_VER_4 */ + +struct mvm_statistics_rx_v3 { + struct mvm_statistics_rx_phy_v2 ofdm; + struct mvm_statistics_rx_phy_v2 cck; + struct mvm_statistics_rx_non_phy_v3 general; + struct mvm_statistics_rx_ht_phy_v1 ofdm_ht; } __packed; /* STATISTICS_RX_API_S_VER_3 */ /* @@ -302,17 +427,17 @@ struct mvm_statistics_rx { struct iwl_notif_statistics_v10 { __le32 flag; - struct mvm_statistics_rx rx; - struct mvm_statistics_tx tx; + struct mvm_statistics_rx_v3 rx; + struct mvm_statistics_tx_v4 tx; struct mvm_statistics_general_v8 general; } __packed; /* STATISTICS_NTFY_API_S_VER_10 */ struct iwl_notif_statistics_v11 { __le32 flag; - struct mvm_statistics_rx rx; - struct mvm_statistics_tx tx; + struct mvm_statistics_rx_v3 rx; + struct mvm_statistics_tx_v4 tx; struct mvm_statistics_general_v8 general; - struct mvm_statistics_load load_stats; + struct mvm_statistics_load_v1 load_stats; } __packed; /* STATISTICS_NTFY_API_S_VER_11 */ struct iwl_notif_statistics_cdb { @@ -320,8 +445,8 @@ struct iwl_notif_statistics_cdb { struct mvm_statistics_rx rx; struct mvm_statistics_tx tx; struct mvm_statistics_general_cdb general; - struct mvm_statistics_load_cdb load_stats; -} __packed; /* STATISTICS_NTFY_API_S_VER_12 */ + struct mvm_statistics_load load_stats; +} __packed; /* STATISTICS_NTFY_API_S_VER_13 */ /** * enum iwl_statistics_notif_flags - flags used in statistics notification diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h index 3e297c95e8ff..aad265dcfaf5 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h @@ -447,7 +447,11 @@ enum iwl_legacy_cmds { TX_ANT_CONFIGURATION_CMD = 0x98, /** - * @STATISTICS_CMD: &struct iwl_statistics_cmd + * @STATISTICS_CMD: + * one of &struct iwl_statistics_cmd, + * &struct iwl_notif_statistics_v11, + * &struct iwl_notif_statistics_v10, + * &struct iwl_notif_statistics_cdb */ STATISTICS_CMD = 0x9c, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 6b8f7817391d..eaacfaf37206 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -780,7 +780,10 @@ struct iwl_mvm { struct iwl_notif_wait_data notif_wait; - struct mvm_statistics_rx rx_stats; + union { + struct mvm_statistics_rx_v3 rx_stats_v3; + struct mvm_statistics_rx rx_stats; + }; struct { u64 rx_time; @@ -1297,6 +1300,12 @@ static inline bool iwl_mvm_is_cdb_supported(struct iwl_mvm *mvm) IWL_UCODE_TLV_CAPA_CDB_SUPPORT); } +static inline bool iwl_mvm_has_new_rx_stats_api(struct iwl_mvm *mvm) +{ + return fw_has_api(&mvm->fw->ucode_capa, + IWL_UCODE_TLV_API_NEW_RX_STATS); +} + static inline struct agg_tx_status * iwl_mvm_get_agg_status(struct iwl_mvm *mvm, void *tx_resp) { diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 1799a3d367f9..4d1188b8736a 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -776,7 +776,11 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, if (err) goto out_unregister; - memset(&mvm->rx_stats, 0, sizeof(struct mvm_statistics_rx)); + if (!iwl_mvm_has_new_rx_stats_api(mvm)) + memset(&mvm->rx_stats_v3, 0, + sizeof(struct mvm_statistics_rx_v3)); + else + memset(&mvm->rx_stats, 0, sizeof(struct mvm_statistics_rx)); /* The transport always starts with a taken reference, we can * release it now if d0i3 is supported */ diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c index 2c07719aa45c..622d543abb70 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c @@ -504,14 +504,6 @@ void iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct napi_struct *napi, iwl_mvm_unref(mvm, IWL_MVM_REF_RX); } -static void iwl_mvm_update_rx_statistics(struct iwl_mvm *mvm, - struct mvm_statistics_rx *rx_stats) -{ - lockdep_assert_held(&mvm->mutex); - - mvm->rx_stats = *rx_stats; -} - struct iwl_mvm_stat_data { struct iwl_mvm *mvm; __le32 mac_id; @@ -555,7 +547,6 @@ static void iwl_mvm_stat_iterator(void *_data, u8 *mac, mvmvif->beacon_stats.avg_signal = -general->beacon_average_energy[vif_id]; } - } if (mvmvif->id != id) @@ -651,7 +642,6 @@ iwl_mvm_rx_stats_check_trigger(struct iwl_mvm *mvm, struct iwl_rx_packet *pkt) void iwl_mvm_handle_rx_statistics(struct iwl_mvm *mvm, struct iwl_rx_packet *pkt) { - struct iwl_notif_statistics_cdb *stats = (void *)&pkt->data; struct iwl_mvm_stat_data data = { .mvm = mvm, }; @@ -659,13 +649,16 @@ void iwl_mvm_handle_rx_statistics(struct iwl_mvm *mvm, int i; u8 *energy; __le32 *bytes, *air_time; + __le32 flags; - if (iwl_mvm_is_cdb_supported(mvm)) - expected_size = sizeof(*stats); - else if (iwl_mvm_has_new_rx_api(mvm)) - expected_size = sizeof(struct iwl_notif_statistics_v11); - else - expected_size = sizeof(struct iwl_notif_statistics_v10); + if (!iwl_mvm_has_new_rx_stats_api(mvm)) { + if (iwl_mvm_has_new_rx_api(mvm)) + expected_size = sizeof(struct iwl_notif_statistics_v11); + else + expected_size = sizeof(struct iwl_notif_statistics_v10); + } else { + expected_size = sizeof(struct iwl_notif_statistics_cdb); + } if (iwl_rx_packet_payload_len(pkt) != expected_size) { IWL_ERR(mvm, "received invalid statistics size (%d)!\n", @@ -673,20 +666,49 @@ void iwl_mvm_handle_rx_statistics(struct iwl_mvm *mvm, return; } - data.mac_id = stats->rx.general.mac_id; - data.beacon_filter_average_energy = - stats->general.common.beacon_filter_average_energy; + if (!iwl_mvm_has_new_rx_stats_api(mvm)) { + struct iwl_notif_statistics_v11 *stats = (void *)&pkt->data; - iwl_mvm_update_rx_statistics(mvm, &stats->rx); + data.mac_id = stats->rx.general.mac_id; + data.beacon_filter_average_energy = + stats->general.common.beacon_filter_average_energy; - mvm->radio_stats.rx_time = le64_to_cpu(stats->general.common.rx_time); - mvm->radio_stats.tx_time = le64_to_cpu(stats->general.common.tx_time); - mvm->radio_stats.on_time_rf = - le64_to_cpu(stats->general.common.on_time_rf); - mvm->radio_stats.on_time_scan = - le64_to_cpu(stats->general.common.on_time_scan); + mvm->rx_stats_v3 = stats->rx; - data.general = &stats->general; + mvm->radio_stats.rx_time = + le64_to_cpu(stats->general.common.rx_time); + mvm->radio_stats.tx_time = + le64_to_cpu(stats->general.common.tx_time); + mvm->radio_stats.on_time_rf = + le64_to_cpu(stats->general.common.on_time_rf); + mvm->radio_stats.on_time_scan = + le64_to_cpu(stats->general.common.on_time_scan); + + data.general = &stats->general; + + flags = stats->flag; + } else { + struct iwl_notif_statistics_cdb *stats = (void *)&pkt->data; + + data.mac_id = stats->rx.general.mac_id; + data.beacon_filter_average_energy = + stats->general.common.beacon_filter_average_energy; + + mvm->rx_stats = stats->rx; + + mvm->radio_stats.rx_time = + le64_to_cpu(stats->general.common.rx_time); + mvm->radio_stats.tx_time = + le64_to_cpu(stats->general.common.tx_time); + mvm->radio_stats.on_time_rf = + le64_to_cpu(stats->general.common.on_time_rf); + mvm->radio_stats.on_time_scan = + le64_to_cpu(stats->general.common.on_time_scan); + + data.general = &stats->general; + + flags = stats->flag; + } iwl_mvm_rx_stats_check_trigger(mvm, pkt); @@ -698,14 +720,15 @@ void iwl_mvm_handle_rx_statistics(struct iwl_mvm *mvm, if (!iwl_mvm_has_new_rx_api(mvm)) return; - if (!iwl_mvm_is_cdb_supported(mvm)) { - struct iwl_notif_statistics_v11 *v11 = - (void *)&pkt->data; + if (!iwl_mvm_has_new_rx_stats_api(mvm)) { + struct iwl_notif_statistics_v11 *v11 = (void *)&pkt->data; energy = (void *)&v11->load_stats.avg_energy; bytes = (void *)&v11->load_stats.byte_count; air_time = (void *)&v11->load_stats.air_time; } else { + struct iwl_notif_statistics_cdb *stats = (void *)&pkt->data; + energy = (void *)&stats->load_stats.avg_energy; bytes = (void *)&stats->load_stats.byte_count; air_time = (void *)&stats->load_stats.air_time; From 51da3d8b94485a8397ae7af3bfdb65feaf582202 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 12 Jun 2017 11:24:06 +0200 Subject: [PATCH 43/46] iwlwifi: mvm: quietly accept non-sta disassoc frames When a station that's not associated sends a data frame (e.g. an NDP) hostapd will respond with a disassoc frame, telling it that it's not associated. The station might also not be authenticated, in which case there will not be a station entry for it, and as a result we need to accept such frames without a station. Fixes: 3ee0f0e23e4f ("iwlwifi: mvm: fix DQA AP mode station assumption") Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index 73967790f7e4..60360ed73f26 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c @@ -568,9 +568,12 @@ static int iwl_mvm_get_ctrl_vif_queue(struct iwl_mvm *mvm, * station that we don't have, or similarly an association * response (with non-success status) for a station we can't * accept. + * Also, disassociate frames might happen, particular with + * reason 7 ("Class 3 frame received from nonassociated STA"). */ if (ieee80211_is_probe_resp(fc) || ieee80211_is_auth(fc) || - ieee80211_is_deauth(fc) || ieee80211_is_assoc_resp(fc)) + ieee80211_is_deauth(fc) || ieee80211_is_assoc_resp(fc) || + ieee80211_is_disassoc(fc)) return mvm->probe_queue; if (info->hw_queue == info->control.vif->cab_queue) return mvmvif->cab_queue; From 52b6e168ae579483d71621e4d64d6491e8973e91 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 27 Jun 2017 12:23:56 +0300 Subject: [PATCH 44/46] iwlwifi: pcie: propagate iwl_pcie_apm_init's status iwl_pcie_apm_init can fail so make sure that the caller takes the status into account. Also, ensure that the error that iwl_pcie_apm_init can emit will appear in the kernel log by default. Signed-off-by: Emmanuel Grumbach Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/pcie/trans.c | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index a7d0b5c5e4a0..cac584cc07b6 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -236,7 +236,8 @@ void iwl_pcie_apm_config(struct iwl_trans *trans) */ static int iwl_pcie_apm_init(struct iwl_trans *trans) { - int ret = 0; + int ret; + IWL_DEBUG_INFO(trans, "Init card's basic functions\n"); /* @@ -287,8 +288,8 @@ static int iwl_pcie_apm_init(struct iwl_trans *trans) CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); if (ret < 0) { - IWL_DEBUG_INFO(trans, "Failed to init the card\n"); - goto out; + IWL_ERR(trans, "Failed to init the card\n"); + return ret; } if (trans->cfg->host_interrupt_operation_mode) { @@ -336,8 +337,7 @@ static int iwl_pcie_apm_init(struct iwl_trans *trans) set_bit(STATUS_DEVICE_ENABLED, &trans->status); -out: - return ret; + return 0; } /* @@ -514,13 +514,16 @@ static void iwl_pcie_apm_stop(struct iwl_trans *trans, bool op_mode_leave) static int iwl_pcie_nic_init(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + int ret; /* nic_init */ spin_lock(&trans_pcie->irq_lock); - iwl_pcie_apm_init(trans); - + ret = iwl_pcie_apm_init(trans); spin_unlock(&trans_pcie->irq_lock); + if (ret) + return ret; + iwl_pcie_set_pwr(trans, false); iwl_op_mode_nic_config(trans->op_mode); @@ -1658,7 +1661,9 @@ static int _iwl_trans_pcie_start_hw(struct iwl_trans *trans, bool low_power) iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); usleep_range(1000, 2000); - iwl_pcie_apm_init(trans); + err = iwl_pcie_apm_init(trans); + if (err) + return err; iwl_pcie_init_msix(trans_pcie); From 099a628bf6d9bb1d66cc0383f97cea19cfa4aacc Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 27 Jun 2017 12:29:26 +0300 Subject: [PATCH 45/46] iwlwifi: pcie: wait longer after device reset The newest devices need a longer time to reset because of their more complex hardware. Wait 5ms after device reset. Consolidate all the places that reset the device in the PCIe transport to avoid future bugs. While at it, unify the flow to use set_bit instead of full write as requested by the hardware designers. Signed-off-by: Emmanuel Grumbach Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/mvm/utils.c | 2 +- .../wireless/intel/iwlwifi/pcie/internal.h | 7 ++++++ .../wireless/intel/iwlwifi/pcie/trans-gen2.c | 8 ++----- .../net/wireless/intel/iwlwifi/pcie/trans.c | 23 ++++--------------- 4 files changed, 15 insertions(+), 25 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c index bd2596fdafda..fc5a490880d0 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c @@ -526,7 +526,7 @@ static void iwl_mvm_dump_lmac_error_log(struct iwl_mvm *mvm, u32 base) /* reset the device */ iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); - usleep_range(1000, 2000); + usleep_range(5000, 6000); /* set INIT_DONE flag */ iwl_set_bit(trans, CSR_GP_CNTRL, diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h index 7ec2d96ccceb..fa315d84e98e 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h @@ -654,6 +654,13 @@ static inline void iwl_enable_fw_load_int(struct iwl_trans *trans) } } +static inline void iwl_pcie_sw_reset(struct iwl_trans *trans) +{ + /* Reset entire device - do controller reset (results in SHRD_HW_RST) */ + iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); + usleep_range(5000, 6000); +} + static inline void *iwl_pcie_get_tfd(struct iwl_trans_pcie *trans_pcie, struct iwl_txq *txq, int idx) { diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c index e84c5ff389a8..b84b78293e7b 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c @@ -136,9 +136,7 @@ static void iwl_pcie_gen2_apm_stop(struct iwl_trans *trans, bool op_mode_leave) /* Stop device's DMA activity */ iwl_pcie_apm_stop_master(trans); - /* Reset the entire device */ - iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); - usleep_range(1000, 2000); + iwl_pcie_sw_reset(trans); /* * Clear "initialization complete" bit to move adapter from @@ -188,9 +186,7 @@ void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans, bool low_power) /* Stop the device, and put it in low power state */ iwl_pcie_gen2_apm_stop(trans, false); - /* stop and reset the on-board processor */ - iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); - usleep_range(1000, 2000); + iwl_pcie_sw_reset(trans); /* * Upon stop, the IVAR table gets erased, so msi-x won't diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index cac584cc07b6..92b3a55d0fbc 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -358,9 +358,7 @@ static void iwl_pcie_apm_lp_xtal_enable(struct iwl_trans *trans) __iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_XTAL_ON); - /* Reset entire device - do controller reset (results in SHRD_HW_RST) */ - iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); - usleep_range(1000, 2000); + iwl_pcie_sw_reset(trans); /* * Set "initialization complete" bit to move adapter from @@ -401,12 +399,7 @@ static void iwl_pcie_apm_lp_xtal_enable(struct iwl_trans *trans) apmg_xtal_cfg_reg | SHR_APMG_XTAL_CFG_XTAL_ON_REQ); - /* - * Reset entire device again - do controller reset (results in - * SHRD_HW_RST). Turn MAC off before proceeding. - */ - iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); - usleep_range(1000, 2000); + iwl_pcie_sw_reset(trans); /* Enable LP XTAL by indirect access through CSR */ apmg_gp1_reg = iwl_trans_pcie_read_shr(trans, SHR_APMG_GP1_REG); @@ -499,9 +492,7 @@ static void iwl_pcie_apm_stop(struct iwl_trans *trans, bool op_mode_leave) return; } - /* Reset the entire device */ - iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); - usleep_range(1000, 2000); + iwl_pcie_sw_reset(trans); /* * Clear "initialization complete" bit to move adapter from @@ -1181,9 +1172,7 @@ static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool low_power) /* Stop the device, and put it in low power state */ iwl_pcie_apm_stop(trans, false); - /* stop and reset the on-board processor */ - iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); - usleep_range(1000, 2000); + iwl_pcie_sw_reset(trans); /* * Upon stop, the IVAR table gets erased, so msi-x won't @@ -1657,9 +1646,7 @@ static int _iwl_trans_pcie_start_hw(struct iwl_trans *trans, bool low_power) return err; } - /* Reset the entire device */ - iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); - usleep_range(1000, 2000); + iwl_pcie_sw_reset(trans); err = iwl_pcie_apm_init(trans); if (err) From ba320dd61ec91bbe98730f3407a486facc174d63 Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Fri, 19 May 2017 15:12:07 +0300 Subject: [PATCH 46/46] iwlwifi: bump MAX API for 8000/9000/A000 to 33 Bump the maximum API supported by these device families to 33. Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/cfg/8000.c | 4 ++-- drivers/net/wireless/intel/iwlwifi/cfg/9000.c | 2 +- drivers/net/wireless/intel/iwlwifi/cfg/a000.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/8000.c b/drivers/net/wireless/intel/iwlwifi/cfg/8000.c index 766bb2037b94..5081720608af 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/8000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/8000.c @@ -70,8 +70,8 @@ #include "iwl-agn-hw.h" /* Highest firmware API version supported */ -#define IWL8000_UCODE_API_MAX 31 -#define IWL8265_UCODE_API_MAX 31 +#define IWL8000_UCODE_API_MAX 33 +#define IWL8265_UCODE_API_MAX 33 /* Lowest firmware API version supported */ #define IWL8000_UCODE_API_MIN 22 diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/9000.c b/drivers/net/wireless/intel/iwlwifi/cfg/9000.c index 42daaddfa740..b4ecd1fe1374 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/9000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/9000.c @@ -55,7 +55,7 @@ #include "iwl-agn-hw.h" /* Highest firmware API version supported */ -#define IWL9000_UCODE_API_MAX 31 +#define IWL9000_UCODE_API_MAX 33 /* Lowest firmware API version supported */ #define IWL9000_UCODE_API_MIN 30 diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/a000.c b/drivers/net/wireless/intel/iwlwifi/cfg/a000.c index 2940c0a6c3d6..98f24cd1b44f 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/a000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/a000.c @@ -55,7 +55,7 @@ #include "iwl-agn-hw.h" /* Highest firmware API version supported */ -#define IWL_A000_UCODE_API_MAX 31 +#define IWL_A000_UCODE_API_MAX 33 /* Lowest firmware API version supported */ #define IWL_A000_UCODE_API_MIN 24