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

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'net-dsa-mt7530-modernize-mib-handling-fix'

Christian Marangi says:

====================
net: dsa: mt7530: modernize MIB handling + fix

This small series modernize MIB handling for MT7530 and also
implement .get_stats64.

It was reported that kernel and Switch MIB desync in scenario where
a packet is forwarded from a port to another. In such case, the
forwarding is offloaded and the kernel is not aware of the
transmitted packet. To handle this, read the counter directly
from Switch registers.
====================

Link: https://patch.msgid.link/20250410163022.3695-1-ansuelsmth@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

+239 -49
+197 -49
drivers/net/dsa/mt7530.c
··· 32 32 33 33 /* String, offset, and register size in bytes if different from 4 bytes */ 34 34 static const struct mt7530_mib_desc mt7530_mib[] = { 35 - MIB_DESC(1, 0x00, "TxDrop"), 36 - MIB_DESC(1, 0x04, "TxCrcErr"), 37 - MIB_DESC(1, 0x08, "TxUnicast"), 38 - MIB_DESC(1, 0x0c, "TxMulticast"), 39 - MIB_DESC(1, 0x10, "TxBroadcast"), 40 - MIB_DESC(1, 0x14, "TxCollision"), 41 - MIB_DESC(1, 0x18, "TxSingleCollision"), 42 - MIB_DESC(1, 0x1c, "TxMultipleCollision"), 43 - MIB_DESC(1, 0x20, "TxDeferred"), 44 - MIB_DESC(1, 0x24, "TxLateCollision"), 45 - MIB_DESC(1, 0x28, "TxExcessiveCollistion"), 46 - MIB_DESC(1, 0x2c, "TxPause"), 47 - MIB_DESC(1, 0x30, "TxPktSz64"), 48 - MIB_DESC(1, 0x34, "TxPktSz65To127"), 49 - MIB_DESC(1, 0x38, "TxPktSz128To255"), 50 - MIB_DESC(1, 0x3c, "TxPktSz256To511"), 51 - MIB_DESC(1, 0x40, "TxPktSz512To1023"), 52 - MIB_DESC(1, 0x44, "Tx1024ToMax"), 53 - MIB_DESC(2, 0x48, "TxBytes"), 54 - MIB_DESC(1, 0x60, "RxDrop"), 55 - MIB_DESC(1, 0x64, "RxFiltering"), 56 - MIB_DESC(1, 0x68, "RxUnicast"), 57 - MIB_DESC(1, 0x6c, "RxMulticast"), 58 - MIB_DESC(1, 0x70, "RxBroadcast"), 59 - MIB_DESC(1, 0x74, "RxAlignErr"), 60 - MIB_DESC(1, 0x78, "RxCrcErr"), 61 - MIB_DESC(1, 0x7c, "RxUnderSizeErr"), 62 - MIB_DESC(1, 0x80, "RxFragErr"), 63 - MIB_DESC(1, 0x84, "RxOverSzErr"), 64 - MIB_DESC(1, 0x88, "RxJabberErr"), 65 - MIB_DESC(1, 0x8c, "RxPause"), 66 - MIB_DESC(1, 0x90, "RxPktSz64"), 67 - MIB_DESC(1, 0x94, "RxPktSz65To127"), 68 - MIB_DESC(1, 0x98, "RxPktSz128To255"), 69 - MIB_DESC(1, 0x9c, "RxPktSz256To511"), 70 - MIB_DESC(1, 0xa0, "RxPktSz512To1023"), 71 - MIB_DESC(1, 0xa4, "RxPktSz1024ToMax"), 72 - MIB_DESC(2, 0xa8, "RxBytes"), 73 - MIB_DESC(1, 0xb0, "RxCtrlDrop"), 74 - MIB_DESC(1, 0xb4, "RxIngressDrop"), 75 - MIB_DESC(1, 0xb8, "RxArlDrop"), 35 + MIB_DESC(1, MT7530_PORT_MIB_TX_DROP, "TxDrop"), 36 + MIB_DESC(1, MT7530_PORT_MIB_TX_CRC_ERR, "TxCrcErr"), 37 + MIB_DESC(1, MT7530_PORT_MIB_TX_COLLISION, "TxCollision"), 38 + MIB_DESC(1, MT7530_PORT_MIB_RX_DROP, "RxDrop"), 39 + MIB_DESC(1, MT7530_PORT_MIB_RX_FILTERING, "RxFiltering"), 40 + MIB_DESC(1, MT7530_PORT_MIB_RX_CRC_ERR, "RxCrcErr"), 41 + MIB_DESC(1, MT7530_PORT_MIB_RX_CTRL_DROP, "RxCtrlDrop"), 42 + MIB_DESC(1, MT7530_PORT_MIB_RX_INGRESS_DROP, "RxIngressDrop"), 43 + MIB_DESC(1, MT7530_PORT_MIB_RX_ARL_DROP, "RxArlDrop"), 76 44 }; 77 45 78 46 static void ··· 758 790 } 759 791 760 792 static void 793 + mt7530_read_port_stats(struct mt7530_priv *priv, int port, 794 + u32 offset, u8 size, uint64_t *data) 795 + { 796 + u32 val, reg = MT7530_PORT_MIB_COUNTER(port) + offset; 797 + 798 + val = mt7530_read(priv, reg); 799 + *data = val; 800 + 801 + if (size == 2) { 802 + val = mt7530_read(priv, reg + 4); 803 + *data |= (u64)val << 32; 804 + } 805 + } 806 + 807 + static void 761 808 mt7530_get_ethtool_stats(struct dsa_switch *ds, int port, 762 809 uint64_t *data) 763 810 { 764 811 struct mt7530_priv *priv = ds->priv; 765 812 const struct mt7530_mib_desc *mib; 766 - u32 reg, i; 767 - u64 hi; 813 + int i; 768 814 769 815 for (i = 0; i < ARRAY_SIZE(mt7530_mib); i++) { 770 816 mib = &mt7530_mib[i]; 771 - reg = MT7530_PORT_MIB_COUNTER(port) + mib->offset; 772 817 773 - data[i] = mt7530_read(priv, reg); 774 - if (mib->size == 2) { 775 - hi = mt7530_read(priv, reg + 4); 776 - data[i] |= hi << 32; 777 - } 818 + mt7530_read_port_stats(priv, port, mib->offset, mib->size, 819 + data + i); 778 820 } 779 821 } 780 822 ··· 795 817 return 0; 796 818 797 819 return ARRAY_SIZE(mt7530_mib); 820 + } 821 + 822 + static void mt7530_get_eth_mac_stats(struct dsa_switch *ds, int port, 823 + struct ethtool_eth_mac_stats *mac_stats) 824 + { 825 + struct mt7530_priv *priv = ds->priv; 826 + 827 + /* MIB counter doesn't provide a FramesTransmittedOK but instead 828 + * provide stats for Unicast, Broadcast and Multicast frames separately. 829 + * To simulate a global frame counter, read Unicast and addition Multicast 830 + * and Broadcast later 831 + */ 832 + mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_UNICAST, 1, 833 + &mac_stats->FramesTransmittedOK); 834 + 835 + mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_SINGLE_COLLISION, 1, 836 + &mac_stats->SingleCollisionFrames); 837 + 838 + mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_MULTIPLE_COLLISION, 1, 839 + &mac_stats->MultipleCollisionFrames); 840 + 841 + mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_UNICAST, 1, 842 + &mac_stats->FramesReceivedOK); 843 + 844 + mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_BYTES, 2, 845 + &mac_stats->OctetsTransmittedOK); 846 + 847 + mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_ALIGN_ERR, 1, 848 + &mac_stats->AlignmentErrors); 849 + 850 + mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_DEFERRED, 1, 851 + &mac_stats->FramesWithDeferredXmissions); 852 + 853 + mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_LATE_COLLISION, 1, 854 + &mac_stats->LateCollisions); 855 + 856 + mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_EXCESSIVE_COLLISION, 1, 857 + &mac_stats->FramesAbortedDueToXSColls); 858 + 859 + mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_BYTES, 2, 860 + &mac_stats->OctetsReceivedOK); 861 + 862 + mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_MULTICAST, 1, 863 + &mac_stats->MulticastFramesXmittedOK); 864 + mac_stats->FramesTransmittedOK += mac_stats->MulticastFramesXmittedOK; 865 + mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_BROADCAST, 1, 866 + &mac_stats->BroadcastFramesXmittedOK); 867 + mac_stats->FramesTransmittedOK += mac_stats->BroadcastFramesXmittedOK; 868 + 869 + mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_MULTICAST, 1, 870 + &mac_stats->MulticastFramesReceivedOK); 871 + mac_stats->FramesReceivedOK += mac_stats->MulticastFramesReceivedOK; 872 + mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_BROADCAST, 1, 873 + &mac_stats->BroadcastFramesReceivedOK); 874 + mac_stats->FramesReceivedOK += mac_stats->BroadcastFramesReceivedOK; 875 + } 876 + 877 + static const struct ethtool_rmon_hist_range mt7530_rmon_ranges[] = { 878 + { 0, 64 }, 879 + { 65, 127 }, 880 + { 128, 255 }, 881 + { 256, 511 }, 882 + { 512, 1023 }, 883 + { 1024, MT7530_MAX_MTU }, 884 + {} 885 + }; 886 + 887 + static void mt7530_get_rmon_stats(struct dsa_switch *ds, int port, 888 + struct ethtool_rmon_stats *rmon_stats, 889 + const struct ethtool_rmon_hist_range **ranges) 890 + { 891 + struct mt7530_priv *priv = ds->priv; 892 + 893 + mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_UNDER_SIZE_ERR, 1, 894 + &rmon_stats->undersize_pkts); 895 + mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_OVER_SZ_ERR, 1, 896 + &rmon_stats->oversize_pkts); 897 + mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_FRAG_ERR, 1, 898 + &rmon_stats->fragments); 899 + mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_JABBER_ERR, 1, 900 + &rmon_stats->jabbers); 901 + 902 + mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_PKT_SZ_64, 1, 903 + &rmon_stats->hist[0]); 904 + mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_PKT_SZ_65_TO_127, 1, 905 + &rmon_stats->hist[1]); 906 + mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_PKT_SZ_128_TO_255, 1, 907 + &rmon_stats->hist[2]); 908 + mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_PKT_SZ_256_TO_511, 1, 909 + &rmon_stats->hist[3]); 910 + mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_PKT_SZ_512_TO_1023, 1, 911 + &rmon_stats->hist[4]); 912 + mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_PKT_SZ_1024_TO_MAX, 1, 913 + &rmon_stats->hist[5]); 914 + 915 + mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_PKT_SZ_64, 1, 916 + &rmon_stats->hist_tx[0]); 917 + mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_PKT_SZ_65_TO_127, 1, 918 + &rmon_stats->hist_tx[1]); 919 + mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_PKT_SZ_128_TO_255, 1, 920 + &rmon_stats->hist_tx[2]); 921 + mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_PKT_SZ_256_TO_511, 1, 922 + &rmon_stats->hist_tx[3]); 923 + mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_PKT_SZ_512_TO_1023, 1, 924 + &rmon_stats->hist_tx[4]); 925 + mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_PKT_SZ_1024_TO_MAX, 1, 926 + &rmon_stats->hist_tx[5]); 927 + 928 + *ranges = mt7530_rmon_ranges; 929 + } 930 + 931 + static void mt7530_get_stats64(struct dsa_switch *ds, int port, 932 + struct rtnl_link_stats64 *storage) 933 + { 934 + struct mt7530_priv *priv = ds->priv; 935 + uint64_t data; 936 + 937 + /* MIB counter doesn't provide a FramesTransmittedOK but instead 938 + * provide stats for Unicast, Broadcast and Multicast frames separately. 939 + * To simulate a global frame counter, read Unicast and addition Multicast 940 + * and Broadcast later 941 + */ 942 + mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_UNICAST, 1, 943 + &storage->rx_packets); 944 + mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_MULTICAST, 1, 945 + &storage->multicast); 946 + storage->rx_packets += storage->multicast; 947 + mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_BROADCAST, 1, 948 + &data); 949 + storage->rx_packets += data; 950 + 951 + mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_UNICAST, 1, 952 + &storage->tx_packets); 953 + mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_MULTICAST, 1, 954 + &data); 955 + storage->tx_packets += data; 956 + mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_BROADCAST, 1, 957 + &data); 958 + storage->tx_packets += data; 959 + 960 + mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_BYTES, 2, 961 + &storage->rx_bytes); 962 + 963 + mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_BYTES, 2, 964 + &storage->tx_bytes); 965 + 966 + mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_DROP, 1, 967 + &storage->rx_dropped); 968 + 969 + mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_DROP, 1, 970 + &storage->tx_dropped); 971 + 972 + mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_CRC_ERR, 1, 973 + &storage->rx_crc_errors); 974 + } 975 + 976 + static void mt7530_get_eth_ctrl_stats(struct dsa_switch *ds, int port, 977 + struct ethtool_eth_ctrl_stats *ctrl_stats) 978 + { 979 + struct mt7530_priv *priv = ds->priv; 980 + 981 + mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_PAUSE, 1, 982 + &ctrl_stats->MACControlFramesTransmitted); 983 + 984 + mt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_PAUSE, 1, 985 + &ctrl_stats->MACControlFramesReceived); 798 986 } 799 987 800 988 static int ··· 3249 3105 .get_strings = mt7530_get_strings, 3250 3106 .get_ethtool_stats = mt7530_get_ethtool_stats, 3251 3107 .get_sset_count = mt7530_get_sset_count, 3108 + .get_eth_mac_stats = mt7530_get_eth_mac_stats, 3109 + .get_rmon_stats = mt7530_get_rmon_stats, 3110 + .get_eth_ctrl_stats = mt7530_get_eth_ctrl_stats, 3111 + .get_stats64 = mt7530_get_stats64, 3252 3112 .set_ageing_time = mt7530_set_ageing_time, 3253 3113 .port_enable = mt7530_port_enable, 3254 3114 .port_disable = mt7530_port_disable,
+42
drivers/net/dsa/mt7530.h
··· 423 423 424 424 /* Register for MIB */ 425 425 #define MT7530_PORT_MIB_COUNTER(x) (0x4000 + (x) * 0x100) 426 + /* Each define is an offset of MT7530_PORT_MIB_COUNTER */ 427 + #define MT7530_PORT_MIB_TX_DROP 0x00 428 + #define MT7530_PORT_MIB_TX_CRC_ERR 0x04 429 + #define MT7530_PORT_MIB_TX_UNICAST 0x08 430 + #define MT7530_PORT_MIB_TX_MULTICAST 0x0c 431 + #define MT7530_PORT_MIB_TX_BROADCAST 0x10 432 + #define MT7530_PORT_MIB_TX_COLLISION 0x14 433 + #define MT7530_PORT_MIB_TX_SINGLE_COLLISION 0x18 434 + #define MT7530_PORT_MIB_TX_MULTIPLE_COLLISION 0x1c 435 + #define MT7530_PORT_MIB_TX_DEFERRED 0x20 436 + #define MT7530_PORT_MIB_TX_LATE_COLLISION 0x24 437 + #define MT7530_PORT_MIB_TX_EXCESSIVE_COLLISION 0x28 438 + #define MT7530_PORT_MIB_TX_PAUSE 0x2c 439 + #define MT7530_PORT_MIB_TX_PKT_SZ_64 0x30 440 + #define MT7530_PORT_MIB_TX_PKT_SZ_65_TO_127 0x34 441 + #define MT7530_PORT_MIB_TX_PKT_SZ_128_TO_255 0x38 442 + #define MT7530_PORT_MIB_TX_PKT_SZ_256_TO_511 0x3c 443 + #define MT7530_PORT_MIB_TX_PKT_SZ_512_TO_1023 0x40 444 + #define MT7530_PORT_MIB_TX_PKT_SZ_1024_TO_MAX 0x44 445 + #define MT7530_PORT_MIB_TX_BYTES 0x48 /* 64 bytes */ 446 + #define MT7530_PORT_MIB_RX_DROP 0x60 447 + #define MT7530_PORT_MIB_RX_FILTERING 0x64 448 + #define MT7530_PORT_MIB_RX_UNICAST 0x68 449 + #define MT7530_PORT_MIB_RX_MULTICAST 0x6c 450 + #define MT7530_PORT_MIB_RX_BROADCAST 0x70 451 + #define MT7530_PORT_MIB_RX_ALIGN_ERR 0x74 452 + #define MT7530_PORT_MIB_RX_CRC_ERR 0x78 453 + #define MT7530_PORT_MIB_RX_UNDER_SIZE_ERR 0x7c 454 + #define MT7530_PORT_MIB_RX_FRAG_ERR 0x80 455 + #define MT7530_PORT_MIB_RX_OVER_SZ_ERR 0x84 456 + #define MT7530_PORT_MIB_RX_JABBER_ERR 0x88 457 + #define MT7530_PORT_MIB_RX_PAUSE 0x8c 458 + #define MT7530_PORT_MIB_RX_PKT_SZ_64 0x90 459 + #define MT7530_PORT_MIB_RX_PKT_SZ_65_TO_127 0x94 460 + #define MT7530_PORT_MIB_RX_PKT_SZ_128_TO_255 0x98 461 + #define MT7530_PORT_MIB_RX_PKT_SZ_256_TO_511 0x9c 462 + #define MT7530_PORT_MIB_RX_PKT_SZ_512_TO_1023 0xa0 463 + #define MT7530_PORT_MIB_RX_PKT_SZ_1024_TO_MAX 0xa4 464 + #define MT7530_PORT_MIB_RX_BYTES 0xa8 /* 64 bytes */ 465 + #define MT7530_PORT_MIB_RX_CTRL_DROP 0xb0 466 + #define MT7530_PORT_MIB_RX_INGRESS_DROP 0xb4 467 + #define MT7530_PORT_MIB_RX_ARL_DROP 0xb8 426 468 #define MT7530_MIB_CCR 0x4fe0 427 469 #define CCR_MIB_ENABLE BIT(31) 428 470 #define CCR_RX_OCT_CNT_GOOD BIT(7)