iwlwifi: pcie: poll RFH for RX DMA stop
authorSara Sharon <sara.sharon@intel.com>
Thu, 19 May 2016 14:53:42 +0000 (17:53 +0300)
committerLuca Coelho <luciano.coelho@intel.com>
Tue, 5 Jul 2016 22:16:08 +0000 (01:16 +0300)
Somehow we ended up stopping RX using legacy RX registers
even for devices that support RFH. Fix it.

Signed-off-by: Sara Sharon <sara.sharon@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
drivers/net/wireless/intel/iwlwifi/iwl-fh.h
drivers/net/wireless/intel/iwlwifi/pcie/rx.c

index f08cdee..73f0ed8 100644 (file)
@@ -344,6 +344,32 @@ static inline unsigned int FH_MEM_CBBC_QUEUE(unsigned int chnl)
 #define RFH_RBDBUF_RBD0_LSB 0xA08300
 #define RFH_RBDBUF_RBD_LSB(q) (RFH_RBDBUF_RBD0_LSB + (q) * 8)
 
+/**
+ * RFH Status Register
+ *
+ * Bit fields:
+ *
+ * Bit 29: RBD_FETCH_IDLE
+ * This status flag is set by the RFH when there is no active RBD fetch from
+ * DRAM.
+ * Once the RFH RBD controller starts fetching (or when there is a pending
+ * RBD read response from DRAM), this flag is immediately turned off.
+ *
+ * Bit 30: SRAM_DMA_IDLE
+ * This status flag is set by the RFH when there is no active transaction from
+ * SRAM to DRAM.
+ * Once the SRAM to DRAM DMA is active, this flag is immediately turned off.
+ *
+ * Bit 31: RXF_DMA_IDLE
+ * This status flag is set by the RFH when there is no active transaction from
+ * RXF to DRAM.
+ * Once the RXF-to-DRAM DMA is active, this flag is immediately turned off.
+ */
+#define RFH_GEN_STATUS 0xA09808
+#define RBD_FETCH_IDLE BIT(29)
+#define SRAM_DMA_IDLE  BIT(30)
+#define RXF_DMA_IDLE   BIT(31)
+
 /* DMA configuration */
 #define RFH_RXF_DMA_CFG 0xA09820
 /* RB size */
index 8d4a60d..c1c3c6a 100644 (file)
@@ -173,9 +173,16 @@ static void iwl_pcie_write_prph_64_no_grab(struct iwl_trans *trans, u64 ofs,
  */
 int iwl_pcie_rx_stop(struct iwl_trans *trans)
 {
-       iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
-       return iwl_poll_direct_bit(trans, FH_MEM_RSSR_RX_STATUS_REG,
-                                  FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000);
+       if (trans->cfg->mq_rx_supported) {
+               iwl_write_prph(trans, RFH_RXF_DMA_CFG, 0);
+               return iwl_poll_prph_bit(trans, RFH_GEN_STATUS,
+                                          RXF_DMA_IDLE, RXF_DMA_IDLE, 1000);
+       } else {
+               iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
+               return iwl_poll_direct_bit(trans, FH_MEM_RSSR_RX_STATUS_REG,
+                                          FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE,
+                                          1000);
+       }
 }
 
 /*