xref: /openbmc/linux/drivers/net/dsa/microchip/ksz_common.h (revision e66f840c08a237acfbb981592047b53e7411012f)
1c2e86691STristram Ha /* SPDX-License-Identifier: GPL-2.0
2c2e86691STristram Ha  * 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 
10ee394feaSMarek Vasut #include <linux/regmap.h>
11ee394feaSMarek Vasut 
127049f9b5STristram Ha void ksz_port_cleanup(struct ksz_device *dev, int port);
13c2e86691STristram Ha void ksz_update_port_member(struct ksz_device *dev, int port);
147c6ff470STristram Ha void ksz_init_mib_timer(struct ksz_device *dev);
15c2e86691STristram Ha 
16c2e86691STristram Ha /* Common DSA access functions */
17c2e86691STristram Ha 
18c2e86691STristram Ha int ksz_phy_read16(struct dsa_switch *ds, int addr, int reg);
19c2e86691STristram Ha int ksz_phy_write16(struct dsa_switch *ds, int addr, int reg, u16 val);
20c30d894bSTristram Ha void ksz_adjust_link(struct dsa_switch *ds, int port,
21c30d894bSTristram Ha 		     struct phy_device *phydev);
22c2e86691STristram Ha int ksz_sset_count(struct dsa_switch *ds, int port, int sset);
237c6ff470STristram Ha void ksz_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *buf);
24c2e86691STristram Ha int ksz_port_bridge_join(struct dsa_switch *ds, int port,
25c2e86691STristram Ha 			 struct net_device *br);
26c2e86691STristram Ha void ksz_port_bridge_leave(struct dsa_switch *ds, int port,
27c2e86691STristram Ha 			   struct net_device *br);
28c2e86691STristram Ha void ksz_port_fast_age(struct dsa_switch *ds, int port);
29c2e86691STristram Ha int ksz_port_vlan_prepare(struct dsa_switch *ds, int port,
30c2e86691STristram Ha 			  const struct switchdev_obj_port_vlan *vlan);
31c2e86691STristram Ha int ksz_port_fdb_dump(struct dsa_switch *ds, int port, dsa_fdb_dump_cb_t *cb,
32c2e86691STristram Ha 		      void *data);
33c2e86691STristram Ha int ksz_port_mdb_prepare(struct dsa_switch *ds, int port,
34c2e86691STristram Ha 			 const struct switchdev_obj_port_mdb *mdb);
35c2e86691STristram Ha void ksz_port_mdb_add(struct dsa_switch *ds, int port,
36c2e86691STristram Ha 		      const struct switchdev_obj_port_mdb *mdb);
37c2e86691STristram Ha int ksz_port_mdb_del(struct dsa_switch *ds, int port,
38c2e86691STristram Ha 		     const struct switchdev_obj_port_mdb *mdb);
39c2e86691STristram Ha int ksz_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy);
4075104db0SAndrew Lunn void ksz_disable_port(struct dsa_switch *ds, int port);
41c2e86691STristram Ha 
42c2e86691STristram Ha /* Common register access functions */
43c2e86691STristram Ha 
44c2e86691STristram Ha static inline int ksz_read8(struct ksz_device *dev, u32 reg, u8 *val)
45c2e86691STristram Ha {
46ee394feaSMarek Vasut 	unsigned int value;
47ee394feaSMarek Vasut 	int ret = regmap_read(dev->regmap[0], reg, &value);
48c2e86691STristram Ha 
49ee394feaSMarek Vasut 	*val = value;
50c2e86691STristram Ha 	return ret;
51c2e86691STristram Ha }
52c2e86691STristram Ha 
53c2e86691STristram Ha static inline int ksz_read16(struct ksz_device *dev, u32 reg, u16 *val)
54c2e86691STristram Ha {
55ee394feaSMarek Vasut 	unsigned int value;
56ee394feaSMarek Vasut 	int ret = regmap_read(dev->regmap[1], reg, &value);
57c2e86691STristram Ha 
58ee394feaSMarek Vasut 	*val = value;
59c2e86691STristram Ha 	return ret;
60c2e86691STristram Ha }
61c2e86691STristram Ha 
62c2e86691STristram Ha static inline int ksz_read32(struct ksz_device *dev, u32 reg, u32 *val)
63c2e86691STristram Ha {
64ee394feaSMarek Vasut 	unsigned int value;
65ee394feaSMarek Vasut 	int ret = regmap_read(dev->regmap[2], reg, &value);
66c2e86691STristram Ha 
67ee394feaSMarek Vasut 	*val = value;
68c2e86691STristram Ha 	return ret;
69c2e86691STristram Ha }
70c2e86691STristram Ha 
71*e66f840cSTristram Ha static inline int ksz_read64(struct ksz_device *dev, u32 reg, u64 *val)
72*e66f840cSTristram Ha {
73*e66f840cSTristram Ha 	u32 value[2];
74*e66f840cSTristram Ha 	int ret;
75*e66f840cSTristram Ha 
76*e66f840cSTristram Ha 	ret = regmap_bulk_read(dev->regmap[2], reg, value, 2);
77*e66f840cSTristram Ha 	if (!ret) {
78*e66f840cSTristram Ha 		/* Ick! ToDo: Add 64bit R/W to regmap on 32bit systems */
79*e66f840cSTristram Ha 		value[0] = swab32(value[0]);
80*e66f840cSTristram Ha 		value[1] = swab32(value[1]);
81*e66f840cSTristram Ha 		*val = swab64((u64)*value);
82*e66f840cSTristram Ha 	}
83*e66f840cSTristram Ha 
84*e66f840cSTristram Ha 	return ret;
85*e66f840cSTristram Ha }
86*e66f840cSTristram Ha 
87c2e86691STristram Ha static inline int ksz_write8(struct ksz_device *dev, u32 reg, u8 value)
88c2e86691STristram Ha {
89ee394feaSMarek Vasut 	return regmap_write(dev->regmap[0], reg, value);
90c2e86691STristram Ha }
91c2e86691STristram Ha 
92c2e86691STristram Ha static inline int ksz_write16(struct ksz_device *dev, u32 reg, u16 value)
93c2e86691STristram Ha {
94ee394feaSMarek Vasut 	return regmap_write(dev->regmap[1], reg, value);
95c2e86691STristram Ha }
96c2e86691STristram Ha 
97c2e86691STristram Ha static inline int ksz_write32(struct ksz_device *dev, u32 reg, u32 value)
98c2e86691STristram Ha {
99ee394feaSMarek Vasut 	return regmap_write(dev->regmap[2], reg, value);
100c2e86691STristram Ha }
101c2e86691STristram Ha 
102*e66f840cSTristram Ha static inline int ksz_write64(struct ksz_device *dev, u32 reg, u64 value)
103*e66f840cSTristram Ha {
104*e66f840cSTristram Ha 	u32 val[2];
105*e66f840cSTristram Ha 
106*e66f840cSTristram Ha 	/* Ick! ToDo: Add 64bit R/W to regmap on 32bit systems */
107*e66f840cSTristram Ha 	value = swab64(value);
108*e66f840cSTristram Ha 	val[0] = swab32(value & 0xffffffffULL);
109*e66f840cSTristram Ha 	val[1] = swab32(value >> 32ULL);
110*e66f840cSTristram Ha 
111*e66f840cSTristram Ha 	return regmap_bulk_write(dev->regmap[2], reg, val, 2);
112*e66f840cSTristram Ha }
113*e66f840cSTristram Ha 
114c2e86691STristram Ha static inline void ksz_pread8(struct ksz_device *dev, int port, int offset,
115c2e86691STristram Ha 			      u8 *data)
116c2e86691STristram Ha {
117c2e86691STristram Ha 	ksz_read8(dev, dev->dev_ops->get_port_addr(port, offset), data);
118c2e86691STristram Ha }
119c2e86691STristram Ha 
120c2e86691STristram Ha static inline void ksz_pread16(struct ksz_device *dev, int port, int offset,
121c2e86691STristram Ha 			       u16 *data)
122c2e86691STristram Ha {
123c2e86691STristram Ha 	ksz_read16(dev, dev->dev_ops->get_port_addr(port, offset), data);
124c2e86691STristram Ha }
125c2e86691STristram Ha 
126c2e86691STristram Ha static inline void ksz_pread32(struct ksz_device *dev, int port, int offset,
127c2e86691STristram Ha 			       u32 *data)
128c2e86691STristram Ha {
129c2e86691STristram Ha 	ksz_read32(dev, dev->dev_ops->get_port_addr(port, offset), data);
130c2e86691STristram Ha }
131c2e86691STristram Ha 
132c2e86691STristram Ha static inline void ksz_pwrite8(struct ksz_device *dev, int port, int offset,
133c2e86691STristram Ha 			       u8 data)
134c2e86691STristram Ha {
135c2e86691STristram Ha 	ksz_write8(dev, dev->dev_ops->get_port_addr(port, offset), data);
136c2e86691STristram Ha }
137c2e86691STristram Ha 
138c2e86691STristram Ha static inline void ksz_pwrite16(struct ksz_device *dev, int port, int offset,
139c2e86691STristram Ha 				u16 data)
140c2e86691STristram Ha {
141c2e86691STristram Ha 	ksz_write16(dev, dev->dev_ops->get_port_addr(port, offset), data);
142c2e86691STristram Ha }
143c2e86691STristram Ha 
144c2e86691STristram Ha static inline void ksz_pwrite32(struct ksz_device *dev, int port, int offset,
145c2e86691STristram Ha 				u32 data)
146c2e86691STristram Ha {
147c2e86691STristram Ha 	ksz_write32(dev, dev->dev_ops->get_port_addr(port, offset), data);
148c2e86691STristram Ha }
149c2e86691STristram Ha 
150255b59adSMarek Vasut /* Regmap tables generation */
151255b59adSMarek Vasut #define KSZ_SPI_OP_RD		3
152255b59adSMarek Vasut #define KSZ_SPI_OP_WR		2
153255b59adSMarek Vasut 
154255b59adSMarek Vasut #define KSZ_SPI_OP_FLAG_MASK(opcode, swp, regbits, regpad)		\
155255b59adSMarek Vasut 	swab##swp((opcode) << ((regbits) + (regpad)))
156255b59adSMarek Vasut 
157255b59adSMarek Vasut #define KSZ_REGMAP_ENTRY(width, swp, regbits, regpad, regalign)		\
158255b59adSMarek Vasut 	{								\
159255b59adSMarek Vasut 		.val_bits = (width),					\
160255b59adSMarek Vasut 		.reg_stride = (width) / 8,				\
161255b59adSMarek Vasut 		.reg_bits = (regbits) + (regalign),			\
162255b59adSMarek Vasut 		.pad_bits = (regpad),					\
163255b59adSMarek Vasut 		.max_register = BIT(regbits) - 1,			\
164255b59adSMarek Vasut 		.cache_type = REGCACHE_NONE,				\
165255b59adSMarek Vasut 		.read_flag_mask =					\
166255b59adSMarek Vasut 			KSZ_SPI_OP_FLAG_MASK(KSZ_SPI_OP_RD, swp,	\
167255b59adSMarek Vasut 					     regbits, regpad),		\
168255b59adSMarek Vasut 		.write_flag_mask =					\
169255b59adSMarek Vasut 			KSZ_SPI_OP_FLAG_MASK(KSZ_SPI_OP_WR, swp,	\
170255b59adSMarek Vasut 					     regbits, regpad),		\
171255b59adSMarek Vasut 		.reg_format_endian = REGMAP_ENDIAN_BIG,			\
172255b59adSMarek Vasut 		.val_format_endian = REGMAP_ENDIAN_BIG			\
173255b59adSMarek Vasut 	}
174255b59adSMarek Vasut 
175255b59adSMarek Vasut #define KSZ_REGMAP_TABLE(ksz, swp, regbits, regpad, regalign)		\
176255b59adSMarek Vasut 	static const struct regmap_config ksz##_regmap_config[] = {	\
177255b59adSMarek Vasut 		KSZ_REGMAP_ENTRY(8, swp, (regbits), (regpad), (regalign)), \
178255b59adSMarek Vasut 		KSZ_REGMAP_ENTRY(16, swp, (regbits), (regpad), (regalign)), \
179255b59adSMarek Vasut 		KSZ_REGMAP_ENTRY(32, swp, (regbits), (regpad), (regalign)), \
180255b59adSMarek Vasut 	}
181255b59adSMarek Vasut 
182c2e86691STristram Ha #endif
183