Commit 5b6a0729 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'fixes-for-ocelot-driver-statistics'

Vladimir Oltean says:

====================
Fixes for Ocelot driver statistics

This series contains bug fixes for the ocelot drivers (both switchdev
and DSA). Some concern the counters exposed to ethtool -S, and others to
the counters exposed to ifconfig. I'm aware that the changes are fairly
large, but I wanted to prioritize on a proper approach to addressing the
issues rather than a quick hack.

Some of the noticed problems:
- bad register offsets for some counters
- unhandled concurrency leading to corrupted counters
- unhandled 32-bit wraparound of ifconfig counters

The issues on the ocelot switchdev driver were noticed through code
inspection, I do not have the hardware to test.

This patch set necessarily converts ocelot->stats_lock from a mutex to a
spinlock. I know this affects Colin Foster's development with the SPI
controlled VSC7512. I have other changes prepared for net-next that
convert this back into a mutex (along with other changes in this area).
====================

Link: https://lore.kernel.org/r/20220816135352.1431497-1-vladimir.oltean@nxp.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 211987f3 e780e319
Loading
Loading
Loading
Loading
+454 −104
Original line number Diff line number Diff line
@@ -274,27 +274,98 @@ static const u32 vsc9959_rew_regmap[] = {

static const u32 vsc9959_sys_regmap[] = {
	REG(SYS_COUNT_RX_OCTETS,		0x000000),
	REG(SYS_COUNT_RX_UNICAST,		0x000004),
	REG(SYS_COUNT_RX_MULTICAST,		0x000008),
	REG(SYS_COUNT_RX_BROADCAST,		0x00000c),
	REG(SYS_COUNT_RX_SHORTS,		0x000010),
	REG(SYS_COUNT_RX_FRAGMENTS,		0x000014),
	REG(SYS_COUNT_RX_JABBERS,		0x000018),
	REG(SYS_COUNT_RX_CRC_ALIGN_ERRS,	0x00001c),
	REG(SYS_COUNT_RX_SYM_ERRS,		0x000020),
	REG(SYS_COUNT_RX_64,			0x000024),
	REG(SYS_COUNT_RX_65_127,		0x000028),
	REG(SYS_COUNT_RX_128_255,		0x00002c),
	REG(SYS_COUNT_RX_256_1023,		0x000030),
	REG(SYS_COUNT_RX_1024_1526,		0x000034),
	REG(SYS_COUNT_RX_1527_MAX,		0x000038),
	REG(SYS_COUNT_RX_LONGS,			0x000044),
	REG(SYS_COUNT_RX_256_511,		0x000030),
	REG(SYS_COUNT_RX_512_1023,		0x000034),
	REG(SYS_COUNT_RX_1024_1526,		0x000038),
	REG(SYS_COUNT_RX_1527_MAX,		0x00003c),
	REG(SYS_COUNT_RX_PAUSE,			0x000040),
	REG(SYS_COUNT_RX_CONTROL,		0x000044),
	REG(SYS_COUNT_RX_LONGS,			0x000048),
	REG(SYS_COUNT_RX_CLASSIFIED_DROPS,	0x00004c),
	REG(SYS_COUNT_RX_RED_PRIO_0,		0x000050),
	REG(SYS_COUNT_RX_RED_PRIO_1,		0x000054),
	REG(SYS_COUNT_RX_RED_PRIO_2,		0x000058),
	REG(SYS_COUNT_RX_RED_PRIO_3,		0x00005c),
	REG(SYS_COUNT_RX_RED_PRIO_4,		0x000060),
	REG(SYS_COUNT_RX_RED_PRIO_5,		0x000064),
	REG(SYS_COUNT_RX_RED_PRIO_6,		0x000068),
	REG(SYS_COUNT_RX_RED_PRIO_7,		0x00006c),
	REG(SYS_COUNT_RX_YELLOW_PRIO_0,		0x000070),
	REG(SYS_COUNT_RX_YELLOW_PRIO_1,		0x000074),
	REG(SYS_COUNT_RX_YELLOW_PRIO_2,		0x000078),
	REG(SYS_COUNT_RX_YELLOW_PRIO_3,		0x00007c),
	REG(SYS_COUNT_RX_YELLOW_PRIO_4,		0x000080),
	REG(SYS_COUNT_RX_YELLOW_PRIO_5,		0x000084),
	REG(SYS_COUNT_RX_YELLOW_PRIO_6,		0x000088),
	REG(SYS_COUNT_RX_YELLOW_PRIO_7,		0x00008c),
	REG(SYS_COUNT_RX_GREEN_PRIO_0,		0x000090),
	REG(SYS_COUNT_RX_GREEN_PRIO_1,		0x000094),
	REG(SYS_COUNT_RX_GREEN_PRIO_2,		0x000098),
	REG(SYS_COUNT_RX_GREEN_PRIO_3,		0x00009c),
	REG(SYS_COUNT_RX_GREEN_PRIO_4,		0x0000a0),
	REG(SYS_COUNT_RX_GREEN_PRIO_5,		0x0000a4),
	REG(SYS_COUNT_RX_GREEN_PRIO_6,		0x0000a8),
	REG(SYS_COUNT_RX_GREEN_PRIO_7,		0x0000ac),
	REG(SYS_COUNT_TX_OCTETS,		0x000200),
	REG(SYS_COUNT_TX_UNICAST,		0x000204),
	REG(SYS_COUNT_TX_MULTICAST,		0x000208),
	REG(SYS_COUNT_TX_BROADCAST,		0x00020c),
	REG(SYS_COUNT_TX_COLLISION,		0x000210),
	REG(SYS_COUNT_TX_DROPS,			0x000214),
	REG(SYS_COUNT_TX_PAUSE,			0x000218),
	REG(SYS_COUNT_TX_64,			0x00021c),
	REG(SYS_COUNT_TX_65_127,		0x000220),
	REG(SYS_COUNT_TX_128_511,		0x000224),
	REG(SYS_COUNT_TX_512_1023,		0x000228),
	REG(SYS_COUNT_TX_1024_1526,		0x00022c),
	REG(SYS_COUNT_TX_1527_MAX,		0x000230),
	REG(SYS_COUNT_TX_128_255,		0x000224),
	REG(SYS_COUNT_TX_256_511,		0x000228),
	REG(SYS_COUNT_TX_512_1023,		0x00022c),
	REG(SYS_COUNT_TX_1024_1526,		0x000230),
	REG(SYS_COUNT_TX_1527_MAX,		0x000234),
	REG(SYS_COUNT_TX_YELLOW_PRIO_0,		0x000238),
	REG(SYS_COUNT_TX_YELLOW_PRIO_1,		0x00023c),
	REG(SYS_COUNT_TX_YELLOW_PRIO_2,		0x000240),
	REG(SYS_COUNT_TX_YELLOW_PRIO_3,		0x000244),
	REG(SYS_COUNT_TX_YELLOW_PRIO_4,		0x000248),
	REG(SYS_COUNT_TX_YELLOW_PRIO_5,		0x00024c),
	REG(SYS_COUNT_TX_YELLOW_PRIO_6,		0x000250),
	REG(SYS_COUNT_TX_YELLOW_PRIO_7,		0x000254),
	REG(SYS_COUNT_TX_GREEN_PRIO_0,		0x000258),
	REG(SYS_COUNT_TX_GREEN_PRIO_1,		0x00025c),
	REG(SYS_COUNT_TX_GREEN_PRIO_2,		0x000260),
	REG(SYS_COUNT_TX_GREEN_PRIO_3,		0x000264),
	REG(SYS_COUNT_TX_GREEN_PRIO_4,		0x000268),
	REG(SYS_COUNT_TX_GREEN_PRIO_5,		0x00026c),
	REG(SYS_COUNT_TX_GREEN_PRIO_6,		0x000270),
	REG(SYS_COUNT_TX_GREEN_PRIO_7,		0x000274),
	REG(SYS_COUNT_TX_AGING,			0x000278),
	REG(SYS_COUNT_DROP_LOCAL,		0x000400),
	REG(SYS_COUNT_DROP_TAIL,		0x000404),
	REG(SYS_COUNT_DROP_YELLOW_PRIO_0,	0x000408),
	REG(SYS_COUNT_DROP_YELLOW_PRIO_1,	0x00040c),
	REG(SYS_COUNT_DROP_YELLOW_PRIO_2,	0x000410),
	REG(SYS_COUNT_DROP_YELLOW_PRIO_3,	0x000414),
	REG(SYS_COUNT_DROP_YELLOW_PRIO_4,	0x000418),
	REG(SYS_COUNT_DROP_YELLOW_PRIO_5,	0x00041c),
	REG(SYS_COUNT_DROP_YELLOW_PRIO_6,	0x000420),
	REG(SYS_COUNT_DROP_YELLOW_PRIO_7,	0x000424),
	REG(SYS_COUNT_DROP_GREEN_PRIO_0,	0x000428),
	REG(SYS_COUNT_DROP_GREEN_PRIO_1,	0x00042c),
	REG(SYS_COUNT_DROP_GREEN_PRIO_2,	0x000430),
	REG(SYS_COUNT_DROP_GREEN_PRIO_3,	0x000434),
	REG(SYS_COUNT_DROP_GREEN_PRIO_4,	0x000438),
	REG(SYS_COUNT_DROP_GREEN_PRIO_5,	0x00043c),
	REG(SYS_COUNT_DROP_GREEN_PRIO_6,	0x000440),
	REG(SYS_COUNT_DROP_GREEN_PRIO_7,	0x000444),
	REG(SYS_RESET_CFG,			0x000e00),
	REG(SYS_SR_ETYPE_CFG,			0x000e04),
	REG(SYS_VLAN_ETYPE_CFG,			0x000e08),
@@ -547,100 +618,379 @@ static const struct reg_field vsc9959_regfields[REGFIELD_MAX] = {
	[SYS_PAUSE_CFG_PAUSE_ENA] = REG_FIELD_ID(SYS_PAUSE_CFG, 0, 1, 7, 4),
};

static const struct ocelot_stat_layout vsc9959_stats_layout[] = {
	{ .offset = 0x00,	.name = "rx_octets", },
	{ .offset = 0x01,	.name = "rx_unicast", },
	{ .offset = 0x02,	.name = "rx_multicast", },
	{ .offset = 0x03,	.name = "rx_broadcast", },
	{ .offset = 0x04,	.name = "rx_shorts", },
	{ .offset = 0x05,	.name = "rx_fragments", },
	{ .offset = 0x06,	.name = "rx_jabbers", },
	{ .offset = 0x07,	.name = "rx_crc_align_errs", },
	{ .offset = 0x08,	.name = "rx_sym_errs", },
	{ .offset = 0x09,	.name = "rx_frames_below_65_octets", },
	{ .offset = 0x0A,	.name = "rx_frames_65_to_127_octets", },
	{ .offset = 0x0B,	.name = "rx_frames_128_to_255_octets", },
	{ .offset = 0x0C,	.name = "rx_frames_256_to_511_octets", },
	{ .offset = 0x0D,	.name = "rx_frames_512_to_1023_octets", },
	{ .offset = 0x0E,	.name = "rx_frames_1024_to_1526_octets", },
	{ .offset = 0x0F,	.name = "rx_frames_over_1526_octets", },
	{ .offset = 0x10,	.name = "rx_pause", },
	{ .offset = 0x11,	.name = "rx_control", },
	{ .offset = 0x12,	.name = "rx_longs", },
	{ .offset = 0x13,	.name = "rx_classified_drops", },
	{ .offset = 0x14,	.name = "rx_red_prio_0", },
	{ .offset = 0x15,	.name = "rx_red_prio_1", },
	{ .offset = 0x16,	.name = "rx_red_prio_2", },
	{ .offset = 0x17,	.name = "rx_red_prio_3", },
	{ .offset = 0x18,	.name = "rx_red_prio_4", },
	{ .offset = 0x19,	.name = "rx_red_prio_5", },
	{ .offset = 0x1A,	.name = "rx_red_prio_6", },
	{ .offset = 0x1B,	.name = "rx_red_prio_7", },
	{ .offset = 0x1C,	.name = "rx_yellow_prio_0", },
	{ .offset = 0x1D,	.name = "rx_yellow_prio_1", },
	{ .offset = 0x1E,	.name = "rx_yellow_prio_2", },
	{ .offset = 0x1F,	.name = "rx_yellow_prio_3", },
	{ .offset = 0x20,	.name = "rx_yellow_prio_4", },
	{ .offset = 0x21,	.name = "rx_yellow_prio_5", },
	{ .offset = 0x22,	.name = "rx_yellow_prio_6", },
	{ .offset = 0x23,	.name = "rx_yellow_prio_7", },
	{ .offset = 0x24,	.name = "rx_green_prio_0", },
	{ .offset = 0x25,	.name = "rx_green_prio_1", },
	{ .offset = 0x26,	.name = "rx_green_prio_2", },
	{ .offset = 0x27,	.name = "rx_green_prio_3", },
	{ .offset = 0x28,	.name = "rx_green_prio_4", },
	{ .offset = 0x29,	.name = "rx_green_prio_5", },
	{ .offset = 0x2A,	.name = "rx_green_prio_6", },
	{ .offset = 0x2B,	.name = "rx_green_prio_7", },
	{ .offset = 0x80,	.name = "tx_octets", },
	{ .offset = 0x81,	.name = "tx_unicast", },
	{ .offset = 0x82,	.name = "tx_multicast", },
	{ .offset = 0x83,	.name = "tx_broadcast", },
	{ .offset = 0x84,	.name = "tx_collision", },
	{ .offset = 0x85,	.name = "tx_drops", },
	{ .offset = 0x86,	.name = "tx_pause", },
	{ .offset = 0x87,	.name = "tx_frames_below_65_octets", },
	{ .offset = 0x88,	.name = "tx_frames_65_to_127_octets", },
	{ .offset = 0x89,	.name = "tx_frames_128_255_octets", },
	{ .offset = 0x8B,	.name = "tx_frames_256_511_octets", },
	{ .offset = 0x8C,	.name = "tx_frames_1024_1526_octets", },
	{ .offset = 0x8D,	.name = "tx_frames_over_1526_octets", },
	{ .offset = 0x8E,	.name = "tx_yellow_prio_0", },
	{ .offset = 0x8F,	.name = "tx_yellow_prio_1", },
	{ .offset = 0x90,	.name = "tx_yellow_prio_2", },
	{ .offset = 0x91,	.name = "tx_yellow_prio_3", },
	{ .offset = 0x92,	.name = "tx_yellow_prio_4", },
	{ .offset = 0x93,	.name = "tx_yellow_prio_5", },
	{ .offset = 0x94,	.name = "tx_yellow_prio_6", },
	{ .offset = 0x95,	.name = "tx_yellow_prio_7", },
	{ .offset = 0x96,	.name = "tx_green_prio_0", },
	{ .offset = 0x97,	.name = "tx_green_prio_1", },
	{ .offset = 0x98,	.name = "tx_green_prio_2", },
	{ .offset = 0x99,	.name = "tx_green_prio_3", },
	{ .offset = 0x9A,	.name = "tx_green_prio_4", },
	{ .offset = 0x9B,	.name = "tx_green_prio_5", },
	{ .offset = 0x9C,	.name = "tx_green_prio_6", },
	{ .offset = 0x9D,	.name = "tx_green_prio_7", },
	{ .offset = 0x9E,	.name = "tx_aged", },
	{ .offset = 0x100,	.name = "drop_local", },
	{ .offset = 0x101,	.name = "drop_tail", },
	{ .offset = 0x102,	.name = "drop_yellow_prio_0", },
	{ .offset = 0x103,	.name = "drop_yellow_prio_1", },
	{ .offset = 0x104,	.name = "drop_yellow_prio_2", },
	{ .offset = 0x105,	.name = "drop_yellow_prio_3", },
	{ .offset = 0x106,	.name = "drop_yellow_prio_4", },
	{ .offset = 0x107,	.name = "drop_yellow_prio_5", },
	{ .offset = 0x108,	.name = "drop_yellow_prio_6", },
	{ .offset = 0x109,	.name = "drop_yellow_prio_7", },
	{ .offset = 0x10A,	.name = "drop_green_prio_0", },
	{ .offset = 0x10B,	.name = "drop_green_prio_1", },
	{ .offset = 0x10C,	.name = "drop_green_prio_2", },
	{ .offset = 0x10D,	.name = "drop_green_prio_3", },
	{ .offset = 0x10E,	.name = "drop_green_prio_4", },
	{ .offset = 0x10F,	.name = "drop_green_prio_5", },
	{ .offset = 0x110,	.name = "drop_green_prio_6", },
	{ .offset = 0x111,	.name = "drop_green_prio_7", },
	OCELOT_STAT_END
static const struct ocelot_stat_layout vsc9959_stats_layout[OCELOT_NUM_STATS] = {
	[OCELOT_STAT_RX_OCTETS] = {
		.name = "rx_octets",
		.reg = SYS_COUNT_RX_OCTETS,
	},
	[OCELOT_STAT_RX_UNICAST] = {
		.name = "rx_unicast",
		.reg = SYS_COUNT_RX_UNICAST,
	},
	[OCELOT_STAT_RX_MULTICAST] = {
		.name = "rx_multicast",
		.reg = SYS_COUNT_RX_MULTICAST,
	},
	[OCELOT_STAT_RX_BROADCAST] = {
		.name = "rx_broadcast",
		.reg = SYS_COUNT_RX_BROADCAST,
	},
	[OCELOT_STAT_RX_SHORTS] = {
		.name = "rx_shorts",
		.reg = SYS_COUNT_RX_SHORTS,
	},
	[OCELOT_STAT_RX_FRAGMENTS] = {
		.name = "rx_fragments",
		.reg = SYS_COUNT_RX_FRAGMENTS,
	},
	[OCELOT_STAT_RX_JABBERS] = {
		.name = "rx_jabbers",
		.reg = SYS_COUNT_RX_JABBERS,
	},
	[OCELOT_STAT_RX_CRC_ALIGN_ERRS] = {
		.name = "rx_crc_align_errs",
		.reg = SYS_COUNT_RX_CRC_ALIGN_ERRS,
	},
	[OCELOT_STAT_RX_SYM_ERRS] = {
		.name = "rx_sym_errs",
		.reg = SYS_COUNT_RX_SYM_ERRS,
	},
	[OCELOT_STAT_RX_64] = {
		.name = "rx_frames_below_65_octets",
		.reg = SYS_COUNT_RX_64,
	},
	[OCELOT_STAT_RX_65_127] = {
		.name = "rx_frames_65_to_127_octets",
		.reg = SYS_COUNT_RX_65_127,
	},
	[OCELOT_STAT_RX_128_255] = {
		.name = "rx_frames_128_to_255_octets",
		.reg = SYS_COUNT_RX_128_255,
	},
	[OCELOT_STAT_RX_256_511] = {
		.name = "rx_frames_256_to_511_octets",
		.reg = SYS_COUNT_RX_256_511,
	},
	[OCELOT_STAT_RX_512_1023] = {
		.name = "rx_frames_512_to_1023_octets",
		.reg = SYS_COUNT_RX_512_1023,
	},
	[OCELOT_STAT_RX_1024_1526] = {
		.name = "rx_frames_1024_to_1526_octets",
		.reg = SYS_COUNT_RX_1024_1526,
	},
	[OCELOT_STAT_RX_1527_MAX] = {
		.name = "rx_frames_over_1526_octets",
		.reg = SYS_COUNT_RX_1527_MAX,
	},
	[OCELOT_STAT_RX_PAUSE] = {
		.name = "rx_pause",
		.reg = SYS_COUNT_RX_PAUSE,
	},
	[OCELOT_STAT_RX_CONTROL] = {
		.name = "rx_control",
		.reg = SYS_COUNT_RX_CONTROL,
	},
	[OCELOT_STAT_RX_LONGS] = {
		.name = "rx_longs",
		.reg = SYS_COUNT_RX_LONGS,
	},
	[OCELOT_STAT_RX_CLASSIFIED_DROPS] = {
		.name = "rx_classified_drops",
		.reg = SYS_COUNT_RX_CLASSIFIED_DROPS,
	},
	[OCELOT_STAT_RX_RED_PRIO_0] = {
		.name = "rx_red_prio_0",
		.reg = SYS_COUNT_RX_RED_PRIO_0,
	},
	[OCELOT_STAT_RX_RED_PRIO_1] = {
		.name = "rx_red_prio_1",
		.reg = SYS_COUNT_RX_RED_PRIO_1,
	},
	[OCELOT_STAT_RX_RED_PRIO_2] = {
		.name = "rx_red_prio_2",
		.reg = SYS_COUNT_RX_RED_PRIO_2,
	},
	[OCELOT_STAT_RX_RED_PRIO_3] = {
		.name = "rx_red_prio_3",
		.reg = SYS_COUNT_RX_RED_PRIO_3,
	},
	[OCELOT_STAT_RX_RED_PRIO_4] = {
		.name = "rx_red_prio_4",
		.reg = SYS_COUNT_RX_RED_PRIO_4,
	},
	[OCELOT_STAT_RX_RED_PRIO_5] = {
		.name = "rx_red_prio_5",
		.reg = SYS_COUNT_RX_RED_PRIO_5,
	},
	[OCELOT_STAT_RX_RED_PRIO_6] = {
		.name = "rx_red_prio_6",
		.reg = SYS_COUNT_RX_RED_PRIO_6,
	},
	[OCELOT_STAT_RX_RED_PRIO_7] = {
		.name = "rx_red_prio_7",
		.reg = SYS_COUNT_RX_RED_PRIO_7,
	},
	[OCELOT_STAT_RX_YELLOW_PRIO_0] = {
		.name = "rx_yellow_prio_0",
		.reg = SYS_COUNT_RX_YELLOW_PRIO_0,
	},
	[OCELOT_STAT_RX_YELLOW_PRIO_1] = {
		.name = "rx_yellow_prio_1",
		.reg = SYS_COUNT_RX_YELLOW_PRIO_1,
	},
	[OCELOT_STAT_RX_YELLOW_PRIO_2] = {
		.name = "rx_yellow_prio_2",
		.reg = SYS_COUNT_RX_YELLOW_PRIO_2,
	},
	[OCELOT_STAT_RX_YELLOW_PRIO_3] = {
		.name = "rx_yellow_prio_3",
		.reg = SYS_COUNT_RX_YELLOW_PRIO_3,
	},
	[OCELOT_STAT_RX_YELLOW_PRIO_4] = {
		.name = "rx_yellow_prio_4",
		.reg = SYS_COUNT_RX_YELLOW_PRIO_4,
	},
	[OCELOT_STAT_RX_YELLOW_PRIO_5] = {
		.name = "rx_yellow_prio_5",
		.reg = SYS_COUNT_RX_YELLOW_PRIO_5,
	},
	[OCELOT_STAT_RX_YELLOW_PRIO_6] = {
		.name = "rx_yellow_prio_6",
		.reg = SYS_COUNT_RX_YELLOW_PRIO_6,
	},
	[OCELOT_STAT_RX_YELLOW_PRIO_7] = {
		.name = "rx_yellow_prio_7",
		.reg = SYS_COUNT_RX_YELLOW_PRIO_7,
	},
	[OCELOT_STAT_RX_GREEN_PRIO_0] = {
		.name = "rx_green_prio_0",
		.reg = SYS_COUNT_RX_GREEN_PRIO_0,
	},
	[OCELOT_STAT_RX_GREEN_PRIO_1] = {
		.name = "rx_green_prio_1",
		.reg = SYS_COUNT_RX_GREEN_PRIO_1,
	},
	[OCELOT_STAT_RX_GREEN_PRIO_2] = {
		.name = "rx_green_prio_2",
		.reg = SYS_COUNT_RX_GREEN_PRIO_2,
	},
	[OCELOT_STAT_RX_GREEN_PRIO_3] = {
		.name = "rx_green_prio_3",
		.reg = SYS_COUNT_RX_GREEN_PRIO_3,
	},
	[OCELOT_STAT_RX_GREEN_PRIO_4] = {
		.name = "rx_green_prio_4",
		.reg = SYS_COUNT_RX_GREEN_PRIO_4,
	},
	[OCELOT_STAT_RX_GREEN_PRIO_5] = {
		.name = "rx_green_prio_5",
		.reg = SYS_COUNT_RX_GREEN_PRIO_5,
	},
	[OCELOT_STAT_RX_GREEN_PRIO_6] = {
		.name = "rx_green_prio_6",
		.reg = SYS_COUNT_RX_GREEN_PRIO_6,
	},
	[OCELOT_STAT_RX_GREEN_PRIO_7] = {
		.name = "rx_green_prio_7",
		.reg = SYS_COUNT_RX_GREEN_PRIO_7,
	},
	[OCELOT_STAT_TX_OCTETS] = {
		.name = "tx_octets",
		.reg = SYS_COUNT_TX_OCTETS,
	},
	[OCELOT_STAT_TX_UNICAST] = {
		.name = "tx_unicast",
		.reg = SYS_COUNT_TX_UNICAST,
	},
	[OCELOT_STAT_TX_MULTICAST] = {
		.name = "tx_multicast",
		.reg = SYS_COUNT_TX_MULTICAST,
	},
	[OCELOT_STAT_TX_BROADCAST] = {
		.name = "tx_broadcast",
		.reg = SYS_COUNT_TX_BROADCAST,
	},
	[OCELOT_STAT_TX_COLLISION] = {
		.name = "tx_collision",
		.reg = SYS_COUNT_TX_COLLISION,
	},
	[OCELOT_STAT_TX_DROPS] = {
		.name = "tx_drops",
		.reg = SYS_COUNT_TX_DROPS,
	},
	[OCELOT_STAT_TX_PAUSE] = {
		.name = "tx_pause",
		.reg = SYS_COUNT_TX_PAUSE,
	},
	[OCELOT_STAT_TX_64] = {
		.name = "tx_frames_below_65_octets",
		.reg = SYS_COUNT_TX_64,
	},
	[OCELOT_STAT_TX_65_127] = {
		.name = "tx_frames_65_to_127_octets",
		.reg = SYS_COUNT_TX_65_127,
	},
	[OCELOT_STAT_TX_128_255] = {
		.name = "tx_frames_128_255_octets",
		.reg = SYS_COUNT_TX_128_255,
	},
	[OCELOT_STAT_TX_256_511] = {
		.name = "tx_frames_256_511_octets",
		.reg = SYS_COUNT_TX_256_511,
	},
	[OCELOT_STAT_TX_512_1023] = {
		.name = "tx_frames_512_1023_octets",
		.reg = SYS_COUNT_TX_512_1023,
	},
	[OCELOT_STAT_TX_1024_1526] = {
		.name = "tx_frames_1024_1526_octets",
		.reg = SYS_COUNT_TX_1024_1526,
	},
	[OCELOT_STAT_TX_1527_MAX] = {
		.name = "tx_frames_over_1526_octets",
		.reg = SYS_COUNT_TX_1527_MAX,
	},
	[OCELOT_STAT_TX_YELLOW_PRIO_0] = {
		.name = "tx_yellow_prio_0",
		.reg = SYS_COUNT_TX_YELLOW_PRIO_0,
	},
	[OCELOT_STAT_TX_YELLOW_PRIO_1] = {
		.name = "tx_yellow_prio_1",
		.reg = SYS_COUNT_TX_YELLOW_PRIO_1,
	},
	[OCELOT_STAT_TX_YELLOW_PRIO_2] = {
		.name = "tx_yellow_prio_2",
		.reg = SYS_COUNT_TX_YELLOW_PRIO_2,
	},
	[OCELOT_STAT_TX_YELLOW_PRIO_3] = {
		.name = "tx_yellow_prio_3",
		.reg = SYS_COUNT_TX_YELLOW_PRIO_3,
	},
	[OCELOT_STAT_TX_YELLOW_PRIO_4] = {
		.name = "tx_yellow_prio_4",
		.reg = SYS_COUNT_TX_YELLOW_PRIO_4,
	},
	[OCELOT_STAT_TX_YELLOW_PRIO_5] = {
		.name = "tx_yellow_prio_5",
		.reg = SYS_COUNT_TX_YELLOW_PRIO_5,
	},
	[OCELOT_STAT_TX_YELLOW_PRIO_6] = {
		.name = "tx_yellow_prio_6",
		.reg = SYS_COUNT_TX_YELLOW_PRIO_6,
	},
	[OCELOT_STAT_TX_YELLOW_PRIO_7] = {
		.name = "tx_yellow_prio_7",
		.reg = SYS_COUNT_TX_YELLOW_PRIO_7,
	},
	[OCELOT_STAT_TX_GREEN_PRIO_0] = {
		.name = "tx_green_prio_0",
		.reg = SYS_COUNT_TX_GREEN_PRIO_0,
	},
	[OCELOT_STAT_TX_GREEN_PRIO_1] = {
		.name = "tx_green_prio_1",
		.reg = SYS_COUNT_TX_GREEN_PRIO_1,
	},
	[OCELOT_STAT_TX_GREEN_PRIO_2] = {
		.name = "tx_green_prio_2",
		.reg = SYS_COUNT_TX_GREEN_PRIO_2,
	},
	[OCELOT_STAT_TX_GREEN_PRIO_3] = {
		.name = "tx_green_prio_3",
		.reg = SYS_COUNT_TX_GREEN_PRIO_3,
	},
	[OCELOT_STAT_TX_GREEN_PRIO_4] = {
		.name = "tx_green_prio_4",
		.reg = SYS_COUNT_TX_GREEN_PRIO_4,
	},
	[OCELOT_STAT_TX_GREEN_PRIO_5] = {
		.name = "tx_green_prio_5",
		.reg = SYS_COUNT_TX_GREEN_PRIO_5,
	},
	[OCELOT_STAT_TX_GREEN_PRIO_6] = {
		.name = "tx_green_prio_6",
		.reg = SYS_COUNT_TX_GREEN_PRIO_6,
	},
	[OCELOT_STAT_TX_GREEN_PRIO_7] = {
		.name = "tx_green_prio_7",
		.reg = SYS_COUNT_TX_GREEN_PRIO_7,
	},
	[OCELOT_STAT_TX_AGED] = {
		.name = "tx_aged",
		.reg = SYS_COUNT_TX_AGING,
	},
	[OCELOT_STAT_DROP_LOCAL] = {
		.name = "drop_local",
		.reg = SYS_COUNT_DROP_LOCAL,
	},
	[OCELOT_STAT_DROP_TAIL] = {
		.name = "drop_tail",
		.reg = SYS_COUNT_DROP_TAIL,
	},
	[OCELOT_STAT_DROP_YELLOW_PRIO_0] = {
		.name = "drop_yellow_prio_0",
		.reg = SYS_COUNT_DROP_YELLOW_PRIO_0,
	},
	[OCELOT_STAT_DROP_YELLOW_PRIO_1] = {
		.name = "drop_yellow_prio_1",
		.reg = SYS_COUNT_DROP_YELLOW_PRIO_1,
	},
	[OCELOT_STAT_DROP_YELLOW_PRIO_2] = {
		.name = "drop_yellow_prio_2",
		.reg = SYS_COUNT_DROP_YELLOW_PRIO_2,
	},
	[OCELOT_STAT_DROP_YELLOW_PRIO_3] = {
		.name = "drop_yellow_prio_3",
		.reg = SYS_COUNT_DROP_YELLOW_PRIO_3,
	},
	[OCELOT_STAT_DROP_YELLOW_PRIO_4] = {
		.name = "drop_yellow_prio_4",
		.reg = SYS_COUNT_DROP_YELLOW_PRIO_4,
	},
	[OCELOT_STAT_DROP_YELLOW_PRIO_5] = {
		.name = "drop_yellow_prio_5",
		.reg = SYS_COUNT_DROP_YELLOW_PRIO_5,
	},
	[OCELOT_STAT_DROP_YELLOW_PRIO_6] = {
		.name = "drop_yellow_prio_6",
		.reg = SYS_COUNT_DROP_YELLOW_PRIO_6,
	},
	[OCELOT_STAT_DROP_YELLOW_PRIO_7] = {
		.name = "drop_yellow_prio_7",
		.reg = SYS_COUNT_DROP_YELLOW_PRIO_7,
	},
	[OCELOT_STAT_DROP_GREEN_PRIO_0] = {
		.name = "drop_green_prio_0",
		.reg = SYS_COUNT_DROP_GREEN_PRIO_0,
	},
	[OCELOT_STAT_DROP_GREEN_PRIO_1] = {
		.name = "drop_green_prio_1",
		.reg = SYS_COUNT_DROP_GREEN_PRIO_1,
	},
	[OCELOT_STAT_DROP_GREEN_PRIO_2] = {
		.name = "drop_green_prio_2",
		.reg = SYS_COUNT_DROP_GREEN_PRIO_2,
	},
	[OCELOT_STAT_DROP_GREEN_PRIO_3] = {
		.name = "drop_green_prio_3",
		.reg = SYS_COUNT_DROP_GREEN_PRIO_3,
	},
	[OCELOT_STAT_DROP_GREEN_PRIO_4] = {
		.name = "drop_green_prio_4",
		.reg = SYS_COUNT_DROP_GREEN_PRIO_4,
	},
	[OCELOT_STAT_DROP_GREEN_PRIO_5] = {
		.name = "drop_green_prio_5",
		.reg = SYS_COUNT_DROP_GREEN_PRIO_5,
	},
	[OCELOT_STAT_DROP_GREEN_PRIO_6] = {
		.name = "drop_green_prio_6",
		.reg = SYS_COUNT_DROP_GREEN_PRIO_6,
	},
	[OCELOT_STAT_DROP_GREEN_PRIO_7] = {
		.name = "drop_green_prio_7",
		.reg = SYS_COUNT_DROP_GREEN_PRIO_7,
	},
};

static const struct vcap_field vsc9959_vcap_es0_keys[] = {
@@ -2166,7 +2516,7 @@ static void vsc9959_psfp_sgi_table_del(struct ocelot *ocelot,
static void vsc9959_psfp_counters_get(struct ocelot *ocelot, u32 index,
				      struct felix_stream_filter_counters *counters)
{
	mutex_lock(&ocelot->stats_lock);
	spin_lock(&ocelot->stats_lock);

	ocelot_rmw(ocelot, SYS_STAT_CFG_STAT_VIEW(index),
		   SYS_STAT_CFG_STAT_VIEW_M,
@@ -2183,7 +2533,7 @@ static void vsc9959_psfp_counters_get(struct ocelot *ocelot, u32 index,
		     SYS_STAT_CFG_STAT_CLEAR_SHOT(0x10),
		     SYS_STAT_CFG);

	mutex_unlock(&ocelot->stats_lock);
	spin_unlock(&ocelot->stats_lock);
}

static int vsc9959_psfp_filter_add(struct ocelot *ocelot, int port,
+451 −102

File changed.

Preview size limit exceeded, changes collapsed.

+37 −25
Original line number Diff line number Diff line
@@ -1860,16 +1860,20 @@ void ocelot_get_strings(struct ocelot *ocelot, int port, u32 sset, u8 *data)
	if (sset != ETH_SS_STATS)
		return;

	for (i = 0; i < ocelot->num_stats; i++)
	for (i = 0; i < OCELOT_NUM_STATS; i++) {
		if (ocelot->stats_layout[i].name[0] == '\0')
			continue;

		memcpy(data + i * ETH_GSTRING_LEN, ocelot->stats_layout[i].name,
		       ETH_GSTRING_LEN);
	}
}
EXPORT_SYMBOL(ocelot_get_strings);

/* Caller must hold &ocelot->stats_lock */
static int ocelot_port_update_stats(struct ocelot *ocelot, int port)
{
	unsigned int idx = port * ocelot->num_stats;
	unsigned int idx = port * OCELOT_NUM_STATS;
	struct ocelot_stats_region *region;
	int err, j;

@@ -1877,8 +1881,7 @@ static int ocelot_port_update_stats(struct ocelot *ocelot, int port)
	ocelot_write(ocelot, SYS_STAT_CFG_STAT_VIEW(port), SYS_STAT_CFG);

	list_for_each_entry(region, &ocelot->stats_regions, node) {
		err = ocelot_bulk_read_rix(ocelot, SYS_COUNT_RX_OCTETS,
					   region->offset, region->buf,
		err = ocelot_bulk_read(ocelot, region->base, region->buf,
				       region->count);
		if (err)
			return err;
@@ -1906,13 +1909,13 @@ static void ocelot_check_stats_work(struct work_struct *work)
					     stats_work);
	int i, err;

	mutex_lock(&ocelot->stats_lock);
	spin_lock(&ocelot->stats_lock);
	for (i = 0; i < ocelot->num_phys_ports; i++) {
		err = ocelot_port_update_stats(ocelot, i);
		if (err)
			break;
	}
	mutex_unlock(&ocelot->stats_lock);
	spin_unlock(&ocelot->stats_lock);

	if (err)
		dev_err(ocelot->dev, "Error %d updating ethtool stats\n",  err);
@@ -1925,16 +1928,22 @@ void ocelot_get_ethtool_stats(struct ocelot *ocelot, int port, u64 *data)
{
	int i, err;

	mutex_lock(&ocelot->stats_lock);
	spin_lock(&ocelot->stats_lock);

	/* check and update now */
	err = ocelot_port_update_stats(ocelot, port);

	/* Copy all counters */
	for (i = 0; i < ocelot->num_stats; i++)
		*data++ = ocelot->stats[port * ocelot->num_stats + i];
	/* Copy all supported counters */
	for (i = 0; i < OCELOT_NUM_STATS; i++) {
		int index = port * OCELOT_NUM_STATS + i;

		if (ocelot->stats_layout[i].name[0] == '\0')
			continue;

		*data++ = ocelot->stats[index];
	}

	mutex_unlock(&ocelot->stats_lock);
	spin_unlock(&ocelot->stats_lock);

	if (err)
		dev_err(ocelot->dev, "Error %d updating ethtool stats\n", err);
@@ -1943,10 +1952,16 @@ EXPORT_SYMBOL(ocelot_get_ethtool_stats);

int ocelot_get_sset_count(struct ocelot *ocelot, int port, int sset)
{
	int i, num_stats = 0;

	if (sset != ETH_SS_STATS)
		return -EOPNOTSUPP;

	return ocelot->num_stats;
	for (i = 0; i < OCELOT_NUM_STATS; i++)
		if (ocelot->stats_layout[i].name[0] != '\0')
			num_stats++;

	return num_stats;
}
EXPORT_SYMBOL(ocelot_get_sset_count);

@@ -1958,8 +1973,11 @@ static int ocelot_prepare_stats_regions(struct ocelot *ocelot)

	INIT_LIST_HEAD(&ocelot->stats_regions);

	for (i = 0; i < ocelot->num_stats; i++) {
		if (region && ocelot->stats_layout[i].offset == last + 1) {
	for (i = 0; i < OCELOT_NUM_STATS; i++) {
		if (ocelot->stats_layout[i].name[0] == '\0')
			continue;

		if (region && ocelot->stats_layout[i].reg == last + 4) {
			region->count++;
		} else {
			region = devm_kzalloc(ocelot->dev, sizeof(*region),
@@ -1967,12 +1985,12 @@ static int ocelot_prepare_stats_regions(struct ocelot *ocelot)
			if (!region)
				return -ENOMEM;

			region->offset = ocelot->stats_layout[i].offset;
			region->base = ocelot->stats_layout[i].reg;
			region->count = 1;
			list_add_tail(&region->node, &ocelot->stats_regions);
		}

		last = ocelot->stats_layout[i].offset;
		last = ocelot->stats_layout[i].reg;
	}

	list_for_each_entry(region, &ocelot->stats_regions, node) {
@@ -3340,7 +3358,6 @@ static void ocelot_detect_features(struct ocelot *ocelot)

int ocelot_init(struct ocelot *ocelot)
{
	const struct ocelot_stat_layout *stat;
	char queue_name[32];
	int i, ret;
	u32 port;
@@ -3353,17 +3370,13 @@ int ocelot_init(struct ocelot *ocelot)
		}
	}

	ocelot->num_stats = 0;
	for_each_stat(ocelot, stat)
		ocelot->num_stats++;

	ocelot->stats = devm_kcalloc(ocelot->dev,
				     ocelot->num_phys_ports * ocelot->num_stats,
				     ocelot->num_phys_ports * OCELOT_NUM_STATS,
				     sizeof(u64), GFP_KERNEL);
	if (!ocelot->stats)
		return -ENOMEM;

	mutex_init(&ocelot->stats_lock);
	spin_lock_init(&ocelot->stats_lock);
	mutex_init(&ocelot->ptp_lock);
	mutex_init(&ocelot->mact_lock);
	mutex_init(&ocelot->fwd_domain_lock);
@@ -3511,7 +3524,6 @@ void ocelot_deinit(struct ocelot *ocelot)
	cancel_delayed_work(&ocelot->stats_work);
	destroy_workqueue(ocelot->stats_queue);
	destroy_workqueue(ocelot->owq);
	mutex_destroy(&ocelot->stats_lock);
}
EXPORT_SYMBOL(ocelot_deinit);

+30 −25

File changed.

Preview size limit exceeded, changes collapsed.

+373 −95

File changed.

Preview size limit exceeded, changes collapsed.

Loading