Commit 03afb6e4 authored by David S. Miller's avatar David S. Miller

Merge tag 'wireless-drivers-for-davem-2017-12-08' of...

Merge tag 'wireless-drivers-for-davem-2017-12-08' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers

Kalle Valo says:

====================
wireless-drivers fixes for 4.15

Second set of fixes for 4.15. This time a lot of iwlwifi patches and
two brcmfmac patches. Most important here are the MIC and IVC fixes
for iwlwifi to unbreak 9000 series.

iwlwifi

* fix rate-scaling to not start lowest possible rate

* fix the TX queue hang detection for AP/GO modes

* fix the TX queue hang timeout in monitor interfaces

* fix packet injection

* remove a wrong error message when dumping PCI registers

* fix race condition with RF-kill

* tell mac80211 when the MIC has been stripped (9000 series)

* tell mac80211 when the IVC has been stripped (9000 series)

* add 2 new PCI IDs, one for 9000 and one for 22000

* fix a queue hang due during a P2P Remain-on-Channel operation

brcmfmac

* fix a race which sometimes caused a crash during sdio unbind

* fix a kernel-doc related build error
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 8a7b741e a41886f5
...@@ -2070,7 +2070,7 @@ static int brcmf_sdio_txpkt_hdalign(struct brcmf_sdio *bus, struct sk_buff *pkt) ...@@ -2070,7 +2070,7 @@ static int brcmf_sdio_txpkt_hdalign(struct brcmf_sdio *bus, struct sk_buff *pkt)
return head_pad; return head_pad;
} }
/** /*
* struct brcmf_skbuff_cb reserves first two bytes in sk_buff::cb for * struct brcmf_skbuff_cb reserves first two bytes in sk_buff::cb for
* bus layer usage. * bus layer usage.
*/ */
...@@ -4121,8 +4121,8 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err, ...@@ -4121,8 +4121,8 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err,
sdio_release_host(sdiodev->func[1]); sdio_release_host(sdiodev->func[1]);
fail: fail:
brcmf_dbg(TRACE, "failed: dev=%s, err=%d\n", dev_name(dev), err); brcmf_dbg(TRACE, "failed: dev=%s, err=%d\n", dev_name(dev), err);
device_release_driver(dev);
device_release_driver(&sdiodev->func[2]->dev); device_release_driver(&sdiodev->func[2]->dev);
device_release_driver(dev);
} }
struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
......
...@@ -68,6 +68,9 @@ ...@@ -68,6 +68,9 @@
* @IWL_MVM_DQA_CMD_QUEUE: a queue reserved for sending HCMDs to the FW * @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_AUX_QUEUE: a queue reserved for aux frames
* @IWL_MVM_DQA_P2P_DEVICE_QUEUE: a queue reserved for P2P device 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_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 * @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. * that we are never left without the possibility to connect to an AP.
...@@ -87,6 +90,7 @@ enum iwl_mvm_dqa_txq { ...@@ -87,6 +90,7 @@ enum iwl_mvm_dqa_txq {
IWL_MVM_DQA_CMD_QUEUE = 0, IWL_MVM_DQA_CMD_QUEUE = 0,
IWL_MVM_DQA_AUX_QUEUE = 1, IWL_MVM_DQA_AUX_QUEUE = 1,
IWL_MVM_DQA_P2P_DEVICE_QUEUE = 2, IWL_MVM_DQA_P2P_DEVICE_QUEUE = 2,
IWL_MVM_DQA_INJECT_MONITOR_QUEUE = 2,
IWL_MVM_DQA_GCAST_QUEUE = 3, IWL_MVM_DQA_GCAST_QUEUE = 3,
IWL_MVM_DQA_BSS_CLIENT_QUEUE = 4, IWL_MVM_DQA_BSS_CLIENT_QUEUE = 4,
IWL_MVM_DQA_MIN_MGMT_QUEUE = 5, IWL_MVM_DQA_MIN_MGMT_QUEUE = 5,
......
...@@ -209,8 +209,6 @@ static inline void iwl_fw_dbg_stop_recording(struct iwl_fw_runtime *fwrt) ...@@ -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) 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; fwrt->dump.conf = FW_DBG_INVALID;
} }
......
...@@ -117,6 +117,7 @@ ...@@ -117,6 +117,7 @@
#define FH_RSCSR_FRAME_INVALID 0x55550000 #define FH_RSCSR_FRAME_INVALID 0x55550000
#define FH_RSCSR_FRAME_ALIGN 0x40 #define FH_RSCSR_FRAME_ALIGN 0x40
#define FH_RSCSR_RPA_EN BIT(25) #define FH_RSCSR_RPA_EN BIT(25)
#define FH_RSCSR_RADA_EN BIT(26)
#define FH_RSCSR_RXQ_POS 16 #define FH_RSCSR_RXQ_POS 16
#define FH_RSCSR_RXQ_MASK 0x3F0000 #define FH_RSCSR_RXQ_MASK 0x3F0000
...@@ -128,7 +129,8 @@ struct iwl_rx_packet { ...@@ -128,7 +129,8 @@ struct iwl_rx_packet {
* 31: flag flush RB request * 31: flag flush RB request
* 30: flag ignore TC (terminal counter) request * 30: flag ignore TC (terminal counter) request
* 29: flag fast IRQ request * 29: flag fast IRQ request
* 28-26: Reserved * 28-27: Reserved
* 26: RADA enabled
* 25: Offload enabled * 25: Offload enabled
* 24: RPF enabled * 24: RPF enabled
* 23: RSS enabled * 23: RSS enabled
......
...@@ -787,7 +787,7 @@ static int iwl_mvm_mac_ctxt_cmd_listener(struct iwl_mvm *mvm, ...@@ -787,7 +787,7 @@ static int iwl_mvm_mac_ctxt_cmd_listener(struct iwl_mvm *mvm,
u32 action) u32 action)
{ {
struct iwl_mac_ctx_cmd cmd = {}; struct iwl_mac_ctx_cmd cmd = {};
u32 tfd_queue_msk = 0; u32 tfd_queue_msk = BIT(mvm->snif_queue);
int ret; int ret;
WARN_ON(vif->type != NL80211_IFTYPE_MONITOR); WARN_ON(vif->type != NL80211_IFTYPE_MONITOR);
......
...@@ -972,6 +972,7 @@ struct iwl_mvm { ...@@ -972,6 +972,7 @@ struct iwl_mvm {
/* Tx queues */ /* Tx queues */
u16 aux_queue; u16 aux_queue;
u16 snif_queue;
u16 probe_queue; u16 probe_queue;
u16 p2p_dev_queue; u16 p2p_dev_queue;
...@@ -1060,6 +1061,7 @@ struct iwl_mvm { ...@@ -1060,6 +1061,7 @@ struct iwl_mvm {
* @IWL_MVM_STATUS_ROC_AUX_RUNNING: AUX remain-on-channel is running * @IWL_MVM_STATUS_ROC_AUX_RUNNING: AUX remain-on-channel is running
* @IWL_MVM_STATUS_D3_RECONFIG: D3 reconfiguration is being done * @IWL_MVM_STATUS_D3_RECONFIG: D3 reconfiguration is being done
* @IWL_MVM_STATUS_FIRMWARE_RUNNING: firmware is running * @IWL_MVM_STATUS_FIRMWARE_RUNNING: firmware is running
* @IWL_MVM_STATUS_NEED_FLUSH_P2P: need to flush P2P bcast STA
*/ */
enum iwl_mvm_status { enum iwl_mvm_status {
IWL_MVM_STATUS_HW_RFKILL, IWL_MVM_STATUS_HW_RFKILL,
...@@ -1071,6 +1073,7 @@ enum iwl_mvm_status { ...@@ -1071,6 +1073,7 @@ enum iwl_mvm_status {
IWL_MVM_STATUS_ROC_AUX_RUNNING, IWL_MVM_STATUS_ROC_AUX_RUNNING,
IWL_MVM_STATUS_D3_RECONFIG, IWL_MVM_STATUS_D3_RECONFIG,
IWL_MVM_STATUS_FIRMWARE_RUNNING, IWL_MVM_STATUS_FIRMWARE_RUNNING,
IWL_MVM_STATUS_NEED_FLUSH_P2P,
}; };
/* Keep track of completed init configuration */ /* Keep track of completed init configuration */
......
...@@ -624,6 +624,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, ...@@ -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->fw_restart = iwlwifi_mod_params.fw_restart ? -1 : 0;
mvm->aux_queue = IWL_MVM_DQA_AUX_QUEUE; 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->probe_queue = IWL_MVM_DQA_AP_PROBE_RESP_QUEUE;
mvm->p2p_dev_queue = IWL_MVM_DQA_P2P_DEVICE_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, ...@@ -213,6 +213,7 @@ static void iwl_mvm_get_signal_strength(struct iwl_mvm *mvm,
struct ieee80211_rx_status *rx_status) struct ieee80211_rx_status *rx_status)
{ {
int energy_a, energy_b, max_energy; int energy_a, energy_b, max_energy;
u32 rate_flags = le32_to_cpu(desc->rate_n_flags);
energy_a = desc->energy_a; energy_a = desc->energy_a;
energy_a = energy_a ? -energy_a : S8_MIN; energy_a = energy_a ? -energy_a : S8_MIN;
...@@ -224,7 +225,8 @@ static void iwl_mvm_get_signal_strength(struct iwl_mvm *mvm, ...@@ -224,7 +225,8 @@ static void iwl_mvm_get_signal_strength(struct iwl_mvm *mvm,
energy_a, energy_b, max_energy); energy_a, energy_b, max_energy);
rx_status->signal = 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[0] = energy_a;
rx_status->chain_signal[1] = energy_b; rx_status->chain_signal[1] = energy_b;
rx_status->chain_signal[2] = S8_MIN; rx_status->chain_signal[2] = S8_MIN;
...@@ -232,8 +234,8 @@ static void iwl_mvm_get_signal_strength(struct iwl_mvm *mvm, ...@@ -232,8 +234,8 @@ static void iwl_mvm_get_signal_strength(struct iwl_mvm *mvm,
static int iwl_mvm_rx_crypto(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr, static int iwl_mvm_rx_crypto(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr,
struct ieee80211_rx_status *stats, struct ieee80211_rx_status *stats,
struct iwl_rx_mpdu_desc *desc, int queue, struct iwl_rx_mpdu_desc *desc, u32 pkt_flags,
u8 *crypt_len) int queue, u8 *crypt_len)
{ {
u16 status = le16_to_cpu(desc->status); u16 status = le16_to_cpu(desc->status);
...@@ -253,6 +255,8 @@ static int iwl_mvm_rx_crypto(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr, ...@@ -253,6 +255,8 @@ static int iwl_mvm_rx_crypto(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr,
return -1; return -1;
stats->flag |= RX_FLAG_DECRYPTED; stats->flag |= RX_FLAG_DECRYPTED;
if (pkt_flags & FH_RSCSR_RADA_EN)
stats->flag |= RX_FLAG_MIC_STRIPPED;
*crypt_len = IEEE80211_CCMP_HDR_LEN; *crypt_len = IEEE80211_CCMP_HDR_LEN;
return 0; return 0;
case IWL_RX_MPDU_STATUS_SEC_TKIP: case IWL_RX_MPDU_STATUS_SEC_TKIP:
...@@ -270,6 +274,10 @@ static int iwl_mvm_rx_crypto(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr, ...@@ -270,6 +274,10 @@ static int iwl_mvm_rx_crypto(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr,
if ((status & IWL_RX_MPDU_STATUS_SEC_MASK) == if ((status & IWL_RX_MPDU_STATUS_SEC_MASK) ==
IWL_RX_MPDU_STATUS_SEC_WEP) IWL_RX_MPDU_STATUS_SEC_WEP)
*crypt_len = IEEE80211_WEP_IV_LEN; *crypt_len = IEEE80211_WEP_IV_LEN;
if (pkt_flags & FH_RSCSR_RADA_EN)
stats->flag |= RX_FLAG_ICV_STRIPPED;
return 0; return 0;
case IWL_RX_MPDU_STATUS_SEC_EXT_ENC: case IWL_RX_MPDU_STATUS_SEC_EXT_ENC:
if (!(status & IWL_RX_MPDU_STATUS_MIC_OK)) if (!(status & IWL_RX_MPDU_STATUS_MIC_OK))
...@@ -848,7 +856,9 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, ...@@ -848,7 +856,9 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
rx_status = IEEE80211_SKB_RXCB(skb); rx_status = IEEE80211_SKB_RXCB(skb);
if (iwl_mvm_rx_crypto(mvm, hdr, rx_status, desc, queue, &crypt_len)) { if (iwl_mvm_rx_crypto(mvm, hdr, rx_status, desc,
le32_to_cpu(pkt->len_n_flags), queue,
&crypt_len)) {
kfree_skb(skb); kfree_skb(skb);
return; return;
} }
......
...@@ -1709,29 +1709,29 @@ void iwl_mvm_dealloc_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta) ...@@ -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; 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 ? unsigned int wdg_timeout = iwlmvm_mod_params.tfd_q_hang_detect ?
mvm->cfg->base_params->wd_timeout : mvm->cfg->base_params->wd_timeout :
IWL_WATCHDOG_DISABLED; IWL_WATCHDOG_DISABLED;
if (iwl_mvm_has_new_tx_api(mvm)) { if (iwl_mvm_has_new_tx_api(mvm)) {
int queue = iwl_mvm_tvqm_enable_txq(mvm, mvm->aux_queue, int tvqm_queue =
mvm->aux_sta.sta_id, iwl_mvm_tvqm_enable_txq(mvm, *queue, sta_id,
IWL_MAX_TID_COUNT, IWL_MAX_TID_COUNT,
wdg_timeout); wdg_timeout);
mvm->aux_queue = queue; *queue = tvqm_queue;
} else { } else {
struct iwl_trans_txq_scd_cfg cfg = { struct iwl_trans_txq_scd_cfg cfg = {
.fifo = IWL_MVM_TX_FIFO_MCAST, .fifo = fifo,
.sta_id = mvm->aux_sta.sta_id, .sta_id = sta_id,
.tid = IWL_MAX_TID_COUNT, .tid = IWL_MAX_TID_COUNT,
.aggregate = false, .aggregate = false,
.frame_limit = IWL_FRAME_LIMIT, .frame_limit = IWL_FRAME_LIMIT,
}; };
iwl_mvm_enable_txq(mvm, mvm->aux_queue, mvm->aux_queue, 0, &cfg, iwl_mvm_enable_txq(mvm, *queue, *queue, 0, &cfg, wdg_timeout);
wdg_timeout);
} }
} }
...@@ -1750,7 +1750,9 @@ int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm) ...@@ -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 */ /* Map Aux queue to fifo - needs to happen before adding Aux station */
if (!iwl_mvm_has_new_tx_api(mvm)) 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, ret = iwl_mvm_add_int_sta_common(mvm, &mvm->aux_sta, NULL,
MAC_INDEX_AUX, 0); MAC_INDEX_AUX, 0);
...@@ -1764,7 +1766,9 @@ int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm) ...@@ -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 * to firmware so enable queue here - after the station was added
*/ */
if (iwl_mvm_has_new_tx_api(mvm)) 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; return 0;
} }
...@@ -1772,10 +1776,31 @@ int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm) ...@@ -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) 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); struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
int ret;
lockdep_assert_held(&mvm->mutex); 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); 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) 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) ...@@ -1784,6 +1809,8 @@ int iwl_mvm_rm_snif_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
lockdep_assert_held(&mvm->mutex); 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); ret = iwl_mvm_rm_sta_common(mvm, mvm->snif_sta.sta_id);
if (ret) if (ret)
IWL_WARN(mvm, "Failed sending remove station\n"); IWL_WARN(mvm, "Failed sending remove station\n");
......
...@@ -132,6 +132,24 @@ void iwl_mvm_roc_done_wk(struct work_struct *wk) ...@@ -132,6 +132,24 @@ void iwl_mvm_roc_done_wk(struct work_struct *wk)
* executed, and a new time event means a new command. * executed, and a new time event means a new command.
*/ */
iwl_mvm_flush_sta(mvm, &mvm->aux_sta, true, CMD_ASYNC); iwl_mvm_flush_sta(mvm, &mvm->aux_sta, true, CMD_ASYNC);
/* Do the same for the P2P device queue (STA) */
if (test_and_clear_bit(IWL_MVM_STATUS_NEED_FLUSH_P2P, &mvm->status)) {
struct iwl_mvm_vif *mvmvif;
/*
* NB: access to this pointer would be racy, but the flush bit
* can only be set when we had a P2P-Device VIF, and we have a
* flush of this work in iwl_mvm_prepare_mac_removal() so it's
* not really racy.
*/
if (!WARN_ON(!mvm->p2p_device_vif)) {
mvmvif = iwl_mvm_vif_from_mac80211(mvm->p2p_device_vif);
iwl_mvm_flush_sta(mvm, &mvmvif->bcast_sta, true,
CMD_ASYNC);
}
}
} }
static void iwl_mvm_roc_finished(struct iwl_mvm *mvm) static void iwl_mvm_roc_finished(struct iwl_mvm *mvm)
...@@ -855,10 +873,12 @@ void iwl_mvm_stop_roc(struct iwl_mvm *mvm) ...@@ -855,10 +873,12 @@ void iwl_mvm_stop_roc(struct iwl_mvm *mvm)
mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif); mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif);
if (te_data->vif->type == NL80211_IFTYPE_P2P_DEVICE) if (te_data->vif->type == NL80211_IFTYPE_P2P_DEVICE) {
iwl_mvm_remove_time_event(mvm, mvmvif, te_data); iwl_mvm_remove_time_event(mvm, mvmvif, te_data);
else set_bit(IWL_MVM_STATUS_NEED_FLUSH_P2P, &mvm->status);
} else {
iwl_mvm_remove_aux_roc_te(mvm, mvmvif, te_data); iwl_mvm_remove_aux_roc_te(mvm, mvmvif, te_data);
}
iwl_mvm_roc_finished(mvm); iwl_mvm_roc_finished(mvm);
} }
......
...@@ -657,7 +657,8 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb) ...@@ -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) if (ap_sta_id != IWL_MVM_INVALID_STA)
sta_id = ap_sta_id; sta_id = ap_sta_id;
} else if (info.control.vif->type == NL80211_IFTYPE_MONITOR) { } 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, ...@@ -1134,9 +1134,18 @@ unsigned int iwl_mvm_get_wd_timeout(struct iwl_mvm *mvm,
unsigned int default_timeout = unsigned int default_timeout =
cmd_q ? IWL_DEF_WD_TIMEOUT : mvm->cfg->base_params->wd_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 ? return iwlmvm_mod_params.tfd_q_hang_detect ?
default_timeout : IWL_WATCHDOG_DISABLED; default_timeout : IWL_WATCHDOG_DISABLED;
}
trigger = iwl_fw_dbg_get_trigger(mvm->fw, FW_DBG_TRIGGER_TXQ_TIMERS); trigger = iwl_fw_dbg_get_trigger(mvm->fw, FW_DBG_TRIGGER_TXQ_TIMERS);
txq_timer = (void *)trigger->data; txq_timer = (void *)trigger->data;
...@@ -1163,6 +1172,8 @@ unsigned int iwl_mvm_get_wd_timeout(struct iwl_mvm *mvm, ...@@ -1163,6 +1172,8 @@ unsigned int iwl_mvm_get_wd_timeout(struct iwl_mvm *mvm,
return le32_to_cpu(txq_timer->p2p_go); return le32_to_cpu(txq_timer->p2p_go);
case NL80211_IFTYPE_P2P_DEVICE: case NL80211_IFTYPE_P2P_DEVICE:
return le32_to_cpu(txq_timer->p2p_device); return le32_to_cpu(txq_timer->p2p_device);
case NL80211_IFTYPE_MONITOR:
return default_timeout;
default: default:
WARN_ON(1); WARN_ON(1);
return mvm->cfg->base_params->wd_timeout; return mvm->cfg->base_params->wd_timeout;
......
...@@ -553,6 +553,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = { ...@@ -553,6 +553,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
{IWL_PCI_DEVICE(0x271B, 0x0014, iwl9160_2ac_cfg)}, {IWL_PCI_DEVICE(0x271B, 0x0014, iwl9160_2ac_cfg)},
{IWL_PCI_DEVICE(0x271B, 0x0210, iwl9160_2ac_cfg)}, {IWL_PCI_DEVICE(0x271B, 0x0210, iwl9160_2ac_cfg)},
{IWL_PCI_DEVICE(0x271B, 0x0214, iwl9260_2ac_cfg)}, {IWL_PCI_DEVICE(0x271B, 0x0214, iwl9260_2ac_cfg)},
{IWL_PCI_DEVICE(0x271C, 0x0214, iwl9260_2ac_cfg)},
{IWL_PCI_DEVICE(0x2720, 0x0034, iwl9560_2ac_cfg)}, {IWL_PCI_DEVICE(0x2720, 0x0034, iwl9560_2ac_cfg)},
{IWL_PCI_DEVICE(0x2720, 0x0038, iwl9560_2ac_cfg)}, {IWL_PCI_DEVICE(0x2720, 0x0038, iwl9560_2ac_cfg)},
{IWL_PCI_DEVICE(0x2720, 0x003C, iwl9560_2ac_cfg)}, {IWL_PCI_DEVICE(0x2720, 0x003C, iwl9560_2ac_cfg)},
...@@ -664,6 +665,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = { ...@@ -664,6 +665,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
{IWL_PCI_DEVICE(0x2720, 0x0310, iwla000_2ac_cfg_hr_cdb)}, {IWL_PCI_DEVICE(0x2720, 0x0310, iwla000_2ac_cfg_hr_cdb)},
{IWL_PCI_DEVICE(0x40C0, 0x0000, iwla000_2ax_cfg_hr)}, {IWL_PCI_DEVICE(0x40C0, 0x0000, iwla000_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0x40C0, 0x0A10, iwla000_2ax_cfg_hr)}, {IWL_PCI_DEVICE(0x40C0, 0x0A10, iwla000_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0xA0F0, 0x0000, iwla000_2ax_cfg_hr)},
#endif /* CONFIG_IWLMVM */ #endif /* CONFIG_IWLMVM */
......
...@@ -49,6 +49,7 @@ ...@@ -49,6 +49,7 @@
* *
*****************************************************************************/ *****************************************************************************/
#include "iwl-trans.h" #include "iwl-trans.h"
#include "iwl-prph.h"
#include "iwl-context-info.h" #include "iwl-context-info.h"
#include "internal.h" #include "internal.h"
...@@ -156,6 +157,11 @@ void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans, bool low_power) ...@@ -156,6 +157,11 @@ void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans, bool low_power)
trans_pcie->is_down = true; 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 */ /* tell the device to stop sending interrupts */
iwl_disable_interrupts(trans); iwl_disable_interrupts(trans);
......
...@@ -166,6 +166,7 @@ static void iwl_trans_pcie_dump_regs(struct iwl_trans *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, print_hex_dump(KERN_ERR, prefix, DUMP_PREFIX_OFFSET, 32,
4, buf, i, 0); 4, buf, i, 0);
} }
goto out;
err_read: err_read:
print_hex_dump(KERN_ERR, prefix, DUMP_PREFIX_OFFSET, 32, 4, buf, i, 0); 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) ...@@ -1226,6 +1227,15 @@ static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool low_power)
trans_pcie->is_down = true; 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 */ /* tell the device to stop sending interrupts */
iwl_disable_interrupts(trans); iwl_disable_interrupts(trans);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment