Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: mscc: ocelot: export ethtool MAC Merge stats for Felix VSC9959

The Felix VSC9959 switch supports frame preemption and has a MAC Merge
layer. In addition to the structured stats that exist for the eMAC,
export the counters associated with its pMAC (pause, RMON, MAC, PHY,
control) plus the high-level MAC Merge layer stats. The unstructured
ethtool counters, as well as the rtnl_link_stats64 were left to report
only the eMAC counters.

Because statistics processing is quite self-contained in ocelot_stats.c
now, I've opted for introducing an ocelot->mm_supported bool, based on
which the common switch lib does everything, rather than pushing the
TSN-specific code in felix_vsc9959.c, as happens for other TSN stuff.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Vladimir Oltean and committed by
David S. Miller
ab3f97a9 497eea9f

+366 -10
+9
drivers/net/dsa/ocelot/felix.c
··· 2024 2024 return ocelot_port_del_dscp_prio(ocelot, port, dscp, prio); 2025 2025 } 2026 2026 2027 + static void felix_get_mm_stats(struct dsa_switch *ds, int port, 2028 + struct ethtool_mm_stats *stats) 2029 + { 2030 + struct ocelot *ocelot = ds->priv; 2031 + 2032 + ocelot_port_get_mm_stats(ocelot, port, stats); 2033 + } 2034 + 2027 2035 const struct dsa_switch_ops felix_switch_ops = { 2028 2036 .get_tag_protocol = felix_get_tag_protocol, 2029 2037 .change_tag_protocol = felix_change_tag_protocol, ··· 2039 2031 .setup = felix_setup, 2040 2032 .teardown = felix_teardown, 2041 2033 .set_ageing_time = felix_set_ageing_time, 2034 + .get_mm_stats = felix_get_mm_stats, 2042 2035 .get_stats64 = felix_get_stats64, 2043 2036 .get_pause_stats = felix_get_pause_stats, 2044 2037 .get_rmon_stats = felix_get_rmon_stats,
+38
drivers/net/dsa/ocelot/felix_vsc9959.c
··· 318 318 REG(SYS_COUNT_RX_GREEN_PRIO_5, 0x0000a4), 319 319 REG(SYS_COUNT_RX_GREEN_PRIO_6, 0x0000a8), 320 320 REG(SYS_COUNT_RX_GREEN_PRIO_7, 0x0000ac), 321 + REG(SYS_COUNT_RX_ASSEMBLY_ERRS, 0x0000b0), 322 + REG(SYS_COUNT_RX_SMD_ERRS, 0x0000b4), 323 + REG(SYS_COUNT_RX_ASSEMBLY_OK, 0x0000b8), 324 + REG(SYS_COUNT_RX_MERGE_FRAGMENTS, 0x0000bc), 325 + REG(SYS_COUNT_RX_PMAC_OCTETS, 0x0000c0), 326 + REG(SYS_COUNT_RX_PMAC_UNICAST, 0x0000c4), 327 + REG(SYS_COUNT_RX_PMAC_MULTICAST, 0x0000c8), 328 + REG(SYS_COUNT_RX_PMAC_BROADCAST, 0x0000cc), 329 + REG(SYS_COUNT_RX_PMAC_SHORTS, 0x0000d0), 330 + REG(SYS_COUNT_RX_PMAC_FRAGMENTS, 0x0000d4), 331 + REG(SYS_COUNT_RX_PMAC_JABBERS, 0x0000d8), 332 + REG(SYS_COUNT_RX_PMAC_CRC_ALIGN_ERRS, 0x0000dc), 333 + REG(SYS_COUNT_RX_PMAC_SYM_ERRS, 0x0000e0), 334 + REG(SYS_COUNT_RX_PMAC_64, 0x0000e4), 335 + REG(SYS_COUNT_RX_PMAC_65_127, 0x0000e8), 336 + REG(SYS_COUNT_RX_PMAC_128_255, 0x0000ec), 337 + REG(SYS_COUNT_RX_PMAC_256_511, 0x0000f0), 338 + REG(SYS_COUNT_RX_PMAC_512_1023, 0x0000f4), 339 + REG(SYS_COUNT_RX_PMAC_1024_1526, 0x0000f8), 340 + REG(SYS_COUNT_RX_PMAC_1527_MAX, 0x0000fc), 341 + REG(SYS_COUNT_RX_PMAC_PAUSE, 0x000100), 342 + REG(SYS_COUNT_RX_PMAC_CONTROL, 0x000104), 343 + REG(SYS_COUNT_RX_PMAC_LONGS, 0x000108), 321 344 REG(SYS_COUNT_TX_OCTETS, 0x000200), 322 345 REG(SYS_COUNT_TX_UNICAST, 0x000204), 323 346 REG(SYS_COUNT_TX_MULTICAST, 0x000208), ··· 372 349 REG(SYS_COUNT_TX_GREEN_PRIO_6, 0x000270), 373 350 REG(SYS_COUNT_TX_GREEN_PRIO_7, 0x000274), 374 351 REG(SYS_COUNT_TX_AGED, 0x000278), 352 + REG(SYS_COUNT_TX_MM_HOLD, 0x00027c), 353 + REG(SYS_COUNT_TX_MERGE_FRAGMENTS, 0x000280), 354 + REG(SYS_COUNT_TX_PMAC_OCTETS, 0x000284), 355 + REG(SYS_COUNT_TX_PMAC_UNICAST, 0x000288), 356 + REG(SYS_COUNT_TX_PMAC_MULTICAST, 0x00028c), 357 + REG(SYS_COUNT_TX_PMAC_BROADCAST, 0x000290), 358 + REG(SYS_COUNT_TX_PMAC_PAUSE, 0x000294), 359 + REG(SYS_COUNT_TX_PMAC_64, 0x000298), 360 + REG(SYS_COUNT_TX_PMAC_65_127, 0x00029c), 361 + REG(SYS_COUNT_TX_PMAC_128_255, 0x0002a0), 362 + REG(SYS_COUNT_TX_PMAC_256_511, 0x0002a4), 363 + REG(SYS_COUNT_TX_PMAC_512_1023, 0x0002a8), 364 + REG(SYS_COUNT_TX_PMAC_1024_1526, 0x0002ac), 365 + REG(SYS_COUNT_TX_PMAC_1527_MAX, 0x0002b0), 375 366 REG(SYS_COUNT_DROP_LOCAL, 0x000400), 376 367 REG(SYS_COUNT_DROP_TAIL, 0x000404), 377 368 REG(SYS_COUNT_DROP_YELLOW_PRIO_0, 0x000408), ··· 2660 2623 } 2661 2624 2662 2625 ocelot->ptp = 1; 2626 + ocelot->mm_supported = true; 2663 2627 2664 2628 ds = kzalloc(sizeof(struct dsa_switch), GFP_KERNEL); 2665 2629 if (!ds) {
+279 -10
drivers/net/ethernet/mscc/ocelot_stats.c
··· 54 54 OCELOT_STAT_RX_GREEN_PRIO_5, 55 55 OCELOT_STAT_RX_GREEN_PRIO_6, 56 56 OCELOT_STAT_RX_GREEN_PRIO_7, 57 + OCELOT_STAT_RX_ASSEMBLY_ERRS, 58 + OCELOT_STAT_RX_SMD_ERRS, 59 + OCELOT_STAT_RX_ASSEMBLY_OK, 60 + OCELOT_STAT_RX_MERGE_FRAGMENTS, 61 + OCELOT_STAT_RX_PMAC_OCTETS, 62 + OCELOT_STAT_RX_PMAC_UNICAST, 63 + OCELOT_STAT_RX_PMAC_MULTICAST, 64 + OCELOT_STAT_RX_PMAC_BROADCAST, 65 + OCELOT_STAT_RX_PMAC_SHORTS, 66 + OCELOT_STAT_RX_PMAC_FRAGMENTS, 67 + OCELOT_STAT_RX_PMAC_JABBERS, 68 + OCELOT_STAT_RX_PMAC_CRC_ALIGN_ERRS, 69 + OCELOT_STAT_RX_PMAC_SYM_ERRS, 70 + OCELOT_STAT_RX_PMAC_64, 71 + OCELOT_STAT_RX_PMAC_65_127, 72 + OCELOT_STAT_RX_PMAC_128_255, 73 + OCELOT_STAT_RX_PMAC_256_511, 74 + OCELOT_STAT_RX_PMAC_512_1023, 75 + OCELOT_STAT_RX_PMAC_1024_1526, 76 + OCELOT_STAT_RX_PMAC_1527_MAX, 77 + OCELOT_STAT_RX_PMAC_PAUSE, 78 + OCELOT_STAT_RX_PMAC_CONTROL, 79 + OCELOT_STAT_RX_PMAC_LONGS, 57 80 OCELOT_STAT_TX_OCTETS, 58 81 OCELOT_STAT_TX_UNICAST, 59 82 OCELOT_STAT_TX_MULTICAST, ··· 108 85 OCELOT_STAT_TX_GREEN_PRIO_6, 109 86 OCELOT_STAT_TX_GREEN_PRIO_7, 110 87 OCELOT_STAT_TX_AGED, 88 + OCELOT_STAT_TX_MM_HOLD, 89 + OCELOT_STAT_TX_MERGE_FRAGMENTS, 90 + OCELOT_STAT_TX_PMAC_OCTETS, 91 + OCELOT_STAT_TX_PMAC_UNICAST, 92 + OCELOT_STAT_TX_PMAC_MULTICAST, 93 + OCELOT_STAT_TX_PMAC_BROADCAST, 94 + OCELOT_STAT_TX_PMAC_PAUSE, 95 + OCELOT_STAT_TX_PMAC_64, 96 + OCELOT_STAT_TX_PMAC_65_127, 97 + OCELOT_STAT_TX_PMAC_128_255, 98 + OCELOT_STAT_TX_PMAC_256_511, 99 + OCELOT_STAT_TX_PMAC_512_1023, 100 + OCELOT_STAT_TX_PMAC_1024_1526, 101 + OCELOT_STAT_TX_PMAC_1527_MAX, 111 102 OCELOT_STAT_DROP_LOCAL, 112 103 OCELOT_STAT_DROP_TAIL, 113 104 OCELOT_STAT_DROP_YELLOW_PRIO_0, ··· 265 228 OCELOT_COMMON_STATS, 266 229 }; 267 230 231 + static const struct ocelot_stat_layout ocelot_mm_stats_layout[OCELOT_NUM_STATS] = { 232 + OCELOT_COMMON_STATS, 233 + OCELOT_STAT(RX_ASSEMBLY_ERRS), 234 + OCELOT_STAT(RX_SMD_ERRS), 235 + OCELOT_STAT(RX_ASSEMBLY_OK), 236 + OCELOT_STAT(RX_MERGE_FRAGMENTS), 237 + OCELOT_STAT(TX_MERGE_FRAGMENTS), 238 + OCELOT_STAT(RX_PMAC_OCTETS), 239 + OCELOT_STAT(RX_PMAC_UNICAST), 240 + OCELOT_STAT(RX_PMAC_MULTICAST), 241 + OCELOT_STAT(RX_PMAC_BROADCAST), 242 + OCELOT_STAT(RX_PMAC_SHORTS), 243 + OCELOT_STAT(RX_PMAC_FRAGMENTS), 244 + OCELOT_STAT(RX_PMAC_JABBERS), 245 + OCELOT_STAT(RX_PMAC_CRC_ALIGN_ERRS), 246 + OCELOT_STAT(RX_PMAC_SYM_ERRS), 247 + OCELOT_STAT(RX_PMAC_64), 248 + OCELOT_STAT(RX_PMAC_65_127), 249 + OCELOT_STAT(RX_PMAC_128_255), 250 + OCELOT_STAT(RX_PMAC_256_511), 251 + OCELOT_STAT(RX_PMAC_512_1023), 252 + OCELOT_STAT(RX_PMAC_1024_1526), 253 + OCELOT_STAT(RX_PMAC_1527_MAX), 254 + OCELOT_STAT(RX_PMAC_PAUSE), 255 + OCELOT_STAT(RX_PMAC_CONTROL), 256 + OCELOT_STAT(RX_PMAC_LONGS), 257 + OCELOT_STAT(TX_PMAC_OCTETS), 258 + OCELOT_STAT(TX_PMAC_UNICAST), 259 + OCELOT_STAT(TX_PMAC_MULTICAST), 260 + OCELOT_STAT(TX_PMAC_BROADCAST), 261 + OCELOT_STAT(TX_PMAC_PAUSE), 262 + OCELOT_STAT(TX_PMAC_64), 263 + OCELOT_STAT(TX_PMAC_65_127), 264 + OCELOT_STAT(TX_PMAC_128_255), 265 + OCELOT_STAT(TX_PMAC_256_511), 266 + OCELOT_STAT(TX_PMAC_512_1023), 267 + OCELOT_STAT(TX_PMAC_1024_1526), 268 + OCELOT_STAT(TX_PMAC_1527_MAX), 269 + }; 270 + 268 271 static const struct ocelot_stat_layout * 269 272 ocelot_get_stats_layout(struct ocelot *ocelot) 270 273 { 274 + if (ocelot->mm_supported) 275 + return ocelot_mm_stats_layout; 276 + 271 277 return ocelot_stats_layout; 272 278 } 273 279 ··· 490 410 pause_stats->rx_pause_frames = s[OCELOT_STAT_RX_PAUSE]; 491 411 } 492 412 413 + static void ocelot_port_pmac_pause_stats_cb(struct ocelot *ocelot, int port, 414 + void *priv) 415 + { 416 + u64 *s = &ocelot->stats[port * OCELOT_NUM_STATS]; 417 + struct ethtool_pause_stats *pause_stats = priv; 418 + 419 + pause_stats->tx_pause_frames = s[OCELOT_STAT_TX_PMAC_PAUSE]; 420 + pause_stats->rx_pause_frames = s[OCELOT_STAT_RX_PMAC_PAUSE]; 421 + } 422 + 423 + static void ocelot_port_mm_stats_cb(struct ocelot *ocelot, int port, 424 + void *priv) 425 + { 426 + u64 *s = &ocelot->stats[port * OCELOT_NUM_STATS]; 427 + struct ethtool_mm_stats *stats = priv; 428 + 429 + stats->MACMergeFrameAssErrorCount = s[OCELOT_STAT_RX_ASSEMBLY_ERRS]; 430 + stats->MACMergeFrameSmdErrorCount = s[OCELOT_STAT_RX_SMD_ERRS]; 431 + stats->MACMergeFrameAssOkCount = s[OCELOT_STAT_RX_ASSEMBLY_OK]; 432 + stats->MACMergeFragCountRx = s[OCELOT_STAT_RX_MERGE_FRAGMENTS]; 433 + stats->MACMergeFragCountTx = s[OCELOT_STAT_TX_MERGE_FRAGMENTS]; 434 + stats->MACMergeHoldCount = s[OCELOT_STAT_TX_MM_HOLD]; 435 + } 436 + 493 437 void ocelot_port_get_pause_stats(struct ocelot *ocelot, int port, 494 438 struct ethtool_pause_stats *pause_stats) 495 439 { 496 - ocelot_port_stats_run(ocelot, port, pause_stats, 497 - ocelot_port_pause_stats_cb); 440 + struct net_device *dev; 441 + 442 + switch (pause_stats->src) { 443 + case ETHTOOL_MAC_STATS_SRC_EMAC: 444 + ocelot_port_stats_run(ocelot, port, pause_stats, 445 + ocelot_port_pause_stats_cb); 446 + break; 447 + case ETHTOOL_MAC_STATS_SRC_PMAC: 448 + if (ocelot->mm_supported) 449 + ocelot_port_stats_run(ocelot, port, pause_stats, 450 + ocelot_port_pmac_pause_stats_cb); 451 + break; 452 + case ETHTOOL_MAC_STATS_SRC_AGGREGATE: 453 + dev = ocelot->ops->port_to_netdev(ocelot, port); 454 + ethtool_aggregate_pause_stats(dev, pause_stats); 455 + break; 456 + } 498 457 } 499 458 EXPORT_SYMBOL_GPL(ocelot_port_get_pause_stats); 459 + 460 + void ocelot_port_get_mm_stats(struct ocelot *ocelot, int port, 461 + struct ethtool_mm_stats *stats) 462 + { 463 + if (!ocelot->mm_supported) 464 + return; 465 + 466 + ocelot_port_stats_run(ocelot, port, stats, ocelot_port_mm_stats_cb); 467 + } 468 + EXPORT_SYMBOL_GPL(ocelot_port_get_mm_stats); 500 469 501 470 static const struct ethtool_rmon_hist_range ocelot_rmon_ranges[] = { 502 471 { 64, 64 }, ··· 585 456 rmon_stats->hist_tx[6] = s[OCELOT_STAT_TX_1024_1526]; 586 457 } 587 458 459 + static void ocelot_port_pmac_rmon_stats_cb(struct ocelot *ocelot, int port, 460 + void *priv) 461 + { 462 + u64 *s = &ocelot->stats[port * OCELOT_NUM_STATS]; 463 + struct ethtool_rmon_stats *rmon_stats = priv; 464 + 465 + rmon_stats->undersize_pkts = s[OCELOT_STAT_RX_PMAC_SHORTS]; 466 + rmon_stats->oversize_pkts = s[OCELOT_STAT_RX_PMAC_LONGS]; 467 + rmon_stats->fragments = s[OCELOT_STAT_RX_PMAC_FRAGMENTS]; 468 + rmon_stats->jabbers = s[OCELOT_STAT_RX_PMAC_JABBERS]; 469 + 470 + rmon_stats->hist[0] = s[OCELOT_STAT_RX_PMAC_64]; 471 + rmon_stats->hist[1] = s[OCELOT_STAT_RX_PMAC_65_127]; 472 + rmon_stats->hist[2] = s[OCELOT_STAT_RX_PMAC_128_255]; 473 + rmon_stats->hist[3] = s[OCELOT_STAT_RX_PMAC_256_511]; 474 + rmon_stats->hist[4] = s[OCELOT_STAT_RX_PMAC_512_1023]; 475 + rmon_stats->hist[5] = s[OCELOT_STAT_RX_PMAC_1024_1526]; 476 + rmon_stats->hist[6] = s[OCELOT_STAT_RX_PMAC_1527_MAX]; 477 + 478 + rmon_stats->hist_tx[0] = s[OCELOT_STAT_TX_PMAC_64]; 479 + rmon_stats->hist_tx[1] = s[OCELOT_STAT_TX_PMAC_65_127]; 480 + rmon_stats->hist_tx[2] = s[OCELOT_STAT_TX_PMAC_128_255]; 481 + rmon_stats->hist_tx[3] = s[OCELOT_STAT_TX_PMAC_128_255]; 482 + rmon_stats->hist_tx[4] = s[OCELOT_STAT_TX_PMAC_256_511]; 483 + rmon_stats->hist_tx[5] = s[OCELOT_STAT_TX_PMAC_512_1023]; 484 + rmon_stats->hist_tx[6] = s[OCELOT_STAT_TX_PMAC_1024_1526]; 485 + } 486 + 588 487 void ocelot_port_get_rmon_stats(struct ocelot *ocelot, int port, 589 488 struct ethtool_rmon_stats *rmon_stats, 590 489 const struct ethtool_rmon_hist_range **ranges) 591 490 { 491 + struct net_device *dev; 492 + 592 493 *ranges = ocelot_rmon_ranges; 593 494 594 - ocelot_port_stats_run(ocelot, port, rmon_stats, 595 - ocelot_port_rmon_stats_cb); 495 + switch (rmon_stats->src) { 496 + case ETHTOOL_MAC_STATS_SRC_EMAC: 497 + ocelot_port_stats_run(ocelot, port, rmon_stats, 498 + ocelot_port_rmon_stats_cb); 499 + break; 500 + case ETHTOOL_MAC_STATS_SRC_PMAC: 501 + if (ocelot->mm_supported) 502 + ocelot_port_stats_run(ocelot, port, rmon_stats, 503 + ocelot_port_pmac_rmon_stats_cb); 504 + break; 505 + case ETHTOOL_MAC_STATS_SRC_AGGREGATE: 506 + dev = ocelot->ops->port_to_netdev(ocelot, port); 507 + ethtool_aggregate_rmon_stats(dev, rmon_stats); 508 + break; 509 + } 596 510 } 597 511 EXPORT_SYMBOL_GPL(ocelot_port_get_rmon_stats); 598 512 ··· 647 475 ctrl_stats->MACControlFramesReceived = s[OCELOT_STAT_RX_CONTROL]; 648 476 } 649 477 478 + static void ocelot_port_pmac_ctrl_stats_cb(struct ocelot *ocelot, int port, 479 + void *priv) 480 + { 481 + u64 *s = &ocelot->stats[port * OCELOT_NUM_STATS]; 482 + struct ethtool_eth_ctrl_stats *ctrl_stats = priv; 483 + 484 + ctrl_stats->MACControlFramesReceived = s[OCELOT_STAT_RX_PMAC_CONTROL]; 485 + } 486 + 650 487 void ocelot_port_get_eth_ctrl_stats(struct ocelot *ocelot, int port, 651 488 struct ethtool_eth_ctrl_stats *ctrl_stats) 652 489 { 653 - ocelot_port_stats_run(ocelot, port, ctrl_stats, 654 - ocelot_port_ctrl_stats_cb); 490 + struct net_device *dev; 491 + 492 + switch (ctrl_stats->src) { 493 + case ETHTOOL_MAC_STATS_SRC_EMAC: 494 + ocelot_port_stats_run(ocelot, port, ctrl_stats, 495 + ocelot_port_ctrl_stats_cb); 496 + break; 497 + case ETHTOOL_MAC_STATS_SRC_PMAC: 498 + if (ocelot->mm_supported) 499 + ocelot_port_stats_run(ocelot, port, ctrl_stats, 500 + ocelot_port_pmac_ctrl_stats_cb); 501 + break; 502 + case ETHTOOL_MAC_STATS_SRC_AGGREGATE: 503 + dev = ocelot->ops->port_to_netdev(ocelot, port); 504 + ethtool_aggregate_ctrl_stats(dev, ctrl_stats); 505 + break; 506 + } 655 507 } 656 508 EXPORT_SYMBOL_GPL(ocelot_port_get_eth_ctrl_stats); 657 509 ··· 721 525 mac_stats->AlignmentErrors = s[OCELOT_STAT_RX_CRC_ALIGN_ERRS]; 722 526 } 723 527 528 + static void ocelot_port_pmac_mac_stats_cb(struct ocelot *ocelot, int port, 529 + void *priv) 530 + { 531 + u64 *s = &ocelot->stats[port * OCELOT_NUM_STATS]; 532 + struct ethtool_eth_mac_stats *mac_stats = priv; 533 + 534 + mac_stats->OctetsTransmittedOK = s[OCELOT_STAT_TX_PMAC_OCTETS]; 535 + mac_stats->FramesTransmittedOK = s[OCELOT_STAT_TX_PMAC_64] + 536 + s[OCELOT_STAT_TX_PMAC_65_127] + 537 + s[OCELOT_STAT_TX_PMAC_128_255] + 538 + s[OCELOT_STAT_TX_PMAC_256_511] + 539 + s[OCELOT_STAT_TX_PMAC_512_1023] + 540 + s[OCELOT_STAT_TX_PMAC_1024_1526] + 541 + s[OCELOT_STAT_TX_PMAC_1527_MAX]; 542 + mac_stats->OctetsReceivedOK = s[OCELOT_STAT_RX_PMAC_OCTETS]; 543 + mac_stats->FramesReceivedOK = s[OCELOT_STAT_RX_PMAC_64] + 544 + s[OCELOT_STAT_RX_PMAC_65_127] + 545 + s[OCELOT_STAT_RX_PMAC_128_255] + 546 + s[OCELOT_STAT_RX_PMAC_256_511] + 547 + s[OCELOT_STAT_RX_PMAC_512_1023] + 548 + s[OCELOT_STAT_RX_PMAC_1024_1526] + 549 + s[OCELOT_STAT_RX_PMAC_1527_MAX]; 550 + mac_stats->MulticastFramesXmittedOK = s[OCELOT_STAT_TX_PMAC_MULTICAST]; 551 + mac_stats->BroadcastFramesXmittedOK = s[OCELOT_STAT_TX_PMAC_BROADCAST]; 552 + mac_stats->MulticastFramesReceivedOK = s[OCELOT_STAT_RX_PMAC_MULTICAST]; 553 + mac_stats->BroadcastFramesReceivedOK = s[OCELOT_STAT_RX_PMAC_BROADCAST]; 554 + mac_stats->FrameTooLongErrors = s[OCELOT_STAT_RX_PMAC_LONGS]; 555 + /* Sadly, C_RX_CRC is the sum of FCS and alignment errors, they are not 556 + * counted individually. 557 + */ 558 + mac_stats->FrameCheckSequenceErrors = s[OCELOT_STAT_RX_PMAC_CRC_ALIGN_ERRS]; 559 + mac_stats->AlignmentErrors = s[OCELOT_STAT_RX_PMAC_CRC_ALIGN_ERRS]; 560 + } 561 + 724 562 void ocelot_port_get_eth_mac_stats(struct ocelot *ocelot, int port, 725 563 struct ethtool_eth_mac_stats *mac_stats) 726 564 { 727 - ocelot_port_stats_run(ocelot, port, mac_stats, 728 - ocelot_port_mac_stats_cb); 565 + struct net_device *dev; 566 + 567 + switch (mac_stats->src) { 568 + case ETHTOOL_MAC_STATS_SRC_EMAC: 569 + ocelot_port_stats_run(ocelot, port, mac_stats, 570 + ocelot_port_mac_stats_cb); 571 + break; 572 + case ETHTOOL_MAC_STATS_SRC_PMAC: 573 + if (ocelot->mm_supported) 574 + ocelot_port_stats_run(ocelot, port, mac_stats, 575 + ocelot_port_pmac_mac_stats_cb); 576 + break; 577 + case ETHTOOL_MAC_STATS_SRC_AGGREGATE: 578 + dev = ocelot->ops->port_to_netdev(ocelot, port); 579 + ethtool_aggregate_mac_stats(dev, mac_stats); 580 + break; 581 + } 729 582 } 730 583 EXPORT_SYMBOL_GPL(ocelot_port_get_eth_mac_stats); 731 584 ··· 786 541 phy_stats->SymbolErrorDuringCarrier = s[OCELOT_STAT_RX_SYM_ERRS]; 787 542 } 788 543 544 + static void ocelot_port_pmac_phy_stats_cb(struct ocelot *ocelot, int port, 545 + void *priv) 546 + { 547 + u64 *s = &ocelot->stats[port * OCELOT_NUM_STATS]; 548 + struct ethtool_eth_phy_stats *phy_stats = priv; 549 + 550 + phy_stats->SymbolErrorDuringCarrier = s[OCELOT_STAT_RX_PMAC_SYM_ERRS]; 551 + } 552 + 789 553 void ocelot_port_get_eth_phy_stats(struct ocelot *ocelot, int port, 790 554 struct ethtool_eth_phy_stats *phy_stats) 791 555 { 792 - ocelot_port_stats_run(ocelot, port, phy_stats, 793 - ocelot_port_phy_stats_cb); 556 + struct net_device *dev; 557 + 558 + switch (phy_stats->src) { 559 + case ETHTOOL_MAC_STATS_SRC_EMAC: 560 + ocelot_port_stats_run(ocelot, port, phy_stats, 561 + ocelot_port_phy_stats_cb); 562 + break; 563 + case ETHTOOL_MAC_STATS_SRC_PMAC: 564 + if (ocelot->mm_supported) 565 + ocelot_port_stats_run(ocelot, port, phy_stats, 566 + ocelot_port_pmac_phy_stats_cb); 567 + break; 568 + case ETHTOOL_MAC_STATS_SRC_AGGREGATE: 569 + dev = ocelot->ops->port_to_netdev(ocelot, port); 570 + ethtool_aggregate_phy_stats(dev, phy_stats); 571 + break; 572 + } 794 573 } 795 574 EXPORT_SYMBOL_GPL(ocelot_port_get_eth_phy_stats); 796 575
+40
include/soc/mscc/ocelot.h
··· 362 362 SYS_COUNT_RX_GREEN_PRIO_5, 363 363 SYS_COUNT_RX_GREEN_PRIO_6, 364 364 SYS_COUNT_RX_GREEN_PRIO_7, 365 + SYS_COUNT_RX_ASSEMBLY_ERRS, 366 + SYS_COUNT_RX_SMD_ERRS, 367 + SYS_COUNT_RX_ASSEMBLY_OK, 368 + SYS_COUNT_RX_MERGE_FRAGMENTS, 369 + SYS_COUNT_RX_PMAC_OCTETS, 370 + SYS_COUNT_RX_PMAC_UNICAST, 371 + SYS_COUNT_RX_PMAC_MULTICAST, 372 + SYS_COUNT_RX_PMAC_BROADCAST, 373 + SYS_COUNT_RX_PMAC_SHORTS, 374 + SYS_COUNT_RX_PMAC_FRAGMENTS, 375 + SYS_COUNT_RX_PMAC_JABBERS, 376 + SYS_COUNT_RX_PMAC_CRC_ALIGN_ERRS, 377 + SYS_COUNT_RX_PMAC_SYM_ERRS, 378 + SYS_COUNT_RX_PMAC_64, 379 + SYS_COUNT_RX_PMAC_65_127, 380 + SYS_COUNT_RX_PMAC_128_255, 381 + SYS_COUNT_RX_PMAC_256_511, 382 + SYS_COUNT_RX_PMAC_512_1023, 383 + SYS_COUNT_RX_PMAC_1024_1526, 384 + SYS_COUNT_RX_PMAC_1527_MAX, 385 + SYS_COUNT_RX_PMAC_PAUSE, 386 + SYS_COUNT_RX_PMAC_CONTROL, 387 + SYS_COUNT_RX_PMAC_LONGS, 365 388 SYS_COUNT_TX_OCTETS, 366 389 SYS_COUNT_TX_UNICAST, 367 390 SYS_COUNT_TX_MULTICAST, ··· 416 393 SYS_COUNT_TX_GREEN_PRIO_6, 417 394 SYS_COUNT_TX_GREEN_PRIO_7, 418 395 SYS_COUNT_TX_AGED, 396 + SYS_COUNT_TX_MM_HOLD, 397 + SYS_COUNT_TX_MERGE_FRAGMENTS, 398 + SYS_COUNT_TX_PMAC_OCTETS, 399 + SYS_COUNT_TX_PMAC_UNICAST, 400 + SYS_COUNT_TX_PMAC_MULTICAST, 401 + SYS_COUNT_TX_PMAC_BROADCAST, 402 + SYS_COUNT_TX_PMAC_PAUSE, 403 + SYS_COUNT_TX_PMAC_64, 404 + SYS_COUNT_TX_PMAC_65_127, 405 + SYS_COUNT_TX_PMAC_128_255, 406 + SYS_COUNT_TX_PMAC_256_511, 407 + SYS_COUNT_TX_PMAC_512_1023, 408 + SYS_COUNT_TX_PMAC_1024_1526, 409 + SYS_COUNT_TX_PMAC_1527_MAX, 419 410 SYS_COUNT_DROP_LOCAL, 420 411 SYS_COUNT_DROP_TAIL, 421 412 SYS_COUNT_DROP_YELLOW_PRIO_0, ··· 851 814 struct workqueue_struct *owq; 852 815 853 816 u8 ptp:1; 817 + u8 mm_supported:1; 854 818 struct ptp_clock *ptp_clock; 855 819 struct ptp_clock_info ptp_info; 856 820 struct hwtstamp_config hwtstamp_config; ··· 975 937 struct rtnl_link_stats64 *stats); 976 938 void ocelot_port_get_pause_stats(struct ocelot *ocelot, int port, 977 939 struct ethtool_pause_stats *pause_stats); 940 + void ocelot_port_get_mm_stats(struct ocelot *ocelot, int port, 941 + struct ethtool_mm_stats *stats); 978 942 void ocelot_port_get_rmon_stats(struct ocelot *ocelot, int port, 979 943 struct ethtool_rmon_stats *rmon_stats, 980 944 const struct ethtool_rmon_hist_range **ranges);