stmmac: add tx_skbuff_dma to save descriptors used by PTP
[firefly-linux-kernel-4.4.55.git] / drivers / net / ethernet / stmicro / stmmac / stmmac_main.c
index ac166be325ede6e1f3946aeebe19d4d8d5b7dcc8..180eed7168c14b3c0641a5b8e91b5601c535a173 100644 (file)
@@ -661,6 +661,8 @@ static void init_dma_desc_rings(struct net_device *dev)
                                            GFP_KERNEL);
        priv->rx_skbuff = kmalloc_array(rxsize, sizeof(struct sk_buff *),
                                        GFP_KERNEL);
+       priv->tx_skbuff_dma = kmalloc_array(txsize, sizeof(dma_addr_t),
+                                       GFP_KERNEL);
        priv->tx_skbuff = kmalloc_array(txsize, sizeof(struct sk_buff *),
                                        GFP_KERNEL);
        if (netif_msg_drv(priv))
@@ -710,6 +712,7 @@ static void init_dma_desc_rings(struct net_device *dev)
                else
                        p = priv->dma_tx + i;
                p->des2 = 0;
+               priv->tx_skbuff_dma[i] = 0;
                priv->tx_skbuff[i] = NULL;
        }
 
@@ -748,12 +751,14 @@ static void dma_free_tx_skbufs(struct stmmac_priv *priv)
                        else
                                p = priv->dma_tx + i;
 
-                       if (p->des2)
-                               dma_unmap_single(priv->device, p->des2,
+                       if (priv->tx_skbuff_dma[i])
+                               dma_unmap_single(priv->device,
+                                                priv->tx_skbuff_dma[i],
                                                 priv->hw->desc->get_tx_len(p),
                                                 DMA_TO_DEVICE);
                        dev_kfree_skb_any(priv->tx_skbuff[i]);
                        priv->tx_skbuff[i] = NULL;
+                       priv->tx_skbuff_dma[i] = 0;
                }
        }
 }
@@ -783,6 +788,7 @@ static void free_dma_desc_resources(struct stmmac_priv *priv)
        }
        kfree(priv->rx_skbuff_dma);
        kfree(priv->rx_skbuff);
+       kfree(priv->tx_skbuff_dma);
        kfree(priv->tx_skbuff);
 }
 
@@ -854,10 +860,13 @@ static void stmmac_tx_clean(struct stmmac_priv *priv)
                TX_DBG("%s: curr %d, dirty %d\n", __func__,
                        priv->cur_tx, priv->dirty_tx);
 
-               if (likely(p->des2))
-                       dma_unmap_single(priv->device, p->des2,
+               if (likely(priv->tx_skbuff_dma[entry])) {
+                       dma_unmap_single(priv->device,
+                                        priv->tx_skbuff_dma[entry],
                                         priv->hw->desc->get_tx_len(p),
                                         DMA_TO_DEVICE);
+                       priv->tx_skbuff_dma[entry] = 0;
+               }
                if (priv->mode == STMMAC_RING_MODE)
                        priv->hw->ring->clean_desc3(p);
 
@@ -1423,6 +1432,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
        if (likely(!is_jumbo)) {
                desc->des2 = dma_map_single(priv->device, skb->data,
                                        nopaged_len, DMA_TO_DEVICE);
+               priv->tx_skbuff_dma[entry] = desc->des2;
                priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len,
                                                csum_insertion, priv->mode);
        } else
@@ -1441,6 +1451,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
                TX_DBG("\t[entry %d] segment len: %d\n", entry, len);
                desc->des2 = skb_frag_dma_map(priv->device, frag, 0, len,
                                              DMA_TO_DEVICE);
+               priv->tx_skbuff_dma[entry] = desc->des2;
                priv->tx_skbuff[entry] = NULL;
                priv->hw->desc->prepare_tx_desc(desc, 0, len, csum_insertion,
                                                priv->mode);