From 81d62d5a9c4df3f4f7b0c5f5e1158f3fc4802fda Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 10 Mar 2015 14:44:00 +0100 Subject: iwlwifi: mvm: continue (with error) CSA on GO time event failure If, on a GO, the CSA time event fails to be scheduled, continue the flow towards mac80211's state machine so it doesn't get stuck, but report an error later on the post switch which will cause mac80211 to tear down the operation. This ensures nothing gets stuck due to the scheduling failure. Signed-off-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 8 ++++++++ drivers/net/wireless/iwlwifi/mvm/mvm.h | 2 ++ drivers/net/wireless/iwlwifi/mvm/time-event.c | 16 ++++++++++------ 3 files changed, 20 insertions(+), 6 deletions(-) (limited to 'drivers/net/wireless/iwlwifi') diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 302c8cc50f25..5f26557e4197 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -3646,6 +3646,8 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw, mutex_lock(&mvm->mutex); + mvmvif->csa_failed = false; + IWL_DEBUG_MAC80211(mvm, "pre CSA to freq %d\n", chsw->chandef.center_freq1); @@ -3721,6 +3723,12 @@ static int iwl_mvm_post_channel_switch(struct ieee80211_hw *hw, mutex_lock(&mvm->mutex); + if (mvmvif->csa_failed) { + mvmvif->csa_failed = false; + ret = -EIO; + goto out_unlock; + } + if (vif->type == NL80211_IFTYPE_STATION) { struct iwl_mvm_sta *mvmsta; diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 432265eb0dd7..4903dec7048a 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -354,6 +354,7 @@ struct iwl_mvm_vif_bf_data { * @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 + * @csa_failed: CSA failed to schedule time event, report an error later */ struct iwl_mvm_vif { struct iwl_mvm *mvm; @@ -433,6 +434,7 @@ struct iwl_mvm_vif { /* Indicates that CSA countdown may be started */ bool csa_countdown; + bool csa_failed; }; static inline struct iwl_mvm_vif * diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c index 8d179ab67cc2..98c8d70c90d2 100644 --- a/drivers/net/wireless/iwlwifi/mvm/time-event.c +++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c @@ -196,19 +196,23 @@ iwl_mvm_te_handle_notify_csa(struct iwl_mvm *mvm, struct iwl_mvm_time_event_data *te_data, struct iwl_time_event_notif *notif) { - if (!le32_to_cpu(notif->status)) { - if (te_data->vif->type == NL80211_IFTYPE_STATION) - ieee80211_connection_loss(te_data->vif); + struct ieee80211_vif *vif = te_data->vif; + struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); + + if (!notif->status) IWL_DEBUG_TE(mvm, "CSA time event failed to start\n"); - iwl_mvm_te_clear_data(mvm, te_data); - return; - } switch (te_data->vif->type) { case NL80211_IFTYPE_AP: + if (!notif->status) + mvmvif->csa_failed = true; iwl_mvm_csa_noa_start(mvm); break; case NL80211_IFTYPE_STATION: + if (!notif->status) { + ieee80211_connection_loss(te_data->vif); + break; + } iwl_mvm_csa_client_absent(mvm, te_data->vif); ieee80211_chswitch_done(te_data->vif, true); break; -- cgit v1.2.3 From 4d165d12e36584c44abb8e912944a84c78f91b7c Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Wed, 25 Feb 2015 11:06:37 +0200 Subject: iwlwifi: mvm: assign new TLV bit for multi-source LAR According to FW methodology, the capability bits should be the only ones that change per-HW. The API bits should remain constant across different HWs. Currently this is not the case with multi-source LAR (API bit 9). Assign a new capability bit to eventually replace the API bit. Until the API bit can be deprecated, the driver will check either to enable multi-source LAR. Signed-off-by: Arik Nemtsov Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/iwl-fw-file.h | 5 +++++ drivers/net/wireless/iwlwifi/mvm/mvm.h | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/net/wireless/iwlwifi') diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h index 291a3382aa3f..60f3f86904fb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h @@ -290,6 +290,10 @@ enum iwl_ucode_tlv_api { * @IWL_UCODE_TLV_CAPA_HOTSPOT_SUPPORT: supports Hot Spot Command * @IWL_UCODE_TLV_CAPA_RADIO_BEACON_STATS: support radio and beacon statistics * @IWL_UCODE_TLV_CAPA_BT_COEX_PLCR: enabled BT Coex packet level co-running + * @IWL_UCODE_TLV_CAPA_LAR_MULTI_MCC: ucode supports LAR updates with different + * sources for the MCC. This TLV bit is a future replacement to + * IWL_UCODE_TLV_API_WIFI_MCC_UPDATE. When either is set, multi-source LAR + * is supported. * @IWL_UCODE_TLV_CAPA_BT_COEX_RRC: supports BT Coex RRC */ enum iwl_ucode_tlv_capa { @@ -307,6 +311,7 @@ enum iwl_ucode_tlv_capa { IWL_UCODE_TLV_CAPA_HOTSPOT_SUPPORT = BIT(18), IWL_UCODE_TLV_CAPA_RADIO_BEACON_STATS = BIT(22), IWL_UCODE_TLV_CAPA_BT_COEX_PLCR = BIT(28), + IWL_UCODE_TLV_CAPA_LAR_MULTI_MCC = BIT(29), IWL_UCODE_TLV_CAPA_BT_COEX_RRC = BIT(30), }; diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 4903dec7048a..23c6c8af4a9f 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -936,7 +936,8 @@ static inline bool iwl_mvm_is_lar_supported(struct iwl_mvm *mvm) static inline bool iwl_mvm_is_wifi_mcc_supported(struct iwl_mvm *mvm) { - return mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_WIFI_MCC_UPDATE; + return mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_WIFI_MCC_UPDATE || + mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_LAR_MULTI_MCC; } static inline bool iwl_mvm_is_scd_cfg_supported(struct iwl_mvm *mvm) -- cgit v1.2.3 From 9243efccd45373fd6431729f88deaa0cf0bbe0be Mon Sep 17 00:00:00 2001 From: Liad Kaufman Date: Sun, 15 Mar 2015 17:38:22 +0200 Subject: iwlwifi: pcie: add rx packet sequence number to dbg print For each RX packet until this patch there only was a debug print of the HCMD and the offset. This adds also the sequence number of the packet for easier matching between what was sent, what came back / was received, and what got stuck somewhere and was never responded by the FW. Signed-off-by: Liad Kaufman Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/pcie/rx.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers/net/wireless/iwlwifi') diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c index 7b7e2f223fb2..7ff69c642103 100644 --- a/drivers/net/wireless/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/iwlwifi/pcie/rx.c @@ -600,9 +600,11 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans, if (pkt->len_n_flags == cpu_to_le32(FH_RSCSR_FRAME_INVALID)) break; - IWL_DEBUG_RX(trans, "cmd at offset %d: %s (0x%.2x)\n", - rxcb._offset, get_cmd_string(trans_pcie, pkt->hdr.cmd), - pkt->hdr.cmd); + IWL_DEBUG_RX(trans, + "cmd at offset %d: %s (0x%.2x, seq 0x%x)\n", + rxcb._offset, + get_cmd_string(trans_pcie, pkt->hdr.cmd), + pkt->hdr.cmd, le16_to_cpu(pkt->hdr.sequence)); len = iwl_rx_packet_len(pkt); len += sizeof(u32); /* account for status word */ -- cgit v1.2.3 From fe92e32ace11b21311fbeb8dbf14ac45b87e700d Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Wed, 11 Mar 2015 09:34:31 +0200 Subject: iwlwifi: mvm: properly flush the queues for buffering transport There are transport that must buffer frames in the driver. This means that we have frames that are not in the op_mode and not visible to the firwmare. This causes issues when we flush the queues: the op_mode flushes a queue, and the firmware flushes all the frames that are *currently* on the rings, but if the transport buffers frames, it can submit these while we are flushing. This leads to a situation where we still have frames on the queues after we flushed them. Preventing those buffered frame from getting into the firmware is possible, but then, we have to run the Tx response path on frames that didn't reach the firmware which is not desirable. The way I solve this here is to let these frames go to the firmware, but make sure the firmware will not transmit them (by setting the station as draining). The op_mode then needs to wait until the transport itself is empty to be sure that the queue is really empty. Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 24 ++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/mvm/sta.c | 14 ++++++++++++++ drivers/net/wireless/iwlwifi/mvm/tx.c | 8 ++++++++ 3 files changed, 46 insertions(+) (limited to 'drivers/net/wireless/iwlwifi') diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 5f26557e4197..babe8922faeb 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -1595,9 +1595,33 @@ static void iwl_mvm_prepare_mac_removal(struct iwl_mvm *mvm, u32 tfd_msk = iwl_mvm_mac_get_queues_mask(vif); if (tfd_msk) { + /* + * mac80211 first removes all the stations of the vif and + * then removes the vif. When it removes a station it also + * flushes the AMPDU session. So by now, all the AMPDU sessions + * of all the stations of this vif are closed, and the queues + * of these AMPDU sessions are properly closed. + * We still need to take care of the shared queues of the vif. + * Flush them here. + */ mutex_lock(&mvm->mutex); iwl_mvm_flush_tx_path(mvm, tfd_msk, true); mutex_unlock(&mvm->mutex); + + /* + * There are transports that buffer a few frames in the host. + * For these, the flush above isn't enough since while we were + * flushing, the transport might have sent more frames to the + * device. To solve this, wait here until the transport is + * empty. Technically, this could have replaced the flush + * above, but flush is much faster than draining. So flush + * first, and drain to make sure we have no frames in the + * transport anymore. + * If a station still had frames on the shared queues, it is + * already marked as draining, so to complete the draining, we + * just need to wait until the transport is empty. + */ + iwl_trans_wait_tx_queue_empty(mvm->trans, tfd_msk); } if (vif->type == NL80211_IFTYPE_P2P_DEVICE) { diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c index 50f9288368af..9bf512bdbbd6 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/iwlwifi/mvm/sta.c @@ -491,8 +491,18 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm, if (vif->type == NL80211_IFTYPE_STATION && mvmvif->ap_sta_id == mvm_sta->sta_id) { + ret = iwl_mvm_drain_sta(mvm, mvm_sta, true); + if (ret) + return ret; /* flush its queues here since we are freeing mvm_sta */ ret = iwl_mvm_flush_tx_path(mvm, mvm_sta->tfd_queue_msk, true); + if (ret) + return ret; + ret = iwl_trans_wait_tx_queue_empty(mvm->trans, + mvm_sta->tfd_queue_msk); + if (ret) + return ret; + ret = iwl_mvm_drain_sta(mvm, mvm_sta, false); /* if we are associated - we can't remove the AP STA now */ if (vif->bss_conf.assoc) @@ -1120,8 +1130,12 @@ int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif, spin_unlock_bh(&mvmsta->lock); if (old_state >= IWL_AGG_ON) { + iwl_mvm_drain_sta(mvm, mvmsta, true); if (iwl_mvm_flush_tx_path(mvm, BIT(txq_id), true)) IWL_ERR(mvm, "Couldn't flush the AGG queue\n"); + iwl_trans_wait_tx_queue_empty(mvm->trans, + mvmsta->tfd_queue_msk); + iwl_mvm_drain_sta(mvm, mvmsta, false); iwl_mvm_sta_tx_agg(mvm, sta, tid, txq_id, false); diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c index 7906b97c81b9..d963439cd899 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/iwlwifi/mvm/tx.c @@ -1047,6 +1047,14 @@ out: return 0; } +/* + * Note that there are transports that buffer frames before they reach + * the firmware. This means that after flush_tx_path is called, the + * queue might not be empty. The race-free way to handle this is to: + * 1) set the station as draining + * 2) flush the Tx path + * 3) wait for the transport queues to be empty + */ int iwl_mvm_flush_tx_path(struct iwl_mvm *mvm, u32 tfd_msk, bool sync) { int ret; -- cgit v1.2.3 From e539761d98dbd80204867194a9f110f8392c2637 Mon Sep 17 00:00:00 2001 From: Liad Kaufman Date: Mon, 2 Mar 2015 11:46:46 +0200 Subject: iwlwifi: mvm: add iccm data to 8000 b-step data dump In 8000 HW family B-step only, the ICCM is separate from the SRAM. This adds the ICCM to the dump data collected for FW debug. Signed-off-by: Liad Kaufman Reviewed-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'drivers/net/wireless/iwlwifi') diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index babe8922faeb..a3a84d1523bc 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -1007,6 +1007,9 @@ void iwl_mvm_free_fw_dump_desc(struct iwl_mvm *mvm) mvm->fw_dump_desc = NULL; } +#define IWL8260_ICCM_OFFSET 0x44000 /* Only for B-step */ +#define IWL8260_ICCM_LEN 0xC000 /* Only for B-step */ + void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm) { struct iwl_fw_error_dump_file *dump_file; @@ -1083,6 +1086,14 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm) fifo_data_len + sizeof(*dump_info); + /* + * In 8000 HW family B-step include the ICCM (which resides separately) + */ + if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_8000 && + CSR_HW_REV_STEP(mvm->trans->hw_rev) == SILICON_B_STEP) + file_len += sizeof(*dump_data) + sizeof(*dump_mem) + + IWL8260_ICCM_LEN; + if (mvm->fw_dump_desc) file_len += sizeof(*dump_data) + sizeof(*dump_trig) + mvm->fw_dump_desc->len; @@ -1170,6 +1181,19 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm) dump_mem->data, sram2_len); } + if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_8000 && + CSR_HW_REV_STEP(mvm->trans->hw_rev) == SILICON_B_STEP) { + dump_data = iwl_fw_error_next_data(dump_data); + dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM); + dump_data->len = cpu_to_le32(IWL8260_ICCM_LEN + + sizeof(*dump_mem)); + dump_mem = (void *)dump_data->data; + dump_mem->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM_SRAM); + dump_mem->offset = cpu_to_le32(IWL8260_ICCM_OFFSET); + iwl_trans_read_mem_bytes(mvm->trans, IWL8260_ICCM_OFFSET, + dump_mem->data, IWL8260_ICCM_LEN); + } + fw_error_dump->trans_ptr = iwl_trans_dump_data(mvm->trans); fw_error_dump->op_mode_len = file_len; if (fw_error_dump->trans_ptr) -- cgit v1.2.3 From bcd535eb5313947917a6a00c2a65561853b1be70 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 12 Mar 2015 09:10:13 +0100 Subject: iwlwifi: mvm: remove time-event start/end failure warning This warning is misleading. In many cases, for example P2P ROC time events, this will happen if the time event is aborted, for example due to a higher priority time event. This is entirely normal and not worth warning about. In other cases, where we actually do act upon this, for example when trying to connect and this fails, we should instead warn as part of the disconnect operation. Change the code to do that, i.e. make the warning a debug message, and make it more prominent (an error) when we actually disconnect because of it. This also fixes confusion in the logs - the warning was mistaken for something that needed investigation, while in most cases it's just expected behaviour that occasionally some lower-priority time events would not complete fully. Signed-off-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/time-event.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'drivers/net/wireless/iwlwifi') diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c index 98c8d70c90d2..a32f612a8b59 100644 --- a/drivers/net/wireless/iwlwifi/mvm/time-event.c +++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c @@ -252,11 +252,16 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm, * events in the system). */ if (!le32_to_cpu(notif->status)) { - bool start = le32_to_cpu(notif->action) & - TE_V2_NOTIF_HOST_EVENT_START; - IWL_WARN(mvm, "Time Event %s notification failure\n", - start ? "start" : "end"); - if (iwl_mvm_te_check_disconnect(mvm, te_data->vif, NULL)) { + const char *msg; + + if (notif->action & cpu_to_le32(TE_V2_NOTIF_HOST_EVENT_START)) + msg = "Time Event start notification failure"; + else + msg = "Time Event end notification failure"; + + IWL_DEBUG_TE(mvm, "%s\n", msg); + + if (iwl_mvm_te_check_disconnect(mvm, te_data->vif, msg)) { iwl_mvm_te_clear_data(mvm, te_data); return; } -- cgit v1.2.3 From 28c8c19a0004a74cd6303fa088b33212d0d80536 Mon Sep 17 00:00:00 2001 From: Eran Harary Date: Tue, 3 Mar 2015 16:19:36 +0200 Subject: iwlwifi: mvm: don't wait for firmware verification The firmware has a race in the flow that indicates the completion of the authentication. Checking the completion of the authentication is not really needed anyway since we can wait for the ALIVE notification instead. Remove the unneeded and buggy code. Signed-off-by: Eran Harary Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/iwl-prph.h | 21 --------------------- drivers/net/wireless/iwlwifi/pcie/trans.c | 15 --------------- 2 files changed, 36 deletions(-) (limited to 'drivers/net/wireless/iwlwifi') diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index bc962888c583..467c4bc68269 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h @@ -295,25 +295,6 @@ #define OSC_CLK (0xa04068) #define OSC_CLK_FORCE_CONTROL (0x8) -/* SECURE boot registers */ -#define LMPM_SECURE_BOOT_CONFIG_ADDR (0x100) -enum secure_boot_config_reg { - LMPM_SECURE_BOOT_CONFIG_INSPECTOR_BURNED_IN_OTP = 0x00000001, - LMPM_SECURE_BOOT_CONFIG_INSPECTOR_NOT_REQ = 0x00000002, -}; - -#define LMPM_SECURE_BOOT_CPU1_STATUS_ADDR_B0 (0xA01E30) -#define LMPM_SECURE_BOOT_CPU1_STATUS_ADDR (0x1E30) -#define LMPM_SECURE_BOOT_CPU2_STATUS_ADDR (0x1E34) -enum secure_boot_status_reg { - LMPM_SECURE_BOOT_CPU_STATUS_VERF_STATUS = 0x00000001, - LMPM_SECURE_BOOT_CPU_STATUS_VERF_COMPLETED = 0x00000002, - LMPM_SECURE_BOOT_CPU_STATUS_VERF_SUCCESS = 0x00000004, - LMPM_SECURE_BOOT_CPU_STATUS_VERF_FAIL = 0x00000008, - LMPM_SECURE_BOOT_CPU_STATUS_SIGN_VERF_FAIL = 0x00000010, - LMPM_SECURE_BOOT_STATUS_SUCCESS = 0x00000003, -}; - #define FH_UCODE_LOAD_STATUS (0x1AF0) #define CSR_UCODE_LOAD_STATUS_ADDR (0x1E70) enum secure_load_status_reg { @@ -334,8 +315,6 @@ enum secure_load_status_reg { #define LMPM_SECURE_CPU1_HDR_MEM_SPACE (0x420000) #define LMPM_SECURE_CPU2_HDR_MEM_SPACE (0x420400) -#define LMPM_SECURE_TIME_OUT (100) /* 10 micro */ - /* Rx FIFO */ #define RXF_SIZE_ADDR (0xa00c88) #define RXF_RD_D_SPACE (0xa00c40) diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index dc247325d8d7..df0022e72cd2 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -930,7 +930,6 @@ static int iwl_pcie_load_given_ucode_8000b(struct iwl_trans *trans, { int ret = 0; int first_ucode_section; - u32 reg; IWL_DEBUG_FW(trans, "working with %s CPU\n", image->is_dual_cpus ? "Dual" : "Single"); @@ -959,20 +958,6 @@ static int iwl_pcie_load_given_ucode_8000b(struct iwl_trans *trans, if (ret) return ret; - /* wait for image verification to complete */ - ret = iwl_poll_prph_bit(trans, LMPM_SECURE_BOOT_CPU1_STATUS_ADDR_B0, - LMPM_SECURE_BOOT_STATUS_SUCCESS, - LMPM_SECURE_BOOT_STATUS_SUCCESS, - LMPM_SECURE_TIME_OUT); - if (ret < 0) { - reg = iwl_read_prph(trans, - LMPM_SECURE_BOOT_CPU1_STATUS_ADDR_B0); - - IWL_ERR(trans, "Timeout on secure boot process, reg = %x\n", - reg); - return ret; - } - return 0; } -- cgit v1.2.3 From 48e67751681654efe9743be64f18f1f08d1dbef2 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Tue, 3 Mar 2015 12:03:20 +0200 Subject: iwlwifi: mvm: take IWL_MVM_REF_UCODE_DOWN before restarting hw we unref IWL_MVM_REF_UCODE_DOWN on iwl_mvm_restart_complete(). Usually, the restart is initiated by iwl_mvm_nic_restart(), which takes the reference before restarting the hw. However, in D3 flow we might call ieee80211_restart_hw() directly (in case of suspend error and on d3_test-resume), which without taking the ref first. fix it. Signed-off-by: Eliad Peller Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/d3.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/net/wireless/iwlwifi') diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c index 5f8afa5f11a3..e730ea2b0812 100644 --- a/drivers/net/wireless/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/iwlwifi/mvm/d3.c @@ -1131,6 +1131,7 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, iwl_trans_d3_suspend(mvm->trans, test); out: if (ret < 0) { + iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN); ieee80211_restart_hw(mvm->hw); iwl_mvm_free_nd(mvm); } @@ -2016,6 +2017,7 @@ static int iwl_mvm_d3_test_release(struct inode *inode, struct file *file) __iwl_mvm_resume(mvm, true); rtnl_unlock(); iwl_abort_notification_waits(&mvm->notif_wait); + iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN); ieee80211_restart_hw(mvm->hw); /* wait for restart and disconnect all interfaces */ -- cgit v1.2.3 From 939e4904e09044f0446a5eccd2bb93090087d713 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sun, 8 Mar 2015 12:19:42 +0200 Subject: iwlwifi: mvm: remove d0i3 ref correctly during AP start The AP_START d0i3 reference was never removed if the AP started correctly. This has the unpleasant side-effect of preventing D0i3 on Android if the WiFi hotspot was ever started on the device. Signed-off-by: Arik Nemtsov Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/net/wireless/iwlwifi') diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index a3a84d1523bc..b4e28ff596bf 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -2215,8 +2215,7 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw, if (iwl_mvm_phy_ctx_count(mvm) > 1) iwl_mvm_teardown_tdls_peers(mvm); - mutex_unlock(&mvm->mutex); - return 0; + goto out_unlock; out_quota_failed: iwl_mvm_power_update_mac(mvm); -- cgit v1.2.3 From 4ffb36505c0d4e0909aa1812b0269eb181a51390 Mon Sep 17 00:00:00 2001 From: David Spinadel Date: Tue, 10 Mar 2015 10:06:02 +0200 Subject: iwlwifi: mvm: inform mac80211 about umac scans that was aborted by restart In nic restart flow we inform mac80211 that scan was aborted, but it was based only on scan_status which is not set by UMAC scan. Fix that. Signed-off-by: David Spinadel Reviewed-by: Johannes Berg Reviewed-by: Luciano Coelho Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/mvm.h | 1 + drivers/net/wireless/iwlwifi/mvm/ops.c | 13 +------------ drivers/net/wireless/iwlwifi/mvm/scan.c | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 12 deletions(-) (limited to 'drivers/net/wireless/iwlwifi') diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 23c6c8af4a9f..02c02e2b097f 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -1149,6 +1149,7 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, bool force_upload, int iwl_mvm_scan_size(struct iwl_mvm *mvm); int iwl_mvm_cancel_scan(struct iwl_mvm *mvm); int iwl_mvm_max_scan_ie_len(struct iwl_mvm *mvm, bool is_sched_scan); +void iwl_mvm_report_scan_aborted(struct iwl_mvm *mvm); /* Scheduled scan */ int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm, diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index 80121e41ca22..a28080ead54f 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c @@ -894,18 +894,7 @@ void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error) * the next start() call from mac80211. If restart isn't called * (no fw restart) scan status will stay busy. */ - switch (mvm->scan_status) { - case IWL_MVM_SCAN_NONE: - break; - case IWL_MVM_SCAN_OS: - ieee80211_scan_completed(mvm->hw, true); - break; - case IWL_MVM_SCAN_SCHED: - /* Sched scan will be restarted by mac80211 in restart_hw. */ - if (!mvm->restart_fw) - ieee80211_sched_scan_stopped(mvm->hw); - break; - } + iwl_mvm_report_scan_aborted(mvm); /* * If we're restarting already, don't cycle restarts. diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c index a75bb150ea27..63525876f68a 100644 --- a/drivers/net/wireless/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/iwlwifi/mvm/scan.c @@ -1613,3 +1613,35 @@ int iwl_mvm_scan_size(struct iwl_mvm *mvm) mvm->fw->ucode_capa.n_scan_channels + sizeof(struct iwl_scan_probe_req); } + +/* + * This function is used in nic restart flow, to inform mac80211 about scans + * that was aborted by restart flow or by an assert. + */ +void iwl_mvm_report_scan_aborted(struct iwl_mvm *mvm) +{ + if (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN) { + if (iwl_mvm_find_scan_type(mvm, IWL_UMAC_SCAN_UID_REG_SCAN)) + ieee80211_scan_completed(mvm->hw, true); + if (iwl_mvm_find_scan_type(mvm, IWL_UMAC_SCAN_UID_SCHED_SCAN) && + !mvm->restart_fw) + ieee80211_sched_scan_stopped(mvm->hw); + } else { + switch (mvm->scan_status) { + case IWL_MVM_SCAN_NONE: + break; + case IWL_MVM_SCAN_OS: + ieee80211_scan_completed(mvm->hw, true); + break; + case IWL_MVM_SCAN_SCHED: + /* + * Sched scan will be restarted by mac80211 in + * restart_hw, so do not report if FW is about to be + * restarted. + */ + if (!mvm->restart_fw) + ieee80211_sched_scan_stopped(mvm->hw); + break; + } + } +} -- cgit v1.2.3 From 483f3ab1754f3c3698db622cc181249a0ca6372c Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Wed, 4 Mar 2015 10:38:32 +0200 Subject: iwlwifi: pcie: initialize trans_pcie->ref_count on configure() ref_count is currently initialized on start_fw(). This causes some issues in restart flow, as currently active references (e.g. unclaimed command) will get cleared, resulting in invalid reference accounting. Move the ref_count initialization to the configure() trans op, so it won't be re-initialized on restart. Signed-off-by: Eliad Peller Reviewed-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/pcie/trans.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers/net/wireless/iwlwifi') diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index df0022e72cd2..39e3cf06e364 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -964,7 +964,6 @@ static int iwl_pcie_load_given_ucode_8000b(struct iwl_trans *trans, static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, const struct fw_img *fw, bool run_in_rfkill) { - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); int ret; bool hw_rfkill; @@ -994,9 +993,6 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, return ret; } - /* init ref_count to 1 (should be cleared when ucode is loaded) */ - trans_pcie->ref_count = 1; - /* make sure rfkill handshake bits are cleared */ iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, @@ -1315,6 +1311,9 @@ static void iwl_trans_pcie_configure(struct iwl_trans *trans, trans_pcie->bc_table_dword = trans_cfg->bc_table_dword; trans_pcie->scd_set_active = trans_cfg->scd_set_active; + /* init ref_count to 1 (should be cleared when ucode is loaded) */ + trans_pcie->ref_count = 1; + /* Initialize NAPI here - it should be before registering to mac80211 * in the opmode but after the HW struct is allocated. * As this function may be called again in some corner cases don't -- cgit v1.2.3 From 2250fd94c8887bdf0fb583a8f35bf555a0fff81c Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Wed, 3 Dec 2014 10:52:26 +0200 Subject: iwlwifi: mvm: add delay to scheduled scan Add support for delaying the start of a scheduled scan (or a WoWLAN net-detect scan). Signed-off-by: Luciano Coelho Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/scan.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers/net/wireless/iwlwifi') diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c index 63525876f68a..2997864fb13f 100644 --- a/drivers/net/wireless/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/iwlwifi/mvm/scan.c @@ -935,6 +935,8 @@ int iwl_mvm_unified_sched_scan_lmac(struct iwl_mvm *mvm, cmd->n_channels = (u8)req->n_channels; + cmd->delay = cpu_to_le32(req->delay); + if (iwl_mvm_scan_pass_all(mvm, req)) flags |= IWL_MVM_LMAC_SCAN_FLAG_PASS_ALL; else @@ -1436,7 +1438,13 @@ int iwl_mvm_sched_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif, cpu_to_le16(req->interval / MSEC_PER_SEC); sec_part->schedule[0].iter_count = 0xff; - sec_part->delay = 0; + if (req->delay > U16_MAX) { + IWL_DEBUG_SCAN(mvm, + "delay value is > 16-bits, set to max possible\n"); + sec_part->delay = cpu_to_le16(U16_MAX); + } else { + sec_part->delay = cpu_to_le16(req->delay); + } iwl_mvm_build_unified_scan_probe(mvm, vif, ies, &sec_part->preq, req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR ? -- cgit v1.2.3 From cb2513bb71cfaedfb9af37c27744b0e5cef15aa3 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Fri, 27 Feb 2015 16:26:57 +0200 Subject: iwlwifi: mvm: use debugfs_create_bool() for enable_scan_iteration_notif There is no need to implement the enable_scan_iteration_notif handling explicitly and there's no reason not to export the current value. So use debugfs_create_bool() instead. Signed-off-by: Luciano Coelho Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/debugfs.c | 28 +++++----------------------- drivers/net/wireless/iwlwifi/mvm/mvm.h | 2 +- 2 files changed, 6 insertions(+), 24 deletions(-) (limited to 'drivers/net/wireless/iwlwifi') diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c index 8c5229892e57..01b97a0c88dc 100644 --- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c @@ -1473,26 +1473,6 @@ out: return count; } -static ssize_t iwl_dbgfs_enable_scan_iteration_notif_write(struct iwl_mvm *mvm, - char *buf, - size_t count, - loff_t *ppos) -{ - int val; - - mutex_lock(&mvm->mutex); - - if (kstrtoint(buf, 10, &val)) { - mutex_unlock(&mvm->mutex); - return -EINVAL; - } - - mvm->scan_iter_notif_enabled = val; - mutex_unlock(&mvm->mutex); - - return count; -} - MVM_DEBUGFS_READ_WRITE_FILE_OPS(prph_reg, 64); /* Device wide debugfs entries */ @@ -1515,7 +1495,6 @@ MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain, 8); MVM_DEBUGFS_READ_WRITE_FILE_OPS(d0i3_refs, 8); MVM_DEBUGFS_READ_WRITE_FILE_OPS(fw_dbg_conf, 8); MVM_DEBUGFS_WRITE_FILE_OPS(fw_dbg_collect, 8); -MVM_DEBUGFS_WRITE_FILE_OPS(enable_scan_iteration_notif, 8); #ifdef CONFIG_IWLWIFI_BCAST_FILTERING MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters, 256); @@ -1559,8 +1538,11 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) MVM_DEBUGFS_ADD_FILE(d0i3_refs, mvm->debugfs_dir, S_IRUSR | S_IWUSR); MVM_DEBUGFS_ADD_FILE(fw_dbg_conf, mvm->debugfs_dir, S_IRUSR | S_IWUSR); MVM_DEBUGFS_ADD_FILE(fw_dbg_collect, mvm->debugfs_dir, S_IWUSR); - MVM_DEBUGFS_ADD_FILE(enable_scan_iteration_notif, mvm->debugfs_dir, - S_IWUSR); + if (!debugfs_create_bool("enable_scan_iteration_notif", + S_IRUSR | S_IWUSR, + mvm->debugfs_dir, + &mvm->scan_iter_notif_enabled)) + goto err; #ifdef CONFIG_IWLWIFI_BCAST_FILTERING if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BCAST_FILTERING) { diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 02c02e2b097f..91c74d4f0754 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -688,7 +688,7 @@ struct iwl_mvm { bool disable_power_off; bool disable_power_off_d3; - bool scan_iter_notif_enabled; + u32 scan_iter_notif_enabled; /* must be u32 for debugfs_create_bool */ struct debugfs_blob_wrapper nvm_hw_blob; struct debugfs_blob_wrapper nvm_sw_blob; -- cgit v1.2.3 From 5dd9c68a854a77da2091b08d8fb7717b04667c6d Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 5 Mar 2015 13:06:13 +0200 Subject: iwlwifi: drop support for early versions of 8000 These early versions are no longer supported. Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/iwl-8000.c | 3 -- drivers/net/wireless/iwlwifi/iwl-config.h | 1 - drivers/net/wireless/iwlwifi/iwl-drv.c | 10 +---- drivers/net/wireless/iwlwifi/iwl-io.c | 13 ++----- drivers/net/wireless/iwlwifi/iwl-nvm-parse.c | 57 ++++++++-------------------- drivers/net/wireless/iwlwifi/iwl-nvm-parse.h | 3 +- drivers/net/wireless/iwlwifi/iwl-prph.h | 4 +- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 10 ----- drivers/net/wireless/iwlwifi/mvm/nvm.c | 20 +++------- drivers/net/wireless/iwlwifi/mvm/ops.c | 11 ++---- drivers/net/wireless/iwlwifi/pcie/trans.c | 30 +++++++-------- 11 files changed, 46 insertions(+), 116 deletions(-) (limited to 'drivers/net/wireless/iwlwifi') diff --git a/drivers/net/wireless/iwlwifi/iwl-8000.c b/drivers/net/wireless/iwlwifi/iwl-8000.c index 9c396a42aec8..4ef50cf7d9a6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-8000.c +++ b/drivers/net/wireless/iwlwifi/iwl-8000.c @@ -94,7 +94,6 @@ IWL8000_FW_PRE "-" __stringify(api) ".ucode" #define NVM_HW_SECTION_NUM_FAMILY_8000 10 -#define DEFAULT_NVM_FILE_FAMILY_8000A "iwl_nvm_8000.bin" #define DEFAULT_NVM_FILE_FAMILY_8000 "iwl_nvm_8000B.bin" /* Max SDIO RX aggregation size of the ADDBA request/response */ @@ -178,7 +177,6 @@ const struct iwl_cfg iwl8260_2ac_sdio_cfg = { .nvm_ver = IWL8000_NVM_VERSION, .nvm_calib_ver = IWL8000_TX_POWER_VERSION, .default_nvm_file = DEFAULT_NVM_FILE_FAMILY_8000, - .default_nvm_file_8000A = DEFAULT_NVM_FILE_FAMILY_8000A, .max_rx_agg_size = MAX_RX_AGG_SIZE_8260_SDIO, .disable_dummy_notification = true, .max_ht_ampdu_exponent = MAX_HT_AMPDU_EXPONENT_8260_SDIO, @@ -193,7 +191,6 @@ const struct iwl_cfg iwl4165_2ac_sdio_cfg = { .nvm_ver = IWL8000_NVM_VERSION, .nvm_calib_ver = IWL8000_TX_POWER_VERSION, .default_nvm_file = DEFAULT_NVM_FILE_FAMILY_8000, - .default_nvm_file_8000A = DEFAULT_NVM_FILE_FAMILY_8000A, .max_rx_agg_size = MAX_RX_AGG_SIZE_8260_SDIO, .bt_shared_single_ant = true, .disable_dummy_notification = true, diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h index 4b190d98a1ec..aa41c778af83 100644 --- a/drivers/net/wireless/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/iwlwifi/iwl-config.h @@ -304,7 +304,6 @@ struct iwl_cfg { const struct iwl_pwr_tx_backoff *pwr_tx_backoffs; bool no_power_up_nic_in_init; const char *default_nvm_file; - const char *default_nvm_file_8000A; unsigned int max_rx_agg_size; bool disable_dummy_notification; unsigned int max_tx_agg_size; diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 66ca000f0da1..885c78708639 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c @@ -241,16 +241,10 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first) * previous name and uses the new format. */ if (drv->trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) { - char rev_step[2] = { - 'A' + CSR_HW_REV_STEP(drv->trans->hw_rev), 0 - }; - - /* A-step doesn't have an indication */ - if (CSR_HW_REV_STEP(drv->trans->hw_rev) == SILICON_A_STEP) - rev_step[0] = 0; + char rev_step = 'A' + CSR_HW_REV_STEP(drv->trans->hw_rev); snprintf(drv->firmware_name, sizeof(drv->firmware_name), - "%s%s-%s.ucode", name_pre, rev_step, tag); + "%s%c-%s.ucode", name_pre, rev_step, tag); } IWL_DEBUG_INFO(drv, "attempting to load firmware %s'%s'\n", diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c index 78cac43e2bcd..27c66e477833 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.c +++ b/drivers/net/wireless/iwlwifi/iwl-io.c @@ -186,21 +186,14 @@ IWL_EXPORT_SYMBOL(iwl_clear_bits_prph); void iwl_force_nmi(struct iwl_trans *trans) { - /* - * In HW previous to the 8000 HW family, and in the 8000 HW family - * itself when the revision step==0, the DEVICE_SET_NMI_REG is used - * to force an NMI. Otherwise, a different register - - * DEVICE_SET_NMI_8000B_REG - is used. - */ - if ((trans->cfg->device_family != IWL_DEVICE_FAMILY_8000) || - (CSR_HW_REV_STEP(trans->hw_rev) == SILICON_A_STEP)) { + if (trans->cfg->device_family != IWL_DEVICE_FAMILY_8000) { iwl_write_prph(trans, DEVICE_SET_NMI_REG, DEVICE_SET_NMI_VAL_DRV); iwl_write_prph(trans, DEVICE_SET_NMI_REG, DEVICE_SET_NMI_VAL_HW); } else { - iwl_write_prph(trans, DEVICE_SET_NMI_8000B_REG, - DEVICE_SET_NMI_8000B_VAL); + iwl_write_prph(trans, DEVICE_SET_NMI_8000_REG, + DEVICE_SET_NMI_8000_VAL); iwl_write_prph(trans, DEVICE_SET_NMI_REG, DEVICE_SET_NMI_VAL_DRV); } diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c index 774637746427..83903a5025c2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c @@ -99,14 +99,9 @@ enum family_8000_nvm_offsets { /* NVM SW-Section offset (in words) definitions */ NVM_SW_SECTION_FAMILY_8000 = 0x1C0, NVM_VERSION_FAMILY_8000 = 0, - RADIO_CFG_FAMILY_8000 = 2, - SKU_FAMILY_8000 = 4, - N_HW_ADDRS_FAMILY_8000 = 5, - - /* NVM PHY-SKU-Section offset (in words) for B0 */ - RADIO_CFG_FAMILY_8000_B0 = 0, - SKU_FAMILY_8000_B0 = 2, - N_HW_ADDRS_FAMILY_8000_B0 = 3, + RADIO_CFG_FAMILY_8000 = 0, + SKU_FAMILY_8000 = 2, + N_HW_ADDRS_FAMILY_8000 = 3, /* NVM REGULATORY -Section offset (in words) definitions */ NVM_CHANNELS_FAMILY_8000 = 0, @@ -446,22 +441,16 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg, n_used, n_channels); } -static int iwl_get_sku(const struct iwl_cfg *cfg, - const __le16 *nvm_sw, const __le16 *phy_sku, - bool is_family_8000_a_step) +static int iwl_get_sku(const struct iwl_cfg *cfg, const __le16 *nvm_sw, + const __le16 *phy_sku) { if (cfg->device_family != IWL_DEVICE_FAMILY_8000) return le16_to_cpup(nvm_sw + SKU); - if (!is_family_8000_a_step) - return le32_to_cpup((__le32 *)(phy_sku + - SKU_FAMILY_8000_B0)); - else - return le32_to_cpup((__le32 *)(nvm_sw + SKU_FAMILY_8000)); + return le32_to_cpup((__le32 *)(phy_sku + SKU_FAMILY_8000)); } -static int iwl_get_nvm_version(const struct iwl_cfg *cfg, - const __le16 *nvm_sw) +static int iwl_get_nvm_version(const struct iwl_cfg *cfg, const __le16 *nvm_sw) { if (cfg->device_family != IWL_DEVICE_FAMILY_8000) return le16_to_cpup(nvm_sw + NVM_VERSION); @@ -470,35 +459,24 @@ static int iwl_get_nvm_version(const struct iwl_cfg *cfg, NVM_VERSION_FAMILY_8000)); } -static int iwl_get_radio_cfg(const struct iwl_cfg *cfg, - const __le16 *nvm_sw, const __le16 *phy_sku, - bool is_family_8000_a_step) +static int iwl_get_radio_cfg(const struct iwl_cfg *cfg, const __le16 *nvm_sw, + const __le16 *phy_sku) { if (cfg->device_family != IWL_DEVICE_FAMILY_8000) return le16_to_cpup(nvm_sw + RADIO_CFG); - if (!is_family_8000_a_step) - return le32_to_cpup((__le32 *)(phy_sku + - RADIO_CFG_FAMILY_8000_B0)); - else - return le32_to_cpup((__le32 *)(nvm_sw + RADIO_CFG_FAMILY_8000)); + return le32_to_cpup((__le32 *)(nvm_sw + RADIO_CFG_FAMILY_8000)); } -static int iwl_get_n_hw_addrs(const struct iwl_cfg *cfg, - const __le16 *nvm_sw, bool is_family_8000_a_step) +static int iwl_get_n_hw_addrs(const struct iwl_cfg *cfg, const __le16 *nvm_sw) { int n_hw_addr; if (cfg->device_family != IWL_DEVICE_FAMILY_8000) return le16_to_cpup(nvm_sw + N_HW_ADDRS); - if (!is_family_8000_a_step) - n_hw_addr = le32_to_cpup((__le32 *)(nvm_sw + - N_HW_ADDRS_FAMILY_8000_B0)); - else - n_hw_addr = le32_to_cpup((__le32 *)(nvm_sw + - N_HW_ADDRS_FAMILY_8000)); + n_hw_addr = le32_to_cpup((__le32 *)(nvm_sw + N_HW_ADDRS_FAMILY_8000)); return n_hw_addr & N_HW_ADDR_MASK; } @@ -594,8 +572,7 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg, const __le16 *nvm_hw, const __le16 *nvm_sw, const __le16 *nvm_calib, const __le16 *regulatory, const __le16 *mac_override, const __le16 *phy_sku, - u8 tx_chains, u8 rx_chains, - bool lar_fw_supported, bool is_family_8000_a_step, + u8 tx_chains, u8 rx_chains, bool lar_fw_supported, u32 mac_addr0, u32 mac_addr1) { struct iwl_nvm_data *data; @@ -618,15 +595,14 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg, data->nvm_version = iwl_get_nvm_version(cfg, nvm_sw); - radio_cfg = - iwl_get_radio_cfg(cfg, nvm_sw, phy_sku, is_family_8000_a_step); + radio_cfg = iwl_get_radio_cfg(cfg, nvm_sw, phy_sku); iwl_set_radio_cfg(cfg, data, radio_cfg); if (data->valid_tx_ant) tx_chains &= data->valid_tx_ant; if (data->valid_rx_ant) rx_chains &= data->valid_rx_ant; - sku = iwl_get_sku(cfg, nvm_sw, phy_sku, is_family_8000_a_step); + sku = iwl_get_sku(cfg, nvm_sw, phy_sku); data->sku_cap_band_24GHz_enable = sku & NVM_SKU_CAP_BAND_24GHZ; data->sku_cap_band_52GHz_enable = sku & NVM_SKU_CAP_BAND_52GHZ; data->sku_cap_11n_enable = sku & NVM_SKU_CAP_11N_ENABLE; @@ -635,8 +611,7 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg, data->sku_cap_11ac_enable = data->sku_cap_11n_enable && (sku & NVM_SKU_CAP_11AC_ENABLE); - data->n_hw_addrs = - iwl_get_n_hw_addrs(cfg, nvm_sw, is_family_8000_a_step); + data->n_hw_addrs = iwl_get_n_hw_addrs(cfg, nvm_sw); if (cfg->device_family != IWL_DEVICE_FAMILY_8000) { /* Checking for required sections */ diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h index c995d2cee3f6..822ba52e0e5a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h +++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h @@ -78,8 +78,7 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg, const __le16 *nvm_hw, const __le16 *nvm_sw, const __le16 *nvm_calib, const __le16 *regulatory, const __le16 *mac_override, const __le16 *phy_sku, - u8 tx_chains, u8 rx_chains, - bool lar_fw_supported, bool is_family_8000_a_step, + u8 tx_chains, u8 rx_chains, bool lar_fw_supported, u32 mac_addr0, u32 mac_addr1); /** diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index 467c4bc68269..88a57e6e232f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h @@ -110,8 +110,8 @@ #define DEVICE_SET_NMI_REG 0x00a01c30 #define DEVICE_SET_NMI_VAL_HW BIT(0) #define DEVICE_SET_NMI_VAL_DRV BIT(7) -#define DEVICE_SET_NMI_8000B_REG 0x00a01c24 -#define DEVICE_SET_NMI_8000B_VAL 0x1000000 +#define DEVICE_SET_NMI_8000_REG 0x00a01c24 +#define DEVICE_SET_NMI_8000_VAL 0x1000000 /* Shared registers (0x0..0x3ff, via target indirect or periphery */ #define SHR_BASE 0x00a10000 diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index b4e28ff596bf..213bd72bd849 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -1025,16 +1025,6 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm) lockdep_assert_held(&mvm->mutex); - /* W/A for 8000 HW family A-step */ - if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_8000 && - CSR_HW_REV_STEP(mvm->trans->hw_rev) == SILICON_A_STEP) { - if (smem_len) - smem_len = 0x38000; - - if (sram2_len) - sram2_len = 0x10000; - } - fw_error_dump = kzalloc(sizeof(*fw_error_dump), GFP_KERNEL); if (!fw_error_dump) return; diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c index 123e0a16aea8..675197d9f03e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/nvm.c +++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c @@ -77,8 +77,7 @@ /* Default NVM size to read */ #define IWL_NVM_DEFAULT_CHUNK_SIZE (2*1024) #define IWL_MAX_NVM_SECTION_SIZE 0x1b58 -#define IWL_MAX_NVM_8000A_SECTION_SIZE 0xffc -#define IWL_MAX_NVM_8000B_SECTION_SIZE 0x1ffc +#define IWL_MAX_NVM_8000_SECTION_SIZE 0x1ffc #define NVM_WRITE_OPCODE 1 #define NVM_READ_OPCODE 0 @@ -267,7 +266,7 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm) { struct iwl_nvm_section *sections = mvm->nvm_sections; const __le16 *hw, *sw, *calib, *regulatory, *mac_override, *phy_sku; - bool is_family_8000_a_step = false, lar_enabled; + bool lar_enabled; u32 mac_addr0, mac_addr1; /* Checking for required sections */ @@ -293,12 +292,8 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm) return NULL; } - if (CSR_HW_REV_STEP(mvm->trans->hw_rev) == SILICON_A_STEP) - is_family_8000_a_step = true; - /* PHY_SKU section is mandatory in B0 */ - if (!is_family_8000_a_step && - !mvm->nvm_sections[NVM_SECTION_TYPE_PHY_SKU].data) { + if (!mvm->nvm_sections[NVM_SECTION_TYPE_PHY_SKU].data) { IWL_ERR(mvm, "Can't parse phy_sku in B0, empty sections\n"); return NULL; @@ -327,8 +322,7 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm) return iwl_parse_nvm_data(mvm->trans->dev, mvm->cfg, hw, sw, calib, regulatory, mac_override, phy_sku, mvm->fw->valid_tx_ant, mvm->fw->valid_rx_ant, - lar_enabled, is_family_8000_a_step, - mac_addr0, mac_addr1); + lar_enabled, mac_addr0, mac_addr1); } #define MAX_NVM_FILE_LEN 16384 @@ -381,10 +375,8 @@ static int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm) /* Maximal size depends on HW family and step */ if (mvm->trans->cfg->device_family != IWL_DEVICE_FAMILY_8000) max_section_size = IWL_MAX_NVM_SECTION_SIZE; - else if (CSR_HW_REV_STEP(mvm->trans->hw_rev) == SILICON_A_STEP) - max_section_size = IWL_MAX_NVM_8000A_SECTION_SIZE; - else /* Family 8000 B-step or C-step */ - max_section_size = IWL_MAX_NVM_8000B_SECTION_SIZE; + else + max_section_size = IWL_MAX_NVM_8000_SECTION_SIZE; /* * Obtain NVM image via request_firmware. Since we already used diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index a28080ead54f..91361be3ecd8 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c @@ -522,15 +522,10 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, min_backoff = calc_min_backoff(trans, cfg); iwl_mvm_tt_initialize(mvm, min_backoff); /* set the nvm_file_name according to priority */ - if (iwlwifi_mod_params.nvm_file) { + if (iwlwifi_mod_params.nvm_file) mvm->nvm_file_name = iwlwifi_mod_params.nvm_file; - } else { - if ((trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) && - (CSR_HW_REV_STEP(trans->hw_rev) == SILICON_A_STEP)) - mvm->nvm_file_name = mvm->cfg->default_nvm_file_8000A; - else - mvm->nvm_file_name = mvm->cfg->default_nvm_file; - } + else + mvm->nvm_file_name = mvm->cfg->default_nvm_file; if (WARN(cfg->no_power_up_nic_in_init && !mvm->nvm_file_name, "not allowing power-up and not having nvm_file\n")) diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 39e3cf06e364..d8984fbb1f0d 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -719,10 +719,10 @@ static int iwl_pcie_rsa_race_bug_wa(struct iwl_trans *trans) return -EIO; } -static int iwl_pcie_load_cpu_sections_8000b(struct iwl_trans *trans, - const struct fw_img *image, - int cpu, - int *first_ucode_section) +static int iwl_pcie_load_cpu_sections_8000(struct iwl_trans *trans, + const struct fw_img *image, + int cpu, + int *first_ucode_section) { int shift_param; int i, ret = 0, sec_num = 0x1; @@ -917,16 +917,13 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans, } /* release CPU reset */ - if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) - iwl_write_prph(trans, RELEASE_CPU_RESET, RELEASE_CPU_RESET_BIT); - else - iwl_write32(trans, CSR_RESET, 0); + iwl_write32(trans, CSR_RESET, 0); return 0; } -static int iwl_pcie_load_given_ucode_8000b(struct iwl_trans *trans, - const struct fw_img *image) +static int iwl_pcie_load_given_ucode_8000(struct iwl_trans *trans, + const struct fw_img *image) { int ret = 0; int first_ucode_section; @@ -947,14 +944,14 @@ static int iwl_pcie_load_given_ucode_8000b(struct iwl_trans *trans, iwl_write_prph(trans, RELEASE_CPU_RESET, RELEASE_CPU_RESET_BIT); /* load to FW the binary Secured sections of CPU1 */ - ret = iwl_pcie_load_cpu_sections_8000b(trans, image, 1, - &first_ucode_section); + ret = iwl_pcie_load_cpu_sections_8000(trans, image, 1, + &first_ucode_section); if (ret) return ret; /* load to FW the binary sections of CPU2 */ - ret = iwl_pcie_load_cpu_sections_8000b(trans, image, 2, - &first_ucode_section); + ret = iwl_pcie_load_cpu_sections_8000(trans, image, 2, + &first_ucode_section); if (ret) return ret; @@ -1007,9 +1004,8 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); /* Load the given image to the HW */ - if ((trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) && - (CSR_HW_REV_STEP(trans->hw_rev) != SILICON_A_STEP)) - return iwl_pcie_load_given_ucode_8000b(trans, fw); + if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) + return iwl_pcie_load_given_ucode_8000(trans, fw); else return iwl_pcie_load_given_ucode(trans, fw); } -- 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') 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 1e16707166caf7499e9e3decc403267d346a5fb7 Mon Sep 17 00:00:00 2001 From: Eran Harary Date: Thu, 19 Mar 2015 13:01:07 +0200 Subject: iwlwifi: mvm: fix debug print in the RSA ownership workaround The semaphore may not be accessible. Fix the debug prints accordingly. Signed-off-by: Eran Harary Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/pcie/trans.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers/net/wireless/iwlwifi') diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index d8984fbb1f0d..2de8fbfe4edf 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -691,11 +691,15 @@ static int iwl_pcie_rsa_race_bug_wa(struct iwl_trans *trans) { u32 val, loop = 1000; - /* Check the RSA semaphore is accessible - if not, we are in trouble */ + /* + * Check the RSA semaphore is accessible. + * If the HW isn't locked and the rsa semaphore isn't accessible, + * we are in trouble. + */ val = iwl_read_prph(trans, PREG_AUX_BUS_WPROT_0); if (val & (BIT(1) | BIT(17))) { - IWL_ERR(trans, - "can't access the RSA semaphore it is write protected\n"); + IWL_INFO(trans, + "can't access the RSA semaphore it is write protected\n"); return 0; } -- cgit v1.2.3 From d383c7409171452aaa6569f1451f9975d44f3d76 Mon Sep 17 00:00:00 2001 From: Eran Harary Date: Tue, 24 Mar 2015 10:59:46 +0200 Subject: iwlwifi: 8000: change PNVM in case it doesn't match to the HW step There is a strong relationship between the NVM version and the hardware step. Enforce that in the driver in case the default NVM on the platform is the wrong one. Signed-off-by: Eran Harary Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/iwl-8000.c | 9 +++++--- drivers/net/wireless/iwlwifi/iwl-config.h | 3 ++- drivers/net/wireless/iwlwifi/mvm/nvm.c | 34 ++++++++++++++++++++++++++++--- drivers/net/wireless/iwlwifi/mvm/ops.c | 10 ++++++--- 4 files changed, 46 insertions(+), 10 deletions(-) (limited to 'drivers/net/wireless/iwlwifi') diff --git a/drivers/net/wireless/iwlwifi/iwl-8000.c b/drivers/net/wireless/iwlwifi/iwl-8000.c index 4ef50cf7d9a6..ce6321b7d241 100644 --- a/drivers/net/wireless/iwlwifi/iwl-8000.c +++ b/drivers/net/wireless/iwlwifi/iwl-8000.c @@ -94,7 +94,8 @@ IWL8000_FW_PRE "-" __stringify(api) ".ucode" #define NVM_HW_SECTION_NUM_FAMILY_8000 10 -#define DEFAULT_NVM_FILE_FAMILY_8000 "iwl_nvm_8000B.bin" +#define DEFAULT_NVM_FILE_FAMILY_8000B "nvmData-8000B" +#define DEFAULT_NVM_FILE_FAMILY_8000C "nvmData-8000C" /* Max SDIO RX aggregation size of the ADDBA request/response */ #define MAX_RX_AGG_SIZE_8260_SDIO 28 @@ -176,7 +177,8 @@ const struct iwl_cfg iwl8260_2ac_sdio_cfg = { .ht_params = &iwl8000_ht_params, .nvm_ver = IWL8000_NVM_VERSION, .nvm_calib_ver = IWL8000_TX_POWER_VERSION, - .default_nvm_file = DEFAULT_NVM_FILE_FAMILY_8000, + .default_nvm_file_B_step = DEFAULT_NVM_FILE_FAMILY_8000B, + .default_nvm_file_C_step = DEFAULT_NVM_FILE_FAMILY_8000C, .max_rx_agg_size = MAX_RX_AGG_SIZE_8260_SDIO, .disable_dummy_notification = true, .max_ht_ampdu_exponent = MAX_HT_AMPDU_EXPONENT_8260_SDIO, @@ -190,7 +192,8 @@ const struct iwl_cfg iwl4165_2ac_sdio_cfg = { .ht_params = &iwl8000_ht_params, .nvm_ver = IWL8000_NVM_VERSION, .nvm_calib_ver = IWL8000_TX_POWER_VERSION, - .default_nvm_file = DEFAULT_NVM_FILE_FAMILY_8000, + .default_nvm_file_B_step = DEFAULT_NVM_FILE_FAMILY_8000B, + .default_nvm_file_C_step = DEFAULT_NVM_FILE_FAMILY_8000C, .max_rx_agg_size = MAX_RX_AGG_SIZE_8260_SDIO, .bt_shared_single_ant = true, .disable_dummy_notification = true, diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h index aa41c778af83..bbed8fc010ce 100644 --- a/drivers/net/wireless/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/iwlwifi/iwl-config.h @@ -303,7 +303,8 @@ struct iwl_cfg { bool lp_xtal_workaround; const struct iwl_pwr_tx_backoff *pwr_tx_backoffs; bool no_power_up_nic_in_init; - const char *default_nvm_file; + const char *default_nvm_file_B_step; + const char *default_nvm_file_C_step; unsigned int max_rx_agg_size; bool disable_dummy_notification; unsigned int max_tx_agg_size; diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c index 675197d9f03e..524ade241418 100644 --- a/drivers/net/wireless/iwlwifi/mvm/nvm.c +++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c @@ -418,6 +418,15 @@ static int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm) IWL_INFO(mvm, "NVM Version %08X\n", le32_to_cpu(dword_buff[2])); IWL_INFO(mvm, "NVM Manufacturing date %08X\n", le32_to_cpu(dword_buff[3])); + + /* nvm file validation, dword_buff[2] holds the file version */ + if ((CSR_HW_REV_STEP(mvm->trans->hw_rev) == SILICON_C_STEP && + le32_to_cpu(dword_buff[2]) < 0xE4A) || + (CSR_HW_REV_STEP(mvm->trans->hw_rev) == SILICON_B_STEP && + le32_to_cpu(dword_buff[2]) >= 0xE4A)) { + ret = -EFAULT; + goto out; + } } else { file_sec = (void *)fw_entry->data; } @@ -516,6 +525,8 @@ int iwl_nvm_init(struct iwl_mvm *mvm, bool read_nvm_from_nic) int ret, section; u32 size_read = 0; u8 *nvm_buffer, *temp; + const char *nvm_file_B = mvm->cfg->default_nvm_file_B_step; + const char *nvm_file_C = mvm->cfg->default_nvm_file_C_step; if (WARN_ON_ONCE(mvm->cfg->nvm_hw_section_num >= NVM_MAX_NUM_SECTIONS)) return -EINVAL; @@ -574,10 +585,27 @@ int iwl_nvm_init(struct iwl_mvm *mvm, bool read_nvm_from_nic) /* load external NVM if configured */ if (mvm->nvm_file_name) { - /* move to External NVM flow */ + /* read External NVM file - take the default */ ret = iwl_mvm_read_external_nvm(mvm); - if (ret) - return ret; + if (ret) { + /* choose the nvm_file name according to the + * HW step + */ + if (CSR_HW_REV_STEP(mvm->trans->hw_rev) == + SILICON_B_STEP) + mvm->nvm_file_name = nvm_file_B; + else + mvm->nvm_file_name = nvm_file_C; + + if (ret == -EFAULT && mvm->nvm_file_name) { + /* in case nvm file was failed try again */ + ret = iwl_mvm_read_external_nvm(mvm); + if (ret) + return ret; + } else { + return ret; + } + } } /* parse the relevant nvm sections */ diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index 388886ce419d..67ed57e17dab 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c @@ -521,10 +521,14 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, min_backoff = calc_min_backoff(trans, cfg); iwl_mvm_tt_initialize(mvm, min_backoff); /* set the nvm_file_name according to priority */ - if (iwlwifi_mod_params.nvm_file) + if (iwlwifi_mod_params.nvm_file) { mvm->nvm_file_name = iwlwifi_mod_params.nvm_file; - else - mvm->nvm_file_name = mvm->cfg->default_nvm_file; + } else if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) { + if (CSR_HW_REV_STEP(trans->hw_rev) == SILICON_B_STEP) + mvm->nvm_file_name = mvm->cfg->default_nvm_file_B_step; + else + mvm->nvm_file_name = mvm->cfg->default_nvm_file_C_step; + } if (WARN(cfg->no_power_up_nic_in_init && !mvm->nvm_file_name, "not allowing power-up and not having nvm_file\n")) -- cgit v1.2.3 From 963221bea4b46b175d51329c63dd6f16601d411b Mon Sep 17 00:00:00 2001 From: Alexander Bondar Date: Thu, 26 Mar 2015 11:07:35 +0200 Subject: iwlwifi: mvm: Clean up UMAC scan UIDs in the reset and drv_stop flows In the reset flow, the driver cancels ongoing scan and sends scan complete notification to mac80211. However it does not clean its UID. Add cleaning scan UID for the ongoing scan. Loop over all other UIDs to make sure there's nothing left there and warn if any is found. Signed-off-by: Alexander Bondar Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 14 +++++++++++ drivers/net/wireless/iwlwifi/mvm/scan.c | 37 ++++++++++++++++++++++++++--- 2 files changed, 48 insertions(+), 3 deletions(-) (limited to 'drivers/net/wireless/iwlwifi') diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 213bd72bd849..07344e11ce0a 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -1413,6 +1413,20 @@ void __iwl_mvm_mac_stop(struct iwl_mvm *mvm) */ clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status); + /* We shouldn't have any UIDs still set. Loop over all the UIDs to + * make sure there's nothing left there and warn if any is found. + */ + if (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN) { + int i; + + for (i = 0; i < IWL_MVM_MAX_SIMULTANEOUS_SCANS; i++) { + if (WARN_ONCE(mvm->scan_uid[i], + "UMAC scan UID %d was not cleaned\n", + mvm->scan_uid[i])) + mvm->scan_uid[i] = 0; + } + } + mvm->ucode_loaded = false; } diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c index 2997864fb13f..74e1c86289dc 100644 --- a/drivers/net/wireless/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/iwlwifi/mvm/scan.c @@ -1179,6 +1179,18 @@ static bool iwl_mvm_find_scan_type(struct iwl_mvm *mvm, return false; } +static int iwl_mvm_find_first_scan(struct iwl_mvm *mvm, + enum iwl_umac_scan_uid_type type) +{ + int i; + + for (i = 0; i < IWL_MVM_MAX_SIMULTANEOUS_SCANS; i++) + if (mvm->scan_uid[i] & type) + return i; + + return i; +} + static u32 iwl_generate_scan_uid(struct iwl_mvm *mvm, enum iwl_umac_scan_uid_type type) { @@ -1629,11 +1641,30 @@ int iwl_mvm_scan_size(struct iwl_mvm *mvm) void iwl_mvm_report_scan_aborted(struct iwl_mvm *mvm) { if (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN) { - if (iwl_mvm_find_scan_type(mvm, IWL_UMAC_SCAN_UID_REG_SCAN)) + u32 uid, i; + + uid = iwl_mvm_find_first_scan(mvm, IWL_UMAC_SCAN_UID_REG_SCAN); + if (uid < IWL_MVM_MAX_SIMULTANEOUS_SCANS) { ieee80211_scan_completed(mvm->hw, true); - if (iwl_mvm_find_scan_type(mvm, IWL_UMAC_SCAN_UID_SCHED_SCAN) && - !mvm->restart_fw) + mvm->scan_uid[uid] = 0; + } + uid = iwl_mvm_find_first_scan(mvm, + IWL_UMAC_SCAN_UID_SCHED_SCAN); + if (uid < IWL_MVM_MAX_SIMULTANEOUS_SCANS && !mvm->restart_fw) { ieee80211_sched_scan_stopped(mvm->hw); + mvm->scan_uid[uid] = 0; + } + + /* We shouldn't have any UIDs still set. Loop over all the + * UIDs to make sure there's nothing left there and warn if + * any is found. + */ + for (i = 0; i < IWL_MVM_MAX_SIMULTANEOUS_SCANS; i++) { + if (WARN_ONCE(mvm->scan_uid[i], + "UMAC scan UID %d was not cleaned\n", + mvm->scan_uid[i])) + mvm->scan_uid[i] = 0; + } } else { switch (mvm->scan_status) { case IWL_MVM_SCAN_NONE: -- cgit v1.2.3 From 90cb12372bf2779406bd0378195d8b5357a06dc3 Mon Sep 17 00:00:00 2001 From: Liad Kaufman Date: Sun, 29 Mar 2015 11:39:34 +0300 Subject: iwlwifi: mvm: rs: fix comment indentation Signed-off-by: Liad Kaufman Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/rs.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/net/wireless/iwlwifi') diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c index dd457df9601e..0388e04b9424 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/iwlwifi/mvm/rs.c @@ -1277,9 +1277,7 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta, info->status.ampdu_ack_len); } } else { - /* - * For legacy, update frame history with for each Tx retry. - */ + /* For legacy, update frame history with for each Tx retry. */ retries = info->status.rates[0].count - 1; /* HW doesn't send more than 15 retries */ retries = min(retries, 15); -- cgit v1.2.3 From 2841a2d3a1b4b4e5cd22851928087b664a4dafad Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 19 Mar 2015 23:14:06 +0200 Subject: iwlwifi: check the size of the trigger struct from the firmware file When we access the triggers we need to make sure that the data we expect was actually provided by the firmware file. Check this when we decode the triggers from the firmware file. Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/iwl-drv.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'drivers/net/wireless/iwlwifi') diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 885c78708639..b8e5690e5716 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c @@ -1102,6 +1102,7 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) const unsigned int api_max = drv->cfg->ucode_api_max; unsigned int api_ok = drv->cfg->ucode_api_ok; const unsigned int api_min = drv->cfg->ucode_api_min; + size_t trigger_tlv_sz[FW_DBG_TRIGGER_MAX]; u32 api_ver; int i; bool load_module = false; @@ -1221,8 +1222,35 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) } } + memset(&trigger_tlv_sz, 0xff, sizeof(trigger_tlv_sz)); + + trigger_tlv_sz[FW_DBG_TRIGGER_MISSED_BEACONS] = + sizeof(struct iwl_fw_dbg_trigger_missed_bcon); + trigger_tlv_sz[FW_DBG_TRIGGER_CHANNEL_SWITCH] = 0; + trigger_tlv_sz[FW_DBG_TRIGGER_FW_NOTIF] = + sizeof(struct iwl_fw_dbg_trigger_cmd); + trigger_tlv_sz[FW_DBG_TRIGGER_MLME] = + sizeof(struct iwl_fw_dbg_trigger_mlme); + trigger_tlv_sz[FW_DBG_TRIGGER_STATS] = + sizeof(struct iwl_fw_dbg_trigger_stats); + trigger_tlv_sz[FW_DBG_TRIGGER_RSSI] = + sizeof(struct iwl_fw_dbg_trigger_low_rssi); + trigger_tlv_sz[FW_DBG_TRIGGER_TXQ_TIMERS] = + sizeof(struct iwl_fw_dbg_trigger_txq_timer); + for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_trigger_tlv); i++) { if (pieces->dbg_trigger_tlv[i]) { + /* + * If the trigger isn't long enough, WARN and exit. + * Someone is trying to debug something and he won't + * be able to catch the bug he is trying to chase. + * We'd better be noisy to be sure he knows what's + * going on. + */ + if (WARN_ON(pieces->dbg_trigger_tlv_len[i] < + (trigger_tlv_sz[i] + + sizeof(struct iwl_fw_dbg_trigger_tlv)))) + goto out_free_fw; drv->fw.dbg_trigger_tlv_len[i] = pieces->dbg_trigger_tlv_len[i]; drv->fw.dbg_trigger_tlv[i] = -- cgit v1.2.3 From 7b9d74e44a9f504e22a505e36327a00dc301a968 Mon Sep 17 00:00:00 2001 From: Eyal Shapira Date: Sun, 29 Mar 2015 18:38:07 +0300 Subject: iwlwifi: mvm: rs: refactor rs_update_rate_tbl Minor cleanup and refactoring. Signed-off-by: Eyal Shapira Reviewed-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/rs.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers/net/wireless/iwlwifi') diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c index 0388e04b9424..e00b454c6c17 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/iwlwifi/mvm/rs.c @@ -1610,9 +1610,9 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search) static void rs_update_rate_tbl(struct iwl_mvm *mvm, struct ieee80211_sta *sta, struct iwl_lq_sta *lq_sta, - struct rs_rate *rate) + struct iwl_scale_tbl_info *tbl) { - rs_fill_lq_cmd(mvm, sta, lq_sta, rate); + rs_fill_lq_cmd(mvm, sta, lq_sta, &tbl->rate); iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, false); } @@ -2142,7 +2142,7 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm, rate->type = LQ_NONE; lq_sta->search_better_tbl = 0; tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); - rs_update_rate_tbl(mvm, sta, lq_sta, &tbl->rate); + rs_update_rate_tbl(mvm, sta, lq_sta, tbl); } return; } @@ -2305,7 +2305,7 @@ lq_update: /* Replace uCode's rate table for the destination station. */ if (update_lq) { tbl->rate.index = index; - rs_update_rate_tbl(mvm, sta, lq_sta, &tbl->rate); + rs_update_rate_tbl(mvm, sta, lq_sta, tbl); } rs_stay_in_table(lq_sta, false); @@ -2352,8 +2352,7 @@ lq_update: rs_dump_rate(mvm, &tbl->rate, "Switch to SEARCH TABLE:"); - rs_fill_lq_cmd(mvm, sta, lq_sta, &tbl->rate); - iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, false); + rs_update_rate_tbl(mvm, sta, lq_sta, tbl); } else { done_search = 1; } -- cgit v1.2.3 From 484b3d13b4ac3d721f3479433ad82100e1277580 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Mon, 30 Mar 2015 20:46:32 +0300 Subject: iwlwifi: mvm: add debugfs entry with the number of net-detect scans Our testers need to know the number of scans performed while in net-detect mode before the device wakes up. The firmware already passes this information to the driver, so we can save it and report it in a debugfs entry. Signed-off-by: Luciano Coelho Reviewed-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/d3.c | 4 ++++ drivers/net/wireless/iwlwifi/mvm/debugfs.c | 3 +++ drivers/net/wireless/iwlwifi/mvm/mvm.h | 1 + 3 files changed, 8 insertions(+) (limited to 'drivers/net/wireless/iwlwifi') diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c index e730ea2b0812..a6c48c7b1e16 100644 --- a/drivers/net/wireless/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/iwlwifi/mvm/d3.c @@ -1726,6 +1726,10 @@ iwl_mvm_netdetect_query_results(struct iwl_mvm *mvm, results->matched_profiles = le32_to_cpu(query->matched_profiles); memcpy(results->matches, query->matches, sizeof(results->matches)); +#ifdef CPTCFG_IWLWIFI_DEBUGFS + mvm->last_netdetect_scans = le32_to_cpu(query->n_scans_done); +#endif + out_free_resp: iwl_free_resp(&cmd); return ret; diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c index 01b97a0c88dc..9ac04c1ea706 100644 --- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c @@ -1569,6 +1569,9 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) if (!debugfs_create_bool("d3_wake_sysassert", S_IRUSR | S_IWUSR, mvm->debugfs_dir, &mvm->d3_wake_sysassert)) goto err; + if (!debugfs_create_u32("last_netdetect_scans", S_IRUSR, + mvm->debugfs_dir, &mvm->last_netdetect_scans)) + goto err; MVM_DEBUGFS_ADD_FILE(netdetect, mvm->debugfs_dir, S_IRUSR | S_IWUSR); #endif diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 3513f27c888f..a3f2078e8dcd 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -748,6 +748,7 @@ struct iwl_mvm { void *d3_resume_sram; u32 d3_test_pme_ptr; struct ieee80211_vif *keep_vif; + u32 last_netdetect_scans; /* no. of scans in the last net-detect wake */ #endif #endif -- cgit v1.2.3 From b6e160ab15c203fe77d13a121081b1a9bce7cbfe Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Mon, 23 Mar 2015 14:32:53 +0200 Subject: iwlwifi: mvm: always reconfigure last MCC on init Currently the last found MCC is reconfigured only in the recovery flow. But it should always be used when available, for the ifdown/up or RF-Kill/CT-Kill scenarios. While at it, fix a couple of bugs in the init-from-last-MCC flow. Return an error value when a current MCC is not found. Pass on the regdomain to cfg80211 only if it was changed and don't ignore the return value from the cfg80211-setter function. Signed-off-by: Arik Nemtsov Reviewed-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 17 ++++++++++++----- drivers/net/wireless/iwlwifi/mvm/nvm.c | 9 ++++----- 2 files changed, 16 insertions(+), 10 deletions(-) (limited to 'drivers/net/wireless/iwlwifi') diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 07344e11ce0a..0dd999ceed36 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -379,11 +379,13 @@ int iwl_mvm_init_fw_regd(struct iwl_mvm *mvm) { enum iwl_mcc_source used_src; struct ieee80211_regdomain *regd; + int ret; + bool changed; const struct ieee80211_regdomain *r = rtnl_dereference(mvm->hw->wiphy->regd); if (!r) - return 0; + return -ENOENT; /* save the last source in case we overwrite it below */ used_src = mvm->mcc_src; @@ -395,14 +397,19 @@ int iwl_mvm_init_fw_regd(struct iwl_mvm *mvm) } /* Now set our last stored MCC and source */ - regd = iwl_mvm_get_regdomain(mvm->hw->wiphy, r->alpha2, used_src, NULL); + regd = iwl_mvm_get_regdomain(mvm->hw->wiphy, r->alpha2, used_src, + &changed); if (IS_ERR_OR_NULL(regd)) return -EIO; - regulatory_set_wiphy_regd(mvm->hw->wiphy, regd); - kfree(regd); + /* update cfg80211 if the regdomain was changed */ + if (changed) + ret = regulatory_set_wiphy_regd_sync_rtnl(mvm->hw->wiphy, regd); + else + ret = 0; - return 0; + kfree(regd); + return ret; } int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c index 524ade241418..87b2a30a2308 100644 --- a/drivers/net/wireless/iwlwifi/mvm/nvm.c +++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c @@ -806,13 +806,12 @@ int iwl_mvm_init_mcc(struct iwl_mvm *mvm) return 0; /* - * During HW restart, only replay the last set MCC to FW. Otherwise, + * try to replay the last set MCC to FW. If it doesn't exist, * queue an update to cfg80211 to retrieve the default alpha2 from FW. */ - if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) { - /* This should only be called during vif up and hold RTNL */ - return iwl_mvm_init_fw_regd(mvm); - } + retval = iwl_mvm_init_fw_regd(mvm); + if (retval != -ENOENT) + return retval; /* * Driver regulatory hint for initial update, this also informs the -- cgit v1.2.3 From 6ed13164450a916116cf7f0f38fe0da4679a45c9 Mon Sep 17 00:00:00 2001 From: Matti Gottlieb Date: Mon, 30 Mar 2015 16:50:07 +0300 Subject: iwlwifi: mvm: Fix wrongfully flushing frames in the roc/off channel queue Sending multiple action frames off channel, one after the other can create a race that will result in a timeout: 1. Start sending action frame off channel. 2. Once the frame is sent or the time event is over, the flow will eventually call ieee80211_start_next_roc to start the next roc frame & iwl_mvm_roc_finished schedules to schedule a work to flush the queue. 3. Start sending new roc frame and write it to the queue before the flush work has started. 4. The work is called and it flushes the new packet that was placed on the on the queue so the packet is lost. This causes the frame to be removed & not sent, that causes a timeout in userspace. Flush the work queue that flushes the roc/off channel queue before starting to send a new frame off channel, in order to avoid a race between the new frame that is transmitted off channel & the flushing of the queue. Signed-off-by: Matti Gottlieb Reviewed-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/net/wireless/iwlwifi') diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 0dd999ceed36..0bd3373315ec 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -3080,6 +3080,8 @@ static int iwl_mvm_roc(struct ieee80211_hw *hw, IWL_DEBUG_MAC80211(mvm, "enter (%d, %d, %d)\n", channel->hw_value, duration, type); + flush_work(&mvm->roc_done_wk); + mutex_lock(&mvm->mutex); switch (vif->type) { -- cgit v1.2.3 From 21023b1e7f9862015fd8c91d5619217da8d9a06a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 31 Mar 2015 08:58:16 +0200 Subject: iwlwifi: mvm: remove unused arguments The str/len arguments to iwl_fw_dbg_trigger_simple_stop() aren't used, and for a simple trigger don't really need to be used as the trigger code itself encodes the reason, so remove them. Signed-off-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 3 +-- drivers/net/wireless/iwlwifi/mvm/mvm.h | 5 ++--- 2 files changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers/net/wireless/iwlwifi') diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 0bd3373315ec..810b6d317b24 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -3711,8 +3711,7 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw, IWL_DEBUG_MAC80211(mvm, "pre CSA to freq %d\n", chsw->chandef.center_freq1); - iwl_fw_dbg_trigger_simple_stop(mvm, vif, FW_DBG_TRIGGER_CHANNEL_SWITCH, - NULL, 0); + iwl_fw_dbg_trigger_simple_stop(mvm, vif, FW_DBG_TRIGGER_CHANNEL_SWITCH); switch (vif->type) { case NL80211_IFTYPE_AP: diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index a3f2078e8dcd..500064f5d8f1 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -1516,8 +1516,7 @@ iwl_fw_dbg_trigger_check_stop(struct iwl_mvm *mvm, static inline void iwl_fw_dbg_trigger_simple_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif, - enum iwl_fw_dbg_trigger trig, - const char *str, size_t len) + enum iwl_fw_dbg_trigger trig) { struct iwl_fw_dbg_trigger_tlv *trigger; @@ -1528,7 +1527,7 @@ iwl_fw_dbg_trigger_simple_stop(struct iwl_mvm *mvm, if (!iwl_fw_dbg_trigger_check_stop(mvm, vif, trigger)) return; - iwl_mvm_fw_dbg_collect_trig(mvm, trigger, str, len); + iwl_mvm_fw_dbg_collect_trig(mvm, trigger, NULL, 0); } #endif /* __IWL_MVM_H__ */ -- cgit v1.2.3 From d42f53503406d5dcedbad9ea18c964f189f72d84 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 10 Feb 2015 14:29:48 +0200 Subject: iwlwifi: mvm: add trigger for firmware dump upon MLME failures This will allow to catch failures in MLME and get the firmware data when this happens. Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h | 4 +- drivers/net/wireless/iwlwifi/iwl-fw-file.h | 35 +++++++++++++ drivers/net/wireless/iwlwifi/mvm/mac80211.c | 65 ++++++++++++++++++++++++ 3 files changed, 102 insertions(+), 2 deletions(-) (limited to 'drivers/net/wireless/iwlwifi') diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h b/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h index 46cbae8f821d..8b926ece0d3a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h @@ -246,7 +246,7 @@ iwl_fw_error_next_data(struct iwl_fw_error_dump_data *data) * @FW_DBG_TRIGGER_CHANNEL_SWITCH: trigger log collection upon channel switch. * @FW_DBG_TRIGGER_FW_NOTIF: trigger log collection when the firmware sends a * command response or a notification. - * @FW_DB_TRIGGER_RESERVED: reserved + * @FW_DBG_TRIGGER_MLME: trigger log collection upon MLME event. * @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. @@ -260,7 +260,7 @@ enum iwl_fw_dbg_trigger { FW_DBG_TRIGGER_MISSED_BEACONS, FW_DBG_TRIGGER_CHANNEL_SWITCH, FW_DBG_TRIGGER_FW_NOTIF, - FW_DB_TRIGGER_RESERVED, + FW_DBG_TRIGGER_MLME, FW_DBG_TRIGGER_STATS, FW_DBG_TRIGGER_RSSI, FW_DBG_TRIGGER_TXQ_TIMERS, diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h index 0cfc66d1aef2..823938e3b7ef 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h @@ -578,6 +578,41 @@ struct iwl_fw_dbg_trigger_low_rssi { __le32 rssi; } __packed; +/** + * struct iwl_fw_dbg_trigger_mlme - configures trigger for mlme events + * @stop_auth_denied: number of denied authentication to collect + * @stop_auth_timeout: number of authentication timeout to collect + * @stop_rx_deauth: number of Rx deauth before to collect + * @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 + * @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 + */ +struct iwl_fw_dbg_trigger_mlme { + u8 stop_auth_denied; + u8 stop_auth_timeout; + u8 stop_rx_deauth; + u8 stop_tx_deauth; + + u8 stop_assoc_denied; + u8 stop_assoc_timeout; + __le16 reserved2; + + u8 start_auth_denied; + u8 start_auth_timeout; + u8 start_rx_deauth; + u8 start_tx_deauth; + + u8 start_assoc_denied; + u8 start_assoc_timeout; + __le16 reserved4; +} __packed; + /** * struct iwl_fw_dbg_trigger_txq_timer - configures the Tx queue's timer * @command_queue: timeout for the command queue in ms diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 810b6d317b24..fc73cc1bda0d 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -3956,6 +3956,69 @@ static void iwl_mvm_mac_sta_statistics(struct ieee80211_hw *hw, mutex_unlock(&mvm->mutex); } +static void iwl_mvm_mac_event_callback(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + const struct ieee80211_event *event) +{ +#define CHECK_MLME_TRIGGER(_mvm, _trig, _buf, _cnt, _str...) \ + do { \ + if ((_cnt) && --(_cnt)) \ + break; \ + snprintf(_buf, sizeof(_buf), ##_str); \ + iwl_mvm_fw_dbg_collect_trig(_mvm, _trig, _buf, \ + sizeof(_buf)); \ + } while (0) + + struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); + struct iwl_fw_dbg_trigger_tlv *trig; + struct iwl_fw_dbg_trigger_mlme *trig_mlme; + char buf[32]; + + if (!iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_MLME)) + return; + + if (event->u.mlme.status == MLME_SUCCESS) + return; + + 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)) + return; + + memset(buf, 0, sizeof(buf)); + + if (event->u.mlme.data == ASSOC_EVENT) { + if (event->u.mlme.status == MLME_DENIED) + CHECK_MLME_TRIGGER(mvm, trig, buf, + trig_mlme->stop_assoc_denied, + "DENIED ASSOC: reason %d", + event->u.mlme.reason); + else if (event->u.mlme.status == MLME_TIMEOUT) + CHECK_MLME_TRIGGER(mvm, trig, buf, + trig_mlme->stop_assoc_timeout, + "ASSOC TIMEOUT"); + } else if (event->u.mlme.data == AUTH_EVENT) { + if (event->u.mlme.status == MLME_DENIED) + CHECK_MLME_TRIGGER(mvm, trig, buf, + trig_mlme->stop_auth_denied, + "DENIED AUTH: reason %d", + event->u.mlme.reason); + else if (event->u.mlme.status == MLME_TIMEOUT) + CHECK_MLME_TRIGGER(mvm, trig, buf, + trig_mlme->stop_auth_timeout, + "AUTH TIMEOUT"); + } else if (event->u.mlme.data == DEAUTH_RX_EVENT) { + CHECK_MLME_TRIGGER(mvm, trig, buf, + trig_mlme->stop_rx_deauth, + "DEAUTH RX %d", event->u.mlme.reason); + } else if (event->u.mlme.data == DEAUTH_TX_EVENT) { + CHECK_MLME_TRIGGER(mvm, trig, buf, + trig_mlme->stop_tx_deauth, + "DEAUTH TX %d", event->u.mlme.reason); + } +#undef CHECK_MLME_TRIGGER +} + const struct ieee80211_ops iwl_mvm_hw_ops = { .tx = iwl_mvm_mac_tx, .ampdu_action = iwl_mvm_mac_ampdu_action, @@ -4009,6 +4072,8 @@ const struct ieee80211_ops iwl_mvm_hw_ops = { .tdls_cancel_channel_switch = iwl_mvm_tdls_cancel_channel_switch, .tdls_recv_channel_switch = iwl_mvm_tdls_recv_channel_switch, + .event_callback = iwl_mvm_mac_event_callback, + CFG80211_TESTMODE_CMD(iwl_mvm_mac_testmode_cmd) #ifdef CONFIG_PM_SLEEP -- cgit v1.2.3 From 10a7c028dbf9920ba6781bf1adde1811dc50de86 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 1 Apr 2015 10:00:31 +0200 Subject: iwlwifi: mvm: don't return uninitialized value in get_survey() If ucode_loaded isn't true the function returns the 'ret' variable without having assigned a value properly. Fix that. Reported-by: Haim Dreyfuss Signed-off-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net/wireless/iwlwifi') diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index fc73cc1bda0d..74912e7fd3b2 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -3911,6 +3911,7 @@ static int iwl_mvm_mac_get_survey(struct ieee80211_hw *hw, int idx, mvm->radio_stats.on_time_scan; do_div(survey->time_scan, USEC_PER_MSEC); + ret = 0; out: mutex_unlock(&mvm->mutex); return ret; -- 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') 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 5d4f929e3d0c09838677a116ffd168d9d519ada7 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 31 Mar 2015 09:12:54 +0200 Subject: iwlwifi: mvm: do string formatting in debug triggers The current code has a lot of duplicates of printing into a buffer (while having to make sure it's NUL-filled and -terminated) and then passing that to the debug trigger collection. Since that's error-prone, instead make the debug trigger collection function take a format string and format arguments (with compiler validity checking) and handle the buffer internally. This makes one behavioural change -- instead of sending the whole buffer to userspace (clearing is needed to not leak stack data) it just passes the actual string (including NUL-terminator.) Signed-off-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/fw.c | 23 ++++++++++++++++++++--- drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c | 2 +- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 9 ++------- drivers/net/wireless/iwlwifi/mvm/mvm.h | 4 ++-- drivers/net/wireless/iwlwifi/mvm/ops.c | 7 +++---- drivers/net/wireless/iwlwifi/mvm/rx.c | 4 ++-- 6 files changed, 30 insertions(+), 19 deletions(-) (limited to 'drivers/net/wireless/iwlwifi') diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c index 6cf7d9837ca5..bc5eac4960e1 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/iwlwifi/mvm/fw.c @@ -526,16 +526,33 @@ int iwl_mvm_fw_dbg_collect(struct iwl_mvm *mvm, enum iwl_fw_dbg_trigger trig, int iwl_mvm_fw_dbg_collect_trig(struct iwl_mvm *mvm, struct iwl_fw_dbg_trigger_tlv *trigger, - const char *str, size_t len) + const char *fmt, ...) { unsigned int delay = msecs_to_jiffies(le32_to_cpu(trigger->stop_delay)); u16 occurrences = le16_to_cpu(trigger->occurrences); - int ret; + int ret, len = 0; + char buf[64]; if (!occurrences) return 0; - ret = iwl_mvm_fw_dbg_collect(mvm, le32_to_cpu(trigger->id), str, + if (fmt) { + va_list ap; + + buf[sizeof(buf) - 1] = '\0'; + + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + + /* check for truncation */ + if (WARN_ON_ONCE(buf[sizeof(buf) - 1])) + buf[sizeof(buf) - 1] = '\0'; + + len = strlen(buf) + 1; + } + + ret = iwl_mvm_fw_dbg_collect(mvm, le32_to_cpu(trigger->id), buf, len, delay); if (ret) return ret; diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c index 09f0124db76e..8088c7137f7c 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c @@ -1412,7 +1412,7 @@ static void iwl_mvm_beacon_loss_iterator(void *_data, u8 *mac, if (rx_missed_bcon_since_rx >= stop_trig_missed_bcon_since_rx || rx_missed_bcon >= stop_trig_missed_bcon) - iwl_mvm_fw_dbg_collect_trig(mvm, trigger, NULL, 0); + iwl_mvm_fw_dbg_collect_trig(mvm, trigger, NULL); } int iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm, diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 74912e7fd3b2..84555170b6f7 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -3961,19 +3961,16 @@ static void iwl_mvm_mac_event_callback(struct ieee80211_hw *hw, struct ieee80211_vif *vif, const struct ieee80211_event *event) { -#define CHECK_MLME_TRIGGER(_mvm, _trig, _buf, _cnt, _str...) \ +#define CHECK_MLME_TRIGGER(_mvm, _trig, _buf, _cnt, _fmt...) \ do { \ if ((_cnt) && --(_cnt)) \ break; \ - snprintf(_buf, sizeof(_buf), ##_str); \ - iwl_mvm_fw_dbg_collect_trig(_mvm, _trig, _buf, \ - sizeof(_buf)); \ + iwl_mvm_fw_dbg_collect_trig(_mvm, _trig, _fmt);\ } while (0) struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); struct iwl_fw_dbg_trigger_tlv *trig; struct iwl_fw_dbg_trigger_mlme *trig_mlme; - char buf[32]; if (!iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_MLME)) return; @@ -3986,8 +3983,6 @@ static void iwl_mvm_mac_event_callback(struct ieee80211_hw *hw, if (!iwl_fw_dbg_trigger_check_stop(mvm, vif, trig)) return; - memset(buf, 0, sizeof(buf)); - if (event->u.mlme.data == ASSOC_EVENT) { if (event->u.mlme.status == MLME_DENIED) CHECK_MLME_TRIGGER(mvm, trig, buf, diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 629b8c7da478..ef78ebc23a0f 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -1480,7 +1480,7 @@ int iwl_mvm_fw_dbg_collect_desc(struct iwl_mvm *mvm, 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); + const char *fmt, ...) __printf(3, 4); unsigned int iwl_mvm_get_wd_timeout(struct iwl_mvm *mvm, struct ieee80211_vif *vif, bool tdls, bool cmd_q); @@ -1527,7 +1527,7 @@ iwl_fw_dbg_trigger_simple_stop(struct iwl_mvm *mvm, if (!iwl_fw_dbg_trigger_check_stop(mvm, vif, trigger)) return; - iwl_mvm_fw_dbg_collect_trig(mvm, trigger, NULL, 0); + iwl_mvm_fw_dbg_collect_trig(mvm, trigger, NULL); } #endif /* __IWL_MVM_H__ */ diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index 67ed57e17dab..e656511bdbec 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c @@ -689,7 +689,6 @@ static inline void iwl_mvm_rx_check_trigger(struct iwl_mvm *mvm, { struct iwl_fw_dbg_trigger_tlv *trig; struct iwl_fw_dbg_trigger_cmd *cmds_trig; - char buf[32]; int i; if (!iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_FW_NOTIF)) @@ -709,9 +708,9 @@ static inline void iwl_mvm_rx_check_trigger(struct iwl_mvm *mvm, if (cmds_trig->cmds[i].cmd_id != pkt->hdr.cmd) continue; - memset(buf, 0, sizeof(buf)); - snprintf(buf, sizeof(buf), "CMD 0x%02x received", pkt->hdr.cmd); - iwl_mvm_fw_dbg_collect_trig(mvm, trig, buf, sizeof(buf)); + iwl_mvm_fw_dbg_collect_trig(mvm, trig, + "CMD 0x%02x received", + pkt->hdr.cmd); break; } } diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c index 6177e24f4c01..78ec7db64ba5 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rx.c +++ b/drivers/net/wireless/iwlwifi/mvm/rx.c @@ -362,7 +362,7 @@ int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, iwl_fw_dbg_trigger_check_stop(mvm, mvmsta->vif, trig); if (trig_check && rx_status->signal < rssi) - iwl_mvm_fw_dbg_collect_trig(mvm, trig, NULL, 0); + iwl_mvm_fw_dbg_collect_trig(mvm, trig, NULL); } } @@ -552,7 +552,7 @@ iwl_mvm_rx_stats_check_trigger(struct iwl_mvm *mvm, struct iwl_rx_packet *pkt) if (le32_to_cpup((__le32 *) (pkt->data + trig_offset)) < trig_thold) return; - iwl_mvm_fw_dbg_collect_trig(mvm, trig, NULL, 0); + iwl_mvm_fw_dbg_collect_trig(mvm, trig, NULL); } void iwl_mvm_handle_rx_statistics(struct iwl_mvm *mvm, -- cgit v1.2.3 From 874c174eb9950a62032a7c90c4a23947a2bb863d Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Wed, 25 Mar 2015 22:40:47 +0200 Subject: iwlwifi: mvm: add trigger for time events This will allow to collect data when a time event notifcation with a certain id and action is coming from the firmware. This can be very useful to debug various flows. Reviewed-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/iwl-drv.c | 2 ++ drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h | 3 ++ drivers/net/wireless/iwlwifi/iwl-fw-file.h | 16 +++++++++ drivers/net/wireless/iwlwifi/mvm/time-event.c | 42 ++++++++++++++++++++++++ 4 files changed, 63 insertions(+) (limited to 'drivers/net/wireless/iwlwifi') diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 7783ac8761c4..e7475629c44e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c @@ -1237,6 +1237,8 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) sizeof(struct iwl_fw_dbg_trigger_low_rssi); trigger_tlv_sz[FW_DBG_TRIGGER_TXQ_TIMERS] = sizeof(struct iwl_fw_dbg_trigger_txq_timer); + trigger_tlv_sz[FW_DBG_TRIGGER_TIME_EVENT] = + sizeof(struct iwl_fw_dbg_trigger_time_event); for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_trigger_tlv); i++) { if (pieces->dbg_trigger_tlv[i]) { diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h b/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h index 37652857b8d0..251bf8dc4a12 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h @@ -252,6 +252,8 @@ iwl_fw_error_next_data(struct iwl_fw_error_dump_data *data) * goes below a threshold. * @FW_DBG_TRIGGER_TXQ_TIMERS: configures the timers for the Tx queue hang * detection. + * @FW_DBG_TRIGGER_TIME_EVENT: trigger log collection upon time events related + * events. */ enum iwl_fw_dbg_trigger { FW_DBG_TRIGGER_INVALID = 0, @@ -264,6 +266,7 @@ enum iwl_fw_dbg_trigger { FW_DBG_TRIGGER_STATS, FW_DBG_TRIGGER_RSSI, FW_DBG_TRIGGER_TXQ_TIMERS, + FW_DBG_TRIGGER_TIME_EVENT, /* 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 cc789cb3c052..ee149482061f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h @@ -636,6 +636,22 @@ struct iwl_fw_dbg_trigger_txq_timer { __le32 reserved[4]; } __packed; +/** + * struct iwl_fw_dbg_trigger_time_event - configures a time event trigger + * time_Events: a list of tuples . The driver will issue a + * trigger each time a time event notification that relates to time event + * id with one of the actions in the bitmap is received and + * BIT(notif->status) is set in status_bitmap. + * + */ +struct iwl_fw_dbg_trigger_time_event { + struct { + __le32 id; + __le32 action_bitmap; + __le32 status_bitmap; + } __packed time_events[16]; +} __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/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c index bd519597eb2d..647822366fe5 100644 --- a/drivers/net/wireless/iwlwifi/mvm/time-event.c +++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c @@ -226,6 +226,44 @@ iwl_mvm_te_handle_notify_csa(struct iwl_mvm *mvm, iwl_mvm_te_clear_data(mvm, te_data); } +static void iwl_mvm_te_check_trigger(struct iwl_mvm *mvm, + struct iwl_time_event_notif *notif, + struct iwl_mvm_time_event_data *te_data) +{ + struct iwl_fw_dbg_trigger_tlv *trig; + struct iwl_fw_dbg_trigger_time_event *te_trig; + int i; + + if (!iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_TIME_EVENT)) + return; + + trig = iwl_fw_dbg_get_trigger(mvm->fw, FW_DBG_TRIGGER_TIME_EVENT); + te_trig = (void *)trig->data; + + if (!iwl_fw_dbg_trigger_check_stop(mvm, te_data->vif, trig)) + return; + + for (i = 0; i < ARRAY_SIZE(te_trig->time_events); i++) { + u32 trig_te_id = le32_to_cpu(te_trig->time_events[i].id); + u32 trig_action_bitmap = + le32_to_cpu(te_trig->time_events[i].action_bitmap); + u32 trig_status_bitmap = + le32_to_cpu(te_trig->time_events[i].status_bitmap); + + if (trig_te_id != te_data->id || + !(trig_action_bitmap & le32_to_cpu(notif->action)) || + !(trig_status_bitmap & BIT(le32_to_cpu(notif->status)))) + continue; + + iwl_mvm_fw_dbg_collect_trig(mvm, trig, + "Time event %d Action 0x%x received status: %d", + te_data->id, + le32_to_cpu(notif->action), + le32_to_cpu(notif->status)); + break; + } +} + /* * Handles a FW notification for an event that is known to the driver. * @@ -243,6 +281,8 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm, le32_to_cpu(notif->unique_id), le32_to_cpu(notif->action)); + iwl_mvm_te_check_trigger(mvm, notif, te_data); + /* * The FW sends the start/end time event notifications even for events * that it fails to schedule. This is indicated in the status field of @@ -324,6 +364,8 @@ static int iwl_mvm_aux_roc_te_handle_notif(struct iwl_mvm *mvm, if (!aux_roc_te) /* Not a Aux ROC time event */ return -EINVAL; + iwl_mvm_te_check_trigger(mvm, notif, te_data); + if (!le32_to_cpu(notif->status)) { IWL_DEBUG_TE(mvm, "ERROR: Aux ROC Time Event %s notification failure\n", -- 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') 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