xref: /openbmc/linux/drivers/net/dsa/mv88e6xxx/chip.h (revision fa8d1179)
14d5f2ba7SVivien Didelot /*
24d5f2ba7SVivien Didelot  * Marvell 88E6xxx Ethernet switch single-chip definition
34d5f2ba7SVivien Didelot  *
44d5f2ba7SVivien Didelot  * Copyright (c) 2008 Marvell Semiconductor
54d5f2ba7SVivien Didelot  *
64d5f2ba7SVivien Didelot  * This program is free software; you can redistribute it and/or modify
74d5f2ba7SVivien Didelot  * it under the terms of the GNU General Public License as published by
84d5f2ba7SVivien Didelot  * the Free Software Foundation; either version 2 of the License, or
94d5f2ba7SVivien Didelot  * (at your option) any later version.
104d5f2ba7SVivien Didelot  */
114d5f2ba7SVivien Didelot 
124d5f2ba7SVivien Didelot #ifndef _MV88E6XXX_CHIP_H
134d5f2ba7SVivien Didelot #define _MV88E6XXX_CHIP_H
144d5f2ba7SVivien Didelot 
154d5f2ba7SVivien Didelot #include <linux/if_vlan.h>
164d5f2ba7SVivien Didelot #include <linux/irq.h>
174d5f2ba7SVivien Didelot #include <linux/gpio/consumer.h>
184d5f2ba7SVivien Didelot #include <linux/phy.h>
194d5f2ba7SVivien Didelot #include <net/dsa.h>
204d5f2ba7SVivien Didelot 
214d5f2ba7SVivien Didelot #ifndef UINT64_MAX
224d5f2ba7SVivien Didelot #define UINT64_MAX		(u64)(~((u64)0))
234d5f2ba7SVivien Didelot #endif
244d5f2ba7SVivien Didelot 
254d5f2ba7SVivien Didelot #define SMI_CMD			0x00
264d5f2ba7SVivien Didelot #define SMI_CMD_BUSY		BIT(15)
274d5f2ba7SVivien Didelot #define SMI_CMD_CLAUSE_22	BIT(12)
284d5f2ba7SVivien Didelot #define SMI_CMD_OP_22_WRITE	((1 << 10) | SMI_CMD_BUSY | SMI_CMD_CLAUSE_22)
294d5f2ba7SVivien Didelot #define SMI_CMD_OP_22_READ	((2 << 10) | SMI_CMD_BUSY | SMI_CMD_CLAUSE_22)
304d5f2ba7SVivien Didelot #define SMI_CMD_OP_45_WRITE_ADDR	((0 << 10) | SMI_CMD_BUSY)
314d5f2ba7SVivien Didelot #define SMI_CMD_OP_45_WRITE_DATA	((1 << 10) | SMI_CMD_BUSY)
324d5f2ba7SVivien Didelot #define SMI_CMD_OP_45_READ_DATA		((2 << 10) | SMI_CMD_BUSY)
334d5f2ba7SVivien Didelot #define SMI_CMD_OP_45_READ_DATA_INC	((3 << 10) | SMI_CMD_BUSY)
344d5f2ba7SVivien Didelot #define SMI_DATA		0x01
354d5f2ba7SVivien Didelot 
364d5f2ba7SVivien Didelot #define MV88E6XXX_N_FID		4096
374d5f2ba7SVivien Didelot 
384d5f2ba7SVivien Didelot /* PVT limits for 4-bit port and 5-bit switch */
394d5f2ba7SVivien Didelot #define MV88E6XXX_MAX_PVT_SWITCHES	32
404d5f2ba7SVivien Didelot #define MV88E6XXX_MAX_PVT_PORTS		16
414d5f2ba7SVivien Didelot 
4231bef4e9SVivien Didelot enum mv88e6xxx_egress_mode {
4331bef4e9SVivien Didelot 	MV88E6XXX_EGRESS_MODE_UNMODIFIED,
4431bef4e9SVivien Didelot 	MV88E6XXX_EGRESS_MODE_UNTAGGED,
4531bef4e9SVivien Didelot 	MV88E6XXX_EGRESS_MODE_TAGGED,
4631bef4e9SVivien Didelot 	MV88E6XXX_EGRESS_MODE_ETHERTYPE,
4731bef4e9SVivien Didelot };
4831bef4e9SVivien Didelot 
494d5f2ba7SVivien Didelot enum mv88e6xxx_frame_mode {
504d5f2ba7SVivien Didelot 	MV88E6XXX_FRAME_MODE_NORMAL,
514d5f2ba7SVivien Didelot 	MV88E6XXX_FRAME_MODE_DSA,
524d5f2ba7SVivien Didelot 	MV88E6XXX_FRAME_MODE_PROVIDER,
534d5f2ba7SVivien Didelot 	MV88E6XXX_FRAME_MODE_ETHERTYPE,
544d5f2ba7SVivien Didelot };
554d5f2ba7SVivien Didelot 
564d5f2ba7SVivien Didelot /* List of supported models */
574d5f2ba7SVivien Didelot enum mv88e6xxx_model {
584d5f2ba7SVivien Didelot 	MV88E6085,
594d5f2ba7SVivien Didelot 	MV88E6095,
604d5f2ba7SVivien Didelot 	MV88E6097,
614d5f2ba7SVivien Didelot 	MV88E6123,
624d5f2ba7SVivien Didelot 	MV88E6131,
634d5f2ba7SVivien Didelot 	MV88E6141,
644d5f2ba7SVivien Didelot 	MV88E6161,
654d5f2ba7SVivien Didelot 	MV88E6165,
664d5f2ba7SVivien Didelot 	MV88E6171,
674d5f2ba7SVivien Didelot 	MV88E6172,
684d5f2ba7SVivien Didelot 	MV88E6175,
694d5f2ba7SVivien Didelot 	MV88E6176,
704d5f2ba7SVivien Didelot 	MV88E6185,
714d5f2ba7SVivien Didelot 	MV88E6190,
724d5f2ba7SVivien Didelot 	MV88E6190X,
734d5f2ba7SVivien Didelot 	MV88E6191,
744d5f2ba7SVivien Didelot 	MV88E6240,
754d5f2ba7SVivien Didelot 	MV88E6290,
764d5f2ba7SVivien Didelot 	MV88E6320,
774d5f2ba7SVivien Didelot 	MV88E6321,
784d5f2ba7SVivien Didelot 	MV88E6341,
794d5f2ba7SVivien Didelot 	MV88E6350,
804d5f2ba7SVivien Didelot 	MV88E6351,
814d5f2ba7SVivien Didelot 	MV88E6352,
824d5f2ba7SVivien Didelot 	MV88E6390,
834d5f2ba7SVivien Didelot 	MV88E6390X,
844d5f2ba7SVivien Didelot };
854d5f2ba7SVivien Didelot 
864d5f2ba7SVivien Didelot enum mv88e6xxx_family {
874d5f2ba7SVivien Didelot 	MV88E6XXX_FAMILY_NONE,
884d5f2ba7SVivien Didelot 	MV88E6XXX_FAMILY_6065,	/* 6031 6035 6061 6065 */
894d5f2ba7SVivien Didelot 	MV88E6XXX_FAMILY_6095,	/* 6092 6095 */
904d5f2ba7SVivien Didelot 	MV88E6XXX_FAMILY_6097,	/* 6046 6085 6096 6097 */
914d5f2ba7SVivien Didelot 	MV88E6XXX_FAMILY_6165,	/* 6123 6161 6165 */
924d5f2ba7SVivien Didelot 	MV88E6XXX_FAMILY_6185,	/* 6108 6121 6122 6131 6152 6155 6182 6185 */
934d5f2ba7SVivien Didelot 	MV88E6XXX_FAMILY_6320,	/* 6320 6321 */
944d5f2ba7SVivien Didelot 	MV88E6XXX_FAMILY_6341,	/* 6141 6341 */
954d5f2ba7SVivien Didelot 	MV88E6XXX_FAMILY_6351,	/* 6171 6175 6350 6351 */
964d5f2ba7SVivien Didelot 	MV88E6XXX_FAMILY_6352,	/* 6172 6176 6240 6352 */
974d5f2ba7SVivien Didelot 	MV88E6XXX_FAMILY_6390,  /* 6190 6190X 6191 6290 6390 6390X */
984d5f2ba7SVivien Didelot };
994d5f2ba7SVivien Didelot 
1004d5f2ba7SVivien Didelot enum mv88e6xxx_cap {
1014d5f2ba7SVivien Didelot 	/* Energy Efficient Ethernet.
1024d5f2ba7SVivien Didelot 	 */
1034d5f2ba7SVivien Didelot 	MV88E6XXX_CAP_EEE,
1044d5f2ba7SVivien Didelot 
1054d5f2ba7SVivien Didelot 	/* Multi-chip Addressing Mode.
1064d5f2ba7SVivien Didelot 	 * Some chips respond to only 2 registers of its own SMI device address
1074d5f2ba7SVivien Didelot 	 * when it is non-zero, and use indirect access to internal registers.
1084d5f2ba7SVivien Didelot 	 */
1094d5f2ba7SVivien Didelot 	MV88E6XXX_CAP_SMI_CMD,		/* (0x00) SMI Command */
1104d5f2ba7SVivien Didelot 	MV88E6XXX_CAP_SMI_DATA,		/* (0x01) SMI Data */
1114d5f2ba7SVivien Didelot 
1124d5f2ba7SVivien Didelot 	/* Switch Global (1) Registers.
1134d5f2ba7SVivien Didelot 	 */
1144d5f2ba7SVivien Didelot 	MV88E6XXX_CAP_G1_ATU_FID,	/* (0x01) ATU FID Register */
1154d5f2ba7SVivien Didelot 	MV88E6XXX_CAP_G1_VTU_FID,	/* (0x02) VTU FID Register */
1164d5f2ba7SVivien Didelot 
1174d5f2ba7SVivien Didelot 	/* Switch Global 2 Registers.
1184d5f2ba7SVivien Didelot 	 * The device contains a second set of global 16-bit registers.
1194d5f2ba7SVivien Didelot 	 */
1204d5f2ba7SVivien Didelot 	MV88E6XXX_CAP_GLOBAL2,
1214d5f2ba7SVivien Didelot 	MV88E6XXX_CAP_G2_INT,		/* (0x00) Interrupt Status */
1224d5f2ba7SVivien Didelot 	MV88E6XXX_CAP_G2_MGMT_EN_2X,	/* (0x02) MGMT Enable Register 2x */
1234d5f2ba7SVivien Didelot 	MV88E6XXX_CAP_G2_MGMT_EN_0X,	/* (0x03) MGMT Enable Register 0x */
1244d5f2ba7SVivien Didelot 	MV88E6XXX_CAP_G2_IRL_CMD,	/* (0x09) Ingress Rate Command */
1254d5f2ba7SVivien Didelot 	MV88E6XXX_CAP_G2_IRL_DATA,	/* (0x0a) Ingress Rate Data */
1264d5f2ba7SVivien Didelot 	MV88E6XXX_CAP_G2_POT,		/* (0x0f) Priority Override Table */
1274d5f2ba7SVivien Didelot 
1284d5f2ba7SVivien Didelot 	/* Per VLAN Spanning Tree Unit (STU).
1294d5f2ba7SVivien Didelot 	 * The Port State database, if present, is accessed through VTU
1304d5f2ba7SVivien Didelot 	 * operations and dedicated SID registers. See GLOBAL_VTU_SID.
1314d5f2ba7SVivien Didelot 	 */
1324d5f2ba7SVivien Didelot 	MV88E6XXX_CAP_STU,
1334d5f2ba7SVivien Didelot 
1344d5f2ba7SVivien Didelot 	/* VLAN Table Unit.
1354d5f2ba7SVivien Didelot 	 * The VTU is used to program 802.1Q VLANs. See GLOBAL_VTU_OP.
1364d5f2ba7SVivien Didelot 	 */
1374d5f2ba7SVivien Didelot 	MV88E6XXX_CAP_VTU,
1384d5f2ba7SVivien Didelot };
1394d5f2ba7SVivien Didelot 
1404d5f2ba7SVivien Didelot /* Bitmask of capabilities */
1414d5f2ba7SVivien Didelot #define MV88E6XXX_FLAG_EEE		BIT_ULL(MV88E6XXX_CAP_EEE)
1424d5f2ba7SVivien Didelot 
1434d5f2ba7SVivien Didelot #define MV88E6XXX_FLAG_SMI_CMD		BIT_ULL(MV88E6XXX_CAP_SMI_CMD)
1444d5f2ba7SVivien Didelot #define MV88E6XXX_FLAG_SMI_DATA		BIT_ULL(MV88E6XXX_CAP_SMI_DATA)
1454d5f2ba7SVivien Didelot 
1464d5f2ba7SVivien Didelot #define MV88E6XXX_FLAG_G1_VTU_FID	BIT_ULL(MV88E6XXX_CAP_G1_VTU_FID)
1474d5f2ba7SVivien Didelot 
1484d5f2ba7SVivien Didelot #define MV88E6XXX_FLAG_GLOBAL2		BIT_ULL(MV88E6XXX_CAP_GLOBAL2)
1494d5f2ba7SVivien Didelot #define MV88E6XXX_FLAG_G2_INT		BIT_ULL(MV88E6XXX_CAP_G2_INT)
1504d5f2ba7SVivien Didelot #define MV88E6XXX_FLAG_G2_MGMT_EN_2X	BIT_ULL(MV88E6XXX_CAP_G2_MGMT_EN_2X)
1514d5f2ba7SVivien Didelot #define MV88E6XXX_FLAG_G2_MGMT_EN_0X	BIT_ULL(MV88E6XXX_CAP_G2_MGMT_EN_0X)
1524d5f2ba7SVivien Didelot #define MV88E6XXX_FLAG_G2_IRL_CMD	BIT_ULL(MV88E6XXX_CAP_G2_IRL_CMD)
1534d5f2ba7SVivien Didelot #define MV88E6XXX_FLAG_G2_IRL_DATA	BIT_ULL(MV88E6XXX_CAP_G2_IRL_DATA)
1544d5f2ba7SVivien Didelot #define MV88E6XXX_FLAG_G2_POT		BIT_ULL(MV88E6XXX_CAP_G2_POT)
1554d5f2ba7SVivien Didelot 
1564d5f2ba7SVivien Didelot /* Ingress Rate Limit unit */
1574d5f2ba7SVivien Didelot #define MV88E6XXX_FLAGS_IRL		\
1584d5f2ba7SVivien Didelot 	(MV88E6XXX_FLAG_G2_IRL_CMD |	\
1594d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAG_G2_IRL_DATA)
1604d5f2ba7SVivien Didelot 
1614d5f2ba7SVivien Didelot /* Multi-chip Addressing Mode */
1624d5f2ba7SVivien Didelot #define MV88E6XXX_FLAGS_MULTI_CHIP	\
1634d5f2ba7SVivien Didelot 	(MV88E6XXX_FLAG_SMI_CMD |	\
1644d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAG_SMI_DATA)
1654d5f2ba7SVivien Didelot 
1664d5f2ba7SVivien Didelot #define MV88E6XXX_FLAGS_FAMILY_6095	\
1674d5f2ba7SVivien Didelot 	(MV88E6XXX_FLAG_GLOBAL2 |	\
1684d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAG_G2_MGMT_EN_0X |	\
1694d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAGS_MULTI_CHIP)
1704d5f2ba7SVivien Didelot 
1714d5f2ba7SVivien Didelot #define MV88E6XXX_FLAGS_FAMILY_6097	\
1724d5f2ba7SVivien Didelot 	(MV88E6XXX_FLAG_G1_VTU_FID |	\
1734d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAG_GLOBAL2 |	\
1744d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAG_G2_INT |        \
1754d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAG_G2_MGMT_EN_2X |	\
1764d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAG_G2_MGMT_EN_0X |	\
1774d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAG_G2_POT |	\
1784d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAGS_IRL |		\
1794d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAGS_MULTI_CHIP)
1804d5f2ba7SVivien Didelot 
1814d5f2ba7SVivien Didelot #define MV88E6XXX_FLAGS_FAMILY_6165	\
1824d5f2ba7SVivien Didelot 	(MV88E6XXX_FLAG_G1_VTU_FID |	\
1834d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAG_GLOBAL2 |	\
1844d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAG_G2_INT |	\
1854d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAG_G2_MGMT_EN_2X |	\
1864d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAG_G2_MGMT_EN_0X |	\
1874d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAG_G2_POT |	\
1884d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAGS_IRL |		\
1894d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAGS_MULTI_CHIP)
1904d5f2ba7SVivien Didelot 
1914d5f2ba7SVivien Didelot #define MV88E6XXX_FLAGS_FAMILY_6185	\
1924d5f2ba7SVivien Didelot 	(MV88E6XXX_FLAG_GLOBAL2 |	\
1934d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAG_G2_INT |	\
1944d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAG_G2_MGMT_EN_0X |	\
1954d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAGS_MULTI_CHIP)
1964d5f2ba7SVivien Didelot 
1974d5f2ba7SVivien Didelot #define MV88E6XXX_FLAGS_FAMILY_6320	\
1984d5f2ba7SVivien Didelot 	(MV88E6XXX_FLAG_EEE |		\
1994d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAG_GLOBAL2 |	\
2004d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAG_G2_MGMT_EN_2X |	\
2014d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAG_G2_MGMT_EN_0X |	\
2024d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAG_G2_POT |	\
2034d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAGS_IRL |		\
2044d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAGS_MULTI_CHIP)
2054d5f2ba7SVivien Didelot 
2064d5f2ba7SVivien Didelot #define MV88E6XXX_FLAGS_FAMILY_6341	\
2074d5f2ba7SVivien Didelot 	(MV88E6XXX_FLAG_EEE |		\
2084d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAG_G1_VTU_FID |	\
2094d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAG_GLOBAL2 |	\
2104d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAG_G2_INT |	\
2114d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAG_G2_POT |	\
2124d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAGS_IRL |		\
2134d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAGS_MULTI_CHIP)
2144d5f2ba7SVivien Didelot 
2154d5f2ba7SVivien Didelot #define MV88E6XXX_FLAGS_FAMILY_6351	\
2164d5f2ba7SVivien Didelot 	(MV88E6XXX_FLAG_G1_VTU_FID |	\
2174d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAG_GLOBAL2 |	\
2184d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAG_G2_INT |	\
2194d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAG_G2_MGMT_EN_2X |	\
2204d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAG_G2_MGMT_EN_0X |	\
2214d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAG_G2_POT |	\
2224d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAGS_IRL |		\
2234d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAGS_MULTI_CHIP)
2244d5f2ba7SVivien Didelot 
2254d5f2ba7SVivien Didelot #define MV88E6XXX_FLAGS_FAMILY_6352	\
2264d5f2ba7SVivien Didelot 	(MV88E6XXX_FLAG_EEE |		\
2274d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAG_G1_VTU_FID |	\
2284d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAG_GLOBAL2 |	\
2294d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAG_G2_INT |	\
2304d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAG_G2_MGMT_EN_2X |	\
2314d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAG_G2_MGMT_EN_0X |	\
2324d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAG_G2_POT |	\
2334d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAGS_IRL |		\
2344d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAGS_MULTI_CHIP)
2354d5f2ba7SVivien Didelot 
2364d5f2ba7SVivien Didelot #define MV88E6XXX_FLAGS_FAMILY_6390	\
2374d5f2ba7SVivien Didelot 	(MV88E6XXX_FLAG_EEE |		\
2384d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAG_GLOBAL2 |	\
2394d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAG_G2_INT |        \
2404d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAGS_IRL |		\
2414d5f2ba7SVivien Didelot 	 MV88E6XXX_FLAGS_MULTI_CHIP)
2424d5f2ba7SVivien Didelot 
2434d5f2ba7SVivien Didelot struct mv88e6xxx_ops;
2444d5f2ba7SVivien Didelot 
2454d5f2ba7SVivien Didelot struct mv88e6xxx_info {
2464d5f2ba7SVivien Didelot 	enum mv88e6xxx_family family;
2474d5f2ba7SVivien Didelot 	u16 prod_num;
2484d5f2ba7SVivien Didelot 	const char *name;
2494d5f2ba7SVivien Didelot 	unsigned int num_databases;
2504d5f2ba7SVivien Didelot 	unsigned int num_ports;
2514d5f2ba7SVivien Didelot 	unsigned int max_vid;
2524d5f2ba7SVivien Didelot 	unsigned int port_base_addr;
2534d5f2ba7SVivien Didelot 	unsigned int global1_addr;
2544d5f2ba7SVivien Didelot 	unsigned int age_time_coeff;
2554d5f2ba7SVivien Didelot 	unsigned int g1_irqs;
2564d5f2ba7SVivien Didelot 	bool pvt;
2574d5f2ba7SVivien Didelot 	enum dsa_tag_protocol tag_protocol;
2584d5f2ba7SVivien Didelot 	unsigned long long flags;
2594d5f2ba7SVivien Didelot 
2604d5f2ba7SVivien Didelot 	/* Mask for FromPort and ToPort value of PortVec used in ATU Move
2614d5f2ba7SVivien Didelot 	 * operation. 0 means that the ATU Move operation is not supported.
2624d5f2ba7SVivien Didelot 	 */
2634d5f2ba7SVivien Didelot 	u8 atu_move_port_mask;
2644d5f2ba7SVivien Didelot 	const struct mv88e6xxx_ops *ops;
2654d5f2ba7SVivien Didelot };
2664d5f2ba7SVivien Didelot 
2674d5f2ba7SVivien Didelot struct mv88e6xxx_atu_entry {
2684d5f2ba7SVivien Didelot 	u8	state;
2694d5f2ba7SVivien Didelot 	bool	trunk;
2704d5f2ba7SVivien Didelot 	u16	portvec;
2714d5f2ba7SVivien Didelot 	u8	mac[ETH_ALEN];
2724d5f2ba7SVivien Didelot };
2734d5f2ba7SVivien Didelot 
2744d5f2ba7SVivien Didelot struct mv88e6xxx_vtu_entry {
2754d5f2ba7SVivien Didelot 	u16	vid;
2764d5f2ba7SVivien Didelot 	u16	fid;
2774d5f2ba7SVivien Didelot 	u8	sid;
2784d5f2ba7SVivien Didelot 	bool	valid;
2794d5f2ba7SVivien Didelot 	u8	member[DSA_MAX_PORTS];
2804d5f2ba7SVivien Didelot 	u8	state[DSA_MAX_PORTS];
2814d5f2ba7SVivien Didelot };
2824d5f2ba7SVivien Didelot 
2834d5f2ba7SVivien Didelot struct mv88e6xxx_bus_ops;
2844d5f2ba7SVivien Didelot struct mv88e6xxx_irq_ops;
2854d5f2ba7SVivien Didelot 
2864d5f2ba7SVivien Didelot struct mv88e6xxx_irq {
2874d5f2ba7SVivien Didelot 	u16 masked;
2884d5f2ba7SVivien Didelot 	struct irq_chip chip;
2894d5f2ba7SVivien Didelot 	struct irq_domain *domain;
2904d5f2ba7SVivien Didelot 	unsigned int nirqs;
2914d5f2ba7SVivien Didelot };
2924d5f2ba7SVivien Didelot 
2934d5f2ba7SVivien Didelot struct mv88e6xxx_chip {
2944d5f2ba7SVivien Didelot 	const struct mv88e6xxx_info *info;
2954d5f2ba7SVivien Didelot 
2964d5f2ba7SVivien Didelot 	/* The dsa_switch this private structure is related to */
2974d5f2ba7SVivien Didelot 	struct dsa_switch *ds;
2984d5f2ba7SVivien Didelot 
2994d5f2ba7SVivien Didelot 	/* The device this structure is associated to */
3004d5f2ba7SVivien Didelot 	struct device *dev;
3014d5f2ba7SVivien Didelot 
3024d5f2ba7SVivien Didelot 	/* This mutex protects the access to the switch registers */
3034d5f2ba7SVivien Didelot 	struct mutex reg_lock;
3044d5f2ba7SVivien Didelot 
3054d5f2ba7SVivien Didelot 	/* The MII bus and the address on the bus that is used to
3064d5f2ba7SVivien Didelot 	 * communication with the switch
3074d5f2ba7SVivien Didelot 	 */
3084d5f2ba7SVivien Didelot 	const struct mv88e6xxx_bus_ops *smi_ops;
3094d5f2ba7SVivien Didelot 	struct mii_bus *bus;
3104d5f2ba7SVivien Didelot 	int sw_addr;
3114d5f2ba7SVivien Didelot 
3124d5f2ba7SVivien Didelot 	/* Handles automatic disabling and re-enabling of the PHY
3134d5f2ba7SVivien Didelot 	 * polling unit.
3144d5f2ba7SVivien Didelot 	 */
3154d5f2ba7SVivien Didelot 	const struct mv88e6xxx_bus_ops *phy_ops;
3164d5f2ba7SVivien Didelot 	struct mutex		ppu_mutex;
3174d5f2ba7SVivien Didelot 	int			ppu_disabled;
3184d5f2ba7SVivien Didelot 	struct work_struct	ppu_work;
3194d5f2ba7SVivien Didelot 	struct timer_list	ppu_timer;
3204d5f2ba7SVivien Didelot 
3214d5f2ba7SVivien Didelot 	/* This mutex serialises access to the statistics unit.
3224d5f2ba7SVivien Didelot 	 * Hold this mutex over snapshot + dump sequences.
3234d5f2ba7SVivien Didelot 	 */
3244d5f2ba7SVivien Didelot 	struct mutex	stats_mutex;
3254d5f2ba7SVivien Didelot 
3264d5f2ba7SVivien Didelot 	/* A switch may have a GPIO line tied to its reset pin. Parse
3274d5f2ba7SVivien Didelot 	 * this from the device tree, and use it before performing
3284d5f2ba7SVivien Didelot 	 * switch soft reset.
3294d5f2ba7SVivien Didelot 	 */
3304d5f2ba7SVivien Didelot 	struct gpio_desc *reset;
3314d5f2ba7SVivien Didelot 
3324d5f2ba7SVivien Didelot 	/* set to size of eeprom if supported by the switch */
3334d5f2ba7SVivien Didelot 	int		eeprom_len;
3344d5f2ba7SVivien Didelot 
3354d5f2ba7SVivien Didelot 	/* List of mdio busses */
3364d5f2ba7SVivien Didelot 	struct list_head mdios;
3374d5f2ba7SVivien Didelot 
3384d5f2ba7SVivien Didelot 	/* There can be two interrupt controllers, which are chained
3394d5f2ba7SVivien Didelot 	 * off a GPIO as interrupt source
3404d5f2ba7SVivien Didelot 	 */
3414d5f2ba7SVivien Didelot 	struct mv88e6xxx_irq g1_irq;
3424d5f2ba7SVivien Didelot 	struct mv88e6xxx_irq g2_irq;
3434d5f2ba7SVivien Didelot 	int irq;
3444d5f2ba7SVivien Didelot 	int device_irq;
3454d5f2ba7SVivien Didelot 	int watchdog_irq;
3464d5f2ba7SVivien Didelot };
3474d5f2ba7SVivien Didelot 
3484d5f2ba7SVivien Didelot struct mv88e6xxx_bus_ops {
3494d5f2ba7SVivien Didelot 	int (*read)(struct mv88e6xxx_chip *chip, int addr, int reg, u16 *val);
3504d5f2ba7SVivien Didelot 	int (*write)(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val);
3514d5f2ba7SVivien Didelot };
3524d5f2ba7SVivien Didelot 
3534d5f2ba7SVivien Didelot struct mv88e6xxx_mdio_bus {
3544d5f2ba7SVivien Didelot 	struct mii_bus *bus;
3554d5f2ba7SVivien Didelot 	struct mv88e6xxx_chip *chip;
3564d5f2ba7SVivien Didelot 	struct list_head list;
3574d5f2ba7SVivien Didelot 	bool external;
3584d5f2ba7SVivien Didelot };
3594d5f2ba7SVivien Didelot 
3604d5f2ba7SVivien Didelot struct mv88e6xxx_ops {
3614d5f2ba7SVivien Didelot 	int (*get_eeprom)(struct mv88e6xxx_chip *chip,
3624d5f2ba7SVivien Didelot 			  struct ethtool_eeprom *eeprom, u8 *data);
3634d5f2ba7SVivien Didelot 	int (*set_eeprom)(struct mv88e6xxx_chip *chip,
3644d5f2ba7SVivien Didelot 			  struct ethtool_eeprom *eeprom, u8 *data);
3654d5f2ba7SVivien Didelot 
3664d5f2ba7SVivien Didelot 	int (*set_switch_mac)(struct mv88e6xxx_chip *chip, u8 *addr);
3674d5f2ba7SVivien Didelot 
3684d5f2ba7SVivien Didelot 	int (*phy_read)(struct mv88e6xxx_chip *chip,
3694d5f2ba7SVivien Didelot 			struct mii_bus *bus,
3704d5f2ba7SVivien Didelot 			int addr, int reg, u16 *val);
3714d5f2ba7SVivien Didelot 	int (*phy_write)(struct mv88e6xxx_chip *chip,
3724d5f2ba7SVivien Didelot 			 struct mii_bus *bus,
3734d5f2ba7SVivien Didelot 			 int addr, int reg, u16 val);
3744d5f2ba7SVivien Didelot 
3754d5f2ba7SVivien Didelot 	/* PHY Polling Unit (PPU) operations */
3764d5f2ba7SVivien Didelot 	int (*ppu_enable)(struct mv88e6xxx_chip *chip);
3774d5f2ba7SVivien Didelot 	int (*ppu_disable)(struct mv88e6xxx_chip *chip);
3784d5f2ba7SVivien Didelot 
3794d5f2ba7SVivien Didelot 	/* Switch Software Reset */
3804d5f2ba7SVivien Didelot 	int (*reset)(struct mv88e6xxx_chip *chip);
3814d5f2ba7SVivien Didelot 
3824d5f2ba7SVivien Didelot 	/* RGMII Receive/Transmit Timing Control
3834d5f2ba7SVivien Didelot 	 * Add delay on PHY_INTERFACE_MODE_RGMII_*ID, no delay otherwise.
3844d5f2ba7SVivien Didelot 	 */
3854d5f2ba7SVivien Didelot 	int (*port_set_rgmii_delay)(struct mv88e6xxx_chip *chip, int port,
3864d5f2ba7SVivien Didelot 				    phy_interface_t mode);
3874d5f2ba7SVivien Didelot 
3884d5f2ba7SVivien Didelot #define LINK_FORCED_DOWN	0
3894d5f2ba7SVivien Didelot #define LINK_FORCED_UP		1
3904d5f2ba7SVivien Didelot #define LINK_UNFORCED		-2
3914d5f2ba7SVivien Didelot 
3924d5f2ba7SVivien Didelot 	/* Port's MAC link state
3934d5f2ba7SVivien Didelot 	 * Use LINK_FORCED_UP or LINK_FORCED_DOWN to force link up or down,
3944d5f2ba7SVivien Didelot 	 * or LINK_UNFORCED for normal link detection.
3954d5f2ba7SVivien Didelot 	 */
3964d5f2ba7SVivien Didelot 	int (*port_set_link)(struct mv88e6xxx_chip *chip, int port, int link);
3974d5f2ba7SVivien Didelot 
3984d5f2ba7SVivien Didelot #define DUPLEX_UNFORCED		-2
3994d5f2ba7SVivien Didelot 
4004d5f2ba7SVivien Didelot 	/* Port's MAC duplex mode
4014d5f2ba7SVivien Didelot 	 *
4024d5f2ba7SVivien Didelot 	 * Use DUPLEX_HALF or DUPLEX_FULL to force half or full duplex,
4034d5f2ba7SVivien Didelot 	 * or DUPLEX_UNFORCED for normal duplex detection.
4044d5f2ba7SVivien Didelot 	 */
4054d5f2ba7SVivien Didelot 	int (*port_set_duplex)(struct mv88e6xxx_chip *chip, int port, int dup);
4064d5f2ba7SVivien Didelot 
4074d5f2ba7SVivien Didelot #define SPEED_MAX		INT_MAX
4084d5f2ba7SVivien Didelot #define SPEED_UNFORCED		-2
4094d5f2ba7SVivien Didelot 
4104d5f2ba7SVivien Didelot 	/* Port's MAC speed (in Mbps)
4114d5f2ba7SVivien Didelot 	 *
4124d5f2ba7SVivien Didelot 	 * Depending on the chip, 10, 100, 200, 1000, 2500, 10000 are valid.
4134d5f2ba7SVivien Didelot 	 * Use SPEED_UNFORCED for normal detection, SPEED_MAX for max value.
4144d5f2ba7SVivien Didelot 	 */
4154d5f2ba7SVivien Didelot 	int (*port_set_speed)(struct mv88e6xxx_chip *chip, int port, int speed);
4164d5f2ba7SVivien Didelot 
4174d5f2ba7SVivien Didelot 	int (*port_tag_remap)(struct mv88e6xxx_chip *chip, int port);
4184d5f2ba7SVivien Didelot 
4194d5f2ba7SVivien Didelot 	int (*port_set_frame_mode)(struct mv88e6xxx_chip *chip, int port,
4204d5f2ba7SVivien Didelot 				   enum mv88e6xxx_frame_mode mode);
4214d5f2ba7SVivien Didelot 	int (*port_set_egress_floods)(struct mv88e6xxx_chip *chip, int port,
4224d5f2ba7SVivien Didelot 				      bool unicast, bool multicast);
4234d5f2ba7SVivien Didelot 	int (*port_set_ether_type)(struct mv88e6xxx_chip *chip, int port,
4244d5f2ba7SVivien Didelot 				   u16 etype);
4254d5f2ba7SVivien Didelot 	int (*port_jumbo_config)(struct mv88e6xxx_chip *chip, int port);
4264d5f2ba7SVivien Didelot 
4274d5f2ba7SVivien Didelot 	int (*port_egress_rate_limiting)(struct mv88e6xxx_chip *chip, int port);
4284d5f2ba7SVivien Didelot 	int (*port_pause_config)(struct mv88e6xxx_chip *chip, int port);
4294d5f2ba7SVivien Didelot 	int (*port_disable_learn_limit)(struct mv88e6xxx_chip *chip, int port);
4304d5f2ba7SVivien Didelot 	int (*port_disable_pri_override)(struct mv88e6xxx_chip *chip, int port);
4314d5f2ba7SVivien Didelot 
4324d5f2ba7SVivien Didelot 	/* CMODE control what PHY mode the MAC will use, eg. SGMII, RGMII, etc.
4334d5f2ba7SVivien Didelot 	 * Some chips allow this to be configured on specific ports.
4344d5f2ba7SVivien Didelot 	 */
4354d5f2ba7SVivien Didelot 	int (*port_set_cmode)(struct mv88e6xxx_chip *chip, int port,
4364d5f2ba7SVivien Didelot 			      phy_interface_t mode);
4374d5f2ba7SVivien Didelot 
4384d5f2ba7SVivien Didelot 	/* Some devices have a per port register indicating what is
4394d5f2ba7SVivien Didelot 	 * the upstream port this port should forward to.
4404d5f2ba7SVivien Didelot 	 */
4414d5f2ba7SVivien Didelot 	int (*port_set_upstream_port)(struct mv88e6xxx_chip *chip, int port,
4424d5f2ba7SVivien Didelot 				      int upstream_port);
4434d5f2ba7SVivien Didelot 
4444d5f2ba7SVivien Didelot 	/* Snapshot the statistics for a port. The statistics can then
4454d5f2ba7SVivien Didelot 	 * be read back a leisure but still with a consistent view.
4464d5f2ba7SVivien Didelot 	 */
4474d5f2ba7SVivien Didelot 	int (*stats_snapshot)(struct mv88e6xxx_chip *chip, int port);
4484d5f2ba7SVivien Didelot 
4494d5f2ba7SVivien Didelot 	/* Set the histogram mode for statistics, when the control registers
4504d5f2ba7SVivien Didelot 	 * are separated out of the STATS_OP register.
4514d5f2ba7SVivien Didelot 	 */
4524d5f2ba7SVivien Didelot 	int (*stats_set_histogram)(struct mv88e6xxx_chip *chip);
4534d5f2ba7SVivien Didelot 
4544d5f2ba7SVivien Didelot 	/* Return the number of strings describing statistics */
4554d5f2ba7SVivien Didelot 	int (*stats_get_sset_count)(struct mv88e6xxx_chip *chip);
4564d5f2ba7SVivien Didelot 	void (*stats_get_strings)(struct mv88e6xxx_chip *chip,  uint8_t *data);
4574d5f2ba7SVivien Didelot 	void (*stats_get_stats)(struct mv88e6xxx_chip *chip,  int port,
4584d5f2ba7SVivien Didelot 				uint64_t *data);
459fa8d1179SVivien Didelot 	int (*set_cpu_port)(struct mv88e6xxx_chip *chip, int port);
460fa8d1179SVivien Didelot 	int (*set_egress_port)(struct mv88e6xxx_chip *chip, int port);
4614d5f2ba7SVivien Didelot 	const struct mv88e6xxx_irq_ops *watchdog_ops;
4624d5f2ba7SVivien Didelot 
4634d5f2ba7SVivien Didelot 	/* Can be either in g1 or g2, so don't use a prefix */
4644d5f2ba7SVivien Didelot 	int (*mgmt_rsvd2cpu)(struct mv88e6xxx_chip *chip);
4654d5f2ba7SVivien Didelot 
4664d5f2ba7SVivien Didelot 	/* Power on/off a SERDES interface */
4674d5f2ba7SVivien Didelot 	int (*serdes_power)(struct mv88e6xxx_chip *chip, int port, bool on);
4684d5f2ba7SVivien Didelot 
4694d5f2ba7SVivien Didelot 	/* VLAN Translation Unit operations */
4704d5f2ba7SVivien Didelot 	int (*vtu_getnext)(struct mv88e6xxx_chip *chip,
4714d5f2ba7SVivien Didelot 			   struct mv88e6xxx_vtu_entry *entry);
4724d5f2ba7SVivien Didelot 	int (*vtu_loadpurge)(struct mv88e6xxx_chip *chip,
4734d5f2ba7SVivien Didelot 			     struct mv88e6xxx_vtu_entry *entry);
4744d5f2ba7SVivien Didelot };
4754d5f2ba7SVivien Didelot 
4764d5f2ba7SVivien Didelot struct mv88e6xxx_irq_ops {
4774d5f2ba7SVivien Didelot 	/* Action to be performed when the interrupt happens */
4784d5f2ba7SVivien Didelot 	int (*irq_action)(struct mv88e6xxx_chip *chip, int irq);
4794d5f2ba7SVivien Didelot 	/* Setup the hardware to generate the interrupt */
4804d5f2ba7SVivien Didelot 	int (*irq_setup)(struct mv88e6xxx_chip *chip);
4814d5f2ba7SVivien Didelot 	/* Reset the hardware to stop generating the interrupt */
4824d5f2ba7SVivien Didelot 	void (*irq_free)(struct mv88e6xxx_chip *chip);
4834d5f2ba7SVivien Didelot };
4844d5f2ba7SVivien Didelot 
4854d5f2ba7SVivien Didelot #define STATS_TYPE_PORT		BIT(0)
4864d5f2ba7SVivien Didelot #define STATS_TYPE_BANK0	BIT(1)
4874d5f2ba7SVivien Didelot #define STATS_TYPE_BANK1	BIT(2)
4884d5f2ba7SVivien Didelot 
4894d5f2ba7SVivien Didelot struct mv88e6xxx_hw_stat {
4904d5f2ba7SVivien Didelot 	char string[ETH_GSTRING_LEN];
4914d5f2ba7SVivien Didelot 	int sizeof_stat;
4924d5f2ba7SVivien Didelot 	int reg;
4934d5f2ba7SVivien Didelot 	int type;
4944d5f2ba7SVivien Didelot };
4954d5f2ba7SVivien Didelot 
4964d5f2ba7SVivien Didelot static inline bool mv88e6xxx_has(struct mv88e6xxx_chip *chip,
4974d5f2ba7SVivien Didelot 				 unsigned long flags)
4984d5f2ba7SVivien Didelot {
4994d5f2ba7SVivien Didelot 	return (chip->info->flags & flags) == flags;
5004d5f2ba7SVivien Didelot }
5014d5f2ba7SVivien Didelot 
5024d5f2ba7SVivien Didelot static inline bool mv88e6xxx_has_pvt(struct mv88e6xxx_chip *chip)
5034d5f2ba7SVivien Didelot {
5044d5f2ba7SVivien Didelot 	return chip->info->pvt;
5054d5f2ba7SVivien Didelot }
5064d5f2ba7SVivien Didelot 
5074d5f2ba7SVivien Didelot static inline unsigned int mv88e6xxx_num_databases(struct mv88e6xxx_chip *chip)
5084d5f2ba7SVivien Didelot {
5094d5f2ba7SVivien Didelot 	return chip->info->num_databases;
5104d5f2ba7SVivien Didelot }
5114d5f2ba7SVivien Didelot 
5124d5f2ba7SVivien Didelot static inline unsigned int mv88e6xxx_num_ports(struct mv88e6xxx_chip *chip)
5134d5f2ba7SVivien Didelot {
5144d5f2ba7SVivien Didelot 	return chip->info->num_ports;
5154d5f2ba7SVivien Didelot }
5164d5f2ba7SVivien Didelot 
5174d5f2ba7SVivien Didelot static inline u16 mv88e6xxx_port_mask(struct mv88e6xxx_chip *chip)
5184d5f2ba7SVivien Didelot {
5194d5f2ba7SVivien Didelot 	return GENMASK(mv88e6xxx_num_ports(chip) - 1, 0);
5204d5f2ba7SVivien Didelot }
5214d5f2ba7SVivien Didelot 
5224d5f2ba7SVivien Didelot int mv88e6xxx_read(struct mv88e6xxx_chip *chip, int addr, int reg, u16 *val);
5234d5f2ba7SVivien Didelot int mv88e6xxx_write(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val);
5244d5f2ba7SVivien Didelot int mv88e6xxx_update(struct mv88e6xxx_chip *chip, int addr, int reg,
5254d5f2ba7SVivien Didelot 		     u16 update);
5264d5f2ba7SVivien Didelot int mv88e6xxx_wait(struct mv88e6xxx_chip *chip, int addr, int reg, u16 mask);
5274d5f2ba7SVivien Didelot struct mii_bus *mv88e6xxx_default_mdio_bus(struct mv88e6xxx_chip *chip);
5284d5f2ba7SVivien Didelot 
5294d5f2ba7SVivien Didelot #endif /* _MV88E6XXX_CHIP_H */
530