| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716 |
- // SPDX-License-Identifier: GPL-2.0+
- #include <linux/netdevice.h>
- #include "lan966x_main.h"
- /* Number of traffic classes */
- #define LAN966X_NUM_TC 8
- #define LAN966X_STATS_CHECK_DELAY (2 * HZ)
- static const struct lan966x_stat_layout lan966x_stats_layout[] = {
- { .name = "rx_octets", .offset = 0x00, },
- { .name = "rx_unicast", .offset = 0x01, },
- { .name = "rx_multicast", .offset = 0x02 },
- { .name = "rx_broadcast", .offset = 0x03 },
- { .name = "rx_short", .offset = 0x04 },
- { .name = "rx_frag", .offset = 0x05 },
- { .name = "rx_jabber", .offset = 0x06 },
- { .name = "rx_crc", .offset = 0x07 },
- { .name = "rx_symbol_err", .offset = 0x08 },
- { .name = "rx_sz_64", .offset = 0x09 },
- { .name = "rx_sz_65_127", .offset = 0x0a},
- { .name = "rx_sz_128_255", .offset = 0x0b},
- { .name = "rx_sz_256_511", .offset = 0x0c },
- { .name = "rx_sz_512_1023", .offset = 0x0d },
- { .name = "rx_sz_1024_1526", .offset = 0x0e },
- { .name = "rx_sz_jumbo", .offset = 0x0f },
- { .name = "rx_pause", .offset = 0x10 },
- { .name = "rx_control", .offset = 0x11 },
- { .name = "rx_long", .offset = 0x12 },
- { .name = "rx_cat_drop", .offset = 0x13 },
- { .name = "rx_red_prio_0", .offset = 0x14 },
- { .name = "rx_red_prio_1", .offset = 0x15 },
- { .name = "rx_red_prio_2", .offset = 0x16 },
- { .name = "rx_red_prio_3", .offset = 0x17 },
- { .name = "rx_red_prio_4", .offset = 0x18 },
- { .name = "rx_red_prio_5", .offset = 0x19 },
- { .name = "rx_red_prio_6", .offset = 0x1a },
- { .name = "rx_red_prio_7", .offset = 0x1b },
- { .name = "rx_yellow_prio_0", .offset = 0x1c },
- { .name = "rx_yellow_prio_1", .offset = 0x1d },
- { .name = "rx_yellow_prio_2", .offset = 0x1e },
- { .name = "rx_yellow_prio_3", .offset = 0x1f },
- { .name = "rx_yellow_prio_4", .offset = 0x20 },
- { .name = "rx_yellow_prio_5", .offset = 0x21 },
- { .name = "rx_yellow_prio_6", .offset = 0x22 },
- { .name = "rx_yellow_prio_7", .offset = 0x23 },
- { .name = "rx_green_prio_0", .offset = 0x24 },
- { .name = "rx_green_prio_1", .offset = 0x25 },
- { .name = "rx_green_prio_2", .offset = 0x26 },
- { .name = "rx_green_prio_3", .offset = 0x27 },
- { .name = "rx_green_prio_4", .offset = 0x28 },
- { .name = "rx_green_prio_5", .offset = 0x29 },
- { .name = "rx_green_prio_6", .offset = 0x2a },
- { .name = "rx_green_prio_7", .offset = 0x2b },
- { .name = "rx_assembly_err", .offset = 0x2c },
- { .name = "rx_smd_err", .offset = 0x2d },
- { .name = "rx_assembly_ok", .offset = 0x2e },
- { .name = "rx_merge_frag", .offset = 0x2f },
- { .name = "rx_pmac_octets", .offset = 0x30, },
- { .name = "rx_pmac_unicast", .offset = 0x31, },
- { .name = "rx_pmac_multicast", .offset = 0x32 },
- { .name = "rx_pmac_broadcast", .offset = 0x33 },
- { .name = "rx_pmac_short", .offset = 0x34 },
- { .name = "rx_pmac_frag", .offset = 0x35 },
- { .name = "rx_pmac_jabber", .offset = 0x36 },
- { .name = "rx_pmac_crc", .offset = 0x37 },
- { .name = "rx_pmac_symbol_err", .offset = 0x38 },
- { .name = "rx_pmac_sz_64", .offset = 0x39 },
- { .name = "rx_pmac_sz_65_127", .offset = 0x3a },
- { .name = "rx_pmac_sz_128_255", .offset = 0x3b },
- { .name = "rx_pmac_sz_256_511", .offset = 0x3c },
- { .name = "rx_pmac_sz_512_1023", .offset = 0x3d },
- { .name = "rx_pmac_sz_1024_1526", .offset = 0x3e },
- { .name = "rx_pmac_sz_jumbo", .offset = 0x3f },
- { .name = "rx_pmac_pause", .offset = 0x40 },
- { .name = "rx_pmac_control", .offset = 0x41 },
- { .name = "rx_pmac_long", .offset = 0x42 },
- { .name = "tx_octets", .offset = 0x80, },
- { .name = "tx_unicast", .offset = 0x81, },
- { .name = "tx_multicast", .offset = 0x82 },
- { .name = "tx_broadcast", .offset = 0x83 },
- { .name = "tx_col", .offset = 0x84 },
- { .name = "tx_drop", .offset = 0x85 },
- { .name = "tx_pause", .offset = 0x86 },
- { .name = "tx_sz_64", .offset = 0x87 },
- { .name = "tx_sz_65_127", .offset = 0x88 },
- { .name = "tx_sz_128_255", .offset = 0x89 },
- { .name = "tx_sz_256_511", .offset = 0x8a },
- { .name = "tx_sz_512_1023", .offset = 0x8b },
- { .name = "tx_sz_1024_1526", .offset = 0x8c },
- { .name = "tx_sz_jumbo", .offset = 0x8d },
- { .name = "tx_yellow_prio_0", .offset = 0x8e },
- { .name = "tx_yellow_prio_1", .offset = 0x8f },
- { .name = "tx_yellow_prio_2", .offset = 0x90 },
- { .name = "tx_yellow_prio_3", .offset = 0x91 },
- { .name = "tx_yellow_prio_4", .offset = 0x92 },
- { .name = "tx_yellow_prio_5", .offset = 0x93 },
- { .name = "tx_yellow_prio_6", .offset = 0x94 },
- { .name = "tx_yellow_prio_7", .offset = 0x95 },
- { .name = "tx_green_prio_0", .offset = 0x96 },
- { .name = "tx_green_prio_1", .offset = 0x97 },
- { .name = "tx_green_prio_2", .offset = 0x98 },
- { .name = "tx_green_prio_3", .offset = 0x99 },
- { .name = "tx_green_prio_4", .offset = 0x9a },
- { .name = "tx_green_prio_5", .offset = 0x9b },
- { .name = "tx_green_prio_6", .offset = 0x9c },
- { .name = "tx_green_prio_7", .offset = 0x9d },
- { .name = "tx_aged", .offset = 0x9e },
- { .name = "tx_llct", .offset = 0x9f },
- { .name = "tx_ct", .offset = 0xa0 },
- { .name = "tx_mm_hold", .offset = 0xa1 },
- { .name = "tx_merge_frag", .offset = 0xa2 },
- { .name = "tx_pmac_octets", .offset = 0xa3, },
- { .name = "tx_pmac_unicast", .offset = 0xa4, },
- { .name = "tx_pmac_multicast", .offset = 0xa5 },
- { .name = "tx_pmac_broadcast", .offset = 0xa6 },
- { .name = "tx_pmac_pause", .offset = 0xa7 },
- { .name = "tx_pmac_sz_64", .offset = 0xa8 },
- { .name = "tx_pmac_sz_65_127", .offset = 0xa9 },
- { .name = "tx_pmac_sz_128_255", .offset = 0xaa },
- { .name = "tx_pmac_sz_256_511", .offset = 0xab },
- { .name = "tx_pmac_sz_512_1023", .offset = 0xac },
- { .name = "tx_pmac_sz_1024_1526", .offset = 0xad },
- { .name = "tx_pmac_sz_jumbo", .offset = 0xae },
- { .name = "dr_local", .offset = 0x100 },
- { .name = "dr_tail", .offset = 0x101 },
- { .name = "dr_yellow_prio_0", .offset = 0x102 },
- { .name = "dr_yellow_prio_1", .offset = 0x103 },
- { .name = "dr_yellow_prio_2", .offset = 0x104 },
- { .name = "dr_yellow_prio_3", .offset = 0x105 },
- { .name = "dr_yellow_prio_4", .offset = 0x106 },
- { .name = "dr_yellow_prio_5", .offset = 0x107 },
- { .name = "dr_yellow_prio_6", .offset = 0x108 },
- { .name = "dr_yellow_prio_7", .offset = 0x109 },
- { .name = "dr_green_prio_0", .offset = 0x10a },
- { .name = "dr_green_prio_1", .offset = 0x10b },
- { .name = "dr_green_prio_2", .offset = 0x10c },
- { .name = "dr_green_prio_3", .offset = 0x10d },
- { .name = "dr_green_prio_4", .offset = 0x10e },
- { .name = "dr_green_prio_5", .offset = 0x10f },
- { .name = "dr_green_prio_6", .offset = 0x110 },
- { .name = "dr_green_prio_7", .offset = 0x111 },
- };
- /* The following numbers are indexes into lan966x_stats_layout[] */
- #define SYS_COUNT_RX_OCT 0
- #define SYS_COUNT_RX_UC 1
- #define SYS_COUNT_RX_MC 2
- #define SYS_COUNT_RX_BC 3
- #define SYS_COUNT_RX_SHORT 4
- #define SYS_COUNT_RX_FRAG 5
- #define SYS_COUNT_RX_JABBER 6
- #define SYS_COUNT_RX_CRC 7
- #define SYS_COUNT_RX_SYMBOL_ERR 8
- #define SYS_COUNT_RX_SZ_64 9
- #define SYS_COUNT_RX_SZ_65_127 10
- #define SYS_COUNT_RX_SZ_128_255 11
- #define SYS_COUNT_RX_SZ_256_511 12
- #define SYS_COUNT_RX_SZ_512_1023 13
- #define SYS_COUNT_RX_SZ_1024_1526 14
- #define SYS_COUNT_RX_SZ_JUMBO 15
- #define SYS_COUNT_RX_PAUSE 16
- #define SYS_COUNT_RX_CONTROL 17
- #define SYS_COUNT_RX_LONG 18
- #define SYS_COUNT_RX_CAT_DROP 19
- #define SYS_COUNT_RX_RED_PRIO_0 20
- #define SYS_COUNT_RX_RED_PRIO_1 21
- #define SYS_COUNT_RX_RED_PRIO_2 22
- #define SYS_COUNT_RX_RED_PRIO_3 23
- #define SYS_COUNT_RX_RED_PRIO_4 24
- #define SYS_COUNT_RX_RED_PRIO_5 25
- #define SYS_COUNT_RX_RED_PRIO_6 26
- #define SYS_COUNT_RX_RED_PRIO_7 27
- #define SYS_COUNT_RX_YELLOW_PRIO_0 28
- #define SYS_COUNT_RX_YELLOW_PRIO_1 29
- #define SYS_COUNT_RX_YELLOW_PRIO_2 30
- #define SYS_COUNT_RX_YELLOW_PRIO_3 31
- #define SYS_COUNT_RX_YELLOW_PRIO_4 32
- #define SYS_COUNT_RX_YELLOW_PRIO_5 33
- #define SYS_COUNT_RX_YELLOW_PRIO_6 34
- #define SYS_COUNT_RX_YELLOW_PRIO_7 35
- #define SYS_COUNT_RX_GREEN_PRIO_0 36
- #define SYS_COUNT_RX_GREEN_PRIO_1 37
- #define SYS_COUNT_RX_GREEN_PRIO_2 38
- #define SYS_COUNT_RX_GREEN_PRIO_3 39
- #define SYS_COUNT_RX_GREEN_PRIO_4 40
- #define SYS_COUNT_RX_GREEN_PRIO_5 41
- #define SYS_COUNT_RX_GREEN_PRIO_6 42
- #define SYS_COUNT_RX_GREEN_PRIO_7 43
- #define SYS_COUNT_RX_ASSEMBLY_ERR 44
- #define SYS_COUNT_RX_SMD_ERR 45
- #define SYS_COUNT_RX_ASSEMBLY_OK 46
- #define SYS_COUNT_RX_MERGE_FRAG 47
- #define SYS_COUNT_RX_PMAC_OCT 48
- #define SYS_COUNT_RX_PMAC_UC 49
- #define SYS_COUNT_RX_PMAC_MC 50
- #define SYS_COUNT_RX_PMAC_BC 51
- #define SYS_COUNT_RX_PMAC_SHORT 52
- #define SYS_COUNT_RX_PMAC_FRAG 53
- #define SYS_COUNT_RX_PMAC_JABBER 54
- #define SYS_COUNT_RX_PMAC_CRC 55
- #define SYS_COUNT_RX_PMAC_SYMBOL_ERR 56
- #define SYS_COUNT_RX_PMAC_SZ_64 57
- #define SYS_COUNT_RX_PMAC_SZ_65_127 58
- #define SYS_COUNT_RX_PMAC_SZ_128_255 59
- #define SYS_COUNT_RX_PMAC_SZ_256_511 60
- #define SYS_COUNT_RX_PMAC_SZ_512_1023 61
- #define SYS_COUNT_RX_PMAC_SZ_1024_1526 62
- #define SYS_COUNT_RX_PMAC_SZ_JUMBO 63
- #define SYS_COUNT_RX_PMAC_PAUSE 64
- #define SYS_COUNT_RX_PMAC_CONTROL 65
- #define SYS_COUNT_RX_PMAC_LONG 66
- #define SYS_COUNT_TX_OCT 67
- #define SYS_COUNT_TX_UC 68
- #define SYS_COUNT_TX_MC 69
- #define SYS_COUNT_TX_BC 70
- #define SYS_COUNT_TX_COL 71
- #define SYS_COUNT_TX_DROP 72
- #define SYS_COUNT_TX_PAUSE 73
- #define SYS_COUNT_TX_SZ_64 74
- #define SYS_COUNT_TX_SZ_65_127 75
- #define SYS_COUNT_TX_SZ_128_255 76
- #define SYS_COUNT_TX_SZ_256_511 77
- #define SYS_COUNT_TX_SZ_512_1023 78
- #define SYS_COUNT_TX_SZ_1024_1526 79
- #define SYS_COUNT_TX_SZ_JUMBO 80
- #define SYS_COUNT_TX_YELLOW_PRIO_0 81
- #define SYS_COUNT_TX_YELLOW_PRIO_1 82
- #define SYS_COUNT_TX_YELLOW_PRIO_2 83
- #define SYS_COUNT_TX_YELLOW_PRIO_3 84
- #define SYS_COUNT_TX_YELLOW_PRIO_4 85
- #define SYS_COUNT_TX_YELLOW_PRIO_5 86
- #define SYS_COUNT_TX_YELLOW_PRIO_6 87
- #define SYS_COUNT_TX_YELLOW_PRIO_7 88
- #define SYS_COUNT_TX_GREEN_PRIO_0 89
- #define SYS_COUNT_TX_GREEN_PRIO_1 90
- #define SYS_COUNT_TX_GREEN_PRIO_2 91
- #define SYS_COUNT_TX_GREEN_PRIO_3 92
- #define SYS_COUNT_TX_GREEN_PRIO_4 93
- #define SYS_COUNT_TX_GREEN_PRIO_5 94
- #define SYS_COUNT_TX_GREEN_PRIO_6 95
- #define SYS_COUNT_TX_GREEN_PRIO_7 96
- #define SYS_COUNT_TX_AGED 97
- #define SYS_COUNT_TX_LLCT 98
- #define SYS_COUNT_TX_CT 99
- #define SYS_COUNT_TX_MM_HOLD 100
- #define SYS_COUNT_TX_MERGE_FRAG 101
- #define SYS_COUNT_TX_PMAC_OCT 102
- #define SYS_COUNT_TX_PMAC_UC 103
- #define SYS_COUNT_TX_PMAC_MC 104
- #define SYS_COUNT_TX_PMAC_BC 105
- #define SYS_COUNT_TX_PMAC_PAUSE 106
- #define SYS_COUNT_TX_PMAC_SZ_64 107
- #define SYS_COUNT_TX_PMAC_SZ_65_127 108
- #define SYS_COUNT_TX_PMAC_SZ_128_255 109
- #define SYS_COUNT_TX_PMAC_SZ_256_511 110
- #define SYS_COUNT_TX_PMAC_SZ_512_1023 111
- #define SYS_COUNT_TX_PMAC_SZ_1024_1526 112
- #define SYS_COUNT_TX_PMAC_SZ_JUMBO 113
- #define SYS_COUNT_DR_LOCAL 114
- #define SYS_COUNT_DR_TAIL 115
- #define SYS_COUNT_DR_YELLOW_PRIO_0 116
- #define SYS_COUNT_DR_YELLOW_PRIO_1 117
- #define SYS_COUNT_DR_YELLOW_PRIO_2 118
- #define SYS_COUNT_DR_YELLOW_PRIO_3 119
- #define SYS_COUNT_DR_YELLOW_PRIO_4 120
- #define SYS_COUNT_DR_YELLOW_PRIO_5 121
- #define SYS_COUNT_DR_YELLOW_PRIO_6 122
- #define SYS_COUNT_DR_YELLOW_PRIO_7 123
- #define SYS_COUNT_DR_GREEN_PRIO_0 124
- #define SYS_COUNT_DR_GREEN_PRIO_1 125
- #define SYS_COUNT_DR_GREEN_PRIO_2 126
- #define SYS_COUNT_DR_GREEN_PRIO_3 127
- #define SYS_COUNT_DR_GREEN_PRIO_4 128
- #define SYS_COUNT_DR_GREEN_PRIO_5 129
- #define SYS_COUNT_DR_GREEN_PRIO_6 130
- #define SYS_COUNT_DR_GREEN_PRIO_7 131
- /* Add a possibly wrapping 32 bit value to a 64 bit counter */
- static void lan966x_add_cnt(u64 *cnt, u32 val)
- {
- if (val < (*cnt & U32_MAX))
- *cnt += (u64)1 << 32; /* value has wrapped */
- *cnt = (*cnt & ~(u64)U32_MAX) + val;
- }
- static void lan966x_stats_update(struct lan966x *lan966x)
- {
- int i, j;
- mutex_lock(&lan966x->stats_lock);
- for (i = 0; i < lan966x->num_phys_ports; i++) {
- uint idx = i * lan966x->num_stats;
- lan_wr(SYS_STAT_CFG_STAT_VIEW_SET(i),
- lan966x, SYS_STAT_CFG);
- for (j = 0; j < lan966x->num_stats; j++) {
- u32 offset = lan966x->stats_layout[j].offset;
- lan966x_add_cnt(&lan966x->stats[idx++],
- lan_rd(lan966x, SYS_CNT(offset)));
- }
- }
- mutex_unlock(&lan966x->stats_lock);
- }
- static int lan966x_get_sset_count(struct net_device *dev, int sset)
- {
- struct lan966x_port *port = netdev_priv(dev);
- struct lan966x *lan966x = port->lan966x;
- if (sset != ETH_SS_STATS)
- return -EOPNOTSUPP;
- return lan966x->num_stats;
- }
- static void lan966x_get_strings(struct net_device *netdev, u32 sset, u8 *data)
- {
- struct lan966x_port *port = netdev_priv(netdev);
- struct lan966x *lan966x = port->lan966x;
- int i;
- if (sset != ETH_SS_STATS)
- return;
- for (i = 0; i < lan966x->num_stats; i++)
- memcpy(data + i * ETH_GSTRING_LEN,
- lan966x->stats_layout[i].name, ETH_GSTRING_LEN);
- }
- static void lan966x_get_ethtool_stats(struct net_device *dev,
- struct ethtool_stats *stats, u64 *data)
- {
- struct lan966x_port *port = netdev_priv(dev);
- struct lan966x *lan966x = port->lan966x;
- int i;
- /* check and update now */
- lan966x_stats_update(lan966x);
- /* Copy all counters */
- for (i = 0; i < lan966x->num_stats; i++)
- *data++ = lan966x->stats[port->chip_port *
- lan966x->num_stats + i];
- }
- static void lan966x_get_eth_mac_stats(struct net_device *dev,
- struct ethtool_eth_mac_stats *mac_stats)
- {
- struct lan966x_port *port = netdev_priv(dev);
- struct lan966x *lan966x = port->lan966x;
- u32 idx;
- lan966x_stats_update(lan966x);
- idx = port->chip_port * lan966x->num_stats;
- mutex_lock(&lan966x->stats_lock);
- mac_stats->FramesTransmittedOK =
- lan966x->stats[idx + SYS_COUNT_TX_UC] +
- lan966x->stats[idx + SYS_COUNT_TX_MC] +
- lan966x->stats[idx + SYS_COUNT_TX_BC] +
- lan966x->stats[idx + SYS_COUNT_TX_PMAC_UC] +
- lan966x->stats[idx + SYS_COUNT_TX_PMAC_MC] +
- lan966x->stats[idx + SYS_COUNT_TX_PMAC_BC];
- mac_stats->SingleCollisionFrames =
- lan966x->stats[idx + SYS_COUNT_TX_COL];
- mac_stats->FramesReceivedOK =
- lan966x->stats[idx + SYS_COUNT_RX_UC] +
- lan966x->stats[idx + SYS_COUNT_RX_MC] +
- lan966x->stats[idx + SYS_COUNT_RX_BC];
- mac_stats->FrameCheckSequenceErrors =
- lan966x->stats[idx + SYS_COUNT_RX_CRC] +
- lan966x->stats[idx + SYS_COUNT_RX_CRC];
- mac_stats->OctetsTransmittedOK =
- lan966x->stats[idx + SYS_COUNT_TX_OCT] +
- lan966x->stats[idx + SYS_COUNT_TX_PMAC_OCT];
- mac_stats->FramesWithDeferredXmissions =
- lan966x->stats[idx + SYS_COUNT_TX_MM_HOLD];
- mac_stats->OctetsReceivedOK =
- lan966x->stats[idx + SYS_COUNT_RX_OCT];
- mac_stats->MulticastFramesXmittedOK =
- lan966x->stats[idx + SYS_COUNT_TX_MC] +
- lan966x->stats[idx + SYS_COUNT_TX_PMAC_MC];
- mac_stats->BroadcastFramesXmittedOK =
- lan966x->stats[idx + SYS_COUNT_TX_BC] +
- lan966x->stats[idx + SYS_COUNT_TX_PMAC_BC];
- mac_stats->MulticastFramesReceivedOK =
- lan966x->stats[idx + SYS_COUNT_RX_MC];
- mac_stats->BroadcastFramesReceivedOK =
- lan966x->stats[idx + SYS_COUNT_RX_BC];
- mac_stats->InRangeLengthErrors =
- lan966x->stats[idx + SYS_COUNT_RX_FRAG] +
- lan966x->stats[idx + SYS_COUNT_RX_JABBER] +
- lan966x->stats[idx + SYS_COUNT_RX_CRC] +
- lan966x->stats[idx + SYS_COUNT_RX_PMAC_FRAG] +
- lan966x->stats[idx + SYS_COUNT_RX_PMAC_JABBER] +
- lan966x->stats[idx + SYS_COUNT_RX_PMAC_CRC];
- mac_stats->OutOfRangeLengthField =
- lan966x->stats[idx + SYS_COUNT_RX_SHORT] +
- lan966x->stats[idx + SYS_COUNT_RX_PMAC_SHORT] +
- lan966x->stats[idx + SYS_COUNT_RX_LONG] +
- lan966x->stats[idx + SYS_COUNT_RX_PMAC_LONG];
- mac_stats->FrameTooLongErrors =
- lan966x->stats[idx + SYS_COUNT_RX_LONG] +
- lan966x->stats[idx + SYS_COUNT_RX_PMAC_LONG];
- mutex_unlock(&lan966x->stats_lock);
- }
- static const struct ethtool_rmon_hist_range lan966x_rmon_ranges[] = {
- { 0, 64 },
- { 65, 127 },
- { 128, 255 },
- { 256, 511 },
- { 512, 1023 },
- { 1024, 1518 },
- { 1519, 10239 },
- {}
- };
- static void lan966x_get_eth_rmon_stats(struct net_device *dev,
- struct ethtool_rmon_stats *rmon_stats,
- const struct ethtool_rmon_hist_range **ranges)
- {
- struct lan966x_port *port = netdev_priv(dev);
- struct lan966x *lan966x = port->lan966x;
- u32 idx;
- lan966x_stats_update(lan966x);
- idx = port->chip_port * lan966x->num_stats;
- mutex_lock(&lan966x->stats_lock);
- rmon_stats->undersize_pkts =
- lan966x->stats[idx + SYS_COUNT_RX_SHORT] +
- lan966x->stats[idx + SYS_COUNT_RX_PMAC_SHORT];
- rmon_stats->oversize_pkts =
- lan966x->stats[idx + SYS_COUNT_RX_LONG] +
- lan966x->stats[idx + SYS_COUNT_RX_PMAC_LONG];
- rmon_stats->fragments =
- lan966x->stats[idx + SYS_COUNT_RX_FRAG] +
- lan966x->stats[idx + SYS_COUNT_RX_PMAC_FRAG];
- rmon_stats->jabbers =
- lan966x->stats[idx + SYS_COUNT_RX_JABBER] +
- lan966x->stats[idx + SYS_COUNT_RX_PMAC_JABBER];
- rmon_stats->hist[0] =
- lan966x->stats[idx + SYS_COUNT_RX_SZ_64] +
- lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_64];
- rmon_stats->hist[1] =
- lan966x->stats[idx + SYS_COUNT_RX_SZ_65_127] +
- lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_65_127];
- rmon_stats->hist[2] =
- lan966x->stats[idx + SYS_COUNT_RX_SZ_128_255] +
- lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_128_255];
- rmon_stats->hist[3] =
- lan966x->stats[idx + SYS_COUNT_RX_SZ_256_511] +
- lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_256_511];
- rmon_stats->hist[4] =
- lan966x->stats[idx + SYS_COUNT_RX_SZ_512_1023] +
- lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_512_1023];
- rmon_stats->hist[5] =
- lan966x->stats[idx + SYS_COUNT_RX_SZ_1024_1526] +
- lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_1024_1526];
- rmon_stats->hist[6] =
- lan966x->stats[idx + SYS_COUNT_RX_SZ_1024_1526] +
- lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_1024_1526];
- rmon_stats->hist_tx[0] =
- lan966x->stats[idx + SYS_COUNT_TX_SZ_64] +
- lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_64];
- rmon_stats->hist_tx[1] =
- lan966x->stats[idx + SYS_COUNT_TX_SZ_65_127] +
- lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_65_127];
- rmon_stats->hist_tx[2] =
- lan966x->stats[idx + SYS_COUNT_TX_SZ_128_255] +
- lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_128_255];
- rmon_stats->hist_tx[3] =
- lan966x->stats[idx + SYS_COUNT_TX_SZ_256_511] +
- lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_256_511];
- rmon_stats->hist_tx[4] =
- lan966x->stats[idx + SYS_COUNT_TX_SZ_512_1023] +
- lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_512_1023];
- rmon_stats->hist_tx[5] =
- lan966x->stats[idx + SYS_COUNT_TX_SZ_1024_1526] +
- lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_1024_1526];
- rmon_stats->hist_tx[6] =
- lan966x->stats[idx + SYS_COUNT_TX_SZ_1024_1526] +
- lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_1024_1526];
- mutex_unlock(&lan966x->stats_lock);
- *ranges = lan966x_rmon_ranges;
- }
- static int lan966x_get_link_ksettings(struct net_device *ndev,
- struct ethtool_link_ksettings *cmd)
- {
- struct lan966x_port *port = netdev_priv(ndev);
- return phylink_ethtool_ksettings_get(port->phylink, cmd);
- }
- static int lan966x_set_link_ksettings(struct net_device *ndev,
- const struct ethtool_link_ksettings *cmd)
- {
- struct lan966x_port *port = netdev_priv(ndev);
- return phylink_ethtool_ksettings_set(port->phylink, cmd);
- }
- static void lan966x_get_pauseparam(struct net_device *dev,
- struct ethtool_pauseparam *pause)
- {
- struct lan966x_port *port = netdev_priv(dev);
- phylink_ethtool_get_pauseparam(port->phylink, pause);
- }
- static int lan966x_set_pauseparam(struct net_device *dev,
- struct ethtool_pauseparam *pause)
- {
- struct lan966x_port *port = netdev_priv(dev);
- return phylink_ethtool_set_pauseparam(port->phylink, pause);
- }
- static int lan966x_get_ts_info(struct net_device *dev,
- struct kernel_ethtool_ts_info *info)
- {
- struct lan966x_port *port = netdev_priv(dev);
- struct lan966x *lan966x = port->lan966x;
- struct lan966x_phc *phc;
- if (!lan966x->ptp)
- return ethtool_op_get_ts_info(dev, info);
- phc = &lan966x->phc[LAN966X_PHC_PORT];
- if (phc->clock) {
- info->phc_index = ptp_clock_index(phc->clock);
- } else {
- info->so_timestamping |= SOF_TIMESTAMPING_TX_SOFTWARE;
- return 0;
- }
- info->so_timestamping |= SOF_TIMESTAMPING_TX_SOFTWARE |
- SOF_TIMESTAMPING_TX_HARDWARE |
- SOF_TIMESTAMPING_RX_HARDWARE |
- SOF_TIMESTAMPING_RAW_HARDWARE;
- info->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON) |
- BIT(HWTSTAMP_TX_ONESTEP_SYNC);
- info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) |
- BIT(HWTSTAMP_FILTER_ALL);
- return 0;
- }
- const struct ethtool_ops lan966x_ethtool_ops = {
- .get_link_ksettings = lan966x_get_link_ksettings,
- .set_link_ksettings = lan966x_set_link_ksettings,
- .get_pauseparam = lan966x_get_pauseparam,
- .set_pauseparam = lan966x_set_pauseparam,
- .get_sset_count = lan966x_get_sset_count,
- .get_strings = lan966x_get_strings,
- .get_ethtool_stats = lan966x_get_ethtool_stats,
- .get_eth_mac_stats = lan966x_get_eth_mac_stats,
- .get_rmon_stats = lan966x_get_eth_rmon_stats,
- .get_link = ethtool_op_get_link,
- .get_ts_info = lan966x_get_ts_info,
- };
- static void lan966x_check_stats_work(struct work_struct *work)
- {
- struct delayed_work *del_work = to_delayed_work(work);
- struct lan966x *lan966x = container_of(del_work, struct lan966x,
- stats_work);
- lan966x_stats_update(lan966x);
- queue_delayed_work(lan966x->stats_queue, &lan966x->stats_work,
- LAN966X_STATS_CHECK_DELAY);
- }
- void lan966x_stats_get(struct net_device *dev,
- struct rtnl_link_stats64 *stats)
- {
- struct lan966x_port *port = netdev_priv(dev);
- struct lan966x *lan966x = port->lan966x;
- u32 idx;
- int i;
- idx = port->chip_port * lan966x->num_stats;
- mutex_lock(&lan966x->stats_lock);
- stats->rx_bytes = lan966x->stats[idx + SYS_COUNT_RX_OCT] +
- lan966x->stats[idx + SYS_COUNT_RX_PMAC_OCT];
- stats->rx_packets = lan966x->stats[idx + SYS_COUNT_RX_SHORT] +
- lan966x->stats[idx + SYS_COUNT_RX_FRAG] +
- lan966x->stats[idx + SYS_COUNT_RX_JABBER] +
- lan966x->stats[idx + SYS_COUNT_RX_CRC] +
- lan966x->stats[idx + SYS_COUNT_RX_SYMBOL_ERR] +
- lan966x->stats[idx + SYS_COUNT_RX_SZ_64] +
- lan966x->stats[idx + SYS_COUNT_RX_SZ_65_127] +
- lan966x->stats[idx + SYS_COUNT_RX_SZ_128_255] +
- lan966x->stats[idx + SYS_COUNT_RX_SZ_256_511] +
- lan966x->stats[idx + SYS_COUNT_RX_SZ_512_1023] +
- lan966x->stats[idx + SYS_COUNT_RX_SZ_1024_1526] +
- lan966x->stats[idx + SYS_COUNT_RX_SZ_JUMBO] +
- lan966x->stats[idx + SYS_COUNT_RX_LONG] +
- lan966x->stats[idx + SYS_COUNT_RX_PMAC_SHORT] +
- lan966x->stats[idx + SYS_COUNT_RX_PMAC_FRAG] +
- lan966x->stats[idx + SYS_COUNT_RX_PMAC_JABBER] +
- lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_64] +
- lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_65_127] +
- lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_128_255] +
- lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_256_511] +
- lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_512_1023] +
- lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_1024_1526] +
- lan966x->stats[idx + SYS_COUNT_RX_PMAC_SZ_JUMBO];
- stats->multicast = lan966x->stats[idx + SYS_COUNT_RX_MC] +
- lan966x->stats[idx + SYS_COUNT_RX_PMAC_MC];
- stats->rx_errors = lan966x->stats[idx + SYS_COUNT_RX_SHORT] +
- lan966x->stats[idx + SYS_COUNT_RX_FRAG] +
- lan966x->stats[idx + SYS_COUNT_RX_JABBER] +
- lan966x->stats[idx + SYS_COUNT_RX_CRC] +
- lan966x->stats[idx + SYS_COUNT_RX_SYMBOL_ERR] +
- lan966x->stats[idx + SYS_COUNT_RX_LONG];
- stats->rx_dropped = dev->stats.rx_dropped +
- lan966x->stats[idx + SYS_COUNT_RX_LONG] +
- lan966x->stats[idx + SYS_COUNT_DR_LOCAL] +
- lan966x->stats[idx + SYS_COUNT_DR_TAIL] +
- lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_0] +
- lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_1] +
- lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_2] +
- lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_3] +
- lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_4] +
- lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_5] +
- lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_6] +
- lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_7];
- for (i = 0; i < LAN966X_NUM_TC; i++) {
- stats->rx_dropped +=
- (lan966x->stats[idx + SYS_COUNT_DR_YELLOW_PRIO_0 + i] +
- lan966x->stats[idx + SYS_COUNT_DR_GREEN_PRIO_0 + i]);
- }
- /* Get Tx stats */
- stats->tx_bytes = lan966x->stats[idx + SYS_COUNT_TX_OCT] +
- lan966x->stats[idx + SYS_COUNT_TX_PMAC_OCT];
- stats->tx_packets = lan966x->stats[idx + SYS_COUNT_TX_SZ_64] +
- lan966x->stats[idx + SYS_COUNT_TX_SZ_65_127] +
- lan966x->stats[idx + SYS_COUNT_TX_SZ_128_255] +
- lan966x->stats[idx + SYS_COUNT_TX_SZ_256_511] +
- lan966x->stats[idx + SYS_COUNT_TX_SZ_512_1023] +
- lan966x->stats[idx + SYS_COUNT_TX_SZ_1024_1526] +
- lan966x->stats[idx + SYS_COUNT_TX_SZ_JUMBO] +
- lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_64] +
- lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_65_127] +
- lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_128_255] +
- lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_256_511] +
- lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_512_1023] +
- lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_1024_1526] +
- lan966x->stats[idx + SYS_COUNT_TX_PMAC_SZ_JUMBO];
- stats->tx_dropped = lan966x->stats[idx + SYS_COUNT_TX_DROP] +
- lan966x->stats[idx + SYS_COUNT_TX_AGED];
- stats->collisions = lan966x->stats[idx + SYS_COUNT_TX_COL];
- mutex_unlock(&lan966x->stats_lock);
- }
- int lan966x_stats_init(struct lan966x *lan966x)
- {
- char queue_name[32];
- lan966x->stats_layout = lan966x_stats_layout;
- lan966x->num_stats = ARRAY_SIZE(lan966x_stats_layout);
- lan966x->stats = devm_kcalloc(lan966x->dev, lan966x->num_phys_ports *
- lan966x->num_stats,
- sizeof(u64), GFP_KERNEL);
- if (!lan966x->stats)
- return -ENOMEM;
- /* Init stats worker */
- mutex_init(&lan966x->stats_lock);
- snprintf(queue_name, sizeof(queue_name), "%s-stats",
- dev_name(lan966x->dev));
- lan966x->stats_queue = create_singlethread_workqueue(queue_name);
- if (!lan966x->stats_queue)
- return -ENOMEM;
- INIT_DELAYED_WORK(&lan966x->stats_work, lan966x_check_stats_work);
- queue_delayed_work(lan966x->stats_queue, &lan966x->stats_work,
- LAN966X_STATS_CHECK_DELAY);
- return 0;
- }
|