12874c5fdSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */ 24d5f2ba7SVivien Didelot /* 34d5f2ba7SVivien Didelot * Marvell 88E6xxx Ethernet switch single-chip definition 44d5f2ba7SVivien Didelot * 54d5f2ba7SVivien Didelot * Copyright (c) 2008 Marvell Semiconductor 64d5f2ba7SVivien Didelot */ 74d5f2ba7SVivien Didelot 84d5f2ba7SVivien Didelot #ifndef _MV88E6XXX_CHIP_H 94d5f2ba7SVivien Didelot #define _MV88E6XXX_CHIP_H 104d5f2ba7SVivien Didelot 11da7dc875SVivien Didelot #include <linux/idr.h> 124d5f2ba7SVivien Didelot #include <linux/if_vlan.h> 134d5f2ba7SVivien Didelot #include <linux/irq.h> 144d5f2ba7SVivien Didelot #include <linux/gpio/consumer.h> 15294d711eSAndrew Lunn #include <linux/kthread.h> 164d5f2ba7SVivien Didelot #include <linux/phy.h> 172fa8d3afSBrandon Streiff #include <linux/ptp_clock_kernel.h> 182fa8d3afSBrandon Streiff #include <linux/timecounter.h> 194d5f2ba7SVivien Didelot #include <net/dsa.h> 204d5f2ba7SVivien Didelot 214d5f2ba7SVivien Didelot #define MV88E6XXX_N_FID 4096 224d5f2ba7SVivien Didelot 234d5f2ba7SVivien Didelot /* PVT limits for 4-bit port and 5-bit switch */ 244d5f2ba7SVivien Didelot #define MV88E6XXX_MAX_PVT_SWITCHES 32 254d5f2ba7SVivien Didelot #define MV88E6XXX_MAX_PVT_PORTS 16 264d5f2ba7SVivien Didelot 27a73ccd61SBrandon Streiff #define MV88E6XXX_MAX_GPIO 16 28a73ccd61SBrandon Streiff 2931bef4e9SVivien Didelot enum mv88e6xxx_egress_mode { 3031bef4e9SVivien Didelot MV88E6XXX_EGRESS_MODE_UNMODIFIED, 3131bef4e9SVivien Didelot MV88E6XXX_EGRESS_MODE_UNTAGGED, 3231bef4e9SVivien Didelot MV88E6XXX_EGRESS_MODE_TAGGED, 3331bef4e9SVivien Didelot MV88E6XXX_EGRESS_MODE_ETHERTYPE, 3431bef4e9SVivien Didelot }; 3531bef4e9SVivien Didelot 365c74c54cSIwan R Timmer enum mv88e6xxx_egress_direction { 375c74c54cSIwan R Timmer MV88E6XXX_EGRESS_DIR_INGRESS, 385c74c54cSIwan R Timmer MV88E6XXX_EGRESS_DIR_EGRESS, 395c74c54cSIwan R Timmer }; 405c74c54cSIwan R Timmer 414d5f2ba7SVivien Didelot enum mv88e6xxx_frame_mode { 424d5f2ba7SVivien Didelot MV88E6XXX_FRAME_MODE_NORMAL, 434d5f2ba7SVivien Didelot MV88E6XXX_FRAME_MODE_DSA, 444d5f2ba7SVivien Didelot MV88E6XXX_FRAME_MODE_PROVIDER, 454d5f2ba7SVivien Didelot MV88E6XXX_FRAME_MODE_ETHERTYPE, 464d5f2ba7SVivien Didelot }; 474d5f2ba7SVivien Didelot 484d5f2ba7SVivien Didelot /* List of supported models */ 494d5f2ba7SVivien Didelot enum mv88e6xxx_model { 504d5f2ba7SVivien Didelot MV88E6085, 514d5f2ba7SVivien Didelot MV88E6095, 524d5f2ba7SVivien Didelot MV88E6097, 534d5f2ba7SVivien Didelot MV88E6123, 544d5f2ba7SVivien Didelot MV88E6131, 554d5f2ba7SVivien Didelot MV88E6141, 564d5f2ba7SVivien Didelot MV88E6161, 574d5f2ba7SVivien Didelot MV88E6165, 584d5f2ba7SVivien Didelot MV88E6171, 594d5f2ba7SVivien Didelot MV88E6172, 604d5f2ba7SVivien Didelot MV88E6175, 614d5f2ba7SVivien Didelot MV88E6176, 624d5f2ba7SVivien Didelot MV88E6185, 634d5f2ba7SVivien Didelot MV88E6190, 644d5f2ba7SVivien Didelot MV88E6190X, 654d5f2ba7SVivien Didelot MV88E6191, 6649022647SHubert Feurstein MV88E6220, 674d5f2ba7SVivien Didelot MV88E6240, 681f71836fSRasmus Villemoes MV88E6250, 694d5f2ba7SVivien Didelot MV88E6290, 704d5f2ba7SVivien Didelot MV88E6320, 714d5f2ba7SVivien Didelot MV88E6321, 724d5f2ba7SVivien Didelot MV88E6341, 734d5f2ba7SVivien Didelot MV88E6350, 744d5f2ba7SVivien Didelot MV88E6351, 754d5f2ba7SVivien Didelot MV88E6352, 764d5f2ba7SVivien Didelot MV88E6390, 774d5f2ba7SVivien Didelot MV88E6390X, 784d5f2ba7SVivien Didelot }; 794d5f2ba7SVivien Didelot 804d5f2ba7SVivien Didelot enum mv88e6xxx_family { 814d5f2ba7SVivien Didelot MV88E6XXX_FAMILY_NONE, 824d5f2ba7SVivien Didelot MV88E6XXX_FAMILY_6065, /* 6031 6035 6061 6065 */ 834d5f2ba7SVivien Didelot MV88E6XXX_FAMILY_6095, /* 6092 6095 */ 844d5f2ba7SVivien Didelot MV88E6XXX_FAMILY_6097, /* 6046 6085 6096 6097 */ 854d5f2ba7SVivien Didelot MV88E6XXX_FAMILY_6165, /* 6123 6161 6165 */ 864d5f2ba7SVivien Didelot MV88E6XXX_FAMILY_6185, /* 6108 6121 6122 6131 6152 6155 6182 6185 */ 8749022647SHubert Feurstein MV88E6XXX_FAMILY_6250, /* 6220 6250 */ 884d5f2ba7SVivien Didelot MV88E6XXX_FAMILY_6320, /* 6320 6321 */ 894d5f2ba7SVivien Didelot MV88E6XXX_FAMILY_6341, /* 6141 6341 */ 904d5f2ba7SVivien Didelot MV88E6XXX_FAMILY_6351, /* 6171 6175 6350 6351 */ 914d5f2ba7SVivien Didelot MV88E6XXX_FAMILY_6352, /* 6172 6176 6240 6352 */ 924d5f2ba7SVivien Didelot MV88E6XXX_FAMILY_6390, /* 6190 6190X 6191 6290 6390 6390X */ 934d5f2ba7SVivien Didelot }; 944d5f2ba7SVivien Didelot 954d5f2ba7SVivien Didelot struct mv88e6xxx_ops; 964d5f2ba7SVivien Didelot 974d5f2ba7SVivien Didelot struct mv88e6xxx_info { 984d5f2ba7SVivien Didelot enum mv88e6xxx_family family; 994d5f2ba7SVivien Didelot u16 prod_num; 1004d5f2ba7SVivien Didelot const char *name; 1014d5f2ba7SVivien Didelot unsigned int num_databases; 102d9ea5620SAndrew Lunn unsigned int num_macs; 1034d5f2ba7SVivien Didelot unsigned int num_ports; 104bc393155SAndrew Lunn unsigned int num_internal_phys; 105a73ccd61SBrandon Streiff unsigned int num_gpio; 1064d5f2ba7SVivien Didelot unsigned int max_vid; 1074d5f2ba7SVivien Didelot unsigned int port_base_addr; 1089255bacdSAndrew Lunn unsigned int phy_base_addr; 1094d5f2ba7SVivien Didelot unsigned int global1_addr; 1109069c13aSVivien Didelot unsigned int global2_addr; 1114d5f2ba7SVivien Didelot unsigned int age_time_coeff; 1124d5f2ba7SVivien Didelot unsigned int g1_irqs; 113d6c5e6afSVivien Didelot unsigned int g2_irqs; 1144d5f2ba7SVivien Didelot bool pvt; 115b3e05aa1SVivien Didelot 116c857486aSHubert Feurstein /* Mark certain ports as invalid. This is required for example for the 117c857486aSHubert Feurstein * MV88E6220 (which is in general a MV88E6250 with 7 ports) but the 118c857486aSHubert Feurstein * ports 2-4 are not routet to pins. 119c857486aSHubert Feurstein */ 120c857486aSHubert Feurstein unsigned int invalid_port_mask; 121b3e05aa1SVivien Didelot /* Multi-chip Addressing Mode. 122b3e05aa1SVivien Didelot * Some chips respond to only 2 registers of its own SMI device address 123b3e05aa1SVivien Didelot * when it is non-zero, and use indirect access to internal registers. 124b3e05aa1SVivien Didelot */ 125b3e05aa1SVivien Didelot bool multi_chip; 126f30a19b8SRasmus Villemoes /* Dual-chip Addressing Mode 127f30a19b8SRasmus Villemoes * Some chips respond to only half of the 32 SMI addresses, 128f30a19b8SRasmus Villemoes * allowing two to coexist on the same SMI interface. 129f30a19b8SRasmus Villemoes */ 130f30a19b8SRasmus Villemoes bool dual_chip; 131f30a19b8SRasmus Villemoes 1324d5f2ba7SVivien Didelot enum dsa_tag_protocol tag_protocol; 1334d5f2ba7SVivien Didelot 1344d5f2ba7SVivien Didelot /* Mask for FromPort and ToPort value of PortVec used in ATU Move 1354d5f2ba7SVivien Didelot * operation. 0 means that the ATU Move operation is not supported. 1364d5f2ba7SVivien Didelot */ 1374d5f2ba7SVivien Didelot u8 atu_move_port_mask; 1384d5f2ba7SVivien Didelot const struct mv88e6xxx_ops *ops; 1392fa8d3afSBrandon Streiff 1402fa8d3afSBrandon Streiff /* Supports PTP */ 1412fa8d3afSBrandon Streiff bool ptp_support; 1424d5f2ba7SVivien Didelot }; 1434d5f2ba7SVivien Didelot 1444d5f2ba7SVivien Didelot struct mv88e6xxx_atu_entry { 1454d5f2ba7SVivien Didelot u8 state; 1464d5f2ba7SVivien Didelot bool trunk; 1474d5f2ba7SVivien Didelot u16 portvec; 1484d5f2ba7SVivien Didelot u8 mac[ETH_ALEN]; 1494d5f2ba7SVivien Didelot }; 1504d5f2ba7SVivien Didelot 1514d5f2ba7SVivien Didelot struct mv88e6xxx_vtu_entry { 1524d5f2ba7SVivien Didelot u16 vid; 1534d5f2ba7SVivien Didelot u16 fid; 1544d5f2ba7SVivien Didelot u8 sid; 1554d5f2ba7SVivien Didelot bool valid; 1564d5f2ba7SVivien Didelot u8 member[DSA_MAX_PORTS]; 1574d5f2ba7SVivien Didelot u8 state[DSA_MAX_PORTS]; 1584d5f2ba7SVivien Didelot }; 1594d5f2ba7SVivien Didelot 1604d5f2ba7SVivien Didelot struct mv88e6xxx_bus_ops; 1614d5f2ba7SVivien Didelot struct mv88e6xxx_irq_ops; 162a73ccd61SBrandon Streiff struct mv88e6xxx_gpio_ops; 1630d632c3dSBrandon Streiff struct mv88e6xxx_avb_ops; 1646d2ac8eeSAndrew Lunn struct mv88e6xxx_ptp_ops; 1654d5f2ba7SVivien Didelot 1664d5f2ba7SVivien Didelot struct mv88e6xxx_irq { 1674d5f2ba7SVivien Didelot u16 masked; 1684d5f2ba7SVivien Didelot struct irq_chip chip; 1694d5f2ba7SVivien Didelot struct irq_domain *domain; 170f1931164SAndrew Lunn int nirqs; 1714d5f2ba7SVivien Didelot }; 1724d5f2ba7SVivien Didelot 173c6fe0ad2SBrandon Streiff /* state flags for mv88e6xxx_port_hwtstamp::state */ 174c6fe0ad2SBrandon Streiff enum { 175c6fe0ad2SBrandon Streiff MV88E6XXX_HWTSTAMP_ENABLED, 176c6fe0ad2SBrandon Streiff MV88E6XXX_HWTSTAMP_TX_IN_PROGRESS, 177c6fe0ad2SBrandon Streiff }; 178c6fe0ad2SBrandon Streiff 179c6fe0ad2SBrandon Streiff struct mv88e6xxx_port_hwtstamp { 180c6fe0ad2SBrandon Streiff /* Port index */ 181c6fe0ad2SBrandon Streiff int port_id; 182c6fe0ad2SBrandon Streiff 183c6fe0ad2SBrandon Streiff /* Timestamping state */ 184c6fe0ad2SBrandon Streiff unsigned long state; 185c6fe0ad2SBrandon Streiff 186c6fe0ad2SBrandon Streiff /* Resources for receive timestamping */ 187c6fe0ad2SBrandon Streiff struct sk_buff_head rx_queue; 188c6fe0ad2SBrandon Streiff struct sk_buff_head rx_queue2; 189c6fe0ad2SBrandon Streiff 190c6fe0ad2SBrandon Streiff /* Resources for transmit timestamping */ 191c6fe0ad2SBrandon Streiff unsigned long tx_tstamp_start; 192c6fe0ad2SBrandon Streiff struct sk_buff *tx_skb; 193c6fe0ad2SBrandon Streiff u16 tx_seq_id; 194c6fe0ad2SBrandon Streiff 195c6fe0ad2SBrandon Streiff /* Current timestamp configuration */ 196c6fe0ad2SBrandon Streiff struct hwtstamp_config tstamp_config; 197c6fe0ad2SBrandon Streiff }; 198c6fe0ad2SBrandon Streiff 199f3a2cd32SVivien Didelot enum mv88e6xxx_policy_mapping { 200f3a2cd32SVivien Didelot MV88E6XXX_POLICY_MAPPING_DA, 201f3a2cd32SVivien Didelot MV88E6XXX_POLICY_MAPPING_SA, 202f3a2cd32SVivien Didelot MV88E6XXX_POLICY_MAPPING_VTU, 203f3a2cd32SVivien Didelot MV88E6XXX_POLICY_MAPPING_ETYPE, 204f3a2cd32SVivien Didelot MV88E6XXX_POLICY_MAPPING_PPPOE, 205f3a2cd32SVivien Didelot MV88E6XXX_POLICY_MAPPING_VBAS, 206f3a2cd32SVivien Didelot MV88E6XXX_POLICY_MAPPING_OPT82, 207f3a2cd32SVivien Didelot MV88E6XXX_POLICY_MAPPING_UDP, 208f3a2cd32SVivien Didelot }; 209f3a2cd32SVivien Didelot 210f3a2cd32SVivien Didelot enum mv88e6xxx_policy_action { 211f3a2cd32SVivien Didelot MV88E6XXX_POLICY_ACTION_NORMAL, 212f3a2cd32SVivien Didelot MV88E6XXX_POLICY_ACTION_MIRROR, 213f3a2cd32SVivien Didelot MV88E6XXX_POLICY_ACTION_TRAP, 214f3a2cd32SVivien Didelot MV88E6XXX_POLICY_ACTION_DISCARD, 215f3a2cd32SVivien Didelot }; 216f3a2cd32SVivien Didelot 217da7dc875SVivien Didelot struct mv88e6xxx_policy { 218da7dc875SVivien Didelot enum mv88e6xxx_policy_mapping mapping; 219da7dc875SVivien Didelot enum mv88e6xxx_policy_action action; 220da7dc875SVivien Didelot struct ethtool_rx_flow_spec fs; 221da7dc875SVivien Didelot u8 addr[ETH_ALEN]; 222da7dc875SVivien Didelot int port; 223da7dc875SVivien Didelot u16 vid; 224da7dc875SVivien Didelot }; 225da7dc875SVivien Didelot 226cda9f4aaSAndrew Lunn struct mv88e6xxx_port { 2277b898469SAndrew Lunn struct mv88e6xxx_chip *chip; 2287b898469SAndrew Lunn int port; 229cda9f4aaSAndrew Lunn u64 serdes_stats[2]; 23065f60e45SAndrew Lunn u64 atu_member_violation; 23165f60e45SAndrew Lunn u64 atu_miss_violation; 23265f60e45SAndrew Lunn u64 atu_full_violation; 23365f60e45SAndrew Lunn u64 vtu_member_violation; 23465f60e45SAndrew Lunn u64 vtu_miss_violation; 235fad58190SRussell King phy_interface_t interface; 2362d2e1dd2SAndrew Lunn u8 cmode; 237f0942e00SIwan R Timmer bool mirror_ingress; 238f0942e00SIwan R Timmer bool mirror_egress; 239f441ed0fSVivien Didelot unsigned int serdes_irq; 2405d1fbdf2SAndrew Lunn char serdes_irq_name[64]; 241cda9f4aaSAndrew Lunn }; 242cda9f4aaSAndrew Lunn 2434d5f2ba7SVivien Didelot struct mv88e6xxx_chip { 2444d5f2ba7SVivien Didelot const struct mv88e6xxx_info *info; 2454d5f2ba7SVivien Didelot 2464d5f2ba7SVivien Didelot /* The dsa_switch this private structure is related to */ 2474d5f2ba7SVivien Didelot struct dsa_switch *ds; 2484d5f2ba7SVivien Didelot 2494d5f2ba7SVivien Didelot /* The device this structure is associated to */ 2504d5f2ba7SVivien Didelot struct device *dev; 2514d5f2ba7SVivien Didelot 2524d5f2ba7SVivien Didelot /* This mutex protects the access to the switch registers */ 2534d5f2ba7SVivien Didelot struct mutex reg_lock; 2544d5f2ba7SVivien Didelot 2554d5f2ba7SVivien Didelot /* The MII bus and the address on the bus that is used to 2564d5f2ba7SVivien Didelot * communication with the switch 2574d5f2ba7SVivien Didelot */ 2584d5f2ba7SVivien Didelot const struct mv88e6xxx_bus_ops *smi_ops; 2594d5f2ba7SVivien Didelot struct mii_bus *bus; 2604d5f2ba7SVivien Didelot int sw_addr; 2614d5f2ba7SVivien Didelot 2624d5f2ba7SVivien Didelot /* Handles automatic disabling and re-enabling of the PHY 2634d5f2ba7SVivien Didelot * polling unit. 2644d5f2ba7SVivien Didelot */ 2654d5f2ba7SVivien Didelot const struct mv88e6xxx_bus_ops *phy_ops; 2664d5f2ba7SVivien Didelot struct mutex ppu_mutex; 2674d5f2ba7SVivien Didelot int ppu_disabled; 2684d5f2ba7SVivien Didelot struct work_struct ppu_work; 2694d5f2ba7SVivien Didelot struct timer_list ppu_timer; 2704d5f2ba7SVivien Didelot 2714d5f2ba7SVivien Didelot /* This mutex serialises access to the statistics unit. 2724d5f2ba7SVivien Didelot * Hold this mutex over snapshot + dump sequences. 2734d5f2ba7SVivien Didelot */ 2744d5f2ba7SVivien Didelot struct mutex stats_mutex; 2754d5f2ba7SVivien Didelot 2764d5f2ba7SVivien Didelot /* A switch may have a GPIO line tied to its reset pin. Parse 2774d5f2ba7SVivien Didelot * this from the device tree, and use it before performing 2784d5f2ba7SVivien Didelot * switch soft reset. 2794d5f2ba7SVivien Didelot */ 2804d5f2ba7SVivien Didelot struct gpio_desc *reset; 2814d5f2ba7SVivien Didelot 2824d5f2ba7SVivien Didelot /* set to size of eeprom if supported by the switch */ 28300baabe5SAndrew Lunn u32 eeprom_len; 2844d5f2ba7SVivien Didelot 2854d5f2ba7SVivien Didelot /* List of mdio busses */ 2864d5f2ba7SVivien Didelot struct list_head mdios; 2874d5f2ba7SVivien Didelot 288da7dc875SVivien Didelot /* Policy Control List IDs and rules */ 289da7dc875SVivien Didelot struct idr policies; 290da7dc875SVivien Didelot 2914d5f2ba7SVivien Didelot /* There can be two interrupt controllers, which are chained 2924d5f2ba7SVivien Didelot * off a GPIO as interrupt source 2934d5f2ba7SVivien Didelot */ 2944d5f2ba7SVivien Didelot struct mv88e6xxx_irq g1_irq; 2954d5f2ba7SVivien Didelot struct mv88e6xxx_irq g2_irq; 2964d5f2ba7SVivien Didelot int irq; 2975d1fbdf2SAndrew Lunn char irq_name[64]; 2984d5f2ba7SVivien Didelot int device_irq; 2995d1fbdf2SAndrew Lunn char device_irq_name[64]; 3004d5f2ba7SVivien Didelot int watchdog_irq; 3015d1fbdf2SAndrew Lunn char watchdog_irq_name[64]; 302cda9f4aaSAndrew Lunn 3030977644cSAndrew Lunn int atu_prob_irq; 3045d1fbdf2SAndrew Lunn char atu_prob_irq_name[64]; 30562eb1162SAndrew Lunn int vtu_prob_irq; 3065d1fbdf2SAndrew Lunn char vtu_prob_irq_name[64]; 307294d711eSAndrew Lunn struct kthread_worker *kworker; 308294d711eSAndrew Lunn struct kthread_delayed_work irq_poll_work; 3092fa8d3afSBrandon Streiff 310a73ccd61SBrandon Streiff /* GPIO resources */ 311a73ccd61SBrandon Streiff u8 gpio_data[2]; 312a73ccd61SBrandon Streiff 3132fa8d3afSBrandon Streiff /* This cyclecounter abstracts the switch PTP time. 3142fa8d3afSBrandon Streiff * reg_lock must be held for any operation that read()s. 3152fa8d3afSBrandon Streiff */ 3162fa8d3afSBrandon Streiff struct cyclecounter tstamp_cc; 3172fa8d3afSBrandon Streiff struct timecounter tstamp_tc; 3182fa8d3afSBrandon Streiff struct delayed_work overflow_work; 3192fa8d3afSBrandon Streiff 3202fa8d3afSBrandon Streiff struct ptp_clock *ptp_clock; 3212fa8d3afSBrandon Streiff struct ptp_clock_info ptp_clock_info; 3224eb3be29SBrandon Streiff struct delayed_work tai_event_work; 3234eb3be29SBrandon Streiff struct ptp_pin_desc pin_config[MV88E6XXX_MAX_GPIO]; 3244eb3be29SBrandon Streiff u16 trig_config; 3254eb3be29SBrandon Streiff u16 evcap_config; 326e2294a8bSAndrew Lunn u16 enable_count; 327c6fe0ad2SBrandon Streiff 328f0942e00SIwan R Timmer /* Current ingress and egress monitor ports */ 329f0942e00SIwan R Timmer int egress_dest_port; 330f0942e00SIwan R Timmer int ingress_dest_port; 331f0942e00SIwan R Timmer 332c6fe0ad2SBrandon Streiff /* Per-port timestamping resources. */ 333c6fe0ad2SBrandon Streiff struct mv88e6xxx_port_hwtstamp port_hwtstamp[DSA_MAX_PORTS]; 334cda9f4aaSAndrew Lunn 335cda9f4aaSAndrew Lunn /* Array of port structures. */ 336cda9f4aaSAndrew Lunn struct mv88e6xxx_port ports[DSA_MAX_PORTS]; 3374d5f2ba7SVivien Didelot }; 3384d5f2ba7SVivien Didelot 3394d5f2ba7SVivien Didelot struct mv88e6xxx_bus_ops { 3404d5f2ba7SVivien Didelot int (*read)(struct mv88e6xxx_chip *chip, int addr, int reg, u16 *val); 3414d5f2ba7SVivien Didelot int (*write)(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val); 3424d5f2ba7SVivien Didelot }; 3434d5f2ba7SVivien Didelot 3444d5f2ba7SVivien Didelot struct mv88e6xxx_mdio_bus { 3454d5f2ba7SVivien Didelot struct mii_bus *bus; 3464d5f2ba7SVivien Didelot struct mv88e6xxx_chip *chip; 3474d5f2ba7SVivien Didelot struct list_head list; 3484d5f2ba7SVivien Didelot bool external; 3494d5f2ba7SVivien Didelot }; 3504d5f2ba7SVivien Didelot 3514d5f2ba7SVivien Didelot struct mv88e6xxx_ops { 352ea89098eSAndrew Lunn /* Switch Setup Errata, called early in the switch setup to 353ea89098eSAndrew Lunn * allow any errata actions to be performed 354ea89098eSAndrew Lunn */ 355ea89098eSAndrew Lunn int (*setup_errata)(struct mv88e6xxx_chip *chip); 356ea89098eSAndrew Lunn 35793e18d61SVivien Didelot int (*ieee_pri_map)(struct mv88e6xxx_chip *chip); 35893e18d61SVivien Didelot int (*ip_pri_map)(struct mv88e6xxx_chip *chip); 35993e18d61SVivien Didelot 360cd8da8bbSVivien Didelot /* Ingress Rate Limit unit (IRL) operations */ 361cd8da8bbSVivien Didelot int (*irl_init_all)(struct mv88e6xxx_chip *chip, int port); 362cd8da8bbSVivien Didelot 3634d5f2ba7SVivien Didelot int (*get_eeprom)(struct mv88e6xxx_chip *chip, 3644d5f2ba7SVivien Didelot struct ethtool_eeprom *eeprom, u8 *data); 3654d5f2ba7SVivien Didelot int (*set_eeprom)(struct mv88e6xxx_chip *chip, 3664d5f2ba7SVivien Didelot struct ethtool_eeprom *eeprom, u8 *data); 3674d5f2ba7SVivien Didelot 3684d5f2ba7SVivien Didelot int (*set_switch_mac)(struct mv88e6xxx_chip *chip, u8 *addr); 3694d5f2ba7SVivien Didelot 3704d5f2ba7SVivien Didelot int (*phy_read)(struct mv88e6xxx_chip *chip, 3714d5f2ba7SVivien Didelot struct mii_bus *bus, 3724d5f2ba7SVivien Didelot int addr, int reg, u16 *val); 3734d5f2ba7SVivien Didelot int (*phy_write)(struct mv88e6xxx_chip *chip, 3744d5f2ba7SVivien Didelot struct mii_bus *bus, 3754d5f2ba7SVivien Didelot int addr, int reg, u16 val); 3764d5f2ba7SVivien Didelot 3779e907d73SVivien Didelot /* Priority Override Table operations */ 3789e907d73SVivien Didelot int (*pot_clear)(struct mv88e6xxx_chip *chip); 3799e907d73SVivien Didelot 3804d5f2ba7SVivien Didelot /* PHY Polling Unit (PPU) operations */ 3814d5f2ba7SVivien Didelot int (*ppu_enable)(struct mv88e6xxx_chip *chip); 3824d5f2ba7SVivien Didelot int (*ppu_disable)(struct mv88e6xxx_chip *chip); 3834d5f2ba7SVivien Didelot 3844d5f2ba7SVivien Didelot /* Switch Software Reset */ 3854d5f2ba7SVivien Didelot int (*reset)(struct mv88e6xxx_chip *chip); 3864d5f2ba7SVivien Didelot 3874d5f2ba7SVivien Didelot /* RGMII Receive/Transmit Timing Control 3884d5f2ba7SVivien Didelot * Add delay on PHY_INTERFACE_MODE_RGMII_*ID, no delay otherwise. 3894d5f2ba7SVivien Didelot */ 3904d5f2ba7SVivien Didelot int (*port_set_rgmii_delay)(struct mv88e6xxx_chip *chip, int port, 3914d5f2ba7SVivien Didelot phy_interface_t mode); 3924d5f2ba7SVivien Didelot 3934d5f2ba7SVivien Didelot #define LINK_FORCED_DOWN 0 3944d5f2ba7SVivien Didelot #define LINK_FORCED_UP 1 3954d5f2ba7SVivien Didelot #define LINK_UNFORCED -2 3964d5f2ba7SVivien Didelot 3974d5f2ba7SVivien Didelot /* Port's MAC link state 3984d5f2ba7SVivien Didelot * Use LINK_FORCED_UP or LINK_FORCED_DOWN to force link up or down, 3994d5f2ba7SVivien Didelot * or LINK_UNFORCED for normal link detection. 4004d5f2ba7SVivien Didelot */ 4014d5f2ba7SVivien Didelot int (*port_set_link)(struct mv88e6xxx_chip *chip, int port, int link); 4024d5f2ba7SVivien Didelot 40354186b91SAndrew Lunn #define PAUSE_ON 1 40454186b91SAndrew Lunn #define PAUSE_OFF 0 40554186b91SAndrew Lunn 40654186b91SAndrew Lunn /* Enable/disable sending Pause */ 40754186b91SAndrew Lunn int (*port_set_pause)(struct mv88e6xxx_chip *chip, int port, 40854186b91SAndrew Lunn int pause); 40954186b91SAndrew Lunn 4104d5f2ba7SVivien Didelot #define SPEED_MAX INT_MAX 4114d5f2ba7SVivien Didelot #define SPEED_UNFORCED -2 412f365c6f7SRussell King #define DUPLEX_UNFORCED -2 4134d5f2ba7SVivien Didelot 414f365c6f7SRussell King /* Port's MAC speed (in Mbps) and MAC duplex mode 4154d5f2ba7SVivien Didelot * 4164d5f2ba7SVivien Didelot * Depending on the chip, 10, 100, 200, 1000, 2500, 10000 are valid. 4174d5f2ba7SVivien Didelot * Use SPEED_UNFORCED for normal detection, SPEED_MAX for max value. 418f365c6f7SRussell King * 419f365c6f7SRussell King * Use DUPLEX_HALF or DUPLEX_FULL to force half or full duplex, 420f365c6f7SRussell King * or DUPLEX_UNFORCED for normal duplex detection. 4214d5f2ba7SVivien Didelot */ 422f365c6f7SRussell King int (*port_set_speed_duplex)(struct mv88e6xxx_chip *chip, int port, 423f365c6f7SRussell King int speed, int duplex); 4244d5f2ba7SVivien Didelot 4257cbbee05SAndrew Lunn /* What interface mode should be used for maximum speed? */ 4267cbbee05SAndrew Lunn phy_interface_t (*port_max_speed_mode)(int port); 4277cbbee05SAndrew Lunn 4284d5f2ba7SVivien Didelot int (*port_tag_remap)(struct mv88e6xxx_chip *chip, int port); 4294d5f2ba7SVivien Didelot 430f3a2cd32SVivien Didelot int (*port_set_policy)(struct mv88e6xxx_chip *chip, int port, 431f3a2cd32SVivien Didelot enum mv88e6xxx_policy_mapping mapping, 432f3a2cd32SVivien Didelot enum mv88e6xxx_policy_action action); 433f3a2cd32SVivien Didelot 4344d5f2ba7SVivien Didelot int (*port_set_frame_mode)(struct mv88e6xxx_chip *chip, int port, 4354d5f2ba7SVivien Didelot enum mv88e6xxx_frame_mode mode); 4364d5f2ba7SVivien Didelot int (*port_set_egress_floods)(struct mv88e6xxx_chip *chip, int port, 4374d5f2ba7SVivien Didelot bool unicast, bool multicast); 4384d5f2ba7SVivien Didelot int (*port_set_ether_type)(struct mv88e6xxx_chip *chip, int port, 4394d5f2ba7SVivien Didelot u16 etype); 440cd782656SVivien Didelot int (*port_set_jumbo_size)(struct mv88e6xxx_chip *chip, int port, 441cd782656SVivien Didelot size_t size); 4424d5f2ba7SVivien Didelot 4434d5f2ba7SVivien Didelot int (*port_egress_rate_limiting)(struct mv88e6xxx_chip *chip, int port); 4440898432cSVivien Didelot int (*port_pause_limit)(struct mv88e6xxx_chip *chip, int port, u8 in, 4450898432cSVivien Didelot u8 out); 4464d5f2ba7SVivien Didelot int (*port_disable_learn_limit)(struct mv88e6xxx_chip *chip, int port); 4474d5f2ba7SVivien Didelot int (*port_disable_pri_override)(struct mv88e6xxx_chip *chip, int port); 448121b8fe2SHubert Feurstein int (*port_setup_message_port)(struct mv88e6xxx_chip *chip, int port); 4494d5f2ba7SVivien Didelot 4504d5f2ba7SVivien Didelot /* CMODE control what PHY mode the MAC will use, eg. SGMII, RGMII, etc. 4514d5f2ba7SVivien Didelot * Some chips allow this to be configured on specific ports. 4524d5f2ba7SVivien Didelot */ 4534d5f2ba7SVivien Didelot int (*port_set_cmode)(struct mv88e6xxx_chip *chip, int port, 4544d5f2ba7SVivien Didelot phy_interface_t mode); 4552d2e1dd2SAndrew Lunn int (*port_get_cmode)(struct mv88e6xxx_chip *chip, int port, u8 *cmode); 4564d5f2ba7SVivien Didelot 4574d5f2ba7SVivien Didelot /* Some devices have a per port register indicating what is 4584d5f2ba7SVivien Didelot * the upstream port this port should forward to. 4594d5f2ba7SVivien Didelot */ 4604d5f2ba7SVivien Didelot int (*port_set_upstream_port)(struct mv88e6xxx_chip *chip, int port, 4614d5f2ba7SVivien Didelot int upstream_port); 4624d5f2ba7SVivien Didelot 4634d5f2ba7SVivien Didelot /* Snapshot the statistics for a port. The statistics can then 4644d5f2ba7SVivien Didelot * be read back a leisure but still with a consistent view. 4654d5f2ba7SVivien Didelot */ 4664d5f2ba7SVivien Didelot int (*stats_snapshot)(struct mv88e6xxx_chip *chip, int port); 4674d5f2ba7SVivien Didelot 4684d5f2ba7SVivien Didelot /* Set the histogram mode for statistics, when the control registers 4694d5f2ba7SVivien Didelot * are separated out of the STATS_OP register. 4704d5f2ba7SVivien Didelot */ 4714d5f2ba7SVivien Didelot int (*stats_set_histogram)(struct mv88e6xxx_chip *chip); 4724d5f2ba7SVivien Didelot 4734d5f2ba7SVivien Didelot /* Return the number of strings describing statistics */ 4744d5f2ba7SVivien Didelot int (*stats_get_sset_count)(struct mv88e6xxx_chip *chip); 475436fe17dSAndrew Lunn int (*stats_get_strings)(struct mv88e6xxx_chip *chip, uint8_t *data); 476436fe17dSAndrew Lunn int (*stats_get_stats)(struct mv88e6xxx_chip *chip, int port, 4774d5f2ba7SVivien Didelot uint64_t *data); 478fa8d1179SVivien Didelot int (*set_cpu_port)(struct mv88e6xxx_chip *chip, int port); 4795c74c54cSIwan R Timmer int (*set_egress_port)(struct mv88e6xxx_chip *chip, 4805c74c54cSIwan R Timmer enum mv88e6xxx_egress_direction direction, 4815c74c54cSIwan R Timmer int port); 48202317e68SVivien Didelot 48302317e68SVivien Didelot #define MV88E6XXX_CASCADE_PORT_NONE 0xe 48402317e68SVivien Didelot #define MV88E6XXX_CASCADE_PORT_MULTIPLE 0xf 48502317e68SVivien Didelot 48602317e68SVivien Didelot int (*set_cascade_port)(struct mv88e6xxx_chip *chip, int port); 48702317e68SVivien Didelot 4884d5f2ba7SVivien Didelot const struct mv88e6xxx_irq_ops *watchdog_ops; 4894d5f2ba7SVivien Didelot 4904d5f2ba7SVivien Didelot int (*mgmt_rsvd2cpu)(struct mv88e6xxx_chip *chip); 4914d5f2ba7SVivien Didelot 4924d5f2ba7SVivien Didelot /* Power on/off a SERDES interface */ 493dc272f60SVivien Didelot int (*serdes_power)(struct mv88e6xxx_chip *chip, int port, u8 lane, 494dc272f60SVivien Didelot bool up); 4954d5f2ba7SVivien Didelot 49617deaf5cSMarek Behún /* SERDES lane mapping */ 4975122d4ecSVivien Didelot u8 (*serdes_get_lane)(struct mv88e6xxx_chip *chip, int port); 49817deaf5cSMarek Behún 499a5a6858bSRussell King int (*serdes_pcs_get_state)(struct mv88e6xxx_chip *chip, int port, 500a5a6858bSRussell King u8 lane, struct phylink_link_state *state); 501a5a6858bSRussell King int (*serdes_pcs_config)(struct mv88e6xxx_chip *chip, int port, 502a5a6858bSRussell King u8 lane, unsigned int mode, 503a5a6858bSRussell King phy_interface_t interface, 504a5a6858bSRussell King const unsigned long *advertise); 505a5a6858bSRussell King int (*serdes_pcs_an_restart)(struct mv88e6xxx_chip *chip, int port, 506a5a6858bSRussell King u8 lane); 507a5a6858bSRussell King int (*serdes_pcs_link_up)(struct mv88e6xxx_chip *chip, int port, 508a5a6858bSRussell King u8 lane, int speed, int duplex); 509a5a6858bSRussell King 510efd1ba6aSAndrew Lunn /* SERDES interrupt handling */ 5114241ef52SVivien Didelot unsigned int (*serdes_irq_mapping)(struct mv88e6xxx_chip *chip, 5124241ef52SVivien Didelot int port); 51361a46b41SVivien Didelot int (*serdes_irq_enable)(struct mv88e6xxx_chip *chip, int port, u8 lane, 51461a46b41SVivien Didelot bool enable); 515907b9b9fSVivien Didelot irqreturn_t (*serdes_irq_status)(struct mv88e6xxx_chip *chip, int port, 516907b9b9fSVivien Didelot u8 lane); 517efd1ba6aSAndrew Lunn 518436fe17dSAndrew Lunn /* Statistics from the SERDES interface */ 519436fe17dSAndrew Lunn int (*serdes_get_sset_count)(struct mv88e6xxx_chip *chip, int port); 52065f60e45SAndrew Lunn int (*serdes_get_strings)(struct mv88e6xxx_chip *chip, int port, 521436fe17dSAndrew Lunn uint8_t *data); 52265f60e45SAndrew Lunn int (*serdes_get_stats)(struct mv88e6xxx_chip *chip, int port, 523436fe17dSAndrew Lunn uint64_t *data); 524436fe17dSAndrew Lunn 5250d30bbd0SAndrew Lunn /* SERDES registers for ethtool */ 5260d30bbd0SAndrew Lunn int (*serdes_get_regs_len)(struct mv88e6xxx_chip *chip, int port); 5270d30bbd0SAndrew Lunn void (*serdes_get_regs)(struct mv88e6xxx_chip *chip, int port, 5280d30bbd0SAndrew Lunn void *_p); 5290d30bbd0SAndrew Lunn 53023e8b470SAndrew Lunn /* Address Translation Unit operations */ 53123e8b470SAndrew Lunn int (*atu_get_hash)(struct mv88e6xxx_chip *chip, u8 *hash); 53223e8b470SAndrew Lunn int (*atu_set_hash)(struct mv88e6xxx_chip *chip, u8 hash); 53323e8b470SAndrew Lunn 5344d5f2ba7SVivien Didelot /* VLAN Translation Unit operations */ 5354d5f2ba7SVivien Didelot int (*vtu_getnext)(struct mv88e6xxx_chip *chip, 5364d5f2ba7SVivien Didelot struct mv88e6xxx_vtu_entry *entry); 5374d5f2ba7SVivien Didelot int (*vtu_loadpurge)(struct mv88e6xxx_chip *chip, 5384d5f2ba7SVivien Didelot struct mv88e6xxx_vtu_entry *entry); 5390d632c3dSBrandon Streiff 540a73ccd61SBrandon Streiff /* GPIO operations */ 541a73ccd61SBrandon Streiff const struct mv88e6xxx_gpio_ops *gpio_ops; 542a73ccd61SBrandon Streiff 5430d632c3dSBrandon Streiff /* Interface to the AVB/PTP registers */ 5440d632c3dSBrandon Streiff const struct mv88e6xxx_avb_ops *avb_ops; 5459e5baf9bSVivien Didelot 5469e5baf9bSVivien Didelot /* Remote Management Unit operations */ 5479e5baf9bSVivien Didelot int (*rmu_disable)(struct mv88e6xxx_chip *chip); 5486d2ac8eeSAndrew Lunn 5496d2ac8eeSAndrew Lunn /* Precision Time Protocol operations */ 5506d2ac8eeSAndrew Lunn const struct mv88e6xxx_ptp_ops *ptp_ops; 5516c422e34SRussell King 5526c422e34SRussell King /* Phylink */ 5536c422e34SRussell King void (*phylink_validate)(struct mv88e6xxx_chip *chip, int port, 5546c422e34SRussell King unsigned long *mask, 5556c422e34SRussell King struct phylink_link_state *state); 5561baf0facSChris Packham 5571baf0facSChris Packham /* Max Frame Size */ 5581baf0facSChris Packham int (*set_max_frame_size)(struct mv88e6xxx_chip *chip, int mtu); 5594d5f2ba7SVivien Didelot }; 5604d5f2ba7SVivien Didelot 5614d5f2ba7SVivien Didelot struct mv88e6xxx_irq_ops { 5624d5f2ba7SVivien Didelot /* Action to be performed when the interrupt happens */ 5634d5f2ba7SVivien Didelot int (*irq_action)(struct mv88e6xxx_chip *chip, int irq); 5644d5f2ba7SVivien Didelot /* Setup the hardware to generate the interrupt */ 5654d5f2ba7SVivien Didelot int (*irq_setup)(struct mv88e6xxx_chip *chip); 5664d5f2ba7SVivien Didelot /* Reset the hardware to stop generating the interrupt */ 5674d5f2ba7SVivien Didelot void (*irq_free)(struct mv88e6xxx_chip *chip); 5684d5f2ba7SVivien Didelot }; 5694d5f2ba7SVivien Didelot 570a73ccd61SBrandon Streiff struct mv88e6xxx_gpio_ops { 571a73ccd61SBrandon Streiff /* Get/set data on GPIO pin */ 572a73ccd61SBrandon Streiff int (*get_data)(struct mv88e6xxx_chip *chip, unsigned int pin); 573a73ccd61SBrandon Streiff int (*set_data)(struct mv88e6xxx_chip *chip, unsigned int pin, 574a73ccd61SBrandon Streiff int value); 575a73ccd61SBrandon Streiff 576a73ccd61SBrandon Streiff /* get/set GPIO direction */ 577a73ccd61SBrandon Streiff int (*get_dir)(struct mv88e6xxx_chip *chip, unsigned int pin); 578a73ccd61SBrandon Streiff int (*set_dir)(struct mv88e6xxx_chip *chip, unsigned int pin, 579a73ccd61SBrandon Streiff bool input); 580a73ccd61SBrandon Streiff 581a73ccd61SBrandon Streiff /* get/set GPIO pin control */ 582a73ccd61SBrandon Streiff int (*get_pctl)(struct mv88e6xxx_chip *chip, unsigned int pin, 583a73ccd61SBrandon Streiff int *func); 584a73ccd61SBrandon Streiff int (*set_pctl)(struct mv88e6xxx_chip *chip, unsigned int pin, 585a73ccd61SBrandon Streiff int func); 586a73ccd61SBrandon Streiff }; 587a73ccd61SBrandon Streiff 5880d632c3dSBrandon Streiff struct mv88e6xxx_avb_ops { 5890d632c3dSBrandon Streiff /* Access port-scoped Precision Time Protocol registers */ 5900d632c3dSBrandon Streiff int (*port_ptp_read)(struct mv88e6xxx_chip *chip, int port, int addr, 5910d632c3dSBrandon Streiff u16 *data, int len); 5920d632c3dSBrandon Streiff int (*port_ptp_write)(struct mv88e6xxx_chip *chip, int port, int addr, 5930d632c3dSBrandon Streiff u16 data); 5940d632c3dSBrandon Streiff 5950d632c3dSBrandon Streiff /* Access global Precision Time Protocol registers */ 5960d632c3dSBrandon Streiff int (*ptp_read)(struct mv88e6xxx_chip *chip, int addr, u16 *data, 5970d632c3dSBrandon Streiff int len); 5980d632c3dSBrandon Streiff int (*ptp_write)(struct mv88e6xxx_chip *chip, int addr, u16 data); 5990d632c3dSBrandon Streiff 6000d632c3dSBrandon Streiff /* Access global Time Application Interface registers */ 6010d632c3dSBrandon Streiff int (*tai_read)(struct mv88e6xxx_chip *chip, int addr, u16 *data, 6020d632c3dSBrandon Streiff int len); 6030d632c3dSBrandon Streiff int (*tai_write)(struct mv88e6xxx_chip *chip, int addr, u16 data); 6040d632c3dSBrandon Streiff }; 6050d632c3dSBrandon Streiff 6066d2ac8eeSAndrew Lunn struct mv88e6xxx_ptp_ops { 6076d2ac8eeSAndrew Lunn u64 (*clock_read)(const struct cyclecounter *cc); 6086d2ac8eeSAndrew Lunn int (*ptp_enable)(struct ptp_clock_info *ptp, 6096d2ac8eeSAndrew Lunn struct ptp_clock_request *rq, int on); 6106d2ac8eeSAndrew Lunn int (*ptp_verify)(struct ptp_clock_info *ptp, unsigned int pin, 6116d2ac8eeSAndrew Lunn enum ptp_pin_function func, unsigned int chan); 6126d2ac8eeSAndrew Lunn void (*event_work)(struct work_struct *ugly); 613ffc705deSAndrew Lunn int (*port_enable)(struct mv88e6xxx_chip *chip, int port); 614ffc705deSAndrew Lunn int (*port_disable)(struct mv88e6xxx_chip *chip, int port); 615e2294a8bSAndrew Lunn int (*global_enable)(struct mv88e6xxx_chip *chip); 616e2294a8bSAndrew Lunn int (*global_disable)(struct mv88e6xxx_chip *chip); 6176d2ac8eeSAndrew Lunn int n_ext_ts; 618ffc705deSAndrew Lunn int arr0_sts_reg; 619ffc705deSAndrew Lunn int arr1_sts_reg; 620ffc705deSAndrew Lunn int dep_sts_reg; 62148cb5e03SAndrew Lunn u32 rx_filters; 62271509614SHubert Feurstein u32 cc_shift; 62371509614SHubert Feurstein u32 cc_mult; 62471509614SHubert Feurstein u32 cc_mult_num; 62571509614SHubert Feurstein u32 cc_mult_dem; 6266d2ac8eeSAndrew Lunn }; 6276d2ac8eeSAndrew Lunn 6284d5f2ba7SVivien Didelot #define STATS_TYPE_PORT BIT(0) 6294d5f2ba7SVivien Didelot #define STATS_TYPE_BANK0 BIT(1) 6304d5f2ba7SVivien Didelot #define STATS_TYPE_BANK1 BIT(2) 6314d5f2ba7SVivien Didelot 6324d5f2ba7SVivien Didelot struct mv88e6xxx_hw_stat { 6334d5f2ba7SVivien Didelot char string[ETH_GSTRING_LEN]; 634cda9f4aaSAndrew Lunn size_t size; 6354d5f2ba7SVivien Didelot int reg; 6364d5f2ba7SVivien Didelot int type; 6374d5f2ba7SVivien Didelot }; 6384d5f2ba7SVivien Didelot 6394d5f2ba7SVivien Didelot static inline bool mv88e6xxx_has_pvt(struct mv88e6xxx_chip *chip) 6404d5f2ba7SVivien Didelot { 6414d5f2ba7SVivien Didelot return chip->info->pvt; 6424d5f2ba7SVivien Didelot } 6434d5f2ba7SVivien Didelot 6444d5f2ba7SVivien Didelot static inline unsigned int mv88e6xxx_num_databases(struct mv88e6xxx_chip *chip) 6454d5f2ba7SVivien Didelot { 6464d5f2ba7SVivien Didelot return chip->info->num_databases; 6474d5f2ba7SVivien Didelot } 6484d5f2ba7SVivien Didelot 649d9ea5620SAndrew Lunn static inline unsigned int mv88e6xxx_num_macs(struct mv88e6xxx_chip *chip) 650d9ea5620SAndrew Lunn { 651d9ea5620SAndrew Lunn return chip->info->num_macs; 652d9ea5620SAndrew Lunn } 653d9ea5620SAndrew Lunn 6544d5f2ba7SVivien Didelot static inline unsigned int mv88e6xxx_num_ports(struct mv88e6xxx_chip *chip) 6554d5f2ba7SVivien Didelot { 6564d5f2ba7SVivien Didelot return chip->info->num_ports; 6574d5f2ba7SVivien Didelot } 6584d5f2ba7SVivien Didelot 6594d5f2ba7SVivien Didelot static inline u16 mv88e6xxx_port_mask(struct mv88e6xxx_chip *chip) 6604d5f2ba7SVivien Didelot { 661f1931164SAndrew Lunn return GENMASK((s32)mv88e6xxx_num_ports(chip) - 1, 0); 6624d5f2ba7SVivien Didelot } 6634d5f2ba7SVivien Didelot 664a73ccd61SBrandon Streiff static inline unsigned int mv88e6xxx_num_gpio(struct mv88e6xxx_chip *chip) 665a73ccd61SBrandon Streiff { 666a73ccd61SBrandon Streiff return chip->info->num_gpio; 667a73ccd61SBrandon Streiff } 668a73ccd61SBrandon Streiff 669c857486aSHubert Feurstein static inline bool mv88e6xxx_is_invalid_port(struct mv88e6xxx_chip *chip, int port) 670c857486aSHubert Feurstein { 671c857486aSHubert Feurstein return (chip->info->invalid_port_mask & BIT(port)) != 0; 672c857486aSHubert Feurstein } 673c857486aSHubert Feurstein 6744d5f2ba7SVivien Didelot int mv88e6xxx_read(struct mv88e6xxx_chip *chip, int addr, int reg, u16 *val); 6754d5f2ba7SVivien Didelot int mv88e6xxx_write(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val); 676683f2244SVivien Didelot int mv88e6xxx_wait_mask(struct mv88e6xxx_chip *chip, int addr, int reg, 677683f2244SVivien Didelot u16 mask, u16 val); 67819fb7f69SVivien Didelot int mv88e6xxx_wait_bit(struct mv88e6xxx_chip *chip, int addr, int reg, 67919fb7f69SVivien Didelot int bit, int val); 6804d5f2ba7SVivien Didelot struct mii_bus *mv88e6xxx_default_mdio_bus(struct mv88e6xxx_chip *chip); 6814d5f2ba7SVivien Didelot 682c9acece0SRasmus Villemoes static inline void mv88e6xxx_reg_lock(struct mv88e6xxx_chip *chip) 683c9acece0SRasmus Villemoes { 684c9acece0SRasmus Villemoes mutex_lock(&chip->reg_lock); 685c9acece0SRasmus Villemoes } 686c9acece0SRasmus Villemoes 687c9acece0SRasmus Villemoes static inline void mv88e6xxx_reg_unlock(struct mv88e6xxx_chip *chip) 688c9acece0SRasmus Villemoes { 689c9acece0SRasmus Villemoes mutex_unlock(&chip->reg_lock); 690c9acece0SRasmus Villemoes } 691c9acece0SRasmus Villemoes 69290b6dbdfSAndrew Lunn int mv88e6xxx_fid_map(struct mv88e6xxx_chip *chip, unsigned long *bitmap); 69390b6dbdfSAndrew Lunn 6944d5f2ba7SVivien Didelot #endif /* _MV88E6XXX_CHIP_H */ 695