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
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.
11 Change-Id: Ic20e240061278f77d703f652e1f7d959db8fac37
12 Signed-off-by: Lei Wei <quic_leiwei@quicinc.com>
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(+)
19 diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_port.c b/drivers/net/ethernet/qualcomm/ppe/ppe_port.c
20 index dcc13889089e..284ee14b8d03 100644
21 --- a/drivers/net/ethernet/qualcomm/ppe/ppe_port.c
22 +++ b/drivers/net/ethernet/qualcomm/ppe/ppe_port.c
24 /* PPE BM port start for PPE MAC ports */
25 #define PPE_BM_PORT_MAC_START 7
27 +/* Poll interval time to poll GMAC MIBs for overflow protection,
28 + * the time should ensure that the 32bit GMAC packet counter
29 + * register would not overflow within this time at line rate
30 + * speed for 64B packet size.
32 +#define PPE_GMIB_POLL_INTERVAL_MS 120000
34 +#define PPE_MAC_MIB_DESC(_s, _o, _n) \
41 +/* PPE MAC MIB description */
42 +struct ppe_mac_mib_info {
48 +/* PPE GMAC MIB statistics type */
49 +enum ppe_gmib_stats_type {
57 + gmib_rx_jumbofcserr,
58 + gmib_rx_jumboalignerr,
61 + gmib_rx_pkt128to255,
62 + gmib_rx_pkt256to511,
63 + gmib_rx_pkt512to1023,
64 + gmib_rx_pkt1024to1518,
65 + gmib_rx_pkt1519tomax,
76 + gmib_tx_pkt128to255,
77 + gmib_tx_pkt256to511,
78 + gmib_tx_pkt512to1023,
79 + gmib_tx_pkt1024to1518,
80 + gmib_tx_pkt1519tomax,
92 +/* PPE XGMAC MIB statistics type */
93 +enum ppe_xgmib_stats_type {
96 + xgmib_tx_broadcast_g,
97 + xgmib_tx_multicast_g,
99 + xgmib_tx_pkt65to127,
100 + xgmib_tx_pkt128to255,
101 + xgmib_tx_pkt256to511,
102 + xgmib_tx_pkt512to1023,
103 + xgmib_tx_pkt1024tomax,
105 + xgmib_tx_multicast,
106 + xgmib_tx_broadcast,
107 + xgmib_tx_underflow_err,
117 + xgmib_rx_broadcast_g,
118 + xgmib_rx_multicast_g,
121 + xgmib_rx_jabber_err,
122 + xgmib_rx_undersize_g,
123 + xgmib_rx_oversize_g,
125 + xgmib_rx_pkt65to127,
126 + xgmib_rx_pkt128to255,
127 + xgmib_rx_pkt256to511,
128 + xgmib_rx_pkt512to1023,
129 + xgmib_rx_pkt1024tomax,
130 + xgmib_rx_unicast_g,
132 + xgmib_rx_outofrange_err,
134 + xgmib_rx_fifo_overflow,
139 + xgmib_rx_drop_frames,
140 + xgmib_rx_drop_bytes,
143 /* PPE port clock and reset name */
144 static const char * const ppe_port_clk_rst_name[] = {
145 [PPE_PORT_CLK_RST_MAC] = "port_mac",
146 @@ -30,6 +146,322 @@ static const char * const ppe_port_clk_rst_name[] = {
147 [PPE_PORT_CLK_RST_TX] = "port_tx",
150 +/* PPE GMAC MIB statistics description information */
151 +static const struct ppe_mac_mib_info gmib_info[] = {
152 + PPE_MAC_MIB_DESC(4, GMAC_RXBROAD_ADDR, "rx_broadcast"),
153 + PPE_MAC_MIB_DESC(4, GMAC_RXPAUSE_ADDR, "rx_pause"),
154 + PPE_MAC_MIB_DESC(4, GMAC_RXMULTI_ADDR, "rx_multicast"),
155 + PPE_MAC_MIB_DESC(4, GMAC_RXFCSERR_ADDR, "rx_fcserr"),
156 + PPE_MAC_MIB_DESC(4, GMAC_RXALIGNERR_ADDR, "rx_alignerr"),
157 + PPE_MAC_MIB_DESC(4, GMAC_RXRUNT_ADDR, "rx_runt"),
158 + PPE_MAC_MIB_DESC(4, GMAC_RXFRAG_ADDR, "rx_frag"),
159 + PPE_MAC_MIB_DESC(4, GMAC_RXJUMBOFCSERR_ADDR, "rx_jumbofcserr"),
160 + PPE_MAC_MIB_DESC(4, GMAC_RXJUMBOALIGNERR_ADDR, "rx_jumboalignerr"),
161 + PPE_MAC_MIB_DESC(4, GMAC_RXPKT64_ADDR, "rx_pkt64"),
162 + PPE_MAC_MIB_DESC(4, GMAC_RXPKT65TO127_ADDR, "rx_pkt65to127"),
163 + PPE_MAC_MIB_DESC(4, GMAC_RXPKT128TO255_ADDR, "rx_pkt128to255"),
164 + PPE_MAC_MIB_DESC(4, GMAC_RXPKT256TO511_ADDR, "rx_pkt256to511"),
165 + PPE_MAC_MIB_DESC(4, GMAC_RXPKT512TO1023_ADDR, "rx_pkt512to1023"),
166 + PPE_MAC_MIB_DESC(4, GMAC_RXPKT1024TO1518_ADDR, "rx_pkt1024to1518"),
167 + PPE_MAC_MIB_DESC(4, GMAC_RXPKT1519TOX_ADDR, "rx_pkt1519tomax"),
168 + PPE_MAC_MIB_DESC(4, GMAC_RXTOOLONG_ADDR, "rx_toolong"),
169 + PPE_MAC_MIB_DESC(8, GMAC_RXBYTE_G_ADDR, "rx_bytes_g"),
170 + PPE_MAC_MIB_DESC(8, GMAC_RXBYTE_B_ADDR, "rx_bytes_b"),
171 + PPE_MAC_MIB_DESC(4, GMAC_RXUNI_ADDR, "rx_unicast"),
172 + PPE_MAC_MIB_DESC(4, GMAC_TXBROAD_ADDR, "tx_broadcast"),
173 + PPE_MAC_MIB_DESC(4, GMAC_TXPAUSE_ADDR, "tx_pause"),
174 + PPE_MAC_MIB_DESC(4, GMAC_TXMULTI_ADDR, "tx_multicast"),
175 + PPE_MAC_MIB_DESC(4, GMAC_TXUNDERRUN_ADDR, "tx_underrun"),
176 + PPE_MAC_MIB_DESC(4, GMAC_TXPKT64_ADDR, "tx_pkt64"),
177 + PPE_MAC_MIB_DESC(4, GMAC_TXPKT65TO127_ADDR, "tx_pkt65to127"),
178 + PPE_MAC_MIB_DESC(4, GMAC_TXPKT128TO255_ADDR, "tx_pkt128to255"),
179 + PPE_MAC_MIB_DESC(4, GMAC_TXPKT256TO511_ADDR, "tx_pkt256to511"),
180 + PPE_MAC_MIB_DESC(4, GMAC_TXPKT512TO1023_ADDR, "tx_pkt512to1023"),
181 + PPE_MAC_MIB_DESC(4, GMAC_TXPKT1024TO1518_ADDR, "tx_pkt1024to1518"),
182 + PPE_MAC_MIB_DESC(4, GMAC_TXPKT1519TOX_ADDR, "tx_pkt1519tomax"),
183 + PPE_MAC_MIB_DESC(8, GMAC_TXBYTE_ADDR, "tx_bytes"),
184 + PPE_MAC_MIB_DESC(4, GMAC_TXCOLLISIONS_ADDR, "tx_collisions"),
185 + PPE_MAC_MIB_DESC(4, GMAC_TXABORTCOL_ADDR, "tx_abortcol"),
186 + PPE_MAC_MIB_DESC(4, GMAC_TXMULTICOL_ADDR, "tx_multicol"),
187 + PPE_MAC_MIB_DESC(4, GMAC_TXSINGLECOL_ADDR, "tx_singlecol"),
188 + PPE_MAC_MIB_DESC(4, GMAC_TXEXCESSIVEDEFER_ADDR, "tx_excdeffer"),
189 + PPE_MAC_MIB_DESC(4, GMAC_TXDEFER_ADDR, "tx_deffer"),
190 + PPE_MAC_MIB_DESC(4, GMAC_TXLATECOL_ADDR, "tx_latecol"),
191 + PPE_MAC_MIB_DESC(4, GMAC_TXUNI_ADDR, "tx_unicast"),
194 +/* PPE XGMAC MIB statistics description information */
195 +static const struct ppe_mac_mib_info xgmib_info[] = {
196 + PPE_MAC_MIB_DESC(8, XGMAC_TXBYTE_GB_ADDR, "tx_bytes"),
197 + PPE_MAC_MIB_DESC(8, XGMAC_TXPKT_GB_ADDR, "tx_frames"),
198 + PPE_MAC_MIB_DESC(8, XGMAC_TXBROAD_G_ADDR, "tx_broadcast_g"),
199 + PPE_MAC_MIB_DESC(8, XGMAC_TXMULTI_G_ADDR, "tx_multicast_g"),
200 + PPE_MAC_MIB_DESC(8, XGMAC_TXPKT64_GB_ADDR, "tx_pkt64"),
201 + PPE_MAC_MIB_DESC(8, XGMAC_TXPKT65TO127_GB_ADDR, "tx_pkt65to127"),
202 + PPE_MAC_MIB_DESC(8, XGMAC_TXPKT128TO255_GB_ADDR, "tx_pkt128to255"),
203 + PPE_MAC_MIB_DESC(8, XGMAC_TXPKT256TO511_GB_ADDR, "tx_pkt256to511"),
204 + PPE_MAC_MIB_DESC(8, XGMAC_TXPKT512TO1023_GB_ADDR, "tx_pkt512to1023"),
205 + PPE_MAC_MIB_DESC(8, XGMAC_TXPKT1024TOMAX_GB_ADDR, "tx_pkt1024tomax"),
206 + PPE_MAC_MIB_DESC(8, XGMAC_TXUNI_GB_ADDR, "tx_unicast"),
207 + PPE_MAC_MIB_DESC(8, XGMAC_TXMULTI_GB_ADDR, "tx_multicast"),
208 + PPE_MAC_MIB_DESC(8, XGMAC_TXBROAD_GB_ADDR, "tx_broadcast"),
209 + PPE_MAC_MIB_DESC(8, XGMAC_TXUNDERFLOW_ERR_ADDR, "tx_underflow_err"),
210 + PPE_MAC_MIB_DESC(8, XGMAC_TXBYTE_G_ADDR, "tx_bytes_g"),
211 + PPE_MAC_MIB_DESC(8, XGMAC_TXPKT_G_ADDR, "tx_frames_g"),
212 + PPE_MAC_MIB_DESC(8, XGMAC_TXPAUSE_ADDR, "tx_pause"),
213 + PPE_MAC_MIB_DESC(8, XGMAC_TXVLAN_G_ADDR, "tx_vlan_g"),
214 + PPE_MAC_MIB_DESC(4, XGMAC_TXLPI_USEC_ADDR, "tx_lpi_usec"),
215 + PPE_MAC_MIB_DESC(4, XGMAC_TXLPI_TRAN_ADDR, "tx_lpi_tran"),
216 + PPE_MAC_MIB_DESC(8, XGMAC_RXPKT_GB_ADDR, "rx_frames"),
217 + PPE_MAC_MIB_DESC(8, XGMAC_RXBYTE_GB_ADDR, "rx_bytes"),
218 + PPE_MAC_MIB_DESC(8, XGMAC_RXBYTE_G_ADDR, "rx_bytes_g"),
219 + PPE_MAC_MIB_DESC(8, XGMAC_RXBROAD_G_ADDR, "rx_broadcast_g"),
220 + PPE_MAC_MIB_DESC(8, XGMAC_RXMULTI_G_ADDR, "rx_multicast_g"),
221 + PPE_MAC_MIB_DESC(8, XGMAC_RXCRC_ERR_ADDR, "rx_crc_err"),
222 + PPE_MAC_MIB_DESC(4, XGMAC_RXRUNT_ERR_ADDR, "rx_runt_err"),
223 + PPE_MAC_MIB_DESC(4, XGMAC_RXJABBER_ERR_ADDR, "rx_jabber_err"),
224 + PPE_MAC_MIB_DESC(4, XGMAC_RXUNDERSIZE_G_ADDR, "rx_undersize_g"),
225 + PPE_MAC_MIB_DESC(4, XGMAC_RXOVERSIZE_G_ADDR, "rx_oversize_g"),
226 + PPE_MAC_MIB_DESC(8, XGMAC_RXPKT64_GB_ADDR, "rx_pkt64"),
227 + PPE_MAC_MIB_DESC(8, XGMAC_RXPKT65TO127_GB_ADDR, "rx_pkt65to127"),
228 + PPE_MAC_MIB_DESC(8, XGMAC_RXPKT128TO255_GB_ADDR, "rx_pkt128to255"),
229 + PPE_MAC_MIB_DESC(8, XGMAC_RXPKT256TO511_GB_ADDR, "rx_pkt256to511"),
230 + PPE_MAC_MIB_DESC(8, XGMAC_RXPKT512TO1023_GB_ADDR, "rx_pkt512to1023"),
231 + PPE_MAC_MIB_DESC(8, XGMAC_RXPKT1024TOMAX_GB_ADDR, "rx_pkt1024tomax"),
232 + PPE_MAC_MIB_DESC(8, XGMAC_RXUNI_G_ADDR, "rx_unicast_g"),
233 + PPE_MAC_MIB_DESC(8, XGMAC_RXLEN_ERR_ADDR, "rx_len_err"),
234 + PPE_MAC_MIB_DESC(8, XGMAC_RXOUTOFRANGE_ADDR, "rx_outofrange_err"),
235 + PPE_MAC_MIB_DESC(8, XGMAC_RXPAUSE_ADDR, "rx_pause"),
236 + PPE_MAC_MIB_DESC(8, XGMAC_RXFIFOOVERFLOW_ADDR, "rx_fifo_overflow"),
237 + PPE_MAC_MIB_DESC(8, XGMAC_RXVLAN_GB_ADDR, "rx_vlan"),
238 + PPE_MAC_MIB_DESC(4, XGMAC_RXWATCHDOG_ERR_ADDR, "rx_wdog_err"),
239 + PPE_MAC_MIB_DESC(4, XGMAC_RXLPI_USEC_ADDR, "rx_lpi_usec"),
240 + PPE_MAC_MIB_DESC(4, XGMAC_RXLPI_TRAN_ADDR, "rx_lpi_tran"),
241 + PPE_MAC_MIB_DESC(8, XGMAC_RXDISCARD_GB_ADDR, "rx_drop_frames"),
242 + PPE_MAC_MIB_DESC(8, XGMAC_RXDISCARDBYTE_GB_ADDR, "rx_drop_bytes"),
245 +/* Get GMAC MIBs from registers and accumulate to PPE port GMIB stats array */
246 +static void ppe_port_gmib_update(struct ppe_port *ppe_port)
248 + struct ppe_device *ppe_dev = ppe_port->ppe_dev;
249 + const struct ppe_mac_mib_info *mib;
250 + int port = ppe_port->port_id;
254 + for (i = 0; i < ARRAY_SIZE(gmib_info); i++) {
255 + mib = &gmib_info[i];
256 + reg = PPE_PORT_GMAC_ADDR(port) + mib->offset;
258 + ret = regmap_read(ppe_dev->regmap, reg, &val);
260 + dev_warn(ppe_dev->dev, "%s: %d\n", __func__, ret);
264 + ppe_port->gmib_stats[i] += val;
265 + if (mib->size == 8) {
266 + ret = regmap_read(ppe_dev->regmap, reg + 4, &val);
268 + dev_warn(ppe_dev->dev, "%s: %d\n",
273 + ppe_port->gmib_stats[i] += (u64)val << 32;
278 +/* Polling task to read GMIB statistics to avoid GMIB 32bit register overflow */
279 +static void ppe_port_gmib_stats_poll(struct work_struct *work)
281 + struct ppe_port *ppe_port = container_of(work, struct ppe_port,
283 + spin_lock(&ppe_port->gmib_stats_lock);
284 + ppe_port_gmib_update(ppe_port);
285 + spin_unlock(&ppe_port->gmib_stats_lock);
287 + schedule_delayed_work(&ppe_port->gmib_read,
288 + msecs_to_jiffies(PPE_GMIB_POLL_INTERVAL_MS));
291 +/* Get the XGMAC MIB counter based on the specific MIB stats type */
292 +static u64 ppe_port_xgmib_get(struct ppe_port *ppe_port,
293 + enum ppe_xgmib_stats_type xgmib_type)
295 + struct ppe_device *ppe_dev = ppe_port->ppe_dev;
296 + const struct ppe_mac_mib_info *mib;
297 + int port = ppe_port->port_id;
302 + mib = &xgmib_info[xgmib_type];
303 + reg = PPE_PORT_XGMAC_ADDR(port) + mib->offset;
305 + ret = regmap_read(ppe_dev->regmap, reg, &val);
307 + dev_warn(ppe_dev->dev, "%s: %d\n", __func__, ret);
312 + if (mib->size == 8) {
313 + ret = regmap_read(ppe_dev->regmap, reg + 4, &val);
315 + dev_warn(ppe_dev->dev, "%s: %d\n", __func__, ret);
319 + data |= (u64)val << 32;
327 + * ppe_port_get_sset_count() - Get PPE port statistics string count
328 + * @ppe_port: PPE port
329 + * @sset: string set ID
331 + * Description: Get the MAC statistics string count for the PPE port
332 + * specified by @ppe_port.
334 + * Return: The count of the statistics string.
336 +int ppe_port_get_sset_count(struct ppe_port *ppe_port, int sset)
338 + if (sset != ETH_SS_STATS)
341 + if (ppe_port->mac_type == PPE_MAC_TYPE_GMAC)
342 + return ARRAY_SIZE(gmib_info);
344 + return ARRAY_SIZE(xgmib_info);
348 + * ppe_port_get_strings() - Get PPE port statistics strings
349 + * @ppe_port: PPE port
350 + * @stringset: string set ID
351 + * @data: pointer to statistics strings
353 + * Description: Get the MAC statistics stings for the PPE port
354 + * specified by @ppe_port. The strings are stored in the buffer
355 + * indicated by @data which used in the ethtool ops.
357 +void ppe_port_get_strings(struct ppe_port *ppe_port, u32 stringset, u8 *data)
361 + if (stringset != ETH_SS_STATS)
364 + if (ppe_port->mac_type == PPE_MAC_TYPE_GMAC) {
365 + for (i = 0; i < ARRAY_SIZE(gmib_info); i++)
366 + strscpy(data + i * ETH_GSTRING_LEN, gmib_info[i].name,
369 + for (i = 0; i < ARRAY_SIZE(xgmib_info); i++)
370 + strscpy(data + i * ETH_GSTRING_LEN, xgmib_info[i].name,
376 + * ppe_port_get_ethtool_stats() - Get PPE port ethtool statistics
377 + * @ppe_port: PPE port
378 + * @data: pointer to statistics data
380 + * Description: Get the MAC statistics for the PPE port specified
381 + * by @ppe_port. The statistics are stored in the buffer indicated
382 + * by @data which used in the ethtool ops.
384 +void ppe_port_get_ethtool_stats(struct ppe_port *ppe_port, u64 *data)
388 + if (ppe_port->mac_type == PPE_MAC_TYPE_GMAC) {
389 + spin_lock(&ppe_port->gmib_stats_lock);
391 + ppe_port_gmib_update(ppe_port);
392 + for (i = 0; i < ARRAY_SIZE(gmib_info); i++)
393 + data[i] = ppe_port->gmib_stats[i];
395 + spin_unlock(&ppe_port->gmib_stats_lock);
397 + for (i = 0; i < ARRAY_SIZE(xgmib_info); i++)
398 + data[i] = ppe_port_xgmib_get(ppe_port, i);
403 + * ppe_port_get_stats64() - Get PPE port statistics
404 + * @ppe_port: PPE port
405 + * @s: statistics pointer
407 + * Description: Get the MAC statistics for the PPE port specified
410 +void ppe_port_get_stats64(struct ppe_port *ppe_port,
411 + struct rtnl_link_stats64 *s)
413 + if (ppe_port->mac_type == PPE_MAC_TYPE_GMAC) {
414 + u64 *src = ppe_port->gmib_stats;
416 + spin_lock(&ppe_port->gmib_stats_lock);
418 + ppe_port_gmib_update(ppe_port);
420 + s->rx_packets = src[gmib_rx_unicast] +
421 + src[gmib_rx_broadcast] + src[gmib_rx_multicast];
423 + s->tx_packets = src[gmib_tx_unicast] +
424 + src[gmib_tx_broadcast] + src[gmib_tx_multicast];
426 + s->rx_bytes = src[gmib_rx_bytes_g];
427 + s->tx_bytes = src[gmib_tx_bytes];
428 + s->multicast = src[gmib_rx_multicast];
430 + s->rx_crc_errors = src[gmib_rx_fcserr] + src[gmib_rx_frag];
431 + s->rx_frame_errors = src[gmib_rx_alignerr];
432 + s->rx_errors = s->rx_crc_errors + s->rx_frame_errors;
433 + s->rx_dropped = src[gmib_rx_toolong] + s->rx_errors;
435 + s->tx_fifo_errors = src[gmib_tx_underrun];
436 + s->tx_aborted_errors = src[gmib_tx_abortcol];
437 + s->tx_errors = s->tx_fifo_errors + s->tx_aborted_errors;
438 + s->collisions = src[gmib_tx_collisions];
440 + spin_unlock(&ppe_port->gmib_stats_lock);
442 + s->multicast = ppe_port_xgmib_get(ppe_port, xgmib_rx_multicast_g);
444 + s->rx_packets = s->multicast;
445 + s->rx_packets += ppe_port_xgmib_get(ppe_port, xgmib_rx_unicast_g);
446 + s->rx_packets += ppe_port_xgmib_get(ppe_port, xgmib_rx_broadcast_g);
448 + s->tx_packets = ppe_port_xgmib_get(ppe_port, xgmib_tx_frames);
449 + s->rx_bytes = ppe_port_xgmib_get(ppe_port, xgmib_rx_bytes);
450 + s->tx_bytes = ppe_port_xgmib_get(ppe_port, xgmib_tx_bytes);
452 + s->rx_crc_errors = ppe_port_xgmib_get(ppe_port, xgmib_rx_crc_err);
453 + s->rx_fifo_errors = ppe_port_xgmib_get(ppe_port, xgmib_rx_fifo_overflow);
455 + s->rx_length_errors = ppe_port_xgmib_get(ppe_port, xgmib_rx_len_err);
456 + s->rx_errors = s->rx_crc_errors +
457 + s->rx_fifo_errors + s->rx_length_errors;
458 + s->rx_dropped = s->rx_errors;
460 + s->tx_fifo_errors = ppe_port_xgmib_get(ppe_port, xgmib_tx_underflow_err);
461 + s->tx_errors = s->tx_packets -
462 + ppe_port_xgmib_get(ppe_port, xgmib_tx_frames_g);
466 /* PPE port and MAC reset */
467 static int ppe_port_mac_reset(struct ppe_port *ppe_port)
469 @@ -261,6 +693,9 @@ static void ppe_port_mac_link_up(struct phylink_config *config,
470 int ret, port = ppe_port->port_id;
473 + /* Start GMIB statistics polling */
474 + schedule_delayed_work(&ppe_port->gmib_read, 0);
476 if (mac_type == PPE_MAC_TYPE_GMAC)
477 ret = ppe_port_gmac_link_up(ppe_port,
478 speed, duplex, tx_pause, rx_pause);
479 @@ -306,6 +741,9 @@ static void ppe_port_mac_link_down(struct phylink_config *config,
480 int ret, port = ppe_port->port_id;
483 + /* Stop GMIB statistics polling */
484 + cancel_delayed_work_sync(&ppe_port->gmib_read);
486 /* Disable PPE port TX */
487 reg = PPE_PORT_BRIDGE_CTRL_ADDR + PPE_PORT_BRIDGE_CTRL_INC * port;
488 ret = regmap_update_bits(ppe_dev->regmap, reg,
489 @@ -627,6 +1065,27 @@ static int ppe_port_mac_hw_init(struct ppe_port *ppe_port)
493 +/* PPE port MAC MIB work task initialization */
494 +static int ppe_port_mac_mib_work_init(struct ppe_port *ppe_port)
496 + struct ppe_device *ppe_dev = ppe_port->ppe_dev;
499 + gstats = devm_kzalloc(ppe_dev->dev,
500 + sizeof(*gstats) * ARRAY_SIZE(gmib_info),
505 + ppe_port->gmib_stats = gstats;
507 + spin_lock_init(&ppe_port->gmib_stats_lock);
508 + INIT_DELAYED_WORK(&ppe_port->gmib_read,
509 + ppe_port_gmib_stats_poll);
515 * ppe_port_mac_init() - Initialization of PPE ports for the PPE device
516 * @ppe_dev: PPE device
517 @@ -693,6 +1152,12 @@ int ppe_port_mac_init(struct ppe_device *ppe_dev)
521 + ret = ppe_port_mac_mib_work_init(&ppe_ports->port[i]);
523 + dev_err(ppe_dev->dev, "Failed to initialize MAC MIB work\n");
524 + goto err_port_node;
530 diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_port.h b/drivers/net/ethernet/qualcomm/ppe/ppe_port.h
531 index 194f65815011..a524d90e1446 100644
532 --- a/drivers/net/ethernet/qualcomm/ppe/ppe_port.h
533 +++ b/drivers/net/ethernet/qualcomm/ppe/ppe_port.h
536 #include <linux/phylink.h>
538 +struct rtnl_link_stats64;
541 * enum ppe_port_clk_rst_type - PPE port clock and reset ID type
542 * @PPE_PORT_CLK_RST_MAC: The clock and reset ID for port MAC
543 @@ -44,6 +46,9 @@ enum ppe_mac_type {
546 * @rstcs: Port resets
547 + * @gmib_read: Delay work task for GMAC MIB statistics polling function
548 + * @gmib_stats: GMAC MIB statistics array
549 + * @gmib_stats_lock: Lock to protect GMAC MIB statistics
552 struct phylink *phylink;
553 @@ -56,6 +61,9 @@ struct ppe_port {
555 struct clk *clks[PPE_PORT_CLK_RST_MAX];
556 struct reset_control *rstcs[PPE_PORT_CLK_RST_MAX];
557 + struct delayed_work gmib_read;
559 + spinlock_t gmib_stats_lock; /* Protects GMIB stats */
563 @@ -73,4 +81,9 @@ void ppe_port_mac_deinit(struct ppe_device *ppe_dev);
564 int ppe_port_phylink_setup(struct ppe_port *ppe_port,
565 struct net_device *netdev);
566 void ppe_port_phylink_destroy(struct ppe_port *ppe_port);
567 +int ppe_port_get_sset_count(struct ppe_port *ppe_port, int sset);
568 +void ppe_port_get_strings(struct ppe_port *ppe_port, u32 stringset, u8 *data);
569 +void ppe_port_get_ethtool_stats(struct ppe_port *ppe_port, u64 *data);
570 +void ppe_port_get_stats64(struct ppe_port *ppe_port,
571 + struct rtnl_link_stats64 *s);
573 diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
574 index 34b659ac0c37..2cd5bd9fa446 100644
575 --- a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
576 +++ b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
578 #define GMAC_MIB_CTRL_MASK \
579 (GMAC_MIB_RD_CLR | GMAC_MIB_RST | GMAC_MIB_EN)
581 +/* GMAC MIB counter registers */
582 +#define GMAC_RXBROAD_ADDR 0x40
583 +#define GMAC_RXPAUSE_ADDR 0x44
584 +#define GMAC_RXMULTI_ADDR 0x48
585 +#define GMAC_RXFCSERR_ADDR 0x4C
586 +#define GMAC_RXALIGNERR_ADDR 0x50
587 +#define GMAC_RXRUNT_ADDR 0x54
588 +#define GMAC_RXFRAG_ADDR 0x58
589 +#define GMAC_RXJUMBOFCSERR_ADDR 0x5C
590 +#define GMAC_RXJUMBOALIGNERR_ADDR 0x60
591 +#define GMAC_RXPKT64_ADDR 0x64
592 +#define GMAC_RXPKT65TO127_ADDR 0x68
593 +#define GMAC_RXPKT128TO255_ADDR 0x6C
594 +#define GMAC_RXPKT256TO511_ADDR 0x70
595 +#define GMAC_RXPKT512TO1023_ADDR 0x74
596 +#define GMAC_RXPKT1024TO1518_ADDR 0x78
597 +#define GMAC_RXPKT1519TOX_ADDR 0x7C
598 +#define GMAC_RXTOOLONG_ADDR 0x80
599 +#define GMAC_RXBYTE_G_ADDR 0x84
600 +#define GMAC_RXBYTE_B_ADDR 0x8C
601 +#define GMAC_RXUNI_ADDR 0x94
602 +#define GMAC_TXBROAD_ADDR 0xA0
603 +#define GMAC_TXPAUSE_ADDR 0xA4
604 +#define GMAC_TXMULTI_ADDR 0xA8
605 +#define GMAC_TXUNDERRUN_ADDR 0xAC
606 +#define GMAC_TXPKT64_ADDR 0xB0
607 +#define GMAC_TXPKT65TO127_ADDR 0xB4
608 +#define GMAC_TXPKT128TO255_ADDR 0xB8
609 +#define GMAC_TXPKT256TO511_ADDR 0xBC
610 +#define GMAC_TXPKT512TO1023_ADDR 0xC0
611 +#define GMAC_TXPKT1024TO1518_ADDR 0xC4
612 +#define GMAC_TXPKT1519TOX_ADDR 0xC8
613 +#define GMAC_TXBYTE_ADDR 0xCC
614 +#define GMAC_TXCOLLISIONS_ADDR 0xD4
615 +#define GMAC_TXABORTCOL_ADDR 0xD8
616 +#define GMAC_TXMULTICOL_ADDR 0xDC
617 +#define GMAC_TXSINGLECOL_ADDR 0xE0
618 +#define GMAC_TXEXCESSIVEDEFER_ADDR 0xE4
619 +#define GMAC_TXDEFER_ADDR 0xE8
620 +#define GMAC_TXLATECOL_ADDR 0xEC
621 +#define GMAC_TXUNI_ADDR 0xF0
623 /* XGMAC TX configuration register */
624 #define XGMAC_TX_CONFIG_ADDR 0x0
625 #define XGMAC_SPEED_M GENMASK(31, 29)
627 #define XGMAC_MCF BIT(3)
628 #define XGMAC_CNTRST BIT(0)
630 +/* XGMAC MIB counter registers */
631 +#define XGMAC_TXBYTE_GB_ADDR 0x814
632 +#define XGMAC_TXPKT_GB_ADDR 0x81C
633 +#define XGMAC_TXBROAD_G_ADDR 0x824
634 +#define XGMAC_TXMULTI_G_ADDR 0x82C
635 +#define XGMAC_TXPKT64_GB_ADDR 0x834
636 +#define XGMAC_TXPKT65TO127_GB_ADDR 0x83C
637 +#define XGMAC_TXPKT128TO255_GB_ADDR 0x844
638 +#define XGMAC_TXPKT256TO511_GB_ADDR 0x84C
639 +#define XGMAC_TXPKT512TO1023_GB_ADDR 0x854
640 +#define XGMAC_TXPKT1024TOMAX_GB_ADDR 0x85C
641 +#define XGMAC_TXUNI_GB_ADDR 0x864
642 +#define XGMAC_TXMULTI_GB_ADDR 0x86C
643 +#define XGMAC_TXBROAD_GB_ADDR 0x874
644 +#define XGMAC_TXUNDERFLOW_ERR_ADDR 0x87C
645 +#define XGMAC_TXBYTE_G_ADDR 0x884
646 +#define XGMAC_TXPKT_G_ADDR 0x88C
647 +#define XGMAC_TXPAUSE_ADDR 0x894
648 +#define XGMAC_TXVLAN_G_ADDR 0x89C
649 +#define XGMAC_TXLPI_USEC_ADDR 0x8A4
650 +#define XGMAC_TXLPI_TRAN_ADDR 0x8A8
651 +#define XGMAC_RXPKT_GB_ADDR 0x900
652 +#define XGMAC_RXBYTE_GB_ADDR 0x908
653 +#define XGMAC_RXBYTE_G_ADDR 0x910
654 +#define XGMAC_RXBROAD_G_ADDR 0x918
655 +#define XGMAC_RXMULTI_G_ADDR 0x920
656 +#define XGMAC_RXCRC_ERR_ADDR 0x928
657 +#define XGMAC_RXRUNT_ERR_ADDR 0x930
658 +#define XGMAC_RXJABBER_ERR_ADDR 0x934
659 +#define XGMAC_RXUNDERSIZE_G_ADDR 0x938
660 +#define XGMAC_RXOVERSIZE_G_ADDR 0x93C
661 +#define XGMAC_RXPKT64_GB_ADDR 0x940
662 +#define XGMAC_RXPKT65TO127_GB_ADDR 0x948
663 +#define XGMAC_RXPKT128TO255_GB_ADDR 0x950
664 +#define XGMAC_RXPKT256TO511_GB_ADDR 0x958
665 +#define XGMAC_RXPKT512TO1023_GB_ADDR 0x960
666 +#define XGMAC_RXPKT1024TOMAX_GB_ADDR 0x968
667 +#define XGMAC_RXUNI_G_ADDR 0x970
668 +#define XGMAC_RXLEN_ERR_ADDR 0x978
669 +#define XGMAC_RXOUTOFRANGE_ADDR 0x980
670 +#define XGMAC_RXPAUSE_ADDR 0x988
671 +#define XGMAC_RXFIFOOVERFLOW_ADDR 0x990
672 +#define XGMAC_RXVLAN_GB_ADDR 0x998
673 +#define XGMAC_RXWATCHDOG_ERR_ADDR 0x9A0
674 +#define XGMAC_RXLPI_USEC_ADDR 0x9A4
675 +#define XGMAC_RXLPI_TRAN_ADDR 0x9A8
676 +#define XGMAC_RXDISCARD_GB_ADDR 0x9AC
677 +#define XGMAC_RXDISCARDBYTE_GB_ADDR 0x9B4