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 --- a/drivers/net/ethernet/qualcomm/ppe/ppe_port.c
20 +++ b/drivers/net/ethernet/qualcomm/ppe/ppe_port.c
22 /* PPE BM port start for PPE MAC ports */
23 #define PPE_BM_PORT_MAC_START 7
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.
30 +#define PPE_GMIB_POLL_INTERVAL_MS 120000
32 +#define PPE_MAC_MIB_DESC(_s, _o, _n) \
39 +/* PPE MAC MIB description */
40 +struct ppe_mac_mib_info {
46 +/* PPE GMAC MIB statistics type */
47 +enum ppe_gmib_stats_type {
55 + gmib_rx_jumbofcserr,
56 + gmib_rx_jumboalignerr,
59 + gmib_rx_pkt128to255,
60 + gmib_rx_pkt256to511,
61 + gmib_rx_pkt512to1023,
62 + gmib_rx_pkt1024to1518,
63 + gmib_rx_pkt1519tomax,
74 + gmib_tx_pkt128to255,
75 + gmib_tx_pkt256to511,
76 + gmib_tx_pkt512to1023,
77 + gmib_tx_pkt1024to1518,
78 + gmib_tx_pkt1519tomax,
90 +/* PPE XGMAC MIB statistics type */
91 +enum ppe_xgmib_stats_type {
94 + xgmib_tx_broadcast_g,
95 + xgmib_tx_multicast_g,
97 + xgmib_tx_pkt65to127,
98 + xgmib_tx_pkt128to255,
99 + xgmib_tx_pkt256to511,
100 + xgmib_tx_pkt512to1023,
101 + xgmib_tx_pkt1024tomax,
103 + xgmib_tx_multicast,
104 + xgmib_tx_broadcast,
105 + xgmib_tx_underflow_err,
115 + xgmib_rx_broadcast_g,
116 + xgmib_rx_multicast_g,
119 + xgmib_rx_jabber_err,
120 + xgmib_rx_undersize_g,
121 + xgmib_rx_oversize_g,
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,
130 + xgmib_rx_outofrange_err,
132 + xgmib_rx_fifo_overflow,
137 + xgmib_rx_drop_frames,
138 + xgmib_rx_drop_bytes,
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",
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"),
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"),
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)
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;
252 + for (i = 0; i < ARRAY_SIZE(gmib_info); i++) {
253 + mib = &gmib_info[i];
254 + reg = PPE_PORT_GMAC_ADDR(port) + mib->offset;
256 + ret = regmap_read(ppe_dev->regmap, reg, &val);
258 + dev_warn(ppe_dev->dev, "%s: %d\n", __func__, ret);
262 + ppe_port->gmib_stats[i] += val;
263 + if (mib->size == 8) {
264 + ret = regmap_read(ppe_dev->regmap, reg + 4, &val);
266 + dev_warn(ppe_dev->dev, "%s: %d\n",
271 + ppe_port->gmib_stats[i] += (u64)val << 32;
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)
279 + struct ppe_port *ppe_port = container_of(work, struct ppe_port,
281 + spin_lock(&ppe_port->gmib_stats_lock);
282 + ppe_port_gmib_update(ppe_port);
283 + spin_unlock(&ppe_port->gmib_stats_lock);
285 + schedule_delayed_work(&ppe_port->gmib_read,
286 + msecs_to_jiffies(PPE_GMIB_POLL_INTERVAL_MS));
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)
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;
300 + mib = &xgmib_info[xgmib_type];
301 + reg = PPE_PORT_XGMAC_ADDR(port) + mib->offset;
303 + ret = regmap_read(ppe_dev->regmap, reg, &val);
305 + dev_warn(ppe_dev->dev, "%s: %d\n", __func__, ret);
310 + if (mib->size == 8) {
311 + ret = regmap_read(ppe_dev->regmap, reg + 4, &val);
313 + dev_warn(ppe_dev->dev, "%s: %d\n", __func__, ret);
317 + data |= (u64)val << 32;
325 + * ppe_port_get_sset_count() - Get PPE port statistics string count
326 + * @ppe_port: PPE port
327 + * @sset: string set ID
329 + * Description: Get the MAC statistics string count for the PPE port
330 + * specified by @ppe_port.
332 + * Return: The count of the statistics string.
334 +int ppe_port_get_sset_count(struct ppe_port *ppe_port, int sset)
336 + if (sset != ETH_SS_STATS)
339 + if (ppe_port->mac_type == PPE_MAC_TYPE_GMAC)
340 + return ARRAY_SIZE(gmib_info);
342 + return ARRAY_SIZE(xgmib_info);
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
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.
355 +void ppe_port_get_strings(struct ppe_port *ppe_port, u32 stringset, u8 *data)
359 + if (stringset != ETH_SS_STATS)
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,
367 + for (i = 0; i < ARRAY_SIZE(xgmib_info); i++)
368 + strscpy(data + i * ETH_GSTRING_LEN, xgmib_info[i].name,
374 + * ppe_port_get_ethtool_stats() - Get PPE port ethtool statistics
375 + * @ppe_port: PPE port
376 + * @data: pointer to statistics data
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.
382 +void ppe_port_get_ethtool_stats(struct ppe_port *ppe_port, u64 *data)
386 + if (ppe_port->mac_type == PPE_MAC_TYPE_GMAC) {
387 + spin_lock(&ppe_port->gmib_stats_lock);
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];
393 + spin_unlock(&ppe_port->gmib_stats_lock);
395 + for (i = 0; i < ARRAY_SIZE(xgmib_info); i++)
396 + data[i] = ppe_port_xgmib_get(ppe_port, i);
401 + * ppe_port_get_stats64() - Get PPE port statistics
402 + * @ppe_port: PPE port
403 + * @s: statistics pointer
405 + * Description: Get the MAC statistics for the PPE port specified
408 +void ppe_port_get_stats64(struct ppe_port *ppe_port,
409 + struct rtnl_link_stats64 *s)
411 + if (ppe_port->mac_type == PPE_MAC_TYPE_GMAC) {
412 + u64 *src = ppe_port->gmib_stats;
414 + spin_lock(&ppe_port->gmib_stats_lock);
416 + ppe_port_gmib_update(ppe_port);
418 + s->rx_packets = src[gmib_rx_unicast] +
419 + src[gmib_rx_broadcast] + src[gmib_rx_multicast];
421 + s->tx_packets = src[gmib_tx_unicast] +
422 + src[gmib_tx_broadcast] + src[gmib_tx_multicast];
424 + s->rx_bytes = src[gmib_rx_bytes_g];
425 + s->tx_bytes = src[gmib_tx_bytes];
426 + s->multicast = src[gmib_rx_multicast];
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;
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];
438 + spin_unlock(&ppe_port->gmib_stats_lock);
440 + s->multicast = ppe_port_xgmib_get(ppe_port, xgmib_rx_multicast_g);
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);
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);
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);
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;
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);
464 /* PPE port and MAC reset */
465 static int ppe_port_mac_reset(struct ppe_port *ppe_port)
467 @@ -261,6 +693,9 @@ static void ppe_port_mac_link_up(struct
468 int ret, port = ppe_port->port_id;
471 + /* Start GMIB statistics polling */
472 + schedule_delayed_work(&ppe_port->gmib_read, 0);
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;
481 + /* Stop GMIB statistics polling */
482 + cancel_delayed_work_sync(&ppe_port->gmib_read);
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
491 +/* PPE port MAC MIB work task initialization */
492 +static int ppe_port_mac_mib_work_init(struct ppe_port *ppe_port)
494 + struct ppe_device *ppe_dev = ppe_port->ppe_dev;
497 + gstats = devm_kzalloc(ppe_dev->dev,
498 + sizeof(*gstats) * ARRAY_SIZE(gmib_info),
503 + ppe_port->gmib_stats = gstats;
505 + spin_lock_init(&ppe_port->gmib_stats_lock);
506 + INIT_DELAYED_WORK(&ppe_port->gmib_read,
507 + ppe_port_gmib_stats_poll);
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
519 + ret = ppe_port_mac_mib_work_init(&ppe_ports->port[i]);
521 + dev_err(ppe_dev->dev, "Failed to initialize MAC MIB work\n");
522 + goto err_port_node;
528 --- a/drivers/net/ethernet/qualcomm/ppe/ppe_port.h
529 +++ b/drivers/net/ethernet/qualcomm/ppe/ppe_port.h
532 #include <linux/phylink.h>
534 +struct rtnl_link_stats64;
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 {
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
548 struct phylink *phylink;
549 @@ -56,6 +61,9 @@ struct ppe_port {
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;
555 + spinlock_t gmib_stats_lock; /* Protects GMIB stats */
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);
569 --- a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
570 +++ b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
572 #define GMAC_MIB_CTRL_MASK \
573 (GMAC_MIB_RD_CLR | GMAC_MIB_RST | GMAC_MIB_EN)
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
617 /* XGMAC TX configuration register */
618 #define XGMAC_TX_CONFIG_ADDR 0x0
619 #define XGMAC_SPEED_M GENMASK(31, 29)
621 #define XGMAC_MCF BIT(3)
622 #define XGMAC_CNTRST BIT(0)
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