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