From 1019f9efcb9fa0cea4b361604b438fef3ea3e394 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 30 Sep 2019 14:45:54 +0200 Subject: [PATCH 01/23] iwlwifi: mvm: update powersave correctly for D3 This fixes a long-standing bug - we haven't been able to check the firmware image that was loaded for D3/not-D3 since the introduction of the unified image... Fix this by keeping a status flag for D3 instead of checking for the firmware image that's loaded. This reduces occurrences of checks for IWL_UCODE_WOWLAN to just the code that actually loads the image or deals with it in other ways. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 6 +++++ drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 2 ++ .../net/wireless/intel/iwlwifi/mvm/power.c | 27 +++++++++---------- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index 43ebb2149b633..8878409d2f079 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -989,6 +989,8 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, mutex_lock(&mvm->mutex); + set_bit(IWL_MVM_STATUS_IN_D3, &mvm->status); + vif = iwl_mvm_get_bss_vif(mvm); if (IS_ERR_OR_NULL(vif)) { ret = 1; @@ -1083,6 +1085,8 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, ieee80211_restart_hw(mvm->hw); } } + + clear_bit(IWL_MVM_STATUS_IN_D3, &mvm->status); } out_noreset: mutex_unlock(&mvm->mutex); @@ -1929,6 +1933,8 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) mutex_lock(&mvm->mutex); + clear_bit(IWL_MVM_STATUS_IN_D3, &mvm->status); + /* get the BSS vif pointer again */ vif = iwl_mvm_get_bss_vif(mvm); if (IS_ERR_OR_NULL(vif)) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 3ec8de00f3aa7..3571b71fc51e8 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -1160,6 +1160,7 @@ struct iwl_mvm { * @IWL_MVM_STATUS_ROC_AUX_RUNNING: AUX remain-on-channel is running * @IWL_MVM_STATUS_FIRMWARE_RUNNING: firmware is running * @IWL_MVM_STATUS_NEED_FLUSH_P2P: need to flush P2P bcast STA + * @IWL_MVM_STATUS_IN_D3: in D3 (or at least about to go into it) */ enum iwl_mvm_status { IWL_MVM_STATUS_HW_RFKILL, @@ -1170,6 +1171,7 @@ enum iwl_mvm_status { IWL_MVM_STATUS_ROC_AUX_RUNNING, IWL_MVM_STATUS_FIRMWARE_RUNNING, IWL_MVM_STATUS_NEED_FLUSH_P2P, + IWL_MVM_STATUS_IN_D3, }; /* Keep track of completed init configuration */ diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/power.c b/drivers/net/wireless/intel/iwlwifi/mvm/power.c index 25d7faea1c629..c146303ec73b1 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/power.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/power.c @@ -198,7 +198,7 @@ static void iwl_mvm_power_configure_uapsd(struct iwl_mvm *mvm, if (!mvmvif->queue_params[ac].uapsd) continue; - if (mvm->fwrt.cur_fw_img != IWL_UCODE_WOWLAN) + if (!test_bit(IWL_MVM_STATUS_IN_D3, &mvm->status)) cmd->flags |= cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK); @@ -233,15 +233,15 @@ static void iwl_mvm_power_configure_uapsd(struct iwl_mvm *mvm, cmd->flags |= cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK); cmd->snooze_interval = cpu_to_le16(IWL_MVM_PS_SNOOZE_INTERVAL); cmd->snooze_window = - (mvm->fwrt.cur_fw_img == IWL_UCODE_WOWLAN) ? + test_bit(IWL_MVM_STATUS_IN_D3, &mvm->status) ? cpu_to_le16(IWL_MVM_WOWLAN_PS_SNOOZE_WINDOW) : cpu_to_le16(IWL_MVM_PS_SNOOZE_WINDOW); } cmd->uapsd_max_sp = mvm->hw->uapsd_max_sp_len; - if (mvm->fwrt.cur_fw_img == IWL_UCODE_WOWLAN || cmd->flags & - cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)) { + if (test_bit(IWL_MVM_STATUS_IN_D3, &mvm->status) || + cmd->flags & cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)) { cmd->rx_data_timeout_uapsd = cpu_to_le32(IWL_MVM_WOWLAN_PS_RX_DATA_TIMEOUT); cmd->tx_data_timeout_uapsd = @@ -354,8 +354,7 @@ static bool iwl_mvm_power_is_radar(struct ieee80211_vif *vif) static void iwl_mvm_power_config_skip_dtim(struct iwl_mvm *mvm, struct ieee80211_vif *vif, - struct iwl_mac_power_cmd *cmd, - bool host_awake) + struct iwl_mac_power_cmd *cmd) { int dtimper = vif->bss_conf.dtim_period ?: 1; int skip; @@ -370,7 +369,7 @@ static void iwl_mvm_power_config_skip_dtim(struct iwl_mvm *mvm, if (dtimper >= 10) return; - if (host_awake) { + if (!test_bit(IWL_MVM_STATUS_IN_D3, &mvm->status)) { if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_LP) return; skip = 2; @@ -390,8 +389,7 @@ static void iwl_mvm_power_config_skip_dtim(struct iwl_mvm *mvm, static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif, - struct iwl_mac_power_cmd *cmd, - bool host_awake) + struct iwl_mac_power_cmd *cmd) { int dtimper, bi; int keep_alive; @@ -437,9 +435,9 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, cmd->lprx_rssi_threshold = POWER_LPRX_RSSI_THRESHOLD; } - iwl_mvm_power_config_skip_dtim(mvm, vif, cmd, host_awake); + iwl_mvm_power_config_skip_dtim(mvm, vif, cmd); - if (!host_awake) { + if (test_bit(IWL_MVM_STATUS_IN_D3, &mvm->status)) { cmd->rx_data_timeout = cpu_to_le32(IWL_MVM_WOWLAN_PS_RX_DATA_TIMEOUT); cmd->tx_data_timeout = @@ -512,8 +510,7 @@ static int iwl_mvm_power_send_cmd(struct iwl_mvm *mvm, { struct iwl_mac_power_cmd cmd = {}; - iwl_mvm_power_build_cmd(mvm, vif, &cmd, - mvm->fwrt.cur_fw_img != IWL_UCODE_WOWLAN); + iwl_mvm_power_build_cmd(mvm, vif, &cmd); iwl_mvm_power_log(mvm, &cmd); #ifdef CONFIG_IWLWIFI_DEBUGFS memcpy(&iwl_mvm_vif_from_mac80211(vif)->mac_pwr_cmd, &cmd, sizeof(cmd)); @@ -536,7 +533,7 @@ int iwl_mvm_power_update_device(struct iwl_mvm *mvm) cmd.flags |= cpu_to_le16(DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK); #ifdef CONFIG_IWLWIFI_DEBUGFS - if ((mvm->fwrt.cur_fw_img == IWL_UCODE_WOWLAN) ? + if (test_bit(IWL_MVM_STATUS_IN_D3, &mvm->status) ? mvm->disable_power_off_d3 : mvm->disable_power_off) cmd.flags &= cpu_to_le16(~DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK); @@ -943,7 +940,7 @@ static int iwl_mvm_power_set_ba(struct iwl_mvm *mvm, if (!mvmvif->bf_data.bf_enabled) return 0; - if (mvm->fwrt.cur_fw_img == IWL_UCODE_WOWLAN) + if (test_bit(IWL_MVM_STATUS_IN_D3, &mvm->status)) cmd.ba_escape_timer = cpu_to_le32(IWL_BA_ESCAPE_TIMER_D3); mvmvif->bf_data.ba_enabled = !(!mvmvif->pm_enabled || From efaaa97c0e7f14c48ee406a37ba25ff3915c6e50 Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Tue, 1 Oct 2019 14:42:28 +0300 Subject: [PATCH 02/23] iwlwifi: dbg_ini: don't skip a TX FIFO when dumping Before we start looping over the internal TX FIFOs increase the fifo number, but that's incorrect and causes a FIFO to be skipped. This is probably due to a copy and paste from the previous loop. Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index ed90dd104366a..c8bc6b9b53a4a 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -1230,13 +1230,15 @@ static bool iwl_ini_txf_iter(struct iwl_fw_runtime *fwrt, iter->lmac = 0; } - if (!iter->internal_txf) + if (!iter->internal_txf) { for (iter->fifo++; iter->fifo < txf_num; iter->fifo++) { iter->fifo_size = cfg->lmac[iter->lmac].txfifo_size[iter->fifo]; if (iter->fifo_size && (lmac_bitmap & BIT(iter->fifo))) return true; } + iter->fifo--; + } iter->internal_txf = 1; From 5b5b9d35e05a01afacda745a0877105d33f7a768 Mon Sep 17 00:00:00 2001 From: Tova Mussai Date: Thu, 3 Oct 2019 20:17:07 +0300 Subject: [PATCH 03/23] iwlwifi: scan: remove support for fw scan api v11 The fw already support scan api v12, v11 is not needed anymore. Signed-off-by: Tova Mussai Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/fw/api/scan.h | 41 ---------------- drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 47 ------------------- 2 files changed, 88 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h b/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h index 408798f351c61..1b2b5fa56e199 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h @@ -921,21 +921,6 @@ struct iwl_scan_probe_params_v4 { #define SCAN_MAX_NUM_CHANS_V3 67 -/** - * struct iwl_scan_channel_params_v3 - * @flags: channel flags &enum iwl_scan_channel_flags - * @count: num of channels in scan request - * @reserved: for future use and alignment - * @channel_config: array of explicit channel configurations - * for 2.4Ghz and 5.2Ghz bands - */ -struct iwl_scan_channel_params_v3 { - u8 flags; - u8 count; - __le16 reserved; - struct iwl_scan_channel_cfg_umac channel_config[SCAN_MAX_NUM_CHANS_V3]; -} __packed; /* SCAN_CHANNEL_PARAMS_API_S_VER_3 */ - /** * struct iwl_scan_channel_params_v4 * @flags: channel flags &enum iwl_scan_channel_flags @@ -1010,20 +995,6 @@ struct iwl_scan_periodic_parms_v1 { __le16 reserved; } __packed; /* SCAN_PERIODIC_PARAMS_API_S_VER_1 */ -/** - * struct iwl_scan_req_params_v11 - * @general_params: &struct iwl_scan_general_params_v10 - * @channel_params: &struct iwl_scan_channel_params_v3 - * @periodic_params: &struct iwl_scan_periodic_parms_v1 - * @probe_params: &struct iwl_scan_probe_params_v3 - */ -struct iwl_scan_req_params_v11 { - struct iwl_scan_general_params_v10 general_params; - struct iwl_scan_channel_params_v3 channel_params; - struct iwl_scan_periodic_parms_v1 periodic_params; - struct iwl_scan_probe_params_v3 probe_params; -} __packed; /* SCAN_REQUEST_PARAMS_API_S_VER_11 */ - /** * struct iwl_scan_req_params_v12 * @general_params: &struct iwl_scan_general_params_v10 @@ -1052,18 +1023,6 @@ struct iwl_scan_req_params_v13 { struct iwl_scan_probe_params_v4 probe_params; } __packed; /* SCAN_REQUEST_PARAMS_API_S_VER_13 */ -/** - * struct iwl_scan_req_umac_v11 - * @uid: scan id, &enum iwl_umac_scan_uid_offsets - * @ooc_priority: out of channel priority - &enum iwl_scan_priority - * @scan_params: scan parameters - */ -struct iwl_scan_req_umac_v11 { - __le32 uid; - __le32 ooc_priority; - struct iwl_scan_req_params_v11 scan_params; -} __packed; /* SCAN_REQUEST_CMD_UMAC_API_S_VER_11 */ - /** * struct iwl_scan_req_umac_v12 * @uid: scan id, &enum iwl_umac_scan_uid_offsets diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c index a046ac9fa8524..c0c89d4607000 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c @@ -1906,20 +1906,6 @@ iwl_mvm_scan_umac_fill_probe_p_v4(struct iwl_mvm_scan_params *params, iwl_scan_build_ssids(params, pp->direct_scan, bitmap_ssid); } -static void -iwl_mvm_scan_umac_fill_ch_p_v3(struct iwl_mvm *mvm, - struct iwl_mvm_scan_params *params, - struct ieee80211_vif *vif, - struct iwl_scan_channel_params_v3 *cp) -{ - cp->flags = iwl_mvm_scan_umac_chan_flags_v2(mvm, params, vif); - cp->count = params->n_channels; - - iwl_mvm_umac_scan_cfg_channels(mvm, params->channels, - params->n_channels, 0, - cp->channel_config); -} - static void iwl_mvm_scan_umac_fill_ch_p_v4(struct iwl_mvm *mvm, struct iwl_mvm_scan_params *params, @@ -1937,37 +1923,6 @@ iwl_mvm_scan_umac_fill_ch_p_v4(struct iwl_mvm *mvm, vif->type); } -static int iwl_mvm_scan_umac_v11(struct iwl_mvm *mvm, struct ieee80211_vif *vif, - struct iwl_mvm_scan_params *params, int type, - int uid) -{ - struct iwl_scan_req_umac_v11 *cmd = mvm->scan_cmd; - struct iwl_scan_req_params_v11 *scan_p = &cmd->scan_params; - int ret; - u16 gen_flags; - - mvm->scan_uid_status[uid] = type; - - cmd->ooc_priority = cpu_to_le32(iwl_mvm_scan_umac_ooc_priority(params)); - cmd->uid = cpu_to_le32(uid); - - gen_flags = iwl_mvm_scan_umac_flags_v2(mvm, params, vif, type); - iwl_mvm_scan_umac_fill_general_p_v10(mvm, params, vif, - &scan_p->general_params, - gen_flags); - - ret = iwl_mvm_fill_scan_sched_params(params, - scan_p->periodic_params.schedule, - &scan_p->periodic_params.delay); - if (ret) - return ret; - - iwl_mvm_scan_umac_fill_probe_p_v3(params, &scan_p->probe_params); - iwl_mvm_scan_umac_fill_ch_p_v3(mvm, params, vif, - &scan_p->channel_params); - - return 0; -} static int iwl_mvm_scan_umac_v12(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct iwl_mvm_scan_params *params, int type, @@ -2152,7 +2107,6 @@ static const struct iwl_scan_umac_handler iwl_scan_umac_handlers[] = { /* set the newest version first to shorten the list traverse time */ IWL_SCAN_UMAC_HANDLER(13), IWL_SCAN_UMAC_HANDLER(12), - IWL_SCAN_UMAC_HANDLER(11), }; static int iwl_mvm_build_scan_cmd(struct iwl_mvm *mvm, @@ -2511,7 +2465,6 @@ static int iwl_scan_req_umac_get_size(u8 scan_ver) switch (scan_ver) { IWL_SCAN_REQ_UMAC_HANDLE_SIZE(13); IWL_SCAN_REQ_UMAC_HANDLE_SIZE(12); - IWL_SCAN_REQ_UMAC_HANDLE_SIZE(11); } return 0; From b59ec4cac5160370d908c60934e799bc6da7d784 Mon Sep 17 00:00:00 2001 From: Avraham Stern Date: Wed, 2 Oct 2019 12:20:32 +0300 Subject: [PATCH 04/23] iwlwifi: mvm: add support for location range request version 8 The new API requires the driver to set the frame format (legacy, HT, VHT etc.) to be used for the measurement. The new API also supports 11az and secured measurement, but these are not supported by the driver for now. Signed-off-by: Avraham Stern Signed-off-by: Luca Coelho --- .../wireless/intel/iwlwifi/fw/api/location.h | 104 +++++++- .../intel/iwlwifi/mvm/ftm-initiator.c | 239 ++++++++++++++---- 2 files changed, 290 insertions(+), 53 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/location.h b/drivers/net/wireless/intel/iwlwifi/fw/api/location.h index 7a0fe5adefa5e..a51fda4c95885 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/location.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/location.h @@ -403,7 +403,7 @@ enum iwl_initiator_ap_flags { }; /** - * struct iwl_tof_range_req_ap_entry - AP configuration parameters + * struct iwl_tof_range_req_ap_entry_v3 - AP configuration parameters * @initiator_ap_flags: see &enum iwl_initiator_ap_flags. * @channel_num: AP Channel number * @bandwidth: AP bandwidth. One of iwl_tof_bandwidth. @@ -420,7 +420,7 @@ enum iwl_initiator_ap_flags { * @reserved: For alignment and future use * @tsf_delta: not in use */ -struct iwl_tof_range_req_ap_entry { +struct iwl_tof_range_req_ap_entry_v3 { __le32 initiator_ap_flags; u8 channel_num; u8 bandwidth; @@ -434,6 +434,72 @@ struct iwl_tof_range_req_ap_entry { __le32 tsf_delta; } __packed; /* LOCATION_RANGE_REQ_AP_ENTRY_CMD_API_S_VER_3 */ +/** + * enum iwl_location_frame_format - location frame formats + * @IWL_LOCATION_FRAME_FORMAT_LEGACY: legacy + * @IWL_LOCATION_FRAME_FORMAT_HT: HT + * @IWL_LOCATION_FRAME_FORMAT_VHT: VHT + * @IWL_LOCATION_FRAME_FORMAT_HE: HE + */ +enum iwl_location_frame_format { + IWL_LOCATION_FRAME_FORMAT_LEGACY, + IWL_LOCATION_FRAME_FORMAT_HT, + IWL_LOCATION_FRAME_FORMAT_VHT, + IWL_LOCATION_FRAME_FORMAT_HE, +}; + +/** + * enum iwl_location_bw - location bandwidth selection + * @IWL_LOCATION_BW_20MHZ: 20MHz + * @IWL_LOCATION_BW_40MHZ: 40MHz + * @IWL_LOCATION_BW_80MHZ: 80MHz + */ +enum iwl_location_bw { + IWL_LOCATION_BW_20MHZ, + IWL_LOCATION_BW_40MHZ, + IWL_LOCATION_BW_80MHZ, +}; + +#define HLTK_11AZ_LEN 32 +#define TK_11AZ_LEN 32 + +#define LOCATION_BW_POS 4 + +/** + * struct iwl_tof_range_req_ap_entry - AP configuration parameters + * @initiator_ap_flags: see &enum iwl_initiator_ap_flags. + * @channel_num: AP Channel number + * @format_bw: bits 0 - 3: &enum iwl_location_frame_format. + * bits 4 - 7: &enum iwl_location_bw. + * @ctrl_ch_position: Coding of the control channel position relative to the + * center frequency, see iwl_mvm_get_ctrl_pos(). + * @ftmr_max_retries: Max number of retries to send the FTMR in case of no + * reply from the AP. + * @bssid: AP's BSSID + * @burst_period: Recommended value to be sent to the AP. Measurement + * periodicity In units of 100ms. ignored if num_of_bursts_exp = 0 + * @samples_per_burst: the number of FTMs pairs in single Burst (1-31); + * @num_of_bursts: Recommended value to be sent to the AP. 2s Exponent of + * the number of measurement iterations (min 2^0 = 1, max 2^14) + * @reserved: For alignment and future use + * @hltk: HLTK to be used for secured 11az measurement + * @tk: TK to be used for secured 11az measurement + */ +struct iwl_tof_range_req_ap_entry { + __le32 initiator_ap_flags; + u8 channel_num; + u8 format_bw; + u8 ctrl_ch_position; + u8 ftmr_max_retries; + u8 bssid[ETH_ALEN]; + __le16 burst_period; + u8 samples_per_burst; + u8 num_of_bursts; + __le16 reserved; + u8 hltk[HLTK_11AZ_LEN]; + u8 tk[TK_11AZ_LEN]; +} __packed; /* LOCATION_RANGE_REQ_AP_ENTRY_CMD_API_S_VER_4 */ + /** * enum iwl_tof_response_mode * @IWL_MVM_TOF_RESPONSE_ASAP: report each AP measurement separately as soon as @@ -535,6 +601,38 @@ struct iwl_tof_range_req_cmd_v5 { } __packed; /* LOCATION_RANGE_REQ_CMD_API_S_VER_5 */ +/** + * struct iwl_tof_range_req_cmd_v7 - start measurement cmd + * @initiator_flags: see flags @ iwl_tof_initiator_flags + * @request_id: A Token incremented per request. The same Token will be + * sent back in the range response + * @num_of_ap: Number of APs to measure (error if > IWL_MVM_TOF_MAX_APS) + * @range_req_bssid: ranging request BSSID + * @macaddr_mask: Bits set to 0 shall be copied from the MAC address template. + * Bits set to 1 shall be randomized by the UMAC + * @macaddr_template: MAC address template to use for non-randomized bits + * @req_timeout_ms: Requested timeout of the response in units of milliseconds. + * This is the session time for completing the measurement. + * @tsf_mac_id: report the measurement start time for each ap in terms of the + * TSF of this mac id. 0xff to disable TSF reporting. + * @common_calib: The common calib value to inject to this measurement calc + * @specific_calib: The specific calib value to inject to this measurement calc + * @ap: per-AP request data, see &struct iwl_tof_range_req_ap_entry_v2. + */ +struct iwl_tof_range_req_cmd_v7 { + __le32 initiator_flags; + u8 request_id; + u8 num_of_ap; + u8 range_req_bssid[ETH_ALEN]; + u8 macaddr_mask[ETH_ALEN]; + u8 macaddr_template[ETH_ALEN]; + __le32 req_timeout_ms; + __le32 tsf_mac_id; + __le16 common_calib; + __le16 specific_calib; + struct iwl_tof_range_req_ap_entry_v3 ap[IWL_MVM_TOF_MAX_APS]; +} __packed; /* LOCATION_RANGE_REQ_CMD_API_S_VER_7 */ + /** * struct iwl_tof_range_req_cmd - start measurement cmd * @initiator_flags: see flags @ iwl_tof_initiator_flags @@ -565,7 +663,7 @@ struct iwl_tof_range_req_cmd { __le16 common_calib; __le16 specific_calib; struct iwl_tof_range_req_ap_entry ap[IWL_MVM_TOF_MAX_APS]; -} __packed; /* LOCATION_RANGE_REQ_CMD_API_S_VER_7 */ +} __packed; /* LOCATION_RANGE_REQ_CMD_API_S_VER_8 */ /* * enum iwl_tof_range_request_status - status of the sent request diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c b/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c index 9f4b117db9d7f..f783d6d53b6fa 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c @@ -208,10 +208,11 @@ static void iwl_mvm_ftm_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif, cmd->tsf_mac_id = cpu_to_le32(0xff); } -static int iwl_mvm_ftm_target_chandef(struct iwl_mvm *mvm, - struct cfg80211_pmsr_request_peer *peer, - u8 *channel, u8 *bandwidth, - u8 *ctrl_ch_position) +static int +iwl_mvm_ftm_target_chandef_v1(struct iwl_mvm *mvm, + struct cfg80211_pmsr_request_peer *peer, + u8 *channel, u8 *bandwidth, + u8 *ctrl_ch_position) { u32 freq = peer->chandef.chan->center_freq; @@ -242,6 +243,45 @@ static int iwl_mvm_ftm_target_chandef(struct iwl_mvm *mvm, return 0; } +static int +iwl_mvm_ftm_target_chandef_v2(struct iwl_mvm *mvm, + struct cfg80211_pmsr_request_peer *peer, + u8 *channel, u8 *format_bw, + u8 *ctrl_ch_position) +{ + u32 freq = peer->chandef.chan->center_freq; + + *channel = ieee80211_frequency_to_channel(freq); + + switch (peer->chandef.width) { + case NL80211_CHAN_WIDTH_20_NOHT: + *format_bw = IWL_LOCATION_FRAME_FORMAT_LEGACY; + *format_bw |= IWL_LOCATION_BW_20MHZ << LOCATION_BW_POS; + break; + case NL80211_CHAN_WIDTH_20: + *format_bw = IWL_LOCATION_FRAME_FORMAT_HT; + *format_bw |= IWL_LOCATION_BW_20MHZ << LOCATION_BW_POS; + break; + case NL80211_CHAN_WIDTH_40: + *format_bw = IWL_LOCATION_FRAME_FORMAT_HT; + *format_bw |= IWL_LOCATION_BW_40MHZ << LOCATION_BW_POS; + break; + case NL80211_CHAN_WIDTH_80: + *format_bw = IWL_LOCATION_FRAME_FORMAT_VHT; + *format_bw |= IWL_LOCATION_BW_80MHZ << LOCATION_BW_POS; + break; + default: + IWL_ERR(mvm, "Unsupported BW in FTM request (%d)\n", + peer->chandef.width); + return -EINVAL; + } + + *ctrl_ch_position = (peer->chandef.width > NL80211_CHAN_WIDTH_20) ? + iwl_mvm_get_ctrl_pos(&peer->chandef) : 0; + + return 0; +} + static int iwl_mvm_ftm_put_target_v2(struct iwl_mvm *mvm, struct cfg80211_pmsr_request_peer *peer, @@ -249,9 +289,9 @@ iwl_mvm_ftm_put_target_v2(struct iwl_mvm *mvm, { int ret; - ret = iwl_mvm_ftm_target_chandef(mvm, peer, &target->channel_num, - &target->bandwidth, - &target->ctrl_ch_position); + ret = iwl_mvm_ftm_target_chandef_v1(mvm, peer, &target->channel_num, + &target->bandwidth, + &target->ctrl_ch_position); if (ret) return ret; @@ -278,18 +318,11 @@ iwl_mvm_ftm_put_target_v2(struct iwl_mvm *mvm, #define FTM_PUT_FLAG(flag) (target->initiator_ap_flags |= \ cpu_to_le32(IWL_INITIATOR_AP_FLAGS_##flag)) -static int iwl_mvm_ftm_put_target(struct iwl_mvm *mvm, - struct cfg80211_pmsr_request_peer *peer, - struct iwl_tof_range_req_ap_entry *target) +static void +iwl_mvm_ftm_put_target_common(struct iwl_mvm *mvm, + struct cfg80211_pmsr_request_peer *peer, + struct iwl_tof_range_req_ap_entry *target) { - int ret; - - ret = iwl_mvm_ftm_target_chandef(mvm, peer, &target->channel_num, - &target->bandwidth, - &target->ctrl_ch_position); - if (ret) - return ret; - memcpy(target->bssid, peer->addr, ETH_ALEN); target->burst_period = cpu_to_le16(peer->ftm.burst_period); @@ -314,60 +347,166 @@ static int iwl_mvm_ftm_put_target(struct iwl_mvm *mvm, FTM_PUT_FLAG(ALGO_LR); else if (IWL_MVM_FTM_INITIATOR_ALGO == IWL_TOF_ALGO_TYPE_FFT) FTM_PUT_FLAG(ALGO_FFT); +} + +static int +iwl_mvm_ftm_put_target_v3(struct iwl_mvm *mvm, + struct cfg80211_pmsr_request_peer *peer, + struct iwl_tof_range_req_ap_entry_v3 *target) +{ + int ret; + + ret = iwl_mvm_ftm_target_chandef_v1(mvm, peer, &target->channel_num, + &target->bandwidth, + &target->ctrl_ch_position); + if (ret) + return ret; + + /* + * Versions 3 and 4 has some common fields, so + * iwl_mvm_ftm_put_target_common() can be used for version 7 too. + */ + iwl_mvm_ftm_put_target_common(mvm, peer, (void *)target); return 0; } -int iwl_mvm_ftm_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif, - struct cfg80211_pmsr_request *req) +static int iwl_mvm_ftm_put_target_v4(struct iwl_mvm *mvm, + struct cfg80211_pmsr_request_peer *peer, + struct iwl_tof_range_req_ap_entry *target) +{ + int ret; + + ret = iwl_mvm_ftm_target_chandef_v2(mvm, peer, &target->channel_num, + &target->format_bw, + &target->ctrl_ch_position); + if (ret) + return ret; + + iwl_mvm_ftm_put_target_common(mvm, peer, target); + + return 0; +} + +static int iwl_mvm_ftm_send_cmd(struct iwl_mvm *mvm, struct iwl_host_cmd *hcmd) +{ + u32 status; + int err = iwl_mvm_send_cmd_status(mvm, hcmd, &status); + + if (!err && status) { + IWL_ERR(mvm, "FTM range request command failure, status: %u\n", + status); + err = iwl_ftm_range_request_status_to_err(status); + } + + return err; +} + +static int iwl_mvm_ftm_start_v5(struct iwl_mvm *mvm, struct ieee80211_vif *vif, + struct cfg80211_pmsr_request *req) { struct iwl_tof_range_req_cmd_v5 cmd_v5; - struct iwl_tof_range_req_cmd cmd; - bool new_api = fw_has_api(&mvm->fw->ucode_capa, - IWL_UCODE_TLV_API_FTM_NEW_RANGE_REQ); - u8 num_of_ap; struct iwl_host_cmd hcmd = { .id = iwl_cmd_id(TOF_RANGE_REQ_CMD, LOCATION_GROUP, 0), .dataflags[0] = IWL_HCMD_DFL_DUP, + .data[0] = &cmd_v5, + .len[0] = sizeof(cmd_v5), }; - u32 status = 0; - int err, i; + u8 i; + int err; - lockdep_assert_held(&mvm->mutex); + iwl_mvm_ftm_cmd_v5(mvm, vif, &cmd_v5, req); - if (mvm->ftm_initiator.req) - return -EBUSY; + for (i = 0; i < cmd_v5.num_of_ap; i++) { + struct cfg80211_pmsr_request_peer *peer = &req->peers[i]; - if (new_api) { - iwl_mvm_ftm_cmd(mvm, vif, &cmd, req); - hcmd.data[0] = &cmd; - hcmd.len[0] = sizeof(cmd); - num_of_ap = cmd.num_of_ap; - } else { - iwl_mvm_ftm_cmd_v5(mvm, vif, &cmd_v5, req); - hcmd.data[0] = &cmd_v5; - hcmd.len[0] = sizeof(cmd_v5); - num_of_ap = cmd_v5.num_of_ap; + err = iwl_mvm_ftm_put_target_v2(mvm, peer, &cmd_v5.ap[i]); + if (err) + return err; } - for (i = 0; i < num_of_ap; i++) { + return iwl_mvm_ftm_send_cmd(mvm, &hcmd); +} + +static int iwl_mvm_ftm_start_v7(struct iwl_mvm *mvm, struct ieee80211_vif *vif, + struct cfg80211_pmsr_request *req) +{ + struct iwl_tof_range_req_cmd_v7 cmd_v7; + struct iwl_host_cmd hcmd = { + .id = iwl_cmd_id(TOF_RANGE_REQ_CMD, LOCATION_GROUP, 0), + .dataflags[0] = IWL_HCMD_DFL_DUP, + .data[0] = &cmd_v7, + .len[0] = sizeof(cmd_v7), + }; + u8 i; + int err; + + /* + * Versions 7 and 8 has the same structure except from the responders + * list, so iwl_mvm_ftm_cmd() can be used for version 7 too. + */ + iwl_mvm_ftm_cmd(mvm, vif, (void *)&cmd_v7, req); + + for (i = 0; i < cmd_v7.num_of_ap; i++) { struct cfg80211_pmsr_request_peer *peer = &req->peers[i]; - if (new_api) - err = iwl_mvm_ftm_put_target(mvm, peer, &cmd.ap[i]); - else - err = iwl_mvm_ftm_put_target_v2(mvm, peer, - &cmd_v5.ap[i]); + err = iwl_mvm_ftm_put_target_v3(mvm, peer, &cmd_v7.ap[i]); + if (err) + return err; + } + + return iwl_mvm_ftm_send_cmd(mvm, &hcmd); +} +static int iwl_mvm_ftm_start_v8(struct iwl_mvm *mvm, struct ieee80211_vif *vif, + struct cfg80211_pmsr_request *req) +{ + struct iwl_tof_range_req_cmd cmd; + struct iwl_host_cmd hcmd = { + .id = iwl_cmd_id(TOF_RANGE_REQ_CMD, LOCATION_GROUP, 0), + .dataflags[0] = IWL_HCMD_DFL_DUP, + .data[0] = &cmd, + .len[0] = sizeof(cmd), + }; + u8 i; + int err; + + iwl_mvm_ftm_cmd(mvm, vif, &cmd, req); + + for (i = 0; i < cmd.num_of_ap; i++) { + struct cfg80211_pmsr_request_peer *peer = &req->peers[i]; + + err = iwl_mvm_ftm_put_target_v4(mvm, peer, &cmd.ap[i]); if (err) return err; } - err = iwl_mvm_send_cmd_status(mvm, &hcmd, &status); - if (!err && status) { - IWL_ERR(mvm, "FTM range request command failure, status: %u\n", - status); - err = iwl_ftm_range_request_status_to_err(status); + return iwl_mvm_ftm_send_cmd(mvm, &hcmd); +} + +int iwl_mvm_ftm_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif, + struct cfg80211_pmsr_request *req) +{ + bool new_api = fw_has_api(&mvm->fw->ucode_capa, + IWL_UCODE_TLV_API_FTM_NEW_RANGE_REQ); + int err; + + lockdep_assert_held(&mvm->mutex); + + if (mvm->ftm_initiator.req) + return -EBUSY; + + if (new_api) { + u8 cmd_ver = iwl_mvm_lookup_cmd_ver(mvm->fw, LOCATION_GROUP, + TOF_RANGE_REQ_CMD); + + if (cmd_ver == 8) + err = iwl_mvm_ftm_start_v8(mvm, vif, req); + else + err = iwl_mvm_ftm_start_v7(mvm, vif, req); + + } else { + err = iwl_mvm_ftm_start_v5(mvm, vif, req); } if (!err) { From b1a6db1320e94bc8e924918fc236b5df97c1cca7 Mon Sep 17 00:00:00 2001 From: Avraham Stern Date: Wed, 2 Oct 2019 13:44:27 +0300 Subject: [PATCH 05/23] iwlwifi: mvm: add support for responder config command version 7 The new API requires the driver to config the supported frame format (legacy, HT, VHT etc.). Signed-off-by: Avraham Stern Signed-off-by: Luca Coelho --- .../wireless/intel/iwlwifi/fw/api/location.h | 40 +++++++- .../intel/iwlwifi/mvm/ftm-responder.c | 95 +++++++++++++++---- 2 files changed, 113 insertions(+), 22 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/location.h b/drivers/net/wireless/intel/iwlwifi/fw/api/location.h index a51fda4c95885..a0d6802c2715b 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/location.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/location.h @@ -240,7 +240,7 @@ enum iwl_tof_responder_cfg_flags { }; /** - * struct iwl_tof_responder_config_cmd - ToF AP mode (for debug) + * struct iwl_tof_responder_config_cmd_v6 - ToF AP mode (for debug) * @cmd_valid_fields: &iwl_tof_responder_cmd_valid_field * @responder_cfg_flags: &iwl_tof_responder_cfg_flags * @bandwidth: current AP Bandwidth: &enum iwl_tof_bandwidth @@ -258,7 +258,7 @@ enum iwl_tof_responder_cfg_flags { * @bssid: Current AP BSSID * @reserved2: reserved */ -struct iwl_tof_responder_config_cmd { +struct iwl_tof_responder_config_cmd_v6 { __le32 cmd_valid_fields; __le32 responder_cfg_flags; u8 bandwidth; @@ -274,6 +274,42 @@ struct iwl_tof_responder_config_cmd { __le16 reserved2; } __packed; /* TOF_RESPONDER_CONFIG_CMD_API_S_VER_6 */ +/** + * struct iwl_tof_responder_config_cmd - ToF AP mode (for debug) + * @cmd_valid_fields: &iwl_tof_responder_cmd_valid_field + * @responder_cfg_flags: &iwl_tof_responder_cfg_flags + * @format_bw: bits 0 - 3: &enum iwl_location_frame_format. + * bits 4 - 7: &enum iwl_location_bw. + * @rate: current AP rate + * @channel_num: current AP Channel + * @ctrl_ch_position: coding of the control channel position relative to + * the center frequency, see iwl_mvm_get_ctrl_pos() + * @sta_id: index of the AP STA when in AP mode + * @reserved1: reserved + * @toa_offset: Artificial addition [pSec] for the ToA - to be used for debug + * purposes, simulating station movement by adding various values + * to this field + * @common_calib: XVT: common calibration value + * @specific_calib: XVT: specific calibration value + * @bssid: Current AP BSSID + * @reserved2: reserved + */ +struct iwl_tof_responder_config_cmd { + __le32 cmd_valid_fields; + __le32 responder_cfg_flags; + u8 format_bw; + u8 rate; + u8 channel_num; + u8 ctrl_ch_position; + u8 sta_id; + u8 reserved1; + __le16 toa_offset; + __le16 common_calib; + __le16 specific_calib; + u8 bssid[ETH_ALEN]; + __le16 reserved2; +} __packed; /* TOF_RESPONDER_CONFIG_CMD_API_S_VER_6 */ + #define IWL_LCI_CIVIC_IE_MAX_SIZE 400 /** diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c b/drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c index 1513b8b4062f7..8345641984094 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c @@ -6,7 +6,7 @@ * GPL LICENSE SUMMARY * * Copyright(c) 2015 - 2017 Intel Deutschland GmbH - * Copyright (C) 2018 Intel Corporation + * Copyright (C) 2018 - 2019 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -27,7 +27,7 @@ * BSD LICENSE * * Copyright(c) 2015 - 2017 Intel Deutschland GmbH - * Copyright (C) 2018 Intel Corporation + * Copyright (C) 2018 - 2019 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -62,12 +62,72 @@ #include "mvm.h" #include "constants.h" +static int iwl_mvm_ftm_responder_set_bw_v1(struct cfg80211_chan_def *chandef, + u8 *bw, u8 *ctrl_ch_position) +{ + switch (chandef->width) { + case NL80211_CHAN_WIDTH_20_NOHT: + *bw = IWL_TOF_BW_20_LEGACY; + break; + case NL80211_CHAN_WIDTH_20: + *bw = IWL_TOF_BW_20_HT; + break; + case NL80211_CHAN_WIDTH_40: + *bw = IWL_TOF_BW_40; + *ctrl_ch_position = iwl_mvm_get_ctrl_pos(chandef); + break; + case NL80211_CHAN_WIDTH_80: + *bw = IWL_TOF_BW_80; + *ctrl_ch_position = iwl_mvm_get_ctrl_pos(chandef); + break; + default: + return -ENOTSUPP; + } + + return 0; +} + +static int iwl_mvm_ftm_responder_set_bw_v2(struct cfg80211_chan_def *chandef, + u8 *format_bw, + u8 *ctrl_ch_position) +{ + switch (chandef->width) { + case NL80211_CHAN_WIDTH_20_NOHT: + *format_bw = IWL_LOCATION_FRAME_FORMAT_LEGACY; + *format_bw |= IWL_LOCATION_BW_20MHZ << LOCATION_BW_POS; + break; + case NL80211_CHAN_WIDTH_20: + *format_bw = IWL_LOCATION_FRAME_FORMAT_HT; + *format_bw |= IWL_LOCATION_BW_20MHZ << LOCATION_BW_POS; + break; + case NL80211_CHAN_WIDTH_40: + *format_bw = IWL_LOCATION_FRAME_FORMAT_HT; + *format_bw |= IWL_LOCATION_BW_40MHZ << LOCATION_BW_POS; + *ctrl_ch_position = iwl_mvm_get_ctrl_pos(chandef); + break; + case NL80211_CHAN_WIDTH_80: + *format_bw = IWL_LOCATION_FRAME_FORMAT_VHT; + *format_bw |= IWL_LOCATION_BW_80MHZ << LOCATION_BW_POS; + *ctrl_ch_position = iwl_mvm_get_ctrl_pos(chandef); + break; + default: + return -ENOTSUPP; + } + + return 0; +} + static int iwl_mvm_ftm_responder_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct cfg80211_chan_def *chandef) { struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); + /* + * The command structure is the same for versions 6 and 7, (only the + * field interpretation is different), so the same struct can be use + * for all cases. + */ struct iwl_tof_responder_config_cmd cmd = { .channel_num = chandef->chan->hw_value, .cmd_valid_fields = @@ -76,27 +136,22 @@ iwl_mvm_ftm_responder_cmd(struct iwl_mvm *mvm, IWL_TOF_RESPONDER_CMD_VALID_STA_ID), .sta_id = mvmvif->bcast_sta.sta_id, }; + u8 cmd_ver = iwl_mvm_lookup_cmd_ver(mvm->fw, LOCATION_GROUP, + TOF_RESPONDER_CONFIG_CMD); + int err; lockdep_assert_held(&mvm->mutex); - switch (chandef->width) { - case NL80211_CHAN_WIDTH_20_NOHT: - cmd.bandwidth = IWL_TOF_BW_20_LEGACY; - break; - case NL80211_CHAN_WIDTH_20: - cmd.bandwidth = IWL_TOF_BW_20_HT; - break; - case NL80211_CHAN_WIDTH_40: - cmd.bandwidth = IWL_TOF_BW_40; - cmd.ctrl_ch_position = iwl_mvm_get_ctrl_pos(chandef); - break; - case NL80211_CHAN_WIDTH_80: - cmd.bandwidth = IWL_TOF_BW_80; - cmd.ctrl_ch_position = iwl_mvm_get_ctrl_pos(chandef); - break; - default: - WARN_ON(1); - return -EINVAL; + if (cmd_ver == 7) + err = iwl_mvm_ftm_responder_set_bw_v2(chandef, &cmd.format_bw, + &cmd.ctrl_ch_position); + else + err = iwl_mvm_ftm_responder_set_bw_v1(chandef, &cmd.format_bw, + &cmd.ctrl_ch_position); + + if (err) { + IWL_ERR(mvm, "Failed to set responder bandwidth\n"); + return err; } memcpy(cmd.bssid, vif->addr, ETH_ALEN); From c042f0c77f3df39ac4d530f5720ed64ff2f38375 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 27 Sep 2019 10:36:02 +0200 Subject: [PATCH 06/23] iwlwifi: allocate more receive buffers for HE devices For HE-capable devices, we need to allocate more receive buffers as there could be 256 frames aggregated into a single A-MPDU, and then they might contain A-MSDUs as well. Until 22000 family, the devices are able to put multiple frames into a single RB and the default RB size is 4k, but starting from AX210 family this is no longer true. On the other hand, those newer devices only use 2k receive buffers (by default). Modify the code and configuration to allocate an appropriate number of RBs depending on the device capabilities: * 4096 for AX210 HE devices, which use 2k buffers by default, * 2048 for 22000 family devices which use 4k buffers by default, * 512 for existing 9000 family devices, which doesn't really change anything since that's the default before this patch, * 512 also for AX210/22000 family devices that don't do HE. Theoretically, for devices lower than AX210, we wouldn't have to allocate that many RBs if the RB size was manually increased, but to support that the code got more complex, and it didn't really seem necessary as that's a use case for monitor mode only, where hopefully the wasted memory isn't really much of a concern. Note that AX210 devices actually support bigger than 12-bit VID, which is required here as we want to allocate 4096 buffers plus some for quick recycling, so adjust the code for that as well. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/cfg/22000.c | 55 +++++++++++++++++++ drivers/net/wireless/intel/iwlwifi/cfg/9000.c | 1 + .../net/wireless/intel/iwlwifi/iwl-config.h | 3 + .../wireless/intel/iwlwifi/iwl-context-info.h | 20 +++---- drivers/net/wireless/intel/iwlwifi/iwl-fh.h | 5 +- .../intel/iwlwifi/pcie/ctxt-info-gen3.c | 2 +- .../wireless/intel/iwlwifi/pcie/ctxt-info.c | 11 ++-- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 13 +++++ .../wireless/intel/iwlwifi/pcie/internal.h | 5 +- drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 34 ++++++++---- 10 files changed, 116 insertions(+), 33 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c index 56dc335a788c8..bd687e745dc9c 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c @@ -236,10 +236,22 @@ static const struct iwl_ht_params iwl_22000_ht_params = { }, \ } +/* + * If the device doesn't support HE, no need to have that many buffers. + * 22000 devices can split multiple frames into a single RB, so fewer are + * needed; AX210 cannot (but use smaller RBs by default) - these sizes + * were picked according to 8 MSDUs inside 256 A-MSDUs in an A-MPDU, with + * additional overhead to account for processing time. + */ +#define IWL_NUM_RBDS_NON_HE 512 +#define IWL_NUM_RBDS_22000_HE 2048 +#define IWL_NUM_RBDS_AX210_HE 4096 + const struct iwl_cfg iwl22000_2ac_cfg_hr = { .name = "Intel(R) Dual Band Wireless AC 22000", .fw_name_pre = IWL_22000_HR_FW_PRE, IWL_DEVICE_22500, + .num_rbds = IWL_NUM_RBDS_NON_HE, }; const struct iwl_cfg iwl22000_2ac_cfg_hr_cdb = { @@ -247,12 +259,14 @@ const struct iwl_cfg iwl22000_2ac_cfg_hr_cdb = { .fw_name_pre = IWL_22000_HR_CDB_FW_PRE, IWL_DEVICE_22500, .cdb = true, + .num_rbds = IWL_NUM_RBDS_NON_HE, }; const struct iwl_cfg iwl22000_2ac_cfg_jf = { .name = "Intel(R) Dual Band Wireless AC 22000", .fw_name_pre = IWL_22000_JF_FW_PRE, IWL_DEVICE_22500, + .num_rbds = IWL_NUM_RBDS_NON_HE, }; const struct iwl_cfg iwl_ax101_cfg_qu_hr = { @@ -266,6 +280,7 @@ const struct iwl_cfg iwl_ax101_cfg_qu_hr = { */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, .tx_with_siso_diversity = true, + .num_rbds = IWL_NUM_RBDS_22000_HE, }; const struct iwl_cfg iwl_ax201_cfg_qu_hr = { @@ -278,6 +293,7 @@ const struct iwl_cfg iwl_ax201_cfg_qu_hr = { * HT size; mac80211 would otherwise pick the HE max (256) by default. */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, + .num_rbds = IWL_NUM_RBDS_22000_HE, }; const struct iwl_cfg iwl_ax101_cfg_qu_c0_hr_b0 = { @@ -290,6 +306,7 @@ const struct iwl_cfg iwl_ax101_cfg_qu_c0_hr_b0 = { * HT size; mac80211 would otherwise pick the HE max (256) by default. */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, + .num_rbds = IWL_NUM_RBDS_22000_HE, }; const struct iwl_cfg iwl_ax201_cfg_qu_c0_hr_b0 = { @@ -302,6 +319,7 @@ const struct iwl_cfg iwl_ax201_cfg_qu_c0_hr_b0 = { * HT size; mac80211 would otherwise pick the HE max (256) by default. */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, + .num_rbds = IWL_NUM_RBDS_22000_HE, }; const struct iwl_cfg iwl_ax101_cfg_quz_hr = { @@ -314,6 +332,7 @@ const struct iwl_cfg iwl_ax101_cfg_quz_hr = { * HT size; mac80211 would otherwise pick the HE max (256) by default. */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, + .num_rbds = IWL_NUM_RBDS_22000_HE, }; const struct iwl_cfg iwl_ax201_cfg_quz_hr = { @@ -326,6 +345,7 @@ const struct iwl_cfg iwl_ax201_cfg_quz_hr = { * HT size; mac80211 would otherwise pick the HE max (256) by default. */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, + .num_rbds = IWL_NUM_RBDS_22000_HE, }; const struct iwl_cfg iwl_ax1650s_cfg_quz_hr = { @@ -338,6 +358,7 @@ const struct iwl_cfg iwl_ax1650s_cfg_quz_hr = { * HT size; mac80211 would otherwise pick the HE max (256) by default. */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, + .num_rbds = IWL_NUM_RBDS_22000_HE, }; const struct iwl_cfg iwl_ax1650i_cfg_quz_hr = { @@ -350,6 +371,7 @@ const struct iwl_cfg iwl_ax1650i_cfg_quz_hr = { * HT size; mac80211 would otherwise pick the HE max (256) by default. */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, + .num_rbds = IWL_NUM_RBDS_22000_HE, }; const struct iwl_cfg iwl_ax200_cfg_cc = { @@ -363,6 +385,7 @@ const struct iwl_cfg iwl_ax200_cfg_cc = { */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, .trans.bisr_workaround = 1, + .num_rbds = IWL_NUM_RBDS_22000_HE, }; const struct iwl_cfg killer1650x_2ax_cfg = { @@ -376,6 +399,7 @@ const struct iwl_cfg killer1650x_2ax_cfg = { */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, .trans.bisr_workaround = 1, + .num_rbds = IWL_NUM_RBDS_22000_HE, }; const struct iwl_cfg killer1650w_2ax_cfg = { @@ -389,6 +413,7 @@ const struct iwl_cfg killer1650w_2ax_cfg = { */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, .trans.bisr_workaround = 1, + .num_rbds = IWL_NUM_RBDS_22000_HE, }; /* @@ -400,48 +425,56 @@ const struct iwl_cfg iwl9461_2ac_cfg_qu_b0_jf_b0 = { .name = "Intel(R) Wireless-AC 9461", .fw_name_pre = IWL_QU_B_JF_B_FW_PRE, IWL_DEVICE_22500, + .num_rbds = IWL_NUM_RBDS_NON_HE, }; const struct iwl_cfg iwl9462_2ac_cfg_qu_b0_jf_b0 = { .name = "Intel(R) Wireless-AC 9462", .fw_name_pre = IWL_QU_B_JF_B_FW_PRE, IWL_DEVICE_22500, + .num_rbds = IWL_NUM_RBDS_NON_HE, }; const struct iwl_cfg iwl9560_2ac_cfg_qu_b0_jf_b0 = { .name = "Intel(R) Wireless-AC 9560", .fw_name_pre = IWL_QU_B_JF_B_FW_PRE, IWL_DEVICE_22500, + .num_rbds = IWL_NUM_RBDS_NON_HE, }; const struct iwl_cfg iwl9560_2ac_160_cfg_qu_b0_jf_b0 = { .name = "Intel(R) Wireless-AC 9560 160MHz", .fw_name_pre = IWL_QU_B_JF_B_FW_PRE, IWL_DEVICE_22500, + .num_rbds = IWL_NUM_RBDS_NON_HE, }; const struct iwl_cfg iwl9461_2ac_cfg_qu_c0_jf_b0 = { .name = "Intel(R) Wireless-AC 9461", .fw_name_pre = IWL_QU_C_JF_B_FW_PRE, IWL_DEVICE_22500, + .num_rbds = IWL_NUM_RBDS_NON_HE, }; const struct iwl_cfg iwl9462_2ac_cfg_qu_c0_jf_b0 = { .name = "Intel(R) Wireless-AC 9462", .fw_name_pre = IWL_QU_C_JF_B_FW_PRE, IWL_DEVICE_22500, + .num_rbds = IWL_NUM_RBDS_NON_HE, }; const struct iwl_cfg iwl9560_2ac_cfg_qu_c0_jf_b0 = { .name = "Intel(R) Wireless-AC 9560", .fw_name_pre = IWL_QU_C_JF_B_FW_PRE, IWL_DEVICE_22500, + .num_rbds = IWL_NUM_RBDS_NON_HE, }; const struct iwl_cfg iwl9560_2ac_160_cfg_qu_c0_jf_b0 = { .name = "Intel(R) Wireless-AC 9560 160MHz", .fw_name_pre = IWL_QU_C_JF_B_FW_PRE, IWL_DEVICE_22500, + .num_rbds = IWL_NUM_RBDS_NON_HE, }; const struct iwl_cfg iwl9560_2ac_cfg_qnj_jf_b0 = { @@ -454,6 +487,7 @@ const struct iwl_cfg iwl9560_2ac_cfg_qnj_jf_b0 = { * HT size; mac80211 would otherwise pick the HE max (256) by default. */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, + .num_rbds = IWL_NUM_RBDS_NON_HE, }; const struct iwl_cfg iwl9560_2ac_cfg_quz_a0_jf_b0_soc = { @@ -468,6 +502,7 @@ const struct iwl_cfg iwl9560_2ac_cfg_quz_a0_jf_b0_soc = { .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, .integrated = true, .soc_latency = 5000, + .num_rbds = IWL_NUM_RBDS_NON_HE, }; const struct iwl_cfg iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc = { @@ -482,6 +517,7 @@ const struct iwl_cfg iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc = { .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, .integrated = true, .soc_latency = 5000, + .num_rbds = IWL_NUM_RBDS_NON_HE, }; const struct iwl_cfg iwl9461_2ac_cfg_quz_a0_jf_b0_soc = { @@ -496,6 +532,7 @@ const struct iwl_cfg iwl9461_2ac_cfg_quz_a0_jf_b0_soc = { .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, .integrated = true, .soc_latency = 5000, + .num_rbds = IWL_NUM_RBDS_NON_HE, }; const struct iwl_cfg iwl9462_2ac_cfg_quz_a0_jf_b0_soc = { @@ -510,6 +547,7 @@ const struct iwl_cfg iwl9462_2ac_cfg_quz_a0_jf_b0_soc = { .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, .integrated = true, .soc_latency = 5000, + .num_rbds = IWL_NUM_RBDS_NON_HE, }; const struct iwl_cfg iwl9560_killer_s_2ac_cfg_quz_a0_jf_b0_soc = { @@ -524,6 +562,7 @@ const struct iwl_cfg iwl9560_killer_s_2ac_cfg_quz_a0_jf_b0_soc = { .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, .integrated = true, .soc_latency = 5000, + .num_rbds = IWL_NUM_RBDS_NON_HE, }; const struct iwl_cfg iwl9560_killer_i_2ac_cfg_quz_a0_jf_b0_soc = { @@ -538,18 +577,21 @@ const struct iwl_cfg iwl9560_killer_i_2ac_cfg_quz_a0_jf_b0_soc = { .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, .integrated = true, .soc_latency = 5000, + .num_rbds = IWL_NUM_RBDS_NON_HE, }; const struct iwl_cfg killer1550i_2ac_cfg_qu_b0_jf_b0 = { .name = "Killer (R) Wireless-AC 1550i Wireless Network Adapter (9560NGW)", .fw_name_pre = IWL_QU_B_JF_B_FW_PRE, IWL_DEVICE_22500, + .num_rbds = IWL_NUM_RBDS_NON_HE, }; const struct iwl_cfg killer1550s_2ac_cfg_qu_b0_jf_b0 = { .name = "Killer (R) Wireless-AC 1550s Wireless Network Adapter (9560NGW)", .fw_name_pre = IWL_QU_B_JF_B_FW_PRE, IWL_DEVICE_22500, + .num_rbds = IWL_NUM_RBDS_NON_HE, }; const struct iwl_cfg killer1650s_2ax_cfg_qu_b0_hr_b0 = { @@ -562,6 +604,7 @@ const struct iwl_cfg killer1650s_2ax_cfg_qu_b0_hr_b0 = { * HT size; mac80211 would otherwise pick the HE max (256) by default. */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, + .num_rbds = IWL_NUM_RBDS_22000_HE, }; const struct iwl_cfg killer1650i_2ax_cfg_qu_b0_hr_b0 = { @@ -574,6 +617,7 @@ const struct iwl_cfg killer1650i_2ax_cfg_qu_b0_hr_b0 = { * HT size; mac80211 would otherwise pick the HE max (256) by default. */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, + .num_rbds = IWL_NUM_RBDS_22000_HE, }; const struct iwl_cfg killer1650s_2ax_cfg_qu_c0_hr_b0 = { @@ -586,6 +630,7 @@ const struct iwl_cfg killer1650s_2ax_cfg_qu_c0_hr_b0 = { * HT size; mac80211 would otherwise pick the HE max (256) by default. */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, + .num_rbds = IWL_NUM_RBDS_22000_HE, }; const struct iwl_cfg killer1650i_2ax_cfg_qu_c0_hr_b0 = { @@ -598,6 +643,7 @@ const struct iwl_cfg killer1650i_2ax_cfg_qu_c0_hr_b0 = { * HT size; mac80211 would otherwise pick the HE max (256) by default. */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, + .num_rbds = IWL_NUM_RBDS_22000_HE, }; const struct iwl_cfg iwl22000_2ax_cfg_jf = { @@ -610,6 +656,7 @@ const struct iwl_cfg iwl22000_2ax_cfg_jf = { * HT size; mac80211 would otherwise pick the HE max (256) by default. */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, + .num_rbds = IWL_NUM_RBDS_22000_HE, }; const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_a0_f0 = { @@ -622,6 +669,7 @@ const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_a0_f0 = { * HT size; mac80211 would otherwise pick the HE max (256) by default. */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, + .num_rbds = IWL_NUM_RBDS_22000_HE, }; const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_b0 = { @@ -634,6 +682,7 @@ const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_b0 = { * HT size; mac80211 would otherwise pick the HE max (256) by default. */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, + .num_rbds = IWL_NUM_RBDS_22000_HE, }; const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_a0 = { @@ -646,18 +695,21 @@ const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_a0 = { * HT size; mac80211 would otherwise pick the HE max (256) by default. */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, + .num_rbds = IWL_NUM_RBDS_22000_HE, }; const struct iwl_cfg iwlax210_2ax_cfg_so_jf_a0 = { .name = "Intel(R) Wireless-AC 9560 160MHz", .fw_name_pre = IWL_22000_SO_A_JF_B_FW_PRE, IWL_DEVICE_AX210, + .num_rbds = IWL_NUM_RBDS_NON_HE, }; const struct iwl_cfg iwlax210_2ax_cfg_so_hr_a0 = { .name = "Intel(R) Wi-Fi 7 AX210 160MHz", .fw_name_pre = IWL_22000_SO_A_HR_B_FW_PRE, IWL_DEVICE_AX210, + .num_rbds = IWL_NUM_RBDS_AX210_HE, }; const struct iwl_cfg iwlax211_2ax_cfg_so_gf_a0 = { @@ -665,6 +717,7 @@ const struct iwl_cfg iwlax211_2ax_cfg_so_gf_a0 = { .fw_name_pre = IWL_22000_SO_A_GF_A_FW_PRE, .uhb_supported = true, IWL_DEVICE_AX210, + .num_rbds = IWL_NUM_RBDS_AX210_HE, }; const struct iwl_cfg iwlax210_2ax_cfg_ty_gf_a0 = { @@ -672,12 +725,14 @@ const struct iwl_cfg iwlax210_2ax_cfg_ty_gf_a0 = { .fw_name_pre = IWL_22000_TY_A_GF_A_FW_PRE, .uhb_supported = true, IWL_DEVICE_AX210, + .num_rbds = IWL_NUM_RBDS_AX210_HE, }; const struct iwl_cfg iwlax411_2ax_cfg_so_gf4_a0 = { .name = "Intel(R) Wi-Fi 7 AX411 160MHz", .fw_name_pre = IWL_22000_SO_A_GF4_A_FW_PRE, IWL_DEVICE_AX210, + .num_rbds = IWL_NUM_RBDS_AX210_HE, }; MODULE_FIRMWARE(IWL_22000_HR_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/9000.c b/drivers/net/wireless/intel/iwlwifi/cfg/9000.c index e9155b9b5ee4d..ac05c1a6ec6bc 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/9000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/9000.c @@ -138,6 +138,7 @@ static const struct iwl_tt_params iwl9000_tt_params = { .thermal_params = &iwl9000_tt_params, \ .apmg_not_supported = true, \ .trans.mq_rx_supported = true, \ + .num_rbds = 512, \ .vht_mu_mimo_supported = true, \ .mac_addr_from_csr = true, \ .trans.rf_id = true, \ diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h index 317eac0660822..f8a93324d7c0c 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h @@ -431,6 +431,8 @@ struct iwl_fw_mon_regs { * @uhb_supported: ultra high band channels supported * @min_256_ba_txq_size: minimum number of slots required in a TX queue which * supports 256 BA aggregation + * @num_rbds: number of receive buffer descriptors to use + * (only used for multi-queue capable devices) * * We enable the driver to be backward compatible wrt. hardware features. * API differences in uCode shouldn't be handled here but through TLVs @@ -485,6 +487,7 @@ struct iwl_cfg { u8 max_vht_ampdu_exponent; u8 ucode_api_max; u8 ucode_api_min; + u16 num_rbds; u32 min_umac_error_event_table; u32 extra_phy_cfg_flags; u32 d3_debug_data_base_addr; diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-context-info.h b/drivers/net/wireless/intel/iwlwifi/iwl-context-info.h index 5ed07e37e3eef..eeaa8cbdddce5 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-context-info.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-context-info.h @@ -6,7 +6,7 @@ * GPL LICENSE SUMMARY * * Copyright(c) 2017 Intel Deutschland GmbH - * Copyright(c) 2018 Intel Corporation + * Copyright(c) 2018 - 2019 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -20,7 +20,7 @@ * BSD LICENSE * * Copyright(c) 2017 Intel Deutschland GmbH - * Copyright(c) 2018 Intel Corporation + * Copyright(c) 2018 - 2019 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -64,12 +64,12 @@ * the init done for driver command that configures several system modes * @IWL_CTXT_INFO_EARLY_DEBUG: enable early debug * @IWL_CTXT_INFO_ENABLE_CDMP: enable core dump - * @IWL_CTXT_INFO_RB_CB_SIZE_POS: position of the RBD Cyclic Buffer Size + * @IWL_CTXT_INFO_RB_CB_SIZE: mask of the RBD Cyclic Buffer Size * exponent, the actual size is 2**value, valid sizes are 8-2048. * The value is four bits long. Maximum valid exponent is 12 * @IWL_CTXT_INFO_TFD_FORMAT_LONG: use long TFD Format (the * default is short format - not supported by the driver) - * @IWL_CTXT_INFO_RB_SIZE_POS: RB size position + * @IWL_CTXT_INFO_RB_SIZE: RB size mask * (values are IWL_CTXT_INFO_RB_SIZE_*K) * @IWL_CTXT_INFO_RB_SIZE_1K: Value for 1K RB size * @IWL_CTXT_INFO_RB_SIZE_2K: Value for 2K RB size @@ -83,12 +83,12 @@ * @IWL_CTXT_INFO_RB_SIZE_32K: Value for 32K RB size */ enum iwl_context_info_flags { - IWL_CTXT_INFO_AUTO_FUNC_INIT = BIT(0), - IWL_CTXT_INFO_EARLY_DEBUG = BIT(1), - IWL_CTXT_INFO_ENABLE_CDMP = BIT(2), - IWL_CTXT_INFO_RB_CB_SIZE_POS = 4, - IWL_CTXT_INFO_TFD_FORMAT_LONG = BIT(8), - IWL_CTXT_INFO_RB_SIZE_POS = 9, + IWL_CTXT_INFO_AUTO_FUNC_INIT = 0x0001, + IWL_CTXT_INFO_EARLY_DEBUG = 0x0002, + IWL_CTXT_INFO_ENABLE_CDMP = 0x0004, + IWL_CTXT_INFO_RB_CB_SIZE = 0x00f0, + IWL_CTXT_INFO_TFD_FORMAT_LONG = 0x0100, + IWL_CTXT_INFO_RB_SIZE = 0x1e00, IWL_CTXT_INFO_RB_SIZE_1K = 0x1, IWL_CTXT_INFO_RB_SIZE_2K = 0x2, IWL_CTXT_INFO_RB_SIZE_4K = 0x4, diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-fh.h b/drivers/net/wireless/intel/iwlwifi/iwl-fh.h index 8836f85afe857..bf673ce5f183e 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-fh.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-fh.h @@ -611,10 +611,7 @@ static inline unsigned int FH_MEM_CBBC_QUEUE(struct iwl_trans *trans, */ #define FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN (0x00000002) -#define MQ_RX_TABLE_SIZE 512 -#define MQ_RX_TABLE_MASK (MQ_RX_TABLE_SIZE - 1) -#define MQ_RX_NUM_RBDS (MQ_RX_TABLE_SIZE - 1) -#define RX_POOL_SIZE (MQ_RX_NUM_RBDS + \ +#define RX_POOL_SIZE(rbds) ((rbds) - 1 + \ IWL_MAX_RX_HW_QUEUES * \ (RX_CLAIM_REQ_ALLOC - RX_POST_REQ_ALLOC)) /* cb size is the exponent */ diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c index a4e09a5b1816c..01f248ba8fecf 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c @@ -206,7 +206,7 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans, ctxt_info_gen3->mtr_size = cpu_to_le16(TFD_QUEUE_CB_SIZE(cmdq_size)); ctxt_info_gen3->mcr_size = - cpu_to_le16(RX_QUEUE_CB_SIZE(MQ_RX_TABLE_SIZE)); + cpu_to_le16(RX_QUEUE_CB_SIZE(trans->cfg->num_rbds)); trans_pcie->ctxt_info_gen3 = ctxt_info_gen3; trans_pcie->prph_info = prph_info; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c index d38cefbb779e8..c34451e7e7ef4 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c @@ -193,11 +193,12 @@ int iwl_pcie_ctxt_info_init(struct iwl_trans *trans, rb_size = IWL_CTXT_INFO_RB_SIZE_4K; } - BUILD_BUG_ON(RX_QUEUE_CB_SIZE(MQ_RX_TABLE_SIZE) > 0xF); - control_flags = IWL_CTXT_INFO_TFD_FORMAT_LONG | - (RX_QUEUE_CB_SIZE(MQ_RX_TABLE_SIZE) << - IWL_CTXT_INFO_RB_CB_SIZE_POS) | - (rb_size << IWL_CTXT_INFO_RB_SIZE_POS); + WARN_ON(RX_QUEUE_CB_SIZE(trans->cfg->num_rbds) > 12); + control_flags = IWL_CTXT_INFO_TFD_FORMAT_LONG; + control_flags |= + u32_encode_bits(RX_QUEUE_CB_SIZE(trans->cfg->num_rbds), + IWL_CTXT_INFO_RB_CB_SIZE); + control_flags |= u32_encode_bits(rb_size, IWL_CTXT_INFO_RB_SIZE); ctxt_info->control.control_flags = cpu_to_le32(control_flags); /* initialize RX default queue */ diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index 040cec17d3ad6..cdf112d6c0f98 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -995,6 +995,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) const struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); const struct iwl_cfg *cfg_7265d __maybe_unused = NULL; struct iwl_trans *iwl_trans; + struct iwl_trans_pcie *trans_pcie; unsigned long flags; int ret; @@ -1002,6 +1003,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (IS_ERR(iwl_trans)) return PTR_ERR(iwl_trans); + trans_pcie = IWL_TRANS_GET_PCIE_TRANS(iwl_trans); + /* the trans_cfg should never change, so set it now */ iwl_trans->trans_cfg = &cfg->trans; @@ -1129,6 +1132,16 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /* now set the real cfg we decided to use */ iwl_trans->cfg = cfg; + if (cfg->trans.mq_rx_supported) { + if (WARN_ON(!cfg->num_rbds)) { + ret = -EINVAL; + goto out_free_trans; + } + trans_pcie->num_rx_bufs = cfg->num_rbds; + } else { + trans_pcie->num_rx_bufs = RX_QUEUE_SIZE; + } + if (iwl_trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_8000 && iwl_trans_grab_nic_access(iwl_trans, &flags)) { u32 hw_step; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h index a091690f6c799..c45df9a485592 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h @@ -513,8 +513,8 @@ struct cont_rec { */ struct iwl_trans_pcie { struct iwl_rxq *rxq; - struct iwl_rx_mem_buffer rx_pool[RX_POOL_SIZE]; - struct iwl_rx_mem_buffer *global_table[RX_POOL_SIZE]; + struct iwl_rx_mem_buffer *rx_pool; + struct iwl_rx_mem_buffer **global_table; struct iwl_rb_allocator rba; union { struct iwl_context_info *ctxt_info; @@ -573,6 +573,7 @@ struct iwl_trans_pcie { u8 no_reclaim_cmds[MAX_NO_RECLAIM_CMDS]; u8 max_tbs; u16 tfd_size; + u16 num_rx_bufs; enum iwl_amsdu_size rx_buf_size; bool bc_table_dword; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c index 452da44a21e05..f03d3cfb50da5 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c @@ -510,7 +510,7 @@ void iwl_pcie_free_rbs_pool(struct iwl_trans *trans) struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); int i; - for (i = 0; i < RX_POOL_SIZE; i++) { + for (i = 0; i < RX_POOL_SIZE(trans_pcie->num_rx_bufs); i++) { if (!trans_pcie->rx_pool[i].page) continue; dma_unmap_page(trans->dev, trans_pcie->rx_pool[i].page_dma, @@ -738,7 +738,7 @@ static int iwl_pcie_alloc_rxq_dma(struct iwl_trans *trans, spin_lock_init(&rxq->lock); if (trans->trans_cfg->mq_rx_supported) - rxq->queue_size = MQ_RX_TABLE_SIZE; + rxq->queue_size = trans->cfg->num_rbds; else rxq->queue_size = RX_QUEUE_SIZE; @@ -807,8 +807,18 @@ static int iwl_pcie_rx_alloc(struct iwl_trans *trans) trans_pcie->rxq = kcalloc(trans->num_rx_queues, sizeof(struct iwl_rxq), GFP_KERNEL); - if (!trans_pcie->rxq) - return -ENOMEM; + trans_pcie->rx_pool = kcalloc(RX_POOL_SIZE(trans_pcie->num_rx_bufs), + sizeof(trans_pcie->rx_pool[0]), + GFP_KERNEL); + trans_pcie->global_table = + kcalloc(RX_POOL_SIZE(trans_pcie->num_rx_bufs), + sizeof(trans_pcie->global_table[0]), + GFP_KERNEL); + if (!trans_pcie->rxq || !trans_pcie->rx_pool || + !trans_pcie->global_table) { + ret = -ENOMEM; + goto err; + } spin_lock_init(&rba->lock); @@ -845,6 +855,8 @@ static int iwl_pcie_rx_alloc(struct iwl_trans *trans) trans_pcie->base_rb_stts = NULL; trans_pcie->base_rb_stts_dma = 0; } + kfree(trans_pcie->rx_pool); + kfree(trans_pcie->global_table); kfree(trans_pcie->rxq); return ret; @@ -1081,12 +1093,11 @@ static int _iwl_pcie_rx_init(struct iwl_trans *trans) /* move the pool to the default queue and allocator ownerships */ queue_size = trans->trans_cfg->mq_rx_supported ? - MQ_RX_NUM_RBDS : RX_QUEUE_SIZE; + trans_pcie->num_rx_bufs - 1 : RX_QUEUE_SIZE; allocator_pool_size = trans->num_rx_queues * (RX_CLAIM_REQ_ALLOC - RX_POST_REQ_ALLOC); num_alloc = queue_size + allocator_pool_size; - BUILD_BUG_ON(ARRAY_SIZE(trans_pcie->global_table) != - ARRAY_SIZE(trans_pcie->rx_pool)); + for (i = 0; i < num_alloc; i++) { struct iwl_rx_mem_buffer *rxb = &trans_pcie->rx_pool[i]; @@ -1177,6 +1188,8 @@ void iwl_pcie_rx_free(struct iwl_trans *trans) if (rxq->napi.poll) netif_napi_del(&rxq->napi); } + kfree(trans_pcie->rx_pool); + kfree(trans_pcie->global_table); kfree(trans_pcie->rxq); } @@ -1390,13 +1403,12 @@ static struct iwl_rx_mem_buffer *iwl_pcie_get_rxb(struct iwl_trans *trans, return rxb; } - /* used_bd is a 32/16 bit but only 12 are used to retrieve the vid */ if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) - vid = le16_to_cpu(rxq->cd[i].rbid) & 0x0FFF; + vid = le16_to_cpu(rxq->cd[i].rbid); else - vid = le32_to_cpu(rxq->bd_32[i]) & 0x0FFF; + vid = le32_to_cpu(rxq->bd_32[i]) & 0x0FFF; /* 12-bit VID */ - if (!vid || vid > ARRAY_SIZE(trans_pcie->global_table)) + if (!vid || vid > RX_POOL_SIZE(trans_pcie->num_rx_bufs)) goto out_err; rxb = trans_pcie->global_table[vid - 1]; From 80084e3591390367f56161a48b6818b3a3fd64df Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 2 Oct 2019 11:33:46 +0200 Subject: [PATCH 07/23] iwlwifi: pcie: map only used part of RX buffers We don't need to map *everything* of the RX buffers, we won't use that much, map only the part we're going to use. This save some IOMMU space (if applicable and it can deal with that) and also prepares a bit for mapping partial pages for 2K buffers later. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/iwl-trans.h | 18 ++++++++++++++++++ .../net/wireless/intel/iwlwifi/pcie/internal.h | 2 ++ drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 13 ++++++------- .../net/wireless/intel/iwlwifi/pcie/trans.c | 4 +++- 4 files changed, 29 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h index 8cadad7364aca..872cda2be0f6c 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h @@ -358,6 +358,24 @@ iwl_trans_get_rb_size_order(enum iwl_amsdu_size rb_size) } } +static inline int +iwl_trans_get_rb_size(enum iwl_amsdu_size rb_size) +{ + switch (rb_size) { + case IWL_AMSDU_2K: + return 2 * 1024; + case IWL_AMSDU_4K: + return 4 * 1024; + case IWL_AMSDU_8K: + return 8 * 1024; + case IWL_AMSDU_12K: + return 12 * 1024; + default: + WARN_ON(1); + return 0; + } +} + struct iwl_hcmd_names { u8 cmd_id; const char *const cmd_name; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h index c45df9a485592..c7d094cf1e4e9 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h @@ -491,6 +491,7 @@ struct cont_rec { * @sw_csum_tx: if true, then the transport will compute the csum of the TXed * frame. * @rx_page_order: page order for receive buffer size + * @rx_buf_bytes: RX buffer (RB) size in bytes * @reg_lock: protect hw register access * @mutex: to protect stop_device / start_fw / start_hw * @cmd_in_flight: true when we have a host command in flight @@ -581,6 +582,7 @@ struct iwl_trans_pcie { bool sw_csum_tx; bool pcie_dbg_dumped_once; u32 rx_page_order; + u32 rx_buf_bytes; /*protect hw register */ spinlock_t reg_lock; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c index f03d3cfb50da5..20f93386fc4d2 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c @@ -485,7 +485,7 @@ void iwl_pcie_rxq_alloc_rbs(struct iwl_trans *trans, gfp_t priority, /* Get physical address of the RB */ rxb->page_dma = dma_map_page(trans->dev, page, 0, - PAGE_SIZE << trans_pcie->rx_page_order, + trans_pcie->rx_buf_bytes, DMA_FROM_DEVICE); if (dma_mapping_error(trans->dev, rxb->page_dma)) { rxb->page = NULL; @@ -514,8 +514,7 @@ void iwl_pcie_free_rbs_pool(struct iwl_trans *trans) if (!trans_pcie->rx_pool[i].page) continue; dma_unmap_page(trans->dev, trans_pcie->rx_pool[i].page_dma, - PAGE_SIZE << trans_pcie->rx_page_order, - DMA_FROM_DEVICE); + trans_pcie->rx_buf_bytes, DMA_FROM_DEVICE); __free_pages(trans_pcie->rx_pool[i].page, trans_pcie->rx_page_order); trans_pcie->rx_pool[i].page = NULL; @@ -575,8 +574,8 @@ static void iwl_pcie_rx_allocator(struct iwl_trans *trans) /* Get physical address of the RB */ rxb->page_dma = dma_map_page(trans->dev, page, 0, - PAGE_SIZE << trans_pcie->rx_page_order, - DMA_FROM_DEVICE); + trans_pcie->rx_buf_bytes, + DMA_FROM_DEVICE); if (dma_mapping_error(trans->dev, rxb->page_dma)) { rxb->page = NULL; __free_pages(page, trans_pcie->rx_page_order); @@ -1248,7 +1247,7 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans, struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_txq *txq = trans_pcie->txq[trans_pcie->cmd_queue]; bool page_stolen = false; - int max_len = PAGE_SIZE << trans_pcie->rx_page_order; + int max_len = trans_pcie->rx_buf_bytes; u32 offset = 0; if (WARN_ON(!rxb)) @@ -1369,7 +1368,7 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans, if (rxb->page != NULL) { rxb->page_dma = dma_map_page(trans->dev, rxb->page, 0, - PAGE_SIZE << trans_pcie->rx_page_order, + trans_pcie->rx_buf_bytes, DMA_FROM_DEVICE); if (dma_mapping_error(trans->dev, rxb->page_dma)) { /* diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index af9bc6b645427..d7617eb52c02c 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -1915,6 +1915,8 @@ static void iwl_trans_pcie_configure(struct iwl_trans *trans, trans_pcie->rx_buf_size = trans_cfg->rx_buf_size; trans_pcie->rx_page_order = iwl_trans_get_rb_size_order(trans_pcie->rx_buf_size); + trans_pcie->rx_buf_bytes = + iwl_trans_get_rb_size(trans_pcie->rx_buf_size); trans_pcie->bc_table_dword = trans_cfg->bc_table_dword; trans_pcie->scd_set_active = trans_cfg->scd_set_active; @@ -2933,7 +2935,7 @@ static u32 iwl_trans_pcie_dump_rbs(struct iwl_trans *trans, int allocated_rb_nums) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - int max_len = PAGE_SIZE << trans_pcie->rx_page_order; + int max_len = trans_pcie->rx_buf_bytes; /* Dump RBs is supported only for pre-9000 devices (1 queue) */ struct iwl_rxq *rxq = &trans_pcie->rxq[0]; u32 i, r, j, rb_len = 0; From cfdc20efebdc1dc918338818b10f1d95b58b2ca5 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 2 Oct 2019 12:11:54 +0200 Subject: [PATCH 08/23] iwlwifi: pcie: use partial pages if applicable If we have only 2k RBs like on the latest (AX210) hardware, then even on x86 where PAGE_SIZE is 4k we currently waste half of the memory. If this is the case, return partial pages from the allocator and track the offset in each RBD (to be able to find the data in them and remap them later.) This might also address other platforms with larger PAGE_SIZE by putting more RBs into a single large page. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- .../wireless/intel/iwlwifi/pcie/internal.h | 14 +++++ drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 59 +++++++++++++++---- .../net/wireless/intel/iwlwifi/pcie/trans.c | 10 +++- 3 files changed, 70 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h index c7d094cf1e4e9..2ac730859eaca 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h @@ -106,6 +106,8 @@ struct iwl_host_cmd; * @page: driver's pointer to the rxb page * @invalid: rxb is in driver ownership - not owned by HW * @vid: index of this rxb in the global table + * @offset: indicates which offset of the page (in bytes) + * this buffer uses (if multiple RBs fit into one page) */ struct iwl_rx_mem_buffer { dma_addr_t page_dma; @@ -113,6 +115,7 @@ struct iwl_rx_mem_buffer { u16 vid; bool invalid; struct list_head list; + u32 offset; }; /** @@ -511,6 +514,11 @@ struct cont_rec { * @in_rescan: true if we have triggered a device rescan * @base_rb_stts: base virtual address of receive buffer status for all queues * @base_rb_stts_dma: base physical address of receive buffer status + * @supported_dma_mask: DMA mask to validate the actual address against, + * will be DMA_BIT_MASK(11) or DMA_BIT_MASK(12) depending on the device + * @alloc_page_lock: spinlock for the page allocator + * @alloc_page: allocated page to still use parts of + * @alloc_page_used: how much of the allocated page was already used (bytes) */ struct iwl_trans_pcie { struct iwl_rxq *rxq; @@ -583,6 +591,12 @@ struct iwl_trans_pcie { bool pcie_dbg_dumped_once; u32 rx_page_order; u32 rx_buf_bytes; + u32 supported_dma_mask; + + /* allocator lock for the two values below */ + spinlock_t alloc_page_lock; + struct page *alloc_page; + u32 alloc_page_used; /*protect hw register */ spinlock_t reg_lock; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c index 20f93386fc4d2..498a14ebac472 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c @@ -298,6 +298,7 @@ static void iwl_pcie_restock_bd(struct iwl_trans *trans, static void iwl_pcie_rxmq_restock(struct iwl_trans *trans, struct iwl_rxq *rxq) { + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_rx_mem_buffer *rxb; /* @@ -318,8 +319,8 @@ static void iwl_pcie_rxmq_restock(struct iwl_trans *trans, list); list_del(&rxb->list); rxb->invalid = false; - /* 12 first bits are expected to be empty */ - WARN_ON(rxb->page_dma & DMA_BIT_MASK(12)); + /* some low bits are expected to be unset (depending on hw) */ + WARN_ON(rxb->page_dma & trans_pcie->supported_dma_mask); /* Point to Rx buffer via next RBD in circular buffer */ iwl_pcie_restock_bd(trans, rxq, rxb); rxq->write = (rxq->write + 1) & (rxq->queue_size - 1); @@ -412,15 +413,34 @@ void iwl_pcie_rxq_restock(struct iwl_trans *trans, struct iwl_rxq *rxq) * */ static struct page *iwl_pcie_rx_alloc_page(struct iwl_trans *trans, - gfp_t priority) + u32 *offset, gfp_t priority) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + unsigned int rbsize = iwl_trans_get_rb_size(trans_pcie->rx_buf_size); + unsigned int allocsize = PAGE_SIZE << trans_pcie->rx_page_order; struct page *page; gfp_t gfp_mask = priority; if (trans_pcie->rx_page_order > 0) gfp_mask |= __GFP_COMP; + if (trans_pcie->alloc_page) { + spin_lock_bh(&trans_pcie->alloc_page_lock); + /* recheck */ + if (trans_pcie->alloc_page) { + *offset = trans_pcie->alloc_page_used; + page = trans_pcie->alloc_page; + trans_pcie->alloc_page_used += rbsize; + if (trans_pcie->alloc_page_used >= allocsize) + trans_pcie->alloc_page = NULL; + else + get_page(page); + spin_unlock_bh(&trans_pcie->alloc_page_lock); + return page; + } + spin_unlock_bh(&trans_pcie->alloc_page_lock); + } + /* Alloc a new receive buffer */ page = alloc_pages(gfp_mask, trans_pcie->rx_page_order); if (!page) { @@ -436,6 +456,18 @@ static struct page *iwl_pcie_rx_alloc_page(struct iwl_trans *trans, "Failed to alloc_pages\n"); return NULL; } + + if (2 * rbsize <= allocsize) { + spin_lock_bh(&trans_pcie->alloc_page_lock); + if (!trans_pcie->alloc_page) { + get_page(page); + trans_pcie->alloc_page = page; + trans_pcie->alloc_page_used = rbsize; + } + spin_unlock_bh(&trans_pcie->alloc_page_lock); + } + + *offset = 0; return page; } @@ -456,6 +488,8 @@ void iwl_pcie_rxq_alloc_rbs(struct iwl_trans *trans, gfp_t priority, struct page *page; while (1) { + unsigned int offset; + spin_lock(&rxq->lock); if (list_empty(&rxq->rx_used)) { spin_unlock(&rxq->lock); @@ -463,8 +497,7 @@ void iwl_pcie_rxq_alloc_rbs(struct iwl_trans *trans, gfp_t priority, } spin_unlock(&rxq->lock); - /* Alloc a new receive buffer */ - page = iwl_pcie_rx_alloc_page(trans, priority); + page = iwl_pcie_rx_alloc_page(trans, &offset, priority); if (!page) return; @@ -482,9 +515,10 @@ void iwl_pcie_rxq_alloc_rbs(struct iwl_trans *trans, gfp_t priority, BUG_ON(rxb->page); rxb->page = page; + rxb->offset = offset; /* Get physical address of the RB */ rxb->page_dma = - dma_map_page(trans->dev, page, 0, + dma_map_page(trans->dev, page, rxb->offset, trans_pcie->rx_buf_bytes, DMA_FROM_DEVICE); if (dma_mapping_error(trans->dev, rxb->page_dma)) { @@ -567,13 +601,15 @@ static void iwl_pcie_rx_allocator(struct iwl_trans *trans) BUG_ON(rxb->page); /* Alloc a new receive buffer */ - page = iwl_pcie_rx_alloc_page(trans, gfp_mask); + page = iwl_pcie_rx_alloc_page(trans, &rxb->offset, + gfp_mask); if (!page) continue; rxb->page = page; /* Get physical address of the RB */ - rxb->page_dma = dma_map_page(trans->dev, page, 0, + rxb->page_dma = dma_map_page(trans->dev, page, + rxb->offset, trans_pcie->rx_buf_bytes, DMA_FROM_DEVICE); if (dma_mapping_error(trans->dev, rxb->page_dma)) { @@ -1190,6 +1226,9 @@ void iwl_pcie_rx_free(struct iwl_trans *trans) kfree(trans_pcie->rx_pool); kfree(trans_pcie->global_table); kfree(trans_pcie->rxq); + + if (trans_pcie->alloc_page) + __free_pages(trans_pcie->alloc_page, trans_pcie->rx_page_order); } static void iwl_pcie_rx_move_to_allocator(struct iwl_rxq *rxq, @@ -1261,7 +1300,7 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans, bool reclaim; int index, cmd_index, len; struct iwl_rx_cmd_buffer rxcb = { - ._offset = offset, + ._offset = rxb->offset + offset, ._rx_page_order = trans_pcie->rx_page_order, ._page = rxb->page, ._page_stolen = false, @@ -1367,7 +1406,7 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans, * rx_free list for reuse later. */ if (rxb->page != NULL) { rxb->page_dma = - dma_map_page(trans->dev, rxb->page, 0, + dma_map_page(trans->dev, rxb->page, rxb->offset, trans_pcie->rx_buf_bytes, DMA_FROM_DEVICE); if (dma_mapping_error(trans->dev, rxb->page_dma)) { diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index d7617eb52c02c..cb49154517925 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -1917,6 +1917,9 @@ static void iwl_trans_pcie_configure(struct iwl_trans *trans, iwl_trans_get_rb_size_order(trans_pcie->rx_buf_size); trans_pcie->rx_buf_bytes = iwl_trans_get_rb_size(trans_pcie->rx_buf_size); + trans_pcie->supported_dma_mask = DMA_BIT_MASK(12); + if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) + trans_pcie->supported_dma_mask = DMA_BIT_MASK(11); trans_pcie->bc_table_dword = trans_cfg->bc_table_dword; trans_pcie->scd_set_active = trans_cfg->scd_set_active; @@ -2961,9 +2964,9 @@ static u32 iwl_trans_pcie_dump_rbs(struct iwl_trans *trans, rb->index = cpu_to_le32(i); memcpy(rb->data, page_address(rxb->page), max_len); /* remap the page for the free benefit */ - rxb->page_dma = dma_map_page(trans->dev, rxb->page, 0, - max_len, - DMA_FROM_DEVICE); + rxb->page_dma = dma_map_page(trans->dev, rxb->page, + rxb->offset, max_len, + DMA_FROM_DEVICE); *data = iwl_fw_error_next_data(*data); } @@ -3454,6 +3457,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, trans_pcie->opmode_down = true; spin_lock_init(&trans_pcie->irq_lock); spin_lock_init(&trans_pcie->reg_lock); + spin_lock_init(&trans_pcie->alloc_page_lock); mutex_init(&trans_pcie->mutex); init_waitqueue_head(&trans_pcie->ucode_write_waitq); From 0e00270863daaf803b32c0ff64b73dabdefd612a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 8 Oct 2019 16:03:15 +0200 Subject: [PATCH 09/23] iwlwifi: pcie: validate queue ID before array deref/bit ops Validate that the queue ID is in range before trying to use it as an index or for test_bit() - the previous bug showed that this has in fact happened, and it was lucky that we caught it there, had the bit been set then we'd have actually used the value despite being far out of range. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/pcie/tx-gen2.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c index 8ca0250de99ec..c3683cddc3010 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c @@ -587,6 +587,10 @@ int iwl_trans_pcie_gen2_tx(struct iwl_trans *trans, struct sk_buff *skb, int idx; void *tfd; + if (WARN_ONCE(txq_id >= IWL_MAX_TVQM_QUEUES, + "queue %d out of range", txq_id)) + return -EINVAL; + if (WARN_ONCE(!test_bit(txq_id, trans_pcie->queue_used), "TX on unused queue %d\n", txq_id)) return -EINVAL; @@ -1101,9 +1105,15 @@ void iwl_pcie_gen2_txq_free_memory(struct iwl_trans *trans, static void iwl_pcie_gen2_txq_free(struct iwl_trans *trans, int txq_id) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - struct iwl_txq *txq = trans_pcie->txq[txq_id]; + struct iwl_txq *txq; int i; + if (WARN_ONCE(txq_id >= IWL_MAX_TVQM_QUEUES, + "queue %d out of range", txq_id)) + return; + + txq = trans_pcie->txq[txq_id]; + if (WARN_ON(!txq)) return; @@ -1258,6 +1268,10 @@ void iwl_trans_pcie_dyn_txq_free(struct iwl_trans *trans, int queue) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + if (WARN(queue >= IWL_MAX_TVQM_QUEUES, + "queue %d out of range", queue)) + return; + /* * Upon HW Rfkill - we stop the device, and then stop the queues * in the op_mode. Just for the sake of the simplicity of the op_mode, From b81b7bd02eda86ae3cb40eb594f5ccd6ca790d8b Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Thu, 10 Oct 2019 10:13:49 +0300 Subject: [PATCH 10/23] iwlwifi: remove some outdated iwl22000 configurations A few configuration structures were either not referenced anymore or assigned to devices IDs that were not in use anymore. Remove them. Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/cfg/22000.c | 22 ------------------- .../net/wireless/intel/iwlwifi/iwl-config.h | 3 --- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 6 ----- 3 files changed, 31 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c index bd687e745dc9c..1d3dc7cf4d63f 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c @@ -247,28 +247,6 @@ static const struct iwl_ht_params iwl_22000_ht_params = { #define IWL_NUM_RBDS_22000_HE 2048 #define IWL_NUM_RBDS_AX210_HE 4096 -const struct iwl_cfg iwl22000_2ac_cfg_hr = { - .name = "Intel(R) Dual Band Wireless AC 22000", - .fw_name_pre = IWL_22000_HR_FW_PRE, - IWL_DEVICE_22500, - .num_rbds = IWL_NUM_RBDS_NON_HE, -}; - -const struct iwl_cfg iwl22000_2ac_cfg_hr_cdb = { - .name = "Intel(R) Dual Band Wireless AC 22000", - .fw_name_pre = IWL_22000_HR_CDB_FW_PRE, - IWL_DEVICE_22500, - .cdb = true, - .num_rbds = IWL_NUM_RBDS_NON_HE, -}; - -const struct iwl_cfg iwl22000_2ac_cfg_jf = { - .name = "Intel(R) Dual Band Wireless AC 22000", - .fw_name_pre = IWL_22000_JF_FW_PRE, - IWL_DEVICE_22500, - .num_rbds = IWL_NUM_RBDS_NON_HE, -}; - const struct iwl_cfg iwl_ax101_cfg_qu_hr = { .name = "Intel(R) Wi-Fi 6 AX101", .fw_name_pre = IWL_22000_QU_B_HR_B_FW_PRE, diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h index f8a93324d7c0c..31a6f286f7f7f 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h @@ -598,9 +598,6 @@ extern const struct iwl_cfg iwl9560_2ac_cfg_shared_clk; extern const struct iwl_cfg iwl9560_2ac_160_cfg_shared_clk; extern const struct iwl_cfg iwl9560_killer_2ac_cfg_shared_clk; extern const struct iwl_cfg iwl9560_killer_s_2ac_cfg_shared_clk; -extern const struct iwl_cfg iwl22000_2ac_cfg_hr; -extern const struct iwl_cfg iwl22000_2ac_cfg_hr_cdb; -extern const struct iwl_cfg iwl22000_2ac_cfg_jf; extern const struct iwl_cfg iwl_ax101_cfg_qu_hr; extern const struct iwl_cfg iwl_ax101_cfg_qu_c0_hr_b0; extern const struct iwl_cfg iwl_ax101_cfg_quz_hr; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index cdf112d6c0f98..bac3d3fa0dece 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -910,7 +910,6 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x2720, 0x0074, iwl_ax201_cfg_qu_hr)}, {IWL_PCI_DEVICE(0x2720, 0x0078, iwl_ax201_cfg_qu_hr)}, {IWL_PCI_DEVICE(0x2720, 0x007C, iwl_ax201_cfg_qu_hr)}, - {IWL_PCI_DEVICE(0x2720, 0x0090, iwl22000_2ac_cfg_hr_cdb)}, {IWL_PCI_DEVICE(0x2720, 0x0244, iwl_ax101_cfg_qu_hr)}, {IWL_PCI_DEVICE(0x2720, 0x0310, iwl_ax201_cfg_qu_hr)}, {IWL_PCI_DEVICE(0x2720, 0x0A10, iwl_ax201_cfg_qu_hr)}, @@ -1083,11 +1082,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) else if ((hw_status & UMAG_GEN_HW_IS_FPGA) && CSR_HW_RF_STEP(iwl_trans->hw_rf_id) == SILICON_A_STEP) { cfg = &iwl22000_2ax_cfg_qnj_hr_a0_f0; - } else { - /* - * a step no FPGA - */ - cfg = &iwl22000_2ac_cfg_hr; } } From 6dece0e99faa2aef6c21406dcd95e53d1a6f99d5 Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Thu, 10 Oct 2019 11:59:30 +0300 Subject: [PATCH 11/23] iwlwifi: remove CSR registers abstraction We needed this abstraction for some CSR registers for IWL_DEVICE_22560, but that has been removed, so we don't need the abstraction anymore. Remove it. Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/cfg/1000.c | 6 +-- drivers/net/wireless/intel/iwlwifi/cfg/2000.c | 12 ++--- .../net/wireless/intel/iwlwifi/cfg/22000.c | 2 - drivers/net/wireless/intel/iwlwifi/cfg/5000.c | 7 +-- drivers/net/wireless/intel/iwlwifi/cfg/6000.c | 19 +++---- drivers/net/wireless/intel/iwlwifi/cfg/7000.c | 3 +- drivers/net/wireless/intel/iwlwifi/cfg/8000.c | 3 +- drivers/net/wireless/intel/iwlwifi/cfg/9000.c | 1 - .../net/wireless/intel/iwlwifi/iwl-config.h | 50 ------------------- drivers/net/wireless/intel/iwlwifi/iwl-csr.h | 27 +++++++++- drivers/net/wireless/intel/iwlwifi/iwl-io.c | 37 ++------------ .../wireless/intel/iwlwifi/iwl-nvm-parse.c | 14 ++---- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 6 --- drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 2 +- .../wireless/intel/iwlwifi/pcie/trans-gen2.c | 5 +- .../net/wireless/intel/iwlwifi/pcie/trans.c | 37 ++++++-------- drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 12 ++--- 17 files changed, 74 insertions(+), 169 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/1000.c b/drivers/net/wireless/intel/iwlwifi/cfg/1000.c index b92255b91b724..8a4579bb10d3e 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/1000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/1000.c @@ -77,8 +77,7 @@ static const struct iwl_eeprom_params iwl1000_eeprom_params = { .trans.base_params = &iwl1000_base_params, \ .eeprom_params = &iwl1000_eeprom_params, \ .led_mode = IWL_LED_BLINK, \ - .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \ - .trans.csr = &iwl_csr_v1 + .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K const struct iwl_cfg iwl1000_bgn_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 1000 BGN", @@ -104,8 +103,7 @@ const struct iwl_cfg iwl1000_bg_cfg = { .eeprom_params = &iwl1000_eeprom_params, \ .led_mode = IWL_LED_RF_STATE, \ .rx_with_siso_diversity = true, \ - .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \ - .trans.csr = &iwl_csr_v1 + .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K const struct iwl_cfg iwl100_bgn_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 100 BGN", diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/2000.c b/drivers/net/wireless/intel/iwlwifi/cfg/2000.c index 2b1ae0cecc83d..7140a5f3ea8b8 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/2000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/2000.c @@ -103,8 +103,7 @@ static const struct iwl_eeprom_params iwl20x0_eeprom_params = { .trans.base_params = &iwl2000_base_params, \ .eeprom_params = &iwl20x0_eeprom_params, \ .led_mode = IWL_LED_RF_STATE, \ - .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \ - .trans.csr = &iwl_csr_v1 + .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K const struct iwl_cfg iwl2000_2bgn_cfg = { @@ -131,8 +130,7 @@ const struct iwl_cfg iwl2000_2bgn_d_cfg = { .trans.base_params = &iwl2030_base_params, \ .eeprom_params = &iwl20x0_eeprom_params, \ .led_mode = IWL_LED_RF_STATE, \ - .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \ - .trans.csr = &iwl_csr_v1 + .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K const struct iwl_cfg iwl2030_2bgn_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 2230 BGN", @@ -153,8 +151,7 @@ const struct iwl_cfg iwl2030_2bgn_cfg = { .eeprom_params = &iwl20x0_eeprom_params, \ .led_mode = IWL_LED_RF_STATE, \ .rx_with_siso_diversity = true, \ - .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \ - .trans.csr = &iwl_csr_v1 + .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K const struct iwl_cfg iwl105_bgn_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 105 BGN", @@ -181,8 +178,7 @@ const struct iwl_cfg iwl105_bgn_d_cfg = { .eeprom_params = &iwl20x0_eeprom_params, \ .led_mode = IWL_LED_RF_STATE, \ .rx_with_siso_diversity = true, \ - .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \ - .trans.csr = &iwl_csr_v1 + .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K const struct iwl_cfg iwl135_bgn_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 135 BGN", diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c index 1d3dc7cf4d63f..837c06891f5e4 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c @@ -199,7 +199,6 @@ static const struct iwl_ht_params iwl_22000_ht_params = { IWL_DEVICE_22000_COMMON, \ .trans.device_family = IWL_DEVICE_FAMILY_22000, \ .trans.base_params = &iwl_22000_base_params, \ - .trans.csr = &iwl_csr_v1, \ .gp2_reg_addr = 0xa02c68, \ .mon_dram_regs = { \ .write_ptr = { \ @@ -217,7 +216,6 @@ static const struct iwl_ht_params iwl_22000_ht_params = { .trans.umac_prph_offset = 0x300000, \ .trans.device_family = IWL_DEVICE_FAMILY_AX210, \ .trans.base_params = &iwl_ax210_base_params, \ - .trans.csr = &iwl_csr_v1, \ .min_txq_size = 128, \ .gp2_reg_addr = 0xd02c68, \ .min_256_ba_txq_size = 512, \ diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/5000.c b/drivers/net/wireless/intel/iwlwifi/cfg/5000.c index aab4495c6085d..3591336dc6443 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/5000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/5000.c @@ -75,8 +75,7 @@ static const struct iwl_eeprom_params iwl5000_eeprom_params = { .trans.base_params = &iwl5000_base_params, \ .eeprom_params = &iwl5000_eeprom_params, \ .led_mode = IWL_LED_BLINK, \ - .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \ - .trans.csr = &iwl_csr_v1 + .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K const struct iwl_cfg iwl5300_agn_cfg = { .name = "Intel(R) Ultimate N WiFi Link 5300 AGN", @@ -125,7 +124,6 @@ const struct iwl_cfg iwl5350_agn_cfg = { .ht_params = &iwl5000_ht_params, .led_mode = IWL_LED_BLINK, .internal_wimax_coex = true, - .trans.csr = &iwl_csr_v1, }; #define IWL_DEVICE_5150 \ @@ -141,8 +139,7 @@ const struct iwl_cfg iwl5350_agn_cfg = { .eeprom_params = &iwl5000_eeprom_params, \ .led_mode = IWL_LED_BLINK, \ .internal_wimax_coex = true, \ - .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \ - .trans.csr = &iwl_csr_v1 + .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K const struct iwl_cfg iwl5150_agn_cfg = { .name = "Intel(R) WiMAX/WiFi Link 5150 AGN", diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/6000.c b/drivers/net/wireless/intel/iwlwifi/cfg/6000.c index 39ea81903dbe3..b4a8a6804c397 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/6000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/6000.c @@ -124,8 +124,7 @@ static const struct iwl_eeprom_params iwl6000_eeprom_params = { .trans.base_params = &iwl6000_g2_base_params, \ .eeprom_params = &iwl6000_eeprom_params, \ .led_mode = IWL_LED_RF_STATE, \ - .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \ - .trans.csr = &iwl_csr_v1 + .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K const struct iwl_cfg iwl6005_2agn_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6205 AGN", @@ -179,8 +178,7 @@ const struct iwl_cfg iwl6005_2agn_mow2_cfg = { .trans.base_params = &iwl6000_g2_base_params, \ .eeprom_params = &iwl6000_eeprom_params, \ .led_mode = IWL_LED_RF_STATE, \ - .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \ - .trans.csr = &iwl_csr_v1 + .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K const struct iwl_cfg iwl6030_2agn_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6230 AGN", @@ -216,8 +214,7 @@ const struct iwl_cfg iwl6030_2bg_cfg = { .trans.base_params = &iwl6000_g2_base_params, \ .eeprom_params = &iwl6000_eeprom_params, \ .led_mode = IWL_LED_RF_STATE, \ - .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \ - .trans.csr = &iwl_csr_v1 + .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K const struct iwl_cfg iwl6035_2agn_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6235 AGN", @@ -272,8 +269,7 @@ const struct iwl_cfg iwl130_bg_cfg = { .trans.base_params = &iwl6000_base_params, \ .eeprom_params = &iwl6000_eeprom_params, \ .led_mode = IWL_LED_BLINK, \ - .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \ - .trans.csr = &iwl_csr_v1 + .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K const struct iwl_cfg iwl6000i_2agn_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6200 AGN", @@ -306,8 +302,7 @@ const struct iwl_cfg iwl6000i_2bg_cfg = { .eeprom_params = &iwl6000_eeprom_params, \ .led_mode = IWL_LED_BLINK, \ .internal_wimax_coex = true, \ - .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \ - .trans.csr = &iwl_csr_v1 + .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K const struct iwl_cfg iwl6050_2agn_cfg = { .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 AGN", @@ -333,8 +328,7 @@ const struct iwl_cfg iwl6050_2abg_cfg = { .eeprom_params = &iwl6000_eeprom_params, \ .led_mode = IWL_LED_BLINK, \ .internal_wimax_coex = true, \ - .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \ - .trans.csr = &iwl_csr_v1 + .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K const struct iwl_cfg iwl6150_bgn_cfg = { .name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BGN", @@ -361,7 +355,6 @@ const struct iwl_cfg iwl6000_3agn_cfg = { .eeprom_params = &iwl6000_eeprom_params, .ht_params = &iwl6000_ht_params, .led_mode = IWL_LED_BLINK, - .trans.csr = &iwl_csr_v1, }; MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/7000.c b/drivers/net/wireless/intel/iwlwifi/cfg/7000.c index deb520aeb3f87..b72993e07fc2e 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/7000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/7000.c @@ -154,8 +154,7 @@ static const struct iwl_ht_params iwl7000_ht_params = { .nvm_hw_section_num = 0, \ .non_shared_ant = ANT_A, \ .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \ - .dccm_offset = IWL7000_DCCM_OFFSET, \ - .trans.csr = &iwl_csr_v1 + .dccm_offset = IWL7000_DCCM_OFFSET #define IWL_DEVICE_7000 \ IWL_DEVICE_7000_COMMON, \ diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/8000.c b/drivers/net/wireless/intel/iwlwifi/cfg/8000.c index b3cc477140c04..280d84fa5cb17 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/8000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/8000.c @@ -151,8 +151,7 @@ static const struct iwl_tt_params iwl8000_tt_params = { .apmg_not_supported = true, \ .nvm_type = IWL_NVM_EXT, \ .dbgc_supported = true, \ - .min_umac_error_event_table = 0x800000, \ - .trans.csr = &iwl_csr_v1 + .min_umac_error_event_table = 0x800000 #define IWL_DEVICE_8000 \ IWL_DEVICE_8000_COMMON, \ diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/9000.c b/drivers/net/wireless/intel/iwlwifi/cfg/9000.c index ac05c1a6ec6bc..79390f880efbd 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/9000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/9000.c @@ -145,7 +145,6 @@ static const struct iwl_tt_params iwl9000_tt_params = { .nvm_type = IWL_NVM_EXT, \ .dbgc_supported = true, \ .min_umac_error_event_table = 0x800000, \ - .trans.csr = &iwl_csr_v1, \ .d3_debug_data_base_addr = 0x401000, \ .d3_debug_data_length = 92 * 1024, \ .ht_params = &iwl9000_ht_params, \ diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h index 31a6f286f7f7f..bb91c36c9d8b2 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h @@ -284,52 +284,6 @@ struct iwl_pwr_tx_backoff { u32 backoff; }; -/** - * struct iwl_csr_params - * - * @flag_sw_reset: reset the device - * @flag_mac_clock_ready: - * Indicates MAC (ucode processor, etc.) is powered up and can run. - * Internal resources are accessible. - * NOTE: This does not indicate that the processor is actually running. - * NOTE: This does not indicate that device has completed - * init or post-power-down restore of internal SRAM memory. - * Use CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP as indication that - * SRAM is restored and uCode is in normal operation mode. - * This note is relevant only for pre 5xxx devices. - * NOTE: After device reset, this bit remains "0" until host sets - * INIT_DONE - * @flag_init_done: Host sets this to put device into fully operational - * D0 power mode. Host resets this after SW_RESET to put device into - * low power mode. - * @flag_mac_access_req: Host sets this to request and maintain MAC wakeup, - * to allow host access to device-internal resources. Host must wait for - * mac_clock_ready (and !GOING_TO_SLEEP) before accessing non-CSR device - * registers. - * @flag_val_mac_access_en: mac access is enabled - * @flag_master_dis: disable master - * @flag_stop_master: stop master - * @addr_sw_reset: address for resetting the device - * @mac_addr0_otp: first part of MAC address from OTP - * @mac_addr1_otp: second part of MAC address from OTP - * @mac_addr0_strap: first part of MAC address from strap - * @mac_addr1_strap: second part of MAC address from strap - */ -struct iwl_csr_params { - u8 flag_sw_reset; - u8 flag_mac_clock_ready; - u8 flag_init_done; - u8 flag_mac_access_req; - u8 flag_val_mac_access_en; - u8 flag_master_dis; - u8 flag_stop_master; - u8 addr_sw_reset; - u32 mac_addr0_otp; - u32 mac_addr1_otp; - u32 mac_addr0_strap; - u32 mac_addr1_strap; -}; - /** * struct iwl_cfg_trans - information needed to start the trans * @@ -348,7 +302,6 @@ struct iwl_csr_params { */ struct iwl_cfg_trans_params { const struct iwl_base_params *base_params; - const struct iwl_csr_params *csr; enum iwl_device_family device_family; u32 umac_prph_offset; u32 rf_id:1, @@ -499,9 +452,6 @@ struct iwl_cfg { const struct iwl_fw_mon_regs mon_smem_regs; }; -extern const struct iwl_csr_params iwl_csr_v1; -extern const struct iwl_csr_params iwl_csr_v2; - /* * This list declares the config structures for all devices. */ diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h index 92d9898ab7c24..2c150778d1446 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h @@ -256,6 +256,7 @@ /* RESET */ #define CSR_RESET_REG_FLAG_NEVO_RESET (0x00000001) #define CSR_RESET_REG_FLAG_FORCE_NMI (0x00000002) +#define CSR_RESET_REG_FLAG_SW_RESET (0x00000080) #define CSR_RESET_REG_FLAG_MASTER_DISABLED (0x00000100) #define CSR_RESET_REG_FLAG_STOP_MASTER (0x00000200) #define CSR_RESET_LINK_PWR_MGMT_DISABLED (0x80000000) @@ -278,11 +279,35 @@ * 4: GOING_TO_SLEEP * Indicates MAC is entering a power-saving sleep power-down. * Not a good time to access device-internal resources. + * 3: MAC_ACCESS_REQ + * Host sets this to request and maintain MAC wakeup, to allow host + * access to device-internal resources. Host must wait for + * MAC_CLOCK_READY (and !GOING_TO_SLEEP) before accessing non-CSR + * device registers. + * 2: INIT_DONE + * Host sets this to put device into fully operational D0 power mode. + * Host resets this after SW_RESET to put device into low power mode. + * 0: MAC_CLOCK_READY + * Indicates MAC (ucode processor, etc.) is powered up and can run. + * Internal resources are accessible. + * NOTE: This does not indicate that the processor is actually running. + * NOTE: This does not indicate that device has completed + * init or post-power-down restore of internal SRAM memory. + * Use CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP as indication that + * SRAM is restored and uCode is in normal operation mode. + * Later devices (5xxx/6xxx/1xxx) use non-volatile SRAM, and + * do not need to save/restore it. + * NOTE: After device reset, this bit remains "0" until host sets + * INIT_DONE */ +#define CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY (0x00000001) #define CSR_GP_CNTRL_REG_FLAG_INIT_DONE (0x00000004) -#define CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP (0x00000010) +#define CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ (0x00000008) +#define CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP (0x00000010) #define CSR_GP_CNTRL_REG_FLAG_XTAL_ON (0x00000400) +#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_RFKILL_WAKE_L1A_EN (0x04000000) #define CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW (0x08000000) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-io.c b/drivers/net/wireless/intel/iwlwifi/iwl-io.c index 1b7414bf7bef2..2139f0b8f2bba 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-io.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-io.c @@ -70,36 +70,6 @@ #include "iwl-prph.h" #include "iwl-fh.h" -const struct iwl_csr_params iwl_csr_v1 = { - .flag_mac_clock_ready = 0, - .flag_val_mac_access_en = 0, - .flag_init_done = 2, - .flag_mac_access_req = 3, - .flag_sw_reset = 7, - .flag_master_dis = 8, - .flag_stop_master = 9, - .addr_sw_reset = CSR_BASE + 0x020, - .mac_addr0_otp = 0x380, - .mac_addr1_otp = 0x384, - .mac_addr0_strap = 0x388, - .mac_addr1_strap = 0x38C -}; - -const struct iwl_csr_params iwl_csr_v2 = { - .flag_init_done = 6, - .flag_mac_clock_ready = 20, - .flag_val_mac_access_en = 20, - .flag_mac_access_req = 21, - .flag_master_dis = 28, - .flag_stop_master = 29, - .flag_sw_reset = 31, - .addr_sw_reset = CSR_BASE + 0x024, - .mac_addr0_otp = 0x30, - .mac_addr1_otp = 0x34, - .mac_addr0_strap = 0x38, - .mac_addr1_strap = 0x3C -}; - void iwl_write8(struct iwl_trans *trans, u32 ofs, u8 val) { trace_iwlwifi_dev_iowrite8(trans->dev, ofs, val); @@ -506,8 +476,7 @@ int iwl_finish_nic_init(struct iwl_trans *trans, * Set "initialization complete" bit to move adapter from * D0U* --> D0A* (powered-up active) state. */ - iwl_set_bit(trans, CSR_GP_CNTRL, - BIT(cfg_trans->csr->flag_init_done)); + iwl_set_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); if (cfg_trans->device_family == IWL_DEVICE_FAMILY_8000) udelay(2); @@ -518,8 +487,8 @@ int iwl_finish_nic_init(struct iwl_trans *trans, * and accesses to uCode SRAM. */ err = iwl_poll_bit(trans, CSR_GP_CNTRL, - BIT(cfg_trans->csr->flag_mac_clock_ready), - BIT(cfg_trans->csr->flag_mac_clock_ready), + CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, + CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); if (err < 0) IWL_DEBUG_INFO(trans, "Failed to wake NIC\n"); diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c index 1e240a2a83290..4e706c684b1d4 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c @@ -801,12 +801,8 @@ static void iwl_flip_hw_address(__le32 mac_addr0, __le32 mac_addr1, u8 *dest) static void iwl_set_hw_address_from_csr(struct iwl_trans *trans, struct iwl_nvm_data *data) { - __le32 mac_addr0 = - cpu_to_le32(iwl_read32(trans, - trans->trans_cfg->csr->mac_addr0_strap)); - __le32 mac_addr1 = - cpu_to_le32(iwl_read32(trans, - trans->trans_cfg->csr->mac_addr1_strap)); + __le32 mac_addr0 = cpu_to_le32(iwl_read32(trans, CSR_MAC_ADDR0_STRAP)); + __le32 mac_addr1 = cpu_to_le32(iwl_read32(trans, CSR_MAC_ADDR1_STRAP)); iwl_flip_hw_address(mac_addr0, mac_addr1, data->hw_addr); /* @@ -816,10 +812,8 @@ static void iwl_set_hw_address_from_csr(struct iwl_trans *trans, if (is_valid_ether_addr(data->hw_addr)) return; - mac_addr0 = cpu_to_le32(iwl_read32(trans, - trans->trans_cfg->csr->mac_addr0_otp)); - mac_addr1 = cpu_to_le32(iwl_read32(trans, - trans->trans_cfg->csr->mac_addr1_otp)); + mac_addr0 = cpu_to_le32(iwl_read32(trans, CSR_MAC_ADDR0_OTP)); + mac_addr1 = cpu_to_le32(iwl_read32(trans, CSR_MAC_ADDR1_OTP)); iwl_flip_hw_address(mac_addr0, mac_addr1, data->hw_addr); } diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index bac3d3fa0dece..79c24c696c8f8 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -1007,12 +1007,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /* the trans_cfg should never change, so set it now */ iwl_trans->trans_cfg = &cfg->trans; - if (WARN_ONCE(!iwl_trans->trans_cfg->csr, - "CSR addresses aren't configured\n")) { - ret = -EINVAL; - goto out_free_trans; - } - #if IS_ENABLED(CONFIG_IWLMVM) /* * special-case 7265D, it has the same PCI IDs. diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c index 498a14ebac472..12fec6d59eb9e 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c @@ -240,7 +240,7 @@ static void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans *trans, IWL_DEBUG_INFO(trans, "Rx queue requesting wakeup, GP1 = 0x%x\n", reg); iwl_set_bit(trans, CSR_GP_CNTRL, - BIT(trans->trans_cfg->csr->flag_mac_access_req)); + CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); rxq->need_update = true; return; } diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c index 0252716c0b247..c1bb7150489a6 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c @@ -157,8 +157,7 @@ static void iwl_pcie_gen2_apm_stop(struct iwl_trans *trans, bool op_mode_leave) * Clear "initialization complete" bit to move adapter from * D0A* (powered-up Active) --> D0U* (Uninitialized) state. */ - iwl_clear_bit(trans, CSR_GP_CNTRL, - BIT(trans->trans_cfg->csr->flag_init_done)); + iwl_clear_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); } void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans) @@ -200,7 +199,7 @@ void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans) /* Make sure (redundant) we've released our request to stay awake */ iwl_clear_bit(trans, CSR_GP_CNTRL, - BIT(trans->trans_cfg->csr->flag_mac_access_req)); + CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); /* Stop the device, and put it in low power state */ iwl_pcie_gen2_apm_stop(trans, false); diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index cb49154517925..3db1313f92706 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -183,8 +183,7 @@ void iwl_trans_pcie_dump_regs(struct iwl_trans *trans) static void iwl_trans_pcie_sw_reset(struct iwl_trans *trans) { /* Reset entire device - do controller reset (results in SHRD_HW_RST) */ - iwl_set_bit(trans, trans->trans_cfg->csr->addr_sw_reset, - BIT(trans->trans_cfg->csr->flag_sw_reset)); + iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); usleep_range(5000, 6000); } @@ -487,8 +486,7 @@ static void iwl_pcie_apm_lp_xtal_enable(struct iwl_trans *trans) * Clear "initialization complete" bit to move adapter from * D0A* (powered-up Active) --> D0U* (Uninitialized) state. */ - iwl_clear_bit(trans, CSR_GP_CNTRL, - BIT(trans->trans_cfg->csr->flag_init_done)); + iwl_clear_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); /* Activates XTAL resources monitor */ __iwl_trans_pcie_set_bit(trans, CSR_MONITOR_CFG_REG, @@ -510,12 +508,11 @@ void iwl_pcie_apm_stop_master(struct iwl_trans *trans) int ret; /* stop device's busmaster DMA activity */ - iwl_set_bit(trans, trans->trans_cfg->csr->addr_sw_reset, - BIT(trans->trans_cfg->csr->flag_stop_master)); + iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER); - ret = iwl_poll_bit(trans, trans->trans_cfg->csr->addr_sw_reset, - BIT(trans->trans_cfg->csr->flag_master_dis), - BIT(trans->trans_cfg->csr->flag_master_dis), 100); + ret = iwl_poll_bit(trans, CSR_RESET, + CSR_RESET_REG_FLAG_MASTER_DISABLED, + CSR_RESET_REG_FLAG_MASTER_DISABLED, 100); if (ret < 0) IWL_WARN(trans, "Master Disable Timed Out, 100 usec\n"); @@ -564,8 +561,7 @@ static void iwl_pcie_apm_stop(struct iwl_trans *trans, bool op_mode_leave) * Clear "initialization complete" bit to move adapter from * D0A* (powered-up Active) --> D0U* (Uninitialized) state. */ - iwl_clear_bit(trans, CSR_GP_CNTRL, - BIT(trans->trans_cfg->csr->flag_init_done)); + iwl_clear_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); } static int iwl_pcie_nic_init(struct iwl_trans *trans) @@ -1270,7 +1266,7 @@ static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans) /* Make sure (redundant) we've released our request to stay awake */ iwl_clear_bit(trans, CSR_GP_CNTRL, - BIT(trans->trans_cfg->csr->flag_mac_access_req)); + CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); /* Stop the device, and put it in low power state */ iwl_pcie_apm_stop(trans, false); @@ -1494,9 +1490,8 @@ void iwl_pcie_d3_complete_suspend(struct iwl_trans *trans, iwl_pcie_synchronize_irqs(trans); iwl_clear_bit(trans, CSR_GP_CNTRL, - BIT(trans->trans_cfg->csr->flag_mac_access_req)); - iwl_clear_bit(trans, CSR_GP_CNTRL, - BIT(trans->trans_cfg->csr->flag_init_done)); + CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); + iwl_clear_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); if (reset) { /* @@ -1561,7 +1556,7 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans, } iwl_set_bit(trans, CSR_GP_CNTRL, - BIT(trans->trans_cfg->csr->flag_mac_access_req)); + CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); ret = iwl_finish_nic_init(trans, trans->trans_cfg); if (ret) @@ -1583,7 +1578,7 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans, if (!reset) { iwl_clear_bit(trans, CSR_GP_CNTRL, - BIT(trans->trans_cfg->csr->flag_mac_access_req)); + CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); } else { iwl_trans_pcie_tx_reset(trans); @@ -2029,7 +2024,7 @@ static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, /* this bit wakes up the NIC */ __iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL, - BIT(trans->trans_cfg->csr->flag_mac_access_req)); + CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_8000) udelay(2); @@ -2054,8 +2049,8 @@ static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, * and do not save/restore SRAM when power cycling. */ ret = iwl_poll_bit(trans, CSR_GP_CNTRL, - BIT(trans->trans_cfg->csr->flag_val_mac_access_en), - (BIT(trans->trans_cfg->csr->flag_mac_clock_ready) | + CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN, + (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY | CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000); if (unlikely(ret < 0)) { u32 cntrl = iwl_read32(trans, CSR_GP_CNTRL); @@ -2137,7 +2132,7 @@ static void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans, goto out; __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL, - BIT(trans->trans_cfg->csr->flag_mac_access_req)); + CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); /* * Above we read the CSR_GP_CNTRL register, which will flush * any previous writes, but we need the write that clears the diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c index f21f16ab2a970..9ac03122653ca 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c @@ -306,7 +306,7 @@ static void iwl_pcie_txq_inc_wr_ptr(struct iwl_trans *trans, IWL_DEBUG_INFO(trans, "Tx queue %d requesting wakeup, GP1 = 0x%x\n", txq_id, reg); iwl_set_bit(trans, CSR_GP_CNTRL, - BIT(trans->trans_cfg->csr->flag_mac_access_req)); + CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); txq->need_update = true; return; } @@ -646,7 +646,7 @@ static void iwl_pcie_clear_cmd_in_flight(struct iwl_trans *trans) trans_pcie->cmd_hold_nic_awake = false; __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL, - BIT(trans->trans_cfg->csr->flag_mac_access_req)); + CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); } /* @@ -1255,16 +1255,16 @@ static int iwl_pcie_set_cmd_in_flight(struct iwl_trans *trans, if (trans->trans_cfg->base_params->apmg_wake_up_wa && !trans_pcie->cmd_hold_nic_awake) { __iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL, - BIT(trans->trans_cfg->csr->flag_mac_access_req)); + CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); ret = iwl_poll_bit(trans, CSR_GP_CNTRL, - BIT(trans->trans_cfg->csr->flag_val_mac_access_en), - (BIT(trans->trans_cfg->csr->flag_mac_clock_ready) | + CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN, + (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY | CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000); if (ret < 0) { __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL, - BIT(trans->trans_cfg->csr->flag_mac_access_req)); + CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); IWL_ERR(trans, "Failed to wake NIC for hcmd\n"); return -EIO; } From 3e8bac0cf131353ddf69f35c89b650c4f5a34a2f Mon Sep 17 00:00:00 2001 From: Andrei Otcheretianski Date: Sun, 27 Oct 2019 14:01:43 +0200 Subject: [PATCH 12/23] iwlwifi: mvm: Update BEACON_TEMPLATE_CMD firmware API The new API version adds support for FILS discovery frames. It adds a new flag and a field for short SSID configuration. The new API is backward compatible, so we can just switch to it. Signed-off-by: Andrei Otcheretianski Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/api/tx.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h b/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h index f89a9e16a8c00..f1d1fe96fecc4 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h @@ -813,6 +813,7 @@ enum iwl_mac_beacon_flags { IWL_MAC_BEACON_ANT_A = BIT(9), IWL_MAC_BEACON_ANT_B = BIT(10), IWL_MAC_BEACON_ANT_C = BIT(11), + IWL_MAC_BEACON_FILS = BIT(12), }; /** @@ -820,6 +821,7 @@ enum iwl_mac_beacon_flags { * @byte_cnt: byte count of the beacon frame. * @flags: least significant byte for rate code. The most significant byte * is &enum iwl_mac_beacon_flags. + * @short_ssid: Short SSID * @reserved: reserved * @template_id: currently equal to the mac context id of the coresponding mac. * @tim_idx: the offset of the tim IE in the beacon @@ -831,14 +833,15 @@ enum iwl_mac_beacon_flags { struct iwl_mac_beacon_cmd { __le16 byte_cnt; __le16 flags; - __le64 reserved; + __le32 short_ssid; + __le32 reserved; __le32 template_id; __le32 tim_idx; __le32 tim_size; __le32 ecsa_offset; __le32 csa_offset; struct ieee80211_hdr frame[0]; -} __packed; /* BEACON_TEMPLATE_CMD_API_S_VER_9 */ +} __packed; /* BEACON_TEMPLATE_CMD_API_S_VER_10 */ struct iwl_beacon_notif { struct iwl_mvm_tx_resp beacon_notify_hdr; From 10137f07571287aaa602f492d11db062f2dd3a29 Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Mon, 28 Oct 2019 11:18:05 +0200 Subject: [PATCH 13/23] iwlwifi: yoyo: don't allow changing the domain via debugfs We don't want to allow changing the domain via debugfs so that we can apply the domain to all TLV types more easily (doing some at runtime is difficult due to buffer allocations etc.). Change the fw_dbg_domain debugfs file to be read-only and remove the write function. Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/fw/debugfs.c | 29 ++----------------- .../net/wireless/intel/iwlwifi/iwl-dbg-tlv.c | 3 +- .../net/wireless/intel/iwlwifi/iwl-dbg-tlv.h | 1 - 3 files changed, 4 insertions(+), 29 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c index ca3b1a461deae..89f74116569d0 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c @@ -320,31 +320,6 @@ static ssize_t iwl_dbgfs_send_hcmd_write(struct iwl_fw_runtime *fwrt, char *buf, FWRT_DEBUGFS_WRITE_FILE_OPS(send_hcmd, 512); -static ssize_t iwl_dbgfs_fw_dbg_domain_write(struct iwl_fw_runtime *fwrt, - char *buf, size_t count) -{ - u32 new_domain; - int ret; - - if (!iwl_trans_fw_running(fwrt->trans)) - return -EIO; - - ret = kstrtou32(buf, 0, &new_domain); - if (ret) - return ret; - - if (new_domain != fwrt->trans->dbg.domains_bitmap) { - ret = iwl_dbg_tlv_gen_active_trigs(fwrt, new_domain); - if (ret) - return ret; - - iwl_dbg_tlv_time_point(fwrt, IWL_FW_INI_TIME_POINT_PERIODIC, - NULL); - } - - return count; -} - static ssize_t iwl_dbgfs_fw_dbg_domain_read(struct iwl_fw_runtime *fwrt, size_t size, char *buf) { @@ -352,7 +327,7 @@ static ssize_t iwl_dbgfs_fw_dbg_domain_read(struct iwl_fw_runtime *fwrt, fwrt->trans->dbg.domains_bitmap); } -FWRT_DEBUGFS_READ_WRITE_FILE_OPS(fw_dbg_domain, 20); +FWRT_DEBUGFS_READ_FILE_OPS(fw_dbg_domain, 20); void iwl_fwrt_dbgfs_register(struct iwl_fw_runtime *fwrt, struct dentry *dbgfs_dir) @@ -360,5 +335,5 @@ void iwl_fwrt_dbgfs_register(struct iwl_fw_runtime *fwrt, INIT_DELAYED_WORK(&fwrt->timestamp.wk, iwl_fw_timestamp_marker_wk); FWRT_DEBUGFS_ADD_FILE(timestamp_marker, dbgfs_dir, 0200); FWRT_DEBUGFS_ADD_FILE(send_hcmd, dbgfs_dir, 0200); - FWRT_DEBUGFS_ADD_FILE(fw_dbg_domain, dbgfs_dir, 0600); + FWRT_DEBUGFS_ADD_FILE(fw_dbg_domain, dbgfs_dir, 0400); } diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c index f266647dc08c8..79c8c8057c2d6 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c @@ -913,7 +913,8 @@ iwl_dbg_tlv_gen_active_trig_list(struct iwl_fw_runtime *fwrt, } } -int iwl_dbg_tlv_gen_active_trigs(struct iwl_fw_runtime *fwrt, u32 new_domain) +static int iwl_dbg_tlv_gen_active_trigs(struct iwl_fw_runtime *fwrt, + u32 new_domain) { int i; diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h index f18946872569b..1360676b3b21a 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h @@ -105,7 +105,6 @@ void iwl_dbg_tlv_init(struct iwl_trans *trans); void iwl_dbg_tlv_time_point(struct iwl_fw_runtime *fwrt, enum iwl_fw_ini_time_point tp_id, union iwl_dbg_tlv_tp_data *tp_data); -int iwl_dbg_tlv_gen_active_trigs(struct iwl_fw_runtime *fwrt, u32 new_domain); void iwl_dbg_tlv_del_timers(struct iwl_trans *trans); #endif /* __iwl_dbg_tlv_h__*/ From 058c411d19b21b8e5581cdeddae2392d5f421daa Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Mon, 28 Oct 2019 12:39:10 +0200 Subject: [PATCH 14/23] iwlwifi: yoyo: remove unnecessary active triggers status flag Now that we can't change the domain at runtime anymore, we don't have to protect the active trigger status. Remove it. Additionally, we don't need to flush the dumps at this point anymore, since this only runs during initialization and there shouldn't be any dumps running. Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 3 --- drivers/net/wireless/intel/iwlwifi/fw/runtime.h | 11 ----------- drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c | 14 +------------- 3 files changed, 1 insertion(+), 27 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index c8bc6b9b53a4a..09daf0f1f6f87 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -2353,9 +2353,6 @@ int iwl_fw_dbg_ini_collect(struct iwl_fw_runtime *fwrt, u32 occur, delay; unsigned long idx; - if (test_bit(STATUS_GEN_ACTIVE_TRIGS, &fwrt->status)) - return -EBUSY; - if (!iwl_fw_ini_trigger_on(fwrt, trig)) { IWL_WARN(fwrt, "WRT: Trigger %d is not active, aborting dump\n", tp_id); diff --git a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h index c24575ff0e54c..1b4bca717e79f 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h @@ -129,14 +129,6 @@ struct iwl_txf_iter_data { u8 internal_txf; }; -/** - * enum iwl_fw_runtime_status - fw runtime status flags - * @STATUS_GEN_ACTIVE_TRIGS: generating active trigger list - */ -enum iwl_fw_runtime_status { - STATUS_GEN_ACTIVE_TRIGS, -}; - /** * struct iwl_fw_runtime - runtime data for firmware * @fw: firmware image @@ -150,7 +142,6 @@ enum iwl_fw_runtime_status { * @smem_cfg: saved firmware SMEM configuration * @cur_fw_img: current firmware image, must be maintained by * the driver by calling &iwl_fw_set_current_image() - * @status: &enum iwl_fw_runtime_status * @dump: debug dump data */ struct iwl_fw_runtime { @@ -171,8 +162,6 @@ struct iwl_fw_runtime { /* memory configuration */ struct iwl_fwrt_shared_mem_cfg smem_cfg; - unsigned long status; - /* debug */ struct { const struct iwl_fw_dump_desc *desc; diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c index 79c8c8057c2d6..4acb24f8fc11a 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c @@ -891,15 +891,10 @@ static void iwl_dbg_tlv_gen_active_trig_list(struct iwl_fw_runtime *fwrt, struct iwl_dbg_tlv_time_point_data *tp) { - struct iwl_dbg_tlv_node *node, *tmp; + struct iwl_dbg_tlv_node *node; struct list_head *trig_list = &tp->trig_list; struct list_head *active_trig_list = &tp->active_trig_list; - list_for_each_entry_safe(node, tmp, active_trig_list, list) { - list_del(&node->list); - kfree(node); - } - list_for_each_entry(node, trig_list, list) { struct iwl_ucode_tlv *tlv = &node->tlv; struct iwl_fw_ini_trigger_tlv *trig = (void *)tlv->data; @@ -918,11 +913,6 @@ static int iwl_dbg_tlv_gen_active_trigs(struct iwl_fw_runtime *fwrt, { int i; - if (test_and_set_bit(STATUS_GEN_ACTIVE_TRIGS, &fwrt->status)) - return -EBUSY; - - iwl_fw_flush_dumps(fwrt); - fwrt->trans->dbg.domains_bitmap = new_domain; IWL_DEBUG_FW(fwrt, @@ -936,8 +926,6 @@ static int iwl_dbg_tlv_gen_active_trigs(struct iwl_fw_runtime *fwrt, iwl_dbg_tlv_gen_active_trig_list(fwrt, tp); } - clear_bit(STATUS_GEN_ACTIVE_TRIGS, &fwrt->status); - return 0; } From 5cbc310810090cf5a295835113d3b9e5dbbe587f Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Mon, 28 Oct 2019 12:57:00 +0200 Subject: [PATCH 15/23] iwlwifi: yoyo: remove the iwl_dbg_tlv_gen_active_trigs() function We only call this function from a single place and it's very very small and self-contained anyway, so remove the function and move the code into the caller. Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/iwl-dbg-tlv.c | 34 +++++++------------ 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c index 4acb24f8fc11a..31a0e885faf6f 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c @@ -908,27 +908,6 @@ iwl_dbg_tlv_gen_active_trig_list(struct iwl_fw_runtime *fwrt, } } -static int iwl_dbg_tlv_gen_active_trigs(struct iwl_fw_runtime *fwrt, - u32 new_domain) -{ - int i; - - fwrt->trans->dbg.domains_bitmap = new_domain; - - IWL_DEBUG_FW(fwrt, - "WRT: Generating active triggers list, domain 0x%x\n", - fwrt->trans->dbg.domains_bitmap); - - for (i = 0; i < ARRAY_SIZE(fwrt->trans->dbg.time_point); i++) { - struct iwl_dbg_tlv_time_point_data *tp = - &fwrt->trans->dbg.time_point[i]; - - iwl_dbg_tlv_gen_active_trig_list(fwrt, tp); - } - - return 0; -} - static bool iwl_dbg_tlv_check_fw_pkt(struct iwl_fw_runtime *fwrt, struct iwl_fwrt_dump_data *dump_data, union iwl_dbg_tlv_tp_data *tp_data, @@ -1002,7 +981,18 @@ static void iwl_dbg_tlv_init_cfg(struct iwl_fw_runtime *fwrt) enum iwl_fw_ini_buffer_location *ini_dest = &fwrt->trans->dbg.ini_dest; int ret, i; - iwl_dbg_tlv_gen_active_trigs(fwrt, IWL_FW_DBG_DOMAIN); + fwrt->trans->dbg.domains_bitmap = IWL_FW_DBG_DOMAIN; + + IWL_DEBUG_FW(fwrt, + "WRT: Generating active triggers list, domain 0x%x\n", + fwrt->trans->dbg.domains_bitmap); + + for (i = 0; i < ARRAY_SIZE(fwrt->trans->dbg.time_point); i++) { + struct iwl_dbg_tlv_time_point_data *tp = + &fwrt->trans->dbg.time_point[i]; + + iwl_dbg_tlv_gen_active_trig_list(fwrt, tp); + } *ini_dest = IWL_FW_INI_LOCATION_INVALID; for (i = 0; i < IWL_FW_INI_ALLOCATION_NUM; i++) { From e6ec237d3068dd023f5a20fd6c11527e57961019 Mon Sep 17 00:00:00 2001 From: Oren Givon Date: Tue, 22 Oct 2019 14:14:24 +0300 Subject: [PATCH 16/23] iwlwifi: add new iwlax411 struct for type SoSnj Add new struct for SoSnj and add uhb support for ax411 structs. Signed-off-by: Oren Givon Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/cfg/22000.c | 10 ++++++++++ drivers/net/wireless/intel/iwlwifi/iwl-config.h | 1 + 2 files changed, 11 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c index 837c06891f5e4..a22a830019c08 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c @@ -92,6 +92,7 @@ #define IWL_22000_SO_A_GF_A_FW_PRE "iwlwifi-so-a0-gf-a0-" #define IWL_22000_TY_A_GF_A_FW_PRE "iwlwifi-ty-a0-gf-a0-" #define IWL_22000_SO_A_GF4_A_FW_PRE "iwlwifi-so-a0-gf4-a0-" +#define IWL_22000_SOSNJ_A_GF4_A_FW_PRE "iwlwifi-SoSnj-a0-gf4-a0-" #define IWL_22000_HR_MODULE_FIRMWARE(api) \ IWL_22000_HR_FW_PRE __stringify(api) ".ucode" @@ -707,6 +708,15 @@ const struct iwl_cfg iwlax210_2ax_cfg_ty_gf_a0 = { const struct iwl_cfg iwlax411_2ax_cfg_so_gf4_a0 = { .name = "Intel(R) Wi-Fi 7 AX411 160MHz", .fw_name_pre = IWL_22000_SO_A_GF4_A_FW_PRE, + .uhb_supported = true, + IWL_DEVICE_AX210, + .num_rbds = IWL_NUM_RBDS_AX210_HE, +}; + +const struct iwl_cfg iwlax411_2ax_cfg_sosnj_gf4_a0 = { + .name = "Intel(R) Wi-Fi 7 AX411 160MHz", + .fw_name_pre = IWL_22000_SOSNJ_A_GF4_A_FW_PRE, + .uhb_supported = true, IWL_DEVICE_AX210, .num_rbds = IWL_NUM_RBDS_AX210_HE, }; diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h index bb91c36c9d8b2..bbeb5fc3caad9 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h @@ -586,6 +586,7 @@ extern const struct iwl_cfg iwlax210_2ax_cfg_so_hr_a0; extern const struct iwl_cfg iwlax211_2ax_cfg_so_gf_a0; extern const struct iwl_cfg iwlax210_2ax_cfg_ty_gf_a0; extern const struct iwl_cfg iwlax411_2ax_cfg_so_gf4_a0; +extern const struct iwl_cfg iwlax411_2ax_cfg_sosnj_gf4_a0; #endif /* CPTCFG_IWLMVM || CPTCFG_IWLFMAC */ #endif /* __IWL_CONFIG_H__ */ From e701da0c2320148a378ed1d191b6c4f7e8e82c4c Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Wed, 30 Oct 2019 09:40:12 +0200 Subject: [PATCH 17/23] iwlwifi: yoyo: check for the domain on all TLV types during init Now that we don't have dynamically changing domains anymore, we can simply skip all the TLVs with domains that are not enabled. To do so, remove the checks from the functions that handle the TLVs when a timepoint is reached to the top allocation function. Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/fw/runtime.h | 2 +- .../net/wireless/intel/iwlwifi/iwl-dbg-tlv.c | 22 ++++++++----------- drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 2 ++ .../net/wireless/intel/iwlwifi/iwl-trans.h | 2 ++ 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h index 1b4bca717e79f..f8c6ed823bc54 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h @@ -69,7 +69,7 @@ #include "iwl-eeprom-parse.h" #include "fw/acpi.h" -#define IWL_FW_DBG_DOMAIN IWL_FW_INI_DOMAIN_ALWAYS_ON +#define IWL_FW_DBG_DOMAIN IWL_TRANS_FW_DBG_DOMAIN(fwrt->trans) struct iwl_fw_runtime_ops { int (*dump_start)(void *ctx); diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c index 31a0e885faf6f..eaf64ca3a1346 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c @@ -290,10 +290,19 @@ void iwl_dbg_tlv_alloc(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv, struct iwl_fw_ini_header *hdr = (void *)&tlv->data[0]; u32 type = le32_to_cpu(tlv->type); u32 tlv_idx = type - IWL_UCODE_TLV_DEBUG_BASE; + u32 domain = le32_to_cpu(hdr->domain); enum iwl_ini_cfg_state *cfg_state = ext ? &trans->dbg.external_ini_cfg : &trans->dbg.internal_ini_cfg; int ret; + if (domain != IWL_FW_INI_DOMAIN_ALWAYS_ON && + !(domain & trans->dbg.domains_bitmap)) { + IWL_DEBUG_FW(trans, + "WRT: Skipping TLV with disabled domain 0x%0x (0x%0x)\n", + domain, trans->dbg.domains_bitmap); + return; + } + if (tlv_idx >= ARRAY_SIZE(dbg_tlv_alloc) || !dbg_tlv_alloc[tlv_idx]) { IWL_ERR(trans, "WRT: Unsupported TLV type 0x%x\n", type); goto out_err; @@ -660,7 +669,6 @@ static void iwl_dbg_tlv_send_hcmds(struct iwl_fw_runtime *fwrt, list_for_each_entry(node, hcmd_list, list) { struct iwl_fw_ini_hcmd_tlv *hcmd = (void *)node->tlv.data; struct iwl_fw_ini_hcmd *hcmd_data = &hcmd->hcmd; - u32 domain = le32_to_cpu(hcmd->hdr.domain); u16 hcmd_len = le32_to_cpu(node->tlv.length) - sizeof(*hcmd); struct iwl_host_cmd cmd = { .id = WIDE_ID(hcmd_data->group, hcmd_data->id), @@ -668,10 +676,6 @@ static void iwl_dbg_tlv_send_hcmds(struct iwl_fw_runtime *fwrt, .data = { hcmd_data->data, }, }; - if (domain != IWL_FW_INI_DOMAIN_ALWAYS_ON && - !(domain & fwrt->trans->dbg.domains_bitmap)) - continue; - iwl_trans_send_cmd(fwrt->trans, &cmd); } } @@ -897,12 +901,6 @@ iwl_dbg_tlv_gen_active_trig_list(struct iwl_fw_runtime *fwrt, list_for_each_entry(node, trig_list, list) { struct iwl_ucode_tlv *tlv = &node->tlv; - struct iwl_fw_ini_trigger_tlv *trig = (void *)tlv->data; - u32 domain = le32_to_cpu(trig->hdr.domain); - - if (domain != IWL_FW_INI_DOMAIN_ALWAYS_ON && - !(domain & fwrt->trans->dbg.domains_bitmap)) - continue; iwl_dbg_tlv_add_active_trigger(fwrt, active_trig_list, tlv); } @@ -981,8 +979,6 @@ static void iwl_dbg_tlv_init_cfg(struct iwl_fw_runtime *fwrt) enum iwl_fw_ini_buffer_location *ini_dest = &fwrt->trans->dbg.ini_dest; int ret, i; - fwrt->trans->dbg.domains_bitmap = IWL_FW_DBG_DOMAIN; - IWL_DEBUG_FW(fwrt, "WRT: Generating active triggers list, domain 0x%x\n", fwrt->trans->dbg.domains_bitmap); diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c index 4096ccf58b070..c6cb5e1a1bd91 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c @@ -1647,6 +1647,8 @@ struct iwl_drv *iwl_drv_start(struct iwl_trans *trans) drv->trans->dbgfs_dir = debugfs_create_dir("trans", drv->dbgfs_drv); #endif + drv->trans->dbg.domains_bitmap = IWL_TRANS_FW_DBG_DOMAIN(drv->trans); + ret = iwl_request_firmware(drv, true); if (ret) { IWL_ERR(trans, "Couldn't request the fw\n"); diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h index 872cda2be0f6c..58bee4442e201 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h @@ -112,6 +112,8 @@ * 6) Eventually, the free function will be called. */ +#define IWL_TRANS_FW_DBG_DOMAIN(trans) IWL_FW_INI_DOMAIN_ALWAYS_ON + #define FH_RSCSR_FRAME_SIZE_MSK 0x00003FFF /* bits 0-13 */ #define FH_RSCSR_FRAME_INVALID 0x55550000 #define FH_RSCSR_FRAME_ALIGN 0x40 From 55b514b479ff8a6e2473e7ef2349d49380c5fa61 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 31 Oct 2019 10:28:32 +0100 Subject: [PATCH 18/23] iwlwifi: incorporate firmware filename into version We have many different firmware images with the same version, and it's sometimes cumbersome to figure out which image was really used, especially as the marketing strings that we do print out can be the same for (slightly) different hardware using different firmware images. Incorporate the firmware filename into the fw_version so it's printed out all the time. Unfortunately, this will make the string be longer than the 32 characters for ethtool, but we almost never really use ethtool, so strip the "iwlwifi-" prefix (if not overridden), and the remaining data that may then be stripped at the end is not usually useful anyway. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/img.h | 2 +- drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 24 +++++++++++++++----- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/img.h b/drivers/net/wireless/intel/iwlwifi/fw/img.h index 994880a83652a..90ca5f929cf9b 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/img.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/img.h @@ -251,7 +251,7 @@ struct iwl_fw_dbg { struct iwl_fw { u32 ucode_ver; - char fw_version[ETHTOOL_FWVERS_LEN]; + char fw_version[64]; /* ucode images */ struct fw_img img[IWL_UCODE_TYPE_MAX]; diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c index c6cb5e1a1bd91..773de0b724be6 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c @@ -493,6 +493,16 @@ static void iwl_set_ucode_capabilities(struct iwl_drv *drv, const u8 *data, } } +static const char *iwl_reduced_fw_name(struct iwl_drv *drv) +{ + const char *name = drv->firmware_name; + + if (strncmp(name, "iwlwifi-", 8) == 0) + name += 8; + + return name; +} + static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv, const struct firmware *ucode_raw, struct iwl_firmware_pieces *pieces) @@ -551,12 +561,12 @@ static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv, snprintf(drv->fw.fw_version, sizeof(drv->fw.fw_version), - "%u.%u.%u.%u%s", + "%u.%u.%u.%u%s %s", IWL_UCODE_MAJOR(drv->fw.ucode_ver), IWL_UCODE_MINOR(drv->fw.ucode_ver), IWL_UCODE_API(drv->fw.ucode_ver), IWL_UCODE_SERIAL(drv->fw.ucode_ver), - buildstr); + buildstr, iwl_reduced_fw_name(drv)); /* Verify size of file vs. image size info in file's header */ @@ -636,12 +646,12 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, snprintf(drv->fw.fw_version, sizeof(drv->fw.fw_version), - "%u.%u.%u.%u%s", + "%u.%u.%u.%u%s %s", IWL_UCODE_MAJOR(drv->fw.ucode_ver), IWL_UCODE_MINOR(drv->fw.ucode_ver), IWL_UCODE_API(drv->fw.ucode_ver), IWL_UCODE_SERIAL(drv->fw.ucode_ver), - buildstr); + buildstr, iwl_reduced_fw_name(drv)); data = ucode->data; @@ -895,11 +905,13 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, if (major >= 35) snprintf(drv->fw.fw_version, sizeof(drv->fw.fw_version), - "%u.%08x.%u", major, minor, local_comp); + "%u.%08x.%u %s", major, minor, + local_comp, iwl_reduced_fw_name(drv)); else snprintf(drv->fw.fw_version, sizeof(drv->fw.fw_version), - "%u.%u.%u", major, minor, local_comp); + "%u.%u.%u %s", major, minor, + local_comp, iwl_reduced_fw_name(drv)); break; } case IWL_UCODE_TLV_FW_DBG_DEST: { From 20f5aef55838241e797ba685235d91a3449e9f91 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 29 Oct 2019 15:45:40 +0100 Subject: [PATCH 19/23] iwlwifi: mvm: print out extended secboot status before dump Print out the secure boot status, extended by the PCs of LMACs and the UMAC. This needs to be before dumping, as dumping will corrupt the PC (if the NMI is handled), so move that down. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/iwl-prph.h | 3 +++ drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 27 ++++++++++++++----- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h index 14c8ba23f3b98..c21d99418af9b 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h @@ -430,6 +430,9 @@ enum aux_misc_master1_en { #define UMAG_SB_CPU_1_STATUS 0xA038C0 #define UMAG_SB_CPU_2_STATUS 0xA038C4 #define UMAG_GEN_HW_STATUS 0xA038C8 +#define UREG_UMAC_CURRENT_PC 0xa05c18 +#define UREG_LMAC1_CURRENT_PC 0xa05c1c +#define UREG_LMAC2_CURRENT_PC 0xa05c20 /* For UMAG_GEN_HW_STATUS reg check */ enum { diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index dd685f7eb4104..67d414e5db193 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -353,22 +353,35 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm, if (ret) { struct iwl_trans *trans = mvm->trans; - if (ret == -ETIMEDOUT) - iwl_fw_dbg_error_collect(&mvm->fwrt, - FW_DBG_TRIGGER_ALIVE_TIMEOUT); - - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22000) + if (trans->trans_cfg->device_family >= + IWL_DEVICE_FAMILY_22000) { IWL_ERR(mvm, "SecBoot CPU1 Status: 0x%x, CPU2 Status: 0x%x\n", iwl_read_umac_prph(trans, UMAG_SB_CPU_1_STATUS), iwl_read_umac_prph(trans, UMAG_SB_CPU_2_STATUS)); - else if (trans->trans_cfg->device_family >= - IWL_DEVICE_FAMILY_8000) + IWL_ERR(mvm, "UMAC PC: 0x%x\n", + iwl_read_umac_prph(trans, + UREG_UMAC_CURRENT_PC)); + IWL_ERR(mvm, "LMAC PC: 0x%x\n", + iwl_read_umac_prph(trans, + UREG_LMAC1_CURRENT_PC)); + if (iwl_mvm_is_cdb_supported(mvm)) + IWL_ERR(mvm, "LMAC2 PC: 0x%x\n", + iwl_read_umac_prph(trans, + UREG_LMAC2_CURRENT_PC)); + } else if (trans->trans_cfg->device_family >= + IWL_DEVICE_FAMILY_8000) { IWL_ERR(mvm, "SecBoot CPU1 Status: 0x%x, CPU2 Status: 0x%x\n", iwl_read_prph(trans, SB_CPU_1_STATUS), iwl_read_prph(trans, SB_CPU_2_STATUS)); + } + + if (ret == -ETIMEDOUT) + iwl_fw_dbg_error_collect(&mvm->fwrt, + FW_DBG_TRIGGER_ALIVE_TIMEOUT); + iwl_fw_set_current_image(&mvm->fwrt, old_type); return ret; } From 87f3073c16326dc6916e277df8961abb6ff17a5f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 31 Oct 2019 11:04:43 +0100 Subject: [PATCH 20/23] iwlwifi: prph: remove some unused register definitions There are some unused register definitions, remove them. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/iwl-prph.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h index c21d99418af9b..1136d9784f9d0 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h @@ -411,13 +411,6 @@ enum { HW_STEP_LOCATION_BITS = 24, }; -#define AUX_MISC_MASTER1_EN 0xA20818 -enum aux_misc_master1_en { - AUX_MISC_MASTER1_EN_SBE_MSK = 0x1, -}; - -#define AUX_MISC_MASTER1_SMPHR_STATUS 0xA20800 -#define RSA_ENABLE 0xA24B08 #define PREG_AUX_BUS_WPROT_0 0xA04CC0 /* device family 9000 WPROT register */ From b3bd6416fc77b5056d2dda7a4d5814ec81af7ecd Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Thu, 10 Oct 2019 15:57:35 +0300 Subject: [PATCH 21/23] iwlwifi: assume the driver_data is a trans_cfg, but allow full cfg With the new concept of separating the trans-specific (trans_cfg) data from the rest of the cfg, we will start mapping only the trans_cfg part to the PCI device ID/subsystem device ID. So we can assume that the data passed to the probe function contains the trans_cfg, but since the full cfg still contains the trans_cfg at the beginning, we can allow a full cfg to be passed as well. This makes it easier to convert the existing tables one by one. Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 90 +++++++++++-------- 1 file changed, 55 insertions(+), 35 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index 79c24c696c8f8..5eb528d2111f3 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -991,21 +991,32 @@ MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids); static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { - const struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); + const struct iwl_cfg_trans_params *trans = + (struct iwl_cfg_trans_params *)(ent->driver_data); const struct iwl_cfg *cfg_7265d __maybe_unused = NULL; struct iwl_trans *iwl_trans; struct iwl_trans_pcie *trans_pcie; unsigned long flags; int ret; + /* + * This is needed for backwards compatibility with the old + * tables, so we don't need to change all the config structs + * at the same time. The cfg is used to compare with the old + * full cfg structs. + */ + const struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); - iwl_trans = iwl_trans_pcie_alloc(pdev, ent, &cfg->trans); + /* make sure trans is the first element in iwl_cfg */ + BUILD_BUG_ON(offsetof(struct iwl_cfg, trans)); + + iwl_trans = iwl_trans_pcie_alloc(pdev, ent, trans); if (IS_ERR(iwl_trans)) return PTR_ERR(iwl_trans); trans_pcie = IWL_TRANS_GET_PCIE_TRANS(iwl_trans); /* the trans_cfg should never change, so set it now */ - iwl_trans->trans_cfg = &cfg->trans; + iwl_trans->trans_cfg = trans; #if IS_ENABLED(CONFIG_IWLMVM) /* @@ -1023,22 +1034,22 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) cfg_7265d = &iwl7265d_n_cfg; if (cfg_7265d && (iwl_trans->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_7265D) - cfg = cfg_7265d; + iwl_trans->cfg = cfg_7265d; iwl_trans->hw_rf_id = iwl_read32(iwl_trans, CSR_HW_RF_ID); if (cfg == &iwlax210_2ax_cfg_so_hr_a0) { if (iwl_trans->hw_rev == CSR_HW_REV_TYPE_TY) { - cfg = &iwlax210_2ax_cfg_ty_gf_a0; + iwl_trans->cfg = &iwlax210_2ax_cfg_ty_gf_a0; } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id) == CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_JF)) { - cfg = &iwlax210_2ax_cfg_so_jf_a0; + iwl_trans->cfg = &iwlax210_2ax_cfg_so_jf_a0; } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id) == CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_GF)) { - cfg = &iwlax211_2ax_cfg_so_gf_a0; + iwl_trans->cfg = &iwlax211_2ax_cfg_so_gf_a0; } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id) == CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_GF4)) { - cfg = &iwlax411_2ax_cfg_so_gf4_a0; + iwl_trans->cfg = &iwlax411_2ax_cfg_so_gf4_a0; } } else if (cfg == &iwl_ax101_cfg_qu_hr) { if ((CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id) == @@ -1046,13 +1057,17 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) iwl_trans->hw_rev == CSR_HW_REV_TYPE_QNJ_B0) || (CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id) == CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR1))) { - cfg = &iwl22000_2ax_cfg_qnj_hr_b0; + iwl_trans->cfg = &iwl22000_2ax_cfg_qnj_hr_b0; + } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id) == + CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR) && + iwl_trans->hw_rev == CSR_HW_REV_TYPE_QUZ) { + iwl_trans->cfg = &iwl_ax101_cfg_quz_hr; } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id) == CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR)) { - cfg = &iwl_ax101_cfg_qu_hr; + iwl_trans->cfg = &iwl_ax101_cfg_qu_hr; } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id) == CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_JF)) { - cfg = &iwl22000_2ax_cfg_jf; + iwl_trans->cfg = &iwl22000_2ax_cfg_jf; } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id) == CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HRCDB)) { IWL_ERR(iwl_trans, "RF ID HRCDB is not supported\n"); @@ -1069,14 +1084,11 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) hw_status = iwl_read_prph(iwl_trans, UMAG_GEN_HW_STATUS); if (CSR_HW_RF_STEP(iwl_trans->hw_rf_id) == SILICON_B_STEP) - /* - * b step fw is the same for physical card and fpga - */ - cfg = &iwl22000_2ax_cfg_qnj_hr_b0; + iwl_trans->cfg = &iwl22000_2ax_cfg_qnj_hr_b0; else if ((hw_status & UMAG_GEN_HW_IS_FPGA) && - CSR_HW_RF_STEP(iwl_trans->hw_rf_id) == SILICON_A_STEP) { - cfg = &iwl22000_2ax_cfg_qnj_hr_a0_f0; - } + CSR_HW_RF_STEP(iwl_trans->hw_rf_id) == + SILICON_A_STEP) + iwl_trans->cfg = &iwl22000_2ax_cfg_qnj_hr_a0_f0; } /* @@ -1087,45 +1099,53 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) */ if (iwl_trans->hw_rev == CSR_HW_REV_TYPE_QU_C0) { if (cfg == &iwl_ax101_cfg_qu_hr) - cfg = &iwl_ax101_cfg_qu_c0_hr_b0; + iwl_trans->cfg = &iwl_ax101_cfg_qu_c0_hr_b0; else if (cfg == &iwl_ax201_cfg_qu_hr) - cfg = &iwl_ax201_cfg_qu_c0_hr_b0; + iwl_trans->cfg = &iwl_ax201_cfg_qu_c0_hr_b0; else if (cfg == &iwl9461_2ac_cfg_qu_b0_jf_b0) - cfg = &iwl9461_2ac_cfg_qu_c0_jf_b0; + iwl_trans->cfg = &iwl9461_2ac_cfg_qu_c0_jf_b0; else if (cfg == &iwl9462_2ac_cfg_qu_b0_jf_b0) - cfg = &iwl9462_2ac_cfg_qu_c0_jf_b0; + iwl_trans->cfg = &iwl9462_2ac_cfg_qu_c0_jf_b0; else if (cfg == &iwl9560_2ac_cfg_qu_b0_jf_b0) - cfg = &iwl9560_2ac_cfg_qu_c0_jf_b0; + iwl_trans->cfg = &iwl9560_2ac_cfg_qu_c0_jf_b0; else if (cfg == &iwl9560_2ac_160_cfg_qu_b0_jf_b0) - cfg = &iwl9560_2ac_160_cfg_qu_c0_jf_b0; + iwl_trans->cfg = &iwl9560_2ac_160_cfg_qu_c0_jf_b0; + else if (cfg == &killer1650s_2ax_cfg_qu_b0_hr_b0) + iwl_trans->cfg = &killer1650s_2ax_cfg_qu_c0_hr_b0; + else if (cfg == &killer1650i_2ax_cfg_qu_b0_hr_b0) + iwl_trans->cfg = &killer1650i_2ax_cfg_qu_c0_hr_b0; } /* same thing for QuZ... */ if (iwl_trans->hw_rev == CSR_HW_REV_TYPE_QUZ) { - if (iwl_trans->cfg == &iwl_ax101_cfg_qu_hr) + if (cfg == &iwl_ax101_cfg_qu_hr) iwl_trans->cfg = &iwl_ax101_cfg_quz_hr; - else if (iwl_trans->cfg == &iwl_ax201_cfg_qu_hr) + else if (cfg == &iwl_ax201_cfg_qu_hr) iwl_trans->cfg = &iwl_ax201_cfg_quz_hr; - else if (iwl_trans->cfg == &iwl9461_2ac_cfg_qu_b0_jf_b0) + else if (cfg == &iwl9461_2ac_cfg_qu_b0_jf_b0) iwl_trans->cfg = &iwl9461_2ac_cfg_quz_a0_jf_b0_soc; - else if (iwl_trans->cfg == &iwl9462_2ac_cfg_qu_b0_jf_b0) + else if (cfg == &iwl9462_2ac_cfg_qu_b0_jf_b0) iwl_trans->cfg = &iwl9462_2ac_cfg_quz_a0_jf_b0_soc; - else if (iwl_trans->cfg == &iwl9560_2ac_cfg_qu_b0_jf_b0) + else if (cfg == &iwl9560_2ac_cfg_qu_b0_jf_b0) iwl_trans->cfg = &iwl9560_2ac_cfg_quz_a0_jf_b0_soc; - else if (iwl_trans->cfg == &iwl9560_2ac_160_cfg_qu_b0_jf_b0) + else if (cfg == &iwl9560_2ac_160_cfg_qu_b0_jf_b0) iwl_trans->cfg = &iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc; } #endif - /* now set the real cfg we decided to use */ - iwl_trans->cfg = cfg; + /* + * If we didn't set the cfg yet, assume the trans is actually + * a full cfg from the old tables. + */ + if (!iwl_trans->cfg) + iwl_trans->cfg = cfg; - if (cfg->trans.mq_rx_supported) { - if (WARN_ON(!cfg->num_rbds)) { + if (iwl_trans->trans_cfg->mq_rx_supported) { + if (WARN_ON(!iwl_trans->cfg->num_rbds)) { ret = -EINVAL; goto out_free_trans; } - trans_pcie->num_rx_bufs = cfg->num_rbds; + trans_pcie->num_rx_bufs = iwl_trans->cfg->num_rbds; } else { trans_pcie->num_rx_bufs = RX_QUEUE_SIZE; } From 2a612a60ab440e6480c77b73403dfee061f74e4b Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Thu, 10 Oct 2019 16:30:11 +0300 Subject: [PATCH 22/23] iwlwifi: implement a new device configuration table Add a new device table that contains information that can be checked at runtime in order to decide which configuration to use. This allows us to map the full cfg independently from the tran-specific configuration. This is the first step in creating the new table. Subsequent patches will add the possibility of checking different values at runtime in order to make the decision. Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/cfg/9000.c | 6 +++ .../net/wireless/intel/iwlwifi/iwl-config.h | 10 +++++ drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 42 +++++++++++++++---- 3 files changed, 49 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/9000.c b/drivers/net/wireless/intel/iwlwifi/cfg/9000.c index 79390f880efbd..e7b95842bb607 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/9000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/9000.c @@ -171,6 +171,12 @@ static const struct iwl_tt_params iwl9000_tt_params = { }, \ } +const struct iwl_cfg_trans_params iwl9000_trans_cfg = { + .device_family = IWL_DEVICE_FAMILY_9000, + .base_params = &iwl9000_base_params, + .mq_rx_supported = true, + .rf_id = true, +}; const struct iwl_cfg iwl9160_2ac_cfg = { .name = "Intel(R) Dual Band Wireless AC 9160", diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h index bbeb5fc3caad9..0af1a5184d824 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h @@ -452,9 +452,19 @@ struct iwl_cfg { const struct iwl_fw_mon_regs mon_smem_regs; }; +#define IWL_CFG_ANY (~0) + +struct iwl_dev_info { + u16 device; + u16 subdevice; + const struct iwl_cfg *cfg; +}; + /* * This list declares the config structures for all devices. */ +extern const struct iwl_cfg_trans_params iwl9000_trans_cfg; + #if IS_ENABLED(CONFIG_IWLDVM) extern const struct iwl_cfg iwl5300_agn_cfg; extern const struct iwl_cfg iwl5100_agn_cfg; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index 5eb528d2111f3..c2cb6283bc5a5 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -565,14 +565,8 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x06F0, 0x40A4, iwl9462_2ac_cfg_quz_a0_jf_b0_soc)}, {IWL_PCI_DEVICE(0x06F0, 0x4234, iwl9560_2ac_cfg_quz_a0_jf_b0_soc)}, {IWL_PCI_DEVICE(0x06F0, 0x42A4, iwl9462_2ac_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x2526, 0x0010, iwl9260_2ac_160_cfg)}, - {IWL_PCI_DEVICE(0x2526, 0x0014, iwl9260_2ac_160_cfg)}, - {IWL_PCI_DEVICE(0x2526, 0x0018, iwl9260_2ac_160_cfg)}, - {IWL_PCI_DEVICE(0x2526, 0x001C, iwl9260_2ac_160_cfg)}, - {IWL_PCI_DEVICE(0x2526, 0x0030, iwl9560_2ac_160_cfg)}, + {IWL_PCI_DEVICE(0x2526, 0x0034, iwl9560_2ac_cfg)}, - {IWL_PCI_DEVICE(0x2526, 0x0038, iwl9560_2ac_160_cfg)}, - {IWL_PCI_DEVICE(0x2526, 0x003C, iwl9560_2ac_160_cfg)}, {IWL_PCI_DEVICE(0x2526, 0x0060, iwl9461_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x2526, 0x0064, iwl9461_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x2526, 0x00A0, iwl9462_2ac_cfg_soc)}, @@ -601,7 +595,6 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x2526, 0x4010, iwl9260_2ac_160_cfg)}, {IWL_PCI_DEVICE(0x2526, 0x4018, iwl9260_2ac_160_cfg)}, {IWL_PCI_DEVICE(0x2526, 0x401C, iwl9260_2ac_160_cfg)}, - {IWL_PCI_DEVICE(0x2526, 0x4030, iwl9560_2ac_160_cfg)}, {IWL_PCI_DEVICE(0x2526, 0x4034, iwl9560_2ac_160_cfg_soc)}, {IWL_PCI_DEVICE(0x2526, 0x40A4, iwl9462_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x2526, 0x4234, iwl9560_2ac_cfg_soc)}, @@ -613,6 +606,8 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x2526, 0xA014, iwl9260_2ac_160_cfg)}, {IWL_PCI_DEVICE(0x2526, 0xE010, iwl9260_2ac_160_cfg)}, {IWL_PCI_DEVICE(0x2526, 0xE014, iwl9260_2ac_160_cfg)}, + {IWL_PCI_DEVICE(0x2526, PCI_ANY_ID, iwl9000_trans_cfg)}, + {IWL_PCI_DEVICE(0x271B, 0x0010, iwl9160_2ac_cfg)}, {IWL_PCI_DEVICE(0x271B, 0x0014, iwl9160_2ac_cfg)}, {IWL_PCI_DEVICE(0x271B, 0x0210, iwl9160_2ac_cfg)}, @@ -986,6 +981,22 @@ static const struct pci_device_id iwl_hw_card_ids[] = { }; MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids); +#define IWL_DEV_INFO(_device, _subdevice, _cfg) \ + {.device = (_device), .subdevice = (_subdevice), .cfg = &(_cfg)} + +static const struct iwl_dev_info iwl_dev_info_table[] = { +#if IS_ENABLED(CONFIG_IWLMVM) + IWL_DEV_INFO(0x2526, 0x0010, iwl9260_2ac_160_cfg), + IWL_DEV_INFO(0x2526, 0x0014, iwl9260_2ac_160_cfg), + IWL_DEV_INFO(0x2526, 0x0018, iwl9260_2ac_160_cfg), + IWL_DEV_INFO(0x2526, 0x001C, iwl9260_2ac_160_cfg), + IWL_DEV_INFO(0x2526, 0x0030, iwl9560_2ac_160_cfg), + IWL_DEV_INFO(0x2526, 0x0038, iwl9560_2ac_160_cfg), + IWL_DEV_INFO(0x2526, 0x003C, iwl9560_2ac_160_cfg), + IWL_DEV_INFO(0x2526, 0x4030, iwl9560_2ac_160_cfg), +#endif /* CONFIG_IWLMVM */ +}; + /* PCI registers */ #define PCI_CFG_RETRY_TIMEOUT 0x041 @@ -997,7 +1008,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) struct iwl_trans *iwl_trans; struct iwl_trans_pcie *trans_pcie; unsigned long flags; - int ret; + int i, ret; /* * This is needed for backwards compatibility with the old * tables, so we don't need to change all the config structs @@ -1018,6 +1029,18 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /* the trans_cfg should never change, so set it now */ iwl_trans->trans_cfg = trans; + for (i = 0; i < ARRAY_SIZE(iwl_dev_info_table); i++) { + const struct iwl_dev_info *dev_info = &iwl_dev_info_table[i]; + + if ((dev_info->device == IWL_CFG_ANY || + dev_info->device == pdev->device) && + (dev_info->subdevice == IWL_CFG_ANY || + dev_info->subdevice == pdev->subsystem_device)) { + iwl_trans->cfg = dev_info->cfg; + goto found; + } + } + #if IS_ENABLED(CONFIG_IWLMVM) /* * special-case 7265D, it has the same PCI IDs. @@ -1140,6 +1163,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (!iwl_trans->cfg) iwl_trans->cfg = cfg; +found: if (iwl_trans->trans_cfg->mq_rx_supported) { if (WARN_ON(!iwl_trans->cfg->num_rbds)) { ret = -EINVAL; From 0b295a1eb81f37dc7d4f4f2ee9ef375fb36ab5d8 Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Thu, 10 Oct 2019 18:29:26 +0300 Subject: [PATCH 23/23] iwlwifi: add device name to device_info We have a lot of mostly duplicated data structures that are repeated only because the device name string is different. To avoid this, move the string from the cfg to the trans structure and add it independently from the rest of the configuration to the PCI mapping tables. Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/cfg/9000.c | 4 +- drivers/net/wireless/intel/iwlwifi/dvm/main.c | 4 +- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 2 +- .../net/wireless/intel/iwlwifi/iwl-config.h | 3 ++ .../net/wireless/intel/iwlwifi/iwl-trans.h | 2 + .../net/wireless/intel/iwlwifi/mvm/debugfs.c | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/nvm.c | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 2 +- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 44 ++++++++++--------- 9 files changed, 38 insertions(+), 27 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/9000.c b/drivers/net/wireless/intel/iwlwifi/cfg/9000.c index e7b95842bb607..379ea788e4247 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/9000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/9000.c @@ -190,8 +190,10 @@ const struct iwl_cfg iwl9260_2ac_cfg = { IWL_DEVICE_9000, }; +const char iwl9260_160_name[] = "Intel(R) Wireless-AC 9260 160MHz"; +const char iwl9560_160_name[] = "Intel(R) Wireless-AC 9560 160MHz"; + const struct iwl_cfg iwl9260_2ac_160_cfg = { - .name = "Intel(R) Wireless-AC 9260 160MHz", .fw_name_pre = IWL9260_FW_PRE, IWL_DEVICE_9000, }; diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/main.c b/drivers/net/wireless/intel/iwlwifi/dvm/main.c index 4f2789bb3b5bf..598ee73155588 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/main.c @@ -1255,7 +1255,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, ************************/ hw = iwl_alloc_all(); if (!hw) { - pr_err("%s: Cannot allocate network device\n", cfg->name); + pr_err("%s: Cannot allocate network device\n", trans->name); goto out; } @@ -1390,7 +1390,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, * 2. Read REV register ***********************/ IWL_INFO(priv, "Detected %s, REV=0x%X\n", - priv->cfg->name, priv->trans->hw_rev); + priv->trans->name, priv->trans->hw_rev); if (iwl_trans_start_hw(priv->trans)) goto out_free_hw; diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 09daf0f1f6f87..89d7968210239 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -929,7 +929,7 @@ iwl_fw_error_dump_file(struct iwl_fw_runtime *fwrt, cpu_to_le32(CSR_HW_REV_STEP(fwrt->trans->hw_rev)); memcpy(dump_info->fw_human_readable, fwrt->fw->human_readable, sizeof(dump_info->fw_human_readable)); - strncpy(dump_info->dev_human_readable, fwrt->trans->cfg->name, + strncpy(dump_info->dev_human_readable, fwrt->trans->name, sizeof(dump_info->dev_human_readable) - 1); strncpy(dump_info->bus_human_readable, fwrt->dev->bus->name, sizeof(dump_info->bus_human_readable) - 1); diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h index 0af1a5184d824..be6a2bf9ce74a 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h @@ -458,12 +458,15 @@ struct iwl_dev_info { u16 device; u16 subdevice; const struct iwl_cfg *cfg; + const char *name; }; /* * This list declares the config structures for all devices. */ extern const struct iwl_cfg_trans_params iwl9000_trans_cfg; +extern const char iwl9260_160_name[]; +extern const char iwl9560_160_name[]; #if IS_ENABLED(CONFIG_IWLDVM) extern const struct iwl_cfg iwl5300_agn_cfg; diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h index 58bee4442e201..ab547be4994bc 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h @@ -859,6 +859,8 @@ struct iwl_trans { enum iwl_plat_pm_mode system_pm_mode; + const char *name; + /* pointer to trans specific struct */ /*Ensure that this pointer will always be aligned to sizeof pointer */ char trans_specific[0] __aligned(sizeof(void *)); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c index aa659162a7c29..190cf15b825ce 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c @@ -752,7 +752,7 @@ static ssize_t iwl_dbgfs_fw_ver_read(struct file *file, char __user *user_buf, pos += scnprintf(pos, endpos - pos, "FW: %s\n", mvm->fwrt.fw->human_readable); pos += scnprintf(pos, endpos - pos, "Device: %s\n", - mvm->fwrt.trans->cfg->name); + mvm->fwrt.trans->name); pos += scnprintf(pos, endpos - pos, "Bus: %s\n", mvm->fwrt.dev->bus->name); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c index 945c1ea5cda86..c46c00706cd5b 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c @@ -178,7 +178,7 @@ static int iwl_nvm_read_chunk(struct iwl_mvm *mvm, u16 section, } else { IWL_DEBUG_EEPROM(mvm->trans->dev, "NVM access command failed with status %d (device: %s)\n", - ret, mvm->cfg->name); + ret, mvm->trans->name); ret = -ENODATA; } goto exit; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 1b07a8e8f0695..dfe02440d4748 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -830,7 +830,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, } IWL_INFO(mvm, "Detected %s, REV=0x%X\n", - mvm->cfg->name, mvm->trans->hw_rev); + mvm->trans->name, mvm->trans->hw_rev); if (iwlwifi_mod_params.nvm_file) mvm->nvm_file_name = iwlwifi_mod_params.nvm_file; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index c2cb6283bc5a5..9d8ffbecf5bed 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -592,20 +592,10 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x2526, 0x1610, iwl9270_2ac_cfg)}, {IWL_PCI_DEVICE(0x2526, 0x2030, iwl9560_2ac_160_cfg_soc)}, {IWL_PCI_DEVICE(0x2526, 0x2034, iwl9560_2ac_160_cfg_soc)}, - {IWL_PCI_DEVICE(0x2526, 0x4010, iwl9260_2ac_160_cfg)}, - {IWL_PCI_DEVICE(0x2526, 0x4018, iwl9260_2ac_160_cfg)}, - {IWL_PCI_DEVICE(0x2526, 0x401C, iwl9260_2ac_160_cfg)}, {IWL_PCI_DEVICE(0x2526, 0x4034, iwl9560_2ac_160_cfg_soc)}, {IWL_PCI_DEVICE(0x2526, 0x40A4, iwl9462_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x2526, 0x4234, iwl9560_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x2526, 0x42A4, iwl9462_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x2526, 0x6010, iwl9260_2ac_160_cfg)}, - {IWL_PCI_DEVICE(0x2526, 0x6014, iwl9260_2ac_160_cfg)}, - {IWL_PCI_DEVICE(0x2526, 0x8014, iwl9260_2ac_160_cfg)}, - {IWL_PCI_DEVICE(0x2526, 0x8010, iwl9260_2ac_160_cfg)}, - {IWL_PCI_DEVICE(0x2526, 0xA014, iwl9260_2ac_160_cfg)}, - {IWL_PCI_DEVICE(0x2526, 0xE010, iwl9260_2ac_160_cfg)}, - {IWL_PCI_DEVICE(0x2526, 0xE014, iwl9260_2ac_160_cfg)}, {IWL_PCI_DEVICE(0x2526, PCI_ANY_ID, iwl9000_trans_cfg)}, {IWL_PCI_DEVICE(0x271B, 0x0010, iwl9160_2ac_cfg)}, @@ -981,19 +971,28 @@ static const struct pci_device_id iwl_hw_card_ids[] = { }; MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids); -#define IWL_DEV_INFO(_device, _subdevice, _cfg) \ - {.device = (_device), .subdevice = (_subdevice), .cfg = &(_cfg)} +#define IWL_DEV_INFO(_device, _subdevice, _cfg, _name) \ + { .device = (_device), .subdevice = (_subdevice), .cfg = &(_cfg), \ + .name = _name } static const struct iwl_dev_info iwl_dev_info_table[] = { #if IS_ENABLED(CONFIG_IWLMVM) - IWL_DEV_INFO(0x2526, 0x0010, iwl9260_2ac_160_cfg), - IWL_DEV_INFO(0x2526, 0x0014, iwl9260_2ac_160_cfg), - IWL_DEV_INFO(0x2526, 0x0018, iwl9260_2ac_160_cfg), - IWL_DEV_INFO(0x2526, 0x001C, iwl9260_2ac_160_cfg), - IWL_DEV_INFO(0x2526, 0x0030, iwl9560_2ac_160_cfg), - IWL_DEV_INFO(0x2526, 0x0038, iwl9560_2ac_160_cfg), - IWL_DEV_INFO(0x2526, 0x003C, iwl9560_2ac_160_cfg), - IWL_DEV_INFO(0x2526, 0x4030, iwl9560_2ac_160_cfg), + IWL_DEV_INFO(0x2526, 0x0010, iwl9260_2ac_160_cfg, iwl9260_160_name), + IWL_DEV_INFO(0x2526, 0x0014, iwl9260_2ac_160_cfg, iwl9260_160_name), + IWL_DEV_INFO(0x2526, 0x0018, iwl9260_2ac_160_cfg, iwl9260_160_name), + IWL_DEV_INFO(0x2526, 0x001C, iwl9260_2ac_160_cfg, iwl9260_160_name), + IWL_DEV_INFO(0x2526, 0x6010, iwl9260_2ac_160_cfg, iwl9260_160_name), + IWL_DEV_INFO(0x2526, 0x6014, iwl9260_2ac_160_cfg, iwl9260_160_name), + IWL_DEV_INFO(0x2526, 0x8014, iwl9260_2ac_160_cfg, iwl9260_160_name), + IWL_DEV_INFO(0x2526, 0x8010, iwl9260_2ac_160_cfg, iwl9260_160_name), + IWL_DEV_INFO(0x2526, 0xA014, iwl9260_2ac_160_cfg, iwl9260_160_name), + IWL_DEV_INFO(0x2526, 0xE010, iwl9260_2ac_160_cfg, iwl9260_160_name), + IWL_DEV_INFO(0x2526, 0xE014, iwl9260_2ac_160_cfg, iwl9260_160_name), + + IWL_DEV_INFO(0x2526, 0x0030, iwl9560_2ac_160_cfg, iwl9560_160_name), + IWL_DEV_INFO(0x2526, 0x0038, iwl9560_2ac_160_cfg, iwl9560_160_name), + IWL_DEV_INFO(0x2526, 0x003C, iwl9560_2ac_160_cfg, iwl9560_160_name), + IWL_DEV_INFO(0x2526, 0x4030, iwl9560_2ac_160_cfg, iwl9560_160_name), #endif /* CONFIG_IWLMVM */ }; @@ -1037,6 +1036,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) (dev_info->subdevice == IWL_CFG_ANY || dev_info->subdevice == pdev->subsystem_device)) { iwl_trans->cfg = dev_info->cfg; + iwl_trans->name = dev_info->name; goto found; } } @@ -1164,6 +1164,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) iwl_trans->cfg = cfg; found: + /* if we don't have a name yet, copy name from the old cfg */ + if (!iwl_trans->name) + iwl_trans->name = iwl_trans->cfg->name; + if (iwl_trans->trans_cfg->mq_rx_supported) { if (WARN_ON(!iwl_trans->cfg->num_rbds)) { ret = -EINVAL;