xref: /openbmc/linux/drivers/net/dsa/mv88e6xxx/chip.h (revision e50e86dbcabda570fc8a1435fe2fca97e9ab7312)
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;
2094dc655d8SShenghao Yang struct mv88e6xxx_cc_coeffs;
2104d5f2ba7SVivien Didelot 
2114d5f2ba7SVivien Didelot struct mv88e6xxx_irq {
2124d5f2ba7SVivien Didelot 	u16 masked;
2134d5f2ba7SVivien Didelot 	struct irq_chip chip;
2144d5f2ba7SVivien Didelot 	struct irq_domain *domain;
215f1931164SAndrew Lunn 	int nirqs;
2164d5f2ba7SVivien Didelot };
2174d5f2ba7SVivien Didelot 
218c6fe0ad2SBrandon Streiff /* state flags for mv88e6xxx_port_hwtstamp::state */
219c6fe0ad2SBrandon Streiff enum {
220c6fe0ad2SBrandon Streiff 	MV88E6XXX_HWTSTAMP_ENABLED,
221c6fe0ad2SBrandon Streiff 	MV88E6XXX_HWTSTAMP_TX_IN_PROGRESS,
222c6fe0ad2SBrandon Streiff };
223c6fe0ad2SBrandon Streiff 
224c6fe0ad2SBrandon Streiff struct mv88e6xxx_port_hwtstamp {
225c6fe0ad2SBrandon Streiff 	/* Port index */
226c6fe0ad2SBrandon Streiff 	int port_id;
227c6fe0ad2SBrandon Streiff 
228c6fe0ad2SBrandon Streiff 	/* Timestamping state */
229c6fe0ad2SBrandon Streiff 	unsigned long state;
230c6fe0ad2SBrandon Streiff 
231c6fe0ad2SBrandon Streiff 	/* Resources for receive timestamping */
232c6fe0ad2SBrandon Streiff 	struct sk_buff_head rx_queue;
233c6fe0ad2SBrandon Streiff 	struct sk_buff_head rx_queue2;
234c6fe0ad2SBrandon Streiff 
235c6fe0ad2SBrandon Streiff 	/* Resources for transmit timestamping */
236c6fe0ad2SBrandon Streiff 	unsigned long tx_tstamp_start;
237c6fe0ad2SBrandon Streiff 	struct sk_buff *tx_skb;
238c6fe0ad2SBrandon Streiff 	u16 tx_seq_id;
239c6fe0ad2SBrandon Streiff 
240c6fe0ad2SBrandon Streiff 	/* Current timestamp configuration */
241c6fe0ad2SBrandon Streiff 	struct hwtstamp_config tstamp_config;
242c6fe0ad2SBrandon Streiff };
243c6fe0ad2SBrandon Streiff 
244f3a2cd32SVivien Didelot enum mv88e6xxx_policy_mapping {
245f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_MAPPING_DA,
246f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_MAPPING_SA,
247f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_MAPPING_VTU,
248f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_MAPPING_ETYPE,
249f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_MAPPING_PPPOE,
250f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_MAPPING_VBAS,
251f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_MAPPING_OPT82,
252f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_MAPPING_UDP,
253f3a2cd32SVivien Didelot };
254f3a2cd32SVivien Didelot 
255f3a2cd32SVivien Didelot enum mv88e6xxx_policy_action {
256f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_ACTION_NORMAL,
257f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_ACTION_MIRROR,
258f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_ACTION_TRAP,
259f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_ACTION_DISCARD,
260f3a2cd32SVivien Didelot };
261f3a2cd32SVivien Didelot 
262da7dc875SVivien Didelot struct mv88e6xxx_policy {
263da7dc875SVivien Didelot 	enum mv88e6xxx_policy_mapping mapping;
264da7dc875SVivien Didelot 	enum mv88e6xxx_policy_action action;
265da7dc875SVivien Didelot 	struct ethtool_rx_flow_spec fs;
266da7dc875SVivien Didelot 	u8 addr[ETH_ALEN];
267da7dc875SVivien Didelot 	int port;
268da7dc875SVivien Didelot 	u16 vid;
269da7dc875SVivien Didelot };
270da7dc875SVivien Didelot 
2718b6836d8SVladimir Oltean struct mv88e6xxx_vlan {
2728b6836d8SVladimir Oltean 	u16	vid;
2738b6836d8SVladimir Oltean 	bool	valid;
2748b6836d8SVladimir Oltean };
2758b6836d8SVladimir Oltean 
276cda9f4aaSAndrew Lunn struct mv88e6xxx_port {
2777b898469SAndrew Lunn 	struct mv88e6xxx_chip *chip;
2787b898469SAndrew Lunn 	int port;
2798b6836d8SVladimir Oltean 	struct mv88e6xxx_vlan bridge_pvid;
280cda9f4aaSAndrew Lunn 	u64 serdes_stats[2];
28165f60e45SAndrew Lunn 	u64 atu_member_violation;
28265f60e45SAndrew Lunn 	u64 atu_miss_violation;
28365f60e45SAndrew Lunn 	u64 atu_full_violation;
28465f60e45SAndrew Lunn 	u64 vtu_member_violation;
28565f60e45SAndrew Lunn 	u64 vtu_miss_violation;
286fad58190SRussell King 	phy_interface_t interface;
2872d2e1dd2SAndrew Lunn 	u8 cmode;
288f0942e00SIwan R Timmer 	bool mirror_ingress;
289f0942e00SIwan R Timmer 	bool mirror_egress;
290bfb25542SAndrew Lunn 	struct devlink_region *region;
291b92143d4SRussell King (Oracle) 	void *pcs_private;
292830763b9SHans J. Schultz 
293830763b9SHans J. Schultz 	/* MacAuth Bypass control flag */
294830763b9SHans J. Schultz 	bool mab;
295bfb25542SAndrew Lunn };
296bfb25542SAndrew Lunn 
297bfb25542SAndrew Lunn enum mv88e6xxx_region_id {
298bfb25542SAndrew Lunn 	MV88E6XXX_REGION_GLOBAL1 = 0,
299bfb25542SAndrew Lunn 	MV88E6XXX_REGION_GLOBAL2,
300bfb25542SAndrew Lunn 	MV88E6XXX_REGION_ATU,
301ca4d632aSTobias Waldekranz 	MV88E6XXX_REGION_VTU,
3027dc96039STobias Waldekranz 	MV88E6XXX_REGION_STU,
303836021a2STobias Waldekranz 	MV88E6XXX_REGION_PVT,
304bfb25542SAndrew Lunn 
305bfb25542SAndrew Lunn 	_MV88E6XXX_REGION_MAX,
306bfb25542SAndrew Lunn };
307bfb25542SAndrew Lunn 
308bfb25542SAndrew Lunn struct mv88e6xxx_region_priv {
309bfb25542SAndrew Lunn 	enum mv88e6xxx_region_id id;
310cda9f4aaSAndrew Lunn };
311cda9f4aaSAndrew Lunn 
312acaf4d2eSTobias Waldekranz struct mv88e6xxx_mst {
313acaf4d2eSTobias Waldekranz 	struct list_head node;
314acaf4d2eSTobias Waldekranz 
315acaf4d2eSTobias Waldekranz 	refcount_t refcnt;
316acaf4d2eSTobias Waldekranz 	struct net_device *br;
317acaf4d2eSTobias Waldekranz 	u16 msti;
318acaf4d2eSTobias Waldekranz 
319acaf4d2eSTobias Waldekranz 	struct mv88e6xxx_stu_entry stu;
320acaf4d2eSTobias Waldekranz };
321acaf4d2eSTobias Waldekranz 
3224d5f2ba7SVivien Didelot struct mv88e6xxx_chip {
3234d5f2ba7SVivien Didelot 	const struct mv88e6xxx_info *info;
3244d5f2ba7SVivien Didelot 
325670bb80fSTobias Waldekranz 	/* Currently configured tagging protocol */
326670bb80fSTobias Waldekranz 	enum dsa_tag_protocol tag_protocol;
327670bb80fSTobias Waldekranz 
3284d5f2ba7SVivien Didelot 	/* The dsa_switch this private structure is related to */
3294d5f2ba7SVivien Didelot 	struct dsa_switch *ds;
3304d5f2ba7SVivien Didelot 
3314d5f2ba7SVivien Didelot 	/* The device this structure is associated to */
3324d5f2ba7SVivien Didelot 	struct device *dev;
3334d5f2ba7SVivien Didelot 
3344d5f2ba7SVivien Didelot 	/* This mutex protects the access to the switch registers */
3354d5f2ba7SVivien Didelot 	struct mutex reg_lock;
3364d5f2ba7SVivien Didelot 
3374d5f2ba7SVivien Didelot 	/* The MII bus and the address on the bus that is used to
3384d5f2ba7SVivien Didelot 	 * communication with the switch
3394d5f2ba7SVivien Didelot 	 */
3404d5f2ba7SVivien Didelot 	const struct mv88e6xxx_bus_ops *smi_ops;
3414d5f2ba7SVivien Didelot 	struct mii_bus *bus;
3424d5f2ba7SVivien Didelot 	int sw_addr;
3434d5f2ba7SVivien Didelot 
3444d5f2ba7SVivien Didelot 	/* Handles automatic disabling and re-enabling of the PHY
3454d5f2ba7SVivien Didelot 	 * polling unit.
3464d5f2ba7SVivien Didelot 	 */
3474d5f2ba7SVivien Didelot 	const struct mv88e6xxx_bus_ops *phy_ops;
3484d5f2ba7SVivien Didelot 	struct mutex		ppu_mutex;
3494d5f2ba7SVivien Didelot 	int			ppu_disabled;
3504d5f2ba7SVivien Didelot 	struct work_struct	ppu_work;
3514d5f2ba7SVivien Didelot 	struct timer_list	ppu_timer;
3524d5f2ba7SVivien Didelot 
3534d5f2ba7SVivien Didelot 	/* This mutex serialises access to the statistics unit.
3544d5f2ba7SVivien Didelot 	 * Hold this mutex over snapshot + dump sequences.
3554d5f2ba7SVivien Didelot 	 */
3564d5f2ba7SVivien Didelot 	struct mutex	stats_mutex;
3574d5f2ba7SVivien Didelot 
3584d5f2ba7SVivien Didelot 	/* A switch may have a GPIO line tied to its reset pin. Parse
3594d5f2ba7SVivien Didelot 	 * this from the device tree, and use it before performing
3604d5f2ba7SVivien Didelot 	 * switch soft reset.
3614d5f2ba7SVivien Didelot 	 */
3624d5f2ba7SVivien Didelot 	struct gpio_desc *reset;
3634d5f2ba7SVivien Didelot 
3644d5f2ba7SVivien Didelot 	/* set to size of eeprom if supported by the switch */
36500baabe5SAndrew Lunn 	u32 eeprom_len;
3664d5f2ba7SVivien Didelot 
3674d5f2ba7SVivien Didelot 	/* List of mdio busses */
3684d5f2ba7SVivien Didelot 	struct list_head mdios;
3694d5f2ba7SVivien Didelot 
370da7dc875SVivien Didelot 	/* Policy Control List IDs and rules */
371da7dc875SVivien Didelot 	struct idr policies;
372da7dc875SVivien Didelot 
3734d5f2ba7SVivien Didelot 	/* There can be two interrupt controllers, which are chained
3744d5f2ba7SVivien Didelot 	 * off a GPIO as interrupt source
3754d5f2ba7SVivien Didelot 	 */
3764d5f2ba7SVivien Didelot 	struct mv88e6xxx_irq g1_irq;
3774d5f2ba7SVivien Didelot 	struct mv88e6xxx_irq g2_irq;
3784d5f2ba7SVivien Didelot 	int irq;
3795d1fbdf2SAndrew Lunn 	char irq_name[64];
3804d5f2ba7SVivien Didelot 	int device_irq;
3815d1fbdf2SAndrew Lunn 	char device_irq_name[64];
3824d5f2ba7SVivien Didelot 	int watchdog_irq;
3835d1fbdf2SAndrew Lunn 	char watchdog_irq_name[64];
384cda9f4aaSAndrew Lunn 
3850977644cSAndrew Lunn 	int atu_prob_irq;
3865d1fbdf2SAndrew Lunn 	char atu_prob_irq_name[64];
38762eb1162SAndrew Lunn 	int vtu_prob_irq;
3885d1fbdf2SAndrew Lunn 	char vtu_prob_irq_name[64];
389294d711eSAndrew Lunn 	struct kthread_worker *kworker;
390294d711eSAndrew Lunn 	struct kthread_delayed_work irq_poll_work;
3912fa8d3afSBrandon Streiff 
392a73ccd61SBrandon Streiff 	/* GPIO resources */
393a73ccd61SBrandon Streiff 	u8 gpio_data[2];
394a73ccd61SBrandon Streiff 
3952fa8d3afSBrandon Streiff 	/* This cyclecounter abstracts the switch PTP time.
3962fa8d3afSBrandon Streiff 	 * reg_lock must be held for any operation that read()s.
3972fa8d3afSBrandon Streiff 	 */
3982fa8d3afSBrandon Streiff 	struct cyclecounter	tstamp_cc;
3992fa8d3afSBrandon Streiff 	struct timecounter	tstamp_tc;
4002fa8d3afSBrandon Streiff 	struct delayed_work	overflow_work;
401*06b1c809SShenghao Yang 	const struct mv88e6xxx_cc_coeffs *cc_coeffs;
4022fa8d3afSBrandon Streiff 
4032fa8d3afSBrandon Streiff 	struct ptp_clock	*ptp_clock;
4042fa8d3afSBrandon Streiff 	struct ptp_clock_info	ptp_clock_info;
4054eb3be29SBrandon Streiff 	struct delayed_work	tai_event_work;
4064eb3be29SBrandon Streiff 	struct ptp_pin_desc	pin_config[MV88E6XXX_MAX_GPIO];
4074eb3be29SBrandon Streiff 	u16 trig_config;
4084eb3be29SBrandon Streiff 	u16 evcap_config;
409e2294a8bSAndrew Lunn 	u16 enable_count;
410c6fe0ad2SBrandon Streiff 
411f0942e00SIwan R Timmer 	/* Current ingress and egress monitor ports */
412f0942e00SIwan R Timmer 	int egress_dest_port;
413f0942e00SIwan R Timmer 	int ingress_dest_port;
414f0942e00SIwan R Timmer 
415c6fe0ad2SBrandon Streiff 	/* Per-port timestamping resources. */
416c6fe0ad2SBrandon Streiff 	struct mv88e6xxx_port_hwtstamp port_hwtstamp[DSA_MAX_PORTS];
417cda9f4aaSAndrew Lunn 
418cda9f4aaSAndrew Lunn 	/* Array of port structures. */
419cda9f4aaSAndrew Lunn 	struct mv88e6xxx_port ports[DSA_MAX_PORTS];
420bfb25542SAndrew Lunn 
421bfb25542SAndrew Lunn 	/* devlink regions */
422bfb25542SAndrew Lunn 	struct devlink_region *regions[_MV88E6XXX_REGION_MAX];
423acaf4d2eSTobias Waldekranz 
424acaf4d2eSTobias Waldekranz 	/* Bridge MST to SID mappings */
425acaf4d2eSTobias Waldekranz 	struct list_head msts;
4264d5f2ba7SVivien Didelot };
4274d5f2ba7SVivien Didelot 
4284d5f2ba7SVivien Didelot struct mv88e6xxx_bus_ops {
4294d5f2ba7SVivien Didelot 	int (*read)(struct mv88e6xxx_chip *chip, int addr, int reg, u16 *val);
4304d5f2ba7SVivien Didelot 	int (*write)(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val);
4317bca16b2STobias Waldekranz 	int (*init)(struct mv88e6xxx_chip *chip);
4324d5f2ba7SVivien Didelot };
4334d5f2ba7SVivien Didelot 
4344d5f2ba7SVivien Didelot struct mv88e6xxx_mdio_bus {
4354d5f2ba7SVivien Didelot 	struct mii_bus *bus;
4364d5f2ba7SVivien Didelot 	struct mv88e6xxx_chip *chip;
4374d5f2ba7SVivien Didelot 	struct list_head list;
4384d5f2ba7SVivien Didelot 	bool external;
4394d5f2ba7SVivien Didelot };
4404d5f2ba7SVivien Didelot 
4414d5f2ba7SVivien Didelot struct mv88e6xxx_ops {
442ea89098eSAndrew Lunn 	/* Switch Setup Errata, called early in the switch setup to
443ea89098eSAndrew Lunn 	 * allow any errata actions to be performed
444ea89098eSAndrew Lunn 	 */
445ea89098eSAndrew Lunn 	int (*setup_errata)(struct mv88e6xxx_chip *chip);
446ea89098eSAndrew Lunn 
44793e18d61SVivien Didelot 	int (*ieee_pri_map)(struct mv88e6xxx_chip *chip);
44893e18d61SVivien Didelot 	int (*ip_pri_map)(struct mv88e6xxx_chip *chip);
44993e18d61SVivien Didelot 
450cd8da8bbSVivien Didelot 	/* Ingress Rate Limit unit (IRL) operations */
451cd8da8bbSVivien Didelot 	int (*irl_init_all)(struct mv88e6xxx_chip *chip, int port);
452cd8da8bbSVivien Didelot 
4534d5f2ba7SVivien Didelot 	int (*get_eeprom)(struct mv88e6xxx_chip *chip,
4544d5f2ba7SVivien Didelot 			  struct ethtool_eeprom *eeprom, u8 *data);
4554d5f2ba7SVivien Didelot 	int (*set_eeprom)(struct mv88e6xxx_chip *chip,
4564d5f2ba7SVivien Didelot 			  struct ethtool_eeprom *eeprom, u8 *data);
4574d5f2ba7SVivien Didelot 
4584d5f2ba7SVivien Didelot 	int (*set_switch_mac)(struct mv88e6xxx_chip *chip, u8 *addr);
4594d5f2ba7SVivien Didelot 
4604d5f2ba7SVivien Didelot 	int (*phy_read)(struct mv88e6xxx_chip *chip,
4614d5f2ba7SVivien Didelot 			struct mii_bus *bus,
4624d5f2ba7SVivien Didelot 			int addr, int reg, u16 *val);
4634d5f2ba7SVivien Didelot 	int (*phy_write)(struct mv88e6xxx_chip *chip,
4644d5f2ba7SVivien Didelot 			 struct mii_bus *bus,
4654d5f2ba7SVivien Didelot 			 int addr, int reg, u16 val);
4664d5f2ba7SVivien Didelot 
467743a19e3SAndrew Lunn 	int (*phy_read_c45)(struct mv88e6xxx_chip *chip,
468743a19e3SAndrew Lunn 			    struct mii_bus *bus,
469743a19e3SAndrew Lunn 			    int addr, int devad, int reg, u16 *val);
470743a19e3SAndrew Lunn 	int (*phy_write_c45)(struct mv88e6xxx_chip *chip,
471743a19e3SAndrew Lunn 			     struct mii_bus *bus,
472743a19e3SAndrew Lunn 			     int addr, int devad, int reg, u16 val);
473743a19e3SAndrew Lunn 
4749e907d73SVivien Didelot 	/* Priority Override Table operations */
4759e907d73SVivien Didelot 	int (*pot_clear)(struct mv88e6xxx_chip *chip);
4769e907d73SVivien Didelot 
4774d5f2ba7SVivien Didelot 	/* PHY Polling Unit (PPU) operations */
4784d5f2ba7SVivien Didelot 	int (*ppu_enable)(struct mv88e6xxx_chip *chip);
4794d5f2ba7SVivien Didelot 	int (*ppu_disable)(struct mv88e6xxx_chip *chip);
4804d5f2ba7SVivien Didelot 
481d1e3dc19SMatthias Schiffer 	/* Additional handlers to run before and after hard reset, to make sure
482d1e3dc19SMatthias Schiffer 	 * that the switch and EEPROM are in a good state.
483d1e3dc19SMatthias Schiffer 	 */
484d1e3dc19SMatthias Schiffer 	int (*hardware_reset_pre)(struct mv88e6xxx_chip *chip);
485d1e3dc19SMatthias Schiffer 	int (*hardware_reset_post)(struct mv88e6xxx_chip *chip);
486d1e3dc19SMatthias Schiffer 
4874d5f2ba7SVivien Didelot 	/* Switch Software Reset */
4884d5f2ba7SVivien Didelot 	int (*reset)(struct mv88e6xxx_chip *chip);
4894d5f2ba7SVivien Didelot 
4904d5f2ba7SVivien Didelot 	/* RGMII Receive/Transmit Timing Control
4914d5f2ba7SVivien Didelot 	 * Add delay on PHY_INTERFACE_MODE_RGMII_*ID, no delay otherwise.
4924d5f2ba7SVivien Didelot 	 */
4934d5f2ba7SVivien Didelot 	int (*port_set_rgmii_delay)(struct mv88e6xxx_chip *chip, int port,
4944d5f2ba7SVivien Didelot 				    phy_interface_t mode);
4954d5f2ba7SVivien Didelot 
4964d5f2ba7SVivien Didelot #define LINK_FORCED_DOWN	0
4974d5f2ba7SVivien Didelot #define LINK_FORCED_UP		1
4984d5f2ba7SVivien Didelot #define LINK_UNFORCED		-2
4994d5f2ba7SVivien Didelot 
5004d5f2ba7SVivien Didelot 	/* Port's MAC link state
5014d5f2ba7SVivien Didelot 	 * Use LINK_FORCED_UP or LINK_FORCED_DOWN to force link up or down,
5024d5f2ba7SVivien Didelot 	 * or LINK_UNFORCED for normal link detection.
5034d5f2ba7SVivien Didelot 	 */
5044d5f2ba7SVivien Didelot 	int (*port_set_link)(struct mv88e6xxx_chip *chip, int port, int link);
5054d5f2ba7SVivien Didelot 
5064efe7662SChris Packham 	/* Synchronise the port link state with that of the SERDES
5074efe7662SChris Packham 	 */
5084efe7662SChris Packham 	int (*port_sync_link)(struct mv88e6xxx_chip *chip, int port, unsigned int mode, bool isup);
5094efe7662SChris Packham 
51054186b91SAndrew Lunn #define PAUSE_ON		1
51154186b91SAndrew Lunn #define PAUSE_OFF		0
51254186b91SAndrew Lunn 
51354186b91SAndrew Lunn 	/* Enable/disable sending Pause */
51454186b91SAndrew Lunn 	int (*port_set_pause)(struct mv88e6xxx_chip *chip, int port,
51554186b91SAndrew Lunn 			      int pause);
51654186b91SAndrew Lunn 
5174d5f2ba7SVivien Didelot #define SPEED_UNFORCED		-2
518f365c6f7SRussell King #define DUPLEX_UNFORCED		-2
5194d5f2ba7SVivien Didelot 
520f365c6f7SRussell King 	/* Port's MAC speed (in Mbps) and MAC duplex mode
5214d5f2ba7SVivien Didelot 	 *
5224d5f2ba7SVivien Didelot 	 * Depending on the chip, 10, 100, 200, 1000, 2500, 10000 are valid.
5233c783b83SRussell King 	 * Use SPEED_UNFORCED for normal detection.
524f365c6f7SRussell King 	 *
525f365c6f7SRussell King 	 * Use DUPLEX_HALF or DUPLEX_FULL to force half or full duplex,
526f365c6f7SRussell King 	 * or DUPLEX_UNFORCED for normal duplex detection.
5274d5f2ba7SVivien Didelot 	 */
528f365c6f7SRussell King 	int (*port_set_speed_duplex)(struct mv88e6xxx_chip *chip, int port,
529f365c6f7SRussell King 				     int speed, int duplex);
5304d5f2ba7SVivien Didelot 
5317cbbee05SAndrew Lunn 	/* What interface mode should be used for maximum speed? */
53218e1b742SAlexis Lothoré 	phy_interface_t (*port_max_speed_mode)(struct mv88e6xxx_chip *chip,
53318e1b742SAlexis Lothoré 					       int port);
5347cbbee05SAndrew Lunn 
5354d5f2ba7SVivien Didelot 	int (*port_tag_remap)(struct mv88e6xxx_chip *chip, int port);
5364d5f2ba7SVivien Didelot 
537f3a2cd32SVivien Didelot 	int (*port_set_policy)(struct mv88e6xxx_chip *chip, int port,
538f3a2cd32SVivien Didelot 			       enum mv88e6xxx_policy_mapping mapping,
539f3a2cd32SVivien Didelot 			       enum mv88e6xxx_policy_action action);
540f3a2cd32SVivien Didelot 
5414d5f2ba7SVivien Didelot 	int (*port_set_frame_mode)(struct mv88e6xxx_chip *chip, int port,
5424d5f2ba7SVivien Didelot 				   enum mv88e6xxx_frame_mode mode);
543a8b659e7SVladimir Oltean 	int (*port_set_ucast_flood)(struct mv88e6xxx_chip *chip, int port,
544a8b659e7SVladimir Oltean 				    bool unicast);
545a8b659e7SVladimir Oltean 	int (*port_set_mcast_flood)(struct mv88e6xxx_chip *chip, int port,
546a8b659e7SVladimir Oltean 				    bool multicast);
5474d5f2ba7SVivien Didelot 	int (*port_set_ether_type)(struct mv88e6xxx_chip *chip, int port,
5484d5f2ba7SVivien Didelot 				   u16 etype);
549cd782656SVivien Didelot 	int (*port_set_jumbo_size)(struct mv88e6xxx_chip *chip, int port,
550cd782656SVivien Didelot 				   size_t size);
5514d5f2ba7SVivien Didelot 
5524d5f2ba7SVivien Didelot 	int (*port_egress_rate_limiting)(struct mv88e6xxx_chip *chip, int port);
5530898432cSVivien Didelot 	int (*port_pause_limit)(struct mv88e6xxx_chip *chip, int port, u8 in,
5540898432cSVivien Didelot 				u8 out);
5554d5f2ba7SVivien Didelot 	int (*port_disable_learn_limit)(struct mv88e6xxx_chip *chip, int port);
5564d5f2ba7SVivien Didelot 	int (*port_disable_pri_override)(struct mv88e6xxx_chip *chip, int port);
557121b8fe2SHubert Feurstein 	int (*port_setup_message_port)(struct mv88e6xxx_chip *chip, int port);
5584d5f2ba7SVivien Didelot 
5594d5f2ba7SVivien Didelot 	/* CMODE control what PHY mode the MAC will use, eg. SGMII, RGMII, etc.
5604d5f2ba7SVivien Didelot 	 * Some chips allow this to be configured on specific ports.
5614d5f2ba7SVivien Didelot 	 */
5624d5f2ba7SVivien Didelot 	int (*port_set_cmode)(struct mv88e6xxx_chip *chip, int port,
5634d5f2ba7SVivien Didelot 			      phy_interface_t mode);
5642d2e1dd2SAndrew Lunn 	int (*port_get_cmode)(struct mv88e6xxx_chip *chip, int port, u8 *cmode);
5654d5f2ba7SVivien Didelot 
5664d5f2ba7SVivien Didelot 	/* Some devices have a per port register indicating what is
5674d5f2ba7SVivien Didelot 	 * the upstream port this port should forward to.
5684d5f2ba7SVivien Didelot 	 */
5694d5f2ba7SVivien Didelot 	int (*port_set_upstream_port)(struct mv88e6xxx_chip *chip, int port,
5704d5f2ba7SVivien Didelot 				      int upstream_port);
5714d5f2ba7SVivien Didelot 
5724d5f2ba7SVivien Didelot 	/* Snapshot the statistics for a port. The statistics can then
5734d5f2ba7SVivien Didelot 	 * be read back a leisure but still with a consistent view.
5744d5f2ba7SVivien Didelot 	 */
5754d5f2ba7SVivien Didelot 	int (*stats_snapshot)(struct mv88e6xxx_chip *chip, int port);
5764d5f2ba7SVivien Didelot 
5774d5f2ba7SVivien Didelot 	/* Set the histogram mode for statistics, when the control registers
5784d5f2ba7SVivien Didelot 	 * are separated out of the STATS_OP register.
5794d5f2ba7SVivien Didelot 	 */
5804d5f2ba7SVivien Didelot 	int (*stats_set_histogram)(struct mv88e6xxx_chip *chip);
5814d5f2ba7SVivien Didelot 
5824d5f2ba7SVivien Didelot 	/* Return the number of strings describing statistics */
5834d5f2ba7SVivien Didelot 	int (*stats_get_sset_count)(struct mv88e6xxx_chip *chip);
584436fe17dSAndrew Lunn 	int (*stats_get_strings)(struct mv88e6xxx_chip *chip,  uint8_t *data);
585436fe17dSAndrew Lunn 	int (*stats_get_stats)(struct mv88e6xxx_chip *chip,  int port,
5864d5f2ba7SVivien Didelot 			       uint64_t *data);
587fa8d1179SVivien Didelot 	int (*set_cpu_port)(struct mv88e6xxx_chip *chip, int port);
5885c74c54cSIwan R Timmer 	int (*set_egress_port)(struct mv88e6xxx_chip *chip,
5895c74c54cSIwan R Timmer 			       enum mv88e6xxx_egress_direction direction,
5905c74c54cSIwan R Timmer 			       int port);
59102317e68SVivien Didelot 
59202317e68SVivien Didelot #define MV88E6XXX_CASCADE_PORT_NONE		0xe
59302317e68SVivien Didelot #define MV88E6XXX_CASCADE_PORT_MULTIPLE		0xf
59402317e68SVivien Didelot 
59502317e68SVivien Didelot 	int (*set_cascade_port)(struct mv88e6xxx_chip *chip, int port);
59602317e68SVivien Didelot 
5974d5f2ba7SVivien Didelot 	const struct mv88e6xxx_irq_ops *watchdog_ops;
5984d5f2ba7SVivien Didelot 
5994d5f2ba7SVivien Didelot 	int (*mgmt_rsvd2cpu)(struct mv88e6xxx_chip *chip);
6004d5f2ba7SVivien Didelot 
60117deaf5cSMarek Behún 	/* SERDES lane mapping */
602193c5b26SPavana Sharma 	int (*serdes_get_lane)(struct mv88e6xxx_chip *chip, int port);
60317deaf5cSMarek Behún 
604efd1ba6aSAndrew Lunn 	/* SERDES interrupt handling */
6054241ef52SVivien Didelot 	unsigned int (*serdes_irq_mapping)(struct mv88e6xxx_chip *chip,
6064241ef52SVivien Didelot 					   int port);
607efd1ba6aSAndrew Lunn 
608436fe17dSAndrew Lunn 	/* Statistics from the SERDES interface */
609436fe17dSAndrew Lunn 	int (*serdes_get_sset_count)(struct mv88e6xxx_chip *chip, int port);
61065f60e45SAndrew Lunn 	int (*serdes_get_strings)(struct mv88e6xxx_chip *chip,  int port,
611436fe17dSAndrew Lunn 				  uint8_t *data);
612f6791424STobias Waldekranz 	size_t (*serdes_get_stats)(struct mv88e6xxx_chip *chip, int port,
613436fe17dSAndrew Lunn 				   uint64_t *data);
614436fe17dSAndrew Lunn 
6150d30bbd0SAndrew Lunn 	/* SERDES registers for ethtool */
6160d30bbd0SAndrew Lunn 	int (*serdes_get_regs_len)(struct mv88e6xxx_chip *chip,  int port);
6170d30bbd0SAndrew Lunn 	void (*serdes_get_regs)(struct mv88e6xxx_chip *chip, int port,
6180d30bbd0SAndrew Lunn 				void *_p);
6190d30bbd0SAndrew Lunn 
620926eae60SHolger Brunck 	/* SERDES SGMII/Fiber Output Amplitude */
621926eae60SHolger Brunck 	int (*serdes_set_tx_amplitude)(struct mv88e6xxx_chip *chip, int port,
622926eae60SHolger Brunck 				       int val);
623926eae60SHolger Brunck 
62423e8b470SAndrew Lunn 	/* Address Translation Unit operations */
62523e8b470SAndrew Lunn 	int (*atu_get_hash)(struct mv88e6xxx_chip *chip, u8 *hash);
62623e8b470SAndrew Lunn 	int (*atu_set_hash)(struct mv88e6xxx_chip *chip, u8 hash);
62723e8b470SAndrew Lunn 
6284d5f2ba7SVivien Didelot 	/* VLAN Translation Unit operations */
6294d5f2ba7SVivien Didelot 	int (*vtu_getnext)(struct mv88e6xxx_chip *chip,
6304d5f2ba7SVivien Didelot 			   struct mv88e6xxx_vtu_entry *entry);
6314d5f2ba7SVivien Didelot 	int (*vtu_loadpurge)(struct mv88e6xxx_chip *chip,
6324d5f2ba7SVivien Didelot 			     struct mv88e6xxx_vtu_entry *entry);
6330d632c3dSBrandon Streiff 
63449c98c1dSTobias Waldekranz 	/* Spanning Tree Unit operations */
63549c98c1dSTobias Waldekranz 	int (*stu_getnext)(struct mv88e6xxx_chip *chip,
63649c98c1dSTobias Waldekranz 			   struct mv88e6xxx_stu_entry *entry);
63749c98c1dSTobias Waldekranz 	int (*stu_loadpurge)(struct mv88e6xxx_chip *chip,
63849c98c1dSTobias Waldekranz 			     struct mv88e6xxx_stu_entry *entry);
63949c98c1dSTobias Waldekranz 
640a73ccd61SBrandon Streiff 	/* GPIO operations */
641a73ccd61SBrandon Streiff 	const struct mv88e6xxx_gpio_ops *gpio_ops;
642a73ccd61SBrandon Streiff 
6430d632c3dSBrandon Streiff 	/* Interface to the AVB/PTP registers */
6440d632c3dSBrandon Streiff 	const struct mv88e6xxx_avb_ops *avb_ops;
6459e5baf9bSVivien Didelot 
6469e5baf9bSVivien Didelot 	/* Remote Management Unit operations */
6479e5baf9bSVivien Didelot 	int (*rmu_disable)(struct mv88e6xxx_chip *chip);
6486d2ac8eeSAndrew Lunn 
6496d2ac8eeSAndrew Lunn 	/* Precision Time Protocol operations */
6506d2ac8eeSAndrew Lunn 	const struct mv88e6xxx_ptp_ops *ptp_ops;
6516c422e34SRussell King 
6526c422e34SRussell King 	/* Phylink */
653d4ebf12bSRussell King (Oracle) 	void (*phylink_get_caps)(struct mv88e6xxx_chip *chip, int port,
654d4ebf12bSRussell King (Oracle) 				 struct phylink_config *config);
6551baf0facSChris Packham 
656b92143d4SRussell King (Oracle) 	const struct mv88e6xxx_pcs_ops *pcs_ops;
657b92143d4SRussell King (Oracle) 
6581baf0facSChris Packham 	/* Max Frame Size */
6591baf0facSChris Packham 	int (*set_max_frame_size)(struct mv88e6xxx_chip *chip, int mtu);
6604d5f2ba7SVivien Didelot };
6614d5f2ba7SVivien Didelot 
6624d5f2ba7SVivien Didelot struct mv88e6xxx_irq_ops {
6634d5f2ba7SVivien Didelot 	/* Action to be performed when the interrupt happens */
6644d5f2ba7SVivien Didelot 	int (*irq_action)(struct mv88e6xxx_chip *chip, int irq);
6654d5f2ba7SVivien Didelot 	/* Setup the hardware to generate the interrupt */
6664d5f2ba7SVivien Didelot 	int (*irq_setup)(struct mv88e6xxx_chip *chip);
6674d5f2ba7SVivien Didelot 	/* Reset the hardware to stop generating the interrupt */
6684d5f2ba7SVivien Didelot 	void (*irq_free)(struct mv88e6xxx_chip *chip);
6694d5f2ba7SVivien Didelot };
6704d5f2ba7SVivien Didelot 
671a73ccd61SBrandon Streiff struct mv88e6xxx_gpio_ops {
672a73ccd61SBrandon Streiff 	/* Get/set data on GPIO pin */
673a73ccd61SBrandon Streiff 	int (*get_data)(struct mv88e6xxx_chip *chip, unsigned int pin);
674a73ccd61SBrandon Streiff 	int (*set_data)(struct mv88e6xxx_chip *chip, unsigned int pin,
675a73ccd61SBrandon Streiff 			int value);
676a73ccd61SBrandon Streiff 
677a73ccd61SBrandon Streiff 	/* get/set GPIO direction */
678a73ccd61SBrandon Streiff 	int (*get_dir)(struct mv88e6xxx_chip *chip, unsigned int pin);
679a73ccd61SBrandon Streiff 	int (*set_dir)(struct mv88e6xxx_chip *chip, unsigned int pin,
680a73ccd61SBrandon Streiff 		       bool input);
681a73ccd61SBrandon Streiff 
682a73ccd61SBrandon Streiff 	/* get/set GPIO pin control */
683a73ccd61SBrandon Streiff 	int (*get_pctl)(struct mv88e6xxx_chip *chip, unsigned int pin,
684a73ccd61SBrandon Streiff 			int *func);
685a73ccd61SBrandon Streiff 	int (*set_pctl)(struct mv88e6xxx_chip *chip, unsigned int pin,
686a73ccd61SBrandon Streiff 			int func);
687a73ccd61SBrandon Streiff };
688a73ccd61SBrandon Streiff 
6890d632c3dSBrandon Streiff struct mv88e6xxx_avb_ops {
6900d632c3dSBrandon Streiff 	/* Access port-scoped Precision Time Protocol registers */
6910d632c3dSBrandon Streiff 	int (*port_ptp_read)(struct mv88e6xxx_chip *chip, int port, int addr,
6920d632c3dSBrandon Streiff 			     u16 *data, int len);
6930d632c3dSBrandon Streiff 	int (*port_ptp_write)(struct mv88e6xxx_chip *chip, int port, int addr,
6940d632c3dSBrandon Streiff 			      u16 data);
6950d632c3dSBrandon Streiff 
6960d632c3dSBrandon Streiff 	/* Access global Precision Time Protocol registers */
6970d632c3dSBrandon Streiff 	int (*ptp_read)(struct mv88e6xxx_chip *chip, int addr, u16 *data,
6980d632c3dSBrandon Streiff 			int len);
6990d632c3dSBrandon Streiff 	int (*ptp_write)(struct mv88e6xxx_chip *chip, int addr, u16 data);
7000d632c3dSBrandon Streiff 
7010d632c3dSBrandon Streiff 	/* Access global Time Application Interface registers */
7020d632c3dSBrandon Streiff 	int (*tai_read)(struct mv88e6xxx_chip *chip, int addr, u16 *data,
7030d632c3dSBrandon Streiff 			int len);
7040d632c3dSBrandon Streiff 	int (*tai_write)(struct mv88e6xxx_chip *chip, int addr, u16 data);
7050d632c3dSBrandon Streiff };
7060d632c3dSBrandon Streiff 
7076d2ac8eeSAndrew Lunn struct mv88e6xxx_ptp_ops {
7086d2ac8eeSAndrew Lunn 	u64 (*clock_read)(const struct cyclecounter *cc);
7096d2ac8eeSAndrew Lunn 	int (*ptp_enable)(struct ptp_clock_info *ptp,
7106d2ac8eeSAndrew Lunn 			  struct ptp_clock_request *rq, int on);
7116d2ac8eeSAndrew Lunn 	int (*ptp_verify)(struct ptp_clock_info *ptp, unsigned int pin,
7126d2ac8eeSAndrew Lunn 			  enum ptp_pin_function func, unsigned int chan);
7136d2ac8eeSAndrew Lunn 	void (*event_work)(struct work_struct *ugly);
714ffc705deSAndrew Lunn 	int (*port_enable)(struct mv88e6xxx_chip *chip, int port);
715ffc705deSAndrew Lunn 	int (*port_disable)(struct mv88e6xxx_chip *chip, int port);
716e2294a8bSAndrew Lunn 	int (*global_enable)(struct mv88e6xxx_chip *chip);
717e2294a8bSAndrew Lunn 	int (*global_disable)(struct mv88e6xxx_chip *chip);
7189627c981SKurt Kanzenbach 	int (*set_ptp_cpu_port)(struct mv88e6xxx_chip *chip, int port);
7196d2ac8eeSAndrew Lunn 	int n_ext_ts;
720ffc705deSAndrew Lunn 	int arr0_sts_reg;
721ffc705deSAndrew Lunn 	int arr1_sts_reg;
722ffc705deSAndrew Lunn 	int dep_sts_reg;
72348cb5e03SAndrew Lunn 	u32 rx_filters;
7246d2ac8eeSAndrew Lunn };
7256d2ac8eeSAndrew Lunn 
726b92143d4SRussell King (Oracle) struct mv88e6xxx_pcs_ops {
727b92143d4SRussell King (Oracle) 	int (*pcs_init)(struct mv88e6xxx_chip *chip, int port);
728b92143d4SRussell King (Oracle) 	void (*pcs_teardown)(struct mv88e6xxx_chip *chip, int port);
729b92143d4SRussell King (Oracle) 	struct phylink_pcs *(*pcs_select)(struct mv88e6xxx_chip *chip, int port,
730b92143d4SRussell King (Oracle) 					  phy_interface_t mode);
731b92143d4SRussell King (Oracle) 
732b92143d4SRussell King (Oracle) };
733b92143d4SRussell King (Oracle) 
7344d5f2ba7SVivien Didelot #define STATS_TYPE_PORT		BIT(0)
7354d5f2ba7SVivien Didelot #define STATS_TYPE_BANK0	BIT(1)
7364d5f2ba7SVivien Didelot #define STATS_TYPE_BANK1	BIT(2)
7374d5f2ba7SVivien Didelot 
7384d5f2ba7SVivien Didelot struct mv88e6xxx_hw_stat {
7394d5f2ba7SVivien Didelot 	char string[ETH_GSTRING_LEN];
740cda9f4aaSAndrew Lunn 	size_t size;
7414d5f2ba7SVivien Didelot 	int reg;
7424d5f2ba7SVivien Didelot 	int type;
7434d5f2ba7SVivien Didelot };
7444d5f2ba7SVivien Didelot 
mv88e6xxx_has_stu(struct mv88e6xxx_chip * chip)74549c98c1dSTobias Waldekranz static inline bool mv88e6xxx_has_stu(struct mv88e6xxx_chip *chip)
74649c98c1dSTobias Waldekranz {
747afaed2b1STobias Waldekranz 	return chip->info->max_sid > 0 &&
748afaed2b1STobias Waldekranz 		chip->info->ops->stu_loadpurge &&
749afaed2b1STobias Waldekranz 		chip->info->ops->stu_getnext;
75049c98c1dSTobias Waldekranz }
75149c98c1dSTobias Waldekranz 
mv88e6xxx_has_pvt(struct mv88e6xxx_chip * chip)7524d5f2ba7SVivien Didelot static inline bool mv88e6xxx_has_pvt(struct mv88e6xxx_chip *chip)
7534d5f2ba7SVivien Didelot {
7544d5f2ba7SVivien Didelot 	return chip->info->pvt;
7554d5f2ba7SVivien Didelot }
7564d5f2ba7SVivien Didelot 
mv88e6xxx_has_lag(struct mv88e6xxx_chip * chip)757b80dc51bSTobias Waldekranz static inline bool mv88e6xxx_has_lag(struct mv88e6xxx_chip *chip)
758b80dc51bSTobias Waldekranz {
759b80dc51bSTobias Waldekranz 	return !!chip->info->global2_addr;
760b80dc51bSTobias Waldekranz }
761b80dc51bSTobias Waldekranz 
mv88e6xxx_num_databases(struct mv88e6xxx_chip * chip)7624d5f2ba7SVivien Didelot static inline unsigned int mv88e6xxx_num_databases(struct mv88e6xxx_chip *chip)
7634d5f2ba7SVivien Didelot {
7644d5f2ba7SVivien Didelot 	return chip->info->num_databases;
7654d5f2ba7SVivien Didelot }
7664d5f2ba7SVivien Didelot 
mv88e6xxx_num_macs(struct mv88e6xxx_chip * chip)767d9ea5620SAndrew Lunn static inline unsigned int mv88e6xxx_num_macs(struct  mv88e6xxx_chip *chip)
768d9ea5620SAndrew Lunn {
769d9ea5620SAndrew Lunn 	return chip->info->num_macs;
770d9ea5620SAndrew Lunn }
771d9ea5620SAndrew Lunn 
mv88e6xxx_num_ports(struct mv88e6xxx_chip * chip)7724d5f2ba7SVivien Didelot static inline unsigned int mv88e6xxx_num_ports(struct mv88e6xxx_chip *chip)
7734d5f2ba7SVivien Didelot {
7744d5f2ba7SVivien Didelot 	return chip->info->num_ports;
7754d5f2ba7SVivien Didelot }
7764d5f2ba7SVivien Didelot 
mv88e6xxx_max_vid(struct mv88e6xxx_chip * chip)777e545f865STobias Waldekranz static inline unsigned int mv88e6xxx_max_vid(struct mv88e6xxx_chip *chip)
778e545f865STobias Waldekranz {
779e545f865STobias Waldekranz 	return chip->info->max_vid;
780e545f865STobias Waldekranz }
781e545f865STobias Waldekranz 
mv88e6xxx_max_sid(struct mv88e6xxx_chip * chip)78249c98c1dSTobias Waldekranz static inline unsigned int mv88e6xxx_max_sid(struct mv88e6xxx_chip *chip)
78349c98c1dSTobias Waldekranz {
78449c98c1dSTobias Waldekranz 	return chip->info->max_sid;
78549c98c1dSTobias Waldekranz }
78649c98c1dSTobias Waldekranz 
mv88e6xxx_port_mask(struct mv88e6xxx_chip * chip)7874d5f2ba7SVivien Didelot static inline u16 mv88e6xxx_port_mask(struct mv88e6xxx_chip *chip)
7884d5f2ba7SVivien Didelot {
789f1931164SAndrew Lunn 	return GENMASK((s32)mv88e6xxx_num_ports(chip) - 1, 0);
7904d5f2ba7SVivien Didelot }
7914d5f2ba7SVivien Didelot 
mv88e6xxx_num_gpio(struct mv88e6xxx_chip * chip)792a73ccd61SBrandon Streiff static inline unsigned int mv88e6xxx_num_gpio(struct mv88e6xxx_chip *chip)
793a73ccd61SBrandon Streiff {
794a73ccd61SBrandon Streiff 	return chip->info->num_gpio;
795a73ccd61SBrandon Streiff }
796a73ccd61SBrandon Streiff 
mv88e6xxx_is_invalid_port(struct mv88e6xxx_chip * chip,int port)797c857486aSHubert Feurstein static inline bool mv88e6xxx_is_invalid_port(struct mv88e6xxx_chip *chip, int port)
798c857486aSHubert Feurstein {
799c857486aSHubert Feurstein 	return (chip->info->invalid_port_mask & BIT(port)) != 0;
800c857486aSHubert Feurstein }
801c857486aSHubert Feurstein 
mv88e6xxx_port_set_mab(struct mv88e6xxx_chip * chip,int port,bool mab)802830763b9SHans J. Schultz static inline void mv88e6xxx_port_set_mab(struct mv88e6xxx_chip *chip,
803830763b9SHans J. Schultz 					  int port, bool mab)
804830763b9SHans J. Schultz {
805830763b9SHans J. Schultz 	chip->ports[port].mab = mab;
806830763b9SHans J. Schultz }
807830763b9SHans J. Schultz 
8084d5f2ba7SVivien Didelot int mv88e6xxx_read(struct mv88e6xxx_chip *chip, int addr, int reg, u16 *val);
8094d5f2ba7SVivien Didelot int mv88e6xxx_write(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val);
810683f2244SVivien Didelot int mv88e6xxx_wait_mask(struct mv88e6xxx_chip *chip, int addr, int reg,
811683f2244SVivien Didelot 			u16 mask, u16 val);
81219fb7f69SVivien Didelot int mv88e6xxx_wait_bit(struct mv88e6xxx_chip *chip, int addr, int reg,
81319fb7f69SVivien Didelot 		       int bit, int val);
8144d5f2ba7SVivien Didelot struct mii_bus *mv88e6xxx_default_mdio_bus(struct mv88e6xxx_chip *chip);
8154d5f2ba7SVivien Didelot 
mv88e6xxx_reg_lock(struct mv88e6xxx_chip * chip)816c9acece0SRasmus Villemoes static inline void mv88e6xxx_reg_lock(struct mv88e6xxx_chip *chip)
817c9acece0SRasmus Villemoes {
818c9acece0SRasmus Villemoes 	mutex_lock(&chip->reg_lock);
819c9acece0SRasmus Villemoes }
820c9acece0SRasmus Villemoes 
mv88e6xxx_reg_unlock(struct mv88e6xxx_chip * chip)821c9acece0SRasmus Villemoes static inline void mv88e6xxx_reg_unlock(struct mv88e6xxx_chip *chip)
822c9acece0SRasmus Villemoes {
823c9acece0SRasmus Villemoes 	mutex_unlock(&chip->reg_lock);
824c9acece0SRasmus Villemoes }
825c9acece0SRasmus Villemoes 
826830763b9SHans J. Schultz int mv88e6xxx_vtu_walk(struct mv88e6xxx_chip *chip,
827830763b9SHans J. Schultz 		       int (*cb)(struct mv88e6xxx_chip *chip,
828830763b9SHans J. Schultz 				 const struct mv88e6xxx_vtu_entry *entry,
829830763b9SHans J. Schultz 				 void *priv),
830830763b9SHans J. Schultz 		       void *priv);
831830763b9SHans J. Schultz 
83290b6dbdfSAndrew Lunn int mv88e6xxx_fid_map(struct mv88e6xxx_chip *chip, unsigned long *bitmap);
83390b6dbdfSAndrew Lunn 
8344d5f2ba7SVivien Didelot #endif /* _MV88E6XXX_CHIP_H */
835