1 /* SPDX-License-Identifier: GPL-2.0 */
2 /* Microchip switch driver common header
4 * Copyright (C) 2017-2019 Microchip Technology Inc.
10 #include <linux/etherdevice.h>
11 #include <linux/kernel.h>
12 #include <linux/mutex.h>
13 #include <linux/phy.h>
14 #include <linux/regmap.h>
22 struct mutex cnt_mutex
; /* structure access */
31 struct phy_device phydev
;
33 u32 on
:1; /* port is not disabled by hardware */
34 u32 phy
:1; /* port has a PHY */
35 u32 fiber
:1; /* port is fiber */
36 u32 sgmii
:1; /* port is SGMII */
38 u32 read
:1; /* read MIB counters in background */
39 u32 freeze
:1; /* MIB counter freeze is enabled */
41 struct ksz_port_mib mib
;
42 phy_interface_t interface
;
46 struct dsa_switch
*ds
;
47 struct ksz_platform_data
*pdata
;
50 struct mutex dev_mutex
; /* device access */
51 struct mutex regmap_mutex
; /* regmap access */
52 struct mutex alu_mutex
; /* ALU access */
53 struct mutex vlan_mutex
; /* vlan access */
54 const struct ksz_dev_ops
*dev_ops
;
57 struct regmap
*regmap
[3];
61 struct gpio_desc
*reset_gpio
; /* Optional reset GPIO */
63 /* chip specific data */
68 int cpu_port
; /* port connected to CPU */
69 int cpu_ports
; /* port bitmap can be cpu port */
74 phy_interface_t compat_interface
;
79 struct vlan_table
*vlan_cache
;
81 struct ksz_port
*ports
;
82 struct delayed_work mib_read
;
83 unsigned long mib_read_interval
;
88 u32 features
; /* chip specific features */
89 u32 overrides
; /* chip functions set by user */
114 u32 (*get_port_addr
)(int port
, int offset
);
115 void (*cfg_port_member
)(struct ksz_device
*dev
, int port
, u8 member
);
116 void (*flush_dyn_mac_table
)(struct ksz_device
*dev
, int port
);
117 void (*port_cleanup
)(struct ksz_device
*dev
, int port
);
118 void (*port_setup
)(struct ksz_device
*dev
, int port
, bool cpu_port
);
119 void (*r_phy
)(struct ksz_device
*dev
, u16 phy
, u16 reg
, u16
*val
);
120 void (*w_phy
)(struct ksz_device
*dev
, u16 phy
, u16 reg
, u16 val
);
121 int (*r_dyn_mac_table
)(struct ksz_device
*dev
, u16 addr
, u8
*mac_addr
,
122 u8
*fid
, u8
*src_port
, u8
*timestamp
,
124 int (*r_sta_mac_table
)(struct ksz_device
*dev
, u16 addr
,
125 struct alu_struct
*alu
);
126 void (*w_sta_mac_table
)(struct ksz_device
*dev
, u16 addr
,
127 struct alu_struct
*alu
);
128 void (*r_mib_cnt
)(struct ksz_device
*dev
, int port
, u16 addr
,
130 void (*r_mib_pkt
)(struct ksz_device
*dev
, int port
, u16 addr
,
131 u64
*dropped
, u64
*cnt
);
132 void (*freeze_mib
)(struct ksz_device
*dev
, int port
, bool freeze
);
133 void (*port_init_cnt
)(struct ksz_device
*dev
, int port
);
134 int (*shutdown
)(struct ksz_device
*dev
);
135 int (*detect
)(struct ksz_device
*dev
);
136 int (*init
)(struct ksz_device
*dev
);
137 void (*exit
)(struct ksz_device
*dev
);
140 struct ksz_device
*ksz_switch_alloc(struct device
*base
, void *priv
);
141 int ksz_switch_register(struct ksz_device
*dev
,
142 const struct ksz_dev_ops
*ops
);
143 void ksz_switch_remove(struct ksz_device
*dev
);
145 int ksz8795_switch_register(struct ksz_device
*dev
);
146 int ksz9477_switch_register(struct ksz_device
*dev
);
148 void ksz_update_port_member(struct ksz_device
*dev
, int port
);
149 void ksz_init_mib_timer(struct ksz_device
*dev
);
151 /* Common DSA access functions */
153 int ksz_phy_read16(struct dsa_switch
*ds
, int addr
, int reg
);
154 int ksz_phy_write16(struct dsa_switch
*ds
, int addr
, int reg
, u16 val
);
155 void ksz_mac_link_down(struct dsa_switch
*ds
, int port
, unsigned int mode
,
156 phy_interface_t interface
);
157 int ksz_sset_count(struct dsa_switch
*ds
, int port
, int sset
);
158 void ksz_get_ethtool_stats(struct dsa_switch
*ds
, int port
, uint64_t *buf
);
159 int ksz_port_bridge_join(struct dsa_switch
*ds
, int port
,
160 struct net_device
*br
);
161 void ksz_port_bridge_leave(struct dsa_switch
*ds
, int port
,
162 struct net_device
*br
);
163 void ksz_port_fast_age(struct dsa_switch
*ds
, int port
);
164 int ksz_port_vlan_prepare(struct dsa_switch
*ds
, int port
,
165 const struct switchdev_obj_port_vlan
*vlan
);
166 int ksz_port_fdb_dump(struct dsa_switch
*ds
, int port
, dsa_fdb_dump_cb_t
*cb
,
168 int ksz_port_mdb_prepare(struct dsa_switch
*ds
, int port
,
169 const struct switchdev_obj_port_mdb
*mdb
);
170 void ksz_port_mdb_add(struct dsa_switch
*ds
, int port
,
171 const struct switchdev_obj_port_mdb
*mdb
);
172 int ksz_port_mdb_del(struct dsa_switch
*ds
, int port
,
173 const struct switchdev_obj_port_mdb
*mdb
);
174 int ksz_enable_port(struct dsa_switch
*ds
, int port
, struct phy_device
*phy
);
176 /* Common register access functions */
178 static inline int ksz_read8(struct ksz_device
*dev
, u32 reg
, u8
*val
)
181 int ret
= regmap_read(dev
->regmap
[0], reg
, &value
);
187 static inline int ksz_read16(struct ksz_device
*dev
, u32 reg
, u16
*val
)
190 int ret
= regmap_read(dev
->regmap
[1], reg
, &value
);
196 static inline int ksz_read32(struct ksz_device
*dev
, u32 reg
, u32
*val
)
199 int ret
= regmap_read(dev
->regmap
[2], reg
, &value
);
205 static inline int ksz_read64(struct ksz_device
*dev
, u32 reg
, u64
*val
)
210 ret
= regmap_bulk_read(dev
->regmap
[2], reg
, value
, 2);
212 /* Ick! ToDo: Add 64bit R/W to regmap on 32bit systems */
213 value
[0] = swab32(value
[0]);
214 value
[1] = swab32(value
[1]);
215 *val
= swab64((u64
)*value
);
221 static inline int ksz_write8(struct ksz_device
*dev
, u32 reg
, u8 value
)
223 return regmap_write(dev
->regmap
[0], reg
, value
);
226 static inline int ksz_write16(struct ksz_device
*dev
, u32 reg
, u16 value
)
228 return regmap_write(dev
->regmap
[1], reg
, value
);
231 static inline int ksz_write32(struct ksz_device
*dev
, u32 reg
, u32 value
)
233 return regmap_write(dev
->regmap
[2], reg
, value
);
236 static inline int ksz_write64(struct ksz_device
*dev
, u32 reg
, u64 value
)
240 /* Ick! ToDo: Add 64bit R/W to regmap on 32bit systems */
241 value
= swab64(value
);
242 val
[0] = swab32(value
& 0xffffffffULL
);
243 val
[1] = swab32(value
>> 32ULL);
245 return regmap_bulk_write(dev
->regmap
[2], reg
, val
, 2);
248 static inline void ksz_pread8(struct ksz_device
*dev
, int port
, int offset
,
251 ksz_read8(dev
, dev
->dev_ops
->get_port_addr(port
, offset
), data
);
254 static inline void ksz_pread16(struct ksz_device
*dev
, int port
, int offset
,
257 ksz_read16(dev
, dev
->dev_ops
->get_port_addr(port
, offset
), data
);
260 static inline void ksz_pread32(struct ksz_device
*dev
, int port
, int offset
,
263 ksz_read32(dev
, dev
->dev_ops
->get_port_addr(port
, offset
), data
);
266 static inline void ksz_pwrite8(struct ksz_device
*dev
, int port
, int offset
,
269 ksz_write8(dev
, dev
->dev_ops
->get_port_addr(port
, offset
), data
);
272 static inline void ksz_pwrite16(struct ksz_device
*dev
, int port
, int offset
,
275 ksz_write16(dev
, dev
->dev_ops
->get_port_addr(port
, offset
), data
);
278 static inline void ksz_pwrite32(struct ksz_device
*dev
, int port
, int offset
,
281 ksz_write32(dev
, dev
->dev_ops
->get_port_addr(port
, offset
), data
);
284 static inline void ksz_regmap_lock(void *__mtx
)
286 struct mutex
*mtx
= __mtx
;
290 static inline void ksz_regmap_unlock(void *__mtx
)
292 struct mutex
*mtx
= __mtx
;
296 /* Regmap tables generation */
297 #define KSZ_SPI_OP_RD 3
298 #define KSZ_SPI_OP_WR 2
300 #define swabnot_used(x) 0
302 #define KSZ_SPI_OP_FLAG_MASK(opcode, swp, regbits, regpad) \
303 swab##swp((opcode) << ((regbits) + (regpad)))
305 #define KSZ_REGMAP_ENTRY(width, swp, regbits, regpad, regalign) \
308 .val_bits = (width), \
310 .reg_bits = (regbits) + (regalign), \
311 .pad_bits = (regpad), \
312 .max_register = BIT(regbits) - 1, \
313 .cache_type = REGCACHE_NONE, \
315 KSZ_SPI_OP_FLAG_MASK(KSZ_SPI_OP_RD, swp, \
318 KSZ_SPI_OP_FLAG_MASK(KSZ_SPI_OP_WR, swp, \
320 .lock = ksz_regmap_lock, \
321 .unlock = ksz_regmap_unlock, \
322 .reg_format_endian = REGMAP_ENDIAN_BIG, \
323 .val_format_endian = REGMAP_ENDIAN_BIG \
326 #define KSZ_REGMAP_TABLE(ksz, swp, regbits, regpad, regalign) \
327 static const struct regmap_config ksz##_regmap_config[] = { \
328 KSZ_REGMAP_ENTRY(8, swp, (regbits), (regpad), (regalign)), \
329 KSZ_REGMAP_ENTRY(16, swp, (regbits), (regpad), (regalign)), \
330 KSZ_REGMAP_ENTRY(32, swp, (regbits), (regpad), (regalign)), \