summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
diff options
context:
space:
mode:
authorSara Sharon <sara.sharon@intel.com>2016-06-21 12:44:01 +0300
committerLuca Coelho <luciano.coelho@intel.com>2016-07-06 10:18:20 +0300
commitb1753c62c72fe70035498b28901f9a4bdcf2b92a (patch)
treedf7a7074fb671ab8f992be15066a6670f3c08bc8 /drivers/net/wireless/intel/iwlwifi/pcie/rx.c
parentf16c3ebfa64fdf0e2dc88e6baa72da95ab70ffd7 (diff)
downloadlinux-b1753c62c72fe70035498b28901f9a4bdcf2b92a.tar.xz
iwlwifi: pcie: track rxb status
In MQ environment and new architecture in early stages we may encounter DMA issues. Track RXB status and bail out in case we receive index to an RXB that was not mapped and handed over to HW. Signed-off-by: Sara Sharon <sara.sharon@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/pcie/rx.c')
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/rx.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
index 45f1b7e716a5..153b3084de0b 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
@@ -266,7 +266,7 @@ static void iwl_pcie_rxmq_restock(struct iwl_trans *trans,
rxb = list_first_entry(&rxq->rx_free, struct iwl_rx_mem_buffer,
list);
list_del(&rxb->list);
-
+ rxb->invalid = false;
/* 12 first bits are expected to be empty */
WARN_ON(rxb->page_dma & DMA_BIT_MASK(12));
/* Point to Rx buffer via next RBD in circular buffer */
@@ -317,6 +317,7 @@ static void iwl_pcie_rxsq_restock(struct iwl_trans *trans,
rxb = list_first_entry(&rxq->rx_free, struct iwl_rx_mem_buffer,
list);
list_del(&rxb->list);
+ rxb->invalid = false;
/* Point to Rx buffer via next RBD in circular buffer */
bd[rxq->write] = iwl_pcie_dma_addr2rbd_ptr(rxb->page_dma);
@@ -961,6 +962,7 @@ int iwl_pcie_rx_init(struct iwl_trans *trans)
list_add(&rxb->list, &def_rxq->rx_used);
trans_pcie->global_table[i] = rxb;
rxb->vid = (u16)(i + 1);
+ rxb->invalid = true;
}
iwl_pcie_rxq_alloc_rbs(trans, GFP_KERNEL, def_rxq);
@@ -1256,6 +1258,12 @@ restart:
goto out;
}
rxb = trans_pcie->global_table[vid - 1];
+ if (WARN(rxb->invalid,
+ "Invalid rxb from HW %u\n", (u32)vid)) {
+ iwl_force_nmi(trans);
+ goto out;
+ }
+ rxb->invalid = true;
} else {
rxb = rxq->queue[i];
rxq->queue[i] = NULL;