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