xref: /openbmc/linux/drivers/net/dsa/mv88e6xxx/chip.h (revision d1e3dc19)
12874c5fdSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */
24d5f2ba7SVivien Didelot /*
34d5f2ba7SVivien Didelot  * Marvell 88E6xxx Ethernet switch single-chip definition
44d5f2ba7SVivien Didelot  *
54d5f2ba7SVivien Didelot  * Copyright (c) 2008 Marvell Semiconductor
64d5f2ba7SVivien Didelot  */
74d5f2ba7SVivien Didelot 
84d5f2ba7SVivien Didelot #ifndef _MV88E6XXX_CHIP_H
94d5f2ba7SVivien Didelot #define _MV88E6XXX_CHIP_H
104d5f2ba7SVivien Didelot 
11da7dc875SVivien Didelot #include <linux/idr.h>
124d5f2ba7SVivien Didelot #include <linux/if_vlan.h>
134d5f2ba7SVivien Didelot #include <linux/irq.h>
144d5f2ba7SVivien Didelot #include <linux/gpio/consumer.h>
15294d711eSAndrew Lunn #include <linux/kthread.h>
164d5f2ba7SVivien Didelot #include <linux/phy.h>
172fa8d3afSBrandon Streiff #include <linux/ptp_clock_kernel.h>
182fa8d3afSBrandon Streiff #include <linux/timecounter.h>
194d5f2ba7SVivien Didelot #include <net/dsa.h>
204d5f2ba7SVivien Didelot 
21b9c587feSAndrew Lunn #define EDSA_HLEN		8
224d5f2ba7SVivien Didelot #define MV88E6XXX_N_FID		4096
2349c98c1dSTobias Waldekranz #define MV88E6XXX_N_SID		64
244d5f2ba7SVivien Didelot 
255bded825SVladimir Oltean #define MV88E6XXX_FID_STANDALONE	0
265bded825SVladimir Oltean #define MV88E6XXX_FID_BRIDGED		1
275bded825SVladimir Oltean 
284d5f2ba7SVivien Didelot /* PVT limits for 4-bit port and 5-bit switch */
294d5f2ba7SVivien Didelot #define MV88E6XXX_MAX_PVT_SWITCHES	32
304d5f2ba7SVivien Didelot #define MV88E6XXX_MAX_PVT_PORTS		16
31836021a2STobias Waldekranz #define MV88E6XXX_MAX_PVT_ENTRIES	\
32836021a2STobias Waldekranz 	(MV88E6XXX_MAX_PVT_SWITCHES * MV88E6XXX_MAX_PVT_PORTS)
334d5f2ba7SVivien Didelot 
34a73ccd61SBrandon Streiff #define MV88E6XXX_MAX_GPIO	16
35a73ccd61SBrandon Streiff 
3631bef4e9SVivien Didelot enum mv88e6xxx_egress_mode {
3731bef4e9SVivien Didelot 	MV88E6XXX_EGRESS_MODE_UNMODIFIED,
3831bef4e9SVivien Didelot 	MV88E6XXX_EGRESS_MODE_UNTAGGED,
3931bef4e9SVivien Didelot 	MV88E6XXX_EGRESS_MODE_TAGGED,
4031bef4e9SVivien Didelot 	MV88E6XXX_EGRESS_MODE_ETHERTYPE,
4131bef4e9SVivien Didelot };
4231bef4e9SVivien Didelot 
435c74c54cSIwan R Timmer enum mv88e6xxx_egress_direction {
445c74c54cSIwan R Timmer         MV88E6XXX_EGRESS_DIR_INGRESS,
455c74c54cSIwan R Timmer         MV88E6XXX_EGRESS_DIR_EGRESS,
465c74c54cSIwan R Timmer };
475c74c54cSIwan R Timmer 
484d5f2ba7SVivien Didelot enum mv88e6xxx_frame_mode {
494d5f2ba7SVivien Didelot 	MV88E6XXX_FRAME_MODE_NORMAL,
504d5f2ba7SVivien Didelot 	MV88E6XXX_FRAME_MODE_DSA,
514d5f2ba7SVivien Didelot 	MV88E6XXX_FRAME_MODE_PROVIDER,
524d5f2ba7SVivien Didelot 	MV88E6XXX_FRAME_MODE_ETHERTYPE,
534d5f2ba7SVivien Didelot };
544d5f2ba7SVivien Didelot 
554d5f2ba7SVivien Didelot /* List of supported models */
564d5f2ba7SVivien Didelot enum mv88e6xxx_model {
5771d94a43SMatthias Schiffer 	MV88E6020,
58372188c8SLukasz Majewski 	MV88E6071,
594d5f2ba7SVivien Didelot 	MV88E6085,
604d5f2ba7SVivien Didelot 	MV88E6095,
614d5f2ba7SVivien Didelot 	MV88E6097,
624d5f2ba7SVivien Didelot 	MV88E6123,
634d5f2ba7SVivien Didelot 	MV88E6131,
644d5f2ba7SVivien Didelot 	MV88E6141,
654d5f2ba7SVivien Didelot 	MV88E6161,
664d5f2ba7SVivien Didelot 	MV88E6165,
674d5f2ba7SVivien Didelot 	MV88E6171,
684d5f2ba7SVivien Didelot 	MV88E6172,
694d5f2ba7SVivien Didelot 	MV88E6175,
704d5f2ba7SVivien Didelot 	MV88E6176,
714d5f2ba7SVivien Didelot 	MV88E6185,
724d5f2ba7SVivien Didelot 	MV88E6190,
734d5f2ba7SVivien Didelot 	MV88E6190X,
744d5f2ba7SVivien Didelot 	MV88E6191,
75de776d0dSPavana Sharma 	MV88E6191X,
76de776d0dSPavana Sharma 	MV88E6193X,
7749022647SHubert Feurstein 	MV88E6220,
784d5f2ba7SVivien Didelot 	MV88E6240,
791f71836fSRasmus Villemoes 	MV88E6250,
804d5f2ba7SVivien Didelot 	MV88E6290,
814d5f2ba7SVivien Didelot 	MV88E6320,
824d5f2ba7SVivien Didelot 	MV88E6321,
834d5f2ba7SVivien Didelot 	MV88E6341,
844d5f2ba7SVivien Didelot 	MV88E6350,
854d5f2ba7SVivien Didelot 	MV88E6351,
864d5f2ba7SVivien Didelot 	MV88E6352,
8712899f29SAlexis Lothoré 	MV88E6361,
884d5f2ba7SVivien Didelot 	MV88E6390,
894d5f2ba7SVivien Didelot 	MV88E6390X,
90de776d0dSPavana Sharma 	MV88E6393X,
914d5f2ba7SVivien Didelot };
924d5f2ba7SVivien Didelot 
934d5f2ba7SVivien Didelot enum mv88e6xxx_family {
944d5f2ba7SVivien Didelot 	MV88E6XXX_FAMILY_NONE,
954d5f2ba7SVivien Didelot 	MV88E6XXX_FAMILY_6065,	/* 6031 6035 6061 6065 */
964d5f2ba7SVivien Didelot 	MV88E6XXX_FAMILY_6095,	/* 6092 6095 */
974d5f2ba7SVivien Didelot 	MV88E6XXX_FAMILY_6097,	/* 6046 6085 6096 6097 */
984d5f2ba7SVivien Didelot 	MV88E6XXX_FAMILY_6165,	/* 6123 6161 6165 */
994d5f2ba7SVivien Didelot 	MV88E6XXX_FAMILY_6185,	/* 6108 6121 6122 6131 6152 6155 6182 6185 */
100372188c8SLukasz Majewski 	MV88E6XXX_FAMILY_6250,	/* 6220 6250 6020 6071 */
1014d5f2ba7SVivien Didelot 	MV88E6XXX_FAMILY_6320,	/* 6320 6321 */
1024d5f2ba7SVivien Didelot 	MV88E6XXX_FAMILY_6341,	/* 6141 6341 */
1034d5f2ba7SVivien Didelot 	MV88E6XXX_FAMILY_6351,	/* 6171 6175 6350 6351 */
1044d5f2ba7SVivien Didelot 	MV88E6XXX_FAMILY_6352,	/* 6172 6176 6240 6352 */
1054d5f2ba7SVivien Didelot 	MV88E6XXX_FAMILY_6390,  /* 6190 6190X 6191 6290 6390 6390X */
10612899f29SAlexis Lothoré 	MV88E6XXX_FAMILY_6393,	/* 6191X 6193X 6361 6393X */
1074d5f2ba7SVivien Didelot };
1084d5f2ba7SVivien Didelot 
109670bb80fSTobias Waldekranz /**
110670bb80fSTobias Waldekranz  * enum mv88e6xxx_edsa_support - Ethertype DSA tag support level
111670bb80fSTobias Waldekranz  * @MV88E6XXX_EDSA_UNSUPPORTED:  Device has no support for EDSA tags
112670bb80fSTobias Waldekranz  * @MV88E6XXX_EDSA_UNDOCUMENTED: Documentation indicates that
113670bb80fSTobias Waldekranz  *                               egressing FORWARD frames with an EDSA
114670bb80fSTobias Waldekranz  *                               tag is reserved for future use, but
115670bb80fSTobias Waldekranz  *                               empirical data shows that this mode
116670bb80fSTobias Waldekranz  *                               is supported.
117670bb80fSTobias Waldekranz  * @MV88E6XXX_EDSA_SUPPORTED:    EDSA tags are fully supported.
118670bb80fSTobias Waldekranz  */
119670bb80fSTobias Waldekranz enum mv88e6xxx_edsa_support {
120670bb80fSTobias Waldekranz 	MV88E6XXX_EDSA_UNSUPPORTED = 0,
121670bb80fSTobias Waldekranz 	MV88E6XXX_EDSA_UNDOCUMENTED,
122670bb80fSTobias Waldekranz 	MV88E6XXX_EDSA_SUPPORTED,
123670bb80fSTobias Waldekranz };
124670bb80fSTobias Waldekranz 
1254d5f2ba7SVivien Didelot struct mv88e6xxx_ops;
1264d5f2ba7SVivien Didelot 
1274d5f2ba7SVivien Didelot struct mv88e6xxx_info {
1284d5f2ba7SVivien Didelot 	enum mv88e6xxx_family family;
1294d5f2ba7SVivien Didelot 	u16 prod_num;
1304d5f2ba7SVivien Didelot 	const char *name;
1314d5f2ba7SVivien Didelot 	unsigned int num_databases;
132d9ea5620SAndrew Lunn 	unsigned int num_macs;
1334d5f2ba7SVivien Didelot 	unsigned int num_ports;
134bc393155SAndrew Lunn 	unsigned int num_internal_phys;
135a73ccd61SBrandon Streiff 	unsigned int num_gpio;
1364d5f2ba7SVivien Didelot 	unsigned int max_vid;
13749c98c1dSTobias Waldekranz 	unsigned int max_sid;
1384d5f2ba7SVivien Didelot 	unsigned int port_base_addr;
1399255bacdSAndrew Lunn 	unsigned int phy_base_addr;
1404d5f2ba7SVivien Didelot 	unsigned int global1_addr;
1419069c13aSVivien Didelot 	unsigned int global2_addr;
1424d5f2ba7SVivien Didelot 	unsigned int age_time_coeff;
1434d5f2ba7SVivien Didelot 	unsigned int g1_irqs;
144d6c5e6afSVivien Didelot 	unsigned int g2_irqs;
1454d5f2ba7SVivien Didelot 	bool pvt;
146b3e05aa1SVivien Didelot 
147c857486aSHubert Feurstein 	/* Mark certain ports as invalid. This is required for example for the
148c857486aSHubert Feurstein 	 * MV88E6220 (which is in general a MV88E6250 with 7 ports) but the
149c857486aSHubert Feurstein 	 * ports 2-4 are not routet to pins.
150c857486aSHubert Feurstein 	 */
151c857486aSHubert Feurstein 	unsigned int invalid_port_mask;
152b3e05aa1SVivien Didelot 	/* Multi-chip Addressing Mode.
153b3e05aa1SVivien Didelot 	 * Some chips respond to only 2 registers of its own SMI device address
154b3e05aa1SVivien Didelot 	 * when it is non-zero, and use indirect access to internal registers.
155b3e05aa1SVivien Didelot 	 */
156b3e05aa1SVivien Didelot 	bool multi_chip;
157f30a19b8SRasmus Villemoes 	/* Dual-chip Addressing Mode
158f30a19b8SRasmus Villemoes 	 * Some chips respond to only half of the 32 SMI addresses,
159f30a19b8SRasmus Villemoes 	 * allowing two to coexist on the same SMI interface.
160f30a19b8SRasmus Villemoes 	 */
161f30a19b8SRasmus Villemoes 	bool dual_chip;
162f30a19b8SRasmus Villemoes 
163670bb80fSTobias Waldekranz 	enum mv88e6xxx_edsa_support edsa_support;
1644d5f2ba7SVivien Didelot 
1654d5f2ba7SVivien Didelot 	/* Mask for FromPort and ToPort value of PortVec used in ATU Move
1664d5f2ba7SVivien Didelot 	 * operation. 0 means that the ATU Move operation is not supported.
1674d5f2ba7SVivien Didelot 	 */
1684d5f2ba7SVivien Didelot 	u8 atu_move_port_mask;
1694d5f2ba7SVivien Didelot 	const struct mv88e6xxx_ops *ops;
1702fa8d3afSBrandon Streiff 
1712fa8d3afSBrandon Streiff 	/* Supports PTP */
1722fa8d3afSBrandon Streiff 	bool ptp_support;
1733ba89b28SAlexis Lothoré 
1743ba89b28SAlexis Lothoré 	/* Internal PHY start index. 0 means that internal PHYs range starts at
1753ba89b28SAlexis Lothoré 	 * port 0, 1 means internal PHYs range starts at port 1, etc
1763ba89b28SAlexis Lothoré 	 */
1773ba89b28SAlexis Lothoré 	unsigned int internal_phys_offset;
1784d5f2ba7SVivien Didelot };
1794d5f2ba7SVivien Didelot 
1804d5f2ba7SVivien Didelot struct mv88e6xxx_atu_entry {
1814d5f2ba7SVivien Didelot 	u8	state;
1824d5f2ba7SVivien Didelot 	bool	trunk;
1834d5f2ba7SVivien Didelot 	u16	portvec;
1844d5f2ba7SVivien Didelot 	u8	mac[ETH_ALEN];
1854d5f2ba7SVivien Didelot };
1864d5f2ba7SVivien Didelot 
1874d5f2ba7SVivien Didelot struct mv88e6xxx_vtu_entry {
1884d5f2ba7SVivien Didelot 	u16	vid;
1894d5f2ba7SVivien Didelot 	u16	fid;
1904d5f2ba7SVivien Didelot 	u8	sid;
1914d5f2ba7SVivien Didelot 	bool	valid;
192bb03b280STobias Waldekranz 	bool	policy;
1934d5f2ba7SVivien Didelot 	u8	member[DSA_MAX_PORTS];
19449c98c1dSTobias Waldekranz 	u8	state[DSA_MAX_PORTS];	/* Older silicon has no STU */
19549c98c1dSTobias Waldekranz };
19649c98c1dSTobias Waldekranz 
19749c98c1dSTobias Waldekranz struct mv88e6xxx_stu_entry {
19849c98c1dSTobias Waldekranz 	u8	sid;
19949c98c1dSTobias Waldekranz 	bool	valid;
2004d5f2ba7SVivien Didelot 	u8	state[DSA_MAX_PORTS];
2014d5f2ba7SVivien Didelot };
2024d5f2ba7SVivien Didelot 
2034d5f2ba7SVivien Didelot struct mv88e6xxx_bus_ops;
2044d5f2ba7SVivien Didelot struct mv88e6xxx_irq_ops;
205a73ccd61SBrandon Streiff struct mv88e6xxx_gpio_ops;
2060d632c3dSBrandon Streiff struct mv88e6xxx_avb_ops;
2076d2ac8eeSAndrew Lunn struct mv88e6xxx_ptp_ops;
208b92143d4SRussell King (Oracle) struct mv88e6xxx_pcs_ops;
2094d5f2ba7SVivien Didelot 
2104d5f2ba7SVivien Didelot struct mv88e6xxx_irq {
2114d5f2ba7SVivien Didelot 	u16 masked;
2124d5f2ba7SVivien Didelot 	struct irq_chip chip;
2134d5f2ba7SVivien Didelot 	struct irq_domain *domain;
214f1931164SAndrew Lunn 	int nirqs;
2154d5f2ba7SVivien Didelot };
2164d5f2ba7SVivien Didelot 
217c6fe0ad2SBrandon Streiff /* state flags for mv88e6xxx_port_hwtstamp::state */
218c6fe0ad2SBrandon Streiff enum {
219c6fe0ad2SBrandon Streiff 	MV88E6XXX_HWTSTAMP_ENABLED,
220c6fe0ad2SBrandon Streiff 	MV88E6XXX_HWTSTAMP_TX_IN_PROGRESS,
221c6fe0ad2SBrandon Streiff };
222c6fe0ad2SBrandon Streiff 
223c6fe0ad2SBrandon Streiff struct mv88e6xxx_port_hwtstamp {
224c6fe0ad2SBrandon Streiff 	/* Port index */
225c6fe0ad2SBrandon Streiff 	int port_id;
226c6fe0ad2SBrandon Streiff 
227c6fe0ad2SBrandon Streiff 	/* Timestamping state */
228c6fe0ad2SBrandon Streiff 	unsigned long state;
229c6fe0ad2SBrandon Streiff 
230c6fe0ad2SBrandon Streiff 	/* Resources for receive timestamping */
231c6fe0ad2SBrandon Streiff 	struct sk_buff_head rx_queue;
232c6fe0ad2SBrandon Streiff 	struct sk_buff_head rx_queue2;
233c6fe0ad2SBrandon Streiff 
234c6fe0ad2SBrandon Streiff 	/* Resources for transmit timestamping */
235c6fe0ad2SBrandon Streiff 	unsigned long tx_tstamp_start;
236c6fe0ad2SBrandon Streiff 	struct sk_buff *tx_skb;
237c6fe0ad2SBrandon Streiff 	u16 tx_seq_id;
238c6fe0ad2SBrandon Streiff 
239c6fe0ad2SBrandon Streiff 	/* Current timestamp configuration */
240c6fe0ad2SBrandon Streiff 	struct hwtstamp_config tstamp_config;
241c6fe0ad2SBrandon Streiff };
242c6fe0ad2SBrandon Streiff 
243f3a2cd32SVivien Didelot enum mv88e6xxx_policy_mapping {
244f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_MAPPING_DA,
245f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_MAPPING_SA,
246f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_MAPPING_VTU,
247f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_MAPPING_ETYPE,
248f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_MAPPING_PPPOE,
249f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_MAPPING_VBAS,
250f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_MAPPING_OPT82,
251f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_MAPPING_UDP,
252f3a2cd32SVivien Didelot };
253f3a2cd32SVivien Didelot 
254f3a2cd32SVivien Didelot enum mv88e6xxx_policy_action {
255f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_ACTION_NORMAL,
256f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_ACTION_MIRROR,
257f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_ACTION_TRAP,
258f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_ACTION_DISCARD,
259f3a2cd32SVivien Didelot };
260f3a2cd32SVivien Didelot 
261da7dc875SVivien Didelot struct mv88e6xxx_policy {
262da7dc875SVivien Didelot 	enum mv88e6xxx_policy_mapping mapping;
263da7dc875SVivien Didelot 	enum mv88e6xxx_policy_action action;
264da7dc875SVivien Didelot 	struct ethtool_rx_flow_spec fs;
265da7dc875SVivien Didelot 	u8 addr[ETH_ALEN];
266da7dc875SVivien Didelot 	int port;
267da7dc875SVivien Didelot 	u16 vid;
268da7dc875SVivien Didelot };
269da7dc875SVivien Didelot 
2708b6836d8SVladimir Oltean struct mv88e6xxx_vlan {
2718b6836d8SVladimir Oltean 	u16	vid;
2728b6836d8SVladimir Oltean 	bool	valid;
2738b6836d8SVladimir Oltean };
2748b6836d8SVladimir Oltean 
275cda9f4aaSAndrew Lunn struct mv88e6xxx_port {
2767b898469SAndrew Lunn 	struct mv88e6xxx_chip *chip;
2777b898469SAndrew Lunn 	int port;
2788b6836d8SVladimir Oltean 	struct mv88e6xxx_vlan bridge_pvid;
279cda9f4aaSAndrew Lunn 	u64 serdes_stats[2];
28065f60e45SAndrew Lunn 	u64 atu_member_violation;
28165f60e45SAndrew Lunn 	u64 atu_miss_violation;
28265f60e45SAndrew Lunn 	u64 atu_full_violation;
28365f60e45SAndrew Lunn 	u64 vtu_member_violation;
28465f60e45SAndrew Lunn 	u64 vtu_miss_violation;
285fad58190SRussell King 	phy_interface_t interface;
2862d2e1dd2SAndrew Lunn 	u8 cmode;
287f0942e00SIwan R Timmer 	bool mirror_ingress;
288f0942e00SIwan R Timmer 	bool mirror_egress;
289bfb25542SAndrew Lunn 	struct devlink_region *region;
290b92143d4SRussell King (Oracle) 	void *pcs_private;
291830763b9SHans J. Schultz 
292830763b9SHans J. Schultz 	/* MacAuth Bypass control flag */
293830763b9SHans J. Schultz 	bool mab;
294bfb25542SAndrew Lunn };
295bfb25542SAndrew Lunn 
296bfb25542SAndrew Lunn enum mv88e6xxx_region_id {
297bfb25542SAndrew Lunn 	MV88E6XXX_REGION_GLOBAL1 = 0,
298bfb25542SAndrew Lunn 	MV88E6XXX_REGION_GLOBAL2,
299bfb25542SAndrew Lunn 	MV88E6XXX_REGION_ATU,
300ca4d632aSTobias Waldekranz 	MV88E6XXX_REGION_VTU,
3017dc96039STobias Waldekranz 	MV88E6XXX_REGION_STU,
302836021a2STobias Waldekranz 	MV88E6XXX_REGION_PVT,
303bfb25542SAndrew Lunn 
304bfb25542SAndrew Lunn 	_MV88E6XXX_REGION_MAX,
305bfb25542SAndrew Lunn };
306bfb25542SAndrew Lunn 
307bfb25542SAndrew Lunn struct mv88e6xxx_region_priv {
308bfb25542SAndrew Lunn 	enum mv88e6xxx_region_id id;
309cda9f4aaSAndrew Lunn };
310cda9f4aaSAndrew Lunn 
311acaf4d2eSTobias Waldekranz struct mv88e6xxx_mst {
312acaf4d2eSTobias Waldekranz 	struct list_head node;
313acaf4d2eSTobias Waldekranz 
314acaf4d2eSTobias Waldekranz 	refcount_t refcnt;
315acaf4d2eSTobias Waldekranz 	struct net_device *br;
316acaf4d2eSTobias Waldekranz 	u16 msti;
317acaf4d2eSTobias Waldekranz 
318acaf4d2eSTobias Waldekranz 	struct mv88e6xxx_stu_entry stu;
319acaf4d2eSTobias Waldekranz };
320acaf4d2eSTobias Waldekranz 
3214d5f2ba7SVivien Didelot struct mv88e6xxx_chip {
3224d5f2ba7SVivien Didelot 	const struct mv88e6xxx_info *info;
3234d5f2ba7SVivien Didelot 
324670bb80fSTobias Waldekranz 	/* Currently configured tagging protocol */
325670bb80fSTobias Waldekranz 	enum dsa_tag_protocol tag_protocol;
326670bb80fSTobias Waldekranz 
3274d5f2ba7SVivien Didelot 	/* The dsa_switch this private structure is related to */
3284d5f2ba7SVivien Didelot 	struct dsa_switch *ds;
3294d5f2ba7SVivien Didelot 
3304d5f2ba7SVivien Didelot 	/* The device this structure is associated to */
3314d5f2ba7SVivien Didelot 	struct device *dev;
3324d5f2ba7SVivien Didelot 
3334d5f2ba7SVivien Didelot 	/* This mutex protects the access to the switch registers */
3344d5f2ba7SVivien Didelot 	struct mutex reg_lock;
3354d5f2ba7SVivien Didelot 
3364d5f2ba7SVivien Didelot 	/* The MII bus and the address on the bus that is used to
3374d5f2ba7SVivien Didelot 	 * communication with the switch
3384d5f2ba7SVivien Didelot 	 */
3394d5f2ba7SVivien Didelot 	const struct mv88e6xxx_bus_ops *smi_ops;
3404d5f2ba7SVivien Didelot 	struct mii_bus *bus;
3414d5f2ba7SVivien Didelot 	int sw_addr;
3424d5f2ba7SVivien Didelot 
3434d5f2ba7SVivien Didelot 	/* Handles automatic disabling and re-enabling of the PHY
3444d5f2ba7SVivien Didelot 	 * polling unit.
3454d5f2ba7SVivien Didelot 	 */
3464d5f2ba7SVivien Didelot 	const struct mv88e6xxx_bus_ops *phy_ops;
3474d5f2ba7SVivien Didelot 	struct mutex		ppu_mutex;
3484d5f2ba7SVivien Didelot 	int			ppu_disabled;
3494d5f2ba7SVivien Didelot 	struct work_struct	ppu_work;
3504d5f2ba7SVivien Didelot 	struct timer_list	ppu_timer;
3514d5f2ba7SVivien Didelot 
3524d5f2ba7SVivien Didelot 	/* This mutex serialises access to the statistics unit.
3534d5f2ba7SVivien Didelot 	 * Hold this mutex over snapshot + dump sequences.
3544d5f2ba7SVivien Didelot 	 */
3554d5f2ba7SVivien Didelot 	struct mutex	stats_mutex;
3564d5f2ba7SVivien Didelot 
3574d5f2ba7SVivien Didelot 	/* A switch may have a GPIO line tied to its reset pin. Parse
3584d5f2ba7SVivien Didelot 	 * this from the device tree, and use it before performing
3594d5f2ba7SVivien Didelot 	 * switch soft reset.
3604d5f2ba7SVivien Didelot 	 */
3614d5f2ba7SVivien Didelot 	struct gpio_desc *reset;
3624d5f2ba7SVivien Didelot 
3634d5f2ba7SVivien Didelot 	/* set to size of eeprom if supported by the switch */
36400baabe5SAndrew Lunn 	u32 eeprom_len;
3654d5f2ba7SVivien Didelot 
3664d5f2ba7SVivien Didelot 	/* List of mdio busses */
3674d5f2ba7SVivien Didelot 	struct list_head mdios;
3684d5f2ba7SVivien Didelot 
369da7dc875SVivien Didelot 	/* Policy Control List IDs and rules */
370da7dc875SVivien Didelot 	struct idr policies;
371da7dc875SVivien Didelot 
3724d5f2ba7SVivien Didelot 	/* There can be two interrupt controllers, which are chained
3734d5f2ba7SVivien Didelot 	 * off a GPIO as interrupt source
3744d5f2ba7SVivien Didelot 	 */
3754d5f2ba7SVivien Didelot 	struct mv88e6xxx_irq g1_irq;
3764d5f2ba7SVivien Didelot 	struct mv88e6xxx_irq g2_irq;
3774d5f2ba7SVivien Didelot 	int irq;
3785d1fbdf2SAndrew Lunn 	char irq_name[64];
3794d5f2ba7SVivien Didelot 	int device_irq;
3805d1fbdf2SAndrew Lunn 	char device_irq_name[64];
3814d5f2ba7SVivien Didelot 	int watchdog_irq;
3825d1fbdf2SAndrew Lunn 	char watchdog_irq_name[64];
383cda9f4aaSAndrew Lunn 
3840977644cSAndrew Lunn 	int atu_prob_irq;
3855d1fbdf2SAndrew Lunn 	char atu_prob_irq_name[64];
38662eb1162SAndrew Lunn 	int vtu_prob_irq;
3875d1fbdf2SAndrew Lunn 	char vtu_prob_irq_name[64];
388294d711eSAndrew Lunn 	struct kthread_worker *kworker;
389294d711eSAndrew Lunn 	struct kthread_delayed_work irq_poll_work;
3902fa8d3afSBrandon Streiff 
391a73ccd61SBrandon Streiff 	/* GPIO resources */
392a73ccd61SBrandon Streiff 	u8 gpio_data[2];
393a73ccd61SBrandon Streiff 
3942fa8d3afSBrandon Streiff 	/* This cyclecounter abstracts the switch PTP time.
3952fa8d3afSBrandon Streiff 	 * reg_lock must be held for any operation that read()s.
3962fa8d3afSBrandon Streiff 	 */
3972fa8d3afSBrandon Streiff 	struct cyclecounter	tstamp_cc;
3982fa8d3afSBrandon Streiff 	struct timecounter	tstamp_tc;
3992fa8d3afSBrandon Streiff 	struct delayed_work	overflow_work;
4002fa8d3afSBrandon Streiff 
4012fa8d3afSBrandon Streiff 	struct ptp_clock	*ptp_clock;
4022fa8d3afSBrandon Streiff 	struct ptp_clock_info	ptp_clock_info;
4034eb3be29SBrandon Streiff 	struct delayed_work	tai_event_work;
4044eb3be29SBrandon Streiff 	struct ptp_pin_desc	pin_config[MV88E6XXX_MAX_GPIO];
4054eb3be29SBrandon Streiff 	u16 trig_config;
4064eb3be29SBrandon Streiff 	u16 evcap_config;
407e2294a8bSAndrew Lunn 	u16 enable_count;
408c6fe0ad2SBrandon Streiff 
409f0942e00SIwan R Timmer 	/* Current ingress and egress monitor ports */
410f0942e00SIwan R Timmer 	int egress_dest_port;
411f0942e00SIwan R Timmer 	int ingress_dest_port;
412f0942e00SIwan R Timmer 
413c6fe0ad2SBrandon Streiff 	/* Per-port timestamping resources. */
414c6fe0ad2SBrandon Streiff 	struct mv88e6xxx_port_hwtstamp port_hwtstamp[DSA_MAX_PORTS];
415cda9f4aaSAndrew Lunn 
416cda9f4aaSAndrew Lunn 	/* Array of port structures. */
417cda9f4aaSAndrew Lunn 	struct mv88e6xxx_port ports[DSA_MAX_PORTS];
418bfb25542SAndrew Lunn 
419bfb25542SAndrew Lunn 	/* devlink regions */
420bfb25542SAndrew Lunn 	struct devlink_region *regions[_MV88E6XXX_REGION_MAX];
421acaf4d2eSTobias Waldekranz 
422acaf4d2eSTobias Waldekranz 	/* Bridge MST to SID mappings */
423acaf4d2eSTobias Waldekranz 	struct list_head msts;
4244d5f2ba7SVivien Didelot };
4254d5f2ba7SVivien Didelot 
4264d5f2ba7SVivien Didelot struct mv88e6xxx_bus_ops {
4274d5f2ba7SVivien Didelot 	int (*read)(struct mv88e6xxx_chip *chip, int addr, int reg, u16 *val);
4284d5f2ba7SVivien Didelot 	int (*write)(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val);
4297bca16b2STobias Waldekranz 	int (*init)(struct mv88e6xxx_chip *chip);
4304d5f2ba7SVivien Didelot };
4314d5f2ba7SVivien Didelot 
4324d5f2ba7SVivien Didelot struct mv88e6xxx_mdio_bus {
4334d5f2ba7SVivien Didelot 	struct mii_bus *bus;
4344d5f2ba7SVivien Didelot 	struct mv88e6xxx_chip *chip;
4354d5f2ba7SVivien Didelot 	struct list_head list;
4364d5f2ba7SVivien Didelot 	bool external;
4374d5f2ba7SVivien Didelot };
4384d5f2ba7SVivien Didelot 
4394d5f2ba7SVivien Didelot struct mv88e6xxx_ops {
440ea89098eSAndrew Lunn 	/* Switch Setup Errata, called early in the switch setup to
441ea89098eSAndrew Lunn 	 * allow any errata actions to be performed
442ea89098eSAndrew Lunn 	 */
443ea89098eSAndrew Lunn 	int (*setup_errata)(struct mv88e6xxx_chip *chip);
444ea89098eSAndrew Lunn 
44593e18d61SVivien Didelot 	int (*ieee_pri_map)(struct mv88e6xxx_chip *chip);
44693e18d61SVivien Didelot 	int (*ip_pri_map)(struct mv88e6xxx_chip *chip);
44793e18d61SVivien Didelot 
448cd8da8bbSVivien Didelot 	/* Ingress Rate Limit unit (IRL) operations */
449cd8da8bbSVivien Didelot 	int (*irl_init_all)(struct mv88e6xxx_chip *chip, int port);
450cd8da8bbSVivien Didelot 
4514d5f2ba7SVivien Didelot 	int (*get_eeprom)(struct mv88e6xxx_chip *chip,
4524d5f2ba7SVivien Didelot 			  struct ethtool_eeprom *eeprom, u8 *data);
4534d5f2ba7SVivien Didelot 	int (*set_eeprom)(struct mv88e6xxx_chip *chip,
4544d5f2ba7SVivien Didelot 			  struct ethtool_eeprom *eeprom, u8 *data);
4554d5f2ba7SVivien Didelot 
4564d5f2ba7SVivien Didelot 	int (*set_switch_mac)(struct mv88e6xxx_chip *chip, u8 *addr);
4574d5f2ba7SVivien Didelot 
4584d5f2ba7SVivien Didelot 	int (*phy_read)(struct mv88e6xxx_chip *chip,
4594d5f2ba7SVivien Didelot 			struct mii_bus *bus,
4604d5f2ba7SVivien Didelot 			int addr, int reg, u16 *val);
4614d5f2ba7SVivien Didelot 	int (*phy_write)(struct mv88e6xxx_chip *chip,
4624d5f2ba7SVivien Didelot 			 struct mii_bus *bus,
4634d5f2ba7SVivien Didelot 			 int addr, int reg, u16 val);
4644d5f2ba7SVivien Didelot 
465743a19e3SAndrew Lunn 	int (*phy_read_c45)(struct mv88e6xxx_chip *chip,
466743a19e3SAndrew Lunn 			    struct mii_bus *bus,
467743a19e3SAndrew Lunn 			    int addr, int devad, int reg, u16 *val);
468743a19e3SAndrew Lunn 	int (*phy_write_c45)(struct mv88e6xxx_chip *chip,
469743a19e3SAndrew Lunn 			     struct mii_bus *bus,
470743a19e3SAndrew Lunn 			     int addr, int devad, int reg, u16 val);
471743a19e3SAndrew Lunn 
4729e907d73SVivien Didelot 	/* Priority Override Table operations */
4739e907d73SVivien Didelot 	int (*pot_clear)(struct mv88e6xxx_chip *chip);
4749e907d73SVivien Didelot 
4754d5f2ba7SVivien Didelot 	/* PHY Polling Unit (PPU) operations */
4764d5f2ba7SVivien Didelot 	int (*ppu_enable)(struct mv88e6xxx_chip *chip);
4774d5f2ba7SVivien Didelot 	int (*ppu_disable)(struct mv88e6xxx_chip *chip);
4784d5f2ba7SVivien Didelot 
479d1e3dc19SMatthias Schiffer 	/* Additional handlers to run before and after hard reset, to make sure
480d1e3dc19SMatthias Schiffer 	 * that the switch and EEPROM are in a good state.
481d1e3dc19SMatthias Schiffer 	 */
482d1e3dc19SMatthias Schiffer 	int (*hardware_reset_pre)(struct mv88e6xxx_chip *chip);
483d1e3dc19SMatthias Schiffer 	int (*hardware_reset_post)(struct mv88e6xxx_chip *chip);
484d1e3dc19SMatthias Schiffer 
4854d5f2ba7SVivien Didelot 	/* Switch Software Reset */
4864d5f2ba7SVivien Didelot 	int (*reset)(struct mv88e6xxx_chip *chip);
4874d5f2ba7SVivien Didelot 
4884d5f2ba7SVivien Didelot 	/* RGMII Receive/Transmit Timing Control
4894d5f2ba7SVivien Didelot 	 * Add delay on PHY_INTERFACE_MODE_RGMII_*ID, no delay otherwise.
4904d5f2ba7SVivien Didelot 	 */
4914d5f2ba7SVivien Didelot 	int (*port_set_rgmii_delay)(struct mv88e6xxx_chip *chip, int port,
4924d5f2ba7SVivien Didelot 				    phy_interface_t mode);
4934d5f2ba7SVivien Didelot 
4944d5f2ba7SVivien Didelot #define LINK_FORCED_DOWN	0
4954d5f2ba7SVivien Didelot #define LINK_FORCED_UP		1
4964d5f2ba7SVivien Didelot #define LINK_UNFORCED		-2
4974d5f2ba7SVivien Didelot 
4984d5f2ba7SVivien Didelot 	/* Port's MAC link state
4994d5f2ba7SVivien Didelot 	 * Use LINK_FORCED_UP or LINK_FORCED_DOWN to force link up or down,
5004d5f2ba7SVivien Didelot 	 * or LINK_UNFORCED for normal link detection.
5014d5f2ba7SVivien Didelot 	 */
5024d5f2ba7SVivien Didelot 	int (*port_set_link)(struct mv88e6xxx_chip *chip, int port, int link);
5034d5f2ba7SVivien Didelot 
5044efe7662SChris Packham 	/* Synchronise the port link state with that of the SERDES
5054efe7662SChris Packham 	 */
5064efe7662SChris Packham 	int (*port_sync_link)(struct mv88e6xxx_chip *chip, int port, unsigned int mode, bool isup);
5074efe7662SChris Packham 
50854186b91SAndrew Lunn #define PAUSE_ON		1
50954186b91SAndrew Lunn #define PAUSE_OFF		0
51054186b91SAndrew Lunn 
51154186b91SAndrew Lunn 	/* Enable/disable sending Pause */
51254186b91SAndrew Lunn 	int (*port_set_pause)(struct mv88e6xxx_chip *chip, int port,
51354186b91SAndrew Lunn 			      int pause);
51454186b91SAndrew Lunn 
5154d5f2ba7SVivien Didelot #define SPEED_UNFORCED		-2
516f365c6f7SRussell King #define DUPLEX_UNFORCED		-2
5174d5f2ba7SVivien Didelot 
518f365c6f7SRussell King 	/* Port's MAC speed (in Mbps) and MAC duplex mode
5194d5f2ba7SVivien Didelot 	 *
5204d5f2ba7SVivien Didelot 	 * Depending on the chip, 10, 100, 200, 1000, 2500, 10000 are valid.
5213c783b83SRussell King 	 * Use SPEED_UNFORCED for normal detection.
522f365c6f7SRussell King 	 *
523f365c6f7SRussell King 	 * Use DUPLEX_HALF or DUPLEX_FULL to force half or full duplex,
524f365c6f7SRussell King 	 * or DUPLEX_UNFORCED for normal duplex detection.
5254d5f2ba7SVivien Didelot 	 */
526f365c6f7SRussell King 	int (*port_set_speed_duplex)(struct mv88e6xxx_chip *chip, int port,
527f365c6f7SRussell King 				     int speed, int duplex);
5284d5f2ba7SVivien Didelot 
5297cbbee05SAndrew Lunn 	/* What interface mode should be used for maximum speed? */
53018e1b742SAlexis Lothoré 	phy_interface_t (*port_max_speed_mode)(struct mv88e6xxx_chip *chip,
53118e1b742SAlexis Lothoré 					       int port);
5327cbbee05SAndrew Lunn 
5334d5f2ba7SVivien Didelot 	int (*port_tag_remap)(struct mv88e6xxx_chip *chip, int port);
5344d5f2ba7SVivien Didelot 
535f3a2cd32SVivien Didelot 	int (*port_set_policy)(struct mv88e6xxx_chip *chip, int port,
536f3a2cd32SVivien Didelot 			       enum mv88e6xxx_policy_mapping mapping,
537f3a2cd32SVivien Didelot 			       enum mv88e6xxx_policy_action action);
538f3a2cd32SVivien Didelot 
5394d5f2ba7SVivien Didelot 	int (*port_set_frame_mode)(struct mv88e6xxx_chip *chip, int port,
5404d5f2ba7SVivien Didelot 				   enum mv88e6xxx_frame_mode mode);
541a8b659e7SVladimir Oltean 	int (*port_set_ucast_flood)(struct mv88e6xxx_chip *chip, int port,
542a8b659e7SVladimir Oltean 				    bool unicast);
543a8b659e7SVladimir Oltean 	int (*port_set_mcast_flood)(struct mv88e6xxx_chip *chip, int port,
544a8b659e7SVladimir Oltean 				    bool multicast);
5454d5f2ba7SVivien Didelot 	int (*port_set_ether_type)(struct mv88e6xxx_chip *chip, int port,
5464d5f2ba7SVivien Didelot 				   u16 etype);
547cd782656SVivien Didelot 	int (*port_set_jumbo_size)(struct mv88e6xxx_chip *chip, int port,
548cd782656SVivien Didelot 				   size_t size);
5494d5f2ba7SVivien Didelot 
5504d5f2ba7SVivien Didelot 	int (*port_egress_rate_limiting)(struct mv88e6xxx_chip *chip, int port);
5510898432cSVivien Didelot 	int (*port_pause_limit)(struct mv88e6xxx_chip *chip, int port, u8 in,
5520898432cSVivien Didelot 				u8 out);
5534d5f2ba7SVivien Didelot 	int (*port_disable_learn_limit)(struct mv88e6xxx_chip *chip, int port);
5544d5f2ba7SVivien Didelot 	int (*port_disable_pri_override)(struct mv88e6xxx_chip *chip, int port);
555121b8fe2SHubert Feurstein 	int (*port_setup_message_port)(struct mv88e6xxx_chip *chip, int port);
5564d5f2ba7SVivien Didelot 
5574d5f2ba7SVivien Didelot 	/* CMODE control what PHY mode the MAC will use, eg. SGMII, RGMII, etc.
5584d5f2ba7SVivien Didelot 	 * Some chips allow this to be configured on specific ports.
5594d5f2ba7SVivien Didelot 	 */
5604d5f2ba7SVivien Didelot 	int (*port_set_cmode)(struct mv88e6xxx_chip *chip, int port,
5614d5f2ba7SVivien Didelot 			      phy_interface_t mode);
5622d2e1dd2SAndrew Lunn 	int (*port_get_cmode)(struct mv88e6xxx_chip *chip, int port, u8 *cmode);
5634d5f2ba7SVivien Didelot 
5644d5f2ba7SVivien Didelot 	/* Some devices have a per port register indicating what is
5654d5f2ba7SVivien Didelot 	 * the upstream port this port should forward to.
5664d5f2ba7SVivien Didelot 	 */
5674d5f2ba7SVivien Didelot 	int (*port_set_upstream_port)(struct mv88e6xxx_chip *chip, int port,
5684d5f2ba7SVivien Didelot 				      int upstream_port);
5694d5f2ba7SVivien Didelot 
5704d5f2ba7SVivien Didelot 	/* Snapshot the statistics for a port. The statistics can then
5714d5f2ba7SVivien Didelot 	 * be read back a leisure but still with a consistent view.
5724d5f2ba7SVivien Didelot 	 */
5734d5f2ba7SVivien Didelot 	int (*stats_snapshot)(struct mv88e6xxx_chip *chip, int port);
5744d5f2ba7SVivien Didelot 
5754d5f2ba7SVivien Didelot 	/* Set the histogram mode for statistics, when the control registers
5764d5f2ba7SVivien Didelot 	 * are separated out of the STATS_OP register.
5774d5f2ba7SVivien Didelot 	 */
5784d5f2ba7SVivien Didelot 	int (*stats_set_histogram)(struct mv88e6xxx_chip *chip);
5794d5f2ba7SVivien Didelot 
5804d5f2ba7SVivien Didelot 	/* Return the number of strings describing statistics */
5814d5f2ba7SVivien Didelot 	int (*stats_get_sset_count)(struct mv88e6xxx_chip *chip);
582436fe17dSAndrew Lunn 	int (*stats_get_strings)(struct mv88e6xxx_chip *chip,  uint8_t *data);
583436fe17dSAndrew Lunn 	int (*stats_get_stats)(struct mv88e6xxx_chip *chip,  int port,
5844d5f2ba7SVivien Didelot 			       uint64_t *data);
585fa8d1179SVivien Didelot 	int (*set_cpu_port)(struct mv88e6xxx_chip *chip, int port);
5865c74c54cSIwan R Timmer 	int (*set_egress_port)(struct mv88e6xxx_chip *chip,
5875c74c54cSIwan R Timmer 			       enum mv88e6xxx_egress_direction direction,
5885c74c54cSIwan R Timmer 			       int port);
58902317e68SVivien Didelot 
59002317e68SVivien Didelot #define MV88E6XXX_CASCADE_PORT_NONE		0xe
59102317e68SVivien Didelot #define MV88E6XXX_CASCADE_PORT_MULTIPLE		0xf
59202317e68SVivien Didelot 
59302317e68SVivien Didelot 	int (*set_cascade_port)(struct mv88e6xxx_chip *chip, int port);
59402317e68SVivien Didelot 
5954d5f2ba7SVivien Didelot 	const struct mv88e6xxx_irq_ops *watchdog_ops;
5964d5f2ba7SVivien Didelot 
5974d5f2ba7SVivien Didelot 	int (*mgmt_rsvd2cpu)(struct mv88e6xxx_chip *chip);
5984d5f2ba7SVivien Didelot 
59917deaf5cSMarek Behún 	/* SERDES lane mapping */
600193c5b26SPavana Sharma 	int (*serdes_get_lane)(struct mv88e6xxx_chip *chip, int port);
60117deaf5cSMarek Behún 
602efd1ba6aSAndrew Lunn 	/* SERDES interrupt handling */
6034241ef52SVivien Didelot 	unsigned int (*serdes_irq_mapping)(struct mv88e6xxx_chip *chip,
6044241ef52SVivien Didelot 					   int port);
605efd1ba6aSAndrew Lunn 
606436fe17dSAndrew Lunn 	/* Statistics from the SERDES interface */
607436fe17dSAndrew Lunn 	int (*serdes_get_sset_count)(struct mv88e6xxx_chip *chip, int port);
60865f60e45SAndrew Lunn 	int (*serdes_get_strings)(struct mv88e6xxx_chip *chip,  int port,
609436fe17dSAndrew Lunn 				  uint8_t *data);
610f6791424STobias Waldekranz 	size_t (*serdes_get_stats)(struct mv88e6xxx_chip *chip, int port,
611436fe17dSAndrew Lunn 				   uint64_t *data);
612436fe17dSAndrew Lunn 
6130d30bbd0SAndrew Lunn 	/* SERDES registers for ethtool */
6140d30bbd0SAndrew Lunn 	int (*serdes_get_regs_len)(struct mv88e6xxx_chip *chip,  int port);
6150d30bbd0SAndrew Lunn 	void (*serdes_get_regs)(struct mv88e6xxx_chip *chip, int port,
6160d30bbd0SAndrew Lunn 				void *_p);
6170d30bbd0SAndrew Lunn 
618926eae60SHolger Brunck 	/* SERDES SGMII/Fiber Output Amplitude */
619926eae60SHolger Brunck 	int (*serdes_set_tx_amplitude)(struct mv88e6xxx_chip *chip, int port,
620926eae60SHolger Brunck 				       int val);
621926eae60SHolger Brunck 
62223e8b470SAndrew Lunn 	/* Address Translation Unit operations */
62323e8b470SAndrew Lunn 	int (*atu_get_hash)(struct mv88e6xxx_chip *chip, u8 *hash);
62423e8b470SAndrew Lunn 	int (*atu_set_hash)(struct mv88e6xxx_chip *chip, u8 hash);
62523e8b470SAndrew Lunn 
6264d5f2ba7SVivien Didelot 	/* VLAN Translation Unit operations */
6274d5f2ba7SVivien Didelot 	int (*vtu_getnext)(struct mv88e6xxx_chip *chip,
6284d5f2ba7SVivien Didelot 			   struct mv88e6xxx_vtu_entry *entry);
6294d5f2ba7SVivien Didelot 	int (*vtu_loadpurge)(struct mv88e6xxx_chip *chip,
6304d5f2ba7SVivien Didelot 			     struct mv88e6xxx_vtu_entry *entry);
6310d632c3dSBrandon Streiff 
63249c98c1dSTobias Waldekranz 	/* Spanning Tree Unit operations */
63349c98c1dSTobias Waldekranz 	int (*stu_getnext)(struct mv88e6xxx_chip *chip,
63449c98c1dSTobias Waldekranz 			   struct mv88e6xxx_stu_entry *entry);
63549c98c1dSTobias Waldekranz 	int (*stu_loadpurge)(struct mv88e6xxx_chip *chip,
63649c98c1dSTobias Waldekranz 			     struct mv88e6xxx_stu_entry *entry);
63749c98c1dSTobias Waldekranz 
638a73ccd61SBrandon Streiff 	/* GPIO operations */
639a73ccd61SBrandon Streiff 	const struct mv88e6xxx_gpio_ops *gpio_ops;
640a73ccd61SBrandon Streiff 
6410d632c3dSBrandon Streiff 	/* Interface to the AVB/PTP registers */
6420d632c3dSBrandon Streiff 	const struct mv88e6xxx_avb_ops *avb_ops;
6439e5baf9bSVivien Didelot 
6449e5baf9bSVivien Didelot 	/* Remote Management Unit operations */
6459e5baf9bSVivien Didelot 	int (*rmu_disable)(struct mv88e6xxx_chip *chip);
6466d2ac8eeSAndrew Lunn 
6476d2ac8eeSAndrew Lunn 	/* Precision Time Protocol operations */
6486d2ac8eeSAndrew Lunn 	const struct mv88e6xxx_ptp_ops *ptp_ops;
6496c422e34SRussell King 
6506c422e34SRussell King 	/* Phylink */
651d4ebf12bSRussell King (Oracle) 	void (*phylink_get_caps)(struct mv88e6xxx_chip *chip, int port,
652d4ebf12bSRussell King (Oracle) 				 struct phylink_config *config);
6531baf0facSChris Packham 
654b92143d4SRussell King (Oracle) 	const struct mv88e6xxx_pcs_ops *pcs_ops;
655b92143d4SRussell King (Oracle) 
6561baf0facSChris Packham 	/* Max Frame Size */
6571baf0facSChris Packham 	int (*set_max_frame_size)(struct mv88e6xxx_chip *chip, int mtu);
6584d5f2ba7SVivien Didelot };
6594d5f2ba7SVivien Didelot 
6604d5f2ba7SVivien Didelot struct mv88e6xxx_irq_ops {
6614d5f2ba7SVivien Didelot 	/* Action to be performed when the interrupt happens */
6624d5f2ba7SVivien Didelot 	int (*irq_action)(struct mv88e6xxx_chip *chip, int irq);
6634d5f2ba7SVivien Didelot 	/* Setup the hardware to generate the interrupt */
6644d5f2ba7SVivien Didelot 	int (*irq_setup)(struct mv88e6xxx_chip *chip);
6654d5f2ba7SVivien Didelot 	/* Reset the hardware to stop generating the interrupt */
6664d5f2ba7SVivien Didelot 	void (*irq_free)(struct mv88e6xxx_chip *chip);
6674d5f2ba7SVivien Didelot };
6684d5f2ba7SVivien Didelot 
669a73ccd61SBrandon Streiff struct mv88e6xxx_gpio_ops {
670a73ccd61SBrandon Streiff 	/* Get/set data on GPIO pin */
671a73ccd61SBrandon Streiff 	int (*get_data)(struct mv88e6xxx_chip *chip, unsigned int pin);
672a73ccd61SBrandon Streiff 	int (*set_data)(struct mv88e6xxx_chip *chip, unsigned int pin,
673a73ccd61SBrandon Streiff 			int value);
674a73ccd61SBrandon Streiff 
675a73ccd61SBrandon Streiff 	/* get/set GPIO direction */
676a73ccd61SBrandon Streiff 	int (*get_dir)(struct mv88e6xxx_chip *chip, unsigned int pin);
677a73ccd61SBrandon Streiff 	int (*set_dir)(struct mv88e6xxx_chip *chip, unsigned int pin,
678a73ccd61SBrandon Streiff 		       bool input);
679a73ccd61SBrandon Streiff 
680a73ccd61SBrandon Streiff 	/* get/set GPIO pin control */
681a73ccd61SBrandon Streiff 	int (*get_pctl)(struct mv88e6xxx_chip *chip, unsigned int pin,
682a73ccd61SBrandon Streiff 			int *func);
683a73ccd61SBrandon Streiff 	int (*set_pctl)(struct mv88e6xxx_chip *chip, unsigned int pin,
684a73ccd61SBrandon Streiff 			int func);
685a73ccd61SBrandon Streiff };
686a73ccd61SBrandon Streiff 
6870d632c3dSBrandon Streiff struct mv88e6xxx_avb_ops {
6880d632c3dSBrandon Streiff 	/* Access port-scoped Precision Time Protocol registers */
6890d632c3dSBrandon Streiff 	int (*port_ptp_read)(struct mv88e6xxx_chip *chip, int port, int addr,
6900d632c3dSBrandon Streiff 			     u16 *data, int len);
6910d632c3dSBrandon Streiff 	int (*port_ptp_write)(struct mv88e6xxx_chip *chip, int port, int addr,
6920d632c3dSBrandon Streiff 			      u16 data);
6930d632c3dSBrandon Streiff 
6940d632c3dSBrandon Streiff 	/* Access global Precision Time Protocol registers */
6950d632c3dSBrandon Streiff 	int (*ptp_read)(struct mv88e6xxx_chip *chip, int addr, u16 *data,
6960d632c3dSBrandon Streiff 			int len);
6970d632c3dSBrandon Streiff 	int (*ptp_write)(struct mv88e6xxx_chip *chip, int addr, u16 data);
6980d632c3dSBrandon Streiff 
6990d632c3dSBrandon Streiff 	/* Access global Time Application Interface registers */
7000d632c3dSBrandon Streiff 	int (*tai_read)(struct mv88e6xxx_chip *chip, int addr, u16 *data,
7010d632c3dSBrandon Streiff 			int len);
7020d632c3dSBrandon Streiff 	int (*tai_write)(struct mv88e6xxx_chip *chip, int addr, u16 data);
7030d632c3dSBrandon Streiff };
7040d632c3dSBrandon Streiff 
7056d2ac8eeSAndrew Lunn struct mv88e6xxx_ptp_ops {
7066d2ac8eeSAndrew Lunn 	u64 (*clock_read)(const struct cyclecounter *cc);
7076d2ac8eeSAndrew Lunn 	int (*ptp_enable)(struct ptp_clock_info *ptp,
7086d2ac8eeSAndrew Lunn 			  struct ptp_clock_request *rq, int on);
7096d2ac8eeSAndrew Lunn 	int (*ptp_verify)(struct ptp_clock_info *ptp, unsigned int pin,
7106d2ac8eeSAndrew Lunn 			  enum ptp_pin_function func, unsigned int chan);
7116d2ac8eeSAndrew Lunn 	void (*event_work)(struct work_struct *ugly);
712ffc705deSAndrew Lunn 	int (*port_enable)(struct mv88e6xxx_chip *chip, int port);
713ffc705deSAndrew Lunn 	int (*port_disable)(struct mv88e6xxx_chip *chip, int port);
714e2294a8bSAndrew Lunn 	int (*global_enable)(struct mv88e6xxx_chip *chip);
715e2294a8bSAndrew Lunn 	int (*global_disable)(struct mv88e6xxx_chip *chip);
7169627c981SKurt Kanzenbach 	int (*set_ptp_cpu_port)(struct mv88e6xxx_chip *chip, int port);
7176d2ac8eeSAndrew Lunn 	int n_ext_ts;
718ffc705deSAndrew Lunn 	int arr0_sts_reg;
719ffc705deSAndrew Lunn 	int arr1_sts_reg;
720ffc705deSAndrew Lunn 	int dep_sts_reg;
72148cb5e03SAndrew Lunn 	u32 rx_filters;
72271509614SHubert Feurstein 	u32 cc_shift;
72371509614SHubert Feurstein 	u32 cc_mult;
72471509614SHubert Feurstein 	u32 cc_mult_num;
72571509614SHubert Feurstein 	u32 cc_mult_dem;
7266d2ac8eeSAndrew Lunn };
7276d2ac8eeSAndrew Lunn 
728b92143d4SRussell King (Oracle) struct mv88e6xxx_pcs_ops {
729b92143d4SRussell King (Oracle) 	int (*pcs_init)(struct mv88e6xxx_chip *chip, int port);
730b92143d4SRussell King (Oracle) 	void (*pcs_teardown)(struct mv88e6xxx_chip *chip, int port);
731b92143d4SRussell King (Oracle) 	struct phylink_pcs *(*pcs_select)(struct mv88e6xxx_chip *chip, int port,
732b92143d4SRussell King (Oracle) 					  phy_interface_t mode);
733b92143d4SRussell King (Oracle) 
734b92143d4SRussell King (Oracle) };
735b92143d4SRussell King (Oracle) 
7364d5f2ba7SVivien Didelot #define STATS_TYPE_PORT		BIT(0)
7374d5f2ba7SVivien Didelot #define STATS_TYPE_BANK0	BIT(1)
7384d5f2ba7SVivien Didelot #define STATS_TYPE_BANK1	BIT(2)
7394d5f2ba7SVivien Didelot 
7404d5f2ba7SVivien Didelot struct mv88e6xxx_hw_stat {
7414d5f2ba7SVivien Didelot 	char string[ETH_GSTRING_LEN];
742cda9f4aaSAndrew Lunn 	size_t size;
7434d5f2ba7SVivien Didelot 	int reg;
7444d5f2ba7SVivien Didelot 	int type;
7454d5f2ba7SVivien Didelot };
7464d5f2ba7SVivien Didelot 
mv88e6xxx_has_stu(struct mv88e6xxx_chip * chip)74749c98c1dSTobias Waldekranz static inline bool mv88e6xxx_has_stu(struct mv88e6xxx_chip *chip)
74849c98c1dSTobias Waldekranz {
749afaed2b1STobias Waldekranz 	return chip->info->max_sid > 0 &&
750afaed2b1STobias Waldekranz 		chip->info->ops->stu_loadpurge &&
751afaed2b1STobias Waldekranz 		chip->info->ops->stu_getnext;
75249c98c1dSTobias Waldekranz }
75349c98c1dSTobias Waldekranz 
mv88e6xxx_has_pvt(struct mv88e6xxx_chip * chip)7544d5f2ba7SVivien Didelot static inline bool mv88e6xxx_has_pvt(struct mv88e6xxx_chip *chip)
7554d5f2ba7SVivien Didelot {
7564d5f2ba7SVivien Didelot 	return chip->info->pvt;
7574d5f2ba7SVivien Didelot }
7584d5f2ba7SVivien Didelot 
mv88e6xxx_has_lag(struct mv88e6xxx_chip * chip)759b80dc51bSTobias Waldekranz static inline bool mv88e6xxx_has_lag(struct mv88e6xxx_chip *chip)
760b80dc51bSTobias Waldekranz {
761b80dc51bSTobias Waldekranz 	return !!chip->info->global2_addr;
762b80dc51bSTobias Waldekranz }
763b80dc51bSTobias Waldekranz 
mv88e6xxx_num_databases(struct mv88e6xxx_chip * chip)7644d5f2ba7SVivien Didelot static inline unsigned int mv88e6xxx_num_databases(struct mv88e6xxx_chip *chip)
7654d5f2ba7SVivien Didelot {
7664d5f2ba7SVivien Didelot 	return chip->info->num_databases;
7674d5f2ba7SVivien Didelot }
7684d5f2ba7SVivien Didelot 
mv88e6xxx_num_macs(struct mv88e6xxx_chip * chip)769d9ea5620SAndrew Lunn static inline unsigned int mv88e6xxx_num_macs(struct  mv88e6xxx_chip *chip)
770d9ea5620SAndrew Lunn {
771d9ea5620SAndrew Lunn 	return chip->info->num_macs;
772d9ea5620SAndrew Lunn }
773d9ea5620SAndrew Lunn 
mv88e6xxx_num_ports(struct mv88e6xxx_chip * chip)7744d5f2ba7SVivien Didelot static inline unsigned int mv88e6xxx_num_ports(struct mv88e6xxx_chip *chip)
7754d5f2ba7SVivien Didelot {
7764d5f2ba7SVivien Didelot 	return chip->info->num_ports;
7774d5f2ba7SVivien Didelot }
7784d5f2ba7SVivien Didelot 
mv88e6xxx_max_vid(struct mv88e6xxx_chip * chip)779e545f865STobias Waldekranz static inline unsigned int mv88e6xxx_max_vid(struct mv88e6xxx_chip *chip)
780e545f865STobias Waldekranz {
781e545f865STobias Waldekranz 	return chip->info->max_vid;
782e545f865STobias Waldekranz }
783e545f865STobias Waldekranz 
mv88e6xxx_max_sid(struct mv88e6xxx_chip * chip)78449c98c1dSTobias Waldekranz static inline unsigned int mv88e6xxx_max_sid(struct mv88e6xxx_chip *chip)
78549c98c1dSTobias Waldekranz {
78649c98c1dSTobias Waldekranz 	return chip->info->max_sid;
78749c98c1dSTobias Waldekranz }
78849c98c1dSTobias Waldekranz 
mv88e6xxx_port_mask(struct mv88e6xxx_chip * chip)7894d5f2ba7SVivien Didelot static inline u16 mv88e6xxx_port_mask(struct mv88e6xxx_chip *chip)
7904d5f2ba7SVivien Didelot {
791f1931164SAndrew Lunn 	return GENMASK((s32)mv88e6xxx_num_ports(chip) - 1, 0);
7924d5f2ba7SVivien Didelot }
7934d5f2ba7SVivien Didelot 
mv88e6xxx_num_gpio(struct mv88e6xxx_chip * chip)794a73ccd61SBrandon Streiff static inline unsigned int mv88e6xxx_num_gpio(struct mv88e6xxx_chip *chip)
795a73ccd61SBrandon Streiff {
796a73ccd61SBrandon Streiff 	return chip->info->num_gpio;
797a73ccd61SBrandon Streiff }
798a73ccd61SBrandon Streiff 
mv88e6xxx_is_invalid_port(struct mv88e6xxx_chip * chip,int port)799c857486aSHubert Feurstein static inline bool mv88e6xxx_is_invalid_port(struct mv88e6xxx_chip *chip, int port)
800c857486aSHubert Feurstein {
801c857486aSHubert Feurstein 	return (chip->info->invalid_port_mask & BIT(port)) != 0;
802c857486aSHubert Feurstein }
803c857486aSHubert Feurstein 
mv88e6xxx_port_set_mab(struct mv88e6xxx_chip * chip,int port,bool mab)804830763b9SHans J. Schultz static inline void mv88e6xxx_port_set_mab(struct mv88e6xxx_chip *chip,
805830763b9SHans J. Schultz 					  int port, bool mab)
806830763b9SHans J. Schultz {
807830763b9SHans J. Schultz 	chip->ports[port].mab = mab;
808830763b9SHans J. Schultz }
809830763b9SHans J. Schultz 
8104d5f2ba7SVivien Didelot int mv88e6xxx_read(struct mv88e6xxx_chip *chip, int addr, int reg, u16 *val);
8114d5f2ba7SVivien Didelot int mv88e6xxx_write(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val);
812683f2244SVivien Didelot int mv88e6xxx_wait_mask(struct mv88e6xxx_chip *chip, int addr, int reg,
813683f2244SVivien Didelot 			u16 mask, u16 val);
81419fb7f69SVivien Didelot int mv88e6xxx_wait_bit(struct mv88e6xxx_chip *chip, int addr, int reg,
81519fb7f69SVivien Didelot 		       int bit, int val);
8164d5f2ba7SVivien Didelot struct mii_bus *mv88e6xxx_default_mdio_bus(struct mv88e6xxx_chip *chip);
8174d5f2ba7SVivien Didelot 
mv88e6xxx_reg_lock(struct mv88e6xxx_chip * chip)818c9acece0SRasmus Villemoes static inline void mv88e6xxx_reg_lock(struct mv88e6xxx_chip *chip)
819c9acece0SRasmus Villemoes {
820c9acece0SRasmus Villemoes 	mutex_lock(&chip->reg_lock);
821c9acece0SRasmus Villemoes }
822c9acece0SRasmus Villemoes 
mv88e6xxx_reg_unlock(struct mv88e6xxx_chip * chip)823c9acece0SRasmus Villemoes static inline void mv88e6xxx_reg_unlock(struct mv88e6xxx_chip *chip)
824c9acece0SRasmus Villemoes {
825c9acece0SRasmus Villemoes 	mutex_unlock(&chip->reg_lock);
826c9acece0SRasmus Villemoes }
827c9acece0SRasmus Villemoes 
828830763b9SHans J. Schultz int mv88e6xxx_vtu_walk(struct mv88e6xxx_chip *chip,
829830763b9SHans J. Schultz 		       int (*cb)(struct mv88e6xxx_chip *chip,
830830763b9SHans J. Schultz 				 const struct mv88e6xxx_vtu_entry *entry,
831830763b9SHans J. Schultz 				 void *priv),
832830763b9SHans J. Schultz 		       void *priv);
833830763b9SHans J. Schultz 
83490b6dbdfSAndrew Lunn int mv88e6xxx_fid_map(struct mv88e6xxx_chip *chip, unsigned long *bitmap);
83590b6dbdfSAndrew Lunn 
8364d5f2ba7SVivien Didelot #endif /* _MV88E6XXX_CHIP_H */
837