xref: /openbmc/linux/drivers/net/dsa/mv88e6xxx/chip.h (revision 5d1fbdf2)
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 
214d5f2ba7SVivien Didelot #define MV88E6XXX_N_FID		4096
224d5f2ba7SVivien Didelot 
234d5f2ba7SVivien Didelot /* PVT limits for 4-bit port and 5-bit switch */
244d5f2ba7SVivien Didelot #define MV88E6XXX_MAX_PVT_SWITCHES	32
254d5f2ba7SVivien Didelot #define MV88E6XXX_MAX_PVT_PORTS		16
264d5f2ba7SVivien Didelot 
27a73ccd61SBrandon Streiff #define MV88E6XXX_MAX_GPIO	16
28a73ccd61SBrandon Streiff 
2931bef4e9SVivien Didelot enum mv88e6xxx_egress_mode {
3031bef4e9SVivien Didelot 	MV88E6XXX_EGRESS_MODE_UNMODIFIED,
3131bef4e9SVivien Didelot 	MV88E6XXX_EGRESS_MODE_UNTAGGED,
3231bef4e9SVivien Didelot 	MV88E6XXX_EGRESS_MODE_TAGGED,
3331bef4e9SVivien Didelot 	MV88E6XXX_EGRESS_MODE_ETHERTYPE,
3431bef4e9SVivien Didelot };
3531bef4e9SVivien Didelot 
365c74c54cSIwan R Timmer enum mv88e6xxx_egress_direction {
375c74c54cSIwan R Timmer         MV88E6XXX_EGRESS_DIR_INGRESS,
385c74c54cSIwan R Timmer         MV88E6XXX_EGRESS_DIR_EGRESS,
395c74c54cSIwan R Timmer };
405c74c54cSIwan R Timmer 
414d5f2ba7SVivien Didelot enum mv88e6xxx_frame_mode {
424d5f2ba7SVivien Didelot 	MV88E6XXX_FRAME_MODE_NORMAL,
434d5f2ba7SVivien Didelot 	MV88E6XXX_FRAME_MODE_DSA,
444d5f2ba7SVivien Didelot 	MV88E6XXX_FRAME_MODE_PROVIDER,
454d5f2ba7SVivien Didelot 	MV88E6XXX_FRAME_MODE_ETHERTYPE,
464d5f2ba7SVivien Didelot };
474d5f2ba7SVivien Didelot 
484d5f2ba7SVivien Didelot /* List of supported models */
494d5f2ba7SVivien Didelot enum mv88e6xxx_model {
504d5f2ba7SVivien Didelot 	MV88E6085,
514d5f2ba7SVivien Didelot 	MV88E6095,
524d5f2ba7SVivien Didelot 	MV88E6097,
534d5f2ba7SVivien Didelot 	MV88E6123,
544d5f2ba7SVivien Didelot 	MV88E6131,
554d5f2ba7SVivien Didelot 	MV88E6141,
564d5f2ba7SVivien Didelot 	MV88E6161,
574d5f2ba7SVivien Didelot 	MV88E6165,
584d5f2ba7SVivien Didelot 	MV88E6171,
594d5f2ba7SVivien Didelot 	MV88E6172,
604d5f2ba7SVivien Didelot 	MV88E6175,
614d5f2ba7SVivien Didelot 	MV88E6176,
624d5f2ba7SVivien Didelot 	MV88E6185,
634d5f2ba7SVivien Didelot 	MV88E6190,
644d5f2ba7SVivien Didelot 	MV88E6190X,
654d5f2ba7SVivien Didelot 	MV88E6191,
6649022647SHubert Feurstein 	MV88E6220,
674d5f2ba7SVivien Didelot 	MV88E6240,
681f71836fSRasmus Villemoes 	MV88E6250,
694d5f2ba7SVivien Didelot 	MV88E6290,
704d5f2ba7SVivien Didelot 	MV88E6320,
714d5f2ba7SVivien Didelot 	MV88E6321,
724d5f2ba7SVivien Didelot 	MV88E6341,
734d5f2ba7SVivien Didelot 	MV88E6350,
744d5f2ba7SVivien Didelot 	MV88E6351,
754d5f2ba7SVivien Didelot 	MV88E6352,
764d5f2ba7SVivien Didelot 	MV88E6390,
774d5f2ba7SVivien Didelot 	MV88E6390X,
784d5f2ba7SVivien Didelot };
794d5f2ba7SVivien Didelot 
804d5f2ba7SVivien Didelot enum mv88e6xxx_family {
814d5f2ba7SVivien Didelot 	MV88E6XXX_FAMILY_NONE,
824d5f2ba7SVivien Didelot 	MV88E6XXX_FAMILY_6065,	/* 6031 6035 6061 6065 */
834d5f2ba7SVivien Didelot 	MV88E6XXX_FAMILY_6095,	/* 6092 6095 */
844d5f2ba7SVivien Didelot 	MV88E6XXX_FAMILY_6097,	/* 6046 6085 6096 6097 */
854d5f2ba7SVivien Didelot 	MV88E6XXX_FAMILY_6165,	/* 6123 6161 6165 */
864d5f2ba7SVivien Didelot 	MV88E6XXX_FAMILY_6185,	/* 6108 6121 6122 6131 6152 6155 6182 6185 */
8749022647SHubert Feurstein 	MV88E6XXX_FAMILY_6250,	/* 6220 6250 */
884d5f2ba7SVivien Didelot 	MV88E6XXX_FAMILY_6320,	/* 6320 6321 */
894d5f2ba7SVivien Didelot 	MV88E6XXX_FAMILY_6341,	/* 6141 6341 */
904d5f2ba7SVivien Didelot 	MV88E6XXX_FAMILY_6351,	/* 6171 6175 6350 6351 */
914d5f2ba7SVivien Didelot 	MV88E6XXX_FAMILY_6352,	/* 6172 6176 6240 6352 */
924d5f2ba7SVivien Didelot 	MV88E6XXX_FAMILY_6390,  /* 6190 6190X 6191 6290 6390 6390X */
934d5f2ba7SVivien Didelot };
944d5f2ba7SVivien Didelot 
954d5f2ba7SVivien Didelot struct mv88e6xxx_ops;
964d5f2ba7SVivien Didelot 
974d5f2ba7SVivien Didelot struct mv88e6xxx_info {
984d5f2ba7SVivien Didelot 	enum mv88e6xxx_family family;
994d5f2ba7SVivien Didelot 	u16 prod_num;
1004d5f2ba7SVivien Didelot 	const char *name;
1014d5f2ba7SVivien Didelot 	unsigned int num_databases;
102d9ea5620SAndrew Lunn 	unsigned int num_macs;
1034d5f2ba7SVivien Didelot 	unsigned int num_ports;
104bc393155SAndrew Lunn 	unsigned int num_internal_phys;
105a73ccd61SBrandon Streiff 	unsigned int num_gpio;
1064d5f2ba7SVivien Didelot 	unsigned int max_vid;
1074d5f2ba7SVivien Didelot 	unsigned int port_base_addr;
1089255bacdSAndrew Lunn 	unsigned int phy_base_addr;
1094d5f2ba7SVivien Didelot 	unsigned int global1_addr;
1109069c13aSVivien Didelot 	unsigned int global2_addr;
1114d5f2ba7SVivien Didelot 	unsigned int age_time_coeff;
1124d5f2ba7SVivien Didelot 	unsigned int g1_irqs;
113d6c5e6afSVivien Didelot 	unsigned int g2_irqs;
1144d5f2ba7SVivien Didelot 	bool pvt;
115b3e05aa1SVivien Didelot 
116c857486aSHubert Feurstein 	/* Mark certain ports as invalid. This is required for example for the
117c857486aSHubert Feurstein 	 * MV88E6220 (which is in general a MV88E6250 with 7 ports) but the
118c857486aSHubert Feurstein 	 * ports 2-4 are not routet to pins.
119c857486aSHubert Feurstein 	 */
120c857486aSHubert Feurstein 	unsigned int invalid_port_mask;
121b3e05aa1SVivien Didelot 	/* Multi-chip Addressing Mode.
122b3e05aa1SVivien Didelot 	 * Some chips respond to only 2 registers of its own SMI device address
123b3e05aa1SVivien Didelot 	 * when it is non-zero, and use indirect access to internal registers.
124b3e05aa1SVivien Didelot 	 */
125b3e05aa1SVivien Didelot 	bool multi_chip;
126f30a19b8SRasmus Villemoes 	/* Dual-chip Addressing Mode
127f30a19b8SRasmus Villemoes 	 * Some chips respond to only half of the 32 SMI addresses,
128f30a19b8SRasmus Villemoes 	 * allowing two to coexist on the same SMI interface.
129f30a19b8SRasmus Villemoes 	 */
130f30a19b8SRasmus Villemoes 	bool dual_chip;
131f30a19b8SRasmus Villemoes 
1324d5f2ba7SVivien Didelot 	enum dsa_tag_protocol tag_protocol;
1334d5f2ba7SVivien Didelot 
1344d5f2ba7SVivien Didelot 	/* Mask for FromPort and ToPort value of PortVec used in ATU Move
1354d5f2ba7SVivien Didelot 	 * operation. 0 means that the ATU Move operation is not supported.
1364d5f2ba7SVivien Didelot 	 */
1374d5f2ba7SVivien Didelot 	u8 atu_move_port_mask;
1384d5f2ba7SVivien Didelot 	const struct mv88e6xxx_ops *ops;
1392fa8d3afSBrandon Streiff 
1402fa8d3afSBrandon Streiff 	/* Supports PTP */
1412fa8d3afSBrandon Streiff 	bool ptp_support;
1424d5f2ba7SVivien Didelot };
1434d5f2ba7SVivien Didelot 
1444d5f2ba7SVivien Didelot struct mv88e6xxx_atu_entry {
1454d5f2ba7SVivien Didelot 	u8	state;
1464d5f2ba7SVivien Didelot 	bool	trunk;
1474d5f2ba7SVivien Didelot 	u16	portvec;
1484d5f2ba7SVivien Didelot 	u8	mac[ETH_ALEN];
1494d5f2ba7SVivien Didelot };
1504d5f2ba7SVivien Didelot 
1514d5f2ba7SVivien Didelot struct mv88e6xxx_vtu_entry {
1524d5f2ba7SVivien Didelot 	u16	vid;
1534d5f2ba7SVivien Didelot 	u16	fid;
1544d5f2ba7SVivien Didelot 	u8	sid;
1554d5f2ba7SVivien Didelot 	bool	valid;
1564d5f2ba7SVivien Didelot 	u8	member[DSA_MAX_PORTS];
1574d5f2ba7SVivien Didelot 	u8	state[DSA_MAX_PORTS];
1584d5f2ba7SVivien Didelot };
1594d5f2ba7SVivien Didelot 
1604d5f2ba7SVivien Didelot struct mv88e6xxx_bus_ops;
1614d5f2ba7SVivien Didelot struct mv88e6xxx_irq_ops;
162a73ccd61SBrandon Streiff struct mv88e6xxx_gpio_ops;
1630d632c3dSBrandon Streiff struct mv88e6xxx_avb_ops;
1646d2ac8eeSAndrew Lunn struct mv88e6xxx_ptp_ops;
1654d5f2ba7SVivien Didelot 
1664d5f2ba7SVivien Didelot struct mv88e6xxx_irq {
1674d5f2ba7SVivien Didelot 	u16 masked;
1684d5f2ba7SVivien Didelot 	struct irq_chip chip;
1694d5f2ba7SVivien Didelot 	struct irq_domain *domain;
1704d5f2ba7SVivien Didelot 	unsigned int nirqs;
1714d5f2ba7SVivien Didelot };
1724d5f2ba7SVivien Didelot 
173c6fe0ad2SBrandon Streiff /* state flags for mv88e6xxx_port_hwtstamp::state */
174c6fe0ad2SBrandon Streiff enum {
175c6fe0ad2SBrandon Streiff 	MV88E6XXX_HWTSTAMP_ENABLED,
176c6fe0ad2SBrandon Streiff 	MV88E6XXX_HWTSTAMP_TX_IN_PROGRESS,
177c6fe0ad2SBrandon Streiff };
178c6fe0ad2SBrandon Streiff 
179c6fe0ad2SBrandon Streiff struct mv88e6xxx_port_hwtstamp {
180c6fe0ad2SBrandon Streiff 	/* Port index */
181c6fe0ad2SBrandon Streiff 	int port_id;
182c6fe0ad2SBrandon Streiff 
183c6fe0ad2SBrandon Streiff 	/* Timestamping state */
184c6fe0ad2SBrandon Streiff 	unsigned long state;
185c6fe0ad2SBrandon Streiff 
186c6fe0ad2SBrandon Streiff 	/* Resources for receive timestamping */
187c6fe0ad2SBrandon Streiff 	struct sk_buff_head rx_queue;
188c6fe0ad2SBrandon Streiff 	struct sk_buff_head rx_queue2;
189c6fe0ad2SBrandon Streiff 
190c6fe0ad2SBrandon Streiff 	/* Resources for transmit timestamping */
191c6fe0ad2SBrandon Streiff 	unsigned long tx_tstamp_start;
192c6fe0ad2SBrandon Streiff 	struct sk_buff *tx_skb;
193c6fe0ad2SBrandon Streiff 	u16 tx_seq_id;
194c6fe0ad2SBrandon Streiff 
195c6fe0ad2SBrandon Streiff 	/* Current timestamp configuration */
196c6fe0ad2SBrandon Streiff 	struct hwtstamp_config tstamp_config;
197c6fe0ad2SBrandon Streiff };
198c6fe0ad2SBrandon Streiff 
199f3a2cd32SVivien Didelot enum mv88e6xxx_policy_mapping {
200f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_MAPPING_DA,
201f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_MAPPING_SA,
202f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_MAPPING_VTU,
203f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_MAPPING_ETYPE,
204f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_MAPPING_PPPOE,
205f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_MAPPING_VBAS,
206f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_MAPPING_OPT82,
207f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_MAPPING_UDP,
208f3a2cd32SVivien Didelot };
209f3a2cd32SVivien Didelot 
210f3a2cd32SVivien Didelot enum mv88e6xxx_policy_action {
211f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_ACTION_NORMAL,
212f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_ACTION_MIRROR,
213f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_ACTION_TRAP,
214f3a2cd32SVivien Didelot 	MV88E6XXX_POLICY_ACTION_DISCARD,
215f3a2cd32SVivien Didelot };
216f3a2cd32SVivien Didelot 
217da7dc875SVivien Didelot struct mv88e6xxx_policy {
218da7dc875SVivien Didelot 	enum mv88e6xxx_policy_mapping mapping;
219da7dc875SVivien Didelot 	enum mv88e6xxx_policy_action action;
220da7dc875SVivien Didelot 	struct ethtool_rx_flow_spec fs;
221da7dc875SVivien Didelot 	u8 addr[ETH_ALEN];
222da7dc875SVivien Didelot 	int port;
223da7dc875SVivien Didelot 	u16 vid;
224da7dc875SVivien Didelot };
225da7dc875SVivien Didelot 
226cda9f4aaSAndrew Lunn struct mv88e6xxx_port {
2277b898469SAndrew Lunn 	struct mv88e6xxx_chip *chip;
2287b898469SAndrew Lunn 	int port;
229cda9f4aaSAndrew Lunn 	u64 serdes_stats[2];
23065f60e45SAndrew Lunn 	u64 atu_member_violation;
23165f60e45SAndrew Lunn 	u64 atu_miss_violation;
23265f60e45SAndrew Lunn 	u64 atu_full_violation;
23365f60e45SAndrew Lunn 	u64 vtu_member_violation;
23465f60e45SAndrew Lunn 	u64 vtu_miss_violation;
2352d2e1dd2SAndrew Lunn 	u8 cmode;
236f0942e00SIwan R Timmer 	bool mirror_ingress;
237f0942e00SIwan R Timmer 	bool mirror_egress;
238f441ed0fSVivien Didelot 	unsigned int serdes_irq;
2395d1fbdf2SAndrew Lunn 	char serdes_irq_name[64];
240cda9f4aaSAndrew Lunn };
241cda9f4aaSAndrew Lunn 
2424d5f2ba7SVivien Didelot struct mv88e6xxx_chip {
2434d5f2ba7SVivien Didelot 	const struct mv88e6xxx_info *info;
2444d5f2ba7SVivien Didelot 
2454d5f2ba7SVivien Didelot 	/* The dsa_switch this private structure is related to */
2464d5f2ba7SVivien Didelot 	struct dsa_switch *ds;
2474d5f2ba7SVivien Didelot 
2484d5f2ba7SVivien Didelot 	/* The device this structure is associated to */
2494d5f2ba7SVivien Didelot 	struct device *dev;
2504d5f2ba7SVivien Didelot 
2514d5f2ba7SVivien Didelot 	/* This mutex protects the access to the switch registers */
2524d5f2ba7SVivien Didelot 	struct mutex reg_lock;
2534d5f2ba7SVivien Didelot 
2544d5f2ba7SVivien Didelot 	/* The MII bus and the address on the bus that is used to
2554d5f2ba7SVivien Didelot 	 * communication with the switch
2564d5f2ba7SVivien Didelot 	 */
2574d5f2ba7SVivien Didelot 	const struct mv88e6xxx_bus_ops *smi_ops;
2584d5f2ba7SVivien Didelot 	struct mii_bus *bus;
2594d5f2ba7SVivien Didelot 	int sw_addr;
2604d5f2ba7SVivien Didelot 
2614d5f2ba7SVivien Didelot 	/* Handles automatic disabling and re-enabling of the PHY
2624d5f2ba7SVivien Didelot 	 * polling unit.
2634d5f2ba7SVivien Didelot 	 */
2644d5f2ba7SVivien Didelot 	const struct mv88e6xxx_bus_ops *phy_ops;
2654d5f2ba7SVivien Didelot 	struct mutex		ppu_mutex;
2664d5f2ba7SVivien Didelot 	int			ppu_disabled;
2674d5f2ba7SVivien Didelot 	struct work_struct	ppu_work;
2684d5f2ba7SVivien Didelot 	struct timer_list	ppu_timer;
2694d5f2ba7SVivien Didelot 
2704d5f2ba7SVivien Didelot 	/* This mutex serialises access to the statistics unit.
2714d5f2ba7SVivien Didelot 	 * Hold this mutex over snapshot + dump sequences.
2724d5f2ba7SVivien Didelot 	 */
2734d5f2ba7SVivien Didelot 	struct mutex	stats_mutex;
2744d5f2ba7SVivien Didelot 
2754d5f2ba7SVivien Didelot 	/* A switch may have a GPIO line tied to its reset pin. Parse
2764d5f2ba7SVivien Didelot 	 * this from the device tree, and use it before performing
2774d5f2ba7SVivien Didelot 	 * switch soft reset.
2784d5f2ba7SVivien Didelot 	 */
2794d5f2ba7SVivien Didelot 	struct gpio_desc *reset;
2804d5f2ba7SVivien Didelot 
2814d5f2ba7SVivien Didelot 	/* set to size of eeprom if supported by the switch */
28200baabe5SAndrew Lunn 	u32 eeprom_len;
2834d5f2ba7SVivien Didelot 
2844d5f2ba7SVivien Didelot 	/* List of mdio busses */
2854d5f2ba7SVivien Didelot 	struct list_head mdios;
2864d5f2ba7SVivien Didelot 
287da7dc875SVivien Didelot 	/* Policy Control List IDs and rules */
288da7dc875SVivien Didelot 	struct idr policies;
289da7dc875SVivien Didelot 
2904d5f2ba7SVivien Didelot 	/* There can be two interrupt controllers, which are chained
2914d5f2ba7SVivien Didelot 	 * off a GPIO as interrupt source
2924d5f2ba7SVivien Didelot 	 */
2934d5f2ba7SVivien Didelot 	struct mv88e6xxx_irq g1_irq;
2944d5f2ba7SVivien Didelot 	struct mv88e6xxx_irq g2_irq;
2954d5f2ba7SVivien Didelot 	int irq;
2965d1fbdf2SAndrew Lunn 	char irq_name[64];
2974d5f2ba7SVivien Didelot 	int device_irq;
2985d1fbdf2SAndrew Lunn 	char device_irq_name[64];
2994d5f2ba7SVivien Didelot 	int watchdog_irq;
3005d1fbdf2SAndrew Lunn 	char watchdog_irq_name[64];
301cda9f4aaSAndrew Lunn 
3020977644cSAndrew Lunn 	int atu_prob_irq;
3035d1fbdf2SAndrew Lunn 	char atu_prob_irq_name[64];
30462eb1162SAndrew Lunn 	int vtu_prob_irq;
3055d1fbdf2SAndrew Lunn 	char vtu_prob_irq_name[64];
306294d711eSAndrew Lunn 	struct kthread_worker *kworker;
307294d711eSAndrew Lunn 	struct kthread_delayed_work irq_poll_work;
3082fa8d3afSBrandon Streiff 
309a73ccd61SBrandon Streiff 	/* GPIO resources */
310a73ccd61SBrandon Streiff 	u8 gpio_data[2];
311a73ccd61SBrandon Streiff 
3122fa8d3afSBrandon Streiff 	/* This cyclecounter abstracts the switch PTP time.
3132fa8d3afSBrandon Streiff 	 * reg_lock must be held for any operation that read()s.
3142fa8d3afSBrandon Streiff 	 */
3152fa8d3afSBrandon Streiff 	struct cyclecounter	tstamp_cc;
3162fa8d3afSBrandon Streiff 	struct timecounter	tstamp_tc;
3172fa8d3afSBrandon Streiff 	struct delayed_work	overflow_work;
3182fa8d3afSBrandon Streiff 
3192fa8d3afSBrandon Streiff 	struct ptp_clock	*ptp_clock;
3202fa8d3afSBrandon Streiff 	struct ptp_clock_info	ptp_clock_info;
3214eb3be29SBrandon Streiff 	struct delayed_work	tai_event_work;
3224eb3be29SBrandon Streiff 	struct ptp_pin_desc	pin_config[MV88E6XXX_MAX_GPIO];
3234eb3be29SBrandon Streiff 	u16 trig_config;
3244eb3be29SBrandon Streiff 	u16 evcap_config;
325e2294a8bSAndrew Lunn 	u16 enable_count;
326c6fe0ad2SBrandon Streiff 
327f0942e00SIwan R Timmer 	/* Current ingress and egress monitor ports */
328f0942e00SIwan R Timmer 	int egress_dest_port;
329f0942e00SIwan R Timmer 	int ingress_dest_port;
330f0942e00SIwan R Timmer 
331c6fe0ad2SBrandon Streiff 	/* Per-port timestamping resources. */
332c6fe0ad2SBrandon Streiff 	struct mv88e6xxx_port_hwtstamp port_hwtstamp[DSA_MAX_PORTS];
333cda9f4aaSAndrew Lunn 
334cda9f4aaSAndrew Lunn 	/* Array of port structures. */
335cda9f4aaSAndrew Lunn 	struct mv88e6xxx_port ports[DSA_MAX_PORTS];
3364d5f2ba7SVivien Didelot };
3374d5f2ba7SVivien Didelot 
3384d5f2ba7SVivien Didelot struct mv88e6xxx_bus_ops {
3394d5f2ba7SVivien Didelot 	int (*read)(struct mv88e6xxx_chip *chip, int addr, int reg, u16 *val);
3404d5f2ba7SVivien Didelot 	int (*write)(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val);
3414d5f2ba7SVivien Didelot };
3424d5f2ba7SVivien Didelot 
3434d5f2ba7SVivien Didelot struct mv88e6xxx_mdio_bus {
3444d5f2ba7SVivien Didelot 	struct mii_bus *bus;
3454d5f2ba7SVivien Didelot 	struct mv88e6xxx_chip *chip;
3464d5f2ba7SVivien Didelot 	struct list_head list;
3474d5f2ba7SVivien Didelot 	bool external;
3484d5f2ba7SVivien Didelot };
3494d5f2ba7SVivien Didelot 
3504d5f2ba7SVivien Didelot struct mv88e6xxx_ops {
351ea89098eSAndrew Lunn 	/* Switch Setup Errata, called early in the switch setup to
352ea89098eSAndrew Lunn 	 * allow any errata actions to be performed
353ea89098eSAndrew Lunn 	 */
354ea89098eSAndrew Lunn 	int (*setup_errata)(struct mv88e6xxx_chip *chip);
355ea89098eSAndrew Lunn 
35693e18d61SVivien Didelot 	int (*ieee_pri_map)(struct mv88e6xxx_chip *chip);
35793e18d61SVivien Didelot 	int (*ip_pri_map)(struct mv88e6xxx_chip *chip);
35893e18d61SVivien Didelot 
359cd8da8bbSVivien Didelot 	/* Ingress Rate Limit unit (IRL) operations */
360cd8da8bbSVivien Didelot 	int (*irl_init_all)(struct mv88e6xxx_chip *chip, int port);
361cd8da8bbSVivien Didelot 
3624d5f2ba7SVivien Didelot 	int (*get_eeprom)(struct mv88e6xxx_chip *chip,
3634d5f2ba7SVivien Didelot 			  struct ethtool_eeprom *eeprom, u8 *data);
3644d5f2ba7SVivien Didelot 	int (*set_eeprom)(struct mv88e6xxx_chip *chip,
3654d5f2ba7SVivien Didelot 			  struct ethtool_eeprom *eeprom, u8 *data);
3664d5f2ba7SVivien Didelot 
3674d5f2ba7SVivien Didelot 	int (*set_switch_mac)(struct mv88e6xxx_chip *chip, u8 *addr);
3684d5f2ba7SVivien Didelot 
3694d5f2ba7SVivien Didelot 	int (*phy_read)(struct mv88e6xxx_chip *chip,
3704d5f2ba7SVivien Didelot 			struct mii_bus *bus,
3714d5f2ba7SVivien Didelot 			int addr, int reg, u16 *val);
3724d5f2ba7SVivien Didelot 	int (*phy_write)(struct mv88e6xxx_chip *chip,
3734d5f2ba7SVivien Didelot 			 struct mii_bus *bus,
3744d5f2ba7SVivien Didelot 			 int addr, int reg, u16 val);
3754d5f2ba7SVivien Didelot 
3769e907d73SVivien Didelot 	/* Priority Override Table operations */
3779e907d73SVivien Didelot 	int (*pot_clear)(struct mv88e6xxx_chip *chip);
3789e907d73SVivien Didelot 
3794d5f2ba7SVivien Didelot 	/* PHY Polling Unit (PPU) operations */
3804d5f2ba7SVivien Didelot 	int (*ppu_enable)(struct mv88e6xxx_chip *chip);
3814d5f2ba7SVivien Didelot 	int (*ppu_disable)(struct mv88e6xxx_chip *chip);
3824d5f2ba7SVivien Didelot 
3834d5f2ba7SVivien Didelot 	/* Switch Software Reset */
3844d5f2ba7SVivien Didelot 	int (*reset)(struct mv88e6xxx_chip *chip);
3854d5f2ba7SVivien Didelot 
3864d5f2ba7SVivien Didelot 	/* RGMII Receive/Transmit Timing Control
3874d5f2ba7SVivien Didelot 	 * Add delay on PHY_INTERFACE_MODE_RGMII_*ID, no delay otherwise.
3884d5f2ba7SVivien Didelot 	 */
3894d5f2ba7SVivien Didelot 	int (*port_set_rgmii_delay)(struct mv88e6xxx_chip *chip, int port,
3904d5f2ba7SVivien Didelot 				    phy_interface_t mode);
3914d5f2ba7SVivien Didelot 
3924d5f2ba7SVivien Didelot #define LINK_FORCED_DOWN	0
3934d5f2ba7SVivien Didelot #define LINK_FORCED_UP		1
3944d5f2ba7SVivien Didelot #define LINK_UNFORCED		-2
3954d5f2ba7SVivien Didelot 
3964d5f2ba7SVivien Didelot 	/* Port's MAC link state
3974d5f2ba7SVivien Didelot 	 * Use LINK_FORCED_UP or LINK_FORCED_DOWN to force link up or down,
3984d5f2ba7SVivien Didelot 	 * or LINK_UNFORCED for normal link detection.
3994d5f2ba7SVivien Didelot 	 */
4004d5f2ba7SVivien Didelot 	int (*port_set_link)(struct mv88e6xxx_chip *chip, int port, int link);
4014d5f2ba7SVivien Didelot 
4024d5f2ba7SVivien Didelot #define DUPLEX_UNFORCED		-2
4034d5f2ba7SVivien Didelot 
4044d5f2ba7SVivien Didelot 	/* Port's MAC duplex mode
4054d5f2ba7SVivien Didelot 	 *
4064d5f2ba7SVivien Didelot 	 * Use DUPLEX_HALF or DUPLEX_FULL to force half or full duplex,
4074d5f2ba7SVivien Didelot 	 * or DUPLEX_UNFORCED for normal duplex detection.
4084d5f2ba7SVivien Didelot 	 */
4094d5f2ba7SVivien Didelot 	int (*port_set_duplex)(struct mv88e6xxx_chip *chip, int port, int dup);
4104d5f2ba7SVivien Didelot 
41154186b91SAndrew Lunn #define PAUSE_ON		1
41254186b91SAndrew Lunn #define PAUSE_OFF		0
41354186b91SAndrew Lunn 
41454186b91SAndrew Lunn 	/* Enable/disable sending Pause */
41554186b91SAndrew Lunn 	int (*port_set_pause)(struct mv88e6xxx_chip *chip, int port,
41654186b91SAndrew Lunn 			      int pause);
41754186b91SAndrew Lunn 
4184d5f2ba7SVivien Didelot #define SPEED_MAX		INT_MAX
4194d5f2ba7SVivien Didelot #define SPEED_UNFORCED		-2
4204d5f2ba7SVivien Didelot 
4214d5f2ba7SVivien Didelot 	/* Port's MAC speed (in Mbps)
4224d5f2ba7SVivien Didelot 	 *
4234d5f2ba7SVivien Didelot 	 * Depending on the chip, 10, 100, 200, 1000, 2500, 10000 are valid.
4244d5f2ba7SVivien Didelot 	 * Use SPEED_UNFORCED for normal detection, SPEED_MAX for max value.
4254d5f2ba7SVivien Didelot 	 */
4264d5f2ba7SVivien Didelot 	int (*port_set_speed)(struct mv88e6xxx_chip *chip, int port, int speed);
4274d5f2ba7SVivien Didelot 
4287cbbee05SAndrew Lunn 	/* What interface mode should be used for maximum speed? */
4297cbbee05SAndrew Lunn 	phy_interface_t (*port_max_speed_mode)(int port);
4307cbbee05SAndrew Lunn 
4314d5f2ba7SVivien Didelot 	int (*port_tag_remap)(struct mv88e6xxx_chip *chip, int port);
4324d5f2ba7SVivien Didelot 
433f3a2cd32SVivien Didelot 	int (*port_set_policy)(struct mv88e6xxx_chip *chip, int port,
434f3a2cd32SVivien Didelot 			       enum mv88e6xxx_policy_mapping mapping,
435f3a2cd32SVivien Didelot 			       enum mv88e6xxx_policy_action action);
436f3a2cd32SVivien Didelot 
4374d5f2ba7SVivien Didelot 	int (*port_set_frame_mode)(struct mv88e6xxx_chip *chip, int port,
4384d5f2ba7SVivien Didelot 				   enum mv88e6xxx_frame_mode mode);
4394d5f2ba7SVivien Didelot 	int (*port_set_egress_floods)(struct mv88e6xxx_chip *chip, int port,
4404d5f2ba7SVivien Didelot 				      bool unicast, bool multicast);
4414d5f2ba7SVivien Didelot 	int (*port_set_ether_type)(struct mv88e6xxx_chip *chip, int port,
4424d5f2ba7SVivien Didelot 				   u16 etype);
443cd782656SVivien Didelot 	int (*port_set_jumbo_size)(struct mv88e6xxx_chip *chip, int port,
444cd782656SVivien Didelot 				   size_t size);
4454d5f2ba7SVivien Didelot 
4464d5f2ba7SVivien Didelot 	int (*port_egress_rate_limiting)(struct mv88e6xxx_chip *chip, int port);
4470898432cSVivien Didelot 	int (*port_pause_limit)(struct mv88e6xxx_chip *chip, int port, u8 in,
4480898432cSVivien Didelot 				u8 out);
4494d5f2ba7SVivien Didelot 	int (*port_disable_learn_limit)(struct mv88e6xxx_chip *chip, int port);
4504d5f2ba7SVivien Didelot 	int (*port_disable_pri_override)(struct mv88e6xxx_chip *chip, int port);
451121b8fe2SHubert Feurstein 	int (*port_setup_message_port)(struct mv88e6xxx_chip *chip, int port);
4524d5f2ba7SVivien Didelot 
4534d5f2ba7SVivien Didelot 	/* CMODE control what PHY mode the MAC will use, eg. SGMII, RGMII, etc.
4544d5f2ba7SVivien Didelot 	 * Some chips allow this to be configured on specific ports.
4554d5f2ba7SVivien Didelot 	 */
4564d5f2ba7SVivien Didelot 	int (*port_set_cmode)(struct mv88e6xxx_chip *chip, int port,
4574d5f2ba7SVivien Didelot 			      phy_interface_t mode);
4582d2e1dd2SAndrew Lunn 	int (*port_get_cmode)(struct mv88e6xxx_chip *chip, int port, u8 *cmode);
4594d5f2ba7SVivien Didelot 
4604d5f2ba7SVivien Didelot 	/* Some devices have a per port register indicating what is
4614d5f2ba7SVivien Didelot 	 * the upstream port this port should forward to.
4624d5f2ba7SVivien Didelot 	 */
4634d5f2ba7SVivien Didelot 	int (*port_set_upstream_port)(struct mv88e6xxx_chip *chip, int port,
4644d5f2ba7SVivien Didelot 				      int upstream_port);
4656c422e34SRussell King 	/* Return the port link state, as required by phylink */
4666c422e34SRussell King 	int (*port_link_state)(struct mv88e6xxx_chip *chip, int port,
4676c422e34SRussell King 			       struct phylink_link_state *state);
4684d5f2ba7SVivien Didelot 
4694d5f2ba7SVivien Didelot 	/* Snapshot the statistics for a port. The statistics can then
4704d5f2ba7SVivien Didelot 	 * be read back a leisure but still with a consistent view.
4714d5f2ba7SVivien Didelot 	 */
4724d5f2ba7SVivien Didelot 	int (*stats_snapshot)(struct mv88e6xxx_chip *chip, int port);
4734d5f2ba7SVivien Didelot 
4744d5f2ba7SVivien Didelot 	/* Set the histogram mode for statistics, when the control registers
4754d5f2ba7SVivien Didelot 	 * are separated out of the STATS_OP register.
4764d5f2ba7SVivien Didelot 	 */
4774d5f2ba7SVivien Didelot 	int (*stats_set_histogram)(struct mv88e6xxx_chip *chip);
4784d5f2ba7SVivien Didelot 
4794d5f2ba7SVivien Didelot 	/* Return the number of strings describing statistics */
4804d5f2ba7SVivien Didelot 	int (*stats_get_sset_count)(struct mv88e6xxx_chip *chip);
481436fe17dSAndrew Lunn 	int (*stats_get_strings)(struct mv88e6xxx_chip *chip,  uint8_t *data);
482436fe17dSAndrew Lunn 	int (*stats_get_stats)(struct mv88e6xxx_chip *chip,  int port,
4834d5f2ba7SVivien Didelot 			       uint64_t *data);
484fa8d1179SVivien Didelot 	int (*set_cpu_port)(struct mv88e6xxx_chip *chip, int port);
4855c74c54cSIwan R Timmer 	int (*set_egress_port)(struct mv88e6xxx_chip *chip,
4865c74c54cSIwan R Timmer 			       enum mv88e6xxx_egress_direction direction,
4875c74c54cSIwan R Timmer 			       int port);
48802317e68SVivien Didelot 
48902317e68SVivien Didelot #define MV88E6XXX_CASCADE_PORT_NONE		0xe
49002317e68SVivien Didelot #define MV88E6XXX_CASCADE_PORT_MULTIPLE		0xf
49102317e68SVivien Didelot 
49202317e68SVivien Didelot 	int (*set_cascade_port)(struct mv88e6xxx_chip *chip, int port);
49302317e68SVivien Didelot 
4944d5f2ba7SVivien Didelot 	const struct mv88e6xxx_irq_ops *watchdog_ops;
4954d5f2ba7SVivien Didelot 
4964d5f2ba7SVivien Didelot 	int (*mgmt_rsvd2cpu)(struct mv88e6xxx_chip *chip);
4974d5f2ba7SVivien Didelot 
4984d5f2ba7SVivien Didelot 	/* Power on/off a SERDES interface */
499dc272f60SVivien Didelot 	int (*serdes_power)(struct mv88e6xxx_chip *chip, int port, u8 lane,
500dc272f60SVivien Didelot 			    bool up);
5014d5f2ba7SVivien Didelot 
50217deaf5cSMarek Behún 	/* SERDES lane mapping */
5035122d4ecSVivien Didelot 	u8 (*serdes_get_lane)(struct mv88e6xxx_chip *chip, int port);
50417deaf5cSMarek Behún 
505efd1ba6aSAndrew Lunn 	/* SERDES interrupt handling */
5064241ef52SVivien Didelot 	unsigned int (*serdes_irq_mapping)(struct mv88e6xxx_chip *chip,
5074241ef52SVivien Didelot 					   int port);
50861a46b41SVivien Didelot 	int (*serdes_irq_enable)(struct mv88e6xxx_chip *chip, int port, u8 lane,
50961a46b41SVivien Didelot 				 bool enable);
510907b9b9fSVivien Didelot 	irqreturn_t (*serdes_irq_status)(struct mv88e6xxx_chip *chip, int port,
511907b9b9fSVivien Didelot 					 u8 lane);
512efd1ba6aSAndrew Lunn 
513436fe17dSAndrew Lunn 	/* Statistics from the SERDES interface */
514436fe17dSAndrew Lunn 	int (*serdes_get_sset_count)(struct mv88e6xxx_chip *chip, int port);
51565f60e45SAndrew Lunn 	int (*serdes_get_strings)(struct mv88e6xxx_chip *chip,  int port,
516436fe17dSAndrew Lunn 				  uint8_t *data);
51765f60e45SAndrew Lunn 	int (*serdes_get_stats)(struct mv88e6xxx_chip *chip,  int port,
518436fe17dSAndrew Lunn 				uint64_t *data);
519436fe17dSAndrew Lunn 
52023e8b470SAndrew Lunn 	/* Address Translation Unit operations */
52123e8b470SAndrew Lunn 	int (*atu_get_hash)(struct mv88e6xxx_chip *chip, u8 *hash);
52223e8b470SAndrew Lunn 	int (*atu_set_hash)(struct mv88e6xxx_chip *chip, u8 hash);
52323e8b470SAndrew Lunn 
5244d5f2ba7SVivien Didelot 	/* VLAN Translation Unit operations */
5254d5f2ba7SVivien Didelot 	int (*vtu_getnext)(struct mv88e6xxx_chip *chip,
5264d5f2ba7SVivien Didelot 			   struct mv88e6xxx_vtu_entry *entry);
5274d5f2ba7SVivien Didelot 	int (*vtu_loadpurge)(struct mv88e6xxx_chip *chip,
5284d5f2ba7SVivien Didelot 			     struct mv88e6xxx_vtu_entry *entry);
5290d632c3dSBrandon Streiff 
530a73ccd61SBrandon Streiff 	/* GPIO operations */
531a73ccd61SBrandon Streiff 	const struct mv88e6xxx_gpio_ops *gpio_ops;
532a73ccd61SBrandon Streiff 
5330d632c3dSBrandon Streiff 	/* Interface to the AVB/PTP registers */
5340d632c3dSBrandon Streiff 	const struct mv88e6xxx_avb_ops *avb_ops;
5359e5baf9bSVivien Didelot 
5369e5baf9bSVivien Didelot 	/* Remote Management Unit operations */
5379e5baf9bSVivien Didelot 	int (*rmu_disable)(struct mv88e6xxx_chip *chip);
5386d2ac8eeSAndrew Lunn 
5396d2ac8eeSAndrew Lunn 	/* Precision Time Protocol operations */
5406d2ac8eeSAndrew Lunn 	const struct mv88e6xxx_ptp_ops *ptp_ops;
5416c422e34SRussell King 
5426c422e34SRussell King 	/* Phylink */
5436c422e34SRussell King 	void (*phylink_validate)(struct mv88e6xxx_chip *chip, int port,
5446c422e34SRussell King 				 unsigned long *mask,
5456c422e34SRussell King 				 struct phylink_link_state *state);
5464d5f2ba7SVivien Didelot };
5474d5f2ba7SVivien Didelot 
5484d5f2ba7SVivien Didelot struct mv88e6xxx_irq_ops {
5494d5f2ba7SVivien Didelot 	/* Action to be performed when the interrupt happens */
5504d5f2ba7SVivien Didelot 	int (*irq_action)(struct mv88e6xxx_chip *chip, int irq);
5514d5f2ba7SVivien Didelot 	/* Setup the hardware to generate the interrupt */
5524d5f2ba7SVivien Didelot 	int (*irq_setup)(struct mv88e6xxx_chip *chip);
5534d5f2ba7SVivien Didelot 	/* Reset the hardware to stop generating the interrupt */
5544d5f2ba7SVivien Didelot 	void (*irq_free)(struct mv88e6xxx_chip *chip);
5554d5f2ba7SVivien Didelot };
5564d5f2ba7SVivien Didelot 
557a73ccd61SBrandon Streiff struct mv88e6xxx_gpio_ops {
558a73ccd61SBrandon Streiff 	/* Get/set data on GPIO pin */
559a73ccd61SBrandon Streiff 	int (*get_data)(struct mv88e6xxx_chip *chip, unsigned int pin);
560a73ccd61SBrandon Streiff 	int (*set_data)(struct mv88e6xxx_chip *chip, unsigned int pin,
561a73ccd61SBrandon Streiff 			int value);
562a73ccd61SBrandon Streiff 
563a73ccd61SBrandon Streiff 	/* get/set GPIO direction */
564a73ccd61SBrandon Streiff 	int (*get_dir)(struct mv88e6xxx_chip *chip, unsigned int pin);
565a73ccd61SBrandon Streiff 	int (*set_dir)(struct mv88e6xxx_chip *chip, unsigned int pin,
566a73ccd61SBrandon Streiff 		       bool input);
567a73ccd61SBrandon Streiff 
568a73ccd61SBrandon Streiff 	/* get/set GPIO pin control */
569a73ccd61SBrandon Streiff 	int (*get_pctl)(struct mv88e6xxx_chip *chip, unsigned int pin,
570a73ccd61SBrandon Streiff 			int *func);
571a73ccd61SBrandon Streiff 	int (*set_pctl)(struct mv88e6xxx_chip *chip, unsigned int pin,
572a73ccd61SBrandon Streiff 			int func);
573a73ccd61SBrandon Streiff };
574a73ccd61SBrandon Streiff 
5750d632c3dSBrandon Streiff struct mv88e6xxx_avb_ops {
5760d632c3dSBrandon Streiff 	/* Access port-scoped Precision Time Protocol registers */
5770d632c3dSBrandon Streiff 	int (*port_ptp_read)(struct mv88e6xxx_chip *chip, int port, int addr,
5780d632c3dSBrandon Streiff 			     u16 *data, int len);
5790d632c3dSBrandon Streiff 	int (*port_ptp_write)(struct mv88e6xxx_chip *chip, int port, int addr,
5800d632c3dSBrandon Streiff 			      u16 data);
5810d632c3dSBrandon Streiff 
5820d632c3dSBrandon Streiff 	/* Access global Precision Time Protocol registers */
5830d632c3dSBrandon Streiff 	int (*ptp_read)(struct mv88e6xxx_chip *chip, int addr, u16 *data,
5840d632c3dSBrandon Streiff 			int len);
5850d632c3dSBrandon Streiff 	int (*ptp_write)(struct mv88e6xxx_chip *chip, int addr, u16 data);
5860d632c3dSBrandon Streiff 
5870d632c3dSBrandon Streiff 	/* Access global Time Application Interface registers */
5880d632c3dSBrandon Streiff 	int (*tai_read)(struct mv88e6xxx_chip *chip, int addr, u16 *data,
5890d632c3dSBrandon Streiff 			int len);
5900d632c3dSBrandon Streiff 	int (*tai_write)(struct mv88e6xxx_chip *chip, int addr, u16 data);
5910d632c3dSBrandon Streiff };
5920d632c3dSBrandon Streiff 
5936d2ac8eeSAndrew Lunn struct mv88e6xxx_ptp_ops {
5946d2ac8eeSAndrew Lunn 	u64 (*clock_read)(const struct cyclecounter *cc);
5956d2ac8eeSAndrew Lunn 	int (*ptp_enable)(struct ptp_clock_info *ptp,
5966d2ac8eeSAndrew Lunn 			  struct ptp_clock_request *rq, int on);
5976d2ac8eeSAndrew Lunn 	int (*ptp_verify)(struct ptp_clock_info *ptp, unsigned int pin,
5986d2ac8eeSAndrew Lunn 			  enum ptp_pin_function func, unsigned int chan);
5996d2ac8eeSAndrew Lunn 	void (*event_work)(struct work_struct *ugly);
600ffc705deSAndrew Lunn 	int (*port_enable)(struct mv88e6xxx_chip *chip, int port);
601ffc705deSAndrew Lunn 	int (*port_disable)(struct mv88e6xxx_chip *chip, int port);
602e2294a8bSAndrew Lunn 	int (*global_enable)(struct mv88e6xxx_chip *chip);
603e2294a8bSAndrew Lunn 	int (*global_disable)(struct mv88e6xxx_chip *chip);
6046d2ac8eeSAndrew Lunn 	int n_ext_ts;
605ffc705deSAndrew Lunn 	int arr0_sts_reg;
606ffc705deSAndrew Lunn 	int arr1_sts_reg;
607ffc705deSAndrew Lunn 	int dep_sts_reg;
60848cb5e03SAndrew Lunn 	u32 rx_filters;
60971509614SHubert Feurstein 	u32 cc_shift;
61071509614SHubert Feurstein 	u32 cc_mult;
61171509614SHubert Feurstein 	u32 cc_mult_num;
61271509614SHubert Feurstein 	u32 cc_mult_dem;
6136d2ac8eeSAndrew Lunn };
6146d2ac8eeSAndrew Lunn 
6154d5f2ba7SVivien Didelot #define STATS_TYPE_PORT		BIT(0)
6164d5f2ba7SVivien Didelot #define STATS_TYPE_BANK0	BIT(1)
6174d5f2ba7SVivien Didelot #define STATS_TYPE_BANK1	BIT(2)
6184d5f2ba7SVivien Didelot 
6194d5f2ba7SVivien Didelot struct mv88e6xxx_hw_stat {
6204d5f2ba7SVivien Didelot 	char string[ETH_GSTRING_LEN];
621cda9f4aaSAndrew Lunn 	size_t size;
6224d5f2ba7SVivien Didelot 	int reg;
6234d5f2ba7SVivien Didelot 	int type;
6244d5f2ba7SVivien Didelot };
6254d5f2ba7SVivien Didelot 
6264d5f2ba7SVivien Didelot static inline bool mv88e6xxx_has_pvt(struct mv88e6xxx_chip *chip)
6274d5f2ba7SVivien Didelot {
6284d5f2ba7SVivien Didelot 	return chip->info->pvt;
6294d5f2ba7SVivien Didelot }
6304d5f2ba7SVivien Didelot 
6314d5f2ba7SVivien Didelot static inline unsigned int mv88e6xxx_num_databases(struct mv88e6xxx_chip *chip)
6324d5f2ba7SVivien Didelot {
6334d5f2ba7SVivien Didelot 	return chip->info->num_databases;
6344d5f2ba7SVivien Didelot }
6354d5f2ba7SVivien Didelot 
636d9ea5620SAndrew Lunn static inline unsigned int mv88e6xxx_num_macs(struct  mv88e6xxx_chip *chip)
637d9ea5620SAndrew Lunn {
638d9ea5620SAndrew Lunn 	return chip->info->num_macs;
639d9ea5620SAndrew Lunn }
640d9ea5620SAndrew Lunn 
6414d5f2ba7SVivien Didelot static inline unsigned int mv88e6xxx_num_ports(struct mv88e6xxx_chip *chip)
6424d5f2ba7SVivien Didelot {
6434d5f2ba7SVivien Didelot 	return chip->info->num_ports;
6444d5f2ba7SVivien Didelot }
6454d5f2ba7SVivien Didelot 
6464d5f2ba7SVivien Didelot static inline u16 mv88e6xxx_port_mask(struct mv88e6xxx_chip *chip)
6474d5f2ba7SVivien Didelot {
6484d5f2ba7SVivien Didelot 	return GENMASK(mv88e6xxx_num_ports(chip) - 1, 0);
6494d5f2ba7SVivien Didelot }
6504d5f2ba7SVivien Didelot 
651a73ccd61SBrandon Streiff static inline unsigned int mv88e6xxx_num_gpio(struct mv88e6xxx_chip *chip)
652a73ccd61SBrandon Streiff {
653a73ccd61SBrandon Streiff 	return chip->info->num_gpio;
654a73ccd61SBrandon Streiff }
655a73ccd61SBrandon Streiff 
656c857486aSHubert Feurstein static inline bool mv88e6xxx_is_invalid_port(struct mv88e6xxx_chip *chip, int port)
657c857486aSHubert Feurstein {
658c857486aSHubert Feurstein 	return (chip->info->invalid_port_mask & BIT(port)) != 0;
659c857486aSHubert Feurstein }
660c857486aSHubert Feurstein 
6614d5f2ba7SVivien Didelot int mv88e6xxx_read(struct mv88e6xxx_chip *chip, int addr, int reg, u16 *val);
6624d5f2ba7SVivien Didelot int mv88e6xxx_write(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val);
663683f2244SVivien Didelot int mv88e6xxx_wait_mask(struct mv88e6xxx_chip *chip, int addr, int reg,
664683f2244SVivien Didelot 			u16 mask, u16 val);
66519fb7f69SVivien Didelot int mv88e6xxx_wait_bit(struct mv88e6xxx_chip *chip, int addr, int reg,
66619fb7f69SVivien Didelot 		       int bit, int val);
66772d8b4fdSHeiner Kallweit int mv88e6xxx_port_setup_mac(struct mv88e6xxx_chip *chip, int port, int link,
66872d8b4fdSHeiner Kallweit 			     int speed, int duplex, int pause,
66972d8b4fdSHeiner Kallweit 			     phy_interface_t mode);
6704d5f2ba7SVivien Didelot struct mii_bus *mv88e6xxx_default_mdio_bus(struct mv88e6xxx_chip *chip);
6714d5f2ba7SVivien Didelot 
672c9acece0SRasmus Villemoes static inline void mv88e6xxx_reg_lock(struct mv88e6xxx_chip *chip)
673c9acece0SRasmus Villemoes {
674c9acece0SRasmus Villemoes 	mutex_lock(&chip->reg_lock);
675c9acece0SRasmus Villemoes }
676c9acece0SRasmus Villemoes 
677c9acece0SRasmus Villemoes static inline void mv88e6xxx_reg_unlock(struct mv88e6xxx_chip *chip)
678c9acece0SRasmus Villemoes {
679c9acece0SRasmus Villemoes 	mutex_unlock(&chip->reg_lock);
680c9acece0SRasmus Villemoes }
681c9acece0SRasmus Villemoes 
6824d5f2ba7SVivien Didelot #endif /* _MV88E6XXX_CHIP_H */
683