1/*
2 * B53 common definitions
3 *
4 * Copyright (C) 2011-2013 Jonas Gorski <jogo@openwrt.org>
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#ifndef __B53_PRIV_H
20#define __B53_PRIV_H
21
22#include <linux/kernel.h>
23#include <linux/mutex.h>
24#include <linux/switch.h>
25
26struct b53_device;
27
28struct b53_io_ops {
29	int (*read8)(struct b53_device *dev, u8 page, u8 reg, u8 *value);
30	int (*read16)(struct b53_device *dev, u8 page, u8 reg, u16 *value);
31	int (*read32)(struct b53_device *dev, u8 page, u8 reg, u32 *value);
32	int (*read48)(struct b53_device *dev, u8 page, u8 reg, u64 *value);
33	int (*read64)(struct b53_device *dev, u8 page, u8 reg, u64 *value);
34	int (*write8)(struct b53_device *dev, u8 page, u8 reg, u8 value);
35	int (*write16)(struct b53_device *dev, u8 page, u8 reg, u16 value);
36	int (*write32)(struct b53_device *dev, u8 page, u8 reg, u32 value);
37	int (*write48)(struct b53_device *dev, u8 page, u8 reg, u64 value);
38	int (*write64)(struct b53_device *dev, u8 page, u8 reg, u64 value);
39	int (*phy_read16)(struct b53_device *dev, int addr, u8 reg, u16 *value);
40	int (*phy_write16)(struct b53_device *dev, int addr, u8 reg, u16 value);
41};
42
43enum {
44	BCM5325_DEVICE_ID = 0x25,
45	BCM5365_DEVICE_ID = 0x65,
46	BCM5395_DEVICE_ID = 0x95,
47	BCM5397_DEVICE_ID = 0x97,
48	BCM5398_DEVICE_ID = 0x98,
49	BCM53115_DEVICE_ID = 0x53115,
50	BCM53125_DEVICE_ID = 0x53125,
51	BCM53128_DEVICE_ID = 0x53128,
52	BCM63XX_DEVICE_ID = 0x6300,
53	BCM53010_DEVICE_ID = 0x53010,
54	BCM53011_DEVICE_ID = 0x53011,
55	BCM53012_DEVICE_ID = 0x53012,
56	BCM53018_DEVICE_ID = 0x53018,
57	BCM53019_DEVICE_ID = 0x53019,
58};
59
60#define B53_N_PORTS	9
61#define B53_N_PORTS_25	6
62
63struct b53_vlan {
64	unsigned int	members:B53_N_PORTS;
65	unsigned int	untag:B53_N_PORTS;
66};
67
68struct b53_port {
69	unsigned int	pvid:12;
70};
71
72struct b53_device {
73	struct switch_dev sw_dev;
74	struct b53_platform_data *pdata;
75
76	struct mutex reg_mutex;
77	const struct b53_io_ops *ops;
78
79	/* chip specific data */
80	u32 chip_id;
81	u8 core_rev;
82	u8 vta_regs[3];
83	u8 duplex_reg;
84	u8 jumbo_pm_reg;
85	u8 jumbo_size_reg;
86	int reset_gpio;
87
88	/* used ports mask */
89	u16 enabled_ports;
90
91	/* connect specific data */
92	u8 current_page;
93	struct device *dev;
94	void *priv;
95
96	/* run time configuration */
97	unsigned enable_vlan:1;
98	unsigned enable_jumbo:1;
99	unsigned allow_vid_4095:1;
100
101	struct b53_port *ports;
102	struct b53_vlan *vlans;
103
104	char *buf;
105};
106
107#define b53_for_each_port(dev, i) \
108	for (i = 0; i < B53_N_PORTS; i++) \
109		if (dev->enabled_ports & BIT(i))
110
111
112
113static inline int is5325(struct b53_device *dev)
114{
115	return dev->chip_id == BCM5325_DEVICE_ID;
116}
117
118static inline int is5365(struct b53_device *dev)
119{
120#ifdef CONFIG_BCM47XX
121	return dev->chip_id == BCM5365_DEVICE_ID;
122#else
123	return 0;
124#endif
125}
126
127static inline int is5397_98(struct b53_device *dev)
128{
129	return dev->chip_id == BCM5397_DEVICE_ID ||
130		dev->chip_id == BCM5398_DEVICE_ID;
131}
132
133static inline int is539x(struct b53_device *dev)
134{
135	return dev->chip_id == BCM5395_DEVICE_ID ||
136		dev->chip_id == BCM5397_DEVICE_ID ||
137		dev->chip_id == BCM5398_DEVICE_ID;
138}
139
140static inline int is531x5(struct b53_device *dev)
141{
142	return dev->chip_id == BCM53115_DEVICE_ID ||
143		dev->chip_id == BCM53125_DEVICE_ID ||
144		dev->chip_id == BCM53128_DEVICE_ID;
145}
146
147static inline int is63xx(struct b53_device *dev)
148{
149#ifdef CONFIG_BCM63XX
150	return dev->chip_id == BCM63XX_DEVICE_ID;
151#else
152	return 0;
153#endif
154}
155
156static inline int is5301x(struct b53_device *dev)
157{
158	return dev->chip_id == BCM53010_DEVICE_ID ||
159		dev->chip_id == BCM53011_DEVICE_ID ||
160		dev->chip_id == BCM53012_DEVICE_ID ||
161		dev->chip_id == BCM53018_DEVICE_ID ||
162		dev->chip_id == BCM53019_DEVICE_ID;
163}
164
165#define B53_CPU_PORT_25	5
166#define B53_CPU_PORT	8
167
168static inline int is_cpu_port(struct b53_device *dev, int port)
169{
170	return dev->sw_dev.cpu_port == port;
171}
172
173static inline struct b53_device *sw_to_b53(struct switch_dev *sw)
174{
175	return container_of(sw, struct b53_device, sw_dev);
176}
177
178struct b53_device *b53_switch_alloc(struct device *base, struct b53_io_ops *ops,
179				    void *priv);
180
181int b53_switch_detect(struct b53_device *dev);
182
183int b53_switch_register(struct b53_device *dev);
184
185static inline void b53_switch_remove(struct b53_device *dev)
186{
187	unregister_switch(&dev->sw_dev);
188}
189
190static inline int b53_read8(struct b53_device *dev, u8 page, u8 reg, u8 *val)
191{
192	int ret;
193
194	mutex_lock(&dev->reg_mutex);
195	ret = dev->ops->read8(dev, page, reg, val);
196	mutex_unlock(&dev->reg_mutex);
197
198	return ret;
199}
200
201static inline int b53_read16(struct b53_device *dev, u8 page, u8 reg, u16 *val)
202{
203	int ret;
204
205	mutex_lock(&dev->reg_mutex);
206	ret = dev->ops->read16(dev, page, reg, val);
207	mutex_unlock(&dev->reg_mutex);
208
209	return ret;
210}
211
212static inline int b53_read32(struct b53_device *dev, u8 page, u8 reg, u32 *val)
213{
214	int ret;
215
216	mutex_lock(&dev->reg_mutex);
217	ret = dev->ops->read32(dev, page, reg, val);
218	mutex_unlock(&dev->reg_mutex);
219
220	return ret;
221}
222
223static inline int b53_read48(struct b53_device *dev, u8 page, u8 reg, u64 *val)
224{
225	int ret;
226
227	mutex_lock(&dev->reg_mutex);
228	ret = dev->ops->read48(dev, page, reg, val);
229	mutex_unlock(&dev->reg_mutex);
230
231	return ret;
232}
233
234static inline int b53_read64(struct b53_device *dev, u8 page, u8 reg, u64 *val)
235{
236	int ret;
237
238	mutex_lock(&dev->reg_mutex);
239	ret = dev->ops->read64(dev, page, reg, val);
240	mutex_unlock(&dev->reg_mutex);
241
242	return ret;
243}
244
245static inline int b53_write8(struct b53_device *dev, u8 page, u8 reg, u8 value)
246{
247	int ret;
248
249	mutex_lock(&dev->reg_mutex);
250	ret = dev->ops->write8(dev, page, reg, value);
251	mutex_unlock(&dev->reg_mutex);
252
253	return ret;
254}
255
256static inline int b53_write16(struct b53_device *dev, u8 page, u8 reg,
257			      u16 value)
258{
259	int ret;
260
261	mutex_lock(&dev->reg_mutex);
262	ret = dev->ops->write16(dev, page, reg, value);
263	mutex_unlock(&dev->reg_mutex);
264
265	return ret;
266}
267
268static inline int b53_write32(struct b53_device *dev, u8 page, u8 reg,
269			      u32 value)
270{
271	int ret;
272
273	mutex_lock(&dev->reg_mutex);
274	ret = dev->ops->write32(dev, page, reg, value);
275	mutex_unlock(&dev->reg_mutex);
276
277	return ret;
278}
279
280static inline int b53_write48(struct b53_device *dev, u8 page, u8 reg,
281			      u64 value)
282{
283	int ret;
284
285	mutex_lock(&dev->reg_mutex);
286	ret = dev->ops->write48(dev, page, reg, value);
287	mutex_unlock(&dev->reg_mutex);
288
289	return ret;
290}
291
292static inline int b53_write64(struct b53_device *dev, u8 page, u8 reg,
293			       u64 value)
294{
295	int ret;
296
297	mutex_lock(&dev->reg_mutex);
298	ret = dev->ops->write64(dev, page, reg, value);
299	mutex_unlock(&dev->reg_mutex);
300
301	return ret;
302}
303
304#ifdef CONFIG_BCM47XX
305
306#include <linux/version.h>
307#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0))
308#include <linux/bcm47xx_nvram.h>
309#else
310#include <bcm47xx_nvram.h>
311#endif
312#include <bcm47xx_board.h>
313static inline int b53_switch_get_reset_gpio(struct b53_device *dev)
314{
315	enum bcm47xx_board board = bcm47xx_board_get();
316
317	switch (board) {
318	case BCM47XX_BOARD_LINKSYS_WRT300NV11:
319	case BCM47XX_BOARD_LINKSYS_WRT310NV1:
320		return 8;
321	default:
322		return bcm47xx_nvram_gpio_pin("robo_reset");
323	}
324}
325#else
326static inline int b53_switch_get_reset_gpio(struct b53_device *dev)
327{
328	return -ENOENT;
329}
330#endif
331#endif
332