1b31141d3SNishad Kamdar /* SPDX-License-Identifier: GPL-2.0 */ 2b31141d3SNishad Kamdar /* Microchip switch driver common header 3c2e86691STristram Ha * 47c6ff470STristram Ha * Copyright (C) 2017-2019 Microchip Technology Inc. 5c2e86691STristram Ha */ 6c2e86691STristram Ha 7c2e86691STristram Ha #ifndef __KSZ_COMMON_H 8c2e86691STristram Ha #define __KSZ_COMMON_H 9c2e86691STristram Ha 106a7abc61SMarek Vasut #include <linux/etherdevice.h> 116a7abc61SMarek Vasut #include <linux/kernel.h> 126a7abc61SMarek Vasut #include <linux/mutex.h> 136a7abc61SMarek Vasut #include <linux/phy.h> 14ee394feaSMarek Vasut #include <linux/regmap.h> 156a7abc61SMarek Vasut #include <net/dsa.h> 16c9cd961cSArun Ramadoss #include <linux/irq.h> 176a7abc61SMarek Vasut 1865ac79e1SArun Ramadoss #define KSZ_MAX_NUM_PORTS 8 1965ac79e1SArun Ramadoss 20f3c16545SArun Ramadoss struct ksz_device; 21f3c16545SArun Ramadoss 226a7abc61SMarek Vasut struct vlan_table { 236a7abc61SMarek Vasut u32 table[3]; 246a7abc61SMarek Vasut }; 256a7abc61SMarek Vasut 266a7abc61SMarek Vasut struct ksz_port_mib { 276a7abc61SMarek Vasut struct mutex cnt_mutex; /* structure access */ 286a7abc61SMarek Vasut u8 cnt_ptr; 296a7abc61SMarek Vasut u64 *counters; 30a7f4f13aSOleksij Rempel struct rtnl_link_stats64 stats64; 31c4748ff6SOleksij Rempel struct ethtool_pause_stats pause_stats; 32a7f4f13aSOleksij Rempel struct spinlock stats64_lock; 336a7abc61SMarek Vasut }; 346a7abc61SMarek Vasut 35a530e6f2SArun Ramadoss struct ksz_mib_names { 36a530e6f2SArun Ramadoss int index; 37a530e6f2SArun Ramadoss char string[ETH_GSTRING_LEN]; 38a530e6f2SArun Ramadoss }; 39a530e6f2SArun Ramadoss 40462d5250SArun Ramadoss struct ksz_chip_data { 41462d5250SArun Ramadoss u32 chip_id; 42462d5250SArun Ramadoss const char *dev_name; 43462d5250SArun Ramadoss int num_vlans; 44462d5250SArun Ramadoss int num_alus; 45462d5250SArun Ramadoss int num_statics; 46462d5250SArun Ramadoss int cpu_ports; 47462d5250SArun Ramadoss int port_cnt; 48978f1f72SArun Ramadoss u8 port_nirqs; 496ec23aaaSArun Ramadoss const struct ksz_dev_ops *ops; 50462d5250SArun Ramadoss bool phy_errata_9477; 51462d5250SArun Ramadoss bool ksz87xx_eee_link_erratum; 52a530e6f2SArun Ramadoss const struct ksz_mib_names *mib_names; 53a530e6f2SArun Ramadoss int mib_cnt; 54a530e6f2SArun Ramadoss u8 reg_mib_cnt; 55a02579dfSArun Ramadoss const u16 *regs; 56d23a5e18SArun Ramadoss const u32 *masks; 5734e48383SArun Ramadoss const u8 *shifts; 58aa5b8b73SArun Ramadoss const u8 *xmii_ctrl0; 5946f80fa8SArun Ramadoss const u8 *xmii_ctrl1; 60e593df51SArun Ramadoss int stp_ctrl_reg; 611ca6437fSArun Ramadoss int broadcast_ctrl_reg; 620abab9f3SArun Ramadoss int multicast_ctrl_reg; 63ad08ac18SArun Ramadoss int start_ctrl_reg; 6465ac79e1SArun Ramadoss bool supports_mii[KSZ_MAX_NUM_PORTS]; 6565ac79e1SArun Ramadoss bool supports_rmii[KSZ_MAX_NUM_PORTS]; 6665ac79e1SArun Ramadoss bool supports_rgmii[KSZ_MAX_NUM_PORTS]; 6765ac79e1SArun Ramadoss bool internal_phy[KSZ_MAX_NUM_PORTS]; 68505bf320SOleksij Rempel bool gbit_capable[KSZ_MAX_NUM_PORTS]; 69ec6ba50cSOleksij Rempel const struct regmap_access_table *wr_table; 70ec6ba50cSOleksij Rempel const struct regmap_access_table *rd_table; 71462d5250SArun Ramadoss }; 72462d5250SArun Ramadoss 73c9cd961cSArun Ramadoss struct ksz_irq { 74c9cd961cSArun Ramadoss u16 masked; 75e1add7ddSArun Ramadoss u16 reg_mask; 76e1add7ddSArun Ramadoss u16 reg_status; 77c9cd961cSArun Ramadoss struct irq_domain *domain; 78c9cd961cSArun Ramadoss int nirqs; 79e1add7ddSArun Ramadoss int irq_num; 80c9cd961cSArun Ramadoss char name[16]; 81e1add7ddSArun Ramadoss struct ksz_device *dev; 82c9cd961cSArun Ramadoss }; 83c9cd961cSArun Ramadoss 846a7abc61SMarek Vasut struct ksz_port { 858f4f58f8SBen Hutchings bool remove_tag; /* Remove Tag flag set, for ksz8795 only */ 8615f7cfaeSVladimir Oltean bool learning; 876a7abc61SMarek Vasut int stp_state; 886a7abc61SMarek Vasut struct phy_device phydev; 896a7abc61SMarek Vasut 906a7abc61SMarek Vasut u32 on:1; /* port is not disabled by hardware */ 916a7abc61SMarek Vasut u32 fiber:1; /* port is fiber */ 926a7abc61SMarek Vasut u32 force:1; 936a7abc61SMarek Vasut u32 read:1; /* read MIB counters in background */ 946a7abc61SMarek Vasut u32 freeze:1; /* MIB counter freeze is enabled */ 956a7abc61SMarek Vasut 966a7abc61SMarek Vasut struct ksz_port_mib mib; 97edecfa98SHelmut Grohne phy_interface_t interface; 98e18058eaSOleksij Rempel u16 max_frame; 99b19ac41fSArun Ramadoss u32 rgmii_tx_val; 100b19ac41fSArun Ramadoss u32 rgmii_rx_val; 101f3c16545SArun Ramadoss struct ksz_device *ksz_dev; 102c9cd961cSArun Ramadoss struct ksz_irq pirq; 103f3c16545SArun Ramadoss u8 num; 1046a7abc61SMarek Vasut }; 1056a7abc61SMarek Vasut 1066a7abc61SMarek Vasut struct ksz_device { 1076a7abc61SMarek Vasut struct dsa_switch *ds; 1086a7abc61SMarek Vasut struct ksz_platform_data *pdata; 109462d5250SArun Ramadoss const struct ksz_chip_data *info; 1106a7abc61SMarek Vasut 1116a7abc61SMarek Vasut struct mutex dev_mutex; /* device access */ 112013572a2SMarek Vasut struct mutex regmap_mutex; /* regmap access */ 1136a7abc61SMarek Vasut struct mutex alu_mutex; /* ALU access */ 1146a7abc61SMarek Vasut struct mutex vlan_mutex; /* vlan access */ 1156a7abc61SMarek Vasut const struct ksz_dev_ops *dev_ops; 1166a7abc61SMarek Vasut 1176a7abc61SMarek Vasut struct device *dev; 1186a7abc61SMarek Vasut struct regmap *regmap[3]; 1196a7abc61SMarek Vasut 1206a7abc61SMarek Vasut void *priv; 121c9cd961cSArun Ramadoss int irq; 1226a7abc61SMarek Vasut 1236a7abc61SMarek Vasut struct gpio_desc *reset_gpio; /* Optional reset GPIO */ 1246a7abc61SMarek Vasut 1256a7abc61SMarek Vasut /* chip specific data */ 1266a7abc61SMarek Vasut u32 chip_id; 12791a98917SArun Ramadoss u8 chip_rev; 1286a7abc61SMarek Vasut int cpu_port; /* port connected to CPU */ 1296a7abc61SMarek Vasut int phy_port_cnt; 130edecfa98SHelmut Grohne phy_interface_t compat_interface; 1316a7abc61SMarek Vasut bool synclko_125; 13248bf8b8aSRobert Hancock bool synclko_disable; 1336a7abc61SMarek Vasut 1346a7abc61SMarek Vasut struct vlan_table *vlan_cache; 1356a7abc61SMarek Vasut 1366a7abc61SMarek Vasut struct ksz_port *ports; 137469b390eSGeorge McCollister struct delayed_work mib_read; 1386a7abc61SMarek Vasut unsigned long mib_read_interval; 1396a7abc61SMarek Vasut u16 mirror_rx; 1406a7abc61SMarek Vasut u16 mirror_tx; 1416a7abc61SMarek Vasut u16 port_mask; 142c9cd961cSArun Ramadoss struct mutex lock_irq; /* IRQ Access */ 143c9cd961cSArun Ramadoss struct ksz_irq girq; 1446a7abc61SMarek Vasut }; 1456a7abc61SMarek Vasut 146462d5250SArun Ramadoss /* List of supported models */ 147462d5250SArun Ramadoss enum ksz_model { 148b4490809SOleksij Rempel KSZ8563, 149462d5250SArun Ramadoss KSZ8795, 150462d5250SArun Ramadoss KSZ8794, 151462d5250SArun Ramadoss KSZ8765, 152462d5250SArun Ramadoss KSZ8830, 153462d5250SArun Ramadoss KSZ9477, 1542eb3ff3cSRomain Naour KSZ9896, 155462d5250SArun Ramadoss KSZ9897, 156462d5250SArun Ramadoss KSZ9893, 157*ef912fe4SRakesh Sankaranarayanan KSZ9563, 158462d5250SArun Ramadoss KSZ9567, 159462d5250SArun Ramadoss LAN9370, 160462d5250SArun Ramadoss LAN9371, 161462d5250SArun Ramadoss LAN9372, 162462d5250SArun Ramadoss LAN9373, 163462d5250SArun Ramadoss LAN9374, 164462d5250SArun Ramadoss }; 165462d5250SArun Ramadoss 166462d5250SArun Ramadoss enum ksz_chip_id { 167b4490809SOleksij Rempel KSZ8563_CHIP_ID = 0x8563, 168462d5250SArun Ramadoss KSZ8795_CHIP_ID = 0x8795, 169462d5250SArun Ramadoss KSZ8794_CHIP_ID = 0x8794, 170462d5250SArun Ramadoss KSZ8765_CHIP_ID = 0x8765, 171462d5250SArun Ramadoss KSZ8830_CHIP_ID = 0x8830, 172462d5250SArun Ramadoss KSZ9477_CHIP_ID = 0x00947700, 1732eb3ff3cSRomain Naour KSZ9896_CHIP_ID = 0x00989600, 174462d5250SArun Ramadoss KSZ9897_CHIP_ID = 0x00989700, 175462d5250SArun Ramadoss KSZ9893_CHIP_ID = 0x00989300, 176*ef912fe4SRakesh Sankaranarayanan KSZ9563_CHIP_ID = 0x00956300, 177462d5250SArun Ramadoss KSZ9567_CHIP_ID = 0x00956700, 178462d5250SArun Ramadoss LAN9370_CHIP_ID = 0x00937000, 179462d5250SArun Ramadoss LAN9371_CHIP_ID = 0x00937100, 180462d5250SArun Ramadoss LAN9372_CHIP_ID = 0x00937200, 181462d5250SArun Ramadoss LAN9373_CHIP_ID = 0x00937300, 182462d5250SArun Ramadoss LAN9374_CHIP_ID = 0x00937400, 183462d5250SArun Ramadoss }; 184462d5250SArun Ramadoss 185486f9ca7SArun Ramadoss enum ksz_regs { 186486f9ca7SArun Ramadoss REG_IND_CTRL_0, 187486f9ca7SArun Ramadoss REG_IND_DATA_8, 188486f9ca7SArun Ramadoss REG_IND_DATA_CHECK, 189486f9ca7SArun Ramadoss REG_IND_DATA_HI, 190486f9ca7SArun Ramadoss REG_IND_DATA_LO, 191486f9ca7SArun Ramadoss REG_IND_MIB_CHECK, 192486f9ca7SArun Ramadoss REG_IND_BYTE, 193486f9ca7SArun Ramadoss P_FORCE_CTRL, 194486f9ca7SArun Ramadoss P_LINK_STATUS, 195486f9ca7SArun Ramadoss P_LOCAL_CTRL, 196486f9ca7SArun Ramadoss P_NEG_RESTART_CTRL, 197486f9ca7SArun Ramadoss P_REMOTE_STATUS, 198486f9ca7SArun Ramadoss P_SPEED_STATUS, 199486f9ca7SArun Ramadoss S_TAIL_TAG_CTRL, 2006877102fSArun Ramadoss P_STP_CTRL, 2019d95329cSArun Ramadoss S_START_CTRL, 2029d95329cSArun Ramadoss S_BROADCAST_CTRL, 2039d95329cSArun Ramadoss S_MULTICAST_CTRL, 204aa5b8b73SArun Ramadoss P_XMII_CTRL_0, 20546f80fa8SArun Ramadoss P_XMII_CTRL_1, 206486f9ca7SArun Ramadoss }; 207486f9ca7SArun Ramadoss 208d23a5e18SArun Ramadoss enum ksz_masks { 209d23a5e18SArun Ramadoss PORT_802_1P_REMAPPING, 210d23a5e18SArun Ramadoss SW_TAIL_TAG_ENABLE, 211d23a5e18SArun Ramadoss MIB_COUNTER_OVERFLOW, 212d23a5e18SArun Ramadoss MIB_COUNTER_VALID, 213d23a5e18SArun Ramadoss VLAN_TABLE_FID, 214d23a5e18SArun Ramadoss VLAN_TABLE_MEMBERSHIP, 215d23a5e18SArun Ramadoss VLAN_TABLE_VALID, 216d23a5e18SArun Ramadoss STATIC_MAC_TABLE_VALID, 217d23a5e18SArun Ramadoss STATIC_MAC_TABLE_USE_FID, 218d23a5e18SArun Ramadoss STATIC_MAC_TABLE_FID, 219d23a5e18SArun Ramadoss STATIC_MAC_TABLE_OVERRIDE, 220d23a5e18SArun Ramadoss STATIC_MAC_TABLE_FWD_PORTS, 221d23a5e18SArun Ramadoss DYNAMIC_MAC_TABLE_ENTRIES_H, 222d23a5e18SArun Ramadoss DYNAMIC_MAC_TABLE_MAC_EMPTY, 223d23a5e18SArun Ramadoss DYNAMIC_MAC_TABLE_NOT_READY, 224d23a5e18SArun Ramadoss DYNAMIC_MAC_TABLE_ENTRIES, 225d23a5e18SArun Ramadoss DYNAMIC_MAC_TABLE_FID, 226d23a5e18SArun Ramadoss DYNAMIC_MAC_TABLE_SRC_PORT, 227d23a5e18SArun Ramadoss DYNAMIC_MAC_TABLE_TIMESTAMP, 228457c182aSArun Ramadoss ALU_STAT_WRITE, 229457c182aSArun Ramadoss ALU_STAT_READ, 2308560664fSArun Ramadoss P_MII_TX_FLOW_CTRL, 2318560664fSArun Ramadoss P_MII_RX_FLOW_CTRL, 232d23a5e18SArun Ramadoss }; 233d23a5e18SArun Ramadoss 23434e48383SArun Ramadoss enum ksz_shifts { 23534e48383SArun Ramadoss VLAN_TABLE_MEMBERSHIP_S, 23634e48383SArun Ramadoss VLAN_TABLE, 23734e48383SArun Ramadoss STATIC_MAC_FWD_PORTS, 23834e48383SArun Ramadoss STATIC_MAC_FID, 23934e48383SArun Ramadoss DYNAMIC_MAC_ENTRIES_H, 24034e48383SArun Ramadoss DYNAMIC_MAC_ENTRIES, 24134e48383SArun Ramadoss DYNAMIC_MAC_FID, 24234e48383SArun Ramadoss DYNAMIC_MAC_TIMESTAMP, 24334e48383SArun Ramadoss DYNAMIC_MAC_SRC_PORT, 244457c182aSArun Ramadoss ALU_STAT_INDEX, 24534e48383SArun Ramadoss }; 24634e48383SArun Ramadoss 247aa5b8b73SArun Ramadoss enum ksz_xmii_ctrl0 { 248aa5b8b73SArun Ramadoss P_MII_100MBIT, 249aa5b8b73SArun Ramadoss P_MII_10MBIT, 2508560664fSArun Ramadoss P_MII_FULL_DUPLEX, 2518560664fSArun Ramadoss P_MII_HALF_DUPLEX, 252aa5b8b73SArun Ramadoss }; 253aa5b8b73SArun Ramadoss 25446f80fa8SArun Ramadoss enum ksz_xmii_ctrl1 { 255dc1c596eSArun Ramadoss P_RGMII_SEL, 256dc1c596eSArun Ramadoss P_RMII_SEL, 257dc1c596eSArun Ramadoss P_GMII_SEL, 258dc1c596eSArun Ramadoss P_MII_SEL, 25946f80fa8SArun Ramadoss P_GMII_1GBIT, 26046f80fa8SArun Ramadoss P_GMII_NOT_1GBIT, 26146f80fa8SArun Ramadoss }; 26246f80fa8SArun Ramadoss 2636a7abc61SMarek Vasut struct alu_struct { 2646a7abc61SMarek Vasut /* entry 1 */ 2656a7abc61SMarek Vasut u8 is_static:1; 2666a7abc61SMarek Vasut u8 is_src_filter:1; 2676a7abc61SMarek Vasut u8 is_dst_filter:1; 2686a7abc61SMarek Vasut u8 prio_age:3; 2696a7abc61SMarek Vasut u32 _reserv_0_1:23; 2706a7abc61SMarek Vasut u8 mstp:3; 2716a7abc61SMarek Vasut /* entry 2 */ 2726a7abc61SMarek Vasut u8 is_override:1; 2736a7abc61SMarek Vasut u8 is_use_fid:1; 2746a7abc61SMarek Vasut u32 _reserv_1_1:23; 2756a7abc61SMarek Vasut u8 port_forward:7; 2766a7abc61SMarek Vasut /* entry 3 & 4*/ 2776a7abc61SMarek Vasut u32 _reserv_2_1:9; 2786a7abc61SMarek Vasut u8 fid:7; 2796a7abc61SMarek Vasut u8 mac[ETH_ALEN]; 2806a7abc61SMarek Vasut }; 2816a7abc61SMarek Vasut 2826a7abc61SMarek Vasut struct ksz_dev_ops { 283d2822e68SArun Ramadoss int (*setup)(struct dsa_switch *ds); 284c9cd961cSArun Ramadoss void (*teardown)(struct dsa_switch *ds); 2856a7abc61SMarek Vasut u32 (*get_port_addr)(int port, int offset); 2866a7abc61SMarek Vasut void (*cfg_port_member)(struct ksz_device *dev, int port, u8 member); 2876a7abc61SMarek Vasut void (*flush_dyn_mac_table)(struct ksz_device *dev, int port); 2886a7abc61SMarek Vasut void (*port_cleanup)(struct ksz_device *dev, int port); 2896a7abc61SMarek Vasut void (*port_setup)(struct ksz_device *dev, int port, bool cpu_port); 2902c119d99SArun Ramadoss int (*set_ageing_time)(struct ksz_device *dev, unsigned int msecs); 2918f420456SOleksij Rempel int (*r_phy)(struct ksz_device *dev, u16 phy, u16 reg, u16 *val); 2928f420456SOleksij Rempel int (*w_phy)(struct ksz_device *dev, u16 phy, u16 reg, u16 val); 2936a7abc61SMarek Vasut void (*r_mib_cnt)(struct ksz_device *dev, int port, u16 addr, 2946a7abc61SMarek Vasut u64 *cnt); 2956a7abc61SMarek Vasut void (*r_mib_pkt)(struct ksz_device *dev, int port, u16 addr, 2966a7abc61SMarek Vasut u64 *dropped, u64 *cnt); 297a7f4f13aSOleksij Rempel void (*r_mib_stat64)(struct ksz_device *dev, int port); 298f0d997e3SArun Ramadoss int (*vlan_filtering)(struct ksz_device *dev, int port, 299f0d997e3SArun Ramadoss bool flag, struct netlink_ext_ack *extack); 300f0d997e3SArun Ramadoss int (*vlan_add)(struct ksz_device *dev, int port, 301f0d997e3SArun Ramadoss const struct switchdev_obj_port_vlan *vlan, 302f0d997e3SArun Ramadoss struct netlink_ext_ack *extack); 303f0d997e3SArun Ramadoss int (*vlan_del)(struct ksz_device *dev, int port, 304f0d997e3SArun Ramadoss const struct switchdev_obj_port_vlan *vlan); 30500a298bbSArun Ramadoss int (*mirror_add)(struct ksz_device *dev, int port, 30600a298bbSArun Ramadoss struct dsa_mall_mirror_tc_entry *mirror, 30700a298bbSArun Ramadoss bool ingress, struct netlink_ext_ack *extack); 30800a298bbSArun Ramadoss void (*mirror_del)(struct ksz_device *dev, int port, 30900a298bbSArun Ramadoss struct dsa_mall_mirror_tc_entry *mirror); 310e587be75SArun Ramadoss int (*fdb_add)(struct ksz_device *dev, int port, 311e587be75SArun Ramadoss const unsigned char *addr, u16 vid, struct dsa_db db); 312e587be75SArun Ramadoss int (*fdb_del)(struct ksz_device *dev, int port, 313e587be75SArun Ramadoss const unsigned char *addr, u16 vid, struct dsa_db db); 314e587be75SArun Ramadoss int (*fdb_dump)(struct ksz_device *dev, int port, 315e587be75SArun Ramadoss dsa_fdb_dump_cb_t *cb, void *data); 316980c7d17SArun Ramadoss int (*mdb_add)(struct ksz_device *dev, int port, 317980c7d17SArun Ramadoss const struct switchdev_obj_port_mdb *mdb, 318980c7d17SArun Ramadoss struct dsa_db db); 319980c7d17SArun Ramadoss int (*mdb_del)(struct ksz_device *dev, int port, 320980c7d17SArun Ramadoss const struct switchdev_obj_port_mdb *mdb, 321980c7d17SArun Ramadoss struct dsa_db db); 3227012033cSArun Ramadoss void (*get_caps)(struct ksz_device *dev, int port, 3237012033cSArun Ramadoss struct phylink_config *config); 3241fe94f54SArun Ramadoss int (*change_mtu)(struct ksz_device *dev, int port, int mtu); 3251fe94f54SArun Ramadoss int (*max_mtu)(struct ksz_device *dev, int port); 3266a7abc61SMarek Vasut void (*freeze_mib)(struct ksz_device *dev, int port, bool freeze); 3276a7abc61SMarek Vasut void (*port_init_cnt)(struct ksz_device *dev, int port); 328a0cb1aa4SArun Ramadoss void (*phylink_mac_config)(struct ksz_device *dev, int port, 329a0cb1aa4SArun Ramadoss unsigned int mode, 330a0cb1aa4SArun Ramadoss const struct phylink_link_state *state); 331f597d3adSArun Ramadoss void (*phylink_mac_link_up)(struct ksz_device *dev, int port, 332f597d3adSArun Ramadoss unsigned int mode, 333f597d3adSArun Ramadoss phy_interface_t interface, 334f597d3adSArun Ramadoss struct phy_device *phydev, int speed, 335f597d3adSArun Ramadoss int duplex, bool tx_pause, bool rx_pause); 336b19ac41fSArun Ramadoss void (*setup_rgmii_delay)(struct ksz_device *dev, int port); 337fb9324beSArun Ramadoss void (*config_cpu_port)(struct dsa_switch *ds); 338331d64f7SArun Ramadoss int (*enable_stp_addr)(struct ksz_device *dev); 339673b196fSArun Ramadoss int (*reset)(struct ksz_device *dev); 3406a7abc61SMarek Vasut int (*init)(struct ksz_device *dev); 3416a7abc61SMarek Vasut void (*exit)(struct ksz_device *dev); 3426a7abc61SMarek Vasut }; 3436a7abc61SMarek Vasut 3446a7abc61SMarek Vasut struct ksz_device *ksz_switch_alloc(struct device *base, void *priv); 3456ec23aaaSArun Ramadoss int ksz_switch_register(struct ksz_device *dev); 3466a7abc61SMarek Vasut void ksz_switch_remove(struct ksz_device *dev); 3476a7abc61SMarek Vasut 3487c6ff470STristram Ha void ksz_init_mib_timer(struct ksz_device *dev); 349c6101dd7SArun Ramadoss void ksz_r_mib_stats64(struct ksz_device *dev, int port); 350e593df51SArun Ramadoss void ksz_port_stp_state_set(struct dsa_switch *ds, int port, u8 state); 35146f80fa8SArun Ramadoss bool ksz_get_gbit(struct ksz_device *dev, int port); 3520ab7f6bfSArun Ramadoss phy_interface_t ksz_get_xmii(struct ksz_device *dev, int port, bool gbit); 3531958eee8SArun Ramadoss extern const struct ksz_chip_data ksz_switch_chips[]; 354c2e86691STristram Ha 355c2e86691STristram Ha /* Common register access functions */ 356c2e86691STristram Ha 357c2e86691STristram Ha static inline int ksz_read8(struct ksz_device *dev, u32 reg, u8 *val) 358c2e86691STristram Ha { 359ee394feaSMarek Vasut unsigned int value; 360ee394feaSMarek Vasut int ret = regmap_read(dev->regmap[0], reg, &value); 361c2e86691STristram Ha 362ec6ba50cSOleksij Rempel if (ret) 363ec6ba50cSOleksij Rempel dev_err(dev->dev, "can't read 8bit reg: 0x%x %pe\n", reg, 364ec6ba50cSOleksij Rempel ERR_PTR(ret)); 365ec6ba50cSOleksij Rempel 366ee394feaSMarek Vasut *val = value; 367c2e86691STristram Ha return ret; 368c2e86691STristram Ha } 369c2e86691STristram Ha 370c2e86691STristram Ha static inline int ksz_read16(struct ksz_device *dev, u32 reg, u16 *val) 371c2e86691STristram Ha { 372ee394feaSMarek Vasut unsigned int value; 373ee394feaSMarek Vasut int ret = regmap_read(dev->regmap[1], reg, &value); 374c2e86691STristram Ha 375ec6ba50cSOleksij Rempel if (ret) 376ec6ba50cSOleksij Rempel dev_err(dev->dev, "can't read 16bit reg: 0x%x %pe\n", reg, 377ec6ba50cSOleksij Rempel ERR_PTR(ret)); 378ec6ba50cSOleksij Rempel 379ee394feaSMarek Vasut *val = value; 380c2e86691STristram Ha return ret; 381c2e86691STristram Ha } 382c2e86691STristram Ha 383c2e86691STristram Ha static inline int ksz_read32(struct ksz_device *dev, u32 reg, u32 *val) 384c2e86691STristram Ha { 385ee394feaSMarek Vasut unsigned int value; 386ee394feaSMarek Vasut int ret = regmap_read(dev->regmap[2], reg, &value); 387c2e86691STristram Ha 388ec6ba50cSOleksij Rempel if (ret) 389ec6ba50cSOleksij Rempel dev_err(dev->dev, "can't read 32bit reg: 0x%x %pe\n", reg, 390ec6ba50cSOleksij Rempel ERR_PTR(ret)); 391ec6ba50cSOleksij Rempel 392ee394feaSMarek Vasut *val = value; 393c2e86691STristram Ha return ret; 394c2e86691STristram Ha } 395c2e86691STristram Ha 396e66f840cSTristram Ha static inline int ksz_read64(struct ksz_device *dev, u32 reg, u64 *val) 397e66f840cSTristram Ha { 398e66f840cSTristram Ha u32 value[2]; 399e66f840cSTristram Ha int ret; 400e66f840cSTristram Ha 401e66f840cSTristram Ha ret = regmap_bulk_read(dev->regmap[2], reg, value, 2); 402ec6ba50cSOleksij Rempel if (ret) 403ec6ba50cSOleksij Rempel dev_err(dev->dev, "can't read 64bit reg: 0x%x %pe\n", reg, 404ec6ba50cSOleksij Rempel ERR_PTR(ret)); 405ec6ba50cSOleksij Rempel else 406c34f674cSBen Hutchings *val = (u64)value[0] << 32 | value[1]; 407e66f840cSTristram Ha 408e66f840cSTristram Ha return ret; 409e66f840cSTristram Ha } 410e66f840cSTristram Ha 411c2e86691STristram Ha static inline int ksz_write8(struct ksz_device *dev, u32 reg, u8 value) 412c2e86691STristram Ha { 413ec6ba50cSOleksij Rempel int ret; 414ec6ba50cSOleksij Rempel 415ec6ba50cSOleksij Rempel ret = regmap_write(dev->regmap[0], reg, value); 416ec6ba50cSOleksij Rempel if (ret) 417ec6ba50cSOleksij Rempel dev_err(dev->dev, "can't write 8bit reg: 0x%x %pe\n", reg, 418ec6ba50cSOleksij Rempel ERR_PTR(ret)); 419ec6ba50cSOleksij Rempel 420ec6ba50cSOleksij Rempel return ret; 421c2e86691STristram Ha } 422c2e86691STristram Ha 423c2e86691STristram Ha static inline int ksz_write16(struct ksz_device *dev, u32 reg, u16 value) 424c2e86691STristram Ha { 425ec6ba50cSOleksij Rempel int ret; 426ec6ba50cSOleksij Rempel 427ec6ba50cSOleksij Rempel ret = regmap_write(dev->regmap[1], reg, value); 428ec6ba50cSOleksij Rempel if (ret) 429ec6ba50cSOleksij Rempel dev_err(dev->dev, "can't write 16bit reg: 0x%x %pe\n", reg, 430ec6ba50cSOleksij Rempel ERR_PTR(ret)); 431ec6ba50cSOleksij Rempel 432ec6ba50cSOleksij Rempel return ret; 433c2e86691STristram Ha } 434c2e86691STristram Ha 435c2e86691STristram Ha static inline int ksz_write32(struct ksz_device *dev, u32 reg, u32 value) 436c2e86691STristram Ha { 437ec6ba50cSOleksij Rempel int ret; 438ec6ba50cSOleksij Rempel 439ec6ba50cSOleksij Rempel ret = regmap_write(dev->regmap[2], reg, value); 440ec6ba50cSOleksij Rempel if (ret) 441ec6ba50cSOleksij Rempel dev_err(dev->dev, "can't write 32bit reg: 0x%x %pe\n", reg, 442ec6ba50cSOleksij Rempel ERR_PTR(ret)); 443ec6ba50cSOleksij Rempel 444ec6ba50cSOleksij Rempel return ret; 445c2e86691STristram Ha } 446c2e86691STristram Ha 447e66f840cSTristram Ha static inline int ksz_write64(struct ksz_device *dev, u32 reg, u64 value) 448e66f840cSTristram Ha { 449e66f840cSTristram Ha u32 val[2]; 450e66f840cSTristram Ha 451e66f840cSTristram Ha /* Ick! ToDo: Add 64bit R/W to regmap on 32bit systems */ 452e66f840cSTristram Ha value = swab64(value); 453e66f840cSTristram Ha val[0] = swab32(value & 0xffffffffULL); 454e66f840cSTristram Ha val[1] = swab32(value >> 32ULL); 455e66f840cSTristram Ha 456e66f840cSTristram Ha return regmap_bulk_write(dev->regmap[2], reg, val, 2); 457e66f840cSTristram Ha } 458e66f840cSTristram Ha 459d38bc3b4SOleksij Rempel static inline int ksz_pread8(struct ksz_device *dev, int port, int offset, 460c2e86691STristram Ha u8 *data) 461c2e86691STristram Ha { 462d38bc3b4SOleksij Rempel return ksz_read8(dev, dev->dev_ops->get_port_addr(port, offset), data); 463c2e86691STristram Ha } 464c2e86691STristram Ha 465d38bc3b4SOleksij Rempel static inline int ksz_pread16(struct ksz_device *dev, int port, int offset, 466c2e86691STristram Ha u16 *data) 467c2e86691STristram Ha { 468d38bc3b4SOleksij Rempel return ksz_read16(dev, dev->dev_ops->get_port_addr(port, offset), data); 469c2e86691STristram Ha } 470c2e86691STristram Ha 471d38bc3b4SOleksij Rempel static inline int ksz_pread32(struct ksz_device *dev, int port, int offset, 472c2e86691STristram Ha u32 *data) 473c2e86691STristram Ha { 474d38bc3b4SOleksij Rempel return ksz_read32(dev, dev->dev_ops->get_port_addr(port, offset), data); 475c2e86691STristram Ha } 476c2e86691STristram Ha 477d38bc3b4SOleksij Rempel static inline int ksz_pwrite8(struct ksz_device *dev, int port, int offset, 478c2e86691STristram Ha u8 data) 479c2e86691STristram Ha { 480d38bc3b4SOleksij Rempel return ksz_write8(dev, dev->dev_ops->get_port_addr(port, offset), data); 481c2e86691STristram Ha } 482c2e86691STristram Ha 483d38bc3b4SOleksij Rempel static inline int ksz_pwrite16(struct ksz_device *dev, int port, int offset, 484c2e86691STristram Ha u16 data) 485c2e86691STristram Ha { 486d38bc3b4SOleksij Rempel return ksz_write16(dev, dev->dev_ops->get_port_addr(port, offset), 487d38bc3b4SOleksij Rempel data); 488c2e86691STristram Ha } 489c2e86691STristram Ha 490d38bc3b4SOleksij Rempel static inline int ksz_pwrite32(struct ksz_device *dev, int port, int offset, 491c2e86691STristram Ha u32 data) 492c2e86691STristram Ha { 493d38bc3b4SOleksij Rempel return ksz_write32(dev, dev->dev_ops->get_port_addr(port, offset), 494d38bc3b4SOleksij Rempel data); 495c2e86691STristram Ha } 496c2e86691STristram Ha 4978560664fSArun Ramadoss static inline void ksz_prmw8(struct ksz_device *dev, int port, int offset, 4988560664fSArun Ramadoss u8 mask, u8 val) 4998560664fSArun Ramadoss { 5008560664fSArun Ramadoss regmap_update_bits(dev->regmap[0], 5018560664fSArun Ramadoss dev->dev_ops->get_port_addr(port, offset), 5028560664fSArun Ramadoss mask, val); 5038560664fSArun Ramadoss } 5048560664fSArun Ramadoss 505013572a2SMarek Vasut static inline void ksz_regmap_lock(void *__mtx) 506013572a2SMarek Vasut { 507013572a2SMarek Vasut struct mutex *mtx = __mtx; 508013572a2SMarek Vasut mutex_lock(mtx); 509013572a2SMarek Vasut } 510013572a2SMarek Vasut 511013572a2SMarek Vasut static inline void ksz_regmap_unlock(void *__mtx) 512013572a2SMarek Vasut { 513013572a2SMarek Vasut struct mutex *mtx = __mtx; 514013572a2SMarek Vasut mutex_unlock(mtx); 515013572a2SMarek Vasut } 516013572a2SMarek Vasut 517f3d890f5SArun Ramadoss static inline bool ksz_is_ksz88x3(struct ksz_device *dev) 518f3d890f5SArun Ramadoss { 519f3d890f5SArun Ramadoss return dev->chip_id == KSZ8830_CHIP_ID; 520f3d890f5SArun Ramadoss } 521f3d890f5SArun Ramadoss 52299b16df0SArun Ramadoss static inline int is_lan937x(struct ksz_device *dev) 52399b16df0SArun Ramadoss { 52499b16df0SArun Ramadoss return dev->chip_id == LAN9370_CHIP_ID || 52599b16df0SArun Ramadoss dev->chip_id == LAN9371_CHIP_ID || 52699b16df0SArun Ramadoss dev->chip_id == LAN9372_CHIP_ID || 52799b16df0SArun Ramadoss dev->chip_id == LAN9373_CHIP_ID || 52899b16df0SArun Ramadoss dev->chip_id == LAN9374_CHIP_ID; 52999b16df0SArun Ramadoss } 53099b16df0SArun Ramadoss 531de6dd626SArun Ramadoss /* STP State Defines */ 532de6dd626SArun Ramadoss #define PORT_TX_ENABLE BIT(2) 533de6dd626SArun Ramadoss #define PORT_RX_ENABLE BIT(1) 534de6dd626SArun Ramadoss #define PORT_LEARN_DISABLE BIT(0) 535de6dd626SArun Ramadoss 53691a98917SArun Ramadoss /* Switch ID Defines */ 53791a98917SArun Ramadoss #define REG_CHIP_ID0 0x00 53891a98917SArun Ramadoss 53991a98917SArun Ramadoss #define SW_FAMILY_ID_M GENMASK(15, 8) 54091a98917SArun Ramadoss #define KSZ87_FAMILY_ID 0x87 54191a98917SArun Ramadoss #define KSZ88_FAMILY_ID 0x88 54291a98917SArun Ramadoss 54391a98917SArun Ramadoss #define KSZ8_PORT_STATUS_0 0x08 54491a98917SArun Ramadoss #define KSZ8_PORT_FIBER_MODE BIT(7) 54591a98917SArun Ramadoss 54691a98917SArun Ramadoss #define SW_CHIP_ID_M GENMASK(7, 4) 54791a98917SArun Ramadoss #define KSZ87_CHIP_ID_94 0x6 54891a98917SArun Ramadoss #define KSZ87_CHIP_ID_95 0x9 54991a98917SArun Ramadoss #define KSZ88_CHIP_ID_63 0x3 55091a98917SArun Ramadoss 55191a98917SArun Ramadoss #define SW_REV_ID_M GENMASK(7, 4) 55291a98917SArun Ramadoss 553b4490809SOleksij Rempel /* KSZ9893, KSZ9563, KSZ8563 specific register */ 554b4490809SOleksij Rempel #define REG_CHIP_ID4 0x0f 555b4490809SOleksij Rempel #define SKU_ID_KSZ8563 0x3c 556*ef912fe4SRakesh Sankaranarayanan #define SKU_ID_KSZ9563 0x1c 557b4490809SOleksij Rempel 5581ca6437fSArun Ramadoss /* Driver set switch broadcast storm protection at 10% rate. */ 5591ca6437fSArun Ramadoss #define BROADCAST_STORM_PROT_RATE 10 5601ca6437fSArun Ramadoss 5611ca6437fSArun Ramadoss /* 148,800 frames * 67 ms / 100 */ 5621ca6437fSArun Ramadoss #define BROADCAST_STORM_VALUE 9969 5631ca6437fSArun Ramadoss 5641ca6437fSArun Ramadoss #define BROADCAST_STORM_RATE_HI 0x07 5651ca6437fSArun Ramadoss #define BROADCAST_STORM_RATE_LO 0xFF 5661ca6437fSArun Ramadoss #define BROADCAST_STORM_RATE 0x07FF 5671ca6437fSArun Ramadoss 5680abab9f3SArun Ramadoss #define MULTICAST_STORM_DISABLE BIT(6) 5690abab9f3SArun Ramadoss 570ad08ac18SArun Ramadoss #define SW_START 0x01 571ad08ac18SArun Ramadoss 57246f80fa8SArun Ramadoss /* xMII configuration */ 5738560664fSArun Ramadoss #define P_MII_DUPLEX_M BIT(6) 574aa5b8b73SArun Ramadoss #define P_MII_100MBIT_M BIT(4) 575aa5b8b73SArun Ramadoss 57646f80fa8SArun Ramadoss #define P_GMII_1GBIT_M BIT(6) 577dc1c596eSArun Ramadoss #define P_RGMII_ID_IG_ENABLE BIT(4) 578dc1c596eSArun Ramadoss #define P_RGMII_ID_EG_ENABLE BIT(3) 5790ab7f6bfSArun Ramadoss #define P_MII_MAC_MODE BIT(2) 580dc1c596eSArun Ramadoss #define P_MII_SEL_M 0x3 58146f80fa8SArun Ramadoss 582ff319a64SArun Ramadoss /* Interrupt */ 583e1add7ddSArun Ramadoss #define REG_SW_PORT_INT_STATUS__1 0x001B 584e1add7ddSArun Ramadoss #define REG_SW_PORT_INT_MASK__1 0x001F 585ff319a64SArun Ramadoss 586ff319a64SArun Ramadoss #define REG_PORT_INT_STATUS 0x001B 587ff319a64SArun Ramadoss #define REG_PORT_INT_MASK 0x001F 588ff319a64SArun Ramadoss 589ff319a64SArun Ramadoss #define PORT_SRC_PHY_INT 1 590ff319a64SArun Ramadoss 591255b59adSMarek Vasut /* Regmap tables generation */ 592255b59adSMarek Vasut #define KSZ_SPI_OP_RD 3 593255b59adSMarek Vasut #define KSZ_SPI_OP_WR 2 594255b59adSMarek Vasut 59520e03777STristram Ha #define swabnot_used(x) 0 59620e03777STristram Ha 597255b59adSMarek Vasut #define KSZ_SPI_OP_FLAG_MASK(opcode, swp, regbits, regpad) \ 598255b59adSMarek Vasut swab##swp((opcode) << ((regbits) + (regpad))) 599255b59adSMarek Vasut 600255b59adSMarek Vasut #define KSZ_REGMAP_ENTRY(width, swp, regbits, regpad, regalign) \ 601255b59adSMarek Vasut { \ 6025f81d545SGeorge McCollister .name = #width, \ 603255b59adSMarek Vasut .val_bits = (width), \ 604a3aa6e65SMarek Vasut .reg_stride = 1, \ 605255b59adSMarek Vasut .reg_bits = (regbits) + (regalign), \ 606255b59adSMarek Vasut .pad_bits = (regpad), \ 607255b59adSMarek Vasut .max_register = BIT(regbits) - 1, \ 608255b59adSMarek Vasut .cache_type = REGCACHE_NONE, \ 609255b59adSMarek Vasut .read_flag_mask = \ 610255b59adSMarek Vasut KSZ_SPI_OP_FLAG_MASK(KSZ_SPI_OP_RD, swp, \ 611255b59adSMarek Vasut regbits, regpad), \ 612255b59adSMarek Vasut .write_flag_mask = \ 613255b59adSMarek Vasut KSZ_SPI_OP_FLAG_MASK(KSZ_SPI_OP_WR, swp, \ 614255b59adSMarek Vasut regbits, regpad), \ 615013572a2SMarek Vasut .lock = ksz_regmap_lock, \ 616013572a2SMarek Vasut .unlock = ksz_regmap_unlock, \ 617255b59adSMarek Vasut .reg_format_endian = REGMAP_ENDIAN_BIG, \ 618255b59adSMarek Vasut .val_format_endian = REGMAP_ENDIAN_BIG \ 619255b59adSMarek Vasut } 620255b59adSMarek Vasut 621255b59adSMarek Vasut #define KSZ_REGMAP_TABLE(ksz, swp, regbits, regpad, regalign) \ 622255b59adSMarek Vasut static const struct regmap_config ksz##_regmap_config[] = { \ 623255b59adSMarek Vasut KSZ_REGMAP_ENTRY(8, swp, (regbits), (regpad), (regalign)), \ 624255b59adSMarek Vasut KSZ_REGMAP_ENTRY(16, swp, (regbits), (regpad), (regalign)), \ 625255b59adSMarek Vasut KSZ_REGMAP_ENTRY(32, swp, (regbits), (regpad), (regalign)), \ 626255b59adSMarek Vasut } 627255b59adSMarek Vasut 628c2e86691STristram Ha #endif 629