diff options
Diffstat (limited to 'drivers/net/wireless/rtlwifi/pci.c')
| -rw-r--r-- | drivers/net/wireless/rtlwifi/pci.c | 31 | 
1 files changed, 23 insertions, 8 deletions
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index c70efb9a6e78..ec456f0d972e 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -578,6 +578,13 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio)  		else  			entry = (u8 *)(&ring->desc[ring->idx]); +		if (rtlpriv->cfg->ops->get_available_desc && +		    rtlpriv->cfg->ops->get_available_desc(hw, prio) <= 1) { +			RT_TRACE(rtlpriv, (COMP_INTR | COMP_SEND), DBG_DMESG, +				 "no available desc!\n"); +			return; +		} +  		if (!rtlpriv->cfg->ops->is_tx_desc_closed(hw, prio, ring->idx))  			return;  		ring->idx = (ring->idx + 1) % ring->entries; @@ -641,10 +648,9 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio)  		ieee80211_tx_status_irqsafe(hw, skb); -		if ((ring->entries - skb_queue_len(&ring->queue)) -				== 2) { +		if ((ring->entries - skb_queue_len(&ring->queue)) <= 4) { -			RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, +			RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG,  				 "more desc left, wake skb_queue@%d, ring->idx = %d, skb_queue_len = 0x%x\n",  				 prio, ring->idx,  				 skb_queue_len(&ring->queue)); @@ -793,7 +799,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)  			rx_remained_cnt =  				rtlpriv->cfg->ops->rx_desc_buff_remained_cnt(hw,  								      hw_queue); -			if (rx_remained_cnt < 1) +			if (rx_remained_cnt == 0)  				return;  		} else {	/* rx descriptor */ @@ -848,18 +854,18 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)  			else  				skb_reserve(skb, stats.rx_drvinfo_size +  					    stats.rx_bufshift); -  		} else {  			RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,  				 "skb->end - skb->tail = %d, len is %d\n",  				 skb->end - skb->tail, len); -			break; +			dev_kfree_skb_any(skb); +			goto new_trx_end;  		}  		/* handle command packet here */  		if (rtlpriv->cfg->ops->rx_command_packet &&  		    rtlpriv->cfg->ops->rx_command_packet(hw, stats, skb)) {  				dev_kfree_skb_any(skb); -				goto end; +				goto new_trx_end;  		}  		/* @@ -909,6 +915,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)  		} else {  			dev_kfree_skb_any(skb);  		} +new_trx_end:  		if (rtlpriv->use_new_trx_flow) {  			rtlpci->rx_ring[hw_queue].next_rx_rp += 1;  			rtlpci->rx_ring[hw_queue].next_rx_rp %= @@ -924,7 +931,6 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)  			rtlpriv->enter_ps = false;  			schedule_work(&rtlpriv->works.lps_change_work);  		} -end:  		skb = new_skb;  no_new:  		if (rtlpriv->use_new_trx_flow) { @@ -1688,6 +1694,15 @@ static int rtl_pci_tx(struct ieee80211_hw *hw,  		}  	} +	if (rtlpriv->cfg->ops->get_available_desc && +	    rtlpriv->cfg->ops->get_available_desc(hw, hw_queue) == 0) { +			RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, +				 "get_available_desc fail\n"); +			spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, +					       flags); +			return skb->len; +	} +  	if (ieee80211_is_data_qos(fc)) {  		tid = rtl_get_tid(skb);  		if (sta) {  | 

