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; 486ec23aaaSArun Ramadoss const struct ksz_dev_ops *ops; 49462d5250SArun Ramadoss bool phy_errata_9477; 50462d5250SArun Ramadoss bool ksz87xx_eee_link_erratum; 51a530e6f2SArun Ramadoss const struct ksz_mib_names *mib_names; 52a530e6f2SArun Ramadoss int mib_cnt; 53a530e6f2SArun Ramadoss u8 reg_mib_cnt; 54a02579dfSArun Ramadoss const u16 *regs; 55d23a5e18SArun Ramadoss const u32 *masks; 5634e48383SArun Ramadoss const u8 *shifts; 57aa5b8b73SArun Ramadoss const u8 *xmii_ctrl0; 5846f80fa8SArun Ramadoss const u8 *xmii_ctrl1; 59e593df51SArun Ramadoss int stp_ctrl_reg; 601ca6437fSArun Ramadoss int broadcast_ctrl_reg; 610abab9f3SArun Ramadoss int multicast_ctrl_reg; 62ad08ac18SArun Ramadoss int start_ctrl_reg; 6365ac79e1SArun Ramadoss bool supports_mii[KSZ_MAX_NUM_PORTS]; 6465ac79e1SArun Ramadoss bool supports_rmii[KSZ_MAX_NUM_PORTS]; 6565ac79e1SArun Ramadoss bool supports_rgmii[KSZ_MAX_NUM_PORTS]; 6665ac79e1SArun Ramadoss bool internal_phy[KSZ_MAX_NUM_PORTS]; 67505bf320SOleksij Rempel bool gbit_capable[KSZ_MAX_NUM_PORTS]; 68ec6ba50cSOleksij Rempel const struct regmap_access_table *wr_table; 69ec6ba50cSOleksij Rempel const struct regmap_access_table *rd_table; 70462d5250SArun Ramadoss }; 71462d5250SArun Ramadoss 72c9cd961cSArun Ramadoss struct ksz_irq { 73c9cd961cSArun Ramadoss u16 masked; 74c9cd961cSArun Ramadoss struct irq_chip chip; 75c9cd961cSArun Ramadoss struct irq_domain *domain; 76c9cd961cSArun Ramadoss int nirqs; 77c9cd961cSArun Ramadoss char name[16]; 78c9cd961cSArun Ramadoss }; 79c9cd961cSArun Ramadoss 806a7abc61SMarek Vasut struct ksz_port { 818f4f58f8SBen Hutchings bool remove_tag; /* Remove Tag flag set, for ksz8795 only */ 8215f7cfaeSVladimir Oltean bool learning; 836a7abc61SMarek Vasut int stp_state; 846a7abc61SMarek Vasut struct phy_device phydev; 856a7abc61SMarek Vasut 866a7abc61SMarek Vasut u32 on:1; /* port is not disabled by hardware */ 876a7abc61SMarek Vasut u32 fiber:1; /* port is fiber */ 886a7abc61SMarek Vasut u32 force:1; 896a7abc61SMarek Vasut u32 read:1; /* read MIB counters in background */ 906a7abc61SMarek Vasut u32 freeze:1; /* MIB counter freeze is enabled */ 916a7abc61SMarek Vasut 926a7abc61SMarek Vasut struct ksz_port_mib mib; 93edecfa98SHelmut Grohne phy_interface_t interface; 94e18058eaSOleksij Rempel u16 max_frame; 95b19ac41fSArun Ramadoss u32 rgmii_tx_val; 96b19ac41fSArun Ramadoss u32 rgmii_rx_val; 97f3c16545SArun Ramadoss struct ksz_device *ksz_dev; 98c9cd961cSArun Ramadoss struct ksz_irq pirq; 99f3c16545SArun Ramadoss u8 num; 1006a7abc61SMarek Vasut }; 1016a7abc61SMarek Vasut 1026a7abc61SMarek Vasut struct ksz_device { 1036a7abc61SMarek Vasut struct dsa_switch *ds; 1046a7abc61SMarek Vasut struct ksz_platform_data *pdata; 105462d5250SArun Ramadoss const struct ksz_chip_data *info; 1066a7abc61SMarek Vasut 1076a7abc61SMarek Vasut struct mutex dev_mutex; /* device access */ 108013572a2SMarek Vasut struct mutex regmap_mutex; /* regmap access */ 1096a7abc61SMarek Vasut struct mutex alu_mutex; /* ALU access */ 1106a7abc61SMarek Vasut struct mutex vlan_mutex; /* vlan access */ 1116a7abc61SMarek Vasut const struct ksz_dev_ops *dev_ops; 1126a7abc61SMarek Vasut 1136a7abc61SMarek Vasut struct device *dev; 1146a7abc61SMarek Vasut struct regmap *regmap[3]; 1156a7abc61SMarek Vasut 1166a7abc61SMarek Vasut void *priv; 117c9cd961cSArun Ramadoss int irq; 1186a7abc61SMarek Vasut 1196a7abc61SMarek Vasut struct gpio_desc *reset_gpio; /* Optional reset GPIO */ 1206a7abc61SMarek Vasut 1216a7abc61SMarek Vasut /* chip specific data */ 1226a7abc61SMarek Vasut u32 chip_id; 12391a98917SArun Ramadoss u8 chip_rev; 1246a7abc61SMarek Vasut int cpu_port; /* port connected to CPU */ 1256a7abc61SMarek Vasut int phy_port_cnt; 126edecfa98SHelmut Grohne phy_interface_t compat_interface; 1276a7abc61SMarek Vasut bool synclko_125; 12848bf8b8aSRobert Hancock bool synclko_disable; 1296a7abc61SMarek Vasut 1306a7abc61SMarek Vasut struct vlan_table *vlan_cache; 1316a7abc61SMarek Vasut 1326a7abc61SMarek Vasut struct ksz_port *ports; 133469b390eSGeorge McCollister struct delayed_work mib_read; 1346a7abc61SMarek Vasut unsigned long mib_read_interval; 1356a7abc61SMarek Vasut u16 mirror_rx; 1366a7abc61SMarek Vasut u16 mirror_tx; 1376a7abc61SMarek Vasut u16 port_mask; 138c9cd961cSArun Ramadoss struct mutex lock_irq; /* IRQ Access */ 139c9cd961cSArun Ramadoss struct ksz_irq girq; 1406a7abc61SMarek Vasut }; 1416a7abc61SMarek Vasut 142462d5250SArun Ramadoss /* List of supported models */ 143462d5250SArun Ramadoss enum ksz_model { 144b4490809SOleksij Rempel KSZ8563, 145462d5250SArun Ramadoss KSZ8795, 146462d5250SArun Ramadoss KSZ8794, 147462d5250SArun Ramadoss KSZ8765, 148462d5250SArun Ramadoss KSZ8830, 149462d5250SArun Ramadoss KSZ9477, 150*2eb3ff3cSRomain Naour KSZ9896, 151462d5250SArun Ramadoss KSZ9897, 152462d5250SArun Ramadoss KSZ9893, 153462d5250SArun Ramadoss KSZ9567, 154462d5250SArun Ramadoss LAN9370, 155462d5250SArun Ramadoss LAN9371, 156462d5250SArun Ramadoss LAN9372, 157462d5250SArun Ramadoss LAN9373, 158462d5250SArun Ramadoss LAN9374, 159462d5250SArun Ramadoss }; 160462d5250SArun Ramadoss 161462d5250SArun Ramadoss enum ksz_chip_id { 162b4490809SOleksij Rempel KSZ8563_CHIP_ID = 0x8563, 163462d5250SArun Ramadoss KSZ8795_CHIP_ID = 0x8795, 164462d5250SArun Ramadoss KSZ8794_CHIP_ID = 0x8794, 165462d5250SArun Ramadoss KSZ8765_CHIP_ID = 0x8765, 166462d5250SArun Ramadoss KSZ8830_CHIP_ID = 0x8830, 167462d5250SArun Ramadoss KSZ9477_CHIP_ID = 0x00947700, 168*2eb3ff3cSRomain Naour KSZ9896_CHIP_ID = 0x00989600, 169462d5250SArun Ramadoss KSZ9897_CHIP_ID = 0x00989700, 170462d5250SArun Ramadoss KSZ9893_CHIP_ID = 0x00989300, 171462d5250SArun Ramadoss KSZ9567_CHIP_ID = 0x00956700, 172462d5250SArun Ramadoss LAN9370_CHIP_ID = 0x00937000, 173462d5250SArun Ramadoss LAN9371_CHIP_ID = 0x00937100, 174462d5250SArun Ramadoss LAN9372_CHIP_ID = 0x00937200, 175462d5250SArun Ramadoss LAN9373_CHIP_ID = 0x00937300, 176462d5250SArun Ramadoss LAN9374_CHIP_ID = 0x00937400, 177462d5250SArun Ramadoss }; 178462d5250SArun Ramadoss 179486f9ca7SArun Ramadoss enum ksz_regs { 180486f9ca7SArun Ramadoss REG_IND_CTRL_0, 181486f9ca7SArun Ramadoss REG_IND_DATA_8, 182486f9ca7SArun Ramadoss REG_IND_DATA_CHECK, 183486f9ca7SArun Ramadoss REG_IND_DATA_HI, 184486f9ca7SArun Ramadoss REG_IND_DATA_LO, 185486f9ca7SArun Ramadoss REG_IND_MIB_CHECK, 186486f9ca7SArun Ramadoss REG_IND_BYTE, 187486f9ca7SArun Ramadoss P_FORCE_CTRL, 188486f9ca7SArun Ramadoss P_LINK_STATUS, 189486f9ca7SArun Ramadoss P_LOCAL_CTRL, 190486f9ca7SArun Ramadoss P_NEG_RESTART_CTRL, 191486f9ca7SArun Ramadoss P_REMOTE_STATUS, 192486f9ca7SArun Ramadoss P_SPEED_STATUS, 193486f9ca7SArun Ramadoss S_TAIL_TAG_CTRL, 1946877102fSArun Ramadoss P_STP_CTRL, 1959d95329cSArun Ramadoss S_START_CTRL, 1969d95329cSArun Ramadoss S_BROADCAST_CTRL, 1979d95329cSArun Ramadoss S_MULTICAST_CTRL, 198aa5b8b73SArun Ramadoss P_XMII_CTRL_0, 19946f80fa8SArun Ramadoss P_XMII_CTRL_1, 200486f9ca7SArun Ramadoss }; 201486f9ca7SArun Ramadoss 202d23a5e18SArun Ramadoss enum ksz_masks { 203d23a5e18SArun Ramadoss PORT_802_1P_REMAPPING, 204d23a5e18SArun Ramadoss SW_TAIL_TAG_ENABLE, 205d23a5e18SArun Ramadoss MIB_COUNTER_OVERFLOW, 206d23a5e18SArun Ramadoss MIB_COUNTER_VALID, 207d23a5e18SArun Ramadoss VLAN_TABLE_FID, 208d23a5e18SArun Ramadoss VLAN_TABLE_MEMBERSHIP, 209d23a5e18SArun Ramadoss VLAN_TABLE_VALID, 210d23a5e18SArun Ramadoss STATIC_MAC_TABLE_VALID, 211d23a5e18SArun Ramadoss STATIC_MAC_TABLE_USE_FID, 212d23a5e18SArun Ramadoss STATIC_MAC_TABLE_FID, 213d23a5e18SArun Ramadoss STATIC_MAC_TABLE_OVERRIDE, 214d23a5e18SArun Ramadoss STATIC_MAC_TABLE_FWD_PORTS, 215d23a5e18SArun Ramadoss DYNAMIC_MAC_TABLE_ENTRIES_H, 216d23a5e18SArun Ramadoss DYNAMIC_MAC_TABLE_MAC_EMPTY, 217d23a5e18SArun Ramadoss DYNAMIC_MAC_TABLE_NOT_READY, 218d23a5e18SArun Ramadoss DYNAMIC_MAC_TABLE_ENTRIES, 219d23a5e18SArun Ramadoss DYNAMIC_MAC_TABLE_FID, 220d23a5e18SArun Ramadoss DYNAMIC_MAC_TABLE_SRC_PORT, 221d23a5e18SArun Ramadoss DYNAMIC_MAC_TABLE_TIMESTAMP, 222457c182aSArun Ramadoss ALU_STAT_WRITE, 223457c182aSArun Ramadoss ALU_STAT_READ, 2248560664fSArun Ramadoss P_MII_TX_FLOW_CTRL, 2258560664fSArun Ramadoss P_MII_RX_FLOW_CTRL, 226d23a5e18SArun Ramadoss }; 227d23a5e18SArun Ramadoss 22834e48383SArun Ramadoss enum ksz_shifts { 22934e48383SArun Ramadoss VLAN_TABLE_MEMBERSHIP_S, 23034e48383SArun Ramadoss VLAN_TABLE, 23134e48383SArun Ramadoss STATIC_MAC_FWD_PORTS, 23234e48383SArun Ramadoss STATIC_MAC_FID, 23334e48383SArun Ramadoss DYNAMIC_MAC_ENTRIES_H, 23434e48383SArun Ramadoss DYNAMIC_MAC_ENTRIES, 23534e48383SArun Ramadoss DYNAMIC_MAC_FID, 23634e48383SArun Ramadoss DYNAMIC_MAC_TIMESTAMP, 23734e48383SArun Ramadoss DYNAMIC_MAC_SRC_PORT, 238457c182aSArun Ramadoss ALU_STAT_INDEX, 23934e48383SArun Ramadoss }; 24034e48383SArun Ramadoss 241aa5b8b73SArun Ramadoss enum ksz_xmii_ctrl0 { 242aa5b8b73SArun Ramadoss P_MII_100MBIT, 243aa5b8b73SArun Ramadoss P_MII_10MBIT, 2448560664fSArun Ramadoss P_MII_FULL_DUPLEX, 2458560664fSArun Ramadoss P_MII_HALF_DUPLEX, 246aa5b8b73SArun Ramadoss }; 247aa5b8b73SArun Ramadoss 24846f80fa8SArun Ramadoss enum ksz_xmii_ctrl1 { 249dc1c596eSArun Ramadoss P_RGMII_SEL, 250dc1c596eSArun Ramadoss P_RMII_SEL, 251dc1c596eSArun Ramadoss P_GMII_SEL, 252dc1c596eSArun Ramadoss P_MII_SEL, 25346f80fa8SArun Ramadoss P_GMII_1GBIT, 25446f80fa8SArun Ramadoss P_GMII_NOT_1GBIT, 25546f80fa8SArun Ramadoss }; 25646f80fa8SArun Ramadoss 2576a7abc61SMarek Vasut struct alu_struct { 2586a7abc61SMarek Vasut /* entry 1 */ 2596a7abc61SMarek Vasut u8 is_static:1; 2606a7abc61SMarek Vasut u8 is_src_filter:1; 2616a7abc61SMarek Vasut u8 is_dst_filter:1; 2626a7abc61SMarek Vasut u8 prio_age:3; 2636a7abc61SMarek Vasut u32 _reserv_0_1:23; 2646a7abc61SMarek Vasut u8 mstp:3; 2656a7abc61SMarek Vasut /* entry 2 */ 2666a7abc61SMarek Vasut u8 is_override:1; 2676a7abc61SMarek Vasut u8 is_use_fid:1; 2686a7abc61SMarek Vasut u32 _reserv_1_1:23; 2696a7abc61SMarek Vasut u8 port_forward:7; 2706a7abc61SMarek Vasut /* entry 3 & 4*/ 2716a7abc61SMarek Vasut u32 _reserv_2_1:9; 2726a7abc61SMarek Vasut u8 fid:7; 2736a7abc61SMarek Vasut u8 mac[ETH_ALEN]; 2746a7abc61SMarek Vasut }; 2756a7abc61SMarek Vasut 2766a7abc61SMarek Vasut struct ksz_dev_ops { 277d2822e68SArun Ramadoss int (*setup)(struct dsa_switch *ds); 278c9cd961cSArun Ramadoss void (*teardown)(struct dsa_switch *ds); 2796a7abc61SMarek Vasut u32 (*get_port_addr)(int port, int offset); 2806a7abc61SMarek Vasut void (*cfg_port_member)(struct ksz_device *dev, int port, u8 member); 2816a7abc61SMarek Vasut void (*flush_dyn_mac_table)(struct ksz_device *dev, int port); 2826a7abc61SMarek Vasut void (*port_cleanup)(struct ksz_device *dev, int port); 2836a7abc61SMarek Vasut void (*port_setup)(struct ksz_device *dev, int port, bool cpu_port); 2848f420456SOleksij Rempel int (*r_phy)(struct ksz_device *dev, u16 phy, u16 reg, u16 *val); 2858f420456SOleksij Rempel int (*w_phy)(struct ksz_device *dev, u16 phy, u16 reg, u16 val); 2866a7abc61SMarek Vasut void (*r_mib_cnt)(struct ksz_device *dev, int port, u16 addr, 2876a7abc61SMarek Vasut u64 *cnt); 2886a7abc61SMarek Vasut void (*r_mib_pkt)(struct ksz_device *dev, int port, u16 addr, 2896a7abc61SMarek Vasut u64 *dropped, u64 *cnt); 290a7f4f13aSOleksij Rempel void (*r_mib_stat64)(struct ksz_device *dev, int port); 291f0d997e3SArun Ramadoss int (*vlan_filtering)(struct ksz_device *dev, int port, 292f0d997e3SArun Ramadoss bool flag, struct netlink_ext_ack *extack); 293f0d997e3SArun Ramadoss int (*vlan_add)(struct ksz_device *dev, int port, 294f0d997e3SArun Ramadoss const struct switchdev_obj_port_vlan *vlan, 295f0d997e3SArun Ramadoss struct netlink_ext_ack *extack); 296f0d997e3SArun Ramadoss int (*vlan_del)(struct ksz_device *dev, int port, 297f0d997e3SArun Ramadoss const struct switchdev_obj_port_vlan *vlan); 29800a298bbSArun Ramadoss int (*mirror_add)(struct ksz_device *dev, int port, 29900a298bbSArun Ramadoss struct dsa_mall_mirror_tc_entry *mirror, 30000a298bbSArun Ramadoss bool ingress, struct netlink_ext_ack *extack); 30100a298bbSArun Ramadoss void (*mirror_del)(struct ksz_device *dev, int port, 30200a298bbSArun Ramadoss struct dsa_mall_mirror_tc_entry *mirror); 303e587be75SArun Ramadoss int (*fdb_add)(struct ksz_device *dev, int port, 304e587be75SArun Ramadoss const unsigned char *addr, u16 vid, struct dsa_db db); 305e587be75SArun Ramadoss int (*fdb_del)(struct ksz_device *dev, int port, 306e587be75SArun Ramadoss const unsigned char *addr, u16 vid, struct dsa_db db); 307e587be75SArun Ramadoss int (*fdb_dump)(struct ksz_device *dev, int port, 308e587be75SArun Ramadoss dsa_fdb_dump_cb_t *cb, void *data); 309980c7d17SArun Ramadoss int (*mdb_add)(struct ksz_device *dev, int port, 310980c7d17SArun Ramadoss const struct switchdev_obj_port_mdb *mdb, 311980c7d17SArun Ramadoss struct dsa_db db); 312980c7d17SArun Ramadoss int (*mdb_del)(struct ksz_device *dev, int port, 313980c7d17SArun Ramadoss const struct switchdev_obj_port_mdb *mdb, 314980c7d17SArun Ramadoss struct dsa_db db); 3157012033cSArun Ramadoss void (*get_caps)(struct ksz_device *dev, int port, 3167012033cSArun Ramadoss struct phylink_config *config); 3171fe94f54SArun Ramadoss int (*change_mtu)(struct ksz_device *dev, int port, int mtu); 3181fe94f54SArun Ramadoss int (*max_mtu)(struct ksz_device *dev, int port); 3196a7abc61SMarek Vasut void (*freeze_mib)(struct ksz_device *dev, int port, bool freeze); 3206a7abc61SMarek Vasut void (*port_init_cnt)(struct ksz_device *dev, int port); 321a0cb1aa4SArun Ramadoss void (*phylink_mac_config)(struct ksz_device *dev, int port, 322a0cb1aa4SArun Ramadoss unsigned int mode, 323a0cb1aa4SArun Ramadoss const struct phylink_link_state *state); 324f597d3adSArun Ramadoss void (*phylink_mac_link_up)(struct ksz_device *dev, int port, 325f597d3adSArun Ramadoss unsigned int mode, 326f597d3adSArun Ramadoss phy_interface_t interface, 327f597d3adSArun Ramadoss struct phy_device *phydev, int speed, 328f597d3adSArun Ramadoss int duplex, bool tx_pause, bool rx_pause); 329b19ac41fSArun Ramadoss void (*setup_rgmii_delay)(struct ksz_device *dev, int port); 330fb9324beSArun Ramadoss void (*config_cpu_port)(struct dsa_switch *ds); 331331d64f7SArun Ramadoss int (*enable_stp_addr)(struct ksz_device *dev); 332673b196fSArun Ramadoss int (*reset)(struct ksz_device *dev); 3336a7abc61SMarek Vasut int (*init)(struct ksz_device *dev); 3346a7abc61SMarek Vasut void (*exit)(struct ksz_device *dev); 3356a7abc61SMarek Vasut }; 3366a7abc61SMarek Vasut 3376a7abc61SMarek Vasut struct ksz_device *ksz_switch_alloc(struct device *base, void *priv); 3386ec23aaaSArun Ramadoss int ksz_switch_register(struct ksz_device *dev); 3396a7abc61SMarek Vasut void ksz_switch_remove(struct ksz_device *dev); 3406a7abc61SMarek Vasut 3417c6ff470STristram Ha void ksz_init_mib_timer(struct ksz_device *dev); 342c6101dd7SArun Ramadoss void ksz_r_mib_stats64(struct ksz_device *dev, int port); 343e593df51SArun Ramadoss void ksz_port_stp_state_set(struct dsa_switch *ds, int port, u8 state); 34446f80fa8SArun Ramadoss bool ksz_get_gbit(struct ksz_device *dev, int port); 3450ab7f6bfSArun Ramadoss phy_interface_t ksz_get_xmii(struct ksz_device *dev, int port, bool gbit); 3461958eee8SArun Ramadoss extern const struct ksz_chip_data ksz_switch_chips[]; 347c2e86691STristram Ha 348c2e86691STristram Ha /* Common register access functions */ 349c2e86691STristram Ha 350c2e86691STristram Ha static inline int ksz_read8(struct ksz_device *dev, u32 reg, u8 *val) 351c2e86691STristram Ha { 352ee394feaSMarek Vasut unsigned int value; 353ee394feaSMarek Vasut int ret = regmap_read(dev->regmap[0], reg, &value); 354c2e86691STristram Ha 355ec6ba50cSOleksij Rempel if (ret) 356ec6ba50cSOleksij Rempel dev_err(dev->dev, "can't read 8bit reg: 0x%x %pe\n", reg, 357ec6ba50cSOleksij Rempel ERR_PTR(ret)); 358ec6ba50cSOleksij Rempel 359ee394feaSMarek Vasut *val = value; 360c2e86691STristram Ha return ret; 361c2e86691STristram Ha } 362c2e86691STristram Ha 363c2e86691STristram Ha static inline int ksz_read16(struct ksz_device *dev, u32 reg, u16 *val) 364c2e86691STristram Ha { 365ee394feaSMarek Vasut unsigned int value; 366ee394feaSMarek Vasut int ret = regmap_read(dev->regmap[1], reg, &value); 367c2e86691STristram Ha 368ec6ba50cSOleksij Rempel if (ret) 369ec6ba50cSOleksij Rempel dev_err(dev->dev, "can't read 16bit reg: 0x%x %pe\n", reg, 370ec6ba50cSOleksij Rempel ERR_PTR(ret)); 371ec6ba50cSOleksij Rempel 372ee394feaSMarek Vasut *val = value; 373c2e86691STristram Ha return ret; 374c2e86691STristram Ha } 375c2e86691STristram Ha 376c2e86691STristram Ha static inline int ksz_read32(struct ksz_device *dev, u32 reg, u32 *val) 377c2e86691STristram Ha { 378ee394feaSMarek Vasut unsigned int value; 379ee394feaSMarek Vasut int ret = regmap_read(dev->regmap[2], reg, &value); 380c2e86691STristram Ha 381ec6ba50cSOleksij Rempel if (ret) 382ec6ba50cSOleksij Rempel dev_err(dev->dev, "can't read 32bit reg: 0x%x %pe\n", reg, 383ec6ba50cSOleksij Rempel ERR_PTR(ret)); 384ec6ba50cSOleksij Rempel 385ee394feaSMarek Vasut *val = value; 386c2e86691STristram Ha return ret; 387c2e86691STristram Ha } 388c2e86691STristram Ha 389e66f840cSTristram Ha static inline int ksz_read64(struct ksz_device *dev, u32 reg, u64 *val) 390e66f840cSTristram Ha { 391e66f840cSTristram Ha u32 value[2]; 392e66f840cSTristram Ha int ret; 393e66f840cSTristram Ha 394e66f840cSTristram Ha ret = regmap_bulk_read(dev->regmap[2], reg, value, 2); 395ec6ba50cSOleksij Rempel if (ret) 396ec6ba50cSOleksij Rempel dev_err(dev->dev, "can't read 64bit reg: 0x%x %pe\n", reg, 397ec6ba50cSOleksij Rempel ERR_PTR(ret)); 398ec6ba50cSOleksij Rempel else 399c34f674cSBen Hutchings *val = (u64)value[0] << 32 | value[1]; 400e66f840cSTristram Ha 401e66f840cSTristram Ha return ret; 402e66f840cSTristram Ha } 403e66f840cSTristram Ha 404c2e86691STristram Ha static inline int ksz_write8(struct ksz_device *dev, u32 reg, u8 value) 405c2e86691STristram Ha { 406ec6ba50cSOleksij Rempel int ret; 407ec6ba50cSOleksij Rempel 408ec6ba50cSOleksij Rempel ret = regmap_write(dev->regmap[0], reg, value); 409ec6ba50cSOleksij Rempel if (ret) 410ec6ba50cSOleksij Rempel dev_err(dev->dev, "can't write 8bit reg: 0x%x %pe\n", reg, 411ec6ba50cSOleksij Rempel ERR_PTR(ret)); 412ec6ba50cSOleksij Rempel 413ec6ba50cSOleksij Rempel return ret; 414c2e86691STristram Ha } 415c2e86691STristram Ha 416c2e86691STristram Ha static inline int ksz_write16(struct ksz_device *dev, u32 reg, u16 value) 417c2e86691STristram Ha { 418ec6ba50cSOleksij Rempel int ret; 419ec6ba50cSOleksij Rempel 420ec6ba50cSOleksij Rempel ret = regmap_write(dev->regmap[1], reg, value); 421ec6ba50cSOleksij Rempel if (ret) 422ec6ba50cSOleksij Rempel dev_err(dev->dev, "can't write 16bit reg: 0x%x %pe\n", reg, 423ec6ba50cSOleksij Rempel ERR_PTR(ret)); 424ec6ba50cSOleksij Rempel 425ec6ba50cSOleksij Rempel return ret; 426c2e86691STristram Ha } 427c2e86691STristram Ha 428c2e86691STristram Ha static inline int ksz_write32(struct ksz_device *dev, u32 reg, u32 value) 429c2e86691STristram Ha { 430ec6ba50cSOleksij Rempel int ret; 431ec6ba50cSOleksij Rempel 432ec6ba50cSOleksij Rempel ret = regmap_write(dev->regmap[2], reg, value); 433ec6ba50cSOleksij Rempel if (ret) 434ec6ba50cSOleksij Rempel dev_err(dev->dev, "can't write 32bit reg: 0x%x %pe\n", reg, 435ec6ba50cSOleksij Rempel ERR_PTR(ret)); 436ec6ba50cSOleksij Rempel 437ec6ba50cSOleksij Rempel return ret; 438c2e86691STristram Ha } 439c2e86691STristram Ha 440e66f840cSTristram Ha static inline int ksz_write64(struct ksz_device *dev, u32 reg, u64 value) 441e66f840cSTristram Ha { 442e66f840cSTristram Ha u32 val[2]; 443e66f840cSTristram Ha 444e66f840cSTristram Ha /* Ick! ToDo: Add 64bit R/W to regmap on 32bit systems */ 445e66f840cSTristram Ha value = swab64(value); 446e66f840cSTristram Ha val[0] = swab32(value & 0xffffffffULL); 447e66f840cSTristram Ha val[1] = swab32(value >> 32ULL); 448e66f840cSTristram Ha 449e66f840cSTristram Ha return regmap_bulk_write(dev->regmap[2], reg, val, 2); 450e66f840cSTristram Ha } 451e66f840cSTristram Ha 452d38bc3b4SOleksij Rempel static inline int ksz_pread8(struct ksz_device *dev, int port, int offset, 453c2e86691STristram Ha u8 *data) 454c2e86691STristram Ha { 455d38bc3b4SOleksij Rempel return ksz_read8(dev, dev->dev_ops->get_port_addr(port, offset), data); 456c2e86691STristram Ha } 457c2e86691STristram Ha 458d38bc3b4SOleksij Rempel static inline int ksz_pread16(struct ksz_device *dev, int port, int offset, 459c2e86691STristram Ha u16 *data) 460c2e86691STristram Ha { 461d38bc3b4SOleksij Rempel return ksz_read16(dev, dev->dev_ops->get_port_addr(port, offset), data); 462c2e86691STristram Ha } 463c2e86691STristram Ha 464d38bc3b4SOleksij Rempel static inline int ksz_pread32(struct ksz_device *dev, int port, int offset, 465c2e86691STristram Ha u32 *data) 466c2e86691STristram Ha { 467d38bc3b4SOleksij Rempel return ksz_read32(dev, dev->dev_ops->get_port_addr(port, offset), data); 468c2e86691STristram Ha } 469c2e86691STristram Ha 470d38bc3b4SOleksij Rempel static inline int ksz_pwrite8(struct ksz_device *dev, int port, int offset, 471c2e86691STristram Ha u8 data) 472c2e86691STristram Ha { 473d38bc3b4SOleksij Rempel return ksz_write8(dev, dev->dev_ops->get_port_addr(port, offset), data); 474c2e86691STristram Ha } 475c2e86691STristram Ha 476d38bc3b4SOleksij Rempel static inline int ksz_pwrite16(struct ksz_device *dev, int port, int offset, 477c2e86691STristram Ha u16 data) 478c2e86691STristram Ha { 479d38bc3b4SOleksij Rempel return ksz_write16(dev, dev->dev_ops->get_port_addr(port, offset), 480d38bc3b4SOleksij Rempel data); 481c2e86691STristram Ha } 482c2e86691STristram Ha 483d38bc3b4SOleksij Rempel static inline int ksz_pwrite32(struct ksz_device *dev, int port, int offset, 484c2e86691STristram Ha u32 data) 485c2e86691STristram Ha { 486d38bc3b4SOleksij Rempel return ksz_write32(dev, dev->dev_ops->get_port_addr(port, offset), 487d38bc3b4SOleksij Rempel data); 488c2e86691STristram Ha } 489c2e86691STristram Ha 4908560664fSArun Ramadoss static inline void ksz_prmw8(struct ksz_device *dev, int port, int offset, 4918560664fSArun Ramadoss u8 mask, u8 val) 4928560664fSArun Ramadoss { 4938560664fSArun Ramadoss regmap_update_bits(dev->regmap[0], 4948560664fSArun Ramadoss dev->dev_ops->get_port_addr(port, offset), 4958560664fSArun Ramadoss mask, val); 4968560664fSArun Ramadoss } 4978560664fSArun Ramadoss 498013572a2SMarek Vasut static inline void ksz_regmap_lock(void *__mtx) 499013572a2SMarek Vasut { 500013572a2SMarek Vasut struct mutex *mtx = __mtx; 501013572a2SMarek Vasut mutex_lock(mtx); 502013572a2SMarek Vasut } 503013572a2SMarek Vasut 504013572a2SMarek Vasut static inline void ksz_regmap_unlock(void *__mtx) 505013572a2SMarek Vasut { 506013572a2SMarek Vasut struct mutex *mtx = __mtx; 507013572a2SMarek Vasut mutex_unlock(mtx); 508013572a2SMarek Vasut } 509013572a2SMarek Vasut 510f3d890f5SArun Ramadoss static inline bool ksz_is_ksz88x3(struct ksz_device *dev) 511f3d890f5SArun Ramadoss { 512f3d890f5SArun Ramadoss return dev->chip_id == KSZ8830_CHIP_ID; 513f3d890f5SArun Ramadoss } 514f3d890f5SArun Ramadoss 51599b16df0SArun Ramadoss static inline int is_lan937x(struct ksz_device *dev) 51699b16df0SArun Ramadoss { 51799b16df0SArun Ramadoss return dev->chip_id == LAN9370_CHIP_ID || 51899b16df0SArun Ramadoss dev->chip_id == LAN9371_CHIP_ID || 51999b16df0SArun Ramadoss dev->chip_id == LAN9372_CHIP_ID || 52099b16df0SArun Ramadoss dev->chip_id == LAN9373_CHIP_ID || 52199b16df0SArun Ramadoss dev->chip_id == LAN9374_CHIP_ID; 52299b16df0SArun Ramadoss } 52399b16df0SArun Ramadoss 524de6dd626SArun Ramadoss /* STP State Defines */ 525de6dd626SArun Ramadoss #define PORT_TX_ENABLE BIT(2) 526de6dd626SArun Ramadoss #define PORT_RX_ENABLE BIT(1) 527de6dd626SArun Ramadoss #define PORT_LEARN_DISABLE BIT(0) 528de6dd626SArun Ramadoss 52991a98917SArun Ramadoss /* Switch ID Defines */ 53091a98917SArun Ramadoss #define REG_CHIP_ID0 0x00 53191a98917SArun Ramadoss 53291a98917SArun Ramadoss #define SW_FAMILY_ID_M GENMASK(15, 8) 53391a98917SArun Ramadoss #define KSZ87_FAMILY_ID 0x87 53491a98917SArun Ramadoss #define KSZ88_FAMILY_ID 0x88 53591a98917SArun Ramadoss 53691a98917SArun Ramadoss #define KSZ8_PORT_STATUS_0 0x08 53791a98917SArun Ramadoss #define KSZ8_PORT_FIBER_MODE BIT(7) 53891a98917SArun Ramadoss 53991a98917SArun Ramadoss #define SW_CHIP_ID_M GENMASK(7, 4) 54091a98917SArun Ramadoss #define KSZ87_CHIP_ID_94 0x6 54191a98917SArun Ramadoss #define KSZ87_CHIP_ID_95 0x9 54291a98917SArun Ramadoss #define KSZ88_CHIP_ID_63 0x3 54391a98917SArun Ramadoss 54491a98917SArun Ramadoss #define SW_REV_ID_M GENMASK(7, 4) 54591a98917SArun Ramadoss 546b4490809SOleksij Rempel /* KSZ9893, KSZ9563, KSZ8563 specific register */ 547b4490809SOleksij Rempel #define REG_CHIP_ID4 0x0f 548b4490809SOleksij Rempel #define SKU_ID_KSZ8563 0x3c 549b4490809SOleksij Rempel 5501ca6437fSArun Ramadoss /* Driver set switch broadcast storm protection at 10% rate. */ 5511ca6437fSArun Ramadoss #define BROADCAST_STORM_PROT_RATE 10 5521ca6437fSArun Ramadoss 5531ca6437fSArun Ramadoss /* 148,800 frames * 67 ms / 100 */ 5541ca6437fSArun Ramadoss #define BROADCAST_STORM_VALUE 9969 5551ca6437fSArun Ramadoss 5561ca6437fSArun Ramadoss #define BROADCAST_STORM_RATE_HI 0x07 5571ca6437fSArun Ramadoss #define BROADCAST_STORM_RATE_LO 0xFF 5581ca6437fSArun Ramadoss #define BROADCAST_STORM_RATE 0x07FF 5591ca6437fSArun Ramadoss 5600abab9f3SArun Ramadoss #define MULTICAST_STORM_DISABLE BIT(6) 5610abab9f3SArun Ramadoss 562ad08ac18SArun Ramadoss #define SW_START 0x01 563ad08ac18SArun Ramadoss 56446f80fa8SArun Ramadoss /* xMII configuration */ 5658560664fSArun Ramadoss #define P_MII_DUPLEX_M BIT(6) 566aa5b8b73SArun Ramadoss #define P_MII_100MBIT_M BIT(4) 567aa5b8b73SArun Ramadoss 56846f80fa8SArun Ramadoss #define P_GMII_1GBIT_M BIT(6) 569dc1c596eSArun Ramadoss #define P_RGMII_ID_IG_ENABLE BIT(4) 570dc1c596eSArun Ramadoss #define P_RGMII_ID_EG_ENABLE BIT(3) 5710ab7f6bfSArun Ramadoss #define P_MII_MAC_MODE BIT(2) 572dc1c596eSArun Ramadoss #define P_MII_SEL_M 0x3 57346f80fa8SArun Ramadoss 574255b59adSMarek Vasut /* Regmap tables generation */ 575255b59adSMarek Vasut #define KSZ_SPI_OP_RD 3 576255b59adSMarek Vasut #define KSZ_SPI_OP_WR 2 577255b59adSMarek Vasut 57820e03777STristram Ha #define swabnot_used(x) 0 57920e03777STristram Ha 580255b59adSMarek Vasut #define KSZ_SPI_OP_FLAG_MASK(opcode, swp, regbits, regpad) \ 581255b59adSMarek Vasut swab##swp((opcode) << ((regbits) + (regpad))) 582255b59adSMarek Vasut 583255b59adSMarek Vasut #define KSZ_REGMAP_ENTRY(width, swp, regbits, regpad, regalign) \ 584255b59adSMarek Vasut { \ 5855f81d545SGeorge McCollister .name = #width, \ 586255b59adSMarek Vasut .val_bits = (width), \ 587a3aa6e65SMarek Vasut .reg_stride = 1, \ 588255b59adSMarek Vasut .reg_bits = (regbits) + (regalign), \ 589255b59adSMarek Vasut .pad_bits = (regpad), \ 590255b59adSMarek Vasut .max_register = BIT(regbits) - 1, \ 591255b59adSMarek Vasut .cache_type = REGCACHE_NONE, \ 592255b59adSMarek Vasut .read_flag_mask = \ 593255b59adSMarek Vasut KSZ_SPI_OP_FLAG_MASK(KSZ_SPI_OP_RD, swp, \ 594255b59adSMarek Vasut regbits, regpad), \ 595255b59adSMarek Vasut .write_flag_mask = \ 596255b59adSMarek Vasut KSZ_SPI_OP_FLAG_MASK(KSZ_SPI_OP_WR, swp, \ 597255b59adSMarek Vasut regbits, regpad), \ 598013572a2SMarek Vasut .lock = ksz_regmap_lock, \ 599013572a2SMarek Vasut .unlock = ksz_regmap_unlock, \ 600255b59adSMarek Vasut .reg_format_endian = REGMAP_ENDIAN_BIG, \ 601255b59adSMarek Vasut .val_format_endian = REGMAP_ENDIAN_BIG \ 602255b59adSMarek Vasut } 603255b59adSMarek Vasut 604255b59adSMarek Vasut #define KSZ_REGMAP_TABLE(ksz, swp, regbits, regpad, regalign) \ 605255b59adSMarek Vasut static const struct regmap_config ksz##_regmap_config[] = { \ 606255b59adSMarek Vasut KSZ_REGMAP_ENTRY(8, swp, (regbits), (regpad), (regalign)), \ 607255b59adSMarek Vasut KSZ_REGMAP_ENTRY(16, swp, (regbits), (regpad), (regalign)), \ 608255b59adSMarek Vasut KSZ_REGMAP_ENTRY(32, swp, (regbits), (regpad), (regalign)), \ 609255b59adSMarek Vasut } 610255b59adSMarek Vasut 611c2e86691STristram Ha #endif 612