1 // SPDX-License-Identifier: GPL-2.0
6 enum sja1105_counter_index {
7 __SJA1105_COUNTER_UNUSED,
51 __MAX_SJA1105ET_PORT_COUNTER,
54 N_DROPS_NOLEARN = __MAX_SJA1105ET_PORT_COUNTER,
77 __MAX_SJA1105PQRS_PORT_COUNTER,
80 struct sja1105_port_counter {
81 enum sja1105_stats_area area;
82 const char name[ETH_GSTRING_LEN];
89 static const struct sja1105_port_counter sja1105_port_counters[] = {
90 /* MAC-Level Diagnostic Counters */
107 .name = "n_alignerr",
119 /* MAC-Level Diagnostic Flags */
192 .name = "pcfbagdrop",
241 .name = "drpnona664err",
260 /* High-Level Diagnostic Counters */
277 .name = "n_unreleased",
298 .name = "n_vlnotfound",
305 .name = "n_ctpolerr",
358 .name = "n_part_drop",
365 .name = "n_egr_disabled",
372 .name = "n_not_reach",
378 [N_DROPS_NOLEARN] = {
380 .name = "n_drops_nolearn",
385 [N_DROPS_NOROUTE] = {
387 .name = "n_drops_noroute",
392 [N_DROPS_ILL_DTAG] = {
394 .name = "n_drops_ill_dtag",
401 .name = "n_drops_dtag",
408 .name = "n_drops_sotag",
415 .name = "n_drops_sitag",
422 .name = "n_drops_utag",
427 [N_TX_BYTES_1024_2047] = {
429 .name = "n_tx_bytes_1024_2047",
434 [N_TX_BYTES_512_1023] = {
436 .name = "n_tx_bytes_512_1023",
441 [N_TX_BYTES_256_511] = {
443 .name = "n_tx_bytes_256_511",
448 [N_TX_BYTES_128_255] = {
450 .name = "n_tx_bytes_128_255",
455 [N_TX_BYTES_65_127] = {
457 .name = "n_tx_bytes_65_127",
464 .name = "n_tx_bytes_64",
471 .name = "n_tx_mcast",
478 .name = "n_tx_bcast",
483 [N_RX_BYTES_1024_2047] = {
485 .name = "n_rx_bytes_1024_2047",
490 [N_RX_BYTES_512_1023] = {
492 .name = "n_rx_bytes_512_1023",
497 [N_RX_BYTES_256_511] = {
499 .name = "n_rx_bytes_256_511",
504 [N_RX_BYTES_128_255] = {
506 .name = "n_rx_bytes_128_255",
511 [N_RX_BYTES_65_127] = {
513 .name = "n_rx_bytes_65_127",
520 .name = "n_rx_bytes_64",
527 .name = "n_rx_mcast",
534 .name = "n_rx_bcast",
541 static int sja1105_port_counter_read(struct sja1105_private *priv, int port,
542 enum sja1105_counter_index idx, u64 *ctr)
544 const struct sja1105_port_counter *c = &sja1105_port_counters[idx];
545 size_t size = c->is_64bit ? 8 : 4;
550 regs = priv->info->regs->stats[c->area][port];
552 rc = sja1105_xfer_buf(priv, SPI_READ, regs + c->offset, buf, size);
556 sja1105_unpack(buf, ctr, c->start, c->end, size);
561 void sja1105_get_ethtool_stats(struct dsa_switch *ds, int port, u64 *data)
563 struct sja1105_private *priv = ds->priv;
564 enum sja1105_counter_index max_ctr, i;
567 if (priv->info->device_id == SJA1105E_DEVICE_ID ||
568 priv->info->device_id == SJA1105T_DEVICE_ID)
569 max_ctr = __MAX_SJA1105ET_PORT_COUNTER;
571 max_ctr = __MAX_SJA1105PQRS_PORT_COUNTER;
573 for (i = 0; i < max_ctr; i++) {
574 rc = sja1105_port_counter_read(priv, port, i, &data[k++]);
577 "Failed to read port %d counters: %d\n",
584 void sja1105_get_strings(struct dsa_switch *ds, int port,
585 u32 stringset, u8 *data)
587 struct sja1105_private *priv = ds->priv;
588 enum sja1105_counter_index max_ctr, i;
590 if (stringset != ETH_SS_STATS)
593 if (priv->info->device_id == SJA1105E_DEVICE_ID ||
594 priv->info->device_id == SJA1105T_DEVICE_ID)
595 max_ctr = __MAX_SJA1105ET_PORT_COUNTER;
597 max_ctr = __MAX_SJA1105PQRS_PORT_COUNTER;
599 for (i = 0; i < max_ctr; i++)
600 ethtool_puts(&data, sja1105_port_counters[i].name);
603 int sja1105_get_sset_count(struct dsa_switch *ds, int port, int sset)
605 struct sja1105_private *priv = ds->priv;
606 enum sja1105_counter_index max_ctr, i;
609 if (sset != ETH_SS_STATS)
612 if (priv->info->device_id == SJA1105E_DEVICE_ID ||
613 priv->info->device_id == SJA1105T_DEVICE_ID)
614 max_ctr = __MAX_SJA1105ET_PORT_COUNTER;
616 max_ctr = __MAX_SJA1105PQRS_PORT_COUNTER;
618 for (i = 0; i < max_ctr; i++) {
619 if (!strlen(sja1105_port_counters[i].name))