]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
Merge tag 'wireless-drivers-for-davem-2017-12-08' of git://git.kernel.org/pub/scm...
authorDavid S. Miller <davem@davemloft.net>
Fri, 8 Dec 2017 19:48:49 +0000 (14:48 -0500)
committerDavid S. Miller <davem@davemloft.net>
Fri, 8 Dec 2017 19:48:49 +0000 (14:48 -0500)
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: David S. Miller <davem@davemloft.net>
15 files changed:
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
drivers/net/wireless/intel/iwlwifi/fw/api/txq.h
drivers/net/wireless/intel/iwlwifi/fw/dbg.h
drivers/net/wireless/intel/iwlwifi/iwl-trans.h
drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
drivers/net/wireless/intel/iwlwifi/mvm/ops.c
drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
drivers/net/wireless/intel/iwlwifi/mvm/sta.c
drivers/net/wireless/intel/iwlwifi/mvm/time-event.c
drivers/net/wireless/intel/iwlwifi/mvm/tx.c
drivers/net/wireless/intel/iwlwifi/mvm/utils.c
drivers/net/wireless/intel/iwlwifi/pcie/drv.c
drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
drivers/net/wireless/intel/iwlwifi/pcie/trans.c

index 310c4e2746aab1da08d62e58812219b5271507e9..cdf9e41615925c6978dc4620e032d65b055ee28d 100644 (file)
@@ -2070,7 +2070,7 @@ static int brcmf_sdio_txpkt_hdalign(struct brcmf_sdio *bus, struct sk_buff *pkt)
        return head_pad;
 }
 
-/**
+/*
  * struct brcmf_skbuff_cb reserves first two bytes in sk_buff::cb for
  * bus layer usage.
  */
@@ -4121,8 +4121,8 @@ release:
        sdio_release_host(sdiodev->func[1]);
 fail:
        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(dev);
 }
 
 struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
index 87b4434224a1f0a121455ef0a2d0877c4e14e42b..dfa111bb411e5b1421ae2060f37d600432d70bd9 100644 (file)
@@ -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,
index 9c889a32fe2424941d9bceb89b8cd1f593e4f3ab..223fb77a3aa9d64456244dd4c5156b8885cec6fd 100644 (file)
@@ -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;
 }
 
index ca0b5536a8a68e1a4dcc8b2d2de61e5dfb7af255..921cab9e2d737bf7fac47028339852dd60c201c6 100644 (file)
 #define FH_RSCSR_FRAME_INVALID         0x55550000
 #define FH_RSCSR_FRAME_ALIGN           0x40
 #define FH_RSCSR_RPA_EN                        BIT(25)
+#define FH_RSCSR_RADA_EN               BIT(26)
 #define FH_RSCSR_RXQ_POS               16
 #define FH_RSCSR_RXQ_MASK              0x3F0000
 
@@ -128,7 +129,8 @@ struct iwl_rx_packet {
         * 31:    flag flush RB request
         * 30:    flag ignore TC (terminal counter) request
         * 29:    flag fast IRQ request
-        * 28-26: Reserved
+        * 28-27: Reserved
+        * 26:    RADA enabled
         * 25:    Offload enabled
         * 24:    RPF enabled
         * 23:    RSS enabled
index a2bf530eeae49e38430d9f05ab33d865ed9fd560..2f22e14e00fe881bc9868a22c25ba41286a9ea51 100644 (file)
@@ -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);
index 4575595ab022600ff7d33da2d789c54f84a0e951..55ab5349dd40d8b886373df6cb0715e977650309 100644 (file)
@@ -972,6 +972,7 @@ struct iwl_mvm {
 
        /* Tx queues */
        u16 aux_queue;
+       u16 snif_queue;
        u16 probe_queue;
        u16 p2p_dev_queue;
 
@@ -1060,6 +1061,7 @@ struct iwl_mvm {
  * @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_FIRMWARE_RUNNING: firmware is running
+ * @IWL_MVM_STATUS_NEED_FLUSH_P2P: need to flush P2P bcast STA
  */
 enum iwl_mvm_status {
        IWL_MVM_STATUS_HW_RFKILL,
@@ -1071,6 +1073,7 @@ enum iwl_mvm_status {
        IWL_MVM_STATUS_ROC_AUX_RUNNING,
        IWL_MVM_STATUS_D3_RECONFIG,
        IWL_MVM_STATUS_FIRMWARE_RUNNING,
+       IWL_MVM_STATUS_NEED_FLUSH_P2P,
 };
 
 /* Keep track of completed init configuration */
index 7078b7e458be84d59e691e88bf791bce9ca9154d..45470b6b351a9a31734b3a77f04fcbd99a8526eb 100644 (file)
@@ -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;
 
index 76dc58381e1c9e443847d2f890b19eceb6b0140e..3b8d44361380de8d2a0a9635a915fe8151388ecf 100644 (file)
@@ -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;
@@ -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,
                             struct ieee80211_rx_status *stats,
-                            struct iwl_rx_mpdu_desc *desc, int queue,
-                            u8 *crypt_len)
+                            struct iwl_rx_mpdu_desc *desc, u32 pkt_flags,
+                            int queue, u8 *crypt_len)
 {
        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,
                        return -1;
 
                stats->flag |= RX_FLAG_DECRYPTED;
+               if (pkt_flags & FH_RSCSR_RADA_EN)
+                       stats->flag |= RX_FLAG_MIC_STRIPPED;
                *crypt_len = IEEE80211_CCMP_HDR_LEN;
                return 0;
        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,
                if ((status & IWL_RX_MPDU_STATUS_SEC_MASK) ==
                                IWL_RX_MPDU_STATUS_SEC_WEP)
                        *crypt_len = IEEE80211_WEP_IV_LEN;
+
+               if (pkt_flags & FH_RSCSR_RADA_EN)
+                       stats->flag |= RX_FLAG_ICV_STRIPPED;
+
                return 0;
        case IWL_RX_MPDU_STATUS_SEC_EXT_ENC:
                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,
 
        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);
                return;
        }
index c19f98489d4e9565e0ee33c0dfd22a757a435db4..1add5615fc3ad9d0a9801920448e79f71e64eda5 100644 (file)
@@ -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,
-                                                   IWL_MAX_TID_COUNT,
-                                                   wdg_timeout);
-               mvm->aux_queue = queue;
+               int tvqm_queue =
+                       iwl_mvm_tvqm_enable_txq(mvm, *queue, sta_id,
+                                               IWL_MAX_TID_COUNT,
+                                               wdg_timeout);
+               *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");
index 4d0314912e94794b7728af17707618cd72ad2908..e25cda9fbf6c34d951b7441b40574bfb9c0a67b7 100644 (file)
@@ -132,6 +132,24 @@ void iwl_mvm_roc_done_wk(struct work_struct *wk)
         * executed, and a new time event means a new command.
         */
        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)
@@ -855,10 +873,12 @@ void iwl_mvm_stop_roc(struct iwl_mvm *mvm)
 
        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);
-       else
+               set_bit(IWL_MVM_STATUS_NEED_FLUSH_P2P, &mvm->status);
+       } else {
                iwl_mvm_remove_aux_roc_te(mvm, mvmvif, te_data);
+       }
 
        iwl_mvm_roc_finished(mvm);
 }
index 593b7f97b29c103f8faf28dd905dd36aed34e763..333bcb75b8afcd17eecd76c1a581c683edef4457 100644 (file)
@@ -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;
                }
        }
 
index d46115e2d69e1d6de1fcc3126e3f1af8a59da99c..03ffd84786ca4f1b832fe78177ac0ef090d4dddd 100644 (file)
@@ -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;
index f21fe59faccff835efe0db590c437f419a89ccb4..ccd7c33c4c2823e3374934a7e25da8cac82996a1 100644 (file)
@@ -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, 0x0210, iwl9160_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, 0x0038, 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[] = {
        {IWL_PCI_DEVICE(0x2720, 0x0310, iwla000_2ac_cfg_hr_cdb)},
        {IWL_PCI_DEVICE(0x40C0, 0x0000, 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 */
 
index c59f4581e97271cc35d07bed98876d300384fa9c..ac05fd1e74c4c80308caf5b630ffd29a6968f888 100644 (file)
@@ -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);
 
index b7a51603465b20752616639cd3f663a6844dcdd8..4541c86881d604e16093eef51cb7ba48afb3685b 100644 (file)
@@ -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);