]> git.ipfire.org Git - thirdparty/openwrt.git/blob
edf62dd057f15ca7df49d831abbb1716583f1830
[thirdparty/openwrt.git] /
1 From 3e8cb061bff0bf74503cd2f206ed5c599a1e7ff7 Mon Sep 17 00:00:00 2001
2 From: Lei Wei <quic_leiwei@quicinc.com>
3 Date: Thu, 29 Feb 2024 20:16:14 +0800
4 Subject: [PATCH 33/50] net: ethernet: qualcomm: Add PPE port MAC MIB
5 statistics functions
6
7 Add PPE port MAC MIB statistics functions which are used by netdev
8 ops and ethtool. For GMAC, a polling task is scheduled to read the
9 MIB counters periodically to avoid 32bit register counter overflow.
10
11 Change-Id: Ic20e240061278f77d703f652e1f7d959db8fac37
12 Signed-off-by: Lei Wei <quic_leiwei@quicinc.com>
13 ---
14 drivers/net/ethernet/qualcomm/ppe/ppe_port.c | 465 +++++++++++++++++++
15 drivers/net/ethernet/qualcomm/ppe/ppe_port.h | 13 +
16 drivers/net/ethernet/qualcomm/ppe/ppe_regs.h | 91 ++++
17 3 files changed, 569 insertions(+)
18
19 --- a/drivers/net/ethernet/qualcomm/ppe/ppe_port.c
20 +++ b/drivers/net/ethernet/qualcomm/ppe/ppe_port.c
21 @@ -23,6 +23,122 @@
22 /* PPE BM port start for PPE MAC ports */
23 #define PPE_BM_PORT_MAC_START 7
24
25 +/* Poll interval time to poll GMAC MIBs for overflow protection,
26 + * the time should ensure that the 32bit GMAC packet counter
27 + * register would not overflow within this time at line rate
28 + * speed for 64B packet size.
29 + */
30 +#define PPE_GMIB_POLL_INTERVAL_MS 120000
31 +
32 +#define PPE_MAC_MIB_DESC(_s, _o, _n) \
33 + { \
34 + .size = (_s), \
35 + .offset = (_o), \
36 + .name = (_n), \
37 + }
38 +
39 +/* PPE MAC MIB description */
40 +struct ppe_mac_mib_info {
41 + u32 size;
42 + u32 offset;
43 + const char *name;
44 +};
45 +
46 +/* PPE GMAC MIB statistics type */
47 +enum ppe_gmib_stats_type {
48 + gmib_rx_broadcast,
49 + gmib_rx_pause,
50 + gmib_rx_multicast,
51 + gmib_rx_fcserr,
52 + gmib_rx_alignerr,
53 + gmib_rx_runt,
54 + gmib_rx_frag,
55 + gmib_rx_jumbofcserr,
56 + gmib_rx_jumboalignerr,
57 + gmib_rx_pkt64,
58 + gmib_rx_pkt65to127,
59 + gmib_rx_pkt128to255,
60 + gmib_rx_pkt256to511,
61 + gmib_rx_pkt512to1023,
62 + gmib_rx_pkt1024to1518,
63 + gmib_rx_pkt1519tomax,
64 + gmib_rx_toolong,
65 + gmib_rx_bytes_g,
66 + gmib_rx_bytes_b,
67 + gmib_rx_unicast,
68 + gmib_tx_broadcast,
69 + gmib_tx_pause,
70 + gmib_tx_multicast,
71 + gmib_tx_underrun,
72 + gmib_tx_pkt64,
73 + gmib_tx_pkt65to127,
74 + gmib_tx_pkt128to255,
75 + gmib_tx_pkt256to511,
76 + gmib_tx_pkt512to1023,
77 + gmib_tx_pkt1024to1518,
78 + gmib_tx_pkt1519tomax,
79 + gmib_tx_bytes,
80 + gmib_tx_collisions,
81 + gmib_tx_abortcol,
82 + gmib_tx_multicol,
83 + gmib_tx_singlecol,
84 + gmib_tx_excdeffer,
85 + gmib_tx_deffer,
86 + gmib_tx_latecol,
87 + gmib_tx_unicast,
88 +};
89 +
90 +/* PPE XGMAC MIB statistics type */
91 +enum ppe_xgmib_stats_type {
92 + xgmib_tx_bytes,
93 + xgmib_tx_frames,
94 + xgmib_tx_broadcast_g,
95 + xgmib_tx_multicast_g,
96 + xgmib_tx_pkt64,
97 + xgmib_tx_pkt65to127,
98 + xgmib_tx_pkt128to255,
99 + xgmib_tx_pkt256to511,
100 + xgmib_tx_pkt512to1023,
101 + xgmib_tx_pkt1024tomax,
102 + xgmib_tx_unicast,
103 + xgmib_tx_multicast,
104 + xgmib_tx_broadcast,
105 + xgmib_tx_underflow_err,
106 + xgmib_tx_bytes_g,
107 + xgmib_tx_frames_g,
108 + xgmib_tx_pause,
109 + xgmib_tx_vlan_g,
110 + xgmib_tx_lpi_usec,
111 + xgmib_tx_lpi_tran,
112 + xgmib_rx_frames,
113 + xgmib_rx_bytes,
114 + xgmib_rx_bytes_g,
115 + xgmib_rx_broadcast_g,
116 + xgmib_rx_multicast_g,
117 + xgmib_rx_crc_err,
118 + xgmib_rx_runt_err,
119 + xgmib_rx_jabber_err,
120 + xgmib_rx_undersize_g,
121 + xgmib_rx_oversize_g,
122 + xgmib_rx_pkt64,
123 + xgmib_rx_pkt65to127,
124 + xgmib_rx_pkt128to255,
125 + xgmib_rx_pkt256to511,
126 + xgmib_rx_pkt512to1023,
127 + xgmib_rx_pkt1024tomax,
128 + xgmib_rx_unicast_g,
129 + xgmib_rx_len_err,
130 + xgmib_rx_outofrange_err,
131 + xgmib_rx_pause,
132 + xgmib_rx_fifo_overflow,
133 + xgmib_rx_vlan,
134 + xgmib_rx_wdog_err,
135 + xgmib_rx_lpi_usec,
136 + xgmib_rx_lpi_tran,
137 + xgmib_rx_drop_frames,
138 + xgmib_rx_drop_bytes,
139 +};
140 +
141 /* PPE port clock and reset name */
142 static const char * const ppe_port_clk_rst_name[] = {
143 [PPE_PORT_CLK_RST_MAC] = "port_mac",
144 @@ -30,6 +146,322 @@ static const char * const ppe_port_clk_r
145 [PPE_PORT_CLK_RST_TX] = "port_tx",
146 };
147
148 +/* PPE GMAC MIB statistics description information */
149 +static const struct ppe_mac_mib_info gmib_info[] = {
150 + PPE_MAC_MIB_DESC(4, GMAC_RXBROAD_ADDR, "rx_broadcast"),
151 + PPE_MAC_MIB_DESC(4, GMAC_RXPAUSE_ADDR, "rx_pause"),
152 + PPE_MAC_MIB_DESC(4, GMAC_RXMULTI_ADDR, "rx_multicast"),
153 + PPE_MAC_MIB_DESC(4, GMAC_RXFCSERR_ADDR, "rx_fcserr"),
154 + PPE_MAC_MIB_DESC(4, GMAC_RXALIGNERR_ADDR, "rx_alignerr"),
155 + PPE_MAC_MIB_DESC(4, GMAC_RXRUNT_ADDR, "rx_runt"),
156 + PPE_MAC_MIB_DESC(4, GMAC_RXFRAG_ADDR, "rx_frag"),
157 + PPE_MAC_MIB_DESC(4, GMAC_RXJUMBOFCSERR_ADDR, "rx_jumbofcserr"),
158 + PPE_MAC_MIB_DESC(4, GMAC_RXJUMBOALIGNERR_ADDR, "rx_jumboalignerr"),
159 + PPE_MAC_MIB_DESC(4, GMAC_RXPKT64_ADDR, "rx_pkt64"),
160 + PPE_MAC_MIB_DESC(4, GMAC_RXPKT65TO127_ADDR, "rx_pkt65to127"),
161 + PPE_MAC_MIB_DESC(4, GMAC_RXPKT128TO255_ADDR, "rx_pkt128to255"),
162 + PPE_MAC_MIB_DESC(4, GMAC_RXPKT256TO511_ADDR, "rx_pkt256to511"),
163 + PPE_MAC_MIB_DESC(4, GMAC_RXPKT512TO1023_ADDR, "rx_pkt512to1023"),
164 + PPE_MAC_MIB_DESC(4, GMAC_RXPKT1024TO1518_ADDR, "rx_pkt1024to1518"),
165 + PPE_MAC_MIB_DESC(4, GMAC_RXPKT1519TOX_ADDR, "rx_pkt1519tomax"),
166 + PPE_MAC_MIB_DESC(4, GMAC_RXTOOLONG_ADDR, "rx_toolong"),
167 + PPE_MAC_MIB_DESC(8, GMAC_RXBYTE_G_ADDR, "rx_bytes_g"),
168 + PPE_MAC_MIB_DESC(8, GMAC_RXBYTE_B_ADDR, "rx_bytes_b"),
169 + PPE_MAC_MIB_DESC(4, GMAC_RXUNI_ADDR, "rx_unicast"),
170 + PPE_MAC_MIB_DESC(4, GMAC_TXBROAD_ADDR, "tx_broadcast"),
171 + PPE_MAC_MIB_DESC(4, GMAC_TXPAUSE_ADDR, "tx_pause"),
172 + PPE_MAC_MIB_DESC(4, GMAC_TXMULTI_ADDR, "tx_multicast"),
173 + PPE_MAC_MIB_DESC(4, GMAC_TXUNDERRUN_ADDR, "tx_underrun"),
174 + PPE_MAC_MIB_DESC(4, GMAC_TXPKT64_ADDR, "tx_pkt64"),
175 + PPE_MAC_MIB_DESC(4, GMAC_TXPKT65TO127_ADDR, "tx_pkt65to127"),
176 + PPE_MAC_MIB_DESC(4, GMAC_TXPKT128TO255_ADDR, "tx_pkt128to255"),
177 + PPE_MAC_MIB_DESC(4, GMAC_TXPKT256TO511_ADDR, "tx_pkt256to511"),
178 + PPE_MAC_MIB_DESC(4, GMAC_TXPKT512TO1023_ADDR, "tx_pkt512to1023"),
179 + PPE_MAC_MIB_DESC(4, GMAC_TXPKT1024TO1518_ADDR, "tx_pkt1024to1518"),
180 + PPE_MAC_MIB_DESC(4, GMAC_TXPKT1519TOX_ADDR, "tx_pkt1519tomax"),
181 + PPE_MAC_MIB_DESC(8, GMAC_TXBYTE_ADDR, "tx_bytes"),
182 + PPE_MAC_MIB_DESC(4, GMAC_TXCOLLISIONS_ADDR, "tx_collisions"),
183 + PPE_MAC_MIB_DESC(4, GMAC_TXABORTCOL_ADDR, "tx_abortcol"),
184 + PPE_MAC_MIB_DESC(4, GMAC_TXMULTICOL_ADDR, "tx_multicol"),
185 + PPE_MAC_MIB_DESC(4, GMAC_TXSINGLECOL_ADDR, "tx_singlecol"),
186 + PPE_MAC_MIB_DESC(4, GMAC_TXEXCESSIVEDEFER_ADDR, "tx_excdeffer"),
187 + PPE_MAC_MIB_DESC(4, GMAC_TXDEFER_ADDR, "tx_deffer"),
188 + PPE_MAC_MIB_DESC(4, GMAC_TXLATECOL_ADDR, "tx_latecol"),
189 + PPE_MAC_MIB_DESC(4, GMAC_TXUNI_ADDR, "tx_unicast"),
190 +};
191 +
192 +/* PPE XGMAC MIB statistics description information */
193 +static const struct ppe_mac_mib_info xgmib_info[] = {
194 + PPE_MAC_MIB_DESC(8, XGMAC_TXBYTE_GB_ADDR, "tx_bytes"),
195 + PPE_MAC_MIB_DESC(8, XGMAC_TXPKT_GB_ADDR, "tx_frames"),
196 + PPE_MAC_MIB_DESC(8, XGMAC_TXBROAD_G_ADDR, "tx_broadcast_g"),
197 + PPE_MAC_MIB_DESC(8, XGMAC_TXMULTI_G_ADDR, "tx_multicast_g"),
198 + PPE_MAC_MIB_DESC(8, XGMAC_TXPKT64_GB_ADDR, "tx_pkt64"),
199 + PPE_MAC_MIB_DESC(8, XGMAC_TXPKT65TO127_GB_ADDR, "tx_pkt65to127"),
200 + PPE_MAC_MIB_DESC(8, XGMAC_TXPKT128TO255_GB_ADDR, "tx_pkt128to255"),
201 + PPE_MAC_MIB_DESC(8, XGMAC_TXPKT256TO511_GB_ADDR, "tx_pkt256to511"),
202 + PPE_MAC_MIB_DESC(8, XGMAC_TXPKT512TO1023_GB_ADDR, "tx_pkt512to1023"),
203 + PPE_MAC_MIB_DESC(8, XGMAC_TXPKT1024TOMAX_GB_ADDR, "tx_pkt1024tomax"),
204 + PPE_MAC_MIB_DESC(8, XGMAC_TXUNI_GB_ADDR, "tx_unicast"),
205 + PPE_MAC_MIB_DESC(8, XGMAC_TXMULTI_GB_ADDR, "tx_multicast"),
206 + PPE_MAC_MIB_DESC(8, XGMAC_TXBROAD_GB_ADDR, "tx_broadcast"),
207 + PPE_MAC_MIB_DESC(8, XGMAC_TXUNDERFLOW_ERR_ADDR, "tx_underflow_err"),
208 + PPE_MAC_MIB_DESC(8, XGMAC_TXBYTE_G_ADDR, "tx_bytes_g"),
209 + PPE_MAC_MIB_DESC(8, XGMAC_TXPKT_G_ADDR, "tx_frames_g"),
210 + PPE_MAC_MIB_DESC(8, XGMAC_TXPAUSE_ADDR, "tx_pause"),
211 + PPE_MAC_MIB_DESC(8, XGMAC_TXVLAN_G_ADDR, "tx_vlan_g"),
212 + PPE_MAC_MIB_DESC(4, XGMAC_TXLPI_USEC_ADDR, "tx_lpi_usec"),
213 + PPE_MAC_MIB_DESC(4, XGMAC_TXLPI_TRAN_ADDR, "tx_lpi_tran"),
214 + PPE_MAC_MIB_DESC(8, XGMAC_RXPKT_GB_ADDR, "rx_frames"),
215 + PPE_MAC_MIB_DESC(8, XGMAC_RXBYTE_GB_ADDR, "rx_bytes"),
216 + PPE_MAC_MIB_DESC(8, XGMAC_RXBYTE_G_ADDR, "rx_bytes_g"),
217 + PPE_MAC_MIB_DESC(8, XGMAC_RXBROAD_G_ADDR, "rx_broadcast_g"),
218 + PPE_MAC_MIB_DESC(8, XGMAC_RXMULTI_G_ADDR, "rx_multicast_g"),
219 + PPE_MAC_MIB_DESC(8, XGMAC_RXCRC_ERR_ADDR, "rx_crc_err"),
220 + PPE_MAC_MIB_DESC(4, XGMAC_RXRUNT_ERR_ADDR, "rx_runt_err"),
221 + PPE_MAC_MIB_DESC(4, XGMAC_RXJABBER_ERR_ADDR, "rx_jabber_err"),
222 + PPE_MAC_MIB_DESC(4, XGMAC_RXUNDERSIZE_G_ADDR, "rx_undersize_g"),
223 + PPE_MAC_MIB_DESC(4, XGMAC_RXOVERSIZE_G_ADDR, "rx_oversize_g"),
224 + PPE_MAC_MIB_DESC(8, XGMAC_RXPKT64_GB_ADDR, "rx_pkt64"),
225 + PPE_MAC_MIB_DESC(8, XGMAC_RXPKT65TO127_GB_ADDR, "rx_pkt65to127"),
226 + PPE_MAC_MIB_DESC(8, XGMAC_RXPKT128TO255_GB_ADDR, "rx_pkt128to255"),
227 + PPE_MAC_MIB_DESC(8, XGMAC_RXPKT256TO511_GB_ADDR, "rx_pkt256to511"),
228 + PPE_MAC_MIB_DESC(8, XGMAC_RXPKT512TO1023_GB_ADDR, "rx_pkt512to1023"),
229 + PPE_MAC_MIB_DESC(8, XGMAC_RXPKT1024TOMAX_GB_ADDR, "rx_pkt1024tomax"),
230 + PPE_MAC_MIB_DESC(8, XGMAC_RXUNI_G_ADDR, "rx_unicast_g"),
231 + PPE_MAC_MIB_DESC(8, XGMAC_RXLEN_ERR_ADDR, "rx_len_err"),
232 + PPE_MAC_MIB_DESC(8, XGMAC_RXOUTOFRANGE_ADDR, "rx_outofrange_err"),
233 + PPE_MAC_MIB_DESC(8, XGMAC_RXPAUSE_ADDR, "rx_pause"),
234 + PPE_MAC_MIB_DESC(8, XGMAC_RXFIFOOVERFLOW_ADDR, "rx_fifo_overflow"),
235 + PPE_MAC_MIB_DESC(8, XGMAC_RXVLAN_GB_ADDR, "rx_vlan"),
236 + PPE_MAC_MIB_DESC(4, XGMAC_RXWATCHDOG_ERR_ADDR, "rx_wdog_err"),
237 + PPE_MAC_MIB_DESC(4, XGMAC_RXLPI_USEC_ADDR, "rx_lpi_usec"),
238 + PPE_MAC_MIB_DESC(4, XGMAC_RXLPI_TRAN_ADDR, "rx_lpi_tran"),
239 + PPE_MAC_MIB_DESC(8, XGMAC_RXDISCARD_GB_ADDR, "rx_drop_frames"),
240 + PPE_MAC_MIB_DESC(8, XGMAC_RXDISCARDBYTE_GB_ADDR, "rx_drop_bytes"),
241 +};
242 +
243 +/* Get GMAC MIBs from registers and accumulate to PPE port GMIB stats array */
244 +static void ppe_port_gmib_update(struct ppe_port *ppe_port)
245 +{
246 + struct ppe_device *ppe_dev = ppe_port->ppe_dev;
247 + const struct ppe_mac_mib_info *mib;
248 + int port = ppe_port->port_id;
249 + u32 reg, val;
250 + int i, ret;
251 +
252 + for (i = 0; i < ARRAY_SIZE(gmib_info); i++) {
253 + mib = &gmib_info[i];
254 + reg = PPE_PORT_GMAC_ADDR(port) + mib->offset;
255 +
256 + ret = regmap_read(ppe_dev->regmap, reg, &val);
257 + if (ret) {
258 + dev_warn(ppe_dev->dev, "%s: %d\n", __func__, ret);
259 + continue;
260 + }
261 +
262 + ppe_port->gmib_stats[i] += val;
263 + if (mib->size == 8) {
264 + ret = regmap_read(ppe_dev->regmap, reg + 4, &val);
265 + if (ret) {
266 + dev_warn(ppe_dev->dev, "%s: %d\n",
267 + __func__, ret);
268 + continue;
269 + }
270 +
271 + ppe_port->gmib_stats[i] += (u64)val << 32;
272 + }
273 + }
274 +}
275 +
276 +/* Polling task to read GMIB statistics to avoid GMIB 32bit register overflow */
277 +static void ppe_port_gmib_stats_poll(struct work_struct *work)
278 +{
279 + struct ppe_port *ppe_port = container_of(work, struct ppe_port,
280 + gmib_read.work);
281 + spin_lock(&ppe_port->gmib_stats_lock);
282 + ppe_port_gmib_update(ppe_port);
283 + spin_unlock(&ppe_port->gmib_stats_lock);
284 +
285 + schedule_delayed_work(&ppe_port->gmib_read,
286 + msecs_to_jiffies(PPE_GMIB_POLL_INTERVAL_MS));
287 +}
288 +
289 +/* Get the XGMAC MIB counter based on the specific MIB stats type */
290 +static u64 ppe_port_xgmib_get(struct ppe_port *ppe_port,
291 + enum ppe_xgmib_stats_type xgmib_type)
292 +{
293 + struct ppe_device *ppe_dev = ppe_port->ppe_dev;
294 + const struct ppe_mac_mib_info *mib;
295 + int port = ppe_port->port_id;
296 + u32 reg, val;
297 + u64 data = 0;
298 + int ret;
299 +
300 + mib = &xgmib_info[xgmib_type];
301 + reg = PPE_PORT_XGMAC_ADDR(port) + mib->offset;
302 +
303 + ret = regmap_read(ppe_dev->regmap, reg, &val);
304 + if (ret) {
305 + dev_warn(ppe_dev->dev, "%s: %d\n", __func__, ret);
306 + goto data_return;
307 + }
308 +
309 + data = val;
310 + if (mib->size == 8) {
311 + ret = regmap_read(ppe_dev->regmap, reg + 4, &val);
312 + if (ret) {
313 + dev_warn(ppe_dev->dev, "%s: %d\n", __func__, ret);
314 + goto data_return;
315 + }
316 +
317 + data |= (u64)val << 32;
318 + }
319 +
320 +data_return:
321 + return data;
322 +}
323 +
324 +/**
325 + * ppe_port_get_sset_count() - Get PPE port statistics string count
326 + * @ppe_port: PPE port
327 + * @sset: string set ID
328 + *
329 + * Description: Get the MAC statistics string count for the PPE port
330 + * specified by @ppe_port.
331 + *
332 + * Return: The count of the statistics string.
333 + */
334 +int ppe_port_get_sset_count(struct ppe_port *ppe_port, int sset)
335 +{
336 + if (sset != ETH_SS_STATS)
337 + return 0;
338 +
339 + if (ppe_port->mac_type == PPE_MAC_TYPE_GMAC)
340 + return ARRAY_SIZE(gmib_info);
341 + else
342 + return ARRAY_SIZE(xgmib_info);
343 +}
344 +
345 +/**
346 + * ppe_port_get_strings() - Get PPE port statistics strings
347 + * @ppe_port: PPE port
348 + * @stringset: string set ID
349 + * @data: pointer to statistics strings
350 + *
351 + * Description: Get the MAC statistics stings for the PPE port
352 + * specified by @ppe_port. The strings are stored in the buffer
353 + * indicated by @data which used in the ethtool ops.
354 + */
355 +void ppe_port_get_strings(struct ppe_port *ppe_port, u32 stringset, u8 *data)
356 +{
357 + int i;
358 +
359 + if (stringset != ETH_SS_STATS)
360 + return;
361 +
362 + if (ppe_port->mac_type == PPE_MAC_TYPE_GMAC) {
363 + for (i = 0; i < ARRAY_SIZE(gmib_info); i++)
364 + strscpy(data + i * ETH_GSTRING_LEN, gmib_info[i].name,
365 + ETH_GSTRING_LEN);
366 + } else {
367 + for (i = 0; i < ARRAY_SIZE(xgmib_info); i++)
368 + strscpy(data + i * ETH_GSTRING_LEN, xgmib_info[i].name,
369 + ETH_GSTRING_LEN);
370 + }
371 +}
372 +
373 +/**
374 + * ppe_port_get_ethtool_stats() - Get PPE port ethtool statistics
375 + * @ppe_port: PPE port
376 + * @data: pointer to statistics data
377 + *
378 + * Description: Get the MAC statistics for the PPE port specified
379 + * by @ppe_port. The statistics are stored in the buffer indicated
380 + * by @data which used in the ethtool ops.
381 + */
382 +void ppe_port_get_ethtool_stats(struct ppe_port *ppe_port, u64 *data)
383 +{
384 + int i;
385 +
386 + if (ppe_port->mac_type == PPE_MAC_TYPE_GMAC) {
387 + spin_lock(&ppe_port->gmib_stats_lock);
388 +
389 + ppe_port_gmib_update(ppe_port);
390 + for (i = 0; i < ARRAY_SIZE(gmib_info); i++)
391 + data[i] = ppe_port->gmib_stats[i];
392 +
393 + spin_unlock(&ppe_port->gmib_stats_lock);
394 + } else {
395 + for (i = 0; i < ARRAY_SIZE(xgmib_info); i++)
396 + data[i] = ppe_port_xgmib_get(ppe_port, i);
397 + }
398 +}
399 +
400 +/**
401 + * ppe_port_get_stats64() - Get PPE port statistics
402 + * @ppe_port: PPE port
403 + * @s: statistics pointer
404 + *
405 + * Description: Get the MAC statistics for the PPE port specified
406 + * by @ppe_port.
407 + */
408 +void ppe_port_get_stats64(struct ppe_port *ppe_port,
409 + struct rtnl_link_stats64 *s)
410 +{
411 + if (ppe_port->mac_type == PPE_MAC_TYPE_GMAC) {
412 + u64 *src = ppe_port->gmib_stats;
413 +
414 + spin_lock(&ppe_port->gmib_stats_lock);
415 +
416 + ppe_port_gmib_update(ppe_port);
417 +
418 + s->rx_packets = src[gmib_rx_unicast] +
419 + src[gmib_rx_broadcast] + src[gmib_rx_multicast];
420 +
421 + s->tx_packets = src[gmib_tx_unicast] +
422 + src[gmib_tx_broadcast] + src[gmib_tx_multicast];
423 +
424 + s->rx_bytes = src[gmib_rx_bytes_g];
425 + s->tx_bytes = src[gmib_tx_bytes];
426 + s->multicast = src[gmib_rx_multicast];
427 +
428 + s->rx_crc_errors = src[gmib_rx_fcserr] + src[gmib_rx_frag];
429 + s->rx_frame_errors = src[gmib_rx_alignerr];
430 + s->rx_errors = s->rx_crc_errors + s->rx_frame_errors;
431 + s->rx_dropped = src[gmib_rx_toolong] + s->rx_errors;
432 +
433 + s->tx_fifo_errors = src[gmib_tx_underrun];
434 + s->tx_aborted_errors = src[gmib_tx_abortcol];
435 + s->tx_errors = s->tx_fifo_errors + s->tx_aborted_errors;
436 + s->collisions = src[gmib_tx_collisions];
437 +
438 + spin_unlock(&ppe_port->gmib_stats_lock);
439 + } else {
440 + s->multicast = ppe_port_xgmib_get(ppe_port, xgmib_rx_multicast_g);
441 +
442 + s->rx_packets = s->multicast;
443 + s->rx_packets += ppe_port_xgmib_get(ppe_port, xgmib_rx_unicast_g);
444 + s->rx_packets += ppe_port_xgmib_get(ppe_port, xgmib_rx_broadcast_g);
445 +
446 + s->tx_packets = ppe_port_xgmib_get(ppe_port, xgmib_tx_frames);
447 + s->rx_bytes = ppe_port_xgmib_get(ppe_port, xgmib_rx_bytes);
448 + s->tx_bytes = ppe_port_xgmib_get(ppe_port, xgmib_tx_bytes);
449 +
450 + s->rx_crc_errors = ppe_port_xgmib_get(ppe_port, xgmib_rx_crc_err);
451 + s->rx_fifo_errors = ppe_port_xgmib_get(ppe_port, xgmib_rx_fifo_overflow);
452 +
453 + s->rx_length_errors = ppe_port_xgmib_get(ppe_port, xgmib_rx_len_err);
454 + s->rx_errors = s->rx_crc_errors +
455 + s->rx_fifo_errors + s->rx_length_errors;
456 + s->rx_dropped = s->rx_errors;
457 +
458 + s->tx_fifo_errors = ppe_port_xgmib_get(ppe_port, xgmib_tx_underflow_err);
459 + s->tx_errors = s->tx_packets -
460 + ppe_port_xgmib_get(ppe_port, xgmib_tx_frames_g);
461 + }
462 +}
463 +
464 /* PPE port and MAC reset */
465 static int ppe_port_mac_reset(struct ppe_port *ppe_port)
466 {
467 @@ -261,6 +693,9 @@ static void ppe_port_mac_link_up(struct
468 int ret, port = ppe_port->port_id;
469 u32 reg, val;
470
471 + /* Start GMIB statistics polling */
472 + schedule_delayed_work(&ppe_port->gmib_read, 0);
473 +
474 if (mac_type == PPE_MAC_TYPE_GMAC)
475 ret = ppe_port_gmac_link_up(ppe_port,
476 speed, duplex, tx_pause, rx_pause);
477 @@ -306,6 +741,9 @@ static void ppe_port_mac_link_down(struc
478 int ret, port = ppe_port->port_id;
479 u32 reg;
480
481 + /* Stop GMIB statistics polling */
482 + cancel_delayed_work_sync(&ppe_port->gmib_read);
483 +
484 /* Disable PPE port TX */
485 reg = PPE_PORT_BRIDGE_CTRL_ADDR + PPE_PORT_BRIDGE_CTRL_INC * port;
486 ret = regmap_update_bits(ppe_dev->regmap, reg,
487 @@ -627,6 +1065,27 @@ static int ppe_port_mac_hw_init(struct p
488 return ret;
489 }
490
491 +/* PPE port MAC MIB work task initialization */
492 +static int ppe_port_mac_mib_work_init(struct ppe_port *ppe_port)
493 +{
494 + struct ppe_device *ppe_dev = ppe_port->ppe_dev;
495 + u64 *gstats;
496 +
497 + gstats = devm_kzalloc(ppe_dev->dev,
498 + sizeof(*gstats) * ARRAY_SIZE(gmib_info),
499 + GFP_KERNEL);
500 + if (!gstats)
501 + return -ENOMEM;
502 +
503 + ppe_port->gmib_stats = gstats;
504 +
505 + spin_lock_init(&ppe_port->gmib_stats_lock);
506 + INIT_DELAYED_WORK(&ppe_port->gmib_read,
507 + ppe_port_gmib_stats_poll);
508 +
509 + return 0;
510 +}
511 +
512 /**
513 * ppe_port_mac_init() - Initialization of PPE ports for the PPE device
514 * @ppe_dev: PPE device
515 @@ -693,6 +1152,12 @@ int ppe_port_mac_init(struct ppe_device
516 goto err_port_node;
517 }
518
519 + ret = ppe_port_mac_mib_work_init(&ppe_ports->port[i]);
520 + if (ret) {
521 + dev_err(ppe_dev->dev, "Failed to initialize MAC MIB work\n");
522 + goto err_port_node;
523 + }
524 +
525 i++;
526 }
527
528 --- a/drivers/net/ethernet/qualcomm/ppe/ppe_port.h
529 +++ b/drivers/net/ethernet/qualcomm/ppe/ppe_port.h
530 @@ -8,6 +8,8 @@
531
532 #include <linux/phylink.h>
533
534 +struct rtnl_link_stats64;
535 +
536 /**
537 * enum ppe_port_clk_rst_type - PPE port clock and reset ID type
538 * @PPE_PORT_CLK_RST_MAC: The clock and reset ID for port MAC
539 @@ -44,6 +46,9 @@ enum ppe_mac_type {
540 * @port_id: Port ID
541 * @clks: Port clocks
542 * @rstcs: Port resets
543 + * @gmib_read: Delay work task for GMAC MIB statistics polling function
544 + * @gmib_stats: GMAC MIB statistics array
545 + * @gmib_stats_lock: Lock to protect GMAC MIB statistics
546 */
547 struct ppe_port {
548 struct phylink *phylink;
549 @@ -56,6 +61,9 @@ struct ppe_port {
550 int port_id;
551 struct clk *clks[PPE_PORT_CLK_RST_MAX];
552 struct reset_control *rstcs[PPE_PORT_CLK_RST_MAX];
553 + struct delayed_work gmib_read;
554 + u64 *gmib_stats;
555 + spinlock_t gmib_stats_lock; /* Protects GMIB stats */
556 };
557
558 /**
559 @@ -73,4 +81,9 @@ void ppe_port_mac_deinit(struct ppe_devi
560 int ppe_port_phylink_setup(struct ppe_port *ppe_port,
561 struct net_device *netdev);
562 void ppe_port_phylink_destroy(struct ppe_port *ppe_port);
563 +int ppe_port_get_sset_count(struct ppe_port *ppe_port, int sset);
564 +void ppe_port_get_strings(struct ppe_port *ppe_port, u32 stringset, u8 *data);
565 +void ppe_port_get_ethtool_stats(struct ppe_port *ppe_port, u64 *data);
566 +void ppe_port_get_stats64(struct ppe_port *ppe_port,
567 + struct rtnl_link_stats64 *s);
568 #endif
569 --- a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
570 +++ b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
571 @@ -606,6 +606,48 @@
572 #define GMAC_MIB_CTRL_MASK \
573 (GMAC_MIB_RD_CLR | GMAC_MIB_RST | GMAC_MIB_EN)
574
575 +/* GMAC MIB counter registers */
576 +#define GMAC_RXBROAD_ADDR 0x40
577 +#define GMAC_RXPAUSE_ADDR 0x44
578 +#define GMAC_RXMULTI_ADDR 0x48
579 +#define GMAC_RXFCSERR_ADDR 0x4C
580 +#define GMAC_RXALIGNERR_ADDR 0x50
581 +#define GMAC_RXRUNT_ADDR 0x54
582 +#define GMAC_RXFRAG_ADDR 0x58
583 +#define GMAC_RXJUMBOFCSERR_ADDR 0x5C
584 +#define GMAC_RXJUMBOALIGNERR_ADDR 0x60
585 +#define GMAC_RXPKT64_ADDR 0x64
586 +#define GMAC_RXPKT65TO127_ADDR 0x68
587 +#define GMAC_RXPKT128TO255_ADDR 0x6C
588 +#define GMAC_RXPKT256TO511_ADDR 0x70
589 +#define GMAC_RXPKT512TO1023_ADDR 0x74
590 +#define GMAC_RXPKT1024TO1518_ADDR 0x78
591 +#define GMAC_RXPKT1519TOX_ADDR 0x7C
592 +#define GMAC_RXTOOLONG_ADDR 0x80
593 +#define GMAC_RXBYTE_G_ADDR 0x84
594 +#define GMAC_RXBYTE_B_ADDR 0x8C
595 +#define GMAC_RXUNI_ADDR 0x94
596 +#define GMAC_TXBROAD_ADDR 0xA0
597 +#define GMAC_TXPAUSE_ADDR 0xA4
598 +#define GMAC_TXMULTI_ADDR 0xA8
599 +#define GMAC_TXUNDERRUN_ADDR 0xAC
600 +#define GMAC_TXPKT64_ADDR 0xB0
601 +#define GMAC_TXPKT65TO127_ADDR 0xB4
602 +#define GMAC_TXPKT128TO255_ADDR 0xB8
603 +#define GMAC_TXPKT256TO511_ADDR 0xBC
604 +#define GMAC_TXPKT512TO1023_ADDR 0xC0
605 +#define GMAC_TXPKT1024TO1518_ADDR 0xC4
606 +#define GMAC_TXPKT1519TOX_ADDR 0xC8
607 +#define GMAC_TXBYTE_ADDR 0xCC
608 +#define GMAC_TXCOLLISIONS_ADDR 0xD4
609 +#define GMAC_TXABORTCOL_ADDR 0xD8
610 +#define GMAC_TXMULTICOL_ADDR 0xDC
611 +#define GMAC_TXSINGLECOL_ADDR 0xE0
612 +#define GMAC_TXEXCESSIVEDEFER_ADDR 0xE4
613 +#define GMAC_TXDEFER_ADDR 0xE8
614 +#define GMAC_TXLATECOL_ADDR 0xEC
615 +#define GMAC_TXUNI_ADDR 0xF0
616 +
617 /* XGMAC TX configuration register */
618 #define XGMAC_TX_CONFIG_ADDR 0x0
619 #define XGMAC_SPEED_M GENMASK(31, 29)
620 @@ -668,4 +710,53 @@
621 #define XGMAC_MCF BIT(3)
622 #define XGMAC_CNTRST BIT(0)
623
624 +/* XGMAC MIB counter registers */
625 +#define XGMAC_TXBYTE_GB_ADDR 0x814
626 +#define XGMAC_TXPKT_GB_ADDR 0x81C
627 +#define XGMAC_TXBROAD_G_ADDR 0x824
628 +#define XGMAC_TXMULTI_G_ADDR 0x82C
629 +#define XGMAC_TXPKT64_GB_ADDR 0x834
630 +#define XGMAC_TXPKT65TO127_GB_ADDR 0x83C
631 +#define XGMAC_TXPKT128TO255_GB_ADDR 0x844
632 +#define XGMAC_TXPKT256TO511_GB_ADDR 0x84C
633 +#define XGMAC_TXPKT512TO1023_GB_ADDR 0x854
634 +#define XGMAC_TXPKT1024TOMAX_GB_ADDR 0x85C
635 +#define XGMAC_TXUNI_GB_ADDR 0x864
636 +#define XGMAC_TXMULTI_GB_ADDR 0x86C
637 +#define XGMAC_TXBROAD_GB_ADDR 0x874
638 +#define XGMAC_TXUNDERFLOW_ERR_ADDR 0x87C
639 +#define XGMAC_TXBYTE_G_ADDR 0x884
640 +#define XGMAC_TXPKT_G_ADDR 0x88C
641 +#define XGMAC_TXPAUSE_ADDR 0x894
642 +#define XGMAC_TXVLAN_G_ADDR 0x89C
643 +#define XGMAC_TXLPI_USEC_ADDR 0x8A4
644 +#define XGMAC_TXLPI_TRAN_ADDR 0x8A8
645 +#define XGMAC_RXPKT_GB_ADDR 0x900
646 +#define XGMAC_RXBYTE_GB_ADDR 0x908
647 +#define XGMAC_RXBYTE_G_ADDR 0x910
648 +#define XGMAC_RXBROAD_G_ADDR 0x918
649 +#define XGMAC_RXMULTI_G_ADDR 0x920
650 +#define XGMAC_RXCRC_ERR_ADDR 0x928
651 +#define XGMAC_RXRUNT_ERR_ADDR 0x930
652 +#define XGMAC_RXJABBER_ERR_ADDR 0x934
653 +#define XGMAC_RXUNDERSIZE_G_ADDR 0x938
654 +#define XGMAC_RXOVERSIZE_G_ADDR 0x93C
655 +#define XGMAC_RXPKT64_GB_ADDR 0x940
656 +#define XGMAC_RXPKT65TO127_GB_ADDR 0x948
657 +#define XGMAC_RXPKT128TO255_GB_ADDR 0x950
658 +#define XGMAC_RXPKT256TO511_GB_ADDR 0x958
659 +#define XGMAC_RXPKT512TO1023_GB_ADDR 0x960
660 +#define XGMAC_RXPKT1024TOMAX_GB_ADDR 0x968
661 +#define XGMAC_RXUNI_G_ADDR 0x970
662 +#define XGMAC_RXLEN_ERR_ADDR 0x978
663 +#define XGMAC_RXOUTOFRANGE_ADDR 0x980
664 +#define XGMAC_RXPAUSE_ADDR 0x988
665 +#define XGMAC_RXFIFOOVERFLOW_ADDR 0x990
666 +#define XGMAC_RXVLAN_GB_ADDR 0x998
667 +#define XGMAC_RXWATCHDOG_ERR_ADDR 0x9A0
668 +#define XGMAC_RXLPI_USEC_ADDR 0x9A4
669 +#define XGMAC_RXLPI_TRAN_ADDR 0x9A8
670 +#define XGMAC_RXDISCARD_GB_ADDR 0x9AC
671 +#define XGMAC_RXDISCARDBYTE_GB_ADDR 0x9B4
672 +
673 #endif