1 /* SPDX-License-Identifier: GPL-2.0
2  * Microchip switch driver common header
3  *
4  * Copyright (C) 2017-2019 Microchip Technology Inc.
5  */
6 
7 #ifndef __KSZ_COMMON_H
8 #define __KSZ_COMMON_H
9 
10 #include <linux/regmap.h>
11 
12 void ksz_port_cleanup(struct ksz_device *dev, int port);
13 void ksz_update_port_member(struct ksz_device *dev, int port);
14 void ksz_init_mib_timer(struct ksz_device *dev);
15 
16 /* Common DSA access functions */
17 
18 int ksz_phy_read16(struct dsa_switch *ds, int addr, int reg);
19 int ksz_phy_write16(struct dsa_switch *ds, int addr, int reg, u16 val);
20 void ksz_adjust_link(struct dsa_switch *ds, int port,
21 		     struct phy_device *phydev);
22 int ksz_sset_count(struct dsa_switch *ds, int port, int sset);
23 void ksz_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *buf);
24 int ksz_port_bridge_join(struct dsa_switch *ds, int port,
25 			 struct net_device *br);
26 void ksz_port_bridge_leave(struct dsa_switch *ds, int port,
27 			   struct net_device *br);
28 void ksz_port_fast_age(struct dsa_switch *ds, int port);
29 int ksz_port_vlan_prepare(struct dsa_switch *ds, int port,
30 			  const struct switchdev_obj_port_vlan *vlan);
31 int ksz_port_fdb_dump(struct dsa_switch *ds, int port, dsa_fdb_dump_cb_t *cb,
32 		      void *data);
33 int ksz_port_mdb_prepare(struct dsa_switch *ds, int port,
34 			 const struct switchdev_obj_port_mdb *mdb);
35 void ksz_port_mdb_add(struct dsa_switch *ds, int port,
36 		      const struct switchdev_obj_port_mdb *mdb);
37 int ksz_port_mdb_del(struct dsa_switch *ds, int port,
38 		     const struct switchdev_obj_port_mdb *mdb);
39 int ksz_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy);
40 void ksz_disable_port(struct dsa_switch *ds, int port);
41 
42 /* Common register access functions */
43 
44 static inline int ksz_read8(struct ksz_device *dev, u32 reg, u8 *val)
45 {
46 	unsigned int value;
47 	int ret = regmap_read(dev->regmap[0], reg, &value);
48 
49 	*val = value;
50 	return ret;
51 }
52 
53 static inline int ksz_read16(struct ksz_device *dev, u32 reg, u16 *val)
54 {
55 	unsigned int value;
56 	int ret = regmap_read(dev->regmap[1], reg, &value);
57 
58 	*val = value;
59 	return ret;
60 }
61 
62 static inline int ksz_read32(struct ksz_device *dev, u32 reg, u32 *val)
63 {
64 	unsigned int value;
65 	int ret = regmap_read(dev->regmap[2], reg, &value);
66 
67 	*val = value;
68 	return ret;
69 }
70 
71 static inline int ksz_write8(struct ksz_device *dev, u32 reg, u8 value)
72 {
73 	return regmap_write(dev->regmap[0], reg, value);
74 }
75 
76 static inline int ksz_write16(struct ksz_device *dev, u32 reg, u16 value)
77 {
78 	return regmap_write(dev->regmap[1], reg, value);
79 }
80 
81 static inline int ksz_write32(struct ksz_device *dev, u32 reg, u32 value)
82 {
83 	return regmap_write(dev->regmap[2], reg, value);
84 }
85 
86 static inline void ksz_pread8(struct ksz_device *dev, int port, int offset,
87 			      u8 *data)
88 {
89 	ksz_read8(dev, dev->dev_ops->get_port_addr(port, offset), data);
90 }
91 
92 static inline void ksz_pread16(struct ksz_device *dev, int port, int offset,
93 			       u16 *data)
94 {
95 	ksz_read16(dev, dev->dev_ops->get_port_addr(port, offset), data);
96 }
97 
98 static inline void ksz_pread32(struct ksz_device *dev, int port, int offset,
99 			       u32 *data)
100 {
101 	ksz_read32(dev, dev->dev_ops->get_port_addr(port, offset), data);
102 }
103 
104 static inline void ksz_pwrite8(struct ksz_device *dev, int port, int offset,
105 			       u8 data)
106 {
107 	ksz_write8(dev, dev->dev_ops->get_port_addr(port, offset), data);
108 }
109 
110 static inline void ksz_pwrite16(struct ksz_device *dev, int port, int offset,
111 				u16 data)
112 {
113 	ksz_write16(dev, dev->dev_ops->get_port_addr(port, offset), data);
114 }
115 
116 static inline void ksz_pwrite32(struct ksz_device *dev, int port, int offset,
117 				u32 data)
118 {
119 	ksz_write32(dev, dev->dev_ops->get_port_addr(port, offset), data);
120 }
121 
122 /* Regmap tables generation */
123 #define KSZ_SPI_OP_RD		3
124 #define KSZ_SPI_OP_WR		2
125 
126 #define KSZ_SPI_OP_FLAG_MASK(opcode, swp, regbits, regpad)		\
127 	swab##swp((opcode) << ((regbits) + (regpad)))
128 
129 #define KSZ_REGMAP_ENTRY(width, swp, regbits, regpad, regalign)		\
130 	{								\
131 		.val_bits = (width),					\
132 		.reg_stride = (width) / 8,				\
133 		.reg_bits = (regbits) + (regalign),			\
134 		.pad_bits = (regpad),					\
135 		.max_register = BIT(regbits) - 1,			\
136 		.cache_type = REGCACHE_NONE,				\
137 		.read_flag_mask =					\
138 			KSZ_SPI_OP_FLAG_MASK(KSZ_SPI_OP_RD, swp,	\
139 					     regbits, regpad),		\
140 		.write_flag_mask =					\
141 			KSZ_SPI_OP_FLAG_MASK(KSZ_SPI_OP_WR, swp,	\
142 					     regbits, regpad),		\
143 		.reg_format_endian = REGMAP_ENDIAN_BIG,			\
144 		.val_format_endian = REGMAP_ENDIAN_BIG			\
145 	}
146 
147 #define KSZ_REGMAP_TABLE(ksz, swp, regbits, regpad, regalign)		\
148 	static const struct regmap_config ksz##_regmap_config[] = {	\
149 		KSZ_REGMAP_ENTRY(8, swp, (regbits), (regpad), (regalign)), \
150 		KSZ_REGMAP_ENTRY(16, swp, (regbits), (regpad), (regalign)), \
151 		KSZ_REGMAP_ENTRY(32, swp, (regbits), (regpad), (regalign)), \
152 	}
153 
154 #endif
155