| From foo@baz Sun Dec 31 11:13:15 CET 2017 |
| From: Fugang Duan <fugang.duan@nxp.com> |
| Date: Fri, 22 Dec 2017 17:12:09 +0800 |
| Subject: net: fec: unmap the xmit buffer that are not transferred by DMA |
| |
| From: Fugang Duan <fugang.duan@nxp.com> |
| |
| |
| [ Upstream commit 178e5f57a8d8f8fc5799a624b96fc31ef9a29ffa ] |
| |
| The enet IP only support 32 bit, it will use swiotlb buffer to do dma |
| mapping when xmit buffer DMA memory address is bigger than 4G in i.MX |
| platform. After stress suspend/resume test, it will print out: |
| |
| log: |
| [12826.352864] fec 5b040000.ethernet: swiotlb buffer is full (sz: 191 bytes) |
| [12826.359676] DMA: Out of SW-IOMMU space for 191 bytes at device 5b040000.ethernet |
| [12826.367110] fec 5b040000.ethernet eth0: Tx DMA memory map failed |
| |
| The issue is that the ready xmit buffers that are dma mapped but DMA still |
| don't copy them into fifo, once MAC restart, these DMA buffers are not unmapped. |
| So it should check the dma mapping buffer and unmap them. |
| |
| Signed-off-by: Fugang Duan <fugang.duan@nxp.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/net/ethernet/freescale/fec_main.c | 6 ++++++ |
| 1 file changed, 6 insertions(+) |
| |
| --- a/drivers/net/ethernet/freescale/fec_main.c |
| +++ b/drivers/net/ethernet/freescale/fec_main.c |
| @@ -813,6 +813,12 @@ static void fec_enet_bd_init(struct net_ |
| for (i = 0; i < txq->bd.ring_size; i++) { |
| /* Initialize the BD for every fragment in the page. */ |
| bdp->cbd_sc = cpu_to_fec16(0); |
| + if (bdp->cbd_bufaddr && |
| + !IS_TSO_HEADER(txq, fec32_to_cpu(bdp->cbd_bufaddr))) |
| + dma_unmap_single(&fep->pdev->dev, |
| + fec32_to_cpu(bdp->cbd_bufaddr), |
| + fec16_to_cpu(bdp->cbd_datlen), |
| + DMA_TO_DEVICE); |
| if (txq->tx_skbuff[i]) { |
| dev_kfree_skb_any(txq->tx_skbuff[i]); |
| txq->tx_skbuff[i] = NULL; |