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, 66de776d0dSPavana Sharma MV88E6191X, 67de776d0dSPavana Sharma MV88E6193X, 6849022647SHubert Feurstein MV88E6220, 694d5f2ba7SVivien Didelot MV88E6240, 701f71836fSRasmus Villemoes MV88E6250, 714d5f2ba7SVivien Didelot MV88E6290, 724d5f2ba7SVivien Didelot MV88E6320, 734d5f2ba7SVivien Didelot MV88E6321, 744d5f2ba7SVivien Didelot MV88E6341, 754d5f2ba7SVivien Didelot MV88E6350, 764d5f2ba7SVivien Didelot MV88E6351, 774d5f2ba7SVivien Didelot MV88E6352, 784d5f2ba7SVivien Didelot MV88E6390, 794d5f2ba7SVivien Didelot MV88E6390X, 80de776d0dSPavana Sharma MV88E6393X, 814d5f2ba7SVivien Didelot }; 824d5f2ba7SVivien Didelot 834d5f2ba7SVivien Didelot enum mv88e6xxx_family { 844d5f2ba7SVivien Didelot MV88E6XXX_FAMILY_NONE, 854d5f2ba7SVivien Didelot MV88E6XXX_FAMILY_6065, /* 6031 6035 6061 6065 */ 864d5f2ba7SVivien Didelot MV88E6XXX_FAMILY_6095, /* 6092 6095 */ 874d5f2ba7SVivien Didelot MV88E6XXX_FAMILY_6097, /* 6046 6085 6096 6097 */ 884d5f2ba7SVivien Didelot MV88E6XXX_FAMILY_6165, /* 6123 6161 6165 */ 894d5f2ba7SVivien Didelot MV88E6XXX_FAMILY_6185, /* 6108 6121 6122 6131 6152 6155 6182 6185 */ 9049022647SHubert Feurstein MV88E6XXX_FAMILY_6250, /* 6220 6250 */ 914d5f2ba7SVivien Didelot MV88E6XXX_FAMILY_6320, /* 6320 6321 */ 924d5f2ba7SVivien Didelot MV88E6XXX_FAMILY_6341, /* 6141 6341 */ 934d5f2ba7SVivien Didelot MV88E6XXX_FAMILY_6351, /* 6171 6175 6350 6351 */ 944d5f2ba7SVivien Didelot MV88E6XXX_FAMILY_6352, /* 6172 6176 6240 6352 */ 954d5f2ba7SVivien Didelot MV88E6XXX_FAMILY_6390, /* 6190 6190X 6191 6290 6390 6390X */ 96de776d0dSPavana Sharma MV88E6XXX_FAMILY_6393, /* 6191X 6193X 6393X */ 974d5f2ba7SVivien Didelot }; 984d5f2ba7SVivien Didelot 99*670bb80fSTobias Waldekranz /** 100*670bb80fSTobias Waldekranz * enum mv88e6xxx_edsa_support - Ethertype DSA tag support level 101*670bb80fSTobias Waldekranz * @MV88E6XXX_EDSA_UNSUPPORTED: Device has no support for EDSA tags 102*670bb80fSTobias Waldekranz * @MV88E6XXX_EDSA_UNDOCUMENTED: Documentation indicates that 103*670bb80fSTobias Waldekranz * egressing FORWARD frames with an EDSA 104*670bb80fSTobias Waldekranz * tag is reserved for future use, but 105*670bb80fSTobias Waldekranz * empirical data shows that this mode 106*670bb80fSTobias Waldekranz * is supported. 107*670bb80fSTobias Waldekranz * @MV88E6XXX_EDSA_SUPPORTED: EDSA tags are fully supported. 108*670bb80fSTobias Waldekranz */ 109*670bb80fSTobias Waldekranz enum mv88e6xxx_edsa_support { 110*670bb80fSTobias Waldekranz MV88E6XXX_EDSA_UNSUPPORTED = 0, 111*670bb80fSTobias Waldekranz MV88E6XXX_EDSA_UNDOCUMENTED, 112*670bb80fSTobias Waldekranz MV88E6XXX_EDSA_SUPPORTED, 113*670bb80fSTobias Waldekranz }; 114*670bb80fSTobias Waldekranz 1154d5f2ba7SVivien Didelot struct mv88e6xxx_ops; 1164d5f2ba7SVivien Didelot 1174d5f2ba7SVivien Didelot struct mv88e6xxx_info { 1184d5f2ba7SVivien Didelot enum mv88e6xxx_family family; 1194d5f2ba7SVivien Didelot u16 prod_num; 1204d5f2ba7SVivien Didelot const char *name; 1214d5f2ba7SVivien Didelot unsigned int num_databases; 122d9ea5620SAndrew Lunn unsigned int num_macs; 1234d5f2ba7SVivien Didelot unsigned int num_ports; 124bc393155SAndrew Lunn unsigned int num_internal_phys; 125a73ccd61SBrandon Streiff unsigned int num_gpio; 1264d5f2ba7SVivien Didelot unsigned int max_vid; 1274d5f2ba7SVivien Didelot unsigned int port_base_addr; 1289255bacdSAndrew Lunn unsigned int phy_base_addr; 1294d5f2ba7SVivien Didelot unsigned int global1_addr; 1309069c13aSVivien Didelot unsigned int global2_addr; 1314d5f2ba7SVivien Didelot unsigned int age_time_coeff; 1324d5f2ba7SVivien Didelot unsigned int g1_irqs; 133d6c5e6afSVivien Didelot unsigned int g2_irqs; 1344d5f2ba7SVivien Didelot bool pvt; 135b3e05aa1SVivien Didelot 136c857486aSHubert Feurstein /* Mark certain ports as invalid. This is required for example for the 137c857486aSHubert Feurstein * MV88E6220 (which is in general a MV88E6250 with 7 ports) but the 138c857486aSHubert Feurstein * ports 2-4 are not routet to pins. 139c857486aSHubert Feurstein */ 140c857486aSHubert Feurstein unsigned int invalid_port_mask; 141b3e05aa1SVivien Didelot /* Multi-chip Addressing Mode. 142b3e05aa1SVivien Didelot * Some chips respond to only 2 registers of its own SMI device address 143b3e05aa1SVivien Didelot * when it is non-zero, and use indirect access to internal registers. 144b3e05aa1SVivien Didelot */ 145b3e05aa1SVivien Didelot bool multi_chip; 146f30a19b8SRasmus Villemoes /* Dual-chip Addressing Mode 147f30a19b8SRasmus Villemoes * Some chips respond to only half of the 32 SMI addresses, 148f30a19b8SRasmus Villemoes * allowing two to coexist on the same SMI interface. 149f30a19b8SRasmus Villemoes */ 150f30a19b8SRasmus Villemoes bool dual_chip; 151f30a19b8SRasmus Villemoes 152*670bb80fSTobias Waldekranz enum mv88e6xxx_edsa_support edsa_support; 1534d5f2ba7SVivien Didelot 1544d5f2ba7SVivien Didelot /* Mask for FromPort and ToPort value of PortVec used in ATU Move 1554d5f2ba7SVivien Didelot * operation. 0 means that the ATU Move operation is not supported. 1564d5f2ba7SVivien Didelot */ 1574d5f2ba7SVivien Didelot u8 atu_move_port_mask; 1584d5f2ba7SVivien Didelot const struct mv88e6xxx_ops *ops; 1592fa8d3afSBrandon Streiff 1602fa8d3afSBrandon Streiff /* Supports PTP */ 1612fa8d3afSBrandon Streiff bool ptp_support; 1624d5f2ba7SVivien Didelot }; 1634d5f2ba7SVivien Didelot 1644d5f2ba7SVivien Didelot struct mv88e6xxx_atu_entry { 1654d5f2ba7SVivien Didelot u8 state; 1664d5f2ba7SVivien Didelot bool trunk; 1674d5f2ba7SVivien Didelot u16 portvec; 1684d5f2ba7SVivien Didelot u8 mac[ETH_ALEN]; 1694d5f2ba7SVivien Didelot }; 1704d5f2ba7SVivien Didelot 1714d5f2ba7SVivien Didelot struct mv88e6xxx_vtu_entry { 1724d5f2ba7SVivien Didelot u16 vid; 1734d5f2ba7SVivien Didelot u16 fid; 1744d5f2ba7SVivien Didelot u8 sid; 1754d5f2ba7SVivien Didelot bool valid; 1764d5f2ba7SVivien Didelot u8 member[DSA_MAX_PORTS]; 1774d5f2ba7SVivien Didelot u8 state[DSA_MAX_PORTS]; 1784d5f2ba7SVivien Didelot }; 1794d5f2ba7SVivien Didelot 1804d5f2ba7SVivien Didelot struct mv88e6xxx_bus_ops; 1814d5f2ba7SVivien Didelot struct mv88e6xxx_irq_ops; 182a73ccd61SBrandon Streiff struct mv88e6xxx_gpio_ops; 1830d632c3dSBrandon Streiff struct mv88e6xxx_avb_ops; 1846d2ac8eeSAndrew Lunn struct mv88e6xxx_ptp_ops; 1854d5f2ba7SVivien Didelot 1864d5f2ba7SVivien Didelot struct mv88e6xxx_irq { 1874d5f2ba7SVivien Didelot u16 masked; 1884d5f2ba7SVivien Didelot struct irq_chip chip; 1894d5f2ba7SVivien Didelot struct irq_domain *domain; 190f1931164SAndrew Lunn int nirqs; 1914d5f2ba7SVivien Didelot }; 1924d5f2ba7SVivien Didelot 193c6fe0ad2SBrandon Streiff /* state flags for mv88e6xxx_port_hwtstamp::state */ 194c6fe0ad2SBrandon Streiff enum { 195c6fe0ad2SBrandon Streiff MV88E6XXX_HWTSTAMP_ENABLED, 196c6fe0ad2SBrandon Streiff MV88E6XXX_HWTSTAMP_TX_IN_PROGRESS, 197c6fe0ad2SBrandon Streiff }; 198c6fe0ad2SBrandon Streiff 199c6fe0ad2SBrandon Streiff struct mv88e6xxx_port_hwtstamp { 200c6fe0ad2SBrandon Streiff /* Port index */ 201c6fe0ad2SBrandon Streiff int port_id; 202c6fe0ad2SBrandon Streiff 203c6fe0ad2SBrandon Streiff /* Timestamping state */ 204c6fe0ad2SBrandon Streiff unsigned long state; 205c6fe0ad2SBrandon Streiff 206c6fe0ad2SBrandon Streiff /* Resources for receive timestamping */ 207c6fe0ad2SBrandon Streiff struct sk_buff_head rx_queue; 208c6fe0ad2SBrandon Streiff struct sk_buff_head rx_queue2; 209c6fe0ad2SBrandon Streiff 210c6fe0ad2SBrandon Streiff /* Resources for transmit timestamping */ 211c6fe0ad2SBrandon Streiff unsigned long tx_tstamp_start; 212c6fe0ad2SBrandon Streiff struct sk_buff *tx_skb; 213c6fe0ad2SBrandon Streiff u16 tx_seq_id; 214c6fe0ad2SBrandon Streiff 215c6fe0ad2SBrandon Streiff /* Current timestamp configuration */ 216c6fe0ad2SBrandon Streiff struct hwtstamp_config tstamp_config; 217c6fe0ad2SBrandon Streiff }; 218c6fe0ad2SBrandon Streiff 219f3a2cd32SVivien Didelot enum mv88e6xxx_policy_mapping { 220f3a2cd32SVivien Didelot MV88E6XXX_POLICY_MAPPING_DA, 221f3a2cd32SVivien Didelot MV88E6XXX_POLICY_MAPPING_SA, 222f3a2cd32SVivien Didelot MV88E6XXX_POLICY_MAPPING_VTU, 223f3a2cd32SVivien Didelot MV88E6XXX_POLICY_MAPPING_ETYPE, 224f3a2cd32SVivien Didelot MV88E6XXX_POLICY_MAPPING_PPPOE, 225f3a2cd32SVivien Didelot MV88E6XXX_POLICY_MAPPING_VBAS, 226f3a2cd32SVivien Didelot MV88E6XXX_POLICY_MAPPING_OPT82, 227f3a2cd32SVivien Didelot MV88E6XXX_POLICY_MAPPING_UDP, 228f3a2cd32SVivien Didelot }; 229f3a2cd32SVivien Didelot 230f3a2cd32SVivien Didelot enum mv88e6xxx_policy_action { 231f3a2cd32SVivien Didelot MV88E6XXX_POLICY_ACTION_NORMAL, 232f3a2cd32SVivien Didelot MV88E6XXX_POLICY_ACTION_MIRROR, 233f3a2cd32SVivien Didelot MV88E6XXX_POLICY_ACTION_TRAP, 234f3a2cd32SVivien Didelot MV88E6XXX_POLICY_ACTION_DISCARD, 235f3a2cd32SVivien Didelot }; 236f3a2cd32SVivien Didelot 237da7dc875SVivien Didelot struct mv88e6xxx_policy { 238da7dc875SVivien Didelot enum mv88e6xxx_policy_mapping mapping; 239da7dc875SVivien Didelot enum mv88e6xxx_policy_action action; 240da7dc875SVivien Didelot struct ethtool_rx_flow_spec fs; 241da7dc875SVivien Didelot u8 addr[ETH_ALEN]; 242da7dc875SVivien Didelot int port; 243da7dc875SVivien Didelot u16 vid; 244da7dc875SVivien Didelot }; 245da7dc875SVivien Didelot 246cda9f4aaSAndrew Lunn struct mv88e6xxx_port { 2477b898469SAndrew Lunn struct mv88e6xxx_chip *chip; 2487b898469SAndrew Lunn int port; 249cda9f4aaSAndrew Lunn u64 serdes_stats[2]; 25065f60e45SAndrew Lunn u64 atu_member_violation; 25165f60e45SAndrew Lunn u64 atu_miss_violation; 25265f60e45SAndrew Lunn u64 atu_full_violation; 25365f60e45SAndrew Lunn u64 vtu_member_violation; 25465f60e45SAndrew Lunn u64 vtu_miss_violation; 255fad58190SRussell King phy_interface_t interface; 2562d2e1dd2SAndrew Lunn u8 cmode; 257f0942e00SIwan R Timmer bool mirror_ingress; 258f0942e00SIwan R Timmer bool mirror_egress; 259f441ed0fSVivien Didelot unsigned int serdes_irq; 2605d1fbdf2SAndrew Lunn char serdes_irq_name[64]; 261bfb25542SAndrew Lunn struct devlink_region *region; 262bfb25542SAndrew Lunn }; 263bfb25542SAndrew Lunn 264bfb25542SAndrew Lunn enum mv88e6xxx_region_id { 265bfb25542SAndrew Lunn MV88E6XXX_REGION_GLOBAL1 = 0, 266bfb25542SAndrew Lunn MV88E6XXX_REGION_GLOBAL2, 267bfb25542SAndrew Lunn MV88E6XXX_REGION_ATU, 268ca4d632aSTobias Waldekranz MV88E6XXX_REGION_VTU, 269bfb25542SAndrew Lunn 270bfb25542SAndrew Lunn _MV88E6XXX_REGION_MAX, 271bfb25542SAndrew Lunn }; 272bfb25542SAndrew Lunn 273bfb25542SAndrew Lunn struct mv88e6xxx_region_priv { 274bfb25542SAndrew Lunn enum mv88e6xxx_region_id id; 275cda9f4aaSAndrew Lunn }; 276cda9f4aaSAndrew Lunn 2774d5f2ba7SVivien Didelot struct mv88e6xxx_chip { 2784d5f2ba7SVivien Didelot const struct mv88e6xxx_info *info; 2794d5f2ba7SVivien Didelot 280*670bb80fSTobias Waldekranz /* Currently configured tagging protocol */ 281*670bb80fSTobias Waldekranz enum dsa_tag_protocol tag_protocol; 282*670bb80fSTobias Waldekranz 2834d5f2ba7SVivien Didelot /* The dsa_switch this private structure is related to */ 2844d5f2ba7SVivien Didelot struct dsa_switch *ds; 2854d5f2ba7SVivien Didelot 2864d5f2ba7SVivien Didelot /* The device this structure is associated to */ 2874d5f2ba7SVivien Didelot struct device *dev; 2884d5f2ba7SVivien Didelot 2894d5f2ba7SVivien Didelot /* This mutex protects the access to the switch registers */ 2904d5f2ba7SVivien Didelot struct mutex reg_lock; 2914d5f2ba7SVivien Didelot 2924d5f2ba7SVivien Didelot /* The MII bus and the address on the bus that is used to 2934d5f2ba7SVivien Didelot * communication with the switch 2944d5f2ba7SVivien Didelot */ 2954d5f2ba7SVivien Didelot const struct mv88e6xxx_bus_ops *smi_ops; 2964d5f2ba7SVivien Didelot struct mii_bus *bus; 2974d5f2ba7SVivien Didelot int sw_addr; 2984d5f2ba7SVivien Didelot 2994d5f2ba7SVivien Didelot /* Handles automatic disabling and re-enabling of the PHY 3004d5f2ba7SVivien Didelot * polling unit. 3014d5f2ba7SVivien Didelot */ 3024d5f2ba7SVivien Didelot const struct mv88e6xxx_bus_ops *phy_ops; 3034d5f2ba7SVivien Didelot struct mutex ppu_mutex; 3044d5f2ba7SVivien Didelot int ppu_disabled; 3054d5f2ba7SVivien Didelot struct work_struct ppu_work; 3064d5f2ba7SVivien Didelot struct timer_list ppu_timer; 3074d5f2ba7SVivien Didelot 3084d5f2ba7SVivien Didelot /* This mutex serialises access to the statistics unit. 3094d5f2ba7SVivien Didelot * Hold this mutex over snapshot + dump sequences. 3104d5f2ba7SVivien Didelot */ 3114d5f2ba7SVivien Didelot struct mutex stats_mutex; 3124d5f2ba7SVivien Didelot 3134d5f2ba7SVivien Didelot /* A switch may have a GPIO line tied to its reset pin. Parse 3144d5f2ba7SVivien Didelot * this from the device tree, and use it before performing 3154d5f2ba7SVivien Didelot * switch soft reset. 3164d5f2ba7SVivien Didelot */ 3174d5f2ba7SVivien Didelot struct gpio_desc *reset; 3184d5f2ba7SVivien Didelot 3194d5f2ba7SVivien Didelot /* set to size of eeprom if supported by the switch */ 32000baabe5SAndrew Lunn u32 eeprom_len; 3214d5f2ba7SVivien Didelot 3224d5f2ba7SVivien Didelot /* List of mdio busses */ 3234d5f2ba7SVivien Didelot struct list_head mdios; 3244d5f2ba7SVivien Didelot 325da7dc875SVivien Didelot /* Policy Control List IDs and rules */ 326da7dc875SVivien Didelot struct idr policies; 327da7dc875SVivien Didelot 3284d5f2ba7SVivien Didelot /* There can be two interrupt controllers, which are chained 3294d5f2ba7SVivien Didelot * off a GPIO as interrupt source 3304d5f2ba7SVivien Didelot */ 3314d5f2ba7SVivien Didelot struct mv88e6xxx_irq g1_irq; 3324d5f2ba7SVivien Didelot struct mv88e6xxx_irq g2_irq; 3334d5f2ba7SVivien Didelot int irq; 3345d1fbdf2SAndrew Lunn char irq_name[64]; 3354d5f2ba7SVivien Didelot int device_irq; 3365d1fbdf2SAndrew Lunn char device_irq_name[64]; 3374d5f2ba7SVivien Didelot int watchdog_irq; 3385d1fbdf2SAndrew Lunn char watchdog_irq_name[64]; 339cda9f4aaSAndrew Lunn 3400977644cSAndrew Lunn int atu_prob_irq; 3415d1fbdf2SAndrew Lunn char atu_prob_irq_name[64]; 34262eb1162SAndrew Lunn int vtu_prob_irq; 3435d1fbdf2SAndrew Lunn char vtu_prob_irq_name[64]; 344294d711eSAndrew Lunn struct kthread_worker *kworker; 345294d711eSAndrew Lunn struct kthread_delayed_work irq_poll_work; 3462fa8d3afSBrandon Streiff 347a73ccd61SBrandon Streiff /* GPIO resources */ 348a73ccd61SBrandon Streiff u8 gpio_data[2]; 349a73ccd61SBrandon Streiff 3502fa8d3afSBrandon Streiff /* This cyclecounter abstracts the switch PTP time. 3512fa8d3afSBrandon Streiff * reg_lock must be held for any operation that read()s. 3522fa8d3afSBrandon Streiff */ 3532fa8d3afSBrandon Streiff struct cyclecounter tstamp_cc; 3542fa8d3afSBrandon Streiff struct timecounter tstamp_tc; 3552fa8d3afSBrandon Streiff struct delayed_work overflow_work; 3562fa8d3afSBrandon Streiff 3572fa8d3afSBrandon Streiff struct ptp_clock *ptp_clock; 3582fa8d3afSBrandon Streiff struct ptp_clock_info ptp_clock_info; 3594eb3be29SBrandon Streiff struct delayed_work tai_event_work; 3604eb3be29SBrandon Streiff struct ptp_pin_desc pin_config[MV88E6XXX_MAX_GPIO]; 3614eb3be29SBrandon Streiff u16 trig_config; 3624eb3be29SBrandon Streiff u16 evcap_config; 363e2294a8bSAndrew Lunn u16 enable_count; 364c6fe0ad2SBrandon Streiff 365f0942e00SIwan R Timmer /* Current ingress and egress monitor ports */ 366f0942e00SIwan R Timmer int egress_dest_port; 367f0942e00SIwan R Timmer int ingress_dest_port; 368f0942e00SIwan R Timmer 369c6fe0ad2SBrandon Streiff /* Per-port timestamping resources. */ 370c6fe0ad2SBrandon Streiff struct mv88e6xxx_port_hwtstamp port_hwtstamp[DSA_MAX_PORTS]; 371cda9f4aaSAndrew Lunn 372cda9f4aaSAndrew Lunn /* Array of port structures. */ 373cda9f4aaSAndrew Lunn struct mv88e6xxx_port ports[DSA_MAX_PORTS]; 374bfb25542SAndrew Lunn 375bfb25542SAndrew Lunn /* devlink regions */ 376bfb25542SAndrew Lunn struct devlink_region *regions[_MV88E6XXX_REGION_MAX]; 3774d5f2ba7SVivien Didelot }; 3784d5f2ba7SVivien Didelot 3794d5f2ba7SVivien Didelot struct mv88e6xxx_bus_ops { 3804d5f2ba7SVivien Didelot int (*read)(struct mv88e6xxx_chip *chip, int addr, int reg, u16 *val); 3814d5f2ba7SVivien Didelot int (*write)(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val); 3824d5f2ba7SVivien Didelot }; 3834d5f2ba7SVivien Didelot 3844d5f2ba7SVivien Didelot struct mv88e6xxx_mdio_bus { 3854d5f2ba7SVivien Didelot struct mii_bus *bus; 3864d5f2ba7SVivien Didelot struct mv88e6xxx_chip *chip; 3874d5f2ba7SVivien Didelot struct list_head list; 3884d5f2ba7SVivien Didelot bool external; 3894d5f2ba7SVivien Didelot }; 3904d5f2ba7SVivien Didelot 3914d5f2ba7SVivien Didelot struct mv88e6xxx_ops { 392ea89098eSAndrew Lunn /* Switch Setup Errata, called early in the switch setup to 393ea89098eSAndrew Lunn * allow any errata actions to be performed 394ea89098eSAndrew Lunn */ 395ea89098eSAndrew Lunn int (*setup_errata)(struct mv88e6xxx_chip *chip); 396ea89098eSAndrew Lunn 39793e18d61SVivien Didelot int (*ieee_pri_map)(struct mv88e6xxx_chip *chip); 39893e18d61SVivien Didelot int (*ip_pri_map)(struct mv88e6xxx_chip *chip); 39993e18d61SVivien Didelot 400cd8da8bbSVivien Didelot /* Ingress Rate Limit unit (IRL) operations */ 401cd8da8bbSVivien Didelot int (*irl_init_all)(struct mv88e6xxx_chip *chip, int port); 402cd8da8bbSVivien Didelot 4034d5f2ba7SVivien Didelot int (*get_eeprom)(struct mv88e6xxx_chip *chip, 4044d5f2ba7SVivien Didelot struct ethtool_eeprom *eeprom, u8 *data); 4054d5f2ba7SVivien Didelot int (*set_eeprom)(struct mv88e6xxx_chip *chip, 4064d5f2ba7SVivien Didelot struct ethtool_eeprom *eeprom, u8 *data); 4074d5f2ba7SVivien Didelot 4084d5f2ba7SVivien Didelot int (*set_switch_mac)(struct mv88e6xxx_chip *chip, u8 *addr); 4094d5f2ba7SVivien Didelot 4104d5f2ba7SVivien Didelot int (*phy_read)(struct mv88e6xxx_chip *chip, 4114d5f2ba7SVivien Didelot struct mii_bus *bus, 4124d5f2ba7SVivien Didelot int addr, int reg, u16 *val); 4134d5f2ba7SVivien Didelot int (*phy_write)(struct mv88e6xxx_chip *chip, 4144d5f2ba7SVivien Didelot struct mii_bus *bus, 4154d5f2ba7SVivien Didelot int addr, int reg, u16 val); 4164d5f2ba7SVivien Didelot 4179e907d73SVivien Didelot /* Priority Override Table operations */ 4189e907d73SVivien Didelot int (*pot_clear)(struct mv88e6xxx_chip *chip); 4199e907d73SVivien Didelot 4204d5f2ba7SVivien Didelot /* PHY Polling Unit (PPU) operations */ 4214d5f2ba7SVivien Didelot int (*ppu_enable)(struct mv88e6xxx_chip *chip); 4224d5f2ba7SVivien Didelot int (*ppu_disable)(struct mv88e6xxx_chip *chip); 4234d5f2ba7SVivien Didelot 4244d5f2ba7SVivien Didelot /* Switch Software Reset */ 4254d5f2ba7SVivien Didelot int (*reset)(struct mv88e6xxx_chip *chip); 4264d5f2ba7SVivien Didelot 4274d5f2ba7SVivien Didelot /* RGMII Receive/Transmit Timing Control 4284d5f2ba7SVivien Didelot * Add delay on PHY_INTERFACE_MODE_RGMII_*ID, no delay otherwise. 4294d5f2ba7SVivien Didelot */ 4304d5f2ba7SVivien Didelot int (*port_set_rgmii_delay)(struct mv88e6xxx_chip *chip, int port, 4314d5f2ba7SVivien Didelot phy_interface_t mode); 4324d5f2ba7SVivien Didelot 4334d5f2ba7SVivien Didelot #define LINK_FORCED_DOWN 0 4344d5f2ba7SVivien Didelot #define LINK_FORCED_UP 1 4354d5f2ba7SVivien Didelot #define LINK_UNFORCED -2 4364d5f2ba7SVivien Didelot 4374d5f2ba7SVivien Didelot /* Port's MAC link state 4384d5f2ba7SVivien Didelot * Use LINK_FORCED_UP or LINK_FORCED_DOWN to force link up or down, 4394d5f2ba7SVivien Didelot * or LINK_UNFORCED for normal link detection. 4404d5f2ba7SVivien Didelot */ 4414d5f2ba7SVivien Didelot int (*port_set_link)(struct mv88e6xxx_chip *chip, int port, int link); 4424d5f2ba7SVivien Didelot 4434efe7662SChris Packham /* Synchronise the port link state with that of the SERDES 4444efe7662SChris Packham */ 4454efe7662SChris Packham int (*port_sync_link)(struct mv88e6xxx_chip *chip, int port, unsigned int mode, bool isup); 4464efe7662SChris Packham 44754186b91SAndrew Lunn #define PAUSE_ON 1 44854186b91SAndrew Lunn #define PAUSE_OFF 0 44954186b91SAndrew Lunn 45054186b91SAndrew Lunn /* Enable/disable sending Pause */ 45154186b91SAndrew Lunn int (*port_set_pause)(struct mv88e6xxx_chip *chip, int port, 45254186b91SAndrew Lunn int pause); 45354186b91SAndrew Lunn 4544d5f2ba7SVivien Didelot #define SPEED_MAX INT_MAX 4554d5f2ba7SVivien Didelot #define SPEED_UNFORCED -2 456f365c6f7SRussell King #define DUPLEX_UNFORCED -2 4574d5f2ba7SVivien Didelot 458f365c6f7SRussell King /* Port's MAC speed (in Mbps) and MAC duplex mode 4594d5f2ba7SVivien Didelot * 4604d5f2ba7SVivien Didelot * Depending on the chip, 10, 100, 200, 1000, 2500, 10000 are valid. 4614d5f2ba7SVivien Didelot * Use SPEED_UNFORCED for normal detection, SPEED_MAX for max value. 462f365c6f7SRussell King * 463f365c6f7SRussell King * Use DUPLEX_HALF or DUPLEX_FULL to force half or full duplex, 464f365c6f7SRussell King * or DUPLEX_UNFORCED for normal duplex detection. 4654d5f2ba7SVivien Didelot */ 466f365c6f7SRussell King int (*port_set_speed_duplex)(struct mv88e6xxx_chip *chip, int port, 467f365c6f7SRussell King int speed, int duplex); 4684d5f2ba7SVivien Didelot 4697cbbee05SAndrew Lunn /* What interface mode should be used for maximum speed? */ 4707cbbee05SAndrew Lunn phy_interface_t (*port_max_speed_mode)(int port); 4717cbbee05SAndrew Lunn 4724d5f2ba7SVivien Didelot int (*port_tag_remap)(struct mv88e6xxx_chip *chip, int port); 4734d5f2ba7SVivien Didelot 474f3a2cd32SVivien Didelot int (*port_set_policy)(struct mv88e6xxx_chip *chip, int port, 475f3a2cd32SVivien Didelot enum mv88e6xxx_policy_mapping mapping, 476f3a2cd32SVivien Didelot enum mv88e6xxx_policy_action action); 477f3a2cd32SVivien Didelot 4784d5f2ba7SVivien Didelot int (*port_set_frame_mode)(struct mv88e6xxx_chip *chip, int port, 4794d5f2ba7SVivien Didelot enum mv88e6xxx_frame_mode mode); 480a8b659e7SVladimir Oltean int (*port_set_ucast_flood)(struct mv88e6xxx_chip *chip, int port, 481a8b659e7SVladimir Oltean bool unicast); 482a8b659e7SVladimir Oltean int (*port_set_mcast_flood)(struct mv88e6xxx_chip *chip, int port, 483a8b659e7SVladimir Oltean bool multicast); 4844d5f2ba7SVivien Didelot int (*port_set_ether_type)(struct mv88e6xxx_chip *chip, int port, 4854d5f2ba7SVivien Didelot u16 etype); 486cd782656SVivien Didelot int (*port_set_jumbo_size)(struct mv88e6xxx_chip *chip, int port, 487cd782656SVivien Didelot size_t size); 4884d5f2ba7SVivien Didelot 4894d5f2ba7SVivien Didelot int (*port_egress_rate_limiting)(struct mv88e6xxx_chip *chip, int port); 4900898432cSVivien Didelot int (*port_pause_limit)(struct mv88e6xxx_chip *chip, int port, u8 in, 4910898432cSVivien Didelot u8 out); 4924d5f2ba7SVivien Didelot int (*port_disable_learn_limit)(struct mv88e6xxx_chip *chip, int port); 4934d5f2ba7SVivien Didelot int (*port_disable_pri_override)(struct mv88e6xxx_chip *chip, int port); 494121b8fe2SHubert Feurstein int (*port_setup_message_port)(struct mv88e6xxx_chip *chip, int port); 4954d5f2ba7SVivien Didelot 4964d5f2ba7SVivien Didelot /* CMODE control what PHY mode the MAC will use, eg. SGMII, RGMII, etc. 4974d5f2ba7SVivien Didelot * Some chips allow this to be configured on specific ports. 4984d5f2ba7SVivien Didelot */ 4994d5f2ba7SVivien Didelot int (*port_set_cmode)(struct mv88e6xxx_chip *chip, int port, 5004d5f2ba7SVivien Didelot phy_interface_t mode); 5012d2e1dd2SAndrew Lunn int (*port_get_cmode)(struct mv88e6xxx_chip *chip, int port, u8 *cmode); 5024d5f2ba7SVivien Didelot 5034d5f2ba7SVivien Didelot /* Some devices have a per port register indicating what is 5044d5f2ba7SVivien Didelot * the upstream port this port should forward to. 5054d5f2ba7SVivien Didelot */ 5064d5f2ba7SVivien Didelot int (*port_set_upstream_port)(struct mv88e6xxx_chip *chip, int port, 5074d5f2ba7SVivien Didelot int upstream_port); 5084d5f2ba7SVivien Didelot 5094d5f2ba7SVivien Didelot /* Snapshot the statistics for a port. The statistics can then 5104d5f2ba7SVivien Didelot * be read back a leisure but still with a consistent view. 5114d5f2ba7SVivien Didelot */ 5124d5f2ba7SVivien Didelot int (*stats_snapshot)(struct mv88e6xxx_chip *chip, int port); 5134d5f2ba7SVivien Didelot 5144d5f2ba7SVivien Didelot /* Set the histogram mode for statistics, when the control registers 5154d5f2ba7SVivien Didelot * are separated out of the STATS_OP register. 5164d5f2ba7SVivien Didelot */ 5174d5f2ba7SVivien Didelot int (*stats_set_histogram)(struct mv88e6xxx_chip *chip); 5184d5f2ba7SVivien Didelot 5194d5f2ba7SVivien Didelot /* Return the number of strings describing statistics */ 5204d5f2ba7SVivien Didelot int (*stats_get_sset_count)(struct mv88e6xxx_chip *chip); 521436fe17dSAndrew Lunn int (*stats_get_strings)(struct mv88e6xxx_chip *chip, uint8_t *data); 522436fe17dSAndrew Lunn int (*stats_get_stats)(struct mv88e6xxx_chip *chip, int port, 5234d5f2ba7SVivien Didelot uint64_t *data); 524fa8d1179SVivien Didelot int (*set_cpu_port)(struct mv88e6xxx_chip *chip, int port); 5255c74c54cSIwan R Timmer int (*set_egress_port)(struct mv88e6xxx_chip *chip, 5265c74c54cSIwan R Timmer enum mv88e6xxx_egress_direction direction, 5275c74c54cSIwan R Timmer int port); 52802317e68SVivien Didelot 52902317e68SVivien Didelot #define MV88E6XXX_CASCADE_PORT_NONE 0xe 53002317e68SVivien Didelot #define MV88E6XXX_CASCADE_PORT_MULTIPLE 0xf 53102317e68SVivien Didelot 53202317e68SVivien Didelot int (*set_cascade_port)(struct mv88e6xxx_chip *chip, int port); 53302317e68SVivien Didelot 5344d5f2ba7SVivien Didelot const struct mv88e6xxx_irq_ops *watchdog_ops; 5354d5f2ba7SVivien Didelot 5364d5f2ba7SVivien Didelot int (*mgmt_rsvd2cpu)(struct mv88e6xxx_chip *chip); 5374d5f2ba7SVivien Didelot 5384d5f2ba7SVivien Didelot /* Power on/off a SERDES interface */ 539193c5b26SPavana Sharma int (*serdes_power)(struct mv88e6xxx_chip *chip, int port, int lane, 540dc272f60SVivien Didelot bool up); 5414d5f2ba7SVivien Didelot 54217deaf5cSMarek Behún /* SERDES lane mapping */ 543193c5b26SPavana Sharma int (*serdes_get_lane)(struct mv88e6xxx_chip *chip, int port); 54417deaf5cSMarek Behún 545a5a6858bSRussell King int (*serdes_pcs_get_state)(struct mv88e6xxx_chip *chip, int port, 546193c5b26SPavana Sharma int lane, struct phylink_link_state *state); 547a5a6858bSRussell King int (*serdes_pcs_config)(struct mv88e6xxx_chip *chip, int port, 548193c5b26SPavana Sharma int lane, unsigned int mode, 549a5a6858bSRussell King phy_interface_t interface, 550a5a6858bSRussell King const unsigned long *advertise); 551a5a6858bSRussell King int (*serdes_pcs_an_restart)(struct mv88e6xxx_chip *chip, int port, 552193c5b26SPavana Sharma int lane); 553a5a6858bSRussell King int (*serdes_pcs_link_up)(struct mv88e6xxx_chip *chip, int port, 554193c5b26SPavana Sharma int lane, int speed, int duplex); 555a5a6858bSRussell King 556efd1ba6aSAndrew Lunn /* SERDES interrupt handling */ 5574241ef52SVivien Didelot unsigned int (*serdes_irq_mapping)(struct mv88e6xxx_chip *chip, 5584241ef52SVivien Didelot int port); 559193c5b26SPavana Sharma int (*serdes_irq_enable)(struct mv88e6xxx_chip *chip, int port, int lane, 56061a46b41SVivien Didelot bool enable); 561907b9b9fSVivien Didelot irqreturn_t (*serdes_irq_status)(struct mv88e6xxx_chip *chip, int port, 562193c5b26SPavana Sharma int lane); 563efd1ba6aSAndrew Lunn 564436fe17dSAndrew Lunn /* Statistics from the SERDES interface */ 565436fe17dSAndrew Lunn int (*serdes_get_sset_count)(struct mv88e6xxx_chip *chip, int port); 56665f60e45SAndrew Lunn int (*serdes_get_strings)(struct mv88e6xxx_chip *chip, int port, 567436fe17dSAndrew Lunn uint8_t *data); 56865f60e45SAndrew Lunn int (*serdes_get_stats)(struct mv88e6xxx_chip *chip, int port, 569436fe17dSAndrew Lunn uint64_t *data); 570436fe17dSAndrew Lunn 5710d30bbd0SAndrew Lunn /* SERDES registers for ethtool */ 5720d30bbd0SAndrew Lunn int (*serdes_get_regs_len)(struct mv88e6xxx_chip *chip, int port); 5730d30bbd0SAndrew Lunn void (*serdes_get_regs)(struct mv88e6xxx_chip *chip, int port, 5740d30bbd0SAndrew Lunn void *_p); 5750d30bbd0SAndrew Lunn 57623e8b470SAndrew Lunn /* Address Translation Unit operations */ 57723e8b470SAndrew Lunn int (*atu_get_hash)(struct mv88e6xxx_chip *chip, u8 *hash); 57823e8b470SAndrew Lunn int (*atu_set_hash)(struct mv88e6xxx_chip *chip, u8 hash); 57923e8b470SAndrew Lunn 5804d5f2ba7SVivien Didelot /* VLAN Translation Unit operations */ 5814d5f2ba7SVivien Didelot int (*vtu_getnext)(struct mv88e6xxx_chip *chip, 5824d5f2ba7SVivien Didelot struct mv88e6xxx_vtu_entry *entry); 5834d5f2ba7SVivien Didelot int (*vtu_loadpurge)(struct mv88e6xxx_chip *chip, 5844d5f2ba7SVivien Didelot struct mv88e6xxx_vtu_entry *entry); 5850d632c3dSBrandon Streiff 586a73ccd61SBrandon Streiff /* GPIO operations */ 587a73ccd61SBrandon Streiff const struct mv88e6xxx_gpio_ops *gpio_ops; 588a73ccd61SBrandon Streiff 5890d632c3dSBrandon Streiff /* Interface to the AVB/PTP registers */ 5900d632c3dSBrandon Streiff const struct mv88e6xxx_avb_ops *avb_ops; 5919e5baf9bSVivien Didelot 5929e5baf9bSVivien Didelot /* Remote Management Unit operations */ 5939e5baf9bSVivien Didelot int (*rmu_disable)(struct mv88e6xxx_chip *chip); 5946d2ac8eeSAndrew Lunn 5956d2ac8eeSAndrew Lunn /* Precision Time Protocol operations */ 5966d2ac8eeSAndrew Lunn const struct mv88e6xxx_ptp_ops *ptp_ops; 5976c422e34SRussell King 5986c422e34SRussell King /* Phylink */ 5996c422e34SRussell King void (*phylink_validate)(struct mv88e6xxx_chip *chip, int port, 6006c422e34SRussell King unsigned long *mask, 6016c422e34SRussell King struct phylink_link_state *state); 6021baf0facSChris Packham 6031baf0facSChris Packham /* Max Frame Size */ 6041baf0facSChris Packham int (*set_max_frame_size)(struct mv88e6xxx_chip *chip, int mtu); 6054d5f2ba7SVivien Didelot }; 6064d5f2ba7SVivien Didelot 6074d5f2ba7SVivien Didelot struct mv88e6xxx_irq_ops { 6084d5f2ba7SVivien Didelot /* Action to be performed when the interrupt happens */ 6094d5f2ba7SVivien Didelot int (*irq_action)(struct mv88e6xxx_chip *chip, int irq); 6104d5f2ba7SVivien Didelot /* Setup the hardware to generate the interrupt */ 6114d5f2ba7SVivien Didelot int (*irq_setup)(struct mv88e6xxx_chip *chip); 6124d5f2ba7SVivien Didelot /* Reset the hardware to stop generating the interrupt */ 6134d5f2ba7SVivien Didelot void (*irq_free)(struct mv88e6xxx_chip *chip); 6144d5f2ba7SVivien Didelot }; 6154d5f2ba7SVivien Didelot 616a73ccd61SBrandon Streiff struct mv88e6xxx_gpio_ops { 617a73ccd61SBrandon Streiff /* Get/set data on GPIO pin */ 618a73ccd61SBrandon Streiff int (*get_data)(struct mv88e6xxx_chip *chip, unsigned int pin); 619a73ccd61SBrandon Streiff int (*set_data)(struct mv88e6xxx_chip *chip, unsigned int pin, 620a73ccd61SBrandon Streiff int value); 621a73ccd61SBrandon Streiff 622a73ccd61SBrandon Streiff /* get/set GPIO direction */ 623a73ccd61SBrandon Streiff int (*get_dir)(struct mv88e6xxx_chip *chip, unsigned int pin); 624a73ccd61SBrandon Streiff int (*set_dir)(struct mv88e6xxx_chip *chip, unsigned int pin, 625a73ccd61SBrandon Streiff bool input); 626a73ccd61SBrandon Streiff 627a73ccd61SBrandon Streiff /* get/set GPIO pin control */ 628a73ccd61SBrandon Streiff int (*get_pctl)(struct mv88e6xxx_chip *chip, unsigned int pin, 629a73ccd61SBrandon Streiff int *func); 630a73ccd61SBrandon Streiff int (*set_pctl)(struct mv88e6xxx_chip *chip, unsigned int pin, 631a73ccd61SBrandon Streiff int func); 632a73ccd61SBrandon Streiff }; 633a73ccd61SBrandon Streiff 6340d632c3dSBrandon Streiff struct mv88e6xxx_avb_ops { 6350d632c3dSBrandon Streiff /* Access port-scoped Precision Time Protocol registers */ 6360d632c3dSBrandon Streiff int (*port_ptp_read)(struct mv88e6xxx_chip *chip, int port, int addr, 6370d632c3dSBrandon Streiff u16 *data, int len); 6380d632c3dSBrandon Streiff int (*port_ptp_write)(struct mv88e6xxx_chip *chip, int port, int addr, 6390d632c3dSBrandon Streiff u16 data); 6400d632c3dSBrandon Streiff 6410d632c3dSBrandon Streiff /* Access global Precision Time Protocol registers */ 6420d632c3dSBrandon Streiff int (*ptp_read)(struct mv88e6xxx_chip *chip, int addr, u16 *data, 6430d632c3dSBrandon Streiff int len); 6440d632c3dSBrandon Streiff int (*ptp_write)(struct mv88e6xxx_chip *chip, int addr, u16 data); 6450d632c3dSBrandon Streiff 6460d632c3dSBrandon Streiff /* Access global Time Application Interface registers */ 6470d632c3dSBrandon Streiff int (*tai_read)(struct mv88e6xxx_chip *chip, int addr, u16 *data, 6480d632c3dSBrandon Streiff int len); 6490d632c3dSBrandon Streiff int (*tai_write)(struct mv88e6xxx_chip *chip, int addr, u16 data); 6500d632c3dSBrandon Streiff }; 6510d632c3dSBrandon Streiff 6526d2ac8eeSAndrew Lunn struct mv88e6xxx_ptp_ops { 6536d2ac8eeSAndrew Lunn u64 (*clock_read)(const struct cyclecounter *cc); 6546d2ac8eeSAndrew Lunn int (*ptp_enable)(struct ptp_clock_info *ptp, 6556d2ac8eeSAndrew Lunn struct ptp_clock_request *rq, int on); 6566d2ac8eeSAndrew Lunn int (*ptp_verify)(struct ptp_clock_info *ptp, unsigned int pin, 6576d2ac8eeSAndrew Lunn enum ptp_pin_function func, unsigned int chan); 6586d2ac8eeSAndrew Lunn void (*event_work)(struct work_struct *ugly); 659ffc705deSAndrew Lunn int (*port_enable)(struct mv88e6xxx_chip *chip, int port); 660ffc705deSAndrew Lunn int (*port_disable)(struct mv88e6xxx_chip *chip, int port); 661e2294a8bSAndrew Lunn int (*global_enable)(struct mv88e6xxx_chip *chip); 662e2294a8bSAndrew Lunn int (*global_disable)(struct mv88e6xxx_chip *chip); 6636d2ac8eeSAndrew Lunn int n_ext_ts; 664ffc705deSAndrew Lunn int arr0_sts_reg; 665ffc705deSAndrew Lunn int arr1_sts_reg; 666ffc705deSAndrew Lunn int dep_sts_reg; 66748cb5e03SAndrew Lunn u32 rx_filters; 66871509614SHubert Feurstein u32 cc_shift; 66971509614SHubert Feurstein u32 cc_mult; 67071509614SHubert Feurstein u32 cc_mult_num; 67171509614SHubert Feurstein u32 cc_mult_dem; 6726d2ac8eeSAndrew Lunn }; 6736d2ac8eeSAndrew Lunn 6744d5f2ba7SVivien Didelot #define STATS_TYPE_PORT BIT(0) 6754d5f2ba7SVivien Didelot #define STATS_TYPE_BANK0 BIT(1) 6764d5f2ba7SVivien Didelot #define STATS_TYPE_BANK1 BIT(2) 6774d5f2ba7SVivien Didelot 6784d5f2ba7SVivien Didelot struct mv88e6xxx_hw_stat { 6794d5f2ba7SVivien Didelot char string[ETH_GSTRING_LEN]; 680cda9f4aaSAndrew Lunn size_t size; 6814d5f2ba7SVivien Didelot int reg; 6824d5f2ba7SVivien Didelot int type; 6834d5f2ba7SVivien Didelot }; 6844d5f2ba7SVivien Didelot 6854d5f2ba7SVivien Didelot static inline bool mv88e6xxx_has_pvt(struct mv88e6xxx_chip *chip) 6864d5f2ba7SVivien Didelot { 6874d5f2ba7SVivien Didelot return chip->info->pvt; 6884d5f2ba7SVivien Didelot } 6894d5f2ba7SVivien Didelot 690b80dc51bSTobias Waldekranz static inline bool mv88e6xxx_has_lag(struct mv88e6xxx_chip *chip) 691b80dc51bSTobias Waldekranz { 692b80dc51bSTobias Waldekranz return !!chip->info->global2_addr; 693b80dc51bSTobias Waldekranz } 694b80dc51bSTobias Waldekranz 6954d5f2ba7SVivien Didelot static inline unsigned int mv88e6xxx_num_databases(struct mv88e6xxx_chip *chip) 6964d5f2ba7SVivien Didelot { 6974d5f2ba7SVivien Didelot return chip->info->num_databases; 6984d5f2ba7SVivien Didelot } 6994d5f2ba7SVivien Didelot 700d9ea5620SAndrew Lunn static inline unsigned int mv88e6xxx_num_macs(struct mv88e6xxx_chip *chip) 701d9ea5620SAndrew Lunn { 702d9ea5620SAndrew Lunn return chip->info->num_macs; 703d9ea5620SAndrew Lunn } 704d9ea5620SAndrew Lunn 7054d5f2ba7SVivien Didelot static inline unsigned int mv88e6xxx_num_ports(struct mv88e6xxx_chip *chip) 7064d5f2ba7SVivien Didelot { 7074d5f2ba7SVivien Didelot return chip->info->num_ports; 7084d5f2ba7SVivien Didelot } 7094d5f2ba7SVivien Didelot 710e545f865STobias Waldekranz static inline unsigned int mv88e6xxx_max_vid(struct mv88e6xxx_chip *chip) 711e545f865STobias Waldekranz { 712e545f865STobias Waldekranz return chip->info->max_vid; 713e545f865STobias Waldekranz } 714e545f865STobias Waldekranz 7154d5f2ba7SVivien Didelot static inline u16 mv88e6xxx_port_mask(struct mv88e6xxx_chip *chip) 7164d5f2ba7SVivien Didelot { 717f1931164SAndrew Lunn return GENMASK((s32)mv88e6xxx_num_ports(chip) - 1, 0); 7184d5f2ba7SVivien Didelot } 7194d5f2ba7SVivien Didelot 720a73ccd61SBrandon Streiff static inline unsigned int mv88e6xxx_num_gpio(struct mv88e6xxx_chip *chip) 721a73ccd61SBrandon Streiff { 722a73ccd61SBrandon Streiff return chip->info->num_gpio; 723a73ccd61SBrandon Streiff } 724a73ccd61SBrandon Streiff 725c857486aSHubert Feurstein static inline bool mv88e6xxx_is_invalid_port(struct mv88e6xxx_chip *chip, int port) 726c857486aSHubert Feurstein { 727c857486aSHubert Feurstein return (chip->info->invalid_port_mask & BIT(port)) != 0; 728c857486aSHubert Feurstein } 729c857486aSHubert Feurstein 7304d5f2ba7SVivien Didelot int mv88e6xxx_read(struct mv88e6xxx_chip *chip, int addr, int reg, u16 *val); 7314d5f2ba7SVivien Didelot int mv88e6xxx_write(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val); 732683f2244SVivien Didelot int mv88e6xxx_wait_mask(struct mv88e6xxx_chip *chip, int addr, int reg, 733683f2244SVivien Didelot u16 mask, u16 val); 73419fb7f69SVivien Didelot int mv88e6xxx_wait_bit(struct mv88e6xxx_chip *chip, int addr, int reg, 73519fb7f69SVivien Didelot int bit, int val); 7364d5f2ba7SVivien Didelot struct mii_bus *mv88e6xxx_default_mdio_bus(struct mv88e6xxx_chip *chip); 7374d5f2ba7SVivien Didelot 738c9acece0SRasmus Villemoes static inline void mv88e6xxx_reg_lock(struct mv88e6xxx_chip *chip) 739c9acece0SRasmus Villemoes { 740c9acece0SRasmus Villemoes mutex_lock(&chip->reg_lock); 741c9acece0SRasmus Villemoes } 742c9acece0SRasmus Villemoes 743c9acece0SRasmus Villemoes static inline void mv88e6xxx_reg_unlock(struct mv88e6xxx_chip *chip) 744c9acece0SRasmus Villemoes { 745c9acece0SRasmus Villemoes mutex_unlock(&chip->reg_lock); 746c9acece0SRasmus Villemoes } 747c9acece0SRasmus Villemoes 74890b6dbdfSAndrew Lunn int mv88e6xxx_fid_map(struct mv88e6xxx_chip *chip, unsigned long *bitmap); 74990b6dbdfSAndrew Lunn 7504d5f2ba7SVivien Didelot #endif /* _MV88E6XXX_CHIP_H */ 751