Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[firefly-linux-kernel-4.4.55.git] / drivers / net / ethernet / stmicro / stmmac / chain_mode.c
index 688c3f4f1781c2e6a764c5985694d05630ca3f29..d234ab540b29101a825afacee7d58e27ef5186f5 100644 (file)
@@ -30,7 +30,7 @@
 
 static unsigned int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum)
 {
-       struct stmmac_priv *priv = (struct stmmac_priv *) p;
+       struct stmmac_priv *priv = (struct stmmac_priv *)p;
        unsigned int txsize = priv->dma_tx_size;
        unsigned int entry = priv->cur_tx % txsize;
        struct dma_desc *desc = priv->dma_tx + entry;
@@ -47,6 +47,7 @@ static unsigned int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum)
 
        desc->des2 = dma_map_single(priv->device, skb->data,
                                    bmax, DMA_TO_DEVICE);
+       priv->tx_skbuff_dma[entry] = desc->des2;
        priv->hw->desc->prepare_tx_desc(desc, 1, bmax, csum, STMMAC_CHAIN_MODE);
 
        while (len != 0) {
@@ -57,6 +58,7 @@ static unsigned int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum)
                        desc->des2 = dma_map_single(priv->device,
                                                    (skb->data + bmax * i),
                                                    bmax, DMA_TO_DEVICE);
+                       priv->tx_skbuff_dma[entry] = desc->des2;
                        priv->hw->desc->prepare_tx_desc(desc, 0, bmax, csum,
                                                        STMMAC_CHAIN_MODE);
                        priv->hw->desc->set_tx_owner(desc);
@@ -67,6 +69,7 @@ static unsigned int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum)
                        desc->des2 = dma_map_single(priv->device,
                                                    (skb->data + bmax * i), len,
                                                    DMA_TO_DEVICE);
+                       priv->tx_skbuff_dma[entry] = desc->des2;
                        priv->hw->desc->prepare_tx_desc(desc, 0, len, csum,
                                                        STMMAC_CHAIN_MODE);
                        priv->hw->desc->set_tx_owner(desc);
@@ -100,7 +103,7 @@ static void stmmac_init_dma_chain(void *des, dma_addr_t phy_addr,
        dma_addr_t dma_phy = phy_addr;
 
        if (extend_desc) {
-               struct dma_extended_desc *p = (struct dma_extended_desc *) des;
+               struct dma_extended_desc *p = (struct dma_extended_desc *)des;
                for (i = 0; i < (size - 1); i++) {
                        dma_phy += sizeof(struct dma_extended_desc);
                        p->basic.des3 = (unsigned int)dma_phy;
@@ -109,7 +112,7 @@ static void stmmac_init_dma_chain(void *des, dma_addr_t phy_addr,
                p->basic.des3 = (unsigned int)phy_addr;
 
        } else {
-               struct dma_desc *p = (struct dma_desc *) des;
+               struct dma_desc *p = (struct dma_desc *)des;
                for (i = 0; i < (size - 1); i++) {
                        dma_phy += sizeof(struct dma_desc);
                        p->des3 = (unsigned int)dma_phy;
@@ -119,8 +122,40 @@ static void stmmac_init_dma_chain(void *des, dma_addr_t phy_addr,
        }
 }
 
+static void stmmac_refill_desc3(void *priv_ptr, struct dma_desc *p)
+{
+       struct stmmac_priv *priv = (struct stmmac_priv *)priv_ptr;
+
+       if (priv->hwts_rx_en && !priv->extend_desc)
+               /* NOTE: Device will overwrite des3 with timestamp value if
+                * 1588-2002 time stamping is enabled, hence reinitialize it
+                * to keep explicit chaining in the descriptor.
+                */
+               p->des3 = (unsigned int)(priv->dma_rx_phy +
+                                        (((priv->dirty_rx) + 1) %
+                                         priv->dma_rx_size) *
+                                        sizeof(struct dma_desc));
+}
+
+static void stmmac_clean_desc3(void *priv_ptr, struct dma_desc *p)
+{
+       struct stmmac_priv *priv = (struct stmmac_priv *)priv_ptr;
+
+       if (priv->hw->desc->get_tx_ls(p) && !priv->extend_desc)
+               /* NOTE: Device will overwrite des3 with timestamp value if
+                * 1588-2002 time stamping is enabled, hence reinitialize it
+                * to keep explicit chaining in the descriptor.
+                */
+               p->des3 = (unsigned int)(priv->dma_tx_phy +
+                                        (((priv->dirty_tx + 1) %
+                                          priv->dma_tx_size) *
+                                         sizeof(struct dma_desc)));
+}
+
 const struct stmmac_chain_mode_ops chain_mode_ops = {
        .init = stmmac_init_dma_chain,
        .is_jumbo_frm = stmmac_is_jumbo_frm,
        .jumbo_frm = stmmac_jumbo_frm,
+       .refill_desc3 = stmmac_refill_desc3,
+       .clean_desc3 = stmmac_clean_desc3,
 };