blob: 1ee4e8016642203e5e79a9e3bacd9d8d2620a657 [file] [log] [blame]
Florian Fainelli967dd822016-06-09 18:23:53 -07001/*
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/phy.h>
25#include <net/dsa.h>
26
Florian Fainelli1da6df82016-06-09 18:23:55 -070027#include "b53_regs.h"
28
Florian Fainelli967dd822016-06-09 18:23:53 -070029struct b53_device;
30
31struct b53_io_ops {
32 int (*read8)(struct b53_device *dev, u8 page, u8 reg, u8 *value);
33 int (*read16)(struct b53_device *dev, u8 page, u8 reg, u16 *value);
34 int (*read32)(struct b53_device *dev, u8 page, u8 reg, u32 *value);
35 int (*read48)(struct b53_device *dev, u8 page, u8 reg, u64 *value);
36 int (*read64)(struct b53_device *dev, u8 page, u8 reg, u64 *value);
37 int (*write8)(struct b53_device *dev, u8 page, u8 reg, u8 value);
38 int (*write16)(struct b53_device *dev, u8 page, u8 reg, u16 value);
39 int (*write32)(struct b53_device *dev, u8 page, u8 reg, u32 value);
40 int (*write48)(struct b53_device *dev, u8 page, u8 reg, u64 value);
41 int (*write64)(struct b53_device *dev, u8 page, u8 reg, u64 value);
42 int (*phy_read16)(struct b53_device *dev, int addr, int reg, u16 *value);
43 int (*phy_write16)(struct b53_device *dev, int addr, int reg, u16 value);
44};
45
46enum {
47 BCM5325_DEVICE_ID = 0x25,
48 BCM5365_DEVICE_ID = 0x65,
49 BCM5395_DEVICE_ID = 0x95,
50 BCM5397_DEVICE_ID = 0x97,
51 BCM5398_DEVICE_ID = 0x98,
52 BCM53115_DEVICE_ID = 0x53115,
53 BCM53125_DEVICE_ID = 0x53125,
54 BCM53128_DEVICE_ID = 0x53128,
55 BCM63XX_DEVICE_ID = 0x6300,
56 BCM53010_DEVICE_ID = 0x53010,
57 BCM53011_DEVICE_ID = 0x53011,
58 BCM53012_DEVICE_ID = 0x53012,
59 BCM53018_DEVICE_ID = 0x53018,
60 BCM53019_DEVICE_ID = 0x53019,
61};
62
63#define B53_N_PORTS 9
64#define B53_N_PORTS_25 6
65
66struct b53_port {
67};
68
69struct b53_device {
70 struct dsa_switch *ds;
71 struct b53_platform_data *pdata;
72 const char *name;
73
74 struct mutex reg_mutex;
75 struct mutex stats_mutex;
76 const struct b53_io_ops *ops;
77
78 /* chip specific data */
79 u32 chip_id;
80 u8 core_rev;
81 u8 vta_regs[3];
82 u8 duplex_reg;
83 u8 jumbo_pm_reg;
84 u8 jumbo_size_reg;
85 int reset_gpio;
Florian Fainelli1da6df82016-06-09 18:23:55 -070086 u8 num_arl_entries;
Florian Fainelli967dd822016-06-09 18:23:53 -070087
88 /* used ports mask */
89 u16 enabled_ports;
90 unsigned int cpu_port;
91
92 /* connect specific data */
93 u8 current_page;
94 struct device *dev;
95
96 /* Master MDIO bus we got probed from */
97 struct mii_bus *bus;
98
99 /* Slave MDIO bus we created */
100 struct mii_bus *slave_bus;
101 void *priv;
102
103 /* run time configuration */
104 unsigned enable_jumbo:1;
105 unsigned allow_vid_4095:1;
106 unsigned int num_vlans;
107 unsigned int num_ports;
108 struct b53_port *ports;
109};
110
111#define b53_for_each_port(dev, i) \
112 for (i = 0; i < B53_N_PORTS; i++) \
113 if (dev->enabled_ports & BIT(i))
114
115
116static inline int is5325(struct b53_device *dev)
117{
118 return dev->chip_id == BCM5325_DEVICE_ID;
119}
120
121static inline int is5365(struct b53_device *dev)
122{
123#ifdef CONFIG_BCM47XX
124 return dev->chip_id == BCM5365_DEVICE_ID;
125#else
126 return 0;
127#endif
128}
129
130static inline int is5397_98(struct b53_device *dev)
131{
132 return dev->chip_id == BCM5397_DEVICE_ID ||
133 dev->chip_id == BCM5398_DEVICE_ID;
134}
135
136static inline int is539x(struct b53_device *dev)
137{
138 return dev->chip_id == BCM5395_DEVICE_ID ||
139 dev->chip_id == BCM5397_DEVICE_ID ||
140 dev->chip_id == BCM5398_DEVICE_ID;
141}
142
143static inline int is531x5(struct b53_device *dev)
144{
145 return dev->chip_id == BCM53115_DEVICE_ID ||
146 dev->chip_id == BCM53125_DEVICE_ID ||
147 dev->chip_id == BCM53128_DEVICE_ID;
148}
149
150static inline int is63xx(struct b53_device *dev)
151{
152#ifdef CONFIG_BCM63XX
153 return dev->chip_id == BCM63XX_DEVICE_ID;
154#else
155 return 0;
156#endif
157}
158
159static inline int is5301x(struct b53_device *dev)
160{
161 return dev->chip_id == BCM53010_DEVICE_ID ||
162 dev->chip_id == BCM53011_DEVICE_ID ||
163 dev->chip_id == BCM53012_DEVICE_ID ||
164 dev->chip_id == BCM53018_DEVICE_ID ||
165 dev->chip_id == BCM53019_DEVICE_ID;
166}
167
168#define B53_CPU_PORT_25 5
169#define B53_CPU_PORT 8
170
171static inline int is_cpu_port(struct b53_device *dev, int port)
172{
173 return dev->cpu_port;
174}
175
176struct b53_device *b53_switch_alloc(struct device *base, struct b53_io_ops *ops,
177 void *priv);
178
179int b53_switch_detect(struct b53_device *dev);
180
181int b53_switch_register(struct b53_device *dev);
182
183static inline void b53_switch_remove(struct b53_device *dev)
184{
185 dsa_unregister_switch(dev->ds);
186}
187
188static inline int b53_read8(struct b53_device *dev, u8 page, u8 reg, u8 *val)
189{
190 int ret;
191
192 mutex_lock(&dev->reg_mutex);
193 ret = dev->ops->read8(dev, page, reg, val);
194 mutex_unlock(&dev->reg_mutex);
195
196 return ret;
197}
198
199static inline int b53_read16(struct b53_device *dev, u8 page, u8 reg, u16 *val)
200{
201 int ret;
202
203 mutex_lock(&dev->reg_mutex);
204 ret = dev->ops->read16(dev, page, reg, val);
205 mutex_unlock(&dev->reg_mutex);
206
207 return ret;
208}
209
210static inline int b53_read32(struct b53_device *dev, u8 page, u8 reg, u32 *val)
211{
212 int ret;
213
214 mutex_lock(&dev->reg_mutex);
215 ret = dev->ops->read32(dev, page, reg, val);
216 mutex_unlock(&dev->reg_mutex);
217
218 return ret;
219}
220
221static inline int b53_read48(struct b53_device *dev, u8 page, u8 reg, u64 *val)
222{
223 int ret;
224
225 mutex_lock(&dev->reg_mutex);
226 ret = dev->ops->read48(dev, page, reg, val);
227 mutex_unlock(&dev->reg_mutex);
228
229 return ret;
230}
231
232static inline int b53_read64(struct b53_device *dev, u8 page, u8 reg, u64 *val)
233{
234 int ret;
235
236 mutex_lock(&dev->reg_mutex);
237 ret = dev->ops->read64(dev, page, reg, val);
238 mutex_unlock(&dev->reg_mutex);
239
240 return ret;
241}
242
243static inline int b53_write8(struct b53_device *dev, u8 page, u8 reg, u8 value)
244{
245 int ret;
246
247 mutex_lock(&dev->reg_mutex);
248 ret = dev->ops->write8(dev, page, reg, value);
249 mutex_unlock(&dev->reg_mutex);
250
251 return ret;
252}
253
254static inline int b53_write16(struct b53_device *dev, u8 page, u8 reg,
255 u16 value)
256{
257 int ret;
258
259 mutex_lock(&dev->reg_mutex);
260 ret = dev->ops->write16(dev, page, reg, value);
261 mutex_unlock(&dev->reg_mutex);
262
263 return ret;
264}
265
266static inline int b53_write32(struct b53_device *dev, u8 page, u8 reg,
267 u32 value)
268{
269 int ret;
270
271 mutex_lock(&dev->reg_mutex);
272 ret = dev->ops->write32(dev, page, reg, value);
273 mutex_unlock(&dev->reg_mutex);
274
275 return ret;
276}
277
278static inline int b53_write48(struct b53_device *dev, u8 page, u8 reg,
279 u64 value)
280{
281 int ret;
282
283 mutex_lock(&dev->reg_mutex);
284 ret = dev->ops->write48(dev, page, reg, value);
285 mutex_unlock(&dev->reg_mutex);
286
287 return ret;
288}
289
290static inline int b53_write64(struct b53_device *dev, u8 page, u8 reg,
291 u64 value)
292{
293 int ret;
294
295 mutex_lock(&dev->reg_mutex);
296 ret = dev->ops->write64(dev, page, reg, value);
297 mutex_unlock(&dev->reg_mutex);
298
299 return ret;
300}
301
Florian Fainelli1da6df82016-06-09 18:23:55 -0700302struct b53_arl_entry {
303 u8 port;
304 u8 mac[ETH_ALEN];
305 u16 vid;
306 u8 is_valid:1;
307 u8 is_age:1;
308 u8 is_static:1;
309};
310
311static inline void b53_mac_from_u64(u64 src, u8 *dst)
312{
313 unsigned int i;
314
315 for (i = 0; i < ETH_ALEN; i++)
316 dst[ETH_ALEN - 1 - i] = (src >> (8 * i)) & 0xff;
317}
318
319static inline u64 b53_mac_to_u64(const u8 *src)
320{
321 unsigned int i;
322 u64 dst = 0;
323
324 for (i = 0; i < ETH_ALEN; i++)
325 dst |= (u64)src[ETH_ALEN - 1 - i] << (8 * i);
326
327 return dst;
328}
329
330static inline void b53_arl_to_entry(struct b53_arl_entry *ent,
331 u64 mac_vid, u32 fwd_entry)
332{
333 memset(ent, 0, sizeof(*ent));
334 ent->port = fwd_entry & ARLTBL_DATA_PORT_ID_MASK;
335 ent->is_valid = !!(fwd_entry & ARLTBL_VALID);
336 ent->is_age = !!(fwd_entry & ARLTBL_AGE);
337 ent->is_static = !!(fwd_entry & ARLTBL_STATIC);
338 b53_mac_from_u64(mac_vid, ent->mac);
339 ent->vid = mac_vid >> ARLTBL_VID_S;
340}
341
342static inline void b53_arl_from_entry(u64 *mac_vid, u32 *fwd_entry,
343 const struct b53_arl_entry *ent)
344{
345 *mac_vid = b53_mac_to_u64(ent->mac);
346 *mac_vid |= (u64)(ent->vid & ARLTBL_VID_MASK) << ARLTBL_VID_S;
347 *fwd_entry = ent->port & ARLTBL_DATA_PORT_ID_MASK;
348 if (ent->is_valid)
349 *fwd_entry |= ARLTBL_VALID;
350 if (ent->is_static)
351 *fwd_entry |= ARLTBL_STATIC;
352 if (ent->is_age)
353 *fwd_entry |= ARLTBL_AGE;
354}
355
Florian Fainelli967dd822016-06-09 18:23:53 -0700356#ifdef CONFIG_BCM47XX
357
358#include <linux/version.h>
359#include <linux/bcm47xx_nvram.h>
360#include <bcm47xx_board.h>
361static inline int b53_switch_get_reset_gpio(struct b53_device *dev)
362{
363 enum bcm47xx_board board = bcm47xx_board_get();
364
365 switch (board) {
366 case BCM47XX_BOARD_LINKSYS_WRT300NV11:
367 case BCM47XX_BOARD_LINKSYS_WRT310NV1:
368 return 8;
369 default:
370 return bcm47xx_nvram_gpio_pin("robo_reset");
371 }
372}
373#else
374static inline int b53_switch_get_reset_gpio(struct b53_device *dev)
375{
376 return -ENOENT;
377}
378#endif
379#endif