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