xref: /openbmc/linux/drivers/net/dsa/mv88e6xxx/chip.h (revision 830763b9)
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 {
574d5f2ba7SVivien Didelot 	MV88E6085,
584d5f2ba7SVivien Didelot 	MV88E6095,
594d5f2ba7SVivien Didelot 	MV88E6097,
604d5f2ba7SVivien Didelot 	MV88E6123,
614d5f2ba7SVivien Didelot 	MV88E6131,
624d5f2ba7SVivien Didelot 	MV88E6141,
634d5f2ba7SVivien Didelot 	MV88E6161,
644d5f2ba7SVivien Didelot 	MV88E6165,
654d5f2ba7SVivien Didelot 	MV88E6171,
664d5f2ba7SVivien Didelot 	MV88E6172,
674d5f2ba7SVivien Didelot 	MV88E6175,
684d5f2ba7SVivien Didelot 	MV88E6176,
694d5f2ba7SVivien Didelot 	MV88E6185,
704d5f2ba7SVivien Didelot 	MV88E6190,
714d5f2ba7SVivien Didelot 	MV88E6190X,
724d5f2ba7SVivien Didelot 	MV88E6191,
73de776d0dSPavana Sharma 	MV88E6191X,
74de776d0dSPavana Sharma 	MV88E6193X,
7549022647SHubert Feurstein 	MV88E6220,
764d5f2ba7SVivien Didelot 	MV88E6240,
771f71836fSRasmus Villemoes 	MV88E6250,
784d5f2ba7SVivien Didelot 	MV88E6290,
794d5f2ba7SVivien Didelot 	MV88E6320,
804d5f2ba7SVivien Didelot 	MV88E6321,
814d5f2ba7SVivien Didelot 	MV88E6341,
824d5f2ba7SVivien Didelot 	MV88E6350,
834d5f2ba7SVivien Didelot 	MV88E6351,
844d5f2ba7SVivien Didelot 	MV88E6352,
854d5f2ba7SVivien Didelot 	MV88E6390,
864d5f2ba7SVivien Didelot 	MV88E6390X,
87de776d0dSPavana Sharma 	MV88E6393X,
884d5f2ba7SVivien Didelot };
894d5f2ba7SVivien Didelot 
904d5f2ba7SVivien Didelot enum mv88e6xxx_family {
914d5f2ba7SVivien Didelot 	MV88E6XXX_FAMILY_NONE,
924d5f2ba7SVivien Didelot 	MV88E6XXX_FAMILY_6065,	/* 6031 6035 6061 6065 */
934d5f2ba7SVivien Didelot 	MV88E6XXX_FAMILY_6095,	/* 6092 6095 */
944d5f2ba7SVivien Didelot 	MV88E6XXX_FAMILY_6097,	/* 6046 6085 6096 6097 */
954d5f2ba7SVivien Didelot 	MV88E6XXX_FAMILY_6165,	/* 6123 6161 6165 */
964d5f2ba7SVivien Didelot 	MV88E6XXX_FAMILY_6185,	/* 6108 6121 6122 6131 6152 6155 6182 6185 */
9749022647SHubert Feurstein 	MV88E6XXX_FAMILY_6250,	/* 6220 6250 */
984d5f2ba7SVivien Didelot 	MV88E6XXX_FAMILY_6320,	/* 6320 6321 */
994d5f2ba7SVivien Didelot 	MV88E6XXX_FAMILY_6341,	/* 6141 6341 */
1004d5f2ba7SVivien Didelot 	MV88E6XXX_FAMILY_6351,	/* 6171 6175 6350 6351 */
1014d5f2ba7SVivien Didelot 	MV88E6XXX_FAMILY_6352,	/* 6172 6176 6240 6352 */
1024d5f2ba7SVivien Didelot 	MV88E6XXX_FAMILY_6390,  /* 6190 6190X 6191 6290 6390 6390X */
103de776d0dSPavana Sharma 	MV88E6XXX_FAMILY_6393,	/* 6191X 6193X 6393X */
1044d5f2ba7SVivien Didelot };
1054d5f2ba7SVivien Didelot 
106670bb80fSTobias Waldekranz /**
107670bb80fSTobias Waldekranz  * enum mv88e6xxx_edsa_support - Ethertype DSA tag support level
108670bb80fSTobias Waldekranz  * @MV88E6XXX_EDSA_UNSUPPORTED:  Device has no support for EDSA tags
109670bb80fSTobias Waldekranz  * @MV88E6XXX_EDSA_UNDOCUMENTED: Documentation indicates that
110670bb80fSTobias Waldekranz  *                               egressing FORWARD frames with an EDSA
111670bb80fSTobias Waldekranz  *                               tag is reserved for future use, but
112670bb80fSTobias Waldekranz  *                               empirical data shows that this mode
113670bb80fSTobias Waldekranz  *                               is supported.
114670bb80fSTobias Waldekranz  * @MV88E6XXX_EDSA_SUPPORTED:    EDSA tags are fully supported.
115670bb80fSTobias Waldekranz  */
116670bb80fSTobias Waldekranz enum mv88e6xxx_edsa_support {
117670bb80fSTobias Waldekranz 	MV88E6XXX_EDSA_UNSUPPORTED = 0,
118670bb80fSTobias Waldekranz 	MV88E6XXX_EDSA_UNDOCUMENTED,
119670bb80fSTobias Waldekranz 	MV88E6XXX_EDSA_SUPPORTED,
120670bb80fSTobias Waldekranz };
121670bb80fSTobias Waldekranz 
1224d5f2ba7SVivien Didelot struct mv88e6xxx_ops;
1234d5f2ba7SVivien Didelot 
1244d5f2ba7SVivien Didelot struct mv88e6xxx_info {
1254d5f2ba7SVivien Didelot 	enum mv88e6xxx_family family;
1264d5f2ba7SVivien Didelot 	u16 prod_num;
1274d5f2ba7SVivien Didelot 	const char *name;
1284d5f2ba7SVivien Didelot 	unsigned int num_databases;
129d9ea5620SAndrew Lunn 	unsigned int num_macs;
1304d5f2ba7SVivien Didelot 	unsigned int num_ports;
131bc393155SAndrew Lunn 	unsigned int num_internal_phys;
132a73ccd61SBrandon Streiff 	unsigned int num_gpio;
1334d5f2ba7SVivien Didelot 	unsigned int max_vid;
13449c98c1dSTobias Waldekranz 	unsigned int max_sid;
1354d5f2ba7SVivien Didelot 	unsigned int port_base_addr;
1369255bacdSAndrew Lunn 	unsigned int phy_base_addr;
1374d5f2ba7SVivien Didelot 	unsigned int global1_addr;
1389069c13aSVivien Didelot 	unsigned int global2_addr;
1394d5f2ba7SVivien Didelot 	unsigned int age_time_coeff;
1404d5f2ba7SVivien Didelot 	unsigned int g1_irqs;
141d6c5e6afSVivien Didelot 	unsigned int g2_irqs;
1424d5f2ba7SVivien Didelot 	bool pvt;
143b3e05aa1SVivien Didelot 
144c857486aSHubert Feurstein 	/* Mark certain ports as invalid. This is required for example for the
145c857486aSHubert Feurstein 	 * MV88E6220 (which is in general a MV88E6250 with 7 ports) but the
146c857486aSHubert Feurstein 	 * ports 2-4 are not routet to pins.
147c857486aSHubert Feurstein 	 */
148c857486aSHubert Feurstein 	unsigned int invalid_port_mask;
149b3e05aa1SVivien Didelot 	/* Multi-chip Addressing Mode.
150b3e05aa1SVivien Didelot 	 * Some chips respond to only 2 registers of its own SMI device address
151b3e05aa1SVivien Didelot 	 * when it is non-zero, and use indirect access to internal registers.
152b3e05aa1SVivien Didelot 	 */
153b3e05aa1SVivien Didelot 	bool multi_chip;
154f30a19b8SRasmus Villemoes 	/* Dual-chip Addressing Mode
155f30a19b8SRasmus Villemoes 	 * Some chips respond to only half of the 32 SMI addresses,
156f30a19b8SRasmus Villemoes 	 * allowing two to coexist on the same SMI interface.
157f30a19b8SRasmus Villemoes 	 */
158f30a19b8SRasmus Villemoes 	bool dual_chip;
159f30a19b8SRasmus Villemoes 
160670bb80fSTobias Waldekranz 	enum mv88e6xxx_edsa_support edsa_support;
1614d5f2ba7SVivien Didelot 
1624d5f2ba7SVivien Didelot 	/* Mask for FromPort and ToPort value of PortVec used in ATU Move
1634d5f2ba7SVivien Didelot 	 * operation. 0 means that the ATU Move operation is not supported.
1644d5f2ba7SVivien Didelot 	 */
1654d5f2ba7SVivien Didelot 	u8 atu_move_port_mask;
1664d5f2ba7SVivien Didelot 	const struct mv88e6xxx_ops *ops;
1672fa8d3afSBrandon Streiff 
1682fa8d3afSBrandon Streiff 	/* Supports PTP */
1692fa8d3afSBrandon Streiff 	bool ptp_support;
1704d5f2ba7SVivien Didelot };
1714d5f2ba7SVivien Didelot 
1724d5f2ba7SVivien Didelot struct mv88e6xxx_atu_entry {
1734d5f2ba7SVivien Didelot 	u8	state;
1744d5f2ba7SVivien Didelot 	bool	trunk;
1754d5f2ba7SVivien Didelot 	u16	portvec;
1764d5f2ba7SVivien Didelot 	u8	mac[ETH_ALEN];
1774d5f2ba7SVivien Didelot };
1784d5f2ba7SVivien Didelot 
1794d5f2ba7SVivien Didelot struct mv88e6xxx_vtu_entry {
1804d5f2ba7SVivien Didelot 	u16	vid;
1814d5f2ba7SVivien Didelot 	u16	fid;
1824d5f2ba7SVivien Didelot 	u8	sid;
1834d5f2ba7SVivien Didelot 	bool	valid;
184bb03b280STobias Waldekranz 	bool	policy;
1854d5f2ba7SVivien Didelot 	u8	member[DSA_MAX_PORTS];
18649c98c1dSTobias Waldekranz 	u8	state[DSA_MAX_PORTS];	/* Older silicon has no STU */
18749c98c1dSTobias Waldekranz };
18849c98c1dSTobias Waldekranz 
18949c98c1dSTobias Waldekranz struct mv88e6xxx_stu_entry {
19049c98c1dSTobias Waldekranz 	u8	sid;
19149c98c1dSTobias Waldekranz 	bool	valid;
1924d5f2ba7SVivien Didelot 	u8	state[DSA_MAX_PORTS];
1934d5f2ba7SVivien Didelot };
1944d5f2ba7SVivien Didelot 
1954d5f2ba7SVivien Didelot struct mv88e6xxx_bus_ops;
1964d5f2ba7SVivien Didelot struct mv88e6xxx_irq_ops;
197a73ccd61SBrandon Streiff struct mv88e6xxx_gpio_ops;
1980d632c3dSBrandon Streiff struct mv88e6xxx_avb_ops;
1996d2ac8eeSAndrew Lunn struct mv88e6xxx_ptp_ops;
2004d5f2ba7SVivien Didelot 
2014d5f2ba7SVivien Didelot struct mv88e6xxx_irq {
2024d5f2ba7SVivien Didelot 	u16 masked;
2034d5f2ba7SVivien Didelot 	struct irq_chip chip;
2044d5f2ba7SVivien Didelot 	struct irq_domain *domain;
205f1931164SAndrew Lunn 	int nirqs;
2064d5f2ba7SVivien Didelot };
2074d5f2ba7SVivien Didelot 
208c6fe0ad2SBrandon Streiff /* state flags for mv88e6xxx_port_hwtstamp::state */
209c6fe0ad2SBrandon Streiff enum {
210c6fe0ad2SBrandon Streiff 	MV88E6XXX_HWTSTAMP_ENABLED,
211c6fe0ad2SBrandon Streiff 	MV88E6XXX_HWTSTAMP_TX_IN_PROGRESS,
212c6fe0ad2SBrandon Streiff };
213c6fe0ad2SBrandon Streiff 
214c6fe0ad2SBrandon Streiff struct mv88e6xxx_port_hwtstamp {
215c6fe0ad2SBrandon Streiff 	/* Port index */
216c6fe0ad2SBrandon Streiff 	int port_id;
217c6fe0ad2SBrandon Streiff 
218c6fe0ad2SBrandon Streiff 	/* Timestamping state */
219c6fe0ad2SBrandon Streiff 	unsigned long state;
220c6fe0ad2SBrandon Streiff 
221c6fe0ad2SBrandon Streiff 	/* Resources for receive timestamping */
222c6fe0ad2SBrandon Streiff 	struct sk_buff_head rx_queue;
223c6fe0ad2SBrandon Streiff 	struct sk_buff_head rx_queue2;
224c6fe0ad2SBrandon Streiff 
225c6fe0ad2SBrandon Streiff 	/* Resources for transmit timestamping */
226c6fe0ad2SBrandon Streiff 	unsigned long tx_tstamp_start;
227c6fe0ad2SBrandon Streiff 	struct sk_buff *tx_skb;
228c6fe0ad2SBrandon Streiff 	u16 tx_seq_id;
229c6fe0ad2SBrandon Streiff 
230c6fe0ad2SBrandon Streiff 	/* Current timestamp configuration */
231c6fe0ad2SBrandon Streiff 	struct hwtstamp_config tstamp_config;
232c6fe0ad2SBrandon Streiff };
233c6fe0ad2SBrandon Streiff 
234f3a2cd32SVivien Didelot enum mv88e6xxx_policy_mapping {
235f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_MAPPING_DA,
236f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_MAPPING_SA,
237f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_MAPPING_VTU,
238f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_MAPPING_ETYPE,
239f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_MAPPING_PPPOE,
240f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_MAPPING_VBAS,
241f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_MAPPING_OPT82,
242f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_MAPPING_UDP,
243f3a2cd32SVivien Didelot };
244f3a2cd32SVivien Didelot 
245f3a2cd32SVivien Didelot enum mv88e6xxx_policy_action {
246f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_ACTION_NORMAL,
247f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_ACTION_MIRROR,
248f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_ACTION_TRAP,
249f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_ACTION_DISCARD,
250f3a2cd32SVivien Didelot };
251f3a2cd32SVivien Didelot 
252da7dc875SVivien Didelot struct mv88e6xxx_policy {
253da7dc875SVivien Didelot 	enum mv88e6xxx_policy_mapping mapping;
254da7dc875SVivien Didelot 	enum mv88e6xxx_policy_action action;
255da7dc875SVivien Didelot 	struct ethtool_rx_flow_spec fs;
256da7dc875SVivien Didelot 	u8 addr[ETH_ALEN];
257da7dc875SVivien Didelot 	int port;
258da7dc875SVivien Didelot 	u16 vid;
259da7dc875SVivien Didelot };
260da7dc875SVivien Didelot 
2618b6836d8SVladimir Oltean struct mv88e6xxx_vlan {
2628b6836d8SVladimir Oltean 	u16	vid;
2638b6836d8SVladimir Oltean 	bool	valid;
2648b6836d8SVladimir Oltean };
2658b6836d8SVladimir Oltean 
266cda9f4aaSAndrew Lunn struct mv88e6xxx_port {
2677b898469SAndrew Lunn 	struct mv88e6xxx_chip *chip;
2687b898469SAndrew Lunn 	int port;
2698b6836d8SVladimir Oltean 	struct mv88e6xxx_vlan bridge_pvid;
270cda9f4aaSAndrew Lunn 	u64 serdes_stats[2];
27165f60e45SAndrew Lunn 	u64 atu_member_violation;
27265f60e45SAndrew Lunn 	u64 atu_miss_violation;
27365f60e45SAndrew Lunn 	u64 atu_full_violation;
27465f60e45SAndrew Lunn 	u64 vtu_member_violation;
27565f60e45SAndrew Lunn 	u64 vtu_miss_violation;
276fad58190SRussell King 	phy_interface_t interface;
2772d2e1dd2SAndrew Lunn 	u8 cmode;
278f0942e00SIwan R Timmer 	bool mirror_ingress;
279f0942e00SIwan R Timmer 	bool mirror_egress;
280f441ed0fSVivien Didelot 	unsigned int serdes_irq;
2815d1fbdf2SAndrew Lunn 	char serdes_irq_name[64];
282bfb25542SAndrew Lunn 	struct devlink_region *region;
283*830763b9SHans J. Schultz 
284*830763b9SHans J. Schultz 	/* MacAuth Bypass control flag */
285*830763b9SHans J. Schultz 	bool mab;
286bfb25542SAndrew Lunn };
287bfb25542SAndrew Lunn 
288bfb25542SAndrew Lunn enum mv88e6xxx_region_id {
289bfb25542SAndrew Lunn 	MV88E6XXX_REGION_GLOBAL1 = 0,
290bfb25542SAndrew Lunn 	MV88E6XXX_REGION_GLOBAL2,
291bfb25542SAndrew Lunn 	MV88E6XXX_REGION_ATU,
292ca4d632aSTobias Waldekranz 	MV88E6XXX_REGION_VTU,
2937dc96039STobias Waldekranz 	MV88E6XXX_REGION_STU,
294836021a2STobias Waldekranz 	MV88E6XXX_REGION_PVT,
295bfb25542SAndrew Lunn 
296bfb25542SAndrew Lunn 	_MV88E6XXX_REGION_MAX,
297bfb25542SAndrew Lunn };
298bfb25542SAndrew Lunn 
299bfb25542SAndrew Lunn struct mv88e6xxx_region_priv {
300bfb25542SAndrew Lunn 	enum mv88e6xxx_region_id id;
301cda9f4aaSAndrew Lunn };
302cda9f4aaSAndrew Lunn 
303acaf4d2eSTobias Waldekranz struct mv88e6xxx_mst {
304acaf4d2eSTobias Waldekranz 	struct list_head node;
305acaf4d2eSTobias Waldekranz 
306acaf4d2eSTobias Waldekranz 	refcount_t refcnt;
307acaf4d2eSTobias Waldekranz 	struct net_device *br;
308acaf4d2eSTobias Waldekranz 	u16 msti;
309acaf4d2eSTobias Waldekranz 
310acaf4d2eSTobias Waldekranz 	struct mv88e6xxx_stu_entry stu;
311acaf4d2eSTobias Waldekranz };
312acaf4d2eSTobias Waldekranz 
3134d5f2ba7SVivien Didelot struct mv88e6xxx_chip {
3144d5f2ba7SVivien Didelot 	const struct mv88e6xxx_info *info;
3154d5f2ba7SVivien Didelot 
316670bb80fSTobias Waldekranz 	/* Currently configured tagging protocol */
317670bb80fSTobias Waldekranz 	enum dsa_tag_protocol tag_protocol;
318670bb80fSTobias Waldekranz 
3194d5f2ba7SVivien Didelot 	/* The dsa_switch this private structure is related to */
3204d5f2ba7SVivien Didelot 	struct dsa_switch *ds;
3214d5f2ba7SVivien Didelot 
3224d5f2ba7SVivien Didelot 	/* The device this structure is associated to */
3234d5f2ba7SVivien Didelot 	struct device *dev;
3244d5f2ba7SVivien Didelot 
3254d5f2ba7SVivien Didelot 	/* This mutex protects the access to the switch registers */
3264d5f2ba7SVivien Didelot 	struct mutex reg_lock;
3274d5f2ba7SVivien Didelot 
3284d5f2ba7SVivien Didelot 	/* The MII bus and the address on the bus that is used to
3294d5f2ba7SVivien Didelot 	 * communication with the switch
3304d5f2ba7SVivien Didelot 	 */
3314d5f2ba7SVivien Didelot 	const struct mv88e6xxx_bus_ops *smi_ops;
3324d5f2ba7SVivien Didelot 	struct mii_bus *bus;
3334d5f2ba7SVivien Didelot 	int sw_addr;
3344d5f2ba7SVivien Didelot 
3354d5f2ba7SVivien Didelot 	/* Handles automatic disabling and re-enabling of the PHY
3364d5f2ba7SVivien Didelot 	 * polling unit.
3374d5f2ba7SVivien Didelot 	 */
3384d5f2ba7SVivien Didelot 	const struct mv88e6xxx_bus_ops *phy_ops;
3394d5f2ba7SVivien Didelot 	struct mutex		ppu_mutex;
3404d5f2ba7SVivien Didelot 	int			ppu_disabled;
3414d5f2ba7SVivien Didelot 	struct work_struct	ppu_work;
3424d5f2ba7SVivien Didelot 	struct timer_list	ppu_timer;
3434d5f2ba7SVivien Didelot 
3444d5f2ba7SVivien Didelot 	/* This mutex serialises access to the statistics unit.
3454d5f2ba7SVivien Didelot 	 * Hold this mutex over snapshot + dump sequences.
3464d5f2ba7SVivien Didelot 	 */
3474d5f2ba7SVivien Didelot 	struct mutex	stats_mutex;
3484d5f2ba7SVivien Didelot 
3494d5f2ba7SVivien Didelot 	/* A switch may have a GPIO line tied to its reset pin. Parse
3504d5f2ba7SVivien Didelot 	 * this from the device tree, and use it before performing
3514d5f2ba7SVivien Didelot 	 * switch soft reset.
3524d5f2ba7SVivien Didelot 	 */
3534d5f2ba7SVivien Didelot 	struct gpio_desc *reset;
3544d5f2ba7SVivien Didelot 
3554d5f2ba7SVivien Didelot 	/* set to size of eeprom if supported by the switch */
35600baabe5SAndrew Lunn 	u32 eeprom_len;
3574d5f2ba7SVivien Didelot 
3584d5f2ba7SVivien Didelot 	/* List of mdio busses */
3594d5f2ba7SVivien Didelot 	struct list_head mdios;
3604d5f2ba7SVivien Didelot 
361da7dc875SVivien Didelot 	/* Policy Control List IDs and rules */
362da7dc875SVivien Didelot 	struct idr policies;
363da7dc875SVivien Didelot 
3644d5f2ba7SVivien Didelot 	/* There can be two interrupt controllers, which are chained
3654d5f2ba7SVivien Didelot 	 * off a GPIO as interrupt source
3664d5f2ba7SVivien Didelot 	 */
3674d5f2ba7SVivien Didelot 	struct mv88e6xxx_irq g1_irq;
3684d5f2ba7SVivien Didelot 	struct mv88e6xxx_irq g2_irq;
3694d5f2ba7SVivien Didelot 	int irq;
3705d1fbdf2SAndrew Lunn 	char irq_name[64];
3714d5f2ba7SVivien Didelot 	int device_irq;
3725d1fbdf2SAndrew Lunn 	char device_irq_name[64];
3734d5f2ba7SVivien Didelot 	int watchdog_irq;
3745d1fbdf2SAndrew Lunn 	char watchdog_irq_name[64];
375cda9f4aaSAndrew Lunn 
3760977644cSAndrew Lunn 	int atu_prob_irq;
3775d1fbdf2SAndrew Lunn 	char atu_prob_irq_name[64];
37862eb1162SAndrew Lunn 	int vtu_prob_irq;
3795d1fbdf2SAndrew Lunn 	char vtu_prob_irq_name[64];
380294d711eSAndrew Lunn 	struct kthread_worker *kworker;
381294d711eSAndrew Lunn 	struct kthread_delayed_work irq_poll_work;
3822fa8d3afSBrandon Streiff 
383a73ccd61SBrandon Streiff 	/* GPIO resources */
384a73ccd61SBrandon Streiff 	u8 gpio_data[2];
385a73ccd61SBrandon Streiff 
3862fa8d3afSBrandon Streiff 	/* This cyclecounter abstracts the switch PTP time.
3872fa8d3afSBrandon Streiff 	 * reg_lock must be held for any operation that read()s.
3882fa8d3afSBrandon Streiff 	 */
3892fa8d3afSBrandon Streiff 	struct cyclecounter	tstamp_cc;
3902fa8d3afSBrandon Streiff 	struct timecounter	tstamp_tc;
3912fa8d3afSBrandon Streiff 	struct delayed_work	overflow_work;
3922fa8d3afSBrandon Streiff 
3932fa8d3afSBrandon Streiff 	struct ptp_clock	*ptp_clock;
3942fa8d3afSBrandon Streiff 	struct ptp_clock_info	ptp_clock_info;
3954eb3be29SBrandon Streiff 	struct delayed_work	tai_event_work;
3964eb3be29SBrandon Streiff 	struct ptp_pin_desc	pin_config[MV88E6XXX_MAX_GPIO];
3974eb3be29SBrandon Streiff 	u16 trig_config;
3984eb3be29SBrandon Streiff 	u16 evcap_config;
399e2294a8bSAndrew Lunn 	u16 enable_count;
400c6fe0ad2SBrandon Streiff 
401f0942e00SIwan R Timmer 	/* Current ingress and egress monitor ports */
402f0942e00SIwan R Timmer 	int egress_dest_port;
403f0942e00SIwan R Timmer 	int ingress_dest_port;
404f0942e00SIwan R Timmer 
405c6fe0ad2SBrandon Streiff 	/* Per-port timestamping resources. */
406c6fe0ad2SBrandon Streiff 	struct mv88e6xxx_port_hwtstamp port_hwtstamp[DSA_MAX_PORTS];
407cda9f4aaSAndrew Lunn 
408cda9f4aaSAndrew Lunn 	/* Array of port structures. */
409cda9f4aaSAndrew Lunn 	struct mv88e6xxx_port ports[DSA_MAX_PORTS];
410bfb25542SAndrew Lunn 
411bfb25542SAndrew Lunn 	/* devlink regions */
412bfb25542SAndrew Lunn 	struct devlink_region *regions[_MV88E6XXX_REGION_MAX];
413acaf4d2eSTobias Waldekranz 
414acaf4d2eSTobias Waldekranz 	/* Bridge MST to SID mappings */
415acaf4d2eSTobias Waldekranz 	struct list_head msts;
4164d5f2ba7SVivien Didelot };
4174d5f2ba7SVivien Didelot 
4184d5f2ba7SVivien Didelot struct mv88e6xxx_bus_ops {
4194d5f2ba7SVivien Didelot 	int (*read)(struct mv88e6xxx_chip *chip, int addr, int reg, u16 *val);
4204d5f2ba7SVivien Didelot 	int (*write)(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val);
4217bca16b2STobias Waldekranz 	int (*init)(struct mv88e6xxx_chip *chip);
4224d5f2ba7SVivien Didelot };
4234d5f2ba7SVivien Didelot 
4244d5f2ba7SVivien Didelot struct mv88e6xxx_mdio_bus {
4254d5f2ba7SVivien Didelot 	struct mii_bus *bus;
4264d5f2ba7SVivien Didelot 	struct mv88e6xxx_chip *chip;
4274d5f2ba7SVivien Didelot 	struct list_head list;
4284d5f2ba7SVivien Didelot 	bool external;
4294d5f2ba7SVivien Didelot };
4304d5f2ba7SVivien Didelot 
4314d5f2ba7SVivien Didelot struct mv88e6xxx_ops {
432ea89098eSAndrew Lunn 	/* Switch Setup Errata, called early in the switch setup to
433ea89098eSAndrew Lunn 	 * allow any errata actions to be performed
434ea89098eSAndrew Lunn 	 */
435ea89098eSAndrew Lunn 	int (*setup_errata)(struct mv88e6xxx_chip *chip);
436ea89098eSAndrew Lunn 
43793e18d61SVivien Didelot 	int (*ieee_pri_map)(struct mv88e6xxx_chip *chip);
43893e18d61SVivien Didelot 	int (*ip_pri_map)(struct mv88e6xxx_chip *chip);
43993e18d61SVivien Didelot 
440cd8da8bbSVivien Didelot 	/* Ingress Rate Limit unit (IRL) operations */
441cd8da8bbSVivien Didelot 	int (*irl_init_all)(struct mv88e6xxx_chip *chip, int port);
442cd8da8bbSVivien Didelot 
4434d5f2ba7SVivien Didelot 	int (*get_eeprom)(struct mv88e6xxx_chip *chip,
4444d5f2ba7SVivien Didelot 			  struct ethtool_eeprom *eeprom, u8 *data);
4454d5f2ba7SVivien Didelot 	int (*set_eeprom)(struct mv88e6xxx_chip *chip,
4464d5f2ba7SVivien Didelot 			  struct ethtool_eeprom *eeprom, u8 *data);
4474d5f2ba7SVivien Didelot 
4484d5f2ba7SVivien Didelot 	int (*set_switch_mac)(struct mv88e6xxx_chip *chip, u8 *addr);
4494d5f2ba7SVivien Didelot 
4504d5f2ba7SVivien Didelot 	int (*phy_read)(struct mv88e6xxx_chip *chip,
4514d5f2ba7SVivien Didelot 			struct mii_bus *bus,
4524d5f2ba7SVivien Didelot 			int addr, int reg, u16 *val);
4534d5f2ba7SVivien Didelot 	int (*phy_write)(struct mv88e6xxx_chip *chip,
4544d5f2ba7SVivien Didelot 			 struct mii_bus *bus,
4554d5f2ba7SVivien Didelot 			 int addr, int reg, u16 val);
4564d5f2ba7SVivien Didelot 
4579e907d73SVivien Didelot 	/* Priority Override Table operations */
4589e907d73SVivien Didelot 	int (*pot_clear)(struct mv88e6xxx_chip *chip);
4599e907d73SVivien Didelot 
4604d5f2ba7SVivien Didelot 	/* PHY Polling Unit (PPU) operations */
4614d5f2ba7SVivien Didelot 	int (*ppu_enable)(struct mv88e6xxx_chip *chip);
4624d5f2ba7SVivien Didelot 	int (*ppu_disable)(struct mv88e6xxx_chip *chip);
4634d5f2ba7SVivien Didelot 
4644d5f2ba7SVivien Didelot 	/* Switch Software Reset */
4654d5f2ba7SVivien Didelot 	int (*reset)(struct mv88e6xxx_chip *chip);
4664d5f2ba7SVivien Didelot 
4674d5f2ba7SVivien Didelot 	/* RGMII Receive/Transmit Timing Control
4684d5f2ba7SVivien Didelot 	 * Add delay on PHY_INTERFACE_MODE_RGMII_*ID, no delay otherwise.
4694d5f2ba7SVivien Didelot 	 */
4704d5f2ba7SVivien Didelot 	int (*port_set_rgmii_delay)(struct mv88e6xxx_chip *chip, int port,
4714d5f2ba7SVivien Didelot 				    phy_interface_t mode);
4724d5f2ba7SVivien Didelot 
4734d5f2ba7SVivien Didelot #define LINK_FORCED_DOWN	0
4744d5f2ba7SVivien Didelot #define LINK_FORCED_UP		1
4754d5f2ba7SVivien Didelot #define LINK_UNFORCED		-2
4764d5f2ba7SVivien Didelot 
4774d5f2ba7SVivien Didelot 	/* Port's MAC link state
4784d5f2ba7SVivien Didelot 	 * Use LINK_FORCED_UP or LINK_FORCED_DOWN to force link up or down,
4794d5f2ba7SVivien Didelot 	 * or LINK_UNFORCED for normal link detection.
4804d5f2ba7SVivien Didelot 	 */
4814d5f2ba7SVivien Didelot 	int (*port_set_link)(struct mv88e6xxx_chip *chip, int port, int link);
4824d5f2ba7SVivien Didelot 
4834efe7662SChris Packham 	/* Synchronise the port link state with that of the SERDES
4844efe7662SChris Packham 	 */
4854efe7662SChris Packham 	int (*port_sync_link)(struct mv88e6xxx_chip *chip, int port, unsigned int mode, bool isup);
4864efe7662SChris Packham 
48754186b91SAndrew Lunn #define PAUSE_ON		1
48854186b91SAndrew Lunn #define PAUSE_OFF		0
48954186b91SAndrew Lunn 
49054186b91SAndrew Lunn 	/* Enable/disable sending Pause */
49154186b91SAndrew Lunn 	int (*port_set_pause)(struct mv88e6xxx_chip *chip, int port,
49254186b91SAndrew Lunn 			      int pause);
49354186b91SAndrew Lunn 
4944d5f2ba7SVivien Didelot #define SPEED_UNFORCED		-2
495f365c6f7SRussell King #define DUPLEX_UNFORCED		-2
4964d5f2ba7SVivien Didelot 
497f365c6f7SRussell King 	/* Port's MAC speed (in Mbps) and MAC duplex mode
4984d5f2ba7SVivien Didelot 	 *
4994d5f2ba7SVivien Didelot 	 * Depending on the chip, 10, 100, 200, 1000, 2500, 10000 are valid.
5003c783b83SRussell King 	 * Use SPEED_UNFORCED for normal detection.
501f365c6f7SRussell King 	 *
502f365c6f7SRussell King 	 * Use DUPLEX_HALF or DUPLEX_FULL to force half or full duplex,
503f365c6f7SRussell King 	 * or DUPLEX_UNFORCED for normal duplex detection.
5044d5f2ba7SVivien Didelot 	 */
505f365c6f7SRussell King 	int (*port_set_speed_duplex)(struct mv88e6xxx_chip *chip, int port,
506f365c6f7SRussell King 				     int speed, int duplex);
5074d5f2ba7SVivien Didelot 
5087cbbee05SAndrew Lunn 	/* What interface mode should be used for maximum speed? */
5097cbbee05SAndrew Lunn 	phy_interface_t (*port_max_speed_mode)(int port);
5107cbbee05SAndrew Lunn 
5114d5f2ba7SVivien Didelot 	int (*port_tag_remap)(struct mv88e6xxx_chip *chip, int port);
5124d5f2ba7SVivien Didelot 
513f3a2cd32SVivien Didelot 	int (*port_set_policy)(struct mv88e6xxx_chip *chip, int port,
514f3a2cd32SVivien Didelot 			       enum mv88e6xxx_policy_mapping mapping,
515f3a2cd32SVivien Didelot 			       enum mv88e6xxx_policy_action action);
516f3a2cd32SVivien Didelot 
5174d5f2ba7SVivien Didelot 	int (*port_set_frame_mode)(struct mv88e6xxx_chip *chip, int port,
5184d5f2ba7SVivien Didelot 				   enum mv88e6xxx_frame_mode mode);
519a8b659e7SVladimir Oltean 	int (*port_set_ucast_flood)(struct mv88e6xxx_chip *chip, int port,
520a8b659e7SVladimir Oltean 				    bool unicast);
521a8b659e7SVladimir Oltean 	int (*port_set_mcast_flood)(struct mv88e6xxx_chip *chip, int port,
522a8b659e7SVladimir Oltean 				    bool multicast);
5234d5f2ba7SVivien Didelot 	int (*port_set_ether_type)(struct mv88e6xxx_chip *chip, int port,
5244d5f2ba7SVivien Didelot 				   u16 etype);
525cd782656SVivien Didelot 	int (*port_set_jumbo_size)(struct mv88e6xxx_chip *chip, int port,
526cd782656SVivien Didelot 				   size_t size);
5274d5f2ba7SVivien Didelot 
5284d5f2ba7SVivien Didelot 	int (*port_egress_rate_limiting)(struct mv88e6xxx_chip *chip, int port);
5290898432cSVivien Didelot 	int (*port_pause_limit)(struct mv88e6xxx_chip *chip, int port, u8 in,
5300898432cSVivien Didelot 				u8 out);
5314d5f2ba7SVivien Didelot 	int (*port_disable_learn_limit)(struct mv88e6xxx_chip *chip, int port);
5324d5f2ba7SVivien Didelot 	int (*port_disable_pri_override)(struct mv88e6xxx_chip *chip, int port);
533121b8fe2SHubert Feurstein 	int (*port_setup_message_port)(struct mv88e6xxx_chip *chip, int port);
5344d5f2ba7SVivien Didelot 
5354d5f2ba7SVivien Didelot 	/* CMODE control what PHY mode the MAC will use, eg. SGMII, RGMII, etc.
5364d5f2ba7SVivien Didelot 	 * Some chips allow this to be configured on specific ports.
5374d5f2ba7SVivien Didelot 	 */
5384d5f2ba7SVivien Didelot 	int (*port_set_cmode)(struct mv88e6xxx_chip *chip, int port,
5394d5f2ba7SVivien Didelot 			      phy_interface_t mode);
5402d2e1dd2SAndrew Lunn 	int (*port_get_cmode)(struct mv88e6xxx_chip *chip, int port, u8 *cmode);
5414d5f2ba7SVivien Didelot 
5424d5f2ba7SVivien Didelot 	/* Some devices have a per port register indicating what is
5434d5f2ba7SVivien Didelot 	 * the upstream port this port should forward to.
5444d5f2ba7SVivien Didelot 	 */
5454d5f2ba7SVivien Didelot 	int (*port_set_upstream_port)(struct mv88e6xxx_chip *chip, int port,
5464d5f2ba7SVivien Didelot 				      int upstream_port);
5474d5f2ba7SVivien Didelot 
5484d5f2ba7SVivien Didelot 	/* Snapshot the statistics for a port. The statistics can then
5494d5f2ba7SVivien Didelot 	 * be read back a leisure but still with a consistent view.
5504d5f2ba7SVivien Didelot 	 */
5514d5f2ba7SVivien Didelot 	int (*stats_snapshot)(struct mv88e6xxx_chip *chip, int port);
5524d5f2ba7SVivien Didelot 
5534d5f2ba7SVivien Didelot 	/* Set the histogram mode for statistics, when the control registers
5544d5f2ba7SVivien Didelot 	 * are separated out of the STATS_OP register.
5554d5f2ba7SVivien Didelot 	 */
5564d5f2ba7SVivien Didelot 	int (*stats_set_histogram)(struct mv88e6xxx_chip *chip);
5574d5f2ba7SVivien Didelot 
5584d5f2ba7SVivien Didelot 	/* Return the number of strings describing statistics */
5594d5f2ba7SVivien Didelot 	int (*stats_get_sset_count)(struct mv88e6xxx_chip *chip);
560436fe17dSAndrew Lunn 	int (*stats_get_strings)(struct mv88e6xxx_chip *chip,  uint8_t *data);
561436fe17dSAndrew Lunn 	int (*stats_get_stats)(struct mv88e6xxx_chip *chip,  int port,
5624d5f2ba7SVivien Didelot 			       uint64_t *data);
563fa8d1179SVivien Didelot 	int (*set_cpu_port)(struct mv88e6xxx_chip *chip, int port);
5645c74c54cSIwan R Timmer 	int (*set_egress_port)(struct mv88e6xxx_chip *chip,
5655c74c54cSIwan R Timmer 			       enum mv88e6xxx_egress_direction direction,
5665c74c54cSIwan R Timmer 			       int port);
56702317e68SVivien Didelot 
56802317e68SVivien Didelot #define MV88E6XXX_CASCADE_PORT_NONE		0xe
56902317e68SVivien Didelot #define MV88E6XXX_CASCADE_PORT_MULTIPLE		0xf
57002317e68SVivien Didelot 
57102317e68SVivien Didelot 	int (*set_cascade_port)(struct mv88e6xxx_chip *chip, int port);
57202317e68SVivien Didelot 
5734d5f2ba7SVivien Didelot 	const struct mv88e6xxx_irq_ops *watchdog_ops;
5744d5f2ba7SVivien Didelot 
5754d5f2ba7SVivien Didelot 	int (*mgmt_rsvd2cpu)(struct mv88e6xxx_chip *chip);
5764d5f2ba7SVivien Didelot 
5774d5f2ba7SVivien Didelot 	/* Power on/off a SERDES interface */
578193c5b26SPavana Sharma 	int (*serdes_power)(struct mv88e6xxx_chip *chip, int port, int lane,
579dc272f60SVivien Didelot 			    bool up);
5804d5f2ba7SVivien Didelot 
58117deaf5cSMarek Behún 	/* SERDES lane mapping */
582193c5b26SPavana Sharma 	int (*serdes_get_lane)(struct mv88e6xxx_chip *chip, int port);
58317deaf5cSMarek Behún 
584a5a6858bSRussell King 	int (*serdes_pcs_get_state)(struct mv88e6xxx_chip *chip, int port,
585193c5b26SPavana Sharma 				    int lane, struct phylink_link_state *state);
586a5a6858bSRussell King 	int (*serdes_pcs_config)(struct mv88e6xxx_chip *chip, int port,
587193c5b26SPavana Sharma 				 int lane, unsigned int mode,
588a5a6858bSRussell King 				 phy_interface_t interface,
589a5a6858bSRussell King 				 const unsigned long *advertise);
590a5a6858bSRussell King 	int (*serdes_pcs_an_restart)(struct mv88e6xxx_chip *chip, int port,
591193c5b26SPavana Sharma 				     int lane);
592a5a6858bSRussell King 	int (*serdes_pcs_link_up)(struct mv88e6xxx_chip *chip, int port,
593193c5b26SPavana Sharma 				  int lane, int speed, int duplex);
594a5a6858bSRussell King 
595efd1ba6aSAndrew Lunn 	/* SERDES interrupt handling */
5964241ef52SVivien Didelot 	unsigned int (*serdes_irq_mapping)(struct mv88e6xxx_chip *chip,
5974241ef52SVivien Didelot 					   int port);
598193c5b26SPavana Sharma 	int (*serdes_irq_enable)(struct mv88e6xxx_chip *chip, int port, int lane,
59961a46b41SVivien Didelot 				 bool enable);
600907b9b9fSVivien Didelot 	irqreturn_t (*serdes_irq_status)(struct mv88e6xxx_chip *chip, int port,
601193c5b26SPavana Sharma 					 int lane);
602efd1ba6aSAndrew Lunn 
603436fe17dSAndrew Lunn 	/* Statistics from the SERDES interface */
604436fe17dSAndrew Lunn 	int (*serdes_get_sset_count)(struct mv88e6xxx_chip *chip, int port);
60565f60e45SAndrew Lunn 	int (*serdes_get_strings)(struct mv88e6xxx_chip *chip,  int port,
606436fe17dSAndrew Lunn 				  uint8_t *data);
60765f60e45SAndrew Lunn 	int (*serdes_get_stats)(struct mv88e6xxx_chip *chip,  int port,
608436fe17dSAndrew Lunn 				uint64_t *data);
609436fe17dSAndrew Lunn 
6100d30bbd0SAndrew Lunn 	/* SERDES registers for ethtool */
6110d30bbd0SAndrew Lunn 	int (*serdes_get_regs_len)(struct mv88e6xxx_chip *chip,  int port);
6120d30bbd0SAndrew Lunn 	void (*serdes_get_regs)(struct mv88e6xxx_chip *chip, int port,
6130d30bbd0SAndrew Lunn 				void *_p);
6140d30bbd0SAndrew Lunn 
615926eae60SHolger Brunck 	/* SERDES SGMII/Fiber Output Amplitude */
616926eae60SHolger Brunck 	int (*serdes_set_tx_amplitude)(struct mv88e6xxx_chip *chip, int port,
617926eae60SHolger Brunck 				       int val);
618926eae60SHolger Brunck 
61923e8b470SAndrew Lunn 	/* Address Translation Unit operations */
62023e8b470SAndrew Lunn 	int (*atu_get_hash)(struct mv88e6xxx_chip *chip, u8 *hash);
62123e8b470SAndrew Lunn 	int (*atu_set_hash)(struct mv88e6xxx_chip *chip, u8 hash);
62223e8b470SAndrew Lunn 
6234d5f2ba7SVivien Didelot 	/* VLAN Translation Unit operations */
6244d5f2ba7SVivien Didelot 	int (*vtu_getnext)(struct mv88e6xxx_chip *chip,
6254d5f2ba7SVivien Didelot 			   struct mv88e6xxx_vtu_entry *entry);
6264d5f2ba7SVivien Didelot 	int (*vtu_loadpurge)(struct mv88e6xxx_chip *chip,
6274d5f2ba7SVivien Didelot 			     struct mv88e6xxx_vtu_entry *entry);
6280d632c3dSBrandon Streiff 
62949c98c1dSTobias Waldekranz 	/* Spanning Tree Unit operations */
63049c98c1dSTobias Waldekranz 	int (*stu_getnext)(struct mv88e6xxx_chip *chip,
63149c98c1dSTobias Waldekranz 			   struct mv88e6xxx_stu_entry *entry);
63249c98c1dSTobias Waldekranz 	int (*stu_loadpurge)(struct mv88e6xxx_chip *chip,
63349c98c1dSTobias Waldekranz 			     struct mv88e6xxx_stu_entry *entry);
63449c98c1dSTobias Waldekranz 
635a73ccd61SBrandon Streiff 	/* GPIO operations */
636a73ccd61SBrandon Streiff 	const struct mv88e6xxx_gpio_ops *gpio_ops;
637a73ccd61SBrandon Streiff 
6380d632c3dSBrandon Streiff 	/* Interface to the AVB/PTP registers */
6390d632c3dSBrandon Streiff 	const struct mv88e6xxx_avb_ops *avb_ops;
6409e5baf9bSVivien Didelot 
6419e5baf9bSVivien Didelot 	/* Remote Management Unit operations */
6429e5baf9bSVivien Didelot 	int (*rmu_disable)(struct mv88e6xxx_chip *chip);
6436d2ac8eeSAndrew Lunn 
6446d2ac8eeSAndrew Lunn 	/* Precision Time Protocol operations */
6456d2ac8eeSAndrew Lunn 	const struct mv88e6xxx_ptp_ops *ptp_ops;
6466c422e34SRussell King 
6476c422e34SRussell King 	/* Phylink */
648d4ebf12bSRussell King (Oracle) 	void (*phylink_get_caps)(struct mv88e6xxx_chip *chip, int port,
649d4ebf12bSRussell King (Oracle) 				 struct phylink_config *config);
6501baf0facSChris Packham 
6511baf0facSChris Packham 	/* Max Frame Size */
6521baf0facSChris Packham 	int (*set_max_frame_size)(struct mv88e6xxx_chip *chip, int mtu);
6534d5f2ba7SVivien Didelot };
6544d5f2ba7SVivien Didelot 
6554d5f2ba7SVivien Didelot struct mv88e6xxx_irq_ops {
6564d5f2ba7SVivien Didelot 	/* Action to be performed when the interrupt happens */
6574d5f2ba7SVivien Didelot 	int (*irq_action)(struct mv88e6xxx_chip *chip, int irq);
6584d5f2ba7SVivien Didelot 	/* Setup the hardware to generate the interrupt */
6594d5f2ba7SVivien Didelot 	int (*irq_setup)(struct mv88e6xxx_chip *chip);
6604d5f2ba7SVivien Didelot 	/* Reset the hardware to stop generating the interrupt */
6614d5f2ba7SVivien Didelot 	void (*irq_free)(struct mv88e6xxx_chip *chip);
6624d5f2ba7SVivien Didelot };
6634d5f2ba7SVivien Didelot 
664a73ccd61SBrandon Streiff struct mv88e6xxx_gpio_ops {
665a73ccd61SBrandon Streiff 	/* Get/set data on GPIO pin */
666a73ccd61SBrandon Streiff 	int (*get_data)(struct mv88e6xxx_chip *chip, unsigned int pin);
667a73ccd61SBrandon Streiff 	int (*set_data)(struct mv88e6xxx_chip *chip, unsigned int pin,
668a73ccd61SBrandon Streiff 			int value);
669a73ccd61SBrandon Streiff 
670a73ccd61SBrandon Streiff 	/* get/set GPIO direction */
671a73ccd61SBrandon Streiff 	int (*get_dir)(struct mv88e6xxx_chip *chip, unsigned int pin);
672a73ccd61SBrandon Streiff 	int (*set_dir)(struct mv88e6xxx_chip *chip, unsigned int pin,
673a73ccd61SBrandon Streiff 		       bool input);
674a73ccd61SBrandon Streiff 
675a73ccd61SBrandon Streiff 	/* get/set GPIO pin control */
676a73ccd61SBrandon Streiff 	int (*get_pctl)(struct mv88e6xxx_chip *chip, unsigned int pin,
677a73ccd61SBrandon Streiff 			int *func);
678a73ccd61SBrandon Streiff 	int (*set_pctl)(struct mv88e6xxx_chip *chip, unsigned int pin,
679a73ccd61SBrandon Streiff 			int func);
680a73ccd61SBrandon Streiff };
681a73ccd61SBrandon Streiff 
6820d632c3dSBrandon Streiff struct mv88e6xxx_avb_ops {
6830d632c3dSBrandon Streiff 	/* Access port-scoped Precision Time Protocol registers */
6840d632c3dSBrandon Streiff 	int (*port_ptp_read)(struct mv88e6xxx_chip *chip, int port, int addr,
6850d632c3dSBrandon Streiff 			     u16 *data, int len);
6860d632c3dSBrandon Streiff 	int (*port_ptp_write)(struct mv88e6xxx_chip *chip, int port, int addr,
6870d632c3dSBrandon Streiff 			      u16 data);
6880d632c3dSBrandon Streiff 
6890d632c3dSBrandon Streiff 	/* Access global Precision Time Protocol registers */
6900d632c3dSBrandon Streiff 	int (*ptp_read)(struct mv88e6xxx_chip *chip, int addr, u16 *data,
6910d632c3dSBrandon Streiff 			int len);
6920d632c3dSBrandon Streiff 	int (*ptp_write)(struct mv88e6xxx_chip *chip, int addr, u16 data);
6930d632c3dSBrandon Streiff 
6940d632c3dSBrandon Streiff 	/* Access global Time Application Interface registers */
6950d632c3dSBrandon Streiff 	int (*tai_read)(struct mv88e6xxx_chip *chip, int addr, u16 *data,
6960d632c3dSBrandon Streiff 			int len);
6970d632c3dSBrandon Streiff 	int (*tai_write)(struct mv88e6xxx_chip *chip, int addr, u16 data);
6980d632c3dSBrandon Streiff };
6990d632c3dSBrandon Streiff 
7006d2ac8eeSAndrew Lunn struct mv88e6xxx_ptp_ops {
7016d2ac8eeSAndrew Lunn 	u64 (*clock_read)(const struct cyclecounter *cc);
7026d2ac8eeSAndrew Lunn 	int (*ptp_enable)(struct ptp_clock_info *ptp,
7036d2ac8eeSAndrew Lunn 			  struct ptp_clock_request *rq, int on);
7046d2ac8eeSAndrew Lunn 	int (*ptp_verify)(struct ptp_clock_info *ptp, unsigned int pin,
7056d2ac8eeSAndrew Lunn 			  enum ptp_pin_function func, unsigned int chan);
7066d2ac8eeSAndrew Lunn 	void (*event_work)(struct work_struct *ugly);
707ffc705deSAndrew Lunn 	int (*port_enable)(struct mv88e6xxx_chip *chip, int port);
708ffc705deSAndrew Lunn 	int (*port_disable)(struct mv88e6xxx_chip *chip, int port);
709e2294a8bSAndrew Lunn 	int (*global_enable)(struct mv88e6xxx_chip *chip);
710e2294a8bSAndrew Lunn 	int (*global_disable)(struct mv88e6xxx_chip *chip);
7116d2ac8eeSAndrew Lunn 	int n_ext_ts;
712ffc705deSAndrew Lunn 	int arr0_sts_reg;
713ffc705deSAndrew Lunn 	int arr1_sts_reg;
714ffc705deSAndrew Lunn 	int dep_sts_reg;
71548cb5e03SAndrew Lunn 	u32 rx_filters;
71671509614SHubert Feurstein 	u32 cc_shift;
71771509614SHubert Feurstein 	u32 cc_mult;
71871509614SHubert Feurstein 	u32 cc_mult_num;
71971509614SHubert Feurstein 	u32 cc_mult_dem;
7206d2ac8eeSAndrew Lunn };
7216d2ac8eeSAndrew Lunn 
7224d5f2ba7SVivien Didelot #define STATS_TYPE_PORT		BIT(0)
7234d5f2ba7SVivien Didelot #define STATS_TYPE_BANK0	BIT(1)
7244d5f2ba7SVivien Didelot #define STATS_TYPE_BANK1	BIT(2)
7254d5f2ba7SVivien Didelot 
7264d5f2ba7SVivien Didelot struct mv88e6xxx_hw_stat {
7274d5f2ba7SVivien Didelot 	char string[ETH_GSTRING_LEN];
728cda9f4aaSAndrew Lunn 	size_t size;
7294d5f2ba7SVivien Didelot 	int reg;
7304d5f2ba7SVivien Didelot 	int type;
7314d5f2ba7SVivien Didelot };
7324d5f2ba7SVivien Didelot 
73349c98c1dSTobias Waldekranz static inline bool mv88e6xxx_has_stu(struct mv88e6xxx_chip *chip)
73449c98c1dSTobias Waldekranz {
735afaed2b1STobias Waldekranz 	return chip->info->max_sid > 0 &&
736afaed2b1STobias Waldekranz 		chip->info->ops->stu_loadpurge &&
737afaed2b1STobias Waldekranz 		chip->info->ops->stu_getnext;
73849c98c1dSTobias Waldekranz }
73949c98c1dSTobias Waldekranz 
7404d5f2ba7SVivien Didelot static inline bool mv88e6xxx_has_pvt(struct mv88e6xxx_chip *chip)
7414d5f2ba7SVivien Didelot {
7424d5f2ba7SVivien Didelot 	return chip->info->pvt;
7434d5f2ba7SVivien Didelot }
7444d5f2ba7SVivien Didelot 
745b80dc51bSTobias Waldekranz static inline bool mv88e6xxx_has_lag(struct mv88e6xxx_chip *chip)
746b80dc51bSTobias Waldekranz {
747b80dc51bSTobias Waldekranz 	return !!chip->info->global2_addr;
748b80dc51bSTobias Waldekranz }
749b80dc51bSTobias Waldekranz 
7504d5f2ba7SVivien Didelot static inline unsigned int mv88e6xxx_num_databases(struct mv88e6xxx_chip *chip)
7514d5f2ba7SVivien Didelot {
7524d5f2ba7SVivien Didelot 	return chip->info->num_databases;
7534d5f2ba7SVivien Didelot }
7544d5f2ba7SVivien Didelot 
755d9ea5620SAndrew Lunn static inline unsigned int mv88e6xxx_num_macs(struct  mv88e6xxx_chip *chip)
756d9ea5620SAndrew Lunn {
757d9ea5620SAndrew Lunn 	return chip->info->num_macs;
758d9ea5620SAndrew Lunn }
759d9ea5620SAndrew Lunn 
7604d5f2ba7SVivien Didelot static inline unsigned int mv88e6xxx_num_ports(struct mv88e6xxx_chip *chip)
7614d5f2ba7SVivien Didelot {
7624d5f2ba7SVivien Didelot 	return chip->info->num_ports;
7634d5f2ba7SVivien Didelot }
7644d5f2ba7SVivien Didelot 
765e545f865STobias Waldekranz static inline unsigned int mv88e6xxx_max_vid(struct mv88e6xxx_chip *chip)
766e545f865STobias Waldekranz {
767e545f865STobias Waldekranz 	return chip->info->max_vid;
768e545f865STobias Waldekranz }
769e545f865STobias Waldekranz 
77049c98c1dSTobias Waldekranz static inline unsigned int mv88e6xxx_max_sid(struct mv88e6xxx_chip *chip)
77149c98c1dSTobias Waldekranz {
77249c98c1dSTobias Waldekranz 	return chip->info->max_sid;
77349c98c1dSTobias Waldekranz }
77449c98c1dSTobias Waldekranz 
7754d5f2ba7SVivien Didelot static inline u16 mv88e6xxx_port_mask(struct mv88e6xxx_chip *chip)
7764d5f2ba7SVivien Didelot {
777f1931164SAndrew Lunn 	return GENMASK((s32)mv88e6xxx_num_ports(chip) - 1, 0);
7784d5f2ba7SVivien Didelot }
7794d5f2ba7SVivien Didelot 
780a73ccd61SBrandon Streiff static inline unsigned int mv88e6xxx_num_gpio(struct mv88e6xxx_chip *chip)
781a73ccd61SBrandon Streiff {
782a73ccd61SBrandon Streiff 	return chip->info->num_gpio;
783a73ccd61SBrandon Streiff }
784a73ccd61SBrandon Streiff 
785c857486aSHubert Feurstein static inline bool mv88e6xxx_is_invalid_port(struct mv88e6xxx_chip *chip, int port)
786c857486aSHubert Feurstein {
787c857486aSHubert Feurstein 	return (chip->info->invalid_port_mask & BIT(port)) != 0;
788c857486aSHubert Feurstein }
789c857486aSHubert Feurstein 
790*830763b9SHans J. Schultz static inline void mv88e6xxx_port_set_mab(struct mv88e6xxx_chip *chip,
791*830763b9SHans J. Schultz 					  int port, bool mab)
792*830763b9SHans J. Schultz {
793*830763b9SHans J. Schultz 	chip->ports[port].mab = mab;
794*830763b9SHans J. Schultz }
795*830763b9SHans J. Schultz 
7964d5f2ba7SVivien Didelot int mv88e6xxx_read(struct mv88e6xxx_chip *chip, int addr, int reg, u16 *val);
7974d5f2ba7SVivien Didelot int mv88e6xxx_write(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val);
798683f2244SVivien Didelot int mv88e6xxx_wait_mask(struct mv88e6xxx_chip *chip, int addr, int reg,
799683f2244SVivien Didelot 			u16 mask, u16 val);
80019fb7f69SVivien Didelot int mv88e6xxx_wait_bit(struct mv88e6xxx_chip *chip, int addr, int reg,
80119fb7f69SVivien Didelot 		       int bit, int val);
8024d5f2ba7SVivien Didelot struct mii_bus *mv88e6xxx_default_mdio_bus(struct mv88e6xxx_chip *chip);
8034d5f2ba7SVivien Didelot 
804c9acece0SRasmus Villemoes static inline void mv88e6xxx_reg_lock(struct mv88e6xxx_chip *chip)
805c9acece0SRasmus Villemoes {
806c9acece0SRasmus Villemoes 	mutex_lock(&chip->reg_lock);
807c9acece0SRasmus Villemoes }
808c9acece0SRasmus Villemoes 
809c9acece0SRasmus Villemoes static inline void mv88e6xxx_reg_unlock(struct mv88e6xxx_chip *chip)
810c9acece0SRasmus Villemoes {
811c9acece0SRasmus Villemoes 	mutex_unlock(&chip->reg_lock);
812c9acece0SRasmus Villemoes }
813c9acece0SRasmus Villemoes 
814*830763b9SHans J. Schultz int mv88e6xxx_vtu_walk(struct mv88e6xxx_chip *chip,
815*830763b9SHans J. Schultz 		       int (*cb)(struct mv88e6xxx_chip *chip,
816*830763b9SHans J. Schultz 				 const struct mv88e6xxx_vtu_entry *entry,
817*830763b9SHans J. Schultz 				 void *priv),
818*830763b9SHans J. Schultz 		       void *priv);
819*830763b9SHans J. Schultz 
82090b6dbdfSAndrew Lunn int mv88e6xxx_fid_map(struct mv88e6xxx_chip *chip, unsigned long *bitmap);
82190b6dbdfSAndrew Lunn 
8224d5f2ba7SVivien Didelot #endif /* _MV88E6XXX_CHIP_H */
823