Second batch of fixes intended for 4.15.
* One fix in rate-scaling; * One fix for the TX queue hang detection for AP/GO modes; * Fix the TX queue hang timeout used in monitor interfaces; * Fix packet injection; * Remove a wrong error message when dumping PCI registers; * Fix race condition with RF-kill; -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEF3LNfgb2BPWm68smoUecoho8xfoFAlodVBwACgkQoUecoho8 xfpyOQ/9Eq3nDZDa5WTxh4IUMKD/MVJwWh/dPQuXqas+obGnRO3N2ETnZkvf/E2W NKwWh5WiptumChk6iwFm9vlWXAyW/olCPQ6jhGANGakjvJE6k1uPh/sW9MrLgjTM c80fYoMFR8+4bPp0ba/LyU7sKfbzzULwqu54fv0c8qnPm00WXOS4o1pquKi6FQYi J0Alm4Q7lCkITUhmegRZQLeAosJSd5BPYbtPe9AuScc4FCE7PFKqTcak7md8YQdY nPRtd4Aw7N9nRNtlR21ijl6VHcMGm+Oxb5fk2Jn94I1NHyKOtGlbBsJSSRo7QEVX sqvFXUHFpwNAZcFoavZaTx7aShh/2vg5wtmPiUd0uvArwILhSIaJg8FbeupIhQ6D Ip8+HklCyHUDR9dUdHZK6nD8Tf6PilvFUBs1VLP+FMh6O3i+teF6P4rWEeuOGYO7 vBa+f/jDy8x4PRHNR1m1t2+kaPi5cPUU4JZwrk2ZHExYyqEzMlsNve2ha4gDivyI arlRT5qDgl7pS3sr3G5XDQ8yqWJmF6ZpTzUZofTIsngbtku6ArV/31wyzKgD/41z zgTQ5Ndq9L0uJBTY42jOMbjjbq6YlgT8Iz83aktIkS9JkHQIttMVq8LB3GSdw6qt ZNoJfdTsux7a0vWdg6A4VvyHGeyP7ySyhxULoVFC85BPMiTEayo= =eD7A -----END PGP SIGNATURE----- Merge tag 'iwlwifi-for-kalle-2017-11-28' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-fixes Second batch of fixes intended for 4.15. * One fix in rate-scaling; * One fix for the TX queue hang detection for AP/GO modes; * Fix the TX queue hang timeout used in monitor interfaces; * Fix packet injection; * Remove a wrong error message when dumping PCI registers; * Fix race condition with RF-kill;
This commit is contained in:
commit
e4875470a7
|
@ -68,6 +68,9 @@
|
|||
* @IWL_MVM_DQA_CMD_QUEUE: a queue reserved for sending HCMDs to the FW
|
||||
* @IWL_MVM_DQA_AUX_QUEUE: a queue reserved for aux frames
|
||||
* @IWL_MVM_DQA_P2P_DEVICE_QUEUE: a queue reserved for P2P device frames
|
||||
* @IWL_MVM_DQA_INJECT_MONITOR_QUEUE: a queue reserved for injection using
|
||||
* monitor mode. Note this queue is the same as the queue for P2P device
|
||||
* but we can't have active monitor mode along with P2P device anyway.
|
||||
* @IWL_MVM_DQA_GCAST_QUEUE: a queue reserved for P2P GO/SoftAP GCAST frames
|
||||
* @IWL_MVM_DQA_BSS_CLIENT_QUEUE: a queue reserved for BSS activity, to ensure
|
||||
* that we are never left without the possibility to connect to an AP.
|
||||
|
@ -87,6 +90,7 @@ enum iwl_mvm_dqa_txq {
|
|||
IWL_MVM_DQA_CMD_QUEUE = 0,
|
||||
IWL_MVM_DQA_AUX_QUEUE = 1,
|
||||
IWL_MVM_DQA_P2P_DEVICE_QUEUE = 2,
|
||||
IWL_MVM_DQA_INJECT_MONITOR_QUEUE = 2,
|
||||
IWL_MVM_DQA_GCAST_QUEUE = 3,
|
||||
IWL_MVM_DQA_BSS_CLIENT_QUEUE = 4,
|
||||
IWL_MVM_DQA_MIN_MGMT_QUEUE = 5,
|
||||
|
|
|
@ -209,8 +209,6 @@ static inline void iwl_fw_dbg_stop_recording(struct iwl_fw_runtime *fwrt)
|
|||
|
||||
static inline void iwl_fw_dump_conf_clear(struct iwl_fw_runtime *fwrt)
|
||||
{
|
||||
iwl_fw_dbg_stop_recording(fwrt);
|
||||
|
||||
fwrt->dump.conf = FW_DBG_INVALID;
|
||||
}
|
||||
|
||||
|
|
|
@ -787,7 +787,7 @@ static int iwl_mvm_mac_ctxt_cmd_listener(struct iwl_mvm *mvm,
|
|||
u32 action)
|
||||
{
|
||||
struct iwl_mac_ctx_cmd cmd = {};
|
||||
u32 tfd_queue_msk = 0;
|
||||
u32 tfd_queue_msk = BIT(mvm->snif_queue);
|
||||
int ret;
|
||||
|
||||
WARN_ON(vif->type != NL80211_IFTYPE_MONITOR);
|
||||
|
|
|
@ -972,6 +972,7 @@ struct iwl_mvm {
|
|||
|
||||
/* Tx queues */
|
||||
u16 aux_queue;
|
||||
u16 snif_queue;
|
||||
u16 probe_queue;
|
||||
u16 p2p_dev_queue;
|
||||
|
||||
|
|
|
@ -624,6 +624,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
|
|||
mvm->fw_restart = iwlwifi_mod_params.fw_restart ? -1 : 0;
|
||||
|
||||
mvm->aux_queue = IWL_MVM_DQA_AUX_QUEUE;
|
||||
mvm->snif_queue = IWL_MVM_DQA_INJECT_MONITOR_QUEUE;
|
||||
mvm->probe_queue = IWL_MVM_DQA_AP_PROBE_RESP_QUEUE;
|
||||
mvm->p2p_dev_queue = IWL_MVM_DQA_P2P_DEVICE_QUEUE;
|
||||
|
||||
|
|
|
@ -213,6 +213,7 @@ static void iwl_mvm_get_signal_strength(struct iwl_mvm *mvm,
|
|||
struct ieee80211_rx_status *rx_status)
|
||||
{
|
||||
int energy_a, energy_b, max_energy;
|
||||
u32 rate_flags = le32_to_cpu(desc->rate_n_flags);
|
||||
|
||||
energy_a = desc->energy_a;
|
||||
energy_a = energy_a ? -energy_a : S8_MIN;
|
||||
|
@ -224,7 +225,8 @@ static void iwl_mvm_get_signal_strength(struct iwl_mvm *mvm,
|
|||
energy_a, energy_b, max_energy);
|
||||
|
||||
rx_status->signal = max_energy;
|
||||
rx_status->chains = 0; /* TODO: phy info */
|
||||
rx_status->chains =
|
||||
(rate_flags & RATE_MCS_ANT_AB_MSK) >> RATE_MCS_ANT_POS;
|
||||
rx_status->chain_signal[0] = energy_a;
|
||||
rx_status->chain_signal[1] = energy_b;
|
||||
rx_status->chain_signal[2] = S8_MIN;
|
||||
|
|
|
@ -1709,29 +1709,29 @@ void iwl_mvm_dealloc_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta)
|
|||
sta->sta_id = IWL_MVM_INVALID_STA;
|
||||
}
|
||||
|
||||
static void iwl_mvm_enable_aux_queue(struct iwl_mvm *mvm)
|
||||
static void iwl_mvm_enable_aux_snif_queue(struct iwl_mvm *mvm, u16 *queue,
|
||||
u8 sta_id, u8 fifo)
|
||||
{
|
||||
unsigned int wdg_timeout = iwlmvm_mod_params.tfd_q_hang_detect ?
|
||||
mvm->cfg->base_params->wd_timeout :
|
||||
IWL_WATCHDOG_DISABLED;
|
||||
|
||||
if (iwl_mvm_has_new_tx_api(mvm)) {
|
||||
int queue = iwl_mvm_tvqm_enable_txq(mvm, mvm->aux_queue,
|
||||
mvm->aux_sta.sta_id,
|
||||
int tvqm_queue =
|
||||
iwl_mvm_tvqm_enable_txq(mvm, *queue, sta_id,
|
||||
IWL_MAX_TID_COUNT,
|
||||
wdg_timeout);
|
||||
mvm->aux_queue = queue;
|
||||
*queue = tvqm_queue;
|
||||
} else {
|
||||
struct iwl_trans_txq_scd_cfg cfg = {
|
||||
.fifo = IWL_MVM_TX_FIFO_MCAST,
|
||||
.sta_id = mvm->aux_sta.sta_id,
|
||||
.fifo = fifo,
|
||||
.sta_id = sta_id,
|
||||
.tid = IWL_MAX_TID_COUNT,
|
||||
.aggregate = false,
|
||||
.frame_limit = IWL_FRAME_LIMIT,
|
||||
};
|
||||
|
||||
iwl_mvm_enable_txq(mvm, mvm->aux_queue, mvm->aux_queue, 0, &cfg,
|
||||
wdg_timeout);
|
||||
iwl_mvm_enable_txq(mvm, *queue, *queue, 0, &cfg, wdg_timeout);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1750,7 +1750,9 @@ int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm)
|
|||
|
||||
/* Map Aux queue to fifo - needs to happen before adding Aux station */
|
||||
if (!iwl_mvm_has_new_tx_api(mvm))
|
||||
iwl_mvm_enable_aux_queue(mvm);
|
||||
iwl_mvm_enable_aux_snif_queue(mvm, &mvm->aux_queue,
|
||||
mvm->aux_sta.sta_id,
|
||||
IWL_MVM_TX_FIFO_MCAST);
|
||||
|
||||
ret = iwl_mvm_add_int_sta_common(mvm, &mvm->aux_sta, NULL,
|
||||
MAC_INDEX_AUX, 0);
|
||||
|
@ -1764,7 +1766,9 @@ int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm)
|
|||
* to firmware so enable queue here - after the station was added
|
||||
*/
|
||||
if (iwl_mvm_has_new_tx_api(mvm))
|
||||
iwl_mvm_enable_aux_queue(mvm);
|
||||
iwl_mvm_enable_aux_snif_queue(mvm, &mvm->aux_queue,
|
||||
mvm->aux_sta.sta_id,
|
||||
IWL_MVM_TX_FIFO_MCAST);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1772,10 +1776,31 @@ int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm)
|
|||
int iwl_mvm_add_snif_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
|
||||
{
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
return iwl_mvm_add_int_sta_common(mvm, &mvm->snif_sta, vif->addr,
|
||||
|
||||
/* Map snif queue to fifo - must happen before adding snif station */
|
||||
if (!iwl_mvm_has_new_tx_api(mvm))
|
||||
iwl_mvm_enable_aux_snif_queue(mvm, &mvm->snif_queue,
|
||||
mvm->snif_sta.sta_id,
|
||||
IWL_MVM_TX_FIFO_BE);
|
||||
|
||||
ret = iwl_mvm_add_int_sta_common(mvm, &mvm->snif_sta, vif->addr,
|
||||
mvmvif->id, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* For 22000 firmware and on we cannot add queue to a station unknown
|
||||
* to firmware so enable queue here - after the station was added
|
||||
*/
|
||||
if (iwl_mvm_has_new_tx_api(mvm))
|
||||
iwl_mvm_enable_aux_snif_queue(mvm, &mvm->snif_queue,
|
||||
mvm->snif_sta.sta_id,
|
||||
IWL_MVM_TX_FIFO_BE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int iwl_mvm_rm_snif_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
|
||||
|
@ -1784,6 +1809,8 @@ int iwl_mvm_rm_snif_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
|
|||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
iwl_mvm_disable_txq(mvm, mvm->snif_queue, mvm->snif_queue,
|
||||
IWL_MAX_TID_COUNT, 0);
|
||||
ret = iwl_mvm_rm_sta_common(mvm, mvm->snif_sta.sta_id);
|
||||
if (ret)
|
||||
IWL_WARN(mvm, "Failed sending remove station\n");
|
||||
|
|
|
@ -657,7 +657,8 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb)
|
|||
if (ap_sta_id != IWL_MVM_INVALID_STA)
|
||||
sta_id = ap_sta_id;
|
||||
} else if (info.control.vif->type == NL80211_IFTYPE_MONITOR) {
|
||||
queue = mvm->aux_queue;
|
||||
queue = mvm->snif_queue;
|
||||
sta_id = mvm->snif_sta.sta_id;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1134,9 +1134,18 @@ unsigned int iwl_mvm_get_wd_timeout(struct iwl_mvm *mvm,
|
|||
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))
|
||||
if (!iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_TXQ_TIMERS)) {
|
||||
/*
|
||||
* We can't know when the station is asleep or awake, so we
|
||||
* must disable the queue hang detection.
|
||||
*/
|
||||
if (fw_has_capa(&mvm->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_CAPA_STA_PM_NOTIF) &&
|
||||
vif && vif->type == NL80211_IFTYPE_AP)
|
||||
return IWL_WATCHDOG_DISABLED;
|
||||
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;
|
||||
|
@ -1163,6 +1172,8 @@ unsigned int iwl_mvm_get_wd_timeout(struct iwl_mvm *mvm,
|
|||
return le32_to_cpu(txq_timer->p2p_go);
|
||||
case NL80211_IFTYPE_P2P_DEVICE:
|
||||
return le32_to_cpu(txq_timer->p2p_device);
|
||||
case NL80211_IFTYPE_MONITOR:
|
||||
return default_timeout;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
return mvm->cfg->base_params->wd_timeout;
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
*
|
||||
*****************************************************************************/
|
||||
#include "iwl-trans.h"
|
||||
#include "iwl-prph.h"
|
||||
#include "iwl-context-info.h"
|
||||
#include "internal.h"
|
||||
|
||||
|
@ -156,6 +157,11 @@ void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans, bool low_power)
|
|||
|
||||
trans_pcie->is_down = true;
|
||||
|
||||
/* Stop dbgc before stopping device */
|
||||
iwl_write_prph(trans, DBGC_IN_SAMPLE, 0);
|
||||
udelay(100);
|
||||
iwl_write_prph(trans, DBGC_OUT_CTRL, 0);
|
||||
|
||||
/* tell the device to stop sending interrupts */
|
||||
iwl_disable_interrupts(trans);
|
||||
|
||||
|
|
|
@ -166,6 +166,7 @@ static void iwl_trans_pcie_dump_regs(struct iwl_trans *trans)
|
|||
print_hex_dump(KERN_ERR, prefix, DUMP_PREFIX_OFFSET, 32,
|
||||
4, buf, i, 0);
|
||||
}
|
||||
goto out;
|
||||
|
||||
err_read:
|
||||
print_hex_dump(KERN_ERR, prefix, DUMP_PREFIX_OFFSET, 32, 4, buf, i, 0);
|
||||
|
@ -1226,6 +1227,15 @@ static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool low_power)
|
|||
|
||||
trans_pcie->is_down = true;
|
||||
|
||||
/* Stop dbgc before stopping device */
|
||||
if (trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
|
||||
iwl_set_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x100);
|
||||
} else {
|
||||
iwl_write_prph(trans, DBGC_IN_SAMPLE, 0);
|
||||
udelay(100);
|
||||
iwl_write_prph(trans, DBGC_OUT_CTRL, 0);
|
||||
}
|
||||
|
||||
/* tell the device to stop sending interrupts */
|
||||
iwl_disable_interrupts(trans);
|
||||
|
||||
|
|
Loading…
Reference in New Issue