summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/pcie/rx.c')
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/rx.c68
1 files changed, 29 insertions, 39 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
index 2bec97133119..fb8491412be4 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
- * Copyright (C) 2003-2014, 2018-2020 Intel Corporation
+ * Copyright (C) 2003-2014, 2018-2021 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2016-2017 Intel Deutschland GmbH
*/
@@ -1023,6 +1023,9 @@ static int iwl_pcie_napi_poll(struct napi_struct *napi, int budget)
ret = iwl_pcie_rx_handle(trans, rxq->id, budget);
+ IWL_DEBUG_ISR(trans, "[%d] handled %d, budget %d\n",
+ rxq->id, ret, budget);
+
if (ret < budget) {
spin_lock(&trans_pcie->irq_lock);
if (test_bit(STATUS_INT_ENABLED, &trans->status))
@@ -1046,33 +1049,19 @@ static int iwl_pcie_napi_poll_msix(struct napi_struct *napi, int budget)
trans = trans_pcie->trans;
ret = iwl_pcie_rx_handle(trans, rxq->id, budget);
+ IWL_DEBUG_ISR(trans, "[%d] handled %d, budget %d\n", rxq->id, ret,
+ budget);
if (ret < budget) {
- spin_lock(&trans_pcie->irq_lock);
- iwl_pcie_clear_irq(trans, rxq->id);
- spin_unlock(&trans_pcie->irq_lock);
+ int irq_line = rxq->id;
- napi_complete_done(&rxq->napi, ret);
- }
+ /* FIRST_RSS is shared with line 0 */
+ if (trans_pcie->shared_vec_mask & IWL_SHARED_IRQ_FIRST_RSS &&
+ rxq->id == 1)
+ irq_line = 0;
- return ret;
-}
-
-static int iwl_pcie_napi_poll_msix_shared(struct napi_struct *napi, int budget)
-{
- struct iwl_rxq *rxq = container_of(napi, struct iwl_rxq, napi);
- struct iwl_trans_pcie *trans_pcie;
- struct iwl_trans *trans;
- int ret;
-
- trans_pcie = container_of(napi->dev, struct iwl_trans_pcie, napi_dev);
- trans = trans_pcie->trans;
-
- ret = iwl_pcie_rx_handle(trans, rxq->id, budget);
-
- if (ret < budget) {
spin_lock(&trans_pcie->irq_lock);
- iwl_pcie_clear_irq(trans, 0);
+ iwl_pcie_clear_irq(trans, irq_line);
spin_unlock(&trans_pcie->irq_lock);
napi_complete_done(&rxq->napi, ret);
@@ -1134,18 +1123,9 @@ static int _iwl_pcie_rx_init(struct iwl_trans *trans)
if (!rxq->napi.poll) {
int (*poll)(struct napi_struct *, int) = iwl_pcie_napi_poll;
- if (trans_pcie->msix_enabled) {
+ if (trans_pcie->msix_enabled)
poll = iwl_pcie_napi_poll_msix;
- if (trans_pcie->shared_vec_mask & IWL_SHARED_IRQ_NON_RX &&
- i == 0)
- poll = iwl_pcie_napi_poll_msix_shared;
-
- if (trans_pcie->shared_vec_mask & IWL_SHARED_IRQ_FIRST_RSS &&
- i == 1)
- poll = iwl_pcie_napi_poll_msix_shared;
- }
-
netif_napi_add(&trans_pcie->napi_dev, &rxq->napi,
poll, NAPI_POLL_WEIGHT);
napi_enable(&rxq->napi);
@@ -1659,10 +1639,13 @@ irqreturn_t iwl_pcie_irq_rx_msix_handler(int irq, void *dev_id)
if (WARN_ON(entry->entry >= trans->num_rx_queues))
return IRQ_NONE;
- if (WARN_ONCE(!rxq, "Got MSI-X interrupt before we have Rx queues"))
+ if (WARN_ONCE(!rxq,
+ "[%d] Got MSI-X interrupt before we have Rx queues",
+ entry->entry))
return IRQ_NONE;
lock_map_acquire(&trans->sync_cmd_lockdep_map);
+ IWL_DEBUG_ISR(trans, "[%d] Got interrupt\n", entry->entry);
local_bh_disable();
if (napi_schedule_prep(&rxq->napi))
@@ -2194,9 +2177,16 @@ irqreturn_t iwl_pcie_irq_msix_handler(int irq, void *dev_id)
struct iwl_trans_pcie *trans_pcie = iwl_pcie_get_trans_pcie(entry);
struct iwl_trans *trans = trans_pcie->trans;
struct isr_statistics *isr_stats = &trans_pcie->isr_stats;
+ u32 inta_fh_msk = ~MSIX_FH_INT_CAUSES_DATA_QUEUE;
u32 inta_fh, inta_hw;
bool polling = false;
+ if (trans_pcie->shared_vec_mask & IWL_SHARED_IRQ_NON_RX)
+ inta_fh_msk |= MSIX_FH_INT_CAUSES_Q0;
+
+ if (trans_pcie->shared_vec_mask & IWL_SHARED_IRQ_FIRST_RSS)
+ inta_fh_msk |= MSIX_FH_INT_CAUSES_Q1;
+
lock_map_acquire(&trans->sync_cmd_lockdep_map);
spin_lock_bh(&trans_pcie->irq_lock);
@@ -2205,7 +2195,7 @@ irqreturn_t iwl_pcie_irq_msix_handler(int irq, void *dev_id)
/*
* Clear causes registers to avoid being handling the same cause.
*/
- iwl_write32(trans, CSR_MSIX_FH_INT_CAUSES_AD, inta_fh);
+ iwl_write32(trans, CSR_MSIX_FH_INT_CAUSES_AD, inta_fh & inta_fh_msk);
iwl_write32(trans, CSR_MSIX_HW_INT_CAUSES_AD, inta_hw);
spin_unlock_bh(&trans_pcie->irq_lock);
@@ -2219,8 +2209,8 @@ irqreturn_t iwl_pcie_irq_msix_handler(int irq, void *dev_id)
if (iwl_have_debug_level(IWL_DL_ISR)) {
IWL_DEBUG_ISR(trans,
- "ISR inta_fh 0x%08x, enabled (sw) 0x%08x (hw) 0x%08x\n",
- inta_fh, trans_pcie->fh_mask,
+ "ISR[%d] inta_fh 0x%08x, enabled (sw) 0x%08x (hw) 0x%08x\n",
+ entry->entry, inta_fh, trans_pcie->fh_mask,
iwl_read32(trans, CSR_MSIX_FH_INT_MASK_AD));
if (inta_fh & ~trans_pcie->fh_mask)
IWL_DEBUG_ISR(trans,
@@ -2275,8 +2265,8 @@ irqreturn_t iwl_pcie_irq_msix_handler(int irq, void *dev_id)
/* After checking FH register check HW register */
if (iwl_have_debug_level(IWL_DL_ISR)) {
IWL_DEBUG_ISR(trans,
- "ISR inta_hw 0x%08x, enabled (sw) 0x%08x (hw) 0x%08x\n",
- inta_hw, trans_pcie->hw_mask,
+ "ISR[%d] inta_hw 0x%08x, enabled (sw) 0x%08x (hw) 0x%08x\n",
+ entry->entry, inta_hw, trans_pcie->hw_mask,
iwl_read32(trans, CSR_MSIX_HW_INT_MASK_AD));
if (inta_hw & ~trans_pcie->hw_mask)
IWL_DEBUG_ISR(trans,