Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / iwlwifi / pcie / rx.c
index 8389cd38338ba70766561d13c35591e1073faca6..4e6591d24e61be2ccccbdf0dd2d08ac1d0448aa3 100644 (file)
@@ -436,7 +436,7 @@ static int iwl_pcie_rx_alloc(struct iwl_trans *trans)
 err_rb_stts:
        dma_free_coherent(dev, sizeof(__le32) * RX_QUEUE_SIZE,
                          rxq->bd, rxq->bd_dma);
-       memset(&rxq->bd_dma, 0, sizeof(rxq->bd_dma));
+       rxq->bd_dma = 0;
        rxq->bd = NULL;
 err_bd:
        return -ENOMEM;
@@ -455,6 +455,10 @@ static void iwl_pcie_rx_hw_init(struct iwl_trans *trans, struct iwl_rxq *rxq)
 
        /* Stop Rx DMA */
        iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
+       /* reset and flush pointers */
+       iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_RBDCB_WPTR, 0);
+       iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_FLUSH_RB_REQ, 0);
+       iwl_write_direct32(trans, FH_RSCSR_CHNL0_RDPTR, 0);
 
        /* Reset driver's Rx queue write index */
        iwl_write_direct32(trans, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0);
@@ -491,7 +495,6 @@ int iwl_pcie_rx_init(struct iwl_trans *trans)
 {
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
        struct iwl_rxq *rxq = &trans_pcie->rxq;
-
        int i, err;
        unsigned long flags;
 
@@ -518,6 +521,7 @@ int iwl_pcie_rx_init(struct iwl_trans *trans)
        rxq->read = rxq->write = 0;
        rxq->write_actual = 0;
        rxq->free_count = 0;
+       memset(rxq->rb_stts, 0, sizeof(*rxq->rb_stts));
        spin_unlock_irqrestore(&rxq->lock, flags);
 
        iwl_pcie_rx_replenish(trans);
@@ -545,13 +549,15 @@ void iwl_pcie_rx_free(struct iwl_trans *trans)
                return;
        }
 
+       cancel_work_sync(&trans_pcie->rx_replenish);
+
        spin_lock_irqsave(&rxq->lock, flags);
        iwl_pcie_rxq_free_rbs(trans);
        spin_unlock_irqrestore(&rxq->lock, flags);
 
        dma_free_coherent(trans->dev, sizeof(__le32) * RX_QUEUE_SIZE,
                          rxq->bd, rxq->bd_dma);
-       memset(&rxq->bd_dma, 0, sizeof(rxq->bd_dma));
+       rxq->bd_dma = 0;
        rxq->bd = NULL;
 
        if (rxq->rb_stts)
@@ -560,7 +566,7 @@ void iwl_pcie_rx_free(struct iwl_trans *trans)
                                  rxq->rb_stts, rxq->rb_stts_dma);
        else
                IWL_DEBUG_INFO(trans, "Free rxq->rb_stts which is NULL\n");
-       memset(&rxq->rb_stts_dma, 0, sizeof(rxq->rb_stts_dma));
+       rxq->rb_stts_dma = 0;
        rxq->rb_stts = NULL;
 }