From 91a8bcde2e7feb2c2782ddc6a266cf5f5294d16f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 14 Jan 2015 18:12:41 +0100 Subject: iwlwifi: mvm: support radio statistics as global survey Export the radio statistics from the statistics v10 API (if the firmware also has the capability to fill these statistics) using the global survey data facility. Signed-off-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/utils.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'drivers/net/wireless/iwlwifi/mvm/utils.c') diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c index 8decf9953229..2b75a0d6d41e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/iwlwifi/mvm/utils.c @@ -643,6 +643,35 @@ void iwl_mvm_update_smps(struct iwl_mvm *mvm, struct ieee80211_vif *vif, ieee80211_request_smps(vif, smps_mode); } +int iwl_mvm_request_statistics(struct iwl_mvm *mvm) +{ + struct iwl_statistics_cmd scmd = {}; + struct iwl_host_cmd cmd = { + .id = STATISTICS_CMD, + .len[0] = sizeof(scmd), + .data[0] = &scmd, + .flags = CMD_WANT_SKB, + }; + int ret; + + ret = iwl_mvm_send_cmd(mvm, &cmd); + if (ret) + return ret; + + iwl_mvm_handle_rx_statistics(mvm, cmd.resp_pkt); + iwl_free_resp(&cmd); + + return 0; +} + +void iwl_mvm_accu_radio_stats(struct iwl_mvm *mvm) +{ + mvm->accu_radio_stats.rx_time += mvm->radio_stats.rx_time; + mvm->accu_radio_stats.tx_time += mvm->radio_stats.tx_time; + mvm->accu_radio_stats.on_time_rf += mvm->radio_stats.on_time_rf; + mvm->accu_radio_stats.on_time_scan += mvm->radio_stats.on_time_scan; +} + static void iwl_mvm_diversity_iter(void *_data, u8 *mac, struct ieee80211_vif *vif) { -- cgit v1.2.3 From 1f9403863c080478ad78247c89b018e95bdfb027 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Tue, 10 Feb 2015 13:03:38 +0200 Subject: iwlwifi: mvm: remove deprecated scan API code The legacy scan API is deprecated and not used anymore with 10 and higher firmware versions. Since we deprecated firmware version 9, we can remove a whole lot of unused code. Signed-off-by: Luciano Coelho Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/iwl-fw-file.h | 2 - drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h | 191 -------- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 23 +- drivers/net/wireless/iwlwifi/mvm/mvm.h | 16 - drivers/net/wireless/iwlwifi/mvm/ops.c | 2 - drivers/net/wireless/iwlwifi/mvm/scan.c | 585 +------------------------ drivers/net/wireless/iwlwifi/mvm/utils.c | 19 - 7 files changed, 20 insertions(+), 818 deletions(-) (limited to 'drivers/net/wireless/iwlwifi/mvm/utils.c') diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h index 8b9040ef20e0..be4393e2c19c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h @@ -237,7 +237,6 @@ enum iwl_ucode_tlv_flag { * enum iwl_ucode_tlv_api - ucode api * @IWL_UCODE_TLV_API_BT_COEX_SPLIT: new API for BT Coex * @IWL_UCODE_TLV_API_DISABLE_STA_TX: ucode supports tx_disable bit. - * @IWL_UCODE_TLV_API_LMAC_SCAN: This ucode uses LMAC unified scan API. * @IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF: ucode supports disabling dummy notif. * @IWL_UCODE_TLV_API_FRAGMENTED_SCAN: This ucode supports active dwell time * longer than the passive one, which is essential for fragmented scan. @@ -255,7 +254,6 @@ enum iwl_ucode_tlv_flag { enum iwl_ucode_tlv_api { IWL_UCODE_TLV_API_BT_COEX_SPLIT = BIT(3), IWL_UCODE_TLV_API_DISABLE_STA_TX = BIT(5), - IWL_UCODE_TLV_API_LMAC_SCAN = BIT(6), IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF = BIT(7), IWL_UCODE_TLV_API_FRAGMENTED_SCAN = BIT(8), IWL_UCODE_TLV_API_HDC_PHASE_0 = BIT(10), diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h index cfc0e65b34a5..a5fbbd637070 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h @@ -70,54 +70,9 @@ /* Scan Commands, Responses, Notifications */ -/* Masks for iwl_scan_channel.type flags */ -#define SCAN_CHANNEL_TYPE_ACTIVE BIT(0) -#define SCAN_CHANNEL_NARROW_BAND BIT(22) - /* Max number of IEs for direct SSID scans in a command */ #define PROBE_OPTION_MAX 20 -/** - * struct iwl_scan_channel - entry in REPLY_SCAN_CMD channel table - * @channel: band is selected by iwl_scan_cmd "flags" field - * @tx_gain: gain for analog radio - * @dsp_atten: gain for DSP - * @active_dwell: dwell time for active scan in TU, typically 5-50 - * @passive_dwell: dwell time for passive scan in TU, typically 20-500 - * @type: type is broken down to these bits: - * bit 0: 0 = passive, 1 = active - * bits 1-20: SSID direct bit map. If any of these bits is set then - * the corresponding SSID IE is transmitted in probe request - * (bit i adds IE in position i to the probe request) - * bit 22: channel width, 0 = regular, 1 = TGj narrow channel - * - * @iteration_count: - * @iteration_interval: - * This struct is used once for each channel in the scan list. - * Each channel can independently select: - * 1) SSID for directed active scans - * 2) Txpower setting (for rate specified within Tx command) - * 3) How long to stay on-channel (behavior may be modified by quiet_time, - * quiet_plcp_th, good_CRC_th) - * - * To avoid uCode errors, make sure the following are true (see comments - * under struct iwl_scan_cmd about max_out_time and quiet_time): - * 1) If using passive_dwell (i.e. passive_dwell != 0): - * active_dwell <= passive_dwell (< max_out_time if max_out_time != 0) - * 2) quiet_time <= active_dwell - * 3) If restricting off-channel time (i.e. max_out_time !=0): - * passive_dwell < max_out_time - * active_dwell < max_out_time - */ -struct iwl_scan_channel { - __le32 type; - __le16 channel; - __le16 iteration_count; - __le32 iteration_interval; - __le16 active_dwell; - __le16 passive_dwell; -} __packed; /* SCAN_CHANNEL_CONTROL_API_S_VER_1 */ - /** * struct iwl_ssid_ie - directed scan network information element * @@ -132,152 +87,6 @@ struct iwl_ssid_ie { u8 ssid[IEEE80211_MAX_SSID_LEN]; } __packed; /* SCAN_DIRECT_SSID_IE_API_S_VER_1 */ -/** - * iwl_scan_flags - masks for scan command flags - *@SCAN_FLAGS_PERIODIC_SCAN: - *@SCAN_FLAGS_P2P_PUBLIC_ACTION_FRAME_TX: - *@SCAN_FLAGS_DELAYED_SCAN_LOWBAND: - *@SCAN_FLAGS_DELAYED_SCAN_HIGHBAND: - *@SCAN_FLAGS_FRAGMENTED_SCAN: - *@SCAN_FLAGS_PASSIVE2ACTIVE: use active scan on channels that was active - * in the past hour, even if they are marked as passive. - */ -enum iwl_scan_flags { - SCAN_FLAGS_PERIODIC_SCAN = BIT(0), - SCAN_FLAGS_P2P_PUBLIC_ACTION_FRAME_TX = BIT(1), - SCAN_FLAGS_DELAYED_SCAN_LOWBAND = BIT(2), - SCAN_FLAGS_DELAYED_SCAN_HIGHBAND = BIT(3), - SCAN_FLAGS_FRAGMENTED_SCAN = BIT(4), - SCAN_FLAGS_PASSIVE2ACTIVE = BIT(5), -}; - -/** - * enum iwl_scan_type - Scan types for scan command - * @SCAN_TYPE_FORCED: - * @SCAN_TYPE_BACKGROUND: - * @SCAN_TYPE_OS: - * @SCAN_TYPE_ROAMING: - * @SCAN_TYPE_ACTION: - * @SCAN_TYPE_DISCOVERY: - * @SCAN_TYPE_DISCOVERY_FORCED: - */ -enum iwl_scan_type { - SCAN_TYPE_FORCED = 0, - SCAN_TYPE_BACKGROUND = 1, - SCAN_TYPE_OS = 2, - SCAN_TYPE_ROAMING = 3, - SCAN_TYPE_ACTION = 4, - SCAN_TYPE_DISCOVERY = 5, - SCAN_TYPE_DISCOVERY_FORCED = 6, -}; /* SCAN_ACTIVITY_TYPE_E_VER_1 */ - -/** - * struct iwl_scan_cmd - scan request command - * ( SCAN_REQUEST_CMD = 0x80 ) - * @len: command length in bytes - * @scan_flags: scan flags from SCAN_FLAGS_* - * @channel_count: num of channels in channel list - * (1 - ucode_capa.n_scan_channels) - * @quiet_time: in msecs, dwell this time for active scan on quiet channels - * @quiet_plcp_th: quiet PLCP threshold (channel is quiet if less than - * this number of packets were received (typically 1) - * @passive2active: is auto switching from passive to active during scan allowed - * @rxchain_sel_flags: RXON_RX_CHAIN_* - * @max_out_time: in TUs, max out of serving channel time - * @suspend_time: how long to pause scan when returning to service channel: - * bits 0-19: beacon interal in TUs (suspend before executing) - * bits 20-23: reserved - * bits 24-31: number of beacons (suspend between channels) - * @rxon_flags: RXON_FLG_* - * @filter_flags: RXON_FILTER_* - * @tx_cmd: for active scans (zero for passive), w/o payload, - * no RS so specify TX rate - * @direct_scan: direct scan SSIDs - * @type: one of SCAN_TYPE_* - * @repeats: how many time to repeat the scan - */ -struct iwl_scan_cmd { - __le16 len; - u8 scan_flags; - u8 channel_count; - __le16 quiet_time; - __le16 quiet_plcp_th; - __le16 passive2active; - __le16 rxchain_sel_flags; - __le32 max_out_time; - __le32 suspend_time; - /* RX_ON_FLAGS_API_S_VER_1 */ - __le32 rxon_flags; - __le32 filter_flags; - struct iwl_tx_cmd tx_cmd; - struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX]; - __le32 type; - __le32 repeats; - - /* - * Probe request frame, followed by channel list. - * - * Size of probe request frame is specified by byte count in tx_cmd. - * Channel list follows immediately after probe request frame. - * Number of channels in list is specified by channel_count. - * Each channel in list is of type: - * - * struct iwl_scan_channel channels[0]; - * - * NOTE: Only one band of channels can be scanned per pass. You - * must not mix 2.4GHz channels and 5.2GHz channels, and you must wait - * for one scan to complete (i.e. receive SCAN_COMPLETE_NOTIFICATION) - * before requesting another scan. - */ - u8 data[0]; -} __packed; /* SCAN_REQUEST_FIXED_PART_API_S_VER_5 */ - -/* Response to scan request contains only status with one of these values */ -#define SCAN_RESPONSE_OK 0x1 -#define SCAN_RESPONSE_ERROR 0x2 - -/* - * SCAN_ABORT_CMD = 0x81 - * When scan abort is requested, the command has no fields except the common - * header. The response contains only a status with one of these values. - */ -#define SCAN_ABORT_POSSIBLE 0x1 -#define SCAN_ABORT_IGNORED 0x2 /* no pending scans */ - -/* TODO: complete documentation */ -#define SCAN_OWNER_STATUS 0x1 -#define MEASURE_OWNER_STATUS 0x2 - -/** - * struct iwl_scan_start_notif - notifies start of scan in the device - * ( SCAN_START_NOTIFICATION = 0x82 ) - * @tsf_low: TSF timer (lower half) in usecs - * @tsf_high: TSF timer (higher half) in usecs - * @beacon_timer: structured as follows: - * bits 0:19 - beacon interval in usecs - * bits 20:23 - reserved (0) - * bits 24:31 - number of beacons - * @channel: which channel is scanned - * @band: 0 for 5.2 GHz, 1 for 2.4 GHz - * @status: one of *_OWNER_STATUS - */ -struct iwl_scan_start_notif { - __le32 tsf_low; - __le32 tsf_high; - __le32 beacon_timer; - u8 channel; - u8 band; - u8 reserved[2]; - __le32 status; -} __packed; /* SCAN_START_NTF_API_S_VER_1 */ - -/* scan results probe_status first bit indicates success */ -#define SCAN_PROBE_STATUS_OK 0 -#define SCAN_PROBE_STATUS_TX_FAILED BIT(0) -/* error statuses combined with TX_FAILED */ -#define SCAN_PROBE_STATUS_FAIL_TTL BIT(1) -#define SCAN_PROBE_STATUS_FAIL_BT BIT(2) - /* How many statistics are gathered for each channel */ #define SCAN_RESULTS_STATISTICS 1 diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 20e1e898e815..0f986d7840b5 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -339,13 +339,10 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) !iwlwifi_mod_params.sw_crypto) hw->flags |= IEEE80211_HW_MFP_CAPABLE; - if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN || - mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN) { - hw->flags |= IEEE80211_SINGLE_HW_SCAN_ON_ALL_BANDS; - hw->wiphy->features |= - NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR | - NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR; - } + hw->flags |= IEEE80211_SINGLE_HW_SCAN_ON_ALL_BANDS; + hw->wiphy->features |= + NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR | + NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR; hw->sta_data_size = sizeof(struct iwl_mvm_sta); hw->vif_data_size = sizeof(struct iwl_mvm_vif); @@ -2204,10 +2201,8 @@ static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw, if (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN) ret = iwl_mvm_scan_umac(mvm, vif, hw_req); - else if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) - ret = iwl_mvm_unified_scan_lmac(mvm, vif, hw_req); else - ret = iwl_mvm_scan_request(mvm, vif, req); + ret = iwl_mvm_unified_scan_lmac(mvm, vif, hw_req); if (ret) iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); @@ -2535,13 +2530,7 @@ static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw, mutex_lock(&mvm->mutex); - /* Newest FW fixes sched scan while connected on another interface */ - if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) { - if (!vif->bss_conf.idle) { - ret = -EBUSY; - goto out; - } - } else if (!iwl_mvm_is_idle(mvm)) { + if (!vif->bss_conf.idle) { ret = -EBUSY; goto out; } diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index d4f3b8400ccc..90a1ea3e6507 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -1080,13 +1080,6 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, /* Scanning */ int iwl_mvm_scan_size(struct iwl_mvm *mvm); -int iwl_mvm_scan_request(struct iwl_mvm *mvm, - struct ieee80211_vif *vif, - struct cfg80211_scan_request *req); -int iwl_mvm_rx_scan_response(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, - struct iwl_device_cmd *cmd); -int iwl_mvm_rx_scan_complete(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, - struct iwl_device_cmd *cmd); int iwl_mvm_cancel_scan(struct iwl_mvm *mvm); int iwl_mvm_max_scan_ie_len(struct iwl_mvm *mvm, bool is_sched_scan); @@ -1097,14 +1090,8 @@ int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm, int iwl_mvm_rx_scan_offload_iter_complete_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd); -int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm, - struct ieee80211_vif *vif, - struct cfg80211_sched_scan_request *req, - struct ieee80211_scan_ies *ies); int iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm, struct cfg80211_sched_scan_request *req); -int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm, - struct cfg80211_sched_scan_request *req); int iwl_mvm_scan_offload_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct cfg80211_sched_scan_request *req, @@ -1359,9 +1346,6 @@ static inline void iwl_mvm_enable_agg_txq(struct iwl_mvm *mvm, int queue, iwl_mvm_enable_txq(mvm, queue, ssn, &cfg, wdg_timeout); } -/* Assoc status */ -bool iwl_mvm_is_idle(struct iwl_mvm *mvm); - /* Thermal management and CT-kill */ void iwl_mvm_tt_tx_backoff(struct iwl_mvm *mvm, u32 backoff); void iwl_mvm_tt_temp_changed(struct iwl_mvm *mvm, u32 temp); diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index 7a045330ab59..1f64d23e7590 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c @@ -237,8 +237,6 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = { RX_HANDLER(EOSP_NOTIFICATION, iwl_mvm_rx_eosp_notif, false), - RX_HANDLER(SCAN_REQUEST_CMD, iwl_mvm_rx_scan_response, false), - RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, true), RX_HANDLER(SCAN_ITERATION_COMPLETE, iwl_mvm_rx_scan_offload_iter_complete_notif, false), RX_HANDLER(SCAN_OFFLOAD_COMPLETE, diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c index 7e9aa3cb3254..ca3a18764ab1 100644 --- a/drivers/net/wireless/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/iwlwifi/mvm/scan.c @@ -191,101 +191,6 @@ static u16 iwl_mvm_get_passive_dwell(struct iwl_mvm *mvm, return band == IEEE80211_BAND_2GHZ ? 100 + 20 : 100 + 10; } -static void iwl_mvm_scan_fill_channels(struct iwl_scan_cmd *cmd, - struct cfg80211_scan_request *req, - bool basic_ssid, - struct iwl_mvm_scan_params *params) -{ - struct iwl_scan_channel *chan = (struct iwl_scan_channel *) - (cmd->data + le16_to_cpu(cmd->tx_cmd.len)); - int i; - int type = BIT(req->n_ssids) - 1; - enum ieee80211_band band = req->channels[0]->band; - - if (!basic_ssid) - type |= BIT(req->n_ssids); - - for (i = 0; i < cmd->channel_count; i++) { - chan->channel = cpu_to_le16(req->channels[i]->hw_value); - chan->type = cpu_to_le32(type); - if (req->channels[i]->flags & IEEE80211_CHAN_NO_IR) - chan->type &= cpu_to_le32(~SCAN_CHANNEL_TYPE_ACTIVE); - chan->active_dwell = cpu_to_le16(params->dwell[band].active); - chan->passive_dwell = cpu_to_le16(params->dwell[band].passive); - chan->iteration_count = cpu_to_le16(1); - chan++; - } -} - -/* - * Fill in probe request with the following parameters: - * TA is our vif HW address, which mac80211 ensures we have. - * Packet is broadcasted, so this is both SA and DA. - * The probe request IE is made out of two: first comes the most prioritized - * SSID if a directed scan is requested. Second comes whatever extra - * information was given to us as the scan request IE. - */ -static u16 iwl_mvm_fill_probe_req(struct ieee80211_mgmt *frame, const u8 *ta, - int n_ssids, const u8 *ssid, int ssid_len, - const u8 *band_ie, int band_ie_len, - const u8 *common_ie, int common_ie_len, - int left) -{ - int len = 0; - u8 *pos = NULL; - - /* Make sure there is enough space for the probe request, - * two mandatory IEs and the data */ - left -= 24; - if (left < 0) - return 0; - - frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ); - eth_broadcast_addr(frame->da); - memcpy(frame->sa, ta, ETH_ALEN); - eth_broadcast_addr(frame->bssid); - frame->seq_ctrl = 0; - - len += 24; - - /* for passive scans, no need to fill anything */ - if (n_ssids == 0) - return (u16)len; - - /* points to the payload of the request */ - pos = &frame->u.probe_req.variable[0]; - - /* fill in our SSID IE */ - left -= ssid_len + 2; - if (left < 0) - return 0; - *pos++ = WLAN_EID_SSID; - *pos++ = ssid_len; - if (ssid && ssid_len) { /* ssid_len may be == 0 even if ssid is valid */ - memcpy(pos, ssid, ssid_len); - pos += ssid_len; - } - - len += ssid_len + 2; - - if (WARN_ON(left < band_ie_len + common_ie_len)) - return len; - - if (band_ie && band_ie_len) { - memcpy(pos, band_ie, band_ie_len); - pos += band_ie_len; - len += band_ie_len; - } - - if (common_ie && common_ie_len) { - memcpy(pos, common_ie, common_ie_len); - pos += common_ie_len; - len += common_ie_len; - } - - return (u16)len; -} - static void iwl_mvm_scan_condition_iterator(void *data, u8 *mac, struct ieee80211_vif *vif) { @@ -379,20 +284,11 @@ static int iwl_mvm_max_scan_ie_fw_cmd_room(struct iwl_mvm *mvm, { int max_probe_len; - if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) - max_probe_len = SCAN_OFFLOAD_PROBE_REQ_SIZE; - else - max_probe_len = mvm->fw->ucode_capa.max_probe_length; + max_probe_len = SCAN_OFFLOAD_PROBE_REQ_SIZE; /* we create the 802.11 header and SSID element */ max_probe_len -= 24 + 2; - /* basic ssid is added only for hw_scan with and old api */ - if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID) && - !(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) && - !is_sched_scan) - max_probe_len -= 32; - /* DS parameter set element is added on 2.4GHZ band if required */ if (iwl_mvm_rrm_scan_needed(mvm)) max_probe_len -= 3; @@ -404,9 +300,6 @@ int iwl_mvm_max_scan_ie_len(struct iwl_mvm *mvm, bool is_sched_scan) { int max_ie_len = iwl_mvm_max_scan_ie_fw_cmd_room(mvm, is_sched_scan); - if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN)) - return max_ie_len; - /* TODO: [BUG] This function should return the maximum allowed size of * scan IEs, however the LMAC scan api contains both 2GHZ and 5GHZ IEs * in the same command. So the correct implementation of this function @@ -420,129 +313,6 @@ int iwl_mvm_max_scan_ie_len(struct iwl_mvm *mvm, bool is_sched_scan) return max_ie_len; } -int iwl_mvm_scan_request(struct iwl_mvm *mvm, - struct ieee80211_vif *vif, - struct cfg80211_scan_request *req) -{ - struct iwl_host_cmd hcmd = { - .id = SCAN_REQUEST_CMD, - .len = { 0, }, - .data = { mvm->scan_cmd, }, - .dataflags = { IWL_HCMD_DFL_NOCOPY, }, - }; - struct iwl_scan_cmd *cmd = mvm->scan_cmd; - int ret; - u32 status; - int ssid_len = 0; - u8 *ssid = NULL; - bool basic_ssid = !(mvm->fw->ucode_capa.flags & - IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID); - struct iwl_mvm_scan_params params = {}; - - lockdep_assert_held(&mvm->mutex); - - /* we should have failed registration if scan_cmd was NULL */ - if (WARN_ON(mvm->scan_cmd == NULL)) - return -ENOMEM; - - IWL_DEBUG_SCAN(mvm, "Handling mac80211 scan request\n"); - mvm->scan_status = IWL_MVM_SCAN_OS; - memset(cmd, 0, ksize(cmd)); - - cmd->channel_count = (u8)req->n_channels; - cmd->quiet_time = cpu_to_le16(IWL_ACTIVE_QUIET_TIME); - cmd->quiet_plcp_th = cpu_to_le16(IWL_PLCP_QUIET_THRESH); - cmd->rxchain_sel_flags = iwl_mvm_scan_rx_chain(mvm); - - iwl_mvm_scan_calc_params(mvm, vif, req->n_ssids, req->flags, ¶ms); - cmd->max_out_time = cpu_to_le32(params.max_out_time); - cmd->suspend_time = cpu_to_le32(params.suspend_time); - if (params.passive_fragmented) - cmd->scan_flags |= SCAN_FLAGS_FRAGMENTED_SCAN; - - cmd->rxon_flags = iwl_mvm_scan_rxon_flags(req->channels[0]->band); - cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP | - MAC_FILTER_IN_BEACON); - - if (vif->type == NL80211_IFTYPE_P2P_DEVICE) - cmd->type = cpu_to_le32(SCAN_TYPE_DISCOVERY_FORCED); - else - cmd->type = cpu_to_le32(SCAN_TYPE_FORCED); - - cmd->repeats = cpu_to_le32(1); - - /* - * If the user asked for passive scan, don't change to active scan if - * you see any activity on the channel - remain passive. - */ - if (req->n_ssids > 0) { - cmd->passive2active = cpu_to_le16(1); - cmd->scan_flags |= SCAN_FLAGS_PASSIVE2ACTIVE; - if (basic_ssid) { - ssid = req->ssids[0].ssid; - ssid_len = req->ssids[0].ssid_len; - } - } else { - cmd->passive2active = 0; - cmd->scan_flags &= ~SCAN_FLAGS_PASSIVE2ACTIVE; - } - - iwl_mvm_scan_fill_ssids(cmd->direct_scan, req->ssids, req->n_ssids, - basic_ssid ? 1 : 0); - - cmd->tx_cmd.tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL | - 3 << TX_CMD_FLG_BT_PRIO_POS); - - cmd->tx_cmd.sta_id = mvm->aux_sta.sta_id; - cmd->tx_cmd.life_time = cpu_to_le32(TX_CMD_LIFE_TIME_INFINITE); - cmd->tx_cmd.rate_n_flags = - iwl_mvm_scan_rate_n_flags(mvm, req->channels[0]->band, - req->no_cck); - - cmd->tx_cmd.len = - cpu_to_le16(iwl_mvm_fill_probe_req( - (struct ieee80211_mgmt *)cmd->data, - vif->addr, - req->n_ssids, ssid, ssid_len, - req->ie, req->ie_len, NULL, 0, - mvm->fw->ucode_capa.max_probe_length)); - - iwl_mvm_scan_fill_channels(cmd, req, basic_ssid, ¶ms); - - cmd->len = cpu_to_le16(sizeof(struct iwl_scan_cmd) + - le16_to_cpu(cmd->tx_cmd.len) + - (cmd->channel_count * sizeof(struct iwl_scan_channel))); - hcmd.len[0] = le16_to_cpu(cmd->len); - - status = SCAN_RESPONSE_OK; - ret = iwl_mvm_send_cmd_status(mvm, &hcmd, &status); - if (!ret && status == SCAN_RESPONSE_OK) { - IWL_DEBUG_SCAN(mvm, "Scan request was sent successfully\n"); - } else { - /* - * If the scan failed, it usually means that the FW was unable - * to allocate the time events. Warn on it, but maybe we - * should try to send the command again with different params. - */ - IWL_ERR(mvm, "Scan failed! status 0x%x ret %d\n", - status, ret); - mvm->scan_status = IWL_MVM_SCAN_NONE; - ret = -EIO; - } - return ret; -} - -int iwl_mvm_rx_scan_response(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, - struct iwl_device_cmd *cmd) -{ - struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl_cmd_response *resp = (void *)pkt->data; - - IWL_DEBUG_SCAN(mvm, "Scan response received. status 0x%x\n", - le32_to_cpu(resp->status)); - return 0; -} - int iwl_mvm_rx_scan_offload_iter_complete_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) @@ -556,130 +326,25 @@ int iwl_mvm_rx_scan_offload_iter_complete_notif(struct iwl_mvm *mvm, return 0; } -int iwl_mvm_rx_scan_complete(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, - struct iwl_device_cmd *cmd) -{ - struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl_scan_complete_notif *notif = (void *)pkt->data; - - lockdep_assert_held(&mvm->mutex); - - IWL_DEBUG_SCAN(mvm, "Scan complete: status=0x%x scanned channels=%d\n", - notif->status, notif->scanned_channels); - - if (mvm->scan_status == IWL_MVM_SCAN_OS) - mvm->scan_status = IWL_MVM_SCAN_NONE; - ieee80211_scan_completed(mvm->hw, notif->status != SCAN_COMP_STATUS_OK); - - iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); - - return 0; -} - int iwl_mvm_rx_scan_offload_results(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { - struct iwl_rx_packet *pkt = rxb_addr(rxb); - - if (!(mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN) && - !(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN)) { - struct iwl_sched_scan_results *notif = (void *)pkt->data; - - if (!(notif->client_bitmap & SCAN_CLIENT_SCHED_SCAN)) - return 0; - } - IWL_DEBUG_SCAN(mvm, "Scheduled scan results\n"); ieee80211_sched_scan_results(mvm->hw); return 0; } -static bool iwl_mvm_scan_abort_notif(struct iwl_notif_wait_data *notif_wait, - struct iwl_rx_packet *pkt, void *data) -{ - struct iwl_mvm *mvm = - container_of(notif_wait, struct iwl_mvm, notif_wait); - struct iwl_scan_complete_notif *notif; - u32 *resp; - - switch (pkt->hdr.cmd) { - case SCAN_ABORT_CMD: - resp = (void *)pkt->data; - if (*resp == CAN_ABORT_STATUS) { - IWL_DEBUG_SCAN(mvm, - "Scan can be aborted, wait until completion\n"); - return false; - } - - /* - * If scan cannot be aborted, it means that we had a - * SCAN_COMPLETE_NOTIFICATION in the pipe and it called - * ieee80211_scan_completed already. - */ - IWL_DEBUG_SCAN(mvm, "Scan cannot be aborted, exit now: %d\n", - *resp); - return true; - - case SCAN_COMPLETE_NOTIFICATION: - notif = (void *)pkt->data; - IWL_DEBUG_SCAN(mvm, "Scan aborted: status 0x%x\n", - notif->status); - return true; - - default: - WARN_ON(1); - return false; - }; -} - -static int iwl_mvm_cancel_regular_scan(struct iwl_mvm *mvm) -{ - struct iwl_notification_wait wait_scan_abort; - static const u8 scan_abort_notif[] = { SCAN_ABORT_CMD, - SCAN_COMPLETE_NOTIFICATION }; - int ret; - - iwl_init_notification_wait(&mvm->notif_wait, &wait_scan_abort, - scan_abort_notif, - ARRAY_SIZE(scan_abort_notif), - iwl_mvm_scan_abort_notif, NULL); - - ret = iwl_mvm_send_cmd_pdu(mvm, SCAN_ABORT_CMD, 0, 0, NULL); - if (ret) { - IWL_ERR(mvm, "Couldn't send SCAN_ABORT_CMD: %d\n", ret); - /* mac80211's state will be cleaned in the nic_restart flow */ - goto out_remove_notif; - } - - return iwl_wait_notification(&mvm->notif_wait, &wait_scan_abort, HZ); - -out_remove_notif: - iwl_remove_notification(&mvm->notif_wait, &wait_scan_abort); - return ret; -} - int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); - u8 status, ebs_status; - - if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) { - struct iwl_periodic_scan_complete *scan_notif; + struct iwl_periodic_scan_complete *scan_notif; - scan_notif = (void *)pkt->data; - status = scan_notif->status; - ebs_status = scan_notif->ebs_status; - } else { - struct iwl_scan_offload_complete *scan_notif; + scan_notif = (void *)pkt->data; - scan_notif = (void *)pkt->data; - status = scan_notif->status; - ebs_status = scan_notif->ebs_status; - } /* scan status must be locked for proper checking */ lockdep_assert_held(&mvm->mutex); @@ -687,9 +352,9 @@ int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm, "%s completed, status %s, EBS status %s\n", mvm->scan_status == IWL_MVM_SCAN_SCHED ? "Scheduled scan" : "Scan", - status == IWL_SCAN_OFFLOAD_COMPLETED ? + scan_notif->status == IWL_SCAN_OFFLOAD_COMPLETED ? "completed" : "aborted", - ebs_status == IWL_SCAN_EBS_SUCCESS ? + scan_notif->ebs_status == IWL_SCAN_EBS_SUCCESS ? "success" : "failed"); @@ -700,64 +365,16 @@ int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm, } else if (mvm->scan_status == IWL_MVM_SCAN_OS) { mvm->scan_status = IWL_MVM_SCAN_NONE; ieee80211_scan_completed(mvm->hw, - status == IWL_SCAN_OFFLOAD_ABORTED); + scan_notif->status == IWL_SCAN_OFFLOAD_ABORTED); iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); } - if (ebs_status) + if (scan_notif->ebs_status) mvm->last_ebs_successful = false; return 0; } -static void iwl_scan_offload_build_tx_cmd(struct iwl_mvm *mvm, - struct ieee80211_vif *vif, - struct ieee80211_scan_ies *ies, - enum ieee80211_band band, - struct iwl_tx_cmd *cmd, - u8 *data) -{ - u16 cmd_len; - - cmd->tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL); - cmd->life_time = cpu_to_le32(TX_CMD_LIFE_TIME_INFINITE); - cmd->sta_id = mvm->aux_sta.sta_id; - - cmd->rate_n_flags = iwl_mvm_scan_rate_n_flags(mvm, band, false); - - cmd_len = iwl_mvm_fill_probe_req((struct ieee80211_mgmt *)data, - vif->addr, - 1, NULL, 0, - ies->ies[band], ies->len[band], - ies->common_ies, ies->common_ie_len, - SCAN_OFFLOAD_PROBE_REQ_SIZE); - cmd->len = cpu_to_le16(cmd_len); -} - -static void iwl_build_scan_cmd(struct iwl_mvm *mvm, - struct ieee80211_vif *vif, - struct cfg80211_sched_scan_request *req, - struct iwl_scan_offload_cmd *scan, - struct iwl_mvm_scan_params *params) -{ - scan->channel_count = req->n_channels; - scan->quiet_time = cpu_to_le16(IWL_ACTIVE_QUIET_TIME); - scan->quiet_plcp_th = cpu_to_le16(IWL_PLCP_QUIET_THRESH); - scan->good_CRC_th = IWL_GOOD_CRC_TH_DEFAULT; - scan->rx_chain = iwl_mvm_scan_rx_chain(mvm); - - scan->max_out_time = cpu_to_le32(params->max_out_time); - scan->suspend_time = cpu_to_le32(params->suspend_time); - - scan->filter_flags |= cpu_to_le32(MAC_FILTER_ACCEPT_GRP | - MAC_FILTER_IN_BEACON); - scan->scan_type = cpu_to_le32(SCAN_TYPE_BACKGROUND); - scan->rep_count = cpu_to_le32(1); - - if (params->passive_fragmented) - scan->scan_flags |= SCAN_FLAGS_FRAGMENTED_SCAN; -} - static int iwl_ssid_exist(u8 *ssid, u8 ssid_len, struct iwl_ssid_ie *ssid_list) { int i; @@ -815,127 +432,6 @@ static void iwl_scan_offload_build_ssid(struct cfg80211_sched_scan_request *req, } } -static void iwl_build_channel_cfg(struct iwl_mvm *mvm, - struct cfg80211_sched_scan_request *req, - u8 *channels_buffer, - enum ieee80211_band band, - int *head, - u32 ssid_bitmap, - struct iwl_mvm_scan_params *params) -{ - u32 n_channels = mvm->fw->ucode_capa.n_scan_channels; - __le32 *type = (__le32 *)channels_buffer; - __le16 *channel_number = (__le16 *)(type + n_channels); - __le16 *iter_count = channel_number + n_channels; - __le32 *iter_interval = (__le32 *)(iter_count + n_channels); - u8 *active_dwell = (u8 *)(iter_interval + n_channels); - u8 *passive_dwell = active_dwell + n_channels; - int i, index = 0; - - for (i = 0; i < req->n_channels; i++) { - struct ieee80211_channel *chan = req->channels[i]; - - if (chan->band != band) - continue; - - index = *head; - (*head)++; - - channel_number[index] = cpu_to_le16(chan->hw_value); - active_dwell[index] = params->dwell[band].active; - passive_dwell[index] = params->dwell[band].passive; - - iter_count[index] = cpu_to_le16(1); - iter_interval[index] = 0; - - if (!(chan->flags & IEEE80211_CHAN_NO_IR)) - type[index] |= - cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_ACTIVE); - - type[index] |= cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_FULL | - IWL_SCAN_OFFLOAD_CHANNEL_PARTIAL); - - if (chan->flags & IEEE80211_CHAN_NO_HT40) - type[index] |= - cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_NARROW); - - /* scan for all SSIDs from req->ssids */ - type[index] |= cpu_to_le32(ssid_bitmap); - } -} - -int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm, - struct ieee80211_vif *vif, - struct cfg80211_sched_scan_request *req, - struct ieee80211_scan_ies *ies) -{ - int band_2ghz = mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels; - int band_5ghz = mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels; - int head = 0; - u32 ssid_bitmap; - int cmd_len; - int ret; - u8 *probes; - bool basic_ssid = !(mvm->fw->ucode_capa.flags & - IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID); - - struct iwl_scan_offload_cfg *scan_cfg; - struct iwl_host_cmd cmd = { - .id = SCAN_OFFLOAD_CONFIG_CMD, - }; - struct iwl_mvm_scan_params params = {}; - - lockdep_assert_held(&mvm->mutex); - - cmd_len = sizeof(struct iwl_scan_offload_cfg) + - mvm->fw->ucode_capa.n_scan_channels * IWL_SCAN_CHAN_SIZE + - 2 * SCAN_OFFLOAD_PROBE_REQ_SIZE; - - scan_cfg = kzalloc(cmd_len, GFP_KERNEL); - if (!scan_cfg) - return -ENOMEM; - - probes = scan_cfg->data + - mvm->fw->ucode_capa.n_scan_channels * IWL_SCAN_CHAN_SIZE; - - iwl_mvm_scan_calc_params(mvm, vif, req->n_ssids, 0, ¶ms); - iwl_build_scan_cmd(mvm, vif, req, &scan_cfg->scan_cmd, ¶ms); - scan_cfg->scan_cmd.len = cpu_to_le16(cmd_len); - - iwl_scan_offload_build_ssid(req, scan_cfg->scan_cmd.direct_scan, - &ssid_bitmap, basic_ssid); - /* build tx frames for supported bands */ - if (band_2ghz) { - iwl_scan_offload_build_tx_cmd(mvm, vif, ies, - IEEE80211_BAND_2GHZ, - &scan_cfg->scan_cmd.tx_cmd[0], - probes); - iwl_build_channel_cfg(mvm, req, scan_cfg->data, - IEEE80211_BAND_2GHZ, &head, - ssid_bitmap, ¶ms); - } - if (band_5ghz) { - iwl_scan_offload_build_tx_cmd(mvm, vif, ies, - IEEE80211_BAND_5GHZ, - &scan_cfg->scan_cmd.tx_cmd[1], - probes + - SCAN_OFFLOAD_PROBE_REQ_SIZE); - iwl_build_channel_cfg(mvm, req, scan_cfg->data, - IEEE80211_BAND_5GHZ, &head, - ssid_bitmap, ¶ms); - } - - cmd.data[0] = scan_cfg; - cmd.len[0] = cmd_len; - cmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY; - - IWL_DEBUG_SCAN(mvm, "Sending scheduled scan config\n"); - - ret = iwl_mvm_send_cmd(mvm, &cmd); - kfree(scan_cfg); - return ret; -} - int iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm, struct cfg80211_sched_scan_request *req) { @@ -1018,33 +514,6 @@ static bool iwl_mvm_scan_pass_all(struct iwl_mvm *mvm, return true; } -int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm, - struct cfg80211_sched_scan_request *req) -{ - struct iwl_scan_offload_req scan_req = { - .watchdog = IWL_SCHED_SCAN_WATCHDOG, - - .schedule_line[0].iterations = IWL_FAST_SCHED_SCAN_ITERATIONS, - .schedule_line[0].delay = cpu_to_le16(req->interval / 1000), - .schedule_line[0].full_scan_mul = 1, - - .schedule_line[1].iterations = 0xff, - .schedule_line[1].delay = cpu_to_le16(req->interval / 1000), - .schedule_line[1].full_scan_mul = IWL_FULL_SCAN_MULTIPLIER, - }; - - if (iwl_mvm_scan_pass_all(mvm, req)) - scan_req.flags |= cpu_to_le16(IWL_SCAN_OFFLOAD_FLAG_PASS_ALL); - - if (mvm->last_ebs_successful && - mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_EBS_SUPPORT) - scan_req.flags |= - cpu_to_le16(IWL_SCAN_OFFLOAD_FLAG_EBS_ACCURATE_MODE); - - return iwl_mvm_send_cmd_pdu(mvm, SCAN_OFFLOAD_REQUEST_CMD, 0, - sizeof(scan_req), &scan_req); -} - int iwl_mvm_scan_offload_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct cfg80211_sched_scan_request *req, @@ -1057,21 +526,12 @@ int iwl_mvm_scan_offload_start(struct iwl_mvm *mvm, if (ret) return ret; ret = iwl_mvm_sched_scan_umac(mvm, vif, req, ies); - } else if ((mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN)) { - mvm->scan_status = IWL_MVM_SCAN_SCHED; - ret = iwl_mvm_config_sched_scan_profiles(mvm, req); - if (ret) - return ret; - ret = iwl_mvm_unified_sched_scan_lmac(mvm, vif, req, ies); } else { mvm->scan_status = IWL_MVM_SCAN_SCHED; - ret = iwl_mvm_config_sched_scan(mvm, vif, req, ies); - if (ret) - return ret; ret = iwl_mvm_config_sched_scan_profiles(mvm, req); if (ret) return ret; - ret = iwl_mvm_sched_scan_start(mvm, req); + ret = iwl_mvm_unified_sched_scan_lmac(mvm, vif, req, ies); } return ret; @@ -1088,9 +548,7 @@ static int iwl_mvm_send_scan_offload_abort(struct iwl_mvm *mvm) /* Exit instantly with error when device is not ready * to receive scan abort command or it does not perform * scheduled scan currently */ - if (mvm->scan_status != IWL_MVM_SCAN_SCHED && - (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) || - mvm->scan_status != IWL_MVM_SCAN_OS)) + if (mvm->scan_status == IWL_MVM_SCAN_NONE) return -EIO; ret = iwl_mvm_send_cmd_status(mvm, &cmd, &status); @@ -1131,13 +589,6 @@ int iwl_mvm_scan_offload_stop(struct iwl_mvm *mvm, bool notify) if (iwl_mvm_is_radio_killed(mvm)) goto out; - if (mvm->scan_status != IWL_MVM_SCAN_SCHED && - (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) || - mvm->scan_status != IWL_MVM_SCAN_OS)) { - IWL_DEBUG_SCAN(mvm, "No scan to stop\n"); - return 0; - } - iwl_init_notification_wait(&mvm->notif_wait, &wait_scan_done, scan_done_notif, ARRAY_SIZE(scan_done_notif), @@ -1580,9 +1031,7 @@ int iwl_mvm_cancel_scan(struct iwl_mvm *mvm) return 0; } - if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) - return iwl_mvm_scan_offload_stop(mvm, true); - return iwl_mvm_cancel_regular_scan(mvm); + return iwl_mvm_scan_offload_stop(mvm, true); } /* UMAC scan API */ @@ -2159,14 +1608,8 @@ int iwl_mvm_scan_size(struct iwl_mvm *mvm) mvm->fw->ucode_capa.n_scan_channels + sizeof(struct iwl_scan_req_umac_tail); - if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) - return sizeof(struct iwl_scan_req_unified_lmac) + - sizeof(struct iwl_scan_channel_cfg_lmac) * - mvm->fw->ucode_capa.n_scan_channels + - sizeof(struct iwl_scan_probe_req); - - return sizeof(struct iwl_scan_cmd) + - mvm->fw->ucode_capa.max_probe_length + - mvm->fw->ucode_capa.n_scan_channels * - sizeof(struct iwl_scan_channel); + return sizeof(struct iwl_scan_req_unified_lmac) + + sizeof(struct iwl_scan_channel_cfg_lmac) * + mvm->fw->ucode_capa.n_scan_channels + + sizeof(struct iwl_scan_probe_req); } diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c index 2b75a0d6d41e..8bdfb8bc7ff3 100644 --- a/drivers/net/wireless/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/iwlwifi/mvm/utils.c @@ -746,25 +746,6 @@ bool iwl_mvm_low_latency(struct iwl_mvm *mvm) return result; } -static void iwl_mvm_idle_iter(void *_data, u8 *mac, struct ieee80211_vif *vif) -{ - bool *idle = _data; - - if (!vif->bss_conf.idle) - *idle = false; -} - -bool iwl_mvm_is_idle(struct iwl_mvm *mvm) -{ - bool idle = true; - - ieee80211_iterate_active_interfaces_atomic( - mvm->hw, IEEE80211_IFACE_ITER_NORMAL, - iwl_mvm_idle_iter, &idle); - - return idle; -} - struct iwl_bss_iter_data { struct ieee80211_vif *vif; bool error; -- cgit v1.2.3 From 33cef9256342f200a708211958cec9c44406631d Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 21 Jan 2015 21:41:29 +0100 Subject: iwlwifi: mvm: support beacon statistics for BSS client Report the average beacon signal and the number of received beacons as measured by the firmware. Since the firmware just counts, and doesn't reset the counter at all, clear it in the firmware whenever we associate. However, accumulate it over firmware restart. Since clearing the statistics in the firmware will also clear the ones for the radio statistics, add those to the accumulator when cleared. Signed-off-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 53 ++++++++++++++++++++++++++++- drivers/net/wireless/iwlwifi/mvm/mvm.h | 10 +++++- drivers/net/wireless/iwlwifi/mvm/rx.c | 14 ++++++++ drivers/net/wireless/iwlwifi/mvm/utils.c | 9 +++-- 4 files changed, 82 insertions(+), 4 deletions(-) (limited to 'drivers/net/wireless/iwlwifi/mvm/utils.c') diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 0f986d7840b5..ce5a5ff06d0f 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -1322,6 +1322,11 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, mutex_lock(&mvm->mutex); + /* make sure that beacon statistics don't go backwards with FW reset */ + if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) + mvmvif->beacon_stats.accu_num_beacons += + mvmvif->beacon_stats.num_beacons; + /* Allocate resources for the MAC context, and add it to the fw */ ret = iwl_mvm_mac_ctxt_init(mvm, vif); if (ret) @@ -1815,6 +1820,11 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm, if (changes & BSS_CHANGED_ASSOC) { if (bss_conf->assoc) { + /* clear statistics to get clean beacon counter */ + iwl_mvm_request_statistics(mvm, true); + memset(&mvmvif->beacon_stats, 0, + sizeof(mvmvif->beacon_stats)); + /* add quota for this interface */ ret = iwl_mvm_update_quotas(mvm, NULL); if (ret) { @@ -3597,7 +3607,7 @@ static int iwl_mvm_mac_get_survey(struct ieee80211_hw *hw, int idx, mutex_lock(&mvm->mutex); if (mvm->ucode_loaded) { - ret = iwl_mvm_request_statistics(mvm); + ret = iwl_mvm_request_statistics(mvm, false); if (ret) goto out; } @@ -3627,6 +3637,46 @@ static int iwl_mvm_mac_get_survey(struct ieee80211_hw *hw, int idx, return ret; } +static void iwl_mvm_mac_sta_statistics(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct station_info *sinfo) +{ + struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); + struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); + struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); + + if (!(mvm->fw->ucode_capa.capa[0] & + IWL_UCODE_TLV_CAPA_RADIO_BEACON_STATS)) + return; + + /* if beacon filtering isn't on mac80211 does it anyway */ + if (!(vif->driver_flags & IEEE80211_VIF_BEACON_FILTER)) + return; + + if (!vif->bss_conf.assoc) + return; + + mutex_lock(&mvm->mutex); + + if (mvmvif->ap_sta_id != mvmsta->sta_id) + goto unlock; + + if (iwl_mvm_request_statistics(mvm, false)) + goto unlock; + + sinfo->rx_beacon = mvmvif->beacon_stats.num_beacons + + mvmvif->beacon_stats.accu_num_beacons; + sinfo->filled |= BIT(NL80211_STA_INFO_BEACON_RX); + if (mvmvif->beacon_stats.avg_signal) { + /* firmware only reports a value after RXing a few beacons */ + sinfo->rx_beacon_signal_avg = mvmvif->beacon_stats.avg_signal; + sinfo->filled |= BIT(NL80211_STA_INFO_BEACON_SIGNAL_AVG); + } + unlock: + mutex_unlock(&mvm->mutex); +} + const struct ieee80211_ops iwl_mvm_hw_ops = { .tx = iwl_mvm_mac_tx, .ampdu_action = iwl_mvm_mac_ampdu_action, @@ -3694,4 +3744,5 @@ const struct ieee80211_ops iwl_mvm_hw_ops = { .set_default_unicast_key = iwl_mvm_set_default_unicast_key, #endif .get_survey = iwl_mvm_mac_get_survey, + .sta_statistics = iwl_mvm_mac_sta_statistics, }; diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 90a1ea3e6507..5e383dbf2594 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -337,6 +337,9 @@ struct iwl_mvm_vif_bf_data { * @beacon_skb: the skb used to hold the AP/GO beacon template * @smps_requests: the SMPS requests of differents parts of the driver, * combined on update to yield the overall request to mac80211. + * @beacon_stats: beacon statistics, containing the # of received beacons, + * # of received beacons accumulated over FW restart, and the current + * average signal of beacons retrieved from the firmware */ struct iwl_mvm_vif { u16 id; @@ -354,6 +357,11 @@ struct iwl_mvm_vif { bool ps_disabled; struct iwl_mvm_vif_bf_data bf_data; + struct { + u32 num_beacons, accu_num_beacons; + u8 avg_signal; + } beacon_stats; + u32 ap_beacon_time; enum iwl_tsf_id tsf_id; @@ -963,7 +971,7 @@ void iwl_mvm_handle_rx_statistics(struct iwl_mvm *mvm, int iwl_mvm_rx_statistics(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd); -int iwl_mvm_request_statistics(struct iwl_mvm *mvm); +int iwl_mvm_request_statistics(struct iwl_mvm *mvm, bool clear); void iwl_mvm_accu_radio_stats(struct iwl_mvm *mvm); /* NVM */ diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c index 2486931fd861..b86ff66ee0ce 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rx.c +++ b/drivers/net/wireless/iwlwifi/mvm/rx.c @@ -427,6 +427,7 @@ struct iwl_mvm_stat_data { struct iwl_mvm *mvm; __le32 mac_id; __s8 beacon_filter_average_energy; + struct mvm_statistics_general_v8 *general; }; static void iwl_mvm_stat_iterator(void *_data, u8 *mac, @@ -441,6 +442,17 @@ static void iwl_mvm_stat_iterator(void *_data, u8 *mac, u16 id = le32_to_cpu(data->mac_id); struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); + /* This doesn't need the MAC ID check since it's not taking the + * data copied into the "data" struct, but rather the data from + * the notification directly. + */ + if (data->general) { + mvmvif->beacon_stats.num_beacons = + le32_to_cpu(data->general->beacon_counter[mvmvif->id]); + mvmvif->beacon_stats.avg_signal = + -data->general->beacon_average_energy[mvmvif->id]; + } + if (mvmvif->id != id) return; @@ -525,6 +537,8 @@ void iwl_mvm_handle_rx_statistics(struct iwl_mvm *mvm, le64_to_cpu(stats->general.on_time_rf); mvm->radio_stats.on_time_scan = le64_to_cpu(stats->general.on_time_scan); + + data.general = &stats->general; } else { struct iwl_notif_statistics_v8 *stats = (void *)&pkt->data; diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c index 8bdfb8bc7ff3..a50122344aac 100644 --- a/drivers/net/wireless/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/iwlwifi/mvm/utils.c @@ -643,9 +643,11 @@ void iwl_mvm_update_smps(struct iwl_mvm *mvm, struct ieee80211_vif *vif, ieee80211_request_smps(vif, smps_mode); } -int iwl_mvm_request_statistics(struct iwl_mvm *mvm) +int iwl_mvm_request_statistics(struct iwl_mvm *mvm, bool clear) { - struct iwl_statistics_cmd scmd = {}; + struct iwl_statistics_cmd scmd = { + .flags = clear ? cpu_to_le32(IWL_STATISTICS_FLG_CLEAR) : 0, + }; struct iwl_host_cmd cmd = { .id = STATISTICS_CMD, .len[0] = sizeof(scmd), @@ -661,6 +663,9 @@ int iwl_mvm_request_statistics(struct iwl_mvm *mvm) iwl_mvm_handle_rx_statistics(mvm, cmd.resp_pkt); iwl_free_resp(&cmd); + if (clear) + iwl_mvm_accu_radio_stats(mvm); + return 0; } -- cgit v1.2.3 From 7e1223b50089ab5901215d2fd8c61b42c7cfe034 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 3 Feb 2015 20:11:48 +0200 Subject: iwlwifi: mvm: new Alive / error table API The new API slightly changes the layout of the version of the firmware - prepare for that. Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/dvm/main.c | 2 +- drivers/net/wireless/iwlwifi/iwl-devtrace.h | 18 ++-- drivers/net/wireless/iwlwifi/iwl-drv.c | 22 +++- drivers/net/wireless/iwlwifi/iwl-fw-file.h | 6 +- drivers/net/wireless/iwlwifi/mvm/fw-api.h | 26 ++++- drivers/net/wireless/iwlwifi/mvm/fw.c | 49 +++++++-- drivers/net/wireless/iwlwifi/mvm/utils.c | 154 ++++++++++++++++++++++++++-- 7 files changed, 245 insertions(+), 32 deletions(-) (limited to 'drivers/net/wireless/iwlwifi/mvm/utils.c') diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c index c4d6dd7402d9..234e30f498b2 100644 --- a/drivers/net/wireless/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/iwlwifi/dvm/main.c @@ -1549,7 +1549,7 @@ static void iwl_dump_nic_error_log(struct iwl_priv *priv) table.blink1, table.blink2, table.ilink1, table.ilink2, table.bcon_time, table.gp1, table.gp2, table.gp3, table.ucode_ver, - table.hw_ver, table.brd_ver); + table.hw_ver, 0, table.brd_ver); IWL_ERR(priv, "0x%08X | %-28s\n", table.error_id, desc_lookup(table.error_id)); IWL_ERR(priv, "0x%08X | uPc\n", table.pc); diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h index 78bd41bf34b0..53555a0fce56 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h @@ -431,11 +431,11 @@ TRACE_EVENT(iwlwifi_dev_ucode_error, TP_PROTO(const struct device *dev, u32 desc, u32 tsf_low, u32 data1, u32 data2, u32 line, u32 blink1, u32 blink2, u32 ilink1, u32 ilink2, u32 bcon_time, - u32 gp1, u32 gp2, u32 gp3, u32 ucode_ver, u32 hw_ver, + u32 gp1, u32 gp2, u32 gp3, u32 major, u32 minor, u32 hw_ver, u32 brd_ver), TP_ARGS(dev, desc, tsf_low, data1, data2, line, blink1, blink2, ilink1, ilink2, bcon_time, gp1, gp2, - gp3, ucode_ver, hw_ver, brd_ver), + gp3, major, minor, hw_ver, brd_ver), TP_STRUCT__entry( DEV_ENTRY __field(u32, desc) @@ -451,7 +451,8 @@ TRACE_EVENT(iwlwifi_dev_ucode_error, __field(u32, gp1) __field(u32, gp2) __field(u32, gp3) - __field(u32, ucode_ver) + __field(u32, major) + __field(u32, minor) __field(u32, hw_ver) __field(u32, brd_ver) ), @@ -470,21 +471,22 @@ TRACE_EVENT(iwlwifi_dev_ucode_error, __entry->gp1 = gp1; __entry->gp2 = gp2; __entry->gp3 = gp3; - __entry->ucode_ver = ucode_ver; + __entry->major = major; + __entry->minor = minor; __entry->hw_ver = hw_ver; __entry->brd_ver = brd_ver; ), TP_printk("[%s] #%02d %010u data 0x%08X 0x%08X line %u, " "blink 0x%05X 0x%05X ilink 0x%05X 0x%05X " - "bcon_tm %010u gp 0x%08X 0x%08X 0x%08X uCode 0x%08X " - "hw 0x%08X brd 0x%08X", + "bcon_tm %010u gp 0x%08X 0x%08X 0x%08X major 0x%08X " + "minor 0x%08X hw 0x%08X brd 0x%08X", __get_str(dev), __entry->desc, __entry->tsf_low, __entry->data1, __entry->data2, __entry->line, __entry->blink1, __entry->blink2, __entry->ilink1, __entry->ilink2, __entry->bcon_time, __entry->gp1, __entry->gp2, - __entry->gp3, __entry->ucode_ver, __entry->hw_ver, - __entry->brd_ver) + __entry->gp3, __entry->major, __entry->minor, + __entry->hw_ver, __entry->brd_ver) ); TRACE_EVENT(iwlwifi_dev_ucode_event, diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 996e7f16adf9..b608114b6b9e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c @@ -842,6 +842,23 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, capa->n_scan_channels = le32_to_cpup((__le32 *)tlv_data); break; + case IWL_UCODE_TLV_FW_VERSION: { + __le32 *ptr = (void *)tlv_data; + u32 major, minor; + u8 local_comp; + + if (tlv_len != sizeof(u32) * 3) + goto invalid_tlv_len; + + major = le32_to_cpup(ptr++); + minor = le32_to_cpup(ptr++); + local_comp = le32_to_cpup(ptr); + + snprintf(drv->fw.fw_version, + sizeof(drv->fw.fw_version), "%u.%u.%u", + major, minor, local_comp); + break; + } case IWL_UCODE_TLV_FW_DBG_DEST: { struct iwl_fw_dbg_dest_tlv *dest = (void *)tlv_data; @@ -1107,7 +1124,10 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) if (err) goto try_again; - api_ver = IWL_UCODE_API(drv->fw.ucode_ver); + if (drv->fw.ucode_capa.api[0] & IWL_UCODE_TLV_API_NEW_VERSION) + api_ver = drv->fw.ucode_ver; + else + api_ver = IWL_UCODE_API(drv->fw.ucode_ver); /* * api_ver should match the api version forming part of the diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h index be4393e2c19c..3ec32e8a3cc4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h @@ -133,6 +133,7 @@ enum iwl_ucode_tlv_type { IWL_UCODE_TLV_N_SCAN_CHANNELS = 31, IWL_UCODE_TLV_SEC_RT_USNIFFER = 34, IWL_UCODE_TLV_SDIO_ADMA_ADDR = 35, + IWL_UCODE_TLV_FW_VERSION = 36, IWL_UCODE_TLV_FW_DBG_DEST = 38, IWL_UCODE_TLV_FW_DBG_CONF = 39, }; @@ -156,7 +157,8 @@ struct iwl_tlv_ucode_header { __le32 zero; __le32 magic; u8 human_readable[FW_VER_HUMAN_READABLE_SZ]; - __le32 ver; /* major/minor/API/serial */ + /* major/minor/API/serial or major in new format */ + __le32 ver; __le32 build; __le64 ignore; /* @@ -250,6 +252,7 @@ enum iwl_ucode_tlv_flag { * @IWL_UCODE_TLV_API_ASYNC_DTM: Async temperature notifications are supported. * @IWL_UCODE_TLV_API_LQ_SS_PARAMS: Configure STBC/BFER via LQ CMD ss_params * @IWL_UCODE_TLV_API_STATS_V10: uCode supports/uses statistics API version 10 + * @IWL_UCODE_TLV_API_NEW_VERSION: new versioning format */ enum iwl_ucode_tlv_api { IWL_UCODE_TLV_API_BT_COEX_SPLIT = BIT(3), @@ -263,6 +266,7 @@ enum iwl_ucode_tlv_api { IWL_UCODE_TLV_API_ASYNC_DTM = BIT(17), IWL_UCODE_TLV_API_LQ_SS_PARAMS = BIT(18), IWL_UCODE_TLV_API_STATS_V10 = BIT(19), + IWL_UCODE_TLV_API_NEW_VERSION = BIT(20), }; /** diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h index c43e5c2bb85c..d95b47213731 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h @@ -432,7 +432,7 @@ enum { #define IWL_ALIVE_FLG_RFKILL BIT(0) -struct mvm_alive_resp { +struct mvm_alive_resp_ver1 { __le16 status; __le16 flags; u8 ucode_minor; @@ -483,6 +483,30 @@ struct mvm_alive_resp_ver2 { __le32 dbg_print_buff_addr; } __packed; /* ALIVE_RES_API_S_VER_2 */ +struct mvm_alive_resp { + __le16 status; + __le16 flags; + __le32 ucode_minor; + __le32 ucode_major; + u8 ver_subtype; + u8 ver_type; + u8 mac; + u8 opt; + __le32 timestamp; + __le32 error_event_table_ptr; /* SRAM address for error log */ + __le32 log_event_table_ptr; /* SRAM address for LMAC event log */ + __le32 cpu_register_ptr; + __le32 dbgm_config_ptr; + __le32 alive_counter_ptr; + __le32 scd_base_ptr; /* SRAM address for SCD */ + __le32 st_fwrd_addr; /* pointer to Store and forward */ + __le32 st_fwrd_size; + __le32 umac_minor; /* UMAC version: minor */ + __le32 umac_major; /* UMAC version: major */ + __le32 error_info_addr; /* SRAM address for UMAC error log */ + __le32 dbg_print_buff_addr; +} __packed; /* ALIVE_RES_API_S_VER_3 */ + /* Error response/notification */ enum { FW_ERR_UNKNOWN_CMD = 0x0, diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c index ab81124c6029..7426bb0811be 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/iwlwifi/mvm/fw.c @@ -112,25 +112,27 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait, struct iwl_mvm *mvm = container_of(notif_wait, struct iwl_mvm, notif_wait); struct iwl_mvm_alive_data *alive_data = data; - struct mvm_alive_resp *palive; + struct mvm_alive_resp_ver1 *palive1; struct mvm_alive_resp_ver2 *palive2; + struct mvm_alive_resp *palive; - if (iwl_rx_packet_payload_len(pkt) == sizeof(*palive)) { - palive = (void *)pkt->data; + if (iwl_rx_packet_payload_len(pkt) == sizeof(*palive1)) { + palive1 = (void *)pkt->data; mvm->support_umac_log = false; mvm->error_event_table = - le32_to_cpu(palive->error_event_table_ptr); - mvm->log_event_table = le32_to_cpu(palive->log_event_table_ptr); - alive_data->scd_base_addr = le32_to_cpu(palive->scd_base_ptr); + le32_to_cpu(palive1->error_event_table_ptr); + mvm->log_event_table = + le32_to_cpu(palive1->log_event_table_ptr); + alive_data->scd_base_addr = le32_to_cpu(palive1->scd_base_ptr); - alive_data->valid = le16_to_cpu(palive->status) == + alive_data->valid = le16_to_cpu(palive1->status) == IWL_ALIVE_STATUS_OK; IWL_DEBUG_FW(mvm, "Alive VER1 ucode status 0x%04x revision 0x%01X 0x%01X flags 0x%01X\n", - le16_to_cpu(palive->status), palive->ver_type, - palive->ver_subtype, palive->flags); - } else { + le16_to_cpu(palive1->status), palive1->ver_type, + palive1->ver_subtype, palive1->flags); + } else if (iwl_rx_packet_payload_len(pkt) == sizeof(*palive2)) { palive2 = (void *)pkt->data; mvm->error_event_table = @@ -156,6 +158,33 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait, IWL_DEBUG_FW(mvm, "UMAC version: Major - 0x%x, Minor - 0x%x\n", palive2->umac_major, palive2->umac_minor); + } else if (iwl_rx_packet_payload_len(pkt) == sizeof(*palive)) { + palive = (void *)pkt->data; + + mvm->error_event_table = + le32_to_cpu(palive->error_event_table_ptr); + mvm->log_event_table = + le32_to_cpu(palive->log_event_table_ptr); + alive_data->scd_base_addr = le32_to_cpu(palive->scd_base_ptr); + mvm->umac_error_event_table = + le32_to_cpu(palive->error_info_addr); + mvm->sf_space.addr = le32_to_cpu(palive->st_fwrd_addr); + mvm->sf_space.size = le32_to_cpu(palive->st_fwrd_size); + + alive_data->valid = le16_to_cpu(palive->status) == + IWL_ALIVE_STATUS_OK; + if (mvm->umac_error_event_table) + mvm->support_umac_log = true; + + IWL_DEBUG_FW(mvm, + "Alive VER3 ucode status 0x%04x revision 0x%01X 0x%01X flags 0x%01X\n", + le16_to_cpu(palive->status), palive->ver_type, + palive->ver_subtype, palive->flags); + + IWL_DEBUG_FW(mvm, + "UMAC version: Major - 0x%x, Minor - 0x%x\n", + le32_to_cpu(palive->umac_major), + le32_to_cpu(palive->umac_minor)); } return true; diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c index a50122344aac..2b9de63951e6 100644 --- a/drivers/net/wireless/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/iwlwifi/mvm/utils.c @@ -332,7 +332,7 @@ static const char *desc_lookup(u32 num) * read with u32-sized accesses, any members with a different size * need to be ordered correctly though! */ -struct iwl_error_event_table { +struct iwl_error_event_table_v1 { u32 valid; /* (nonzero) valid, (0) log is empty */ u32 error_id; /* type of error */ u32 pc; /* program counter */ @@ -377,7 +377,55 @@ struct iwl_error_event_table { u32 u_timestamp; /* indicate when the date and time of the * compilation */ u32 flow_handler; /* FH read/write pointers, RX credit */ -} __packed; +} __packed /* LOG_ERROR_TABLE_API_S_VER_1 */; + +struct iwl_error_event_table { + u32 valid; /* (nonzero) valid, (0) log is empty */ + u32 error_id; /* type of error */ + u32 pc; /* program counter */ + u32 blink1; /* branch link */ + u32 blink2; /* branch link */ + u32 ilink1; /* interrupt link */ + u32 ilink2; /* interrupt link */ + u32 data1; /* error-specific data */ + u32 data2; /* error-specific data */ + u32 data3; /* error-specific data */ + u32 bcon_time; /* beacon timer */ + u32 tsf_low; /* network timestamp function timer */ + u32 tsf_hi; /* network timestamp function timer */ + u32 gp1; /* GP1 timer register */ + u32 gp2; /* GP2 timer register */ + u32 gp3; /* GP3 timer register */ + u32 major; /* uCode version major */ + u32 minor; /* uCode version minor */ + u32 hw_ver; /* HW Silicon version */ + u32 brd_ver; /* HW board version */ + u32 log_pc; /* log program counter */ + u32 frame_ptr; /* frame pointer */ + u32 stack_ptr; /* stack pointer */ + u32 hcmd; /* last host command header */ + u32 isr0; /* isr status register LMPM_NIC_ISR0: + * rxtx_flag */ + u32 isr1; /* isr status register LMPM_NIC_ISR1: + * host_flag */ + u32 isr2; /* isr status register LMPM_NIC_ISR2: + * enc_flag */ + u32 isr3; /* isr status register LMPM_NIC_ISR3: + * time_flag */ + u32 isr4; /* isr status register LMPM_NIC_ISR4: + * wico interrupt */ + u32 isr_pref; /* isr status register LMPM_NIC_PREF_STAT */ + u32 wait_event; /* wait event() caller address */ + u32 l2p_control; /* L2pControlField */ + u32 l2p_duration; /* L2pDurationField */ + u32 l2p_mhvalid; /* L2pMhValidBits */ + u32 l2p_addr_match; /* L2pAddrMatchStat */ + u32 lmpm_pmg_sel; /* indicate which clocks are turned on + * (LMPM_PMG_SEL) */ + u32 u_timestamp; /* indicate when the date and time of the + * compilation */ + u32 flow_handler; /* FH read/write pointers, RX credit */ +} __packed /* LOG_ERROR_TABLE_API_S_VER_2 */; /* * UMAC error struct - relevant starting from family 8000 chip. @@ -396,11 +444,11 @@ struct iwl_umac_error_event_table { u32 data1; /* error-specific data */ u32 data2; /* error-specific data */ u32 data3; /* error-specific data */ - u32 umac_fw_ver; /* UMAC version */ - u32 umac_fw_api_ver; /* UMAC FW API ver */ + u32 umac_major; + u32 umac_minor; u32 frame_pointer; /* core register 27*/ u32 stack_pointer; /* core register 28 */ - u32 cmd_header; /* latest host cmd sent to UMAC */ + u32 cmd_header; /* latest host cmd sent to UMAC */ u32 nic_isr_pref; /* ISR status register */ } __packed; @@ -441,18 +489,18 @@ static void iwl_mvm_dump_umac_error_log(struct iwl_mvm *mvm) IWL_ERR(mvm, "0x%08X | umac data1\n", table.data1); IWL_ERR(mvm, "0x%08X | umac data2\n", table.data2); IWL_ERR(mvm, "0x%08X | umac data3\n", table.data3); - IWL_ERR(mvm, "0x%08X | umac version\n", table.umac_fw_ver); - IWL_ERR(mvm, "0x%08X | umac api version\n", table.umac_fw_api_ver); + IWL_ERR(mvm, "0x%08X | umac major\n", table.umac_major); + IWL_ERR(mvm, "0x%08X | umac minor\n", table.umac_minor); IWL_ERR(mvm, "0x%08X | frame pointer\n", table.frame_pointer); IWL_ERR(mvm, "0x%08X | stack pointer\n", table.stack_pointer); IWL_ERR(mvm, "0x%08X | last host cmd\n", table.cmd_header); IWL_ERR(mvm, "0x%08X | isr status reg\n", table.nic_isr_pref); } -void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm) +static void iwl_mvm_dump_nic_error_log_old(struct iwl_mvm *mvm) { struct iwl_trans *trans = mvm->trans; - struct iwl_error_event_table table; + struct iwl_error_event_table_v1 table; u32 base; base = mvm->error_event_table; @@ -489,7 +537,7 @@ void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm) table.data1, table.data2, table.data3, table.blink1, table.blink2, table.ilink1, table.ilink2, table.bcon_time, table.gp1, - table.gp2, table.gp3, table.ucode_ver, + table.gp2, table.gp3, table.ucode_ver, 0, table.hw_ver, table.brd_ver); IWL_ERR(mvm, "0x%08X | %-28s\n", table.error_id, desc_lookup(table.error_id)); @@ -530,6 +578,92 @@ void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm) iwl_mvm_dump_umac_error_log(mvm); } +void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm) +{ + struct iwl_trans *trans = mvm->trans; + struct iwl_error_event_table table; + u32 base; + + if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_NEW_VERSION)) { + iwl_mvm_dump_nic_error_log_old(mvm); + return; + } + + base = mvm->error_event_table; + if (mvm->cur_ucode == IWL_UCODE_INIT) { + if (!base) + base = mvm->fw->init_errlog_ptr; + } else { + if (!base) + base = mvm->fw->inst_errlog_ptr; + } + + if (base < 0x800000) { + IWL_ERR(mvm, + "Not valid error log pointer 0x%08X for %s uCode\n", + base, + (mvm->cur_ucode == IWL_UCODE_INIT) + ? "Init" : "RT"); + return; + } + + iwl_trans_read_mem_bytes(trans, base, &table, sizeof(table)); + + if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) { + IWL_ERR(trans, "Start IWL Error Log Dump:\n"); + IWL_ERR(trans, "Status: 0x%08lX, count: %d\n", + mvm->status, table.valid); + } + + /* Do not change this output - scripts rely on it */ + + IWL_ERR(mvm, "Loaded firmware version: %s\n", mvm->fw->fw_version); + + trace_iwlwifi_dev_ucode_error(trans->dev, table.error_id, table.tsf_low, + table.data1, table.data2, table.data3, + table.blink1, table.blink2, table.ilink1, + table.ilink2, table.bcon_time, table.gp1, + table.gp2, table.gp3, table.major, + table.minor, table.hw_ver, table.brd_ver); + IWL_ERR(mvm, "0x%08X | %-28s\n", table.error_id, + desc_lookup(table.error_id)); + IWL_ERR(mvm, "0x%08X | uPc\n", table.pc); + IWL_ERR(mvm, "0x%08X | branchlink1\n", table.blink1); + IWL_ERR(mvm, "0x%08X | branchlink2\n", table.blink2); + IWL_ERR(mvm, "0x%08X | interruptlink1\n", table.ilink1); + IWL_ERR(mvm, "0x%08X | interruptlink2\n", table.ilink2); + IWL_ERR(mvm, "0x%08X | data1\n", table.data1); + IWL_ERR(mvm, "0x%08X | data2\n", table.data2); + IWL_ERR(mvm, "0x%08X | data3\n", table.data3); + IWL_ERR(mvm, "0x%08X | beacon time\n", table.bcon_time); + IWL_ERR(mvm, "0x%08X | tsf low\n", table.tsf_low); + IWL_ERR(mvm, "0x%08X | tsf hi\n", table.tsf_hi); + IWL_ERR(mvm, "0x%08X | time gp1\n", table.gp1); + IWL_ERR(mvm, "0x%08X | time gp2\n", table.gp2); + IWL_ERR(mvm, "0x%08X | time gp3\n", table.gp3); + IWL_ERR(mvm, "0x%08X | uCode version major\n", table.major); + IWL_ERR(mvm, "0x%08X | uCode version minor\n", table.minor); + IWL_ERR(mvm, "0x%08X | hw version\n", table.hw_ver); + IWL_ERR(mvm, "0x%08X | board version\n", table.brd_ver); + IWL_ERR(mvm, "0x%08X | hcmd\n", table.hcmd); + IWL_ERR(mvm, "0x%08X | isr0\n", table.isr0); + IWL_ERR(mvm, "0x%08X | isr1\n", table.isr1); + IWL_ERR(mvm, "0x%08X | isr2\n", table.isr2); + IWL_ERR(mvm, "0x%08X | isr3\n", table.isr3); + IWL_ERR(mvm, "0x%08X | isr4\n", table.isr4); + IWL_ERR(mvm, "0x%08X | isr_pref\n", table.isr_pref); + IWL_ERR(mvm, "0x%08X | wait_event\n", table.wait_event); + IWL_ERR(mvm, "0x%08X | l2p_control\n", table.l2p_control); + IWL_ERR(mvm, "0x%08X | l2p_duration\n", table.l2p_duration); + IWL_ERR(mvm, "0x%08X | l2p_mhvalid\n", table.l2p_mhvalid); + IWL_ERR(mvm, "0x%08X | l2p_addr_match\n", table.l2p_addr_match); + IWL_ERR(mvm, "0x%08X | lmpm_pmg_sel\n", table.lmpm_pmg_sel); + IWL_ERR(mvm, "0x%08X | timestamp\n", table.u_timestamp); + IWL_ERR(mvm, "0x%08X | flow_handler\n", table.flow_handler); + + if (mvm->support_umac_log) + iwl_mvm_dump_umac_error_log(mvm); +} void iwl_mvm_enable_txq(struct iwl_mvm *mvm, int queue, u16 ssn, const struct iwl_trans_txq_scd_cfg *cfg, unsigned int wdg_timeout) -- cgit v1.2.3 From 7754ae79e218bfd7782655fdebc8966c8a858358 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 26 Feb 2015 15:14:35 +0200 Subject: iwlwifi: mvm: always update the quota after association When we associate we always need to update the quotas. This fixes a bug for cases in which quotas weren't udapted after association. Reviewed-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 20 ++++++++++---------- drivers/net/wireless/iwlwifi/mvm/mvm.h | 2 +- drivers/net/wireless/iwlwifi/mvm/quota.c | 3 ++- drivers/net/wireless/iwlwifi/mvm/utils.c | 2 +- 4 files changed, 14 insertions(+), 13 deletions(-) (limited to 'drivers/net/wireless/iwlwifi/mvm/utils.c') diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 74847244c833..7eab892de29b 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -1298,7 +1298,7 @@ static void iwl_mvm_restart_complete(struct iwl_mvm *mvm) clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status); iwl_mvm_d0i3_enable_tx(mvm, NULL); - ret = iwl_mvm_update_quotas(mvm, NULL); + ret = iwl_mvm_update_quotas(mvm, false, NULL); if (ret) IWL_ERR(mvm, "Failed to update quotas after restart (%d)\n", ret); @@ -1977,7 +1977,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm, sizeof(mvmvif->beacon_stats)); /* add quota for this interface */ - ret = iwl_mvm_update_quotas(mvm, NULL); + ret = iwl_mvm_update_quotas(mvm, true, NULL); if (ret) { IWL_ERR(mvm, "failed to update quotas\n"); return; @@ -2029,7 +2029,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm, mvm->d0i3_ap_sta_id = IWL_MVM_STATION_COUNT; mvmvif->ap_sta_id = IWL_MVM_STATION_COUNT; /* remove quota for this interface */ - ret = iwl_mvm_update_quotas(mvm, NULL); + ret = iwl_mvm_update_quotas(mvm, false, NULL); if (ret) IWL_ERR(mvm, "failed to update quotas\n"); @@ -2148,7 +2148,7 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw, /* power updated needs to be done before quotas */ iwl_mvm_power_update_mac(mvm); - ret = iwl_mvm_update_quotas(mvm, NULL); + ret = iwl_mvm_update_quotas(mvm, false, NULL); if (ret) goto out_quota_failed; @@ -2214,7 +2214,7 @@ static void iwl_mvm_stop_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_update_quotas(mvm, NULL); + iwl_mvm_update_quotas(mvm, false, NULL); iwl_mvm_send_rm_bcast_sta(mvm, vif); iwl_mvm_binding_remove_vif(mvm, vif); @@ -3247,14 +3247,14 @@ static int __iwl_mvm_assign_vif_chanctx(struct iwl_mvm *mvm, */ if (vif->type == NL80211_IFTYPE_MONITOR) { mvmvif->monitor_active = true; - ret = iwl_mvm_update_quotas(mvm, NULL); + ret = iwl_mvm_update_quotas(mvm, false, NULL); if (ret) goto out_remove_binding; } /* Handle binding during CSA */ if (vif->type == NL80211_IFTYPE_AP) { - iwl_mvm_update_quotas(mvm, NULL); + iwl_mvm_update_quotas(mvm, false, NULL); iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL); } @@ -3278,7 +3278,7 @@ static int __iwl_mvm_assign_vif_chanctx(struct iwl_mvm *mvm, iwl_mvm_unref(mvm, IWL_MVM_REF_PROTECT_CSA); - iwl_mvm_update_quotas(mvm, NULL); + iwl_mvm_update_quotas(mvm, false, NULL); } goto out; @@ -3351,7 +3351,7 @@ static void __iwl_mvm_unassign_vif_chanctx(struct iwl_mvm *mvm, break; } - iwl_mvm_update_quotas(mvm, disabled_vif); + iwl_mvm_update_quotas(mvm, false, disabled_vif); iwl_mvm_binding_remove_vif(mvm, vif); out: @@ -3543,7 +3543,7 @@ static int __iwl_mvm_mac_testmode_cmd(struct iwl_mvm *mvm, mvm->noa_duration = noa_duration; mvm->noa_vif = vif; - return iwl_mvm_update_quotas(mvm, NULL); + return iwl_mvm_update_quotas(mvm, false, NULL); case IWL_MVM_TM_CMD_SET_BEACON_FILTER: /* must be associated client vif - ignore authorized */ if (!vif || vif->type != NL80211_IFTYPE_STATION || diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 4d44cf07475a..52135a4fd8d3 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -1139,7 +1139,7 @@ int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif); int iwl_mvm_binding_remove_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif); /* Quota management */ -int iwl_mvm_update_quotas(struct iwl_mvm *mvm, +int iwl_mvm_update_quotas(struct iwl_mvm *mvm, bool force_upload, struct ieee80211_vif *disabled_vif); /* Scanning */ diff --git a/drivers/net/wireless/iwlwifi/mvm/quota.c b/drivers/net/wireless/iwlwifi/mvm/quota.c index dbb2594390e9..509a66d05245 100644 --- a/drivers/net/wireless/iwlwifi/mvm/quota.c +++ b/drivers/net/wireless/iwlwifi/mvm/quota.c @@ -172,6 +172,7 @@ static void iwl_mvm_adjust_quota_for_noa(struct iwl_mvm *mvm, } int iwl_mvm_update_quotas(struct iwl_mvm *mvm, + bool force_update, struct ieee80211_vif *disabled_vif) { struct iwl_time_quota_cmd cmd = {}; @@ -309,7 +310,7 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, "zero quota on binding %d\n", i); } - if (!send) { + if (!send && !force_update) { /* don't send a practically unchanged command, the firmware has * to re-initialize a lot of state and that can have an adverse * impact on it diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c index 2b9de63951e6..435faee0a28e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/iwlwifi/mvm/utils.c @@ -857,7 +857,7 @@ int iwl_mvm_update_low_latency(struct iwl_mvm *mvm, struct ieee80211_vif *vif, mvmvif->low_latency = value; - res = iwl_mvm_update_quotas(mvm, NULL); + res = iwl_mvm_update_quotas(mvm, false, NULL); if (res) return res; -- cgit v1.2.3 From 5d42e7b2a39d015180af44f8e56b0c2fc46874e1 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 19 Mar 2015 20:04:51 +0200 Subject: iwlwifi: mvm: allow to configure the timeout for the Tx queues Sometimes we will want to configure the timeouts for the Tx queues based on the vif type. Allow to do that using the trigger mechanism. Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h | 3 ++ drivers/net/wireless/iwlwifi/iwl-fw-file.h | 23 +++++++++++++ drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c | 5 ++- drivers/net/wireless/iwlwifi/mvm/mvm.h | 4 ++- drivers/net/wireless/iwlwifi/mvm/ops.c | 3 +- drivers/net/wireless/iwlwifi/mvm/sta.c | 10 +++--- drivers/net/wireless/iwlwifi/mvm/utils.c | 44 ++++++++++++++++++++++++ 7 files changed, 80 insertions(+), 12 deletions(-) (limited to 'drivers/net/wireless/iwlwifi/mvm/utils.c') diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h b/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h index 37b38a585dd1..46cbae8f821d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h @@ -250,6 +250,8 @@ iwl_fw_error_next_data(struct iwl_fw_error_dump_data *data) * @FW_DBG_TRIGGER_STATS: trigger log collection upon statistics threshold. * @FW_DBG_TRIGGER_RSSI: trigger log collection when the rssi of the beacon * goes below a threshold. + * @FW_DBG_TRIGGER_TXQ_TIMERS: configures the timers for the Tx queue hang + * detection. */ enum iwl_fw_dbg_trigger { FW_DBG_TRIGGER_INVALID = 0, @@ -261,6 +263,7 @@ enum iwl_fw_dbg_trigger { FW_DB_TRIGGER_RESERVED, FW_DBG_TRIGGER_STATS, FW_DBG_TRIGGER_RSSI, + FW_DBG_TRIGGER_TXQ_TIMERS, /* must be last */ FW_DBG_TRIGGER_MAX, diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h index 60f3f86904fb..0cfc66d1aef2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h @@ -578,6 +578,29 @@ struct iwl_fw_dbg_trigger_low_rssi { __le32 rssi; } __packed; +/** + * struct iwl_fw_dbg_trigger_txq_timer - configures the Tx queue's timer + * @command_queue: timeout for the command queue in ms + * @bss: timeout for the queues of a BSS (except for TDLS queues) in ms + * @softap: timeout for the queues of a softAP in ms + * @p2p_go: timeout for the queues of a P2P GO in ms + * @p2p_client: timeout for the queues of a P2P client in ms + * @p2p_device: timeout for the queues of a P2P device in ms + * @ibss: timeout for the queues of an IBSS in ms + * @tdls: timeout for the queues of a TDLS station in ms + */ +struct iwl_fw_dbg_trigger_txq_timer { + __le32 command_queue; + __le32 bss; + __le32 softap; + __le32 p2p_go; + __le32 p2p_client; + __le32 p2p_device; + __le32 ibss; + __le32 tdls; + __le32 reserved[4]; +} __packed; + /** * struct iwl_fw_dbg_conf_tlv - a TLV that describes a debug configuration. * @id: conf id diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c index 581b3b8f29f9..09f0124db76e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c @@ -470,9 +470,8 @@ exit_fail: int iwl_mvm_mac_ctxt_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif) { - unsigned int wdg_timeout = iwlmvm_mod_params.tfd_q_hang_detect ? - mvm->cfg->base_params->wd_timeout : - IWL_WATCHDOG_DISABLED; + unsigned int wdg_timeout = + iwl_mvm_get_wd_timeout(mvm, vif, false, false); u32 ac; int ret; diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 91c74d4f0754..3513f27c888f 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -1480,7 +1480,9 @@ void iwl_mvm_free_fw_dump_desc(struct iwl_mvm *mvm); int iwl_mvm_fw_dbg_collect_trig(struct iwl_mvm *mvm, struct iwl_fw_dbg_trigger_tlv *trigger, const char *str, size_t len); - +unsigned int iwl_mvm_get_wd_timeout(struct iwl_mvm *mvm, + struct ieee80211_vif *vif, + bool tdls, bool cmd_q); static inline bool iwl_fw_dbg_trigger_vif_match(struct iwl_fw_dbg_trigger_tlv *trig, struct ieee80211_vif *vif) diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index 91361be3ecd8..388886ce419d 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c @@ -488,8 +488,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, /* Set a short watchdog for the command queue */ trans_cfg.cmd_q_wdg_timeout = - iwlmvm_mod_params.tfd_q_hang_detect ? IWL_DEF_WD_TIMEOUT : - IWL_WATCHDOG_DISABLED; + iwl_mvm_get_wd_timeout(mvm, NULL, false, true); snprintf(mvm->hw->wiphy->fw_version, sizeof(mvm->hw->wiphy->fw_version), diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c index 9bf512bdbbd6..231e7dd6c8f0 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/iwlwifi/mvm/sta.c @@ -209,9 +209,8 @@ static int iwl_mvm_tdls_sta_init(struct iwl_mvm *mvm, { unsigned long used_hw_queues; struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); - unsigned int wdg_timeout = iwlmvm_mod_params.tfd_q_hang_detect ? - mvm->cfg->base_params->wd_timeout : - IWL_WATCHDOG_DISABLED; + unsigned int wdg_timeout = + iwl_mvm_get_wd_timeout(mvm, NULL, true, false); u32 ac; lockdep_assert_held(&mvm->mutex); @@ -981,9 +980,8 @@ int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif, { struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid]; - unsigned int wdg_timeout = iwlmvm_mod_params.tfd_q_hang_detect ? - mvm->cfg->base_params->wd_timeout : - IWL_WATCHDOG_DISABLED; + unsigned int wdg_timeout = + iwl_mvm_get_wd_timeout(mvm, vif, sta->tdls, false); int queue, fifo, ret; u16 ssn; diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c index 435faee0a28e..593a810fe53e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/iwlwifi/mvm/utils.c @@ -921,3 +921,47 @@ struct ieee80211_vif *iwl_mvm_get_bss_vif(struct iwl_mvm *mvm) return bss_iter_data.vif; } + +unsigned int iwl_mvm_get_wd_timeout(struct iwl_mvm *mvm, + struct ieee80211_vif *vif, + bool tdls, bool cmd_q) +{ + 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; + + if (!iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_TXQ_TIMERS)) + return iwlmvm_mod_params.tfd_q_hang_detect ? + default_timeout : IWL_WATCHDOG_DISABLED; + + trigger = iwl_fw_dbg_get_trigger(mvm->fw, FW_DBG_TRIGGER_TXQ_TIMERS); + txq_timer = (void *)trigger->data; + + if (tdls) + return le32_to_cpu(txq_timer->tdls); + + if (cmd_q) + return le32_to_cpu(txq_timer->command_queue); + + if (WARN_ON(!vif)) + return default_timeout; + + switch (ieee80211_vif_type_p2p(vif)) { + case NL80211_IFTYPE_ADHOC: + return le32_to_cpu(txq_timer->ibss); + case NL80211_IFTYPE_STATION: + return le32_to_cpu(txq_timer->bss); + case NL80211_IFTYPE_AP: + return le32_to_cpu(txq_timer->softap); + case NL80211_IFTYPE_P2P_CLIENT: + return le32_to_cpu(txq_timer->p2p_client); + case NL80211_IFTYPE_P2P_GO: + return le32_to_cpu(txq_timer->p2p_go); + case NL80211_IFTYPE_P2P_DEVICE: + return le32_to_cpu(txq_timer->p2p_device); + default: + WARN_ON(1); + return mvm->cfg->base_params->wd_timeout; + } +} -- cgit v1.2.3 From 0d365ae5f2715a4a749e41ce5e75e34f03090db6 Mon Sep 17 00:00:00 2001 From: Sara Sharon Date: Tue, 31 Mar 2015 12:24:05 +0300 Subject: iwlwifi: fix spelling errors Fix spelling error across the driver. Modified only comments and prints. Signed-off-by: Sara Sharon Reviewed-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/iwl-config.h | 2 +- drivers/net/wireless/iwlwifi/iwl-drv.c | 2 +- drivers/net/wireless/iwlwifi/iwl-drv.h | 2 +- drivers/net/wireless/iwlwifi/iwl-eeprom-read.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-fh.h | 2 +- drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h | 2 +- drivers/net/wireless/iwlwifi/iwl-fw-file.h | 2 +- drivers/net/wireless/iwlwifi/iwl-op-mode.h | 4 ++-- drivers/net/wireless/iwlwifi/iwl-phy-db.c | 2 +- drivers/net/wireless/iwlwifi/iwl-trans.h | 12 ++++++------ drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h | 4 ++-- drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h | 2 +- drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h | 14 +++++++------- drivers/net/wireless/iwlwifi/mvm/mvm.h | 2 +- drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c | 2 +- drivers/net/wireless/iwlwifi/mvm/rs.c | 4 ++-- drivers/net/wireless/iwlwifi/mvm/sta.c | 4 ++-- drivers/net/wireless/iwlwifi/mvm/sta.h | 6 +++--- drivers/net/wireless/iwlwifi/mvm/time-event.c | 4 ++-- drivers/net/wireless/iwlwifi/mvm/time-event.h | 4 ++-- drivers/net/wireless/iwlwifi/mvm/utils.c | 4 ++-- 21 files changed, 42 insertions(+), 42 deletions(-) (limited to 'drivers/net/wireless/iwlwifi/mvm/utils.c') diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h index bbed8fc010ce..07e999a32a7f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/iwlwifi/iwl-config.h @@ -228,7 +228,7 @@ struct iwl_pwr_tx_backoff { /** * struct iwl_cfg - * @name: Offical name of the device + * @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 * filename is constructed as fw_name_pre.ucode. diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index b8e5690e5716..7783ac8761c4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c @@ -145,7 +145,7 @@ static struct iwlwifi_opmode_table { #define IWL_DEFAULT_SCAN_CHANNELS 40 /* - * struct fw_sec: Just for the image parsing proccess. + * struct fw_sec: Just for the image parsing process. * For the fw storage we are using struct fw_desc. */ struct fw_sec { diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.h b/drivers/net/wireless/iwlwifi/iwl-drv.h index 67a3a241b331..cda746b33db1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.h +++ b/drivers/net/wireless/iwlwifi/iwl-drv.h @@ -123,7 +123,7 @@ struct iwl_cfg; * starts the driver: fetches the firmware. This should be called by bus * specific system flows implementations. For example, the bus specific probe * function should do bus related operations only, and then call to this - * function. It returns the driver object or %NULL if an error occured. + * function. It returns the driver object or %NULL if an error occurred. */ struct iwl_drv *iwl_drv_start(struct iwl_trans *trans, const struct iwl_cfg *cfg); diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c index 25d0105741db..219ca8acca62 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c @@ -248,7 +248,7 @@ static int iwl_read_otp_word(struct iwl_trans *trans, u16 addr, otpgp = iwl_read32(trans, CSR_OTP_GP_REG); if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) { /* stop in this case */ - /* set the uncorrectable OTP ECC bit for acknowledgement */ + /* set the uncorrectable OTP ECC bit for acknowledgment */ iwl_set_bit(trans, CSR_OTP_GP_REG, CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); IWL_ERR(trans, "Uncorrectable OTP ECC error, abort OTP read\n"); @@ -256,7 +256,7 @@ static int iwl_read_otp_word(struct iwl_trans *trans, u16 addr, } if (otpgp & CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK) { /* continue in this case */ - /* set the correctable OTP ECC bit for acknowledgement */ + /* set the correctable OTP ECC bit for acknowledgment */ iwl_set_bit(trans, CSR_OTP_GP_REG, CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK); IWL_ERR(trans, "Correctable OTP ECC error, continue read\n"); diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h index 1f7f15eb86da..d45dc021cda2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fh.h +++ b/drivers/net/wireless/iwlwifi/iwl-fh.h @@ -445,7 +445,7 @@ static inline unsigned int FH_MEM_CBBC_QUEUE(unsigned int chnl) #define RX_LOW_WATERMARK 8 /** - * struct iwl_rb_status - reseve buffer status + * struct iwl_rb_status - reserve buffer status * host memory mapped FH registers * @closed_rb_num [0:11] - Indicates the index of the RB which was closed * @closed_fr_num [0:11] - Indicates the index of the RX Frame which was closed diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h b/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h index 8b926ece0d3a..37652857b8d0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h @@ -183,7 +183,7 @@ struct iwl_fw_error_dump_info { * struct iwl_fw_error_dump_fw_mon - FW monitor data * @fw_mon_wr_ptr: the position of the write pointer in the cyclic buffer * @fw_mon_base_ptr: base pointer of the data - * @fw_mon_cycle_cnt: number of wrap arounds + * @fw_mon_cycle_cnt: number of wraparounds * @reserved: for future use * @data: captured data */ diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h index 823938e3b7ef..cc789cb3c052 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h @@ -191,7 +191,7 @@ struct iwl_ucode_capa { * enum iwl_ucode_tlv_flag - ucode API flags * @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously * was a separate TLV but moved here to save space. - * @IWL_UCODE_TLV_FLAGS_NEWSCAN: new uCode scan behaviour on hidden SSID, + * @IWL_UCODE_TLV_FLAGS_NEWSCAN: new uCode scan behavior on hidden SSID, * treats good CRC threshold as a boolean * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w). * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P. diff --git a/drivers/net/wireless/iwlwifi/iwl-op-mode.h b/drivers/net/wireless/iwlwifi/iwl-op-mode.h index 17de6d46222a..ce1cdd7604e8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-op-mode.h +++ b/drivers/net/wireless/iwlwifi/iwl-op-mode.h @@ -94,7 +94,7 @@ struct iwl_cfg; * The operational mode has a very simple life cycle. * * 1) The driver layer (iwl-drv.c) chooses the op_mode based on the - * capabilities advertized by the fw file (in TLV format). + * capabilities advertised by the fw file (in TLV format). * 2) The driver layer starts the op_mode (ops->start) * 3) The op_mode registers mac80211 * 4) The op_mode is governed by mac80211 @@ -116,7 +116,7 @@ struct iwl_cfg; * May sleep * @rx: Rx notification to the op_mode. rxb is the Rx buffer itself. Cmd is the * HCMD this Rx responds to. Can't sleep. - * @napi_add: NAPI initialisation. The transport is fully responsible for NAPI, + * @napi_add: NAPI initialization. The transport is fully responsible for NAPI, * but the higher layers need to know about it (in particular mac80211 to * to able to call the right NAPI RX functions); this function is needed * to eventually call netif_napi_add() with higher layer involvement. diff --git a/drivers/net/wireless/iwlwifi/iwl-phy-db.c b/drivers/net/wireless/iwlwifi/iwl-phy-db.c index e893c6eb260c..a105455b6a24 100644 --- a/drivers/net/wireless/iwlwifi/iwl-phy-db.c +++ b/drivers/net/wireless/iwlwifi/iwl-phy-db.c @@ -125,7 +125,7 @@ struct iwl_phy_db_chg_txp { } __packed; /* - * phy db - Receieve phy db chunk after calibrations + * phy db - Receive phy db chunk after calibrations */ struct iwl_calib_res_notif_phy_db { __le16 type; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 11ac5c58527f..6dfed1259260 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -77,10 +77,10 @@ /** * DOC: Transport layer - what is it ? * - * The tranport layer is the layer that deals with the HW directly. It provides + * The transport layer is the layer that deals with the HW directly. It provides * an abstraction of the underlying HW to the upper layer. The transport layer * doesn't provide any policy, algorithm or anything of this kind, but only - * mechanisms to make the HW do something.It is not completely stateless but + * mechanisms to make the HW do something. It is not completely stateless but * close to it. * We will have an implementation for each different supported bus. */ @@ -111,10 +111,10 @@ /** * DOC: Host command section * - * A host command is a commaned issued by the upper layer to the fw. There are + * A host command is a command issued by the upper layer to the fw. There are * several versions of fw that have several APIs. The transport layer is * completely agnostic to these differences. - * The transport does provide helper functionnality (i.e. SYNC / ASYNC mode), + * The transport does provide helper functionality (i.e. SYNC / ASYNC mode), */ #define SEQ_TO_QUEUE(s) (((s) >> 8) & 0x1f) #define QUEUE_TO_SEQ(q) (((q) & 0x1f) << 8) @@ -195,7 +195,7 @@ static inline u32 iwl_rx_packet_payload_len(const struct iwl_rx_packet *pkt) * @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 + * 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. @@ -582,7 +582,7 @@ enum iwl_d0i3_mode { * @cfg - pointer to the configuration * @status: a bit-mask of transport status flags * @dev - pointer to struct device * that represents the device - * @hw_id: a u32 with the ID of the device / subdevice. + * @hw_id: a u32 with the ID of the device / sub-device. * Set during transport allocation. * @hw_id_str: a string with info about HW ID. Set during transport allocation. * @pm_support: set to true in start_hw if link pm is supported diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h index 6d3bea5c59d1..d7658d16e965 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h @@ -132,7 +132,7 @@ struct iwl_proto_offload_cmd_common { * @solicited_node_ipv6_addr: broken -- solicited node address exists * for each target address * @target_ipv6_addr: our target addresses - * @ndp_mac_addr: neighbor soliciation response MAC address + * @ndp_mac_addr: neighbor solicitation response MAC address */ struct iwl_proto_offload_cmd_v1 { struct iwl_proto_offload_cmd_common common; @@ -150,7 +150,7 @@ struct iwl_proto_offload_cmd_v1 { * @solicited_node_ipv6_addr: broken -- solicited node address exists * for each target address * @target_ipv6_addr: our target addresses - * @ndp_mac_addr: neighbor soliciation response MAC address + * @ndp_mac_addr: neighbor solicitation response MAC address */ struct iwl_proto_offload_cmd_v2 { struct iwl_proto_offload_cmd_common common; diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h index aabaedd3b3ee..f3f3ee0a766b 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h @@ -255,7 +255,7 @@ struct iwl_mac_data_p2p_dev { /** * enum iwl_mac_filter_flags - MAC context filter flags * @MAC_FILTER_IN_PROMISC: accept all data frames - * @MAC_FILTER_IN_CONTROL_AND_MGMT: pass all mangement and + * @MAC_FILTER_IN_CONTROL_AND_MGMT: pass all management and * control frames to the host * @MAC_FILTER_ACCEPT_GRP: accept multicast frames * @MAC_FILTER_DIS_DECRYPT: don't decrypt unicast frames diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h index a5fbbd637070..4f81dcf57a73 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h @@ -103,7 +103,7 @@ struct iwl_ssid_ie { * @SCAN_COMP_STATUS_ERR_COEX: medium was lost ot WiMax * @SCAN_COMP_STATUS_P2P_ACTION_OK: P2P public action frame TX was successful * (not an error!) - * @SCAN_COMP_STATUS_ITERATION_END: indicates end of one repeatition the driver + * @SCAN_COMP_STATUS_ITERATION_END: indicates end of one repetition the driver * asked for * @SCAN_COMP_STATUS_ERR_ALLOC_TE: scan could not allocate time events */ @@ -187,11 +187,11 @@ enum scan_framework_client { * struct iwl_scan_offload_cmd - SCAN_REQUEST_FIXED_PART_API_S_VER_6 * @scan_flags: see enum iwl_scan_flags * @channel_count: channels in channel list - * @quiet_time: dwell time, in milisiconds, on quiet channel + * @quiet_time: dwell time, in milliseconds, on quiet channel * @quiet_plcp_th: quiet channel num of packets threshold * @good_CRC_th: passive to active promotion threshold * @rx_chain: RXON rx chain. - * @max_out_time: max TUs to be out of assoceated channel + * @max_out_time: max TUs to be out of associated channel * @suspend_time: pause scan this TUs when returning to service channel * @flags: RXON flags * @filter_flags: RXONfilter @@ -232,7 +232,7 @@ enum iwl_scan_offload_channel_flags { * see enum iwl_scan_offload_channel_flags. * __le16 channel_number: channel number 1-13 etc. * __le16 iter_count: repetition count for the channel. - * __le32 iter_interval: interval between two innteration on one channel. + * __le32 iter_interval: interval between two iterations on one channel. * u8 active_dwell. * u8 passive_dwell. */ @@ -275,8 +275,8 @@ enum iwl_scan_offload_band_selection { /** * iwl_scan_offload_profile - SCAN_OFFLOAD_PROFILE_S * @ssid_index: index to ssid list in fixed part - * @unicast_cipher: encryption olgorithm to match - bitmap - * @aut_alg: authentication olgorithm to match - bitmap + * @unicast_cipher: encryption algorithm to match - bitmap + * @aut_alg: authentication algorithm to match - bitmap * @network_type: enum iwl_scan_offload_network_type * @band_selection: enum iwl_scan_offload_band_selection * @client_bitmap: clients waiting for match - enum scan_framework_client @@ -748,7 +748,7 @@ enum iwl_umac_scan_general_flags { * @flags: bitmap - 0-19: directed scan to i'th ssid. * @channel_num: channel number 1-13 etc. * @iter_count: repetition count for the channel. - * @iter_interval: interval between two scan interations on one channel. + * @iter_interval: interval between two scan iterations on one channel. */ struct iwl_scan_channel_cfg_umac { __le32 flags; diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 2b7e6cb1dbd9..629b8c7da478 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -349,7 +349,7 @@ struct iwl_mvm_vif_bf_data { * @bcast_sta: station used for broadcast packets. Used by the following * vifs: P2P_DEVICE, GO and AP. * @beacon_skb: the skb used to hold the AP/GO beacon template - * @smps_requests: the SMPS requests of differents parts of the driver, + * @smps_requests: the SMPS requests of different parts of the driver, * combined on update to yield the overall request to mac80211. * @beacon_stats: beacon statistics, containing the # of received beacons, * # of received beacons accumulated over FW restart, and the current diff --git a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c index 192b74bc8cf6..e68a475e3071 100644 --- a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c +++ b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c @@ -67,7 +67,7 @@ #include "fw-api.h" #include "mvm.h" -/* Maps the driver specific channel width definition to the the fw values */ +/* Maps the driver specific channel width definition to the fw values */ u8 iwl_mvm_get_channel_width(struct cfg80211_chan_def *chandef) { switch (chandef->width) { diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c index e00b454c6c17..c1c8c56727d2 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/iwlwifi/mvm/rs.c @@ -3221,7 +3221,7 @@ static void rs_fill_lq_cmd(struct iwl_mvm *mvm, lq_cmd->agg_frame_cnt_limit = mvmsta->max_agg_bufsize; /* - * In case of low latency, tell the firwmare to leave a frame in the + * In case of low latency, tell the firmware to leave a frame in the * Tx Fifo so that it can start a transaction in the same TxOP. This * basically allows the firmware to send bursts. */ @@ -3722,7 +3722,7 @@ void iwl_mvm_rate_control_unregister(void) /** * iwl_mvm_tx_protection - Gets LQ command, change it to enable/disable - * Tx protection, according to this rquest and previous requests, + * Tx protection, according to this request and previous requests, * and send the LQ command. * @mvmsta: The station * @enable: Enable Tx protection? diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c index 231e7dd6c8f0..1845b79487c8 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/iwlwifi/mvm/sta.c @@ -1714,8 +1714,8 @@ void iwl_mvm_sta_modify_disable_tx_ap(struct iwl_mvm *mvm, mvm_sta->disable_tx = disable; /* - * Tell mac80211 to start/stop queueing tx for this station, - * but don't stop queueing if there are still pending frames + * Tell mac80211 to start/stop queuing tx for this station, + * but don't stop queuing if there are still pending frames * for this station. */ if (disable || !atomic_read(&mvm->pending_frames[mvm_sta->sta_id])) diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.h b/drivers/net/wireless/iwlwifi/mvm/sta.h index d8f48975ad08..748f5dc3f9f4 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.h +++ b/drivers/net/wireless/iwlwifi/mvm/sta.h @@ -150,7 +150,7 @@ struct iwl_mvm_vif; * DOC: station table - AP Station in STA mode * * %iwl_mvm_vif includes the index of the AP station in the fw's STA table: - * %ap_sta_id. To get the point to the coresponsding %ieee80211_sta, + * %ap_sta_id. To get the point to the corresponding %ieee80211_sta, * &fw_id_to_mac_id can be used. Due to the way the fw works, we must not remove * the AP station from the fw before setting the MAC context as unassociated. * Hence, %fw_id_to_mac_id[%ap_sta_id] will be NULLed when the AP station is @@ -209,14 +209,14 @@ struct iwl_mvm_vif; * When a trigger frame is received, mac80211 tells the driver to send frames * from the AMPDU queues or sends frames to non-aggregation queues itself, * depending on which ACs are delivery-enabled and what TID has frames to - * transmit. Note that mac80211 has all the knowledege since all the non-agg + * transmit. Note that mac80211 has all the knowledge since all the non-agg * frames are buffered / filtered, and the driver tells mac80211 about agg * frames). The driver needs to tell the fw to let frames out even if the * station is asleep. This is done by %iwl_mvm_sta_modify_sleep_tx_count. * * When we receive a frame from that station with PM bit unset, the driver * needs to let the fw know that this station isn't asleep any more. This is - * done by %iwl_mvm_sta_modify_ps_wake in response to mac80211 signalling the + * done by %iwl_mvm_sta_modify_ps_wake in response to mac80211 signaling the * station's wakeup. * * For a GO, the Service Period might be cut short due to an absence period diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c index a32f612a8b59..bd519597eb2d 100644 --- a/drivers/net/wireless/iwlwifi/mvm/time-event.c +++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c @@ -119,7 +119,7 @@ void iwl_mvm_roc_done_wk(struct work_struct *wk) /* * Flush the offchannel queue -- this is called when the time - * event finishes or is cancelled, so that frames queued for it + * event finishes or is canceled, so that frames queued for it * won't get stuck on the queue and be transmitted in the next * time event. * We have to send the command asynchronously since this cannot @@ -778,7 +778,7 @@ void iwl_mvm_stop_roc(struct iwl_mvm *mvm) * Iterate over the list of aux roc time events and find the time * event that is associated with a BSS interface. * This assumes that a BSS interface can have only a single time - * event at any given time and this time event coresponds to a ROC + * event at any given time and this time event corresponds to a ROC * request */ list_for_each_entry(te_data, &mvm->aux_roc_te_list, list) { diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.h b/drivers/net/wireless/iwlwifi/mvm/time-event.h index 6f6b35db3ab8..de4fbc6d57f1 100644 --- a/drivers/net/wireless/iwlwifi/mvm/time-event.h +++ b/drivers/net/wireless/iwlwifi/mvm/time-event.h @@ -147,7 +147,7 @@ void iwl_mvm_protect_session(struct iwl_mvm *mvm, * @vif: the virtual interface for which the session is issued * * This functions cancels the session protection which is an act of good - * citizenship. If it is not needed any more it should be cancelled because + * citizenship. If it is not needed any more it should be canceled because * the other bindings wait for the medium during that time. * This funtions doesn't sleep. */ @@ -162,7 +162,7 @@ int iwl_mvm_rx_time_event_notif(struct iwl_mvm *mvm, struct iwl_device_cmd *cmd); /** - * iwl_mvm_start_p2p_roc - start remain on channel for p2p device functionlity + * iwl_mvm_start_p2p_roc - start remain on channel for p2p device functionality * @mvm: the mvm component * @vif: the virtual interface for which the roc is requested. It is assumed * that the vif type is NL80211_IFTYPE_P2P_DEVICE diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c index 593a810fe53e..54e3556842c4 100644 --- a/drivers/net/wireless/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/iwlwifi/mvm/utils.c @@ -122,7 +122,7 @@ int iwl_mvm_send_cmd_pdu(struct iwl_mvm *mvm, u8 id, } /* - * We assume that the caller set the status to the sucess value + * We assume that the caller set the status to the success value */ int iwl_mvm_send_cmd_status(struct iwl_mvm *mvm, struct iwl_host_cmd *cmd, u32 *status) @@ -737,7 +737,7 @@ int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, bool init) } /** - * iwl_mvm_update_smps - Get a requst to change the SMPS mode + * iwl_mvm_update_smps - Get a request to change the SMPS mode * @req_type: The part of the driver who call for a change. * @smps_requests: The request to change the SMPS mode. * -- cgit v1.2.3 From 31755207afc5d5a30e3eea9e4f2a518fc5b680c1 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Mon, 30 Mar 2015 10:55:57 +0300 Subject: iwlwifi: mvm: capture connection loss as part of MLME trigger The only other way to catch these would have been to monitor the Tx deauth event, but we can send a deauth when we roam. So it would have been tricky to make sure we capture the connection losses only. Define a separate trigger for the connection losses to make it easier to catch them. Reviewed-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/iwl-fw-file.h | 8 ++++++-- drivers/net/wireless/iwlwifi/mvm/mvm.h | 2 ++ drivers/net/wireless/iwlwifi/mvm/ops.c | 2 +- drivers/net/wireless/iwlwifi/mvm/time-event.c | 6 ++++-- drivers/net/wireless/iwlwifi/mvm/utils.c | 24 ++++++++++++++++++++++++ 5 files changed, 37 insertions(+), 5 deletions(-) (limited to 'drivers/net/wireless/iwlwifi/mvm/utils.c') diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h index ee149482061f..bfdf3faa6c47 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h @@ -586,12 +586,14 @@ struct iwl_fw_dbg_trigger_low_rssi { * @stop_tx_deauth: number of Tx deauth before to collect * @stop_assoc_denied: number of denied association to collect * @stop_assoc_timeout: number of association timeout to collect + * @stop_connection_loss: number of connection loss to collect * @start_auth_denied: number of denied authentication to start recording * @start_auth_timeout: number of authentication timeout to start recording * @start_rx_deauth: number of Rx deauth to start recording * @start_tx_deauth: number of Tx deauth to start recording * @start_assoc_denied: number of denied association to start recording * @start_assoc_timeout: number of association timeout to start recording + * @start_connection_loss: number of connection loss to start recording */ struct iwl_fw_dbg_trigger_mlme { u8 stop_auth_denied; @@ -601,7 +603,8 @@ struct iwl_fw_dbg_trigger_mlme { u8 stop_assoc_denied; u8 stop_assoc_timeout; - __le16 reserved2; + u8 stop_connection_loss; + u8 reserved; u8 start_auth_denied; u8 start_auth_timeout; @@ -610,7 +613,8 @@ struct iwl_fw_dbg_trigger_mlme { u8 start_assoc_denied; u8 start_assoc_timeout; - __le16 reserved4; + u8 start_connection_loss; + u8 reserved2; } __packed; /** diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index ef78ebc23a0f..d5522a161242 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -1484,6 +1484,8 @@ int iwl_mvm_fw_dbg_collect_trig(struct iwl_mvm *mvm, unsigned int iwl_mvm_get_wd_timeout(struct iwl_mvm *mvm, struct ieee80211_vif *vif, bool tdls, bool cmd_q); +void iwl_mvm_connection_loss(struct iwl_mvm *mvm, struct ieee80211_vif *vif, + const char *errmsg); static inline bool iwl_fw_dbg_trigger_vif_match(struct iwl_fw_dbg_trigger_tlv *trig, struct ieee80211_vif *vif) diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index e656511bdbec..a08b03d58d4b 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c @@ -1161,7 +1161,7 @@ static void iwl_mvm_d0i3_disconnect_iter(void *data, u8 *mac, if (vif->type == NL80211_IFTYPE_STATION && vif->bss_conf.assoc && mvm->d0i3_ap_sta_id == mvmvif->ap_sta_id) - ieee80211_connection_loss(vif); + iwl_mvm_connection_loss(mvm, vif, "D0i3"); } void iwl_mvm_d0i3_enable_tx(struct iwl_mvm *mvm, __le16 *qos_seq) diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c index 647822366fe5..fd7b0d36f9a6 100644 --- a/drivers/net/wireless/iwlwifi/mvm/time-event.c +++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c @@ -187,7 +187,8 @@ static bool iwl_mvm_te_check_disconnect(struct iwl_mvm *mvm, return false; if (errmsg) IWL_ERR(mvm, "%s\n", errmsg); - ieee80211_connection_loss(vif); + + iwl_mvm_connection_loss(mvm, vif, errmsg); return true; } @@ -210,7 +211,8 @@ iwl_mvm_te_handle_notify_csa(struct iwl_mvm *mvm, break; case NL80211_IFTYPE_STATION: if (!notif->status) { - ieee80211_connection_loss(te_data->vif); + iwl_mvm_connection_loss(mvm, vif, + "CSA TE failed to start"); break; } iwl_mvm_csa_client_absent(mvm, te_data->vif); diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c index 54e3556842c4..bc55a8b82db6 100644 --- a/drivers/net/wireless/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/iwlwifi/mvm/utils.c @@ -965,3 +965,27 @@ unsigned int iwl_mvm_get_wd_timeout(struct iwl_mvm *mvm, return mvm->cfg->base_params->wd_timeout; } } + +void iwl_mvm_connection_loss(struct iwl_mvm *mvm, struct ieee80211_vif *vif, + const char *errmsg) +{ + struct iwl_fw_dbg_trigger_tlv *trig; + struct iwl_fw_dbg_trigger_mlme *trig_mlme; + + if (!iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_MLME)) + goto out; + + trig = iwl_fw_dbg_get_trigger(mvm->fw, FW_DBG_TRIGGER_MLME); + trig_mlme = (void *)trig->data; + if (!iwl_fw_dbg_trigger_check_stop(mvm, vif, trig)) + goto out; + + if (trig_mlme->stop_connection_loss && + --trig_mlme->stop_connection_loss) + goto out; + + iwl_mvm_fw_dbg_collect_trig(mvm, trig, "%s", errmsg); + +out: + ieee80211_connection_loss(vif); +} -- cgit v1.2.3