]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
ftgmac100: Remove tx descriptor accessors
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>
Mon, 10 Apr 2017 01:15:26 +0000 (11:15 +1000)
committerDavid S. Miller <davem@davemloft.net>
Mon, 10 Apr 2017 20:03:57 +0000 (16:03 -0400)
Directly access the fields when needed. The accessors add clutter
not clarity and in some cases cause unnecessary read-modify-write
type access on the slow (uncached) descriptor memory.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/faraday/ftgmac100.c
drivers/net/ethernet/faraday/ftgmac100.h

index abe2442673a02043b74f986099dddccf614533cd..7156f9ff6b7ef8e209daae4f88c00b08de56ddec 100644 (file)
@@ -468,77 +468,13 @@ static bool ftgmac100_rx_packet(struct ftgmac100 *priv, int *processed)
        return true;
 }
 
-static bool ftgmac100_txdes_owned_by_dma(struct ftgmac100_txdes *txdes)
+static u32 ftgmac100_base_tx_ctlstat(struct ftgmac100 *priv,
+                                    unsigned int index)
 {
-       return txdes->txdes0 & cpu_to_le32(FTGMAC100_TXDES0_TXDMA_OWN);
-}
-
-static void ftgmac100_txdes_set_dma_own(struct ftgmac100_txdes *txdes)
-{
-       txdes->txdes0 |= cpu_to_le32(FTGMAC100_TXDES0_TXDMA_OWN);
-}
-
-static void ftgmac100_txdes_set_end_of_ring(const struct ftgmac100 *priv,
-                                           struct ftgmac100_txdes *txdes)
-{
-       txdes->txdes0 |= cpu_to_le32(priv->txdes0_edotr_mask);
-}
-
-static void ftgmac100_txdes_set_first_segment(struct ftgmac100_txdes *txdes)
-{
-       txdes->txdes0 |= cpu_to_le32(FTGMAC100_TXDES0_FTS);
-}
-
-static inline bool ftgmac100_txdes_get_first_segment(struct ftgmac100_txdes *txdes)
-{
-       return (txdes->txdes0 & cpu_to_le32(FTGMAC100_TXDES0_FTS)) != 0;
-}
-
-static void ftgmac100_txdes_set_last_segment(struct ftgmac100_txdes *txdes)
-{
-       txdes->txdes0 |= cpu_to_le32(FTGMAC100_TXDES0_LTS);
-}
-
-static inline bool ftgmac100_txdes_get_last_segment(struct ftgmac100_txdes *txdes)
-{
-       return (txdes->txdes0 & cpu_to_le32(FTGMAC100_TXDES0_LTS)) != 0;
-}
-
-static void ftgmac100_txdes_set_buffer_size(struct ftgmac100_txdes *txdes,
-                                           unsigned int len)
-{
-       txdes->txdes0 |= cpu_to_le32(FTGMAC100_TXDES0_TXBUF_SIZE(len));
-}
-
-static inline unsigned int ftgmac100_txdes_get_buffer_size(struct ftgmac100_txdes *txdes)
-{
-       return FTGMAC100_TXDES0_TXBUF_SIZE(cpu_to_le32(txdes->txdes0));
-}
-
-static void ftgmac100_txdes_set_tcpcs(struct ftgmac100_txdes *txdes)
-{
-       txdes->txdes1 |= cpu_to_le32(FTGMAC100_TXDES1_TCP_CHKSUM);
-}
-
-static void ftgmac100_txdes_set_udpcs(struct ftgmac100_txdes *txdes)
-{
-       txdes->txdes1 |= cpu_to_le32(FTGMAC100_TXDES1_UDP_CHKSUM);
-}
-
-static void ftgmac100_txdes_set_ipcs(struct ftgmac100_txdes *txdes)
-{
-       txdes->txdes1 |= cpu_to_le32(FTGMAC100_TXDES1_IP_CHKSUM);
-}
-
-static void ftgmac100_txdes_set_dma_addr(struct ftgmac100_txdes *txdes,
-                                        dma_addr_t addr)
-{
-       txdes->txdes3 = cpu_to_le32(addr);
-}
-
-static dma_addr_t ftgmac100_txdes_get_dma_addr(struct ftgmac100_txdes *txdes)
-{
-       return (dma_addr_t)le32_to_cpu(txdes->txdes3);
+       if (index == (TX_QUEUE_ENTRIES - 1))
+               return priv->txdes0_edotr_mask;
+       else
+               return 0;
 }
 
 static int ftgmac100_next_tx_pointer(int pointer)
@@ -566,29 +502,24 @@ static bool ftgmac100_tx_buf_cleanable(struct ftgmac100 *priv)
 static void ftgmac100_free_tx_packet(struct ftgmac100 *priv,
                                     unsigned int pointer,
                                     struct sk_buff *skb,
-                                    struct ftgmac100_txdes *txdes)
+                                    struct ftgmac100_txdes *txdes,
+                                    u32 ctl_stat)
 {
-       dma_addr_t map = ftgmac100_txdes_get_dma_addr(txdes);
+       dma_addr_t map = le32_to_cpu(txdes->txdes3);
+       size_t len;
 
-       if (ftgmac100_txdes_get_first_segment(txdes)) {
-               dma_unmap_single(priv->dev, map, skb_headlen(skb),
-                                DMA_TO_DEVICE);
+       if (ctl_stat & FTGMAC100_TXDES0_FTS) {
+               len = skb_headlen(skb);
+               dma_unmap_single(priv->dev, map, len, DMA_TO_DEVICE);
        } else {
-               dma_unmap_page(priv->dev, map,
-                              ftgmac100_txdes_get_buffer_size(txdes),
-                              DMA_TO_DEVICE);
+               len = FTGMAC100_TXDES0_TXBUF_SIZE(ctl_stat);
+               dma_unmap_page(priv->dev, map, len, DMA_TO_DEVICE);
        }
 
-       if (ftgmac100_txdes_get_last_segment(txdes))
+       /* Free SKB on last segment */
+       if (ctl_stat & FTGMAC100_TXDES0_LTS)
                dev_kfree_skb(skb);
        priv->tx_skbs[pointer] = NULL;
-
-       /* Clear txdes0 except end of ring bit, clear txdes1 as we
-        * only "OR" into it, leave 2 and 3 alone as 2 is unused
-        * and 3 will be overwritten entirely
-        */
-       txdes->txdes0 &= cpu_to_le32(priv->txdes0_edotr_mask);
-       txdes->txdes1 = 0;
 }
 
 static bool ftgmac100_tx_complete_packet(struct ftgmac100 *priv)
@@ -597,17 +528,20 @@ static bool ftgmac100_tx_complete_packet(struct ftgmac100 *priv)
        struct ftgmac100_txdes *txdes;
        struct sk_buff *skb;
        unsigned int pointer;
+       u32 ctl_stat;
 
        pointer = priv->tx_clean_pointer;
        txdes = &priv->descs->txdes[pointer];
 
-       if (ftgmac100_txdes_owned_by_dma(txdes))
+       ctl_stat = le32_to_cpu(txdes->txdes0);
+       if (ctl_stat & FTGMAC100_TXDES0_TXDMA_OWN)
                return false;
 
        skb = priv->tx_skbs[pointer];
        netdev->stats.tx_packets++;
        netdev->stats.tx_bytes += skb->len;
-       ftgmac100_free_tx_packet(priv, pointer, skb, txdes);
+       ftgmac100_free_tx_packet(priv, pointer, skb, txdes, ctl_stat);
+       txdes->txdes0 = cpu_to_le32(ctl_stat & priv->txdes0_edotr_mask);
 
        priv->tx_clean_pointer = ftgmac100_next_tx_pointer(pointer);
 
@@ -644,6 +578,7 @@ static int ftgmac100_hard_start_xmit(struct sk_buff *skb,
        struct ftgmac100 *priv = netdev_priv(netdev);
        struct ftgmac100_txdes *txdes, *first;
        unsigned int pointer, nfrags, len, i, j;
+       u32 f_ctl_stat, ctl_stat, csum_vlan;
        dma_addr_t map;
 
        /* The HW doesn't pad small frames */
@@ -679,26 +614,34 @@ static int ftgmac100_hard_start_xmit(struct sk_buff *skb,
        pointer = priv->tx_pointer;
        txdes = first = &priv->descs->txdes[pointer];
 
-       /* Setup it up with the packet head. We don't set the OWN bit yet. */
+       /* Setup it up with the packet head. Don't write the head to the
+        * ring just yet
+        */
        priv->tx_skbs[pointer] = skb;
-       ftgmac100_txdes_set_dma_addr(txdes, map);
-       ftgmac100_txdes_set_buffer_size(txdes, len);
-       ftgmac100_txdes_set_first_segment(txdes);
+       f_ctl_stat = ftgmac100_base_tx_ctlstat(priv, pointer);
+       f_ctl_stat |= FTGMAC100_TXDES0_TXDMA_OWN;
+       f_ctl_stat |= FTGMAC100_TXDES0_TXBUF_SIZE(len);
+       f_ctl_stat |= FTGMAC100_TXDES0_FTS;
+       if (nfrags == 0)
+               f_ctl_stat |= FTGMAC100_TXDES0_LTS;
+       txdes->txdes3 = cpu_to_le32(map);
 
        /* Setup HW checksumming */
+       csum_vlan = 0;
        if (skb->ip_summed == CHECKSUM_PARTIAL) {
                __be16 protocol = skb->protocol;
 
                if (protocol == cpu_to_be16(ETH_P_IP)) {
                        u8 ip_proto = ip_hdr(skb)->protocol;
 
-                       ftgmac100_txdes_set_ipcs(txdes);
+                       csum_vlan |= FTGMAC100_TXDES1_IP_CHKSUM;
                        if (ip_proto == IPPROTO_TCP)
-                               ftgmac100_txdes_set_tcpcs(txdes);
+                               csum_vlan |= FTGMAC100_TXDES1_TCP_CHKSUM;
                        else if (ip_proto == IPPROTO_UDP)
-                               ftgmac100_txdes_set_udpcs(txdes);
+                               csum_vlan |= FTGMAC100_TXDES1_UDP_CHKSUM;
                }
        }
+       txdes->txdes1 = cpu_to_le32(csum_vlan);
 
        /* Next descriptor */
        pointer = ftgmac100_next_tx_pointer(pointer);
@@ -718,20 +661,24 @@ static int ftgmac100_hard_start_xmit(struct sk_buff *skb,
                /* Setup descriptor */
                priv->tx_skbs[pointer] = skb;
                txdes = &priv->descs->txdes[pointer];
-               ftgmac100_txdes_set_dma_addr(txdes, map);
-               ftgmac100_txdes_set_buffer_size(txdes, len);
-               ftgmac100_txdes_set_dma_own(txdes);
+               ctl_stat = ftgmac100_base_tx_ctlstat(priv, pointer);
+               ctl_stat |= FTGMAC100_TXDES0_TXDMA_OWN;
+               ctl_stat |= FTGMAC100_TXDES0_TXBUF_SIZE(len);
+               if (i == (nfrags - 1))
+                       ctl_stat |= FTGMAC100_TXDES0_LTS;
+               txdes->txdes0 = cpu_to_le32(ctl_stat);
+               txdes->txdes1 = 0;
+               txdes->txdes3 = cpu_to_le32(map);
+
+               /* Next one */
                pointer = ftgmac100_next_tx_pointer(pointer);
        }
 
-       /* Tag last fragment */
-       ftgmac100_txdes_set_last_segment(txdes);
-
        /* Order the previous packet and descriptor udpates
-        * before setting the OWN bit.
+        * before setting the OWN bit on the first descriptor.
         */
        dma_wmb();
-       ftgmac100_txdes_set_dma_own(first);
+       first->txdes0 = cpu_to_le32(f_ctl_stat);
 
        /* Update next TX pointer */
        priv->tx_pointer = pointer;
@@ -758,13 +705,16 @@ static int ftgmac100_hard_start_xmit(struct sk_buff *skb,
 
        /* Free head */
        pointer = priv->tx_pointer;
-       ftgmac100_free_tx_packet(priv, pointer, skb, first);
+       ftgmac100_free_tx_packet(priv, pointer, skb, first, f_ctl_stat);
+       first->txdes0 = cpu_to_le32(f_ctl_stat & priv->txdes0_edotr_mask);
 
        /* Then all fragments */
        for (j = 0; j < i; j++) {
                pointer = ftgmac100_next_tx_pointer(pointer);
                txdes = &priv->descs->txdes[pointer];
-               ftgmac100_free_tx_packet(priv, pointer, skb, txdes);
+               ctl_stat = le32_to_cpu(txdes->txdes0);
+               ftgmac100_free_tx_packet(priv, pointer, skb, txdes, ctl_stat);
+               txdes->txdes0 = cpu_to_le32(ctl_stat & priv->txdes0_edotr_mask);
        }
 
        /* This cannot be reached if we successfully mapped the
@@ -802,8 +752,10 @@ static void ftgmac100_free_buffers(struct ftgmac100 *priv)
                struct ftgmac100_txdes *txdes = &priv->descs->txdes[i];
                struct sk_buff *skb = priv->tx_skbs[i];
 
-               if (skb)
-                       ftgmac100_free_tx_packet(priv, i, skb, txdes);
+               if (!skb)
+                       continue;
+               ftgmac100_free_tx_packet(priv, i, skb, txdes,
+                                        le32_to_cpu(txdes->txdes0));
        }
 }
 
@@ -843,6 +795,7 @@ static int ftgmac100_alloc_rings(struct ftgmac100 *priv)
 static void ftgmac100_init_rings(struct ftgmac100 *priv)
 {
        struct ftgmac100_rxdes *rxdes;
+       struct ftgmac100_txdes *txdes;
        int i;
 
        /* Initialize RX ring */
@@ -855,9 +808,11 @@ static void ftgmac100_init_rings(struct ftgmac100 *priv)
        rxdes->rxdes0 |= cpu_to_le32(priv->rxdes0_edorr_mask);
 
        /* Initialize TX ring */
-       for (i = 0; i < TX_QUEUE_ENTRIES; i++)
-               priv->descs->txdes[i].txdes0 = 0;
-       ftgmac100_txdes_set_end_of_ring(priv, &priv->descs->txdes[i -1]);
+       for (i = 0; i < TX_QUEUE_ENTRIES; i++) {
+               txdes = &priv->descs->txdes[i];
+               txdes->txdes0 = 0;
+       }
+       txdes->txdes0 |= cpu_to_le32(priv->txdes0_edotr_mask);
 }
 
 static int ftgmac100_alloc_rx_buffers(struct ftgmac100 *priv)
index 9124785a4ab9be518982b08586c32c7ae1e51bf1..97912c456e800ac27aa7836a86fef4e777c66b84 100644 (file)
  * Transmit descriptor, aligned to 16 bytes
  */
 struct ftgmac100_txdes {
-       unsigned int    txdes0;
-       unsigned int    txdes1;
-       unsigned int    txdes2; /* not used by HW */
-       unsigned int    txdes3; /* TXBUF_BADR */
+       __le32  txdes0; /* Control & status bits */
+       __le32  txdes1; /* Irq, checksum and vlan control */
+       __le32  txdes2; /* Reserved */
+       __le32  txdes3; /* DMA buffer address */
 } __attribute__ ((aligned(16)));
 
 #define FTGMAC100_TXDES0_TXBUF_SIZE(x) ((x) & 0x3fff)