From 9cb63bf664fb6714f8ed8240d5d28f40879206f9 Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Wed, 10 Apr 2019 09:23:39 +0300 Subject: [PATCH 01/80] iwlwifi: bump FW API to 49 for 22000 series Start supporting API version 49 for 22000 series. Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/cfg/22000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c index 55b713255b8e..0d89223f377d 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c @@ -56,7 +56,7 @@ #include "iwl-config.h" /* Highest firmware API version supported */ -#define IWL_22000_UCODE_API_MAX 48 +#define IWL_22000_UCODE_API_MAX 49 /* Lowest firmware API version supported */ #define IWL_22000_UCODE_API_MIN 39 From 79660869bf750b3b52672cbae119e3a1e96a3165 Mon Sep 17 00:00:00 2001 From: Ilia Lin Date: Tue, 14 May 2019 17:19:06 +0300 Subject: [PATCH 02/80] iwlwifi: Send DQA enable command only if TVL is on The newer targets don't support the DQA enablement command and will return error status, while older targets need it. The feature is defined by the corresponding TLV. Send the command only if the TLV is enabled. Signed-off-by: Ilia Lin Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index 5de54d1559dd..a57fc6198a72 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -1246,9 +1246,11 @@ int iwl_mvm_up(struct iwl_mvm *mvm) /* reset quota debouncing buffer - 0xff will yield invalid data */ memset(&mvm->last_quota_cmd, 0xff, sizeof(mvm->last_quota_cmd)); - ret = iwl_mvm_send_dqa_cmd(mvm); - if (ret) - goto error; + if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_DQA_SUPPORT)) { + ret = iwl_mvm_send_dqa_cmd(mvm); + if (ret) + goto error; + } /* Add auxiliary station for scanning */ ret = iwl_mvm_add_aux_sta(mvm); From 07c89a601b64e7474dc86dfeed3a1628cad77444 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 21 May 2019 22:13:10 +0300 Subject: [PATCH 03/80] iwlwifi: mvm: remove redundant condition in iwl_mvm_set_hw_rfkill_state If mvm->fwrt.cur_fw_img != IWL_UCODE_INIT, then rfkill_safe_init_done must be true since rfkill_safe_init_done is set to true before we start to load the runtime image. Remove the redundant condition. Signed-off-by: Emmanuel Grumbach Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 4888054dc3d8..722e427d534c 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -1234,8 +1234,7 @@ static bool iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state) * Stop the device if we run OPERATIONAL firmware or if we are in the * middle of the calibrations. */ - return state && (mvm->fwrt.cur_fw_img != IWL_UCODE_INIT || - rfkill_safe_init_done); + return state && rfkill_safe_init_done; } static void iwl_mvm_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb) From 4f58121dc40a1d5dd2f630a5ec4dac5afa1ce3f4 Mon Sep 17 00:00:00 2001 From: Ilan Peer Date: Sun, 19 May 2019 14:56:31 +0300 Subject: [PATCH 04/80] iwlwifi: mvm: Block 26-tone RU OFDMA transmissions In case that there are OBSS that do not know how to properly interpret 26-tone RU OFDMA transmissions, instruct the FW not to use such transmissions. The check is currently only performed upon association. Signed-off-by: Ilan Peer Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/fw/api/mac.h | 4 ++ .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 54 +++++++++++++++++++ drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 3 ++ 3 files changed, 61 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/mac.h b/drivers/net/wireless/intel/iwlwifi/fw/api/mac.h index 85c5e367cbf1..73fb0030c496 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/mac.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/mac.h @@ -500,6 +500,9 @@ struct iwl_he_pkt_ext { * enabled AGG, i.e. both BACK and non-BACK frames in a single AGG * @STA_CTXT_HE_MU_EDCA_CW: indicates that there is an element of MU EDCA * parameter set, i.e. the backoff counters for trig-based ACs + * @STA_CTXT_HE_RU_2MHZ_BLOCK: indicates that 26-tone RU OFDMA transmission are + * not allowed (as there are OBSS that might classify such transmissions as + * radar pulses). */ enum iwl_he_sta_ctxt_flags { STA_CTXT_HE_REF_BSSID_VALID = BIT(4), @@ -511,6 +514,7 @@ enum iwl_he_sta_ctxt_flags { STA_CTXT_HE_CONST_TRIG_RND_ALLOC = BIT(10), STA_CTXT_HE_ACK_ENABLED = BIT(11), STA_CTXT_HE_MU_EDCA_CW = BIT(12), + STA_CTXT_HE_RU_2MHZ_BLOCK = BIT(14), }; /** diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index d6499763f0dd..3d63cc4c9eaf 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -2254,6 +2254,10 @@ static void iwl_mvm_cfg_he_sta(struct iwl_mvm *mvm, flags = 0; + /* Block 26-tone RU OFDMA transmissions */ + if (mvmvif->he_ru_2mhz_block) + flags |= STA_CTXT_HE_RU_2MHZ_BLOCK; + /* HTC flags */ if (sta->he_cap.he_cap_elem.mac_cap_info[0] & IEEE80211_HE_MAC_CAP0_HTC_HE) @@ -3205,6 +3209,51 @@ iwl_mvm_tdls_check_trigger(struct iwl_mvm *mvm, peer_addr, action); } +struct iwl_mvm_he_obss_narrow_bw_ru_data { + bool tolerated; +}; + +static void iwl_mvm_check_he_obss_narrow_bw_ru_iter(struct wiphy *wiphy, + struct cfg80211_bss *bss, + void *_data) +{ + struct iwl_mvm_he_obss_narrow_bw_ru_data *data = _data; + const struct element *elem; + + elem = cfg80211_find_elem(WLAN_EID_EXT_CAPABILITY, bss->ies->data, + bss->ies->len); + + if (!elem || elem->datalen < 10 || + !(elem->data[10] & + WLAN_EXT_CAPA10_OBSS_NARROW_BW_RU_TOLERANCE_SUPPORT)) { + data->tolerated = false; + } +} + +static void iwl_mvm_check_he_obss_narrow_bw_ru(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); + struct iwl_mvm_he_obss_narrow_bw_ru_data iter_data = { + .tolerated = true, + }; + + if (!(vif->bss_conf.chandef.chan->flags & IEEE80211_CHAN_RADAR)) { + mvmvif->he_ru_2mhz_block = false; + return; + } + + cfg80211_bss_iter(hw->wiphy, &vif->bss_conf.chandef, + iwl_mvm_check_he_obss_narrow_bw_ru_iter, + &iter_data); + + /* + * If there is at least one AP on radar channel that cannot + * tolerate 26-tone RU UL OFDMA transmissions using HE TB PPDU. + */ + mvmvif->he_ru_2mhz_block = !iter_data.tolerated; +} + static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta, @@ -3306,6 +3355,11 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw, iwl_mvm_cfg_he_sta(mvm, vif, mvm_sta->sta_id); } else if (vif->type == NL80211_IFTYPE_STATION) { vif->bss_conf.he_support = sta->he_cap.has_he; + + mvmvif->he_ru_2mhz_block = false; + if (sta->he_cap.has_he) + iwl_mvm_check_he_obss_narrow_bw_ru(hw, vif); + iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL); } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index a263cc629d75..a14701c8933b 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -504,6 +504,9 @@ struct iwl_mvm_vif { /* we can only have 2 GTK + 2 IGTK active at a time */ struct ieee80211_key_conf *ap_early_keys[4]; + + /* 26-tone RU OFDMA transmissions should be blocked */ + bool he_ru_2mhz_block; }; static inline struct iwl_mvm_vif * From 5a28c2148b0bc7cfa91e6942781b944fd2236c0c Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 20 May 2019 11:26:16 +0200 Subject: [PATCH 05/80] iwlwifi: mvm: remove unnecessary forward declarations These static functions are only used after their definition, so we don't need the forward declarations. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c index 10f18536dd0d..4fae0cb22195 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c @@ -67,14 +67,6 @@ #include "sta.h" #include "rs.h" -static int iwl_mvm_set_fw_key_idx(struct iwl_mvm *mvm); - -static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm, - u32 sta_id, - struct ieee80211_key_conf *key, bool mcast, - u32 tkip_iv32, u16 *tkip_p1k, u32 cmd_flags, - u8 key_offset, bool mfp); - /* * New version of ADD_STA_sta command added new fields at the end of the * structure, so sending the size of the relevant API's structure is enough to From b721f5b1be18ae6d74f306d92a272eb74d3eb964 Mon Sep 17 00:00:00 2001 From: Shahar S Matityahu Date: Tue, 21 May 2019 09:42:15 +0300 Subject: [PATCH 06/80] iwlwifi: dbg: move monitor recording functionality from header file The recording functions are quite big to be inline and the driver should expose only the stop and restart functions that are allowed to be used rather then the internal helper functions. Move the functions from the header file. Signed-off-by: Shahar S Matityahu Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 85 ++++++++++++++++++++ drivers/net/wireless/intel/iwlwifi/fw/dbg.h | 89 +-------------------- 2 files changed, 89 insertions(+), 85 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 4d81776f576d..dfb0c50df94c 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -2937,3 +2937,88 @@ void iwl_fw_error_print_fseq_regs(struct iwl_fw_runtime *fwrt) iwl_trans_release_nic_access(trans, &flags); } IWL_EXPORT_SYMBOL(iwl_fw_error_print_fseq_regs); + +static void _iwl_fw_dbg_stop_recording(struct iwl_trans *trans, + struct iwl_fw_dbg_params *params) +{ + if (trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) { + iwl_set_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x100); + return; + } + + if (params) { + params->in_sample = iwl_read_umac_prph(trans, DBGC_IN_SAMPLE); + params->out_ctrl = iwl_read_umac_prph(trans, DBGC_OUT_CTRL); + } + + iwl_write_umac_prph(trans, DBGC_IN_SAMPLE, 0); + /* wait for the DBGC to finish writing the internal buffer to DRAM to + * avoid halting the HW while writing + */ + usleep_range(700, 1000); + iwl_write_umac_prph(trans, DBGC_OUT_CTRL, 0); +#ifdef CONFIG_IWLWIFI_DEBUGFS + trans->dbg.rec_on = false; +#endif +} + +void iwl_fw_dbg_stop_recording(struct iwl_trans *trans, + struct iwl_fw_dbg_params *params) +{ + /* if the FW crashed or not debug monitor cfg was given, there is + * no point in stopping + */ + if (test_bit(STATUS_FW_ERROR, &trans->status) || + (!trans->dbg.dest_tlv && + trans->dbg.ini_dest == IWL_FW_INI_LOCATION_INVALID)) + return; + + if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) { + IWL_ERR(trans, + "WRT: unsupported device family %d for debug stop recording\n", + trans->cfg->device_family); + return; + } + _iwl_fw_dbg_stop_recording(trans, params); +} +IWL_EXPORT_SYMBOL(iwl_fw_dbg_stop_recording); + +static void _iwl_fw_dbg_restart_recording(struct iwl_trans *trans, + struct iwl_fw_dbg_params *params) +{ + if (WARN_ON(!params)) + return; + + if (trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) { + iwl_clear_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x100); + iwl_clear_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x1); + iwl_set_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x1); + } else { + iwl_write_umac_prph(trans, DBGC_IN_SAMPLE, params->in_sample); + iwl_write_umac_prph(trans, DBGC_OUT_CTRL, params->out_ctrl); + } +} + +void iwl_fw_dbg_restart_recording(struct iwl_fw_runtime *fwrt, + struct iwl_fw_dbg_params *params) +{ + /* if the FW crashed or not debug monitor cfg was given, there is + * no point in restarting + */ + if (test_bit(STATUS_FW_ERROR, &fwrt->trans->status) || + (!fwrt->trans->dbg.dest_tlv && + fwrt->trans->dbg.ini_dest == IWL_FW_INI_LOCATION_INVALID)) + return; + + if (fwrt->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) { + IWL_ERR(fwrt, + "WRT: unsupported device family %d for debug restart recording\n", + fwrt->trans->cfg->device_family); + return; + } + _iwl_fw_dbg_restart_recording(fwrt->trans, params); +#ifdef CONFIG_IWLWIFI_DEBUGFS + iwl_fw_set_dbg_rec_on(fwrt); +#endif +} +IWL_EXPORT_SYMBOL(iwl_fw_dbg_restart_recording); diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h index a8459ac71b2c..d6b012459b04 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h @@ -263,68 +263,11 @@ _iwl_fw_dbg_trigger_simple_stop(struct iwl_fw_runtime *fwrt, iwl_fw_dbg_get_trigger((fwrt)->fw,\ (trig))) -static inline void -_iwl_fw_dbg_stop_recording(struct iwl_trans *trans, - struct iwl_fw_dbg_params *params) -{ - if (trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) { - iwl_set_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x100); - return; - } +void iwl_fw_dbg_stop_recording(struct iwl_trans *trans, + struct iwl_fw_dbg_params *params); - if (params) { - params->in_sample = iwl_read_umac_prph(trans, DBGC_IN_SAMPLE); - params->out_ctrl = iwl_read_umac_prph(trans, DBGC_OUT_CTRL); - } - - iwl_write_umac_prph(trans, DBGC_IN_SAMPLE, 0); - /* wait for the DBGC to finish writing the internal buffer to DRAM to - * avoid halting the HW while writing - */ - usleep_range(700, 1000); - iwl_write_umac_prph(trans, DBGC_OUT_CTRL, 0); -#ifdef CONFIG_IWLWIFI_DEBUGFS - trans->dbg.rec_on = false; -#endif -} - -static inline void -iwl_fw_dbg_stop_recording(struct iwl_trans *trans, - struct iwl_fw_dbg_params *params) -{ - /* if the FW crashed or not debug monitor cfg was given, there is - * no point in stopping - */ - if (test_bit(STATUS_FW_ERROR, &trans->status) || - (!trans->dbg.dest_tlv && - trans->dbg.ini_dest == IWL_FW_INI_LOCATION_INVALID)) - return; - - if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) { - IWL_ERR(trans, - "WRT: unsupported device family %d for debug stop recording\n", - trans->cfg->device_family); - return; - } - _iwl_fw_dbg_stop_recording(trans, params); -} - -static inline void -_iwl_fw_dbg_restart_recording(struct iwl_trans *trans, - struct iwl_fw_dbg_params *params) -{ - if (WARN_ON(!params)) - return; - - if (trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) { - iwl_clear_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x100); - iwl_clear_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x1); - iwl_set_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x1); - } else { - iwl_write_umac_prph(trans, DBGC_IN_SAMPLE, params->in_sample); - iwl_write_umac_prph(trans, DBGC_OUT_CTRL, params->out_ctrl); - } -} +void iwl_fw_dbg_restart_recording(struct iwl_fw_runtime *fwrt, + struct iwl_fw_dbg_params *params); #ifdef CONFIG_IWLWIFI_DEBUGFS static inline void iwl_fw_set_dbg_rec_on(struct iwl_fw_runtime *fwrt) @@ -336,30 +279,6 @@ static inline void iwl_fw_set_dbg_rec_on(struct iwl_fw_runtime *fwrt) } #endif -static inline void -iwl_fw_dbg_restart_recording(struct iwl_fw_runtime *fwrt, - struct iwl_fw_dbg_params *params) -{ - /* if the FW crashed or not debug monitor cfg was given, there is - * no point in restarting - */ - if (test_bit(STATUS_FW_ERROR, &fwrt->trans->status) || - (!fwrt->trans->dbg.dest_tlv && - fwrt->trans->dbg.ini_dest == IWL_FW_INI_LOCATION_INVALID)) - return; - - if (fwrt->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) { - IWL_ERR(fwrt, - "WRT: unsupported device family %d for debug restart recording\n", - fwrt->trans->cfg->device_family); - return; - } - _iwl_fw_dbg_restart_recording(fwrt->trans, params); -#ifdef CONFIG_IWLWIFI_DEBUGFS - iwl_fw_set_dbg_rec_on(fwrt); -#endif -} - static inline void iwl_fw_dump_conf_clear(struct iwl_fw_runtime *fwrt) { fwrt->dump.conf = FW_DBG_INVALID; From 203c83d3b256d8eb6b8d4508b2dd7266e9dd2285 Mon Sep 17 00:00:00 2001 From: Shahar S Matityahu Date: Wed, 22 May 2019 13:47:29 +0300 Subject: [PATCH 07/80] iwlwifi: dbg: move debug recording stop from trans to op mode The op mode should stop the debug recording and not the transport layer. Rename iwl_fwrt_stop_device into iwl_fw_dbg_stop_sync and move the debug stop recording to it. Signed-off-by: Shahar S Matityahu Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 6 +++--- drivers/net/wireless/intel/iwlwifi/fw/dbg.h | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 1 + drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 3 ++- drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c | 3 --- drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 3 --- 6 files changed, 7 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index dfb0c50df94c..9ccaecc10474 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -2862,7 +2862,7 @@ void iwl_fw_dbg_apply_point(struct iwl_fw_runtime *fwrt, } IWL_EXPORT_SYMBOL(iwl_fw_dbg_apply_point); -void iwl_fwrt_stop_device(struct iwl_fw_runtime *fwrt) +void iwl_fw_dbg_stop_sync(struct iwl_fw_runtime *fwrt) { int i; @@ -2870,9 +2870,9 @@ void iwl_fwrt_stop_device(struct iwl_fw_runtime *fwrt) for (i = 0; i < IWL_FW_RUNTIME_DUMP_WK_NUM; i++) iwl_fw_dbg_collect_sync(fwrt, i); - iwl_trans_stop_device(fwrt->trans); + iwl_fw_dbg_stop_recording(fwrt->trans, NULL); } -IWL_EXPORT_SYMBOL(iwl_fwrt_stop_device); +IWL_EXPORT_SYMBOL(iwl_fw_dbg_stop_sync); void iwl_fw_dbg_periodic_trig_handler(struct timer_list *t) { diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h index d6b012459b04..5582a11f7c89 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h @@ -373,7 +373,7 @@ static inline void iwl_fw_resume_timestamp(struct iwl_fw_runtime *fwrt) {} void iwl_fw_dbg_apply_point(struct iwl_fw_runtime *fwrt, enum iwl_fw_ini_apply_point apply_point); -void iwl_fwrt_stop_device(struct iwl_fw_runtime *fwrt); +void iwl_fw_dbg_stop_sync(struct iwl_fw_runtime *fwrt); static inline void iwl_fw_lmac1_set_alive_err_table(struct iwl_trans *trans, u32 lmac_error_event_table) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index a57fc6198a72..ed6453b2fc79 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -1140,6 +1140,7 @@ static int iwl_mvm_load_rt_fw(struct iwl_mvm *mvm) return ret; } + iwl_fw_dbg_stop_sync(&mvm->fwrt); /* * Stop and start the transport without entering low power * mode. This will save the state of other components on the diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index a14701c8933b..e5703aa7935e 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -2037,7 +2037,8 @@ static inline void iwl_mvm_stop_device(struct iwl_mvm *mvm) lockdep_assert_held(&mvm->mutex); iwl_fw_cancel_timestamp(&mvm->fwrt); clear_bit(IWL_MVM_STATUS_FIRMWARE_RUNNING, &mvm->status); - iwl_fwrt_stop_device(&mvm->fwrt); + iwl_fw_dbg_stop_sync(&mvm->fwrt); + iwl_trans_stop_device(mvm->trans); iwl_free_fw_paging(&mvm->fwrt); iwl_fw_dump_conf_clear(&mvm->fwrt); } diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c index 8d17e68577fd..104b7cc75248 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c @@ -147,9 +147,6 @@ void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans, bool low_power) trans_pcie->is_down = true; - /* Stop dbgc before stopping device */ - iwl_fw_dbg_stop_recording(trans, NULL); - /* tell the device to stop sending interrupts */ iwl_disable_interrupts(trans); diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index db62c8314603..d8b0f3b01acb 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -1242,9 +1242,6 @@ static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool low_power) trans_pcie->is_down = true; - /* Stop dbgc before stopping device */ - iwl_fw_dbg_stop_recording(trans, NULL); - /* tell the device to stop sending interrupts */ iwl_disable_interrupts(trans); From 576058330f2d2403c93a66f48dfa98d90c6f7922 Mon Sep 17 00:00:00 2001 From: Shahar S Matityahu Date: Sun, 19 May 2019 10:52:59 +0300 Subject: [PATCH 08/80] iwlwifi: dbg: support debug recording suspend resume command Support the new DBGC_SUSPEND_RESUME command to change the recording state. Signed-off-by: Shahar S Matityahu Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/fw/api/debug.h | 30 +++++- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 99 ++++++++++--------- drivers/net/wireless/intel/iwlwifi/fw/dbg.h | 9 +- drivers/net/wireless/intel/iwlwifi/fw/file.h | 1 + drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 1 + 6 files changed, 87 insertions(+), 55 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/debug.h b/drivers/net/wireless/intel/iwlwifi/fw/api/debug.h index 988584973aba..b627c31d06ed 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/debug.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/debug.h @@ -8,7 +8,7 @@ * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH - * Copyright (C) 2018 Intel Corporation + * Copyright (C) 2018 - 2019 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -31,7 +31,7 @@ * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH - * Copyright (C) 2018 Intel Corporation + * Copyright (C) 2018 - 2019 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -80,6 +80,13 @@ enum iwl_debug_cmds { * &struct iwl_dbg_mem_access_rsp */ UMAC_RD_WR = 0x1, + /** + * @DBGC_SUSPEND_RESUME: + * DBGC suspend/resume commad. Uses a single dword as data: + * 0 - resume DBGC recording + * 1 - suspend DBGC recording + */ + DBGC_SUSPEND_RESUME = 0x7, /** * @MFU_ASSERT_DUMP_NTF: * &struct iwl_mfu_assert_dump_notif @@ -102,6 +109,16 @@ enum { FW_ERR_FATAL = 0xFF }; +/** enum iwl_dbg_suspend_resume_cmds - dbgc suspend resume operations + * dbgc suspend resume command operations + * @DBGC_RESUME_CMD: resume dbgc recording + * @DBGC_SUSPEND_CMD: stop dbgc recording + */ +enum iwl_dbg_suspend_resume_cmds { + DBGC_RESUME_CMD, + DBGC_SUSPEND_CMD, +}; + /** * struct iwl_error_resp - FW error indication * ( REPLY_ERROR = 0x2 ) @@ -380,4 +397,13 @@ struct iwl_ldbg_config_cmd { }; /* LDBG_CFG_BODY_API_U_VER_2 (partially) */ } __packed; /* LDBG_CFG_CMD_API_S_VER_2 */ +/** + * struct iwl_dbg_suspend_resume_cmd - dbgc suspend resume command + * @operation: suspend or resume operation, uses + * &enum iwl_dbg_suspend_resume_cmds + */ +struct iwl_dbg_suspend_resume_cmd { + __le32 operation; +} __packed; + #endif /* __iwl_fw_api_debug_h__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 9ccaecc10474..34f4cda3b090 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -2372,7 +2372,10 @@ static void iwl_fw_dbg_collect_sync(struct iwl_fw_runtime *fwrt, u8 wk_idx) goto out; } - iwl_fw_dbg_stop_recording(fwrt->trans, ¶ms); + if (iwl_fw_dbg_stop_restart_recording(fwrt, ¶ms, true)) { + IWL_ERR(fwrt, "Failed to stop DBGC recording, aborting dump\n"); + goto out; + } IWL_DEBUG_FW_INFO(fwrt, "WRT: data collection start\n"); if (fwrt->trans->dbg.ini_valid) @@ -2381,7 +2384,7 @@ static void iwl_fw_dbg_collect_sync(struct iwl_fw_runtime *fwrt, u8 wk_idx) iwl_fw_error_dump(fwrt); IWL_DEBUG_FW_INFO(fwrt, "WRT: data collection done\n"); - iwl_fw_dbg_restart_recording(fwrt, ¶ms); + iwl_fw_dbg_stop_restart_recording(fwrt, ¶ms, false); out: clear_bit(wk_idx, &fwrt->dump.active_wks); @@ -2870,7 +2873,7 @@ void iwl_fw_dbg_stop_sync(struct iwl_fw_runtime *fwrt) for (i = 0; i < IWL_FW_RUNTIME_DUMP_WK_NUM; i++) iwl_fw_dbg_collect_sync(fwrt, i); - iwl_fw_dbg_stop_recording(fwrt->trans, NULL); + iwl_fw_dbg_stop_restart_recording(fwrt, NULL, true); } IWL_EXPORT_SYMBOL(iwl_fw_dbg_stop_sync); @@ -2938,8 +2941,24 @@ void iwl_fw_error_print_fseq_regs(struct iwl_fw_runtime *fwrt) } IWL_EXPORT_SYMBOL(iwl_fw_error_print_fseq_regs); -static void _iwl_fw_dbg_stop_recording(struct iwl_trans *trans, - struct iwl_fw_dbg_params *params) +static int iwl_fw_dbg_suspend_resume_hcmd(struct iwl_trans *trans, bool suspend) +{ + struct iwl_dbg_suspend_resume_cmd cmd = { + .operation = suspend ? + cpu_to_le32(DBGC_SUSPEND_CMD) : + cpu_to_le32(DBGC_RESUME_CMD), + }; + struct iwl_host_cmd hcmd = { + .id = WIDE_ID(DEBUG_GROUP, DBGC_SUSPEND_RESUME), + .data[0] = &cmd, + .len[0] = sizeof(cmd), + }; + + return iwl_trans_send_cmd(trans, &hcmd); +} + +static void iwl_fw_dbg_stop_recording(struct iwl_trans *trans, + struct iwl_fw_dbg_params *params) { if (trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) { iwl_set_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x100); @@ -2957,37 +2976,13 @@ static void _iwl_fw_dbg_stop_recording(struct iwl_trans *trans, */ usleep_range(700, 1000); iwl_write_umac_prph(trans, DBGC_OUT_CTRL, 0); -#ifdef CONFIG_IWLWIFI_DEBUGFS - trans->dbg.rec_on = false; -#endif } -void iwl_fw_dbg_stop_recording(struct iwl_trans *trans, - struct iwl_fw_dbg_params *params) +static int iwl_fw_dbg_restart_recording(struct iwl_trans *trans, + struct iwl_fw_dbg_params *params) { - /* if the FW crashed or not debug monitor cfg was given, there is - * no point in stopping - */ - if (test_bit(STATUS_FW_ERROR, &trans->status) || - (!trans->dbg.dest_tlv && - trans->dbg.ini_dest == IWL_FW_INI_LOCATION_INVALID)) - return; - - if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) { - IWL_ERR(trans, - "WRT: unsupported device family %d for debug stop recording\n", - trans->cfg->device_family); - return; - } - _iwl_fw_dbg_stop_recording(trans, params); -} -IWL_EXPORT_SYMBOL(iwl_fw_dbg_stop_recording); - -static void _iwl_fw_dbg_restart_recording(struct iwl_trans *trans, - struct iwl_fw_dbg_params *params) -{ - if (WARN_ON(!params)) - return; + if (!params) + return -EIO; if (trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) { iwl_clear_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x100); @@ -2997,28 +2992,40 @@ static void _iwl_fw_dbg_restart_recording(struct iwl_trans *trans, iwl_write_umac_prph(trans, DBGC_IN_SAMPLE, params->in_sample); iwl_write_umac_prph(trans, DBGC_OUT_CTRL, params->out_ctrl); } + + return 0; } -void iwl_fw_dbg_restart_recording(struct iwl_fw_runtime *fwrt, - struct iwl_fw_dbg_params *params) +int iwl_fw_dbg_stop_restart_recording(struct iwl_fw_runtime *fwrt, + struct iwl_fw_dbg_params *params, + bool stop) { + int ret = 0; + /* if the FW crashed or not debug monitor cfg was given, there is - * no point in restarting + * no point in changing the recording state */ if (test_bit(STATUS_FW_ERROR, &fwrt->trans->status) || (!fwrt->trans->dbg.dest_tlv && fwrt->trans->dbg.ini_dest == IWL_FW_INI_LOCATION_INVALID)) - return; + return 0; - if (fwrt->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) { - IWL_ERR(fwrt, - "WRT: unsupported device family %d for debug restart recording\n", - fwrt->trans->cfg->device_family); - return; - } - _iwl_fw_dbg_restart_recording(fwrt->trans, params); + if (fw_has_capa(&fwrt->fw->ucode_capa, + IWL_UCODE_TLV_CAPA_DBG_SUSPEND_RESUME_CMD_SUPP)) + ret = iwl_fw_dbg_suspend_resume_hcmd(fwrt->trans, stop); + else if (stop) + iwl_fw_dbg_stop_recording(fwrt->trans, params); + else + ret = iwl_fw_dbg_restart_recording(fwrt->trans, params); #ifdef CONFIG_IWLWIFI_DEBUGFS - iwl_fw_set_dbg_rec_on(fwrt); + if (!ret) { + if (stop) + fwrt->trans->dbg.rec_on = false; + else + iwl_fw_set_dbg_rec_on(fwrt); + } #endif + + return ret; } -IWL_EXPORT_SYMBOL(iwl_fw_dbg_restart_recording); +IWL_EXPORT_SYMBOL(iwl_fw_dbg_stop_restart_recording); diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h index 5582a11f7c89..461331703ea6 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h @@ -262,12 +262,9 @@ _iwl_fw_dbg_trigger_simple_stop(struct iwl_fw_runtime *fwrt, _iwl_fw_dbg_trigger_simple_stop((fwrt), (wdev), \ iwl_fw_dbg_get_trigger((fwrt)->fw,\ (trig))) - -void iwl_fw_dbg_stop_recording(struct iwl_trans *trans, - struct iwl_fw_dbg_params *params); - -void iwl_fw_dbg_restart_recording(struct iwl_fw_runtime *fwrt, - struct iwl_fw_dbg_params *params); +int iwl_fw_dbg_stop_restart_recording(struct iwl_fw_runtime *fwrt, + struct iwl_fw_dbg_params *params, + bool stop); #ifdef CONFIG_IWLWIFI_DEBUGFS static inline void iwl_fw_set_dbg_rec_on(struct iwl_fw_runtime *fwrt) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h index 0c38e7392b61..ea2b3d77f848 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/file.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h @@ -465,6 +465,7 @@ enum iwl_ucode_tlv_capa { IWL_UCODE_TLV_CAPA_LED_CMD_SUPPORT = (__force iwl_ucode_tlv_capa_t)88, IWL_UCODE_TLV_CAPA_MCC_UPDATE_11AX_SUPPORT = (__force iwl_ucode_tlv_capa_t)89, IWL_UCODE_TLV_CAPA_CSI_REPORTING = (__force iwl_ucode_tlv_capa_t)90, + IWL_UCODE_TLV_CAPA_DBG_SUSPEND_RESUME_CMD_SUPP = (__force iwl_ucode_tlv_capa_t)92, /* set 3 */ IWL_UCODE_TLV_CAPA_MLME_OFFLOAD = (__force iwl_ucode_tlv_capa_t)96, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index cec40855a641..3a8a0c43cb6e 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -1083,7 +1083,7 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, * recording automatically. */ if (mvm->trans->cfg->device_family < IWL_DEVICE_FAMILY_9000) - iwl_fw_dbg_stop_recording(mvm->trans, NULL); + iwl_fw_dbg_stop_restart_recording(&mvm->fwrt, NULL, true); /* must be last -- this switches firmware state */ ret = iwl_mvm_send_cmd(mvm, &d3_cfg_cmd); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 722e427d534c..bf0b9ee05c44 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -465,6 +465,7 @@ static const struct iwl_hcmd_names iwl_mvm_data_path_names[] = { * Access is done through binary search */ static const struct iwl_hcmd_names iwl_mvm_debug_names[] = { + HCMD_NAME(DBGC_SUSPEND_RESUME), HCMD_NAME(MFU_ASSERT_DUMP_NTF), }; From 60ced7973f4188163133dc60873f89991fb5a9d3 Mon Sep 17 00:00:00 2001 From: Shahar S Matityahu Date: Thu, 23 May 2019 08:39:27 +0300 Subject: [PATCH 09/80] iwlwifi: add ldbg config cmd debug print add support to print ldbg command in mvm and xvt mode Signed-off-by: Shahar S Matityahu Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index bf0b9ee05c44..2aa5320e9d1a 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -414,6 +414,7 @@ static const struct iwl_hcmd_names iwl_mvm_legacy_names[] = { HCMD_NAME(SCAN_ITERATION_COMPLETE), HCMD_NAME(D0I3_END_CMD), HCMD_NAME(LTR_CONFIG), + HCMD_NAME(LDBG_CONFIG_CMD), }; /* Please keep this array *SORTED* by hex value. From 06eb547c4ae4382e70d556ba213d13c95ca1801b Mon Sep 17 00:00:00 2001 From: Beker Ayala Date: Sun, 2 Jun 2019 13:55:44 +0300 Subject: [PATCH 10/80] iwlwifi: mvm: fix scan config command size Use the actual length of channels array and not the max capable length. Signed-off-by: Beker Ayala Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c index c284e6975b1b..5999b4ebd699 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c @@ -1205,7 +1205,7 @@ int iwl_mvm_config_scan(struct iwl_mvm *mvm) cmd_size = sizeof(struct iwl_scan_config); else cmd_size = sizeof(struct iwl_scan_config_v1); - cmd_size += mvm->fw->ucode_capa.n_scan_channels; + cmd_size += num_channels; cfg = kzalloc(cmd_size, GFP_KERNEL); if (!cfg) From f38acea63a5c733e4fbb0f6762a124d52293f8af Mon Sep 17 00:00:00 2001 From: Shaul Triebitz Date: Tue, 4 Jun 2019 11:50:34 +0300 Subject: [PATCH 11/80] iwlwifi: mvm: add the skb length to a print When printing a TX, add to the print the length of the frame. That will help with BSEP (buffer status report poll) tests. Signed-off-by: Shaul Triebitz Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index 6ac114a393cc..4effb90b4f75 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c @@ -1169,8 +1169,9 @@ static int iwl_mvm_tx_mpdu(struct iwl_mvm *mvm, struct sk_buff *skb, schedule_work(&mvm->add_stream_wk); } - IWL_DEBUG_TX(mvm, "TX to [%d|%d] Q:%d - seq: 0x%x\n", mvmsta->sta_id, - tid, txq_id, IEEE80211_SEQ_TO_SN(seq_number)); + IWL_DEBUG_TX(mvm, "TX to [%d|%d] Q:%d - seq: 0x%x len %d\n", + mvmsta->sta_id, tid, txq_id, + IEEE80211_SEQ_TO_SN(seq_number), skb->len); /* From now on, we cannot access info->control */ iwl_mvm_skb_prepare_status(skb, dev_cmd); From 2b7f47539b768468d677211c106ec480e1b14660 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 6 Jun 2019 09:52:56 +0300 Subject: [PATCH 12/80] iwlwifi: mvm: start to remove the code for d0i3 For runtime PM to work with d0i3 code, a lot of integration work needs to be done with the platform (e.g. the out-of-band wake up interrupt) and we currently don't have any platforms where this integration happened. So, this code has been pretty much stale for a while and when someone enables it, it just breaks things. Therefore, to simplify the code base and make sure no one enables this by mistake, we will remove the whole code. This is only the very start, much more work is needed. Remove the places where we check iwl_mvm_is_d0i3_supported but leave all the refs, those will be removed in a different patch. Signed-off-by: Emmanuel Grumbach Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 3d63cc4c9eaf..a7ed4e85cf8f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -762,12 +762,6 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) mvm->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; #ifdef CONFIG_PM_SLEEP - if (iwl_mvm_is_d0i3_supported(mvm) && - device_can_wakeup(mvm->trans->dev)) { - mvm->wowlan.flags = WIPHY_WOWLAN_ANY; - hw->wiphy->wowlan = &mvm->wowlan; - } - if ((unified || mvm->fw->img[IWL_UCODE_WOWLAN].num_sec) && mvm->trans->ops->d3_suspend && mvm->trans->ops->d3_resume && @@ -1359,17 +1353,6 @@ static void iwl_mvm_restart_complete(struct iwl_mvm *mvm) mutex_unlock(&mvm->mutex); } -static void iwl_mvm_resume_complete(struct iwl_mvm *mvm) -{ - if (iwl_mvm_is_d0i3_supported(mvm) && - iwl_mvm_enter_d0i3_on_suspend(mvm)) - WARN_ONCE(!wait_event_timeout(mvm->d0i3_exit_waitq, - !test_bit(IWL_MVM_STATUS_IN_D0I3, - &mvm->status), - HZ), - "D0i3 exit on resume timed out\n"); -} - static void iwl_mvm_mac_reconfig_complete(struct ieee80211_hw *hw, enum ieee80211_reconfig_type reconfig_type) @@ -1381,7 +1364,6 @@ iwl_mvm_mac_reconfig_complete(struct ieee80211_hw *hw, iwl_mvm_restart_complete(mvm); break; case IEEE80211_RECONFIG_TYPE_SUSPEND: - iwl_mvm_resume_complete(mvm); break; } } From 58d3bef4163b40147058649b225fddcdd9de7e82 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 11 Jun 2019 13:15:24 +0300 Subject: [PATCH 13/80] iwlwifi: remove all the d0i3 references As part of the d0i3 removal. Signed-off-by: Emmanuel Grumbach Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/iwl-op-mode.h | 4 +- drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 9 - .../net/wireless/intel/iwlwifi/mvm/debugfs.c | 111 ---------- drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 4 - .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 195 ------------------ drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 49 ----- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 42 +--- drivers/net/wireless/intel/iwlwifi/mvm/rx.c | 18 +- drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 7 - drivers/net/wireless/intel/iwlwifi/mvm/tdls.c | 9 - .../wireless/intel/iwlwifi/mvm/time-event.c | 8 +- drivers/net/wireless/intel/iwlwifi/mvm/tt.c | 12 +- .../net/wireless/intel/iwlwifi/mvm/utils.c | 8 +- 13 files changed, 11 insertions(+), 465 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h b/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h index cbd1a8eed620..f37d6fee0225 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h @@ -8,7 +8,7 @@ * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH * Copyright(c) 2015 Intel Deutschland GmbH - * Copyright(c) 2018 Intel Corporation + * Copyright(c) 2018 - 2019 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -31,7 +31,7 @@ * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH * Copyright(c) 2015 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 diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index 3a8a0c43cb6e..7493cae70ea6 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -1106,7 +1106,6 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, iwl_mvm_free_nd(mvm); if (!unified_image) { - iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN); if (mvm->fw_restart > 0) { mvm->fw_restart--; ieee80211_restart_hw(mvm->hw); @@ -2115,14 +2114,6 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) * 2. We are using a unified image but had an error while exiting D3 */ set_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status); - /* - * When switching images we return 1, which causes mac80211 - * to do a reconfig with IEEE80211_RECONFIG_TYPE_RESTART. - * This type of reconfig calls iwl_mvm_restart_complete(), - * where we unref the IWL_MVM_REF_UCODE_DOWN, so we need - * to take the reference here. - */ - iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN); return 1; } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c index 0c188a82cfc1..6d67d3da31e0 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c @@ -1056,19 +1056,11 @@ static ssize_t iwl_dbgfs_fw_restart_write(struct iwl_mvm *mvm, char *buf, static ssize_t iwl_dbgfs_fw_nmi_write(struct iwl_mvm *mvm, char *buf, size_t count, loff_t *ppos) { - int ret; - if (!iwl_mvm_firmware_running(mvm)) return -EIO; - ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_NMI); - if (ret) - return ret; - iwl_force_nmi(mvm->trans); - iwl_mvm_unref(mvm, IWL_MVM_REF_NMI); - return count; } @@ -1380,19 +1372,12 @@ static ssize_t iwl_dbgfs_fw_dbg_collect_write(struct iwl_mvm *mvm, char *buf, size_t count, loff_t *ppos) { - int ret; - - ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PRPH_WRITE); - if (ret) - return ret; if (count == 0) return 0; iwl_fw_dbg_collect(&mvm->fwrt, FW_DBG_TRIGGER_USER, buf, (count - 1), NULL); - iwl_mvm_unref(mvm, IWL_MVM_REF_PRPH_WRITE); - return count; } @@ -1579,87 +1564,6 @@ static ssize_t iwl_dbgfs_bcast_filters_macs_write(struct iwl_mvm *mvm, } #endif -#define PRINT_MVM_REF(ref) do { \ - if (mvm->refs[ref]) \ - pos += scnprintf(buf + pos, bufsz - pos, \ - "\t(0x%lx): %d %s\n", \ - BIT(ref), mvm->refs[ref], #ref); \ -} while (0) - -static ssize_t iwl_dbgfs_d0i3_refs_read(struct file *file, - char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct iwl_mvm *mvm = file->private_data; - int i, pos = 0; - char buf[256]; - const size_t bufsz = sizeof(buf); - u32 refs = 0; - - for (i = 0; i < IWL_MVM_REF_COUNT; i++) - if (mvm->refs[i]) - refs |= BIT(i); - - pos += scnprintf(buf + pos, bufsz - pos, "taken mvm refs: 0x%x\n", - refs); - - PRINT_MVM_REF(IWL_MVM_REF_UCODE_DOWN); - PRINT_MVM_REF(IWL_MVM_REF_SCAN); - PRINT_MVM_REF(IWL_MVM_REF_ROC); - PRINT_MVM_REF(IWL_MVM_REF_ROC_AUX); - PRINT_MVM_REF(IWL_MVM_REF_P2P_CLIENT); - PRINT_MVM_REF(IWL_MVM_REF_AP_IBSS); - PRINT_MVM_REF(IWL_MVM_REF_USER); - PRINT_MVM_REF(IWL_MVM_REF_TX); - PRINT_MVM_REF(IWL_MVM_REF_TX_AGG); - PRINT_MVM_REF(IWL_MVM_REF_ADD_IF); - PRINT_MVM_REF(IWL_MVM_REF_START_AP); - PRINT_MVM_REF(IWL_MVM_REF_BSS_CHANGED); - PRINT_MVM_REF(IWL_MVM_REF_PREPARE_TX); - PRINT_MVM_REF(IWL_MVM_REF_PROTECT_TDLS); - PRINT_MVM_REF(IWL_MVM_REF_CHECK_CTKILL); - PRINT_MVM_REF(IWL_MVM_REF_PRPH_READ); - PRINT_MVM_REF(IWL_MVM_REF_PRPH_WRITE); - PRINT_MVM_REF(IWL_MVM_REF_NMI); - PRINT_MVM_REF(IWL_MVM_REF_TM_CMD); - PRINT_MVM_REF(IWL_MVM_REF_EXIT_WORK); - PRINT_MVM_REF(IWL_MVM_REF_PROTECT_CSA); - PRINT_MVM_REF(IWL_MVM_REF_FW_DBG_COLLECT); - PRINT_MVM_REF(IWL_MVM_REF_INIT_UCODE); - PRINT_MVM_REF(IWL_MVM_REF_SENDING_CMD); - PRINT_MVM_REF(IWL_MVM_REF_RX); - - return simple_read_from_buffer(user_buf, count, ppos, buf, pos); -} - -static ssize_t iwl_dbgfs_d0i3_refs_write(struct iwl_mvm *mvm, char *buf, - size_t count, loff_t *ppos) -{ - unsigned long value; - int ret; - bool taken; - - ret = kstrtoul(buf, 10, &value); - if (ret < 0) - return ret; - - mutex_lock(&mvm->mutex); - - taken = mvm->refs[IWL_MVM_REF_USER]; - if (value == 1 && !taken) - iwl_mvm_ref(mvm, IWL_MVM_REF_USER); - else if (value == 0 && taken) - iwl_mvm_unref(mvm, IWL_MVM_REF_USER); - else - ret = -EINVAL; - - mutex_unlock(&mvm->mutex); - - if (ret < 0) - return ret; - return count; -} - #define MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz) \ _MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct iwl_mvm) #define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \ @@ -1692,21 +1596,14 @@ iwl_dbgfs_prph_reg_read(struct file *file, int pos = 0; char buf[32]; const size_t bufsz = sizeof(buf); - int ret; if (!mvm->dbgfs_prph_reg_addr) return -EINVAL; - ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PRPH_READ); - if (ret) - return ret; - pos += scnprintf(buf + pos, bufsz - pos, "Reg 0x%x: (0x%x)\n", mvm->dbgfs_prph_reg_addr, iwl_read_prph(mvm->trans, mvm->dbgfs_prph_reg_addr)); - iwl_mvm_unref(mvm, IWL_MVM_REF_PRPH_READ); - return simple_read_from_buffer(user_buf, count, ppos, buf, pos); } @@ -1716,7 +1613,6 @@ iwl_dbgfs_prph_reg_write(struct iwl_mvm *mvm, char *buf, { u8 args; u32 value; - int ret; args = sscanf(buf, "%i %i", &mvm->dbgfs_prph_reg_addr, &value); /* if we only want to set the reg address - nothing more to do */ @@ -1727,13 +1623,8 @@ iwl_dbgfs_prph_reg_write(struct iwl_mvm *mvm, char *buf, if (args != 2) return -EINVAL; - ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PRPH_WRITE); - if (ret) - return ret; - iwl_write_prph(mvm->trans, mvm->dbgfs_prph_reg_addr, value); - iwl_mvm_unref(mvm, IWL_MVM_REF_PRPH_WRITE); out: return count; } @@ -1892,7 +1783,6 @@ MVM_DEBUGFS_WRITE_FILE_OPS(fw_nmi, 10); MVM_DEBUGFS_WRITE_FILE_OPS(bt_tx_prio, 10); MVM_DEBUGFS_WRITE_FILE_OPS(bt_force_ant, 10); MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain, 8); -MVM_DEBUGFS_READ_WRITE_FILE_OPS(d0i3_refs, 8); MVM_DEBUGFS_READ_WRITE_FILE_OPS(fw_dbg_conf, 8); MVM_DEBUGFS_WRITE_FILE_OPS(fw_dbg_collect, 64); MVM_DEBUGFS_WRITE_FILE_OPS(indirection_tbl, @@ -2091,7 +1981,6 @@ void iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) MVM_DEBUGFS_ADD_FILE(bt_force_ant, mvm->debugfs_dir, 0200); MVM_DEBUGFS_ADD_FILE(scan_ant_rxchain, mvm->debugfs_dir, 0600); MVM_DEBUGFS_ADD_FILE(prph_reg, mvm->debugfs_dir, 0600); - MVM_DEBUGFS_ADD_FILE(d0i3_refs, mvm->debugfs_dir, 0600); MVM_DEBUGFS_ADD_FILE(fw_dbg_conf, mvm->debugfs_dir, 0600); MVM_DEBUGFS_ADD_FILE(fw_dbg_collect, mvm->debugfs_dir, 0200); MVM_DEBUGFS_ADD_FILE(send_echo_cmd, mvm->debugfs_dir, 0200); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index ed6453b2fc79..251e7c235aaa 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -1326,10 +1326,6 @@ int iwl_mvm_up(struct iwl_mvm *mvm) goto error; } - /* allow FW/transport low power modes if not during restart */ - if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) - iwl_mvm_unref(mvm, IWL_MVM_REF_UCODE_DOWN); - if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) iwl_mvm_send_recovery_cmd(mvm, ERROR_RECOVERY_UPDATE_DB); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index a7ed4e85cf8f..c17f769b3451 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -213,91 +213,6 @@ static int __iwl_mvm_mac_set_key(struct ieee80211_hw *hw, struct ieee80211_sta *sta, struct ieee80211_key_conf *key); -void iwl_mvm_ref(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type) -{ - if (!iwl_mvm_is_d0i3_supported(mvm)) - return; - - IWL_DEBUG_RPM(mvm, "Take mvm reference - type %d\n", ref_type); - spin_lock_bh(&mvm->refs_lock); - mvm->refs[ref_type]++; - spin_unlock_bh(&mvm->refs_lock); - iwl_trans_ref(mvm->trans); -} - -void iwl_mvm_unref(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type) -{ - if (!iwl_mvm_is_d0i3_supported(mvm)) - return; - - IWL_DEBUG_RPM(mvm, "Leave mvm reference - type %d\n", ref_type); - spin_lock_bh(&mvm->refs_lock); - if (WARN_ON(!mvm->refs[ref_type])) { - spin_unlock_bh(&mvm->refs_lock); - return; - } - mvm->refs[ref_type]--; - spin_unlock_bh(&mvm->refs_lock); - iwl_trans_unref(mvm->trans); -} - -static void iwl_mvm_unref_all_except(struct iwl_mvm *mvm, - enum iwl_mvm_ref_type except_ref) -{ - int i, j; - - if (!iwl_mvm_is_d0i3_supported(mvm)) - return; - - spin_lock_bh(&mvm->refs_lock); - for (i = 0; i < IWL_MVM_REF_COUNT; i++) { - if (except_ref == i || !mvm->refs[i]) - continue; - - IWL_DEBUG_RPM(mvm, "Cleanup: remove mvm ref type %d (%d)\n", - i, mvm->refs[i]); - for (j = 0; j < mvm->refs[i]; j++) - iwl_trans_unref(mvm->trans); - mvm->refs[i] = 0; - } - spin_unlock_bh(&mvm->refs_lock); -} - -bool iwl_mvm_ref_taken(struct iwl_mvm *mvm) -{ - int i; - bool taken = false; - - if (!iwl_mvm_is_d0i3_supported(mvm)) - return true; - - spin_lock_bh(&mvm->refs_lock); - for (i = 0; i < IWL_MVM_REF_COUNT; i++) { - if (mvm->refs[i]) { - taken = true; - break; - } - } - spin_unlock_bh(&mvm->refs_lock); - - return taken; -} - -int iwl_mvm_ref_sync(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type) -{ - iwl_mvm_ref(mvm, ref_type); - - if (!wait_event_timeout(mvm->d0i3_exit_waitq, - !test_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status), - HZ)) { - WARN_ON_ONCE(1); - iwl_mvm_unref(mvm, ref_type); - return -EIO; - } - - return 0; -} - static void iwl_mvm_reset_phy_ctxts(struct iwl_mvm *mvm) { int i; @@ -857,10 +772,6 @@ static bool iwl_mvm_defer_tx(struct iwl_mvm *mvm, __skb_queue_tail(&mvm->d0i3_tx, skb); - /* trigger wakeup */ - iwl_mvm_ref(mvm, IWL_MVM_REF_TX); - iwl_mvm_unref(mvm, IWL_MVM_REF_TX); - defer = true; out: spin_unlock(&mvm->d0i3_tx_lock); @@ -1080,7 +991,6 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw, { struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); int ret; - bool tx_agg_ref = false; struct ieee80211_sta *sta = params->sta; enum ieee80211_ampdu_mlme_action action = params->action; u16 tid = params->tid; @@ -1095,31 +1005,6 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw, if (!(mvm->nvm_data->sku_cap_11n_enable)) return -EACCES; - /* return from D0i3 before starting a new Tx aggregation */ - switch (action) { - case IEEE80211_AMPDU_TX_START: - case IEEE80211_AMPDU_TX_STOP_CONT: - case IEEE80211_AMPDU_TX_STOP_FLUSH: - case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: - case IEEE80211_AMPDU_TX_OPERATIONAL: - /* - * for tx start, wait synchronously until D0i3 exit to - * get the correct sequence number for the tid. - * additionally, some other ampdu actions use direct - * target access, which is not handled automatically - * by the trans layer (unlike commands), so wait for - * d0i3 exit in these cases as well. - */ - ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_TX_AGG); - if (ret) - return ret; - - tx_agg_ref = true; - break; - default: - break; - } - mutex_lock(&mvm->mutex); switch (action) { @@ -1180,13 +1065,6 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw, } mutex_unlock(&mvm->mutex); - /* - * If the tid is marked as started, we won't use it for offloaded - * traffic on the next D0i3 entry. It's safe to unref. - */ - if (tx_agg_ref) - iwl_mvm_unref(mvm, IWL_MVM_REF_TX_AGG); - return ret; } @@ -1210,11 +1088,6 @@ static void iwl_mvm_cleanup_iterator(void *data, u8 *mac, static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm) { - /* cleanup all stale references (scan, roc), but keep the - * ucode_down ref until reconfig is complete - */ - iwl_mvm_unref_all_except(mvm, IWL_MVM_REF_UCODE_DOWN); - iwl_mvm_stop_device(mvm); mvm->cur_aid = 0; @@ -1272,14 +1145,6 @@ int __iwl_mvm_mac_start(struct iwl_mvm *mvm) clear_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status); /* Clean up some internal and mac80211 state on restart */ iwl_mvm_restart_cleanup(mvm); - } else { - /* Hold the reference to prevent runtime suspend while - * the start procedure runs. It's a bit confusing - * that the UCODE_DOWN reference is taken, but it just - * means "UCODE is not UP yet". ( TODO: rename this - * reference). - */ - iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN); } ret = iwl_mvm_up(mvm); @@ -1339,9 +1204,6 @@ static void iwl_mvm_restart_complete(struct iwl_mvm *mvm) IWL_ERR(mvm, "Failed to update quotas after restart (%d)\n", ret); - /* allow transport/FW low power modes */ - iwl_mvm_unref(mvm, IWL_MVM_REF_UCODE_DOWN); - iwl_mvm_send_recovery_cmd(mvm, ERROR_RECOVERY_END_OF_RECOVERY); /* @@ -1593,15 +1455,6 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, mvmvif->mvm = mvm; RCU_INIT_POINTER(mvmvif->probe_resp_data, NULL); - /* - * make sure D0i3 exit is completed, otherwise a target access - * during tx queue configuration could be done when still in - * D0i3 state. - */ - ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_ADD_IF); - if (ret) - return ret; - /* * Not much to do here. The stack will not allow interface * types or combinations that we didn't advertise, so we @@ -1737,8 +1590,6 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, out_unlock: mutex_unlock(&mvm->mutex); - iwl_mvm_unref(mvm, IWL_MVM_REF_ADD_IF); - return ret; } @@ -2506,7 +2357,6 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm, iwl_mvm_sf_update(mvm, vif, false); iwl_mvm_power_vif_assoc(mvm, vif); if (vif->p2p) { - iwl_mvm_ref(mvm, IWL_MVM_REF_P2P_CLIENT); iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_PROT, IEEE80211_SMPS_DYNAMIC); @@ -2553,9 +2403,6 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm, if (ret) IWL_ERR(mvm, "failed to update quotas\n"); - if (vif->p2p) - iwl_mvm_unref(mvm, IWL_MVM_REF_P2P_CLIENT); - /* this will take the cleared BSSID from bss_conf */ ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL); if (ret) @@ -2643,14 +2490,6 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw, struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); int ret, i; - /* - * iwl_mvm_mac_ctxt_add() might read directly from the device - * (the system time), so make sure it is available. - */ - ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_START_AP); - if (ret) - return ret; - mutex_lock(&mvm->mutex); /* Send the beacon template */ @@ -2746,8 +2585,6 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw, if (vif->p2p && mvm->p2p_device_vif) iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif, false, NULL); - iwl_mvm_ref(mvm, IWL_MVM_REF_AP_IBSS); - iwl_mvm_bt_coex_vif_change(mvm); /* we don't support TDLS during DCM */ @@ -2769,7 +2606,6 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw, iwl_mvm_mac_ctxt_remove(mvm, vif); out_unlock: mutex_unlock(&mvm->mutex); - iwl_mvm_unref(mvm, IWL_MVM_REF_START_AP); return ret; } @@ -2807,8 +2643,6 @@ static void iwl_mvm_stop_ap_ibss(struct ieee80211_hw *hw, iwl_mvm_bt_coex_vif_change(mvm); - iwl_mvm_unref(mvm, IWL_MVM_REF_AP_IBSS); - /* Need to update the P2P Device MAC (only GO, IBSS is single vif) */ if (vif->p2p && mvm->p2p_device_vif) iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif, false, NULL); @@ -2882,14 +2716,6 @@ static void iwl_mvm_bss_info_changed(struct ieee80211_hw *hw, { struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); - /* - * iwl_mvm_bss_info_changed_station() might call - * iwl_mvm_protect_session(), which reads directly from - * the device (the system time), so make sure it is available. - */ - if (iwl_mvm_ref_sync(mvm, IWL_MVM_REF_BSS_CHANGED)) - return; - mutex_lock(&mvm->mutex); if (changes & BSS_CHANGED_IDLE && !bss_conf->idle) @@ -2913,7 +2739,6 @@ static void iwl_mvm_bss_info_changed(struct ieee80211_hw *hw, } mutex_unlock(&mvm->mutex); - iwl_mvm_unref(mvm, IWL_MVM_REF_BSS_CHANGED); } static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw, @@ -3483,13 +3308,6 @@ static void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw, u32 duration = IWL_MVM_TE_SESSION_PROTECTION_MAX_TIME_MS; u32 min_duration = IWL_MVM_TE_SESSION_PROTECTION_MIN_TIME_MS; - /* - * iwl_mvm_protect_session() reads directly from the device - * (the system time), so make sure it is available. - */ - if (iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PREPARE_TX)) - return; - if (req_duration > duration) duration = req_duration; @@ -3497,8 +3315,6 @@ static void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw, /* Try really hard to protect the session and hear a beacon */ iwl_mvm_protect_session(mvm, vif, duration, min_duration, 500, false); mutex_unlock(&mvm->mutex); - - iwl_mvm_unref(mvm, IWL_MVM_REF_PREPARE_TX); } static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw, @@ -4314,23 +4130,12 @@ static int __iwl_mvm_assign_vif_chanctx(struct iwl_mvm *mvm, IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD)) { u32 duration = 3 * vif->bss_conf.beacon_int; - - /* iwl_mvm_protect_session() reads directly from the - * device (the system time), so make sure it is - * available. - */ - ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PROTECT_CSA); - if (ret) - goto out_remove_binding; - /* Protect the session to make sure we hear the first * beacon on the new channel. */ iwl_mvm_protect_session(mvm, vif, duration, duration, vif->bss_conf.beacon_int / 2, true); - - iwl_mvm_unref(mvm, IWL_MVM_REF_PROTECT_CSA); } iwl_mvm_update_quotas(mvm, false, NULL); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index e5703aa7935e..245e8c721102 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -258,38 +258,6 @@ enum iwl_mvm_smps_type_request { NUM_IWL_MVM_SMPS_REQ, }; -enum iwl_mvm_ref_type { - IWL_MVM_REF_UCODE_DOWN, - IWL_MVM_REF_SCAN, - IWL_MVM_REF_ROC, - IWL_MVM_REF_ROC_AUX, - IWL_MVM_REF_P2P_CLIENT, - IWL_MVM_REF_AP_IBSS, - IWL_MVM_REF_USER, - IWL_MVM_REF_TX, - IWL_MVM_REF_TX_AGG, - IWL_MVM_REF_ADD_IF, - IWL_MVM_REF_START_AP, - IWL_MVM_REF_BSS_CHANGED, - IWL_MVM_REF_PREPARE_TX, - IWL_MVM_REF_PROTECT_TDLS, - IWL_MVM_REF_CHECK_CTKILL, - IWL_MVM_REF_PRPH_READ, - IWL_MVM_REF_PRPH_WRITE, - IWL_MVM_REF_NMI, - IWL_MVM_REF_TM_CMD, - IWL_MVM_REF_EXIT_WORK, - IWL_MVM_REF_PROTECT_CSA, - IWL_MVM_REF_FW_DBG_COLLECT, - IWL_MVM_REF_INIT_UCODE, - IWL_MVM_REF_SENDING_CMD, - IWL_MVM_REF_RX, - - /* update debugfs.c when changing this */ - - IWL_MVM_REF_COUNT, -}; - enum iwl_bt_force_ant_mode { BT_FORCE_ANT_DIS = 0, BT_FORCE_ANT_AUTO, @@ -1014,10 +982,6 @@ struct iwl_mvm { unsigned long fw_key_table[BITS_TO_LONGS(STA_KEY_MAX_NUM)]; u8 fw_key_deleted[STA_KEY_MAX_NUM]; - /* references taken by the driver and spinlock protecting them */ - spinlock_t refs_lock; - u8 refs[IWL_MVM_REF_COUNT]; - u8 vif_count; struct ieee80211_vif __rcu *vif_id_to_mac[NUM_MAC_INDEX_DRIVER]; @@ -1294,13 +1258,6 @@ iwl_mvm_rcu_dereference_vif_id(struct iwl_mvm *mvm, u8 vif_id, bool rcu) lockdep_is_held(&mvm->mutex)); } -static inline bool iwl_mvm_is_d0i3_supported(struct iwl_mvm *mvm) -{ - return !iwlwifi_mod_params.d0i3_disable && - fw_has_capa(&mvm->fw->ucode_capa, - IWL_UCODE_TLV_CAPA_D0I3_SUPPORT); -} - static inline bool iwl_mvm_is_adaptive_dwell_supported(struct iwl_mvm *mvm) { return fw_has_api(&mvm->fw->ucode_capa, @@ -1903,12 +1860,6 @@ int iwl_mvm_send_proto_offload(struct iwl_mvm *mvm, bool offload_ns, u32 cmd_flags); -/* D0i3 */ -void iwl_mvm_ref(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type); -void iwl_mvm_unref(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type); -int iwl_mvm_ref_sync(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type); -bool iwl_mvm_ref_taken(struct iwl_mvm *mvm); - #ifdef CONFIG_PM void iwl_mvm_d0i3_enable_tx(struct iwl_mvm *mvm, __le16 *qos_seq); int iwl_mvm_enter_d0i3(struct iwl_op_mode *op_mode); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 2aa5320e9d1a..255b402f7b19 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -566,23 +566,16 @@ static void iwl_mvm_tx_unblock_dwork(struct work_struct *work) static int iwl_mvm_fwrt_dump_start(void *ctx) { struct iwl_mvm *mvm = ctx; - int ret = 0; mutex_lock(&mvm->mutex); - ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_FW_DBG_COLLECT); - if (ret) - mutex_unlock(&mvm->mutex); - - return ret; + return 0; } static void iwl_mvm_fwrt_dump_end(void *ctx) { struct iwl_mvm *mvm = ctx; - iwl_mvm_unref(mvm, IWL_MVM_REF_FW_DBG_COLLECT); - mutex_unlock(&mvm->mutex); } @@ -721,7 +714,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, INIT_LIST_HEAD(&mvm->add_stream_txqs); spin_lock_init(&mvm->d0i3_tx_lock); - spin_lock_init(&mvm->refs_lock); skb_queue_head_init(&mvm->d0i3_tx); init_waitqueue_head(&mvm->d0i3_exit_waitq); init_waitqueue_head(&mvm->rx_sync_waitq); @@ -834,13 +826,11 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, goto out_free; mutex_lock(&mvm->mutex); - iwl_mvm_ref(mvm, IWL_MVM_REF_INIT_UCODE); err = iwl_run_init_mvm_ucode(mvm, true); if (err && err != -ERFKILL) iwl_fw_dbg_error_collect(&mvm->fwrt, FW_DBG_TRIGGER_DRIVER); if (!iwlmvm_mod_params.init_dbg || !err) iwl_mvm_stop_device(mvm); - iwl_mvm_unref(mvm, IWL_MVM_REF_INIT_UCODE); mutex_unlock(&mvm->mutex); if (err < 0) { IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", err); @@ -872,11 +862,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, else memset(&mvm->rx_stats, 0, sizeof(struct mvm_statistics_rx)); - /* The transport always starts with a taken reference, we can - * release it now if d0i3 is supported */ - if (iwl_mvm_is_d0i3_supported(mvm)) - iwl_trans_unref(mvm->trans); - iwl_mvm_toggle_tx_ant(mvm, &mvm->mgmt_last_antenna_idx); return op_mode; @@ -900,13 +885,6 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode) struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); int i; - /* If d0i3 is supported, we have released the reference that - * the transport started with, so we should take it back now - * that we are leaving. - */ - if (iwl_mvm_is_d0i3_supported(mvm)) - iwl_trans_ref(mvm->trans); - iwl_mvm_leds_exit(mvm); iwl_mvm_thermal_exit(mvm); @@ -1320,9 +1298,6 @@ void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error) } else if (mvm->fwrt.cur_fw_img == IWL_UCODE_REGULAR && mvm->hw_registered && !test_bit(STATUS_TRANS_DEAD, &mvm->trans->status)) { - /* don't let the transport/FW power down */ - iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN); - if (mvm->fw->ucode_capa.error_log_size) { u32 src_size = mvm->fw->ucode_capa.error_log_size; u32 src_addr = mvm->fw->ucode_capa.error_log_addr; @@ -1520,19 +1495,6 @@ int iwl_mvm_enter_d0i3(struct iwl_op_mode *op_mode) set_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status); - /* - * iwl_mvm_ref_sync takes a reference before checking the flag. - * so by checking there is no held reference we prevent a state - * in which iwl_mvm_ref_sync continues successfully while we - * configure the firmware to enter d0i3 - */ - if (iwl_mvm_ref_taken(mvm)) { - IWL_DEBUG_RPM(mvm->trans, "abort d0i3 due to taken ref\n"); - clear_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status); - wake_up(&mvm->d0i3_exit_waitq); - return 1; - } - ieee80211_iterate_active_interfaces_atomic(mvm->hw, IEEE80211_IFACE_ITER_NORMAL, iwl_mvm_enter_d0i3_iterator, @@ -1728,7 +1690,6 @@ static void iwl_mvm_d0i3_exit_work(struct work_struct *wk) iwl_mvm_update_changed_regdom(mvm); iwl_mvm_resume_tcm(mvm); - iwl_mvm_unref(mvm, IWL_MVM_REF_EXIT_WORK); mutex_unlock(&mvm->mutex); } @@ -1769,7 +1730,6 @@ int iwl_mvm_exit_d0i3(struct iwl_op_mode *op_mode) { struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); - iwl_mvm_ref(mvm, IWL_MVM_REF_EXIT_WORK); return _iwl_mvm_exit_d0i3(mvm); } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c index 160b0db27103..0ad8ed23a455 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c @@ -8,6 +8,7 @@ * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH + * Copyright(c) 2018 - 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 @@ -29,6 +30,8 @@ * * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH + * Copyright(c) 2016 - 2017 Intel Deutschland GmbH + * Copyright(c) 2018 - 2019 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -349,7 +352,6 @@ void iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct napi_struct *napi, u32 rate_n_flags; u32 rx_pkt_status; u8 crypt_len = 0; - bool take_ref; phy_info = &mvm->last_phy_info; rx_res = (struct iwl_rx_mpdu_res_start *)pkt->data; @@ -557,22 +559,8 @@ void iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct napi_struct *napi, ieee80211_is_probe_resp(hdr->frame_control))) rx_status->boottime_ns = ktime_get_boottime_ns(); - /* Take a reference briefly to kick off a d0i3 entry delay so - * we can handle bursts of RX packets without toggling the - * state too often. But don't do this for beacons if we are - * going to idle because the beacon filtering changes we make - * cause the firmware to send us collateral beacons. */ - take_ref = !(test_bit(STATUS_TRANS_GOING_IDLE, &mvm->trans->status) && - ieee80211_is_beacon(hdr->frame_control)); - - if (take_ref) - iwl_mvm_ref(mvm, IWL_MVM_REF_RX); - iwl_mvm_pass_packet_to_mac80211(mvm, sta, napi, skb, hdr, len, crypt_len, rxb); - - if (take_ref) - iwl_mvm_unref(mvm, IWL_MVM_REF_RX); } struct iwl_mvm_stat_data { diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c index 5999b4ebd699..2652e6ce4089 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c @@ -512,7 +512,6 @@ void iwl_mvm_rx_lmac_scan_complete_notif(struct iwl_mvm *mvm, mvm->scan_status &= ~IWL_MVM_SCAN_REGULAR; ieee80211_scan_completed(mvm->hw, &info); - iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); cancel_delayed_work(&mvm->scan_timeout_dwork); iwl_mvm_resume_tcm(mvm); } else { @@ -1758,7 +1757,6 @@ int iwl_mvm_reg_scan_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif, IWL_DEBUG_SCAN(mvm, "Scan request was sent successfully\n"); mvm->scan_status |= IWL_MVM_SCAN_REGULAR; mvm->scan_vif = iwl_mvm_vif_from_mac80211(vif); - iwl_mvm_ref(mvm, IWL_MVM_REF_SCAN); schedule_delayed_work(&mvm->scan_timeout_dwork, msecs_to_jiffies(SCAN_TIMEOUT)); @@ -1884,7 +1882,6 @@ void iwl_mvm_rx_umac_scan_complete_notif(struct iwl_mvm *mvm, memcpy(info.tsf_bssid, mvm->scan_vif->bssid, ETH_ALEN); ieee80211_scan_completed(mvm->hw, &info); mvm->scan_vif = NULL; - iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); cancel_delayed_work(&mvm->scan_timeout_dwork); iwl_mvm_resume_tcm(mvm); } else if (mvm->scan_uid_status[uid] == IWL_MVM_SCAN_SCHED) { @@ -2099,10 +2096,6 @@ int iwl_mvm_scan_stop(struct iwl_mvm *mvm, int type, bool notify) mvm->scan_status &= ~type; if (type == IWL_MVM_SCAN_REGULAR) { - /* Since the rx handler won't do anything now, we have - * to release the scan reference here. - */ - iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); cancel_delayed_work(&mvm->scan_timeout_dwork); if (notify) { struct cfg80211_scan_info info = { diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tdls.c b/drivers/net/wireless/intel/iwlwifi/mvm/tdls.c index 9df21a8d1fc1..1851719e9f4b 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tdls.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tdls.c @@ -205,19 +205,10 @@ void iwl_mvm_mac_mgd_protect_tdls_discover(struct ieee80211_hw *hw, struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); u32 duration = 2 * vif->bss_conf.dtim_period * vif->bss_conf.beacon_int; - /* - * iwl_mvm_protect_session() reads directly from the device - * (the system time), so make sure it is available. - */ - if (iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PROTECT_TDLS)) - return; - mutex_lock(&mvm->mutex); /* Protect the session to hear the TDLS setup response on the channel */ iwl_mvm_protect_session(mvm, vif, duration, duration, 100, true); mutex_unlock(&mvm->mutex); - - iwl_mvm_unref(mvm, IWL_MVM_REF_PROTECT_TDLS); } static const char * diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c index 4d34e5ab1bff..a06bc63fb516 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c @@ -106,10 +106,8 @@ void iwl_mvm_roc_done_wk(struct work_struct *wk) * in the case that the time event actually completed in the firmware * (which is handled in iwl_mvm_te_handle_notif). */ - if (test_and_clear_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status)) - iwl_mvm_unref(mvm, IWL_MVM_REF_ROC); - if (test_and_clear_bit(IWL_MVM_STATUS_ROC_AUX_RUNNING, &mvm->status)) - iwl_mvm_unref(mvm, IWL_MVM_REF_ROC_AUX); + clear_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status); + clear_bit(IWL_MVM_STATUS_ROC_AUX_RUNNING, &mvm->status); synchronize_net(); @@ -357,7 +355,6 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm, if (te_data->vif->type == NL80211_IFTYPE_P2P_DEVICE) { set_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status); - iwl_mvm_ref(mvm, IWL_MVM_REF_ROC); ieee80211_ready_on_channel(mvm->hw); } else if (te_data->id == TE_CHANNEL_SWITCH_PERIOD) { iwl_mvm_te_handle_notify_csa(mvm, te_data, notif); @@ -405,7 +402,6 @@ static int iwl_mvm_aux_roc_te_handle_notif(struct iwl_mvm *mvm, } else if (le32_to_cpu(notif->action) == TE_V2_NOTIF_HOST_EVENT_START) { set_bit(IWL_MVM_STATUS_ROC_AUX_RUNNING, &mvm->status); te_data->running = true; - iwl_mvm_ref(mvm, IWL_MVM_REF_ROC_AUX); ieee80211_ready_on_channel(mvm->hw); /* Start TE */ } else { IWL_DEBUG_TE(mvm, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c index 0b3e5c99d316..32a708301cfc 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. + * Copyright(c) 2013 - 2014, 2019 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH * Copyright(c) 2015 - 2016 Intel Deutschland GmbH * @@ -27,7 +27,7 @@ * * BSD LICENSE * - * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. + * Copyright(c) 2012 - 2014, 2019 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH * Copyright(c) 2015 - 2016 Intel Deutschland GmbH * All rights reserved. @@ -298,16 +298,8 @@ static void check_exit_ctkill(struct work_struct *work) if (__iwl_mvm_mac_start(mvm)) goto reschedule; - /* make sure the device is available for direct read/writes */ - if (iwl_mvm_ref_sync(mvm, IWL_MVM_REF_CHECK_CTKILL)) { - __iwl_mvm_mac_stop(mvm); - goto reschedule; - } - ret = iwl_mvm_get_temp(mvm, &temp); - iwl_mvm_unref(mvm, IWL_MVM_REF_CHECK_CTKILL); - __iwl_mvm_mac_stop(mvm); if (ret) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c index b8e20a01c192..06ef853fb84a 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c @@ -88,17 +88,11 @@ int iwl_mvm_send_cmd(struct iwl_mvm *mvm, struct iwl_host_cmd *cmd) * the mutex, this ensures we don't try to send two * (or more) synchronous commands at a time. */ - if (!(cmd->flags & CMD_ASYNC)) { + if (!(cmd->flags & CMD_ASYNC)) lockdep_assert_held(&mvm->mutex); - if (!(cmd->flags & CMD_SEND_IN_IDLE)) - iwl_mvm_ref(mvm, IWL_MVM_REF_SENDING_CMD); - } ret = iwl_trans_send_cmd(mvm->trans, cmd); - if (!(cmd->flags & (CMD_ASYNC | CMD_SEND_IN_IDLE))) - iwl_mvm_unref(mvm, IWL_MVM_REF_SENDING_CMD); - /* * If the caller wants the SKB, then don't hide any problems, the * caller might access the response buffer which will be NULL if From 4d4183c45e677f28d1c8a956093658613ed7b97f Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 6 Jun 2019 10:41:17 +0300 Subject: [PATCH 14/80] iwlwifi: mvm: remove the tx defer for d0i3 This is not needed anymore Signed-off-by: Emmanuel Grumbach Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 45 +------------ drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 4 -- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 63 ------------------- 3 files changed, 1 insertion(+), 111 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index c17f769b3451..d0cd992bf532 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -742,42 +742,6 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) return ret; } -static bool iwl_mvm_defer_tx(struct iwl_mvm *mvm, - struct ieee80211_sta *sta, - struct sk_buff *skb) -{ - struct iwl_mvm_sta *mvmsta; - bool defer = false; - - /* - * double check the IN_D0I3 flag both before and after - * taking the spinlock, in order to prevent taking - * the spinlock when not needed. - */ - if (likely(!test_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status))) - return false; - - spin_lock(&mvm->d0i3_tx_lock); - /* - * testing the flag again ensures the skb dequeue - * loop (on d0i3 exit) hasn't run yet. - */ - if (!test_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status)) - goto out; - - mvmsta = iwl_mvm_sta_from_mac80211(sta); - if (mvmsta->sta_id == IWL_MVM_INVALID_STA || - mvmsta->sta_id != mvm->d0i3_ap_sta_id) - goto out; - - __skb_queue_tail(&mvm->d0i3_tx, skb); - - defer = true; -out: - spin_unlock(&mvm->d0i3_tx_lock); - return defer; -} - static void iwl_mvm_mac_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, struct sk_buff *skb) @@ -822,8 +786,6 @@ static void iwl_mvm_mac_tx(struct ieee80211_hw *hw, } if (sta) { - if (iwl_mvm_defer_tx(mvm, sta, skb)) - return; if (iwl_mvm_tx_skb(mvm, skb, sta)) goto drop; return; @@ -1156,9 +1118,6 @@ int __iwl_mvm_mac_start(struct iwl_mvm *mvm) * would do. */ clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status); -#ifdef CONFIG_PM - iwl_mvm_d0i3_enable_tx(mvm, NULL); -#endif } return ret; @@ -1196,9 +1155,7 @@ static void iwl_mvm_restart_complete(struct iwl_mvm *mvm) mutex_lock(&mvm->mutex); clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status); -#ifdef CONFIG_PM - iwl_mvm_d0i3_enable_tx(mvm, NULL); -#endif + ret = iwl_mvm_update_quotas(mvm, true, NULL); if (ret) IWL_ERR(mvm, "Failed to update quotas after restart (%d)\n", diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 245e8c721102..6a79b6c49cd5 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -1019,12 +1019,9 @@ struct iwl_mvm { u8 d0i3_ap_sta_id; bool d0i3_offloading; struct work_struct d0i3_exit_work; - struct sk_buff_head d0i3_tx; /* protect d0i3_suspend_flags */ struct mutex d0i3_suspend_mutex; unsigned long d0i3_suspend_flags; - /* sync d0i3_tx queue and IWL_MVM_STATUS_IN_D0I3 status flag */ - spinlock_t d0i3_tx_lock; wait_queue_head_t d0i3_exit_waitq; wait_queue_head_t rx_sync_waitq; @@ -1861,7 +1858,6 @@ int iwl_mvm_send_proto_offload(struct iwl_mvm *mvm, u32 cmd_flags); #ifdef CONFIG_PM -void iwl_mvm_d0i3_enable_tx(struct iwl_mvm *mvm, __le16 *qos_seq); int iwl_mvm_enter_d0i3(struct iwl_op_mode *op_mode); int iwl_mvm_exit_d0i3(struct iwl_op_mode *op_mode); int _iwl_mvm_exit_d0i3(struct iwl_mvm *mvm); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 255b402f7b19..e9b0aee38f35 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -713,8 +713,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, INIT_WORK(&mvm->add_stream_wk, iwl_mvm_add_new_dqa_stream_wk); INIT_LIST_HEAD(&mvm->add_stream_txqs); - spin_lock_init(&mvm->d0i3_tx_lock); - skb_queue_head_init(&mvm->d0i3_tx); init_waitqueue_head(&mvm->d0i3_exit_waitq); init_waitqueue_head(&mvm->rx_sync_waitq); @@ -1590,62 +1588,6 @@ static void iwl_mvm_d0i3_exit_work_iter(void *_data, u8 *mac, iwl_mvm_d0i3_update_keys(data->mvm, vif, data->status); } -void iwl_mvm_d0i3_enable_tx(struct iwl_mvm *mvm, __le16 *qos_seq) -{ - struct ieee80211_sta *sta = NULL; - struct iwl_mvm_sta *mvm_ap_sta; - int i; - bool wake_queues = false; - - lockdep_assert_held(&mvm->mutex); - - spin_lock_bh(&mvm->d0i3_tx_lock); - - if (mvm->d0i3_ap_sta_id == IWL_MVM_INVALID_STA) - goto out; - - IWL_DEBUG_RPM(mvm, "re-enqueue packets\n"); - - /* get the sta in order to update seq numbers and re-enqueue skbs */ - sta = rcu_dereference_protected( - mvm->fw_id_to_mac_id[mvm->d0i3_ap_sta_id], - lockdep_is_held(&mvm->mutex)); - - if (IS_ERR_OR_NULL(sta)) { - sta = NULL; - goto out; - } - - if (mvm->d0i3_offloading && qos_seq) { - /* update qos seq numbers if offloading was enabled */ - mvm_ap_sta = iwl_mvm_sta_from_mac80211(sta); - for (i = 0; i < IWL_MAX_TID_COUNT; i++) { - u16 seq = le16_to_cpu(qos_seq[i]); - /* firmware stores last-used one, we store next one */ - seq += 0x10; - mvm_ap_sta->tid_data[i].seq_number = seq; - } - } -out: - /* re-enqueue (or drop) all packets */ - while (!skb_queue_empty(&mvm->d0i3_tx)) { - struct sk_buff *skb = __skb_dequeue(&mvm->d0i3_tx); - - if (!sta || iwl_mvm_tx_skb(mvm, skb, sta)) - ieee80211_free_txskb(mvm->hw, skb); - - /* if the skb_queue is not empty, we need to wake queues */ - wake_queues = true; - } - clear_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status); - wake_up(&mvm->d0i3_exit_waitq); - mvm->d0i3_ap_sta_id = IWL_MVM_INVALID_STA; - if (wake_queues) - ieee80211_wake_queues(mvm->hw); - - spin_unlock_bh(&mvm->d0i3_tx_lock); -} - static void iwl_mvm_d0i3_exit_work(struct work_struct *wk) { struct iwl_mvm *mvm = container_of(wk, struct iwl_mvm, d0i3_exit_work); @@ -1655,7 +1597,6 @@ static void iwl_mvm_d0i3_exit_work(struct work_struct *wk) struct iwl_wowlan_status *status; u32 wakeup_reasons = 0; - __le16 *qos_seq = NULL; mutex_lock(&mvm->mutex); @@ -1667,7 +1608,6 @@ static void iwl_mvm_d0i3_exit_work(struct work_struct *wk) } wakeup_reasons = le32_to_cpu(status->wakeup_reasons); - qos_seq = status->qos_seq_ctr; IWL_DEBUG_RPM(mvm, "wakeup reasons: 0x%x\n", wakeup_reasons); @@ -1678,12 +1618,9 @@ static void iwl_mvm_d0i3_exit_work(struct work_struct *wk) iwl_mvm_d0i3_exit_work_iter, &iter_data); out: - iwl_mvm_d0i3_enable_tx(mvm, qos_seq); - IWL_DEBUG_INFO(mvm, "d0i3 exit completed (wakeup reasons: 0x%x)\n", wakeup_reasons); - /* qos_seq might point inside resp_pkt, so free it only now */ kfree(status); /* the FW might have updated the regdomain */ From 45745363336ebc99424668ddf9e927f83b2d828f Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 6 Jun 2019 10:47:33 +0300 Subject: [PATCH 15/80] iwlwifi: mvm: remove the d0i3 entry/exit flow Signed-off-by: Emmanuel Grumbach Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 111 +----- .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 14 - drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 35 +- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 350 ------------------ 4 files changed, 2 insertions(+), 508 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index 7493cae70ea6..2ddc6cc56d1d 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -1118,37 +1118,12 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, return ret; } -static int iwl_mvm_enter_d0i3_sync(struct iwl_mvm *mvm) -{ - struct iwl_notification_wait wait_d3; - static const u16 d3_notif[] = { D3_CONFIG_CMD }; - int ret; - - iwl_init_notification_wait(&mvm->notif_wait, &wait_d3, - d3_notif, ARRAY_SIZE(d3_notif), - NULL, NULL); - - ret = iwl_mvm_enter_d0i3(mvm->hw->priv); - if (ret) - goto remove_notif; - - ret = iwl_wait_notification(&mvm->notif_wait, &wait_d3, HZ); - WARN_ON_ONCE(ret); - return ret; - -remove_notif: - iwl_remove_notification(&mvm->notif_wait, &wait_d3); - return ret; -} - int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) { struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); struct iwl_trans *trans = mvm->trans; int ret; - /* make sure the d0i3 exit work is not pending */ - flush_work(&mvm->d0i3_exit_work); iwl_mvm_pause_tcm(mvm, true); iwl_fw_runtime_suspend(&mvm->fwrt); @@ -1157,25 +1132,6 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) if (ret) return ret; - if (wowlan->any) { - trans->system_pm_mode = IWL_PLAT_PM_MODE_D0I3; - - if (iwl_mvm_enter_d0i3_on_suspend(mvm)) { - ret = iwl_mvm_enter_d0i3_sync(mvm); - - if (ret) - return ret; - } - - mutex_lock(&mvm->d0i3_suspend_mutex); - __set_bit(D0I3_DEFER_WAKEUP, &mvm->d0i3_suspend_flags); - mutex_unlock(&mvm->d0i3_suspend_mutex); - - iwl_trans_d3_suspend(trans, false, false); - - return 0; - } - trans->system_pm_mode = IWL_PLAT_PM_MODE_D3; return __iwl_mvm_suspend(hw, wowlan, false); @@ -1751,30 +1707,6 @@ static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm, return false; } -void iwl_mvm_d0i3_update_keys(struct iwl_mvm *mvm, - struct ieee80211_vif *vif, - struct iwl_wowlan_status *status) -{ - struct iwl_mvm_d3_gtk_iter_data gtkdata = { - .mvm = mvm, - .status = status, - }; - - /* - * rekey handling requires taking locks that can't be taken now. - * however, d0i3 doesn't offload rekey, so we're fine. - */ - if (WARN_ON_ONCE(status->num_of_gtk_rekeys)) - return; - - /* find last GTK that we used initially, if any */ - gtkdata.find_phase = true; - iwl_mvm_iter_d0i3_ap_keys(mvm, vif, iwl_mvm_d3_update_keys, >kdata); - - gtkdata.find_phase = false; - iwl_mvm_iter_d0i3_ap_keys(mvm, vif, iwl_mvm_d3_update_keys, >kdata); -} - #define ND_QUERY_BUF_LEN (sizeof(struct iwl_scan_offload_profile_match) * \ IWL_SCAN_MAX_PROFILES) @@ -2125,53 +2057,12 @@ static int iwl_mvm_resume_d3(struct iwl_mvm *mvm) return __iwl_mvm_resume(mvm, false); } -static int iwl_mvm_resume_d0i3(struct iwl_mvm *mvm) -{ - bool exit_now; - enum iwl_d3_status d3_status; - struct iwl_trans *trans = mvm->trans; - - iwl_trans_d3_resume(trans, &d3_status, false, false); - - /* - * make sure to clear D0I3_DEFER_WAKEUP before - * calling iwl_trans_resume(), which might wait - * for d0i3 exit completion. - */ - mutex_lock(&mvm->d0i3_suspend_mutex); - __clear_bit(D0I3_DEFER_WAKEUP, &mvm->d0i3_suspend_flags); - exit_now = __test_and_clear_bit(D0I3_PENDING_WAKEUP, - &mvm->d0i3_suspend_flags); - mutex_unlock(&mvm->d0i3_suspend_mutex); - if (exit_now) { - IWL_DEBUG_RPM(mvm, "Run deferred d0i3 exit\n"); - _iwl_mvm_exit_d0i3(mvm); - } - - iwl_trans_resume(trans); - - if (iwl_mvm_enter_d0i3_on_suspend(mvm)) { - int ret = iwl_mvm_exit_d0i3(mvm->hw->priv); - - if (ret) - return ret; - /* - * d0i3 exit will be deferred until reconfig_complete. - * make sure there we are out of d0i3. - */ - } - return 0; -} - int iwl_mvm_resume(struct ieee80211_hw *hw) { struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); int ret; - if (mvm->trans->system_pm_mode == IWL_PLAT_PM_MODE_D0I3) - ret = iwl_mvm_resume_d0i3(mvm); - else - ret = iwl_mvm_resume_d3(mvm); + ret = iwl_mvm_resume_d3(mvm); mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index d0cd992bf532..394662cdd700 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -1128,19 +1128,6 @@ static int iwl_mvm_mac_start(struct ieee80211_hw *hw) struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); int ret; - /* Some hw restart cleanups must not hold the mutex */ - if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) { - /* - * Make sure we are out of d0i3. This is needed - * to make sure the reference accounting is correct - * (and there is no stale d0i3_exit_work). - */ - wait_event_timeout(mvm->d0i3_exit_waitq, - !test_bit(IWL_MVM_STATUS_IN_D0I3, - &mvm->status), - HZ); - } - mutex_lock(&mvm->mutex); ret = __iwl_mvm_mac_start(mvm); mutex_unlock(&mvm->mutex); @@ -1244,7 +1231,6 @@ static void iwl_mvm_mac_stop(struct ieee80211_hw *hw) { struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); - flush_work(&mvm->d0i3_exit_work); flush_work(&mvm->async_handlers_wk); flush_work(&mvm->add_stream_wk); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 6a79b6c49cd5..2cf5d31ad3ed 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -1017,12 +1017,7 @@ struct iwl_mvm { /* d0i3 */ u8 d0i3_ap_sta_id; - bool d0i3_offloading; - struct work_struct d0i3_exit_work; - /* protect d0i3_suspend_flags */ - struct mutex d0i3_suspend_mutex; - unsigned long d0i3_suspend_flags; - wait_queue_head_t d0i3_exit_waitq; + wait_queue_head_t rx_sync_waitq; /* BT-Coex */ @@ -1290,19 +1285,6 @@ static inline bool iwl_mvm_is_short_beacon_notif_supported(struct iwl_mvm *mvm) IWL_UCODE_TLV_API_SHORT_BEACON_NOTIF); } -static inline bool iwl_mvm_enter_d0i3_on_suspend(struct iwl_mvm *mvm) -{ - /* For now we only use this mode to differentiate between - * slave transports, which handle D0i3 entry in suspend by - * themselves in conjunction with runtime PM D0i3. So, this - * function is used to check whether we need to do anything - * when entering suspend or if the transport layer has already - * done it. - */ - return (mvm->trans->system_pm_mode == IWL_PLAT_PM_MODE_D0I3) && - (mvm->trans->runtime_pm_mode != IWL_PLAT_PM_MODE_D0I3); -} - static inline bool iwl_mvm_is_dqa_data_queue(struct iwl_mvm *mvm, u8 queue) { return (queue >= IWL_MVM_DQA_MIN_DATA_QUEUE) && @@ -1824,9 +1806,6 @@ int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm, struct ieee80211_vif *vif, bool host_awake, u32 cmd_flags); -void iwl_mvm_d0i3_update_keys(struct iwl_mvm *mvm, - struct ieee80211_vif *vif, - struct iwl_wowlan_status *status); void iwl_mvm_set_last_nonqos_seq(struct iwl_mvm *mvm, struct ieee80211_vif *vif); #else @@ -1838,12 +1817,6 @@ static inline int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm, return 0; } -static inline void iwl_mvm_d0i3_update_keys(struct iwl_mvm *mvm, - struct ieee80211_vif *vif, - struct iwl_wowlan_status *status) -{ -} - static inline void iwl_mvm_set_last_nonqos_seq(struct iwl_mvm *mvm, struct ieee80211_vif *vif) { @@ -1857,12 +1830,6 @@ int iwl_mvm_send_proto_offload(struct iwl_mvm *mvm, bool offload_ns, u32 cmd_flags); -#ifdef CONFIG_PM -int iwl_mvm_enter_d0i3(struct iwl_op_mode *op_mode); -int iwl_mvm_exit_d0i3(struct iwl_op_mode *op_mode); -int _iwl_mvm_exit_d0i3(struct iwl_mvm *mvm); -#endif - /* BT Coex */ int iwl_mvm_send_bt_init_conf(struct iwl_mvm *mvm); void iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index e9b0aee38f35..efd694fd8b79 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -516,9 +516,6 @@ static const struct iwl_hcmd_arr iwl_mvm_groups[] = { /* this forward declaration can avoid to export the function */ static void iwl_mvm_async_handlers_wk(struct work_struct *wk); -#ifdef CONFIG_PM -static void iwl_mvm_d0i3_exit_work(struct work_struct *wk); -#endif static u32 iwl_mvm_min_backoff(struct iwl_mvm *mvm) { @@ -695,7 +692,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, mvm->drop_bcn_ap_mode = true; mutex_init(&mvm->mutex); - mutex_init(&mvm->d0i3_suspend_mutex); spin_lock_init(&mvm->async_handlers_lock); INIT_LIST_HEAD(&mvm->time_event_list); INIT_LIST_HEAD(&mvm->aux_roc_te_list); @@ -705,15 +701,11 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, INIT_WORK(&mvm->async_handlers_wk, iwl_mvm_async_handlers_wk); INIT_WORK(&mvm->roc_done_wk, iwl_mvm_roc_done_wk); -#ifdef CONFIG_PM - INIT_WORK(&mvm->d0i3_exit_work, iwl_mvm_d0i3_exit_work); -#endif INIT_DELAYED_WORK(&mvm->tdls_cs.dwork, iwl_mvm_tdls_ch_switch_work); INIT_DELAYED_WORK(&mvm->scan_timeout_dwork, iwl_mvm_scan_timeout_wk); INIT_WORK(&mvm->add_stream_wk, iwl_mvm_add_new_dqa_stream_wk); INIT_LIST_HEAD(&mvm->add_stream_txqs); - init_waitqueue_head(&mvm->d0i3_exit_waitq); init_waitqueue_head(&mvm->rx_sync_waitq); atomic_set(&mvm->queue_sync_counter, 0); @@ -909,7 +901,6 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode) iwl_fw_runtime_free(&mvm->fwrt); mutex_destroy(&mvm->mutex); - mutex_destroy(&mvm->d0i3_suspend_mutex); ieee80211_free_hw(mvm->hw); } @@ -1337,346 +1328,6 @@ static void iwl_mvm_cmd_queue_full(struct iwl_op_mode *op_mode) iwl_mvm_nic_restart(mvm, true); } -#ifdef CONFIG_PM -struct iwl_d0i3_iter_data { - struct iwl_mvm *mvm; - struct ieee80211_vif *connected_vif; - u8 ap_sta_id; - u8 vif_count; - u8 offloading_tid; - bool disable_offloading; -}; - -static bool iwl_mvm_disallow_offloading(struct iwl_mvm *mvm, - struct ieee80211_vif *vif, - struct iwl_d0i3_iter_data *iter_data) -{ - struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); - struct iwl_mvm_sta *mvmsta; - u32 available_tids = 0; - u8 tid; - - if (WARN_ON(vif->type != NL80211_IFTYPE_STATION || - mvmvif->ap_sta_id == IWL_MVM_INVALID_STA)) - return false; - - mvmsta = iwl_mvm_sta_from_staid_rcu(mvm, mvmvif->ap_sta_id); - if (!mvmsta) - return false; - - spin_lock_bh(&mvmsta->lock); - for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) { - struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid]; - - /* - * in case of pending tx packets, don't use this tid - * for offloading in order to prevent reuse of the same - * qos seq counters. - */ - if (iwl_mvm_tid_queued(mvm, tid_data)) - continue; - - if (tid_data->state != IWL_AGG_OFF) - continue; - - available_tids |= BIT(tid); - } - spin_unlock_bh(&mvmsta->lock); - - /* - * disallow protocol offloading if we have no available tid - * (with no pending frames and no active aggregation, - * as we don't handle "holes" properly - the scheduler needs the - * frame's seq number and TFD index to match) - */ - if (!available_tids) - return true; - - /* for simplicity, just use the first available tid */ - iter_data->offloading_tid = ffs(available_tids) - 1; - return false; -} - -static void iwl_mvm_enter_d0i3_iterator(void *_data, u8 *mac, - struct ieee80211_vif *vif) -{ - struct iwl_d0i3_iter_data *data = _data; - struct iwl_mvm *mvm = data->mvm; - struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); - u32 flags = CMD_ASYNC | CMD_HIGH_PRIO | CMD_SEND_IN_IDLE; - - IWL_DEBUG_RPM(mvm, "entering D0i3 - vif %pM\n", vif->addr); - if (vif->type != NL80211_IFTYPE_STATION || - !vif->bss_conf.assoc) - return; - - /* - * in case of pending tx packets or active aggregations, - * avoid offloading features in order to prevent reuse of - * the same qos seq counters. - */ - if (iwl_mvm_disallow_offloading(mvm, vif, data)) - data->disable_offloading = true; - - iwl_mvm_update_d0i3_power_mode(mvm, vif, true, flags); - iwl_mvm_send_proto_offload(mvm, vif, data->disable_offloading, - false, flags); - - /* - * on init/association, mvm already configures POWER_TABLE_CMD - * and REPLY_MCAST_FILTER_CMD, so currently don't - * reconfigure them (we might want to use different - * params later on, though). - */ - data->ap_sta_id = mvmvif->ap_sta_id; - data->vif_count++; - - /* - * no new commands can be sent at this stage, so it's safe - * to save the vif pointer during d0i3 entrance. - */ - data->connected_vif = vif; -} - -static void iwl_mvm_set_wowlan_data(struct iwl_mvm *mvm, - struct iwl_wowlan_config_cmd *cmd, - struct iwl_d0i3_iter_data *iter_data) -{ - struct ieee80211_sta *ap_sta; - struct iwl_mvm_sta *mvm_ap_sta; - - if (iter_data->ap_sta_id == IWL_MVM_INVALID_STA) - return; - - rcu_read_lock(); - - ap_sta = rcu_dereference(mvm->fw_id_to_mac_id[iter_data->ap_sta_id]); - if (IS_ERR_OR_NULL(ap_sta)) - goto out; - - mvm_ap_sta = iwl_mvm_sta_from_mac80211(ap_sta); - cmd->is_11n_connection = ap_sta->ht_cap.ht_supported; - cmd->offloading_tid = iter_data->offloading_tid; - cmd->flags = ENABLE_L3_FILTERING | ENABLE_NBNS_FILTERING | - ENABLE_DHCP_FILTERING | ENABLE_STORE_BEACON; - /* - * The d0i3 uCode takes care of the nonqos counters, - * so configure only the qos seq ones. - */ - iwl_mvm_set_wowlan_qos_seq(mvm_ap_sta, cmd); -out: - rcu_read_unlock(); -} - -int iwl_mvm_enter_d0i3(struct iwl_op_mode *op_mode) -{ - struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); - u32 flags = CMD_ASYNC | CMD_HIGH_PRIO | CMD_SEND_IN_IDLE; - int ret; - struct iwl_d0i3_iter_data d0i3_iter_data = { - .mvm = mvm, - }; - struct iwl_wowlan_config_cmd wowlan_config_cmd = { - .wakeup_filter = cpu_to_le32(IWL_WOWLAN_WAKEUP_RX_FRAME | - IWL_WOWLAN_WAKEUP_BEACON_MISS | - IWL_WOWLAN_WAKEUP_LINK_CHANGE), - }; - struct iwl_d3_manager_config d3_cfg_cmd = { - .min_sleep_time = cpu_to_le32(1000), - .wakeup_flags = cpu_to_le32(IWL_WAKEUP_D3_CONFIG_FW_ERROR), - }; - - IWL_DEBUG_RPM(mvm, "MVM entering D0i3\n"); - - if (WARN_ON_ONCE(mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR)) - return -EINVAL; - - set_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status); - - ieee80211_iterate_active_interfaces_atomic(mvm->hw, - IEEE80211_IFACE_ITER_NORMAL, - iwl_mvm_enter_d0i3_iterator, - &d0i3_iter_data); - if (d0i3_iter_data.vif_count == 1) { - mvm->d0i3_ap_sta_id = d0i3_iter_data.ap_sta_id; - mvm->d0i3_offloading = !d0i3_iter_data.disable_offloading; - } else { - WARN_ON_ONCE(d0i3_iter_data.vif_count > 1); - mvm->d0i3_ap_sta_id = IWL_MVM_INVALID_STA; - mvm->d0i3_offloading = false; - } - - iwl_mvm_pause_tcm(mvm, true); - /* make sure we have no running tx while configuring the seqno */ - synchronize_net(); - - /* Flush the hw queues, in case something got queued during entry */ - /* TODO new tx api */ - if (iwl_mvm_has_new_tx_api(mvm)) { - WARN_ONCE(1, "d0i3: Need to implement flush TX queue\n"); - } else { - ret = iwl_mvm_flush_tx_path(mvm, iwl_mvm_flushable_queues(mvm), - flags); - if (ret) - return ret; - } - - /* configure wowlan configuration only if needed */ - if (mvm->d0i3_ap_sta_id != IWL_MVM_INVALID_STA) { - /* wake on beacons only if beacon storing isn't supported */ - if (!fw_has_capa(&mvm->fw->ucode_capa, - IWL_UCODE_TLV_CAPA_BEACON_STORING)) - wowlan_config_cmd.wakeup_filter |= - cpu_to_le32(IWL_WOWLAN_WAKEUP_BCN_FILTERING); - - iwl_mvm_wowlan_config_key_params(mvm, - d0i3_iter_data.connected_vif, - true, flags); - - iwl_mvm_set_wowlan_data(mvm, &wowlan_config_cmd, - &d0i3_iter_data); - - ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_CONFIGURATION, flags, - sizeof(wowlan_config_cmd), - &wowlan_config_cmd); - if (ret) - return ret; - } - - return iwl_mvm_send_cmd_pdu(mvm, D3_CONFIG_CMD, - flags | CMD_MAKE_TRANS_IDLE, - sizeof(d3_cfg_cmd), &d3_cfg_cmd); -} - -static void iwl_mvm_exit_d0i3_iterator(void *_data, u8 *mac, - struct ieee80211_vif *vif) -{ - struct iwl_mvm *mvm = _data; - u32 flags = CMD_ASYNC | CMD_HIGH_PRIO; - - IWL_DEBUG_RPM(mvm, "exiting D0i3 - vif %pM\n", vif->addr); - if (vif->type != NL80211_IFTYPE_STATION || - !vif->bss_conf.assoc) - return; - - iwl_mvm_update_d0i3_power_mode(mvm, vif, false, flags); -} - -struct iwl_mvm_d0i3_exit_work_iter_data { - struct iwl_mvm *mvm; - struct iwl_wowlan_status *status; - u32 wakeup_reasons; -}; - -static void iwl_mvm_d0i3_exit_work_iter(void *_data, u8 *mac, - struct ieee80211_vif *vif) -{ - struct iwl_mvm_d0i3_exit_work_iter_data *data = _data; - struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); - u32 reasons = data->wakeup_reasons; - - /* consider only the relevant station interface */ - if (vif->type != NL80211_IFTYPE_STATION || !vif->bss_conf.assoc || - data->mvm->d0i3_ap_sta_id != mvmvif->ap_sta_id) - return; - - if (reasons & IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH) - iwl_mvm_connection_loss(data->mvm, vif, "D0i3"); - else if (reasons & IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON) - ieee80211_beacon_loss(vif); - else - iwl_mvm_d0i3_update_keys(data->mvm, vif, data->status); -} - -static void iwl_mvm_d0i3_exit_work(struct work_struct *wk) -{ - struct iwl_mvm *mvm = container_of(wk, struct iwl_mvm, d0i3_exit_work); - struct iwl_mvm_d0i3_exit_work_iter_data iter_data = { - .mvm = mvm, - }; - - struct iwl_wowlan_status *status; - u32 wakeup_reasons = 0; - - mutex_lock(&mvm->mutex); - - status = iwl_mvm_send_wowlan_get_status(mvm); - if (IS_ERR_OR_NULL(status)) { - /* set to NULL so we don't need to check before kfree'ing */ - status = NULL; - goto out; - } - - wakeup_reasons = le32_to_cpu(status->wakeup_reasons); - - IWL_DEBUG_RPM(mvm, "wakeup reasons: 0x%x\n", wakeup_reasons); - - iter_data.wakeup_reasons = wakeup_reasons; - iter_data.status = status; - ieee80211_iterate_active_interfaces(mvm->hw, - IEEE80211_IFACE_ITER_NORMAL, - iwl_mvm_d0i3_exit_work_iter, - &iter_data); -out: - IWL_DEBUG_INFO(mvm, "d0i3 exit completed (wakeup reasons: 0x%x)\n", - wakeup_reasons); - - kfree(status); - - /* the FW might have updated the regdomain */ - iwl_mvm_update_changed_regdom(mvm); - - iwl_mvm_resume_tcm(mvm); - mutex_unlock(&mvm->mutex); -} - -int _iwl_mvm_exit_d0i3(struct iwl_mvm *mvm) -{ - u32 flags = CMD_ASYNC | CMD_HIGH_PRIO | CMD_SEND_IN_IDLE | - CMD_WAKE_UP_TRANS; - int ret; - - IWL_DEBUG_RPM(mvm, "MVM exiting D0i3\n"); - - if (WARN_ON_ONCE(mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR)) - return -EINVAL; - - mutex_lock(&mvm->d0i3_suspend_mutex); - if (test_bit(D0I3_DEFER_WAKEUP, &mvm->d0i3_suspend_flags)) { - IWL_DEBUG_RPM(mvm, "Deferring d0i3 exit until resume\n"); - __set_bit(D0I3_PENDING_WAKEUP, &mvm->d0i3_suspend_flags); - mutex_unlock(&mvm->d0i3_suspend_mutex); - return 0; - } - mutex_unlock(&mvm->d0i3_suspend_mutex); - - ret = iwl_mvm_send_cmd_pdu(mvm, D0I3_END_CMD, flags, 0, NULL); - if (ret) - goto out; - - ieee80211_iterate_active_interfaces_atomic(mvm->hw, - IEEE80211_IFACE_ITER_NORMAL, - iwl_mvm_exit_d0i3_iterator, - mvm); -out: - schedule_work(&mvm->d0i3_exit_work); - return ret; -} - -int iwl_mvm_exit_d0i3(struct iwl_op_mode *op_mode) -{ - struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); - - return _iwl_mvm_exit_d0i3(mvm); -} - -#define IWL_MVM_D0I3_OPS \ - .enter_d0i3 = iwl_mvm_enter_d0i3, \ - .exit_d0i3 = iwl_mvm_exit_d0i3, -#else /* CONFIG_PM */ -#define IWL_MVM_D0I3_OPS -#endif /* CONFIG_PM */ - #define IWL_MVM_COMMON_OPS \ /* these could be differentiated */ \ .async_cb = iwl_mvm_async_cb, \ @@ -1687,7 +1338,6 @@ int iwl_mvm_exit_d0i3(struct iwl_op_mode *op_mode) .nic_error = iwl_mvm_nic_error, \ .cmd_queue_full = iwl_mvm_cmd_queue_full, \ .nic_config = iwl_mvm_nic_config, \ - IWL_MVM_D0I3_OPS \ /* as we only register one, these MUST be common! */ \ .start = iwl_op_mode_mvm_start, \ .stop = iwl_op_mode_mvm_stop From 0ea933880a5f86b1416b3a99ed8a97c93a6f1fe4 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 6 Jun 2019 10:58:46 +0300 Subject: [PATCH 16/80] iwlwifi: mvm: iwl_mvm_wowlan_config_key_params is for wowlan only Now that d0i3 is dead, this function can't be called from d0i3 flows. Change its signature and make it static. Signed-off-by: Emmanuel Grumbach Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 64 +++++--------------- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 12 ---- 2 files changed, 15 insertions(+), 61 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index 2ddc6cc56d1d..89839a83d8c2 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -735,40 +735,16 @@ iwl_mvm_get_wowlan_config(struct iwl_mvm *mvm, return 0; } -static void -iwl_mvm_iter_d0i3_ap_keys(struct iwl_mvm *mvm, - struct ieee80211_vif *vif, - void (*iter)(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta, - struct ieee80211_key_conf *key, - void *data), - void *data) -{ - struct ieee80211_sta *ap_sta; - - rcu_read_lock(); - - ap_sta = rcu_dereference(mvm->fw_id_to_mac_id[mvm->d0i3_ap_sta_id]); - if (IS_ERR_OR_NULL(ap_sta)) - goto out; - - ieee80211_iter_keys_rcu(mvm->hw, vif, iter, data); -out: - rcu_read_unlock(); -} - -int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm, - struct ieee80211_vif *vif, - bool d0i3, - u32 cmd_flags) +static int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm, + struct ieee80211_vif *vif, + u32 cmd_flags) { struct iwl_wowlan_kek_kck_material_cmd kek_kck_cmd = {}; struct iwl_wowlan_tkip_params_cmd tkip_cmd = {}; bool unified = fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG); struct wowlan_key_data key_data = { - .configure_keys = !d0i3 && !unified, + .configure_keys = !unified, .use_rsc_tsc = false, .tkip = &tkip_cmd, .use_tkip = false, @@ -784,25 +760,16 @@ int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm, * if we have to configure keys, call ieee80211_iter_keys(), * as we need non-atomic context in order to take the * required locks. - * for the d0i3 we can't use ieee80211_iter_keys(), as - * taking (almost) any mutex might result in deadlock. */ - if (!d0i3) { - /* - * Note that currently we don't propagate cmd_flags - * to the iterator. In case of key_data.configure_keys, - * all the configured commands are SYNC, and - * iwl_mvm_wowlan_program_keys() will take care of - * locking/unlocking mvm->mutex. - */ - ieee80211_iter_keys(mvm->hw, vif, - iwl_mvm_wowlan_program_keys, - &key_data); - } else { - iwl_mvm_iter_d0i3_ap_keys(mvm, vif, - iwl_mvm_wowlan_program_keys, - &key_data); - } + /* + * Note that currently we don't propagate cmd_flags + * to the iterator. In case of key_data.configure_keys, + * all the configured commands are SYNC, and + * iwl_mvm_wowlan_program_keys() will take care of + * locking/unlocking mvm->mutex. + */ + ieee80211_iter_keys(mvm->hw, vif, iwl_mvm_wowlan_program_keys, + &key_data); if (key_data.error) { ret = -EIO; @@ -830,7 +797,7 @@ int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm, } /* configure rekey data only if offloaded rekey is supported (d3) */ - if (mvmvif->rekey_data.valid && !d0i3) { + if (mvmvif->rekey_data.valid) { memset(&kek_kck_cmd, 0, sizeof(kek_kck_cmd)); memcpy(kek_kck_cmd.kck, mvmvif->rekey_data.kck, NL80211_KCK_LEN); @@ -881,8 +848,7 @@ iwl_mvm_wowlan_config(struct iwl_mvm *mvm, * that isn't really a problem though. */ mutex_unlock(&mvm->mutex); - ret = iwl_mvm_wowlan_config_key_params(mvm, vif, false, - CMD_ASYNC); + ret = iwl_mvm_wowlan_config_key_params(mvm, vif, CMD_ASYNC); mutex_lock(&mvm->mutex); if (ret) return ret; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 2cf5d31ad3ed..03f3faa02781 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -1802,21 +1802,9 @@ void iwl_mvm_set_default_unicast_key(struct ieee80211_hw *hw, extern const struct file_operations iwl_dbgfs_d3_test_ops; struct iwl_wowlan_status *iwl_mvm_send_wowlan_get_status(struct iwl_mvm *mvm); #ifdef CONFIG_PM -int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm, - struct ieee80211_vif *vif, - bool host_awake, - u32 cmd_flags); void iwl_mvm_set_last_nonqos_seq(struct iwl_mvm *mvm, struct ieee80211_vif *vif); #else -static inline int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm, - struct ieee80211_vif *vif, - bool host_awake, - u32 cmd_flags) -{ - return 0; -} - static inline void iwl_mvm_set_last_nonqos_seq(struct iwl_mvm *mvm, struct ieee80211_vif *vif) { From 99970e4afbab55628cdc49ca602386f6a48b1d28 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 6 Jun 2019 11:00:09 +0300 Subject: [PATCH 17/80] iwlwifi: mvm: remove d0i3_ap_sta_id This variable read, but never set. Remove it. Signed-off-by: Emmanuel Grumbach Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 4 ---- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 3 --- drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 4 ---- 3 files changed, 11 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 394662cdd700..4ace2761a19d 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -1071,7 +1071,6 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm) ieee80211_iterate_interfaces(mvm->hw, 0, iwl_mvm_cleanup_iterator, mvm); mvm->p2p_device_vif = NULL; - mvm->d0i3_ap_sta_id = IWL_MVM_INVALID_STA; iwl_mvm_reset_phy_ctxts(mvm); memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table)); @@ -2335,9 +2334,6 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm, IWL_ERR(mvm, "failed to remove AP station\n"); - if (mvm->d0i3_ap_sta_id == mvmvif->ap_sta_id) - mvm->d0i3_ap_sta_id = - IWL_MVM_INVALID_STA; mvmvif->ap_sta_id = IWL_MVM_INVALID_STA; } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 03f3faa02781..4a9e8ae99cac 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -1015,9 +1015,6 @@ struct iwl_mvm { #endif #endif - /* d0i3 */ - u8 d0i3_ap_sta_id; - wait_queue_head_t rx_sync_waitq; /* BT-Coex */ diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c index 4fae0cb22195..b0f92c9b20f0 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c @@ -1887,10 +1887,6 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm, /* unassoc - go ahead - remove the AP STA now */ mvmvif->ap_sta_id = IWL_MVM_INVALID_STA; - - /* clear d0i3_ap_sta_id if no longer relevant */ - if (mvm->d0i3_ap_sta_id == sta_id) - mvm->d0i3_ap_sta_id = IWL_MVM_INVALID_STA; } /* From 632fa0eabc6666031629f6f9858155dc4e8ff0c7 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 6 Jun 2019 11:03:01 +0300 Subject: [PATCH 18/80] iwlwifi: mvm: remove iwl_mvm_update_d0i3_power_mode Also change the signature of the power functions that won't receive d0i3=true anymore. Signed-off-by: Emmanuel Grumbach Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 3 - .../net/wireless/intel/iwlwifi/mvm/power.c | 82 +++---------------- 2 files changed, 11 insertions(+), 74 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 4a9e8ae99cac..15780e994a30 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -1845,9 +1845,6 @@ iwl_mvm_beacon_filter_debugfs_parameters(struct ieee80211_vif *vif, struct iwl_beacon_filter_cmd *cmd) {} #endif -int iwl_mvm_update_d0i3_power_mode(struct iwl_mvm *mvm, - struct ieee80211_vif *vif, - bool enable, u32 flags); int iwl_mvm_enable_beacon_filter(struct iwl_mvm *mvm, struct ieee80211_vif *vif, u32 flags); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/power.c b/drivers/net/wireless/intel/iwlwifi/mvm/power.c index 36f5fa1ee793..22136e4832ea 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/power.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/power.c @@ -127,12 +127,11 @@ int iwl_mvm_beacon_filter_send_cmd(struct iwl_mvm *mvm, static void iwl_mvm_beacon_filter_set_cqm_params(struct iwl_mvm *mvm, struct ieee80211_vif *vif, - struct iwl_beacon_filter_cmd *cmd, - bool d0i3) + struct iwl_beacon_filter_cmd *cmd) { struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); - if (vif->bss_conf.cqm_rssi_thold && !d0i3) { + if (vif->bss_conf.cqm_rssi_thold) { cmd->bf_energy_delta = cpu_to_le32(vif->bss_conf.cqm_rssi_hyst); /* fw uses an absolute value for this */ @@ -849,8 +848,7 @@ iwl_mvm_beacon_filter_debugfs_parameters(struct ieee80211_vif *vif, static int _iwl_mvm_enable_beacon_filter(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct iwl_beacon_filter_cmd *cmd, - u32 cmd_flags, - bool d0i3) + u32 cmd_flags) { struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); int ret; @@ -859,13 +857,11 @@ static int _iwl_mvm_enable_beacon_filter(struct iwl_mvm *mvm, vif->type != NL80211_IFTYPE_STATION || vif->p2p) return 0; - iwl_mvm_beacon_filter_set_cqm_params(mvm, vif, cmd, d0i3); - if (!d0i3) - iwl_mvm_beacon_filter_debugfs_parameters(vif, cmd); + iwl_mvm_beacon_filter_set_cqm_params(mvm, vif, cmd); + iwl_mvm_beacon_filter_debugfs_parameters(vif, cmd); ret = iwl_mvm_beacon_filter_send_cmd(mvm, cmd, cmd_flags); - /* don't change bf_enabled in case of temporary d0i3 configuration */ - if (!ret && !d0i3) + if (!ret) mvmvif->bf_data.bf_enabled = true; return ret; @@ -880,12 +876,12 @@ int iwl_mvm_enable_beacon_filter(struct iwl_mvm *mvm, .bf_enable_beacon_filter = cpu_to_le32(1), }; - return _iwl_mvm_enable_beacon_filter(mvm, vif, &cmd, flags, false); + return _iwl_mvm_enable_beacon_filter(mvm, vif, &cmd, flags); } static int _iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm, struct ieee80211_vif *vif, - u32 flags, bool d0i3) + u32 flags) { struct iwl_beacon_filter_cmd cmd = {}; struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); @@ -896,8 +892,7 @@ static int _iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm, ret = iwl_mvm_beacon_filter_send_cmd(mvm, &cmd, flags); - /* don't change bf_enabled in case of temporary d0i3 configuration */ - if (!ret && !d0i3) + if (!ret) mvmvif->bf_data.bf_enabled = false; return ret; @@ -907,7 +902,7 @@ int iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm, struct ieee80211_vif *vif, u32 flags) { - return _iwl_mvm_disable_beacon_filter(mvm, vif, flags, false); + return _iwl_mvm_disable_beacon_filter(mvm, vif, flags); } static int iwl_mvm_power_set_ps(struct iwl_mvm *mvm) @@ -958,7 +953,7 @@ static int iwl_mvm_power_set_ba(struct iwl_mvm *mvm, !vif->bss_conf.ps || iwl_mvm_vif_low_latency(mvmvif)); - return _iwl_mvm_enable_beacon_filter(mvm, vif, &cmd, 0, false); + return _iwl_mvm_enable_beacon_filter(mvm, vif, &cmd, 0); } int iwl_mvm_power_update_ps(struct iwl_mvm *mvm) @@ -1022,58 +1017,3 @@ int iwl_mvm_power_update_mac(struct iwl_mvm *mvm) return 0; } - -int iwl_mvm_update_d0i3_power_mode(struct iwl_mvm *mvm, - struct ieee80211_vif *vif, - bool enable, u32 flags) -{ - int ret; - struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); - struct iwl_mac_power_cmd cmd = {}; - - if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) - return 0; - - if (!vif->bss_conf.assoc) - return 0; - - iwl_mvm_power_build_cmd(mvm, vif, &cmd, !enable); - - iwl_mvm_power_log(mvm, &cmd); -#ifdef CONFIG_IWLWIFI_DEBUGFS - memcpy(&mvmvif->mac_pwr_cmd, &cmd, sizeof(cmd)); -#endif - ret = iwl_mvm_send_cmd_pdu(mvm, MAC_PM_POWER_TABLE, flags, - sizeof(cmd), &cmd); - if (ret) - return ret; - - /* configure beacon filtering */ - if (mvmvif != mvm->bf_allowed_vif) - return 0; - - if (enable) { - struct iwl_beacon_filter_cmd cmd_bf = { - IWL_BF_CMD_CONFIG_D0I3, - .bf_enable_beacon_filter = cpu_to_le32(1), - }; - /* - * When beacon storing is supported - disable beacon filtering - * altogether - the latest beacon will be sent when exiting d0i3 - */ - if (fw_has_capa(&mvm->fw->ucode_capa, - IWL_UCODE_TLV_CAPA_BEACON_STORING)) - ret = _iwl_mvm_disable_beacon_filter(mvm, vif, flags, - true); - else - ret = _iwl_mvm_enable_beacon_filter(mvm, vif, &cmd_bf, - flags, true); - } else { - if (mvmvif->bf_data.bf_enabled) - ret = iwl_mvm_enable_beacon_filter(mvm, vif, flags); - else - ret = iwl_mvm_disable_beacon_filter(mvm, vif, flags); - } - - return ret; -} From 66cdca01e047742682ba54e926c7731b16e65486 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 6 Jun 2019 11:06:45 +0300 Subject: [PATCH 19/80] iwlwifi: mvm: remove last leftovers of d0i3 We're now left with a status bit that is never set and a few other leftovers. Signed-off-by: Emmanuel Grumbach Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 3 --- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 7 ------- drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 7 ------- 3 files changed, 17 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 4ace2761a19d..73302fe1c66d 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -1079,9 +1079,6 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm) ieee80211_wake_queues(mvm->hw); - /* clear any stale d0i3 state */ - clear_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status); - mvm->vif_count = 0; mvm->rx_ba_sessions = 0; mvm->fwrt.dump.conf = FW_DBG_INVALID; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 15780e994a30..ed52e2ea97d9 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -588,11 +588,6 @@ struct iwl_mvm_frame_stats { int last_frame_idx; }; -enum { - D0I3_DEFER_WAKEUP, - D0I3_PENDING_WAKEUP, -}; - #define IWL_MVM_DEBUG_SET_TEMPERATURE_DISABLE 0xff #define IWL_MVM_DEBUG_SET_TEMPERATURE_MIN -100 #define IWL_MVM_DEBUG_SET_TEMPERATURE_MAX 200 @@ -1157,7 +1152,6 @@ struct iwl_mvm { * @IWL_MVM_STATUS_ROC_RUNNING: remain-on-channel is running * @IWL_MVM_STATUS_HW_RESTART_REQUESTED: HW restart was requested * @IWL_MVM_STATUS_IN_HW_RESTART: HW restart is active - * @IWL_MVM_STATUS_IN_D0I3: NIC is in D0i3 * @IWL_MVM_STATUS_ROC_AUX_RUNNING: AUX remain-on-channel is running * @IWL_MVM_STATUS_FIRMWARE_RUNNING: firmware is running * @IWL_MVM_STATUS_NEED_FLUSH_P2P: need to flush P2P bcast STA @@ -1168,7 +1162,6 @@ enum iwl_mvm_status { IWL_MVM_STATUS_ROC_RUNNING, IWL_MVM_STATUS_HW_RESTART_REQUESTED, IWL_MVM_STATUS_IN_HW_RESTART, - IWL_MVM_STATUS_IN_D0I3, IWL_MVM_STATUS_ROC_AUX_RUNNING, IWL_MVM_STATUS_FIRMWARE_RUNNING, IWL_MVM_STATUS_NEED_FLUSH_P2P, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c index b0f92c9b20f0..aa0a2a3e0875 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c @@ -2759,13 +2759,6 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif, spin_lock_bh(&mvmsta->lock); - /* possible race condition - we entered D0i3 while starting agg */ - if (test_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status)) { - spin_unlock_bh(&mvmsta->lock); - IWL_ERR(mvm, "Entered D0i3 while starting Tx agg\n"); - return -EIO; - } - /* * Note the possible cases: * 1. An enabled TXQ - TXQ needs to become agg'ed From 1877fa3d5fb6a3537a9d147c3a404f7c97cd6c8a Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 6 Jun 2019 11:10:25 +0300 Subject: [PATCH 20/80] iwlwifi: remove CMD_HIGH_PRIO This flag is never set on any host command. Remove it. Signed-off-by: Emmanuel Grumbach Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/iwl-trans.h | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h index 0f8aeb111b0e..20251f5e6f41 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h @@ -159,9 +159,6 @@ static inline u32 iwl_rx_packet_payload_len(const struct iwl_rx_packet *pkt) * @CMD_ASYNC: Return right away and don't wait for the response * @CMD_WANT_SKB: Not valid with CMD_ASYNC. The caller needs the buffer of * the response. The caller needs to call iwl_free_resp when done. - * @CMD_HIGH_PRIO: The command is high priority - it goes to the front of the - * command queue, but after other high priority commands. Valid only - * with CMD_ASYNC. * @CMD_SEND_IN_IDLE: The command should be sent even when the trans is idle. * @CMD_MAKE_TRANS_IDLE: The command response should mark the trans as idle. * @CMD_WAKE_UP_TRANS: The command response should wake up the trans @@ -173,11 +170,10 @@ enum CMD_MODE { CMD_ASYNC = BIT(0), CMD_WANT_SKB = BIT(1), CMD_SEND_IN_RFKILL = BIT(2), - CMD_HIGH_PRIO = BIT(3), - CMD_SEND_IN_IDLE = BIT(4), - CMD_MAKE_TRANS_IDLE = BIT(5), - CMD_WAKE_UP_TRANS = BIT(6), - CMD_WANT_ASYNC_CALLBACK = BIT(7), + CMD_SEND_IN_IDLE = BIT(3), + CMD_MAKE_TRANS_IDLE = BIT(4), + CMD_WAKE_UP_TRANS = BIT(5), + CMD_WANT_ASYNC_CALLBACK = BIT(6), }; #define DEF_CMD_PAYLOAD_SIZE 320 From 3596ad2b3e87ba3dee0a7c74c1d90c9f31e5fdd8 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 6 Jun 2019 11:18:46 +0300 Subject: [PATCH 21/80] iwlwifi: trans: remove suspending flag This is set but never read. Signed-off-by: Emmanuel Grumbach Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/iwl-trans.h | 1 - drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 14 -------------- 2 files changed, 15 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h index 20251f5e6f41..942662eaf523 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h @@ -841,7 +841,6 @@ struct iwl_trans { enum iwl_plat_pm_mode system_pm_mode; enum iwl_plat_pm_mode runtime_pm_mode; - bool suspending; /* pointer to trans specific struct */ /*Ensure that this pointer will always be aligned to sizeof pointer */ diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index d9ed53b7c768..63a04cec32af 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -1314,12 +1314,6 @@ static int iwl_pci_system_prepare(struct device *device) IWL_DEBUG_RPM(trans, "preparing for system suspend\n"); - /* This is called before entering system suspend and before - * the runtime resume is called. Set the suspending flag to - * prevent the wakelock from being taken. - */ - trans->suspending = true; - /* Wake the device up from runtime suspend before going to * platform suspend. This is needed because we don't know * whether wowlan any is set and, if it's not, mac80211 will @@ -1336,14 +1330,6 @@ static void iwl_pci_system_complete(struct device *device) struct iwl_trans *trans = pci_get_drvdata(pdev); IWL_DEBUG_RPM(trans, "completing system suspend\n"); - - /* This is called as a counterpart to the prepare op. It is - * called either when suspending fails or when suspend - * completed successfully. Now there's no risk of grabbing - * the wakelock anymore, so we can release the suspending - * flag. - */ - trans->suspending = false; } #endif /* CONFIG_IWLWIFI_PCIE_RTPM */ From 24d2176d1778690eb15d203ae5ae37a7be9f3556 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 6 Jun 2019 11:22:16 +0300 Subject: [PATCH 22/80] iwlwifi: remove the code under IWLWIFI_PCIE_RTPM This flag should never be set unless integration work with the platform is done. We don't support any platforms officially and don't plan to do so in the near future, so we can remove this option entirely in order to avoid having it enabled by mistake. This has been marked with "depends on EXPERT", so there shouldn't be many systems running with it set. And, if there are systems, they should not be using this flag. Signed-off-by: Emmanuel Grumbach Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/Kconfig | 14 ---- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 71 ------------------- .../net/wireless/intel/iwlwifi/pcie/trans.c | 4 -- 3 files changed, 89 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/Kconfig b/drivers/net/wireless/intel/iwlwifi/Kconfig index 235349a33a3c..7dbc0d38bb3b 100644 --- a/drivers/net/wireless/intel/iwlwifi/Kconfig +++ b/drivers/net/wireless/intel/iwlwifi/Kconfig @@ -92,20 +92,6 @@ config IWLWIFI_BCAST_FILTERING If unsure, don't enable this option, as some programs might expect incoming broadcasts for their normal operations. -config IWLWIFI_PCIE_RTPM - bool "Enable runtime power management mode for PCIe devices" - depends on IWLMVM && PM && EXPERT - help - Say Y here to enable runtime power management for PCIe - devices. If enabled, the device will go into low power mode - when idle for a short period of time, allowing for improved - power saving during runtime. Note that this feature requires - a tight integration with the platform. It is not recommended - to enable this feature without proper validation with the - specific target platform. - - If unsure, say N. - menu "Debugging Options" config IWLWIFI_DEBUG diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index 63a04cec32af..a037dfedb56e 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -1269,80 +1269,9 @@ int iwl_pci_fw_exit_d0i3(struct iwl_trans *trans) return ret; } -#ifdef CONFIG_IWLWIFI_PCIE_RTPM -static int iwl_pci_runtime_suspend(struct device *device) -{ - struct pci_dev *pdev = to_pci_dev(device); - struct iwl_trans *trans = pci_get_drvdata(pdev); - int ret; - - IWL_DEBUG_RPM(trans, "entering runtime suspend\n"); - - if (test_bit(STATUS_DEVICE_ENABLED, &trans->status)) { - ret = iwl_pci_fw_enter_d0i3(trans); - if (ret < 0) - return ret; - } - - trans->system_pm_mode = IWL_PLAT_PM_MODE_D0I3; - - iwl_trans_d3_suspend(trans, false, false); - - return 0; -} - -static int iwl_pci_runtime_resume(struct device *device) -{ - struct pci_dev *pdev = to_pci_dev(device); - struct iwl_trans *trans = pci_get_drvdata(pdev); - enum iwl_d3_status d3_status; - - IWL_DEBUG_RPM(trans, "exiting runtime suspend (resume)\n"); - - iwl_trans_d3_resume(trans, &d3_status, false, false); - - if (test_bit(STATUS_DEVICE_ENABLED, &trans->status)) - return iwl_pci_fw_exit_d0i3(trans); - - return 0; -} - -static int iwl_pci_system_prepare(struct device *device) -{ - struct pci_dev *pdev = to_pci_dev(device); - struct iwl_trans *trans = pci_get_drvdata(pdev); - - IWL_DEBUG_RPM(trans, "preparing for system suspend\n"); - - /* Wake the device up from runtime suspend before going to - * platform suspend. This is needed because we don't know - * whether wowlan any is set and, if it's not, mac80211 will - * disconnect (in which case, we can't be in D0i3). - */ - pm_runtime_resume(device); - - return 0; -} - -static void iwl_pci_system_complete(struct device *device) -{ - struct pci_dev *pdev = to_pci_dev(device); - struct iwl_trans *trans = pci_get_drvdata(pdev); - - IWL_DEBUG_RPM(trans, "completing system suspend\n"); -} -#endif /* CONFIG_IWLWIFI_PCIE_RTPM */ - static const struct dev_pm_ops iwl_dev_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(iwl_pci_suspend, iwl_pci_resume) -#ifdef CONFIG_IWLWIFI_PCIE_RTPM - SET_RUNTIME_PM_OPS(iwl_pci_runtime_suspend, - iwl_pci_runtime_resume, - NULL) - .prepare = iwl_pci_system_prepare, - .complete = iwl_pci_system_complete, -#endif /* CONFIG_IWLWIFI_PCIE_RTPM */ }; #define IWL_PM_OPS (&iwl_dev_pm_ops) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index d8b0f3b01acb..1bbbf978245d 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -3654,11 +3654,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, WQ_HIGHPRI | WQ_UNBOUND, 1); INIT_WORK(&trans_pcie->rba.rx_alloc, iwl_pcie_rx_allocator_work); -#ifdef CONFIG_IWLWIFI_PCIE_RTPM - trans->runtime_pm_mode = IWL_PLAT_PM_MODE_D0I3; -#else trans->runtime_pm_mode = IWL_PLAT_PM_MODE_DISABLED; -#endif /* CONFIG_IWLWIFI_PCIE_RTPM */ #ifdef CONFIG_IWLWIFI_DEBUGFS trans_pcie->fw_mon_data.state = IWL_FW_MON_DBGFS_STATE_CLOSED; From aa43ae1216753773ad5c8620c597b1d4cce1b14d Mon Sep 17 00:00:00 2001 From: Alex Malamud Date: Wed, 22 May 2019 13:49:18 +0300 Subject: [PATCH 23/80] iwlwifi: LTR updates New FW versions introduces LTR feature enablement by default. For such FW versions, driver (mvm/xvt) should not send host command to enable LTR feature, also it should be possible to override LTR configuration through the debugfs. 1. Send LTR feature enablement command only for FW versions which does not advertises SET_LTR_GEN2 capability. 2. Implement ltr_config file in debugfs for LTR configuration override. Signed-off-by: Alex Malamud --- drivers/net/wireless/intel/iwlwifi/fw/file.h | 3 +- .../net/wireless/intel/iwlwifi/mvm/debugfs.c | 37 +++++++++++++++++++ drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 3 +- 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h index ea2b3d77f848..418064ced337 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/file.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h @@ -441,9 +441,10 @@ enum iwl_ucode_tlv_capa { IWL_UCODE_TLV_CAPA_DYNAMIC_QUOTA = (__force iwl_ucode_tlv_capa_t)44, IWL_UCODE_TLV_CAPA_COEX_SCHEMA_2 = (__force iwl_ucode_tlv_capa_t)45, IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD = (__force iwl_ucode_tlv_capa_t)46, - IWL_UCODE_TLV_CAPA_ULTRA_HB_CHANNELS = (__force iwl_ucode_tlv_capa_t)48, IWL_UCODE_TLV_CAPA_FTM_CALIBRATED = (__force iwl_ucode_tlv_capa_t)47, + IWL_UCODE_TLV_CAPA_ULTRA_HB_CHANNELS = (__force iwl_ucode_tlv_capa_t)48, IWL_UCODE_TLV_CAPA_CS_MODIFY = (__force iwl_ucode_tlv_capa_t)49, + IWL_UCODE_TLV_CAPA_SET_LTR_GEN2 = (__force iwl_ucode_tlv_capa_t)50, /* set 2 */ IWL_UCODE_TLV_CAPA_EXTENDED_DTS_MEASURE = (__force iwl_ucode_tlv_capa_t)64, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c index 6d67d3da31e0..994a4ba07204 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c @@ -1758,6 +1758,38 @@ iwl_dbgfs_uapsd_noagg_bssids_read(struct file *file, char __user *user_buf, return simple_read_from_buffer(user_buf, count, ppos, buf, pos); } +static ssize_t +iwl_dbgfs_ltr_config_write(struct iwl_mvm *mvm, + char *buf, size_t count, loff_t *ppos) +{ + int ret; + struct iwl_ltr_config_cmd ltr_config = {0}; + + if (!iwl_mvm_firmware_running(mvm)) + return -EIO; + + if (sscanf(buf, "%x,%x,%x,%x,%x,%x,%x", + <r_config.flags, + <r_config.static_long, + <r_config.static_short, + <r_config.ltr_cfg_values[0], + <r_config.ltr_cfg_values[1], + <r_config.ltr_cfg_values[2], + <r_config.ltr_cfg_values[3]) != 7) { + return -EINVAL; + } + + mutex_lock(&mvm->mutex); + ret = iwl_mvm_send_cmd_pdu(mvm, LTR_CONFIG, 0, sizeof(ltr_config), + <r_config); + mutex_unlock(&mvm->mutex); + + if (ret) + IWL_ERR(mvm, "failed to send ltr configuration cmd\n"); + + return ret ?: count; +} + MVM_DEBUGFS_READ_WRITE_FILE_OPS(prph_reg, 64); /* Device wide debugfs entries */ @@ -1806,6 +1838,8 @@ MVM_DEBUGFS_READ_WRITE_STA_FILE_OPS(amsdu_len, 16); MVM_DEBUGFS_READ_WRITE_FILE_OPS(he_sniffer_params, 32); +MVM_DEBUGFS_WRITE_FILE_OPS(ltr_config, 512); + static ssize_t iwl_dbgfs_mem_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { @@ -1993,6 +2027,9 @@ void iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) #endif MVM_DEBUGFS_ADD_FILE(he_sniffer_params, mvm->debugfs_dir, 0600); + if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_SET_LTR_GEN2)) + MVM_DEBUGFS_ADD_FILE(ltr_config, mvm->debugfs_dir, 0200); + debugfs_create_bool("enable_scan_iteration_notif", 0600, mvm->debugfs_dir, &mvm->scan_iter_notif_enabled); debugfs_create_bool("drop_bcn_ap_mode", 0600, mvm->debugfs_dir, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index 251e7c235aaa..bb2aec9c6738 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -1302,7 +1302,8 @@ int iwl_mvm_up(struct iwl_mvm *mvm) iwl_mvm_tt_tx_backoff(mvm, 0); #endif - WARN_ON(iwl_mvm_config_ltr(mvm)); + if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_SET_LTR_GEN2)) + WARN_ON(iwl_mvm_config_ltr(mvm)); ret = iwl_mvm_power_update_device(mvm); if (ret) From de645c934660fc1d5f4695c2c389537ac6601049 Mon Sep 17 00:00:00 2001 From: Ayala Beker Date: Fri, 24 May 2019 01:06:01 +0300 Subject: [PATCH 24/80] iwlwifi: scan: add support for new scan request command version Scan API was changed to support 6Ghz channels as well. Support the new version. Signed-off-by: Ayala Beker Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/fw/api/scan.h | 55 ++++++++++-- drivers/net/wireless/intel/iwlwifi/fw/file.h | 1 + drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 6 ++ drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 86 +++++++++++++------ 4 files changed, 116 insertions(+), 32 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h b/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h index c4960f045415..39c64850cb6f 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h @@ -93,6 +93,8 @@ struct iwl_ssid_ie { #define IWL_SCAN_SHORT_BLACKLIST_LEN 16 #define IWL_SCAN_MAX_PROFILES 11 #define SCAN_OFFLOAD_PROBE_REQ_SIZE 512 +#define SCAN_NUM_BAND_PROBE_DATA_V_1 2 +#define SCAN_NUM_BAND_PROBE_DATA_V_2 3 /* Default watchdog (in MS) for scheduled scan iteration */ #define IWL_SCHED_SCAN_WATCHDOG cpu_to_le16(15000) @@ -251,9 +253,22 @@ struct iwl_scan_probe_segment { * @common_data: last (and common) part of the probe * @buf: raw data block */ +struct iwl_scan_probe_req_v1 { + struct iwl_scan_probe_segment mac_header; + struct iwl_scan_probe_segment band_data[SCAN_NUM_BAND_PROBE_DATA_V_1]; + struct iwl_scan_probe_segment common_data; + u8 buf[SCAN_OFFLOAD_PROBE_REQ_SIZE]; +} __packed; + +/* iwl_scan_probe_req - PROBE_REQUEST_FRAME_API_S_VER_v2 + * @mac_header: first (and common) part of the probe + * @band_data: band specific data + * @common_data: last (and common) part of the probe + * @buf: raw data block + */ struct iwl_scan_probe_req { struct iwl_scan_probe_segment mac_header; - struct iwl_scan_probe_segment band_data[2]; + struct iwl_scan_probe_segment band_data[SCAN_NUM_BAND_PROBE_DATA_V_2]; struct iwl_scan_probe_segment common_data; u8 buf[SCAN_OFFLOAD_PROBE_REQ_SIZE]; } __packed; @@ -608,15 +623,29 @@ enum iwl_umac_scan_general_flags2 { * struct iwl_scan_channel_cfg_umac * @flags: bitmap - 0-19: directed scan to i'th ssid. * @channel_num: channel number 1-13 etc. + * @band: band of channel: 0 for 2GHz, 1 for 5GHz * @iter_count: repetition count for the channel. * @iter_interval: interval between two scan iterations on one channel. */ -struct iwl_scan_channel_cfg_umac { +struct iwl_scan_channel_cfg_umac { __le32 flags; - u8 channel_num; - u8 iter_count; - __le16 iter_interval; -} __packed; /* SCAN_CHANNEL_CFG_S_VER2 */ + /* Both versions are of the same size, so use a union without adjusting + * the command size later + */ + union { + struct { + u8 channel_num; + u8 iter_count; + __le16 iter_interval; + } v1; /* SCAN_CHANNEL_CFG_S_VER1 */ + struct { + u8 channel_num; + u8 band; + u8 iter_count; + u8 iter_interval; + } v2; /* SCAN_CHANNEL_CFG_S_VER2 */ + }; +} __packed; /** * struct iwl_scan_umac_schedule @@ -630,6 +659,16 @@ struct iwl_scan_umac_schedule { u8 reserved; } __packed; /* SCAN_SCHED_PARAM_API_S_VER_1 */ +struct iwl_scan_req_umac_tail_v1 { + /* SCAN_PERIODIC_PARAMS_API_S_VER_1 */ + struct iwl_scan_umac_schedule schedule[IWL_MAX_SCHED_SCAN_PLANS]; + __le16 delay; + __le16 reserved; + /* SCAN_PROBE_PARAMS_API_S_VER_1 */ + struct iwl_scan_probe_req_v1 preq; + struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX]; +} __packed; + /** * struct iwl_scan_req_umac_tail - the rest of the UMAC scan request command * parameters following channels configuration array. @@ -639,12 +678,12 @@ struct iwl_scan_umac_schedule { * @preq: probe request with IEs blocks * @direct_scan: list of SSIDs for directed active scan */ -struct iwl_scan_req_umac_tail { +struct iwl_scan_req_umac_tail_v2 { /* SCAN_PERIODIC_PARAMS_API_S_VER_1 */ struct iwl_scan_umac_schedule schedule[IWL_MAX_SCHED_SCAN_PLANS]; __le16 delay; __le16 reserved; - /* SCAN_PROBE_PARAMS_API_S_VER_1 */ + /* SCAN_PROBE_PARAMS_API_S_VER_2 */ struct iwl_scan_probe_req preq; struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX]; } __packed; diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h index 418064ced337..3d567240ef11 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/file.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h @@ -323,6 +323,7 @@ enum iwl_ucode_tlv_api { IWL_UCODE_TLV_API_FTM_RTT_ACCURACY = (__force iwl_ucode_tlv_api_t)54, IWL_UCODE_TLV_API_SAR_TABLE_VER = (__force iwl_ucode_tlv_api_t)55, IWL_UCODE_TLV_API_ADWELL_HB_DEF_N_AP = (__force iwl_ucode_tlv_api_t)57, + IWL_UCODE_TLV_API_SCAN_EXT_CHAN_VER = (__force iwl_ucode_tlv_api_t)58, NUM_IWL_UCODE_TLV_API #ifdef __CHECKER__ diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index ed52e2ea97d9..2aa9bfc5e113 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -1387,6 +1387,12 @@ static inline bool iwl_mvm_cdb_scan_api(struct iwl_mvm *mvm) return mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22000; } +static inline bool iwl_mvm_is_scan_ext_chan_supported(struct iwl_mvm *mvm) +{ + return fw_has_api(&mvm->fw->ucode_capa, + IWL_UCODE_TLV_API_SCAN_EXT_CHAN_VER); +} + static inline bool iwl_mvm_has_new_rx_stats_api(struct iwl_mvm *mvm) { return fw_has_api(&mvm->fw->ucode_capa, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c index 2652e6ce4089..85e33310804e 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c @@ -77,7 +77,10 @@ #define IWL_SCAN_DWELL_FRAGMENTED 44 #define IWL_SCAN_DWELL_EXTENDED 90 #define IWL_SCAN_NUM_OF_FRAGS 3 +#define IWL_SCAN_LAST_2_4_CHN 14 +#define IWL_SCAN_BAND_5_2 0 +#define IWL_SCAN_BAND_2_4 1 /* adaptive dwell max budget time [TU] for full scan */ #define IWL_SCAN_ADWELL_MAX_BUDGET_FULL_SCAN 300 @@ -956,11 +959,24 @@ static int iwl_mvm_scan_lmac_flags(struct iwl_mvm *mvm, return flags; } +static void +iwl_mvm_scan_set_legacy_probe_req(struct iwl_scan_probe_req_v1 *p_req, + struct iwl_scan_probe_req src_p_req) +{ + int i; + + p_req->mac_header = src_p_req.mac_header; + for (i = 0; i < SCAN_NUM_BAND_PROBE_DATA_V_1; i++) + p_req->band_data[i] = src_p_req.band_data[i]; + p_req->common_data = src_p_req.common_data; + memcpy(p_req->buf, src_p_req.buf, SCAN_OFFLOAD_PROBE_REQ_SIZE); +} + static int iwl_mvm_scan_lmac(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct iwl_mvm_scan_params *params) { struct iwl_scan_req_lmac *cmd = mvm->scan_cmd; - struct iwl_scan_probe_req *preq = + struct iwl_scan_probe_req_v1 *preq = (void *)(cmd->data + sizeof(struct iwl_scan_channel_cfg_lmac) * mvm->fw->ucode_capa.n_scan_channels); u32 ssid_bitmap = 0; @@ -1030,7 +1046,7 @@ static int iwl_mvm_scan_lmac(struct iwl_mvm *mvm, struct ieee80211_vif *vif, iwl_mvm_lmac_scan_cfg_channels(mvm, params->channels, params->n_channels, ssid_bitmap, cmd); - *preq = params->preq; + iwl_mvm_scan_set_legacy_probe_req(preq, params->preq); return 0; } @@ -1384,9 +1400,17 @@ iwl_mvm_umac_scan_cfg_channels(struct iwl_mvm *mvm, for (i = 0; i < n_channels; i++) { channel_cfg[i].flags = cpu_to_le32(ssid_bitmap); - channel_cfg[i].channel_num = channels[i]->hw_value; - channel_cfg[i].iter_count = 1; - channel_cfg[i].iter_interval = 0; + channel_cfg[i].v1.channel_num = channels[i]->hw_value; + if (iwl_mvm_is_scan_ext_chan_supported(mvm)) { + channel_cfg[i].v2.band = + channels[i]->hw_value <= IWL_SCAN_LAST_2_4_CHN ? + IWL_SCAN_BAND_2_4 : IWL_SCAN_BAND_5_2; + channel_cfg[i].v2.iter_count = 1; + channel_cfg[i].v2.iter_interval = 0; + } else { + channel_cfg[i].v1.iter_count = 1; + channel_cfg[i].v1.iter_interval = 0; + } } } @@ -1476,9 +1500,12 @@ static int iwl_mvm_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct iwl_scan_req_umac *cmd = mvm->scan_cmd; struct iwl_scan_umac_chan_param *chan_param; void *cmd_data = iwl_mvm_get_scan_req_umac_data(mvm); - struct iwl_scan_req_umac_tail *sec_part = cmd_data + - sizeof(struct iwl_scan_channel_cfg_umac) * - mvm->fw->ucode_capa.n_scan_channels; + void *sec_part = cmd_data + sizeof(struct iwl_scan_channel_cfg_umac) * + mvm->fw->ucode_capa.n_scan_channels; + struct iwl_scan_req_umac_tail_v2 *tail_v2 = + (struct iwl_scan_req_umac_tail_v2 *)sec_part; + struct iwl_scan_req_umac_tail_v1 *tail_v1; + struct iwl_ssid_ie *direct_scan; int uid, i; u32 ssid_bitmap = 0; u8 channel_flags = 0; @@ -1540,18 +1567,12 @@ static int iwl_mvm_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif, chan_param->flags = channel_flags; chan_param->count = params->n_channels; - iwl_scan_build_ssids(params, sec_part->direct_scan, &ssid_bitmap); - - iwl_mvm_umac_scan_cfg_channels(mvm, params->channels, - params->n_channels, ssid_bitmap, - cmd_data); - for (i = 0; i < params->n_scan_plans; i++) { struct cfg80211_sched_scan_plan *scan_plan = ¶ms->scan_plans[i]; - sec_part->schedule[i].iter_count = scan_plan->iterations; - sec_part->schedule[i].interval = + tail_v2->schedule[i].iter_count = scan_plan->iterations; + tail_v2->schedule[i].interval = cpu_to_le16(scan_plan->interval); } @@ -1561,12 +1582,23 @@ static int iwl_mvm_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif, * For example, when regular scan is requested the driver sets one scan * plan with one iteration. */ - if (!sec_part->schedule[i - 1].iter_count) - sec_part->schedule[i - 1].iter_count = 0xff; + if (!tail_v2->schedule[i - 1].iter_count) + tail_v2->schedule[i - 1].iter_count = 0xff; - sec_part->delay = cpu_to_le16(params->delay); - sec_part->preq = params->preq; + tail_v2->delay = cpu_to_le16(params->delay); + if (iwl_mvm_is_scan_ext_chan_supported(mvm)) { + tail_v2->preq = params->preq; + direct_scan = tail_v2->direct_scan; + } else { + tail_v1 = (struct iwl_scan_req_umac_tail_v1 *)sec_part; + iwl_mvm_scan_set_legacy_probe_req(&tail_v1->preq, params->preq); + direct_scan = tail_v1->direct_scan; + } + iwl_scan_build_ssids(params, direct_scan, &ssid_bitmap); + iwl_mvm_umac_scan_cfg_channels(mvm, params->channels, + params->n_channels, ssid_bitmap, + cmd_data); return 0; } @@ -1996,6 +2028,7 @@ static int iwl_mvm_scan_stop_wait(struct iwl_mvm *mvm, int type) int iwl_mvm_scan_size(struct iwl_mvm *mvm) { int base_size = IWL_SCAN_REQ_UMAC_SIZE_V1; + int tail_size; if (iwl_mvm_is_adaptive_dwell_v2_supported(mvm)) base_size = IWL_SCAN_REQ_UMAC_SIZE_V8; @@ -2004,16 +2037,21 @@ int iwl_mvm_scan_size(struct iwl_mvm *mvm) else if (iwl_mvm_cdb_scan_api(mvm)) base_size = IWL_SCAN_REQ_UMAC_SIZE_V6; - if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_UMAC_SCAN)) + if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_UMAC_SCAN)) { + if (iwl_mvm_is_scan_ext_chan_supported(mvm)) + tail_size = sizeof(struct iwl_scan_req_umac_tail_v2); + else + tail_size = sizeof(struct iwl_scan_req_umac_tail_v1); + return base_size + sizeof(struct iwl_scan_channel_cfg_umac) * mvm->fw->ucode_capa.n_scan_channels + - sizeof(struct iwl_scan_req_umac_tail); - + tail_size; + } return sizeof(struct iwl_scan_req_lmac) + sizeof(struct iwl_scan_channel_cfg_lmac) * mvm->fw->ucode_capa.n_scan_channels + - sizeof(struct iwl_scan_probe_req); + sizeof(struct iwl_scan_probe_req_v1); } /* From 2e838c6f18db420e7fd3fd128418102f6bfe306c Mon Sep 17 00:00:00 2001 From: Mordechay Goodstein Date: Wed, 29 May 2019 15:39:07 +0300 Subject: [PATCH 25/80] iwlwifi: mvm: name magic numbers with enum It's hard to follow the numbers so rename it with enum Signed-off-by: Mordechay Goodstein Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/fw/api/rs.h | 18 +++++++++++++----- .../net/wireless/intel/iwlwifi/mvm/rs-fw.c | 19 +++++++++++-------- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h b/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h index 9eddc4dc2ae6..4347be6491e9 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h @@ -7,7 +7,7 @@ * * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * 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 @@ -29,7 +29,7 @@ * * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * 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 @@ -166,8 +166,16 @@ enum iwl_tlc_mng_ht_rates { IWL_TLC_MNG_HT_RATE_MAX = IWL_TLC_MNG_HT_RATE_MCS11, }; -/* Maximum supported tx antennas number */ -#define MAX_NSS 2 +enum IWL_TLC_MNG_NSS { + IWL_TLC_NSS_1, + IWL_TLC_NSS_2, + IWL_TLC_NSS_MAX +}; + +enum IWL_TLC_HT_BW_RATES { + IWL_TLC_HT_BW_NONE_160, + IWL_TLC_HT_BW_160, +}; /** * struct tlc_config_cmd - TLC configuration @@ -195,7 +203,7 @@ struct iwl_tlc_config_cmd { u8 amsdu; __le16 flags; __le16 non_ht_rates; - __le16 ht_rates[MAX_NSS][2]; + __le16 ht_rates[IWL_TLC_NSS_MAX][2]; __le16 max_mpdu_len; u8 sgi_ch_width_supp; u8 reserved2[1]; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c index 08b67812e94e..8f50e2b121bd 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c @@ -193,7 +193,7 @@ rs_fw_vht_set_enabled_rates(const struct ieee80211_sta *sta, int i, highest_mcs; for (i = 0; i < sta->rx_nss; i++) { - if (i == MAX_NSS) + if (i == IWL_TLC_NSS_MAX) break; highest_mcs = rs_fw_vht_highest_rx_mcs_index(vht_cap, i + 1); @@ -204,9 +204,10 @@ rs_fw_vht_set_enabled_rates(const struct ieee80211_sta *sta, if (sta->bandwidth == IEEE80211_STA_RX_BW_20) supp &= ~BIT(IWL_TLC_MNG_HT_RATE_MCS9); - cmd->ht_rates[i][0] = cpu_to_le16(supp); + cmd->ht_rates[i][IWL_TLC_HT_BW_NONE_160] = cpu_to_le16(supp); if (sta->bandwidth == IEEE80211_STA_RX_BW_160) - cmd->ht_rates[i][1] = cmd->ht_rates[i][0]; + cmd->ht_rates[i][IWL_TLC_HT_BW_160] = + cmd->ht_rates[i][IWL_TLC_HT_BW_NONE_160]; } } @@ -241,7 +242,7 @@ rs_fw_he_set_enabled_rates(const struct ieee80211_sta *sta, le16_to_cpu(sband->iftype_data->he_cap.he_mcs_nss_supp.tx_mcs_160); int i; - for (i = 0; i < sta->rx_nss && i < MAX_NSS; i++) { + for (i = 0; i < sta->rx_nss && i < IWL_TLC_NSS_MAX; i++) { u16 _mcs_160 = (mcs_160 >> (2 * i)) & 0x3; u16 _mcs_80 = (mcs_80 >> (2 * i)) & 0x3; u16 _tx_mcs_160 = (tx_mcs_160 >> (2 * i)) & 0x3; @@ -255,7 +256,7 @@ rs_fw_he_set_enabled_rates(const struct ieee80211_sta *sta, } if (_mcs_80 > _tx_mcs_80) _mcs_80 = _tx_mcs_80; - cmd->ht_rates[i][0] = + cmd->ht_rates[i][IWL_TLC_HT_BW_NONE_160] = cpu_to_le16(rs_fw_he_ieee80211_mcs_to_rs_mcs(_mcs_80)); /* If one side doesn't support - mark both as not supporting */ @@ -266,7 +267,7 @@ rs_fw_he_set_enabled_rates(const struct ieee80211_sta *sta, } if (_mcs_160 > _tx_mcs_160) _mcs_160 = _tx_mcs_160; - cmd->ht_rates[i][1] = + cmd->ht_rates[i][IWL_TLC_HT_BW_160] = cpu_to_le16(rs_fw_he_ieee80211_mcs_to_rs_mcs(_mcs_160)); } } @@ -300,8 +301,10 @@ static void rs_fw_set_supp_rates(struct ieee80211_sta *sta, rs_fw_vht_set_enabled_rates(sta, vht_cap, cmd); } else if (ht_cap->ht_supported) { cmd->mode = IWL_TLC_MNG_MODE_HT; - cmd->ht_rates[0][0] = cpu_to_le16(ht_cap->mcs.rx_mask[0]); - cmd->ht_rates[1][0] = cpu_to_le16(ht_cap->mcs.rx_mask[1]); + cmd->ht_rates[IWL_TLC_NSS_1][IWL_TLC_HT_BW_NONE_160] = + cpu_to_le16(ht_cap->mcs.rx_mask[0]); + cmd->ht_rates[IWL_TLC_NSS_2][IWL_TLC_HT_BW_NONE_160] = + cpu_to_le16(ht_cap->mcs.rx_mask[1]); } } From 242d9c8b9a9348ca3226323161b5e837937f830f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 11 Jun 2019 15:38:13 +0200 Subject: [PATCH 26/80] iwlwifi: mvm: use FW thermal monitoring regardless of CONFIG_THERMAL It doesn't make sense to use the FW thermal monitoring only if we have CONFIG_THERMAL, because then we use the default thresholds etc. which may be different from what the firmware implements, as we don't maintain them in the driver now. Only the CTDP code needs to actually be under CONFIG_THERMAL. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 5 +---- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 4 ---- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index bb2aec9c6738..411a79e15333 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -1273,7 +1273,6 @@ int iwl_mvm_up(struct iwl_mvm *mvm) goto error; } -#ifdef CONFIG_THERMAL if (iwl_mvm_is_tt_in_fw(mvm)) { /* in order to give the responsibility of ct-kill and * TX backoff to FW we need to send empty temperature reporting @@ -1285,6 +1284,7 @@ int iwl_mvm_up(struct iwl_mvm *mvm) iwl_mvm_tt_tx_backoff(mvm, 0); } +#ifdef CONFIG_THERMAL /* TODO: read the budget from BIOS / Platform NVM */ /* @@ -1297,9 +1297,6 @@ int iwl_mvm_up(struct iwl_mvm *mvm) if (ret) goto error; } -#else - /* Initialize tx backoffs to the minimal possible */ - iwl_mvm_tt_tx_backoff(mvm, 0); #endif if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_SET_LTR_GEN2)) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 2aa9bfc5e113..3efcc3a939b8 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -1422,7 +1422,6 @@ iwl_mvm_get_agg_status(struct iwl_mvm *mvm, void *tx_resp) static inline bool iwl_mvm_is_tt_in_fw(struct iwl_mvm *mvm) { -#ifdef CONFIG_THERMAL /* these two TLV are redundant since the responsibility to CT-kill by * FW happens only after we send at least one command of * temperature THs report. @@ -1431,9 +1430,6 @@ static inline bool iwl_mvm_is_tt_in_fw(struct iwl_mvm *mvm) IWL_UCODE_TLV_CAPA_CT_KILL_BY_FW) && fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_TEMP_THS_REPORT_SUPPORT); -#else /* CONFIG_THERMAL */ - return false; -#endif /* CONFIG_THERMAL */ } static inline bool iwl_mvm_is_ctdp_supported(struct iwl_mvm *mvm) From ba7136f3f9e849e5776429317bf45ac3d4cfa3f7 Mon Sep 17 00:00:00 2001 From: Alex Malamud Date: Mon, 10 Jun 2019 15:19:23 +0300 Subject: [PATCH 27/80] iwlwifi: Set w-pointer upon resume according to SN During D3 state, FW may send packets. As a result, "write" queue pointer will be incremented by FW. Upon resume from D3, driver should adjust its shadows of "write" and "read" pointers to the value reported by FW. 1. Keep TID used during wowlan configuration. 2. Upon resume, set driver's "write" and "read" queue pointers to the value reported by FW. Signed-off-by: Alex Malamud Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/iwl-trans.h | 13 +++++++++++++ drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 9 +++++++++ drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 1 + drivers/net/wireless/intel/iwlwifi/pcie/internal.h | 1 + drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 2 ++ drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 14 ++++++++++++++ 6 files changed, 40 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h index 942662eaf523..034c935b5579 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h @@ -562,6 +562,8 @@ struct iwl_trans_ops { void (*reclaim)(struct iwl_trans *trans, int queue, int ssn, struct sk_buff_head *skbs); + void (*set_q_ptrs)(struct iwl_trans *trans, int queue, int ptr); + bool (*txq_enable)(struct iwl_trans *trans, int queue, u16 ssn, const struct iwl_trans_txq_scd_cfg *cfg, unsigned int queue_wdg_timeout); @@ -999,6 +1001,17 @@ static inline void iwl_trans_reclaim(struct iwl_trans *trans, int queue, trans->ops->reclaim(trans, queue, ssn, skbs); } +static inline void iwl_trans_set_q_ptrs(struct iwl_trans *trans, int queue, + int ptr) +{ + if (WARN_ON_ONCE(trans->state != IWL_TRANS_FW_ALIVE)) { + IWL_ERR(trans, "%s bad state = %d\n", __func__, trans->state); + return; + } + + trans->ops->set_q_ptrs(trans, queue, ptr); +} + static inline void iwl_trans_txq_disable(struct iwl_trans *trans, int queue, bool configure_scd) { diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index 89839a83d8c2..6f7345b121a6 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -831,6 +831,8 @@ iwl_mvm_wowlan_config(struct iwl_mvm *mvm, bool unified_image = fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG); + mvm->offload_tid = wowlan_config_cmd->offloading_tid; + if (!unified_image) { ret = iwl_mvm_switch_to_d3(mvm); if (ret) @@ -1656,6 +1658,13 @@ static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm, mvm_ap_sta->tid_data[i].seq_number = seq; } + if (mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22000) { + i = mvm->offload_tid; + iwl_trans_set_q_ptrs(mvm->trans, + mvm_ap_sta->tid_data[i].txq_id, + mvm_ap_sta->tid_data[i].seq_number >> 4); + } + /* now we have all the data we need, unlock to avoid mac80211 issues */ mutex_unlock(&mvm->mutex); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 3efcc3a939b8..79bbdf8121cc 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -1001,6 +1001,7 @@ struct iwl_mvm { struct ieee80211_channel **nd_channels; int n_nd_channels; bool net_detect; + u8 offload_tid; #ifdef CONFIG_IWLWIFI_DEBUGFS bool d3_wake_sysassert; bool d3_test_active; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h index 9f5d0fc839fe..6bf2a816e221 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h @@ -697,6 +697,7 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans, struct iwl_rx_cmd_buffer *rxb); void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn, struct sk_buff_head *skbs); +void iwl_trans_pcie_set_q_ptrs(struct iwl_trans *trans, int txq_id, int ptr); void iwl_trans_pcie_tx_reset(struct iwl_trans *trans); void iwl_pcie_gen2_update_byte_tbl(struct iwl_trans_pcie *trans_pcie, struct iwl_txq *txq, u16 byte_cnt, diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index 1bbbf978245d..59b72a8de737 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -3397,6 +3397,8 @@ static const struct iwl_trans_ops trans_ops_pcie_gen2 = { .tx = iwl_trans_pcie_gen2_tx, .reclaim = iwl_trans_pcie_reclaim, + .set_q_ptrs = iwl_trans_pcie_set_q_ptrs, + .txq_alloc = iwl_trans_pcie_dyn_txq_alloc, .txq_free = iwl_trans_pcie_dyn_txq_free, .wait_txq_empty = iwl_trans_pcie_wait_txq_empty, diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c index 2f0ba7ef53b8..b25f51b5893c 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c @@ -1234,6 +1234,20 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn, spin_unlock_bh(&txq->lock); } +/* Set wr_ptr of specific device and txq */ +void iwl_trans_pcie_set_q_ptrs(struct iwl_trans *trans, int txq_id, int ptr) +{ + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + struct iwl_txq *txq = trans_pcie->txq[txq_id]; + + spin_lock_bh(&txq->lock); + + txq->write_ptr = ptr; + txq->read_ptr = txq->write_ptr; + + spin_unlock_bh(&txq->lock); +} + static int iwl_pcie_set_cmd_in_flight(struct iwl_trans *trans, const struct iwl_host_cmd *cmd) { From f60e27508165e8c3292c894d6c1c22409be63944 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 6 Jun 2019 11:27:13 +0300 Subject: [PATCH 28/80] iwlwifi: remove runtime_pm_mode This is always set to IWL_PLAT_PM_MODE_DISABLED Signed-off-by: Emmanuel Grumbach Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/iwl-trans.h | 33 +++---------------- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 28 ---------------- .../net/wireless/intel/iwlwifi/pcie/trans.c | 9 ----- 3 files changed, 5 insertions(+), 65 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h index 034c935b5579..b50290a724ff 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h @@ -630,9 +630,6 @@ enum iwl_trans_state { /** * DOC: Platform power management * - * There are two types of platform power management: system-wide - * (WoWLAN) and runtime. - * * In system-wide power management the entire platform goes into a low * power state (e.g. idle or suspend to RAM) at the same time and the * device is configured as a wakeup source for the entire platform. @@ -641,48 +638,32 @@ enum iwl_trans_state { * put the platform in low power mode). The device's behavior in this * mode is dictated by the wake-on-WLAN configuration. * - * In runtime power management, only the devices which are themselves - * idle enter a low power state. This is done at runtime, which means - * that the entire system is still running normally. This mode is - * usually triggered automatically by the device driver and requires - * the ability to enter and exit the low power modes in a very short - * time, so there is not much impact in usability. - * * The terms used for the device's behavior are as follows: * * - D0: the device is fully powered and the host is awake; * - D3: the device is in low power mode and only reacts to * specific events (e.g. magic-packet received or scan * results found); - * - D0I3: the device is in low power mode and reacts to any - * activity (e.g. RX); * * These terms reflect the power modes in the firmware and are not to - * be confused with the physical device power state. The NIC can be - * in D0I3 mode even if, for instance, the PCI device is in D3 state. + * be confused with the physical device power state. */ /** * enum iwl_plat_pm_mode - platform power management mode * * This enumeration describes the device's platform power management - * behavior when in idle mode (i.e. runtime power management) or when - * in system-wide suspend (i.e WoWLAN). + * behavior when in system-wide suspend (i.e WoWLAN). * * @IWL_PLAT_PM_MODE_DISABLED: power management is disabled for this - * device. At runtime, this means that nothing happens and the - * device always remains in active. In system-wide suspend mode, - * it means that the all connections will be closed automatically - * by mac80211 before the platform is suspended. + * device. In system-wide suspend mode, it means that the all + * connections will be closed automatically by mac80211 before + * the platform is suspended. * @IWL_PLAT_PM_MODE_D3: the device goes into D3 mode (i.e. WoWLAN). - * For runtime power management, this mode is not officially - * supported. - * @IWL_PLAT_PM_MODE_D0I3: the device goes into D0I3 mode. */ enum iwl_plat_pm_mode { IWL_PLAT_PM_MODE_DISABLED, IWL_PLAT_PM_MODE_D3, - IWL_PLAT_PM_MODE_D0I3, }; /* Max time to wait for trans to become idle/non-idle on d0i3 @@ -795,9 +776,6 @@ struct iwl_trans_debug { * @system_pm_mode: the system-wide power management mode in use. * This mode is set dynamically, depending on the WoWLAN values * configured from the userspace at runtime. - * @runtime_pm_mode: the runtime power management mode in use. This - * mode is set during the initialization phase and is not - * supposed to change during runtime. */ struct iwl_trans { const struct iwl_trans_ops *ops; @@ -842,7 +820,6 @@ struct iwl_trans { struct iwl_self_init_dram init_dram; enum iwl_plat_pm_mode system_pm_mode; - enum iwl_plat_pm_mode runtime_pm_mode; /* pointer to trans specific struct */ /*Ensure that this pointer will always be aligned to sizeof pointer */ diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index a037dfedb56e..c11f32721ad2 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -1097,25 +1097,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /* register transport layer debugfs here */ iwl_trans_pcie_dbgfs_register(iwl_trans); - /* if RTPM is in use, enable it in our device */ - if (iwl_trans->runtime_pm_mode != IWL_PLAT_PM_MODE_DISABLED) { - /* We explicitly set the device to active here to - * clear contingent errors. - */ - pm_runtime_set_active(&pdev->dev); - - pm_runtime_set_autosuspend_delay(&pdev->dev, - iwlwifi_mod_params.d0i3_timeout); - pm_runtime_use_autosuspend(&pdev->dev); - - /* We are not supposed to call pm_runtime_allow() by - * ourselves, but let userspace enable runtime PM via - * sysfs. However, since we don't enable this from - * userspace yet, we need to allow/forbid() ourselves. - */ - pm_runtime_allow(&pdev->dev); - } - /* The PCI device starts with a reference taken and we are * supposed to release it here. But to simplify the * interaction with the opmode, we don't do it now, but let @@ -1133,15 +1114,6 @@ static void iwl_pci_remove(struct pci_dev *pdev) { struct iwl_trans *trans = pci_get_drvdata(pdev); - /* if RTPM was in use, restore it to the state before probe */ - if (trans->runtime_pm_mode != IWL_PLAT_PM_MODE_DISABLED) { - /* We should not call forbid here, but we do for now. - * Check the comment to pm_runtime_allow() in - * iwl_pci_probe(). - */ - pm_runtime_forbid(trans->dev); - } - iwl_drv_stop(trans->drv); iwl_trans_pcie_free(trans); diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index 59b72a8de737..8d6d1192fde8 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -3312,18 +3312,11 @@ static struct iwl_trans_dump_data #ifdef CONFIG_PM_SLEEP static int iwl_trans_pcie_suspend(struct iwl_trans *trans) { - if (trans->runtime_pm_mode == IWL_PLAT_PM_MODE_D0I3 && - (trans->system_pm_mode == IWL_PLAT_PM_MODE_D0I3)) - return iwl_pci_fw_enter_d0i3(trans); - return 0; } static void iwl_trans_pcie_resume(struct iwl_trans *trans) { - if (trans->runtime_pm_mode == IWL_PLAT_PM_MODE_D0I3 && - (trans->system_pm_mode == IWL_PLAT_PM_MODE_D0I3)) - iwl_pci_fw_exit_d0i3(trans); } #endif /* CONFIG_PM_SLEEP */ @@ -3656,8 +3649,6 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, WQ_HIGHPRI | WQ_UNBOUND, 1); INIT_WORK(&trans_pcie->rba.rx_alloc, iwl_pcie_rx_allocator_work); - trans->runtime_pm_mode = IWL_PLAT_PM_MODE_DISABLED; - #ifdef CONFIG_IWLWIFI_DEBUGFS trans_pcie->fw_mon_data.state = IWL_FW_MON_DBGFS_STATE_CLOSED; mutex_init(&trans_pcie->fw_mon_data.mutex); From ea74343aeb1c21ae1f4389e2aafbab28ee071666 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 6 Jun 2019 11:31:04 +0300 Subject: [PATCH 29/80] iwlwifi: remove the opmode's d0i3 handlers Remove the now unneeded functions that called those from the transport layer. Signed-off-by: Emmanuel Grumbach Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/iwl-op-mode.h | 23 ------ drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 70 ------------------- .../wireless/intel/iwlwifi/pcie/internal.h | 3 - 3 files changed, 96 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h b/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h index f37d6fee0225..3008a5246be8 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h @@ -140,9 +140,6 @@ struct iwl_cfg; * @nic_config: configure NIC, called before firmware is started. * May sleep * @wimax_active: invoked when WiMax becomes active. May sleep - * @enter_d0i3: configure the fw to enter d0i3. return 1 to indicate d0i3 - * entrance is aborted (e.g. due to held reference). May sleep. - * @exit_d0i3: configure the fw to exit d0i3. May sleep. */ struct iwl_op_mode_ops { struct iwl_op_mode *(*start)(struct iwl_trans *trans, @@ -164,8 +161,6 @@ struct iwl_op_mode_ops { void (*cmd_queue_full)(struct iwl_op_mode *op_mode); void (*nic_config)(struct iwl_op_mode *op_mode); void (*wimax_active)(struct iwl_op_mode *op_mode); - int (*enter_d0i3)(struct iwl_op_mode *op_mode); - int (*exit_d0i3)(struct iwl_op_mode *op_mode); }; int iwl_opmode_register(const char *name, const struct iwl_op_mode_ops *ops); @@ -258,22 +253,4 @@ static inline void iwl_op_mode_wimax_active(struct iwl_op_mode *op_mode) op_mode->ops->wimax_active(op_mode); } -static inline int iwl_op_mode_enter_d0i3(struct iwl_op_mode *op_mode) -{ - might_sleep(); - - if (!op_mode->ops->enter_d0i3) - return 0; - return op_mode->ops->enter_d0i3(op_mode); -} - -static inline int iwl_op_mode_exit_d0i3(struct iwl_op_mode *op_mode) -{ - might_sleep(); - - if (!op_mode->ops->exit_d0i3) - return 0; - return op_mode->ops->exit_d0i3(op_mode); -} - #endif /* __iwl_op_mode_h__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index c11f32721ad2..df722ed6a6ec 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -1171,76 +1171,6 @@ static int iwl_pci_resume(struct device *device) return 0; } -int iwl_pci_fw_enter_d0i3(struct iwl_trans *trans) -{ - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - int ret; - - if (test_bit(STATUS_FW_ERROR, &trans->status)) - return 0; - - set_bit(STATUS_TRANS_GOING_IDLE, &trans->status); - - /* config the fw */ - ret = iwl_op_mode_enter_d0i3(trans->op_mode); - if (ret == 1) { - IWL_DEBUG_RPM(trans, "aborting d0i3 entrance\n"); - clear_bit(STATUS_TRANS_GOING_IDLE, &trans->status); - return -EBUSY; - } - if (ret) - goto err; - - ret = wait_event_timeout(trans_pcie->d0i3_waitq, - test_bit(STATUS_TRANS_IDLE, &trans->status), - msecs_to_jiffies(IWL_TRANS_IDLE_TIMEOUT)); - if (!ret) { - IWL_ERR(trans, "Timeout entering D0i3\n"); - ret = -ETIMEDOUT; - goto err; - } - - clear_bit(STATUS_TRANS_GOING_IDLE, &trans->status); - - return 0; -err: - clear_bit(STATUS_TRANS_GOING_IDLE, &trans->status); - iwl_trans_fw_error(trans); - return ret; -} - -int iwl_pci_fw_exit_d0i3(struct iwl_trans *trans) -{ - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - int ret; - - /* sometimes a D0i3 entry is not followed through */ - if (!test_bit(STATUS_TRANS_IDLE, &trans->status)) - return 0; - - /* config the fw */ - ret = iwl_op_mode_exit_d0i3(trans->op_mode); - if (ret) - goto err; - - /* we clear STATUS_TRANS_IDLE only when D0I3_END command is completed */ - - ret = wait_event_timeout(trans_pcie->d0i3_waitq, - !test_bit(STATUS_TRANS_IDLE, &trans->status), - msecs_to_jiffies(IWL_TRANS_IDLE_TIMEOUT)); - if (!ret) { - IWL_ERR(trans, "Timeout exiting D0i3\n"); - ret = -ETIMEDOUT; - goto err; - } - - return 0; -err: - clear_bit(STATUS_TRANS_IDLE, &trans->status); - iwl_trans_fw_error(trans); - return ret; -} - static const struct dev_pm_ops iwl_dev_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(iwl_pci_suspend, iwl_pci_resume) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h index 6bf2a816e221..b5534fc33539 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h @@ -1059,9 +1059,6 @@ void iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans); static inline void iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans) { } #endif -int iwl_pci_fw_exit_d0i3(struct iwl_trans *trans); -int iwl_pci_fw_enter_d0i3(struct iwl_trans *trans); - void iwl_pcie_rx_allocator_work(struct work_struct *data); /* common functions that are used by gen2 transport */ From 0d52497ac8ee03bdf292f59bfed5e15319e448ac Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 6 Jun 2019 11:44:26 +0300 Subject: [PATCH 30/80] iwlwifi: pcie: remove the refs / unrefs from the transport This code is now stale Signed-off-by: Emmanuel Grumbach Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/iwl-trans.c | 14 ----- .../net/wireless/intel/iwlwifi/iwl-trans.h | 9 ---- .../net/wireless/intel/iwlwifi/pcie/trans.c | 33 ------------ .../net/wireless/intel/iwlwifi/pcie/tx-gen2.c | 31 +---------- drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 53 +++++-------------- 5 files changed, 15 insertions(+), 125 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.c b/drivers/net/wireless/intel/iwlwifi/iwl-trans.c index 727f73e0b3f1..d47ba334c7ac 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.c @@ -202,17 +202,3 @@ int iwl_cmd_groups_verify_sorted(const struct iwl_trans_config *trans) return 0; } IWL_EXPORT_SYMBOL(iwl_cmd_groups_verify_sorted); - -void iwl_trans_ref(struct iwl_trans *trans) -{ - if (trans->ops->ref) - trans->ops->ref(trans); -} -IWL_EXPORT_SYMBOL(iwl_trans_ref); - -void iwl_trans_unref(struct iwl_trans *trans) -{ - if (trans->ops->unref) - trans->ops->unref(trans); -} -IWL_EXPORT_SYMBOL(iwl_trans_unref); diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h index b50290a724ff..7c63706eb07b 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h @@ -531,11 +531,6 @@ struct iwl_trans_rxq_dma_data { * @release_nic_access: let the NIC go to sleep. The "flags" parameter * must be the same one that was sent before to the grab_nic_access. * @set_bits_mask - set SRAM register according to value and mask. - * @ref: grab a reference to the transport/FW layers, disallowing - * certain low power states - * @unref: release a reference previously taken with @ref. Note that - * initially the reference count is 1, making an initial @unref - * necessary to allow low power states. * @dump_data: return a vmalloc'ed buffer with debug data, maybe containing last * TX'ed commands and similar. The buffer will be vfree'd by the caller. * Note that the transport must fill in the proper file headers. @@ -605,8 +600,6 @@ struct iwl_trans_ops { unsigned long *flags); void (*set_bits_mask)(struct iwl_trans *trans, u32 reg, u32 mask, u32 value); - void (*ref)(struct iwl_trans *trans); - void (*unref)(struct iwl_trans *trans); int (*suspend)(struct iwl_trans *trans); void (*resume)(struct iwl_trans *trans); @@ -1254,8 +1247,6 @@ struct iwl_trans *iwl_trans_alloc(unsigned int priv_size, const struct iwl_cfg *cfg, const struct iwl_trans_ops *ops); void iwl_trans_free(struct iwl_trans *trans); -void iwl_trans_ref(struct iwl_trans *trans); -void iwl_trans_unref(struct iwl_trans *trans); /***************************************************** * driver (transport) register/unregister functions diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index 8d6d1192fde8..ad0c255d5f2e 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -2360,37 +2360,6 @@ static void iwl_trans_pcie_set_bits_mask(struct iwl_trans *trans, u32 reg, spin_unlock_irqrestore(&trans_pcie->reg_lock, flags); } -static void iwl_trans_pcie_ref(struct iwl_trans *trans) -{ - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - - if (iwlwifi_mod_params.d0i3_disable) - return; - - pm_runtime_get(&trans_pcie->pci_dev->dev); - -#ifdef CONFIG_PM - IWL_DEBUG_RPM(trans, "runtime usage count: %d\n", - atomic_read(&trans_pcie->pci_dev->dev.power.usage_count)); -#endif /* CONFIG_PM */ -} - -static void iwl_trans_pcie_unref(struct iwl_trans *trans) -{ - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - - if (iwlwifi_mod_params.d0i3_disable) - return; - - pm_runtime_mark_last_busy(&trans_pcie->pci_dev->dev); - pm_runtime_put_autosuspend(&trans_pcie->pci_dev->dev); - -#ifdef CONFIG_PM - IWL_DEBUG_RPM(trans, "runtime usage count: %d\n", - atomic_read(&trans_pcie->pci_dev->dev.power.usage_count)); -#endif /* CONFIG_PM */ -} - static const char *get_csr_string(int cmd) { #define IWL_CMD(x) case x: return #x @@ -3335,8 +3304,6 @@ static void iwl_trans_pcie_resume(struct iwl_trans *trans) .grab_nic_access = iwl_trans_pcie_grab_nic_access, \ .release_nic_access = iwl_trans_pcie_release_nic_access, \ .set_bits_mask = iwl_trans_pcie_set_bits_mask, \ - .ref = iwl_trans_pcie_ref, \ - .unref = iwl_trans_pcie_unref, \ .dump_data = iwl_trans_pcie_dump_data, \ .d3_suspend = iwl_trans_pcie_d3_suspend, \ .d3_resume = iwl_trans_pcie_d3_resume, \ diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c index 9ef6b8fe03c1..5f52bf849a01 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c @@ -647,12 +647,8 @@ int iwl_trans_pcie_gen2_tx(struct iwl_trans *trans, struct sk_buff *skb, iwl_pcie_gen2_get_num_tbs(trans, tfd)); /* start timer if queue currently empty */ - if (txq->read_ptr == txq->write_ptr) { - if (txq->wd_timeout) - mod_timer(&txq->stuck_timer, jiffies + txq->wd_timeout); - IWL_DEBUG_RPM(trans, "Q: %d first tx - take ref\n", txq->id); - iwl_trans_ref(trans); - } + if (txq->read_ptr == txq->write_ptr && txq->wd_timeout) + mod_timer(&txq->stuck_timer, jiffies + txq->wd_timeout); /* Tell device the write index *just past* this latest filled TFD */ txq->write_ptr = iwl_queue_inc_wrap(trans, txq->write_ptr); @@ -897,12 +893,6 @@ static int iwl_pcie_gen2_enqueue_hcmd(struct iwl_trans *trans, mod_timer(&txq->stuck_timer, jiffies + txq->wd_timeout); spin_lock_irqsave(&trans_pcie->reg_lock, flags); - if (!(cmd->flags & CMD_SEND_IN_IDLE) && - !trans_pcie->ref_cmd_in_flight) { - trans_pcie->ref_cmd_in_flight = true; - IWL_DEBUG_RPM(trans, "set ref_cmd_in_flight - ref\n"); - iwl_trans_ref(trans); - } /* Increment and update queue's write index */ txq->write_ptr = iwl_queue_inc_wrap(trans, txq->write_ptr); iwl_pcie_gen2_txq_inc_wr_ptr(trans, txq); @@ -1070,23 +1060,6 @@ void iwl_pcie_gen2_txq_unmap(struct iwl_trans *trans, int txq_id) } iwl_pcie_gen2_free_tfd(trans, txq); txq->read_ptr = iwl_queue_inc_wrap(trans, txq->read_ptr); - - if (txq->read_ptr == txq->write_ptr) { - unsigned long flags; - - spin_lock_irqsave(&trans_pcie->reg_lock, flags); - if (txq_id != trans_pcie->cmd_queue) { - IWL_DEBUG_RPM(trans, "Q %d - last tx freed\n", - txq->id); - iwl_trans_unref(trans); - } else if (trans_pcie->ref_cmd_in_flight) { - trans_pcie->ref_cmd_in_flight = false; - IWL_DEBUG_RPM(trans, - "clear ref_cmd_in_flight\n"); - iwl_trans_unref(trans); - } - spin_unlock_irqrestore(&trans_pcie->reg_lock, flags); - } } while (!skb_queue_empty(&txq->overflow_q)) { diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c index b25f51b5893c..45356195c228 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c @@ -639,12 +639,6 @@ static void iwl_pcie_clear_cmd_in_flight(struct iwl_trans *trans) lockdep_assert_held(&trans_pcie->reg_lock); - if (trans_pcie->ref_cmd_in_flight) { - trans_pcie->ref_cmd_in_flight = false; - IWL_DEBUG_RPM(trans, "clear ref_cmd_in_flight - unref\n"); - iwl_trans_unref(trans); - } - if (!trans->cfg->base_params->apmg_wake_up_wa) return; if (WARN_ON(!trans_pcie->cmd_hold_nic_awake)) @@ -683,13 +677,8 @@ static void iwl_pcie_txq_unmap(struct iwl_trans *trans, int txq_id) unsigned long flags; spin_lock_irqsave(&trans_pcie->reg_lock, flags); - if (txq_id != trans_pcie->cmd_queue) { - IWL_DEBUG_RPM(trans, "Q %d - last tx freed\n", - txq->id); - iwl_trans_unref(trans); - } else { + if (txq_id == trans_pcie->cmd_queue) iwl_pcie_clear_cmd_in_flight(trans); - } spin_unlock_irqrestore(&trans_pcie->reg_lock, flags); } } @@ -1225,11 +1214,6 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn, txq->overflow_tx = false; } - if (txq->read_ptr == txq->write_ptr) { - IWL_DEBUG_RPM(trans, "Q %d - last tx reclaimed\n", txq->id); - iwl_trans_unref(trans); - } - out: spin_unlock_bh(&txq->lock); } @@ -1261,13 +1245,6 @@ static int iwl_pcie_set_cmd_in_flight(struct iwl_trans *trans, if (test_bit(STATUS_TRANS_DEAD, &trans->status)) return -ENODEV; - if (!(cmd->flags & CMD_SEND_IN_IDLE) && - !trans_pcie->ref_cmd_in_flight) { - trans_pcie->ref_cmd_in_flight = true; - IWL_DEBUG_RPM(trans, "set ref_cmd_in_flight - ref\n"); - iwl_trans_ref(trans); - } - /* * wake up the NIC to make sure that the firmware will see the host * command - we will let the NIC sleep once all the host commands @@ -2518,22 +2495,18 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, wait_write_ptr = ieee80211_has_morefrags(fc); /* start timer if queue currently empty */ - if (txq->read_ptr == txq->write_ptr) { - if (txq->wd_timeout) { - /* - * If the TXQ is active, then set the timer, if not, - * set the timer in remainder so that the timer will - * be armed with the right value when the station will - * wake up. - */ - if (!txq->frozen) - mod_timer(&txq->stuck_timer, - jiffies + txq->wd_timeout); - else - txq->frozen_expiry_remainder = txq->wd_timeout; - } - IWL_DEBUG_RPM(trans, "Q: %d first tx - take ref\n", txq->id); - iwl_trans_ref(trans); + if (txq->read_ptr == txq->write_ptr && txq->wd_timeout) { + /* + * If the TXQ is active, then set the timer, if not, + * set the timer in remainder so that the timer will + * be armed with the right value when the station will + * wake up. + */ + if (!txq->frozen) + mod_timer(&txq->stuck_timer, + jiffies + txq->wd_timeout); + else + txq->frozen_expiry_remainder = txq->wd_timeout; } /* Tell device the write index *just past* this latest filled TFD */ From 043fa901736f5b9c388c7e366682b550699b9649 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 6 Jun 2019 12:07:30 +0300 Subject: [PATCH 31/80] iwlwifi: pcie: remove some more d0i3 code from the transport CMD_SEND_IN_IDLE, CMD_MAKE_TRANS_IDLE and CMD_WAKE_UP_TRANS are not used. Remove them. Signed-off-by: Emmanuel Grumbach Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/iwl-trans.h | 14 +---------- .../wireless/intel/iwlwifi/pcie/internal.h | 2 -- .../net/wireless/intel/iwlwifi/pcie/trans.c | 2 -- .../net/wireless/intel/iwlwifi/pcie/tx-gen2.c | 10 -------- drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 24 ------------------- 5 files changed, 1 insertion(+), 51 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h index 7c63706eb07b..687eced8b548 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h @@ -159,10 +159,6 @@ static inline u32 iwl_rx_packet_payload_len(const struct iwl_rx_packet *pkt) * @CMD_ASYNC: Return right away and don't wait for the response * @CMD_WANT_SKB: Not valid with CMD_ASYNC. The caller needs the buffer of * the response. The caller needs to call iwl_free_resp when done. - * @CMD_SEND_IN_IDLE: The command should be sent even when the trans is idle. - * @CMD_MAKE_TRANS_IDLE: The command response should mark the trans as idle. - * @CMD_WAKE_UP_TRANS: The command response should wake up the trans - * (i.e. mark it as non-idle). * @CMD_WANT_ASYNC_CALLBACK: the op_mode's async callback function must be * called after this command completes. Valid only with CMD_ASYNC. */ @@ -170,10 +166,7 @@ enum CMD_MODE { CMD_ASYNC = BIT(0), CMD_WANT_SKB = BIT(1), CMD_SEND_IN_RFKILL = BIT(2), - CMD_SEND_IN_IDLE = BIT(3), - CMD_MAKE_TRANS_IDLE = BIT(4), - CMD_WAKE_UP_TRANS = BIT(5), - CMD_WANT_ASYNC_CALLBACK = BIT(6), + CMD_WANT_ASYNC_CALLBACK = BIT(3), }; #define DEF_CMD_PAYLOAD_SIZE 320 @@ -659,11 +652,6 @@ enum iwl_plat_pm_mode { IWL_PLAT_PM_MODE_D3, }; -/* Max time to wait for trans to become idle/non-idle on d0i3 - * enter/exit (in msecs). - */ -#define IWL_TRANS_IDLE_TIMEOUT 2000 - /* Max time to wait for nmi interrupt */ #define IWL_TRANS_NMI_TIMEOUT (HZ / 4) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h index b5534fc33539..97f9f0aa5c5f 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h @@ -558,7 +558,6 @@ struct iwl_trans_pcie { bool ucode_write_complete; wait_queue_head_t ucode_write_waitq; wait_queue_head_t wait_command_queue; - wait_queue_head_t d0i3_waitq; u8 page_offs, dev_cmd_offs; @@ -581,7 +580,6 @@ struct iwl_trans_pcie { /*protect hw register */ spinlock_t reg_lock; bool cmd_hold_nic_awake; - bool ref_cmd_in_flight; #ifdef CONFIG_IWLWIFI_DEBUGFS struct cont_rec fw_mon_data; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index ad0c255d5f2e..081a3a37210b 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -3590,8 +3590,6 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, /* Initialize the wait queue for commands */ init_waitqueue_head(&trans_pcie->wait_command_queue); - init_waitqueue_head(&trans_pcie->d0i3_waitq); - if (trans_pcie->msix_enabled) { ret = iwl_pcie_init_msix_handler(pdev, trans_pcie); if (ret) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c index 5f52bf849a01..e65d4ef6de2b 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c @@ -926,16 +926,6 @@ static int iwl_pcie_gen2_send_hcmd_sync(struct iwl_trans *trans, IWL_DEBUG_INFO(trans, "Setting HCMD_ACTIVE for command %s\n", cmd_str); - if (pm_runtime_suspended(&trans_pcie->pci_dev->dev)) { - ret = wait_event_timeout(trans_pcie->d0i3_waitq, - pm_runtime_active(&trans_pcie->pci_dev->dev), - msecs_to_jiffies(IWL_TRANS_IDLE_TIMEOUT)); - if (!ret) { - IWL_ERR(trans, "Timeout exiting D0i3 before hcmd\n"); - return -ETIMEDOUT; - } - } - cmd_idx = iwl_pcie_gen2_enqueue_hcmd(trans, cmd); if (cmd_idx < 0) { ret = cmd_idx; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c index 45356195c228..9432374b69e2 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c @@ -1858,20 +1858,6 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans, wake_up(&trans_pcie->wait_command_queue); } - if (meta->flags & CMD_MAKE_TRANS_IDLE) { - IWL_DEBUG_INFO(trans, "complete %s - mark trans as idle\n", - iwl_get_cmd_string(trans, cmd->hdr.cmd)); - set_bit(STATUS_TRANS_IDLE, &trans->status); - wake_up(&trans_pcie->d0i3_waitq); - } - - if (meta->flags & CMD_WAKE_UP_TRANS) { - IWL_DEBUG_INFO(trans, "complete %s - clear trans idle flag\n", - iwl_get_cmd_string(trans, cmd->hdr.cmd)); - clear_bit(STATUS_TRANS_IDLE, &trans->status); - wake_up(&trans_pcie->d0i3_waitq); - } - meta->flags = 0; spin_unlock_bh(&txq->lock); @@ -1918,16 +1904,6 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans, IWL_DEBUG_INFO(trans, "Setting HCMD_ACTIVE for command %s\n", iwl_get_cmd_string(trans, cmd->id)); - if (pm_runtime_suspended(&trans_pcie->pci_dev->dev)) { - ret = wait_event_timeout(trans_pcie->d0i3_waitq, - pm_runtime_active(&trans_pcie->pci_dev->dev), - msecs_to_jiffies(IWL_TRANS_IDLE_TIMEOUT)); - if (!ret) { - IWL_ERR(trans, "Timeout exiting D0i3 before hcmd\n"); - return -ETIMEDOUT; - } - } - cmd_idx = iwl_pcie_enqueue_hcmd(trans, cmd); if (cmd_idx < 0) { ret = cmd_idx; From 75dfa6d58ba234f7a342e69756048519f115e1f3 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 6 Jun 2019 14:24:45 +0300 Subject: [PATCH 32/80] iwlwifi: remove the d0i3 related module parameters Those are now effectless. Signed-off-by: Emmanuel Grumbach Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 8 -------- drivers/net/wireless/intel/iwlwifi/iwl-modparams.h | 9 ++------- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c index 38672dd5aae9..7afc6e43502a 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c @@ -1704,8 +1704,6 @@ struct iwl_mod_params iwlwifi_mod_params = { .fw_restart = true, .bt_coex_active = true, .power_level = IWL_POWER_INDEX_1, - .d0i3_disable = true, - .d0i3_timeout = 1000, .uapsd_disable = IWL_DISABLE_UAPSD_BSS | IWL_DISABLE_UAPSD_P2P_CLIENT, /* the rest are 0 by default */ }; @@ -1823,9 +1821,6 @@ MODULE_PARM_DESC(antenna_coupling, module_param_named(nvm_file, iwlwifi_mod_params.nvm_file, charp, 0444); MODULE_PARM_DESC(nvm_file, "NVM file name"); -module_param_named(d0i3_disable, iwlwifi_mod_params.d0i3_disable, bool, 0444); -MODULE_PARM_DESC(d0i3_disable, "disable d0i3 functionality (default: Y)"); - module_param_named(lar_disable, iwlwifi_mod_params.lar_disable, bool, 0444); MODULE_PARM_DESC(lar_disable, "disable LAR functionality (default: N)"); @@ -1873,9 +1868,6 @@ module_param_named(fw_monitor, iwlwifi_mod_params.fw_monitor, bool, 0444); MODULE_PARM_DESC(fw_monitor, "firmware monitor - to debug FW (default: false - needs lots of memory)"); -module_param_named(d0i3_timeout, iwlwifi_mod_params.d0i3_timeout, uint, 0444); -MODULE_PARM_DESC(d0i3_timeout, "Timeout to D0i3 entry when idle (ms)"); - module_param_named(disable_11ac, iwlwifi_mod_params.disable_11ac, bool, 0444); MODULE_PARM_DESC(disable_11ac, "Disable VHT capabilities (default: false)"); diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-modparams.h b/drivers/net/wireless/intel/iwlwifi/iwl-modparams.h index 0cae2ef9b9df..ebea3f308b5d 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-modparams.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-modparams.h @@ -6,7 +6,7 @@ * GPL LICENSE SUMMARY * * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. - * 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) 2005 - 2014 Intel Corporation. All rights reserved. - * 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 @@ -115,9 +115,6 @@ enum iwl_uapsd_disable { * @nvm_file: specifies a external NVM file * @uapsd_disable: disable U-APSD, see &enum iwl_uapsd_disable, default = * IWL_DISABLE_UAPSD_BSS | IWL_DISABLE_UAPSD_P2P_CLIENT - * @d0i3_disable: disable d0i3, default = 1, - * @d0i3_timeout: time to wait after no refs are taken before - * entering D0i3 (in msecs) * @lar_disable: disable LAR (regulatory), default = 0 * @fw_monitor: allow to use firmware monitor * @disable_11ac: disable VHT capabilities, default = false. @@ -139,8 +136,6 @@ struct iwl_mod_params { int antenna_coupling; char *nvm_file; u32 uapsd_disable; - bool d0i3_disable; - unsigned int d0i3_timeout; bool lar_disable; bool fw_monitor; bool disable_11ac; From bab3cb9285a736165bbd51d327ee78d0edc061b2 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 6 Jun 2019 14:56:14 +0300 Subject: [PATCH 33/80] iwlwifi: remove pm_runtime completely This means: 1) stop calling pm_runtime_resume when starting the hardware 2) removing the unneeded low_power parameter to start / stop hw / fw transport ops 3) squashing transport functions that are now the same _iwl_trans_pcie_start_hw / iwl_trans_pcie_start_hw Signed-off-by: Emmanuel Grumbach Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/iwl-trans.h | 33 ++++++------------- drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 9 ++--- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 1 - .../wireless/intel/iwlwifi/pcie/internal.h | 5 ++- .../wireless/intel/iwlwifi/pcie/trans-gen2.c | 6 ++-- .../net/wireless/intel/iwlwifi/pcie/trans.c | 21 +++++------- .../net/wireless/intel/iwlwifi/pcie/tx-gen2.c | 1 - drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 1 - 8 files changed, 25 insertions(+), 52 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h index 687eced8b548..fce0112b3ad4 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h @@ -452,9 +452,8 @@ struct iwl_trans_rxq_dma_data { * * All the handlers MUST be implemented * - * @start_hw: starts the HW. If low_power is true, the NIC needs to be taken - * out of a low power state. From that point on, the HW can send - * interrupts. May sleep. + * @start_hw: starts the HW. From that point on, the HW can send interrupts. + * May sleep. * @op_mode_leave: Turn off the HW RF kill indication if on * May sleep * @start_fw: allocates and inits all the resources for the transport @@ -464,9 +463,8 @@ struct iwl_trans_rxq_dma_data { * the SCD base address in SRAM, then provide it here, or 0 otherwise. * May sleep * @stop_device: stops the whole device (embedded CPU put to reset) and stops - * the HW. If low_power is true, the NIC will be put in low power state. - * From that point on, the HW will be stopped but will still issue an - * interrupt if the HW RF kill switch is triggered. + * the HW. From that point on, the HW will be stopped but will still issue + * an interrupt if the HW RF kill switch is triggered. * This callback must do the right thing and not crash even if %start_hw() * was called but not &start_fw(). May sleep. * @d3_suspend: put the device into the correct mode for WoWLAN during @@ -532,12 +530,12 @@ struct iwl_trans_rxq_dma_data { */ struct iwl_trans_ops { - int (*start_hw)(struct iwl_trans *iwl_trans, bool low_power); + int (*start_hw)(struct iwl_trans *iwl_trans); void (*op_mode_leave)(struct iwl_trans *iwl_trans); int (*start_fw)(struct iwl_trans *trans, const struct fw_img *fw, bool run_in_rfkill); void (*fw_alive)(struct iwl_trans *trans, u32 scd_addr); - void (*stop_device)(struct iwl_trans *trans, bool low_power); + void (*stop_device)(struct iwl_trans *trans); void (*d3_suspend)(struct iwl_trans *trans, bool test, bool reset); int (*d3_resume)(struct iwl_trans *trans, enum iwl_d3_status *status, @@ -819,16 +817,11 @@ static inline void iwl_trans_configure(struct iwl_trans *trans, WARN_ON(iwl_cmd_groups_verify_sorted(trans_cfg)); } -static inline int _iwl_trans_start_hw(struct iwl_trans *trans, bool low_power) +static inline int iwl_trans_start_hw(struct iwl_trans *trans) { might_sleep(); - return trans->ops->start_hw(trans, low_power); -} - -static inline int iwl_trans_start_hw(struct iwl_trans *trans) -{ - return trans->ops->start_hw(trans, true); + return trans->ops->start_hw(trans); } static inline void iwl_trans_op_mode_leave(struct iwl_trans *trans) @@ -864,21 +857,15 @@ static inline int iwl_trans_start_fw(struct iwl_trans *trans, return trans->ops->start_fw(trans, fw, run_in_rfkill); } -static inline void _iwl_trans_stop_device(struct iwl_trans *trans, - bool low_power) +static inline void iwl_trans_stop_device(struct iwl_trans *trans) { might_sleep(); - trans->ops->stop_device(trans, low_power); + trans->ops->stop_device(trans); trans->state = IWL_TRANS_NO_FW; } -static inline void iwl_trans_stop_device(struct iwl_trans *trans) -{ - _iwl_trans_stop_device(trans, true); -} - static inline void iwl_trans_d3_suspend(struct iwl_trans *trans, bool test, bool reset) { diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index 411a79e15333..0f6925a51435 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -1141,13 +1141,8 @@ static int iwl_mvm_load_rt_fw(struct iwl_mvm *mvm) } iwl_fw_dbg_stop_sync(&mvm->fwrt); - /* - * Stop and start the transport without entering low power - * mode. This will save the state of other components on the - * device that are triggered by the INIT firwmare (MFUART). - */ - _iwl_trans_stop_device(mvm->trans, false); - ret = _iwl_trans_start_hw(mvm->trans, false); + iwl_trans_stop_device(mvm->trans); + ret = iwl_trans_start_hw(mvm->trans); if (ret) return ret; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index df722ed6a6ec..c02cb976cafe 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -65,7 +65,6 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include -#include #include #include diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h index 97f9f0aa5c5f..95f78d8b4ae5 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h @@ -1109,9 +1109,8 @@ int iwl_trans_pcie_gen2_tx(struct iwl_trans *trans, struct sk_buff *skb, struct iwl_device_cmd *dev_cmd, int txq_id); int iwl_trans_pcie_gen2_send_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd); -void iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans, - bool low_power); -void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans, bool low_power); +void iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans); +void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans); void iwl_pcie_gen2_txq_unmap(struct iwl_trans *trans, int txq_id); void iwl_pcie_gen2_tx_free(struct iwl_trans *trans); void iwl_pcie_gen2_tx_stop(struct iwl_trans *trans); diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c index 104b7cc75248..c099ad8b003f 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c @@ -136,7 +136,7 @@ static void iwl_pcie_gen2_apm_stop(struct iwl_trans *trans, bool op_mode_leave) BIT(trans->cfg->csr->flag_init_done)); } -void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans, bool low_power) +void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); @@ -215,7 +215,7 @@ void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans, bool low_power) iwl_pcie_prepare_card_hw(trans); } -void iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans, bool low_power) +void iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); bool was_in_rfkill; @@ -223,7 +223,7 @@ void iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans, bool low_power) mutex_lock(&trans_pcie->mutex); trans_pcie->opmode_down = true; was_in_rfkill = test_bit(STATUS_RFKILL_OPMODE, &trans->status); - _iwl_trans_pcie_gen2_stop_device(trans, low_power); + _iwl_trans_pcie_gen2_stop_device(trans); iwl_trans_pcie_handle_stop_rfkill(trans, was_in_rfkill); mutex_unlock(&trans_pcie->mutex); } diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index 081a3a37210b..073d2ec99348 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -69,7 +69,6 @@ #include #include #include -#include #include #include @@ -1231,7 +1230,7 @@ static void iwl_pcie_init_msix(struct iwl_trans_pcie *trans_pcie) trans_pcie->hw_mask = trans_pcie->hw_init_mask; } -static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool low_power) +static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); @@ -1448,7 +1447,7 @@ void iwl_trans_pcie_handle_stop_rfkill(struct iwl_trans *trans, iwl_trans_pcie_rf_kill(trans, hw_rfkill); } -static void iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool low_power) +static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); bool was_in_rfkill; @@ -1456,7 +1455,7 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool low_power) mutex_lock(&trans_pcie->mutex); trans_pcie->opmode_down = true; was_in_rfkill = test_bit(STATUS_RFKILL_OPMODE, &trans->status); - _iwl_trans_pcie_stop_device(trans, low_power); + _iwl_trans_pcie_stop_device(trans); iwl_trans_pcie_handle_stop_rfkill(trans, was_in_rfkill); mutex_unlock(&trans_pcie->mutex); } @@ -1472,9 +1471,9 @@ void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state) state ? "disabled" : "enabled"); if (iwl_op_mode_hw_rf_kill(trans->op_mode, state)) { if (trans->cfg->gen2) - _iwl_trans_pcie_gen2_stop_device(trans, true); + _iwl_trans_pcie_gen2_stop_device(trans); else - _iwl_trans_pcie_stop_device(trans, true); + _iwl_trans_pcie_stop_device(trans); } } @@ -1733,7 +1732,7 @@ static int iwl_trans_pcie_clear_persistence_bit(struct iwl_trans *trans) return 0; } -static int _iwl_trans_pcie_start_hw(struct iwl_trans *trans, bool low_power) +static int _iwl_trans_pcie_start_hw(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); int err; @@ -1769,20 +1768,16 @@ static int _iwl_trans_pcie_start_hw(struct iwl_trans *trans, bool low_power) /* ...rfkill can call stop_device and set it false if needed */ iwl_pcie_check_hw_rf_kill(trans); - /* Make sure we sync here, because we'll need full access later */ - if (low_power) - pm_runtime_resume(trans->dev); - return 0; } -static int iwl_trans_pcie_start_hw(struct iwl_trans *trans, bool low_power) +static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); int ret; mutex_lock(&trans_pcie->mutex); - ret = _iwl_trans_pcie_start_hw(trans, low_power); + ret = _iwl_trans_pcie_start_hw(trans); mutex_unlock(&trans_pcie->mutex); return ret; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c index e65d4ef6de2b..70a15364190c 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c @@ -50,7 +50,6 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *****************************************************************************/ -#include #include #include diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c index 9432374b69e2..8b7b918e71ad 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c @@ -65,7 +65,6 @@ #include #include #include -#include #include #include From b5baefdad2fe9368498df95af8cee854193d0ea3 Mon Sep 17 00:00:00 2001 From: Ayala Beker Date: Mon, 17 Jun 2019 20:15:55 +0300 Subject: [PATCH 34/80] iwlwifi: scan: don't pass large argument by value Function iwl_mvm_scan_set_legacy_probe_req() second argument size is too large to be passed by value. Fix it to be passed by reference. Signed-off-by: Ayala Beker Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c index 85e33310804e..afa44345f37b 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c @@ -961,15 +961,15 @@ static int iwl_mvm_scan_lmac_flags(struct iwl_mvm *mvm, static void iwl_mvm_scan_set_legacy_probe_req(struct iwl_scan_probe_req_v1 *p_req, - struct iwl_scan_probe_req src_p_req) + struct iwl_scan_probe_req *src_p_req) { int i; - p_req->mac_header = src_p_req.mac_header; + p_req->mac_header = src_p_req->mac_header; for (i = 0; i < SCAN_NUM_BAND_PROBE_DATA_V_1; i++) - p_req->band_data[i] = src_p_req.band_data[i]; - p_req->common_data = src_p_req.common_data; - memcpy(p_req->buf, src_p_req.buf, SCAN_OFFLOAD_PROBE_REQ_SIZE); + p_req->band_data[i] = src_p_req->band_data[i]; + p_req->common_data = src_p_req->common_data; + memcpy(p_req->buf, src_p_req->buf, sizeof(p_req->buf)); } static int iwl_mvm_scan_lmac(struct iwl_mvm *mvm, struct ieee80211_vif *vif, @@ -1046,7 +1046,7 @@ static int iwl_mvm_scan_lmac(struct iwl_mvm *mvm, struct ieee80211_vif *vif, iwl_mvm_lmac_scan_cfg_channels(mvm, params->channels, params->n_channels, ssid_bitmap, cmd); - iwl_mvm_scan_set_legacy_probe_req(preq, params->preq); + iwl_mvm_scan_set_legacy_probe_req(preq, ¶ms->preq); return 0; } @@ -1592,7 +1592,8 @@ static int iwl_mvm_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif, direct_scan = tail_v2->direct_scan; } else { tail_v1 = (struct iwl_scan_req_umac_tail_v1 *)sec_part; - iwl_mvm_scan_set_legacy_probe_req(&tail_v1->preq, params->preq); + iwl_mvm_scan_set_legacy_probe_req(&tail_v1->preq, + ¶ms->preq); direct_scan = tail_v1->direct_scan; } iwl_scan_build_ssids(params, direct_scan, &ssid_bitmap); From 41874d3a0b992f03b2bd717041d7ccf29dba3844 Mon Sep 17 00:00:00 2001 From: Shahar S Matityahu Date: Thu, 13 Jun 2019 15:01:07 +0300 Subject: [PATCH 35/80] iwlwifi: dbg_ini: align dbg tlv functions names to a single format align the naming to iwl_dbg_tlv_* Signed-off-by: Shahar S Matityahu Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/iwl-dbg-tlv.c | 20 +++++++++---------- .../net/wireless/intel/iwlwifi/iwl-dbg-tlv.h | 14 ++++++------- drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 10 +++++----- 3 files changed, 22 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 fcaec410b3be..240e48b1d1c7 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c @@ -63,8 +63,8 @@ #include "iwl-trans.h" #include "iwl-dbg-tlv.h" -void iwl_fw_dbg_copy_tlv(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv, - bool ext) +void iwl_dbg_tlv_copy(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv, + bool ext) { struct iwl_apply_point_data *data; struct iwl_fw_ini_header *header = (void *)&tlv->data[0]; @@ -106,7 +106,7 @@ void iwl_fw_dbg_copy_tlv(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv, data->offset += offset_size; } -void iwl_alloc_dbg_tlv(struct iwl_trans *trans, size_t len, const u8 *data, +void iwl_dbg_tlv_alloc(struct iwl_trans *trans, size_t len, const u8 *data, bool ext) { struct iwl_ucode_tlv *tlv; @@ -183,7 +183,7 @@ void iwl_alloc_dbg_tlv(struct iwl_trans *trans, size_t len, const u8 *data, } } -void iwl_fw_dbg_free(struct iwl_trans *trans) +void iwl_dbg_tlv_free(struct iwl_trans *trans) { int i; @@ -198,8 +198,8 @@ void iwl_fw_dbg_free(struct iwl_trans *trans) } } -static int iwl_parse_fw_dbg_tlv(struct iwl_trans *trans, const u8 *data, - size_t len) +static int iwl_dbg_tlv_parse_bin(struct iwl_trans *trans, const u8 *data, + size_t len) { struct iwl_ucode_tlv *tlv; enum iwl_ucode_tlv_type tlv_type; @@ -227,7 +227,7 @@ static int iwl_parse_fw_dbg_tlv(struct iwl_trans *trans, const u8 *data, case IWL_UCODE_TLV_TYPE_REGIONS: case IWL_UCODE_TLV_TYPE_TRIGGERS: case IWL_UCODE_TLV_TYPE_DEBUG_FLOW: - iwl_fw_dbg_copy_tlv(trans, tlv, true); + iwl_dbg_tlv_copy(trans, tlv, true); break; default: WARN_ONCE(1, "Invalid TLV %x\n", tlv_type); @@ -238,7 +238,7 @@ static int iwl_parse_fw_dbg_tlv(struct iwl_trans *trans, const u8 *data, return 0; } -void iwl_load_fw_dbg_tlv(struct device *dev, struct iwl_trans *trans) +void iwl_dbg_tlv_load_bin(struct device *dev, struct iwl_trans *trans) { const struct firmware *fw; int res; @@ -250,8 +250,8 @@ void iwl_load_fw_dbg_tlv(struct device *dev, struct iwl_trans *trans) if (res) return; - iwl_alloc_dbg_tlv(trans, fw->size, fw->data, true); - iwl_parse_fw_dbg_tlv(trans, fw->data, fw->size); + iwl_dbg_tlv_alloc(trans, fw->size, fw->data, true); + iwl_dbg_tlv_parse_bin(trans, fw->data, fw->size); trans->dbg.external_ini_loaded = true; release_firmware(fw); diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h index 222cd789e07a..e4911ec6ce13 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright (C) 2018 Intel Corporation + * Copyright (C) 2018 - 2019 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -28,7 +28,7 @@ * * BSD LICENSE * - * Copyright (C) 2018 Intel Corporation + * Copyright (C) 2018 - 2019 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -77,11 +77,11 @@ struct iwl_apply_point_data { }; struct iwl_trans; -void iwl_load_fw_dbg_tlv(struct device *dev, struct iwl_trans *trans); -void iwl_fw_dbg_free(struct iwl_trans *trans); -void iwl_fw_dbg_copy_tlv(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv, - bool ext); -void iwl_alloc_dbg_tlv(struct iwl_trans *trans, size_t len, const u8 *data, +void iwl_dbg_tlv_load_bin(struct device *dev, struct iwl_trans *trans); +void iwl_dbg_tlv_free(struct iwl_trans *trans); +void iwl_dbg_tlv_copy(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv, + bool ext); +void iwl_dbg_tlv_alloc(struct iwl_trans *trans, size_t len, const u8 *data, bool ext); #endif /* __iwl_dbg_tlv_h__*/ diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c index 7afc6e43502a..595dc2fbc3b3 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c @@ -648,7 +648,7 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, len -= sizeof(*ucode); if (iwlwifi_mod_params.enable_ini) - iwl_alloc_dbg_tlv(drv->trans, len, data, false); + iwl_dbg_tlv_alloc(drv->trans, len, data, false); while (len >= sizeof(*tlv)) { len -= sizeof(*tlv); @@ -1156,7 +1156,7 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, case IWL_UCODE_TLV_TYPE_TRIGGERS: case IWL_UCODE_TLV_TYPE_DEBUG_FLOW: if (iwlwifi_mod_params.enable_ini) - iwl_fw_dbg_copy_tlv(drv->trans, tlv, false); + iwl_dbg_tlv_copy(drv->trans, tlv, false); break; case IWL_UCODE_TLV_CMD_VERSIONS: if (tlv_len % sizeof(struct iwl_fw_cmd_version)) { @@ -1640,7 +1640,7 @@ struct iwl_drv *iwl_drv_start(struct iwl_trans *trans) init_completion(&drv->request_firmware_complete); INIT_LIST_HEAD(&drv->list); - iwl_load_fw_dbg_tlv(drv->trans->dev, drv->trans); + iwl_dbg_tlv_load_bin(drv->trans->dev, drv->trans); #ifdef CONFIG_IWLWIFI_DEBUGFS /* Create the device debugfs entries. */ @@ -1662,8 +1662,8 @@ struct iwl_drv *iwl_drv_start(struct iwl_trans *trans) err_fw: #ifdef CONFIG_IWLWIFI_DEBUGFS debugfs_remove_recursive(drv->dbgfs_drv); + iwl_dbg_tlv_free(drv->trans); #endif - iwl_fw_dbg_free(drv->trans); kfree(drv); err: return ERR_PTR(ret); @@ -1693,7 +1693,7 @@ void iwl_drv_stop(struct iwl_drv *drv) debugfs_remove_recursive(drv->dbgfs_drv); #endif - iwl_fw_dbg_free(drv->trans); + iwl_dbg_tlv_free(drv->trans); kfree(drv); } From 1971c4f9d9a64f51477a3bea98bc586dff960609 Mon Sep 17 00:00:00 2001 From: Haim Dreyfuss Date: Thu, 13 Jun 2019 13:10:50 +0300 Subject: [PATCH 36/80] iwlwifi: remove unused regdb_ptrs allocation regdb_ptrs is not in used anymore, remove it. Signed-off-by: Haim Dreyfuss Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c index d87a6bb3e456..fd386bfbd5df 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c @@ -1066,11 +1066,6 @@ static u32 iwl_nvm_get_regdom_bw_flags(const u16 *nvm_chan, return flags; } -struct regdb_ptrs { - struct ieee80211_wmm_rule *rule; - u32 token; -}; - struct ieee80211_regdomain * iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg, int num_of_ch, __le32 *channels, u16 fw_mcc, @@ -1082,7 +1077,6 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg, const u16 *nvm_chan; struct ieee80211_regdomain *regd, *copy_rd; struct ieee80211_reg_rule *rule; - struct regdb_ptrs *regdb_ptrs; enum nl80211_band band; int center_freq, prev_center_freq = 0; int valid_rules = 0; @@ -1114,12 +1108,6 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg, if (!regd) return ERR_PTR(-ENOMEM); - regdb_ptrs = kcalloc(num_of_ch, sizeof(*regdb_ptrs), GFP_KERNEL); - if (!regdb_ptrs) { - copy_rd = ERR_PTR(-ENOMEM); - goto out; - } - /* set alpha2 from FW. */ regd->alpha2[0] = fw_mcc >> 8; regd->alpha2[1] = fw_mcc & 0xff; @@ -1191,8 +1179,6 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg, if (!copy_rd) copy_rd = ERR_PTR(-ENOMEM); -out: - kfree(regdb_ptrs); kfree(regd); return copy_rd; } From 15995b759307b39dc28d4480db970eacd9a2a80c Mon Sep 17 00:00:00 2001 From: Shahar S Matityahu Date: Mon, 24 Jun 2019 10:37:05 +0300 Subject: [PATCH 37/80] iwlwifi: dbg: add debug periphery registers to 9000 device family Add debug HW periphery registers to 9000 device family. Signed-off-by: Shahar S Matityahu Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 34f4cda3b090..40b867f984cf 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -468,6 +468,9 @@ static const struct iwl_prph_range iwl_prph_dump_addr_9000[] = { { .start = 0x00a05400, .end = 0x00a056e8 }, { .start = 0x00a08000, .end = 0x00a098bc }, { .start = 0x00a02400, .end = 0x00a02758 }, + { .start = 0x00a04764, .end = 0x00a0476c }, + { .start = 0x00a04770, .end = 0x00a04774 }, + { .start = 0x00a04620, .end = 0x00a04624 }, }; static const struct iwl_prph_range iwl_prph_dump_addr_22000[] = { From ccdc3d6d15555b170a977e9dd82c5e9db465f10a Mon Sep 17 00:00:00 2001 From: Shahar S Matityahu Date: Thu, 13 Jun 2019 08:29:55 +0300 Subject: [PATCH 38/80] iwlwifi: dbg_ini: maintain buffer allocations from trans instead of TLVs buffer Maintain DRAM debug buffer status in trans instead of keeping it as part of the TLVs buffer to avoid allocating extra space for it. Needed for future changes. Signed-off-by: Shahar S Matityahu Signed-off-by: Luca Coelho --- .../wireless/intel/iwlwifi/fw/api/dbg-tlv.h | 2 ++ drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 31 ++++++++++--------- drivers/net/wireless/intel/iwlwifi/fw/img.h | 9 ------ .../net/wireless/intel/iwlwifi/iwl-dbg-tlv.c | 18 ----------- .../net/wireless/intel/iwlwifi/iwl-trans.h | 4 ++- 5 files changed, 21 insertions(+), 43 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h b/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h index aaf3974a9a20..e02e289d29b1 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h @@ -439,6 +439,7 @@ enum iwl_fw_ini_apply_point { * @IWL_FW_INI_ALLOCATION_ID_SDFX: for SDFX module * @IWL_FW_INI_ALLOCATION_ID_FW_DUMP: used for crash and runtime dumps * @IWL_FW_INI_ALLOCATION_ID_USER_DEFINED: for future user scenarios + * @IWL_FW_INI_ALLOCATION_NUM: number of allocation ids */ enum iwl_fw_ini_allocation_id { IWL_FW_INI_ALLOCATION_INVALID, @@ -448,6 +449,7 @@ enum iwl_fw_ini_allocation_id { IWL_FW_INI_ALLOCATION_ID_SDFX, IWL_FW_INI_ALLOCATION_ID_FW_DUMP, IWL_FW_INI_ALLOCATION_ID_USER_DEFINED, + IWL_FW_INI_ALLOCATION_NUM, }; /* FW_DEBUG_TLV_ALLOCATION_ID_E_VER_1 */ /** diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 40b867f984cf..6d69ed17e7f8 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -2503,7 +2503,7 @@ iwl_fw_dbg_buffer_allocation(struct iwl_fw_runtime *fwrt, u32 size) } static void iwl_fw_dbg_buffer_apply(struct iwl_fw_runtime *fwrt, - struct iwl_fw_ini_allocation_data *alloc, + struct iwl_fw_ini_allocation_tlv *alloc, enum iwl_fw_ini_apply_point pnt) { struct iwl_trans *trans = fwrt->trans; @@ -2518,7 +2518,14 @@ static void iwl_fw_dbg_buffer_apply(struct iwl_fw_runtime *fwrt, .len[0] = sizeof(ldbg_cmd), }; int block_idx = trans->dbg.num_blocks; - u32 buf_location = le32_to_cpu(alloc->tlv.buffer_location); + u32 buf_location = le32_to_cpu(alloc->buffer_location); + u32 alloc_id = le32_to_cpu(alloc->allocation_id); + + if (alloc_id <= IWL_FW_INI_ALLOCATION_INVALID || + alloc_id >= IWL_FW_INI_ALLOCATION_NUM) { + IWL_ERR(fwrt, "WRT: Invalid allocation id %d\n", alloc_id); + return; + } if (fwrt->trans->dbg.ini_dest == IWL_FW_INI_LOCATION_INVALID) fwrt->trans->dbg.ini_dest = buf_location; @@ -2543,12 +2550,11 @@ static void iwl_fw_dbg_buffer_apply(struct iwl_fw_runtime *fwrt, if (buf_location != IWL_FW_INI_LOCATION_DRAM_PATH) return; - if (!alloc->is_alloc) { - iwl_fw_dbg_buffer_allocation(fwrt, - le32_to_cpu(alloc->tlv.size)); + if (!(BIT(alloc_id) & fwrt->trans->dbg.is_alloc)) { + iwl_fw_dbg_buffer_allocation(fwrt, le32_to_cpu(alloc->size)); if (block_idx == trans->dbg.num_blocks) return; - alloc->is_alloc = 1; + fwrt->trans->dbg.is_alloc |= BIT(alloc_id); } /* First block is assigned via registers / context info */ @@ -2561,9 +2567,9 @@ static void iwl_fw_dbg_buffer_apply(struct iwl_fw_runtime *fwrt, cmd->num_frags = cpu_to_le32(1); cmd->fragments[0].address = cpu_to_le64(trans->dbg.fw_mon[block_idx].physical); - cmd->fragments[0].size = alloc->tlv.size; - cmd->allocation_id = alloc->tlv.allocation_id; - cmd->buffer_location = alloc->tlv.buffer_location; + cmd->fragments[0].size = alloc->size; + cmd->allocation_id = alloc->allocation_id; + cmd->buffer_location = alloc->buffer_location; iwl_trans_send_cmd(trans, &hcmd); } @@ -2788,20 +2794,15 @@ static void _iwl_fw_dbg_apply_point(struct iwl_fw_runtime *fwrt, case IWL_UCODE_TLV_TYPE_DEBUG_INFO: iwl_fw_dbg_info_apply(fwrt, ini_tlv, ext, pnt); break; - case IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION: { - struct iwl_fw_ini_allocation_data *buf_alloc = ini_tlv; - + case IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION: if (pnt != IWL_FW_INI_APPLY_EARLY) { IWL_ERR(fwrt, "WRT: ext=%d. Invalid apply point %d for buffer allocation\n", ext, pnt); goto next; } - iwl_fw_dbg_buffer_apply(fwrt, ini_tlv, pnt); - iter += sizeof(buf_alloc->is_alloc); break; - } case IWL_UCODE_TLV_TYPE_HCMD: if (pnt < IWL_FW_INI_APPLY_AFTER_ALIVE) { IWL_ERR(fwrt, diff --git a/drivers/net/wireless/intel/iwlwifi/fw/img.h b/drivers/net/wireless/intel/iwlwifi/fw/img.h index 18ca5f152be6..039576d71276 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/img.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/img.h @@ -227,15 +227,6 @@ struct iwl_fw_dbg { u32 dump_mask; }; -/** - * @tlv: the buffer allocation tlv - * @is_alloc: indicates if the buffer was already allocated - */ -struct iwl_fw_ini_allocation_data { - struct iwl_fw_ini_allocation_tlv tlv; - u32 is_alloc; -} __packed; - /** * struct iwl_fw_ini_active_triggers * @active: is this trigger active diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c index 240e48b1d1c7..5948d769eed0 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c @@ -85,14 +85,6 @@ void iwl_dbg_tlv_copy(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv, else data = &trans->dbg.apply_points[apply_point]; - /* add room for is_alloc field in &iwl_fw_ini_allocation_data struct */ - if (le32_to_cpu(tlv->type) == IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION) { - struct iwl_fw_ini_allocation_data *buf_alloc = - (void *)tlv->data; - - offset_size += sizeof(buf_alloc->is_alloc); - } - /* * Make sure we still have room to copy this TLV. Offset points to the * location the last copy ended. @@ -145,16 +137,6 @@ void iwl_dbg_tlv_alloc(struct iwl_trans *trans, size_t len, const u8 *data, if (WARN_ON(apply >= IWL_FW_INI_APPLY_NUM)) continue; - /* add room for is_alloc field in &iwl_fw_ini_allocation_data - * struct - */ - if (tlv_type == IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION) { - struct iwl_fw_ini_allocation_data *buf_alloc = - (void *)tlv->data; - - size[apply] += sizeof(buf_alloc->is_alloc); - } - size[apply] += sizeof(*tlv) + tlv_len; } diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h index fce0112b3ad4..0fa4b100f109 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h @@ -695,6 +695,7 @@ struct iwl_self_init_dram { * @ini_valid: indicates if debug ini mode is on * @num_blocks: number of blocks in fw_mon * @fw_mon: address of the buffers for firmware monitor + * @is_alloc: bit i is set if buffer i was allocated * @hw_error: equals true if hw error interrupt was received from the FW * @ini_dest: debug monitor destination uses &enum iwl_fw_ini_buffer_location */ @@ -717,7 +718,8 @@ struct iwl_trans_debug { struct iwl_apply_point_data apply_points_ext[IWL_FW_INI_APPLY_NUM]; int num_blocks; - struct iwl_dram_data fw_mon[IWL_FW_INI_APPLY_NUM]; + struct iwl_dram_data fw_mon[IWL_FW_INI_ALLOCATION_NUM]; + u32 is_alloc; bool hw_error; enum iwl_fw_ini_buffer_location ini_dest; From 40b7d22d1f0e9697bb78c9da377e06efa925d035 Mon Sep 17 00:00:00 2001 From: Shahar S Matityahu Date: Mon, 10 Jun 2019 16:14:20 +0300 Subject: [PATCH 39/80] iwlwifi: dbg_ini: use linked list to store debug TLVs Use a linked list to maintain the debug TLVs instead of a single buffer. This way, the driver does not need to iterate over the binary file twice and allocates smaller chunks of memory. Also, in case one allocation fails the driver will work with the partial configuration instead of aborting the entire debug configuration. Signed-off-by: Shahar S Matityahu Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 15 +-- .../net/wireless/intel/iwlwifi/iwl-dbg-tlv.c | 119 ++++++------------ .../net/wireless/intel/iwlwifi/iwl-dbg-tlv.h | 12 +- drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 3 - 4 files changed, 48 insertions(+), 101 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 6d69ed17e7f8..78e13cd182cb 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -2783,10 +2783,13 @@ static void _iwl_fw_dbg_apply_point(struct iwl_fw_runtime *fwrt, enum iwl_fw_ini_apply_point pnt, bool ext) { - void *iter = data->data; + struct iwl_apply_point_data *iter; - while (iter && iter < data->data + data->size) { - struct iwl_ucode_tlv *tlv = iter; + if (!data->list.next) + return; + + list_for_each_entry(iter, &data->list, list) { + struct iwl_ucode_tlv *tlv = &iter->tlv; void *ini_tlv = (void *)tlv->data; u32 type = le32_to_cpu(tlv->type); @@ -2799,7 +2802,7 @@ static void _iwl_fw_dbg_apply_point(struct iwl_fw_runtime *fwrt, IWL_ERR(fwrt, "WRT: ext=%d. Invalid apply point %d for buffer allocation\n", ext, pnt); - goto next; + break; } iwl_fw_dbg_buffer_apply(fwrt, ini_tlv, pnt); break; @@ -2808,7 +2811,7 @@ static void _iwl_fw_dbg_apply_point(struct iwl_fw_runtime *fwrt, IWL_ERR(fwrt, "WRT: ext=%d. Invalid apply point %d for host command\n", ext, pnt); - goto next; + break; } iwl_fw_dbg_send_hcmd(fwrt, tlv, ext); break; @@ -2826,8 +2829,6 @@ static void _iwl_fw_dbg_apply_point(struct iwl_fw_runtime *fwrt, ext, type); break; } -next: - iter += sizeof(*tlv) + le32_to_cpu(tlv->length); } } diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c index 5948d769eed0..7c1e76ee7ede 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c @@ -66,102 +66,56 @@ void iwl_dbg_tlv_copy(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv, bool ext) { - struct iwl_apply_point_data *data; + struct iwl_apply_point_data *dbg_cfg, *tlv_copy; struct iwl_fw_ini_header *header = (void *)&tlv->data[0]; + u32 tlv_type = le32_to_cpu(tlv->type); + u32 len = le32_to_cpu(tlv->length); u32 apply_point = le32_to_cpu(header->apply_point); - int copy_size = le32_to_cpu(tlv->length) + sizeof(*tlv); - int offset_size = copy_size; - if (le32_to_cpu(header->tlv_version) != 1) return; if (WARN_ONCE(apply_point >= IWL_FW_INI_APPLY_NUM, - "Invalid apply point id %d\n", apply_point)) + "Invalid apply point %d\n", apply_point)) return; + IWL_DEBUG_FW(trans, "WRT: read TLV 0x%x, apply point %d\n", + tlv_type, apply_point); + if (ext) - data = &trans->dbg.apply_points_ext[apply_point]; + dbg_cfg = &trans->dbg.apply_points_ext[apply_point]; else - data = &trans->dbg.apply_points[apply_point]; + dbg_cfg = &trans->dbg.apply_points[apply_point]; - /* - * Make sure we still have room to copy this TLV. Offset points to the - * location the last copy ended. - */ - if (WARN_ONCE(data->offset + offset_size > data->size, - "Not enough memory for apply point %d\n", - apply_point)) + tlv_copy = kzalloc(sizeof(*tlv_copy) + len, GFP_KERNEL); + if (!tlv_copy) { + IWL_ERR(trans, "WRT: No memory for TLV 0x%x, apply point %d\n", + tlv_type, apply_point); return; - - memcpy(data->data + data->offset, (void *)tlv, copy_size); - data->offset += offset_size; -} - -void iwl_dbg_tlv_alloc(struct iwl_trans *trans, size_t len, const u8 *data, - bool ext) -{ - struct iwl_ucode_tlv *tlv; - u32 size[IWL_FW_INI_APPLY_NUM] = {0}; - int i; - - while (len >= sizeof(*tlv)) { - u32 tlv_len, tlv_type, apply; - struct iwl_fw_ini_header *hdr; - - len -= sizeof(*tlv); - tlv = (void *)data; - - tlv_len = le32_to_cpu(tlv->length); - tlv_type = le32_to_cpu(tlv->type); - - if (len < tlv_len) - return; - - len -= ALIGN(tlv_len, 4); - data += sizeof(*tlv) + ALIGN(tlv_len, 4); - - if (tlv_type < IWL_UCODE_TLV_DEBUG_BASE || - tlv_type > IWL_UCODE_TLV_DEBUG_MAX) - continue; - - hdr = (void *)&tlv->data[0]; - apply = le32_to_cpu(hdr->apply_point); - - if (le32_to_cpu(hdr->tlv_version) != 1) - continue; - - IWL_DEBUG_FW(trans, "WRT: read TLV 0x%x, apply point %d\n", - le32_to_cpu(tlv->type), apply); - - if (WARN_ON(apply >= IWL_FW_INI_APPLY_NUM)) - continue; - - size[apply] += sizeof(*tlv) + tlv_len; } - for (i = 0; i < ARRAY_SIZE(size); i++) { - void *mem; + INIT_LIST_HEAD(&tlv_copy->list); + memcpy(&tlv_copy->tlv, tlv, sizeof(*tlv) + len); - if (!size[i]) - continue; + if (!dbg_cfg->list.next) + INIT_LIST_HEAD(&dbg_cfg->list); - mem = kzalloc(size[i], GFP_KERNEL); + list_add_tail(&tlv_copy->list, &dbg_cfg->list); - if (!mem) { - IWL_ERR(trans, "No memory for apply point %d\n", i); - return; - } + trans->dbg.ini_valid = true; +} - if (ext) { - trans->dbg.apply_points_ext[i].data = mem; - trans->dbg.apply_points_ext[i].size = size[i]; - } else { - trans->dbg.apply_points[i].data = mem; - trans->dbg.apply_points[i].size = size[i]; - } +static void iwl_dbg_tlv_free_list(struct list_head *list) +{ + if (!list || !list->next) + return; - trans->dbg.ini_valid = true; + while (!list_empty(list)) { + struct iwl_apply_point_data *node = + list_entry(list->next, typeof(*node), list); + + list_del(&node->list); + kfree(node); } } @@ -170,13 +124,13 @@ void iwl_dbg_tlv_free(struct iwl_trans *trans) int i; for (i = 0; i < ARRAY_SIZE(trans->dbg.apply_points); i++) { - kfree(trans->dbg.apply_points[i].data); - trans->dbg.apply_points[i].size = 0; - trans->dbg.apply_points[i].offset = 0; + struct iwl_apply_point_data *data; - kfree(trans->dbg.apply_points_ext[i].data); - trans->dbg.apply_points_ext[i].size = 0; - trans->dbg.apply_points_ext[i].offset = 0; + data = &trans->dbg.apply_points[i]; + iwl_dbg_tlv_free_list(&data->list); + + data = &trans->dbg.apply_points_ext[i]; + iwl_dbg_tlv_free_list(&data->list); } } @@ -232,7 +186,6 @@ void iwl_dbg_tlv_load_bin(struct device *dev, struct iwl_trans *trans) if (res) return; - iwl_dbg_tlv_alloc(trans, fw->size, fw->data, true); iwl_dbg_tlv_parse_bin(trans, fw->data, fw->size); trans->dbg.external_ini_loaded = true; diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h index e4911ec6ce13..72552de801d4 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h @@ -66,14 +66,12 @@ /** * struct iwl_apply_point_data - * @data: start address of this apply point data - * @size total size of the data - * @offset: current offset of the copied data + * @list: list to go through the TLVs of the apply point + * @tlv: a debug TLV */ struct iwl_apply_point_data { - void *data; - int size; - int offset; + struct list_head list; + struct iwl_ucode_tlv tlv; }; struct iwl_trans; @@ -81,7 +79,5 @@ void iwl_dbg_tlv_load_bin(struct device *dev, struct iwl_trans *trans); void iwl_dbg_tlv_free(struct iwl_trans *trans); void iwl_dbg_tlv_copy(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv, bool ext); -void iwl_dbg_tlv_alloc(struct iwl_trans *trans, size_t len, const u8 *data, - bool ext); #endif /* __iwl_dbg_tlv_h__*/ diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c index 595dc2fbc3b3..3792b421746e 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c @@ -647,9 +647,6 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, len -= sizeof(*ucode); - if (iwlwifi_mod_params.enable_ini) - iwl_dbg_tlv_alloc(drv->trans, len, data, false); - while (len >= sizeof(*tlv)) { len -= sizeof(*tlv); tlv = (void *)data; From 5b79c323525ba8ece9b8b17ce89983a76add5a83 Mon Sep 17 00:00:00 2001 From: Shahar S Matityahu Date: Tue, 18 Jun 2019 08:31:58 +0300 Subject: [PATCH 40/80] iwlwifi: dbg_ini: remove periphery phy and aux regions handling periphery phy and aux regions should not be collected like periphery mac region. Remove their handling. The handling will be added in the future once the FW will support it. Signed-off-by: Shahar S Matityahu Fixes: 7a14c23dcdee ("iwlwifi: dbg: dump data according to the new ini TLVs") Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 78e13cd182cb..1aa880936121 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -1908,8 +1908,6 @@ static void iwl_fw_ini_dump_trigger(struct iwl_fw_runtime *fwrt, iwl_dump_ini_mem(fwrt, data, reg, &ops); break; case IWL_FW_INI_REGION_PERIPHERY_MAC: - case IWL_FW_INI_REGION_PERIPHERY_PHY: - case IWL_FW_INI_REGION_PERIPHERY_AUX: ops.get_num_of_ranges = iwl_dump_ini_mem_ranges; ops.get_size = iwl_dump_ini_mem_get_size; ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header; @@ -1974,6 +1972,8 @@ static void iwl_fw_ini_dump_trigger(struct iwl_fw_runtime *fwrt, ops.fill_range = iwl_dump_ini_csr_iter; iwl_dump_ini_mem(fwrt, data, reg, &ops); break; + case IWL_FW_INI_REGION_PERIPHERY_PHY: + case IWL_FW_INI_REGION_PERIPHERY_AUX: case IWL_FW_INI_REGION_DRAM_IMR: /* This is undefined yet */ default: From 2d46f7af5ee32cee327b982f60fdf9da11e3efcc Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 14 Jun 2019 15:47:20 +0200 Subject: [PATCH 41/80] iwlwifi: stop passing bogus gfp flags arguments to dma_alloc_coherent dma_alloc_coherent is not just the page allocator. The only valid arguments to pass are either GFP_ATOMIC or GFP_ATOMIC with possible modifiers of __GFP_NORETRY or __GFP_NOWARN. Signed-off-by: Christoph Hellwig Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 3 +-- drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 1aa880936121..f52427ec60e9 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -2485,8 +2485,7 @@ iwl_fw_dbg_buffer_allocation(struct iwl_fw_runtime *fwrt, u32 size) virtual_addr = dma_alloc_coherent(fwrt->trans->dev, size, &phys_addr, - GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO | - __GFP_COMP); + GFP_KERNEL | __GFP_NOWARN); /* TODO: alloc fragments if needed */ if (!virtual_addr) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index 073d2ec99348..d15a667600cd 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -215,8 +215,7 @@ static void iwl_pcie_alloc_fw_monitor_block(struct iwl_trans *trans, for (power = max_power; power >= min_power; power--) { size = BIT(power); cpu_addr = dma_alloc_coherent(trans->dev, size, &phys, - GFP_KERNEL | __GFP_NOWARN | - __GFP_ZERO | __GFP_COMP); + GFP_KERNEL | __GFP_NOWARN); if (!cpu_addr) continue; From 0202bcf0e36a51dd2ccdae3e729de02e4286630a Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 30 Jun 2019 15:40:19 +0300 Subject: [PATCH 42/80] iwlwifi: mvm: simplify the channel switch flow for newer firmware Any firmware that supports the new channel switch flow is able to close / re-open the queues when needed. It takes into account the channel switch mode etc... Don't open / close the queues or enable / disable beacon abort before and after the channel switch in case the firmware is able to do this by itself. Signed-off-by: Emmanuel Grumbach Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/mvm/mac-ctxt.c | 4 +- .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 81 ++++++++++++------- 2 files changed, 54 insertions(+), 31 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c index fe776e35b9d0..8fa356402bbd 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c @@ -1594,7 +1594,9 @@ void iwl_mvm_channel_switch_noa_notif(struct iwl_mvm *mvm, RCU_INIT_POINTER(mvm->csa_vif, NULL); return; case NL80211_IFTYPE_STATION: - iwl_mvm_csa_client_absent(mvm, vif); + if (!fw_has_capa(&mvm->fw->ucode_capa, + IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD)) + iwl_mvm_csa_client_absent(mvm, vif); cancel_delayed_work(&mvmvif->csa_work); ieee80211_chswitch_done(vif, true); break; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 73302fe1c66d..b8d82509f9fd 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -1326,15 +1326,20 @@ static int iwl_mvm_post_channel_switch(struct ieee80211_hw *hw, goto out_unlock; } - iwl_mvm_sta_modify_disable_tx(mvm, mvmsta, false); + if (!fw_has_capa(&mvm->fw->ucode_capa, + IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD)) + iwl_mvm_sta_modify_disable_tx(mvm, mvmsta, false); iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL); - ret = iwl_mvm_enable_beacon_filter(mvm, vif, 0); - if (ret) - goto out_unlock; + if (!fw_has_capa(&mvm->fw->ucode_capa, + IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD)) { + ret = iwl_mvm_enable_beacon_filter(mvm, vif, 0); + if (ret) + goto out_unlock; - iwl_mvm_stop_session_protection(mvm, vif); + iwl_mvm_stop_session_protection(mvm, vif); + } } mvmvif->ps_disabled = false; @@ -4421,6 +4426,42 @@ static int iwl_mvm_schedule_client_csa(struct iwl_mvm *mvm, 0, sizeof(cmd), &cmd); } +static int iwl_mvm_old_pre_chan_sw_sta(struct iwl_mvm *mvm, + struct ieee80211_vif *vif, + struct ieee80211_channel_switch *chsw) +{ + struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); + u32 apply_time; + + /* Schedule the time event to a bit before beacon 1, + * to make sure we're in the new channel when the + * GO/AP arrives. In case count <= 1 immediately schedule the + * TE (this might result with some packet loss or connection + * loss). + */ + if (chsw->count <= 1) + apply_time = 0; + else + apply_time = chsw->device_timestamp + + ((vif->bss_conf.beacon_int * (chsw->count - 1) - + IWL_MVM_CHANNEL_SWITCH_TIME_CLIENT) * 1024); + + if (chsw->block_tx) + iwl_mvm_csa_client_absent(mvm, vif); + + if (mvmvif->bf_data.bf_enabled) { + int ret = iwl_mvm_disable_beacon_filter(mvm, vif, 0); + + if (ret) + return ret; + } + + iwl_mvm_schedule_csa_period(mvm, vif, vif->bss_conf.beacon_int, + apply_time); + + return 0; +} + #define IWL_MAX_CSA_BLOCK_TX 1500 static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw, struct ieee80211_vif *vif, @@ -4429,7 +4470,6 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw, struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); struct ieee80211_vif *csa_vif; struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); - u32 apply_time; int ret; mutex_lock(&mvm->mutex); @@ -4473,21 +4513,7 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw, break; case NL80211_IFTYPE_STATION: - /* Schedule the time event to a bit before beacon 1, - * to make sure we're in the new channel when the - * GO/AP arrives. In case count <= 1 immediately schedule the - * TE (this might result with some packet loss or connection - * loss). - */ - if (chsw->count <= 1) - apply_time = 0; - else - apply_time = chsw->device_timestamp + - ((vif->bss_conf.beacon_int * (chsw->count - 1) - - IWL_MVM_CHANNEL_SWITCH_TIME_CLIENT) * 1024); - if (chsw->block_tx) { - iwl_mvm_csa_client_absent(mvm, vif); /* * In case of undetermined / long time with immediate * quiet monitor status to gracefully disconnect @@ -4499,19 +4525,14 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw, msecs_to_jiffies(IWL_MAX_CSA_BLOCK_TX)); } - if (mvmvif->bf_data.bf_enabled) { - ret = iwl_mvm_disable_beacon_filter(mvm, vif, 0); + if (!fw_has_capa(&mvm->fw->ucode_capa, + IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD)) { + ret = iwl_mvm_old_pre_chan_sw_sta(mvm, vif, chsw); if (ret) goto out_unlock; - } - - if (fw_has_capa(&mvm->fw->ucode_capa, - IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD)) + } else { iwl_mvm_schedule_client_csa(mvm, vif, chsw); - else - iwl_mvm_schedule_csa_period(mvm, vif, - vif->bss_conf.beacon_int, - apply_time); + } mvmvif->csa_count = chsw->count; mvmvif->csa_misbehave = false; From e533f74589685a43fb191764c26f33a41a908ec3 Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Tue, 2 Jul 2019 15:18:47 +0300 Subject: [PATCH 43/80] iwlwifi: mvm: remove check for lq_sta in __iwl_mvm_rs_tx_status() The check is not necessary anymore, because now the struct is not allocated separately, but is part of the mvmsta struct. Remove the check, since it's dead code. Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/rs.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c index e4415e58fa78..fcd1b15d2fa0 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c @@ -3079,11 +3079,7 @@ static void __iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta.rs_drv; - /* Treat uninitialized rate scaling data same as non-existing. */ - if (!lq_sta) { - IWL_DEBUG_RATE(mvm, "Station rate scaling not created yet.\n"); - return; - } else if (!lq_sta->pers.drv) { + if (!lq_sta->pers.drv) { IWL_DEBUG_RATE(mvm, "Rate scaling not initialized yet.\n"); return; } From 6ce1e5c0c207d9a0dbd0f451ed58f333c8e3594c Mon Sep 17 00:00:00 2001 From: Gil Adam Date: Sun, 16 Jun 2019 13:18:28 +0300 Subject: [PATCH 44/80] iwlwifi: support per-platform antenna gain TX power limits as defined in the OTP assume the worst case scenario in terms of the platform's atenna gain, but most platforms are below that value so they can use more TX power without passing the regulatory limit. If the platform indicates in the BIOS that it indeed has lower gain, and the geographic location allows it, higher TX power can be used. The driver reads the PPAG (Per-Platform Antenna Gain) data from BIOS (if it exists), validates it and sends the appropriate command to the FW. This flow happens once at FW init, in case of suspend/resume there is no need to read again from BIOS as we save those values during init, so just send the PPAG command again to FW. Signed-off-by: Gil Adam Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/acpi.h | 12 ++ .../net/wireless/intel/iwlwifi/fw/api/phy.h | 7 + .../net/wireless/intel/iwlwifi/fw/api/power.h | 12 ++ drivers/net/wireless/intel/iwlwifi/fw/file.h | 1 + drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 3 + drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 121 ++++++++++++++++++ drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 3 + 7 files changed, 159 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h index 991a23450999..6cb2d1f5efea 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h @@ -68,6 +68,7 @@ #define ACPI_WRDD_METHOD "WRDD" #define ACPI_SPLC_METHOD "SPLC" #define ACPI_ECKV_METHOD "ECKV" +#define ACPI_PPAG_METHOD "PPAG" #define ACPI_WIFI_DOMAIN (0x07) @@ -92,6 +93,17 @@ #define ACPI_WGDS_NUM_BANDS 2 #define ACPI_WGDS_TABLE_SIZE 3 +#define ACPI_PPAG_NUM_CHAINS 2 +#define ACPI_PPAG_NUM_SUB_BANDS 5 +#define ACPI_PPAG_WIFI_DATA_SIZE ((ACPI_PPAG_NUM_CHAINS * \ + ACPI_PPAG_NUM_SUB_BANDS) + 3) + +/* PPAG gain value bounds in 1/8 dBm */ +#define ACPI_PPAG_MIN_LB -16 +#define ACPI_PPAG_MAX_LB 24 +#define ACPI_PPAG_MIN_HB -16 +#define ACPI_PPAG_MAX_HB 40 + #ifdef CONFIG_ACPI void *iwl_acpi_get_object(struct device *dev, acpi_string method); diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/phy.h b/drivers/net/wireless/intel/iwlwifi/fw/api/phy.h index 9cc59e00bd95..8991ddffbf5e 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/phy.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/phy.h @@ -8,6 +8,7 @@ * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH + * Copyright(c) 2019 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,6 +31,7 @@ * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH + * Copyright(c) 2019 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -89,6 +91,11 @@ enum iwl_phy_ops_subcmd_ids { */ GEO_TX_POWER_LIMIT = 0x05, + /** + * @PER_PLATFORM_ANT_GAIN_CMD: &struct iwl_ppag_table_cmd + */ + PER_PLATFORM_ANT_GAIN_CMD = 0x07, + /** * @CT_KILL_NOTIFICATION: &struct ct_kill_notif */ diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/power.h b/drivers/net/wireless/intel/iwlwifi/fw/api/power.h index f195db398bed..6e1b9b21904e 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/power.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/power.h @@ -449,6 +449,18 @@ struct iwl_geo_tx_power_profiles_resp { __le32 profile_idx; } __packed; /* GEO_TX_POWER_LIMIT_RESP */ +/** + * struct iwl_ppag_table_cmd - struct for PER_PLATFORM_ANT_GAIN_CMD cmd. + * @enabled: 1 if PPAG is enabled, 0 otherwise + * @gain: table of antenna gain values per chain and sub-band + * @reserved: reserved + */ +struct iwl_ppag_table_cmd { + __le32 enabled; + s8 gain[IWL_NUM_CHAIN_LIMITS][IWL_NUM_SUB_BANDS]; + s8 reserved[2]; +} __packed; /* PER_PLATFORM_ANT_GAIN_CMD */ + /** * struct iwl_beacon_filter_cmd * REPLY_BEACON_FILTERING_CMD = 0xd2 (command) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h index 3d567240ef11..73cd41480c2f 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/file.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h @@ -446,6 +446,7 @@ enum iwl_ucode_tlv_capa { IWL_UCODE_TLV_CAPA_ULTRA_HB_CHANNELS = (__force iwl_ucode_tlv_capa_t)48, IWL_UCODE_TLV_CAPA_CS_MODIFY = (__force iwl_ucode_tlv_capa_t)49, IWL_UCODE_TLV_CAPA_SET_LTR_GEN2 = (__force iwl_ucode_tlv_capa_t)50, + IWL_UCODE_TLV_CAPA_SET_PPAG = (__force iwl_ucode_tlv_capa_t)52, /* set 2 */ IWL_UCODE_TLV_CAPA_EXTENDED_DTS_MEASURE = (__force iwl_ucode_tlv_capa_t)64, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index 6f7345b121a6..2bf5b83e116c 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -1965,6 +1965,9 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) */ iwl_mvm_update_changed_regdom(mvm); + /* Re-configure PPAG settings */ + iwl_mvm_ppag_send_cmd(mvm); + if (!unified_image) /* Re-configure default SAR profile */ iwl_mvm_sar_select_profile(mvm, 1, 1); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index 0f6925a51435..af46723f790f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -1002,6 +1002,113 @@ static int iwl_mvm_sar_geo_init(struct iwl_mvm *mvm) return iwl_mvm_send_cmd_pdu(mvm, cmd_wide_id, 0, sizeof(cmd), &cmd); } +static int iwl_mvm_get_ppag_table(struct iwl_mvm *mvm) +{ + union acpi_object *wifi_pkg, *data, *enabled; + int i, j, ret, tbl_rev; + int idx = 2; + + mvm->ppag_table.enabled = cpu_to_le32(0); + data = iwl_acpi_get_object(mvm->dev, ACPI_PPAG_METHOD); + if (IS_ERR(data)) + return PTR_ERR(data); + + wifi_pkg = iwl_acpi_get_wifi_pkg(mvm->dev, data, + ACPI_PPAG_WIFI_DATA_SIZE, &tbl_rev); + + if (IS_ERR(wifi_pkg) || tbl_rev != 0) { + ret = PTR_ERR(wifi_pkg); + goto out_free; + } + + enabled = &wifi_pkg->package.elements[1]; + if (enabled->type != ACPI_TYPE_INTEGER || + (enabled->integer.value != 0 && enabled->integer.value != 1)) { + ret = -EINVAL; + goto out_free; + } + + mvm->ppag_table.enabled = cpu_to_le32(enabled->integer.value); + if (!mvm->ppag_table.enabled) { + ret = 0; + goto out_free; + } + + /* + * read, verify gain values and save them into the PPAG table. + * first sub-band (j=0) corresponds to Low-Band (2.4GHz), and the + * following sub-bands to High-Band (5GHz). + */ + for (i = 0; i < ACPI_PPAG_NUM_CHAINS; i++) { + for (j = 0; j < ACPI_PPAG_NUM_SUB_BANDS; j++) { + union acpi_object *ent; + + ent = &wifi_pkg->package.elements[idx++]; + if (ent->type != ACPI_TYPE_INTEGER || + (j == 0 && ent->integer.value > ACPI_PPAG_MAX_LB) || + (j == 0 && ent->integer.value < ACPI_PPAG_MIN_LB) || + (j != 0 && ent->integer.value > ACPI_PPAG_MAX_HB) || + (j != 0 && ent->integer.value < ACPI_PPAG_MIN_HB)) { + mvm->ppag_table.enabled = cpu_to_le32(0); + ret = -EINVAL; + goto out_free; + } + mvm->ppag_table.gain[i][j] = ent->integer.value; + } + } + ret = 0; +out_free: + kfree(data); + return ret; +} + +int iwl_mvm_ppag_send_cmd(struct iwl_mvm *mvm) +{ + int i, j, ret; + + if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_SET_PPAG)) { + IWL_DEBUG_RADIO(mvm, + "PPAG capability not supported by FW, command not sent.\n"); + return 0; + } + + IWL_DEBUG_RADIO(mvm, "Sending PER_PLATFORM_ANT_GAIN_CMD\n"); + IWL_DEBUG_RADIO(mvm, "PPAG is %s\n", + mvm->ppag_table.enabled ? "enabled" : "disabled"); + + for (i = 0; i < ACPI_PPAG_NUM_CHAINS; i++) { + for (j = 0; j < ACPI_PPAG_NUM_SUB_BANDS; j++) { + IWL_DEBUG_RADIO(mvm, + "PPAG table: chain[%d] band[%d]: gain = %d\n", + i, j, mvm->ppag_table.gain[i][j]); + } + } + + ret = iwl_mvm_send_cmd_pdu(mvm, WIDE_ID(PHY_OPS_GROUP, + PER_PLATFORM_ANT_GAIN_CMD), + 0, sizeof(mvm->ppag_table), + &mvm->ppag_table); + if (ret < 0) + IWL_ERR(mvm, "failed to send PER_PLATFORM_ANT_GAIN_CMD (%d)\n", + ret); + + return ret; +} + +static int iwl_mvm_ppag_init(struct iwl_mvm *mvm) +{ + int ret; + + ret = iwl_mvm_get_ppag_table(mvm); + if (ret < 0) { + IWL_DEBUG_RADIO(mvm, + "PPAG BIOS table invalid or unavailable. (%d)\n", + ret); + return 0; + } + return iwl_mvm_ppag_send_cmd(mvm); +} + #else /* CONFIG_ACPI */ static int iwl_mvm_sar_get_wrds_table(struct iwl_mvm *mvm) { @@ -1033,6 +1140,16 @@ int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm) { return -ENOENT; } + +int iwl_mvm_ppag_send_cmd(struct iwl_mvm *mvm) +{ + return -ENOENT; +} + +static int iwl_mvm_ppag_init(struct iwl_mvm *mvm) +{ + return -ENOENT; +} #endif /* CONFIG_ACPI */ void iwl_mvm_send_recovery_cmd(struct iwl_mvm *mvm, u32 flags) @@ -1325,6 +1442,10 @@ int iwl_mvm_up(struct iwl_mvm *mvm) if (iwl_acpi_get_eckv(mvm->dev, &mvm->ext_clock_valid)) IWL_DEBUG_INFO(mvm, "ECKV table doesn't exist in BIOS\n"); + ret = iwl_mvm_ppag_init(mvm); + if (ret) + goto error; + ret = iwl_mvm_sar_init(mvm); if (ret == 0) { ret = iwl_mvm_sar_geo_init(mvm); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 79bbdf8121cc..0ea0f72880af 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -1136,6 +1136,8 @@ struct iwl_mvm { struct iwl_mvm_sar_profile sar_profiles[ACPI_SAR_PROFILE_NUM]; struct iwl_mvm_geo_profile geo_profiles[ACPI_NUM_GEO_PROFILES]; u32 geo_rev; + struct iwl_ppag_table_cmd ppag_table; + u32 ppag_rev; #endif }; @@ -2050,6 +2052,7 @@ void iwl_mvm_event_frame_timeout_callback(struct iwl_mvm *mvm, int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b); int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm); +int iwl_mvm_ppag_send_cmd(struct iwl_mvm *mvm); #ifdef CONFIG_IWLWIFI_DEBUGFS void iwl_mvm_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif, From 94c4a2e4c091f7a62883771ecfbb143faef2207a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 5 Jul 2019 13:53:30 +0200 Subject: [PATCH 45/80] iwlwifi: api: fix FTM struct documentation The real name is struct iwl_tof_range_req_ext_cmd, fix that. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/api/location.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/location.h b/drivers/net/wireless/intel/iwlwifi/fw/api/location.h index ec864c7b497f..7a0fe5adefa5 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/location.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/location.h @@ -82,7 +82,7 @@ enum iwl_location_subcmd_ids { TOF_RANGE_ABORT_CMD = 0x2, /** * @TOF_RANGE_REQ_EXT_CMD: TOF extended ranging config, - * uses &struct iwl_tof_range_request_ext_cmd + * uses &struct iwl_tof_range_req_ext_cmd */ TOF_RANGE_REQ_EXT_CMD = 0x3, /** @@ -292,7 +292,7 @@ struct iwl_tof_responder_dyn_config_cmd { } __packed; /* TOF_RESPONDER_DYN_CONFIG_CMD_API_S_VER_2 */ /** - * struct iwl_tof_range_request_ext_cmd - extended range req for WLS + * struct iwl_tof_range_req_ext_cmd - extended range req for WLS * @tsf_timer_offset_msec: the recommended time offset (mSec) from the AP's TSF * @reserved: reserved * @min_delta_ftm: Minimal time between two consecutive measurements, From 2196ea9c8d0fb44a0563234b5481b79bc55b499c Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Wed, 10 Apr 2019 09:23:39 +0300 Subject: [PATCH 46/80] iwlwifi: bump FW API to 50 for 22000 series Start supporting API version 50 for 22000 series. Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/cfg/22000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c index 0d89223f377d..49189369f70c 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c @@ -56,7 +56,7 @@ #include "iwl-config.h" /* Highest firmware API version supported */ -#define IWL_22000_UCODE_API_MAX 49 +#define IWL_22000_UCODE_API_MAX 50 /* Lowest firmware API version supported */ #define IWL_22000_UCODE_API_MIN 39 From 4a7bd3cf83fdddb2e2e902680e4d253fac21f279 Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Mon, 8 Jul 2019 12:20:01 +0300 Subject: [PATCH 47/80] iwlwifi: remove duplicate FW string definitions The string we define as IWL_22000_HR_B_F0_FW_PRE is duplicate with IWL_22000_QU_B_HR_B_FW_PRE. Remove the former to avoid confusion. Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/cfg/22000.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c index 49189369f70c..8ecdaabf710b 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c @@ -76,7 +76,6 @@ #define IWL_22000_HR_FW_PRE "iwlwifi-Qu-a0-hr-a0-" #define IWL_22000_HR_CDB_FW_PRE "iwlwifi-QuIcp-z0-hrcdb-a0-" #define IWL_22000_HR_A_F0_FW_PRE "iwlwifi-QuQnj-f0-hr-a0-" -#define IWL_22000_HR_B_F0_FW_PRE "iwlwifi-Qu-b0-hr-b0-" #define IWL_22000_QU_B_HR_B_FW_PRE "iwlwifi-Qu-b0-hr-b0-" #define IWL_22000_HR_B_FW_PRE "iwlwifi-QuQnj-b0-hr-b0-" #define IWL_22000_HR_A0_FW_PRE "iwlwifi-QuQnj-a0-hr-a0-" @@ -99,8 +98,6 @@ IWL_22000_JF_FW_PRE __stringify(api) ".ucode" #define IWL_22000_HR_A_F0_QNJ_MODULE_FIRMWARE(api) \ IWL_22000_HR_A_F0_FW_PRE __stringify(api) ".ucode" -#define IWL_22000_HR_B_F0_QNJ_MODULE_FIRMWARE(api) \ - IWL_22000_HR_B_F0_FW_PRE __stringify(api) ".ucode" #define IWL_22000_QU_B_HR_B_MODULE_FIRMWARE(api) \ IWL_22000_QU_B_HR_B_FW_PRE __stringify(api) ".ucode" #define IWL_22000_HR_B_QNJ_MODULE_FIRMWARE(api) \ @@ -663,7 +660,6 @@ const struct iwl_cfg iwlax411_2ax_cfg_so_gf4_a0 = { MODULE_FIRMWARE(IWL_22000_HR_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_22000_JF_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_22000_HR_A_F0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); -MODULE_FIRMWARE(IWL_22000_HR_B_F0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_22000_HR_B_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_22000_HR_A0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_QU_C_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); From a1af4c486ae7901480afc0f140f4ce91f0c389cd Mon Sep 17 00:00:00 2001 From: Shahar S Matityahu Date: Sun, 30 Jun 2019 09:31:22 +0300 Subject: [PATCH 48/80] iwlwifi: dbg_ini: use function to check if ini dbg mode is on use iwl_trans_dbg_ini_valid function instead of a boolean value check if dbg_ini mode is on. It is needed for a future patch. Signed-off-by: Shahar S Matityahu Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 4 ++-- drivers/net/wireless/intel/iwlwifi/fw/dbg.h | 9 +++++---- drivers/net/wireless/intel/iwlwifi/iwl-trans.h | 5 +++++ drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 2 +- drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c | 2 +- drivers/net/wireless/intel/iwlwifi/pcie/internal.h | 2 +- drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 2 +- 7 files changed, 16 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index f52427ec60e9..3679ba89ea9d 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -2101,7 +2101,7 @@ int iwl_fw_dbg_collect_desc(struct iwl_fw_runtime *fwrt, u32 trig_type = le32_to_cpu(desc->trig_desc.type); int ret; - if (fwrt->trans->dbg.ini_valid) { + if (iwl_trans_dbg_ini_valid(fwrt->trans)) { ret = iwl_fw_dbg_ini_collect(fwrt, trig_type); if (!ret) iwl_fw_free_dump_desc(fwrt); @@ -2381,7 +2381,7 @@ static void iwl_fw_dbg_collect_sync(struct iwl_fw_runtime *fwrt, u8 wk_idx) } IWL_DEBUG_FW_INFO(fwrt, "WRT: data collection start\n"); - if (fwrt->trans->dbg.ini_valid) + if (iwl_trans_dbg_ini_valid(fwrt->trans)) iwl_fw_error_ini_dump(fwrt, wk_idx); else iwl_fw_error_dump(fwrt); diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h index 461331703ea6..8faea2571788 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h @@ -202,7 +202,7 @@ _iwl_fw_dbg_trigger_on(struct iwl_fw_runtime *fwrt, { struct iwl_fw_dbg_trigger_tlv *trig; - if (fwrt->trans->dbg.ini_valid) + if (iwl_trans_dbg_ini_valid(fwrt->trans)) return NULL; if (!iwl_fw_dbg_trigger_enabled(fwrt->fw, id)) @@ -229,8 +229,9 @@ iwl_fw_ini_trigger_on(struct iwl_fw_runtime *fwrt, struct iwl_fw_ini_trigger *trig; u32 usec; - if (!fwrt->trans->dbg.ini_valid || id == IWL_FW_TRIGGER_ID_INVALID || - id >= IWL_FW_TRIGGER_ID_NUM || !fwrt->dump.active_trigs[id].active) + if (!iwl_trans_dbg_ini_valid(fwrt->trans) || + id == IWL_FW_TRIGGER_ID_INVALID || id >= IWL_FW_TRIGGER_ID_NUM || + !fwrt->dump.active_trigs[id].active) return false; trig = fwrt->dump.active_trigs[id].trig; @@ -394,7 +395,7 @@ static inline void iwl_fw_umac_set_alive_err_table(struct iwl_trans *trans, static inline void iwl_fw_error_collect(struct iwl_fw_runtime *fwrt) { - if (fwrt->trans->dbg.ini_valid && fwrt->trans->dbg.hw_error) { + if (iwl_trans_dbg_ini_valid(fwrt->trans) && fwrt->trans->dbg.hw_error) { _iwl_fw_dbg_ini_collect(fwrt, IWL_FW_TRIGGER_ID_FW_HW_ERROR); fwrt->trans->dbg.hw_error = false; } else { diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h index 0fa4b100f109..731ffb4a33af 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h @@ -1216,6 +1216,11 @@ static inline void iwl_trans_sync_nmi(struct iwl_trans *trans) trans->ops->sync_nmi(trans); } +static inline bool iwl_trans_dbg_ini_valid(struct iwl_trans *trans) +{ + return trans->dbg.ini_valid; +} + /***************************************************** * transport helper functions *****************************************************/ diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index af46723f790f..d2baea22cba2 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -1304,7 +1304,7 @@ int iwl_mvm_up(struct iwl_mvm *mvm) if (ret) IWL_ERR(mvm, "Failed to initialize Smart Fifo\n"); - if (!mvm->trans->dbg.ini_valid) { + if (!iwl_trans_dbg_ini_valid(mvm->trans)) { mvm->fwrt.dump.conf = FW_DBG_INVALID; /* if we have a destination, assume EARLY START */ if (mvm->fw->dbg.dest_tlv) 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 5e86783d616b..9b27c955b8dc 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c @@ -96,7 +96,7 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans, cpu_to_le64(trans_pcie->rxq->bd_dma); /* Configure debug, for integration */ - if (!trans->dbg.ini_valid) + if (!iwl_trans_dbg_ini_valid(trans)) iwl_pcie_alloc_fw_monitor(trans, 0); if (trans->dbg.num_blocks) { prph_sc_ctrl->hwm_cfg.hwm_base_addr = diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h index 95f78d8b4ae5..906e1da3923d 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h @@ -1044,7 +1044,7 @@ static inline void __iwl_trans_pcie_set_bit(struct iwl_trans *trans, static inline bool iwl_pcie_dbg_on(struct iwl_trans *trans) { - return (trans->dbg.dest_tlv || trans->dbg.ini_valid); + return (trans->dbg.dest_tlv || iwl_trans_dbg_ini_valid(trans)); } void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state); diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index d15a667600cd..97808a251012 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -896,7 +896,7 @@ void iwl_pcie_apply_destination(struct iwl_trans *trans) const struct iwl_fw_dbg_dest_tlv_v1 *dest = trans->dbg.dest_tlv; int i; - if (trans->dbg.ini_valid) { + if (iwl_trans_dbg_ini_valid(trans)) { if (!trans->dbg.num_blocks) return; From 341bd290b9a25a59e0a20873de0dc14fa12c4b67 Mon Sep 17 00:00:00 2001 From: Shahar S Matityahu Date: Sun, 30 Jun 2019 10:23:26 +0300 Subject: [PATCH 49/80] iwlwifi: dbg_ini: verify debug TLVs at allocation phase Reimplement debug TLV allocation flow. The driver will check the validity of the debug TLVs prior allocating space for them. Any malformed or unsupported TLV will be skipped. The TLV specific checks will be added in later patches. Signed-off-by: Shahar S Matityahu Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 15 +- .../net/wireless/intel/iwlwifi/iwl-dbg-tlv.c | 157 ++++++++++++------ .../net/wireless/intel/iwlwifi/iwl-dbg-tlv.h | 4 +- drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 2 +- .../net/wireless/intel/iwlwifi/iwl-trans.h | 24 ++- 5 files changed, 142 insertions(+), 60 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 3679ba89ea9d..6e5a3289e04a 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -1739,7 +1739,7 @@ static void iwl_dump_ini_info(struct iwl_fw_runtime *fwrt, dump->version = cpu_to_le32(IWL_INI_DUMP_VER); dump->trigger_id = trigger->trigger_id; dump->is_external_cfg = - cpu_to_le32(fwrt->trans->dbg.external_ini_loaded); + cpu_to_le32(fwrt->trans->dbg.external_ini_cfg); dump->ver_type = cpu_to_le32(fwrt->dump.fw_ver.type); dump->ver_subtype = cpu_to_le32(fwrt->dump.fw_ver.subtype); @@ -2855,17 +2855,22 @@ static void iwl_fw_dbg_ini_reset_cfg(struct iwl_fw_runtime *fwrt) void iwl_fw_dbg_apply_point(struct iwl_fw_runtime *fwrt, enum iwl_fw_ini_apply_point apply_point) { - void *data = &fwrt->trans->dbg.apply_points[apply_point]; + void *data; IWL_DEBUG_FW(fwrt, "WRT: enabling apply point %d\n", apply_point); if (apply_point == IWL_FW_INI_APPLY_EARLY) iwl_fw_dbg_ini_reset_cfg(fwrt); - _iwl_fw_dbg_apply_point(fwrt, data, apply_point, false); + if (fwrt->trans->dbg.internal_ini_cfg != IWL_INI_CFG_STATE_NOT_LOADED) { + data = &fwrt->trans->dbg.apply_points[apply_point]; + _iwl_fw_dbg_apply_point(fwrt, data, apply_point, false); + } - data = &fwrt->trans->dbg.apply_points_ext[apply_point]; - _iwl_fw_dbg_apply_point(fwrt, data, apply_point, true); + if (fwrt->trans->dbg.external_ini_cfg != IWL_INI_CFG_STATE_NOT_LOADED) { + data = &fwrt->trans->dbg.apply_points_ext[apply_point]; + _iwl_fw_dbg_apply_point(fwrt, data, apply_point, true); + } } IWL_EXPORT_SYMBOL(iwl_fw_dbg_apply_point); diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c index 7c1e76ee7ede..5b1644a70ace 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c @@ -63,46 +63,124 @@ #include "iwl-trans.h" #include "iwl-dbg-tlv.h" -void iwl_dbg_tlv_copy(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv, - bool ext) +/** + * enum iwl_dbg_tlv_type - debug TLV types + * @IWL_DBG_TLV_TYPE_DEBUG_INFO: debug info TLV + * @IWL_DBG_TLV_TYPE_BUF_ALLOC: buffer allocation TLV + * @IWL_DBG_TLV_TYPE_HCMD: host command TLV + * @IWL_DBG_TLV_TYPE_REGION: region TLV + * @IWL_DBG_TLV_TYPE_TRIGGER: trigger TLV + * @IWL_DBG_TLV_TYPE_NUM: number of debug TLVs + */ +enum iwl_dbg_tlv_type { + IWL_DBG_TLV_TYPE_DEBUG_INFO = + IWL_UCODE_TLV_TYPE_DEBUG_INFO - IWL_UCODE_TLV_DEBUG_BASE, + IWL_DBG_TLV_TYPE_BUF_ALLOC, + IWL_DBG_TLV_TYPE_HCMD, + IWL_DBG_TLV_TYPE_REGION, + IWL_DBG_TLV_TYPE_TRIGGER, + IWL_DBG_TLV_TYPE_NUM, +}; + +/** + * struct iwl_dbg_tlv_ver_data - debug TLV version struct + * @min_ver: min version supported + * @max_ver: max version supported + */ +struct iwl_dbg_tlv_ver_data { + int min_ver; + int max_ver; +}; + +static const struct iwl_dbg_tlv_ver_data +dbg_ver_table[IWL_DBG_TLV_TYPE_NUM] = { + [IWL_DBG_TLV_TYPE_DEBUG_INFO] = {.min_ver = 1, .max_ver = 1,}, + [IWL_DBG_TLV_TYPE_BUF_ALLOC] = {.min_ver = 1, .max_ver = 1,}, + [IWL_DBG_TLV_TYPE_HCMD] = {.min_ver = 1, .max_ver = 1,}, + [IWL_DBG_TLV_TYPE_REGION] = {.min_ver = 1, .max_ver = 1,}, + [IWL_DBG_TLV_TYPE_TRIGGER] = {.min_ver = 1, .max_ver = 1,}, +}; + +static int iwl_dbg_tlv_copy(struct iwl_ucode_tlv *tlv, struct list_head *list) { - struct iwl_apply_point_data *dbg_cfg, *tlv_copy; - struct iwl_fw_ini_header *header = (void *)&tlv->data[0]; - u32 tlv_type = le32_to_cpu(tlv->type); + struct iwl_apply_point_data *tlv_copy; u32 len = le32_to_cpu(tlv->length); - u32 apply_point = le32_to_cpu(header->apply_point); - - if (le32_to_cpu(header->tlv_version) != 1) - return; - - if (WARN_ONCE(apply_point >= IWL_FW_INI_APPLY_NUM, - "Invalid apply point %d\n", apply_point)) - return; - - IWL_DEBUG_FW(trans, "WRT: read TLV 0x%x, apply point %d\n", - tlv_type, apply_point); - - if (ext) - dbg_cfg = &trans->dbg.apply_points_ext[apply_point]; - else - dbg_cfg = &trans->dbg.apply_points[apply_point]; tlv_copy = kzalloc(sizeof(*tlv_copy) + len, GFP_KERNEL); - if (!tlv_copy) { - IWL_ERR(trans, "WRT: No memory for TLV 0x%x, apply point %d\n", - tlv_type, apply_point); - return; - } + if (!tlv_copy) + return -ENOMEM; INIT_LIST_HEAD(&tlv_copy->list); memcpy(&tlv_copy->tlv, tlv, sizeof(*tlv) + len); - if (!dbg_cfg->list.next) - INIT_LIST_HEAD(&dbg_cfg->list); + if (!list->next) + INIT_LIST_HEAD(list); - list_add_tail(&tlv_copy->list, &dbg_cfg->list); + list_add_tail(&tlv_copy->list, list); - trans->dbg.ini_valid = true; + return 0; +} + +static bool iwl_dbg_tlv_ver_support(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 ver = le32_to_cpu(hdr->tlv_version); + + if (ver < dbg_ver_table[tlv_idx].min_ver || + ver > dbg_ver_table[tlv_idx].max_ver) + return false; + + return true; +} + +void iwl_dbg_tlv_alloc(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv, + bool ext) +{ + struct iwl_fw_ini_header *hdr = (void *)&tlv->data[0]; + u32 type = le32_to_cpu(tlv->type); + u32 pnt = le32_to_cpu(hdr->apply_point); + u32 tlv_idx = type - IWL_UCODE_TLV_DEBUG_BASE; + enum iwl_ini_cfg_state *cfg_state = ext ? + &trans->dbg.external_ini_cfg : &trans->dbg.internal_ini_cfg; + struct list_head *dbg_cfg_list = ext ? + &trans->dbg.apply_points_ext[pnt].list : + &trans->dbg.apply_points[pnt].list; + + IWL_DEBUG_FW(trans, "WRT: read TLV 0x%x, apply point %d\n", + type, pnt); + + if (tlv_idx >= IWL_DBG_TLV_TYPE_NUM) { + IWL_ERR(trans, "WRT: Unsupported TLV 0x%x\n", type); + goto out_err; + } + + if (pnt >= IWL_FW_INI_APPLY_NUM) { + IWL_ERR(trans, "WRT: Invalid apply point %d\n", pnt); + goto out_err; + } + + if (!iwl_dbg_tlv_ver_support(tlv)) { + IWL_ERR(trans, "WRT: Unsupported TLV 0x%x version %u\n", type, + le32_to_cpu(hdr->tlv_version)); + goto out_err; + } + + if (iwl_dbg_tlv_copy(tlv, dbg_cfg_list)) { + IWL_ERR(trans, + "WRT: Failed to allocate TLV 0x%x, apply point %d\n", + type, pnt); + goto out_err; + } + + if (*cfg_state == IWL_INI_CFG_STATE_NOT_LOADED) + *cfg_state = IWL_INI_CFG_STATE_LOADED; + + return; + +out_err: + *cfg_state = IWL_INI_CFG_STATE_CORRUPTED; } static void iwl_dbg_tlv_free_list(struct list_head *list) @@ -138,7 +216,6 @@ static int iwl_dbg_tlv_parse_bin(struct iwl_trans *trans, const u8 *data, size_t len) { struct iwl_ucode_tlv *tlv; - enum iwl_ucode_tlv_type tlv_type; u32 tlv_len; while (len >= sizeof(*tlv)) { @@ -146,7 +223,6 @@ static int iwl_dbg_tlv_parse_bin(struct iwl_trans *trans, const u8 *data, tlv = (void *)data; tlv_len = le32_to_cpu(tlv->length); - tlv_type = le32_to_cpu(tlv->type); if (len < tlv_len) { IWL_ERR(trans, "invalid TLV len: %zd/%u\n", @@ -156,19 +232,7 @@ static int iwl_dbg_tlv_parse_bin(struct iwl_trans *trans, const u8 *data, len -= ALIGN(tlv_len, 4); data += sizeof(*tlv) + ALIGN(tlv_len, 4); - switch (tlv_type) { - case IWL_UCODE_TLV_TYPE_DEBUG_INFO: - case IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION: - case IWL_UCODE_TLV_TYPE_HCMD: - case IWL_UCODE_TLV_TYPE_REGIONS: - case IWL_UCODE_TLV_TYPE_TRIGGERS: - case IWL_UCODE_TLV_TYPE_DEBUG_FLOW: - iwl_dbg_tlv_copy(trans, tlv, true); - break; - default: - WARN_ONCE(1, "Invalid TLV %x\n", tlv_type); - break; - } + iwl_dbg_tlv_alloc(trans, tlv, true); } return 0; @@ -179,7 +243,7 @@ void iwl_dbg_tlv_load_bin(struct device *dev, struct iwl_trans *trans) const struct firmware *fw; int res; - if (trans->dbg.external_ini_loaded || !iwlwifi_mod_params.enable_ini) + if (!iwlwifi_mod_params.enable_ini) return; res = request_firmware(&fw, "iwl-dbg-tlv.ini", dev); @@ -188,6 +252,5 @@ void iwl_dbg_tlv_load_bin(struct device *dev, struct iwl_trans *trans) iwl_dbg_tlv_parse_bin(trans, fw->data, fw->size); - trans->dbg.external_ini_loaded = true; release_firmware(fw); } diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h index 72552de801d4..3a60590d274d 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h @@ -77,7 +77,7 @@ struct iwl_apply_point_data { struct iwl_trans; void iwl_dbg_tlv_load_bin(struct device *dev, struct iwl_trans *trans); void iwl_dbg_tlv_free(struct iwl_trans *trans); -void iwl_dbg_tlv_copy(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv, - bool ext); +void iwl_dbg_tlv_alloc(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv, + bool ext); #endif /* __iwl_dbg_tlv_h__*/ diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c index 3792b421746e..1351f7fe5ae2 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c @@ -1153,7 +1153,7 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, case IWL_UCODE_TLV_TYPE_TRIGGERS: case IWL_UCODE_TLV_TYPE_DEBUG_FLOW: if (iwlwifi_mod_params.enable_ini) - iwl_dbg_tlv_copy(drv->trans, tlv, false); + iwl_dbg_tlv_alloc(drv->trans, tlv, false); break; case IWL_UCODE_TLV_CMD_VERSIONS: if (tlv_len % sizeof(struct iwl_fw_cmd_version)) { diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h index 731ffb4a33af..09ed0dd163eb 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h @@ -650,6 +650,19 @@ enum iwl_plat_pm_mode { IWL_PLAT_PM_MODE_D3, }; +/** + * enum iwl_ini_cfg_state + * @IWL_INI_CFG_STATE_NOT_LOADED: no debug cfg was given + * @IWL_INI_CFG_STATE_LOADED: debug cfg was found and loaded + * @IWL_INI_CFG_STATE_CORRUPTED: debug cfg was found and some of the TLVs + * are corrupted. The rest of the debug TLVs will still be used + */ +enum iwl_ini_cfg_state { + IWL_INI_CFG_STATE_NOT_LOADED, + IWL_INI_CFG_STATE_LOADED, + IWL_INI_CFG_STATE_CORRUPTED, +}; + /* Max time to wait for nmi interrupt */ #define IWL_TRANS_NMI_TIMEOUT (HZ / 4) @@ -691,8 +704,8 @@ struct iwl_self_init_dram { * @umac_error_event_table: addr of umac error table * @error_event_table_tlv_status: bitmap that indicates what error table * pointers was recevied via TLV. uses enum &iwl_error_event_table_status - * @external_ini_loaded: indicates if an external ini cfg was given - * @ini_valid: indicates if debug ini mode is on + * @internal_ini_cfg: internal debug cfg state. Uses &enum iwl_ini_cfg_state + * @external_ini_cfg: external debug cfg state. Uses &enum iwl_ini_cfg_state * @num_blocks: number of blocks in fw_mon * @fw_mon: address of the buffers for firmware monitor * @is_alloc: bit i is set if buffer i was allocated @@ -711,8 +724,8 @@ struct iwl_trans_debug { u32 umac_error_event_table; unsigned int error_event_table_tlv_status; - bool external_ini_loaded; - bool ini_valid; + enum iwl_ini_cfg_state internal_ini_cfg; + enum iwl_ini_cfg_state external_ini_cfg; struct iwl_apply_point_data apply_points[IWL_FW_INI_APPLY_NUM]; struct iwl_apply_point_data apply_points_ext[IWL_FW_INI_APPLY_NUM]; @@ -1218,7 +1231,8 @@ static inline void iwl_trans_sync_nmi(struct iwl_trans *trans) static inline bool iwl_trans_dbg_ini_valid(struct iwl_trans *trans) { - return trans->dbg.ini_valid; + return trans->dbg.internal_ini_cfg != IWL_INI_CFG_STATE_NOT_LOADED || + trans->dbg.external_ini_cfg != IWL_INI_CFG_STATE_NOT_LOADED; } /***************************************************** From f259fc896e8d35b2cb528207e7e1e71b81079131 Mon Sep 17 00:00:00 2001 From: Shahar S Matityahu Date: Sun, 30 Jun 2019 16:36:36 +0300 Subject: [PATCH 50/80] iwlwifi: dbg_ini: remove debug flow TLV Debug flow TLV was removed from the FW. Remove the TLV from the driver as well. Signed-off-by: Shahar S Matityahu Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h | 11 ----------- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 2 -- drivers/net/wireless/intel/iwlwifi/fw/file.h | 3 +-- drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 1 - 4 files changed, 1 insertion(+), 16 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h b/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h index e02e289d29b1..798e61d4d683 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h @@ -140,17 +140,6 @@ struct iwl_fw_ini_hcmd_tlv { struct iwl_fw_ini_hcmd hcmd; } __packed; /* FW_DEBUG_TLV_HCMD_API_S_VER_1 */ -/** - * struct iwl_fw_ini_debug_flow_tlv - (IWL_UCODE_TLV_TYPE_DEBUG_FLOW) - * - * @header: header - * @debug_flow_cfg: &enum iwl_fw_ini_debug_flow - */ -struct iwl_fw_ini_debug_flow_tlv { - struct iwl_fw_ini_header header; - __le32 debug_flow_cfg; -} __packed; /* FW_DEBUG_TLV_FLOW_TLV_S_VER_1 */ - #define IWL_FW_INI_MAX_REGION_ID 64 #define IWL_FW_INI_MAX_NAME 32 diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 6e5a3289e04a..2d37628694d2 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -2820,8 +2820,6 @@ static void _iwl_fw_dbg_apply_point(struct iwl_fw_runtime *fwrt, case IWL_UCODE_TLV_TYPE_TRIGGERS: iwl_fw_dbg_update_triggers(fwrt, ini_tlv, ext, pnt); break; - case IWL_UCODE_TLV_TYPE_DEBUG_FLOW: - break; default: WARN_ONCE(1, "WRT: ext=%d. Invalid TLV 0x%x for apply point\n", diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h index 73cd41480c2f..00db39427be7 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/file.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h @@ -157,8 +157,7 @@ enum iwl_ucode_tlv_type { IWL_UCODE_TLV_TYPE_HCMD = IWL_UCODE_TLV_DEBUG_BASE + 2, IWL_UCODE_TLV_TYPE_REGIONS = IWL_UCODE_TLV_DEBUG_BASE + 3, IWL_UCODE_TLV_TYPE_TRIGGERS = IWL_UCODE_TLV_DEBUG_BASE + 4, - IWL_UCODE_TLV_TYPE_DEBUG_FLOW = IWL_UCODE_TLV_DEBUG_BASE + 5, - IWL_UCODE_TLV_DEBUG_MAX = IWL_UCODE_TLV_TYPE_DEBUG_FLOW, + IWL_UCODE_TLV_DEBUG_MAX = IWL_UCODE_TLV_TYPE_TRIGGERS, /* TLVs 0x1000-0x2000 are for internal driver usage */ IWL_UCODE_TLV_FW_DBG_DUMP_LST = 0x1000, diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c index 1351f7fe5ae2..ae61ad129f06 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c @@ -1151,7 +1151,6 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, case IWL_UCODE_TLV_TYPE_HCMD: case IWL_UCODE_TLV_TYPE_REGIONS: case IWL_UCODE_TLV_TYPE_TRIGGERS: - case IWL_UCODE_TLV_TYPE_DEBUG_FLOW: if (iwlwifi_mod_params.enable_ini) iwl_dbg_tlv_alloc(drv->trans, tlv, false); break; From a64d4e8d451d443faf407479a09ba5197a8b4a88 Mon Sep 17 00:00:00 2001 From: Shahar S Matityahu Date: Mon, 27 May 2019 15:12:52 +0300 Subject: [PATCH 51/80] iwlwifi: dbg: align wrt log prints to the same format Align wrt log prints to the driver coding style Remove the ext field from the log and print it at the beginning of the apply point. Signed-off-by: Shahar S Matityahu Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 87 +++++++++---------- .../net/wireless/intel/iwlwifi/pcie/trans.c | 2 +- 2 files changed, 42 insertions(+), 47 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 2d37628694d2..2a4c2e772d1b 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -1688,7 +1688,7 @@ iwl_dump_ini_mem(struct iwl_fw_runtime *fwrt, if (!size) return; - IWL_DEBUG_FW(fwrt, "WRT: collecting region: id=%d, type=%d\n", + IWL_DEBUG_FW(fwrt, "WRT: Collecting region: id=%d, type=%d\n", le32_to_cpu(reg->region_id), type); num_of_ranges = ops->get_num_of_ranges(fwrt, reg); @@ -1705,7 +1705,7 @@ iwl_dump_ini_mem(struct iwl_fw_runtime *fwrt, range = ops->fill_mem_hdr(fwrt, reg, header); if (!range) { IWL_ERR(fwrt, - "WRT: failed to fill region header: id=%d, type=%d\n", + "WRT: Failed to fill region header: id=%d, type=%d\n", le32_to_cpu(reg->region_id), type); memset(*data, 0, size); return; @@ -1716,7 +1716,7 @@ iwl_dump_ini_mem(struct iwl_fw_runtime *fwrt, if (range_size < 0) { IWL_ERR(fwrt, - "WRT: failed to dump region: id=%d, type=%d\n", + "WRT: Failed to dump region: id=%d, type=%d\n", le32_to_cpu(reg->region_id), type); memset(*data, 0, size); return; @@ -1805,7 +1805,7 @@ static int iwl_fw_ini_get_trigger_len(struct iwl_fw_runtime *fwrt, reg = fwrt->dump.active_regs[reg_id]; if (!reg) { IWL_WARN(fwrt, - "WRT: unassigned region id %d, skipping\n", + "WRT: Unassigned region id %d, skipping\n", reg_id); continue; } @@ -2223,7 +2223,7 @@ int _iwl_fw_dbg_ini_collect(struct iwl_fw_runtime *fwrt, active->trig->occurrences = cpu_to_le32(--occur); if (le32_to_cpu(active->trig->force_restart)) { - IWL_WARN(fwrt, "WRT: force restart: trigger %d fired.\n", id); + IWL_WARN(fwrt, "WRT: Force restart: trigger %d fired.\n", id); iwl_force_nmi(fwrt->trans); return 0; } @@ -2243,7 +2243,7 @@ int _iwl_fw_dbg_ini_collect(struct iwl_fw_runtime *fwrt, fwrt->dump.wks[idx].ini_trig_id = id; - IWL_WARN(fwrt, "WRT: collecting data: ini trigger %d fired.\n", id); + IWL_WARN(fwrt, "WRT: Collecting data: ini trigger %d fired.\n", id); schedule_delayed_work(&fwrt->dump.wks[idx].wk, usecs_to_jiffies(delay)); @@ -2380,12 +2380,12 @@ static void iwl_fw_dbg_collect_sync(struct iwl_fw_runtime *fwrt, u8 wk_idx) goto out; } - IWL_DEBUG_FW_INFO(fwrt, "WRT: data collection start\n"); + IWL_DEBUG_FW_INFO(fwrt, "WRT: Data collection start\n"); if (iwl_trans_dbg_ini_valid(fwrt->trans)) iwl_fw_error_ini_dump(fwrt, wk_idx); else iwl_fw_error_dump(fwrt); - IWL_DEBUG_FW_INFO(fwrt, "WRT: data collection done\n"); + IWL_DEBUG_FW_INFO(fwrt, "WRT: Data collection done\n"); iwl_fw_dbg_stop_restart_recording(fwrt, ¶ms, false); @@ -2538,7 +2538,7 @@ static void iwl_fw_dbg_buffer_apply(struct iwl_fw_runtime *fwrt, } if (buf_location == IWL_FW_INI_LOCATION_SRAM_PATH) { - IWL_DEBUG_FW(trans, "WRT: applying SMEM buffer destination\n"); + IWL_DEBUG_FW(trans, "WRT: Applying SMEM buffer destination\n"); /* set sram monitor by enabling bit 7 */ iwl_set_bit(fwrt->trans, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_MONITOR_SRAM); @@ -2561,7 +2561,7 @@ static void iwl_fw_dbg_buffer_apply(struct iwl_fw_runtime *fwrt, return; IWL_DEBUG_FW(trans, - "WRT: applying DRAM buffer[%d] destination\n", block_idx); + "WRT: Applying DRAM buffer[%d] destination\n", block_idx); cmd->num_frags = cpu_to_le32(1); cmd->fragments[0].address = @@ -2574,8 +2574,7 @@ static void iwl_fw_dbg_buffer_apply(struct iwl_fw_runtime *fwrt, } static void iwl_fw_dbg_send_hcmd(struct iwl_fw_runtime *fwrt, - struct iwl_ucode_tlv *tlv, - bool ext) + struct iwl_ucode_tlv *tlv) { struct iwl_fw_ini_hcmd_tlv *hcmd_tlv = (void *)&tlv->data[0]; struct iwl_fw_ini_hcmd *data = &hcmd_tlv->hcmd; @@ -2591,45 +2590,41 @@ static void iwl_fw_dbg_send_hcmd(struct iwl_fw_runtime *fwrt, if (le32_to_cpu(hcmd_tlv->domain) != IWL_FW_INI_DBG_DOMAIN_ALWAYS_ON) return; - IWL_DEBUG_FW(fwrt, - "WRT: ext=%d. Sending host command id=0x%x, group=0x%x\n", - ext, data->id, data->group); + IWL_DEBUG_FW(fwrt, "WRT: Sending host command id=0x%x, group=0x%x\n", + data->id, data->group); iwl_trans_send_cmd(fwrt->trans, &hcmd); } static void iwl_fw_dbg_update_regions(struct iwl_fw_runtime *fwrt, struct iwl_fw_ini_region_tlv *tlv, - bool ext, enum iwl_fw_ini_apply_point pnt) + enum iwl_fw_ini_apply_point pnt) { void *iter = (void *)tlv->region_config; int i, size = le32_to_cpu(tlv->num_regions); const char *err_st = - "WRT: ext=%d. Invalid region %s %d for apply point %d\n"; + "WRT: Invalid region %s %d for apply point %d\n"; for (i = 0; i < size; i++) { struct iwl_fw_ini_region_cfg *reg = iter, **active; int id = le32_to_cpu(reg->region_id); u32 type = le32_to_cpu(reg->region_type); - if (WARN(id >= ARRAY_SIZE(fwrt->dump.active_regs), err_st, ext, - "id", id, pnt)) + if (WARN(id >= ARRAY_SIZE(fwrt->dump.active_regs), err_st, "id", + id, pnt)) break; if (WARN(type == 0 || type >= IWL_FW_INI_REGION_NUM, err_st, - ext, "type", type, pnt)) + "type", type, pnt)) break; active = &fwrt->dump.active_regs[id]; if (*active) - IWL_WARN(fwrt->trans, - "WRT: ext=%d. Region id %d override\n", - ext, id); + IWL_WARN(fwrt->trans, "WRT: Region id %d override\n", + id); - IWL_DEBUG_FW(fwrt, - "WRT: ext=%d. Activating region id %d\n", - ext, id); + IWL_DEBUG_FW(fwrt, "WRT: Activating region id %d\n", id); *active = reg; @@ -2676,7 +2671,6 @@ static int iwl_fw_dbg_trig_realloc(struct iwl_fw_runtime *fwrt, static void iwl_fw_dbg_update_triggers(struct iwl_fw_runtime *fwrt, struct iwl_fw_ini_trigger_tlv *tlv, - bool ext, enum iwl_fw_ini_apply_point apply_point) { int i, size = le32_to_cpu(tlv->num_triggers); @@ -2690,8 +2684,8 @@ static void iwl_fw_dbg_update_triggers(struct iwl_fw_runtime *fwrt, sizeof(__le32); if (WARN(id >= ARRAY_SIZE(fwrt->dump.active_trigs), - "WRT: ext=%d. Invalid trigger id %d for apply point %d\n", - ext, id, apply_point)) + "WRT: Invalid trigger id %d for apply point %d\n", id, + apply_point)) break; active = &fwrt->dump.active_trigs[id]; @@ -2699,9 +2693,7 @@ static void iwl_fw_dbg_update_triggers(struct iwl_fw_runtime *fwrt, if (!active->active) { size_t trig_size = sizeof(*trig) + trig_regs_size; - IWL_DEBUG_FW(fwrt, - "WRT: ext=%d. Activating trigger %d\n", - ext, id); + IWL_DEBUG_FW(fwrt, "WRT: Activating trigger %d\n", id); if (iwl_fw_dbg_trig_realloc(fwrt, active, id, trig_size)) @@ -2722,14 +2714,14 @@ static void iwl_fw_dbg_update_triggers(struct iwl_fw_runtime *fwrt, if (region_override) { IWL_DEBUG_FW(fwrt, - "WRT: ext=%d. Trigger %d regions override\n", - ext, id); + "WRT: Trigger %d regions override\n", + id); mem_to_add -= active_regs * sizeof(__le32); } else { IWL_DEBUG_FW(fwrt, - "WRT: ext=%d. Trigger %d regions appending\n", - ext, id); + "WRT: Trigger %d regions appending\n", + id); offset += active_regs; new_regs += active_regs; @@ -2741,8 +2733,8 @@ static void iwl_fw_dbg_update_triggers(struct iwl_fw_runtime *fwrt, if (conf_override) { IWL_DEBUG_FW(fwrt, - "WRT: ext=%d. Trigger %d configuration override\n", - ext, id); + "WRT: Trigger %d configuration override\n", + id); memcpy(active->trig, trig, sizeof(*trig)); } @@ -2812,18 +2804,17 @@ static void _iwl_fw_dbg_apply_point(struct iwl_fw_runtime *fwrt, ext, pnt); break; } - iwl_fw_dbg_send_hcmd(fwrt, tlv, ext); + iwl_fw_dbg_send_hcmd(fwrt, tlv); break; case IWL_UCODE_TLV_TYPE_REGIONS: - iwl_fw_dbg_update_regions(fwrt, ini_tlv, ext, pnt); + iwl_fw_dbg_update_regions(fwrt, ini_tlv, pnt); break; case IWL_UCODE_TLV_TYPE_TRIGGERS: - iwl_fw_dbg_update_triggers(fwrt, ini_tlv, ext, pnt); + iwl_fw_dbg_update_triggers(fwrt, ini_tlv, pnt); break; default: - WARN_ONCE(1, - "WRT: ext=%d. Invalid TLV 0x%x for apply point\n", - ext, type); + WARN_ONCE(1, "WRT: Invalid TLV 0x%x for apply point\n", + type); break; } } @@ -2855,17 +2846,21 @@ void iwl_fw_dbg_apply_point(struct iwl_fw_runtime *fwrt, { void *data; - IWL_DEBUG_FW(fwrt, "WRT: enabling apply point %d\n", apply_point); - if (apply_point == IWL_FW_INI_APPLY_EARLY) iwl_fw_dbg_ini_reset_cfg(fwrt); if (fwrt->trans->dbg.internal_ini_cfg != IWL_INI_CFG_STATE_NOT_LOADED) { + IWL_DEBUG_FW(fwrt, + "WRT: Enabling internal configuration apply point %d\n", + apply_point); data = &fwrt->trans->dbg.apply_points[apply_point]; _iwl_fw_dbg_apply_point(fwrt, data, apply_point, false); } if (fwrt->trans->dbg.external_ini_cfg != IWL_INI_CFG_STATE_NOT_LOADED) { + IWL_DEBUG_FW(fwrt, + "WRT: Enabling external configuration apply point %d\n", + apply_point); data = &fwrt->trans->dbg.apply_points_ext[apply_point]; _iwl_fw_dbg_apply_point(fwrt, data, apply_point, true); } diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index 97808a251012..8639e60b4f40 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -901,7 +901,7 @@ void iwl_pcie_apply_destination(struct iwl_trans *trans) return; IWL_DEBUG_FW(trans, - "WRT: applying DRAM buffer[0] destination\n"); + "WRT: Applying DRAM buffer[0] destination\n"); iwl_write_umac_prph(trans, MON_BUFF_BASE_ADDR_VER2, trans->dbg.fw_mon[0].physical >> MON_BUFF_SHIFT_VER2); From 2c0c0240354754234c5152ddf5627f98fb01e88a Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Wed, 10 Jul 2019 15:00:18 +0300 Subject: [PATCH 52/80] iwlwifi: remove unnecessary IWL_DEVICE_AX200_COMMON definition Remove the IWL_DEVICE_AX200_COMMON definition, since it's only used once and relies mostly on IWL_DEVICE_22000_COMMON anyway. Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/cfg/22000.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c index 8ecdaabf710b..fd4bc43d8734 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c @@ -188,10 +188,6 @@ static const struct iwl_ht_params iwl_22000_ht_params = { .fw_mon_smem_cycle_cnt_ptr_addr = 0xa0c174, \ .fw_mon_smem_cycle_cnt_ptr_msk = 0xfffff -#define IWL_DEVICE_AX200_COMMON \ - IWL_DEVICE_22000_COMMON, \ - .umac_prph_offset = 0x300000 - #define IWL_DEVICE_22500 \ IWL_DEVICE_22000_COMMON, \ .device_family = IWL_DEVICE_FAMILY_22000, \ @@ -206,7 +202,8 @@ static const struct iwl_ht_params iwl_22000_ht_params = { .csr = &iwl_csr_v2 #define IWL_DEVICE_AX210 \ - IWL_DEVICE_AX200_COMMON, \ + IWL_DEVICE_22000_COMMON, \ + .umac_prph_offset = 0x300000, \ .device_family = IWL_DEVICE_FAMILY_AX210, \ .base_params = &iwl_22560_base_params, \ .csr = &iwl_csr_v1, \ From c8cfa08e39c17be2956c0379de38c885e1b11b66 Mon Sep 17 00:00:00 2001 From: Tova Mussai Date: Thu, 4 Jul 2019 13:41:01 +0300 Subject: [PATCH 53/80] iwlwifi: allocate bigger nvm data in case of UHB In case of Ultra-high-band (UHB), need to allocate nvm data structure in size of UHB channels array. Signed-off-by: Tova Mussai Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c index fd386bfbd5df..6d95941f56a7 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c @@ -942,7 +942,11 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg, u16 lar_config; const __le16 *ch_section; - if (cfg->nvm_type != IWL_NVM_EXT) + if (cfg->uhb_supported) + data = kzalloc(struct_size(data, channels, + IWL_NVM_NUM_CHANNELS_UHB), + GFP_KERNEL); + else if (cfg->nvm_type != IWL_NVM_EXT) data = kzalloc(struct_size(data, channels, IWL_NVM_NUM_CHANNELS), GFP_KERNEL); From dd36a507c806165c0f725413ee2e24c41d8a520d Mon Sep 17 00:00:00 2001 From: Tova Mussai Date: Thu, 4 Jul 2019 14:34:54 +0300 Subject: [PATCH 54/80] iwlwifi: mvm: look for the first supported channel when add/remove phy ctxt Can't rely that band 2.4 is always supported by the NIC and use the first channel in this band for the phy ctxt. Instead, look for the first channel in the first band that is supported Signed-off-by: Tova Mussai Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 11 ++++++++++- drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c | 11 ++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index d2baea22cba2..a6e360194e00 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -1282,6 +1282,7 @@ int iwl_mvm_up(struct iwl_mvm *mvm) int ret, i; struct ieee80211_channel *chan; struct cfg80211_chan_def chandef; + struct ieee80211_supported_band *sband = NULL; lockdep_assert_held(&mvm->mutex); @@ -1371,7 +1372,15 @@ int iwl_mvm_up(struct iwl_mvm *mvm) goto error; /* Add all the PHY contexts */ - chan = &mvm->hw->wiphy->bands[NL80211_BAND_2GHZ]->channels[0]; + i = 0; + while (!sband && i < NUM_NL80211_BANDS) + sband = mvm->hw->wiphy->bands[i++]; + + if (WARN_ON_ONCE(!sband)) + goto error; + + chan = &sband->channels[0]; + cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_NO_HT); for (i = 0; i < NUM_PHY_CTX; i++) { /* diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c index 86e40bae57e3..0243dbe8ac49 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c @@ -289,8 +289,17 @@ void iwl_mvm_phy_ctxt_unref(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt) if (ctxt->ref == 0) { struct ieee80211_channel *chan; struct cfg80211_chan_def chandef; + struct ieee80211_supported_band *sband = NULL; + enum nl80211_band band = NL80211_BAND_2GHZ; + + while (!sband && band < NUM_NL80211_BANDS) + sband = mvm->hw->wiphy->bands[band++]; + + if (WARN_ON(!sband)) + return; + + chan = &sband->channels[0]; - chan = &mvm->hw->wiphy->bands[NL80211_BAND_2GHZ]->channels[0]; cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_NO_HT); iwl_mvm_phy_ctxt_changed(mvm, ctxt, &chandef, 1, 1); } From 00eacde4974a2439ef44bf20a9fc6aa68bd953f8 Mon Sep 17 00:00:00 2001 From: Shahar S Matityahu Date: Thu, 13 Jun 2019 16:41:35 +0300 Subject: [PATCH 55/80] iwlwifi: dbg_ini: separate cfg and dump flows to different modules separate configuration flows and dump collection flows. make ini configuration flows be in iwl-dbg-tlv.c and dump related flows in dbg.c to better reflect their logical difference. Signed-off-by: Shahar S Matityahu Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 429 ------------------ drivers/net/wireless/intel/iwlwifi/fw/dbg.h | 3 - .../net/wireless/intel/iwlwifi/fw/runtime.h | 1 - .../net/wireless/intel/iwlwifi/iwl-dbg-tlv.c | 429 ++++++++++++++++++ .../net/wireless/intel/iwlwifi/iwl-dbg-tlv.h | 4 + drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 8 +- .../net/wireless/intel/iwlwifi/mvm/mac-ctxt.c | 2 +- .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 2 +- 9 files changed, 440 insertions(+), 440 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 2a4c2e772d1b..3320acc8a52f 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -2438,435 +2438,6 @@ void iwl_fw_dbg_read_d3_debug_data(struct iwl_fw_runtime *fwrt) } IWL_EXPORT_SYMBOL(iwl_fw_dbg_read_d3_debug_data); -static void iwl_fw_dbg_info_apply(struct iwl_fw_runtime *fwrt, - struct iwl_fw_ini_debug_info_tlv *dbg_info, - bool ext, enum iwl_fw_ini_apply_point pnt) -{ - u32 img_name_len = le32_to_cpu(dbg_info->img_name_len); - u32 dbg_cfg_name_len = le32_to_cpu(dbg_info->dbg_cfg_name_len); - - if (img_name_len != IWL_FW_INI_MAX_IMG_NAME_LEN) { - IWL_WARN(fwrt, - "WRT: ext=%d. Invalid image name length %d, expected %d\n", - ext, img_name_len, - IWL_FW_INI_MAX_IMG_NAME_LEN); - return; - } - - if (dbg_cfg_name_len != IWL_FW_INI_MAX_DBG_CFG_NAME_LEN) { - IWL_WARN(fwrt, - "WRT: ext=%d. Invalid debug cfg name length %d, expected %d\n", - ext, dbg_cfg_name_len, - IWL_FW_INI_MAX_DBG_CFG_NAME_LEN); - return; - } - - if (ext) { - memcpy(fwrt->dump.external_dbg_cfg_name, dbg_info->dbg_cfg_name, - sizeof(fwrt->dump.external_dbg_cfg_name)); - } else { - memcpy(fwrt->dump.img_name, dbg_info->img_name, - sizeof(fwrt->dump.img_name)); - memcpy(fwrt->dump.internal_dbg_cfg_name, dbg_info->dbg_cfg_name, - sizeof(fwrt->dump.internal_dbg_cfg_name)); - } -} - -static void -iwl_fw_dbg_buffer_allocation(struct iwl_fw_runtime *fwrt, u32 size) -{ - struct iwl_trans *trans = fwrt->trans; - void *virtual_addr = NULL; - dma_addr_t phys_addr; - - if (WARN_ON_ONCE(trans->dbg.num_blocks == - ARRAY_SIZE(trans->dbg.fw_mon))) - return; - - virtual_addr = - dma_alloc_coherent(fwrt->trans->dev, size, &phys_addr, - GFP_KERNEL | __GFP_NOWARN); - - /* TODO: alloc fragments if needed */ - if (!virtual_addr) - IWL_ERR(fwrt, "Failed to allocate debug memory\n"); - - IWL_DEBUG_FW(trans, - "Allocated DRAM buffer[%d], size=0x%x\n", - trans->dbg.num_blocks, size); - - trans->dbg.fw_mon[trans->dbg.num_blocks].block = virtual_addr; - trans->dbg.fw_mon[trans->dbg.num_blocks].physical = phys_addr; - trans->dbg.fw_mon[trans->dbg.num_blocks].size = size; - trans->dbg.num_blocks++; -} - -static void iwl_fw_dbg_buffer_apply(struct iwl_fw_runtime *fwrt, - struct iwl_fw_ini_allocation_tlv *alloc, - enum iwl_fw_ini_apply_point pnt) -{ - struct iwl_trans *trans = fwrt->trans; - struct iwl_ldbg_config_cmd ldbg_cmd = { - .type = cpu_to_le32(BUFFER_ALLOCATION), - }; - struct iwl_buffer_allocation_cmd *cmd = &ldbg_cmd.buffer_allocation; - struct iwl_host_cmd hcmd = { - .id = LDBG_CONFIG_CMD, - .flags = CMD_ASYNC, - .data[0] = &ldbg_cmd, - .len[0] = sizeof(ldbg_cmd), - }; - int block_idx = trans->dbg.num_blocks; - u32 buf_location = le32_to_cpu(alloc->buffer_location); - u32 alloc_id = le32_to_cpu(alloc->allocation_id); - - if (alloc_id <= IWL_FW_INI_ALLOCATION_INVALID || - alloc_id >= IWL_FW_INI_ALLOCATION_NUM) { - IWL_ERR(fwrt, "WRT: Invalid allocation id %d\n", alloc_id); - return; - } - - if (fwrt->trans->dbg.ini_dest == IWL_FW_INI_LOCATION_INVALID) - fwrt->trans->dbg.ini_dest = buf_location; - - if (buf_location != fwrt->trans->dbg.ini_dest) { - WARN(fwrt, - "WRT: attempt to override buffer location on apply point %d\n", - pnt); - - return; - } - - if (buf_location == IWL_FW_INI_LOCATION_SRAM_PATH) { - IWL_DEBUG_FW(trans, "WRT: Applying SMEM buffer destination\n"); - /* set sram monitor by enabling bit 7 */ - iwl_set_bit(fwrt->trans, CSR_HW_IF_CONFIG_REG, - CSR_HW_IF_CONFIG_REG_BIT_MONITOR_SRAM); - - return; - } - - if (buf_location != IWL_FW_INI_LOCATION_DRAM_PATH) - return; - - if (!(BIT(alloc_id) & fwrt->trans->dbg.is_alloc)) { - iwl_fw_dbg_buffer_allocation(fwrt, le32_to_cpu(alloc->size)); - if (block_idx == trans->dbg.num_blocks) - return; - fwrt->trans->dbg.is_alloc |= BIT(alloc_id); - } - - /* First block is assigned via registers / context info */ - if (trans->dbg.num_blocks == 1) - return; - - IWL_DEBUG_FW(trans, - "WRT: Applying DRAM buffer[%d] destination\n", block_idx); - - cmd->num_frags = cpu_to_le32(1); - cmd->fragments[0].address = - cpu_to_le64(trans->dbg.fw_mon[block_idx].physical); - cmd->fragments[0].size = alloc->size; - cmd->allocation_id = alloc->allocation_id; - cmd->buffer_location = alloc->buffer_location; - - iwl_trans_send_cmd(trans, &hcmd); -} - -static void iwl_fw_dbg_send_hcmd(struct iwl_fw_runtime *fwrt, - struct iwl_ucode_tlv *tlv) -{ - struct iwl_fw_ini_hcmd_tlv *hcmd_tlv = (void *)&tlv->data[0]; - struct iwl_fw_ini_hcmd *data = &hcmd_tlv->hcmd; - u16 len = le32_to_cpu(tlv->length) - sizeof(*hcmd_tlv); - - struct iwl_host_cmd hcmd = { - .id = WIDE_ID(data->group, data->id), - .len = { len, }, - .data = { data->data, }, - }; - - /* currently the driver supports always on domain only */ - if (le32_to_cpu(hcmd_tlv->domain) != IWL_FW_INI_DBG_DOMAIN_ALWAYS_ON) - return; - - IWL_DEBUG_FW(fwrt, "WRT: Sending host command id=0x%x, group=0x%x\n", - data->id, data->group); - - iwl_trans_send_cmd(fwrt->trans, &hcmd); -} - -static void iwl_fw_dbg_update_regions(struct iwl_fw_runtime *fwrt, - struct iwl_fw_ini_region_tlv *tlv, - enum iwl_fw_ini_apply_point pnt) -{ - void *iter = (void *)tlv->region_config; - int i, size = le32_to_cpu(tlv->num_regions); - const char *err_st = - "WRT: Invalid region %s %d for apply point %d\n"; - - for (i = 0; i < size; i++) { - struct iwl_fw_ini_region_cfg *reg = iter, **active; - int id = le32_to_cpu(reg->region_id); - u32 type = le32_to_cpu(reg->region_type); - - if (WARN(id >= ARRAY_SIZE(fwrt->dump.active_regs), err_st, "id", - id, pnt)) - break; - - if (WARN(type == 0 || type >= IWL_FW_INI_REGION_NUM, err_st, - "type", type, pnt)) - break; - - active = &fwrt->dump.active_regs[id]; - - if (*active) - IWL_WARN(fwrt->trans, "WRT: Region id %d override\n", - id); - - IWL_DEBUG_FW(fwrt, "WRT: Activating region id %d\n", id); - - *active = reg; - - if (type == IWL_FW_INI_REGION_TXF || - type == IWL_FW_INI_REGION_RXF) - iter += le32_to_cpu(reg->fifos.num_of_registers) * - sizeof(__le32); - else if (type == IWL_FW_INI_REGION_DEVICE_MEMORY || - type == IWL_FW_INI_REGION_PERIPHERY_MAC || - type == IWL_FW_INI_REGION_PERIPHERY_PHY || - type == IWL_FW_INI_REGION_PERIPHERY_AUX || - type == IWL_FW_INI_REGION_INTERNAL_BUFFER || - type == IWL_FW_INI_REGION_PAGING || - type == IWL_FW_INI_REGION_CSR || - type == IWL_FW_INI_REGION_LMAC_ERROR_TABLE || - type == IWL_FW_INI_REGION_UMAC_ERROR_TABLE) - iter += le32_to_cpu(reg->internal.num_of_ranges) * - sizeof(__le32); - - iter += sizeof(*reg); - } -} - -static int iwl_fw_dbg_trig_realloc(struct iwl_fw_runtime *fwrt, - struct iwl_fw_ini_active_triggers *active, - u32 id, int size) -{ - void *ptr; - - if (size <= active->size) - return 0; - - ptr = krealloc(active->trig, size, GFP_KERNEL); - if (!ptr) { - IWL_ERR(fwrt, "WRT: Failed to allocate memory for trigger %d\n", - id); - return -ENOMEM; - } - active->trig = ptr; - active->size = size; - - return 0; -} - -static void iwl_fw_dbg_update_triggers(struct iwl_fw_runtime *fwrt, - struct iwl_fw_ini_trigger_tlv *tlv, - enum iwl_fw_ini_apply_point apply_point) -{ - int i, size = le32_to_cpu(tlv->num_triggers); - void *iter = (void *)tlv->trigger_config; - - for (i = 0; i < size; i++) { - struct iwl_fw_ini_trigger *trig = iter; - struct iwl_fw_ini_active_triggers *active; - int id = le32_to_cpu(trig->trigger_id); - u32 trig_regs_size = le32_to_cpu(trig->num_regions) * - sizeof(__le32); - - if (WARN(id >= ARRAY_SIZE(fwrt->dump.active_trigs), - "WRT: Invalid trigger id %d for apply point %d\n", id, - apply_point)) - break; - - active = &fwrt->dump.active_trigs[id]; - - if (!active->active) { - size_t trig_size = sizeof(*trig) + trig_regs_size; - - IWL_DEBUG_FW(fwrt, "WRT: Activating trigger %d\n", id); - - if (iwl_fw_dbg_trig_realloc(fwrt, active, id, - trig_size)) - goto next; - - memcpy(active->trig, trig, trig_size); - - } else { - u32 conf_override = - !(le32_to_cpu(trig->override_trig) & 0xff); - u32 region_override = - !(le32_to_cpu(trig->override_trig) & 0xff00); - u32 offset = 0; - u32 active_regs = - le32_to_cpu(active->trig->num_regions); - u32 new_regs = le32_to_cpu(trig->num_regions); - int mem_to_add = trig_regs_size; - - if (region_override) { - IWL_DEBUG_FW(fwrt, - "WRT: Trigger %d regions override\n", - id); - - mem_to_add -= active_regs * sizeof(__le32); - } else { - IWL_DEBUG_FW(fwrt, - "WRT: Trigger %d regions appending\n", - id); - - offset += active_regs; - new_regs += active_regs; - } - - if (iwl_fw_dbg_trig_realloc(fwrt, active, id, - active->size + mem_to_add)) - goto next; - - if (conf_override) { - IWL_DEBUG_FW(fwrt, - "WRT: Trigger %d configuration override\n", - id); - - memcpy(active->trig, trig, sizeof(*trig)); - } - - memcpy(active->trig->data + offset, trig->data, - trig_regs_size); - active->trig->num_regions = cpu_to_le32(new_regs); - } - - /* Since zero means infinity - just set to -1 */ - if (!le32_to_cpu(active->trig->occurrences)) - active->trig->occurrences = cpu_to_le32(-1); - - active->active = true; - - if (id == IWL_FW_TRIGGER_ID_PERIODIC_TRIGGER) { - u32 collect_interval = le32_to_cpu(trig->trigger_data); - - /* the minimum allowed interval is 50ms */ - if (collect_interval < 50) { - collect_interval = 50; - trig->trigger_data = - cpu_to_le32(collect_interval); - } - - mod_timer(&fwrt->dump.periodic_trig, - jiffies + msecs_to_jiffies(collect_interval)); - } -next: - iter += sizeof(*trig) + trig_regs_size; - - } -} - -static void _iwl_fw_dbg_apply_point(struct iwl_fw_runtime *fwrt, - struct iwl_apply_point_data *data, - enum iwl_fw_ini_apply_point pnt, - bool ext) -{ - struct iwl_apply_point_data *iter; - - if (!data->list.next) - return; - - list_for_each_entry(iter, &data->list, list) { - struct iwl_ucode_tlv *tlv = &iter->tlv; - void *ini_tlv = (void *)tlv->data; - u32 type = le32_to_cpu(tlv->type); - - switch (type) { - case IWL_UCODE_TLV_TYPE_DEBUG_INFO: - iwl_fw_dbg_info_apply(fwrt, ini_tlv, ext, pnt); - break; - case IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION: - if (pnt != IWL_FW_INI_APPLY_EARLY) { - IWL_ERR(fwrt, - "WRT: ext=%d. Invalid apply point %d for buffer allocation\n", - ext, pnt); - break; - } - iwl_fw_dbg_buffer_apply(fwrt, ini_tlv, pnt); - break; - case IWL_UCODE_TLV_TYPE_HCMD: - if (pnt < IWL_FW_INI_APPLY_AFTER_ALIVE) { - IWL_ERR(fwrt, - "WRT: ext=%d. Invalid apply point %d for host command\n", - ext, pnt); - break; - } - iwl_fw_dbg_send_hcmd(fwrt, tlv); - break; - case IWL_UCODE_TLV_TYPE_REGIONS: - iwl_fw_dbg_update_regions(fwrt, ini_tlv, pnt); - break; - case IWL_UCODE_TLV_TYPE_TRIGGERS: - iwl_fw_dbg_update_triggers(fwrt, ini_tlv, pnt); - break; - default: - WARN_ONCE(1, "WRT: Invalid TLV 0x%x for apply point\n", - type); - break; - } - } -} - -static void iwl_fw_dbg_ini_reset_cfg(struct iwl_fw_runtime *fwrt) -{ - int i; - - for (i = 0; i < IWL_FW_INI_MAX_REGION_ID; i++) - fwrt->dump.active_regs[i] = NULL; - - /* disable the triggers, used in recovery flow */ - for (i = 0; i < IWL_FW_TRIGGER_ID_NUM; i++) - fwrt->dump.active_trigs[i].active = false; - - memset(fwrt->dump.img_name, 0, - sizeof(fwrt->dump.img_name)); - memset(fwrt->dump.internal_dbg_cfg_name, 0, - sizeof(fwrt->dump.internal_dbg_cfg_name)); - memset(fwrt->dump.external_dbg_cfg_name, 0, - sizeof(fwrt->dump.external_dbg_cfg_name)); - - fwrt->trans->dbg.ini_dest = IWL_FW_INI_LOCATION_INVALID; -} - -void iwl_fw_dbg_apply_point(struct iwl_fw_runtime *fwrt, - enum iwl_fw_ini_apply_point apply_point) -{ - void *data; - - if (apply_point == IWL_FW_INI_APPLY_EARLY) - iwl_fw_dbg_ini_reset_cfg(fwrt); - - if (fwrt->trans->dbg.internal_ini_cfg != IWL_INI_CFG_STATE_NOT_LOADED) { - IWL_DEBUG_FW(fwrt, - "WRT: Enabling internal configuration apply point %d\n", - apply_point); - data = &fwrt->trans->dbg.apply_points[apply_point]; - _iwl_fw_dbg_apply_point(fwrt, data, apply_point, false); - } - - if (fwrt->trans->dbg.external_ini_cfg != IWL_INI_CFG_STATE_NOT_LOADED) { - IWL_DEBUG_FW(fwrt, - "WRT: Enabling external configuration apply point %d\n", - apply_point); - data = &fwrt->trans->dbg.apply_points_ext[apply_point]; - _iwl_fw_dbg_apply_point(fwrt, data, apply_point, true); - } -} -IWL_EXPORT_SYMBOL(iwl_fw_dbg_apply_point); - void iwl_fw_dbg_stop_sync(struct iwl_fw_runtime *fwrt) { int i; diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h index 8faea2571788..deb84ba3dc7e 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h @@ -368,9 +368,6 @@ static inline void iwl_fw_resume_timestamp(struct iwl_fw_runtime *fwrt) {} #endif /* CONFIG_IWLWIFI_DEBUGFS */ -void iwl_fw_dbg_apply_point(struct iwl_fw_runtime *fwrt, - enum iwl_fw_ini_apply_point apply_point); - void iwl_fw_dbg_stop_sync(struct iwl_fw_runtime *fwrt); static inline void iwl_fw_lmac1_set_alive_err_table(struct iwl_trans *trans, diff --git a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h index 406ef73992c1..0a4e13e4cc2c 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h @@ -64,7 +64,6 @@ #include "iwl-trans.h" #include "img.h" #include "fw/api/debug.h" -#include "fw/api/dbg-tlv.h" #include "fw/api/paging.h" #include "iwl-eeprom-parse.h" diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c index 5b1644a70ace..b4fba73b5b23 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c @@ -60,8 +60,11 @@ *****************************************************************************/ #include +#include "iwl-drv.h" #include "iwl-trans.h" #include "iwl-dbg-tlv.h" +#include "fw/dbg.h" +#include "fw/runtime.h" /** * enum iwl_dbg_tlv_type - debug TLV types @@ -254,3 +257,429 @@ void iwl_dbg_tlv_load_bin(struct device *dev, struct iwl_trans *trans) release_firmware(fw); } + +static void +iwl_dbg_tlv_apply_debug_info(struct iwl_fw_runtime *fwrt, + struct iwl_fw_ini_debug_info_tlv *dbg_info, + bool ext, enum iwl_fw_ini_apply_point pnt) +{ + u32 img_name_len = le32_to_cpu(dbg_info->img_name_len); + u32 dbg_cfg_name_len = le32_to_cpu(dbg_info->dbg_cfg_name_len); + const char err_str[] = + "WRT: Invalid %s name length %d, expected %d\n"; + + if (img_name_len != IWL_FW_INI_MAX_IMG_NAME_LEN) { + IWL_WARN(fwrt, err_str, "image", img_name_len, + IWL_FW_INI_MAX_IMG_NAME_LEN); + return; + } + + if (dbg_cfg_name_len != IWL_FW_INI_MAX_DBG_CFG_NAME_LEN) { + IWL_WARN(fwrt, err_str, "debug cfg", dbg_cfg_name_len, + IWL_FW_INI_MAX_DBG_CFG_NAME_LEN); + return; + } + + if (ext) { + memcpy(fwrt->dump.external_dbg_cfg_name, dbg_info->dbg_cfg_name, + sizeof(fwrt->dump.external_dbg_cfg_name)); + } else { + memcpy(fwrt->dump.img_name, dbg_info->img_name, + sizeof(fwrt->dump.img_name)); + memcpy(fwrt->dump.internal_dbg_cfg_name, dbg_info->dbg_cfg_name, + sizeof(fwrt->dump.internal_dbg_cfg_name)); + } +} + +static void iwl_dbg_tlv_alloc_buffer(struct iwl_fw_runtime *fwrt, u32 size) +{ + struct iwl_trans *trans = fwrt->trans; + void *virtual_addr = NULL; + dma_addr_t phys_addr; + + if (WARN_ON_ONCE(trans->dbg.num_blocks == + ARRAY_SIZE(trans->dbg.fw_mon))) + return; + + virtual_addr = + dma_alloc_coherent(fwrt->trans->dev, size, &phys_addr, + GFP_KERNEL | __GFP_NOWARN); + + /* TODO: alloc fragments if needed */ + if (!virtual_addr) + IWL_ERR(fwrt, "Failed to allocate debug memory\n"); + + IWL_DEBUG_FW(trans, + "Allocated DRAM buffer[%d], size=0x%x\n", + trans->dbg.num_blocks, size); + + trans->dbg.fw_mon[trans->dbg.num_blocks].block = virtual_addr; + trans->dbg.fw_mon[trans->dbg.num_blocks].physical = phys_addr; + trans->dbg.fw_mon[trans->dbg.num_blocks].size = size; + trans->dbg.num_blocks++; +} + +static void iwl_dbg_tlv_apply_buffer(struct iwl_fw_runtime *fwrt, + struct iwl_fw_ini_allocation_tlv *alloc, + enum iwl_fw_ini_apply_point pnt) +{ + struct iwl_trans *trans = fwrt->trans; + struct iwl_ldbg_config_cmd ldbg_cmd = { + .type = cpu_to_le32(BUFFER_ALLOCATION), + }; + struct iwl_buffer_allocation_cmd *cmd = &ldbg_cmd.buffer_allocation; + struct iwl_host_cmd hcmd = { + .id = LDBG_CONFIG_CMD, + .flags = CMD_ASYNC, + .data[0] = &ldbg_cmd, + .len[0] = sizeof(ldbg_cmd), + }; + int block_idx = trans->dbg.num_blocks; + u32 buf_location = le32_to_cpu(alloc->buffer_location); + u32 alloc_id = le32_to_cpu(alloc->allocation_id); + + if (alloc_id <= IWL_FW_INI_ALLOCATION_INVALID || + alloc_id >= IWL_FW_INI_ALLOCATION_NUM) { + IWL_ERR(fwrt, "WRT: Invalid allocation id %d\n", alloc_id); + return; + } + + if (fwrt->trans->dbg.ini_dest == IWL_FW_INI_LOCATION_INVALID) + fwrt->trans->dbg.ini_dest = buf_location; + + if (buf_location != fwrt->trans->dbg.ini_dest) { + WARN(fwrt, + "WRT: attempt to override buffer location on apply point %d\n", + pnt); + + return; + } + + if (buf_location == IWL_FW_INI_LOCATION_SRAM_PATH) { + IWL_DEBUG_FW(trans, "WRT: Applying SMEM buffer destination\n"); + /* set sram monitor by enabling bit 7 */ + iwl_set_bit(fwrt->trans, CSR_HW_IF_CONFIG_REG, + CSR_HW_IF_CONFIG_REG_BIT_MONITOR_SRAM); + + return; + } + + if (buf_location != IWL_FW_INI_LOCATION_DRAM_PATH) + return; + + if (!(BIT(alloc_id) & fwrt->trans->dbg.is_alloc)) { + iwl_dbg_tlv_alloc_buffer(fwrt, le32_to_cpu(alloc->size)); + if (block_idx == trans->dbg.num_blocks) + return; + fwrt->trans->dbg.is_alloc |= BIT(alloc_id); + } + + /* First block is assigned via registers / context info */ + if (trans->dbg.num_blocks == 1) + return; + + IWL_DEBUG_FW(trans, + "WRT: Applying DRAM buffer[%d] destination\n", block_idx); + + cmd->num_frags = cpu_to_le32(1); + cmd->fragments[0].address = + cpu_to_le64(trans->dbg.fw_mon[block_idx].physical); + cmd->fragments[0].size = alloc->size; + cmd->allocation_id = alloc->allocation_id; + cmd->buffer_location = alloc->buffer_location; + + iwl_trans_send_cmd(trans, &hcmd); +} + +static void iwl_dbg_tlv_apply_hcmd(struct iwl_fw_runtime *fwrt, + struct iwl_ucode_tlv *tlv) +{ + struct iwl_fw_ini_hcmd_tlv *hcmd_tlv = (void *)&tlv->data[0]; + struct iwl_fw_ini_hcmd *data = &hcmd_tlv->hcmd; + u16 len = le32_to_cpu(tlv->length) - sizeof(*hcmd_tlv); + + struct iwl_host_cmd hcmd = { + .id = WIDE_ID(data->group, data->id), + .len = { len, }, + .data = { data->data, }, + }; + + /* currently the driver supports always on domain only */ + if (le32_to_cpu(hcmd_tlv->domain) != IWL_FW_INI_DBG_DOMAIN_ALWAYS_ON) + return; + + IWL_DEBUG_FW(fwrt, "WRT: Sending host command id=0x%x, group=0x%x\n", + data->id, data->group); + + iwl_trans_send_cmd(fwrt->trans, &hcmd); +} + +static void iwl_dbg_tlv_apply_region(struct iwl_fw_runtime *fwrt, + struct iwl_fw_ini_region_tlv *tlv, + enum iwl_fw_ini_apply_point pnt) +{ + void *iter = (void *)tlv->region_config; + int i, size = le32_to_cpu(tlv->num_regions); + const char *err_st = + "WRT: Invalid region %s %d for apply point %d\n"; + + for (i = 0; i < size; i++) { + struct iwl_fw_ini_region_cfg *reg = iter, **active; + int id = le32_to_cpu(reg->region_id); + u32 type = le32_to_cpu(reg->region_type); + + if (WARN(id >= ARRAY_SIZE(fwrt->dump.active_regs), err_st, "id", + id, pnt)) + break; + + if (WARN(type == 0 || type >= IWL_FW_INI_REGION_NUM, err_st, + "type", type, pnt)) + break; + + active = &fwrt->dump.active_regs[id]; + + if (*active) + IWL_WARN(fwrt->trans, "WRT: Region id %d override\n", + id); + + IWL_DEBUG_FW(fwrt, "WRT: Activating region id %d\n", id); + + *active = reg; + + if (type == IWL_FW_INI_REGION_TXF || + type == IWL_FW_INI_REGION_RXF) + iter += le32_to_cpu(reg->fifos.num_of_registers) * + sizeof(__le32); + else if (type == IWL_FW_INI_REGION_DEVICE_MEMORY || + type == IWL_FW_INI_REGION_PERIPHERY_MAC || + type == IWL_FW_INI_REGION_PERIPHERY_PHY || + type == IWL_FW_INI_REGION_PERIPHERY_AUX || + type == IWL_FW_INI_REGION_INTERNAL_BUFFER || + type == IWL_FW_INI_REGION_PAGING || + type == IWL_FW_INI_REGION_CSR || + type == IWL_FW_INI_REGION_LMAC_ERROR_TABLE || + type == IWL_FW_INI_REGION_UMAC_ERROR_TABLE) + iter += le32_to_cpu(reg->internal.num_of_ranges) * + sizeof(__le32); + + iter += sizeof(*reg); + } +} + +static int iwl_dbg_tlv_trig_realloc(struct iwl_fw_runtime *fwrt, + struct iwl_fw_ini_active_triggers *active, + u32 id, int size) +{ + void *ptr; + + if (size <= active->size) + return 0; + + ptr = krealloc(active->trig, size, GFP_KERNEL); + if (!ptr) { + IWL_ERR(fwrt, "WRT: Failed to allocate memory for trigger %d\n", + id); + return -ENOMEM; + } + active->trig = ptr; + active->size = size; + + return 0; +} + +static void iwl_dbg_tlv_apply_trigger(struct iwl_fw_runtime *fwrt, + struct iwl_fw_ini_trigger_tlv *tlv, + enum iwl_fw_ini_apply_point apply_point) +{ + int i, size = le32_to_cpu(tlv->num_triggers); + void *iter = (void *)tlv->trigger_config; + + for (i = 0; i < size; i++) { + struct iwl_fw_ini_trigger *trig = iter; + struct iwl_fw_ini_active_triggers *active; + int id = le32_to_cpu(trig->trigger_id); + u32 trig_regs_size = le32_to_cpu(trig->num_regions) * + sizeof(__le32); + + if (WARN(id >= ARRAY_SIZE(fwrt->dump.active_trigs), + "WRT: Invalid trigger id %d for apply point %d\n", id, + apply_point)) + break; + + active = &fwrt->dump.active_trigs[id]; + + if (!active->active) { + size_t trig_size = sizeof(*trig) + trig_regs_size; + + IWL_DEBUG_FW(fwrt, "WRT: Activating trigger %d\n", id); + + if (iwl_dbg_tlv_trig_realloc(fwrt, active, id, + trig_size)) + goto next; + + memcpy(active->trig, trig, trig_size); + + } else { + u32 conf_override = + !(le32_to_cpu(trig->override_trig) & 0xff); + u32 region_override = + !(le32_to_cpu(trig->override_trig) & 0xff00); + u32 offset = 0; + u32 active_regs = + le32_to_cpu(active->trig->num_regions); + u32 new_regs = le32_to_cpu(trig->num_regions); + int mem_to_add = trig_regs_size; + + if (region_override) { + IWL_DEBUG_FW(fwrt, + "WRT: Trigger %d regions override\n", + id); + + mem_to_add -= active_regs * sizeof(__le32); + } else { + IWL_DEBUG_FW(fwrt, + "WRT: Trigger %d regions appending\n", + id); + + offset += active_regs; + new_regs += active_regs; + } + + if (iwl_dbg_tlv_trig_realloc(fwrt, active, id, + active->size + mem_to_add)) + goto next; + + if (conf_override) { + IWL_DEBUG_FW(fwrt, + "WRT: Trigger %d configuration override\n", + id); + + memcpy(active->trig, trig, sizeof(*trig)); + } + + memcpy(active->trig->data + offset, trig->data, + trig_regs_size); + active->trig->num_regions = cpu_to_le32(new_regs); + } + + /* Since zero means infinity - just set to -1 */ + if (!le32_to_cpu(active->trig->occurrences)) + active->trig->occurrences = cpu_to_le32(-1); + + active->active = true; + + if (id == IWL_FW_TRIGGER_ID_PERIODIC_TRIGGER) { + u32 collect_interval = le32_to_cpu(trig->trigger_data); + + /* the minimum allowed interval is 50ms */ + if (collect_interval < 50) { + collect_interval = 50; + trig->trigger_data = + cpu_to_le32(collect_interval); + } + + mod_timer(&fwrt->dump.periodic_trig, + jiffies + msecs_to_jiffies(collect_interval)); + } +next: + iter += sizeof(*trig) + trig_regs_size; + } +} + +static void _iwl_dbg_tlv_apply_point(struct iwl_fw_runtime *fwrt, + struct iwl_apply_point_data *data, + enum iwl_fw_ini_apply_point pnt, + bool ext) +{ + struct iwl_apply_point_data *iter; + + if (!data->list.next) + return; + + list_for_each_entry(iter, &data->list, list) { + struct iwl_ucode_tlv *tlv = &iter->tlv; + void *ini_tlv = (void *)tlv->data; + u32 type = le32_to_cpu(tlv->type); + const char invalid_ap_str[] = + "WRT: Invalid apply point %d for %s\n"; + + switch (type) { + case IWL_UCODE_TLV_TYPE_DEBUG_INFO: + iwl_dbg_tlv_apply_debug_info(fwrt, ini_tlv, ext, pnt); + break; + case IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION: + if (pnt != IWL_FW_INI_APPLY_EARLY) { + IWL_ERR(fwrt, invalid_ap_str, pnt, + "buffer allocation"); + break; + } + iwl_dbg_tlv_apply_buffer(fwrt, ini_tlv, pnt); + break; + case IWL_UCODE_TLV_TYPE_HCMD: + if (pnt < IWL_FW_INI_APPLY_AFTER_ALIVE) { + IWL_ERR(fwrt, invalid_ap_str, pnt, + "host command"); + break; + } + iwl_dbg_tlv_apply_hcmd(fwrt, tlv); + break; + case IWL_UCODE_TLV_TYPE_REGIONS: + iwl_dbg_tlv_apply_region(fwrt, ini_tlv, pnt); + break; + case IWL_UCODE_TLV_TYPE_TRIGGERS: + iwl_dbg_tlv_apply_trigger(fwrt, ini_tlv, pnt); + break; + default: + WARN_ONCE(1, "WRT: Invalid TLV 0x%x for apply point\n", + type); + break; + } + } +} + +static void iwl_dbg_tlv_reset_cfg(struct iwl_fw_runtime *fwrt) +{ + int i; + + for (i = 0; i < IWL_FW_INI_MAX_REGION_ID; i++) + fwrt->dump.active_regs[i] = NULL; + + /* disable the triggers, used in recovery flow */ + for (i = 0; i < IWL_FW_TRIGGER_ID_NUM; i++) + fwrt->dump.active_trigs[i].active = false; + + memset(fwrt->dump.img_name, 0, + sizeof(fwrt->dump.img_name)); + memset(fwrt->dump.internal_dbg_cfg_name, 0, + sizeof(fwrt->dump.internal_dbg_cfg_name)); + memset(fwrt->dump.external_dbg_cfg_name, 0, + sizeof(fwrt->dump.external_dbg_cfg_name)); + + fwrt->trans->dbg.ini_dest = IWL_FW_INI_LOCATION_INVALID; +} + +void iwl_dbg_tlv_apply_point(struct iwl_fw_runtime *fwrt, + enum iwl_fw_ini_apply_point apply_point) +{ + void *data; + + if (apply_point == IWL_FW_INI_APPLY_EARLY) + iwl_dbg_tlv_reset_cfg(fwrt); + + if (fwrt->trans->dbg.internal_ini_cfg != IWL_INI_CFG_STATE_NOT_LOADED) { + IWL_DEBUG_FW(fwrt, + "WRT: Enabling internal configuration apply point %d\n", + apply_point); + data = &fwrt->trans->dbg.apply_points[apply_point]; + _iwl_dbg_tlv_apply_point(fwrt, data, apply_point, false); + } + + if (fwrt->trans->dbg.external_ini_cfg != IWL_INI_CFG_STATE_NOT_LOADED) { + IWL_DEBUG_FW(fwrt, + "WRT: Enabling external configuration apply point %d\n", + apply_point); + data = &fwrt->trans->dbg.apply_points_ext[apply_point]; + _iwl_dbg_tlv_apply_point(fwrt, data, apply_point, true); + } +} +IWL_EXPORT_SYMBOL(iwl_dbg_tlv_apply_point); diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h index 3a60590d274d..93496945d313 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h @@ -75,9 +75,13 @@ struct iwl_apply_point_data { }; struct iwl_trans; +struct iwl_fw_runtime; + void iwl_dbg_tlv_load_bin(struct device *dev, struct iwl_trans *trans); void iwl_dbg_tlv_free(struct iwl_trans *trans); void iwl_dbg_tlv_alloc(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv, bool ext); +void iwl_dbg_tlv_apply_point(struct iwl_fw_runtime *fwrt, + enum iwl_fw_ini_apply_point apply_point); #endif /* __iwl_dbg_tlv_h__*/ diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index a6e360194e00..f09f24089fe7 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -430,7 +430,7 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) iwl_wait_init_complete, NULL); - iwl_fw_dbg_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_EARLY); + iwl_dbg_tlv_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_EARLY); /* Will also start the device */ ret = iwl_mvm_load_ucode_wait_alive(mvm, IWL_UCODE_REGULAR); @@ -438,7 +438,7 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) IWL_ERR(mvm, "Failed to start RT ucode: %d\n", ret); goto error; } - iwl_fw_dbg_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_AFTER_ALIVE); + iwl_dbg_tlv_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_AFTER_ALIVE); /* Send init config command to mark that we are sending NVM access * commands @@ -1263,7 +1263,7 @@ static int iwl_mvm_load_rt_fw(struct iwl_mvm *mvm) if (ret) return ret; - iwl_fw_dbg_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_EARLY); + iwl_dbg_tlv_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_EARLY); mvm->rfkill_safe_init_done = false; ret = iwl_mvm_load_ucode_wait_alive(mvm, IWL_UCODE_REGULAR); @@ -1272,7 +1272,7 @@ static int iwl_mvm_load_rt_fw(struct iwl_mvm *mvm) mvm->rfkill_safe_init_done = true; - iwl_fw_dbg_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_AFTER_ALIVE); + iwl_dbg_tlv_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_AFTER_ALIVE); return iwl_init_paging(&mvm->fwrt, mvm->fwrt.cur_fw_img); } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c index 8fa356402bbd..62536c09e727 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c @@ -1447,7 +1447,7 @@ void iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm, rx_missed_bcon >= stop_trig_missed_bcon) iwl_fw_dbg_collect_trig(&mvm->fwrt, trigger, NULL); - iwl_fw_dbg_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_MISSED_BEACONS); + iwl_dbg_tlv_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_MISSED_BEACONS); out: rcu_read_unlock(); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index b8d82509f9fd..acc7fee9cb3f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -1106,7 +1106,7 @@ int __iwl_mvm_mac_start(struct iwl_mvm *mvm) } ret = iwl_mvm_up(mvm); - iwl_fw_dbg_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_POST_INIT); + iwl_dbg_tlv_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_POST_INIT); if (ret && test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) { /* Something went wrong - we need to finish some cleanup diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c index afa44345f37b..892db3dcdc27 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c @@ -1940,7 +1940,7 @@ void iwl_mvm_rx_umac_scan_complete_notif(struct iwl_mvm *mvm, mvm->scan_uid_status[uid] = 0; - iwl_fw_dbg_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_SCAN_COMPLETE); + iwl_dbg_tlv_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_SCAN_COMPLETE); } void iwl_mvm_rx_umac_scan_iter_complete_notif(struct iwl_mvm *mvm, From 0fc296f8efbcb718b82f43504e5b7ee583585b64 Mon Sep 17 00:00:00 2001 From: Shahar S Matityahu Date: Sun, 16 Jun 2019 17:05:21 +0300 Subject: [PATCH 56/80] iwlwifi: dbg_ini: use linked list for dump TLVs during dump creation Avoid iterating over dump TLVs twice for size calculation by using linked list to store the dump TLVs. Signed-off-by: Shahar S Matityahu Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 288 ++++++++---------- .../wireless/intel/iwlwifi/fw/error-dump.h | 22 ++ 2 files changed, 152 insertions(+), 158 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 3320acc8a52f..73af6e6a54c3 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -1664,38 +1664,50 @@ struct iwl_dump_ini_mem_ops { }; /** - * iwl_dump_ini_mem - copy a memory region into the dump - * @fwrt: fw runtime struct. - * @data: dump memory data. - * @reg: region to copy to the dump. - * @ops: memory dump operations. + * iwl_dump_ini_mem + * + * Creates a dump tlv and copy a memory region into it. + * Returns the size of the current dump tlv or 0 if failed + * + * @fwrt: fw runtime struct + * @list: list to add the dump tlv to + * @reg: memory region + * @ops: memory dump operations */ -static void -iwl_dump_ini_mem(struct iwl_fw_runtime *fwrt, - struct iwl_fw_error_dump_data **data, - struct iwl_fw_ini_region_cfg *reg, - struct iwl_dump_ini_mem_ops *ops) +static u32 iwl_dump_ini_mem(struct iwl_fw_runtime *fwrt, struct list_head *list, + struct iwl_fw_ini_region_cfg *reg, + struct iwl_dump_ini_mem_ops *ops) { - struct iwl_fw_ini_error_dump_header *header = (void *)(*data)->data; + struct iwl_fw_ini_dump_entry *entry; + struct iwl_fw_error_dump_data *tlv; + struct iwl_fw_ini_error_dump_header *header; u32 num_of_ranges, i, type = le32_to_cpu(reg->region_type), size; void *range; if (WARN_ON(!ops || !ops->get_num_of_ranges || !ops->get_size || !ops->fill_mem_hdr || !ops->fill_range)) - return; + return 0; size = ops->get_size(fwrt, reg); if (!size) - return; + return 0; + + entry = kmalloc(sizeof(*entry) + sizeof(*tlv) + size, GFP_KERNEL); + if (!entry) + return 0; + + entry->size = sizeof(*tlv) + size; + + tlv = (void *)entry->data; + tlv->type = cpu_to_le32(type); + tlv->len = cpu_to_le32(size); IWL_DEBUG_FW(fwrt, "WRT: Collecting region: id=%d, type=%d\n", le32_to_cpu(reg->region_id), type); num_of_ranges = ops->get_num_of_ranges(fwrt, reg); - (*data)->type = cpu_to_le32(type); - (*data)->len = cpu_to_le32(size); - + header = (void *)tlv->data; header->region_id = reg->region_id; header->num_of_ranges = cpu_to_le32(num_of_ranges); header->name_len = cpu_to_le32(min_t(int, IWL_FW_INI_MAX_NAME, @@ -1707,8 +1719,7 @@ iwl_dump_ini_mem(struct iwl_fw_runtime *fwrt, IWL_ERR(fwrt, "WRT: Failed to fill region header: id=%d, type=%d\n", le32_to_cpu(reg->region_id), type); - memset(*data, 0, size); - return; + goto out_err; } for (i = 0; i < num_of_ranges; i++) { @@ -1718,23 +1729,42 @@ iwl_dump_ini_mem(struct iwl_fw_runtime *fwrt, IWL_ERR(fwrt, "WRT: Failed to dump region: id=%d, type=%d\n", le32_to_cpu(reg->region_id), type); - memset(*data, 0, size); - return; + goto out_err; } range = range + range_size; } - *data = iwl_fw_error_next_data(*data); + + list_add_tail(&entry->list, list); + + return entry->size; + +out_err: + kfree(entry); + + return 0; } -static void iwl_dump_ini_info(struct iwl_fw_runtime *fwrt, - struct iwl_fw_ini_trigger *trigger, - struct iwl_fw_error_dump_data **data) +static u32 iwl_dump_ini_info(struct iwl_fw_runtime *fwrt, + struct iwl_fw_ini_trigger *trigger, + struct list_head *list) { - struct iwl_fw_ini_dump_info *dump = (void *)(*data)->data; + struct iwl_fw_ini_dump_entry *entry; + struct iwl_fw_error_dump_data *tlv; + struct iwl_fw_ini_dump_info *dump; u32 reg_ids_size = le32_to_cpu(trigger->num_regions) * sizeof(__le32); + u32 size = sizeof(*tlv) + sizeof(*dump) + reg_ids_size; - (*data)->type = cpu_to_le32(IWL_INI_DUMP_INFO_TYPE); - (*data)->len = cpu_to_le32(sizeof(*dump) + reg_ids_size); + entry = kmalloc(sizeof(*entry) + size, GFP_KERNEL); + if (!entry) + return 0; + + entry->size = size; + + tlv = (void *)entry->data; + tlv->type = cpu_to_le32(IWL_INI_DUMP_INFO_TYPE); + tlv->len = cpu_to_le32(sizeof(*dump) + reg_ids_size); + + dump = (void *)tlv->data; dump->version = cpu_to_le32(IWL_INI_DUMP_VER); dump->trigger_id = trigger->trigger_id; @@ -1773,31 +1803,31 @@ static void iwl_dump_ini_info(struct iwl_fw_runtime *fwrt, dump->external_dbg_cfg_name_len = cpu_to_le32(sizeof(dump->external_dbg_cfg_name)); - /* dump info size is allocated in iwl_fw_ini_get_trigger_len. - * The driver allocates (sizeof(*dump) + reg_ids_size) so it is safe to - * use reg_ids_size - */ memcpy(dump->external_dbg_cfg_name, fwrt->dump.external_dbg_cfg_name, sizeof(dump->external_dbg_cfg_name)); dump->regions_num = trigger->num_regions; memcpy(dump->region_ids, trigger->data, reg_ids_size); - *data = iwl_fw_error_next_data(*data); + /* add dump info TLV to the beginning of the list since it needs to be + * the first TLV in the dump + */ + list_add(&entry->list, list); + + return entry->size; } -static int iwl_fw_ini_get_trigger_len(struct iwl_fw_runtime *fwrt, - struct iwl_fw_ini_trigger *trigger) +static u32 iwl_dump_ini_trigger(struct iwl_fw_runtime *fwrt, + struct iwl_fw_ini_trigger *trigger, + struct list_head *list) { - int i, ret_size = 0, hdr_len = sizeof(struct iwl_fw_error_dump_data); - u32 size; - - if (!trigger || !trigger->num_regions) - return 0; + int i; + u32 size = 0; for (i = 0; i < le32_to_cpu(trigger->num_regions); i++) { u32 reg_id = le32_to_cpu(trigger->data[i]); struct iwl_fw_ini_region_cfg *reg; + struct iwl_dump_ini_mem_ops ops; if (WARN_ON(reg_id >= ARRAY_SIZE(fwrt->dump.active_regs))) continue; @@ -1810,89 +1840,6 @@ static int iwl_fw_ini_get_trigger_len(struct iwl_fw_runtime *fwrt, continue; } - /* currently the driver supports always on domain only */ - if (le32_to_cpu(reg->domain) != IWL_FW_INI_DBG_DOMAIN_ALWAYS_ON) - continue; - - switch (le32_to_cpu(reg->region_type)) { - case IWL_FW_INI_REGION_DEVICE_MEMORY: - case IWL_FW_INI_REGION_PERIPHERY_MAC: - case IWL_FW_INI_REGION_PERIPHERY_PHY: - case IWL_FW_INI_REGION_PERIPHERY_AUX: - case IWL_FW_INI_REGION_CSR: - case IWL_FW_INI_REGION_LMAC_ERROR_TABLE: - case IWL_FW_INI_REGION_UMAC_ERROR_TABLE: - size = iwl_dump_ini_mem_get_size(fwrt, reg); - if (size) - ret_size += hdr_len + size; - break; - case IWL_FW_INI_REGION_TXF: - size = iwl_dump_ini_txf_get_size(fwrt, reg); - if (size) - ret_size += hdr_len + size; - break; - case IWL_FW_INI_REGION_RXF: - size = iwl_dump_ini_rxf_get_size(fwrt, reg); - if (size) - ret_size += hdr_len + size; - break; - case IWL_FW_INI_REGION_PAGING: - if (iwl_fw_dbg_is_paging_enabled(fwrt)) - size = iwl_dump_ini_paging_get_size(fwrt, reg); - else - size = iwl_dump_ini_paging_gen2_get_size(fwrt, - reg); - if (size) - ret_size += hdr_len + size; - break; - case IWL_FW_INI_REGION_DRAM_BUFFER: - if (!fwrt->trans->dbg.num_blocks) - break; - size = iwl_dump_ini_mon_dram_get_size(fwrt, reg); - if (size) - ret_size += hdr_len + size; - break; - case IWL_FW_INI_REGION_INTERNAL_BUFFER: - size = iwl_dump_ini_mon_smem_get_size(fwrt, reg); - if (size) - ret_size += hdr_len + size; - break; - case IWL_FW_INI_REGION_DRAM_IMR: - /* Undefined yet */ - default: - break; - } - } - - /* add dump info size */ - if (ret_size) - ret_size += hdr_len + sizeof(struct iwl_fw_ini_dump_info) + - (le32_to_cpu(trigger->num_regions) * sizeof(__le32)); - - return ret_size; -} - -static void iwl_fw_ini_dump_trigger(struct iwl_fw_runtime *fwrt, - struct iwl_fw_ini_trigger *trigger, - struct iwl_fw_error_dump_data **data) -{ - int i, num = le32_to_cpu(trigger->num_regions); - - iwl_dump_ini_info(fwrt, trigger, data); - - for (i = 0; i < num; i++) { - u32 reg_id = le32_to_cpu(trigger->data[i]); - struct iwl_fw_ini_region_cfg *reg; - struct iwl_dump_ini_mem_ops ops; - - if (reg_id >= ARRAY_SIZE(fwrt->dump.active_regs)) - continue; - - reg = fwrt->dump.active_regs[reg_id]; - /* Don't warn, get_trigger_len already warned */ - if (!reg) - continue; - /* currently the driver supports always on domain only */ if (le32_to_cpu(reg->domain) != IWL_FW_INI_DBG_DOMAIN_ALWAYS_ON) continue; @@ -1905,28 +1852,28 @@ static void iwl_fw_ini_dump_trigger(struct iwl_fw_runtime *fwrt, ops.get_size = iwl_dump_ini_mem_get_size; ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header; ops.fill_range = iwl_dump_ini_dev_mem_iter; - iwl_dump_ini_mem(fwrt, data, reg, &ops); + size += iwl_dump_ini_mem(fwrt, list, reg, &ops); break; case IWL_FW_INI_REGION_PERIPHERY_MAC: ops.get_num_of_ranges = iwl_dump_ini_mem_ranges; ops.get_size = iwl_dump_ini_mem_get_size; ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header; ops.fill_range = iwl_dump_ini_prph_iter; - iwl_dump_ini_mem(fwrt, data, reg, &ops); + size += iwl_dump_ini_mem(fwrt, list, reg, &ops); break; case IWL_FW_INI_REGION_DRAM_BUFFER: ops.get_num_of_ranges = iwl_dump_ini_mon_dram_ranges; ops.get_size = iwl_dump_ini_mon_dram_get_size; ops.fill_mem_hdr = iwl_dump_ini_mon_dram_fill_header; ops.fill_range = iwl_dump_ini_mon_dram_iter; - iwl_dump_ini_mem(fwrt, data, reg, &ops); + size += iwl_dump_ini_mem(fwrt, list, reg, &ops); break; case IWL_FW_INI_REGION_INTERNAL_BUFFER: ops.get_num_of_ranges = iwl_dump_ini_mem_ranges; ops.get_size = iwl_dump_ini_mon_smem_get_size; ops.fill_mem_hdr = iwl_dump_ini_mon_smem_fill_header; ops.fill_range = iwl_dump_ini_dev_mem_iter; - iwl_dump_ini_mem(fwrt, data, reg, &ops); + size += iwl_dump_ini_mem(fwrt, list, reg, &ops); break; case IWL_FW_INI_REGION_PAGING: ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header; @@ -1942,8 +1889,7 @@ static void iwl_fw_ini_dump_trigger(struct iwl_fw_runtime *fwrt, iwl_dump_ini_paging_gen2_get_size; ops.fill_range = iwl_dump_ini_paging_gen2_iter; } - - iwl_dump_ini_mem(fwrt, data, reg, &ops); + size += iwl_dump_ini_mem(fwrt, list, reg, &ops); break; case IWL_FW_INI_REGION_TXF: { struct iwl_ini_txf_iter_data iter = { .init = true }; @@ -1954,7 +1900,7 @@ static void iwl_fw_ini_dump_trigger(struct iwl_fw_runtime *fwrt, ops.get_size = iwl_dump_ini_txf_get_size; ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header; ops.fill_range = iwl_dump_ini_txf_iter; - iwl_dump_ini_mem(fwrt, data, reg, &ops); + size += iwl_dump_ini_mem(fwrt, list, reg, &ops); fwrt->dump.fifo_iter = fifo_iter; break; } @@ -1963,14 +1909,14 @@ static void iwl_fw_ini_dump_trigger(struct iwl_fw_runtime *fwrt, ops.get_size = iwl_dump_ini_rxf_get_size; ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header; ops.fill_range = iwl_dump_ini_rxf_iter; - iwl_dump_ini_mem(fwrt, data, reg, &ops); + size += iwl_dump_ini_mem(fwrt, list, reg, &ops); break; case IWL_FW_INI_REGION_CSR: ops.get_num_of_ranges = iwl_dump_ini_mem_ranges; ops.get_size = iwl_dump_ini_mem_get_size; ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header; ops.fill_range = iwl_dump_ini_csr_iter; - iwl_dump_ini_mem(fwrt, data, reg, &ops); + size += iwl_dump_ini_mem(fwrt, list, reg, &ops); break; case IWL_FW_INI_REGION_PERIPHERY_PHY: case IWL_FW_INI_REGION_PERIPHERY_AUX: @@ -1980,39 +1926,48 @@ static void iwl_fw_ini_dump_trigger(struct iwl_fw_runtime *fwrt, break; } } + + if (size) + size += iwl_dump_ini_info(fwrt, trigger, list); + + return size; } -static struct iwl_fw_error_dump_file * -iwl_fw_error_ini_dump_file(struct iwl_fw_runtime *fwrt, - enum iwl_fw_ini_trigger_id trig_id) +static u32 iwl_dump_ini_file_gen(struct iwl_fw_runtime *fwrt, + enum iwl_fw_ini_trigger_id trig_id, + struct list_head *list) { - int size; - struct iwl_fw_error_dump_data *dump_data; - struct iwl_fw_error_dump_file *dump_file; + struct iwl_fw_ini_dump_entry *entry; + struct iwl_fw_ini_dump_file_hdr *hdr; struct iwl_fw_ini_trigger *trigger; + u32 size; if (!iwl_fw_ini_trigger_on(fwrt, trig_id)) - return NULL; + return 0; trigger = fwrt->dump.active_trigs[trig_id].trig; + if (!trigger || !le32_to_cpu(trigger->num_regions)) + return 0; - size = iwl_fw_ini_get_trigger_len(fwrt, trigger); - if (!size) - return NULL; + entry = kmalloc(sizeof(*entry) + sizeof(*hdr), GFP_KERNEL); + if (!entry) + return 0; - size += sizeof(*dump_file); + entry->size = sizeof(*hdr); - dump_file = vzalloc(size); - if (!dump_file) - return NULL; + size = iwl_dump_ini_trigger(fwrt, trigger, list); + if (!size) { + kfree(entry); + return 0; + } - dump_file->barker = cpu_to_le32(IWL_FW_INI_ERROR_DUMP_BARKER); - dump_data = (void *)dump_file->data; - dump_file->file_len = cpu_to_le32(size); + hdr = (void *)entry->data; + hdr->barker = cpu_to_le32(IWL_FW_INI_ERROR_DUMP_BARKER); + hdr->file_len = cpu_to_le32(size + entry->size); - iwl_fw_ini_dump_trigger(fwrt, trigger, &dump_data); + list_add(&entry->list, list); - return dump_file; + return le32_to_cpu(hdr->file_len); } static void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt) @@ -2061,27 +2016,44 @@ static void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt) iwl_fw_free_dump_desc(fwrt); } +static void iwl_dump_ini_list_free(struct list_head *list) +{ + while (!list_empty(list)) { + struct iwl_fw_ini_dump_entry *entry = + list_entry(list->next, typeof(*entry), list); + + list_del(&entry->list); + kfree(entry); + } +} + static void iwl_fw_error_ini_dump(struct iwl_fw_runtime *fwrt, u8 wk_idx) { enum iwl_fw_ini_trigger_id trig_id = fwrt->dump.wks[wk_idx].ini_trig_id; - struct iwl_fw_error_dump_file *dump_file; + struct list_head dump_list = LIST_HEAD_INIT(dump_list); struct scatterlist *sg_dump_data; u32 file_len; - dump_file = iwl_fw_error_ini_dump_file(fwrt, trig_id); - if (!dump_file) + file_len = iwl_dump_ini_file_gen(fwrt, trig_id, &dump_list); + if (!file_len) goto out; - file_len = le32_to_cpu(dump_file->file_len); - sg_dump_data = alloc_sgtable(file_len); if (sg_dump_data) { - sg_pcopy_from_buffer(sg_dump_data, sg_nents(sg_dump_data), - dump_file, file_len, 0); + struct iwl_fw_ini_dump_entry *entry; + int sg_entries = sg_nents(sg_dump_data); + u32 offs = 0; + + list_for_each_entry(entry, &dump_list, list) { + sg_pcopy_from_buffer(sg_dump_data, sg_entries, + entry->data, entry->size, offs); + offs += entry->size; + } dev_coredumpsg(fwrt->trans->dev, sg_dump_data, file_len, GFP_KERNEL); } - vfree(dump_file); + iwl_dump_ini_list_free(&dump_list); + out: fwrt->dump.wks[wk_idx].ini_trig_id = IWL_FW_TRIGGER_ID_INVALID; } diff --git a/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h b/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h index 00a45ea85b69..9529e5925ad5 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h @@ -287,6 +287,28 @@ struct iwl_fw_error_dump_mem { /* Use bit 31 as dump info type to avoid colliding with region types */ #define IWL_INI_DUMP_INFO_TYPE BIT(31) +/** + * struct iwl_fw_ini_dump_entry + * @list: list of dump entries + * @size: size of the data + * @data: entry data + */ +struct iwl_fw_ini_dump_entry { + struct list_head list; + u32 size; + u8 data[]; +} __packed; + +/** + * struct iwl_fw_error_dump_file - header of dump file + * @barker: must be %IWL_FW_INI_ERROR_DUMP_BARKER + * @file_len: the length of all the file including the header + */ +struct iwl_fw_ini_dump_file_hdr { + __le32 barker; + __le32 file_len; +} __packed; + /** * struct iwl_fw_ini_fifo_hdr - fifo range header * @fifo_num: the fifo number. In case of umac rx fifo, set BIT(31) to From d4c444ef0dfabeac222f0e76011dc28cb1a18b68 Mon Sep 17 00:00:00 2001 From: Shahar S Matityahu Date: Mon, 17 Jun 2019 14:51:51 +0300 Subject: [PATCH 57/80] iwlwifi: dbg_ini: move tx fifo data into fw runtime Needed for future changes. Signed-off-by: Shahar S Matityahu Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 53 +++++-------------- .../net/wireless/intel/iwlwifi/fw/runtime.h | 17 +++++- 2 files changed, 28 insertions(+), 42 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 73af6e6a54c3..77eeca3eb3bf 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -1166,35 +1166,23 @@ iwl_dump_ini_mon_dram_iter(struct iwl_fw_runtime *fwrt, return sizeof(*range) + le32_to_cpu(range->range_data_size); } -struct iwl_ini_txf_iter_data { - int fifo; - int lmac; - u32 fifo_size; - bool internal_txf; - bool init; -}; - static bool iwl_ini_txf_iter(struct iwl_fw_runtime *fwrt, - struct iwl_fw_ini_region_cfg *reg) + struct iwl_fw_ini_region_cfg *reg, int idx) { - struct iwl_ini_txf_iter_data *iter = fwrt->dump.fifo_iter; + struct iwl_txf_iter_data *iter = &fwrt->dump.txf_iter_data; struct iwl_fwrt_shared_mem_cfg *cfg = &fwrt->smem_cfg; int txf_num = cfg->num_txfifo_entries; int int_txf_num = ARRAY_SIZE(cfg->internal_txfifo_size); u32 lmac_bitmap = le32_to_cpu(reg->fifos.fid1); - if (!iter) - return false; - - if (iter->init) { + if (!idx) { if (le32_to_cpu(reg->offset) && WARN_ONCE(cfg->num_lmacs == 1, "Invalid lmac offset: 0x%x\n", le32_to_cpu(reg->offset))) return false; - iter->init = false; - iter->internal_txf = false; + iter->internal_txf = 0; iter->fifo_size = 0; iter->fifo = -1; if (le32_to_cpu(reg->offset)) @@ -1211,7 +1199,7 @@ static bool iwl_ini_txf_iter(struct iwl_fw_runtime *fwrt, return true; } - iter->internal_txf = true; + iter->internal_txf = 1; if (!fw_has_capa(&fwrt->fw->ucode_capa, IWL_UCODE_TLV_CAPA_EXTEND_SHARED_MEM_CFG)) @@ -1232,7 +1220,7 @@ static int iwl_dump_ini_txf_iter(struct iwl_fw_runtime *fwrt, void *range_ptr, int idx) { struct iwl_fw_ini_error_dump_range *range = range_ptr; - struct iwl_ini_txf_iter_data *iter; + struct iwl_txf_iter_data *iter = &fwrt->dump.txf_iter_data; struct iwl_fw_ini_error_dump_register *reg_dump = (void *)range->data; u32 offs = le32_to_cpu(reg->offset), addr; u32 registers_size = @@ -1241,14 +1229,12 @@ static int iwl_dump_ini_txf_iter(struct iwl_fw_runtime *fwrt, unsigned long flags; int i; - if (!iwl_ini_txf_iter(fwrt, reg)) + if (!iwl_ini_txf_iter(fwrt, reg, idx)) return -EIO; if (!iwl_trans_grab_nic_access(fwrt->trans, &flags)) return -EBUSY; - iter = fwrt->dump.fifo_iter; - range->fifo_hdr.fifo_num = cpu_to_le32(iter->fifo); range->fifo_hdr.num_of_registers = reg->fifos.num_of_registers; range->range_data_size = cpu_to_le32(iter->fifo_size + registers_size); @@ -1520,16 +1506,11 @@ static u32 iwl_dump_ini_mon_dram_ranges(struct iwl_fw_runtime *fwrt, static u32 iwl_dump_ini_txf_ranges(struct iwl_fw_runtime *fwrt, struct iwl_fw_ini_region_cfg *reg) { - struct iwl_ini_txf_iter_data iter = { .init = true }; - void *fifo_iter = fwrt->dump.fifo_iter; u32 num_of_fifos = 0; - fwrt->dump.fifo_iter = &iter; - while (iwl_ini_txf_iter(fwrt, reg)) + while (iwl_ini_txf_iter(fwrt, reg, num_of_fifos)) num_of_fifos++; - fwrt->dump.fifo_iter = fifo_iter; - return num_of_fifos; } @@ -1602,25 +1583,21 @@ static u32 iwl_dump_ini_mon_smem_get_size(struct iwl_fw_runtime *fwrt, static u32 iwl_dump_ini_txf_get_size(struct iwl_fw_runtime *fwrt, struct iwl_fw_ini_region_cfg *reg) { - struct iwl_ini_txf_iter_data iter = { .init = true }; - void *fifo_iter = fwrt->dump.fifo_iter; + struct iwl_txf_iter_data *iter = &fwrt->dump.txf_iter_data; u32 size = 0; u32 fifo_hdr = sizeof(struct iwl_fw_ini_error_dump_range) + le32_to_cpu(reg->fifos.num_of_registers) * sizeof(struct iwl_fw_ini_error_dump_register); - fwrt->dump.fifo_iter = &iter; - while (iwl_ini_txf_iter(fwrt, reg)) { + while (iwl_ini_txf_iter(fwrt, reg, size)) { size += fifo_hdr; if (!reg->fifos.header_only) - size += iter.fifo_size; + size += iter->fifo_size; } if (size) size += sizeof(struct iwl_fw_ini_error_dump); - fwrt->dump.fifo_iter = fifo_iter; - return size; } @@ -1891,19 +1868,13 @@ static u32 iwl_dump_ini_trigger(struct iwl_fw_runtime *fwrt, } size += iwl_dump_ini_mem(fwrt, list, reg, &ops); break; - case IWL_FW_INI_REGION_TXF: { - struct iwl_ini_txf_iter_data iter = { .init = true }; - void *fifo_iter = fwrt->dump.fifo_iter; - - fwrt->dump.fifo_iter = &iter; + case IWL_FW_INI_REGION_TXF: ops.get_num_of_ranges = iwl_dump_ini_txf_ranges; ops.get_size = iwl_dump_ini_txf_get_size; ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header; ops.fill_range = iwl_dump_ini_txf_iter; size += iwl_dump_ini_mem(fwrt, list, reg, &ops); - fwrt->dump.fifo_iter = fifo_iter; break; - } case IWL_FW_INI_REGION_RXF: ops.get_num_of_ranges = iwl_dump_ini_rxf_ranges; ops.get_size = iwl_dump_ini_rxf_get_size; diff --git a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h index 0a4e13e4cc2c..40b92509085d 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h @@ -90,6 +90,20 @@ struct iwl_fwrt_shared_mem_cfg { #define IWL_FW_RUNTIME_DUMP_WK_NUM 5 +/** + * struct iwl_txf_iter_data - Tx fifo iterator data struct + * @fifo: fifo number + * @lmac: lmac number + * @fifo_size: fifo size + * @internal_txf: non zero if fifo is internal Tx fifo + */ +struct iwl_txf_iter_data { + int fifo; + int lmac; + u32 fifo_size; + u8 internal_txf; +}; + /** * struct iwl_fw_runtime - runtime data for firmware * @fw: firmware image @@ -143,7 +157,8 @@ struct iwl_fw_runtime { struct iwl_fw_ini_active_triggers active_trigs[IWL_FW_TRIGGER_ID_NUM]; u32 lmac_err_id[MAX_NUM_LMAC]; u32 umac_err_id; - void *fifo_iter; + + struct iwl_txf_iter_data txf_iter_data; struct timer_list periodic_trig; u8 img_name[IWL_FW_INI_MAX_IMG_NAME_LEN]; From bdc62390145687b14dc9806b30ccf56cf66c0087 Mon Sep 17 00:00:00 2001 From: Shahar S Matityahu Date: Mon, 17 Jun 2019 17:16:36 +0300 Subject: [PATCH 58/80] iwlwifi: dbg_ini: make a single ops struct for paging collect Needed for future changes. Signed-off-by: Shahar S Matityahu Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 92 +++++++++------------ 1 file changed, 39 insertions(+), 53 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 77eeca3eb3bf..0c7035033f27 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -1106,25 +1106,9 @@ static int iwl_dump_ini_dev_mem_iter(struct iwl_fw_runtime *fwrt, return sizeof(*range) + le32_to_cpu(range->range_data_size); } -static int -iwl_dump_ini_paging_gen2_iter(struct iwl_fw_runtime *fwrt, - struct iwl_fw_ini_region_cfg *reg, - void *range_ptr, int idx) -{ - struct iwl_fw_ini_error_dump_range *range = range_ptr; - u32 page_size = fwrt->trans->init_dram.paging[idx].size; - - range->page_num = cpu_to_le32(idx); - range->range_data_size = cpu_to_le32(page_size); - memcpy(range->data, fwrt->trans->init_dram.paging[idx].block, - page_size); - - return sizeof(*range) + le32_to_cpu(range->range_data_size); -} - -static int iwl_dump_ini_paging_iter(struct iwl_fw_runtime *fwrt, - struct iwl_fw_ini_region_cfg *reg, - void *range_ptr, int idx) +static int _iwl_dump_ini_paging_iter(struct iwl_fw_runtime *fwrt, + struct iwl_fw_ini_region_cfg *reg, + void *range_ptr, int idx) { /* increase idx by 1 since the pages are from 1 to * fwrt->num_of_paging_blk + 1 @@ -1145,6 +1129,27 @@ static int iwl_dump_ini_paging_iter(struct iwl_fw_runtime *fwrt, return sizeof(*range) + le32_to_cpu(range->range_data_size); } +static int iwl_dump_ini_paging_iter(struct iwl_fw_runtime *fwrt, + struct iwl_fw_ini_region_cfg *reg, + void *range_ptr, int idx) +{ + struct iwl_fw_ini_error_dump_range *range; + u32 page_size; + + if (!fwrt->trans->cfg->gen2) + return _iwl_dump_ini_paging_iter(fwrt, reg, range_ptr, idx); + + range = range_ptr; + page_size = fwrt->trans->init_dram.paging[idx].size; + + range->page_num = cpu_to_le32(idx); + range->range_data_size = cpu_to_le32(page_size); + memcpy(range->data, fwrt->trans->init_dram.paging[idx].block, + page_size); + + return sizeof(*range) + le32_to_cpu(range->range_data_size); +} + static int iwl_dump_ini_mon_dram_iter(struct iwl_fw_runtime *fwrt, struct iwl_fw_ini_region_cfg *reg, void *range_ptr, @@ -1485,15 +1490,12 @@ static u32 iwl_dump_ini_mem_ranges(struct iwl_fw_runtime *fwrt, return le32_to_cpu(reg->internal.num_of_ranges); } -static u32 iwl_dump_ini_paging_gen2_ranges(struct iwl_fw_runtime *fwrt, - struct iwl_fw_ini_region_cfg *reg) -{ - return fwrt->trans->init_dram.paging_cnt; -} - static u32 iwl_dump_ini_paging_ranges(struct iwl_fw_runtime *fwrt, struct iwl_fw_ini_region_cfg *reg) { + if (fwrt->trans->cfg->gen2) + return fwrt->trans->init_dram.paging_cnt; + return fwrt->num_of_paging_blk; } @@ -1532,20 +1534,6 @@ static u32 iwl_dump_ini_mem_get_size(struct iwl_fw_runtime *fwrt, le32_to_cpu(reg->internal.range_data_size)); } -static u32 iwl_dump_ini_paging_gen2_get_size(struct iwl_fw_runtime *fwrt, - struct iwl_fw_ini_region_cfg *reg) -{ - int i; - u32 range_header_len = sizeof(struct iwl_fw_ini_error_dump_range); - u32 size = sizeof(struct iwl_fw_ini_error_dump); - - for (i = 0; i < iwl_dump_ini_paging_gen2_ranges(fwrt, reg); i++) - size += range_header_len + - fwrt->trans->init_dram.paging[i].size; - - return size; -} - static u32 iwl_dump_ini_paging_get_size(struct iwl_fw_runtime *fwrt, struct iwl_fw_ini_region_cfg *reg) { @@ -1553,8 +1541,15 @@ static u32 iwl_dump_ini_paging_get_size(struct iwl_fw_runtime *fwrt, u32 range_header_len = sizeof(struct iwl_fw_ini_error_dump_range); u32 size = sizeof(struct iwl_fw_ini_error_dump); - for (i = 1; i <= iwl_dump_ini_paging_ranges(fwrt, reg); i++) - size += range_header_len + fwrt->fw_paging_db[i].fw_paging_size; + if (fwrt->trans->cfg->gen2) { + for (i = 0; i < iwl_dump_ini_paging_ranges(fwrt, reg); i++) + size += range_header_len + + fwrt->trans->init_dram.paging[i].size; + } else { + for (i = 1; i <= iwl_dump_ini_paging_ranges(fwrt, reg); i++) + size += range_header_len + + fwrt->fw_paging_db[i].fw_paging_size; + } return size; } @@ -1854,18 +1849,9 @@ static u32 iwl_dump_ini_trigger(struct iwl_fw_runtime *fwrt, break; case IWL_FW_INI_REGION_PAGING: ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header; - if (iwl_fw_dbg_is_paging_enabled(fwrt)) { - ops.get_num_of_ranges = - iwl_dump_ini_paging_ranges; - ops.get_size = iwl_dump_ini_paging_get_size; - ops.fill_range = iwl_dump_ini_paging_iter; - } else { - ops.get_num_of_ranges = - iwl_dump_ini_paging_gen2_ranges; - ops.get_size = - iwl_dump_ini_paging_gen2_get_size; - ops.fill_range = iwl_dump_ini_paging_gen2_iter; - } + ops.get_num_of_ranges = iwl_dump_ini_paging_ranges; + ops.get_size = iwl_dump_ini_paging_get_size; + ops.fill_range = iwl_dump_ini_paging_iter; size += iwl_dump_ini_mem(fwrt, list, reg, &ops); break; case IWL_FW_INI_REGION_TXF: From cd6de838e179287cbbfb7b655701183f2d32936e Mon Sep 17 00:00:00 2001 From: Shahar S Matityahu Date: Tue, 18 Jun 2019 08:24:21 +0300 Subject: [PATCH 59/80] iwlwifi: dbg_ini: use regions ops array instead of switch case in dump flow Make a static regions ops array and use it instead of switch case when determining what op to use to collect a region. Signed-off-by: Shahar S Matityahu Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 150 +++++++++++--------- 1 file changed, 79 insertions(+), 71 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 0c7035033f27..04afaec2d80e 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -1648,7 +1648,7 @@ struct iwl_dump_ini_mem_ops { */ static u32 iwl_dump_ini_mem(struct iwl_fw_runtime *fwrt, struct list_head *list, struct iwl_fw_ini_region_cfg *reg, - struct iwl_dump_ini_mem_ops *ops) + const struct iwl_dump_ini_mem_ops *ops) { struct iwl_fw_ini_dump_entry *entry; struct iwl_fw_error_dump_data *tlv; @@ -1656,8 +1656,8 @@ static u32 iwl_dump_ini_mem(struct iwl_fw_runtime *fwrt, struct list_head *list, u32 num_of_ranges, i, type = le32_to_cpu(reg->region_type), size; void *range; - if (WARN_ON(!ops || !ops->get_num_of_ranges || !ops->get_size || - !ops->fill_mem_hdr || !ops->fill_range)) + if (!ops->get_num_of_ranges || !ops->get_size || !ops->fill_mem_hdr || + !ops->fill_range) return 0; size = ops->get_size(fwrt, reg); @@ -1789,6 +1789,75 @@ static u32 iwl_dump_ini_info(struct iwl_fw_runtime *fwrt, return entry->size; } +static const struct iwl_dump_ini_mem_ops iwl_dump_ini_region_ops[] = { + [IWL_FW_INI_REGION_INVALID] = {}, + [IWL_FW_INI_REGION_DEVICE_MEMORY] = { + .get_num_of_ranges = iwl_dump_ini_mem_ranges, + .get_size = iwl_dump_ini_mem_get_size, + .fill_mem_hdr = iwl_dump_ini_mem_fill_header, + .fill_range = iwl_dump_ini_dev_mem_iter, + }, + [IWL_FW_INI_REGION_PERIPHERY_MAC] = { + .get_num_of_ranges = iwl_dump_ini_mem_ranges, + .get_size = iwl_dump_ini_mem_get_size, + .fill_mem_hdr = iwl_dump_ini_mem_fill_header, + .fill_range = iwl_dump_ini_prph_iter, + }, + [IWL_FW_INI_REGION_PERIPHERY_PHY] = {}, + [IWL_FW_INI_REGION_PERIPHERY_AUX] = {}, + [IWL_FW_INI_REGION_DRAM_BUFFER] = { + .get_num_of_ranges = iwl_dump_ini_mon_dram_ranges, + .get_size = iwl_dump_ini_mon_dram_get_size, + .fill_mem_hdr = iwl_dump_ini_mon_dram_fill_header, + .fill_range = iwl_dump_ini_mon_dram_iter, + }, + [IWL_FW_INI_REGION_DRAM_IMR] = {}, + [IWL_FW_INI_REGION_INTERNAL_BUFFER] = { + .get_num_of_ranges = iwl_dump_ini_mem_ranges, + .get_size = iwl_dump_ini_mon_smem_get_size, + .fill_mem_hdr = iwl_dump_ini_mon_smem_fill_header, + .fill_range = iwl_dump_ini_dev_mem_iter, + }, + [IWL_FW_INI_REGION_TXF] = { + .get_num_of_ranges = iwl_dump_ini_txf_ranges, + .get_size = iwl_dump_ini_txf_get_size, + .fill_mem_hdr = iwl_dump_ini_mem_fill_header, + .fill_range = iwl_dump_ini_txf_iter, + }, + [IWL_FW_INI_REGION_RXF] = { + .get_num_of_ranges = iwl_dump_ini_rxf_ranges, + .get_size = iwl_dump_ini_rxf_get_size, + .fill_mem_hdr = iwl_dump_ini_mem_fill_header, + .fill_range = iwl_dump_ini_rxf_iter, + }, + [IWL_FW_INI_REGION_PAGING] = { + .fill_mem_hdr = iwl_dump_ini_mem_fill_header, + .get_num_of_ranges = iwl_dump_ini_paging_ranges, + .get_size = iwl_dump_ini_paging_get_size, + .fill_range = iwl_dump_ini_paging_iter, + }, + [IWL_FW_INI_REGION_CSR] = { + .get_num_of_ranges = iwl_dump_ini_mem_ranges, + .get_size = iwl_dump_ini_mem_get_size, + .fill_mem_hdr = iwl_dump_ini_mem_fill_header, + .fill_range = iwl_dump_ini_csr_iter, + }, + [IWL_FW_INI_REGION_NOTIFICATION] = {}, + [IWL_FW_INI_REGION_DHC] = {}, + [IWL_FW_INI_REGION_LMAC_ERROR_TABLE] = { + .get_num_of_ranges = iwl_dump_ini_mem_ranges, + .get_size = iwl_dump_ini_mem_get_size, + .fill_mem_hdr = iwl_dump_ini_mem_fill_header, + .fill_range = iwl_dump_ini_dev_mem_iter, + }, + [IWL_FW_INI_REGION_UMAC_ERROR_TABLE] = { + .get_num_of_ranges = iwl_dump_ini_mem_ranges, + .get_size = iwl_dump_ini_mem_get_size, + .fill_mem_hdr = iwl_dump_ini_mem_fill_header, + .fill_range = iwl_dump_ini_dev_mem_iter, + }, +}; + static u32 iwl_dump_ini_trigger(struct iwl_fw_runtime *fwrt, struct iwl_fw_ini_trigger *trigger, struct list_head *list) @@ -1797,9 +1866,8 @@ static u32 iwl_dump_ini_trigger(struct iwl_fw_runtime *fwrt, u32 size = 0; for (i = 0; i < le32_to_cpu(trigger->num_regions); i++) { - u32 reg_id = le32_to_cpu(trigger->data[i]); + u32 reg_id = le32_to_cpu(trigger->data[i]), reg_type; struct iwl_fw_ini_region_cfg *reg; - struct iwl_dump_ini_mem_ops ops; if (WARN_ON(reg_id >= ARRAY_SIZE(fwrt->dump.active_regs))) continue; @@ -1816,72 +1884,12 @@ static u32 iwl_dump_ini_trigger(struct iwl_fw_runtime *fwrt, if (le32_to_cpu(reg->domain) != IWL_FW_INI_DBG_DOMAIN_ALWAYS_ON) continue; - switch (le32_to_cpu(reg->region_type)) { - case IWL_FW_INI_REGION_DEVICE_MEMORY: - case IWL_FW_INI_REGION_LMAC_ERROR_TABLE: - case IWL_FW_INI_REGION_UMAC_ERROR_TABLE: - ops.get_num_of_ranges = iwl_dump_ini_mem_ranges; - ops.get_size = iwl_dump_ini_mem_get_size; - ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header; - ops.fill_range = iwl_dump_ini_dev_mem_iter; - size += iwl_dump_ini_mem(fwrt, list, reg, &ops); - break; - case IWL_FW_INI_REGION_PERIPHERY_MAC: - ops.get_num_of_ranges = iwl_dump_ini_mem_ranges; - ops.get_size = iwl_dump_ini_mem_get_size; - ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header; - ops.fill_range = iwl_dump_ini_prph_iter; - size += iwl_dump_ini_mem(fwrt, list, reg, &ops); - break; - case IWL_FW_INI_REGION_DRAM_BUFFER: - ops.get_num_of_ranges = iwl_dump_ini_mon_dram_ranges; - ops.get_size = iwl_dump_ini_mon_dram_get_size; - ops.fill_mem_hdr = iwl_dump_ini_mon_dram_fill_header; - ops.fill_range = iwl_dump_ini_mon_dram_iter; - size += iwl_dump_ini_mem(fwrt, list, reg, &ops); - break; - case IWL_FW_INI_REGION_INTERNAL_BUFFER: - ops.get_num_of_ranges = iwl_dump_ini_mem_ranges; - ops.get_size = iwl_dump_ini_mon_smem_get_size; - ops.fill_mem_hdr = iwl_dump_ini_mon_smem_fill_header; - ops.fill_range = iwl_dump_ini_dev_mem_iter; - size += iwl_dump_ini_mem(fwrt, list, reg, &ops); - break; - case IWL_FW_INI_REGION_PAGING: - ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header; - ops.get_num_of_ranges = iwl_dump_ini_paging_ranges; - ops.get_size = iwl_dump_ini_paging_get_size; - ops.fill_range = iwl_dump_ini_paging_iter; - size += iwl_dump_ini_mem(fwrt, list, reg, &ops); - break; - case IWL_FW_INI_REGION_TXF: - ops.get_num_of_ranges = iwl_dump_ini_txf_ranges; - ops.get_size = iwl_dump_ini_txf_get_size; - ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header; - ops.fill_range = iwl_dump_ini_txf_iter; - size += iwl_dump_ini_mem(fwrt, list, reg, &ops); - break; - case IWL_FW_INI_REGION_RXF: - ops.get_num_of_ranges = iwl_dump_ini_rxf_ranges; - ops.get_size = iwl_dump_ini_rxf_get_size; - ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header; - ops.fill_range = iwl_dump_ini_rxf_iter; - size += iwl_dump_ini_mem(fwrt, list, reg, &ops); - break; - case IWL_FW_INI_REGION_CSR: - ops.get_num_of_ranges = iwl_dump_ini_mem_ranges; - ops.get_size = iwl_dump_ini_mem_get_size; - ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header; - ops.fill_range = iwl_dump_ini_csr_iter; - size += iwl_dump_ini_mem(fwrt, list, reg, &ops); - break; - case IWL_FW_INI_REGION_PERIPHERY_PHY: - case IWL_FW_INI_REGION_PERIPHERY_AUX: - case IWL_FW_INI_REGION_DRAM_IMR: - /* This is undefined yet */ - default: - break; - } + reg_type = le32_to_cpu(reg->region_type); + if (reg_type >= ARRAY_SIZE(iwl_dump_ini_region_ops)) + continue; + + size += iwl_dump_ini_mem(fwrt, list, reg, + &iwl_dump_ini_region_ops[reg_type]); } if (size) From 79b6c8feb63589196cd4c557c91bfafd2da47f4e Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Thu, 2 Aug 2018 14:57:55 +0300 Subject: [PATCH 60/80] iwlwifi: separate elements from cfg that are needed by trans_alloc In order to be able to select the cfg depending on the HW revision or on the RF ID, we need to set up the trans before selecting the cfg. To do so, move the elements from cfg that are needed by iwl_trans_alloc() to a separate struct at the top of the cfg, so it can be used by other cfg types as well, before selecting the rest of the configuration. Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/cfg/1000.c | 14 +- drivers/net/wireless/intel/iwlwifi/cfg/2000.c | 26 ++-- .../net/wireless/intel/iwlwifi/cfg/22000.c | 34 ++--- drivers/net/wireless/intel/iwlwifi/cfg/5000.c | 18 +-- drivers/net/wireless/intel/iwlwifi/cfg/6000.c | 44 +++--- drivers/net/wireless/intel/iwlwifi/cfg/7000.c | 10 +- drivers/net/wireless/intel/iwlwifi/cfg/8000.c | 10 +- drivers/net/wireless/intel/iwlwifi/cfg/9000.c | 10 +- .../net/wireless/intel/iwlwifi/dvm/devices.c | 3 +- drivers/net/wireless/intel/iwlwifi/dvm/led.c | 5 +- .../net/wireless/intel/iwlwifi/dvm/mac80211.c | 4 +- drivers/net/wireless/intel/iwlwifi/dvm/main.c | 6 +- .../net/wireless/intel/iwlwifi/dvm/power.c | 3 +- drivers/net/wireless/intel/iwlwifi/dvm/tx.c | 5 +- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 32 +++-- drivers/net/wireless/intel/iwlwifi/fw/dbg.h | 2 +- .../net/wireless/intel/iwlwifi/fw/paging.c | 6 +- drivers/net/wireless/intel/iwlwifi/fw/smem.c | 2 +- .../net/wireless/intel/iwlwifi/iwl-config.h | 49 ++++--- drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 10 +- .../wireless/intel/iwlwifi/iwl-eeprom-parse.c | 6 +- .../wireless/intel/iwlwifi/iwl-eeprom-read.c | 14 +- drivers/net/wireless/intel/iwlwifi/iwl-fh.h | 6 +- drivers/net/wireless/intel/iwlwifi/iwl-io.c | 21 +-- drivers/net/wireless/intel/iwlwifi/iwl-io.h | 18 ++- .../wireless/intel/iwlwifi/iwl-nvm-parse.c | 16 +-- drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 4 +- .../net/wireless/intel/iwlwifi/mvm/debugfs.c | 6 +- drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 9 +- drivers/net/wireless/intel/iwlwifi/mvm/led.c | 6 +- .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 4 +- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 8 +- drivers/net/wireless/intel/iwlwifi/mvm/nvm.c | 4 +- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 8 +- drivers/net/wireless/intel/iwlwifi/mvm/rs.c | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 11 +- drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 10 +- drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 4 +- .../net/wireless/intel/iwlwifi/mvm/utils.c | 11 +- .../intel/iwlwifi/pcie/ctxt-info-gen3.c | 2 +- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 4 +- .../wireless/intel/iwlwifi/pcie/internal.h | 14 +- drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 56 ++++---- .../wireless/intel/iwlwifi/pcie/trans-gen2.c | 10 +- .../net/wireless/intel/iwlwifi/pcie/trans.c | 132 ++++++++++-------- .../net/wireless/intel/iwlwifi/pcie/tx-gen2.c | 10 +- drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 83 +++++------ 47 files changed, 407 insertions(+), 365 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/1000.c b/drivers/net/wireless/intel/iwlwifi/cfg/1000.c index a1aa2956b382..b92255b91b72 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/1000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/1000.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. - * Copyright(c) 2018 Intel Corporation + * Copyright(c) 2018 - 2019 Intel Corporation * * Contact Information: * Intel Linux Wireless @@ -69,16 +69,16 @@ static const struct iwl_eeprom_params iwl1000_eeprom_params = { .fw_name_pre = IWL1000_FW_PRE, \ .ucode_api_max = IWL1000_UCODE_API_MAX, \ .ucode_api_min = IWL1000_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_1000, \ + .trans.device_family = IWL_DEVICE_FAMILY_1000, \ .max_inst_size = IWLAGN_RTC_INST_SIZE, \ .max_data_size = IWLAGN_RTC_DATA_SIZE, \ .nvm_ver = EEPROM_1000_EEPROM_VERSION, \ .nvm_calib_ver = EEPROM_1000_TX_POWER_VERSION, \ - .base_params = &iwl1000_base_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, \ - .csr = &iwl_csr_v1 + .trans.csr = &iwl_csr_v1 const struct iwl_cfg iwl1000_bgn_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 1000 BGN", @@ -95,17 +95,17 @@ const struct iwl_cfg iwl1000_bg_cfg = { .fw_name_pre = IWL100_FW_PRE, \ .ucode_api_max = IWL100_UCODE_API_MAX, \ .ucode_api_min = IWL100_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_100, \ + .trans.device_family = IWL_DEVICE_FAMILY_100, \ .max_inst_size = IWLAGN_RTC_INST_SIZE, \ .max_data_size = IWLAGN_RTC_DATA_SIZE, \ .nvm_ver = EEPROM_1000_EEPROM_VERSION, \ .nvm_calib_ver = EEPROM_1000_TX_POWER_VERSION, \ - .base_params = &iwl1000_base_params, \ + .trans.base_params = &iwl1000_base_params, \ .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, \ - .csr = &iwl_csr_v1 + .trans.csr = &iwl_csr_v1 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 4a988b676913..2b1ae0cecc83 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/2000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/2000.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. - * Copyright(c) 2018 Intel Corporation + * Copyright(c) 2018 - 2019 Intel Corporation * * Contact Information: * Intel Linux Wireless @@ -95,16 +95,16 @@ static const struct iwl_eeprom_params iwl20x0_eeprom_params = { .fw_name_pre = IWL2000_FW_PRE, \ .ucode_api_max = IWL2000_UCODE_API_MAX, \ .ucode_api_min = IWL2000_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_2000, \ + .trans.device_family = IWL_DEVICE_FAMILY_2000, \ .max_inst_size = IWL60_RTC_INST_SIZE, \ .max_data_size = IWL60_RTC_DATA_SIZE, \ .nvm_ver = EEPROM_2000_EEPROM_VERSION, \ .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ - .base_params = &iwl2000_base_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, \ - .csr = &iwl_csr_v1 + .trans.csr = &iwl_csr_v1 const struct iwl_cfg iwl2000_2bgn_cfg = { @@ -123,16 +123,16 @@ const struct iwl_cfg iwl2000_2bgn_d_cfg = { .fw_name_pre = IWL2030_FW_PRE, \ .ucode_api_max = IWL2030_UCODE_API_MAX, \ .ucode_api_min = IWL2030_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_2030, \ + .trans.device_family = IWL_DEVICE_FAMILY_2030, \ .max_inst_size = IWL60_RTC_INST_SIZE, \ .max_data_size = IWL60_RTC_DATA_SIZE, \ .nvm_ver = EEPROM_2000_EEPROM_VERSION, \ .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ - .base_params = &iwl2030_base_params, \ + .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, \ - .csr = &iwl_csr_v1 + .trans.csr = &iwl_csr_v1 const struct iwl_cfg iwl2030_2bgn_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 2230 BGN", @@ -144,17 +144,17 @@ const struct iwl_cfg iwl2030_2bgn_cfg = { .fw_name_pre = IWL105_FW_PRE, \ .ucode_api_max = IWL105_UCODE_API_MAX, \ .ucode_api_min = IWL105_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_105, \ + .trans.device_family = IWL_DEVICE_FAMILY_105, \ .max_inst_size = IWL60_RTC_INST_SIZE, \ .max_data_size = IWL60_RTC_DATA_SIZE, \ .nvm_ver = EEPROM_2000_EEPROM_VERSION, \ .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ - .base_params = &iwl2000_base_params, \ + .trans.base_params = &iwl2000_base_params, \ .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, \ - .csr = &iwl_csr_v1 + .trans.csr = &iwl_csr_v1 const struct iwl_cfg iwl105_bgn_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 105 BGN", @@ -172,17 +172,17 @@ const struct iwl_cfg iwl105_bgn_d_cfg = { .fw_name_pre = IWL135_FW_PRE, \ .ucode_api_max = IWL135_UCODE_API_MAX, \ .ucode_api_min = IWL135_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_135, \ + .trans.device_family = IWL_DEVICE_FAMILY_135, \ .max_inst_size = IWL60_RTC_INST_SIZE, \ .max_data_size = IWL60_RTC_DATA_SIZE, \ .nvm_ver = EEPROM_2000_EEPROM_VERSION, \ .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ - .base_params = &iwl2030_base_params, \ + .trans.base_params = &iwl2030_base_params, \ .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, \ - .csr = &iwl_csr_v1 + .trans.csr = &iwl_csr_v1 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 fd4bc43d8734..db09ca9ff89d 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c @@ -169,15 +169,15 @@ static const struct iwl_ht_params iwl_22000_ht_params = { .smem_len = IWL_22000_SMEM_LEN, \ .features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM, \ .apmg_not_supported = true, \ - .mq_rx_supported = true, \ + .trans.mq_rx_supported = true, \ .vht_mu_mimo_supported = true, \ .mac_addr_from_csr = true, \ .ht_params = &iwl_22000_ht_params, \ .nvm_ver = IWL_22000_NVM_VERSION, \ .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \ - .use_tfh = true, \ - .rf_id = true, \ - .gen2 = true, \ + .trans.use_tfh = true, \ + .trans.rf_id = true, \ + .trans.gen2 = true, \ .nvm_type = IWL_NVM_EXT, \ .dbgc_supported = true, \ .min_umac_error_event_table = 0x400000, \ @@ -190,23 +190,23 @@ static const struct iwl_ht_params iwl_22000_ht_params = { #define IWL_DEVICE_22500 \ IWL_DEVICE_22000_COMMON, \ - .device_family = IWL_DEVICE_FAMILY_22000, \ - .base_params = &iwl_22000_base_params, \ - .csr = &iwl_csr_v1, \ + .trans.device_family = IWL_DEVICE_FAMILY_22000, \ + .trans.base_params = &iwl_22000_base_params, \ + .trans.csr = &iwl_csr_v1, \ .gp2_reg_addr = 0xa02c68 #define IWL_DEVICE_22560 \ IWL_DEVICE_22000_COMMON, \ - .device_family = IWL_DEVICE_FAMILY_22560, \ - .base_params = &iwl_22560_base_params, \ - .csr = &iwl_csr_v2 + .trans.device_family = IWL_DEVICE_FAMILY_22560, \ + .trans.base_params = &iwl_22560_base_params, \ + .trans.csr = &iwl_csr_v2 #define IWL_DEVICE_AX210 \ IWL_DEVICE_22000_COMMON, \ - .umac_prph_offset = 0x300000, \ - .device_family = IWL_DEVICE_FAMILY_AX210, \ - .base_params = &iwl_22560_base_params, \ - .csr = &iwl_csr_v1, \ + .trans.umac_prph_offset = 0x300000, \ + .trans.device_family = IWL_DEVICE_FAMILY_AX210, \ + .trans.base_params = &iwl_22560_base_params, \ + .trans.csr = &iwl_csr_v1, \ .min_txq_size = 128, \ .gp2_reg_addr = 0xd02c68, \ .min_256_ba_txq_size = 512 @@ -336,7 +336,7 @@ const struct iwl_cfg iwl_ax200_cfg_cc = { * HT size; mac80211 would otherwise pick the HE max (256) by default. */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, - .bisr_workaround = 1, + .trans.bisr_workaround = 1, }; const struct iwl_cfg killer1650x_2ax_cfg = { @@ -349,7 +349,7 @@ const struct iwl_cfg killer1650x_2ax_cfg = { * HT size; mac80211 would otherwise pick the HE max (256) by default. */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, - .bisr_workaround = 1, + .trans.bisr_workaround = 1, }; const struct iwl_cfg killer1650w_2ax_cfg = { @@ -362,7 +362,7 @@ const struct iwl_cfg killer1650w_2ax_cfg = { * HT size; mac80211 would otherwise pick the HE max (256) by default. */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, - .bisr_workaround = 1, + .trans.bisr_workaround = 1, }; /* diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/5000.c b/drivers/net/wireless/intel/iwlwifi/cfg/5000.c index ce25c690d69c..aab4495c6085 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/5000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/5000.c @@ -67,16 +67,16 @@ static const struct iwl_eeprom_params iwl5000_eeprom_params = { .fw_name_pre = IWL5000_FW_PRE, \ .ucode_api_max = IWL5000_UCODE_API_MAX, \ .ucode_api_min = IWL5000_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_5000, \ + .trans.device_family = IWL_DEVICE_FAMILY_5000, \ .max_inst_size = IWLAGN_RTC_INST_SIZE, \ .max_data_size = IWLAGN_RTC_DATA_SIZE, \ .nvm_ver = EEPROM_5000_EEPROM_VERSION, \ .nvm_calib_ver = EEPROM_5000_TX_POWER_VERSION, \ - .base_params = &iwl5000_base_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, \ - .csr = &iwl_csr_v1 + .trans.csr = &iwl_csr_v1 const struct iwl_cfg iwl5300_agn_cfg = { .name = "Intel(R) Ultimate N WiFi Link 5300 AGN", @@ -115,34 +115,34 @@ const struct iwl_cfg iwl5350_agn_cfg = { .fw_name_pre = IWL5000_FW_PRE, .ucode_api_max = IWL5000_UCODE_API_MAX, .ucode_api_min = IWL5000_UCODE_API_MIN, - .device_family = IWL_DEVICE_FAMILY_5000, + .trans.device_family = IWL_DEVICE_FAMILY_5000, .max_inst_size = IWLAGN_RTC_INST_SIZE, .max_data_size = IWLAGN_RTC_DATA_SIZE, .nvm_ver = EEPROM_5050_EEPROM_VERSION, .nvm_calib_ver = EEPROM_5050_TX_POWER_VERSION, - .base_params = &iwl5000_base_params, + .trans.base_params = &iwl5000_base_params, .eeprom_params = &iwl5000_eeprom_params, .ht_params = &iwl5000_ht_params, .led_mode = IWL_LED_BLINK, .internal_wimax_coex = true, - .csr = &iwl_csr_v1, + .trans.csr = &iwl_csr_v1, }; #define IWL_DEVICE_5150 \ .fw_name_pre = IWL5150_FW_PRE, \ .ucode_api_max = IWL5150_UCODE_API_MAX, \ .ucode_api_min = IWL5150_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_5150, \ + .trans.device_family = IWL_DEVICE_FAMILY_5150, \ .max_inst_size = IWLAGN_RTC_INST_SIZE, \ .max_data_size = IWLAGN_RTC_DATA_SIZE, \ .nvm_ver = EEPROM_5050_EEPROM_VERSION, \ .nvm_calib_ver = EEPROM_5050_TX_POWER_VERSION, \ - .base_params = &iwl5000_base_params, \ + .trans.base_params = &iwl5000_base_params, \ .eeprom_params = &iwl5000_eeprom_params, \ .led_mode = IWL_LED_BLINK, \ .internal_wimax_coex = true, \ .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \ - .csr = &iwl_csr_v1 + .trans.csr = &iwl_csr_v1 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 67d61a1588a9..39ea81903dbe 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/6000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/6000.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. - * Copyright(c) 2018 Intel Corporation + * Copyright(c) 2018 - 2019 Intel Corporation * * Contact Information: * Intel Linux Wireless @@ -116,16 +116,16 @@ static const struct iwl_eeprom_params iwl6000_eeprom_params = { .fw_name_pre = IWL6005_FW_PRE, \ .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ .ucode_api_min = IWL6000G2_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_6005, \ + .trans.device_family = IWL_DEVICE_FAMILY_6005, \ .max_inst_size = IWL60_RTC_INST_SIZE, \ .max_data_size = IWL60_RTC_DATA_SIZE, \ .nvm_ver = EEPROM_6005_EEPROM_VERSION, \ .nvm_calib_ver = EEPROM_6005_TX_POWER_VERSION, \ - .base_params = &iwl6000_g2_base_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, \ - .csr = &iwl_csr_v1 + .trans.csr = &iwl_csr_v1 const struct iwl_cfg iwl6005_2agn_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6205 AGN", @@ -171,16 +171,16 @@ const struct iwl_cfg iwl6005_2agn_mow2_cfg = { .fw_name_pre = IWL6030_FW_PRE, \ .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ .ucode_api_min = IWL6000G2_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_6030, \ + .trans.device_family = IWL_DEVICE_FAMILY_6030, \ .max_inst_size = IWL60_RTC_INST_SIZE, \ .max_data_size = IWL60_RTC_DATA_SIZE, \ .nvm_ver = EEPROM_6030_EEPROM_VERSION, \ .nvm_calib_ver = EEPROM_6030_TX_POWER_VERSION, \ - .base_params = &iwl6000_g2_base_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, \ - .csr = &iwl_csr_v1 + .trans.csr = &iwl_csr_v1 const struct iwl_cfg iwl6030_2agn_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6230 AGN", @@ -208,16 +208,16 @@ const struct iwl_cfg iwl6030_2bg_cfg = { .fw_name_pre = IWL6030_FW_PRE, \ .ucode_api_max = IWL6035_UCODE_API_MAX, \ .ucode_api_min = IWL6035_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_6030, \ + .trans.device_family = IWL_DEVICE_FAMILY_6030, \ .max_inst_size = IWL60_RTC_INST_SIZE, \ .max_data_size = IWL60_RTC_DATA_SIZE, \ .nvm_ver = EEPROM_6030_EEPROM_VERSION, \ .nvm_calib_ver = EEPROM_6030_TX_POWER_VERSION, \ - .base_params = &iwl6000_g2_base_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, \ - .csr = &iwl_csr_v1 + .trans.csr = &iwl_csr_v1 const struct iwl_cfg iwl6035_2agn_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6235 AGN", @@ -262,18 +262,18 @@ const struct iwl_cfg iwl130_bg_cfg = { .fw_name_pre = IWL6000_FW_PRE, \ .ucode_api_max = IWL6000_UCODE_API_MAX, \ .ucode_api_min = IWL6000_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_6000i, \ + .trans.device_family = IWL_DEVICE_FAMILY_6000i, \ .max_inst_size = IWL60_RTC_INST_SIZE, \ .max_data_size = IWL60_RTC_DATA_SIZE, \ .valid_tx_ant = ANT_BC, /* .cfg overwrite */ \ .valid_rx_ant = ANT_BC, /* .cfg overwrite */ \ .nvm_ver = EEPROM_6000_EEPROM_VERSION, \ .nvm_calib_ver = EEPROM_6000_TX_POWER_VERSION, \ - .base_params = &iwl6000_base_params, \ + .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, \ - .csr = &iwl_csr_v1 + .trans.csr = &iwl_csr_v1 const struct iwl_cfg iwl6000i_2agn_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6200 AGN", @@ -295,19 +295,19 @@ const struct iwl_cfg iwl6000i_2bg_cfg = { .fw_name_pre = IWL6050_FW_PRE, \ .ucode_api_max = IWL6050_UCODE_API_MAX, \ .ucode_api_min = IWL6050_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_6050, \ + .trans.device_family = IWL_DEVICE_FAMILY_6050, \ .max_inst_size = IWL60_RTC_INST_SIZE, \ .max_data_size = IWL60_RTC_DATA_SIZE, \ .valid_tx_ant = ANT_AB, /* .cfg overwrite */ \ .valid_rx_ant = ANT_AB, /* .cfg overwrite */ \ .nvm_ver = EEPROM_6050_EEPROM_VERSION, \ .nvm_calib_ver = EEPROM_6050_TX_POWER_VERSION, \ - .base_params = &iwl6050_base_params, \ + .trans.base_params = &iwl6050_base_params, \ .eeprom_params = &iwl6000_eeprom_params, \ .led_mode = IWL_LED_BLINK, \ .internal_wimax_coex = true, \ .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \ - .csr = &iwl_csr_v1 + .trans.csr = &iwl_csr_v1 const struct iwl_cfg iwl6050_2agn_cfg = { .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 AGN", @@ -324,17 +324,17 @@ const struct iwl_cfg iwl6050_2abg_cfg = { .fw_name_pre = IWL6050_FW_PRE, \ .ucode_api_max = IWL6050_UCODE_API_MAX, \ .ucode_api_min = IWL6050_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_6150, \ + .trans.device_family = IWL_DEVICE_FAMILY_6150, \ .max_inst_size = IWL60_RTC_INST_SIZE, \ .max_data_size = IWL60_RTC_DATA_SIZE, \ .nvm_ver = EEPROM_6150_EEPROM_VERSION, \ .nvm_calib_ver = EEPROM_6150_TX_POWER_VERSION, \ - .base_params = &iwl6050_base_params, \ + .trans.base_params = &iwl6050_base_params, \ .eeprom_params = &iwl6000_eeprom_params, \ .led_mode = IWL_LED_BLINK, \ .internal_wimax_coex = true, \ .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \ - .csr = &iwl_csr_v1 + .trans.csr = &iwl_csr_v1 const struct iwl_cfg iwl6150_bgn_cfg = { .name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BGN", @@ -352,16 +352,16 @@ const struct iwl_cfg iwl6000_3agn_cfg = { .fw_name_pre = IWL6000_FW_PRE, .ucode_api_max = IWL6000_UCODE_API_MAX, .ucode_api_min = IWL6000_UCODE_API_MIN, - .device_family = IWL_DEVICE_FAMILY_6000, + .trans.device_family = IWL_DEVICE_FAMILY_6000, .max_inst_size = IWL60_RTC_INST_SIZE, .max_data_size = IWL60_RTC_DATA_SIZE, .nvm_ver = EEPROM_6000_EEPROM_VERSION, .nvm_calib_ver = EEPROM_6000_TX_POWER_VERSION, - .base_params = &iwl6000_base_params, + .trans.base_params = &iwl6000_base_params, .eeprom_params = &iwl6000_eeprom_params, .ht_params = &iwl6000_ht_params, .led_mode = IWL_LED_BLINK, - .csr = &iwl_csr_v1, + .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 289e3c398a12..deb520aeb3f8 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/7000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/7000.c @@ -8,7 +8,7 @@ * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH * Copyright(c) 2015 Intel Deutschland GmbH - * Copyright(c) 2018 Intel Corporation + * Copyright(c) 2018 - 2019 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -31,7 +31,7 @@ * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH * Copyright(c) 2015 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 @@ -148,14 +148,14 @@ static const struct iwl_ht_params iwl7000_ht_params = { }; #define IWL_DEVICE_7000_COMMON \ - .device_family = IWL_DEVICE_FAMILY_7000, \ - .base_params = &iwl7000_base_params, \ + .trans.device_family = IWL_DEVICE_FAMILY_7000, \ + .trans.base_params = &iwl7000_base_params, \ .led_mode = IWL_LED_RF_STATE, \ .nvm_hw_section_num = 0, \ .non_shared_ant = ANT_A, \ .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \ .dccm_offset = IWL7000_DCCM_OFFSET, \ - .csr = &iwl_csr_v1 + .trans.csr = &iwl_csr_v1 #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 d7d17c1cceea..b3cc477140c0 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/8000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/8000.c @@ -8,7 +8,7 @@ * Copyright(c) 2014 Intel Corporation. All rights reserved. * Copyright(c) 2014 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 Intel Deutschland GmbH - * Copyright(c) 2018 Intel Corporation + * Copyright(c) 2018 - 2019 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,7 +30,7 @@ * * Copyright(c) 2014 Intel Corporation. All rights reserved. * Copyright(c) 2014 - 2015 Intel Mobile Communications GmbH - * Copyright(c) 2018 Intel Corporation + * Copyright(c) 2018 - 2019 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -134,8 +134,8 @@ static const struct iwl_tt_params iwl8000_tt_params = { }; #define IWL_DEVICE_8000_COMMON \ - .device_family = IWL_DEVICE_FAMILY_8000, \ - .base_params = &iwl8000_base_params, \ + .trans.device_family = IWL_DEVICE_FAMILY_8000, \ + .trans.base_params = &iwl8000_base_params, \ .led_mode = IWL_LED_RF_STATE, \ .nvm_hw_section_num = 10, \ .features = NETIF_F_RXCSUM, \ @@ -152,7 +152,7 @@ static const struct iwl_tt_params iwl8000_tt_params = { .nvm_type = IWL_NVM_EXT, \ .dbgc_supported = true, \ .min_umac_error_event_table = 0x800000, \ - .csr = &iwl_csr_v1 + .trans.csr = &iwl_csr_v1 #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 41bdd0eaf62c..e8372b67df03 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/9000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/9000.c @@ -122,8 +122,8 @@ static const struct iwl_tt_params iwl9000_tt_params = { #define IWL_DEVICE_9000 \ .ucode_api_max = IWL9000_UCODE_API_MAX, \ .ucode_api_min = IWL9000_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_9000, \ - .base_params = &iwl9000_base_params, \ + .trans.device_family = IWL_DEVICE_FAMILY_9000, \ + .trans.base_params = &iwl9000_base_params, \ .led_mode = IWL_LED_RF_STATE, \ .nvm_hw_section_num = 10, \ .non_shared_ant = ANT_B, \ @@ -136,14 +136,14 @@ static const struct iwl_tt_params iwl9000_tt_params = { .features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM, \ .thermal_params = &iwl9000_tt_params, \ .apmg_not_supported = true, \ - .mq_rx_supported = true, \ + .trans.mq_rx_supported = true, \ .vht_mu_mimo_supported = true, \ .mac_addr_from_csr = true, \ - .rf_id = true, \ + .trans.rf_id = true, \ .nvm_type = IWL_NVM_EXT, \ .dbgc_supported = true, \ .min_umac_error_event_table = 0x800000, \ - .csr = &iwl_csr_v1, \ + .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/dvm/devices.c b/drivers/net/wireless/intel/iwlwifi/dvm/devices.c index b39f8b1475e1..73b3a947ab7a 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/devices.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/devices.c @@ -2,6 +2,7 @@ /****************************************************************************** * * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. + * Copyright (C) 2019 Intel Corporation * * Contact Information: * Intel Linux Wireless @@ -483,7 +484,7 @@ static void iwl6000_set_ct_threshold(struct iwl_priv *priv) /* NIC configuration for 6000 series */ static void iwl6000_nic_config(struct iwl_priv *priv) { - switch (priv->cfg->device_family) { + switch (priv->cfg->trans.device_family) { case IWL_DEVICE_FAMILY_6005: case IWL_DEVICE_FAMILY_6030: case IWL_DEVICE_FAMILY_6000: diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/led.c b/drivers/net/wireless/intel/iwlwifi/dvm/led.c index 38fd41fba661..1e1664ecf30b 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/led.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/led.c @@ -2,6 +2,7 @@ /****************************************************************************** * * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. + * Copyright (C) 2019 Intel Corporation * * Contact Information: * Intel Linux Wireless @@ -120,9 +121,9 @@ static int iwl_led_cmd(struct iwl_priv *priv, } led_cmd.on = iwl_blink_compensation(priv, on, - priv->cfg->base_params->led_compensation); + priv->cfg->trans.base_params->led_compensation); led_cmd.off = iwl_blink_compensation(priv, off, - priv->cfg->base_params->led_compensation); + priv->cfg->trans.base_params->led_compensation); ret = iwl_send_led_cmd(priv, &led_cmd); if (!ret) { diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c index 6c170636110a..c223f26f046e 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. - * Copyright (C) 2018 Intel Corporation + * Copyright (C) 2018 - 2019 Intel Corporation * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. @@ -1099,7 +1099,7 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, goto done; } - scd_queues = BIT(priv->cfg->base_params->num_of_queues) - 1; + scd_queues = BIT(priv->cfg->trans.base_params->num_of_queues) - 1; scd_queues &= ~(BIT(IWL_IPAN_CMD_QUEUE_NUM) | BIT(IWL_DEFAULT_CMD_QUEUE_NUM)); diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/main.c b/drivers/net/wireless/intel/iwlwifi/dvm/main.c index ae5e4570f1c1..8e47a075089f 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/main.c @@ -3,7 +3,7 @@ * * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2015 Intel Deutschland GmbH - * Copyright (C) 2018 Intel Corporation + * Copyright (C) 2018 - 2019 Intel Corporation * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. @@ -1267,7 +1267,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, priv->cfg = cfg; priv->fw = fw; - switch (priv->cfg->device_family) { + switch (priv->cfg->trans.device_family) { case IWL_DEVICE_FAMILY_1000: case IWL_DEVICE_FAMILY_100: priv->lib = &iwl_dvm_1000_cfg; @@ -1342,7 +1342,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, driver_data[2]); WARN_ON(sizeof(priv->transport_queue_stop) * BITS_PER_BYTE < - priv->cfg->base_params->num_of_queues); + priv->cfg->trans.base_params->num_of_queues); ucode_flags = fw->ucode_capa.flags; diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/power.c b/drivers/net/wireless/intel/iwlwifi/dvm/power.c index dcb948068c1d..e4e02fcbcd9f 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/power.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/power.c @@ -2,6 +2,7 @@ /****************************************************************************** * * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. + * Copyright (C) 2019 Intel Corporation * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. @@ -199,7 +200,7 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv, else cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK; - if (priv->cfg->base_params->shadow_reg_enable) + if (priv->cfg->trans.base_params->shadow_reg_enable) cmd->flags |= IWL_POWER_SHADOW_REG_ENA; else cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA; diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/tx.c b/drivers/net/wireless/intel/iwlwifi/dvm/tx.c index 247f41705912..75dc911b8f00 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/tx.c @@ -2,6 +2,7 @@ /****************************************************************************** * * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. + * Copyright (C) 2019 Intel Corporation * * Contact Information: * Intel Linux Wireless @@ -467,7 +468,7 @@ static int iwlagn_alloc_agg_txq(struct iwl_priv *priv, int mq) int q; for (q = IWLAGN_FIRST_AMPDU_QUEUE; - q < priv->cfg->base_params->num_of_queues; q++) { + q < priv->cfg->trans.base_params->num_of_queues; q++) { if (!test_and_set_bit(q, priv->agg_q_alloc)) { priv->queue_to_mac80211[q] = mq; return q; @@ -1281,7 +1282,7 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, * (in Tx queue's circular buffer) of first TFD/frame in window */ u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn); - if (scd_flow >= priv->cfg->base_params->num_of_queues) { + if (scd_flow >= priv->cfg->trans.base_params->num_of_queues) { IWL_ERR(priv, "BUG_ON scd_flow is bigger than number of queues\n"); return; diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 04afaec2d80e..ef5c75bbd0dd 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -243,7 +243,7 @@ static void iwl_fw_dump_rxf(struct iwl_fw_runtime *fwrt, /* Pull RXF2 */ iwl_fwrt_dump_rxf(fwrt, dump_data, cfg->rxfifo2_size, RXF_DIFF_FROM_PREV + - fwrt->trans->cfg->umac_prph_offset, 1); + fwrt->trans->cfg->trans.umac_prph_offset, 1); /* Pull LMAC2 RXF1 */ if (fwrt->smem_cfg.num_lmacs > 1) iwl_fwrt_dump_rxf(fwrt, dump_data, @@ -684,17 +684,18 @@ static void iwl_fw_prph_handler(struct iwl_fw_runtime *fwrt, void *ptr, { u32 range_len; - if (fwrt->trans->cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { + if (fwrt->trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_AX210) { range_len = ARRAY_SIZE(iwl_prph_dump_addr_ax210); handler(fwrt, iwl_prph_dump_addr_ax210, range_len, ptr); - } else if (fwrt->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22000) { + } else if (fwrt->trans->cfg->trans.device_family >= + IWL_DEVICE_FAMILY_22000) { range_len = ARRAY_SIZE(iwl_prph_dump_addr_22000); handler(fwrt, iwl_prph_dump_addr_22000, range_len, ptr); } else { range_len = ARRAY_SIZE(iwl_prph_dump_addr_comm); handler(fwrt, iwl_prph_dump_addr_comm, range_len, ptr); - if (fwrt->trans->cfg->mq_rx_supported) { + if (fwrt->trans->cfg->trans.mq_rx_supported) { range_len = ARRAY_SIZE(iwl_prph_dump_addr_9000); handler(fwrt, iwl_prph_dump_addr_9000, range_len, ptr); } @@ -856,7 +857,8 @@ iwl_fw_error_dump_file(struct iwl_fw_runtime *fwrt, iwl_fw_prph_handler(fwrt, &prph_len, iwl_fw_get_prph_len); - if (fwrt->trans->cfg->device_family == IWL_DEVICE_FAMILY_7000 && + if (fwrt->trans->cfg->trans.device_family == + IWL_DEVICE_FAMILY_7000 && iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_RADIO_REG)) radio_len = sizeof(*dump_data) + RADIO_REG_MAX_READ; } @@ -1136,7 +1138,7 @@ static int iwl_dump_ini_paging_iter(struct iwl_fw_runtime *fwrt, struct iwl_fw_ini_error_dump_range *range; u32 page_size; - if (!fwrt->trans->cfg->gen2) + if (!fwrt->trans->cfg->trans.gen2) return _iwl_dump_ini_paging_iter(fwrt, reg, range_ptr, idx); range = range_ptr; @@ -1442,7 +1444,7 @@ static void struct iwl_fw_ini_monitor_dump *mon_dump = (void *)data; u32 write_ptr_addr, write_ptr_msk, cycle_cnt_addr, cycle_cnt_msk; - switch (fwrt->trans->cfg->device_family) { + switch (fwrt->trans->cfg->trans.device_family) { case IWL_DEVICE_FAMILY_9000: case IWL_DEVICE_FAMILY_22000: write_ptr_addr = MON_BUFF_WRPTR_VER2; @@ -1452,7 +1454,7 @@ static void break; default: IWL_ERR(fwrt, "Unsupported device family %d\n", - fwrt->trans->cfg->device_family); + fwrt->trans->cfg->trans.device_family); return NULL; } @@ -1469,10 +1471,10 @@ static void struct iwl_fw_ini_monitor_dump *mon_dump = (void *)data; const struct iwl_cfg *cfg = fwrt->trans->cfg; - if (fwrt->trans->cfg->device_family != IWL_DEVICE_FAMILY_9000 && - fwrt->trans->cfg->device_family != IWL_DEVICE_FAMILY_22000) { + if (fwrt->trans->cfg->trans.device_family != IWL_DEVICE_FAMILY_9000 && + fwrt->trans->cfg->trans.device_family != IWL_DEVICE_FAMILY_22000) { IWL_ERR(fwrt, "Unsupported device family %d\n", - fwrt->trans->cfg->device_family); + fwrt->trans->cfg->trans.device_family); return NULL; } @@ -1493,7 +1495,7 @@ static u32 iwl_dump_ini_mem_ranges(struct iwl_fw_runtime *fwrt, static u32 iwl_dump_ini_paging_ranges(struct iwl_fw_runtime *fwrt, struct iwl_fw_ini_region_cfg *reg) { - if (fwrt->trans->cfg->gen2) + if (fwrt->trans->cfg->trans.gen2) return fwrt->trans->init_dram.paging_cnt; return fwrt->num_of_paging_blk; @@ -1541,7 +1543,7 @@ static u32 iwl_dump_ini_paging_get_size(struct iwl_fw_runtime *fwrt, u32 range_header_len = sizeof(struct iwl_fw_ini_error_dump_range); u32 size = sizeof(struct iwl_fw_ini_error_dump); - if (fwrt->trans->cfg->gen2) { + if (fwrt->trans->cfg->trans.gen2) { for (i = 0; i < iwl_dump_ini_paging_ranges(fwrt, reg); i++) size += range_header_len + fwrt->trans->init_dram.paging[i].size; @@ -2470,7 +2472,7 @@ static int iwl_fw_dbg_suspend_resume_hcmd(struct iwl_trans *trans, bool suspend) static void iwl_fw_dbg_stop_recording(struct iwl_trans *trans, struct iwl_fw_dbg_params *params) { - if (trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) { + if (trans->cfg->trans.device_family == IWL_DEVICE_FAMILY_7000) { iwl_set_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x100); return; } @@ -2494,7 +2496,7 @@ static int iwl_fw_dbg_restart_recording(struct iwl_trans *trans, if (!params) return -EIO; - if (trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) { + if (trans->cfg->trans.device_family == IWL_DEVICE_FAMILY_7000) { iwl_clear_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x100); iwl_clear_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x1); iwl_set_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x1); diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h index deb84ba3dc7e..0c8da5e07854 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h @@ -302,7 +302,7 @@ static inline bool iwl_fw_dbg_is_d3_debug_enabled(struct iwl_fw_runtime *fwrt) static inline bool iwl_fw_dbg_is_paging_enabled(struct iwl_fw_runtime *fwrt) { return iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_PAGING) && - !fwrt->trans->cfg->gen2 && + !fwrt->trans->cfg->trans.gen2 && fwrt->cur_fw_img < IWL_UCODE_TYPE_MAX && fwrt->fw->img[fwrt->cur_fw_img].paging_mem_size && fwrt->fw_paging_db[0].fw_paging_block; diff --git a/drivers/net/wireless/intel/iwlwifi/fw/paging.c b/drivers/net/wireless/intel/iwlwifi/fw/paging.c index 9b8dd7fe7112..705eeff1a645 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/paging.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/paging.c @@ -8,7 +8,7 @@ * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH - * Copyright(c) 2018 Intel Corporation + * Copyright(c) 2018 - 2019 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -31,7 +31,7 @@ * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH - * Copyright(c) 2018 Intel Corporation + * Copyright(c) 2018 - 2019 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -322,7 +322,7 @@ int iwl_init_paging(struct iwl_fw_runtime *fwrt, enum iwl_ucode_type type) const struct fw_img *fw = &fwrt->fw->img[type]; int ret; - if (fwrt->trans->cfg->gen2) + if (fwrt->trans->cfg->trans.gen2) return 0; /* diff --git a/drivers/net/wireless/intel/iwlwifi/fw/smem.c b/drivers/net/wireless/intel/iwlwifi/fw/smem.c index 557ee47bffd8..a88117d48ade 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/smem.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/smem.c @@ -151,7 +151,7 @@ void iwl_get_shared_mem_conf(struct iwl_fw_runtime *fwrt) } pkt = cmd.resp_pkt; - if (fwrt->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22000) + if (fwrt->trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_22000) iwl_parse_shared_mem_22000(fwrt, pkt); else iwl_parse_shared_mem(fwrt, pkt); diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h index 6c04f8223aff..284352d9df0e 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h @@ -161,7 +161,8 @@ static inline u8 num_of_ant(u8 mask) !!((mask) & ANT_C); } -/* +/** + * struct iwl_base_params - params not likely to change within a device family * @max_ll_items: max number of OTP blocks * @shadow_ram_support: shadow support for OTP memory * @led_compensation: compensate on the led on/off time per HW according @@ -330,8 +331,37 @@ struct iwl_csr_params { u32 mac_addr1_strap; }; +/** + * struct iwl_cfg_trans - information needed to start the trans + * + * These values cannot be changed when multiple configs are used for a + * single PCI ID, because they are needed before the HW REV or RFID + * can be read. + * + * @base_params: pointer to basic parameters + * @csr: csr flags and addresses that are different across devices + * @device_family: the device family + * @umac_prph_offset: offset to add to UMAC periphery address + * @rf_id: need to read rf_id to determine the firmware image + * @use_tfh: use TFH + * @gen2: 22000 and on transport operation + * @mq_rx_supported: multi-queue rx support + */ +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, + use_tfh:1, + gen2:1, + mq_rx_supported:1, + bisr_workaround:1; +}; + /** * struct iwl_cfg + * @trans: the trans-specific configuration part * @name: Official name of the device * @fw_name_pre: Firmware filename prefix. The api version and extension * (.ucode) will be added to filename before loading from disk. The @@ -346,7 +376,6 @@ struct iwl_csr_params { * @nvm_ver: NVM version * @nvm_calib_ver: NVM calibration version * @lib: pointer to the lib ops - * @base_params: pointer to basic parameters * @ht_params: point to ht parameters * @led_mode: 0=blinking, 1=On(RF On)/Off(RF Off) * @rx_with_siso_diversity: 1x1 device with rx antenna diversity @@ -358,7 +387,6 @@ struct iwl_csr_params { * @mac_addr_from_csr: read HW address from CSR registers * @features: hw features, any combination of feature_whitelist * @pwr_tx_backoffs: translation table between power limits and backoffs - * @csr: csr flags and addresses that are different across devices * @max_rx_agg_size: max RX aggregation size of the ADDBA request/response * @max_tx_agg_size: max TX aggregation size of the ADDBA request/response * @max_ht_ampdu_factor: the exponent of the max length of A-MPDU that the @@ -371,18 +399,14 @@ struct iwl_csr_params { * @dccm2_len: length of the second DCCM * @smem_offset: offset from which the SMEM begins * @smem_len: the length of SMEM - * @mq_rx_supported: multi-queue rx support * @vht_mu_mimo_supported: VHT MU-MIMO support - * @rf_id: need to read rf_id to determine the firmware image * @integrated: discrete or integrated - * @gen2: 22000 and on transport operation * @cdb: CDB support * @nvm_type: see &enum iwl_nvm_type * @d3_debug_data_base_addr: base address where D3 debug data is stored * @d3_debug_data_length: length of the D3 debug data * @bisr_workaround: BISR hardware workaround (for 22260 series devices) * @min_txq_size: minimum number of slots required in a TX queue - * @umac_prph_offset: offset to add to UMAC periphery address * @uhb_supported: ultra high band channels supported * @min_256_ba_txq_size: minimum number of slots required in a TX queue which * supports 256 BA aggregation @@ -392,19 +416,16 @@ struct iwl_csr_params { * and/or the uCode API version instead. */ struct iwl_cfg { + struct iwl_cfg_trans_params trans; /* params specific to an individual device within a device family */ const char *name; const char *fw_name_pre; - /* params not likely to change within a device family */ - const struct iwl_base_params *base_params; /* params likely to change within a device family */ const struct iwl_ht_params *ht_params; const struct iwl_eeprom_params *eeprom_params; const struct iwl_pwr_tx_backoff *pwr_tx_backoffs; const char *default_nvm_file_C_step; const struct iwl_tt_params *thermal_params; - const struct iwl_csr_params *csr; - enum iwl_device_family device_family; enum iwl_led_mode led_mode; enum iwl_nvm_type nvm_type; u32 max_data_size; @@ -428,15 +449,10 @@ struct iwl_cfg { lp_xtal_workaround:1, disable_dummy_notification:1, apmg_not_supported:1, - mq_rx_supported:1, vht_mu_mimo_supported:1, - rf_id:1, integrated:1, - use_tfh:1, - gen2:1, cdb:1, dbgc_supported:1, - bisr_workaround:1, uhb_supported:1; u8 valid_tx_ant; u8 valid_rx_ant; @@ -453,7 +469,6 @@ struct iwl_cfg { u32 d3_debug_data_base_addr; u32 d3_debug_data_length; u32 min_txq_size; - u32 umac_prph_offset; u32 fw_mon_smem_write_ptr_addr; u32 fw_mon_smem_write_ptr_msk; u32 fw_mon_smem_cycle_cnt_ptr_addr; diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c index ae61ad129f06..a204ecbdacaf 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c @@ -215,7 +215,7 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first) const struct iwl_cfg *cfg = drv->trans->cfg; char tag[8]; - if (drv->trans->cfg->device_family == IWL_DEVICE_FAMILY_9000 && + if (drv->trans->cfg->trans.device_family == IWL_DEVICE_FAMILY_9000 && (CSR_HW_REV_STEP(drv->trans->hw_rev) != SILICON_B_STEP && CSR_HW_REV_STEP(drv->trans->hw_rev) != SILICON_C_STEP)) { IWL_ERR(drv, @@ -1120,7 +1120,7 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, if (tlv_len != sizeof(*dbg_ptrs)) goto invalid_tlv_len; - if (drv->trans->cfg->device_family < + if (drv->trans->cfg->trans.device_family < IWL_DEVICE_FAMILY_22000) break; drv->trans->dbg.umac_error_event_table = @@ -1136,7 +1136,7 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, if (tlv_len != sizeof(*dbg_ptrs)) goto invalid_tlv_len; - if (drv->trans->cfg->device_family < + if (drv->trans->cfg->trans.device_family < IWL_DEVICE_FAMILY_22000) break; drv->trans->dbg.lmac_error_event_table[0] = @@ -1522,14 +1522,14 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) fw->init_evtlog_size = (pieces->init_evtlog_size - 16)/12; else fw->init_evtlog_size = - drv->trans->cfg->base_params->max_event_log_size; + drv->trans->cfg->trans.base_params->max_event_log_size; fw->init_errlog_ptr = pieces->init_errlog_ptr; fw->inst_evtlog_ptr = pieces->inst_evtlog_ptr; if (pieces->inst_evtlog_size) fw->inst_evtlog_size = (pieces->inst_evtlog_size - 16)/12; else fw->inst_evtlog_size = - drv->trans->cfg->base_params->max_event_log_size; + drv->trans->cfg->trans.base_params->max_event_log_size; fw->inst_errlog_ptr = pieces->inst_errlog_ptr; /* diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c index 04338c3a6205..75e7053f6807 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c @@ -7,7 +7,7 @@ * * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2015 Intel Mobile Communications 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 @@ -29,7 +29,7 @@ * * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2015 Intel Mobile Communications GmbH - * Copyright(c) 2018 Intel Corporation + * Copyright(c) 2018 - 2019 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -765,7 +765,7 @@ void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg, if (cfg->ht_params->ldpc) ht_info->cap |= IEEE80211_HT_CAP_LDPC_CODING; - if ((cfg->mq_rx_supported && + if ((cfg->trans.mq_rx_supported && iwlwifi_mod_params.amsdu_size == IWL_AMSDU_DEF) || iwlwifi_mod_params.amsdu_size >= IWL_AMSDU_8K) ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU; diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c index 82e87192119e..88f38e4cf7ef 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c @@ -6,7 +6,7 @@ * GPL LICENSE SUMMARY * * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. - * 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) 2005 - 2014 Intel Corporation. All rights reserved. - * 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 @@ -193,7 +193,7 @@ static int iwl_init_otp_access(struct iwl_trans *trans) { int ret; - ret = iwl_finish_nic_init(trans); + ret = iwl_finish_nic_init(trans, &trans->cfg->trans); if (ret) return ret; @@ -207,7 +207,7 @@ static int iwl_init_otp_access(struct iwl_trans *trans) * CSR auto clock gate disable bit - * this is only applicable for HW with OTP shadow RAM */ - if (trans->cfg->base_params->shadow_ram_support) + if (trans->cfg->trans.base_params->shadow_ram_support) iwl_set_bit(trans, CSR_DBG_LINK_PWR_MGMT_REG, CSR_RESET_LINK_PWR_MGMT_DISABLED); @@ -328,7 +328,7 @@ static int iwl_find_otp_image(struct iwl_trans *trans, } /* more in the link list, continue */ usedblocks++; - } while (usedblocks <= trans->cfg->base_params->max_ll_items); + } while (usedblocks <= trans->cfg->trans.base_params->max_ll_items); /* OTP has no valid blocks */ IWL_DEBUG_EEPROM(trans->dev, "OTP has no valid blocks\n"); @@ -361,7 +361,7 @@ int iwl_read_eeprom(struct iwl_trans *trans, u8 **eeprom, size_t *eeprom_size) if (nvm_is_otp < 0) return nvm_is_otp; - sz = trans->cfg->base_params->eeprom_size; + sz = trans->cfg->trans.base_params->eeprom_size; IWL_DEBUG_EEPROM(trans->dev, "NVM size = %d\n", sz); e = kmalloc(sz, GFP_KERNEL); @@ -396,7 +396,7 @@ int iwl_read_eeprom(struct iwl_trans *trans, u8 **eeprom, size_t *eeprom_size) CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK | CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); /* traversing the linked list if no shadow ram supported */ - if (!trans->cfg->base_params->shadow_ram_support) { + if (!trans->cfg->trans.base_params->shadow_ram_support) { ret = iwl_find_otp_image(trans, &validblockaddr); if (ret) goto err_unlock; diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-fh.h b/drivers/net/wireless/intel/iwlwifi/iwl-fh.h index c6a534303936..dfaad564ef09 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-fh.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-fh.h @@ -7,7 +7,7 @@ * * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. * 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 @@ -29,7 +29,7 @@ * * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. * 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 @@ -127,7 +127,7 @@ static inline unsigned int FH_MEM_CBBC_QUEUE(struct iwl_trans *trans, unsigned int chnl) { - if (trans->cfg->use_tfh) { + if (trans->cfg->trans.use_tfh) { WARN_ON_ONCE(chnl >= 64); return TFH_TFDQ_CBB_TABLE + 8 * chnl; } diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-io.c b/drivers/net/wireless/intel/iwlwifi/iwl-io.c index a704e25af810..7561a3891788 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-io.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-io.c @@ -304,10 +304,10 @@ IWL_EXPORT_SYMBOL(iwl_clear_bits_prph); void iwl_force_nmi(struct iwl_trans *trans) { - if (trans->cfg->device_family < IWL_DEVICE_FAMILY_9000) + if (trans->cfg->trans.device_family < IWL_DEVICE_FAMILY_9000) iwl_write_prph(trans, DEVICE_SET_NMI_REG, DEVICE_SET_NMI_VAL_DRV); - else if (trans->cfg->device_family < IWL_DEVICE_FAMILY_AX210) + else if (trans->cfg->trans.device_family < IWL_DEVICE_FAMILY_AX210) iwl_write_umac_prph(trans, UREG_NIC_SET_NMI_DRIVER, UREG_NIC_SET_NMI_DRIVER_NMI_FROM_DRIVER_MSK); else @@ -458,7 +458,7 @@ int iwl_dump_fh(struct iwl_trans *trans, char **buf) FH_TSSR_TX_ERROR_REG }; - if (trans->cfg->mq_rx_supported) + if (trans->cfg->trans.mq_rx_supported) return iwl_dump_rfh(trans, buf); #ifdef CONFIG_IWLWIFI_DEBUGFS @@ -492,11 +492,12 @@ int iwl_dump_fh(struct iwl_trans *trans, char **buf) return 0; } -int iwl_finish_nic_init(struct iwl_trans *trans) +int iwl_finish_nic_init(struct iwl_trans *trans, + const struct iwl_cfg_trans_params *cfg_trans) { int err; - if (trans->cfg->bisr_workaround) { + if (cfg_trans->bisr_workaround) { /* ensure the TOP FSM isn't still in previous reset */ mdelay(2); } @@ -506,9 +507,9 @@ int iwl_finish_nic_init(struct iwl_trans *trans) * D0U* --> D0A* (powered-up active) state. */ iwl_set_bit(trans, CSR_GP_CNTRL, - BIT(trans->cfg->csr->flag_init_done)); + BIT(cfg_trans->csr->flag_init_done)); - if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) + if (cfg_trans->device_family == IWL_DEVICE_FAMILY_8000) udelay(2); /* @@ -517,13 +518,13 @@ int iwl_finish_nic_init(struct iwl_trans *trans) * and accesses to uCode SRAM. */ err = iwl_poll_bit(trans, CSR_GP_CNTRL, - BIT(trans->cfg->csr->flag_mac_clock_ready), - BIT(trans->cfg->csr->flag_mac_clock_ready), + BIT(cfg_trans->csr->flag_mac_clock_ready), + BIT(cfg_trans->csr->flag_mac_clock_ready), 25000); if (err < 0) IWL_DEBUG_INFO(trans, "Failed to wake NIC\n"); - if (trans->cfg->bisr_workaround) { + if (cfg_trans->bisr_workaround) { /* ensure BISR shift has finished */ udelay(200); } diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-io.h b/drivers/net/wireless/intel/iwlwifi/iwl-io.h index 920e2146ea3f..f8e4f0f5de0c 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-io.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-io.h @@ -99,7 +99,8 @@ void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs, void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask); void iwl_force_nmi(struct iwl_trans *trans); -int iwl_finish_nic_init(struct iwl_trans *trans); +int iwl_finish_nic_init(struct iwl_trans *trans, + const struct iwl_cfg_trans_params *cfg_trans); /* Error handling */ int iwl_dump_fh(struct iwl_trans *trans, char **buf); @@ -111,35 +112,38 @@ int iwl_dump_fh(struct iwl_trans *trans, char **buf); */ static inline u32 iwl_umac_prph(struct iwl_trans *trans, u32 ofs) { - return ofs + trans->cfg->umac_prph_offset; + return ofs + trans->cfg->trans.umac_prph_offset; } static inline u32 iwl_read_umac_prph_no_grab(struct iwl_trans *trans, u32 ofs) { - return iwl_read_prph_no_grab(trans, ofs + trans->cfg->umac_prph_offset); + return iwl_read_prph_no_grab(trans, ofs + + trans->cfg->trans.umac_prph_offset); } static inline u32 iwl_read_umac_prph(struct iwl_trans *trans, u32 ofs) { - return iwl_read_prph(trans, ofs + trans->cfg->umac_prph_offset); + return iwl_read_prph(trans, ofs + trans->cfg->trans.umac_prph_offset); } static inline void iwl_write_umac_prph_no_grab(struct iwl_trans *trans, u32 ofs, u32 val) { - iwl_write_prph_no_grab(trans, ofs + trans->cfg->umac_prph_offset, val); + iwl_write_prph_no_grab(trans, ofs + trans->cfg->trans.umac_prph_offset, + val); } static inline void iwl_write_umac_prph(struct iwl_trans *trans, u32 ofs, u32 val) { - iwl_write_prph(trans, ofs + trans->cfg->umac_prph_offset, val); + iwl_write_prph(trans, ofs + trans->cfg->trans.umac_prph_offset, val); } static inline int iwl_poll_umac_prph_bit(struct iwl_trans *trans, u32 addr, u32 bits, u32 mask, int timeout) { - return iwl_poll_prph_bit(trans, addr + trans->cfg->umac_prph_offset, + return iwl_poll_prph_bit(trans, addr + + trans->cfg->trans.umac_prph_offset, bits, mask, timeout); } diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c index 6d95941f56a7..10aef19680d0 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c @@ -434,14 +434,14 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg, switch (iwlwifi_mod_params.amsdu_size) { case IWL_AMSDU_DEF: - if (cfg->mq_rx_supported) + if (cfg->trans.mq_rx_supported) vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454; else vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895; break; case IWL_AMSDU_2K: - if (cfg->mq_rx_supported) + if (cfg->trans.mq_rx_supported) vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454; else @@ -793,10 +793,10 @@ static void iwl_set_hw_address_from_csr(struct iwl_trans *trans, { __le32 mac_addr0 = cpu_to_le32(iwl_read32(trans, - trans->cfg->csr->mac_addr0_strap)); + trans->cfg->trans.csr->mac_addr0_strap)); __le32 mac_addr1 = cpu_to_le32(iwl_read32(trans, - trans->cfg->csr->mac_addr1_strap)); + trans->cfg->trans.csr->mac_addr1_strap)); iwl_flip_hw_address(mac_addr0, mac_addr1, data->hw_addr); /* @@ -807,9 +807,9 @@ static void iwl_set_hw_address_from_csr(struct iwl_trans *trans, return; mac_addr0 = cpu_to_le32(iwl_read32(trans, - trans->cfg->csr->mac_addr0_otp)); + trans->cfg->trans.csr->mac_addr0_otp)); mac_addr1 = cpu_to_le32(iwl_read32(trans, - trans->cfg->csr->mac_addr1_otp)); + trans->cfg->trans.csr->mac_addr1_otp)); iwl_flip_hw_address(mac_addr0, mac_addr1, data->hw_addr); } @@ -908,7 +908,7 @@ iwl_nvm_no_wide_in_5ghz(struct device *dev, const struct iwl_cfg *cfg, * in 5GHz otherwise the FW will throw a sysassert when we try * to use them. */ - if (cfg->device_family == IWL_DEVICE_FAMILY_7000) { + if (cfg->trans.device_family == IWL_DEVICE_FAMILY_7000) { /* * Unlike the other sections in the NVM, the hw * section uses big-endian. @@ -1301,7 +1301,7 @@ int iwl_read_external_nvm(struct iwl_trans *trans, le32_to_cpu(dword_buff[3])); /* nvm file validation, dword_buff[2] holds the file version */ - if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000 && + if (trans->cfg->trans.device_family == IWL_DEVICE_FAMILY_8000 && CSR_HW_REV_STEP(trans->hw_rev) == SILICON_C_STEP && le32_to_cpu(dword_buff[2]) < 0xE4A) { ret = -EFAULT; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index 2bf5b83e116c..cd067653814c 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -1050,7 +1050,7 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, * recording before entering D3. In later devices the FW stops the * recording automatically. */ - if (mvm->trans->cfg->device_family < IWL_DEVICE_FAMILY_9000) + if (mvm->trans->cfg->trans.device_family < IWL_DEVICE_FAMILY_9000) iwl_fw_dbg_stop_restart_recording(&mvm->fwrt, NULL, true); /* must be last -- this switches firmware state */ @@ -1658,7 +1658,7 @@ static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm, mvm_ap_sta->tid_data[i].seq_number = seq; } - if (mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22000) { + if (mvm->trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_22000) { i = mvm->offload_tid; iwl_trans_set_q_ptrs(mvm->trans, mvm_ap_sta->tid_data[i].txq_id, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c index 994a4ba07204..2dbb02666851 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c @@ -1173,8 +1173,8 @@ static ssize_t iwl_dbgfs_inject_packet_write(struct iwl_mvm *mvm, struct iwl_rx_mpdu_desc *desc; int bin_len = count / 2; int ret = -EINVAL; - size_t mpdu_cmd_hdr_size = - (mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) ? + size_t mpdu_cmd_hdr_size = (mvm->trans->cfg->trans.device_family >= + IWL_DEVICE_FAMILY_22560) ? sizeof(struct iwl_rx_mpdu_desc) : IWL_RX_DESC_SIZE_V1; @@ -1182,7 +1182,7 @@ static ssize_t iwl_dbgfs_inject_packet_write(struct iwl_mvm *mvm, return -EIO; /* supporting only 9000 descriptor */ - if (!mvm->trans->cfg->mq_rx_supported) + if (!mvm->trans->cfg->trans.mq_rx_supported) return -ENOTSUPP; rxb._page = alloc_pages(GFP_ATOMIC, 0); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index f09f24089fe7..474e61f436a7 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -357,13 +357,14 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm, iwl_fw_dbg_error_collect(&mvm->fwrt, FW_DBG_TRIGGER_ALIVE_TIMEOUT); - if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22000) + if (trans->cfg->trans.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->cfg->device_family >= IWL_DEVICE_FAMILY_8000) + else if (trans->cfg->trans.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), @@ -557,7 +558,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) goto remove_notif; } - if (mvm->cfg->device_family < IWL_DEVICE_FAMILY_8000) { + if (mvm->cfg->trans.device_family < IWL_DEVICE_FAMILY_8000) { ret = iwl_mvm_send_bt_init_conf(mvm); if (ret) goto remove_notif; @@ -1333,7 +1334,7 @@ int iwl_mvm_up(struct iwl_mvm *mvm) goto error; /* Init RSS configuration */ - if (mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22000) { + if (mvm->trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_22000) { ret = iwl_configure_rxq(mvm); if (ret) { IWL_ERR(mvm, "Failed to configure RX queues: %d\n", diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/led.c b/drivers/net/wireless/intel/iwlwifi/mvm/led.c index 4348bb00e761..64298aec893a 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/led.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/led.c @@ -7,7 +7,7 @@ * * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * 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 @@ -29,7 +29,7 @@ * * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * 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 @@ -156,7 +156,7 @@ void iwl_mvm_leds_sync(struct iwl_mvm *mvm) * if we control through the register, we're doing it * even when the firmware isn't up, so no need to sync */ - if (mvm->cfg->device_family < IWL_DEVICE_FAMILY_8000) + if (mvm->cfg->trans.device_family < IWL_DEVICE_FAMILY_8000) return; iwl_mvm_led_set(mvm, mvm->led.brightness > 0); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index acc7fee9cb3f..7f37e34b74d4 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -400,7 +400,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) * for older devices. We also don't see this issue on any newer * devices. */ - if (mvm->cfg->device_family >= IWL_DEVICE_FAMILY_9000) + if (mvm->cfg->trans.device_family >= IWL_DEVICE_FAMILY_9000) ieee80211_hw_set(hw, TX_AMSDU); ieee80211_hw_set(hw, TX_FRAG_LIST); @@ -3330,7 +3330,7 @@ static int __iwl_mvm_mac_set_key(struct ieee80211_hw *hw, switch (key->cipher) { case WLAN_CIPHER_SUITE_TKIP: - if (!mvm->trans->cfg->gen2) { + if (!mvm->trans->cfg->trans.gen2) { key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; key->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE; } else if (vif->type == NL80211_IFTYPE_STATION) { diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 0ea0f72880af..7d3484144891 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -1356,13 +1356,13 @@ static inline bool iwl_mvm_has_new_rx_api(struct iwl_mvm *mvm) static inline bool iwl_mvm_has_new_tx_api(struct iwl_mvm *mvm) { /* TODO - replace with TLV once defined */ - return mvm->trans->cfg->use_tfh; + return mvm->trans->cfg->trans.use_tfh; } static inline bool iwl_mvm_has_unified_ucode(struct iwl_mvm *mvm) { /* TODO - better define this */ - return mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22000; + return mvm->trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_22000; } static inline bool iwl_mvm_is_cdb_supported(struct iwl_mvm *mvm) @@ -1387,7 +1387,7 @@ static inline bool iwl_mvm_cdb_scan_api(struct iwl_mvm *mvm) * but then there's a little bit of code in scan that won't make * any sense... */ - return mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22000; + return mvm->trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_22000; } static inline bool iwl_mvm_is_scan_ext_chan_supported(struct iwl_mvm *mvm) @@ -1922,7 +1922,7 @@ void iwl_mvm_vif_set_low_latency(struct iwl_mvm_vif *mvmvif, bool set, */ static inline u32 iwl_mvm_flushable_queues(struct iwl_mvm *mvm) { - return ((BIT(mvm->cfg->base_params->num_of_queues) - 1) & + return ((BIT(mvm->cfg->trans.base_params->num_of_queues) - 1) & ~BIT(IWL_MVM_DQA_CMD_QUEUE)); } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c index a9bb43a2f27b..e2855efc2afd 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c @@ -249,7 +249,7 @@ static int iwl_nvm_read_section(struct iwl_mvm *mvm, u16 section, while (ret == length) { /* Check no memory assumptions fail and cause an overflow */ if ((size_read + offset + length) > - mvm->cfg->base_params->eeprom_size) { + mvm->cfg->trans.base_params->eeprom_size) { IWL_ERR(mvm, "EEPROM size is too small for NVM\n"); return -ENOBUFS; } @@ -372,7 +372,7 @@ int iwl_nvm_init(struct iwl_mvm *mvm) /* Read From FW NVM */ IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from NVM\n"); - nvm_buffer = kmalloc(mvm->cfg->base_params->eeprom_size, + nvm_buffer = kmalloc(mvm->cfg->trans.base_params->eeprom_size, GFP_KERNEL); if (!nvm_buffer) return -ENOMEM; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index efd694fd8b79..c30ce004af14 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -173,7 +173,7 @@ static void iwl_mvm_nic_config(struct iwl_op_mode *op_mode) * unrelated errors. Need to further investigate this, but for now * we'll separate cases. */ - if (mvm->trans->cfg->device_family < IWL_DEVICE_FAMILY_8000) + if (mvm->trans->cfg->trans.device_family < IWL_DEVICE_FAMILY_8000) reg_val |= CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI; if (iwl_fw_dbg_is_d3_debug_enabled(&mvm->fwrt)) @@ -664,7 +664,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, if (iwl_mvm_has_new_rx_api(mvm)) { op_mode->ops = &iwl_mvm_ops_mq; trans->rx_mpdu_cmd_hdr_size = - (trans->cfg->device_family >= + (trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_22560) ? sizeof(struct iwl_rx_mpdu_desc) : IWL_RX_DESC_SIZE_V1; @@ -728,7 +728,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, trans_cfg.no_reclaim_cmds = no_reclaim_cmds; trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds); - if (mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) + if (mvm->trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_22560) rb_size_default = IWL_AMSDU_2K; else rb_size_default = IWL_AMSDU_4K; @@ -757,7 +757,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, trans->wide_cmd_header = true; trans_cfg.bc_table_dword = - mvm->trans->cfg->device_family < IWL_DEVICE_FAMILY_22560; + mvm->trans->cfg->trans.device_family < IWL_DEVICE_FAMILY_22560; trans_cfg.command_groups = iwl_mvm_groups; trans_cfg.command_groups_size = ARRAY_SIZE(iwl_mvm_groups); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c index fcd1b15d2fa0..7300eea03b4c 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c @@ -3338,7 +3338,7 @@ static void rs_build_rates_table_from_fixed(struct iwl_mvm *mvm, if (num_of_ant(ant) == 1) lq_cmd->single_stream_ant_msk = ant; - if (!mvm->trans->cfg->gen2) + if (!mvm->trans->cfg->trans.gen2) lq_cmd->agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF; else lq_cmd->agg_frame_cnt_limit = diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c index 854edd7d7103..65a8f0ad5f29 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c @@ -349,7 +349,7 @@ static int iwl_mvm_rx_crypto(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr, !(status & IWL_RX_MPDU_RES_STATUS_TTAK_OK)) return 0; - if (mvm->trans->cfg->gen2 && + if (mvm->trans->cfg->trans.gen2 && !(status & RX_MPDU_RES_STATUS_MIC_OK)) stats->flag |= RX_FLAG_MMIC_ERROR; @@ -366,7 +366,7 @@ static int iwl_mvm_rx_crypto(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr, if (pkt_flags & FH_RSCSR_RADA_EN) { stats->flag |= RX_FLAG_ICV_STRIPPED; - if (mvm->trans->cfg->gen2) + if (mvm->trans->cfg->trans.gen2) stats->flag |= RX_FLAG_MMIC_STRIPPED; } @@ -1504,7 +1504,7 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, if (unlikely(test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))) return; - if (mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) { + if (mvm->trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_22560) { rate_n_flags = le32_to_cpu(desc->v3.rate_n_flags); channel = desc->v3.channel; gp2_on_air_rise = le32_to_cpu(desc->v3.gp2_on_air_rise); @@ -1605,7 +1605,8 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, if (likely(!(phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD))) { u64 tsf_on_air_rise; - if (mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) + if (mvm->trans->cfg->trans.device_family >= + IWL_DEVICE_FAMILY_22560) tsf_on_air_rise = le64_to_cpu(desc->v3.tsf_on_air_rise); else tsf_on_air_rise = le64_to_cpu(desc->v1.tsf_on_air_rise); @@ -1731,7 +1732,7 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, *qc &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT; - if (mvm->trans->cfg->device_family == + if (mvm->trans->cfg->trans.device_family == IWL_DEVICE_FAMILY_9000) { iwl_mvm_flip_address(hdr->addr3); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c index aa0a2a3e0875..ca7e51313381 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c @@ -1604,7 +1604,7 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm, mvm_sta->mac_id_n_color = FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color); mvm_sta->vif = vif; - if (!mvm->trans->cfg->gen2) + if (!mvm->trans->cfg->trans.gen2) mvm_sta->max_agg_bufsize = LINK_QUAL_AGG_FRAME_LIMIT_DEF; else mvm_sta->max_agg_bufsize = LINK_QUAL_AGG_FRAME_LIMIT_GEN2_DEF; @@ -1954,8 +1954,8 @@ static void iwl_mvm_enable_aux_snif_queue(struct iwl_mvm *mvm, u16 *queue, u8 sta_id, u8 fifo) { unsigned int wdg_timeout = iwlmvm_mod_params.tfd_q_hang_detect ? - mvm->cfg->base_params->wd_timeout : - IWL_WATCHDOG_DISABLED; + mvm->cfg->trans.base_params->wd_timeout : + IWL_WATCHDOG_DISABLED; if (iwl_mvm_has_new_tx_api(mvm)) { int tvqm_queue = @@ -2813,7 +2813,7 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif, * to align the wrap around of ssn so we compare relevant values. */ normalized_ssn = tid_data->ssn; - if (mvm->trans->cfg->gen2) + if (mvm->trans->cfg->trans.gen2) normalized_ssn &= 0xff; if (normalized_ssn == tid_data->next_reclaimed) { @@ -3853,7 +3853,7 @@ u16 iwl_mvm_tid_queued(struct iwl_mvm *mvm, struct iwl_mvm_tid_data *tid_data) * In 22000 HW, the next_reclaimed index is only 8 bit, so we'll need * to align the wrap around of ssn so we compare relevant values. */ - if (mvm->trans->cfg->gen2) + if (mvm->trans->cfg->trans.gen2) sn &= 0xff; return ieee80211_sn_sub(sn, tid_data->next_reclaimed); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index 4effb90b4f75..48d305c9b737 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c @@ -546,7 +546,7 @@ iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb, hdr->frame_control); } - if (mvm->trans->cfg->device_family >= + if (mvm->trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_22560) { struct iwl_tx_cmd_gen3 *cmd = (void *)dev_cmd->payload; @@ -1272,7 +1272,7 @@ static void iwl_mvm_check_ratid_empty(struct iwl_mvm *mvm, * to align the wrap around of ssn so we compare relevant values. */ normalized_ssn = tid_data->ssn; - if (mvm->trans->cfg->gen2) + if (mvm->trans->cfg->trans.gen2) normalized_ssn &= 0xff; if (normalized_ssn != tid_data->next_reclaimed) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c index 06ef853fb84a..f8d6e5672867 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c @@ -531,7 +531,7 @@ static void iwl_mvm_dump_lmac_error_log(struct iwl_mvm *mvm, u8 lmac_num) /* reset the device */ iwl_trans_sw_reset(trans); - err = iwl_finish_nic_init(trans); + err = iwl_finish_nic_init(trans, &trans->cfg->trans); if (err) return; } @@ -939,8 +939,9 @@ unsigned int iwl_mvm_get_wd_timeout(struct iwl_mvm *mvm, { struct iwl_fw_dbg_trigger_tlv *trigger; struct iwl_fw_dbg_trigger_txq_timer *txq_timer; - unsigned int default_timeout = - cmd_q ? IWL_DEF_WD_TIMEOUT : mvm->cfg->base_params->wd_timeout; + unsigned int default_timeout = cmd_q ? + IWL_DEF_WD_TIMEOUT : + mvm->cfg->trans.base_params->wd_timeout; if (!iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_TXQ_TIMERS)) { /* @@ -984,7 +985,7 @@ unsigned int iwl_mvm_get_wd_timeout(struct iwl_mvm *mvm, return default_timeout; default: WARN_ON(1); - return mvm->cfg->base_params->wd_timeout; + return mvm->cfg->trans.base_params->wd_timeout; } } @@ -1430,7 +1431,7 @@ u32 iwl_mvm_get_systime(struct iwl_mvm *mvm) { u32 reg_addr = DEVICE_SYSTEM_TIME_REG; - if (mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22000 && + if (mvm->trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_22000 && mvm->trans->cfg->gp2_reg_addr) reg_addr = mvm->trans->cfg->gp2_reg_addr; 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 9b27c955b8dc..1b5de527f141 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c @@ -180,7 +180,7 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans, iwl_set_bit(trans, CSR_CTXT_INFO_BOOT_CTRL, CSR_AUTO_FUNC_BOOT_ENA); - if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_AX210) + if (trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_AX210) iwl_write_umac_prph(trans, UREG_CPU_INIT_RUN, 1); else iwl_set_bit(trans, CSR_GP_CNTRL, CSR_AUTO_FUNC_INIT); diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index c02cb976cafe..08990694dd0e 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -995,7 +995,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) struct iwl_trans *iwl_trans; int ret; - if (WARN_ONCE(!cfg->csr, "CSR addresses aren't configured\n")) + if (WARN_ONCE(!cfg->trans.csr, "CSR addresses aren't configured\n")) return -EINVAL; iwl_trans = iwl_trans_pcie_alloc(pdev, ent, cfg); @@ -1022,7 +1022,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) iwl_trans->cfg = cfg_7265d; } - if (iwl_trans->cfg->rf_id && cfg == &iwl22000_2ac_cfg_hr_cdb && + if (iwl_trans->cfg->trans.rf_id && cfg == &iwl22000_2ac_cfg_hr_cdb && iwl_trans->hw_rev != CSR_HW_REV_TYPE_HR_CDB) { u32 rf_id_chp = CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id); u32 jf_chp_id = CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_JF); diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h index 906e1da3923d..53999ea7bb04 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h @@ -253,7 +253,8 @@ struct iwl_dma_ptr { */ static inline int iwl_queue_inc_wrap(struct iwl_trans *trans, int index) { - return ++index & (trans->cfg->base_params->max_tfd_queue_size - 1); + return ++index & + (trans->cfg->trans.base_params->max_tfd_queue_size - 1); } /** @@ -263,7 +264,7 @@ static inline int iwl_queue_inc_wrap(struct iwl_trans *trans, int index) static inline __le16 iwl_get_closed_rb_stts(struct iwl_trans *trans, struct iwl_rxq *rxq) { - if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) { + if (trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_22560) { __le16 *rb_stts = rxq->rb_stts; return READ_ONCE(*rb_stts); @@ -280,7 +281,8 @@ static inline __le16 iwl_get_closed_rb_stts(struct iwl_trans *trans, */ static inline int iwl_queue_dec_wrap(struct iwl_trans *trans, int index) { - return --index & (trans->cfg->base_params->max_tfd_queue_size - 1); + return --index & + (trans->cfg->trans.base_params->max_tfd_queue_size - 1); } struct iwl_cmd_meta { @@ -704,7 +706,7 @@ void iwl_pcie_gen2_update_byte_tbl(struct iwl_trans_pcie *trans_pcie, static inline u16 iwl_pcie_tfd_tb_get_len(struct iwl_trans *trans, void *_tfd, u8 idx) { - if (trans->cfg->use_tfh) { + if (trans->cfg->trans.use_tfh) { struct iwl_tfh_tfd *tfd = _tfd; struct iwl_tfh_tb *tb = &tfd->tbs[idx]; @@ -910,7 +912,7 @@ static inline void *iwl_pcie_get_tfd(struct iwl_trans *trans, { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - if (trans->cfg->use_tfh) + if (trans->cfg->trans.use_tfh) idx = iwl_pcie_get_cmd_index(txq, idx); return txq->tfds + trans_pcie->tfd_size * idx; @@ -954,7 +956,7 @@ static inline void iwl_enable_rfkill_int(struct iwl_trans *trans) MSIX_HW_INT_CAUSES_REG_RF_KILL); } - if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_9000) { + if (trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_9000) { /* * On 9000-series devices this bit isn't enabled by default, so * when we power down the device we need set the bit to allow it diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c index a2d709642b2a..79b012e881f0 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c @@ -200,12 +200,12 @@ static inline __le32 iwl_pcie_dma_addr2rbd_ptr(dma_addr_t dma_addr) */ int iwl_pcie_rx_stop(struct iwl_trans *trans) { - if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) { + if (trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_22560) { /* TODO: remove this for 22560 once fw does it */ iwl_write_umac_prph(trans, RFH_RXF_DMA_CFG_GEN3, 0); return iwl_poll_umac_prph_bit(trans, RFH_GEN_STATUS_GEN3, RXF_DMA_IDLE, RXF_DMA_IDLE, 1000); - } else if (trans->cfg->mq_rx_supported) { + } else if (trans->cfg->trans.mq_rx_supported) { iwl_write_prph(trans, RFH_RXF_DMA_CFG, 0); return iwl_poll_prph_bit(trans, RFH_GEN_STATUS, RXF_DMA_IDLE, RXF_DMA_IDLE, 1000); @@ -232,7 +232,7 @@ static void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans *trans, * 1. shadow registers aren't enabled * 2. there is a chance that the NIC is asleep */ - if (!trans->cfg->base_params->shadow_reg_enable && + if (!trans->cfg->trans.base_params->shadow_reg_enable && test_bit(STATUS_TPOWER_PMI, &trans->status)) { reg = iwl_read32(trans, CSR_UCODE_DRV_GP1); @@ -240,18 +240,18 @@ 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->cfg->csr->flag_mac_access_req)); + BIT(trans->cfg->trans.csr->flag_mac_access_req)); rxq->need_update = true; return; } } rxq->write_actual = round_down(rxq->write, 8); - if (trans->cfg->device_family == IWL_DEVICE_FAMILY_22560) + if (trans->cfg->trans.device_family == IWL_DEVICE_FAMILY_22560) iwl_write32(trans, HBUS_TARG_WRPTR, (rxq->write_actual | ((FIRST_RX_QUEUE + rxq->id) << 16))); - else if (trans->cfg->mq_rx_supported) + else if (trans->cfg->trans.mq_rx_supported) iwl_write32(trans, RFH_Q_FRBDCB_WIDX_TRG(rxq->id), rxq->write_actual); else @@ -279,7 +279,7 @@ static void iwl_pcie_restock_bd(struct iwl_trans *trans, struct iwl_rxq *rxq, struct iwl_rx_mem_buffer *rxb) { - if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) { + if (trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_22560) { struct iwl_rx_transfer_desc *bd = rxq->bd; BUILD_BUG_ON(sizeof(*bd) != 2 * sizeof(u64)); @@ -405,7 +405,7 @@ static void iwl_pcie_rxsq_restock(struct iwl_trans *trans, static void iwl_pcie_rxq_restock(struct iwl_trans *trans, struct iwl_rxq *rxq) { - if (trans->cfg->mq_rx_supported) + if (trans->cfg->trans.mq_rx_supported) iwl_pcie_rxmq_restock(trans, rxq); else iwl_pcie_rxsq_restock(trans, rxq); @@ -682,7 +682,7 @@ static int iwl_pcie_free_bd_size(struct iwl_trans *trans, bool use_rx_td) if (use_rx_td) return sizeof(*rx_td); else - return trans->cfg->mq_rx_supported ? sizeof(__le64) : + return trans->cfg->trans.mq_rx_supported ? sizeof(__le64) : sizeof(__le32); } @@ -690,7 +690,7 @@ static void iwl_pcie_free_rxq_dma(struct iwl_trans *trans, struct iwl_rxq *rxq) { struct device *dev = trans->dev; - bool use_rx_td = (trans->cfg->device_family >= + bool use_rx_td = (trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_22560); int free_size = iwl_pcie_free_bd_size(trans, use_rx_td); @@ -712,7 +712,7 @@ static void iwl_pcie_free_rxq_dma(struct iwl_trans *trans, rxq->used_bd_dma = 0; rxq->used_bd = NULL; - if (trans->cfg->device_family < IWL_DEVICE_FAMILY_22560) + if (trans->cfg->trans.device_family < IWL_DEVICE_FAMILY_22560) return; if (rxq->tr_tail) @@ -735,13 +735,13 @@ static int iwl_pcie_alloc_rxq_dma(struct iwl_trans *trans, struct device *dev = trans->dev; int i; int free_size; - bool use_rx_td = (trans->cfg->device_family >= + bool use_rx_td = (trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_22560); size_t rb_stts_size = use_rx_td ? sizeof(__le16) : sizeof(struct iwl_rb_status); spin_lock_init(&rxq->lock); - if (trans->cfg->mq_rx_supported) + if (trans->cfg->trans.mq_rx_supported) rxq->queue_size = MQ_RX_TABLE_SIZE; else rxq->queue_size = RX_QUEUE_SIZE; @@ -757,7 +757,7 @@ static int iwl_pcie_alloc_rxq_dma(struct iwl_trans *trans, if (!rxq->bd) goto err; - if (trans->cfg->mq_rx_supported) { + if (trans->cfg->trans.mq_rx_supported) { rxq->used_bd = dma_alloc_coherent(dev, (use_rx_td ? sizeof(*rxq->cd) : sizeof(__le32)) * rxq->queue_size, &rxq->used_bd_dma, @@ -807,7 +807,7 @@ int iwl_pcie_rx_alloc(struct iwl_trans *trans) struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_rb_allocator *rba = &trans_pcie->rba; int i, ret; - size_t rb_stts_size = trans->cfg->device_family >= + size_t rb_stts_size = trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_22560 ? sizeof(__le16) : sizeof(struct iwl_rb_status); @@ -1074,8 +1074,8 @@ int _iwl_pcie_rx_init(struct iwl_trans *trans) rxq->read = 0; rxq->write = 0; rxq->write_actual = 0; - memset(rxq->rb_stts, 0, - (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) ? + memset(rxq->rb_stts, 0, (trans->cfg->trans.device_family >= + IWL_DEVICE_FAMILY_22560) ? sizeof(__le16) : sizeof(struct iwl_rb_status)); iwl_pcie_rx_init_rxb_lists(rxq); @@ -1088,7 +1088,7 @@ int _iwl_pcie_rx_init(struct iwl_trans *trans) } /* move the pool to the default queue and allocator ownerships */ - queue_size = trans->cfg->mq_rx_supported ? + queue_size = trans->cfg->trans.mq_rx_supported ? MQ_RX_NUM_RBDS : RX_QUEUE_SIZE; allocator_pool_size = trans->num_rx_queues * (RX_CLAIM_REQ_ALLOC - RX_POST_REQ_ALLOC); @@ -1120,7 +1120,7 @@ int iwl_pcie_rx_init(struct iwl_trans *trans) if (ret) return ret; - if (trans->cfg->mq_rx_supported) + if (trans->cfg->trans.mq_rx_supported) iwl_pcie_rx_mq_hw_init(trans); else iwl_pcie_rx_hw_init(trans, trans_pcie->rxq); @@ -1151,7 +1151,7 @@ void iwl_pcie_rx_free(struct iwl_trans *trans) struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_rb_allocator *rba = &trans_pcie->rba; int i; - size_t rb_stts_size = trans->cfg->device_family >= + size_t rb_stts_size = trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_22560 ? sizeof(__le16) : sizeof(struct iwl_rb_status); @@ -1347,7 +1347,7 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans, } page_stolen |= rxcb._page_stolen; - if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) + if (trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_22560) break; offset += ALIGN(len, FH_RSCSR_FRAME_ALIGN); } @@ -1392,14 +1392,14 @@ static struct iwl_rx_mem_buffer *iwl_pcie_get_rxb(struct iwl_trans *trans, BUILD_BUG_ON(sizeof(struct iwl_rx_completion_desc) != 32); - if (!trans->cfg->mq_rx_supported) { + if (!trans->cfg->trans.mq_rx_supported) { rxb = rxq->queue[i]; rxq->queue[i] = NULL; return rxb; } /* used_bd is a 32/16 bit but only 12 are used to retrieve the vid */ - if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) + if (trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_22560) vid = le16_to_cpu(rxq->cd[i].rbid) & 0x0FFF; else vid = le32_to_cpu(rxq->bd_32[i]) & 0x0FFF; @@ -1515,7 +1515,7 @@ static void iwl_pcie_rx_handle(struct iwl_trans *trans, int queue) /* Backtrack one entry */ rxq->read = i; /* update cr tail with the rxq read pointer */ - if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) + if (trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_22560) *rxq->cr_tail = cpu_to_le16(r); spin_unlock(&rxq->lock); @@ -1597,7 +1597,7 @@ static void iwl_pcie_irq_handle_error(struct iwl_trans *trans) return; } - for (i = 0; i < trans->cfg->base_params->num_of_queues; i++) { + for (i = 0; i < trans->cfg->trans.base_params->num_of_queues; i++) { if (!trans_pcie->txq[i]) continue; del_timer(&trans_pcie->txq[i]->stuck_timer); @@ -1838,7 +1838,7 @@ irqreturn_t iwl_pcie_irq_handler(int irq, void *dev_id) if (inta & CSR_INT_BIT_ALIVE) { IWL_DEBUG_ISR(trans, "Alive interrupt\n"); isr_stats->alive++; - if (trans->cfg->gen2) { + if (trans->cfg->trans.gen2) { /* * We can restock, since firmware configured * the RFH @@ -2179,13 +2179,13 @@ irqreturn_t iwl_pcie_irq_msix_handler(int irq, void *dev_id) if (inta_hw & MSIX_HW_INT_CAUSES_REG_ALIVE) { IWL_DEBUG_ISR(trans, "Alive interrupt\n"); isr_stats->alive++; - if (trans->cfg->gen2) { + if (trans->cfg->trans.gen2) { /* We can restock, since firmware configured the RFH */ iwl_pcie_rxmq_restock(trans, trans_pcie->rxq); } } - if (trans->cfg->device_family == IWL_DEVICE_FAMILY_22560 && + if (trans->cfg->trans.device_family == IWL_DEVICE_FAMILY_22560 && inta_hw & MSIX_HW_INT_CAUSES_REG_IPC) { /* Reflect IML transfer status */ int res = iwl_read32(trans, CSR_IML_RESP_ADDR); diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c index c099ad8b003f..919b69ab836d 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c @@ -92,7 +92,7 @@ int iwl_pcie_gen2_apm_init(struct iwl_trans *trans) iwl_pcie_apm_config(trans); - ret = iwl_finish_nic_init(trans); + ret = iwl_finish_nic_init(trans, &trans->cfg->trans); if (ret) return ret; @@ -133,7 +133,7 @@ static void iwl_pcie_gen2_apm_stop(struct iwl_trans *trans, bool op_mode_leave) * D0A* (powered-up Active) --> D0U* (Uninitialized) state. */ iwl_clear_bit(trans, CSR_GP_CNTRL, - BIT(trans->cfg->csr->flag_init_done)); + BIT(trans->cfg->trans.csr->flag_init_done)); } void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans) @@ -168,14 +168,14 @@ void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans) } iwl_pcie_ctxt_info_free_paging(trans); - if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) + if (trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_22560) iwl_pcie_ctxt_info_gen3_free(trans); else iwl_pcie_ctxt_info_free(trans); /* Make sure (redundant) we've released our request to stay awake */ iwl_clear_bit(trans, CSR_GP_CNTRL, - BIT(trans->cfg->csr->flag_mac_access_req)); + BIT(trans->cfg->trans.csr->flag_mac_access_req)); /* Stop the device, and put it in low power state */ iwl_pcie_gen2_apm_stop(trans, false); @@ -340,7 +340,7 @@ int iwl_trans_pcie_gen2_start_fw(struct iwl_trans *trans, goto out; } - if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) + if (trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_22560) ret = iwl_pcie_ctxt_info_gen3_init(trans, fw); else ret = iwl_pcie_ctxt_info_init(trans, fw); diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index 8639e60b4f40..db75a79aa8a4 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -184,8 +184,8 @@ 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->cfg->csr->addr_sw_reset, - BIT(trans->cfg->csr->flag_sw_reset)); + iwl_set_bit(trans, trans->cfg->trans.csr->addr_sw_reset, + BIT(trans->cfg->trans.csr->flag_sw_reset)); usleep_range(5000, 6000); } @@ -341,7 +341,7 @@ static int iwl_pcie_apm_init(struct iwl_trans *trans) */ /* Disable L0S exit timer (platform NMI Work/Around) */ - if (trans->cfg->device_family < IWL_DEVICE_FAMILY_8000) + if (trans->cfg->trans.device_family < IWL_DEVICE_FAMILY_8000) iwl_set_bit(trans, CSR_GIO_CHICKEN_BITS, CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER); @@ -365,10 +365,10 @@ static int iwl_pcie_apm_init(struct iwl_trans *trans) iwl_pcie_apm_config(trans); /* Configure analog phase-lock-loop before activating to D0A */ - if (trans->cfg->base_params->pll_cfg) + if (trans->cfg->trans.base_params->pll_cfg) iwl_set_bit(trans, CSR_ANA_PLL_CFG, CSR50_ANA_PLL_CFG_VAL); - ret = iwl_finish_nic_init(trans); + ret = iwl_finish_nic_init(trans, &trans->cfg->trans); if (ret) return ret; @@ -440,7 +440,7 @@ static void iwl_pcie_apm_lp_xtal_enable(struct iwl_trans *trans) iwl_trans_pcie_sw_reset(trans); - ret = iwl_finish_nic_init(trans); + ret = iwl_finish_nic_init(trans, &trans->cfg->trans); if (WARN_ON(ret)) { /* Release XTAL ON request */ __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL, @@ -490,7 +490,7 @@ static void iwl_pcie_apm_lp_xtal_enable(struct iwl_trans *trans) * D0A* (powered-up Active) --> D0U* (Uninitialized) state. */ iwl_clear_bit(trans, CSR_GP_CNTRL, - BIT(trans->cfg->csr->flag_init_done)); + BIT(trans->cfg->trans.csr->flag_init_done)); /* Activates XTAL resources monitor */ __iwl_trans_pcie_set_bit(trans, CSR_MONITOR_CFG_REG, @@ -512,12 +512,12 @@ void iwl_pcie_apm_stop_master(struct iwl_trans *trans) int ret; /* stop device's busmaster DMA activity */ - iwl_set_bit(trans, trans->cfg->csr->addr_sw_reset, - BIT(trans->cfg->csr->flag_stop_master)); + iwl_set_bit(trans, trans->cfg->trans.csr->addr_sw_reset, + BIT(trans->cfg->trans.csr->flag_stop_master)); - ret = iwl_poll_bit(trans, trans->cfg->csr->addr_sw_reset, - BIT(trans->cfg->csr->flag_master_dis), - BIT(trans->cfg->csr->flag_master_dis), 100); + ret = iwl_poll_bit(trans, trans->cfg->trans.csr->addr_sw_reset, + BIT(trans->cfg->trans.csr->flag_master_dis), + BIT(trans->cfg->trans.csr->flag_master_dis), 100); if (ret < 0) IWL_WARN(trans, "Master Disable Timed Out, 100 usec\n"); @@ -533,10 +533,11 @@ static void iwl_pcie_apm_stop(struct iwl_trans *trans, bool op_mode_leave) iwl_pcie_apm_init(trans); /* inform ME that we are leaving */ - if (trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) + if (trans->cfg->trans.device_family == IWL_DEVICE_FAMILY_7000) iwl_set_bits_prph(trans, APMG_PCIDEV_STT_REG, APMG_PCIDEV_STT_VAL_WAKE_ME); - else if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_8000) { + else if (trans->cfg->trans.device_family >= + IWL_DEVICE_FAMILY_8000) { iwl_set_bit(trans, CSR_DBG_LINK_PWR_MGMT_REG, CSR_RESET_LINK_PWR_MGMT_DISABLED); iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG, @@ -566,7 +567,7 @@ static void iwl_pcie_apm_stop(struct iwl_trans *trans, bool op_mode_leave) * D0A* (powered-up Active) --> D0U* (Uninitialized) state. */ iwl_clear_bit(trans, CSR_GP_CNTRL, - BIT(trans->cfg->csr->flag_init_done)); + BIT(trans->cfg->trans.csr->flag_init_done)); } static int iwl_pcie_nic_init(struct iwl_trans *trans) @@ -593,7 +594,7 @@ static int iwl_pcie_nic_init(struct iwl_trans *trans) if (iwl_pcie_tx_init(trans)) return -ENOMEM; - if (trans->cfg->base_params->shadow_reg_enable) { + if (trans->cfg->trans.base_params->shadow_reg_enable) { /* enable shadow regs in HW */ iwl_set_bit(trans, CSR_MAC_SHADOW_REG_CTRL, 0x800FFFFF); IWL_DEBUG_INFO(trans, "Enabling shadow registers in device\n"); @@ -831,7 +832,7 @@ static int iwl_pcie_load_cpu_sections_8000(struct iwl_trans *trans, iwl_enable_interrupts(trans); - if (trans->cfg->use_tfh) { + if (trans->cfg->trans.use_tfh) { if (cpu == 1) iwl_write_prph(trans, UREG_UCODE_LOAD_STATUS, 0xFFFF); @@ -963,7 +964,7 @@ void iwl_pcie_apply_destination(struct iwl_trans *trans) iwl_write_prph(trans, le32_to_cpu(dest->base_reg), trans->dbg.fw_mon[0].physical >> dest->base_shift); - if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_8000) + if (trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_8000) iwl_write_prph(trans, le32_to_cpu(dest->end_reg), (trans->dbg.fw_mon[0].physical + trans->dbg.fw_mon[0].size - 256) >> @@ -1005,7 +1006,7 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans, /* supported for 7000 only for the moment */ if (iwlwifi_mod_params.fw_monitor && - trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) { + trans->cfg->trans.device_family == IWL_DEVICE_FAMILY_7000) { iwl_pcie_alloc_fw_monitor(trans, 0); if (trans->dbg.fw_mon[0].size) { @@ -1134,7 +1135,7 @@ static void iwl_pcie_map_non_rx_causes(struct iwl_trans *trans) struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); int val = trans_pcie->def_irq | MSIX_NON_AUTO_CLEAR_CAUSE; int i, arr_size = - (trans->cfg->device_family != IWL_DEVICE_FAMILY_22560) ? + (trans->cfg->trans.device_family != IWL_DEVICE_FAMILY_22560) ? ARRAY_SIZE(causes_list) : ARRAY_SIZE(causes_list_v2); /* @@ -1144,7 +1145,8 @@ static void iwl_pcie_map_non_rx_causes(struct iwl_trans *trans) */ for (i = 0; i < arr_size; i++) { struct iwl_causes_list *causes = - (trans->cfg->device_family != IWL_DEVICE_FAMILY_22560) ? + (trans->cfg->trans.device_family != + IWL_DEVICE_FAMILY_22560) ? causes_list : causes_list_v2; iwl_write8(trans, CSR_MSIX_IVAR(causes[i].addr), val); @@ -1188,7 +1190,7 @@ void iwl_pcie_conf_msix_hw(struct iwl_trans_pcie *trans_pcie) struct iwl_trans *trans = trans_pcie->trans; if (!trans_pcie->msix_enabled) { - if (trans->cfg->mq_rx_supported && + if (trans->cfg->trans.mq_rx_supported && test_bit(STATUS_DEVICE_ENABLED, &trans->status)) iwl_write_umac_prph(trans, UREG_CHICK, UREG_CHICK_MSI_ENABLE); @@ -1269,7 +1271,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->cfg->csr->flag_mac_access_req)); + BIT(trans->cfg->trans.csr->flag_mac_access_req)); /* Stop the device, and put it in low power state */ iwl_pcie_apm_stop(trans, false); @@ -1396,7 +1398,7 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); /* Load the given image to the HW */ - if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_8000) + if (trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_8000) ret = iwl_pcie_load_given_ucode_8000(trans, fw); else ret = iwl_pcie_load_given_ucode(trans, fw); @@ -1469,7 +1471,7 @@ void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state) IWL_WARN(trans, "reporting RF_KILL (radio %s)\n", state ? "disabled" : "enabled"); if (iwl_op_mode_hw_rf_kill(trans->op_mode, state)) { - if (trans->cfg->gen2) + if (trans->cfg->trans.gen2) _iwl_trans_pcie_gen2_stop_device(trans); else _iwl_trans_pcie_stop_device(trans); @@ -1499,9 +1501,9 @@ static void iwl_trans_pcie_d3_suspend(struct iwl_trans *trans, bool test, iwl_pcie_synchronize_irqs(trans); iwl_clear_bit(trans, CSR_GP_CNTRL, - BIT(trans->cfg->csr->flag_mac_access_req)); + BIT(trans->cfg->trans.csr->flag_mac_access_req)); iwl_clear_bit(trans, CSR_GP_CNTRL, - BIT(trans->cfg->csr->flag_init_done)); + BIT(trans->cfg->trans.csr->flag_init_done)); if (reset) { /* @@ -1530,9 +1532,9 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans, } iwl_set_bit(trans, CSR_GP_CNTRL, - BIT(trans->cfg->csr->flag_mac_access_req)); + BIT(trans->cfg->trans.csr->flag_mac_access_req)); - ret = iwl_finish_nic_init(trans); + ret = iwl_finish_nic_init(trans, &trans->cfg->trans); if (ret) return ret; @@ -1552,7 +1554,7 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans, if (!reset) { iwl_clear_bit(trans, CSR_GP_CNTRL, - BIT(trans->cfg->csr->flag_mac_access_req)); + BIT(trans->cfg->trans.csr->flag_mac_access_req)); } else { iwl_trans_pcie_tx_reset(trans); @@ -1583,7 +1585,7 @@ static void iwl_pcie_set_interrupt_capa(struct pci_dev *pdev, int max_irqs, num_irqs, i, ret; u16 pci_cmd; - if (!trans->cfg->mq_rx_supported) + if (!trans->cfg->trans.mq_rx_supported) goto enable_msi; max_irqs = min_t(u32, num_online_cpus() + 2, IWL_MAX_RX_HW_QUEUES); @@ -1704,7 +1706,7 @@ static int iwl_trans_pcie_clear_persistence_bit(struct iwl_trans *trans) { u32 hpm, wprot; - switch (trans->cfg->device_family) { + switch (trans->cfg->trans.device_family) { case IWL_DEVICE_FAMILY_9000: wprot = PREG_PRPH_WPROT_9000; break; @@ -1819,7 +1821,7 @@ static u32 iwl_trans_pcie_read32(struct iwl_trans *trans, u32 ofs) static u32 iwl_trans_pcie_prph_msk(struct iwl_trans *trans) { - if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) + if (trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_22560) return 0x00FFFFFF; else return 0x000FFFFF; @@ -1890,7 +1892,7 @@ void iwl_trans_pcie_free(struct iwl_trans *trans) iwl_pcie_synchronize_irqs(trans); - if (trans->cfg->gen2) + if (trans->cfg->trans.gen2) iwl_pcie_gen2_tx_free(trans); else iwl_pcie_tx_free(trans); @@ -1972,8 +1974,8 @@ 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->cfg->csr->flag_mac_access_req)); - if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_8000) + BIT(trans->cfg->trans.csr->flag_mac_access_req)); + if (trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_8000) udelay(2); /* @@ -1997,8 +1999,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->cfg->csr->flag_val_mac_access_en), - (BIT(trans->cfg->csr->flag_mac_clock_ready) | + BIT(trans->cfg->trans.csr->flag_val_mac_access_en), + (BIT(trans->cfg->trans.csr->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); @@ -2080,7 +2082,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->cfg->csr->flag_mac_access_req)); + BIT(trans->cfg->trans.csr->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 @@ -2187,7 +2189,7 @@ static void iwl_trans_pcie_block_txq_ptrs(struct iwl_trans *trans, bool block) struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); int i; - for (i = 0; i < trans->cfg->base_params->num_of_queues; i++) { + for (i = 0; i < trans->cfg->trans.base_params->num_of_queues; i++) { struct iwl_txq *txq = trans_pcie->txq[i]; if (i == trans_pcie->cmd_queue) @@ -2218,7 +2220,7 @@ void iwl_trans_pcie_log_scd_error(struct iwl_trans *trans, struct iwl_txq *txq) bool active; u8 fifo; - if (trans->cfg->use_tfh) { + if (trans->cfg->trans.use_tfh) { IWL_ERR(trans, "Queue %d is stuck %d %d\n", txq_id, txq->read_ptr, txq->write_ptr); /* TODO: access new SCD registers and dump them */ @@ -2235,9 +2237,9 @@ void iwl_trans_pcie_log_scd_error(struct iwl_trans *trans, struct iwl_txq *txq) jiffies_to_msecs(txq->wd_timeout), txq->read_ptr, txq->write_ptr, iwl_read_prph(trans, SCD_QUEUE_RDPTR(txq_id)) & - (trans->cfg->base_params->max_tfd_queue_size - 1), + (trans->cfg->trans.base_params->max_tfd_queue_size - 1), iwl_read_prph(trans, SCD_QUEUE_WRPTR(txq_id)) & - (trans->cfg->base_params->max_tfd_queue_size - 1), + (trans->cfg->trans.base_params->max_tfd_queue_size - 1), iwl_read_direct32(trans, FH_TX_TRB_REG(fifo))); } @@ -2326,7 +2328,9 @@ static int iwl_trans_pcie_wait_txqs_empty(struct iwl_trans *trans, u32 txq_bm) int ret = 0; /* waiting for all the tx frames complete might take a while */ - for (cnt = 0; cnt < trans->cfg->base_params->num_of_queues; cnt++) { + for (cnt = 0; + cnt < trans->cfg->trans.base_params->num_of_queues; + cnt++) { if (cnt == trans_pcie->cmd_queue) continue; @@ -2470,7 +2474,8 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file, int ret; size_t bufsz; - bufsz = sizeof(char) * 75 * trans->cfg->base_params->num_of_queues; + bufsz = sizeof(char) * 75 * + trans->cfg->trans.base_params->num_of_queues; if (!trans_pcie->txq_memory) return -EAGAIN; @@ -2479,7 +2484,9 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file, if (!buf) return -ENOMEM; - for (cnt = 0; cnt < trans->cfg->base_params->num_of_queues; cnt++) { + for (cnt = 0; + cnt < trans->cfg->trans.base_params->num_of_queues; + cnt++) { txq = trans_pcie->txq[cnt]; pos += scnprintf(buf + pos, bufsz - pos, "hwq %.2d: read=%u write=%u use=%d stop=%d need_update=%d frozen=%d%s\n", @@ -2949,7 +2956,7 @@ static u32 iwl_trans_pcie_fh_regs_dump(struct iwl_trans *trans, (*data)->len = cpu_to_le32(fh_regs_len); val = (void *)(*data)->data; - if (!trans->cfg->gen2) + if (!trans->cfg->trans.gen2) for (i = FH_MEM_LOWER_BOUND; i < FH_MEM_UPPER_BOUND; i += sizeof(u32)) *val++ = cpu_to_le32(iwl_trans_pcie_read32(trans, i)); @@ -2997,7 +3004,7 @@ iwl_trans_pcie_dump_pointers(struct iwl_trans *trans, { u32 base, base_high, write_ptr, write_ptr_val, wrap_cnt; - if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { + if (trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_AX210) { base = DBGC_CUR_DBGBUF_BASE_ADDR_LSB; base_high = DBGC_CUR_DBGBUF_BASE_ADDR_MSB; write_ptr = DBGC_CUR_DBGBUF_STATUS; @@ -3017,7 +3024,7 @@ iwl_trans_pcie_dump_pointers(struct iwl_trans *trans, cpu_to_le32(iwl_read_prph(trans, wrap_cnt)); fw_mon_data->fw_mon_base_ptr = cpu_to_le32(iwl_read_prph(trans, base)); - if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { + if (trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_AX210) { fw_mon_data->fw_mon_base_high_ptr = cpu_to_le32(iwl_read_prph(trans, base_high)); write_ptr_val &= DBGC_CUR_DBGBUF_STATUS_OFFSET_MSK; @@ -3034,8 +3041,8 @@ iwl_trans_pcie_dump_monitor(struct iwl_trans *trans, if (trans->dbg.dest_tlv || (trans->dbg.num_blocks && - (trans->cfg->device_family == IWL_DEVICE_FAMILY_7000 || - trans->cfg->device_family >= IWL_DEVICE_FAMILY_AX210))) { + (trans->cfg->trans.device_family == IWL_DEVICE_FAMILY_7000 || + trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_AX210))) { struct iwl_fw_error_dump_fw_mon *fw_mon_data; (*data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_FW_MONITOR); @@ -3118,7 +3125,7 @@ static int iwl_trans_get_fw_monitor_len(struct iwl_trans *trans, u32 *len) trans->dbg.dest_tlv->end_shift; /* Make "end" point to the actual end */ - if (trans->cfg->device_family >= + if (trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_8000 || trans->dbg.dest_tlv->monitor_mode == MARBH_MODE) end += (1 << trans->dbg.dest_tlv->end_shift); @@ -3144,7 +3151,7 @@ static struct iwl_trans_dump_data u32 len, num_rbs = 0, monitor_len = 0; int i, ptr; bool dump_rbs = test_bit(STATUS_FW_ERROR, &trans->status) && - !trans->cfg->mq_rx_supported && + !trans->cfg->trans.mq_rx_supported && dump_mask & BIT(IWL_FW_ERROR_DUMP_RB); if (!dump_mask) @@ -3169,7 +3176,7 @@ static struct iwl_trans_dump_data /* FH registers */ if (dump_mask & BIT(IWL_FW_ERROR_DUMP_FH_REGS)) { - if (trans->cfg->gen2) + if (trans->cfg->trans.gen2) len += sizeof(*data) + (iwl_umac_prph(trans, FH_MEM_UPPER_BOUND_GEN2) - iwl_umac_prph(trans, FH_MEM_LOWER_BOUND_GEN2)); @@ -3193,7 +3200,7 @@ static struct iwl_trans_dump_data } /* Paged memory for gen2 HW */ - if (trans->cfg->gen2 && dump_mask & BIT(IWL_FW_ERROR_DUMP_PAGING)) + if (trans->cfg->trans.gen2 && dump_mask & BIT(IWL_FW_ERROR_DUMP_PAGING)) for (i = 0; i < trans->init_dram.paging_cnt; i++) len += sizeof(*data) + sizeof(struct iwl_fw_error_dump_paging) + @@ -3248,7 +3255,8 @@ static struct iwl_trans_dump_data len += iwl_trans_pcie_dump_rbs(trans, &data, num_rbs); /* Paged memory for gen2 HW */ - if (trans->cfg->gen2 && dump_mask & BIT(IWL_FW_ERROR_DUMP_PAGING)) { + if (trans->cfg->trans.gen2 && + dump_mask & BIT(IWL_FW_ERROR_DUMP_PAGING)) { for (i = 0; i < trans->init_dram.paging_cnt; i++) { struct iwl_fw_error_dump_paging *paging; u32 page_len = trans->init_dram.paging[i].size; @@ -3374,7 +3382,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, if (ret) return ERR_PTR(ret); - if (cfg->gen2) + if (cfg->trans.gen2) trans = iwl_trans_alloc(sizeof(struct iwl_trans_pcie), &pdev->dev, cfg, &trans_ops_pcie_gen2); else @@ -3398,7 +3406,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, } trans_pcie->debug_rfkill = -1; - if (!cfg->base_params->pcie_l1_allowed) { + if (!cfg->trans.base_params->pcie_l1_allowed) { /* * W/A - seems to solve weird behavior. We need to remove this * if we don't want to stay in L1 all the time. This wastes a @@ -3411,7 +3419,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, trans_pcie->def_rx_queue = 0; - if (cfg->use_tfh) { + if (cfg->trans.use_tfh) { addr_size = 64; trans_pcie->max_tbs = IWL_TFH_NUM_TBS; trans_pcie->tfd_size = sizeof(struct iwl_tfh_tfd); @@ -3473,7 +3481,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, * "dash" value). To keep hw_rev backwards compatible - we'll store it * in the old format. */ - if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_8000) { + if (trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_8000) { unsigned long flags; trans->hw_rev = (trans->hw_rev & 0xfff0) | @@ -3489,7 +3497,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, * in-order to recognize C step driver should read chip version * id located at the AUX bus MISC address space. */ - ret = iwl_finish_nic_init(trans); + ret = iwl_finish_nic_init(trans, &trans->cfg->trans); if (ret) goto out_no_pci; @@ -3516,7 +3524,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, #if IS_ENABLED(CONFIG_IWLMVM) trans->hw_rf_id = iwl_read32(trans, CSR_HW_RF_ID); - if (cfg == &iwlax210_2ax_cfg_so_hr_a0) { + if (trans->cfg == &iwlax210_2ax_cfg_so_hr_a0) { if (trans->hw_rev == CSR_HW_REV_TYPE_TY) { trans->cfg = &iwlax210_2ax_cfg_ty_gf_a0; } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) == diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c index 70a15364190c..3fb688826302 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c @@ -113,7 +113,7 @@ void iwl_pcie_gen2_update_byte_tbl(struct iwl_trans_pcie *trans_pcie, */ num_fetch_chunks = DIV_ROUND_UP(filled_tfd_size, 64) - 1; - if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) { + if (trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_22560) { /* Starting from 22560, the HW expects bytes */ WARN_ON(trans_pcie->bc_table_dword); WARN_ON(len > 0x3FFF); @@ -547,7 +547,7 @@ struct iwl_tfh_tfd *iwl_pcie_gen2_build_tfd(struct iwl_trans *trans, memset(tfd, 0, sizeof(*tfd)); - if (trans->cfg->device_family < IWL_DEVICE_FAMILY_22560) + if (trans->cfg->trans.device_family < IWL_DEVICE_FAMILY_22560) len = sizeof(struct iwl_tx_cmd_gen2); else len = sizeof(struct iwl_tx_cmd_gen3); @@ -629,7 +629,7 @@ int iwl_trans_pcie_gen2_tx(struct iwl_trans *trans, struct sk_buff *skb, return -1; } - if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) { + if (trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_22560) { struct iwl_tx_cmd_gen3 *tx_cmd_gen3 = (void *)dev_cmd->payload; @@ -1129,7 +1129,7 @@ int iwl_trans_pcie_dyn_txq_alloc_dma(struct iwl_trans *trans, if (!txq) return -ENOMEM; ret = iwl_pcie_alloc_dma_ptr(trans, &txq->bc_tbl, - (trans->cfg->device_family >= + (trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_22560) ? sizeof(struct iwl_gen3_bc_tbl) : sizeof(struct iwlagn_scd_bc_tbl)); @@ -1193,7 +1193,7 @@ int iwl_trans_pcie_txq_alloc_response(struct iwl_trans *trans, txq->id = qid; trans_pcie->txq[qid] = txq; - wr_ptr &= (trans->cfg->base_params->max_tfd_queue_size - 1); + wr_ptr &= (trans->cfg->trans.base_params->max_tfd_queue_size - 1); /* Place first TFD at index corresponding to start sequence number */ txq->read_ptr = wr_ptr; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c index 8b7b918e71ad..774c8bfe8450 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c @@ -113,17 +113,17 @@ int iwl_queue_space(struct iwl_trans *trans, const struct iwl_txq *q) * If q->n_window is smaller than max_tfd_queue_size, there is no need * to reserve any queue entries for this purpose. */ - if (q->n_window < trans->cfg->base_params->max_tfd_queue_size) + if (q->n_window < trans->cfg->trans.base_params->max_tfd_queue_size) max = q->n_window; else - max = trans->cfg->base_params->max_tfd_queue_size - 1; + max = trans->cfg->trans.base_params->max_tfd_queue_size - 1; /* * max_tfd_queue_size is a power of 2, so the following is equivalent to * modulo by max_tfd_queue_size and is well defined. */ used = (q->write_ptr - q->read_ptr) & - (trans->cfg->base_params->max_tfd_queue_size - 1); + (trans->cfg->trans.base_params->max_tfd_queue_size - 1); if (WARN_ON(used > max)) return 0; @@ -292,7 +292,7 @@ static void iwl_pcie_txq_inc_wr_ptr(struct iwl_trans *trans, * 2. NIC is woken up for CMD regardless of shadow outside this function * 3. there is a chance that the NIC is asleep */ - if (!trans->cfg->base_params->shadow_reg_enable && + if (!trans->cfg->trans.base_params->shadow_reg_enable && txq_id != trans_pcie->cmd_queue && test_bit(STATUS_TPOWER_PMI, &trans->status)) { /* @@ -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->cfg->csr->flag_mac_access_req)); + BIT(trans->cfg->trans.csr->flag_mac_access_req)); txq->need_update = true; return; } @@ -327,7 +327,7 @@ void iwl_pcie_txq_check_wrptrs(struct iwl_trans *trans) struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); int i; - for (i = 0; i < trans->cfg->base_params->num_of_queues; i++) { + for (i = 0; i < trans->cfg->trans.base_params->num_of_queues; i++) { struct iwl_txq *txq = trans_pcie->txq[i]; if (!test_bit(i, trans_pcie->queue_used)) @@ -346,7 +346,7 @@ static inline dma_addr_t iwl_pcie_tfd_tb_get_addr(struct iwl_trans *trans, void *_tfd, u8 idx) { - if (trans->cfg->use_tfh) { + if (trans->cfg->trans.use_tfh) { struct iwl_tfh_tfd *tfd = _tfd; struct iwl_tfh_tb *tb = &tfd->tbs[idx]; @@ -389,7 +389,7 @@ static inline void iwl_pcie_tfd_set_tb(struct iwl_trans *trans, void *tfd, static inline u8 iwl_pcie_tfd_get_num_tbs(struct iwl_trans *trans, void *_tfd) { - if (trans->cfg->use_tfh) { + if (trans->cfg->trans.use_tfh) { struct iwl_tfh_tfd *tfd = _tfd; return le16_to_cpu(tfd->num_tbs) & 0x1f; @@ -436,7 +436,7 @@ static void iwl_pcie_tfd_unmap(struct iwl_trans *trans, meta->tbs = 0; - if (trans->cfg->use_tfh) { + if (trans->cfg->trans.use_tfh) { struct iwl_tfh_tfd *tfd_fh = (void *)tfd; tfd_fh->num_tbs = 0; @@ -524,14 +524,14 @@ int iwl_pcie_txq_alloc(struct iwl_trans *trans, struct iwl_txq *txq, { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); size_t tfd_sz = trans_pcie->tfd_size * - trans->cfg->base_params->max_tfd_queue_size; + trans->cfg->trans.base_params->max_tfd_queue_size; size_t tb0_buf_sz; int i; if (WARN_ON(txq->entries || txq->tfds)) return -EINVAL; - if (trans->cfg->use_tfh) + if (trans->cfg->trans.use_tfh) tfd_sz = trans_pcie->tfd_size * slots_num; timer_setup(&txq->stuck_timer, iwl_pcie_txq_stuck_timer, 0); @@ -590,7 +590,8 @@ int iwl_pcie_txq_init(struct iwl_trans *trans, struct iwl_txq *txq, int slots_num, bool cmd_queue) { int ret; - u32 tfd_queue_max_size = trans->cfg->base_params->max_tfd_queue_size; + u32 tfd_queue_max_size = + trans->cfg->trans.base_params->max_tfd_queue_size; txq->need_update = false; @@ -638,14 +639,14 @@ static void iwl_pcie_clear_cmd_in_flight(struct iwl_trans *trans) lockdep_assert_held(&trans_pcie->reg_lock); - if (!trans->cfg->base_params->apmg_wake_up_wa) + if (!trans->cfg->trans.base_params->apmg_wake_up_wa) return; if (WARN_ON(!trans_pcie->cmd_hold_nic_awake)) return; trans_pcie->cmd_hold_nic_awake = false; __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL, - BIT(trans->cfg->csr->flag_mac_access_req)); + BIT(trans->cfg->trans.csr->flag_mac_access_req)); } /* @@ -725,7 +726,7 @@ static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id) if (txq->tfds) { dma_free_coherent(dev, trans_pcie->tfd_size * - trans->cfg->base_params->max_tfd_queue_size, + trans->cfg->trans.base_params->max_tfd_queue_size, txq->tfds, txq->dma_addr); txq->dma_addr = 0; txq->tfds = NULL; @@ -747,7 +748,7 @@ static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id) void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - int nq = trans->cfg->base_params->num_of_queues; + int nq = trans->cfg->trans.base_params->num_of_queues; int chan; u32 reg_val; int clear_dwords = (SCD_TRANS_TBL_OFFSET_QUEUE(nq) - @@ -774,7 +775,7 @@ void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr) /* The chain extension of the SCD doesn't work well. This feature is * enabled by default by the HW, so we need to disable it manually. */ - if (trans->cfg->base_params->scd_chain_ext_wa) + if (trans->cfg->trans.base_params->scd_chain_ext_wa) iwl_write_prph(trans, SCD_CHAINEXT_EN, 0); iwl_trans_ac_txq_enable(trans, trans_pcie->cmd_queue, @@ -796,7 +797,7 @@ void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr) reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN); /* Enable L1-Active */ - if (trans->cfg->device_family < IWL_DEVICE_FAMILY_8000) + if (trans->cfg->trans.device_family < IWL_DEVICE_FAMILY_8000) iwl_clear_bits_prph(trans, APMG_PCIDEV_STT_REG, APMG_PCIDEV_STT_VAL_L1_ACT_DIS); } @@ -810,13 +811,13 @@ void iwl_trans_pcie_tx_reset(struct iwl_trans *trans) * we should never get here in gen2 trans mode return early to avoid * having invalid accesses */ - if (WARN_ON_ONCE(trans->cfg->gen2)) + if (WARN_ON_ONCE(trans->cfg->trans.gen2)) return; - for (txq_id = 0; txq_id < trans->cfg->base_params->num_of_queues; + for (txq_id = 0; txq_id < trans->cfg->trans.base_params->num_of_queues; txq_id++) { struct iwl_txq *txq = trans_pcie->txq[txq_id]; - if (trans->cfg->use_tfh) + if (trans->cfg->trans.use_tfh) iwl_write_direct64(trans, FH_MEM_CBBC_QUEUE(trans, txq_id), txq->dma_addr); @@ -899,7 +900,7 @@ int iwl_pcie_tx_stop(struct iwl_trans *trans) return 0; /* Unmap DMA from host system and free skb's */ - for (txq_id = 0; txq_id < trans->cfg->base_params->num_of_queues; + for (txq_id = 0; txq_id < trans->cfg->trans.base_params->num_of_queues; txq_id++) iwl_pcie_txq_unmap(trans, txq_id); @@ -921,7 +922,7 @@ void iwl_pcie_tx_free(struct iwl_trans *trans) /* Tx queues */ if (trans_pcie->txq_memory) { for (txq_id = 0; - txq_id < trans->cfg->base_params->num_of_queues; + txq_id < trans->cfg->trans.base_params->num_of_queues; txq_id++) { iwl_pcie_txq_free(trans, txq_id); trans_pcie->txq[txq_id] = NULL; @@ -945,9 +946,10 @@ static int iwl_pcie_tx_alloc(struct iwl_trans *trans) int ret; int txq_id, slots_num; struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - u16 bc_tbls_size = trans->cfg->base_params->num_of_queues; + u16 bc_tbls_size = trans->cfg->trans.base_params->num_of_queues; - bc_tbls_size *= (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) ? + bc_tbls_size *= (trans->cfg->trans.device_family >= + IWL_DEVICE_FAMILY_22560) ? sizeof(struct iwl_gen3_bc_tbl) : sizeof(struct iwlagn_scd_bc_tbl); @@ -972,8 +974,9 @@ static int iwl_pcie_tx_alloc(struct iwl_trans *trans) goto error; } - trans_pcie->txq_memory = kcalloc(trans->cfg->base_params->num_of_queues, - sizeof(struct iwl_txq), GFP_KERNEL); + trans_pcie->txq_memory = + kcalloc(trans->cfg->trans.base_params->num_of_queues, + sizeof(struct iwl_txq), GFP_KERNEL); if (!trans_pcie->txq_memory) { IWL_ERR(trans, "Not enough memory for txq\n"); ret = -ENOMEM; @@ -981,7 +984,7 @@ static int iwl_pcie_tx_alloc(struct iwl_trans *trans) } /* Alloc and init all Tx queues, including the command queue (#4/#9) */ - for (txq_id = 0; txq_id < trans->cfg->base_params->num_of_queues; + for (txq_id = 0; txq_id < trans->cfg->trans.base_params->num_of_queues; txq_id++) { bool cmd_queue = (txq_id == trans_pcie->cmd_queue); @@ -1035,7 +1038,7 @@ int iwl_pcie_tx_init(struct iwl_trans *trans) spin_unlock(&trans_pcie->irq_lock); /* Alloc and init all Tx queues, including the command queue (#4/#9) */ - for (txq_id = 0; txq_id < trans->cfg->base_params->num_of_queues; + for (txq_id = 0; txq_id < trans->cfg->trans.base_params->num_of_queues; txq_id++) { bool cmd_queue = (txq_id == trans_pcie->cmd_queue); @@ -1063,7 +1066,7 @@ int iwl_pcie_tx_init(struct iwl_trans *trans) } iwl_set_bits_prph(trans, SCD_GP_CTRL, SCD_GP_CTRL_AUTO_ACTIVE_MODE); - if (trans->cfg->base_params->num_of_queues > 20) + if (trans->cfg->trans.base_params->num_of_queues > 20) iwl_set_bits_prph(trans, SCD_GP_CTRL, SCD_GP_CTRL_ENABLE_31_QUEUES); @@ -1135,7 +1138,7 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn, IWL_ERR(trans, "%s: Read index for txq id (%d), last_to_free %d is out of range [0-%d] %d %d.\n", __func__, txq_id, last_to_free, - trans->cfg->base_params->max_tfd_queue_size, + trans->cfg->trans.base_params->max_tfd_queue_size, txq->write_ptr, txq->read_ptr); goto out; } @@ -1158,7 +1161,7 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn, txq->entries[read_ptr].skb = NULL; - if (!trans->cfg->use_tfh) + if (!trans->cfg->trans.use_tfh) iwl_pcie_txq_inval_byte_cnt_tbl(trans, txq); iwl_pcie_txq_free_tfd(trans, txq); @@ -1250,19 +1253,19 @@ static int iwl_pcie_set_cmd_in_flight(struct iwl_trans *trans, * returned. This needs to be done only on NICs that have * apmg_wake_up_wa set. */ - if (cfg->base_params->apmg_wake_up_wa && + if (cfg->trans.base_params->apmg_wake_up_wa && !trans_pcie->cmd_hold_nic_awake) { __iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL, - BIT(cfg->csr->flag_mac_access_req)); + BIT(cfg->trans.csr->flag_mac_access_req)); ret = iwl_poll_bit(trans, CSR_GP_CNTRL, - BIT(cfg->csr->flag_val_mac_access_en), - (BIT(cfg->csr->flag_mac_clock_ready) | + BIT(cfg->trans.csr->flag_val_mac_access_en), + (BIT(cfg->trans.csr->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(cfg->csr->flag_mac_access_req)); + BIT(cfg->trans.csr->flag_mac_access_req)); IWL_ERR(trans, "Failed to wake NIC for hcmd\n"); return -EIO; } @@ -1292,12 +1295,12 @@ void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx) idx = iwl_pcie_get_cmd_index(txq, idx); r = iwl_pcie_get_cmd_index(txq, txq->read_ptr); - if (idx >= trans->cfg->base_params->max_tfd_queue_size || + if (idx >= trans->cfg->trans.base_params->max_tfd_queue_size || (!iwl_queue_used(txq, idx))) { WARN_ONCE(test_bit(txq_id, trans_pcie->queue_used), "%s: Read index for DMA queue txq id (%d), index %d is out of range [0-%d] %d %d.\n", __func__, txq_id, idx, - trans->cfg->base_params->max_tfd_queue_size, + trans->cfg->trans.base_params->max_tfd_queue_size, txq->write_ptr, txq->read_ptr); return; } @@ -1411,7 +1414,7 @@ bool iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn, * this sad hardware issue. * This bug has been fixed on devices 9000 and up. */ - scd_bug = !trans->cfg->mq_rx_supported && + scd_bug = !trans->cfg->trans.mq_rx_supported && !((ssn - txq->write_ptr) & 0x3f) && (ssn != txq->write_ptr); if (scd_bug) From 91eff3f8200599afc9b98b8e47cdfed824c84b00 Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Thu, 2 Aug 2018 16:16:27 +0300 Subject: [PATCH 61/80] iwlwifi: pcie: use the cfg we passed to iwl_trans_pcie_alloc() Instead of using iwl_trans->cfg in iwl_trans_pcie_alloc(), use the local argument that we received. This will allow us to not to set the cfg during iwl_trans_alloc() so it can be decided later. Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index db75a79aa8a4..a1164a0a384f 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -3481,7 +3481,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, * "dash" value). To keep hw_rev backwards compatible - we'll store it * in the old format. */ - if (trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_8000) { + if (cfg->trans.device_family >= IWL_DEVICE_FAMILY_8000) { unsigned long flags; trans->hw_rev = (trans->hw_rev & 0xfff0) | @@ -3497,7 +3497,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, * in-order to recognize C step driver should read chip version * id located at the AUX bus MISC address space. */ - ret = iwl_finish_nic_init(trans, &trans->cfg->trans); + ret = iwl_finish_nic_init(trans, &cfg->trans); if (ret) goto out_no_pci; @@ -3524,7 +3524,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, #if IS_ENABLED(CONFIG_IWLMVM) trans->hw_rf_id = iwl_read32(trans, CSR_HW_RF_ID); - if (trans->cfg == &iwlax210_2ax_cfg_so_hr_a0) { + if (cfg == &iwlax210_2ax_cfg_so_hr_a0) { if (trans->hw_rev == CSR_HW_REV_TYPE_TY) { trans->cfg = &iwlax210_2ax_cfg_ty_gf_a0; } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) == From 809805a820c6445f7a701ded24fdc6bbc841d1e4 Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Thu, 2 Aug 2018 17:08:40 +0300 Subject: [PATCH 62/80] iwlwifi: pcie: move some cfg mangling from trans_pcie_alloc to probe There were a couple of special handling to find the correct cfg inside iwl_trans_pcie_alloc(). Move them to iwl_pci_probe() so they're together with the rest of the decisions. Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 110 ++++++++++++------ .../net/wireless/intel/iwlwifi/pcie/trans.c | 63 ---------- 2 files changed, 75 insertions(+), 98 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index 08990694dd0e..d62d1ef01855 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -72,6 +72,7 @@ #include "iwl-trans.h" #include "iwl-drv.h" +#include "iwl-prph.h" #include "internal.h" #define IWL_PCI_DEVICE(dev, subdev, cfg) \ @@ -1017,29 +1018,70 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) else if (cfg == &iwl7265_n_cfg) cfg_7265d = &iwl7265d_n_cfg; if (cfg_7265d && - (iwl_trans->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_7265D) { + (iwl_trans->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_7265D) cfg = cfg_7265d; - iwl_trans->cfg = cfg_7265d; - } - if (iwl_trans->cfg->trans.rf_id && cfg == &iwl22000_2ac_cfg_hr_cdb && - iwl_trans->hw_rev != CSR_HW_REV_TYPE_HR_CDB) { - u32 rf_id_chp = CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id); - u32 jf_chp_id = CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_JF); - u32 hr_chp_id = CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR); + iwl_trans->hw_rf_id = iwl_read32(iwl_trans, CSR_HW_RF_ID); - if (rf_id_chp == jf_chp_id) { - if (iwl_trans->hw_rev == CSR_HW_REV_TYPE_QNJ) - cfg = &iwl9560_2ac_cfg_qnj_jf_b0; - else - cfg = &iwl22000_2ac_cfg_jf; - } else if (rf_id_chp == hr_chp_id) { - if (iwl_trans->hw_rev == CSR_HW_REV_TYPE_QNJ) - cfg = &iwl22000_2ax_cfg_qnj_hr_a0; - else - cfg = &iwl22000_2ac_cfg_hr; + 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; + } 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; + } 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; + } 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; + } + } else if (cfg == &iwl_ax101_cfg_qu_hr) { + 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_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; + } 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; + } 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; + } 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"); + return -EINVAL; + } else { + IWL_ERR(iwl_trans, "Unrecognized RF ID 0x%08x\n", + CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id)); + return -EINVAL; + } + } 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_ax200_cfg_cc && + cfg != &killer1650x_2ax_cfg && + cfg != &killer1650w_2ax_cfg && + cfg != &iwl_ax201_cfg_quz_hr) || + iwl_trans->hw_rev == CSR_HW_REV_TYPE_QNJ_B0)) { + u32 hw_status; + + 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; + 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; } - iwl_trans->cfg = cfg; } /* @@ -1049,22 +1091,18 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) * thing to do to support Qu C-step. */ if (iwl_trans->hw_rev == CSR_HW_REV_TYPE_QU_C0) { - if (iwl_trans->cfg == &iwl_ax101_cfg_qu_hr) - iwl_trans->cfg = &iwl_ax101_cfg_qu_c0_hr_b0; - else if (iwl_trans->cfg == &iwl_ax201_cfg_qu_hr) - iwl_trans->cfg = &iwl_ax201_cfg_qu_c0_hr_b0; - else if (iwl_trans->cfg == &iwl9461_2ac_cfg_qu_b0_jf_b0) - iwl_trans->cfg = &iwl9461_2ac_cfg_qu_c0_jf_b0; - else if (iwl_trans->cfg == &iwl9462_2ac_cfg_qu_b0_jf_b0) - iwl_trans->cfg = &iwl9462_2ac_cfg_qu_c0_jf_b0; - else if (iwl_trans->cfg == &iwl9560_2ac_cfg_qu_b0_jf_b0) - iwl_trans->cfg = &iwl9560_2ac_cfg_qu_c0_jf_b0; - else if (iwl_trans->cfg == &iwl9560_2ac_160_cfg_qu_b0_jf_b0) - iwl_trans->cfg = &iwl9560_2ac_160_cfg_qu_c0_jf_b0; - else if (iwl_trans->cfg == &killer1650s_2ax_cfg_qu_b0_hr_b0) - iwl_trans->cfg = &killer1650s_2ax_cfg_qu_c0_hr_b0; - else if (iwl_trans->cfg == &killer1650i_2ax_cfg_qu_b0_hr_b0) - iwl_trans->cfg = &killer1650i_2ax_cfg_qu_c0_hr_b0; + if (cfg == &iwl_ax101_cfg_qu_hr) + cfg = &iwl_ax101_cfg_qu_c0_hr_b0; + else if (cfg == &iwl_ax201_cfg_qu_hr) + 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; + else if (cfg == &iwl9462_2ac_cfg_qu_b0_jf_b0) + 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; + else if (cfg == &iwl9560_2ac_160_cfg_qu_b0_jf_b0) + cfg = &iwl9560_2ac_160_cfg_qu_c0_jf_b0; } /* same thing for QuZ... */ @@ -1084,6 +1122,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } #endif + /* now set the real cfg we decided to use */ + iwl_trans->cfg = cfg; pci_set_drvdata(pdev, iwl_trans); iwl_trans->drv = iwl_drv_start(iwl_trans); diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index a1164a0a384f..a1863b9bf1f6 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -3521,69 +3521,6 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, IWL_DEBUG_INFO(trans, "HW REV: 0x%0x\n", trans->hw_rev); -#if IS_ENABLED(CONFIG_IWLMVM) - trans->hw_rf_id = iwl_read32(trans, CSR_HW_RF_ID); - - if (cfg == &iwlax210_2ax_cfg_so_hr_a0) { - if (trans->hw_rev == CSR_HW_REV_TYPE_TY) { - trans->cfg = &iwlax210_2ax_cfg_ty_gf_a0; - } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) == - CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_JF)) { - trans->cfg = &iwlax210_2ax_cfg_so_jf_a0; - } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) == - CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_GF)) { - trans->cfg = &iwlax211_2ax_cfg_so_gf_a0; - } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) == - CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_GF4)) { - trans->cfg = &iwlax411_2ax_cfg_so_gf4_a0; - } - } else if (cfg == &iwl_ax101_cfg_qu_hr) { - if ((CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) == - CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR) && - trans->hw_rev == CSR_HW_REV_TYPE_QNJ_B0) || - (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) == - CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR1))) { - trans->cfg = &iwl22000_2ax_cfg_qnj_hr_b0; - } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) == - CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR)) { - trans->cfg = &iwl_ax101_cfg_qu_hr; - } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) == - CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_JF)) { - trans->cfg = &iwl22000_2ax_cfg_jf; - } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) == - CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HRCDB)) { - IWL_ERR(trans, "RF ID HRCDB is not supported\n"); - ret = -EINVAL; - goto out_no_pci; - } else { - IWL_ERR(trans, "Unrecognized RF ID 0x%08x\n", - CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id)); - ret = -EINVAL; - goto out_no_pci; - } - } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) == - CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR) && - trans->hw_rev == CSR_HW_REV_TYPE_QNJ_B0) { - u32 hw_status; - - hw_status = iwl_read_prph(trans, UMAG_GEN_HW_STATUS); - if (CSR_HW_RF_STEP(trans->hw_rf_id) == SILICON_B_STEP) - /* - * b step fw is the same for physical card and fpga - */ - trans->cfg = &iwl22000_2ax_cfg_qnj_hr_b0; - else if ((hw_status & UMAG_GEN_HW_IS_FPGA) && - CSR_HW_RF_STEP(trans->hw_rf_id) == SILICON_A_STEP) { - trans->cfg = &iwl22000_2ax_cfg_qnj_hr_a0_f0; - } else { - /* - * a step no FPGA - */ - trans->cfg = &iwl22000_2ac_cfg_hr; - } - } -#endif - iwl_pcie_set_interrupt_capa(pdev, trans); trans->hw_id = (pdev->device << 16) + pdev->subsystem_device; snprintf(trans->hw_id_str, sizeof(trans->hw_id_str), From 0c18714a0d32142eb0fa1e41b49eefb5811fcd19 Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Thu, 2 Aug 2018 16:24:53 +0300 Subject: [PATCH 63/80] iwlwifi: pcie: set iwl_trans->cfg later in the probe function Instead of setting the cfg to iwl_trans already during allocation, set it only later when we have had the time to decide which cfg to use. This is part of the effort to be able to decide the cfg based on HW revision and RF ID after iwl_trans_alloc() has been called. For now, since we still have a bunch of code checking the HW revision and the RF ID, we set iwl_trans->cfg early, even before we decided the real cfg to use. We only use the trans configuration at this point, so this is fine for now. In the future, the trans configuration will be completely independent from the rest of the config structure, so we'll be able to avoid this. Additionally, we can't access the PRPH registers in iwl_trans_alloc() anymore, so move the HW REV C-step check for family 8000 code later to the probe function as well. This step is probably not necessary, but if that's the case it should be removed separately later on. Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/iwl-trans.c | 2 -- .../net/wireless/intel/iwlwifi/iwl-trans.h | 1 - drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 28 ++++++++++++++++ .../net/wireless/intel/iwlwifi/pcie/trans.c | 33 +++++-------------- 4 files changed, 37 insertions(+), 27 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.c b/drivers/net/wireless/intel/iwlwifi/iwl-trans.c index d47ba334c7ac..28bdc9a9617e 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.c @@ -66,7 +66,6 @@ struct iwl_trans *iwl_trans_alloc(unsigned int priv_size, struct device *dev, - const struct iwl_cfg *cfg, const struct iwl_trans_ops *ops) { struct iwl_trans *trans; @@ -84,7 +83,6 @@ struct iwl_trans *iwl_trans_alloc(unsigned int priv_size, #endif trans->dev = dev; - trans->cfg = cfg; trans->ops = ops; trans->num_rx_queues = 1; diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h index 09ed0dd163eb..1b9bf9f94367 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h @@ -1240,7 +1240,6 @@ static inline bool iwl_trans_dbg_ini_valid(struct iwl_trans *trans) *****************************************************/ struct iwl_trans *iwl_trans_alloc(unsigned int priv_size, struct device *dev, - const struct iwl_cfg *cfg, const struct iwl_trans_ops *ops); void iwl_trans_free(struct iwl_trans *trans); diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index d62d1ef01855..c64a40edd75d 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -994,6 +994,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; + unsigned long flags; int ret; if (WARN_ONCE(!cfg->trans.csr, "CSR addresses aren't configured\n")) @@ -1023,6 +1024,18 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) iwl_trans->hw_rf_id = iwl_read32(iwl_trans, CSR_HW_RF_ID); + /* + * We can already set the cfg to iwl_trans here, because the + * only part we use at this point is the cfg_trans + * information. Once we decide the real cfg, we set it again + * (happens later in this function). TODO: this is only + * temporary, while we're sorting out this whole thing, but in + * the future it won't be necessary, because we will separate + * the trans configuration entirely from the rest of the + * config struct. + */ + iwl_trans->cfg = cfg; + 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; @@ -1125,6 +1138,21 @@ 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.device_family >= IWL_DEVICE_FAMILY_8000 && + iwl_trans_grab_nic_access(iwl_trans, &flags)) { + u32 hw_step; + + hw_step = iwl_read_umac_prph_no_grab(iwl_trans, WFPM_CTRL_REG); + hw_step |= ENABLE_WFPM; + iwl_write_umac_prph_no_grab(iwl_trans, WFPM_CTRL_REG, hw_step); + hw_step = iwl_read_prph_no_grab(iwl_trans, CNVI_AUX_MISC_CHIP); + hw_step = (hw_step >> HW_STEP_LOCATION_BITS) & 0xF; + if (hw_step == 0x3) + iwl_trans->hw_rev = (iwl_trans->hw_rev & 0xFFFFFFF3) | + (SILICON_C_STEP << 2); + iwl_trans_release_nic_access(iwl_trans, &flags); + } + pci_set_drvdata(pdev, iwl_trans); iwl_trans->drv = iwl_drv_start(iwl_trans); diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index a1863b9bf1f6..c602e4914424 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -1578,14 +1578,16 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans, return 0; } -static void iwl_pcie_set_interrupt_capa(struct pci_dev *pdev, - struct iwl_trans *trans) +static void +iwl_pcie_set_interrupt_capa(struct pci_dev *pdev, + struct iwl_trans *trans, + const struct iwl_cfg_trans_params *cfg_trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); int max_irqs, num_irqs, i, ret; u16 pci_cmd; - if (!trans->cfg->trans.mq_rx_supported) + if (!cfg_trans->mq_rx_supported) goto enable_msi; max_irqs = min_t(u32, num_online_cpus() + 2, IWL_MAX_RX_HW_QUEUES); @@ -3384,10 +3386,11 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, if (cfg->trans.gen2) trans = iwl_trans_alloc(sizeof(struct iwl_trans_pcie), - &pdev->dev, cfg, &trans_ops_pcie_gen2); + &pdev->dev, &trans_ops_pcie_gen2); else trans = iwl_trans_alloc(sizeof(struct iwl_trans_pcie), - &pdev->dev, cfg, &trans_ops_pcie); + &pdev->dev, &trans_ops_pcie); + if (!trans) return ERR_PTR(-ENOMEM); @@ -3482,8 +3485,6 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, * in the old format. */ if (cfg->trans.device_family >= IWL_DEVICE_FAMILY_8000) { - unsigned long flags; - trans->hw_rev = (trans->hw_rev & 0xfff0) | (CSR_HW_REV_STEP(trans->hw_rev << 2) << 2); @@ -3501,27 +3502,11 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, if (ret) goto out_no_pci; - if (iwl_trans_grab_nic_access(trans, &flags)) { - u32 hw_step; - - hw_step = iwl_read_umac_prph_no_grab(trans, - WFPM_CTRL_REG); - hw_step |= ENABLE_WFPM; - iwl_write_umac_prph_no_grab(trans, WFPM_CTRL_REG, - hw_step); - hw_step = iwl_read_prph_no_grab(trans, - CNVI_AUX_MISC_CHIP); - hw_step = (hw_step >> HW_STEP_LOCATION_BITS) & 0xF; - if (hw_step == 0x3) - trans->hw_rev = (trans->hw_rev & 0xFFFFFFF3) | - (SILICON_C_STEP << 2); - iwl_trans_release_nic_access(trans, &flags); - } } IWL_DEBUG_INFO(trans, "HW REV: 0x%0x\n", trans->hw_rev); - iwl_pcie_set_interrupt_capa(pdev, trans); + iwl_pcie_set_interrupt_capa(pdev, trans, &cfg->trans); trans->hw_id = (pdev->device << 16) + pdev->subsystem_device; snprintf(trans->hw_id_str, sizeof(trans->hw_id_str), "PCI ID: 0x%04X:0x%04X", pdev->device, pdev->subsystem_device); From 7e8258c09f56e3285ffffa8d894280eb1f1b927f Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Fri, 3 Aug 2018 13:24:18 +0300 Subject: [PATCH 64/80] iwlwifi: pass the iwl_config_trans_params when needed Instead of accessing the iwl_config_trans_params from the cfg that is stored in the trans struct, pass this structure directly to functions that need it during trans_alloc. This will be useful to isolate the elements needed during allocation and pass them separately before the actual cfg struct is known. Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 2 +- .../net/wireless/intel/iwlwifi/pcie/internal.h | 7 ++++--- drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 16 ++++++++-------- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index c64a40edd75d..2010eaca5140 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -1000,7 +1000,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (WARN_ONCE(!cfg->trans.csr, "CSR addresses aren't configured\n")) return -EINVAL; - iwl_trans = iwl_trans_pcie_alloc(pdev, ent, cfg); + iwl_trans = iwl_trans_pcie_alloc(pdev, ent, &cfg->trans); if (IS_ERR(iwl_trans)) return PTR_ERR(iwl_trans); diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h index 53999ea7bb04..eba9660a2bc8 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h @@ -635,9 +635,10 @@ iwl_trans_pcie_get_trans(struct iwl_trans_pcie *trans_pcie) * Convention: trans API functions: iwl_trans_pcie_XXX * Other functions: iwl_pcie_XXX */ -struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, - const struct pci_device_id *ent, - const struct iwl_cfg *cfg); +struct iwl_trans +*iwl_trans_pcie_alloc(struct pci_dev *pdev, + const struct pci_device_id *ent, + const struct iwl_cfg_trans_params *cfg_trans); void iwl_trans_pcie_free(struct iwl_trans *trans); /***************************************************** diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index c602e4914424..e196e3b87574 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -3373,8 +3373,8 @@ static const struct iwl_trans_ops trans_ops_pcie_gen2 = { }; struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, - const struct pci_device_id *ent, - const struct iwl_cfg *cfg) + const struct pci_device_id *ent, + const struct iwl_cfg_trans_params *cfg_trans) { struct iwl_trans_pcie *trans_pcie; struct iwl_trans *trans; @@ -3384,7 +3384,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, if (ret) return ERR_PTR(ret); - if (cfg->trans.gen2) + if (cfg_trans->gen2) trans = iwl_trans_alloc(sizeof(struct iwl_trans_pcie), &pdev->dev, &trans_ops_pcie_gen2); else @@ -3409,7 +3409,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, } trans_pcie->debug_rfkill = -1; - if (!cfg->trans.base_params->pcie_l1_allowed) { + if (!cfg_trans->base_params->pcie_l1_allowed) { /* * W/A - seems to solve weird behavior. We need to remove this * if we don't want to stay in L1 all the time. This wastes a @@ -3422,7 +3422,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, trans_pcie->def_rx_queue = 0; - if (cfg->trans.use_tfh) { + if (cfg_trans->use_tfh) { addr_size = 64; trans_pcie->max_tbs = IWL_TFH_NUM_TBS; trans_pcie->tfd_size = sizeof(struct iwl_tfh_tfd); @@ -3484,7 +3484,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, * "dash" value). To keep hw_rev backwards compatible - we'll store it * in the old format. */ - if (cfg->trans.device_family >= IWL_DEVICE_FAMILY_8000) { + if (cfg_trans->device_family >= IWL_DEVICE_FAMILY_8000) { trans->hw_rev = (trans->hw_rev & 0xfff0) | (CSR_HW_REV_STEP(trans->hw_rev << 2) << 2); @@ -3498,7 +3498,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, * in-order to recognize C step driver should read chip version * id located at the AUX bus MISC address space. */ - ret = iwl_finish_nic_init(trans, &cfg->trans); + ret = iwl_finish_nic_init(trans, cfg_trans); if (ret) goto out_no_pci; @@ -3506,7 +3506,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, IWL_DEBUG_INFO(trans, "HW REV: 0x%0x\n", trans->hw_rev); - iwl_pcie_set_interrupt_capa(pdev, trans, &cfg->trans); + iwl_pcie_set_interrupt_capa(pdev, trans, cfg_trans); trans->hw_id = (pdev->device << 16) + pdev->subsystem_device; snprintf(trans->hw_id_str, sizeof(trans->hw_id_str), "PCI ID: 0x%04X:0x%04X", pdev->device, pdev->subsystem_device); From 286ca8eb4d0a9721046e75cc91d2a5338051c093 Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Fri, 12 Jul 2019 15:03:48 +0300 Subject: [PATCH 65/80] iwlwifi: add a pointer to the trans_cfg directly in trans Add a pointer to the iwl_trans structure and point it to the trans part of the cfg. This is the first step in disassociating the trans configuration from the rest of the configuration. Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 30 ++--- drivers/net/wireless/intel/iwlwifi/fw/dbg.h | 2 +- .../net/wireless/intel/iwlwifi/fw/paging.c | 2 +- drivers/net/wireless/intel/iwlwifi/fw/smem.c | 2 +- drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 10 +- .../wireless/intel/iwlwifi/iwl-eeprom-read.c | 8 +- drivers/net/wireless/intel/iwlwifi/iwl-fh.h | 2 +- drivers/net/wireless/intel/iwlwifi/iwl-io.c | 6 +- .../wireless/intel/iwlwifi/iwl-nvm-parse.c | 10 +- .../net/wireless/intel/iwlwifi/iwl-trans.h | 2 + drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 4 +- .../net/wireless/intel/iwlwifi/mvm/debugfs.c | 4 +- drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 6 +- .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 6 +- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 8 +- drivers/net/wireless/intel/iwlwifi/mvm/rs.c | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 10 +- drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 6 +- drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 4 +- .../net/wireless/intel/iwlwifi/mvm/utils.c | 2 +- .../intel/iwlwifi/pcie/ctxt-info-gen3.c | 2 +- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 15 +-- .../wireless/intel/iwlwifi/pcie/internal.h | 12 +- drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 54 ++++----- .../wireless/intel/iwlwifi/pcie/trans-gen2.c | 8 +- .../net/wireless/intel/iwlwifi/pcie/trans.c | 108 +++++++++--------- .../net/wireless/intel/iwlwifi/pcie/tx-gen2.c | 10 +- drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 68 +++++------ 29 files changed, 199 insertions(+), 206 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index ef5c75bbd0dd..310b85b508b3 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -243,7 +243,7 @@ static void iwl_fw_dump_rxf(struct iwl_fw_runtime *fwrt, /* Pull RXF2 */ iwl_fwrt_dump_rxf(fwrt, dump_data, cfg->rxfifo2_size, RXF_DIFF_FROM_PREV + - fwrt->trans->cfg->trans.umac_prph_offset, 1); + fwrt->trans->trans_cfg->umac_prph_offset, 1); /* Pull LMAC2 RXF1 */ if (fwrt->smem_cfg.num_lmacs > 1) iwl_fwrt_dump_rxf(fwrt, dump_data, @@ -684,10 +684,10 @@ static void iwl_fw_prph_handler(struct iwl_fw_runtime *fwrt, void *ptr, { u32 range_len; - if (fwrt->trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_AX210) { + if (fwrt->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { range_len = ARRAY_SIZE(iwl_prph_dump_addr_ax210); handler(fwrt, iwl_prph_dump_addr_ax210, range_len, ptr); - } else if (fwrt->trans->cfg->trans.device_family >= + } else if (fwrt->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22000) { range_len = ARRAY_SIZE(iwl_prph_dump_addr_22000); handler(fwrt, iwl_prph_dump_addr_22000, range_len, ptr); @@ -695,7 +695,7 @@ static void iwl_fw_prph_handler(struct iwl_fw_runtime *fwrt, void *ptr, range_len = ARRAY_SIZE(iwl_prph_dump_addr_comm); handler(fwrt, iwl_prph_dump_addr_comm, range_len, ptr); - if (fwrt->trans->cfg->trans.mq_rx_supported) { + if (fwrt->trans->trans_cfg->mq_rx_supported) { range_len = ARRAY_SIZE(iwl_prph_dump_addr_9000); handler(fwrt, iwl_prph_dump_addr_9000, range_len, ptr); } @@ -857,7 +857,7 @@ iwl_fw_error_dump_file(struct iwl_fw_runtime *fwrt, iwl_fw_prph_handler(fwrt, &prph_len, iwl_fw_get_prph_len); - if (fwrt->trans->cfg->trans.device_family == + if (fwrt->trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_7000 && iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_RADIO_REG)) radio_len = sizeof(*dump_data) + RADIO_REG_MAX_READ; @@ -1138,7 +1138,7 @@ static int iwl_dump_ini_paging_iter(struct iwl_fw_runtime *fwrt, struct iwl_fw_ini_error_dump_range *range; u32 page_size; - if (!fwrt->trans->cfg->trans.gen2) + if (!fwrt->trans->trans_cfg->gen2) return _iwl_dump_ini_paging_iter(fwrt, reg, range_ptr, idx); range = range_ptr; @@ -1444,7 +1444,7 @@ static void struct iwl_fw_ini_monitor_dump *mon_dump = (void *)data; u32 write_ptr_addr, write_ptr_msk, cycle_cnt_addr, cycle_cnt_msk; - switch (fwrt->trans->cfg->trans.device_family) { + switch (fwrt->trans->trans_cfg->device_family) { case IWL_DEVICE_FAMILY_9000: case IWL_DEVICE_FAMILY_22000: write_ptr_addr = MON_BUFF_WRPTR_VER2; @@ -1454,7 +1454,7 @@ static void break; default: IWL_ERR(fwrt, "Unsupported device family %d\n", - fwrt->trans->cfg->trans.device_family); + fwrt->trans->trans_cfg->device_family); return NULL; } @@ -1471,10 +1471,10 @@ static void struct iwl_fw_ini_monitor_dump *mon_dump = (void *)data; const struct iwl_cfg *cfg = fwrt->trans->cfg; - if (fwrt->trans->cfg->trans.device_family != IWL_DEVICE_FAMILY_9000 && - fwrt->trans->cfg->trans.device_family != IWL_DEVICE_FAMILY_22000) { + if (fwrt->trans->trans_cfg->device_family != IWL_DEVICE_FAMILY_9000 && + fwrt->trans->trans_cfg->device_family != IWL_DEVICE_FAMILY_22000) { IWL_ERR(fwrt, "Unsupported device family %d\n", - fwrt->trans->cfg->trans.device_family); + fwrt->trans->trans_cfg->device_family); return NULL; } @@ -1495,7 +1495,7 @@ static u32 iwl_dump_ini_mem_ranges(struct iwl_fw_runtime *fwrt, static u32 iwl_dump_ini_paging_ranges(struct iwl_fw_runtime *fwrt, struct iwl_fw_ini_region_cfg *reg) { - if (fwrt->trans->cfg->trans.gen2) + if (fwrt->trans->trans_cfg->gen2) return fwrt->trans->init_dram.paging_cnt; return fwrt->num_of_paging_blk; @@ -1543,7 +1543,7 @@ static u32 iwl_dump_ini_paging_get_size(struct iwl_fw_runtime *fwrt, u32 range_header_len = sizeof(struct iwl_fw_ini_error_dump_range); u32 size = sizeof(struct iwl_fw_ini_error_dump); - if (fwrt->trans->cfg->trans.gen2) { + if (fwrt->trans->trans_cfg->gen2) { for (i = 0; i < iwl_dump_ini_paging_ranges(fwrt, reg); i++) size += range_header_len + fwrt->trans->init_dram.paging[i].size; @@ -2472,7 +2472,7 @@ static int iwl_fw_dbg_suspend_resume_hcmd(struct iwl_trans *trans, bool suspend) static void iwl_fw_dbg_stop_recording(struct iwl_trans *trans, struct iwl_fw_dbg_params *params) { - if (trans->cfg->trans.device_family == IWL_DEVICE_FAMILY_7000) { + if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_7000) { iwl_set_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x100); return; } @@ -2496,7 +2496,7 @@ static int iwl_fw_dbg_restart_recording(struct iwl_trans *trans, if (!params) return -EIO; - if (trans->cfg->trans.device_family == IWL_DEVICE_FAMILY_7000) { + if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_7000) { iwl_clear_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x100); iwl_clear_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x1); iwl_set_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x1); diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h index 0c8da5e07854..b2445bef908c 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h @@ -302,7 +302,7 @@ static inline bool iwl_fw_dbg_is_d3_debug_enabled(struct iwl_fw_runtime *fwrt) static inline bool iwl_fw_dbg_is_paging_enabled(struct iwl_fw_runtime *fwrt) { return iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_PAGING) && - !fwrt->trans->cfg->trans.gen2 && + !fwrt->trans->trans_cfg->gen2 && fwrt->cur_fw_img < IWL_UCODE_TYPE_MAX && fwrt->fw->img[fwrt->cur_fw_img].paging_mem_size && fwrt->fw_paging_db[0].fw_paging_block; diff --git a/drivers/net/wireless/intel/iwlwifi/fw/paging.c b/drivers/net/wireless/intel/iwlwifi/fw/paging.c index 705eeff1a645..2bd76bd9dfa5 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/paging.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/paging.c @@ -322,7 +322,7 @@ int iwl_init_paging(struct iwl_fw_runtime *fwrt, enum iwl_ucode_type type) const struct fw_img *fw = &fwrt->fw->img[type]; int ret; - if (fwrt->trans->cfg->trans.gen2) + if (fwrt->trans->trans_cfg->gen2) return 0; /* diff --git a/drivers/net/wireless/intel/iwlwifi/fw/smem.c b/drivers/net/wireless/intel/iwlwifi/fw/smem.c index a88117d48ade..409b2dd854ac 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/smem.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/smem.c @@ -151,7 +151,7 @@ void iwl_get_shared_mem_conf(struct iwl_fw_runtime *fwrt) } pkt = cmd.resp_pkt; - if (fwrt->trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_22000) + if (fwrt->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22000) iwl_parse_shared_mem_22000(fwrt, pkt); else iwl_parse_shared_mem(fwrt, pkt); diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c index a204ecbdacaf..ff0519ea00a5 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c @@ -215,7 +215,7 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first) const struct iwl_cfg *cfg = drv->trans->cfg; char tag[8]; - if (drv->trans->cfg->trans.device_family == IWL_DEVICE_FAMILY_9000 && + if (drv->trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_9000 && (CSR_HW_REV_STEP(drv->trans->hw_rev) != SILICON_B_STEP && CSR_HW_REV_STEP(drv->trans->hw_rev) != SILICON_C_STEP)) { IWL_ERR(drv, @@ -1120,7 +1120,7 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, if (tlv_len != sizeof(*dbg_ptrs)) goto invalid_tlv_len; - if (drv->trans->cfg->trans.device_family < + if (drv->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_22000) break; drv->trans->dbg.umac_error_event_table = @@ -1136,7 +1136,7 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, if (tlv_len != sizeof(*dbg_ptrs)) goto invalid_tlv_len; - if (drv->trans->cfg->trans.device_family < + if (drv->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_22000) break; drv->trans->dbg.lmac_error_event_table[0] = @@ -1522,14 +1522,14 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) fw->init_evtlog_size = (pieces->init_evtlog_size - 16)/12; else fw->init_evtlog_size = - drv->trans->cfg->trans.base_params->max_event_log_size; + drv->trans->trans_cfg->base_params->max_event_log_size; fw->init_errlog_ptr = pieces->init_errlog_ptr; fw->inst_evtlog_ptr = pieces->inst_evtlog_ptr; if (pieces->inst_evtlog_size) fw->inst_evtlog_size = (pieces->inst_evtlog_size - 16)/12; else fw->inst_evtlog_size = - drv->trans->cfg->trans.base_params->max_event_log_size; + drv->trans->trans_cfg->base_params->max_event_log_size; fw->inst_errlog_ptr = pieces->inst_errlog_ptr; /* diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c index 88f38e4cf7ef..80bc2e44c7b1 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c @@ -207,7 +207,7 @@ static int iwl_init_otp_access(struct iwl_trans *trans) * CSR auto clock gate disable bit - * this is only applicable for HW with OTP shadow RAM */ - if (trans->cfg->trans.base_params->shadow_ram_support) + if (trans->trans_cfg->base_params->shadow_ram_support) iwl_set_bit(trans, CSR_DBG_LINK_PWR_MGMT_REG, CSR_RESET_LINK_PWR_MGMT_DISABLED); @@ -328,7 +328,7 @@ static int iwl_find_otp_image(struct iwl_trans *trans, } /* more in the link list, continue */ usedblocks++; - } while (usedblocks <= trans->cfg->trans.base_params->max_ll_items); + } while (usedblocks <= trans->trans_cfg->base_params->max_ll_items); /* OTP has no valid blocks */ IWL_DEBUG_EEPROM(trans->dev, "OTP has no valid blocks\n"); @@ -361,7 +361,7 @@ int iwl_read_eeprom(struct iwl_trans *trans, u8 **eeprom, size_t *eeprom_size) if (nvm_is_otp < 0) return nvm_is_otp; - sz = trans->cfg->trans.base_params->eeprom_size; + sz = trans->trans_cfg->base_params->eeprom_size; IWL_DEBUG_EEPROM(trans->dev, "NVM size = %d\n", sz); e = kmalloc(sz, GFP_KERNEL); @@ -396,7 +396,7 @@ int iwl_read_eeprom(struct iwl_trans *trans, u8 **eeprom, size_t *eeprom_size) CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK | CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); /* traversing the linked list if no shadow ram supported */ - if (!trans->cfg->trans.base_params->shadow_ram_support) { + if (!trans->trans_cfg->base_params->shadow_ram_support) { ret = iwl_find_otp_image(trans, &validblockaddr); if (ret) goto err_unlock; diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-fh.h b/drivers/net/wireless/intel/iwlwifi/iwl-fh.h index dfaad564ef09..0c12df558240 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-fh.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-fh.h @@ -127,7 +127,7 @@ static inline unsigned int FH_MEM_CBBC_QUEUE(struct iwl_trans *trans, unsigned int chnl) { - if (trans->cfg->trans.use_tfh) { + if (trans->trans_cfg->use_tfh) { WARN_ON_ONCE(chnl >= 64); return TFH_TFDQ_CBB_TABLE + 8 * chnl; } diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-io.c b/drivers/net/wireless/intel/iwlwifi/iwl-io.c index 7561a3891788..1b7414bf7bef 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-io.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-io.c @@ -304,10 +304,10 @@ IWL_EXPORT_SYMBOL(iwl_clear_bits_prph); void iwl_force_nmi(struct iwl_trans *trans) { - if (trans->cfg->trans.device_family < IWL_DEVICE_FAMILY_9000) + if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_9000) iwl_write_prph(trans, DEVICE_SET_NMI_REG, DEVICE_SET_NMI_VAL_DRV); - else if (trans->cfg->trans.device_family < IWL_DEVICE_FAMILY_AX210) + else if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210) iwl_write_umac_prph(trans, UREG_NIC_SET_NMI_DRIVER, UREG_NIC_SET_NMI_DRIVER_NMI_FROM_DRIVER_MSK); else @@ -458,7 +458,7 @@ int iwl_dump_fh(struct iwl_trans *trans, char **buf) FH_TSSR_TX_ERROR_REG }; - if (trans->cfg->trans.mq_rx_supported) + if (trans->trans_cfg->mq_rx_supported) return iwl_dump_rfh(trans, buf); #ifdef CONFIG_IWLWIFI_DEBUGFS diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c index 10aef19680d0..e43e452403f5 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c @@ -793,10 +793,10 @@ static void iwl_set_hw_address_from_csr(struct iwl_trans *trans, { __le32 mac_addr0 = cpu_to_le32(iwl_read32(trans, - trans->cfg->trans.csr->mac_addr0_strap)); + trans->trans_cfg->csr->mac_addr0_strap)); __le32 mac_addr1 = cpu_to_le32(iwl_read32(trans, - trans->cfg->trans.csr->mac_addr1_strap)); + trans->trans_cfg->csr->mac_addr1_strap)); iwl_flip_hw_address(mac_addr0, mac_addr1, data->hw_addr); /* @@ -807,9 +807,9 @@ static void iwl_set_hw_address_from_csr(struct iwl_trans *trans, return; mac_addr0 = cpu_to_le32(iwl_read32(trans, - trans->cfg->trans.csr->mac_addr0_otp)); + trans->trans_cfg->csr->mac_addr0_otp)); mac_addr1 = cpu_to_le32(iwl_read32(trans, - trans->cfg->trans.csr->mac_addr1_otp)); + trans->trans_cfg->csr->mac_addr1_otp)); iwl_flip_hw_address(mac_addr0, mac_addr1, data->hw_addr); } @@ -1301,7 +1301,7 @@ int iwl_read_external_nvm(struct iwl_trans *trans, le32_to_cpu(dword_buff[3])); /* nvm file validation, dword_buff[2] holds the file version */ - if (trans->cfg->trans.device_family == IWL_DEVICE_FAMILY_8000 && + if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_8000 && CSR_HW_REV_STEP(trans->hw_rev) == SILICON_C_STEP && le32_to_cpu(dword_buff[2]) < 0xE4A) { ret = -EFAULT; diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h index 1b9bf9f94367..4152ae972aa7 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h @@ -743,6 +743,7 @@ struct iwl_trans_debug { * * @ops - pointer to iwl_trans_ops * @op_mode - pointer to the op_mode + * @trans_cfg: the trans-specific configuration part * @cfg - pointer to the configuration * @drv - pointer to iwl_drv * @status: a bit-mask of transport status flags @@ -774,6 +775,7 @@ struct iwl_trans_debug { struct iwl_trans { const struct iwl_trans_ops *ops; struct iwl_op_mode *op_mode; + const struct iwl_cfg_trans_params *trans_cfg; const struct iwl_cfg *cfg; struct iwl_drv *drv; enum iwl_trans_state state; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index cd067653814c..cd7172d7f72e 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -1050,7 +1050,7 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, * recording before entering D3. In later devices the FW stops the * recording automatically. */ - if (mvm->trans->cfg->trans.device_family < IWL_DEVICE_FAMILY_9000) + if (mvm->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_9000) iwl_fw_dbg_stop_restart_recording(&mvm->fwrt, NULL, true); /* must be last -- this switches firmware state */ @@ -1658,7 +1658,7 @@ static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm, mvm_ap_sta->tid_data[i].seq_number = seq; } - if (mvm->trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_22000) { + if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22000) { i = mvm->offload_tid; iwl_trans_set_q_ptrs(mvm->trans, mvm_ap_sta->tid_data[i].txq_id, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c index 2dbb02666851..ad18c2f1a806 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c @@ -1173,7 +1173,7 @@ static ssize_t iwl_dbgfs_inject_packet_write(struct iwl_mvm *mvm, struct iwl_rx_mpdu_desc *desc; int bin_len = count / 2; int ret = -EINVAL; - size_t mpdu_cmd_hdr_size = (mvm->trans->cfg->trans.device_family >= + size_t mpdu_cmd_hdr_size = (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560) ? sizeof(struct iwl_rx_mpdu_desc) : IWL_RX_DESC_SIZE_V1; @@ -1182,7 +1182,7 @@ static ssize_t iwl_dbgfs_inject_packet_write(struct iwl_mvm *mvm, return -EIO; /* supporting only 9000 descriptor */ - if (!mvm->trans->cfg->trans.mq_rx_supported) + if (!mvm->trans->trans_cfg->mq_rx_supported) return -ENOTSUPP; rxb._page = alloc_pages(GFP_ATOMIC, 0); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index 474e61f436a7..fcb51cb3010e 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -357,13 +357,13 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm, iwl_fw_dbg_error_collect(&mvm->fwrt, FW_DBG_TRIGGER_ALIVE_TIMEOUT); - if (trans->cfg->trans.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->cfg->trans.device_family >= + else if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_8000) IWL_ERR(mvm, "SecBoot CPU1 Status: 0x%x, CPU2 Status: 0x%x\n", @@ -1334,7 +1334,7 @@ int iwl_mvm_up(struct iwl_mvm *mvm) goto error; /* Init RSS configuration */ - if (mvm->trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_22000) { + if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22000) { ret = iwl_configure_rxq(mvm); if (ret) { IWL_ERR(mvm, "Failed to configure RX queues: %d\n", diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 7f37e34b74d4..98c9562647c3 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -3330,7 +3330,7 @@ static int __iwl_mvm_mac_set_key(struct ieee80211_hw *hw, switch (key->cipher) { case WLAN_CIPHER_SUITE_TKIP: - if (!mvm->trans->cfg->trans.gen2) { + if (!mvm->trans->trans_cfg->gen2) { key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; key->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE; } else if (vif->type == NL80211_IFTYPE_STATION) { diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 7d3484144891..9e76d494c45c 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -1356,13 +1356,13 @@ static inline bool iwl_mvm_has_new_rx_api(struct iwl_mvm *mvm) static inline bool iwl_mvm_has_new_tx_api(struct iwl_mvm *mvm) { /* TODO - replace with TLV once defined */ - return mvm->trans->cfg->trans.use_tfh; + return mvm->trans->trans_cfg->use_tfh; } static inline bool iwl_mvm_has_unified_ucode(struct iwl_mvm *mvm) { /* TODO - better define this */ - return mvm->trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_22000; + return mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22000; } static inline bool iwl_mvm_is_cdb_supported(struct iwl_mvm *mvm) @@ -1387,7 +1387,7 @@ static inline bool iwl_mvm_cdb_scan_api(struct iwl_mvm *mvm) * but then there's a little bit of code in scan that won't make * any sense... */ - return mvm->trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_22000; + return mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22000; } static inline bool iwl_mvm_is_scan_ext_chan_supported(struct iwl_mvm *mvm) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index c30ce004af14..35b393f8cd85 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -173,7 +173,7 @@ static void iwl_mvm_nic_config(struct iwl_op_mode *op_mode) * unrelated errors. Need to further investigate this, but for now * we'll separate cases. */ - if (mvm->trans->cfg->trans.device_family < IWL_DEVICE_FAMILY_8000) + if (mvm->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_8000) reg_val |= CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI; if (iwl_fw_dbg_is_d3_debug_enabled(&mvm->fwrt)) @@ -664,7 +664,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, if (iwl_mvm_has_new_rx_api(mvm)) { op_mode->ops = &iwl_mvm_ops_mq; trans->rx_mpdu_cmd_hdr_size = - (trans->cfg->trans.device_family >= + (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560) ? sizeof(struct iwl_rx_mpdu_desc) : IWL_RX_DESC_SIZE_V1; @@ -728,7 +728,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, trans_cfg.no_reclaim_cmds = no_reclaim_cmds; trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds); - if (mvm->trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_22560) + if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560) rb_size_default = IWL_AMSDU_2K; else rb_size_default = IWL_AMSDU_4K; @@ -757,7 +757,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, trans->wide_cmd_header = true; trans_cfg.bc_table_dword = - mvm->trans->cfg->trans.device_family < IWL_DEVICE_FAMILY_22560; + mvm->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_22560; trans_cfg.command_groups = iwl_mvm_groups; trans_cfg.command_groups_size = ARRAY_SIZE(iwl_mvm_groups); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c index 7300eea03b4c..42d525e46e80 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c @@ -3338,7 +3338,7 @@ static void rs_build_rates_table_from_fixed(struct iwl_mvm *mvm, if (num_of_ant(ant) == 1) lq_cmd->single_stream_ant_msk = ant; - if (!mvm->trans->cfg->trans.gen2) + if (!mvm->trans->trans_cfg->gen2) lq_cmd->agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF; else lq_cmd->agg_frame_cnt_limit = diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c index 65a8f0ad5f29..25d038092eec 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c @@ -349,7 +349,7 @@ static int iwl_mvm_rx_crypto(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr, !(status & IWL_RX_MPDU_RES_STATUS_TTAK_OK)) return 0; - if (mvm->trans->cfg->trans.gen2 && + if (mvm->trans->trans_cfg->gen2 && !(status & RX_MPDU_RES_STATUS_MIC_OK)) stats->flag |= RX_FLAG_MMIC_ERROR; @@ -366,7 +366,7 @@ static int iwl_mvm_rx_crypto(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr, if (pkt_flags & FH_RSCSR_RADA_EN) { stats->flag |= RX_FLAG_ICV_STRIPPED; - if (mvm->trans->cfg->trans.gen2) + if (mvm->trans->trans_cfg->gen2) stats->flag |= RX_FLAG_MMIC_STRIPPED; } @@ -1504,7 +1504,7 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, if (unlikely(test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))) return; - if (mvm->trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_22560) { + if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560) { rate_n_flags = le32_to_cpu(desc->v3.rate_n_flags); channel = desc->v3.channel; gp2_on_air_rise = le32_to_cpu(desc->v3.gp2_on_air_rise); @@ -1605,7 +1605,7 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, if (likely(!(phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD))) { u64 tsf_on_air_rise; - if (mvm->trans->cfg->trans.device_family >= + if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560) tsf_on_air_rise = le64_to_cpu(desc->v3.tsf_on_air_rise); else @@ -1732,7 +1732,7 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, *qc &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT; - if (mvm->trans->cfg->trans.device_family == + if (mvm->trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_9000) { iwl_mvm_flip_address(hdr->addr3); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c index ca7e51313381..eaa8b1c9938a 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c @@ -1604,7 +1604,7 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm, mvm_sta->mac_id_n_color = FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color); mvm_sta->vif = vif; - if (!mvm->trans->cfg->trans.gen2) + if (!mvm->trans->trans_cfg->gen2) mvm_sta->max_agg_bufsize = LINK_QUAL_AGG_FRAME_LIMIT_DEF; else mvm_sta->max_agg_bufsize = LINK_QUAL_AGG_FRAME_LIMIT_GEN2_DEF; @@ -2813,7 +2813,7 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif, * to align the wrap around of ssn so we compare relevant values. */ normalized_ssn = tid_data->ssn; - if (mvm->trans->cfg->trans.gen2) + if (mvm->trans->trans_cfg->gen2) normalized_ssn &= 0xff; if (normalized_ssn == tid_data->next_reclaimed) { @@ -3853,7 +3853,7 @@ u16 iwl_mvm_tid_queued(struct iwl_mvm *mvm, struct iwl_mvm_tid_data *tid_data) * In 22000 HW, the next_reclaimed index is only 8 bit, so we'll need * to align the wrap around of ssn so we compare relevant values. */ - if (mvm->trans->cfg->trans.gen2) + if (mvm->trans->trans_cfg->gen2) sn &= 0xff; return ieee80211_sn_sub(sn, tid_data->next_reclaimed); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index 48d305c9b737..8a059da7a1fa 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c @@ -546,7 +546,7 @@ iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb, hdr->frame_control); } - if (mvm->trans->cfg->trans.device_family >= + if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560) { struct iwl_tx_cmd_gen3 *cmd = (void *)dev_cmd->payload; @@ -1272,7 +1272,7 @@ static void iwl_mvm_check_ratid_empty(struct iwl_mvm *mvm, * to align the wrap around of ssn so we compare relevant values. */ normalized_ssn = tid_data->ssn; - if (mvm->trans->cfg->trans.gen2) + if (mvm->trans->trans_cfg->gen2) normalized_ssn &= 0xff; if (normalized_ssn != tid_data->next_reclaimed) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c index f8d6e5672867..ba1524727a1f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c @@ -1431,7 +1431,7 @@ u32 iwl_mvm_get_systime(struct iwl_mvm *mvm) { u32 reg_addr = DEVICE_SYSTEM_TIME_REG; - if (mvm->trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_22000 && + if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22000 && mvm->trans->cfg->gp2_reg_addr) reg_addr = mvm->trans->cfg->gp2_reg_addr; 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 1b5de527f141..75fa8a6aafee 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c @@ -180,7 +180,7 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans, iwl_set_bit(trans, CSR_CTXT_INFO_BOOT_CTRL, CSR_AUTO_FUNC_BOOT_ENA); - if (trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_AX210) + if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) iwl_write_umac_prph(trans, UREG_CPU_INIT_RUN, 1); else iwl_set_bit(trans, CSR_GP_CNTRL, CSR_AUTO_FUNC_INIT); diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index 2010eaca5140..e6a3fa2080e2 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -1004,6 +1004,9 @@ 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); + /* the trans_cfg should never change, so set it now */ + iwl_trans->trans_cfg = &cfg->trans; + #if IS_ENABLED(CONFIG_IWLMVM) /* * special-case 7265D, it has the same PCI IDs. @@ -1024,18 +1027,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) iwl_trans->hw_rf_id = iwl_read32(iwl_trans, CSR_HW_RF_ID); - /* - * We can already set the cfg to iwl_trans here, because the - * only part we use at this point is the cfg_trans - * information. Once we decide the real cfg, we set it again - * (happens later in this function). TODO: this is only - * temporary, while we're sorting out this whole thing, but in - * the future it won't be necessary, because we will separate - * the trans configuration entirely from the rest of the - * config struct. - */ - iwl_trans->cfg = cfg; - 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; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h index eba9660a2bc8..f07559b3633a 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h @@ -254,7 +254,7 @@ struct iwl_dma_ptr { static inline int iwl_queue_inc_wrap(struct iwl_trans *trans, int index) { return ++index & - (trans->cfg->trans.base_params->max_tfd_queue_size - 1); + (trans->trans_cfg->base_params->max_tfd_queue_size - 1); } /** @@ -264,7 +264,7 @@ static inline int iwl_queue_inc_wrap(struct iwl_trans *trans, int index) static inline __le16 iwl_get_closed_rb_stts(struct iwl_trans *trans, struct iwl_rxq *rxq) { - if (trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_22560) { + if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560) { __le16 *rb_stts = rxq->rb_stts; return READ_ONCE(*rb_stts); @@ -282,7 +282,7 @@ static inline __le16 iwl_get_closed_rb_stts(struct iwl_trans *trans, static inline int iwl_queue_dec_wrap(struct iwl_trans *trans, int index) { return --index & - (trans->cfg->trans.base_params->max_tfd_queue_size - 1); + (trans->trans_cfg->base_params->max_tfd_queue_size - 1); } struct iwl_cmd_meta { @@ -707,7 +707,7 @@ void iwl_pcie_gen2_update_byte_tbl(struct iwl_trans_pcie *trans_pcie, static inline u16 iwl_pcie_tfd_tb_get_len(struct iwl_trans *trans, void *_tfd, u8 idx) { - if (trans->cfg->trans.use_tfh) { + if (trans->trans_cfg->use_tfh) { struct iwl_tfh_tfd *tfd = _tfd; struct iwl_tfh_tb *tb = &tfd->tbs[idx]; @@ -913,7 +913,7 @@ static inline void *iwl_pcie_get_tfd(struct iwl_trans *trans, { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - if (trans->cfg->trans.use_tfh) + if (trans->trans_cfg->use_tfh) idx = iwl_pcie_get_cmd_index(txq, idx); return txq->tfds + trans_pcie->tfd_size * idx; @@ -957,7 +957,7 @@ static inline void iwl_enable_rfkill_int(struct iwl_trans *trans) MSIX_HW_INT_CAUSES_REG_RF_KILL); } - if (trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_9000) { + if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_9000) { /* * On 9000-series devices this bit isn't enabled by default, so * when we power down the device we need set the bit to allow it diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c index 79b012e881f0..fce8c500ec02 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c @@ -200,12 +200,12 @@ static inline __le32 iwl_pcie_dma_addr2rbd_ptr(dma_addr_t dma_addr) */ int iwl_pcie_rx_stop(struct iwl_trans *trans) { - if (trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_22560) { + if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560) { /* TODO: remove this for 22560 once fw does it */ iwl_write_umac_prph(trans, RFH_RXF_DMA_CFG_GEN3, 0); return iwl_poll_umac_prph_bit(trans, RFH_GEN_STATUS_GEN3, RXF_DMA_IDLE, RXF_DMA_IDLE, 1000); - } else if (trans->cfg->trans.mq_rx_supported) { + } else if (trans->trans_cfg->mq_rx_supported) { iwl_write_prph(trans, RFH_RXF_DMA_CFG, 0); return iwl_poll_prph_bit(trans, RFH_GEN_STATUS, RXF_DMA_IDLE, RXF_DMA_IDLE, 1000); @@ -232,7 +232,7 @@ static void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans *trans, * 1. shadow registers aren't enabled * 2. there is a chance that the NIC is asleep */ - if (!trans->cfg->trans.base_params->shadow_reg_enable && + if (!trans->trans_cfg->base_params->shadow_reg_enable && test_bit(STATUS_TPOWER_PMI, &trans->status)) { reg = iwl_read32(trans, CSR_UCODE_DRV_GP1); @@ -240,18 +240,18 @@ 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->cfg->trans.csr->flag_mac_access_req)); + BIT(trans->trans_cfg->csr->flag_mac_access_req)); rxq->need_update = true; return; } } rxq->write_actual = round_down(rxq->write, 8); - if (trans->cfg->trans.device_family == IWL_DEVICE_FAMILY_22560) + if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22560) iwl_write32(trans, HBUS_TARG_WRPTR, (rxq->write_actual | ((FIRST_RX_QUEUE + rxq->id) << 16))); - else if (trans->cfg->trans.mq_rx_supported) + else if (trans->trans_cfg->mq_rx_supported) iwl_write32(trans, RFH_Q_FRBDCB_WIDX_TRG(rxq->id), rxq->write_actual); else @@ -279,7 +279,7 @@ static void iwl_pcie_restock_bd(struct iwl_trans *trans, struct iwl_rxq *rxq, struct iwl_rx_mem_buffer *rxb) { - if (trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_22560) { + if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560) { struct iwl_rx_transfer_desc *bd = rxq->bd; BUILD_BUG_ON(sizeof(*bd) != 2 * sizeof(u64)); @@ -405,7 +405,7 @@ static void iwl_pcie_rxsq_restock(struct iwl_trans *trans, static void iwl_pcie_rxq_restock(struct iwl_trans *trans, struct iwl_rxq *rxq) { - if (trans->cfg->trans.mq_rx_supported) + if (trans->trans_cfg->mq_rx_supported) iwl_pcie_rxmq_restock(trans, rxq); else iwl_pcie_rxsq_restock(trans, rxq); @@ -682,7 +682,7 @@ static int iwl_pcie_free_bd_size(struct iwl_trans *trans, bool use_rx_td) if (use_rx_td) return sizeof(*rx_td); else - return trans->cfg->trans.mq_rx_supported ? sizeof(__le64) : + return trans->trans_cfg->mq_rx_supported ? sizeof(__le64) : sizeof(__le32); } @@ -690,7 +690,7 @@ static void iwl_pcie_free_rxq_dma(struct iwl_trans *trans, struct iwl_rxq *rxq) { struct device *dev = trans->dev; - bool use_rx_td = (trans->cfg->trans.device_family >= + bool use_rx_td = (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560); int free_size = iwl_pcie_free_bd_size(trans, use_rx_td); @@ -712,7 +712,7 @@ static void iwl_pcie_free_rxq_dma(struct iwl_trans *trans, rxq->used_bd_dma = 0; rxq->used_bd = NULL; - if (trans->cfg->trans.device_family < IWL_DEVICE_FAMILY_22560) + if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_22560) return; if (rxq->tr_tail) @@ -735,13 +735,13 @@ static int iwl_pcie_alloc_rxq_dma(struct iwl_trans *trans, struct device *dev = trans->dev; int i; int free_size; - bool use_rx_td = (trans->cfg->trans.device_family >= + bool use_rx_td = (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560); size_t rb_stts_size = use_rx_td ? sizeof(__le16) : sizeof(struct iwl_rb_status); spin_lock_init(&rxq->lock); - if (trans->cfg->trans.mq_rx_supported) + if (trans->trans_cfg->mq_rx_supported) rxq->queue_size = MQ_RX_TABLE_SIZE; else rxq->queue_size = RX_QUEUE_SIZE; @@ -757,7 +757,7 @@ static int iwl_pcie_alloc_rxq_dma(struct iwl_trans *trans, if (!rxq->bd) goto err; - if (trans->cfg->trans.mq_rx_supported) { + if (trans->trans_cfg->mq_rx_supported) { rxq->used_bd = dma_alloc_coherent(dev, (use_rx_td ? sizeof(*rxq->cd) : sizeof(__le32)) * rxq->queue_size, &rxq->used_bd_dma, @@ -807,7 +807,7 @@ int iwl_pcie_rx_alloc(struct iwl_trans *trans) struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_rb_allocator *rba = &trans_pcie->rba; int i, ret; - size_t rb_stts_size = trans->cfg->trans.device_family >= + size_t rb_stts_size = trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560 ? sizeof(__le16) : sizeof(struct iwl_rb_status); @@ -1074,7 +1074,7 @@ int _iwl_pcie_rx_init(struct iwl_trans *trans) rxq->read = 0; rxq->write = 0; rxq->write_actual = 0; - memset(rxq->rb_stts, 0, (trans->cfg->trans.device_family >= + memset(rxq->rb_stts, 0, (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560) ? sizeof(__le16) : sizeof(struct iwl_rb_status)); @@ -1088,7 +1088,7 @@ int _iwl_pcie_rx_init(struct iwl_trans *trans) } /* move the pool to the default queue and allocator ownerships */ - queue_size = trans->cfg->trans.mq_rx_supported ? + queue_size = trans->trans_cfg->mq_rx_supported ? MQ_RX_NUM_RBDS : RX_QUEUE_SIZE; allocator_pool_size = trans->num_rx_queues * (RX_CLAIM_REQ_ALLOC - RX_POST_REQ_ALLOC); @@ -1120,7 +1120,7 @@ int iwl_pcie_rx_init(struct iwl_trans *trans) if (ret) return ret; - if (trans->cfg->trans.mq_rx_supported) + if (trans->trans_cfg->mq_rx_supported) iwl_pcie_rx_mq_hw_init(trans); else iwl_pcie_rx_hw_init(trans, trans_pcie->rxq); @@ -1151,7 +1151,7 @@ void iwl_pcie_rx_free(struct iwl_trans *trans) struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_rb_allocator *rba = &trans_pcie->rba; int i; - size_t rb_stts_size = trans->cfg->trans.device_family >= + size_t rb_stts_size = trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560 ? sizeof(__le16) : sizeof(struct iwl_rb_status); @@ -1347,7 +1347,7 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans, } page_stolen |= rxcb._page_stolen; - if (trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_22560) + if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560) break; offset += ALIGN(len, FH_RSCSR_FRAME_ALIGN); } @@ -1392,14 +1392,14 @@ static struct iwl_rx_mem_buffer *iwl_pcie_get_rxb(struct iwl_trans *trans, BUILD_BUG_ON(sizeof(struct iwl_rx_completion_desc) != 32); - if (!trans->cfg->trans.mq_rx_supported) { + if (!trans->trans_cfg->mq_rx_supported) { rxb = rxq->queue[i]; rxq->queue[i] = NULL; return rxb; } /* used_bd is a 32/16 bit but only 12 are used to retrieve the vid */ - if (trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_22560) + if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560) vid = le16_to_cpu(rxq->cd[i].rbid) & 0x0FFF; else vid = le32_to_cpu(rxq->bd_32[i]) & 0x0FFF; @@ -1515,7 +1515,7 @@ static void iwl_pcie_rx_handle(struct iwl_trans *trans, int queue) /* Backtrack one entry */ rxq->read = i; /* update cr tail with the rxq read pointer */ - if (trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_22560) + if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560) *rxq->cr_tail = cpu_to_le16(r); spin_unlock(&rxq->lock); @@ -1597,7 +1597,7 @@ static void iwl_pcie_irq_handle_error(struct iwl_trans *trans) return; } - for (i = 0; i < trans->cfg->trans.base_params->num_of_queues; i++) { + for (i = 0; i < trans->trans_cfg->base_params->num_of_queues; i++) { if (!trans_pcie->txq[i]) continue; del_timer(&trans_pcie->txq[i]->stuck_timer); @@ -1838,7 +1838,7 @@ irqreturn_t iwl_pcie_irq_handler(int irq, void *dev_id) if (inta & CSR_INT_BIT_ALIVE) { IWL_DEBUG_ISR(trans, "Alive interrupt\n"); isr_stats->alive++; - if (trans->cfg->trans.gen2) { + if (trans->trans_cfg->gen2) { /* * We can restock, since firmware configured * the RFH @@ -2179,13 +2179,13 @@ irqreturn_t iwl_pcie_irq_msix_handler(int irq, void *dev_id) if (inta_hw & MSIX_HW_INT_CAUSES_REG_ALIVE) { IWL_DEBUG_ISR(trans, "Alive interrupt\n"); isr_stats->alive++; - if (trans->cfg->trans.gen2) { + if (trans->trans_cfg->gen2) { /* We can restock, since firmware configured the RFH */ iwl_pcie_rxmq_restock(trans, trans_pcie->rxq); } } - if (trans->cfg->trans.device_family == IWL_DEVICE_FAMILY_22560 && + if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22560 && inta_hw & MSIX_HW_INT_CAUSES_REG_IPC) { /* Reflect IML transfer status */ int res = iwl_read32(trans, CSR_IML_RESP_ADDR); diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c index 919b69ab836d..b6db3c42c467 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c @@ -133,7 +133,7 @@ static void iwl_pcie_gen2_apm_stop(struct iwl_trans *trans, bool op_mode_leave) * D0A* (powered-up Active) --> D0U* (Uninitialized) state. */ iwl_clear_bit(trans, CSR_GP_CNTRL, - BIT(trans->cfg->trans.csr->flag_init_done)); + BIT(trans->trans_cfg->csr->flag_init_done)); } void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans) @@ -168,14 +168,14 @@ void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans) } iwl_pcie_ctxt_info_free_paging(trans); - if (trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_22560) + if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560) iwl_pcie_ctxt_info_gen3_free(trans); else iwl_pcie_ctxt_info_free(trans); /* Make sure (redundant) we've released our request to stay awake */ iwl_clear_bit(trans, CSR_GP_CNTRL, - BIT(trans->cfg->trans.csr->flag_mac_access_req)); + BIT(trans->trans_cfg->csr->flag_mac_access_req)); /* Stop the device, and put it in low power state */ iwl_pcie_gen2_apm_stop(trans, false); @@ -340,7 +340,7 @@ int iwl_trans_pcie_gen2_start_fw(struct iwl_trans *trans, goto out; } - if (trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_22560) + if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560) ret = iwl_pcie_ctxt_info_gen3_init(trans, fw); else ret = iwl_pcie_ctxt_info_init(trans, fw); diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index e196e3b87574..d2fe8ff45bbb 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -184,8 +184,8 @@ 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->cfg->trans.csr->addr_sw_reset, - BIT(trans->cfg->trans.csr->flag_sw_reset)); + iwl_set_bit(trans, trans->trans_cfg->csr->addr_sw_reset, + BIT(trans->trans_cfg->csr->flag_sw_reset)); usleep_range(5000, 6000); } @@ -341,7 +341,7 @@ static int iwl_pcie_apm_init(struct iwl_trans *trans) */ /* Disable L0S exit timer (platform NMI Work/Around) */ - if (trans->cfg->trans.device_family < IWL_DEVICE_FAMILY_8000) + if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_8000) iwl_set_bit(trans, CSR_GIO_CHICKEN_BITS, CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER); @@ -365,7 +365,7 @@ static int iwl_pcie_apm_init(struct iwl_trans *trans) iwl_pcie_apm_config(trans); /* Configure analog phase-lock-loop before activating to D0A */ - if (trans->cfg->trans.base_params->pll_cfg) + if (trans->trans_cfg->base_params->pll_cfg) iwl_set_bit(trans, CSR_ANA_PLL_CFG, CSR50_ANA_PLL_CFG_VAL); ret = iwl_finish_nic_init(trans, &trans->cfg->trans); @@ -490,7 +490,7 @@ static void iwl_pcie_apm_lp_xtal_enable(struct iwl_trans *trans) * D0A* (powered-up Active) --> D0U* (Uninitialized) state. */ iwl_clear_bit(trans, CSR_GP_CNTRL, - BIT(trans->cfg->trans.csr->flag_init_done)); + BIT(trans->trans_cfg->csr->flag_init_done)); /* Activates XTAL resources monitor */ __iwl_trans_pcie_set_bit(trans, CSR_MONITOR_CFG_REG, @@ -512,12 +512,12 @@ void iwl_pcie_apm_stop_master(struct iwl_trans *trans) int ret; /* stop device's busmaster DMA activity */ - iwl_set_bit(trans, trans->cfg->trans.csr->addr_sw_reset, - BIT(trans->cfg->trans.csr->flag_stop_master)); + iwl_set_bit(trans, trans->trans_cfg->csr->addr_sw_reset, + BIT(trans->trans_cfg->csr->flag_stop_master)); - ret = iwl_poll_bit(trans, trans->cfg->trans.csr->addr_sw_reset, - BIT(trans->cfg->trans.csr->flag_master_dis), - BIT(trans->cfg->trans.csr->flag_master_dis), 100); + 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); if (ret < 0) IWL_WARN(trans, "Master Disable Timed Out, 100 usec\n"); @@ -533,10 +533,10 @@ static void iwl_pcie_apm_stop(struct iwl_trans *trans, bool op_mode_leave) iwl_pcie_apm_init(trans); /* inform ME that we are leaving */ - if (trans->cfg->trans.device_family == IWL_DEVICE_FAMILY_7000) + if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_7000) iwl_set_bits_prph(trans, APMG_PCIDEV_STT_REG, APMG_PCIDEV_STT_VAL_WAKE_ME); - else if (trans->cfg->trans.device_family >= + else if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_8000) { iwl_set_bit(trans, CSR_DBG_LINK_PWR_MGMT_REG, CSR_RESET_LINK_PWR_MGMT_DISABLED); @@ -567,7 +567,7 @@ static void iwl_pcie_apm_stop(struct iwl_trans *trans, bool op_mode_leave) * D0A* (powered-up Active) --> D0U* (Uninitialized) state. */ iwl_clear_bit(trans, CSR_GP_CNTRL, - BIT(trans->cfg->trans.csr->flag_init_done)); + BIT(trans->trans_cfg->csr->flag_init_done)); } static int iwl_pcie_nic_init(struct iwl_trans *trans) @@ -594,7 +594,7 @@ static int iwl_pcie_nic_init(struct iwl_trans *trans) if (iwl_pcie_tx_init(trans)) return -ENOMEM; - if (trans->cfg->trans.base_params->shadow_reg_enable) { + if (trans->trans_cfg->base_params->shadow_reg_enable) { /* enable shadow regs in HW */ iwl_set_bit(trans, CSR_MAC_SHADOW_REG_CTRL, 0x800FFFFF); IWL_DEBUG_INFO(trans, "Enabling shadow registers in device\n"); @@ -832,7 +832,7 @@ static int iwl_pcie_load_cpu_sections_8000(struct iwl_trans *trans, iwl_enable_interrupts(trans); - if (trans->cfg->trans.use_tfh) { + if (trans->trans_cfg->use_tfh) { if (cpu == 1) iwl_write_prph(trans, UREG_UCODE_LOAD_STATUS, 0xFFFF); @@ -964,7 +964,7 @@ void iwl_pcie_apply_destination(struct iwl_trans *trans) iwl_write_prph(trans, le32_to_cpu(dest->base_reg), trans->dbg.fw_mon[0].physical >> dest->base_shift); - if (trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_8000) + if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_8000) iwl_write_prph(trans, le32_to_cpu(dest->end_reg), (trans->dbg.fw_mon[0].physical + trans->dbg.fw_mon[0].size - 256) >> @@ -1006,7 +1006,7 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans, /* supported for 7000 only for the moment */ if (iwlwifi_mod_params.fw_monitor && - trans->cfg->trans.device_family == IWL_DEVICE_FAMILY_7000) { + trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_7000) { iwl_pcie_alloc_fw_monitor(trans, 0); if (trans->dbg.fw_mon[0].size) { @@ -1135,7 +1135,7 @@ static void iwl_pcie_map_non_rx_causes(struct iwl_trans *trans) struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); int val = trans_pcie->def_irq | MSIX_NON_AUTO_CLEAR_CAUSE; int i, arr_size = - (trans->cfg->trans.device_family != IWL_DEVICE_FAMILY_22560) ? + (trans->trans_cfg->device_family != IWL_DEVICE_FAMILY_22560) ? ARRAY_SIZE(causes_list) : ARRAY_SIZE(causes_list_v2); /* @@ -1145,7 +1145,7 @@ static void iwl_pcie_map_non_rx_causes(struct iwl_trans *trans) */ for (i = 0; i < arr_size; i++) { struct iwl_causes_list *causes = - (trans->cfg->trans.device_family != + (trans->trans_cfg->device_family != IWL_DEVICE_FAMILY_22560) ? causes_list : causes_list_v2; @@ -1190,7 +1190,7 @@ void iwl_pcie_conf_msix_hw(struct iwl_trans_pcie *trans_pcie) struct iwl_trans *trans = trans_pcie->trans; if (!trans_pcie->msix_enabled) { - if (trans->cfg->trans.mq_rx_supported && + if (trans->trans_cfg->mq_rx_supported && test_bit(STATUS_DEVICE_ENABLED, &trans->status)) iwl_write_umac_prph(trans, UREG_CHICK, UREG_CHICK_MSI_ENABLE); @@ -1271,7 +1271,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->cfg->trans.csr->flag_mac_access_req)); + BIT(trans->trans_cfg->csr->flag_mac_access_req)); /* Stop the device, and put it in low power state */ iwl_pcie_apm_stop(trans, false); @@ -1398,7 +1398,7 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); /* Load the given image to the HW */ - if (trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_8000) + if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_8000) ret = iwl_pcie_load_given_ucode_8000(trans, fw); else ret = iwl_pcie_load_given_ucode(trans, fw); @@ -1471,7 +1471,7 @@ void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state) IWL_WARN(trans, "reporting RF_KILL (radio %s)\n", state ? "disabled" : "enabled"); if (iwl_op_mode_hw_rf_kill(trans->op_mode, state)) { - if (trans->cfg->trans.gen2) + if (trans->trans_cfg->gen2) _iwl_trans_pcie_gen2_stop_device(trans); else _iwl_trans_pcie_stop_device(trans); @@ -1501,9 +1501,9 @@ static void iwl_trans_pcie_d3_suspend(struct iwl_trans *trans, bool test, iwl_pcie_synchronize_irqs(trans); iwl_clear_bit(trans, CSR_GP_CNTRL, - BIT(trans->cfg->trans.csr->flag_mac_access_req)); + BIT(trans->trans_cfg->csr->flag_mac_access_req)); iwl_clear_bit(trans, CSR_GP_CNTRL, - BIT(trans->cfg->trans.csr->flag_init_done)); + BIT(trans->trans_cfg->csr->flag_init_done)); if (reset) { /* @@ -1532,7 +1532,7 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans, } iwl_set_bit(trans, CSR_GP_CNTRL, - BIT(trans->cfg->trans.csr->flag_mac_access_req)); + BIT(trans->trans_cfg->csr->flag_mac_access_req)); ret = iwl_finish_nic_init(trans, &trans->cfg->trans); if (ret) @@ -1554,7 +1554,7 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans, if (!reset) { iwl_clear_bit(trans, CSR_GP_CNTRL, - BIT(trans->cfg->trans.csr->flag_mac_access_req)); + BIT(trans->trans_cfg->csr->flag_mac_access_req)); } else { iwl_trans_pcie_tx_reset(trans); @@ -1708,7 +1708,7 @@ static int iwl_trans_pcie_clear_persistence_bit(struct iwl_trans *trans) { u32 hpm, wprot; - switch (trans->cfg->trans.device_family) { + switch (trans->trans_cfg->device_family) { case IWL_DEVICE_FAMILY_9000: wprot = PREG_PRPH_WPROT_9000; break; @@ -1823,7 +1823,7 @@ static u32 iwl_trans_pcie_read32(struct iwl_trans *trans, u32 ofs) static u32 iwl_trans_pcie_prph_msk(struct iwl_trans *trans) { - if (trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_22560) + if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560) return 0x00FFFFFF; else return 0x000FFFFF; @@ -1894,7 +1894,7 @@ void iwl_trans_pcie_free(struct iwl_trans *trans) iwl_pcie_synchronize_irqs(trans); - if (trans->cfg->trans.gen2) + if (trans->trans_cfg->gen2) iwl_pcie_gen2_tx_free(trans); else iwl_pcie_tx_free(trans); @@ -1976,8 +1976,8 @@ 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->cfg->trans.csr->flag_mac_access_req)); - if (trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_8000) + BIT(trans->trans_cfg->csr->flag_mac_access_req)); + if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_8000) udelay(2); /* @@ -2001,8 +2001,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->cfg->trans.csr->flag_val_mac_access_en), - (BIT(trans->cfg->trans.csr->flag_mac_clock_ready) | + BIT(trans->trans_cfg->csr->flag_val_mac_access_en), + (BIT(trans->trans_cfg->csr->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); @@ -2084,7 +2084,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->cfg->trans.csr->flag_mac_access_req)); + BIT(trans->trans_cfg->csr->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 @@ -2191,7 +2191,7 @@ static void iwl_trans_pcie_block_txq_ptrs(struct iwl_trans *trans, bool block) struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); int i; - for (i = 0; i < trans->cfg->trans.base_params->num_of_queues; i++) { + for (i = 0; i < trans->trans_cfg->base_params->num_of_queues; i++) { struct iwl_txq *txq = trans_pcie->txq[i]; if (i == trans_pcie->cmd_queue) @@ -2222,7 +2222,7 @@ void iwl_trans_pcie_log_scd_error(struct iwl_trans *trans, struct iwl_txq *txq) bool active; u8 fifo; - if (trans->cfg->trans.use_tfh) { + if (trans->trans_cfg->use_tfh) { IWL_ERR(trans, "Queue %d is stuck %d %d\n", txq_id, txq->read_ptr, txq->write_ptr); /* TODO: access new SCD registers and dump them */ @@ -2239,10 +2239,10 @@ void iwl_trans_pcie_log_scd_error(struct iwl_trans *trans, struct iwl_txq *txq) jiffies_to_msecs(txq->wd_timeout), txq->read_ptr, txq->write_ptr, iwl_read_prph(trans, SCD_QUEUE_RDPTR(txq_id)) & - (trans->cfg->trans.base_params->max_tfd_queue_size - 1), - iwl_read_prph(trans, SCD_QUEUE_WRPTR(txq_id)) & - (trans->cfg->trans.base_params->max_tfd_queue_size - 1), - iwl_read_direct32(trans, FH_TX_TRB_REG(fifo))); + (trans->trans_cfg->base_params->max_tfd_queue_size - 1), + iwl_read_prph(trans, SCD_QUEUE_WRPTR(txq_id)) & + (trans->trans_cfg->base_params->max_tfd_queue_size - 1), + iwl_read_direct32(trans, FH_TX_TRB_REG(fifo))); } static int iwl_trans_pcie_rxq_dma_data(struct iwl_trans *trans, int queue, @@ -2331,7 +2331,7 @@ static int iwl_trans_pcie_wait_txqs_empty(struct iwl_trans *trans, u32 txq_bm) /* waiting for all the tx frames complete might take a while */ for (cnt = 0; - cnt < trans->cfg->trans.base_params->num_of_queues; + cnt < trans->trans_cfg->base_params->num_of_queues; cnt++) { if (cnt == trans_pcie->cmd_queue) @@ -2477,7 +2477,7 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file, size_t bufsz; bufsz = sizeof(char) * 75 * - trans->cfg->trans.base_params->num_of_queues; + trans->trans_cfg->base_params->num_of_queues; if (!trans_pcie->txq_memory) return -EAGAIN; @@ -2487,7 +2487,7 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file, return -ENOMEM; for (cnt = 0; - cnt < trans->cfg->trans.base_params->num_of_queues; + cnt < trans->trans_cfg->base_params->num_of_queues; cnt++) { txq = trans_pcie->txq[cnt]; pos += scnprintf(buf + pos, bufsz - pos, @@ -2958,7 +2958,7 @@ static u32 iwl_trans_pcie_fh_regs_dump(struct iwl_trans *trans, (*data)->len = cpu_to_le32(fh_regs_len); val = (void *)(*data)->data; - if (!trans->cfg->trans.gen2) + if (!trans->trans_cfg->gen2) for (i = FH_MEM_LOWER_BOUND; i < FH_MEM_UPPER_BOUND; i += sizeof(u32)) *val++ = cpu_to_le32(iwl_trans_pcie_read32(trans, i)); @@ -3006,7 +3006,7 @@ iwl_trans_pcie_dump_pointers(struct iwl_trans *trans, { u32 base, base_high, write_ptr, write_ptr_val, wrap_cnt; - if (trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_AX210) { + if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { base = DBGC_CUR_DBGBUF_BASE_ADDR_LSB; base_high = DBGC_CUR_DBGBUF_BASE_ADDR_MSB; write_ptr = DBGC_CUR_DBGBUF_STATUS; @@ -3026,7 +3026,7 @@ iwl_trans_pcie_dump_pointers(struct iwl_trans *trans, cpu_to_le32(iwl_read_prph(trans, wrap_cnt)); fw_mon_data->fw_mon_base_ptr = cpu_to_le32(iwl_read_prph(trans, base)); - if (trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_AX210) { + if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { fw_mon_data->fw_mon_base_high_ptr = cpu_to_le32(iwl_read_prph(trans, base_high)); write_ptr_val &= DBGC_CUR_DBGBUF_STATUS_OFFSET_MSK; @@ -3043,8 +3043,8 @@ iwl_trans_pcie_dump_monitor(struct iwl_trans *trans, if (trans->dbg.dest_tlv || (trans->dbg.num_blocks && - (trans->cfg->trans.device_family == IWL_DEVICE_FAMILY_7000 || - trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_AX210))) { + (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_7000 || + trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210))) { struct iwl_fw_error_dump_fw_mon *fw_mon_data; (*data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_FW_MONITOR); @@ -3127,7 +3127,7 @@ static int iwl_trans_get_fw_monitor_len(struct iwl_trans *trans, u32 *len) trans->dbg.dest_tlv->end_shift; /* Make "end" point to the actual end */ - if (trans->cfg->trans.device_family >= + if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_8000 || trans->dbg.dest_tlv->monitor_mode == MARBH_MODE) end += (1 << trans->dbg.dest_tlv->end_shift); @@ -3153,7 +3153,7 @@ static struct iwl_trans_dump_data u32 len, num_rbs = 0, monitor_len = 0; int i, ptr; bool dump_rbs = test_bit(STATUS_FW_ERROR, &trans->status) && - !trans->cfg->trans.mq_rx_supported && + !trans->trans_cfg->mq_rx_supported && dump_mask & BIT(IWL_FW_ERROR_DUMP_RB); if (!dump_mask) @@ -3178,7 +3178,7 @@ static struct iwl_trans_dump_data /* FH registers */ if (dump_mask & BIT(IWL_FW_ERROR_DUMP_FH_REGS)) { - if (trans->cfg->trans.gen2) + if (trans->trans_cfg->gen2) len += sizeof(*data) + (iwl_umac_prph(trans, FH_MEM_UPPER_BOUND_GEN2) - iwl_umac_prph(trans, FH_MEM_LOWER_BOUND_GEN2)); @@ -3202,7 +3202,7 @@ static struct iwl_trans_dump_data } /* Paged memory for gen2 HW */ - if (trans->cfg->trans.gen2 && dump_mask & BIT(IWL_FW_ERROR_DUMP_PAGING)) + if (trans->trans_cfg->gen2 && dump_mask & BIT(IWL_FW_ERROR_DUMP_PAGING)) for (i = 0; i < trans->init_dram.paging_cnt; i++) len += sizeof(*data) + sizeof(struct iwl_fw_error_dump_paging) + @@ -3257,7 +3257,7 @@ static struct iwl_trans_dump_data len += iwl_trans_pcie_dump_rbs(trans, &data, num_rbs); /* Paged memory for gen2 HW */ - if (trans->cfg->trans.gen2 && + if (trans->trans_cfg->gen2 && dump_mask & BIT(IWL_FW_ERROR_DUMP_PAGING)) { for (i = 0; i < trans->init_dram.paging_cnt; i++) { struct iwl_fw_error_dump_paging *paging; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c index 3fb688826302..8894027429d6 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c @@ -113,7 +113,7 @@ void iwl_pcie_gen2_update_byte_tbl(struct iwl_trans_pcie *trans_pcie, */ num_fetch_chunks = DIV_ROUND_UP(filled_tfd_size, 64) - 1; - if (trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_22560) { + if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560) { /* Starting from 22560, the HW expects bytes */ WARN_ON(trans_pcie->bc_table_dword); WARN_ON(len > 0x3FFF); @@ -547,7 +547,7 @@ struct iwl_tfh_tfd *iwl_pcie_gen2_build_tfd(struct iwl_trans *trans, memset(tfd, 0, sizeof(*tfd)); - if (trans->cfg->trans.device_family < IWL_DEVICE_FAMILY_22560) + if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_22560) len = sizeof(struct iwl_tx_cmd_gen2); else len = sizeof(struct iwl_tx_cmd_gen3); @@ -629,7 +629,7 @@ int iwl_trans_pcie_gen2_tx(struct iwl_trans *trans, struct sk_buff *skb, return -1; } - if (trans->cfg->trans.device_family >= IWL_DEVICE_FAMILY_22560) { + if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560) { struct iwl_tx_cmd_gen3 *tx_cmd_gen3 = (void *)dev_cmd->payload; @@ -1129,7 +1129,7 @@ int iwl_trans_pcie_dyn_txq_alloc_dma(struct iwl_trans *trans, if (!txq) return -ENOMEM; ret = iwl_pcie_alloc_dma_ptr(trans, &txq->bc_tbl, - (trans->cfg->trans.device_family >= + (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560) ? sizeof(struct iwl_gen3_bc_tbl) : sizeof(struct iwlagn_scd_bc_tbl)); @@ -1193,7 +1193,7 @@ int iwl_trans_pcie_txq_alloc_response(struct iwl_trans *trans, txq->id = qid; trans_pcie->txq[qid] = txq; - wr_ptr &= (trans->cfg->trans.base_params->max_tfd_queue_size - 1); + wr_ptr &= (trans->trans_cfg->base_params->max_tfd_queue_size - 1); /* Place first TFD at index corresponding to start sequence number */ txq->read_ptr = wr_ptr; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c index 774c8bfe8450..5787cdefacd6 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c @@ -113,17 +113,17 @@ int iwl_queue_space(struct iwl_trans *trans, const struct iwl_txq *q) * If q->n_window is smaller than max_tfd_queue_size, there is no need * to reserve any queue entries for this purpose. */ - if (q->n_window < trans->cfg->trans.base_params->max_tfd_queue_size) + if (q->n_window < trans->trans_cfg->base_params->max_tfd_queue_size) max = q->n_window; else - max = trans->cfg->trans.base_params->max_tfd_queue_size - 1; + max = trans->trans_cfg->base_params->max_tfd_queue_size - 1; /* * max_tfd_queue_size is a power of 2, so the following is equivalent to * modulo by max_tfd_queue_size and is well defined. */ used = (q->write_ptr - q->read_ptr) & - (trans->cfg->trans.base_params->max_tfd_queue_size - 1); + (trans->trans_cfg->base_params->max_tfd_queue_size - 1); if (WARN_ON(used > max)) return 0; @@ -292,7 +292,7 @@ static void iwl_pcie_txq_inc_wr_ptr(struct iwl_trans *trans, * 2. NIC is woken up for CMD regardless of shadow outside this function * 3. there is a chance that the NIC is asleep */ - if (!trans->cfg->trans.base_params->shadow_reg_enable && + if (!trans->trans_cfg->base_params->shadow_reg_enable && txq_id != trans_pcie->cmd_queue && test_bit(STATUS_TPOWER_PMI, &trans->status)) { /* @@ -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->cfg->trans.csr->flag_mac_access_req)); + BIT(trans->trans_cfg->csr->flag_mac_access_req)); txq->need_update = true; return; } @@ -327,7 +327,7 @@ void iwl_pcie_txq_check_wrptrs(struct iwl_trans *trans) struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); int i; - for (i = 0; i < trans->cfg->trans.base_params->num_of_queues; i++) { + for (i = 0; i < trans->trans_cfg->base_params->num_of_queues; i++) { struct iwl_txq *txq = trans_pcie->txq[i]; if (!test_bit(i, trans_pcie->queue_used)) @@ -346,7 +346,7 @@ static inline dma_addr_t iwl_pcie_tfd_tb_get_addr(struct iwl_trans *trans, void *_tfd, u8 idx) { - if (trans->cfg->trans.use_tfh) { + if (trans->trans_cfg->use_tfh) { struct iwl_tfh_tfd *tfd = _tfd; struct iwl_tfh_tb *tb = &tfd->tbs[idx]; @@ -389,7 +389,7 @@ static inline void iwl_pcie_tfd_set_tb(struct iwl_trans *trans, void *tfd, static inline u8 iwl_pcie_tfd_get_num_tbs(struct iwl_trans *trans, void *_tfd) { - if (trans->cfg->trans.use_tfh) { + if (trans->trans_cfg->use_tfh) { struct iwl_tfh_tfd *tfd = _tfd; return le16_to_cpu(tfd->num_tbs) & 0x1f; @@ -436,7 +436,7 @@ static void iwl_pcie_tfd_unmap(struct iwl_trans *trans, meta->tbs = 0; - if (trans->cfg->trans.use_tfh) { + if (trans->trans_cfg->use_tfh) { struct iwl_tfh_tfd *tfd_fh = (void *)tfd; tfd_fh->num_tbs = 0; @@ -524,14 +524,14 @@ int iwl_pcie_txq_alloc(struct iwl_trans *trans, struct iwl_txq *txq, { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); size_t tfd_sz = trans_pcie->tfd_size * - trans->cfg->trans.base_params->max_tfd_queue_size; + trans->trans_cfg->base_params->max_tfd_queue_size; size_t tb0_buf_sz; int i; if (WARN_ON(txq->entries || txq->tfds)) return -EINVAL; - if (trans->cfg->trans.use_tfh) + if (trans->trans_cfg->use_tfh) tfd_sz = trans_pcie->tfd_size * slots_num; timer_setup(&txq->stuck_timer, iwl_pcie_txq_stuck_timer, 0); @@ -591,7 +591,7 @@ int iwl_pcie_txq_init(struct iwl_trans *trans, struct iwl_txq *txq, { int ret; u32 tfd_queue_max_size = - trans->cfg->trans.base_params->max_tfd_queue_size; + trans->trans_cfg->base_params->max_tfd_queue_size; txq->need_update = false; @@ -639,14 +639,14 @@ static void iwl_pcie_clear_cmd_in_flight(struct iwl_trans *trans) lockdep_assert_held(&trans_pcie->reg_lock); - if (!trans->cfg->trans.base_params->apmg_wake_up_wa) + if (!trans->trans_cfg->base_params->apmg_wake_up_wa) return; if (WARN_ON(!trans_pcie->cmd_hold_nic_awake)) return; trans_pcie->cmd_hold_nic_awake = false; __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL, - BIT(trans->cfg->trans.csr->flag_mac_access_req)); + BIT(trans->trans_cfg->csr->flag_mac_access_req)); } /* @@ -726,7 +726,7 @@ static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id) if (txq->tfds) { dma_free_coherent(dev, trans_pcie->tfd_size * - trans->cfg->trans.base_params->max_tfd_queue_size, + trans->trans_cfg->base_params->max_tfd_queue_size, txq->tfds, txq->dma_addr); txq->dma_addr = 0; txq->tfds = NULL; @@ -748,7 +748,7 @@ static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id) void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - int nq = trans->cfg->trans.base_params->num_of_queues; + int nq = trans->trans_cfg->base_params->num_of_queues; int chan; u32 reg_val; int clear_dwords = (SCD_TRANS_TBL_OFFSET_QUEUE(nq) - @@ -775,7 +775,7 @@ void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr) /* The chain extension of the SCD doesn't work well. This feature is * enabled by default by the HW, so we need to disable it manually. */ - if (trans->cfg->trans.base_params->scd_chain_ext_wa) + if (trans->trans_cfg->base_params->scd_chain_ext_wa) iwl_write_prph(trans, SCD_CHAINEXT_EN, 0); iwl_trans_ac_txq_enable(trans, trans_pcie->cmd_queue, @@ -797,7 +797,7 @@ void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr) reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN); /* Enable L1-Active */ - if (trans->cfg->trans.device_family < IWL_DEVICE_FAMILY_8000) + if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_8000) iwl_clear_bits_prph(trans, APMG_PCIDEV_STT_REG, APMG_PCIDEV_STT_VAL_L1_ACT_DIS); } @@ -811,13 +811,13 @@ void iwl_trans_pcie_tx_reset(struct iwl_trans *trans) * we should never get here in gen2 trans mode return early to avoid * having invalid accesses */ - if (WARN_ON_ONCE(trans->cfg->trans.gen2)) + if (WARN_ON_ONCE(trans->trans_cfg->gen2)) return; - for (txq_id = 0; txq_id < trans->cfg->trans.base_params->num_of_queues; + for (txq_id = 0; txq_id < trans->trans_cfg->base_params->num_of_queues; txq_id++) { struct iwl_txq *txq = trans_pcie->txq[txq_id]; - if (trans->cfg->trans.use_tfh) + if (trans->trans_cfg->use_tfh) iwl_write_direct64(trans, FH_MEM_CBBC_QUEUE(trans, txq_id), txq->dma_addr); @@ -900,7 +900,7 @@ int iwl_pcie_tx_stop(struct iwl_trans *trans) return 0; /* Unmap DMA from host system and free skb's */ - for (txq_id = 0; txq_id < trans->cfg->trans.base_params->num_of_queues; + for (txq_id = 0; txq_id < trans->trans_cfg->base_params->num_of_queues; txq_id++) iwl_pcie_txq_unmap(trans, txq_id); @@ -922,7 +922,7 @@ void iwl_pcie_tx_free(struct iwl_trans *trans) /* Tx queues */ if (trans_pcie->txq_memory) { for (txq_id = 0; - txq_id < trans->cfg->trans.base_params->num_of_queues; + txq_id < trans->trans_cfg->base_params->num_of_queues; txq_id++) { iwl_pcie_txq_free(trans, txq_id); trans_pcie->txq[txq_id] = NULL; @@ -946,9 +946,9 @@ static int iwl_pcie_tx_alloc(struct iwl_trans *trans) int ret; int txq_id, slots_num; struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - u16 bc_tbls_size = trans->cfg->trans.base_params->num_of_queues; + u16 bc_tbls_size = trans->trans_cfg->base_params->num_of_queues; - bc_tbls_size *= (trans->cfg->trans.device_family >= + bc_tbls_size *= (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560) ? sizeof(struct iwl_gen3_bc_tbl) : sizeof(struct iwlagn_scd_bc_tbl); @@ -975,7 +975,7 @@ static int iwl_pcie_tx_alloc(struct iwl_trans *trans) } trans_pcie->txq_memory = - kcalloc(trans->cfg->trans.base_params->num_of_queues, + kcalloc(trans->trans_cfg->base_params->num_of_queues, sizeof(struct iwl_txq), GFP_KERNEL); if (!trans_pcie->txq_memory) { IWL_ERR(trans, "Not enough memory for txq\n"); @@ -984,7 +984,7 @@ static int iwl_pcie_tx_alloc(struct iwl_trans *trans) } /* Alloc and init all Tx queues, including the command queue (#4/#9) */ - for (txq_id = 0; txq_id < trans->cfg->trans.base_params->num_of_queues; + for (txq_id = 0; txq_id < trans->trans_cfg->base_params->num_of_queues; txq_id++) { bool cmd_queue = (txq_id == trans_pcie->cmd_queue); @@ -1038,7 +1038,7 @@ int iwl_pcie_tx_init(struct iwl_trans *trans) spin_unlock(&trans_pcie->irq_lock); /* Alloc and init all Tx queues, including the command queue (#4/#9) */ - for (txq_id = 0; txq_id < trans->cfg->trans.base_params->num_of_queues; + for (txq_id = 0; txq_id < trans->trans_cfg->base_params->num_of_queues; txq_id++) { bool cmd_queue = (txq_id == trans_pcie->cmd_queue); @@ -1066,7 +1066,7 @@ int iwl_pcie_tx_init(struct iwl_trans *trans) } iwl_set_bits_prph(trans, SCD_GP_CTRL, SCD_GP_CTRL_AUTO_ACTIVE_MODE); - if (trans->cfg->trans.base_params->num_of_queues > 20) + if (trans->trans_cfg->base_params->num_of_queues > 20) iwl_set_bits_prph(trans, SCD_GP_CTRL, SCD_GP_CTRL_ENABLE_31_QUEUES); @@ -1138,7 +1138,7 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn, IWL_ERR(trans, "%s: Read index for txq id (%d), last_to_free %d is out of range [0-%d] %d %d.\n", __func__, txq_id, last_to_free, - trans->cfg->trans.base_params->max_tfd_queue_size, + trans->trans_cfg->base_params->max_tfd_queue_size, txq->write_ptr, txq->read_ptr); goto out; } @@ -1161,7 +1161,7 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn, txq->entries[read_ptr].skb = NULL; - if (!trans->cfg->trans.use_tfh) + if (!trans->trans_cfg->use_tfh) iwl_pcie_txq_inval_byte_cnt_tbl(trans, txq); iwl_pcie_txq_free_tfd(trans, txq); @@ -1295,12 +1295,12 @@ void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx) idx = iwl_pcie_get_cmd_index(txq, idx); r = iwl_pcie_get_cmd_index(txq, txq->read_ptr); - if (idx >= trans->cfg->trans.base_params->max_tfd_queue_size || + if (idx >= trans->trans_cfg->base_params->max_tfd_queue_size || (!iwl_queue_used(txq, idx))) { WARN_ONCE(test_bit(txq_id, trans_pcie->queue_used), "%s: Read index for DMA queue txq id (%d), index %d is out of range [0-%d] %d %d.\n", __func__, txq_id, idx, - trans->cfg->trans.base_params->max_tfd_queue_size, + trans->trans_cfg->base_params->max_tfd_queue_size, txq->write_ptr, txq->read_ptr); return; } @@ -1414,7 +1414,7 @@ bool iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn, * this sad hardware issue. * This bug has been fixed on devices 9000 and up. */ - scd_bug = !trans->cfg->trans.mq_rx_supported && + scd_bug = !trans->trans_cfg->mq_rx_supported && !((ssn - txq->write_ptr) & 0x3f) && (ssn != txq->write_ptr); if (scd_bug) From d8913b803f3a7fbcfbe4e8b1d598a0bee7637139 Mon Sep 17 00:00:00 2001 From: Shaul Triebitz Date: Mon, 21 May 2018 18:39:23 -0400 Subject: [PATCH 66/80] iwlwifi: pass the iwl_trans instead of cfg to some functions A few functions were receiving the iwl_cfg struct directly, but we will also need other parts of the trans, so pass the trans (which includes the cfg) to them. Signed-off-by: Ido Yariv Signed-off-by: Shaul Triebitz Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c index e43e452403f5..83d4311e83d7 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c @@ -393,11 +393,12 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg, return n_channels; } -static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg, +static void iwl_init_vht_hw_capab(struct iwl_trans *trans, struct iwl_nvm_data *data, struct ieee80211_sta_vht_cap *vht_cap, u8 tx_chains, u8 rx_chains) { + const struct iwl_cfg *cfg = trans->cfg; int num_rx_ants = num_of_ant(rx_chains); int num_tx_ants = num_of_ant(tx_chains); unsigned int max_ampdu_exponent = (cfg->max_vht_ampdu_exponent ?: @@ -669,11 +670,13 @@ static void iwl_init_he_hw_capab(struct ieee80211_supported_band *sband, } } -static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg, +static void iwl_init_sbands(struct iwl_trans *trans, struct iwl_nvm_data *data, const void *nvm_ch_flags, u8 tx_chains, u8 rx_chains, u32 sbands_flags, bool v4) { + struct device *dev = trans->dev; + const struct iwl_cfg *cfg = trans->cfg; int n_channels; int n_used = 0; struct ieee80211_supported_band *sband; @@ -701,7 +704,7 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg, iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, NL80211_BAND_5GHZ, tx_chains, rx_chains); if (data->sku_cap_11ac_enable && !iwlwifi_mod_params.disable_11ac) - iwl_init_vht_hw_capab(cfg, data, &sband->vht_cap, + iwl_init_vht_hw_capab(trans, data, &sband->vht_cap, tx_chains, rx_chains); if (data->sku_cap_11ax_enable && !iwlwifi_mod_params.disable_11ax) @@ -1019,7 +1022,7 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg, if (iwl_nvm_no_wide_in_5ghz(dev, cfg, nvm_hw)) sbands_flags |= IWL_NVM_SBANDS_FLAGS_NO_WIDE_IN_5GHZ; - iwl_init_sbands(dev, cfg, data, ch_section, tx_chains, rx_chains, + iwl_init_sbands(trans, data, ch_section, tx_chains, rx_chains, sbands_flags, false); data->calib_version = 255; @@ -1485,7 +1488,7 @@ struct iwl_nvm_data *iwl_get_nvm(struct iwl_trans *trans, channel_profile = v4 ? (void *)rsp->regulatory.channel_profile : (void *)rsp_v3->regulatory.channel_profile; - iwl_init_sbands(trans->dev, trans->cfg, nvm, + iwl_init_sbands(trans, nvm, channel_profile, nvm->valid_tx_ant & fw->valid_tx_ant, nvm->valid_rx_ant & fw->valid_rx_ant, From 7d34a7d7da97bc8e0039b07d56390ea555c4858c Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Fri, 12 Jul 2019 15:52:39 +0300 Subject: [PATCH 67/80] iwlwifi: always access the trans configuration via trans Stop accessing the trans configuration via the iwl_cfg structure and always access it via the iwl_trans structure. This completes the requirements to disassociate the trans-specific configuration from the rest of the configuration. Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/dvm/devices.c | 2 +- drivers/net/wireless/intel/iwlwifi/dvm/led.c | 4 ++-- .../net/wireless/intel/iwlwifi/dvm/mac80211.c | 2 +- drivers/net/wireless/intel/iwlwifi/dvm/main.c | 10 +++++----- drivers/net/wireless/intel/iwlwifi/dvm/power.c | 2 +- drivers/net/wireless/intel/iwlwifi/dvm/tx.c | 4 ++-- .../wireless/intel/iwlwifi/iwl-eeprom-parse.c | 17 ++++++++++------- .../wireless/intel/iwlwifi/iwl-eeprom-parse.h | 4 ++-- .../wireless/intel/iwlwifi/iwl-eeprom-read.c | 2 +- .../net/wireless/intel/iwlwifi/iwl-nvm-parse.c | 17 ++++++++--------- drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/led.c | 2 +- .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/nvm.c | 4 ++-- drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/utils.c | 6 +++--- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 11 +++++++---- .../wireless/intel/iwlwifi/pcie/trans-gen2.c | 2 +- drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 6 +++--- drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 11 +++++------ 21 files changed, 59 insertions(+), 55 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/devices.c b/drivers/net/wireless/intel/iwlwifi/dvm/devices.c index 73b3a947ab7a..dc3f197f94d9 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/devices.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/devices.c @@ -484,7 +484,7 @@ static void iwl6000_set_ct_threshold(struct iwl_priv *priv) /* NIC configuration for 6000 series */ static void iwl6000_nic_config(struct iwl_priv *priv) { - switch (priv->cfg->trans.device_family) { + switch (priv->trans->trans_cfg->device_family) { case IWL_DEVICE_FAMILY_6005: case IWL_DEVICE_FAMILY_6030: case IWL_DEVICE_FAMILY_6000: diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/led.c b/drivers/net/wireless/intel/iwlwifi/dvm/led.c index 1e1664ecf30b..dd387aba3317 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/led.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/led.c @@ -121,9 +121,9 @@ static int iwl_led_cmd(struct iwl_priv *priv, } led_cmd.on = iwl_blink_compensation(priv, on, - priv->cfg->trans.base_params->led_compensation); + priv->trans->trans_cfg->base_params->led_compensation); led_cmd.off = iwl_blink_compensation(priv, off, - priv->cfg->trans.base_params->led_compensation); + priv->trans->trans_cfg->base_params->led_compensation); ret = iwl_send_led_cmd(priv, &led_cmd); if (!ret) { diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c index c223f26f046e..6512d25e3563 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c @@ -1099,7 +1099,7 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, goto done; } - scd_queues = BIT(priv->cfg->trans.base_params->num_of_queues) - 1; + scd_queues = BIT(priv->trans->trans_cfg->base_params->num_of_queues) - 1; scd_queues &= ~(BIT(IWL_IPAN_CMD_QUEUE_NUM) | BIT(IWL_DEFAULT_CMD_QUEUE_NUM)); diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/main.c b/drivers/net/wireless/intel/iwlwifi/dvm/main.c index 8e47a075089f..4f2789bb3b5b 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/main.c @@ -1267,7 +1267,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, priv->cfg = cfg; priv->fw = fw; - switch (priv->cfg->trans.device_family) { + switch (priv->trans->trans_cfg->device_family) { case IWL_DEVICE_FAMILY_1000: case IWL_DEVICE_FAMILY_100: priv->lib = &iwl_dvm_1000_cfg; @@ -1342,7 +1342,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, driver_data[2]); WARN_ON(sizeof(priv->transport_queue_stop) * BITS_PER_BYTE < - priv->cfg->trans.base_params->num_of_queues); + priv->trans->trans_cfg->base_params->num_of_queues); ucode_flags = fw->ucode_capa.flags; @@ -1405,9 +1405,9 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, /* Reset chip to save power until we load uCode during "up". */ iwl_trans_stop_device(priv->trans); - priv->nvm_data = iwl_parse_eeprom_data(priv->trans->dev, priv->cfg, - priv->eeprom_blob, - priv->eeprom_blob_size); + priv->nvm_data = iwl_parse_eeprom_data(priv->trans, priv->cfg, + priv->eeprom_blob, + priv->eeprom_blob_size); if (!priv->nvm_data) goto out_free_eeprom_blob; diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/power.c b/drivers/net/wireless/intel/iwlwifi/dvm/power.c index e4e02fcbcd9f..93ef023905c9 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/power.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/power.c @@ -200,7 +200,7 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv, else cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK; - if (priv->cfg->trans.base_params->shadow_reg_enable) + if (priv->trans->trans_cfg->base_params->shadow_reg_enable) cmd->flags |= IWL_POWER_SHADOW_REG_ENA; else cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA; diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/tx.c b/drivers/net/wireless/intel/iwlwifi/dvm/tx.c index 75dc911b8f00..3029e3f6de63 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/tx.c @@ -468,7 +468,7 @@ static int iwlagn_alloc_agg_txq(struct iwl_priv *priv, int mq) int q; for (q = IWLAGN_FIRST_AMPDU_QUEUE; - q < priv->cfg->trans.base_params->num_of_queues; q++) { + q < priv->trans->trans_cfg->base_params->num_of_queues; q++) { if (!test_and_set_bit(q, priv->agg_q_alloc)) { priv->queue_to_mac80211[q] = mq; return q; @@ -1282,7 +1282,7 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, * (in Tx queue's circular buffer) of first TFD/frame in window */ u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn); - if (scd_flow >= priv->cfg->trans.base_params->num_of_queues) { + if (scd_flow >= priv->trans->trans_cfg->base_params->num_of_queues) { IWL_ERR(priv, "BUG_ON scd_flow is bigger than number of queues\n"); return; diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c index 75e7053f6807..cf7e2a9232e5 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c @@ -728,12 +728,13 @@ int iwl_init_sband_channels(struct iwl_nvm_data *data, #define MAX_BIT_RATE_40_MHZ 150 /* Mbps */ #define MAX_BIT_RATE_20_MHZ 72 /* Mbps */ -void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg, +void iwl_init_ht_hw_capab(struct iwl_trans *trans, struct iwl_nvm_data *data, struct ieee80211_sta_ht_cap *ht_info, enum nl80211_band band, u8 tx_chains, u8 rx_chains) { + const struct iwl_cfg *cfg = trans->cfg; int max_bit_rate = 0; tx_chains = hweight8(tx_chains); @@ -765,7 +766,7 @@ void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg, if (cfg->ht_params->ldpc) ht_info->cap |= IEEE80211_HT_CAP_LDPC_CODING; - if ((cfg->trans.mq_rx_supported && + if ((trans->trans_cfg->mq_rx_supported && iwlwifi_mod_params.amsdu_size == IWL_AMSDU_DEF) || iwlwifi_mod_params.amsdu_size >= IWL_AMSDU_8K) ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU; @@ -805,10 +806,11 @@ void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg, } } -static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg, +static void iwl_init_sbands(struct iwl_trans *trans, const struct iwl_cfg *cfg, struct iwl_nvm_data *data, const u8 *eeprom, size_t eeprom_size) { + struct device *dev = trans->dev; int n_channels = iwl_init_channel_map(dev, cfg, data, eeprom, eeprom_size); int n_used = 0; @@ -820,7 +822,7 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg, sband->n_bitrates = N_RATES_24; n_used += iwl_init_sband_channels(data, sband, n_channels, NL80211_BAND_2GHZ); - iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, NL80211_BAND_2GHZ, + iwl_init_ht_hw_capab(trans, data, &sband->ht_cap, NL80211_BAND_2GHZ, data->valid_tx_ant, data->valid_rx_ant); sband = &data->bands[NL80211_BAND_5GHZ]; @@ -829,7 +831,7 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg, sband->n_bitrates = N_RATES_52; n_used += iwl_init_sband_channels(data, sband, n_channels, NL80211_BAND_5GHZ); - iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, NL80211_BAND_5GHZ, + iwl_init_ht_hw_capab(trans, data, &sband->ht_cap, NL80211_BAND_5GHZ, data->valid_tx_ant, data->valid_rx_ant); if (n_channels != n_used) @@ -840,10 +842,11 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg, /* EEPROM data functions */ struct iwl_nvm_data * -iwl_parse_eeprom_data(struct device *dev, const struct iwl_cfg *cfg, +iwl_parse_eeprom_data(struct iwl_trans *trans, const struct iwl_cfg *cfg, const u8 *eeprom, size_t eeprom_size) { struct iwl_nvm_data *data; + struct device *dev = trans->dev; const void *tmp; u16 radio_cfg, sku; @@ -918,7 +921,7 @@ iwl_parse_eeprom_data(struct device *dev, const struct iwl_cfg *cfg, goto err_free; } - iwl_init_sbands(dev, cfg, data, eeprom, eeprom_size); + iwl_init_sbands(trans, cfg, data, eeprom, eeprom_size); return data; err_free: diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.h b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.h index 2375d300a7cd..03a748cc98fa 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.h @@ -116,14 +116,14 @@ struct iwl_nvm_data { * later with iwl_free_nvm_data(). */ struct iwl_nvm_data * -iwl_parse_eeprom_data(struct device *dev, const struct iwl_cfg *cfg, +iwl_parse_eeprom_data(struct iwl_trans *trans, const struct iwl_cfg *cfg, const u8 *eeprom, size_t eeprom_size); int iwl_init_sband_channels(struct iwl_nvm_data *data, struct ieee80211_supported_band *sband, int n_channels, enum nl80211_band band); -void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg, +void iwl_init_ht_hw_capab(struct iwl_trans *trans, struct iwl_nvm_data *data, struct ieee80211_sta_ht_cap *ht_info, enum nl80211_band band, diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c index 80bc2e44c7b1..ad6dc4497437 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c @@ -193,7 +193,7 @@ static int iwl_init_otp_access(struct iwl_trans *trans) { int ret; - ret = iwl_finish_nic_init(trans, &trans->cfg->trans); + ret = iwl_finish_nic_init(trans, trans->trans_cfg); if (ret) return ret; diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c index 83d4311e83d7..c8972f6e38ba 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c @@ -435,14 +435,14 @@ static void iwl_init_vht_hw_capab(struct iwl_trans *trans, switch (iwlwifi_mod_params.amsdu_size) { case IWL_AMSDU_DEF: - if (cfg->trans.mq_rx_supported) + if (trans->trans_cfg->mq_rx_supported) vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454; else vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895; break; case IWL_AMSDU_2K: - if (cfg->trans.mq_rx_supported) + if (trans->trans_cfg->mq_rx_supported) vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454; else @@ -689,7 +689,7 @@ static void iwl_init_sbands(struct iwl_trans *trans, sband->n_bitrates = N_RATES_24; n_used += iwl_init_sband_channels(data, sband, n_channels, NL80211_BAND_2GHZ); - iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, NL80211_BAND_2GHZ, + iwl_init_ht_hw_capab(trans, data, &sband->ht_cap, NL80211_BAND_2GHZ, tx_chains, rx_chains); if (data->sku_cap_11ax_enable && !iwlwifi_mod_params.disable_11ax) @@ -701,7 +701,7 @@ static void iwl_init_sbands(struct iwl_trans *trans, sband->n_bitrates = N_RATES_52; n_used += iwl_init_sband_channels(data, sband, n_channels, NL80211_BAND_5GHZ); - iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, NL80211_BAND_5GHZ, + iwl_init_ht_hw_capab(trans, data, &sband->ht_cap, NL80211_BAND_5GHZ, tx_chains, rx_chains); if (data->sku_cap_11ac_enable && !iwlwifi_mod_params.disable_11ac) iwl_init_vht_hw_capab(trans, data, &sband->vht_cap, @@ -899,7 +899,7 @@ static int iwl_set_hw_address(struct iwl_trans *trans, } static bool -iwl_nvm_no_wide_in_5ghz(struct device *dev, const struct iwl_cfg *cfg, +iwl_nvm_no_wide_in_5ghz(struct iwl_trans *trans, const struct iwl_cfg *cfg, const __be16 *nvm_hw) { /* @@ -911,7 +911,7 @@ iwl_nvm_no_wide_in_5ghz(struct device *dev, const struct iwl_cfg *cfg, * in 5GHz otherwise the FW will throw a sysassert when we try * to use them. */ - if (cfg->trans.device_family == IWL_DEVICE_FAMILY_7000) { + if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_7000) { /* * Unlike the other sections in the NVM, the hw * section uses big-endian. @@ -920,7 +920,7 @@ iwl_nvm_no_wide_in_5ghz(struct device *dev, const struct iwl_cfg *cfg, u8 sku = (subsystem_id & 0x1e) >> 1; if (sku == 5 || sku == 9) { - IWL_DEBUG_EEPROM(dev, + IWL_DEBUG_EEPROM(trans->dev, "disabling wide channels in 5GHz (0x%0x %d)\n", subsystem_id, sku); return true; @@ -937,7 +937,6 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg, const __le16 *mac_override, const __le16 *phy_sku, u8 tx_chains, u8 rx_chains, bool lar_fw_supported) { - struct device *dev = trans->dev; struct iwl_nvm_data *data; bool lar_enabled; u32 sku, radio_cfg; @@ -1019,7 +1018,7 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg, if (lar_fw_supported && lar_enabled) sbands_flags |= IWL_NVM_SBANDS_FLAGS_LAR; - if (iwl_nvm_no_wide_in_5ghz(dev, cfg, nvm_hw)) + if (iwl_nvm_no_wide_in_5ghz(trans, cfg, nvm_hw)) sbands_flags |= IWL_NVM_SBANDS_FLAGS_NO_WIDE_IN_5GHZ; iwl_init_sbands(trans, data, ch_section, tx_chains, rx_chains, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index fcb51cb3010e..f93d50ceca68 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -558,7 +558,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) goto remove_notif; } - if (mvm->cfg->trans.device_family < IWL_DEVICE_FAMILY_8000) { + if (mvm->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_8000) { ret = iwl_mvm_send_bt_init_conf(mvm); if (ret) goto remove_notif; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/led.c b/drivers/net/wireless/intel/iwlwifi/mvm/led.c index 64298aec893a..d104da9170ca 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/led.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/led.c @@ -156,7 +156,7 @@ void iwl_mvm_leds_sync(struct iwl_mvm *mvm) * if we control through the register, we're doing it * even when the firmware isn't up, so no need to sync */ - if (mvm->cfg->trans.device_family < IWL_DEVICE_FAMILY_8000) + if (mvm->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_8000) return; iwl_mvm_led_set(mvm, mvm->led.brightness > 0); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 98c9562647c3..bec48a55f890 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -400,7 +400,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) * for older devices. We also don't see this issue on any newer * devices. */ - if (mvm->cfg->trans.device_family >= IWL_DEVICE_FAMILY_9000) + if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_9000) ieee80211_hw_set(hw, TX_AMSDU); ieee80211_hw_set(hw, TX_FRAG_LIST); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 9e76d494c45c..2540d7ffbbc1 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -1922,7 +1922,7 @@ void iwl_mvm_vif_set_low_latency(struct iwl_mvm_vif *mvmvif, bool set, */ static inline u32 iwl_mvm_flushable_queues(struct iwl_mvm *mvm) { - return ((BIT(mvm->cfg->trans.base_params->num_of_queues) - 1) & + return ((BIT(mvm->trans->trans_cfg->base_params->num_of_queues) - 1) & ~BIT(IWL_MVM_DQA_CMD_QUEUE)); } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c index e2855efc2afd..945c1ea5cda8 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c @@ -249,7 +249,7 @@ static int iwl_nvm_read_section(struct iwl_mvm *mvm, u16 section, while (ret == length) { /* Check no memory assumptions fail and cause an overflow */ if ((size_read + offset + length) > - mvm->cfg->trans.base_params->eeprom_size) { + mvm->trans->trans_cfg->base_params->eeprom_size) { IWL_ERR(mvm, "EEPROM size is too small for NVM\n"); return -ENOBUFS; } @@ -372,7 +372,7 @@ int iwl_nvm_init(struct iwl_mvm *mvm) /* Read From FW NVM */ IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from NVM\n"); - nvm_buffer = kmalloc(mvm->cfg->trans.base_params->eeprom_size, + nvm_buffer = kmalloc(mvm->trans->trans_cfg->base_params->eeprom_size, GFP_KERNEL); if (!nvm_buffer) return -ENOMEM; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c index eaa8b1c9938a..0bedba4c61f2 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c @@ -1954,7 +1954,7 @@ static void iwl_mvm_enable_aux_snif_queue(struct iwl_mvm *mvm, u16 *queue, u8 sta_id, u8 fifo) { unsigned int wdg_timeout = iwlmvm_mod_params.tfd_q_hang_detect ? - mvm->cfg->trans.base_params->wd_timeout : + mvm->trans->trans_cfg->base_params->wd_timeout : IWL_WATCHDOG_DISABLED; if (iwl_mvm_has_new_tx_api(mvm)) { diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c index ba1524727a1f..8686107da116 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c @@ -531,7 +531,7 @@ static void iwl_mvm_dump_lmac_error_log(struct iwl_mvm *mvm, u8 lmac_num) /* reset the device */ iwl_trans_sw_reset(trans); - err = iwl_finish_nic_init(trans, &trans->cfg->trans); + err = iwl_finish_nic_init(trans, trans->trans_cfg); if (err) return; } @@ -941,7 +941,7 @@ unsigned int iwl_mvm_get_wd_timeout(struct iwl_mvm *mvm, struct iwl_fw_dbg_trigger_txq_timer *txq_timer; unsigned int default_timeout = cmd_q ? IWL_DEF_WD_TIMEOUT : - mvm->cfg->trans.base_params->wd_timeout; + mvm->trans->trans_cfg->base_params->wd_timeout; if (!iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_TXQ_TIMERS)) { /* @@ -985,7 +985,7 @@ unsigned int iwl_mvm_get_wd_timeout(struct iwl_mvm *mvm, return default_timeout; default: WARN_ON(1); - return mvm->cfg->trans.base_params->wd_timeout; + return mvm->trans->trans_cfg->base_params->wd_timeout; } } diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index e6a3fa2080e2..e5ca1f2685b6 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -997,9 +997,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) unsigned long flags; int ret; - if (WARN_ONCE(!cfg->trans.csr, "CSR addresses aren't configured\n")) - return -EINVAL; - iwl_trans = iwl_trans_pcie_alloc(pdev, ent, &cfg->trans); if (IS_ERR(iwl_trans)) return PTR_ERR(iwl_trans); @@ -1007,6 +1004,12 @@ 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. @@ -1129,7 +1132,7 @@ 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.device_family >= IWL_DEVICE_FAMILY_8000 && + 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/trans-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c index b6db3c42c467..df8455f14e4d 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c @@ -92,7 +92,7 @@ int iwl_pcie_gen2_apm_init(struct iwl_trans *trans) iwl_pcie_apm_config(trans); - ret = iwl_finish_nic_init(trans, &trans->cfg->trans); + ret = iwl_finish_nic_init(trans, trans->trans_cfg); if (ret) return ret; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index d2fe8ff45bbb..ae4f84016c3c 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -368,7 +368,7 @@ static int iwl_pcie_apm_init(struct iwl_trans *trans) if (trans->trans_cfg->base_params->pll_cfg) iwl_set_bit(trans, CSR_ANA_PLL_CFG, CSR50_ANA_PLL_CFG_VAL); - ret = iwl_finish_nic_init(trans, &trans->cfg->trans); + ret = iwl_finish_nic_init(trans, trans->trans_cfg); if (ret) return ret; @@ -440,7 +440,7 @@ static void iwl_pcie_apm_lp_xtal_enable(struct iwl_trans *trans) iwl_trans_pcie_sw_reset(trans); - ret = iwl_finish_nic_init(trans, &trans->cfg->trans); + ret = iwl_finish_nic_init(trans, trans->trans_cfg); if (WARN_ON(ret)) { /* Release XTAL ON request */ __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL, @@ -1534,7 +1534,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)); - ret = iwl_finish_nic_init(trans, &trans->cfg->trans); + ret = iwl_finish_nic_init(trans, trans->trans_cfg); if (ret) return ret; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c index 5787cdefacd6..4806a04cec8c 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c @@ -1238,7 +1238,6 @@ static int iwl_pcie_set_cmd_in_flight(struct iwl_trans *trans, const struct iwl_host_cmd *cmd) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - const struct iwl_cfg *cfg = trans->cfg; int ret; lockdep_assert_held(&trans_pcie->reg_lock); @@ -1253,19 +1252,19 @@ static int iwl_pcie_set_cmd_in_flight(struct iwl_trans *trans, * returned. This needs to be done only on NICs that have * apmg_wake_up_wa set. */ - if (cfg->trans.base_params->apmg_wake_up_wa && + 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(cfg->trans.csr->flag_mac_access_req)); + BIT(trans->trans_cfg->csr->flag_mac_access_req)); ret = iwl_poll_bit(trans, CSR_GP_CNTRL, - BIT(cfg->trans.csr->flag_val_mac_access_en), - (BIT(cfg->trans.csr->flag_mac_clock_ready) | + BIT(trans->trans_cfg->csr->flag_val_mac_access_en), + (BIT(trans->trans_cfg->csr->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(cfg->trans.csr->flag_mac_access_req)); + BIT(trans->trans_cfg->csr->flag_mac_access_req)); IWL_ERR(trans, "Failed to wake NIC for hcmd\n"); return -EIO; } From 973ef19e9d506963cb882b9450da3703cf5892c0 Mon Sep 17 00:00:00 2001 From: Hariprasad Kelam Date: Sun, 26 May 2019 17:08:16 +0530 Subject: [PATCH 68/80] iwlwifi: fix warning iwl-trans.h is included more than once Remove duplicate inclusion of iwl-trans.h. This issue was found by includecheck. Signed-off-by: Hariprasad Kelam Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h index cba958eb5186..fc8bc212ee84 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h @@ -75,7 +75,6 @@ static inline size_t iwl_rx_trace_len(const struct iwl_trans *trans, #include #include -#include "iwl-trans.h" #if !defined(CONFIG_IWLWIFI_DEVICE_TRACING) || defined(__CHECKER__) From e5f3f215d07f0f802373a123cbd29c6387aa818d Mon Sep 17 00:00:00 2001 From: Haim Dreyfuss Date: Wed, 3 Apr 2019 14:37:54 +0300 Subject: [PATCH 69/80] iwlwifi: add support for suspend-resume flow for new device generation The new device generation has a slightly different suspend resume flow Currently, the way the driver instruct the device to move to D3 is by sending D3_CONFIG_CMD. Instead of using the host command the indication is by writing to the doorbell interrupt. The FW will respond with interrupt to indicate transition completion. Signed-off-by: Haim Dreyfuss Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/iwl-prph.h | 5 ++ .../net/wireless/intel/iwlwifi/iwl-trans.h | 12 ++-- drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 20 +++--- .../wireless/intel/iwlwifi/pcie/internal.h | 4 ++ drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 21 ++++-- .../net/wireless/intel/iwlwifi/pcie/trans.c | 69 ++++++++++++++++--- 6 files changed, 102 insertions(+), 29 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h index 8d930bfe0727..f47e0f97acf8 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h @@ -451,6 +451,8 @@ enum { #define UREG_DOORBELL_TO_ISR6 0xA05C04 #define UREG_DOORBELL_TO_ISR6_NMI_BIT BIT(0) +#define UREG_DOORBELL_TO_ISR6_SUSPEND BIT(18) +#define UREG_DOORBELL_TO_ISR6_RESUME BIT(19) #define FSEQ_ERROR_CODE 0xA340C8 #define FSEQ_TOP_INIT_VERSION 0xA34038 @@ -460,4 +462,7 @@ enum { #define FSEQ_ALIVE_TOKEN 0xA340F0 #define FSEQ_CNVI_ID 0xA3408C #define FSEQ_CNVR_ID 0xA34090 + +#define IWL_D3_SLEEP_STATUS_SUSPEND 0xD3 +#define IWL_D3_SLEEP_STATUS_RESUME 0xD0 #endif /* __iwl_prph_h__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h index 4152ae972aa7..b6c79f45d1ec 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h @@ -537,7 +537,7 @@ struct iwl_trans_ops { void (*fw_alive)(struct iwl_trans *trans, u32 scd_addr); void (*stop_device)(struct iwl_trans *trans); - void (*d3_suspend)(struct iwl_trans *trans, bool test, bool reset); + int (*d3_suspend)(struct iwl_trans *trans, bool test, bool reset); int (*d3_resume)(struct iwl_trans *trans, enum iwl_d3_status *status, bool test, bool reset); @@ -883,12 +883,14 @@ static inline void iwl_trans_stop_device(struct iwl_trans *trans) trans->state = IWL_TRANS_NO_FW; } -static inline void iwl_trans_d3_suspend(struct iwl_trans *trans, bool test, - bool reset) +static inline int iwl_trans_d3_suspend(struct iwl_trans *trans, bool test, + bool reset) { might_sleep(); - if (trans->ops->d3_suspend) - trans->ops->d3_suspend(trans, test, reset); + if (!trans->ops->d3_suspend) + return 0; + + return trans->ops->d3_suspend(trans, test, reset); } static inline int iwl_trans_d3_resume(struct iwl_trans *trans, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index cd7172d7f72e..66d610a2f3d6 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -1068,7 +1068,7 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status); - iwl_trans_d3_suspend(mvm->trans, test, !unified_image); + ret = iwl_trans_d3_suspend(mvm->trans, test, !unified_image); out: if (ret < 0) { iwl_mvm_free_nd(mvm); @@ -1930,15 +1930,6 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) if (IS_ERR_OR_NULL(vif)) goto err; - ret = iwl_trans_d3_resume(mvm->trans, &d3_status, test, !unified_image); - if (ret) - goto err; - - if (d3_status != IWL_D3_STATUS_ALIVE) { - IWL_INFO(mvm, "Device was reset during suspend\n"); - goto err; - } - iwl_fw_dbg_read_d3_debug_data(&mvm->fwrt); if (iwl_mvm_check_rt_status(mvm, vif)) { @@ -1950,6 +1941,15 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) goto err; } + ret = iwl_trans_d3_resume(mvm->trans, &d3_status, test, !unified_image); + if (ret) + goto err; + + if (d3_status != IWL_D3_STATUS_ALIVE) { + IWL_INFO(mvm, "Device was reset during suspend\n"); + goto err; + } + if (d0i3_first) { ret = iwl_mvm_send_cmd_pdu(mvm, D0I3_END_CMD, 0, 0, NULL); if (ret < 0) { diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h index f07559b3633a..1047d48beaa5 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h @@ -558,8 +558,10 @@ struct iwl_trans_pcie { void __iomem *hw_base; bool ucode_write_complete; + bool sx_complete; wait_queue_head_t ucode_write_waitq; wait_queue_head_t wait_command_queue; + wait_queue_head_t sx_waitq; u8 page_offs, dev_cmd_offs; @@ -1117,4 +1119,6 @@ void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans); void iwl_pcie_gen2_txq_unmap(struct iwl_trans *trans, int txq_id); void iwl_pcie_gen2_tx_free(struct iwl_trans *trans); void iwl_pcie_gen2_tx_stop(struct iwl_trans *trans); +void iwl_pcie_d3_complete_suspend(struct iwl_trans *trans, + bool test, bool reset); #endif /* __iwl_trans_int_pcie_h__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c index fce8c500ec02..19dd075f2f63 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c @@ -2196,12 +2196,23 @@ irqreturn_t iwl_pcie_irq_msix_handler(int irq, void *dev_id) iwl_pcie_irq_handle_error(trans); } } else if (inta_hw & MSIX_HW_INT_CAUSES_REG_WAKEUP) { - /* uCode wakes up after power-down sleep */ - IWL_DEBUG_ISR(trans, "Wakeup interrupt\n"); - iwl_pcie_rxq_check_wrptr(trans); - iwl_pcie_txq_check_wrptrs(trans); + u32 sleep_notif = + le32_to_cpu(trans_pcie->prph_info->sleep_notif); + if (sleep_notif == IWL_D3_SLEEP_STATUS_SUSPEND || + sleep_notif == IWL_D3_SLEEP_STATUS_RESUME) { + IWL_DEBUG_ISR(trans, + "Sx interrupt: sleep notification = 0x%x\n", + sleep_notif); + trans_pcie->sx_complete = true; + wake_up(&trans_pcie->sx_waitq); + } else { + /* uCode wakes up after power-down sleep */ + IWL_DEBUG_ISR(trans, "Wakeup interrupt\n"); + iwl_pcie_rxq_check_wrptr(trans); + iwl_pcie_txq_check_wrptrs(trans); - isr_stats->wakeup++; + isr_stats->wakeup++; + } } if (inta_hw & MSIX_HW_INT_CAUSES_REG_IML) { diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index ae4f84016c3c..5ab87a8dc907 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -1478,15 +1478,9 @@ void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state) } } -static void iwl_trans_pcie_d3_suspend(struct iwl_trans *trans, bool test, - bool reset) +void iwl_pcie_d3_complete_suspend(struct iwl_trans *trans, + bool test, bool reset) { - if (!reset) { - /* Enable persistence mode to avoid reset */ - iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG, - CSR_HW_IF_CONFIG_REG_PERSIST_MODE); - } - iwl_disable_interrupts(trans); /* @@ -1517,6 +1511,42 @@ static void iwl_trans_pcie_d3_suspend(struct iwl_trans *trans, bool test, iwl_pcie_set_pwr(trans, true); } +static int iwl_trans_pcie_d3_suspend(struct iwl_trans *trans, bool test, + bool reset) +{ + int ret; + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + + /* + * Family IWL_DEVICE_FAMILY_AX210 and above persist mode is set by FW. + */ + if (!reset && trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210) { + /* Enable persistence mode to avoid reset */ + iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG, + CSR_HW_IF_CONFIG_REG_PERSIST_MODE); + } + + if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { + iwl_write_umac_prph(trans, UREG_DOORBELL_TO_ISR6, + UREG_DOORBELL_TO_ISR6_SUSPEND); + + ret = wait_event_timeout(trans_pcie->sx_waitq, + trans_pcie->sx_complete, 2 * HZ); + /* + * Invalidate it toward resume. + */ + trans_pcie->sx_complete = false; + + if (!ret) { + IWL_ERR(trans, "Timeout entering D3\n"); + return -ETIMEDOUT; + } + } + iwl_pcie_d3_complete_suspend(trans, test, reset); + + return 0; +} + static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans, enum iwl_d3_status *status, bool test, bool reset) @@ -1528,7 +1558,7 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans, if (test) { iwl_enable_interrupts(trans); *status = IWL_D3_STATUS_ALIVE; - return 0; + goto out; } iwl_set_bit(trans, CSR_GP_CNTRL, @@ -1575,6 +1605,25 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans, else *status = IWL_D3_STATUS_ALIVE; +out: + if (*status == IWL_D3_STATUS_ALIVE && + trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { + trans_pcie->sx_complete = false; + iwl_write_umac_prph(trans, UREG_DOORBELL_TO_ISR6, + UREG_DOORBELL_TO_ISR6_RESUME); + + ret = wait_event_timeout(trans_pcie->sx_waitq, + trans_pcie->sx_complete, 2 * HZ); + /* + * Invalidate it toward next suspend. + */ + trans_pcie->sx_complete = false; + + if (!ret) { + IWL_ERR(trans, "Timeout exiting D3\n"); + return -ETIMEDOUT; + } + } return 0; } @@ -3514,6 +3563,8 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, /* Initialize the wait queue for commands */ init_waitqueue_head(&trans_pcie->wait_command_queue); + init_waitqueue_head(&trans_pcie->sx_waitq); + if (trans_pcie->msix_enabled) { ret = iwl_pcie_init_msix_handler(pdev, trans_pcie); if (ret) From f005fd88e96578ee0e16843f236574188f299529 Mon Sep 17 00:00:00 2001 From: Haim Dreyfuss Date: Tue, 16 Jul 2019 12:44:40 +0300 Subject: [PATCH 70/80] iwlwifi: add sta_id to WOWLAN_CONFIG_CMD WoWlan feature within the FW uses the station id for various of reasons. Thus we need to add this information to the command. Signed-off-by: Haim Dreyfuss Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/api/d3.h | 6 ++++-- drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 4 ++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h b/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h index 31231b223aae..4c3219e7beb6 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h @@ -396,6 +396,7 @@ enum iwl_wowlan_flags { * @is_11n_connection: indicates HT connection * @offloading_tid: TID reserved for firmware use * @flags: extra flags, see &enum iwl_wowlan_flags + * @sta_id: station ID for wowlan. * @reserved: reserved */ struct iwl_wowlan_config_cmd { @@ -406,8 +407,9 @@ struct iwl_wowlan_config_cmd { u8 is_11n_connection; u8 offloading_tid; u8 flags; - u8 reserved[2]; -} __packed; /* WOWLAN_CONFIG_API_S_VER_4 */ + u8 sta_id; + u8 reserved; +} __packed; /* WOWLAN_CONFIG_API_S_VER_5 */ /* * WOWLAN_TSC_RSC_PARAMS diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index 66d610a2f3d6..86c2c587e755 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -904,6 +904,8 @@ iwl_mvm_netdetect_config(struct iwl_mvm *mvm, wowlan_config_cmd.wakeup_filter |= cpu_to_le32(IWL_WOWLAN_WAKEUP_RF_KILL_DEASSERT); + wowlan_config_cmd.sta_id = mvm->aux_sta.sta_id; + ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_CONFIGURATION, 0, sizeof(wowlan_config_cmd), &wowlan_config_cmd); @@ -1011,6 +1013,8 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, } else { struct iwl_wowlan_config_cmd wowlan_config_cmd = {}; + wowlan_config_cmd.sta_id = mvmvif->ap_sta_id; + ap_sta = rcu_dereference_protected( mvm->fw_id_to_mac_id[mvmvif->ap_sta_id], lockdep_is_held(&mvm->mutex)); From 0968fbfa4141ed176b6f8fb4aa620c01751c2f09 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 16 Jul 2019 14:57:18 +0200 Subject: [PATCH 71/80] iwlwifi: mvm: drop BA sessions on too many old-SN frames Certain APs (I think a certain Broadcom model) interact badly with our full state BA bitmap handling, and if triggered badly with many powersave transitions they keep sending frames from before the window, which our hardware then doesn't appear to ACK (to them) since it has moved on and is sending ACKs for higher SNs now. Try to detect this situation and if this keeps happening, disable the aggregation session. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- .../wireless/intel/iwlwifi/mvm/constants.h | 1 + drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 9 ++++ drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 53 +++++++++++++++++++ 3 files changed, 63 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/constants.h b/drivers/net/wireless/intel/iwlwifi/mvm/constants.h index 915b172da57a..60aff2ecec12 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/constants.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/constants.h @@ -153,5 +153,6 @@ #define IWL_MVM_FTM_INITIATOR_DYNACK true #define IWL_MVM_D3_DEBUG false #define IWL_MVM_USE_TWT false +#define IWL_MVM_AMPDU_CONSEC_DROPS_DELBA 10 #endif /* __MVM_CONSTANTS_H */ diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 2540d7ffbbc1..b8a8369457b9 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -661,6 +661,12 @@ struct iwl_mvm_tcm { * @valid: reordering is valid for this queue * @lock: protect reorder buffer internal state * @mvm: mvm pointer, needed for frame timer context + * @consec_oldsn_drops: consecutive drops due to old SN + * @consec_oldsn_ampdu_gp2: A-MPDU GP2 timestamp to track + * when to apply old SN consecutive drop workaround + * @consec_oldsn_prev_drop: track whether or not an MPDU + * that was single/part of the previous A-MPDU was + * dropped due to old SN */ struct iwl_mvm_reorder_buffer { u16 head_sn; @@ -674,6 +680,9 @@ struct iwl_mvm_reorder_buffer { bool valid; spinlock_t lock; struct iwl_mvm *mvm; + unsigned int consec_oldsn_drops; + u32 consec_oldsn_ampdu_gp2; + unsigned int consec_oldsn_prev_drop:1; } ____cacheline_aligned_in_smp; /** diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c index 25d038092eec..f3f9e641ae70 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c @@ -781,6 +781,55 @@ void iwl_mvm_rx_queue_notif(struct iwl_mvm *mvm, struct napi_struct *napi, wake_up(&mvm->rx_sync_waitq); } +static void iwl_mvm_oldsn_workaround(struct iwl_mvm *mvm, + struct ieee80211_sta *sta, int tid, + struct iwl_mvm_reorder_buffer *buffer, + u32 reorder, u32 gp2, int queue) +{ + struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); + + if (gp2 != buffer->consec_oldsn_ampdu_gp2) { + /* we have a new (A-)MPDU ... */ + + /* + * reset counter to 0 if we didn't have any oldsn in + * the last A-MPDU (as detected by GP2 being identical) + */ + if (!buffer->consec_oldsn_prev_drop) + buffer->consec_oldsn_drops = 0; + + /* either way, update our tracking state */ + buffer->consec_oldsn_ampdu_gp2 = gp2; + } else if (buffer->consec_oldsn_prev_drop) { + /* + * tracking state didn't change, and we had an old SN + * indication before - do nothing in this case, we + * already noted this one down and are waiting for the + * next A-MPDU (by GP2) + */ + return; + } + + /* return unless this MPDU has old SN */ + if (!(reorder & IWL_RX_MPDU_REORDER_BA_OLD_SN)) + return; + + /* update state */ + buffer->consec_oldsn_prev_drop = 1; + buffer->consec_oldsn_drops++; + + /* if limit is reached, send del BA and reset state */ + if (buffer->consec_oldsn_drops == IWL_MVM_AMPDU_CONSEC_DROPS_DELBA) { + IWL_WARN(mvm, + "reached %d old SN frames from %pM on queue %d, stopping BA session on TID %d\n", + IWL_MVM_AMPDU_CONSEC_DROPS_DELBA, + sta->addr, queue, tid); + ieee80211_stop_rx_ba_session(mvmsta->vif, BIT(tid), sta->addr); + buffer->consec_oldsn_prev_drop = 0; + buffer->consec_oldsn_drops = 0; + } +} + /* * Returns true if the MPDU was buffered\dropped, false if it should be passed * to upper layer. @@ -792,6 +841,7 @@ static bool iwl_mvm_reorder(struct iwl_mvm *mvm, struct sk_buff *skb, struct iwl_rx_mpdu_desc *desc) { + struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb); struct ieee80211_hdr *hdr = iwl_mvm_skb_get_hdr(skb); struct iwl_mvm_sta *mvm_sta; struct iwl_mvm_baid_data *baid_data; @@ -894,6 +944,9 @@ static bool iwl_mvm_reorder(struct iwl_mvm *mvm, min_sn, IWL_MVM_RELEASE_SEND_RSS_SYNC); } + iwl_mvm_oldsn_workaround(mvm, sta, tid, buffer, reorder, + rx_status->device_timestamp, queue); + /* drop any oudated packets */ if (ieee80211_sn_less(sn, buffer->head_sn)) goto drop; From fe69b7d1243a42fedee944e873e80456a743c964 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 4 Jul 2019 17:24:47 +0200 Subject: [PATCH 72/80] iwlwifi: mvm: handle BAR_FRAME_RELEASE (0xc2) notification In prior hardware generations (e.g. 9000 series), we received the BAR frame with fake NSSN information to handle releasing frames from the reorder buffer for the default queue, the other queues were getting the FRAME_RELEASE notification in this case. With multi-TID block-ack, the firmware no longer sends us the BAR frame because the fake RX is quite big (just the metadata is around 48 bytes or so). Instead, it now sends us one (or multiple) special release notifications (0xc2). The hardware consumes these as well, but only generates the FRAME_RELEASE (0xc3) for queues other than the default queue. We thus need to handle them in the same way we handle the normal FRAME_RELEASE. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- .../wireless/intel/iwlwifi/fw/api/commands.h | 7 ++++ .../net/wireless/intel/iwlwifi/fw/api/rx.h | 32 +++++++++++++++ drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 2 + drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 3 ++ drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 39 +++++++++++++++++++ 5 files changed, 83 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h b/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h index 4d2274bcc0b5..22dff2c92d4f 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h @@ -474,6 +474,13 @@ enum iwl_legacy_cmds { */ REPLY_RX_MPDU_CMD = 0xc1, + /** + * @BAR_FRAME_RELEASE: Frame release from BAR notification, used for + * multi-TID BAR (previously, the BAR frame itself was reported + * instead). Uses &struct iwl_bar_frame_release. + */ + BAR_FRAME_RELEASE = 0xc2, + /** * @FRAME_RELEASE: * Frame release (reorder helper) notification, uses diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h b/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h index 9b0bb89599fc..a93449db7bb2 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h @@ -746,6 +746,38 @@ struct iwl_frame_release { __le16 nssn; }; +/** + * enum iwl_bar_frame_release_sta_tid - STA/TID information for BAR release + * @IWL_BAR_FRAME_RELEASE_TID_MASK: TID mask + * @IWL_BAR_FRAME_RELEASE_STA_MASK: STA mask + */ +enum iwl_bar_frame_release_sta_tid { + IWL_BAR_FRAME_RELEASE_TID_MASK = 0x0000000f, + IWL_BAR_FRAME_RELEASE_STA_MASK = 0x000001f0, +}; + +/** + * enum iwl_bar_frame_release_ba_info - BA information for BAR release + * @IWL_BAR_FRAME_RELEASE_NSSN_MASK: NSSN mask + * @IWL_BAR_FRAME_RELEASE_SN_MASK: SN mask (ignored by driver) + * @IWL_BAR_FRAME_RELEASE_BAID_MASK: BAID mask + */ +enum iwl_bar_frame_release_ba_info { + IWL_BAR_FRAME_RELEASE_NSSN_MASK = 0x00000fff, + IWL_BAR_FRAME_RELEASE_SN_MASK = 0x00fff000, + IWL_BAR_FRAME_RELEASE_BAID_MASK = 0x3f000000, +}; + +/** + * struct iwl_bar_frame_release - frame release from BAR info + * @sta_tid: STA & TID information, see &enum iwl_bar_frame_release_sta_tid. + * @ba_info: BA information, see &enum iwl_bar_frame_release_ba_info. + */ +struct iwl_bar_frame_release { + __le32 sta_tid; + __le32 ba_info; +} __packed; /* RX_BAR_TO_FRAME_RELEASE_API_S_VER_1 */ + enum iwl_rss_hash_func_en { IWL_RSS_HASH_TYPE_IPV4_TCP, IWL_RSS_HASH_TYPE_IPV4_UDP, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index b8a8369457b9..843d00bf2bd5 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -1606,6 +1606,8 @@ void iwl_mvm_rx_monitor_no_data(struct iwl_mvm *mvm, struct napi_struct *napi, struct iwl_rx_cmd_buffer *rxb, int queue); void iwl_mvm_rx_frame_release(struct iwl_mvm *mvm, struct napi_struct *napi, struct iwl_rx_cmd_buffer *rxb, int queue); +void iwl_mvm_rx_bar_frame_release(struct iwl_mvm *mvm, struct napi_struct *napi, + struct iwl_rx_cmd_buffer *rxb, int queue); int iwl_mvm_notify_rx_queue(struct iwl_mvm *mvm, u32 rxq_mask, const u8 *data, u32 count, bool async); void iwl_mvm_rx_queue_notif(struct iwl_mvm *mvm, struct napi_struct *napi, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 35b393f8cd85..961c7ab7950b 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -389,6 +389,7 @@ static const struct iwl_hcmd_names iwl_mvm_legacy_names[] = { HCMD_NAME(SCAN_ITERATION_COMPLETE_UMAC), HCMD_NAME(REPLY_RX_PHY_CMD), HCMD_NAME(REPLY_RX_MPDU_CMD), + HCMD_NAME(BAR_FRAME_RELEASE), HCMD_NAME(FRAME_RELEASE), HCMD_NAME(BA_NOTIF), HCMD_NAME(MCC_UPDATE_CMD), @@ -1060,6 +1061,8 @@ static void iwl_mvm_rx_mq(struct iwl_op_mode *op_mode, iwl_mvm_rx_queue_notif(mvm, napi, rxb, 0); else if (cmd == WIDE_ID(LEGACY_GROUP, FRAME_RELEASE)) iwl_mvm_rx_frame_release(mvm, napi, rxb, 0); + else if (cmd == WIDE_ID(LEGACY_GROUP, BAR_FRAME_RELEASE)) + iwl_mvm_rx_bar_frame_release(mvm, napi, rxb, 0); else if (cmd == WIDE_ID(DATA_PATH_GROUP, RX_NO_DATA_NOTIF)) iwl_mvm_rx_monitor_no_data(mvm, napi, rxb, 0); else diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c index f3f9e641ae70..c48d6fb16408 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c @@ -2014,3 +2014,42 @@ void iwl_mvm_rx_frame_release(struct iwl_mvm *mvm, struct napi_struct *napi, le16_to_cpu(release->nssn), queue, 0); } + +void iwl_mvm_rx_bar_frame_release(struct iwl_mvm *mvm, struct napi_struct *napi, + struct iwl_rx_cmd_buffer *rxb, int queue) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl_bar_frame_release *release = (void *)pkt->data; + unsigned int baid = le32_get_bits(release->ba_info, + IWL_BAR_FRAME_RELEASE_BAID_MASK); + unsigned int nssn = le32_get_bits(release->ba_info, + IWL_BAR_FRAME_RELEASE_NSSN_MASK); + unsigned int sta_id = le32_get_bits(release->sta_tid, + IWL_BAR_FRAME_RELEASE_STA_MASK); + unsigned int tid = le32_get_bits(release->sta_tid, + IWL_BAR_FRAME_RELEASE_TID_MASK); + struct iwl_mvm_baid_data *baid_data; + + if (WARN_ON_ONCE(baid == IWL_RX_REORDER_DATA_INVALID_BAID || + baid >= ARRAY_SIZE(mvm->baid_map))) + return; + + rcu_read_lock(); + baid_data = rcu_dereference(mvm->baid_map[baid]); + if (!baid_data) { + IWL_DEBUG_RX(mvm, + "Got valid BAID %d but not allocated, invalid BAR release!\n", + baid); + goto out; + } + + if (WARN(tid != baid_data->tid || sta_id != baid_data->sta_id, + "baid 0x%x is mapped to sta:%d tid:%d, but BAR release received for sta:%d tid:%d\n", + baid, baid_data->sta_id, baid_data->tid, sta_id, + tid)) + goto out; + + iwl_mvm_release_frames_from_notif(mvm, napi, baid, nssn, queue, 0); +out: + rcu_read_unlock(); +} From 5952e0ec3f05cc38aceaa3eef13d828aef0b6b3b Mon Sep 17 00:00:00 2001 From: Haim Dreyfuss Date: Mon, 22 Jul 2019 16:45:21 +0300 Subject: [PATCH 73/80] iwlwifi: mvm: add support for single antenna diversity There are products which have a single chain with 2 antennas. In these products, we need to inform the FW that the device has the single antenna diversity(SAD) feature. In the future, we will read the active antenna from a BIOS configuration. Currently, we use a default configuration which means that the FW decides which antenna to use. Signed-off-by: Haim Dreyfuss Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/cfg/22000.c | 1 + drivers/net/wireless/intel/iwlwifi/fw/file.h | 4 ++++ drivers/net/wireless/intel/iwlwifi/iwl-config.h | 2 ++ 3 files changed, 7 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c index db09ca9ff89d..5e355c4957df 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c @@ -240,6 +240,7 @@ const struct iwl_cfg iwl_ax101_cfg_qu_hr = { * HT size; mac80211 would otherwise pick the HE max (256) by default. */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, + .tx_with_siso_diversity = true, }; const struct iwl_cfg iwl_ax201_cfg_qu_hr = { diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h index 00db39427be7..329b00e90fa4 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/file.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h @@ -524,6 +524,10 @@ enum iwl_fw_phy_cfg { FW_PHY_CFG_TX_CHAIN = 0xf << FW_PHY_CFG_TX_CHAIN_POS, FW_PHY_CFG_RX_CHAIN_POS = 20, FW_PHY_CFG_RX_CHAIN = 0xf << FW_PHY_CFG_RX_CHAIN_POS, + FW_PHY_CFG_CHAIN_SAD_POS = 23, + FW_PHY_CFG_CHAIN_SAD_ENABLED = 0x1 << FW_PHY_CFG_CHAIN_SAD_POS, + FW_PHY_CFG_CHAIN_SAD_ANT_A = 0x2 << FW_PHY_CFG_CHAIN_SAD_POS, + FW_PHY_CFG_CHAIN_SAD_ANT_B = 0x4 << FW_PHY_CFG_CHAIN_SAD_POS, FW_PHY_CFG_SHARED_CLK = BIT(31), }; diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h index 284352d9df0e..214495a7165f 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h @@ -379,6 +379,7 @@ struct iwl_cfg_trans_params { * @ht_params: point to ht parameters * @led_mode: 0=blinking, 1=On(RF On)/Off(RF Off) * @rx_with_siso_diversity: 1x1 device with rx antenna diversity + * @tx_with_siso_diversity: 1x1 device with tx antenna diversity * @internal_wimax_coex: internal wifi/wimax combo device * @high_temp: Is this NIC is designated to be in high temperature. * @host_interrupt_operation_mode: device needs host interrupt operation @@ -441,6 +442,7 @@ struct iwl_cfg { u16 nvm_ver; u16 nvm_calib_ver; u32 rx_with_siso_diversity:1, + tx_with_siso_diversity:1, bt_shared_single_ant:1, internal_wimax_coex:1, host_interrupt_operation_mode:1, From 94b952b55c4d0a925aaa17e0a6994d8d7e47a7df Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 23 Jul 2019 12:54:15 +0300 Subject: [PATCH 74/80] iwlwifi: mvm: don't log un-decrypted frames Sometimes the firmware won't be able to decrypt frames because the keys were not installed yet or other scenarios. The firmware will soon stop dropping multicast frames when MAC_FILTER_ACCEPT_GRP is not set. The firmware will simply always pass multicast frame in. In order to avoid logging any such frame coming in when we don't have the keys, drop the print. Signed-off-by: Emmanuel Grumbach Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c index c48d6fb16408..77b03b757193 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c @@ -377,8 +377,16 @@ static int iwl_mvm_rx_crypto(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr, stats->flag |= RX_FLAG_DECRYPTED; return 0; default: - /* Expected in monitor (not having the keys) */ - if (!mvm->monitor_on) + /* + * Sometimes we can get frames that were not decrypted + * because the firmware didn't have the keys yet. This can + * happen after connection where we can get multicast frames + * before the GTK is installed. + * Silently drop those frames. + * Also drop un-decrypted frames in monitor mode. + */ + if (!is_multicast_ether_addr(hdr->addr1) && + !mvm->monitor_on && net_ratelimit()) IWL_ERR(mvm, "Unhandled alg: 0x%x\n", status); } From a29f6576c31d53076c717bd8b1a525f175b671cd Mon Sep 17 00:00:00 2001 From: Shahar S Matityahu Date: Mon, 22 Jul 2019 12:40:51 +0300 Subject: [PATCH 75/80] iwlwifi: add iwl_tlv_array_len() Allows to easily calculate array length at the end of a TLV. Signed-off-by: Shahar S Matityahu Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/file.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h index 329b00e90fa4..1bdcab9b9275 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/file.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h @@ -972,4 +972,19 @@ struct iwl_fw_cmd_version { u8 notif_ver; } __packed; +static inline size_t _iwl_tlv_array_len(const struct iwl_ucode_tlv *tlv, + size_t fixed_size, size_t var_size) +{ + size_t var_len = le32_to_cpu(tlv->length) - fixed_size; + + if (WARN_ON(var_len % var_size)) + return 0; + + return var_len / var_size; +} + +#define iwl_tlv_array_len(_tlv_ptr, _struct_ptr, _memb) \ + _iwl_tlv_array_len((_tlv_ptr), sizeof(*(_struct_ptr)), \ + sizeof(_struct_ptr->_memb[0])) + #endif /* __iwl_fw_file_h__ */ From b108d8c782cc21ed22825c72167a9e84c614a3ac Mon Sep 17 00:00:00 2001 From: Shahar S Matityahu Date: Mon, 22 Jul 2019 13:04:16 +0300 Subject: [PATCH 76/80] iwlwifi: dbg_ini: remove apply point, switch to time point API Remove the "apply points" mechanism as preparation for the changed debug API where this is now a "time point" instead. Use a new API across the code at the trigger points ("time points"), but don't yet implement it since that requires some more preparation. Signed-off-by: Shahar S Matityahu Signed-off-by: Luca Coelho --- .../wireless/intel/iwlwifi/fw/api/dbg-tlv.h | 89 +++- .../net/wireless/intel/iwlwifi/fw/api/debug.h | 45 -- .../net/wireless/intel/iwlwifi/iwl-dbg-tlv.c | 489 +----------------- .../net/wireless/intel/iwlwifi/iwl-dbg-tlv.h | 13 +- .../net/wireless/intel/iwlwifi/iwl-trans.h | 5 - drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 10 +- .../net/wireless/intel/iwlwifi/mvm/mac-ctxt.c | 5 +- .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 5 +- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 6 +- drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 2 - 10 files changed, 101 insertions(+), 568 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h b/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h index 798e61d4d683..ba586f148c14 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h @@ -397,27 +397,6 @@ enum iwl_fw_ini_trigger_id { IWL_FW_TRIGGER_ID_NUM, }; /* FW_DEBUG_TLV_TRIGGER_ID_E_VER_1 */ -/** - * enum iwl_fw_ini_apply_point - * - * @IWL_FW_INI_APPLY_INVALID: invalid - * @IWL_FW_INI_APPLY_EARLY: pre loading FW - * @IWL_FW_INI_APPLY_AFTER_ALIVE: first cmd from host after alive - * @IWL_FW_INI_APPLY_POST_INIT: last cmd in initialization sequence - * @IWL_FW_INI_APPLY_MISSED_BEACONS: missed beacons notification - * @IWL_FW_INI_APPLY_SCAN_COMPLETE: scan completed - * @IWL_FW_INI_APPLY_NUM: number of apply points -*/ -enum iwl_fw_ini_apply_point { - IWL_FW_INI_APPLY_INVALID, - IWL_FW_INI_APPLY_EARLY, - IWL_FW_INI_APPLY_AFTER_ALIVE, - IWL_FW_INI_APPLY_POST_INIT, - IWL_FW_INI_APPLY_MISSED_BEACONS, - IWL_FW_INI_APPLY_SCAN_COMPLETE, - IWL_FW_INI_APPLY_NUM, -}; /* FW_DEBUG_TLV_APPLY_POINT_E_VER_1 */ - /** * enum iwl_fw_ini_allocation_id * @@ -510,4 +489,72 @@ enum iwl_fw_ini_region_type { IWL_FW_INI_REGION_NUM }; /* FW_DEBUG_TLV_REGION_TYPE_E_VER_1 */ +/** + * enum iwl_fw_ini_time_point + * + * Hard coded time points in which the driver can send hcmd or perform dump + * collection + * + * @IWL_FW_INI_TIME_POINT_EARLY: pre loading the FW + * @IWL_FW_INI_TIME_POINT_AFTER_ALIVE: first cmd from host after alive notif + * @IWL_FW_INI_TIME_POINT_POST_INIT: last cmd in series of init sequence + * @IWL_FW_INI_TIME_POINT_FW_ASSERT: FW assert + * @IWL_FW_INI_TIME_POINT_FW_HW_ERROR: FW HW error + * @IWL_FW_INI_TIME_POINT_FW_TFD_Q_HANG: TFD queue hang + * @IWL_FW_INI_TIME_POINT_FW_DHC_NOTIFOCATION: DHC cmd response and notif + * @IWL_FW_INI_TIME_POINT_FW_RSP_OR_NOTIF: FW response or notification. + * data field holds id and group + * @IWL_FW_INI_TIME_POINT_USER_TRIGGER: user trigger time point + * @IWL_FW_INI_TIME_POINT_PERIODIC: periodic timepoint that fires in constant + * intervals. data field holds the interval time in msec + * @IWL_FW_INI_TIME_POINT_WDG_TIMEOUT: watchdog timeout + * @IWL_FW_INI_TIME_POINT_HOST_ASSERT: Unused + * @IWL_FW_INI_TIME_POINT_HOST_ALIVE_TIMEOUT: alive timeout + * @IWL_FW_INI_TIME_POINT_HOST_DEVICE_ENABLE: device enable + * @IWL_FW_INI_TIME_POINT_HOST_DEVICE_DISABLE: device disable + * @IWL_FW_INI_TIME_POINT_HOST_D3_START: D3 start + * @IWL_FW_INI_TIME_POINT_HOST_D3_END: D3 end + * @IWL_FW_INI_TIME_POINT_MISSED_BEACONS: missed beacons + * @IWL_FW_INI_TIME_POINT_ASSOC_FAILED: association failure + * @IWL_FW_INI_TIME_POINT_TX_FAILED: Tx frame failed + * @IWL_FW_INI_TIME_POINT_TX_WFD_ACTION_FRAME_FAILED: wifi direct action + * frame failed + * @IWL_FW_INI_TIME_POINT_TX_LATENCY_THRESHOLD: Tx latency threshold + * @IWL_FW_INI_TIME_POINT_HANG_OCCURRED: hang occurred + * @IWL_FW_INI_TIME_POINT_EAPOL_FAILED: EAPOL failed + * @IWL_FW_INI_TIME_POINT_FAKE_TX: fake Tx + * @IWL_FW_INI_TIME_POINT_DEASSOC: de association + * @IWL_FW_INI_TIME_POINT_NUM: number of time points + */ +enum iwl_fw_ini_time_point { + IWL_FW_INI_TIME_POINT_INVALID, + IWL_FW_INI_TIME_POINT_EARLY, + IWL_FW_INI_TIME_POINT_AFTER_ALIVE, + IWL_FW_INI_TIME_POINT_POST_INIT, + IWL_FW_INI_TIME_POINT_FW_ASSERT, + IWL_FW_INI_TIME_POINT_FW_HW_ERROR, + IWL_FW_INI_TIME_POINT_FW_TFD_Q_HANG, + IWL_FW_INI_TIME_POINT_FW_DHC_NOTIFOCATION, + IWL_FW_INI_TIME_POINT_FW_RSP_OR_NOTIF, + IWL_FW_INI_TIME_POINT_USER_TRIGGER, + IWL_FW_INI_TIME_POINT_PERIODIC, + IWL_FW_INI_TIME_POINT_WDG_TIMEOUT, + IWL_FW_INI_TIME_POINT_HOST_ASSERT, + IWL_FW_INI_TIME_POINT_HOST_ALIVE_TIMEOUT, + IWL_FW_INI_TIME_POINT_HOST_DEVICE_ENABLE, + IWL_FW_INI_TIME_POINT_HOST_DEVICE_DISABLE, + IWL_FW_INI_TIME_POINT_HOST_D3_START, + IWL_FW_INI_TIME_POINT_HOST_D3_END, + IWL_FW_INI_TIME_POINT_MISSED_BEACONS, + IWL_FW_INI_TIME_POINT_ASSOC_FAILED, + IWL_FW_INI_TIME_POINT_TX_FAILED, + IWL_FW_INI_TIME_POINT_TX_WFD_ACTION_FRAME_FAILED, + IWL_FW_INI_TIME_POINT_TX_LATENCY_THRESHOLD, + IWL_FW_INI_TIME_POINT_HANG_OCCURRED, + IWL_FW_INI_TIME_POINT_EAPOL_FAILED, + IWL_FW_INI_TIME_POINT_FAKE_TX, + IWL_FW_INI_TIME_POINT_DEASSOC, + IWL_FW_INI_TIME_POINT_NUM, +}; /* FW_TLV_DEBUG_TIME_POINT_API_E */ + #endif diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/debug.h b/drivers/net/wireless/intel/iwlwifi/fw/api/debug.h index b627c31d06ed..c67a6ab6491c 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/debug.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/debug.h @@ -352,51 +352,6 @@ struct iwl_dbg_mem_access_rsp { __le32 data[]; } __packed; /* DEBUG_(U|L)MAC_RD_WR_RSP_API_S_VER_1 */ -#define LDBG_CFG_COMMAND_SIZE 80 -#define BUFFER_ALLOCATION 0x27 -#define START_DEBUG_RECORDING 0x29 -#define STOP_DEBUG_RECORDING 0x2A - -/* maximum fragments to be allocated per target of allocationId */ -#define IWL_BUFFER_LOCATION_MAX_FRAGS 2 - -/** - * struct iwl_fragment_data single fragment structure - * @address: 64bit start address - * @size: size in bytes - */ -struct iwl_fragment_data { - __le64 address; - __le32 size; -} __packed; /* FRAGMENT_STRUCTURE_API_S_VER_1 */ - -/** - * struct iwl_buffer_allocation_cmd - buffer allocation command structure - * @allocation_id: id of the allocation - * @buffer_location: location of the buffer - * @num_frags: number of fragments - * @fragments: memory fragments - */ -struct iwl_buffer_allocation_cmd { - __le32 allocation_id; - __le32 buffer_location; - __le32 num_frags; - struct iwl_fragment_data fragments[IWL_BUFFER_LOCATION_MAX_FRAGS]; -} __packed; /* BUFFER_ALLOCATION_CMD_API_S_VER_1 */ - -/** - * struct iwl_ldbg_config_cmd - LDBG config command - * @type: configuration type - * @pad: reserved space for type-dependent data - */ -struct iwl_ldbg_config_cmd { - __le32 type; - union { - u8 pad[LDBG_CFG_COMMAND_SIZE - sizeof(__le32)]; - struct iwl_buffer_allocation_cmd buffer_allocation; - }; /* LDBG_CFG_BODY_API_U_VER_2 (partially) */ -} __packed; /* LDBG_CFG_CMD_API_S_VER_2 */ - /** * struct iwl_dbg_suspend_resume_cmd - dbgc suspend resume command * @operation: suspend or resume operation, uses diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c index b4fba73b5b23..db76b28eac40 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c @@ -104,26 +104,6 @@ dbg_ver_table[IWL_DBG_TLV_TYPE_NUM] = { [IWL_DBG_TLV_TYPE_TRIGGER] = {.min_ver = 1, .max_ver = 1,}, }; -static int iwl_dbg_tlv_copy(struct iwl_ucode_tlv *tlv, struct list_head *list) -{ - struct iwl_apply_point_data *tlv_copy; - u32 len = le32_to_cpu(tlv->length); - - tlv_copy = kzalloc(sizeof(*tlv_copy) + len, GFP_KERNEL); - if (!tlv_copy) - return -ENOMEM; - - INIT_LIST_HEAD(&tlv_copy->list); - memcpy(&tlv_copy->tlv, tlv, sizeof(*tlv) + len); - - if (!list->next) - INIT_LIST_HEAD(list); - - list_add_tail(&tlv_copy->list, list); - - return 0; -} - static bool iwl_dbg_tlv_ver_support(struct iwl_ucode_tlv *tlv) { struct iwl_fw_ini_header *hdr = (void *)&tlv->data[0]; @@ -147,9 +127,6 @@ void iwl_dbg_tlv_alloc(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv, u32 tlv_idx = type - IWL_UCODE_TLV_DEBUG_BASE; enum iwl_ini_cfg_state *cfg_state = ext ? &trans->dbg.external_ini_cfg : &trans->dbg.internal_ini_cfg; - struct list_head *dbg_cfg_list = ext ? - &trans->dbg.apply_points_ext[pnt].list : - &trans->dbg.apply_points[pnt].list; IWL_DEBUG_FW(trans, "WRT: read TLV 0x%x, apply point %d\n", type, pnt); @@ -159,24 +136,12 @@ void iwl_dbg_tlv_alloc(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv, goto out_err; } - if (pnt >= IWL_FW_INI_APPLY_NUM) { - IWL_ERR(trans, "WRT: Invalid apply point %d\n", pnt); - goto out_err; - } - if (!iwl_dbg_tlv_ver_support(tlv)) { IWL_ERR(trans, "WRT: Unsupported TLV 0x%x version %u\n", type, le32_to_cpu(hdr->tlv_version)); goto out_err; } - if (iwl_dbg_tlv_copy(tlv, dbg_cfg_list)) { - IWL_ERR(trans, - "WRT: Failed to allocate TLV 0x%x, apply point %d\n", - type, pnt); - goto out_err; - } - if (*cfg_state == IWL_INI_CFG_STATE_NOT_LOADED) *cfg_state = IWL_INI_CFG_STATE_LOADED; @@ -186,33 +151,9 @@ void iwl_dbg_tlv_alloc(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv, *cfg_state = IWL_INI_CFG_STATE_CORRUPTED; } -static void iwl_dbg_tlv_free_list(struct list_head *list) -{ - if (!list || !list->next) - return; - - while (!list_empty(list)) { - struct iwl_apply_point_data *node = - list_entry(list->next, typeof(*node), list); - - list_del(&node->list); - kfree(node); - } -} - void iwl_dbg_tlv_free(struct iwl_trans *trans) { - int i; - - for (i = 0; i < ARRAY_SIZE(trans->dbg.apply_points); i++) { - struct iwl_apply_point_data *data; - - data = &trans->dbg.apply_points[i]; - iwl_dbg_tlv_free_list(&data->list); - - data = &trans->dbg.apply_points_ext[i]; - iwl_dbg_tlv_free_list(&data->list); - } + /* will be used again later */ } static int iwl_dbg_tlv_parse_bin(struct iwl_trans *trans, const u8 *data, @@ -258,428 +199,10 @@ void iwl_dbg_tlv_load_bin(struct device *dev, struct iwl_trans *trans) release_firmware(fw); } -static void -iwl_dbg_tlv_apply_debug_info(struct iwl_fw_runtime *fwrt, - struct iwl_fw_ini_debug_info_tlv *dbg_info, - bool ext, enum iwl_fw_ini_apply_point pnt) +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) { - u32 img_name_len = le32_to_cpu(dbg_info->img_name_len); - u32 dbg_cfg_name_len = le32_to_cpu(dbg_info->dbg_cfg_name_len); - const char err_str[] = - "WRT: Invalid %s name length %d, expected %d\n"; - - if (img_name_len != IWL_FW_INI_MAX_IMG_NAME_LEN) { - IWL_WARN(fwrt, err_str, "image", img_name_len, - IWL_FW_INI_MAX_IMG_NAME_LEN); - return; - } - - if (dbg_cfg_name_len != IWL_FW_INI_MAX_DBG_CFG_NAME_LEN) { - IWL_WARN(fwrt, err_str, "debug cfg", dbg_cfg_name_len, - IWL_FW_INI_MAX_DBG_CFG_NAME_LEN); - return; - } - - if (ext) { - memcpy(fwrt->dump.external_dbg_cfg_name, dbg_info->dbg_cfg_name, - sizeof(fwrt->dump.external_dbg_cfg_name)); - } else { - memcpy(fwrt->dump.img_name, dbg_info->img_name, - sizeof(fwrt->dump.img_name)); - memcpy(fwrt->dump.internal_dbg_cfg_name, dbg_info->dbg_cfg_name, - sizeof(fwrt->dump.internal_dbg_cfg_name)); - } + /* will be used later */ } - -static void iwl_dbg_tlv_alloc_buffer(struct iwl_fw_runtime *fwrt, u32 size) -{ - struct iwl_trans *trans = fwrt->trans; - void *virtual_addr = NULL; - dma_addr_t phys_addr; - - if (WARN_ON_ONCE(trans->dbg.num_blocks == - ARRAY_SIZE(trans->dbg.fw_mon))) - return; - - virtual_addr = - dma_alloc_coherent(fwrt->trans->dev, size, &phys_addr, - GFP_KERNEL | __GFP_NOWARN); - - /* TODO: alloc fragments if needed */ - if (!virtual_addr) - IWL_ERR(fwrt, "Failed to allocate debug memory\n"); - - IWL_DEBUG_FW(trans, - "Allocated DRAM buffer[%d], size=0x%x\n", - trans->dbg.num_blocks, size); - - trans->dbg.fw_mon[trans->dbg.num_blocks].block = virtual_addr; - trans->dbg.fw_mon[trans->dbg.num_blocks].physical = phys_addr; - trans->dbg.fw_mon[trans->dbg.num_blocks].size = size; - trans->dbg.num_blocks++; -} - -static void iwl_dbg_tlv_apply_buffer(struct iwl_fw_runtime *fwrt, - struct iwl_fw_ini_allocation_tlv *alloc, - enum iwl_fw_ini_apply_point pnt) -{ - struct iwl_trans *trans = fwrt->trans; - struct iwl_ldbg_config_cmd ldbg_cmd = { - .type = cpu_to_le32(BUFFER_ALLOCATION), - }; - struct iwl_buffer_allocation_cmd *cmd = &ldbg_cmd.buffer_allocation; - struct iwl_host_cmd hcmd = { - .id = LDBG_CONFIG_CMD, - .flags = CMD_ASYNC, - .data[0] = &ldbg_cmd, - .len[0] = sizeof(ldbg_cmd), - }; - int block_idx = trans->dbg.num_blocks; - u32 buf_location = le32_to_cpu(alloc->buffer_location); - u32 alloc_id = le32_to_cpu(alloc->allocation_id); - - if (alloc_id <= IWL_FW_INI_ALLOCATION_INVALID || - alloc_id >= IWL_FW_INI_ALLOCATION_NUM) { - IWL_ERR(fwrt, "WRT: Invalid allocation id %d\n", alloc_id); - return; - } - - if (fwrt->trans->dbg.ini_dest == IWL_FW_INI_LOCATION_INVALID) - fwrt->trans->dbg.ini_dest = buf_location; - - if (buf_location != fwrt->trans->dbg.ini_dest) { - WARN(fwrt, - "WRT: attempt to override buffer location on apply point %d\n", - pnt); - - return; - } - - if (buf_location == IWL_FW_INI_LOCATION_SRAM_PATH) { - IWL_DEBUG_FW(trans, "WRT: Applying SMEM buffer destination\n"); - /* set sram monitor by enabling bit 7 */ - iwl_set_bit(fwrt->trans, CSR_HW_IF_CONFIG_REG, - CSR_HW_IF_CONFIG_REG_BIT_MONITOR_SRAM); - - return; - } - - if (buf_location != IWL_FW_INI_LOCATION_DRAM_PATH) - return; - - if (!(BIT(alloc_id) & fwrt->trans->dbg.is_alloc)) { - iwl_dbg_tlv_alloc_buffer(fwrt, le32_to_cpu(alloc->size)); - if (block_idx == trans->dbg.num_blocks) - return; - fwrt->trans->dbg.is_alloc |= BIT(alloc_id); - } - - /* First block is assigned via registers / context info */ - if (trans->dbg.num_blocks == 1) - return; - - IWL_DEBUG_FW(trans, - "WRT: Applying DRAM buffer[%d] destination\n", block_idx); - - cmd->num_frags = cpu_to_le32(1); - cmd->fragments[0].address = - cpu_to_le64(trans->dbg.fw_mon[block_idx].physical); - cmd->fragments[0].size = alloc->size; - cmd->allocation_id = alloc->allocation_id; - cmd->buffer_location = alloc->buffer_location; - - iwl_trans_send_cmd(trans, &hcmd); -} - -static void iwl_dbg_tlv_apply_hcmd(struct iwl_fw_runtime *fwrt, - struct iwl_ucode_tlv *tlv) -{ - struct iwl_fw_ini_hcmd_tlv *hcmd_tlv = (void *)&tlv->data[0]; - struct iwl_fw_ini_hcmd *data = &hcmd_tlv->hcmd; - u16 len = le32_to_cpu(tlv->length) - sizeof(*hcmd_tlv); - - struct iwl_host_cmd hcmd = { - .id = WIDE_ID(data->group, data->id), - .len = { len, }, - .data = { data->data, }, - }; - - /* currently the driver supports always on domain only */ - if (le32_to_cpu(hcmd_tlv->domain) != IWL_FW_INI_DBG_DOMAIN_ALWAYS_ON) - return; - - IWL_DEBUG_FW(fwrt, "WRT: Sending host command id=0x%x, group=0x%x\n", - data->id, data->group); - - iwl_trans_send_cmd(fwrt->trans, &hcmd); -} - -static void iwl_dbg_tlv_apply_region(struct iwl_fw_runtime *fwrt, - struct iwl_fw_ini_region_tlv *tlv, - enum iwl_fw_ini_apply_point pnt) -{ - void *iter = (void *)tlv->region_config; - int i, size = le32_to_cpu(tlv->num_regions); - const char *err_st = - "WRT: Invalid region %s %d for apply point %d\n"; - - for (i = 0; i < size; i++) { - struct iwl_fw_ini_region_cfg *reg = iter, **active; - int id = le32_to_cpu(reg->region_id); - u32 type = le32_to_cpu(reg->region_type); - - if (WARN(id >= ARRAY_SIZE(fwrt->dump.active_regs), err_st, "id", - id, pnt)) - break; - - if (WARN(type == 0 || type >= IWL_FW_INI_REGION_NUM, err_st, - "type", type, pnt)) - break; - - active = &fwrt->dump.active_regs[id]; - - if (*active) - IWL_WARN(fwrt->trans, "WRT: Region id %d override\n", - id); - - IWL_DEBUG_FW(fwrt, "WRT: Activating region id %d\n", id); - - *active = reg; - - if (type == IWL_FW_INI_REGION_TXF || - type == IWL_FW_INI_REGION_RXF) - iter += le32_to_cpu(reg->fifos.num_of_registers) * - sizeof(__le32); - else if (type == IWL_FW_INI_REGION_DEVICE_MEMORY || - type == IWL_FW_INI_REGION_PERIPHERY_MAC || - type == IWL_FW_INI_REGION_PERIPHERY_PHY || - type == IWL_FW_INI_REGION_PERIPHERY_AUX || - type == IWL_FW_INI_REGION_INTERNAL_BUFFER || - type == IWL_FW_INI_REGION_PAGING || - type == IWL_FW_INI_REGION_CSR || - type == IWL_FW_INI_REGION_LMAC_ERROR_TABLE || - type == IWL_FW_INI_REGION_UMAC_ERROR_TABLE) - iter += le32_to_cpu(reg->internal.num_of_ranges) * - sizeof(__le32); - - iter += sizeof(*reg); - } -} - -static int iwl_dbg_tlv_trig_realloc(struct iwl_fw_runtime *fwrt, - struct iwl_fw_ini_active_triggers *active, - u32 id, int size) -{ - void *ptr; - - if (size <= active->size) - return 0; - - ptr = krealloc(active->trig, size, GFP_KERNEL); - if (!ptr) { - IWL_ERR(fwrt, "WRT: Failed to allocate memory for trigger %d\n", - id); - return -ENOMEM; - } - active->trig = ptr; - active->size = size; - - return 0; -} - -static void iwl_dbg_tlv_apply_trigger(struct iwl_fw_runtime *fwrt, - struct iwl_fw_ini_trigger_tlv *tlv, - enum iwl_fw_ini_apply_point apply_point) -{ - int i, size = le32_to_cpu(tlv->num_triggers); - void *iter = (void *)tlv->trigger_config; - - for (i = 0; i < size; i++) { - struct iwl_fw_ini_trigger *trig = iter; - struct iwl_fw_ini_active_triggers *active; - int id = le32_to_cpu(trig->trigger_id); - u32 trig_regs_size = le32_to_cpu(trig->num_regions) * - sizeof(__le32); - - if (WARN(id >= ARRAY_SIZE(fwrt->dump.active_trigs), - "WRT: Invalid trigger id %d for apply point %d\n", id, - apply_point)) - break; - - active = &fwrt->dump.active_trigs[id]; - - if (!active->active) { - size_t trig_size = sizeof(*trig) + trig_regs_size; - - IWL_DEBUG_FW(fwrt, "WRT: Activating trigger %d\n", id); - - if (iwl_dbg_tlv_trig_realloc(fwrt, active, id, - trig_size)) - goto next; - - memcpy(active->trig, trig, trig_size); - - } else { - u32 conf_override = - !(le32_to_cpu(trig->override_trig) & 0xff); - u32 region_override = - !(le32_to_cpu(trig->override_trig) & 0xff00); - u32 offset = 0; - u32 active_regs = - le32_to_cpu(active->trig->num_regions); - u32 new_regs = le32_to_cpu(trig->num_regions); - int mem_to_add = trig_regs_size; - - if (region_override) { - IWL_DEBUG_FW(fwrt, - "WRT: Trigger %d regions override\n", - id); - - mem_to_add -= active_regs * sizeof(__le32); - } else { - IWL_DEBUG_FW(fwrt, - "WRT: Trigger %d regions appending\n", - id); - - offset += active_regs; - new_regs += active_regs; - } - - if (iwl_dbg_tlv_trig_realloc(fwrt, active, id, - active->size + mem_to_add)) - goto next; - - if (conf_override) { - IWL_DEBUG_FW(fwrt, - "WRT: Trigger %d configuration override\n", - id); - - memcpy(active->trig, trig, sizeof(*trig)); - } - - memcpy(active->trig->data + offset, trig->data, - trig_regs_size); - active->trig->num_regions = cpu_to_le32(new_regs); - } - - /* Since zero means infinity - just set to -1 */ - if (!le32_to_cpu(active->trig->occurrences)) - active->trig->occurrences = cpu_to_le32(-1); - - active->active = true; - - if (id == IWL_FW_TRIGGER_ID_PERIODIC_TRIGGER) { - u32 collect_interval = le32_to_cpu(trig->trigger_data); - - /* the minimum allowed interval is 50ms */ - if (collect_interval < 50) { - collect_interval = 50; - trig->trigger_data = - cpu_to_le32(collect_interval); - } - - mod_timer(&fwrt->dump.periodic_trig, - jiffies + msecs_to_jiffies(collect_interval)); - } -next: - iter += sizeof(*trig) + trig_regs_size; - } -} - -static void _iwl_dbg_tlv_apply_point(struct iwl_fw_runtime *fwrt, - struct iwl_apply_point_data *data, - enum iwl_fw_ini_apply_point pnt, - bool ext) -{ - struct iwl_apply_point_data *iter; - - if (!data->list.next) - return; - - list_for_each_entry(iter, &data->list, list) { - struct iwl_ucode_tlv *tlv = &iter->tlv; - void *ini_tlv = (void *)tlv->data; - u32 type = le32_to_cpu(tlv->type); - const char invalid_ap_str[] = - "WRT: Invalid apply point %d for %s\n"; - - switch (type) { - case IWL_UCODE_TLV_TYPE_DEBUG_INFO: - iwl_dbg_tlv_apply_debug_info(fwrt, ini_tlv, ext, pnt); - break; - case IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION: - if (pnt != IWL_FW_INI_APPLY_EARLY) { - IWL_ERR(fwrt, invalid_ap_str, pnt, - "buffer allocation"); - break; - } - iwl_dbg_tlv_apply_buffer(fwrt, ini_tlv, pnt); - break; - case IWL_UCODE_TLV_TYPE_HCMD: - if (pnt < IWL_FW_INI_APPLY_AFTER_ALIVE) { - IWL_ERR(fwrt, invalid_ap_str, pnt, - "host command"); - break; - } - iwl_dbg_tlv_apply_hcmd(fwrt, tlv); - break; - case IWL_UCODE_TLV_TYPE_REGIONS: - iwl_dbg_tlv_apply_region(fwrt, ini_tlv, pnt); - break; - case IWL_UCODE_TLV_TYPE_TRIGGERS: - iwl_dbg_tlv_apply_trigger(fwrt, ini_tlv, pnt); - break; - default: - WARN_ONCE(1, "WRT: Invalid TLV 0x%x for apply point\n", - type); - break; - } - } -} - -static void iwl_dbg_tlv_reset_cfg(struct iwl_fw_runtime *fwrt) -{ - int i; - - for (i = 0; i < IWL_FW_INI_MAX_REGION_ID; i++) - fwrt->dump.active_regs[i] = NULL; - - /* disable the triggers, used in recovery flow */ - for (i = 0; i < IWL_FW_TRIGGER_ID_NUM; i++) - fwrt->dump.active_trigs[i].active = false; - - memset(fwrt->dump.img_name, 0, - sizeof(fwrt->dump.img_name)); - memset(fwrt->dump.internal_dbg_cfg_name, 0, - sizeof(fwrt->dump.internal_dbg_cfg_name)); - memset(fwrt->dump.external_dbg_cfg_name, 0, - sizeof(fwrt->dump.external_dbg_cfg_name)); - - fwrt->trans->dbg.ini_dest = IWL_FW_INI_LOCATION_INVALID; -} - -void iwl_dbg_tlv_apply_point(struct iwl_fw_runtime *fwrt, - enum iwl_fw_ini_apply_point apply_point) -{ - void *data; - - if (apply_point == IWL_FW_INI_APPLY_EARLY) - iwl_dbg_tlv_reset_cfg(fwrt); - - if (fwrt->trans->dbg.internal_ini_cfg != IWL_INI_CFG_STATE_NOT_LOADED) { - IWL_DEBUG_FW(fwrt, - "WRT: Enabling internal configuration apply point %d\n", - apply_point); - data = &fwrt->trans->dbg.apply_points[apply_point]; - _iwl_dbg_tlv_apply_point(fwrt, data, apply_point, false); - } - - if (fwrt->trans->dbg.external_ini_cfg != IWL_INI_CFG_STATE_NOT_LOADED) { - IWL_DEBUG_FW(fwrt, - "WRT: Enabling external configuration apply point %d\n", - apply_point); - data = &fwrt->trans->dbg.apply_points_ext[apply_point]; - _iwl_dbg_tlv_apply_point(fwrt, data, apply_point, true); - } -} -IWL_EXPORT_SYMBOL(iwl_dbg_tlv_apply_point); +IWL_EXPORT_SYMBOL(iwl_dbg_tlv_time_point); diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h index 93496945d313..c7988b6a209a 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h @@ -74,6 +74,14 @@ struct iwl_apply_point_data { struct iwl_ucode_tlv tlv; }; +/** + * union iwl_dbg_tlv_tp_data - data that is given in a time point + * @fw_pkt: a packet received from the FW + */ +union iwl_dbg_tlv_tp_data { + struct iwl_rx_packet *fw_pkt; +}; + struct iwl_trans; struct iwl_fw_runtime; @@ -81,7 +89,8 @@ void iwl_dbg_tlv_load_bin(struct device *dev, struct iwl_trans *trans); void iwl_dbg_tlv_free(struct iwl_trans *trans); void iwl_dbg_tlv_alloc(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv, bool ext); -void iwl_dbg_tlv_apply_point(struct iwl_fw_runtime *fwrt, - enum iwl_fw_ini_apply_point apply_point); +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); #endif /* __iwl_dbg_tlv_h__*/ diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h index b6c79f45d1ec..a31408188ed0 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h @@ -708,7 +708,6 @@ struct iwl_self_init_dram { * @external_ini_cfg: external debug cfg state. Uses &enum iwl_ini_cfg_state * @num_blocks: number of blocks in fw_mon * @fw_mon: address of the buffers for firmware monitor - * @is_alloc: bit i is set if buffer i was allocated * @hw_error: equals true if hw error interrupt was received from the FW * @ini_dest: debug monitor destination uses &enum iwl_fw_ini_buffer_location */ @@ -727,12 +726,8 @@ struct iwl_trans_debug { enum iwl_ini_cfg_state internal_ini_cfg; enum iwl_ini_cfg_state external_ini_cfg; - struct iwl_apply_point_data apply_points[IWL_FW_INI_APPLY_NUM]; - struct iwl_apply_point_data apply_points_ext[IWL_FW_INI_APPLY_NUM]; - int num_blocks; struct iwl_dram_data fw_mon[IWL_FW_INI_ALLOCATION_NUM]; - u32 is_alloc; bool hw_error; enum iwl_fw_ini_buffer_location ini_dest; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index f93d50ceca68..014eca6596e2 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -431,7 +431,7 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) iwl_wait_init_complete, NULL); - iwl_dbg_tlv_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_EARLY); + iwl_dbg_tlv_time_point(&mvm->fwrt, IWL_FW_INI_TIME_POINT_EARLY, NULL); /* Will also start the device */ ret = iwl_mvm_load_ucode_wait_alive(mvm, IWL_UCODE_REGULAR); @@ -439,7 +439,8 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) IWL_ERR(mvm, "Failed to start RT ucode: %d\n", ret); goto error; } - iwl_dbg_tlv_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_AFTER_ALIVE); + iwl_dbg_tlv_time_point(&mvm->fwrt, IWL_FW_INI_TIME_POINT_AFTER_ALIVE, + NULL); /* Send init config command to mark that we are sending NVM access * commands @@ -1264,7 +1265,7 @@ static int iwl_mvm_load_rt_fw(struct iwl_mvm *mvm) if (ret) return ret; - iwl_dbg_tlv_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_EARLY); + iwl_dbg_tlv_time_point(&mvm->fwrt, IWL_FW_INI_TIME_POINT_EARLY, NULL); mvm->rfkill_safe_init_done = false; ret = iwl_mvm_load_ucode_wait_alive(mvm, IWL_UCODE_REGULAR); @@ -1273,7 +1274,8 @@ static int iwl_mvm_load_rt_fw(struct iwl_mvm *mvm) mvm->rfkill_safe_init_done = true; - iwl_dbg_tlv_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_AFTER_ALIVE); + iwl_dbg_tlv_time_point(&mvm->fwrt, IWL_FW_INI_TIME_POINT_AFTER_ALIVE, + NULL); return iwl_init_paging(&mvm->fwrt, mvm->fwrt.cur_fw_img); } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c index 62536c09e727..9c417dd06291 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c @@ -1431,6 +1431,9 @@ void iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm, else if (rx_missed_bcon_since_rx > IWL_MVM_MISSED_BEACONS_THRESHOLD) ieee80211_beacon_loss(vif); + iwl_dbg_tlv_time_point(&mvm->fwrt, + IWL_FW_INI_TIME_POINT_MISSED_BEACONS, NULL); + trigger = iwl_fw_dbg_trigger_on(&mvm->fwrt, ieee80211_vif_to_wdev(vif), FW_DBG_TRIGGER_MISSED_BEACONS); if (!trigger) @@ -1447,8 +1450,6 @@ void iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm, rx_missed_bcon >= stop_trig_missed_bcon) iwl_fw_dbg_collect_trig(&mvm->fwrt, trigger, NULL); - iwl_dbg_tlv_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_MISSED_BEACONS); - out: rcu_read_unlock(); } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index bec48a55f890..352f174da460 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -1106,7 +1106,10 @@ int __iwl_mvm_mac_start(struct iwl_mvm *mvm) } ret = iwl_mvm_up(mvm); - iwl_dbg_tlv_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_POST_INIT); + iwl_dbg_tlv_time_point(&mvm->fwrt, IWL_FW_INI_TIME_POINT_POST_INIT, + NULL); + iwl_dbg_tlv_time_point(&mvm->fwrt, IWL_FW_INI_TIME_POINT_PERIODIC, + NULL); if (ret && test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) { /* Something went wrong - we need to finish some cleanup diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 961c7ab7950b..28e836a55119 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -753,9 +753,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, trans_cfg.rx_buf_size = rb_size_default; } - BUILD_BUG_ON(sizeof(struct iwl_ldbg_config_cmd) != - LDBG_CFG_COMMAND_SIZE); - trans->wide_cmd_header = true; trans_cfg.bc_table_dword = mvm->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_22560; @@ -990,7 +987,10 @@ static void iwl_mvm_rx_common(struct iwl_mvm *mvm, struct iwl_rx_packet *pkt) { int i; + union iwl_dbg_tlv_tp_data tp_data = { .fw_pkt = pkt }; + iwl_dbg_tlv_time_point(&mvm->fwrt, + IWL_FW_INI_TIME_POINT_FW_RSP_OR_NOTIF, &tp_data); iwl_mvm_rx_check_trigger(mvm, pkt); /* diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c index 892db3dcdc27..f6b3045badbd 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c @@ -1939,8 +1939,6 @@ void iwl_mvm_rx_umac_scan_complete_notif(struct iwl_mvm *mvm, mvm->last_ebs_successful = false; mvm->scan_uid_status[uid] = 0; - - iwl_dbg_tlv_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_SCAN_COMPLETE); } void iwl_mvm_rx_umac_scan_iter_complete_notif(struct iwl_mvm *mvm, From 4d3f5e8e7e3c5783676fbf1c61436e47a4b6b4bd Mon Sep 17 00:00:00 2001 From: Shahar S Matityahu Date: Thu, 4 Jul 2019 17:53:52 +0300 Subject: [PATCH 77/80] iwlwifi: fw api: add DRAM buffer allocation command Add support code to be able to use the DRAM buffer allocation command, which allows us to send information about a buffer to the firmware to use it with the DBGC hardware. Signed-off-by: Shahar S Matityahu Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/fw/api/debug.h | 32 +++++++++++++++++++ drivers/net/wireless/intel/iwlwifi/fw/file.h | 1 + drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 1 + 3 files changed, 34 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/debug.h b/drivers/net/wireless/intel/iwlwifi/fw/api/debug.h index c67a6ab6491c..98e957ecbeed 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/debug.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/debug.h @@ -87,6 +87,12 @@ enum iwl_debug_cmds { * 1 - suspend DBGC recording */ DBGC_SUSPEND_RESUME = 0x7, + /** + * @BUFFER_ALLOCATION: + * passes DRAM buffers to a DBGC + * &struct iwl_buf_alloc_cmd + */ + BUFFER_ALLOCATION = 0x8, /** * @MFU_ASSERT_DUMP_NTF: * &struct iwl_mfu_assert_dump_notif @@ -361,4 +367,30 @@ struct iwl_dbg_suspend_resume_cmd { __le32 operation; } __packed; +#define BUF_ALLOC_MAX_NUM_FRAGS 16 + +/** + * struct iwl_buf_alloc_frag - a DBGC fragment + * @addr: base address of the fragment + * @size: size of the fragment + */ +struct iwl_buf_alloc_frag { + __le64 addr; + __le32 size; +} __packed; /* FRAGMENT_STRUCTURE_API_S_VER_1 */ + +/** + * struct iwl_buf_alloc_cmd - buffer allocation command + * @alloc_id: &enum iwl_fw_ini_allocation_id + * @buf_location: &enum iwl_fw_ini_buffer_location + * @num_frags: number of fragments + * @frags: fragments array + */ +struct iwl_buf_alloc_cmd { + __le32 alloc_id; + __le32 buf_location; + __le32 num_frags; + struct iwl_buf_alloc_frag frags[BUF_ALLOC_MAX_NUM_FRAGS]; +} __packed; /* BUFFER_ALLOCATION_CMD_API_S_VER_2 */ + #endif /* __iwl_fw_api_debug_h__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h index 1bdcab9b9275..423cc0cf8e78 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/file.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h @@ -468,6 +468,7 @@ enum iwl_ucode_tlv_capa { IWL_UCODE_TLV_CAPA_MCC_UPDATE_11AX_SUPPORT = (__force iwl_ucode_tlv_capa_t)89, IWL_UCODE_TLV_CAPA_CSI_REPORTING = (__force iwl_ucode_tlv_capa_t)90, IWL_UCODE_TLV_CAPA_DBG_SUSPEND_RESUME_CMD_SUPP = (__force iwl_ucode_tlv_capa_t)92, + IWL_UCODE_TLV_CAPA_DBG_BUF_ALLOC_CMD_SUPP = (__force iwl_ucode_tlv_capa_t)93, /* set 3 */ IWL_UCODE_TLV_CAPA_MLME_OFFLOAD = (__force iwl_ucode_tlv_capa_t)96, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 28e836a55119..35af56acc30b 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -468,6 +468,7 @@ static const struct iwl_hcmd_names iwl_mvm_data_path_names[] = { */ static const struct iwl_hcmd_names iwl_mvm_debug_names[] = { HCMD_NAME(DBGC_SUSPEND_RESUME), + HCMD_NAME(BUFFER_ALLOCATION), HCMD_NAME(MFU_ASSERT_DUMP_NTF), }; From 4828f462b5eb32bf99d5c770e81f683a79e9712c Mon Sep 17 00:00:00 2001 From: Shahar S Matityahu Date: Wed, 10 Jul 2019 13:23:30 +0300 Subject: [PATCH 78/80] iwlwifi: dbg_ini: fix dump structs doc Fix the documentation of struct iwl_fw_ini_monitor_dump and iwl_fw_ini_error_dump_range. Signed-off-by: Shahar S Matityahu Signed-off-by: Luca Coelho --- .../net/wireless/intel/iwlwifi/fw/error-dump.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h b/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h index 9529e5925ad5..2e763678dbdb 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h @@ -323,10 +323,10 @@ struct iwl_fw_ini_fifo_hdr { /** * struct iwl_fw_ini_error_dump_range - range of memory * @range_data_size: the size of this range, in bytes - * @internal_base_addr - base address of internal memory range - * @dram_base_addr - base address of dram monitor range - * @page_num - page number of memory range - * @fifo_hdr - fifo header of memory range + * @internal_base_addr: base address of internal memory range + * @dram_base_addr: base address of dram monitor range + * @page_num: page number of memory range + * @fifo_hdr: fifo header of memory range * @data: the actual memory */ struct iwl_fw_ini_error_dump_range { @@ -454,10 +454,10 @@ struct iwl_fw_error_dump_rb { /** * struct iwl_fw_ini_monitor_dump - ini monitor dump - * @header - header of the region - * @write_ptr - write pointer position in the buffer - * @cycle_cnt - cycles count - * @ranges - the memory ranges of this this region + * @header: header of the region + * @write_ptr: write pointer position in the buffer + * @cycle_cnt: cycles count + * @ranges: the memory ranges of this this region */ struct iwl_fw_ini_monitor_dump { struct iwl_fw_ini_error_dump_header header; From 9b1bcfcc6e068ab2106749bf8faffb8a7d73b976 Mon Sep 17 00:00:00 2001 From: Shahar S Matityahu Date: Mon, 1 Jul 2019 16:03:48 +0300 Subject: [PATCH 79/80] iwlwifi: dbg_ini: remove periodic trigger Remove periodic trigger functionality. After moving to the new API we will add periodic trigger functionality that matches the new API. Signed-off-by: Shahar S Matityahu Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 27 +------------------ drivers/net/wireless/intel/iwlwifi/fw/dbg.h | 6 ++--- drivers/net/wireless/intel/iwlwifi/fw/init.c | 2 -- .../net/wireless/intel/iwlwifi/fw/runtime.h | 1 - .../net/wireless/intel/iwlwifi/iwl-dbg-tlv.c | 6 +++++ .../net/wireless/intel/iwlwifi/iwl-dbg-tlv.h | 1 + drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 2 +- 7 files changed, 11 insertions(+), 34 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 310b85b508b3..5c8602de9168 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -2381,7 +2381,7 @@ void iwl_fw_dbg_stop_sync(struct iwl_fw_runtime *fwrt) { int i; - del_timer(&fwrt->dump.periodic_trig); + iwl_dbg_tlv_del_timers(fwrt->trans); for (i = 0; i < IWL_FW_RUNTIME_DUMP_WK_NUM; i++) iwl_fw_dbg_collect_sync(fwrt, i); @@ -2389,31 +2389,6 @@ void iwl_fw_dbg_stop_sync(struct iwl_fw_runtime *fwrt) } IWL_EXPORT_SYMBOL(iwl_fw_dbg_stop_sync); -void iwl_fw_dbg_periodic_trig_handler(struct timer_list *t) -{ - struct iwl_fw_runtime *fwrt; - enum iwl_fw_ini_trigger_id id = IWL_FW_TRIGGER_ID_PERIODIC_TRIGGER; - int ret; - typeof(fwrt->dump) *dump_ptr = container_of(t, typeof(fwrt->dump), - periodic_trig); - - fwrt = container_of(dump_ptr, typeof(*fwrt), dump); - - ret = _iwl_fw_dbg_ini_collect(fwrt, id); - if (!ret || ret == -EBUSY) { - struct iwl_fw_ini_trigger *trig = - fwrt->dump.active_trigs[id].trig; - u32 occur = le32_to_cpu(trig->occurrences); - u32 collect_interval = le32_to_cpu(trig->trigger_data); - - if (!occur) - return; - - mod_timer(&fwrt->dump.periodic_trig, - jiffies + msecs_to_jiffies(collect_interval)); - } -} - #define FSEQ_REG(x) { .addr = (x), .str = #x, } void iwl_fw_error_print_fseq_regs(struct iwl_fw_runtime *fwrt) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h index b2445bef908c..14181e6dc00d 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h @@ -314,7 +314,7 @@ static inline void iwl_fw_flush_dumps(struct iwl_fw_runtime *fwrt) { int i; - del_timer(&fwrt->dump.periodic_trig); + iwl_dbg_tlv_del_timers(fwrt->trans); for (i = 0; i < IWL_FW_RUNTIME_DUMP_WK_NUM; i++) { flush_delayed_work(&fwrt->dump.wks[i].wk); fwrt->dump.wks[i].ini_trig_id = IWL_FW_TRIGGER_ID_INVALID; @@ -325,7 +325,7 @@ static inline void iwl_fw_cancel_dumps(struct iwl_fw_runtime *fwrt) { int i; - del_timer(&fwrt->dump.periodic_trig); + iwl_dbg_tlv_del_timers(fwrt->trans); for (i = 0; i < IWL_FW_RUNTIME_DUMP_WK_NUM; i++) { cancel_delayed_work_sync(&fwrt->dump.wks[i].wk); fwrt->dump.wks[i].ini_trig_id = IWL_FW_TRIGGER_ID_INVALID; @@ -400,8 +400,6 @@ static inline void iwl_fw_error_collect(struct iwl_fw_runtime *fwrt) } } -void iwl_fw_dbg_periodic_trig_handler(struct timer_list *t); - void iwl_fw_error_print_fseq_regs(struct iwl_fw_runtime *fwrt); static inline void iwl_fwrt_update_fw_versions(struct iwl_fw_runtime *fwrt, diff --git a/drivers/net/wireless/intel/iwlwifi/fw/init.c b/drivers/net/wireless/intel/iwlwifi/fw/init.c index c16d6e126e3c..ba00d162ce72 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/init.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/init.c @@ -81,8 +81,6 @@ void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans, INIT_DELAYED_WORK(&fwrt->dump.wks[i].wk, iwl_fw_error_dump_wk); } iwl_fwrt_dbgfs_register(fwrt, dbgfs_dir); - timer_setup(&fwrt->dump.periodic_trig, - iwl_fw_dbg_periodic_trig_handler, 0); } IWL_EXPORT_SYMBOL(iwl_fw_runtime_init); diff --git a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h index 40b92509085d..8b8ab6d692b6 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h @@ -159,7 +159,6 @@ struct iwl_fw_runtime { u32 umac_err_id; struct iwl_txf_iter_data txf_iter_data; - struct timer_list periodic_trig; u8 img_name[IWL_FW_INI_MAX_IMG_NAME_LEN]; u8 internal_dbg_cfg_name[IWL_FW_INI_MAX_DBG_CFG_NAME_LEN]; diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c index db76b28eac40..3d7f8ff8ef58 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c @@ -151,6 +151,12 @@ void iwl_dbg_tlv_alloc(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv, *cfg_state = IWL_INI_CFG_STATE_CORRUPTED; } +void iwl_dbg_tlv_del_timers(struct iwl_trans *trans) +{ + /* will be used later */ +} +IWL_EXPORT_SYMBOL(iwl_dbg_tlv_del_timers); + void iwl_dbg_tlv_free(struct iwl_trans *trans) { /* will be used again later */ diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h index c7988b6a209a..e257ad358c94 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h @@ -92,5 +92,6 @@ void iwl_dbg_tlv_alloc(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv, 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); +void iwl_dbg_tlv_del_timers(struct iwl_trans *trans); #endif /* __iwl_dbg_tlv_h__*/ diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 35af56acc30b..3acbd5b7ab4b 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -1239,7 +1239,7 @@ static void iwl_mvm_reprobe_wk(struct work_struct *wk) void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error) { iwl_abort_notification_waits(&mvm->notif_wait); - del_timer(&mvm->fwrt.dump.periodic_trig); + iwl_dbg_tlv_del_timers(mvm->trans); /* * This is a bit racy, but worst case we tell mac80211 about From 787350ef8d8044754582e79d28a0d5ef4df08ba4 Mon Sep 17 00:00:00 2001 From: Shahar S Matityahu Date: Tue, 9 Jul 2019 12:27:07 +0300 Subject: [PATCH 80/80] iwlwifi: dbg: remove iwl_fw_cancel_dumps function Use cancel_delayed_work_sync on the dump workers only in case of unloading the op mode. In any other case use iwl_fw_flush_dumps or iwl_fw_dbg_stop_sync (depends if the op mode mutex is held or not). This way, the driver will wait until debug data is collected in all cases but op mode unloading. Signed-off-by: Shahar S Matityahu Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.h | 11 ----------- drivers/net/wireless/intel/iwlwifi/fw/runtime.h | 4 ++++ drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 1 - 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h index 14181e6dc00d..e3b5dd34643f 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h @@ -321,17 +321,6 @@ static inline void iwl_fw_flush_dumps(struct iwl_fw_runtime *fwrt) } } -static inline void iwl_fw_cancel_dumps(struct iwl_fw_runtime *fwrt) -{ - int i; - - iwl_dbg_tlv_del_timers(fwrt->trans); - for (i = 0; i < IWL_FW_RUNTIME_DUMP_WK_NUM; i++) { - cancel_delayed_work_sync(&fwrt->dump.wks[i].wk); - fwrt->dump.wks[i].ini_trig_id = IWL_FW_TRIGGER_ID_INVALID; - } -} - #ifdef CONFIG_IWLWIFI_DEBUGFS static inline void iwl_fw_cancel_timestamp(struct iwl_fw_runtime *fwrt) { diff --git a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h index 8b8ab6d692b6..be436c18a047 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h @@ -203,6 +203,10 @@ static inline void iwl_fw_runtime_free(struct iwl_fw_runtime *fwrt) kfree(active->trig); active->trig = NULL; } + + iwl_dbg_tlv_del_timers(fwrt->trans); + for (i = 0; i < IWL_FW_RUNTIME_DUMP_WK_NUM; i++) + cancel_delayed_work_sync(&fwrt->dump.wks[i].wk); } void iwl_fw_runtime_suspend(struct iwl_fw_runtime *fwrt); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 352f174da460..cd1b10042fbf 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -1243,7 +1243,6 @@ static void iwl_mvm_mac_stop(struct ieee80211_hw *hw) */ clear_bit(IWL_MVM_STATUS_FIRMWARE_RUNNING, &mvm->status); - iwl_fw_cancel_dumps(&mvm->fwrt); cancel_delayed_work_sync(&mvm->cs_tx_unblock_dwork); cancel_delayed_work_sync(&mvm->scan_timeout_dwork); iwl_fw_free_dump_desc(&mvm->fwrt);