diff options
Diffstat (limited to 'drivers/net/ethernet/hisilicon/hns3/hns3_enet.c')
| -rw-r--r-- | drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 37 | 
1 files changed, 22 insertions, 15 deletions
| diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c index 468b8f07bf47..4b886a13e079 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c @@ -1847,7 +1847,6 @@ void hns3_shinfo_pack(struct skb_shared_info *shinfo, __u32 *size)  static int hns3_skb_linearize(struct hns3_enet_ring *ring,  			      struct sk_buff *skb, -			      u8 max_non_tso_bd_num,  			      unsigned int bd_num)  {  	/* 'bd_num == UINT_MAX' means the skb' fraglist has a @@ -1864,8 +1863,7 @@ static int hns3_skb_linearize(struct hns3_enet_ring *ring,  	 * will not help.  	 */  	if (skb->len > HNS3_MAX_TSO_SIZE || -	    (!skb_is_gso(skb) && skb->len > -	     HNS3_MAX_NON_TSO_SIZE(max_non_tso_bd_num))) { +	    (!skb_is_gso(skb) && skb->len > HNS3_MAX_NON_TSO_SIZE)) {  		u64_stats_update_begin(&ring->syncp);  		ring->stats.hw_limitation++;  		u64_stats_update_end(&ring->syncp); @@ -1900,8 +1898,7 @@ static int hns3_nic_maybe_stop_tx(struct hns3_enet_ring *ring,  			goto out;  		} -		if (hns3_skb_linearize(ring, skb, max_non_tso_bd_num, -				       bd_num)) +		if (hns3_skb_linearize(ring, skb, bd_num))  			return -ENOMEM;  		bd_num = hns3_tx_bd_count(skb->len); @@ -3258,6 +3255,7 @@ static void hns3_buffer_detach(struct hns3_enet_ring *ring, int i)  {  	hns3_unmap_buffer(ring, &ring->desc_cb[i]);  	ring->desc[i].addr = 0; +	ring->desc_cb[i].refill = 0;  }  static void hns3_free_buffer_detach(struct hns3_enet_ring *ring, int i, @@ -3336,6 +3334,7 @@ static int hns3_alloc_and_attach_buffer(struct hns3_enet_ring *ring, int i)  	ring->desc[i].addr = cpu_to_le64(ring->desc_cb[i].dma +  					 ring->desc_cb[i].page_offset); +	ring->desc_cb[i].refill = 1;  	return 0;  } @@ -3365,6 +3364,7 @@ static void hns3_replace_buffer(struct hns3_enet_ring *ring, int i,  {  	hns3_unmap_buffer(ring, &ring->desc_cb[i]);  	ring->desc_cb[i] = *res_cb; +	ring->desc_cb[i].refill = 1;  	ring->desc[i].addr = cpu_to_le64(ring->desc_cb[i].dma +  					 ring->desc_cb[i].page_offset);  	ring->desc[i].rx.bd_base_info = 0; @@ -3373,6 +3373,7 @@ static void hns3_replace_buffer(struct hns3_enet_ring *ring, int i,  static void hns3_reuse_buffer(struct hns3_enet_ring *ring, int i)  {  	ring->desc_cb[i].reuse_flag = 0; +	ring->desc_cb[i].refill = 1;  	ring->desc[i].addr = cpu_to_le64(ring->desc_cb[i].dma +  					 ring->desc_cb[i].page_offset);  	ring->desc[i].rx.bd_base_info = 0; @@ -3479,10 +3480,14 @@ static int hns3_desc_unused(struct hns3_enet_ring *ring)  	int ntc = ring->next_to_clean;  	int ntu = ring->next_to_use; +	if (unlikely(ntc == ntu && !ring->desc_cb[ntc].refill)) +		return ring->desc_num; +  	return ((ntc >= ntu) ? 0 : ring->desc_num) + ntc - ntu;  } -static void hns3_nic_alloc_rx_buffers(struct hns3_enet_ring *ring, +/* Return true if there is any allocation failure */ +static bool hns3_nic_alloc_rx_buffers(struct hns3_enet_ring *ring,  				      int cleand_count)  {  	struct hns3_desc_cb *desc_cb; @@ -3507,7 +3512,10 @@ static void hns3_nic_alloc_rx_buffers(struct hns3_enet_ring *ring,  				hns3_rl_err(ring_to_netdev(ring),  					    "alloc rx buffer failed: %d\n",  					    ret); -				break; + +				writel(i, ring->tqp->io_base + +				       HNS3_RING_RX_RING_HEAD_REG); +				return true;  			}  			hns3_replace_buffer(ring, ring->next_to_use, &res_cbs); @@ -3520,6 +3528,7 @@ static void hns3_nic_alloc_rx_buffers(struct hns3_enet_ring *ring,  	}  	writel(i, ring->tqp->io_base + HNS3_RING_RX_RING_HEAD_REG); +	return false;  }  static bool hns3_can_reuse_page(struct hns3_desc_cb *cb) @@ -3824,6 +3833,7 @@ static void hns3_rx_ring_move_fw(struct hns3_enet_ring *ring)  {  	ring->desc[ring->next_to_clean].rx.bd_base_info &=  		cpu_to_le32(~BIT(HNS3_RXD_VLD_B)); +	ring->desc_cb[ring->next_to_clean].refill = 0;  	ring->next_to_clean += 1;  	if (unlikely(ring->next_to_clean == ring->desc_num)) @@ -4170,6 +4180,7 @@ int hns3_clean_rx_ring(struct hns3_enet_ring *ring, int budget,  {  #define RCB_NOF_ALLOC_RX_BUFF_ONCE 16  	int unused_count = hns3_desc_unused(ring); +	bool failure = false;  	int recv_pkts = 0;  	int err; @@ -4178,9 +4189,9 @@ int hns3_clean_rx_ring(struct hns3_enet_ring *ring, int budget,  	while (recv_pkts < budget) {  		/* Reuse or realloc buffers */  		if (unused_count >= RCB_NOF_ALLOC_RX_BUFF_ONCE) { -			hns3_nic_alloc_rx_buffers(ring, unused_count); -			unused_count = hns3_desc_unused(ring) - -					ring->pending_buf; +			failure = failure || +				hns3_nic_alloc_rx_buffers(ring, unused_count); +			unused_count = 0;  		}  		/* Poll one pkt */ @@ -4199,11 +4210,7 @@ int hns3_clean_rx_ring(struct hns3_enet_ring *ring, int budget,  	}  out: -	/* Make all data has been write before submit */ -	if (unused_count > 0) -		hns3_nic_alloc_rx_buffers(ring, unused_count); - -	return recv_pkts; +	return failure ? budget : recv_pkts;  }  static void hns3_update_rx_int_coalesce(struct hns3_enet_tqp_vector *tqp_vector) |