162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* Microchip switch driver common header 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Copyright (C) 2017-2019 Microchip Technology Inc. 562306a36Sopenharmony_ci */ 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#ifndef __KSZ_COMMON_H 862306a36Sopenharmony_ci#define __KSZ_COMMON_H 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include <linux/etherdevice.h> 1162306a36Sopenharmony_ci#include <linux/kernel.h> 1262306a36Sopenharmony_ci#include <linux/mutex.h> 1362306a36Sopenharmony_ci#include <linux/phy.h> 1462306a36Sopenharmony_ci#include <linux/regmap.h> 1562306a36Sopenharmony_ci#include <net/dsa.h> 1662306a36Sopenharmony_ci#include <linux/irq.h> 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci#include "ksz_ptp.h" 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci#define KSZ_MAX_NUM_PORTS 8 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_cistruct ksz_device; 2362306a36Sopenharmony_cistruct ksz_port; 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_cienum ksz_regmap_width { 2662306a36Sopenharmony_ci KSZ_REGMAP_8, 2762306a36Sopenharmony_ci KSZ_REGMAP_16, 2862306a36Sopenharmony_ci KSZ_REGMAP_32, 2962306a36Sopenharmony_ci __KSZ_NUM_REGMAPS, 3062306a36Sopenharmony_ci}; 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_cistruct vlan_table { 3362306a36Sopenharmony_ci u32 table[3]; 3462306a36Sopenharmony_ci}; 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_cistruct ksz_port_mib { 3762306a36Sopenharmony_ci struct mutex cnt_mutex; /* structure access */ 3862306a36Sopenharmony_ci u8 cnt_ptr; 3962306a36Sopenharmony_ci u64 *counters; 4062306a36Sopenharmony_ci struct rtnl_link_stats64 stats64; 4162306a36Sopenharmony_ci struct ethtool_pause_stats pause_stats; 4262306a36Sopenharmony_ci struct spinlock stats64_lock; 4362306a36Sopenharmony_ci}; 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_cistruct ksz_mib_names { 4662306a36Sopenharmony_ci int index; 4762306a36Sopenharmony_ci char string[ETH_GSTRING_LEN]; 4862306a36Sopenharmony_ci}; 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_cistruct ksz_chip_data { 5162306a36Sopenharmony_ci u32 chip_id; 5262306a36Sopenharmony_ci const char *dev_name; 5362306a36Sopenharmony_ci int num_vlans; 5462306a36Sopenharmony_ci int num_alus; 5562306a36Sopenharmony_ci int num_statics; 5662306a36Sopenharmony_ci int cpu_ports; 5762306a36Sopenharmony_ci int port_cnt; 5862306a36Sopenharmony_ci u8 port_nirqs; 5962306a36Sopenharmony_ci u8 num_tx_queues; 6062306a36Sopenharmony_ci bool tc_cbs_supported; 6162306a36Sopenharmony_ci bool tc_ets_supported; 6262306a36Sopenharmony_ci const struct ksz_dev_ops *ops; 6362306a36Sopenharmony_ci bool ksz87xx_eee_link_erratum; 6462306a36Sopenharmony_ci const struct ksz_mib_names *mib_names; 6562306a36Sopenharmony_ci int mib_cnt; 6662306a36Sopenharmony_ci u8 reg_mib_cnt; 6762306a36Sopenharmony_ci const u16 *regs; 6862306a36Sopenharmony_ci const u32 *masks; 6962306a36Sopenharmony_ci const u8 *shifts; 7062306a36Sopenharmony_ci const u8 *xmii_ctrl0; 7162306a36Sopenharmony_ci const u8 *xmii_ctrl1; 7262306a36Sopenharmony_ci int stp_ctrl_reg; 7362306a36Sopenharmony_ci int broadcast_ctrl_reg; 7462306a36Sopenharmony_ci int multicast_ctrl_reg; 7562306a36Sopenharmony_ci int start_ctrl_reg; 7662306a36Sopenharmony_ci bool supports_mii[KSZ_MAX_NUM_PORTS]; 7762306a36Sopenharmony_ci bool supports_rmii[KSZ_MAX_NUM_PORTS]; 7862306a36Sopenharmony_ci bool supports_rgmii[KSZ_MAX_NUM_PORTS]; 7962306a36Sopenharmony_ci bool internal_phy[KSZ_MAX_NUM_PORTS]; 8062306a36Sopenharmony_ci bool gbit_capable[KSZ_MAX_NUM_PORTS]; 8162306a36Sopenharmony_ci const struct regmap_access_table *wr_table; 8262306a36Sopenharmony_ci const struct regmap_access_table *rd_table; 8362306a36Sopenharmony_ci}; 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_cistruct ksz_irq { 8662306a36Sopenharmony_ci u16 masked; 8762306a36Sopenharmony_ci u16 reg_mask; 8862306a36Sopenharmony_ci u16 reg_status; 8962306a36Sopenharmony_ci struct irq_domain *domain; 9062306a36Sopenharmony_ci int nirqs; 9162306a36Sopenharmony_ci int irq_num; 9262306a36Sopenharmony_ci char name[16]; 9362306a36Sopenharmony_ci struct ksz_device *dev; 9462306a36Sopenharmony_ci}; 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_cistruct ksz_ptp_irq { 9762306a36Sopenharmony_ci struct ksz_port *port; 9862306a36Sopenharmony_ci u16 ts_reg; 9962306a36Sopenharmony_ci bool ts_en; 10062306a36Sopenharmony_ci char name[16]; 10162306a36Sopenharmony_ci int num; 10262306a36Sopenharmony_ci}; 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_cistruct ksz_port { 10562306a36Sopenharmony_ci bool remove_tag; /* Remove Tag flag set, for ksz8795 only */ 10662306a36Sopenharmony_ci bool learning; 10762306a36Sopenharmony_ci int stp_state; 10862306a36Sopenharmony_ci struct phy_device phydev; 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci u32 fiber:1; /* port is fiber */ 11162306a36Sopenharmony_ci u32 force:1; 11262306a36Sopenharmony_ci u32 read:1; /* read MIB counters in background */ 11362306a36Sopenharmony_ci u32 freeze:1; /* MIB counter freeze is enabled */ 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci struct ksz_port_mib mib; 11662306a36Sopenharmony_ci phy_interface_t interface; 11762306a36Sopenharmony_ci u32 rgmii_tx_val; 11862306a36Sopenharmony_ci u32 rgmii_rx_val; 11962306a36Sopenharmony_ci struct ksz_device *ksz_dev; 12062306a36Sopenharmony_ci struct ksz_irq pirq; 12162306a36Sopenharmony_ci u8 num; 12262306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_NET_DSA_MICROCHIP_KSZ_PTP) 12362306a36Sopenharmony_ci struct hwtstamp_config tstamp_config; 12462306a36Sopenharmony_ci bool hwts_tx_en; 12562306a36Sopenharmony_ci bool hwts_rx_en; 12662306a36Sopenharmony_ci struct ksz_irq ptpirq; 12762306a36Sopenharmony_ci struct ksz_ptp_irq ptpmsg_irq[3]; 12862306a36Sopenharmony_ci ktime_t tstamp_msg; 12962306a36Sopenharmony_ci struct completion tstamp_msg_comp; 13062306a36Sopenharmony_ci#endif 13162306a36Sopenharmony_ci}; 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_cistruct ksz_device { 13462306a36Sopenharmony_ci struct dsa_switch *ds; 13562306a36Sopenharmony_ci struct ksz_platform_data *pdata; 13662306a36Sopenharmony_ci const struct ksz_chip_data *info; 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci struct mutex dev_mutex; /* device access */ 13962306a36Sopenharmony_ci struct mutex regmap_mutex; /* regmap access */ 14062306a36Sopenharmony_ci struct mutex alu_mutex; /* ALU access */ 14162306a36Sopenharmony_ci struct mutex vlan_mutex; /* vlan access */ 14262306a36Sopenharmony_ci const struct ksz_dev_ops *dev_ops; 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci struct device *dev; 14562306a36Sopenharmony_ci struct regmap *regmap[__KSZ_NUM_REGMAPS]; 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci void *priv; 14862306a36Sopenharmony_ci int irq; 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ci struct gpio_desc *reset_gpio; /* Optional reset GPIO */ 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci /* chip specific data */ 15362306a36Sopenharmony_ci u32 chip_id; 15462306a36Sopenharmony_ci u8 chip_rev; 15562306a36Sopenharmony_ci int cpu_port; /* port connected to CPU */ 15662306a36Sopenharmony_ci int phy_port_cnt; 15762306a36Sopenharmony_ci phy_interface_t compat_interface; 15862306a36Sopenharmony_ci bool synclko_125; 15962306a36Sopenharmony_ci bool synclko_disable; 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ci struct vlan_table *vlan_cache; 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci struct ksz_port *ports; 16462306a36Sopenharmony_ci struct delayed_work mib_read; 16562306a36Sopenharmony_ci unsigned long mib_read_interval; 16662306a36Sopenharmony_ci u16 mirror_rx; 16762306a36Sopenharmony_ci u16 mirror_tx; 16862306a36Sopenharmony_ci u16 port_mask; 16962306a36Sopenharmony_ci struct mutex lock_irq; /* IRQ Access */ 17062306a36Sopenharmony_ci struct ksz_irq girq; 17162306a36Sopenharmony_ci struct ksz_ptp_data ptp_data; 17262306a36Sopenharmony_ci}; 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ci/* List of supported models */ 17562306a36Sopenharmony_cienum ksz_model { 17662306a36Sopenharmony_ci KSZ8563, 17762306a36Sopenharmony_ci KSZ8795, 17862306a36Sopenharmony_ci KSZ8794, 17962306a36Sopenharmony_ci KSZ8765, 18062306a36Sopenharmony_ci KSZ8830, 18162306a36Sopenharmony_ci KSZ9477, 18262306a36Sopenharmony_ci KSZ9896, 18362306a36Sopenharmony_ci KSZ9897, 18462306a36Sopenharmony_ci KSZ9893, 18562306a36Sopenharmony_ci KSZ9563, 18662306a36Sopenharmony_ci KSZ9567, 18762306a36Sopenharmony_ci LAN9370, 18862306a36Sopenharmony_ci LAN9371, 18962306a36Sopenharmony_ci LAN9372, 19062306a36Sopenharmony_ci LAN9373, 19162306a36Sopenharmony_ci LAN9374, 19262306a36Sopenharmony_ci}; 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_cienum ksz_chip_id { 19562306a36Sopenharmony_ci KSZ8563_CHIP_ID = 0x8563, 19662306a36Sopenharmony_ci KSZ8795_CHIP_ID = 0x8795, 19762306a36Sopenharmony_ci KSZ8794_CHIP_ID = 0x8794, 19862306a36Sopenharmony_ci KSZ8765_CHIP_ID = 0x8765, 19962306a36Sopenharmony_ci KSZ8830_CHIP_ID = 0x8830, 20062306a36Sopenharmony_ci KSZ9477_CHIP_ID = 0x00947700, 20162306a36Sopenharmony_ci KSZ9896_CHIP_ID = 0x00989600, 20262306a36Sopenharmony_ci KSZ9897_CHIP_ID = 0x00989700, 20362306a36Sopenharmony_ci KSZ9893_CHIP_ID = 0x00989300, 20462306a36Sopenharmony_ci KSZ9563_CHIP_ID = 0x00956300, 20562306a36Sopenharmony_ci KSZ9567_CHIP_ID = 0x00956700, 20662306a36Sopenharmony_ci LAN9370_CHIP_ID = 0x00937000, 20762306a36Sopenharmony_ci LAN9371_CHIP_ID = 0x00937100, 20862306a36Sopenharmony_ci LAN9372_CHIP_ID = 0x00937200, 20962306a36Sopenharmony_ci LAN9373_CHIP_ID = 0x00937300, 21062306a36Sopenharmony_ci LAN9374_CHIP_ID = 0x00937400, 21162306a36Sopenharmony_ci}; 21262306a36Sopenharmony_ci 21362306a36Sopenharmony_cienum ksz_regs { 21462306a36Sopenharmony_ci REG_IND_CTRL_0, 21562306a36Sopenharmony_ci REG_IND_DATA_8, 21662306a36Sopenharmony_ci REG_IND_DATA_CHECK, 21762306a36Sopenharmony_ci REG_IND_DATA_HI, 21862306a36Sopenharmony_ci REG_IND_DATA_LO, 21962306a36Sopenharmony_ci REG_IND_MIB_CHECK, 22062306a36Sopenharmony_ci REG_IND_BYTE, 22162306a36Sopenharmony_ci P_FORCE_CTRL, 22262306a36Sopenharmony_ci P_LINK_STATUS, 22362306a36Sopenharmony_ci P_LOCAL_CTRL, 22462306a36Sopenharmony_ci P_NEG_RESTART_CTRL, 22562306a36Sopenharmony_ci P_REMOTE_STATUS, 22662306a36Sopenharmony_ci P_SPEED_STATUS, 22762306a36Sopenharmony_ci S_TAIL_TAG_CTRL, 22862306a36Sopenharmony_ci P_STP_CTRL, 22962306a36Sopenharmony_ci S_START_CTRL, 23062306a36Sopenharmony_ci S_BROADCAST_CTRL, 23162306a36Sopenharmony_ci S_MULTICAST_CTRL, 23262306a36Sopenharmony_ci P_XMII_CTRL_0, 23362306a36Sopenharmony_ci P_XMII_CTRL_1, 23462306a36Sopenharmony_ci}; 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_cienum ksz_masks { 23762306a36Sopenharmony_ci PORT_802_1P_REMAPPING, 23862306a36Sopenharmony_ci SW_TAIL_TAG_ENABLE, 23962306a36Sopenharmony_ci MIB_COUNTER_OVERFLOW, 24062306a36Sopenharmony_ci MIB_COUNTER_VALID, 24162306a36Sopenharmony_ci VLAN_TABLE_FID, 24262306a36Sopenharmony_ci VLAN_TABLE_MEMBERSHIP, 24362306a36Sopenharmony_ci VLAN_TABLE_VALID, 24462306a36Sopenharmony_ci STATIC_MAC_TABLE_VALID, 24562306a36Sopenharmony_ci STATIC_MAC_TABLE_USE_FID, 24662306a36Sopenharmony_ci STATIC_MAC_TABLE_FID, 24762306a36Sopenharmony_ci STATIC_MAC_TABLE_OVERRIDE, 24862306a36Sopenharmony_ci STATIC_MAC_TABLE_FWD_PORTS, 24962306a36Sopenharmony_ci DYNAMIC_MAC_TABLE_ENTRIES_H, 25062306a36Sopenharmony_ci DYNAMIC_MAC_TABLE_MAC_EMPTY, 25162306a36Sopenharmony_ci DYNAMIC_MAC_TABLE_NOT_READY, 25262306a36Sopenharmony_ci DYNAMIC_MAC_TABLE_ENTRIES, 25362306a36Sopenharmony_ci DYNAMIC_MAC_TABLE_FID, 25462306a36Sopenharmony_ci DYNAMIC_MAC_TABLE_SRC_PORT, 25562306a36Sopenharmony_ci DYNAMIC_MAC_TABLE_TIMESTAMP, 25662306a36Sopenharmony_ci ALU_STAT_WRITE, 25762306a36Sopenharmony_ci ALU_STAT_READ, 25862306a36Sopenharmony_ci P_MII_TX_FLOW_CTRL, 25962306a36Sopenharmony_ci P_MII_RX_FLOW_CTRL, 26062306a36Sopenharmony_ci}; 26162306a36Sopenharmony_ci 26262306a36Sopenharmony_cienum ksz_shifts { 26362306a36Sopenharmony_ci VLAN_TABLE_MEMBERSHIP_S, 26462306a36Sopenharmony_ci VLAN_TABLE, 26562306a36Sopenharmony_ci STATIC_MAC_FWD_PORTS, 26662306a36Sopenharmony_ci STATIC_MAC_FID, 26762306a36Sopenharmony_ci DYNAMIC_MAC_ENTRIES_H, 26862306a36Sopenharmony_ci DYNAMIC_MAC_ENTRIES, 26962306a36Sopenharmony_ci DYNAMIC_MAC_FID, 27062306a36Sopenharmony_ci DYNAMIC_MAC_TIMESTAMP, 27162306a36Sopenharmony_ci DYNAMIC_MAC_SRC_PORT, 27262306a36Sopenharmony_ci ALU_STAT_INDEX, 27362306a36Sopenharmony_ci}; 27462306a36Sopenharmony_ci 27562306a36Sopenharmony_cienum ksz_xmii_ctrl0 { 27662306a36Sopenharmony_ci P_MII_100MBIT, 27762306a36Sopenharmony_ci P_MII_10MBIT, 27862306a36Sopenharmony_ci P_MII_FULL_DUPLEX, 27962306a36Sopenharmony_ci P_MII_HALF_DUPLEX, 28062306a36Sopenharmony_ci}; 28162306a36Sopenharmony_ci 28262306a36Sopenharmony_cienum ksz_xmii_ctrl1 { 28362306a36Sopenharmony_ci P_RGMII_SEL, 28462306a36Sopenharmony_ci P_RMII_SEL, 28562306a36Sopenharmony_ci P_GMII_SEL, 28662306a36Sopenharmony_ci P_MII_SEL, 28762306a36Sopenharmony_ci P_GMII_1GBIT, 28862306a36Sopenharmony_ci P_GMII_NOT_1GBIT, 28962306a36Sopenharmony_ci}; 29062306a36Sopenharmony_ci 29162306a36Sopenharmony_cistruct alu_struct { 29262306a36Sopenharmony_ci /* entry 1 */ 29362306a36Sopenharmony_ci u8 is_static:1; 29462306a36Sopenharmony_ci u8 is_src_filter:1; 29562306a36Sopenharmony_ci u8 is_dst_filter:1; 29662306a36Sopenharmony_ci u8 prio_age:3; 29762306a36Sopenharmony_ci u32 _reserv_0_1:23; 29862306a36Sopenharmony_ci u8 mstp:3; 29962306a36Sopenharmony_ci /* entry 2 */ 30062306a36Sopenharmony_ci u8 is_override:1; 30162306a36Sopenharmony_ci u8 is_use_fid:1; 30262306a36Sopenharmony_ci u32 _reserv_1_1:23; 30362306a36Sopenharmony_ci u8 port_forward:7; 30462306a36Sopenharmony_ci /* entry 3 & 4*/ 30562306a36Sopenharmony_ci u32 _reserv_2_1:9; 30662306a36Sopenharmony_ci u8 fid:7; 30762306a36Sopenharmony_ci u8 mac[ETH_ALEN]; 30862306a36Sopenharmony_ci}; 30962306a36Sopenharmony_ci 31062306a36Sopenharmony_cistruct ksz_dev_ops { 31162306a36Sopenharmony_ci int (*setup)(struct dsa_switch *ds); 31262306a36Sopenharmony_ci void (*teardown)(struct dsa_switch *ds); 31362306a36Sopenharmony_ci u32 (*get_port_addr)(int port, int offset); 31462306a36Sopenharmony_ci void (*cfg_port_member)(struct ksz_device *dev, int port, u8 member); 31562306a36Sopenharmony_ci void (*flush_dyn_mac_table)(struct ksz_device *dev, int port); 31662306a36Sopenharmony_ci void (*port_cleanup)(struct ksz_device *dev, int port); 31762306a36Sopenharmony_ci void (*port_setup)(struct ksz_device *dev, int port, bool cpu_port); 31862306a36Sopenharmony_ci int (*set_ageing_time)(struct ksz_device *dev, unsigned int msecs); 31962306a36Sopenharmony_ci int (*r_phy)(struct ksz_device *dev, u16 phy, u16 reg, u16 *val); 32062306a36Sopenharmony_ci int (*w_phy)(struct ksz_device *dev, u16 phy, u16 reg, u16 val); 32162306a36Sopenharmony_ci void (*r_mib_cnt)(struct ksz_device *dev, int port, u16 addr, 32262306a36Sopenharmony_ci u64 *cnt); 32362306a36Sopenharmony_ci void (*r_mib_pkt)(struct ksz_device *dev, int port, u16 addr, 32462306a36Sopenharmony_ci u64 *dropped, u64 *cnt); 32562306a36Sopenharmony_ci void (*r_mib_stat64)(struct ksz_device *dev, int port); 32662306a36Sopenharmony_ci int (*vlan_filtering)(struct ksz_device *dev, int port, 32762306a36Sopenharmony_ci bool flag, struct netlink_ext_ack *extack); 32862306a36Sopenharmony_ci int (*vlan_add)(struct ksz_device *dev, int port, 32962306a36Sopenharmony_ci const struct switchdev_obj_port_vlan *vlan, 33062306a36Sopenharmony_ci struct netlink_ext_ack *extack); 33162306a36Sopenharmony_ci int (*vlan_del)(struct ksz_device *dev, int port, 33262306a36Sopenharmony_ci const struct switchdev_obj_port_vlan *vlan); 33362306a36Sopenharmony_ci int (*mirror_add)(struct ksz_device *dev, int port, 33462306a36Sopenharmony_ci struct dsa_mall_mirror_tc_entry *mirror, 33562306a36Sopenharmony_ci bool ingress, struct netlink_ext_ack *extack); 33662306a36Sopenharmony_ci void (*mirror_del)(struct ksz_device *dev, int port, 33762306a36Sopenharmony_ci struct dsa_mall_mirror_tc_entry *mirror); 33862306a36Sopenharmony_ci int (*fdb_add)(struct ksz_device *dev, int port, 33962306a36Sopenharmony_ci const unsigned char *addr, u16 vid, struct dsa_db db); 34062306a36Sopenharmony_ci int (*fdb_del)(struct ksz_device *dev, int port, 34162306a36Sopenharmony_ci const unsigned char *addr, u16 vid, struct dsa_db db); 34262306a36Sopenharmony_ci int (*fdb_dump)(struct ksz_device *dev, int port, 34362306a36Sopenharmony_ci dsa_fdb_dump_cb_t *cb, void *data); 34462306a36Sopenharmony_ci int (*mdb_add)(struct ksz_device *dev, int port, 34562306a36Sopenharmony_ci const struct switchdev_obj_port_mdb *mdb, 34662306a36Sopenharmony_ci struct dsa_db db); 34762306a36Sopenharmony_ci int (*mdb_del)(struct ksz_device *dev, int port, 34862306a36Sopenharmony_ci const struct switchdev_obj_port_mdb *mdb, 34962306a36Sopenharmony_ci struct dsa_db db); 35062306a36Sopenharmony_ci void (*get_caps)(struct ksz_device *dev, int port, 35162306a36Sopenharmony_ci struct phylink_config *config); 35262306a36Sopenharmony_ci int (*change_mtu)(struct ksz_device *dev, int port, int mtu); 35362306a36Sopenharmony_ci void (*freeze_mib)(struct ksz_device *dev, int port, bool freeze); 35462306a36Sopenharmony_ci void (*port_init_cnt)(struct ksz_device *dev, int port); 35562306a36Sopenharmony_ci void (*phylink_mac_config)(struct ksz_device *dev, int port, 35662306a36Sopenharmony_ci unsigned int mode, 35762306a36Sopenharmony_ci const struct phylink_link_state *state); 35862306a36Sopenharmony_ci void (*phylink_mac_link_up)(struct ksz_device *dev, int port, 35962306a36Sopenharmony_ci unsigned int mode, 36062306a36Sopenharmony_ci phy_interface_t interface, 36162306a36Sopenharmony_ci struct phy_device *phydev, int speed, 36262306a36Sopenharmony_ci int duplex, bool tx_pause, bool rx_pause); 36362306a36Sopenharmony_ci void (*setup_rgmii_delay)(struct ksz_device *dev, int port); 36462306a36Sopenharmony_ci int (*tc_cbs_set_cinc)(struct ksz_device *dev, int port, u32 val); 36562306a36Sopenharmony_ci void (*config_cpu_port)(struct dsa_switch *ds); 36662306a36Sopenharmony_ci int (*enable_stp_addr)(struct ksz_device *dev); 36762306a36Sopenharmony_ci int (*reset)(struct ksz_device *dev); 36862306a36Sopenharmony_ci int (*init)(struct ksz_device *dev); 36962306a36Sopenharmony_ci void (*exit)(struct ksz_device *dev); 37062306a36Sopenharmony_ci}; 37162306a36Sopenharmony_ci 37262306a36Sopenharmony_cistruct ksz_device *ksz_switch_alloc(struct device *base, void *priv); 37362306a36Sopenharmony_ciint ksz_switch_register(struct ksz_device *dev); 37462306a36Sopenharmony_civoid ksz_switch_remove(struct ksz_device *dev); 37562306a36Sopenharmony_ci 37662306a36Sopenharmony_civoid ksz_init_mib_timer(struct ksz_device *dev); 37762306a36Sopenharmony_civoid ksz_r_mib_stats64(struct ksz_device *dev, int port); 37862306a36Sopenharmony_civoid ksz88xx_r_mib_stats64(struct ksz_device *dev, int port); 37962306a36Sopenharmony_civoid ksz_port_stp_state_set(struct dsa_switch *ds, int port, u8 state); 38062306a36Sopenharmony_cibool ksz_get_gbit(struct ksz_device *dev, int port); 38162306a36Sopenharmony_ciphy_interface_t ksz_get_xmii(struct ksz_device *dev, int port, bool gbit); 38262306a36Sopenharmony_ciextern const struct ksz_chip_data ksz_switch_chips[]; 38362306a36Sopenharmony_ci 38462306a36Sopenharmony_ci/* Common register access functions */ 38562306a36Sopenharmony_cistatic inline struct regmap *ksz_regmap_8(struct ksz_device *dev) 38662306a36Sopenharmony_ci{ 38762306a36Sopenharmony_ci return dev->regmap[KSZ_REGMAP_8]; 38862306a36Sopenharmony_ci} 38962306a36Sopenharmony_ci 39062306a36Sopenharmony_cistatic inline struct regmap *ksz_regmap_16(struct ksz_device *dev) 39162306a36Sopenharmony_ci{ 39262306a36Sopenharmony_ci return dev->regmap[KSZ_REGMAP_16]; 39362306a36Sopenharmony_ci} 39462306a36Sopenharmony_ci 39562306a36Sopenharmony_cistatic inline struct regmap *ksz_regmap_32(struct ksz_device *dev) 39662306a36Sopenharmony_ci{ 39762306a36Sopenharmony_ci return dev->regmap[KSZ_REGMAP_32]; 39862306a36Sopenharmony_ci} 39962306a36Sopenharmony_ci 40062306a36Sopenharmony_cistatic inline int ksz_read8(struct ksz_device *dev, u32 reg, u8 *val) 40162306a36Sopenharmony_ci{ 40262306a36Sopenharmony_ci unsigned int value; 40362306a36Sopenharmony_ci int ret = regmap_read(ksz_regmap_8(dev), reg, &value); 40462306a36Sopenharmony_ci 40562306a36Sopenharmony_ci if (ret) 40662306a36Sopenharmony_ci dev_err(dev->dev, "can't read 8bit reg: 0x%x %pe\n", reg, 40762306a36Sopenharmony_ci ERR_PTR(ret)); 40862306a36Sopenharmony_ci 40962306a36Sopenharmony_ci *val = value; 41062306a36Sopenharmony_ci return ret; 41162306a36Sopenharmony_ci} 41262306a36Sopenharmony_ci 41362306a36Sopenharmony_cistatic inline int ksz_read16(struct ksz_device *dev, u32 reg, u16 *val) 41462306a36Sopenharmony_ci{ 41562306a36Sopenharmony_ci unsigned int value; 41662306a36Sopenharmony_ci int ret = regmap_read(ksz_regmap_16(dev), reg, &value); 41762306a36Sopenharmony_ci 41862306a36Sopenharmony_ci if (ret) 41962306a36Sopenharmony_ci dev_err(dev->dev, "can't read 16bit reg: 0x%x %pe\n", reg, 42062306a36Sopenharmony_ci ERR_PTR(ret)); 42162306a36Sopenharmony_ci 42262306a36Sopenharmony_ci *val = value; 42362306a36Sopenharmony_ci return ret; 42462306a36Sopenharmony_ci} 42562306a36Sopenharmony_ci 42662306a36Sopenharmony_cistatic inline int ksz_read32(struct ksz_device *dev, u32 reg, u32 *val) 42762306a36Sopenharmony_ci{ 42862306a36Sopenharmony_ci unsigned int value; 42962306a36Sopenharmony_ci int ret = regmap_read(ksz_regmap_32(dev), reg, &value); 43062306a36Sopenharmony_ci 43162306a36Sopenharmony_ci if (ret) 43262306a36Sopenharmony_ci dev_err(dev->dev, "can't read 32bit reg: 0x%x %pe\n", reg, 43362306a36Sopenharmony_ci ERR_PTR(ret)); 43462306a36Sopenharmony_ci 43562306a36Sopenharmony_ci *val = value; 43662306a36Sopenharmony_ci return ret; 43762306a36Sopenharmony_ci} 43862306a36Sopenharmony_ci 43962306a36Sopenharmony_cistatic inline int ksz_read64(struct ksz_device *dev, u32 reg, u64 *val) 44062306a36Sopenharmony_ci{ 44162306a36Sopenharmony_ci u32 value[2]; 44262306a36Sopenharmony_ci int ret; 44362306a36Sopenharmony_ci 44462306a36Sopenharmony_ci ret = regmap_bulk_read(ksz_regmap_32(dev), reg, value, 2); 44562306a36Sopenharmony_ci if (ret) 44662306a36Sopenharmony_ci dev_err(dev->dev, "can't read 64bit reg: 0x%x %pe\n", reg, 44762306a36Sopenharmony_ci ERR_PTR(ret)); 44862306a36Sopenharmony_ci else 44962306a36Sopenharmony_ci *val = (u64)value[0] << 32 | value[1]; 45062306a36Sopenharmony_ci 45162306a36Sopenharmony_ci return ret; 45262306a36Sopenharmony_ci} 45362306a36Sopenharmony_ci 45462306a36Sopenharmony_cistatic inline int ksz_write8(struct ksz_device *dev, u32 reg, u8 value) 45562306a36Sopenharmony_ci{ 45662306a36Sopenharmony_ci int ret; 45762306a36Sopenharmony_ci 45862306a36Sopenharmony_ci ret = regmap_write(ksz_regmap_8(dev), reg, value); 45962306a36Sopenharmony_ci if (ret) 46062306a36Sopenharmony_ci dev_err(dev->dev, "can't write 8bit reg: 0x%x %pe\n", reg, 46162306a36Sopenharmony_ci ERR_PTR(ret)); 46262306a36Sopenharmony_ci 46362306a36Sopenharmony_ci return ret; 46462306a36Sopenharmony_ci} 46562306a36Sopenharmony_ci 46662306a36Sopenharmony_cistatic inline int ksz_write16(struct ksz_device *dev, u32 reg, u16 value) 46762306a36Sopenharmony_ci{ 46862306a36Sopenharmony_ci int ret; 46962306a36Sopenharmony_ci 47062306a36Sopenharmony_ci ret = regmap_write(ksz_regmap_16(dev), reg, value); 47162306a36Sopenharmony_ci if (ret) 47262306a36Sopenharmony_ci dev_err(dev->dev, "can't write 16bit reg: 0x%x %pe\n", reg, 47362306a36Sopenharmony_ci ERR_PTR(ret)); 47462306a36Sopenharmony_ci 47562306a36Sopenharmony_ci return ret; 47662306a36Sopenharmony_ci} 47762306a36Sopenharmony_ci 47862306a36Sopenharmony_cistatic inline int ksz_write32(struct ksz_device *dev, u32 reg, u32 value) 47962306a36Sopenharmony_ci{ 48062306a36Sopenharmony_ci int ret; 48162306a36Sopenharmony_ci 48262306a36Sopenharmony_ci ret = regmap_write(ksz_regmap_32(dev), reg, value); 48362306a36Sopenharmony_ci if (ret) 48462306a36Sopenharmony_ci dev_err(dev->dev, "can't write 32bit reg: 0x%x %pe\n", reg, 48562306a36Sopenharmony_ci ERR_PTR(ret)); 48662306a36Sopenharmony_ci 48762306a36Sopenharmony_ci return ret; 48862306a36Sopenharmony_ci} 48962306a36Sopenharmony_ci 49062306a36Sopenharmony_cistatic inline int ksz_rmw16(struct ksz_device *dev, u32 reg, u16 mask, 49162306a36Sopenharmony_ci u16 value) 49262306a36Sopenharmony_ci{ 49362306a36Sopenharmony_ci int ret; 49462306a36Sopenharmony_ci 49562306a36Sopenharmony_ci ret = regmap_update_bits(ksz_regmap_16(dev), reg, mask, value); 49662306a36Sopenharmony_ci if (ret) 49762306a36Sopenharmony_ci dev_err(dev->dev, "can't rmw 16bit reg 0x%x: %pe\n", reg, 49862306a36Sopenharmony_ci ERR_PTR(ret)); 49962306a36Sopenharmony_ci 50062306a36Sopenharmony_ci return ret; 50162306a36Sopenharmony_ci} 50262306a36Sopenharmony_ci 50362306a36Sopenharmony_cistatic inline int ksz_rmw32(struct ksz_device *dev, u32 reg, u32 mask, 50462306a36Sopenharmony_ci u32 value) 50562306a36Sopenharmony_ci{ 50662306a36Sopenharmony_ci int ret; 50762306a36Sopenharmony_ci 50862306a36Sopenharmony_ci ret = regmap_update_bits(ksz_regmap_32(dev), reg, mask, value); 50962306a36Sopenharmony_ci if (ret) 51062306a36Sopenharmony_ci dev_err(dev->dev, "can't rmw 32bit reg 0x%x: %pe\n", reg, 51162306a36Sopenharmony_ci ERR_PTR(ret)); 51262306a36Sopenharmony_ci 51362306a36Sopenharmony_ci return ret; 51462306a36Sopenharmony_ci} 51562306a36Sopenharmony_ci 51662306a36Sopenharmony_cistatic inline int ksz_write64(struct ksz_device *dev, u32 reg, u64 value) 51762306a36Sopenharmony_ci{ 51862306a36Sopenharmony_ci u32 val[2]; 51962306a36Sopenharmony_ci 52062306a36Sopenharmony_ci /* Ick! ToDo: Add 64bit R/W to regmap on 32bit systems */ 52162306a36Sopenharmony_ci value = swab64(value); 52262306a36Sopenharmony_ci val[0] = swab32(value & 0xffffffffULL); 52362306a36Sopenharmony_ci val[1] = swab32(value >> 32ULL); 52462306a36Sopenharmony_ci 52562306a36Sopenharmony_ci return regmap_bulk_write(ksz_regmap_32(dev), reg, val, 2); 52662306a36Sopenharmony_ci} 52762306a36Sopenharmony_ci 52862306a36Sopenharmony_cistatic inline int ksz_rmw8(struct ksz_device *dev, int offset, u8 mask, u8 val) 52962306a36Sopenharmony_ci{ 53062306a36Sopenharmony_ci int ret; 53162306a36Sopenharmony_ci 53262306a36Sopenharmony_ci ret = regmap_update_bits(ksz_regmap_8(dev), offset, mask, val); 53362306a36Sopenharmony_ci if (ret) 53462306a36Sopenharmony_ci dev_err(dev->dev, "can't rmw 8bit reg 0x%x: %pe\n", offset, 53562306a36Sopenharmony_ci ERR_PTR(ret)); 53662306a36Sopenharmony_ci 53762306a36Sopenharmony_ci return ret; 53862306a36Sopenharmony_ci} 53962306a36Sopenharmony_ci 54062306a36Sopenharmony_cistatic inline int ksz_pread8(struct ksz_device *dev, int port, int offset, 54162306a36Sopenharmony_ci u8 *data) 54262306a36Sopenharmony_ci{ 54362306a36Sopenharmony_ci return ksz_read8(dev, dev->dev_ops->get_port_addr(port, offset), data); 54462306a36Sopenharmony_ci} 54562306a36Sopenharmony_ci 54662306a36Sopenharmony_cistatic inline int ksz_pread16(struct ksz_device *dev, int port, int offset, 54762306a36Sopenharmony_ci u16 *data) 54862306a36Sopenharmony_ci{ 54962306a36Sopenharmony_ci return ksz_read16(dev, dev->dev_ops->get_port_addr(port, offset), data); 55062306a36Sopenharmony_ci} 55162306a36Sopenharmony_ci 55262306a36Sopenharmony_cistatic inline int ksz_pread32(struct ksz_device *dev, int port, int offset, 55362306a36Sopenharmony_ci u32 *data) 55462306a36Sopenharmony_ci{ 55562306a36Sopenharmony_ci return ksz_read32(dev, dev->dev_ops->get_port_addr(port, offset), data); 55662306a36Sopenharmony_ci} 55762306a36Sopenharmony_ci 55862306a36Sopenharmony_cistatic inline int ksz_pwrite8(struct ksz_device *dev, int port, int offset, 55962306a36Sopenharmony_ci u8 data) 56062306a36Sopenharmony_ci{ 56162306a36Sopenharmony_ci return ksz_write8(dev, dev->dev_ops->get_port_addr(port, offset), data); 56262306a36Sopenharmony_ci} 56362306a36Sopenharmony_ci 56462306a36Sopenharmony_cistatic inline int ksz_pwrite16(struct ksz_device *dev, int port, int offset, 56562306a36Sopenharmony_ci u16 data) 56662306a36Sopenharmony_ci{ 56762306a36Sopenharmony_ci return ksz_write16(dev, dev->dev_ops->get_port_addr(port, offset), 56862306a36Sopenharmony_ci data); 56962306a36Sopenharmony_ci} 57062306a36Sopenharmony_ci 57162306a36Sopenharmony_cistatic inline int ksz_pwrite32(struct ksz_device *dev, int port, int offset, 57262306a36Sopenharmony_ci u32 data) 57362306a36Sopenharmony_ci{ 57462306a36Sopenharmony_ci return ksz_write32(dev, dev->dev_ops->get_port_addr(port, offset), 57562306a36Sopenharmony_ci data); 57662306a36Sopenharmony_ci} 57762306a36Sopenharmony_ci 57862306a36Sopenharmony_cistatic inline int ksz_prmw8(struct ksz_device *dev, int port, int offset, 57962306a36Sopenharmony_ci u8 mask, u8 val) 58062306a36Sopenharmony_ci{ 58162306a36Sopenharmony_ci return ksz_rmw8(dev, dev->dev_ops->get_port_addr(port, offset), 58262306a36Sopenharmony_ci mask, val); 58362306a36Sopenharmony_ci} 58462306a36Sopenharmony_ci 58562306a36Sopenharmony_cistatic inline int ksz_prmw32(struct ksz_device *dev, int port, int offset, 58662306a36Sopenharmony_ci u32 mask, u32 val) 58762306a36Sopenharmony_ci{ 58862306a36Sopenharmony_ci return ksz_rmw32(dev, dev->dev_ops->get_port_addr(port, offset), 58962306a36Sopenharmony_ci mask, val); 59062306a36Sopenharmony_ci} 59162306a36Sopenharmony_ci 59262306a36Sopenharmony_cistatic inline void ksz_regmap_lock(void *__mtx) 59362306a36Sopenharmony_ci{ 59462306a36Sopenharmony_ci struct mutex *mtx = __mtx; 59562306a36Sopenharmony_ci mutex_lock(mtx); 59662306a36Sopenharmony_ci} 59762306a36Sopenharmony_ci 59862306a36Sopenharmony_cistatic inline void ksz_regmap_unlock(void *__mtx) 59962306a36Sopenharmony_ci{ 60062306a36Sopenharmony_ci struct mutex *mtx = __mtx; 60162306a36Sopenharmony_ci mutex_unlock(mtx); 60262306a36Sopenharmony_ci} 60362306a36Sopenharmony_ci 60462306a36Sopenharmony_cistatic inline bool ksz_is_ksz87xx(struct ksz_device *dev) 60562306a36Sopenharmony_ci{ 60662306a36Sopenharmony_ci return dev->chip_id == KSZ8795_CHIP_ID || 60762306a36Sopenharmony_ci dev->chip_id == KSZ8794_CHIP_ID || 60862306a36Sopenharmony_ci dev->chip_id == KSZ8765_CHIP_ID; 60962306a36Sopenharmony_ci} 61062306a36Sopenharmony_ci 61162306a36Sopenharmony_cistatic inline bool ksz_is_ksz88x3(struct ksz_device *dev) 61262306a36Sopenharmony_ci{ 61362306a36Sopenharmony_ci return dev->chip_id == KSZ8830_CHIP_ID; 61462306a36Sopenharmony_ci} 61562306a36Sopenharmony_ci 61662306a36Sopenharmony_cistatic inline int is_lan937x(struct ksz_device *dev) 61762306a36Sopenharmony_ci{ 61862306a36Sopenharmony_ci return dev->chip_id == LAN9370_CHIP_ID || 61962306a36Sopenharmony_ci dev->chip_id == LAN9371_CHIP_ID || 62062306a36Sopenharmony_ci dev->chip_id == LAN9372_CHIP_ID || 62162306a36Sopenharmony_ci dev->chip_id == LAN9373_CHIP_ID || 62262306a36Sopenharmony_ci dev->chip_id == LAN9374_CHIP_ID; 62362306a36Sopenharmony_ci} 62462306a36Sopenharmony_ci 62562306a36Sopenharmony_ci/* STP State Defines */ 62662306a36Sopenharmony_ci#define PORT_TX_ENABLE BIT(2) 62762306a36Sopenharmony_ci#define PORT_RX_ENABLE BIT(1) 62862306a36Sopenharmony_ci#define PORT_LEARN_DISABLE BIT(0) 62962306a36Sopenharmony_ci 63062306a36Sopenharmony_ci/* Switch ID Defines */ 63162306a36Sopenharmony_ci#define REG_CHIP_ID0 0x00 63262306a36Sopenharmony_ci 63362306a36Sopenharmony_ci#define SW_FAMILY_ID_M GENMASK(15, 8) 63462306a36Sopenharmony_ci#define KSZ87_FAMILY_ID 0x87 63562306a36Sopenharmony_ci#define KSZ88_FAMILY_ID 0x88 63662306a36Sopenharmony_ci 63762306a36Sopenharmony_ci#define KSZ8_PORT_STATUS_0 0x08 63862306a36Sopenharmony_ci#define KSZ8_PORT_FIBER_MODE BIT(7) 63962306a36Sopenharmony_ci 64062306a36Sopenharmony_ci#define SW_CHIP_ID_M GENMASK(7, 4) 64162306a36Sopenharmony_ci#define KSZ87_CHIP_ID_94 0x6 64262306a36Sopenharmony_ci#define KSZ87_CHIP_ID_95 0x9 64362306a36Sopenharmony_ci#define KSZ88_CHIP_ID_63 0x3 64462306a36Sopenharmony_ci 64562306a36Sopenharmony_ci#define SW_REV_ID_M GENMASK(7, 4) 64662306a36Sopenharmony_ci 64762306a36Sopenharmony_ci/* KSZ9893, KSZ9563, KSZ8563 specific register */ 64862306a36Sopenharmony_ci#define REG_CHIP_ID4 0x0f 64962306a36Sopenharmony_ci#define SKU_ID_KSZ8563 0x3c 65062306a36Sopenharmony_ci#define SKU_ID_KSZ9563 0x1c 65162306a36Sopenharmony_ci 65262306a36Sopenharmony_ci/* Driver set switch broadcast storm protection at 10% rate. */ 65362306a36Sopenharmony_ci#define BROADCAST_STORM_PROT_RATE 10 65462306a36Sopenharmony_ci 65562306a36Sopenharmony_ci/* 148,800 frames * 67 ms / 100 */ 65662306a36Sopenharmony_ci#define BROADCAST_STORM_VALUE 9969 65762306a36Sopenharmony_ci 65862306a36Sopenharmony_ci#define BROADCAST_STORM_RATE_HI 0x07 65962306a36Sopenharmony_ci#define BROADCAST_STORM_RATE_LO 0xFF 66062306a36Sopenharmony_ci#define BROADCAST_STORM_RATE 0x07FF 66162306a36Sopenharmony_ci 66262306a36Sopenharmony_ci#define MULTICAST_STORM_DISABLE BIT(6) 66362306a36Sopenharmony_ci 66462306a36Sopenharmony_ci#define SW_START 0x01 66562306a36Sopenharmony_ci 66662306a36Sopenharmony_ci/* xMII configuration */ 66762306a36Sopenharmony_ci#define P_MII_DUPLEX_M BIT(6) 66862306a36Sopenharmony_ci#define P_MII_100MBIT_M BIT(4) 66962306a36Sopenharmony_ci 67062306a36Sopenharmony_ci#define P_GMII_1GBIT_M BIT(6) 67162306a36Sopenharmony_ci#define P_RGMII_ID_IG_ENABLE BIT(4) 67262306a36Sopenharmony_ci#define P_RGMII_ID_EG_ENABLE BIT(3) 67362306a36Sopenharmony_ci#define P_MII_MAC_MODE BIT(2) 67462306a36Sopenharmony_ci#define P_MII_SEL_M 0x3 67562306a36Sopenharmony_ci 67662306a36Sopenharmony_ci/* Interrupt */ 67762306a36Sopenharmony_ci#define REG_SW_PORT_INT_STATUS__1 0x001B 67862306a36Sopenharmony_ci#define REG_SW_PORT_INT_MASK__1 0x001F 67962306a36Sopenharmony_ci 68062306a36Sopenharmony_ci#define REG_PORT_INT_STATUS 0x001B 68162306a36Sopenharmony_ci#define REG_PORT_INT_MASK 0x001F 68262306a36Sopenharmony_ci 68362306a36Sopenharmony_ci#define PORT_SRC_PHY_INT 1 68462306a36Sopenharmony_ci#define PORT_SRC_PTP_INT 2 68562306a36Sopenharmony_ci 68662306a36Sopenharmony_ci#define KSZ8795_HUGE_PACKET_SIZE 2000 68762306a36Sopenharmony_ci#define KSZ8863_HUGE_PACKET_SIZE 1916 68862306a36Sopenharmony_ci#define KSZ8863_NORMAL_PACKET_SIZE 1536 68962306a36Sopenharmony_ci#define KSZ8_LEGAL_PACKET_SIZE 1518 69062306a36Sopenharmony_ci#define KSZ9477_MAX_FRAME_SIZE 9000 69162306a36Sopenharmony_ci 69262306a36Sopenharmony_ci#define KSZ9477_REG_PORT_OUT_RATE_0 0x0420 69362306a36Sopenharmony_ci#define KSZ9477_OUT_RATE_NO_LIMIT 0 69462306a36Sopenharmony_ci 69562306a36Sopenharmony_ci#define KSZ9477_PORT_MRI_TC_MAP__4 0x0808 69662306a36Sopenharmony_ci 69762306a36Sopenharmony_ci#define KSZ9477_PORT_TC_MAP_S 4 69862306a36Sopenharmony_ci#define KSZ9477_MAX_TC_PRIO 7 69962306a36Sopenharmony_ci 70062306a36Sopenharmony_ci/* CBS related registers */ 70162306a36Sopenharmony_ci#define REG_PORT_MTI_QUEUE_INDEX__4 0x0900 70262306a36Sopenharmony_ci 70362306a36Sopenharmony_ci#define REG_PORT_MTI_QUEUE_CTRL_0 0x0914 70462306a36Sopenharmony_ci 70562306a36Sopenharmony_ci#define MTI_SCHEDULE_MODE_M GENMASK(7, 6) 70662306a36Sopenharmony_ci#define MTI_SCHEDULE_STRICT_PRIO 0 70762306a36Sopenharmony_ci#define MTI_SCHEDULE_WRR 2 70862306a36Sopenharmony_ci#define MTI_SHAPING_M GENMASK(5, 4) 70962306a36Sopenharmony_ci#define MTI_SHAPING_OFF 0 71062306a36Sopenharmony_ci#define MTI_SHAPING_SRP 1 71162306a36Sopenharmony_ci#define MTI_SHAPING_TIME_AWARE 2 71262306a36Sopenharmony_ci 71362306a36Sopenharmony_ci#define KSZ9477_PORT_MTI_QUEUE_CTRL_1 0x0915 71462306a36Sopenharmony_ci#define KSZ9477_DEFAULT_WRR_WEIGHT 1 71562306a36Sopenharmony_ci 71662306a36Sopenharmony_ci#define REG_PORT_MTI_HI_WATER_MARK 0x0916 71762306a36Sopenharmony_ci#define REG_PORT_MTI_LO_WATER_MARK 0x0918 71862306a36Sopenharmony_ci 71962306a36Sopenharmony_ci/* Regmap tables generation */ 72062306a36Sopenharmony_ci#define KSZ_SPI_OP_RD 3 72162306a36Sopenharmony_ci#define KSZ_SPI_OP_WR 2 72262306a36Sopenharmony_ci 72362306a36Sopenharmony_ci#define swabnot_used(x) 0 72462306a36Sopenharmony_ci 72562306a36Sopenharmony_ci#define KSZ_SPI_OP_FLAG_MASK(opcode, swp, regbits, regpad) \ 72662306a36Sopenharmony_ci swab##swp((opcode) << ((regbits) + (regpad))) 72762306a36Sopenharmony_ci 72862306a36Sopenharmony_ci#define KSZ_REGMAP_ENTRY(width, swp, regbits, regpad, regalign) \ 72962306a36Sopenharmony_ci { \ 73062306a36Sopenharmony_ci .name = #width, \ 73162306a36Sopenharmony_ci .val_bits = (width), \ 73262306a36Sopenharmony_ci .reg_stride = 1, \ 73362306a36Sopenharmony_ci .reg_bits = (regbits) + (regalign), \ 73462306a36Sopenharmony_ci .pad_bits = (regpad), \ 73562306a36Sopenharmony_ci .max_register = BIT(regbits) - 1, \ 73662306a36Sopenharmony_ci .cache_type = REGCACHE_NONE, \ 73762306a36Sopenharmony_ci .read_flag_mask = \ 73862306a36Sopenharmony_ci KSZ_SPI_OP_FLAG_MASK(KSZ_SPI_OP_RD, swp, \ 73962306a36Sopenharmony_ci regbits, regpad), \ 74062306a36Sopenharmony_ci .write_flag_mask = \ 74162306a36Sopenharmony_ci KSZ_SPI_OP_FLAG_MASK(KSZ_SPI_OP_WR, swp, \ 74262306a36Sopenharmony_ci regbits, regpad), \ 74362306a36Sopenharmony_ci .lock = ksz_regmap_lock, \ 74462306a36Sopenharmony_ci .unlock = ksz_regmap_unlock, \ 74562306a36Sopenharmony_ci .reg_format_endian = REGMAP_ENDIAN_BIG, \ 74662306a36Sopenharmony_ci .val_format_endian = REGMAP_ENDIAN_BIG \ 74762306a36Sopenharmony_ci } 74862306a36Sopenharmony_ci 74962306a36Sopenharmony_ci#define KSZ_REGMAP_TABLE(ksz, swp, regbits, regpad, regalign) \ 75062306a36Sopenharmony_ci static const struct regmap_config ksz##_regmap_config[] = { \ 75162306a36Sopenharmony_ci [KSZ_REGMAP_8] = KSZ_REGMAP_ENTRY(8, swp, (regbits), (regpad), (regalign)), \ 75262306a36Sopenharmony_ci [KSZ_REGMAP_16] = KSZ_REGMAP_ENTRY(16, swp, (regbits), (regpad), (regalign)), \ 75362306a36Sopenharmony_ci [KSZ_REGMAP_32] = KSZ_REGMAP_ENTRY(32, swp, (regbits), (regpad), (regalign)), \ 75462306a36Sopenharmony_ci } 75562306a36Sopenharmony_ci 75662306a36Sopenharmony_ci#endif 757