diff options
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/pcie/rx.c')
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 68 | 
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, | 
