diff options
Diffstat (limited to 'drivers/net/ethernet/freescale/fec_main.c')
| -rw-r--r-- | drivers/net/ethernet/freescale/fec_main.c | 19 | 
1 files changed, 14 insertions, 5 deletions
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 1b55047c0237..4566848e1d7c 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -1591,19 +1591,22 @@ static void fec_enet_tx(struct net_device *ndev, int budget)  		fec_enet_tx_queue(ndev, i, budget);  } -static void fec_enet_update_cbd(struct fec_enet_priv_rx_q *rxq, +static int fec_enet_update_cbd(struct fec_enet_priv_rx_q *rxq,  				struct bufdesc *bdp, int index)  {  	struct page *new_page;  	dma_addr_t phys_addr;  	new_page = page_pool_dev_alloc_pages(rxq->page_pool); -	WARN_ON(!new_page); -	rxq->rx_skb_info[index].page = new_page; +	if (unlikely(!new_page)) +		return -ENOMEM; +	rxq->rx_skb_info[index].page = new_page;  	rxq->rx_skb_info[index].offset = FEC_ENET_XDP_HEADROOM;  	phys_addr = page_pool_get_dma_addr(new_page) + FEC_ENET_XDP_HEADROOM;  	bdp->cbd_bufaddr = cpu_to_fec32(phys_addr); + +	return 0;  }  static u32 @@ -1698,6 +1701,7 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)  	int cpu = smp_processor_id();  	struct xdp_buff xdp;  	struct page *page; +	__fec32 cbd_bufaddr;  	u32 sub_len = 4;  #if !defined(CONFIG_M5272) @@ -1766,12 +1770,17 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)  		index = fec_enet_get_bd_index(bdp, &rxq->bd);  		page = rxq->rx_skb_info[index].page; +		cbd_bufaddr = bdp->cbd_bufaddr; +		if (fec_enet_update_cbd(rxq, bdp, index)) { +			ndev->stats.rx_dropped++; +			goto rx_processing_done; +		} +  		dma_sync_single_for_cpu(&fep->pdev->dev, -					fec32_to_cpu(bdp->cbd_bufaddr), +					fec32_to_cpu(cbd_bufaddr),  					pkt_len,  					DMA_FROM_DEVICE);  		prefetch(page_address(page)); -		fec_enet_update_cbd(rxq, bdp, index);  		if (xdp_prog) {  			xdp_buff_clear_frags_flag(&xdp);  | 
