First git repo commit for the libreCMC project
[librecmc/librecmc.git] / target / linux / generic / patches-4.4 / 072-0002-bgmac-Add-support-for-ethtool-statistics.patch
1 From f6613d4fa937fa8388f2c1cb4e69ccc25e9e2336 Mon Sep 17 00:00:00 2001
2 From: Florian Fainelli <f.fainelli@gmail.com>
3 Date: Tue, 7 Jun 2016 15:06:14 -0700
4 Subject: [PATCH 2/3] bgmac: Add support for ethtool statistics
5
6 Read the statistics from the BGMAC's builtin MAC and return them to
7 user-space using the standard ethtool helpers.
8
9 Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
10 Signed-off-by: David S. Miller <davem@davemloft.net>
11 ---
12  drivers/net/ethernet/broadcom/bgmac.c | 124 ++++++++++++++++++++++++++++++++++
13  drivers/net/ethernet/broadcom/bgmac.h |   4 +-
14  2 files changed, 126 insertions(+), 2 deletions(-)
15
16 --- a/drivers/net/ethernet/broadcom/bgmac.c
17 +++ b/drivers/net/ethernet/broadcom/bgmac.c
18 @@ -1385,6 +1385,127 @@ static const struct net_device_ops bgmac
19   * ethtool_ops
20   **************************************************/
21  
22 +struct bgmac_stat {
23 +       u8 size;
24 +       u32 offset;
25 +       const char *name;
26 +};
27 +
28 +static struct bgmac_stat bgmac_get_strings_stats[] = {
29 +       { 8, BGMAC_TX_GOOD_OCTETS, "tx_good_octets" },
30 +       { 4, BGMAC_TX_GOOD_PKTS, "tx_good" },
31 +       { 8, BGMAC_TX_OCTETS, "tx_octets" },
32 +       { 4, BGMAC_TX_PKTS, "tx_pkts" },
33 +       { 4, BGMAC_TX_BROADCAST_PKTS, "tx_broadcast" },
34 +       { 4, BGMAC_TX_MULTICAST_PKTS, "tx_multicast" },
35 +       { 4, BGMAC_TX_LEN_64, "tx_64" },
36 +       { 4, BGMAC_TX_LEN_65_TO_127, "tx_65_127" },
37 +       { 4, BGMAC_TX_LEN_128_TO_255, "tx_128_255" },
38 +       { 4, BGMAC_TX_LEN_256_TO_511, "tx_256_511" },
39 +       { 4, BGMAC_TX_LEN_512_TO_1023, "tx_512_1023" },
40 +       { 4, BGMAC_TX_LEN_1024_TO_1522, "tx_1024_1522" },
41 +       { 4, BGMAC_TX_LEN_1523_TO_2047, "tx_1523_2047" },
42 +       { 4, BGMAC_TX_LEN_2048_TO_4095, "tx_2048_4095" },
43 +       { 4, BGMAC_TX_LEN_4096_TO_8191, "tx_4096_8191" },
44 +       { 4, BGMAC_TX_LEN_8192_TO_MAX, "tx_8192_max" },
45 +       { 4, BGMAC_TX_JABBER_PKTS, "tx_jabber" },
46 +       { 4, BGMAC_TX_OVERSIZE_PKTS, "tx_oversize" },
47 +       { 4, BGMAC_TX_FRAGMENT_PKTS, "tx_fragment" },
48 +       { 4, BGMAC_TX_UNDERRUNS, "tx_underruns" },
49 +       { 4, BGMAC_TX_TOTAL_COLS, "tx_total_cols" },
50 +       { 4, BGMAC_TX_SINGLE_COLS, "tx_single_cols" },
51 +       { 4, BGMAC_TX_MULTIPLE_COLS, "tx_multiple_cols" },
52 +       { 4, BGMAC_TX_EXCESSIVE_COLS, "tx_excessive_cols" },
53 +       { 4, BGMAC_TX_LATE_COLS, "tx_late_cols" },
54 +       { 4, BGMAC_TX_DEFERED, "tx_defered" },
55 +       { 4, BGMAC_TX_CARRIER_LOST, "tx_carrier_lost" },
56 +       { 4, BGMAC_TX_PAUSE_PKTS, "tx_pause" },
57 +       { 4, BGMAC_TX_UNI_PKTS, "tx_unicast" },
58 +       { 4, BGMAC_TX_Q0_PKTS, "tx_q0" },
59 +       { 8, BGMAC_TX_Q0_OCTETS, "tx_q0_octets" },
60 +       { 4, BGMAC_TX_Q1_PKTS, "tx_q1" },
61 +       { 8, BGMAC_TX_Q1_OCTETS, "tx_q1_octets" },
62 +       { 4, BGMAC_TX_Q2_PKTS, "tx_q2" },
63 +       { 8, BGMAC_TX_Q2_OCTETS, "tx_q2_octets" },
64 +       { 4, BGMAC_TX_Q3_PKTS, "tx_q3" },
65 +       { 8, BGMAC_TX_Q3_OCTETS, "tx_q3_octets" },
66 +       { 8, BGMAC_RX_GOOD_OCTETS, "rx_good_octets" },
67 +       { 4, BGMAC_RX_GOOD_PKTS, "rx_good" },
68 +       { 8, BGMAC_RX_OCTETS, "rx_octets" },
69 +       { 4, BGMAC_RX_PKTS, "rx_pkts" },
70 +       { 4, BGMAC_RX_BROADCAST_PKTS, "rx_broadcast" },
71 +       { 4, BGMAC_RX_MULTICAST_PKTS, "rx_multicast" },
72 +       { 4, BGMAC_RX_LEN_64, "rx_64" },
73 +       { 4, BGMAC_RX_LEN_65_TO_127, "rx_65_127" },
74 +       { 4, BGMAC_RX_LEN_128_TO_255, "rx_128_255" },
75 +       { 4, BGMAC_RX_LEN_256_TO_511, "rx_256_511" },
76 +       { 4, BGMAC_RX_LEN_512_TO_1023, "rx_512_1023" },
77 +       { 4, BGMAC_RX_LEN_1024_TO_1522, "rx_1024_1522" },
78 +       { 4, BGMAC_RX_LEN_1523_TO_2047, "rx_1523_2047" },
79 +       { 4, BGMAC_RX_LEN_2048_TO_4095, "rx_2048_4095" },
80 +       { 4, BGMAC_RX_LEN_4096_TO_8191, "rx_4096_8191" },
81 +       { 4, BGMAC_RX_LEN_8192_TO_MAX, "rx_8192_max" },
82 +       { 4, BGMAC_RX_JABBER_PKTS, "rx_jabber" },
83 +       { 4, BGMAC_RX_OVERSIZE_PKTS, "rx_oversize" },
84 +       { 4, BGMAC_RX_FRAGMENT_PKTS, "rx_fragment" },
85 +       { 4, BGMAC_RX_MISSED_PKTS, "rx_missed" },
86 +       { 4, BGMAC_RX_CRC_ALIGN_ERRS, "rx_crc_align" },
87 +       { 4, BGMAC_RX_UNDERSIZE, "rx_undersize" },
88 +       { 4, BGMAC_RX_CRC_ERRS, "rx_crc" },
89 +       { 4, BGMAC_RX_ALIGN_ERRS, "rx_align" },
90 +       { 4, BGMAC_RX_SYMBOL_ERRS, "rx_symbol" },
91 +       { 4, BGMAC_RX_PAUSE_PKTS, "rx_pause" },
92 +       { 4, BGMAC_RX_NONPAUSE_PKTS, "rx_nonpause" },
93 +       { 4, BGMAC_RX_SACHANGES, "rx_sa_changes" },
94 +       { 4, BGMAC_RX_UNI_PKTS, "rx_unicast" },
95 +};
96 +
97 +#define BGMAC_STATS_LEN        ARRAY_SIZE(bgmac_get_strings_stats)
98 +
99 +static int bgmac_get_sset_count(struct net_device *dev, int string_set)
100 +{
101 +       switch (string_set) {
102 +       case ETH_SS_STATS:
103 +               return BGMAC_STATS_LEN;
104 +       }
105 +
106 +       return -EOPNOTSUPP;
107 +}
108 +
109 +static void bgmac_get_strings(struct net_device *dev, u32 stringset,
110 +                             u8 *data)
111 +{
112 +       int i;
113 +
114 +       if (stringset != ETH_SS_STATS)
115 +               return;
116 +
117 +       for (i = 0; i < BGMAC_STATS_LEN; i++)
118 +               strlcpy(data + i * ETH_GSTRING_LEN,
119 +                       bgmac_get_strings_stats[i].name, ETH_GSTRING_LEN);
120 +}
121 +
122 +static void bgmac_get_ethtool_stats(struct net_device *dev,
123 +                                   struct ethtool_stats *ss, uint64_t *data)
124 +{
125 +       struct bgmac *bgmac = netdev_priv(dev);
126 +       const struct bgmac_stat *s;
127 +       unsigned int i;
128 +       u64 val;
129 +
130 +       if (!netif_running(dev))
131 +               return;
132 +
133 +       for (i = 0; i < BGMAC_STATS_LEN; i++) {
134 +               s = &bgmac_get_strings_stats[i];
135 +               val = 0;
136 +               if (s->size == 8)
137 +                       val = (u64)bgmac_read(bgmac, s->offset + 4) << 32;
138 +               val |= bgmac_read(bgmac, s->offset);
139 +               data[i] = val;
140 +       }
141 +}
142 +
143  static int bgmac_get_settings(struct net_device *net_dev,
144                               struct ethtool_cmd *cmd)
145  {
146 @@ -1409,6 +1530,9 @@ static void bgmac_get_drvinfo(struct net
147  }
148  
149  static const struct ethtool_ops bgmac_ethtool_ops = {
150 +       .get_strings            = bgmac_get_strings,
151 +       .get_sset_count         = bgmac_get_sset_count,
152 +       .get_ethtool_stats      = bgmac_get_ethtool_stats,
153         .get_settings           = bgmac_get_settings,
154         .set_settings           = bgmac_set_settings,
155         .get_drvinfo            = bgmac_get_drvinfo,
156 --- a/drivers/net/ethernet/broadcom/bgmac.h
157 +++ b/drivers/net/ethernet/broadcom/bgmac.h
158 @@ -123,7 +123,7 @@
159  #define BGMAC_TX_LEN_1024_TO_1522              0x334
160  #define BGMAC_TX_LEN_1523_TO_2047              0x338
161  #define BGMAC_TX_LEN_2048_TO_4095              0x33c
162 -#define BGMAC_TX_LEN_4095_TO_8191              0x340
163 +#define BGMAC_TX_LEN_4096_TO_8191              0x340
164  #define BGMAC_TX_LEN_8192_TO_MAX               0x344
165  #define BGMAC_TX_JABBER_PKTS                   0x348           /* Error */
166  #define BGMAC_TX_OVERSIZE_PKTS                 0x34c           /* Error */
167 @@ -166,7 +166,7 @@
168  #define BGMAC_RX_LEN_1024_TO_1522              0x3e4
169  #define BGMAC_RX_LEN_1523_TO_2047              0x3e8
170  #define BGMAC_RX_LEN_2048_TO_4095              0x3ec
171 -#define BGMAC_RX_LEN_4095_TO_8191              0x3f0
172 +#define BGMAC_RX_LEN_4096_TO_8191              0x3f0
173  #define BGMAC_RX_LEN_8192_TO_MAX               0x3f4
174  #define BGMAC_RX_JABBER_PKTS                   0x3f8           /* Error */
175  #define BGMAC_RX_OVERSIZE_PKTS                 0x3fc           /* Error */