amd-xgbe: Add per queue Tx and Rx statistics
authorLendacky, Thomas <Thomas.Lendacky@amd.com>
Fri, 18 Aug 2017 14:03:35 +0000 (09:03 -0500)
committerDavid S. Miller <davem@davemloft.net>
Fri, 18 Aug 2017 23:30:17 +0000 (16:30 -0700)
Add per queue Tx and Rx packet and byte counts.

Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/amd/xgbe/xgbe-dev.c
drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c
drivers/net/ethernet/amd/xgbe/xgbe.h

index 75a479caac03f5542916da4ae78b5a9578f680d0..a9784084202adce7774cbc939146c2372ecdeff2 100644 (file)
@@ -1609,6 +1609,7 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel)
        struct xgbe_ring_data *rdata;
        struct xgbe_ring_desc *rdesc;
        struct xgbe_packet_data *packet = &ring->packet_data;
+       unsigned int tx_packets, tx_bytes;
        unsigned int csum, tso, vlan;
        unsigned int tso_context, vlan_context;
        unsigned int tx_set_ic;
@@ -1618,6 +1619,9 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel)
 
        DBGPR("-->xgbe_dev_xmit\n");
 
+       tx_packets = packet->tx_packets;
+       tx_bytes = packet->tx_bytes;
+
        csum = XGMAC_GET_BITS(packet->attributes, TX_PACKET_ATTRIBUTES,
                              CSUM_ENABLE);
        tso = XGMAC_GET_BITS(packet->attributes, TX_PACKET_ATTRIBUTES,
@@ -1645,13 +1649,12 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel)
         *     - Addition of Tx frame count to the frame count since the
         *       last interrupt was set does not exceed the frame count setting
         */
-       ring->coalesce_count += packet->tx_packets;
+       ring->coalesce_count += tx_packets;
        if (!pdata->tx_frames)
                tx_set_ic = 0;
-       else if (packet->tx_packets > pdata->tx_frames)
+       else if (tx_packets > pdata->tx_frames)
                tx_set_ic = 1;
-       else if ((ring->coalesce_count % pdata->tx_frames) <
-                packet->tx_packets)
+       else if ((ring->coalesce_count % pdata->tx_frames) < tx_packets)
                tx_set_ic = 1;
        else
                tx_set_ic = 0;
@@ -1741,7 +1744,7 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel)
                XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, TCPHDRLEN,
                                  packet->tcp_header_len / 4);
 
-               pdata->ext_stats.tx_tso_packets += packet->tx_packets;
+               pdata->ext_stats.tx_tso_packets += tx_packets;
        } else {
                /* Enable CRC and Pad Insertion */
                XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, CPC, 0);
@@ -1789,8 +1792,11 @@ static void xgbe_dev_xmit(struct xgbe_channel *channel)
                XGMAC_SET_BITS_LE(rdesc->desc2, TX_NORMAL_DESC2, IC, 1);
 
        /* Save the Tx info to report back during cleanup */
-       rdata->tx.packets = packet->tx_packets;
-       rdata->tx.bytes = packet->tx_bytes;
+       rdata->tx.packets = tx_packets;
+       rdata->tx.bytes = tx_bytes;
+
+       pdata->ext_stats.txq_packets[channel->queue_index] += tx_packets;
+       pdata->ext_stats.txq_bytes[channel->queue_index] += tx_bytes;
 
        /* In case the Tx DMA engine is running, make sure everything
         * is written to the descriptor(s) before setting the OWN bit
@@ -1944,6 +1950,9 @@ static int xgbe_dev_read(struct xgbe_channel *channel)
                                       FRAME, 1);
        }
 
+       pdata->ext_stats.rxq_packets[channel->queue_index]++;
+       pdata->ext_stats.rxq_bytes[channel->queue_index] += rdata->rx.len;
+
        DBGPR("<--xgbe_dev_read: %s - descriptor=%u (cur=%d)\n", channel->name,
              ring->cur & (ring->rdesc_count - 1), ring->cur);
 
index 67a2e52ad25ddb9c54fac01f489094152f646eba..f80b186779b72182096a050351ddf3337234f6ea 100644 (file)
@@ -186,6 +186,7 @@ static const struct xgbe_stats xgbe_gstring_stats[] = {
 
 static void xgbe_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
 {
+       struct xgbe_prv_data *pdata = netdev_priv(netdev);
        int i;
 
        switch (stringset) {
@@ -195,6 +196,18 @@ static void xgbe_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
                               ETH_GSTRING_LEN);
                        data += ETH_GSTRING_LEN;
                }
+               for (i = 0; i < pdata->tx_ring_count; i++) {
+                       sprintf(data, "txq_%u_packets", i);
+                       data += ETH_GSTRING_LEN;
+                       sprintf(data, "txq_%u_bytes", i);
+                       data += ETH_GSTRING_LEN;
+               }
+               for (i = 0; i < pdata->rx_ring_count; i++) {
+                       sprintf(data, "rxq_%u_packets", i);
+                       data += ETH_GSTRING_LEN;
+                       sprintf(data, "rxq_%u_bytes", i);
+                       data += ETH_GSTRING_LEN;
+               }
                break;
        }
 }
@@ -211,15 +224,26 @@ static void xgbe_get_ethtool_stats(struct net_device *netdev,
                stat = (u8 *)pdata + xgbe_gstring_stats[i].stat_offset;
                *data++ = *(u64 *)stat;
        }
+       for (i = 0; i < pdata->tx_ring_count; i++) {
+               *data++ = pdata->ext_stats.txq_packets[i];
+               *data++ = pdata->ext_stats.txq_bytes[i];
+       }
+       for (i = 0; i < pdata->rx_ring_count; i++) {
+               *data++ = pdata->ext_stats.rxq_packets[i];
+               *data++ = pdata->ext_stats.rxq_bytes[i];
+       }
 }
 
 static int xgbe_get_sset_count(struct net_device *netdev, int stringset)
 {
+       struct xgbe_prv_data *pdata = netdev_priv(netdev);
        int ret;
 
        switch (stringset) {
        case ETH_SS_STATS:
-               ret = XGBE_STATS_COUNT;
+               ret = XGBE_STATS_COUNT +
+                     (pdata->tx_ring_count * 2) +
+                     (pdata->rx_ring_count * 2);
                break;
 
        default:
index 58bb455bf1a1984e2fcc1b4a952b4f94197d18ca..0e93155bc2d50c3ba553385b6e233f1e9d38c373 100644 (file)
@@ -668,6 +668,11 @@ struct xgbe_ext_stats {
        u64 tx_tso_packets;
        u64 rx_split_header_packets;
        u64 rx_buffer_unavailable;
+
+       u64 txq_packets[XGBE_MAX_DMA_CHANNELS];
+       u64 txq_bytes[XGBE_MAX_DMA_CHANNELS];
+       u64 rxq_packets[XGBE_MAX_DMA_CHANNELS];
+       u64 rxq_bytes[XGBE_MAX_DMA_CHANNELS];
 };
 
 struct xgbe_hw_if {