generic: b53: clear SM_SW_FWD_MODE unconditionally when enabling VLAN
[openwrt.git] / target / linux / generic / files / drivers / net / phy / b53 / b53_common.c
1 /*
2  * B53 switch driver main logic
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 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
20
21 #include <linux/delay.h>
22 #include <linux/export.h>
23 #include <linux/kernel.h>
24 #include <linux/module.h>
25 #include <linux/switch.h>
26 #include <linux/platform_data/b53.h>
27
28 #include "b53_regs.h"
29 #include "b53_priv.h"
30
31 /* buffer size needed for displaying all MIBs with max'd values */
32 #define B53_BUF_SIZE    1188
33
34 struct b53_mib_desc {
35         u8 size;
36         u8 offset;
37         const char *name;
38 };
39
40
41 /* BCM5365 MIB counters */
42 static const struct b53_mib_desc b53_mibs_65[] = {
43         { 8, 0x00, "TxOctets" },
44         { 4, 0x08, "TxDropPkts" },
45         { 4, 0x10, "TxBroadcastPkts" },
46         { 4, 0x14, "TxMulticastPkts" },
47         { 4, 0x18, "TxUnicastPkts" },
48         { 4, 0x1c, "TxCollisions" },
49         { 4, 0x20, "TxSingleCollision" },
50         { 4, 0x24, "TxMultipleCollision" },
51         { 4, 0x28, "TxDeferredTransmit" },
52         { 4, 0x2c, "TxLateCollision" },
53         { 4, 0x30, "TxExcessiveCollision" },
54         { 4, 0x38, "TxPausePkts" },
55         { 8, 0x44, "RxOctets" },
56         { 4, 0x4c, "RxUndersizePkts" },
57         { 4, 0x50, "RxPausePkts" },
58         { 4, 0x54, "Pkts64Octets" },
59         { 4, 0x58, "Pkts65to127Octets" },
60         { 4, 0x5c, "Pkts128to255Octets" },
61         { 4, 0x60, "Pkts256to511Octets" },
62         { 4, 0x64, "Pkts512to1023Octets" },
63         { 4, 0x68, "Pkts1024to1522Octets" },
64         { 4, 0x6c, "RxOversizePkts" },
65         { 4, 0x70, "RxJabbers" },
66         { 4, 0x74, "RxAlignmentErrors" },
67         { 4, 0x78, "RxFCSErrors" },
68         { 8, 0x7c, "RxGoodOctets" },
69         { 4, 0x84, "RxDropPkts" },
70         { 4, 0x88, "RxUnicastPkts" },
71         { 4, 0x8c, "RxMulticastPkts" },
72         { 4, 0x90, "RxBroadcastPkts" },
73         { 4, 0x94, "RxSAChanges" },
74         { 4, 0x98, "RxFragments" },
75         { },
76 };
77
78 /* BCM63xx MIB counters */
79 static const struct b53_mib_desc b53_mibs_63xx[] = {
80         { 8, 0x00, "TxOctets" },
81         { 4, 0x08, "TxDropPkts" },
82         { 4, 0x0c, "TxQoSPkts" },
83         { 4, 0x10, "TxBroadcastPkts" },
84         { 4, 0x14, "TxMulticastPkts" },
85         { 4, 0x18, "TxUnicastPkts" },
86         { 4, 0x1c, "TxCollisions" },
87         { 4, 0x20, "TxSingleCollision" },
88         { 4, 0x24, "TxMultipleCollision" },
89         { 4, 0x28, "TxDeferredTransmit" },
90         { 4, 0x2c, "TxLateCollision" },
91         { 4, 0x30, "TxExcessiveCollision" },
92         { 4, 0x38, "TxPausePkts" },
93         { 8, 0x3c, "TxQoSOctets" },
94         { 8, 0x44, "RxOctets" },
95         { 4, 0x4c, "RxUndersizePkts" },
96         { 4, 0x50, "RxPausePkts" },
97         { 4, 0x54, "Pkts64Octets" },
98         { 4, 0x58, "Pkts65to127Octets" },
99         { 4, 0x5c, "Pkts128to255Octets" },
100         { 4, 0x60, "Pkts256to511Octets" },
101         { 4, 0x64, "Pkts512to1023Octets" },
102         { 4, 0x68, "Pkts1024to1522Octets" },
103         { 4, 0x6c, "RxOversizePkts" },
104         { 4, 0x70, "RxJabbers" },
105         { 4, 0x74, "RxAlignmentErrors" },
106         { 4, 0x78, "RxFCSErrors" },
107         { 8, 0x7c, "RxGoodOctets" },
108         { 4, 0x84, "RxDropPkts" },
109         { 4, 0x88, "RxUnicastPkts" },
110         { 4, 0x8c, "RxMulticastPkts" },
111         { 4, 0x90, "RxBroadcastPkts" },
112         { 4, 0x94, "RxSAChanges" },
113         { 4, 0x98, "RxFragments" },
114         { 4, 0xa0, "RxSymbolErrors" },
115         { 4, 0xa4, "RxQoSPkts" },
116         { 8, 0xa8, "RxQoSOctets" },
117         { 4, 0xb0, "Pkts1523to2047Octets" },
118         { 4, 0xb4, "Pkts2048to4095Octets" },
119         { 4, 0xb8, "Pkts4096to8191Octets" },
120         { 4, 0xbc, "Pkts8192to9728Octets" },
121         { 4, 0xc0, "RxDiscarded" },
122         { }
123 };
124
125 /* MIB counters */
126 static const struct b53_mib_desc b53_mibs[] = {
127         { 8, 0x00, "TxOctets" },
128         { 4, 0x08, "TxDropPkts" },
129         { 4, 0x10, "TxBroadcastPkts" },
130         { 4, 0x14, "TxMulticastPkts" },
131         { 4, 0x18, "TxUnicastPkts" },
132         { 4, 0x1c, "TxCollisions" },
133         { 4, 0x20, "TxSingleCollision" },
134         { 4, 0x24, "TxMultipleCollision" },
135         { 4, 0x28, "TxDeferredTransmit" },
136         { 4, 0x2c, "TxLateCollision" },
137         { 4, 0x30, "TxExcessiveCollision" },
138         { 4, 0x38, "TxPausePkts" },
139         { 8, 0x50, "RxOctets" },
140         { 4, 0x58, "RxUndersizePkts" },
141         { 4, 0x5c, "RxPausePkts" },
142         { 4, 0x60, "Pkts64Octets" },
143         { 4, 0x64, "Pkts65to127Octets" },
144         { 4, 0x68, "Pkts128to255Octets" },
145         { 4, 0x6c, "Pkts256to511Octets" },
146         { 4, 0x70, "Pkts512to1023Octets" },
147         { 4, 0x74, "Pkts1024to1522Octets" },
148         { 4, 0x78, "RxOversizePkts" },
149         { 4, 0x7c, "RxJabbers" },
150         { 4, 0x80, "RxAlignmentErrors" },
151         { 4, 0x84, "RxFCSErrors" },
152         { 8, 0x88, "RxGoodOctets" },
153         { 4, 0x90, "RxDropPkts" },
154         { 4, 0x94, "RxUnicastPkts" },
155         { 4, 0x98, "RxMulticastPkts" },
156         { 4, 0x9c, "RxBroadcastPkts" },
157         { 4, 0xa0, "RxSAChanges" },
158         { 4, 0xa4, "RxFragments" },
159         { 4, 0xa8, "RxJumboPkts" },
160         { 4, 0xac, "RxSymbolErrors" },
161         { 4, 0xc0, "RxDiscarded" },
162         { }
163 };
164
165 static int b53_do_vlan_op(struct b53_device *dev, u8 op)
166 {
167         unsigned int i;
168
169         b53_write8(dev, B53_ARLIO_PAGE, dev->vta_regs[0], VTA_START_CMD | op);
170
171         for (i = 0; i < 10; i++) {
172                 u8 vta;
173
174                 b53_read8(dev, B53_ARLIO_PAGE, dev->vta_regs[0], &vta);
175                 if (!(vta & VTA_START_CMD))
176                         return 0;
177
178                 usleep_range(100, 200);
179         }
180
181         return -EIO;
182 }
183
184 static void b53_set_vlan_entry(struct b53_device *dev, u16 vid, u16 members,
185                                u16 untag)
186 {
187         if (is5325(dev)) {
188                 u32 entry = 0;
189
190                 if (members)
191                         entry = (untag << VA_UNTAG_S) | members | VA_VALID_25;
192
193                 b53_write32(dev, B53_VLAN_PAGE, B53_VLAN_WRITE_25, entry);
194                 b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_TABLE_ACCESS_25, vid |
195                             VTA_RW_STATE_WR | VTA_RW_OP_EN);
196         } else if (is5365(dev)) {
197                 u16 entry = 0;
198
199                 if (members)
200                         entry = (untag << VA_UNTAG_S) | members | VA_VALID_65;
201
202                 b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_WRITE_65, entry);
203                 b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_TABLE_ACCESS_65, vid |
204                             VTA_RW_STATE_WR | VTA_RW_OP_EN);
205         } else {
206                 b53_write16(dev, B53_ARLIO_PAGE, dev->vta_regs[1], vid);
207                 b53_write32(dev, B53_ARLIO_PAGE, dev->vta_regs[2],
208                             (untag << VTE_UNTAG_S) | members);
209
210                 b53_do_vlan_op(dev, VTA_CMD_WRITE);
211         }
212 }
213
214 void b53_set_forwarding(struct b53_device *dev, int enable)
215 {
216         u8 mgmt;
217
218         b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, &mgmt);
219
220         if (enable)
221                 mgmt |= SM_SW_FWD_EN;
222         else
223                 mgmt &= ~SM_SW_FWD_EN;
224
225         b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, mgmt);
226 }
227
228 static void b53_enable_vlan(struct b53_device *dev, int enable)
229 {
230         u8 mgmt, vc0, vc1, vc4 = 0, vc5;
231
232         b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, &mgmt);
233         b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL0, &vc0);
234         b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL1, &vc1);
235
236         if (is5325(dev) || is5365(dev)) {
237                 b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL4_25, &vc4);
238                 b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL5_25, &vc5);
239         } else if (is63xx(dev)) {
240                 b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL4_63XX, &vc4);
241                 b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL5_63XX, &vc5);
242         } else {
243                 b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL4, &vc4);
244                 b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL5, &vc5);
245         }
246
247         mgmt &= ~SM_SW_FWD_MODE;
248
249         if (enable) {
250                 vc0 |= VC0_VLAN_EN | VC0_VID_CHK_EN | VC0_VID_HASH_VID;
251                 vc1 |= VC1_RX_MCST_UNTAG_EN | VC1_RX_MCST_FWD_EN;
252                 vc4 &= ~VC4_ING_VID_CHECK_MASK;
253                 vc4 |= VC4_ING_VID_VIO_DROP << VC4_ING_VID_CHECK_S;
254                 vc5 |= VC5_DROP_VTABLE_MISS;
255
256                 if (is5325(dev))
257                         vc0 &= ~VC0_RESERVED_1;
258
259                 if (is5325(dev) || is5365(dev))
260                         vc1 |= VC1_RX_MCST_TAG_EN;
261
262                 if (!is5325(dev) && !is5365(dev)) {
263                         if (dev->allow_vid_4095)
264                                 vc5 |= VC5_VID_FFF_EN;
265                         else
266                                 vc5 &= ~VC5_VID_FFF_EN;
267                 }
268         } else {
269                 vc0 &= ~(VC0_VLAN_EN | VC0_VID_CHK_EN | VC0_VID_HASH_VID);
270                 vc1 &= ~(VC1_RX_MCST_UNTAG_EN | VC1_RX_MCST_FWD_EN);
271                 vc4 &= ~VC4_ING_VID_CHECK_MASK;
272                 vc5 &= ~VC5_DROP_VTABLE_MISS;
273
274                 if (is5325(dev) || is5365(dev))
275                         vc4 |= VC4_ING_VID_VIO_FWD << VC4_ING_VID_CHECK_S;
276                 else
277                         vc4 |= VC4_ING_VID_VIO_TO_IMP << VC4_ING_VID_CHECK_S;
278
279                 if (is5325(dev) || is5365(dev))
280                         vc1 &= ~VC1_RX_MCST_TAG_EN;
281
282                 if (!is5325(dev) && !is5365(dev))
283                         vc5 &= ~VC5_VID_FFF_EN;
284         }
285
286         b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL0, vc0);
287         b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL1, vc1);
288
289         if (is5325(dev) || is5365(dev)) {
290                 /* enable the high 8 bit vid check on 5325 */
291                 if (is5325(dev) && enable)
292                         b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL3,
293                                    VC3_HIGH_8BIT_EN);
294                 else
295                         b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL3, 0);
296
297                 b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL4_25, vc4);
298                 b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL5_25, vc5);
299         } else if (is63xx(dev)) {
300                 b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_CTRL3_63XX, 0);
301                 b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL4_63XX, vc4);
302                 b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL5_63XX, vc5);
303         } else {
304                 b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_CTRL3, 0);
305                 b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL4, vc4);
306                 b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL5, vc5);
307         }
308
309         b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, mgmt);
310 }
311
312 static int b53_set_jumbo(struct b53_device *dev, int enable, int allow_10_100)
313 {
314         u32 port_mask = 0;
315         u16 max_size = JMS_MIN_SIZE;
316
317         if (is5325(dev) || is5365(dev))
318                 return -EINVAL;
319
320         if (enable) {
321                 port_mask = dev->enabled_ports;
322                 max_size = JMS_MAX_SIZE;
323                 if (allow_10_100)
324                         port_mask |= JPM_10_100_JUMBO_EN;
325         }
326
327         b53_write32(dev, B53_JUMBO_PAGE, dev->jumbo_pm_reg, port_mask);
328         return b53_write16(dev, B53_JUMBO_PAGE, dev->jumbo_size_reg, max_size);
329 }
330
331 static int b53_flush_arl(struct b53_device *dev)
332 {
333         unsigned int i;
334
335         b53_write8(dev, B53_CTRL_PAGE, B53_FAST_AGE_CTRL,
336                    FAST_AGE_DONE | FAST_AGE_DYNAMIC | FAST_AGE_STATIC);
337
338         for (i = 0; i < 10; i++) {
339                 u8 fast_age_ctrl;
340
341                 b53_read8(dev, B53_CTRL_PAGE, B53_FAST_AGE_CTRL,
342                           &fast_age_ctrl);
343
344                 if (!(fast_age_ctrl & FAST_AGE_DONE))
345                         return 0;
346
347                 mdelay(1);
348         }
349
350         pr_warn("time out while flushing ARL\n");
351
352         return -EINVAL;
353 }
354
355 static void b53_enable_ports(struct b53_device *dev)
356 {
357         unsigned i;
358
359         b53_for_each_port(dev, i) {
360                 u8 port_ctrl;
361                 u16 pvlan_mask;
362
363                 /*
364                  * prevent leaking packets between wan and lan in unmanaged
365                  * mode through port vlans.
366                  */
367                 if (dev->enable_vlan || is_cpu_port(dev, i))
368                         pvlan_mask = 0x1ff;
369                 else if (is531x5(dev))
370                         /* BCM53115 may use a different port as cpu port */
371                         pvlan_mask = BIT(dev->sw_dev.cpu_port);
372                 else
373                         pvlan_mask = BIT(B53_CPU_PORT);
374
375                 /* BCM5325 CPU port is at 8 */
376                 if ((is5325(dev) || is5365(dev)) && i == B53_CPU_PORT_25)
377                         i = B53_CPU_PORT;
378
379                 if (dev->chip_id == BCM5398_DEVICE_ID && (i == 6 || i == 7))
380                         /* disable unused ports 6 & 7 */
381                         port_ctrl = PORT_CTRL_RX_DISABLE | PORT_CTRL_TX_DISABLE;
382                 else if (i == B53_CPU_PORT)
383                         port_ctrl = PORT_CTRL_RX_BCST_EN |
384                                     PORT_CTRL_RX_MCST_EN |
385                                     PORT_CTRL_RX_UCST_EN;
386                 else
387                         port_ctrl = 0;
388
389                 b53_write16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(i),
390                             pvlan_mask);
391
392                 /* port state is handled by bcm63xx_enet driver */
393                 if (!is63xx(dev))
394                         b53_write8(dev, B53_CTRL_PAGE, B53_PORT_CTRL(i),
395                                    port_ctrl);
396         }
397 }
398
399 static void b53_enable_mib(struct b53_device *dev)
400 {
401         u8 gc;
402
403         b53_read8(dev, B53_CTRL_PAGE, B53_GLOBAL_CONFIG, &gc);
404
405         gc &= ~(GC_RESET_MIB | GC_MIB_AC_EN);
406
407         b53_write8(dev, B53_CTRL_PAGE, B53_GLOBAL_CONFIG, gc);
408 }
409
410 static int b53_apply(struct b53_device *dev)
411 {
412         int i;
413
414         /* clear all vlan entries */
415         if (is5325(dev) || is5365(dev)) {
416                 for (i = 1; i < dev->sw_dev.vlans; i++)
417                         b53_set_vlan_entry(dev, i, 0, 0);
418         } else {
419                 b53_do_vlan_op(dev, VTA_CMD_CLEAR);
420         }
421
422         b53_enable_vlan(dev, dev->enable_vlan);
423
424         /* fill VLAN table */
425         if (dev->enable_vlan) {
426                 for (i = 0; i < dev->sw_dev.vlans; i++) {
427                         struct b53_vlan *vlan = &dev->vlans[i];
428
429                         if (!vlan->members)
430                                 continue;
431
432                         b53_set_vlan_entry(dev, i, vlan->members, vlan->untag);
433                 }
434
435                 b53_for_each_port(dev, i)
436                         b53_write16(dev, B53_VLAN_PAGE,
437                                     B53_VLAN_PORT_DEF_TAG(i),
438                                     dev->ports[i].pvid);
439         } else {
440                 b53_for_each_port(dev, i)
441                         b53_write16(dev, B53_VLAN_PAGE,
442                                     B53_VLAN_PORT_DEF_TAG(i), 1);
443
444         }
445
446         b53_enable_ports(dev);
447
448         if (!is5325(dev) && !is5365(dev))
449                 b53_set_jumbo(dev, dev->enable_jumbo, 1);
450
451         return 0;
452 }
453
454 static int b53_switch_reset(struct b53_device *dev)
455 {
456         u8 mgmt;
457
458         b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, &mgmt);
459
460         if (!(mgmt & SM_SW_FWD_EN)) {
461                 mgmt &= ~SM_SW_FWD_MODE;
462                 mgmt |= SM_SW_FWD_EN;
463
464                 b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, mgmt);
465                 b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, &mgmt);
466
467                 if (!(mgmt & SM_SW_FWD_EN)) {
468                         pr_err("Failed to enable switch!\n");
469                         return -EINVAL;
470                 }
471         }
472
473         /* enable all ports */
474         b53_enable_ports(dev);
475
476         /* configure MII port if necessary */
477         if (is5325(dev)) {
478                 u8 mii_port_override;
479
480                 b53_read8(dev, B53_CTRL_PAGE, B53_PORT_OVERRIDE_CTRL,
481                           &mii_port_override);
482                 /* reverse mii needs to be enabled */
483                 if (!(mii_port_override & PORT_OVERRIDE_RV_MII_25)) {
484                         b53_write8(dev, B53_CTRL_PAGE, B53_PORT_OVERRIDE_CTRL,
485                                    mii_port_override | PORT_OVERRIDE_RV_MII_25);
486                         b53_read8(dev, B53_CTRL_PAGE, B53_PORT_OVERRIDE_CTRL,
487                                   &mii_port_override);
488
489                         if (!(mii_port_override & PORT_OVERRIDE_RV_MII_25)) {
490                                 pr_err("Failed to enable reverse MII mode\n");
491                                 return -EINVAL;
492                         }
493                 }
494         } else if (is531x5(dev) && dev->sw_dev.cpu_port == B53_CPU_PORT) {
495                 u8 mii_port_override;
496
497                 b53_read8(dev, B53_CTRL_PAGE, B53_PORT_OVERRIDE_CTRL,
498                           &mii_port_override);
499                 b53_write8(dev, B53_CTRL_PAGE, B53_PORT_OVERRIDE_CTRL,
500                            mii_port_override | PORT_OVERRIDE_EN |
501                            PORT_OVERRIDE_LINK);
502         }
503
504         b53_enable_mib(dev);
505
506         return b53_flush_arl(dev);
507 }
508
509 /*
510  * Swconfig glue functions
511  */
512
513 static int b53_global_get_vlan_enable(struct switch_dev *dev,
514                                       const struct switch_attr *attr,
515                                       struct switch_val *val)
516 {
517         struct b53_device *priv = sw_to_b53(dev);
518
519         val->value.i = priv->enable_vlan;
520
521         return 0;
522 }
523
524 static int b53_global_set_vlan_enable(struct switch_dev *dev,
525                                       const struct switch_attr *attr,
526                                       struct switch_val *val)
527 {
528         struct b53_device *priv = sw_to_b53(dev);
529
530         priv->enable_vlan = val->value.i;
531
532         return 0;
533 }
534
535 static int b53_global_get_jumbo_enable(struct switch_dev *dev,
536                                        const struct switch_attr *attr,
537                                        struct switch_val *val)
538 {
539         struct b53_device *priv = sw_to_b53(dev);
540
541         val->value.i = priv->enable_jumbo;
542
543         return 0;
544 }
545
546 static int b53_global_set_jumbo_enable(struct switch_dev *dev,
547                                        const struct switch_attr *attr,
548                                        struct switch_val *val)
549 {
550         struct b53_device *priv = sw_to_b53(dev);
551
552         priv->enable_jumbo = val->value.i;
553
554         return 0;
555 }
556
557 static int b53_global_get_4095_enable(struct switch_dev *dev,
558                                       const struct switch_attr *attr,
559                                       struct switch_val *val)
560 {
561         struct b53_device *priv = sw_to_b53(dev);
562
563         val->value.i = priv->allow_vid_4095;
564
565         return 0;
566 }
567
568 static int b53_global_set_4095_enable(struct switch_dev *dev,
569                                       const struct switch_attr *attr,
570                                       struct switch_val *val)
571 {
572         struct b53_device *priv = sw_to_b53(dev);
573
574         priv->allow_vid_4095 = val->value.i;
575
576         return 0;
577 }
578
579 static int b53_global_get_ports(struct switch_dev *dev,
580                                 const struct switch_attr *attr,
581                                 struct switch_val *val)
582 {
583         struct b53_device *priv = sw_to_b53(dev);
584
585         val->len = snprintf(priv->buf, B53_BUF_SIZE, "0x%04x",
586                             priv->enabled_ports);
587         val->value.s = priv->buf;
588
589         return 0;
590 }
591
592 static int b53_port_get_pvid(struct switch_dev *dev, int port, int *val)
593 {
594         struct b53_device *priv = sw_to_b53(dev);
595
596         *val = priv->ports[port].pvid;
597
598         return 0;
599 }
600
601 static int b53_port_set_pvid(struct switch_dev *dev, int port, int val)
602 {
603         struct b53_device *priv = sw_to_b53(dev);
604
605         if (val > 15 && is5325(priv))
606                 return -EINVAL;
607         if (val == 4095 && !priv->allow_vid_4095)
608                 return -EINVAL;
609
610         priv->ports[port].pvid = val;
611
612         return 0;
613 }
614
615 static int b53_vlan_get_ports(struct switch_dev *dev, struct switch_val *val)
616 {
617         struct b53_device *priv = sw_to_b53(dev);
618         struct switch_port *port = &val->value.ports[0];
619         struct b53_vlan *vlan = &priv->vlans[val->port_vlan];
620         int i;
621
622         val->len = 0;
623
624         if (!vlan->members)
625                 return 0;
626
627         for (i = 0; i < dev->ports; i++) {
628                 if (!(vlan->members & BIT(i)))
629                         continue;
630
631
632                 if (!(vlan->untag & BIT(i)))
633                         port->flags = BIT(SWITCH_PORT_FLAG_TAGGED);
634                 else
635                         port->flags = 0;
636
637                 port->id = i;
638                 val->len++;
639                 port++;
640         }
641
642         return 0;
643 }
644
645 static int b53_vlan_set_ports(struct switch_dev *dev, struct switch_val *val)
646 {
647         struct b53_device *priv = sw_to_b53(dev);
648         struct switch_port *port;
649         struct b53_vlan *vlan = &priv->vlans[val->port_vlan];
650         int i;
651
652         /* only BCM5325 and BCM5365 supports VID 0 */
653         if (val->port_vlan == 0 && !is5325(priv) && !is5365(priv))
654                 return -EINVAL;
655
656         /* VLAN 4095 needs special handling */
657         if (val->port_vlan == 4095 && !priv->allow_vid_4095)
658                 return -EINVAL;
659
660         port = &val->value.ports[0];
661         vlan->members = 0;
662         vlan->untag = 0;
663         for (i = 0; i < val->len; i++, port++) {
664                 vlan->members |= BIT(port->id);
665
666                 if (!(port->flags & BIT(SWITCH_PORT_FLAG_TAGGED))) {
667                         vlan->untag |= BIT(port->id);
668                         priv->ports[port->id].pvid = val->port_vlan;
669                 };
670         }
671
672         /* ignore disabled ports */
673         vlan->members &= priv->enabled_ports;
674         vlan->untag &= priv->enabled_ports;
675
676         return 0;
677 }
678
679 static int b53_port_get_link(struct switch_dev *dev, int port,
680                              struct switch_port_link *link)
681 {
682         struct b53_device *priv = sw_to_b53(dev);
683
684         if (is_cpu_port(priv, port)) {
685                 link->link = 1;
686                 link->duplex = 1;
687                 link->speed = is5325(priv) || is5365(priv) ?
688                                 SWITCH_PORT_SPEED_100 : SWITCH_PORT_SPEED_1000;
689                 link->aneg = 0;
690         } else if (priv->enabled_ports & BIT(port)) {
691                 u32 speed;
692                 u16 lnk, duplex;
693
694                 b53_read16(priv, B53_STAT_PAGE, B53_LINK_STAT, &lnk);
695                 b53_read16(priv, B53_STAT_PAGE, priv->duplex_reg, &duplex);
696
697                 lnk = (lnk >> port) & 1;
698                 duplex = (duplex >> port) & 1;
699
700                 if (is5325(priv) || is5365(priv)) {
701                         u16 tmp;
702
703                         b53_read16(priv, B53_STAT_PAGE, B53_SPEED_STAT, &tmp);
704                         speed = SPEED_PORT_FE(tmp, port);
705                 } else {
706                         b53_read32(priv, B53_STAT_PAGE, B53_SPEED_STAT, &speed);
707                         speed = SPEED_PORT_GE(speed, port);
708                 }
709
710                 link->link = lnk;
711                 if (lnk) {
712                         link->duplex = duplex;
713                         switch (speed) {
714                         case SPEED_STAT_10M:
715                                 link->speed = SWITCH_PORT_SPEED_10;
716                                 break;
717                         case SPEED_STAT_100M:
718                                 link->speed = SWITCH_PORT_SPEED_100;
719                                 break;
720                         case SPEED_STAT_1000M:
721                                 link->speed = SWITCH_PORT_SPEED_1000;
722                                 break;
723                         }
724                 }
725
726                 link->aneg = 1;
727         } else {
728                 link->link = 0;
729         }
730
731         return 0;
732
733 }
734
735 static int b53_global_reset_switch(struct switch_dev *dev)
736 {
737         struct b53_device *priv = sw_to_b53(dev);
738
739         /* reset vlans */
740         priv->enable_vlan = 0;
741         priv->enable_jumbo = 0;
742         priv->allow_vid_4095 = 0;
743
744         memset(priv->vlans, 0, sizeof(priv->vlans) * dev->vlans);
745         memset(priv->ports, 0, sizeof(priv->ports) * dev->ports);
746
747         return b53_switch_reset(priv);
748 }
749
750 static int b53_global_apply_config(struct switch_dev *dev)
751 {
752         struct b53_device *priv = sw_to_b53(dev);
753
754         /* disable switching */
755         b53_set_forwarding(priv, 0);
756
757         b53_apply(priv);
758
759         /* enable switching */
760         b53_set_forwarding(priv, 1);
761
762         return 0;
763 }
764
765
766 static int b53_global_reset_mib(struct switch_dev *dev,
767                                 const struct switch_attr *attr,
768                                 struct switch_val *val)
769 {
770         struct b53_device *priv = sw_to_b53(dev);
771         u8 gc;
772
773         b53_read8(priv, B53_MGMT_PAGE, B53_GLOBAL_CONFIG, &gc);
774
775         b53_write8(priv, B53_MGMT_PAGE, B53_GLOBAL_CONFIG, gc | GC_RESET_MIB);
776         mdelay(1);
777         b53_write8(priv, B53_MGMT_PAGE, B53_GLOBAL_CONFIG, gc & ~GC_RESET_MIB);
778         mdelay(1);
779
780         return 0;
781 }
782
783 static int b53_port_get_mib(struct switch_dev *sw_dev,
784                             const struct switch_attr *attr,
785                             struct switch_val *val)
786 {
787         struct b53_device *dev = sw_to_b53(sw_dev);
788         const struct b53_mib_desc *mibs;
789         int port = val->port_vlan;
790         int len = 0;
791
792         if (!(BIT(port) & dev->enabled_ports))
793                 return -1;
794
795         if (is5365(dev)) {
796                 if (port == 5)
797                         port = 8;
798
799                 mibs = b53_mibs_65;
800         } else if (is63xx(dev)) {
801                 mibs = b53_mibs_63xx;
802         } else {
803                 mibs = b53_mibs;
804         }
805
806         dev->buf[0] = 0;
807
808         for (; mibs->size > 0; mibs++) {
809                 u64 val;
810
811                 if (mibs->size == 8) {
812                         b53_read64(dev, B53_MIB_PAGE(port), mibs->offset, &val);
813                 } else {
814                         u32 val32;
815
816                         b53_read32(dev, B53_MIB_PAGE(port), mibs->offset,
817                                    &val32);
818                         val = val32;
819                 }
820
821                 len += snprintf(dev->buf + len, B53_BUF_SIZE - len,
822                                 "%-20s: %llu\n", mibs->name, val);
823         }
824
825         val->len = len;
826         val->value.s = dev->buf;
827
828         return 0;
829 }
830
831 static struct switch_attr b53_global_ops_25[] = {
832         {
833                 .type = SWITCH_TYPE_INT,
834                 .name = "enable_vlan",
835                 .description = "Enable VLAN mode",
836                 .set = b53_global_set_vlan_enable,
837                 .get = b53_global_get_vlan_enable,
838                 .max = 1,
839         },
840         {
841                 .type = SWITCH_TYPE_STRING,
842                 .name = "ports",
843                 .description = "Available ports (as bitmask)",
844                 .get = b53_global_get_ports,
845         },
846 };
847
848 static struct switch_attr b53_global_ops_65[] = {
849         {
850                 .type = SWITCH_TYPE_INT,
851                 .name = "enable_vlan",
852                 .description = "Enable VLAN mode",
853                 .set = b53_global_set_vlan_enable,
854                 .get = b53_global_get_vlan_enable,
855                 .max = 1,
856         },
857         {
858                 .type = SWITCH_TYPE_STRING,
859                 .name = "ports",
860                 .description = "Available ports (as bitmask)",
861                 .get = b53_global_get_ports,
862         },
863         {
864                 .type = SWITCH_TYPE_INT,
865                 .name = "reset_mib",
866                 .description = "Reset MIB counters",
867                 .set = b53_global_reset_mib,
868         },
869 };
870
871 static struct switch_attr b53_global_ops[] = {
872         {
873                 .type = SWITCH_TYPE_INT,
874                 .name = "enable_vlan",
875                 .description = "Enable VLAN mode",
876                 .set = b53_global_set_vlan_enable,
877                 .get = b53_global_get_vlan_enable,
878                 .max = 1,
879         },
880         {
881                 .type = SWITCH_TYPE_STRING,
882                 .name = "ports",
883                 .description = "Available Ports (as bitmask)",
884                 .get = b53_global_get_ports,
885         },
886         {
887                 .type = SWITCH_TYPE_INT,
888                 .name = "reset_mib",
889                 .description = "Reset MIB counters",
890                 .set = b53_global_reset_mib,
891         },
892         {
893                 .type = SWITCH_TYPE_INT,
894                 .name = "enable_jumbo",
895                 .description = "Enable Jumbo Frames",
896                 .set = b53_global_set_jumbo_enable,
897                 .get = b53_global_get_jumbo_enable,
898                 .max = 1,
899         },
900         {
901                 .type = SWITCH_TYPE_INT,
902                 .name = "allow_vid_4095",
903                 .description = "Allow VID 4095",
904                 .set = b53_global_set_4095_enable,
905                 .get = b53_global_get_4095_enable,
906                 .max = 1,
907         },
908 };
909
910 static struct switch_attr b53_port_ops[] = {
911         {
912                 .type = SWITCH_TYPE_STRING,
913                 .name = "mib",
914                 .description = "Get port's MIB counters",
915                 .get = b53_port_get_mib,
916         },
917 };
918
919 static struct switch_attr b53_no_ops[] = {
920 };
921
922 static const struct switch_dev_ops b53_switch_ops_25 = {
923         .attr_global = {
924                 .attr = b53_global_ops_25,
925                 .n_attr = ARRAY_SIZE(b53_global_ops_25),
926         },
927         .attr_port = {
928                 .attr = b53_no_ops,
929                 .n_attr = ARRAY_SIZE(b53_no_ops),
930         },
931         .attr_vlan = {
932                 .attr = b53_no_ops,
933                 .n_attr = ARRAY_SIZE(b53_no_ops),
934         },
935
936         .get_vlan_ports = b53_vlan_get_ports,
937         .set_vlan_ports = b53_vlan_set_ports,
938         .get_port_pvid = b53_port_get_pvid,
939         .set_port_pvid = b53_port_set_pvid,
940         .apply_config = b53_global_apply_config,
941         .reset_switch = b53_global_reset_switch,
942         .get_port_link = b53_port_get_link,
943 };
944
945 static const struct switch_dev_ops b53_switch_ops_65 = {
946         .attr_global = {
947                 .attr = b53_global_ops_25,
948                 .n_attr = ARRAY_SIZE(b53_global_ops_65),
949         },
950         .attr_port = {
951                 .attr = b53_no_ops,
952                 .n_attr = ARRAY_SIZE(b53_port_ops),
953         },
954         .attr_vlan = {
955                 .attr = b53_no_ops,
956                 .n_attr = ARRAY_SIZE(b53_no_ops),
957         },
958
959         .get_vlan_ports = b53_vlan_get_ports,
960         .set_vlan_ports = b53_vlan_set_ports,
961         .get_port_pvid = b53_port_get_pvid,
962         .set_port_pvid = b53_port_set_pvid,
963         .apply_config = b53_global_apply_config,
964         .reset_switch = b53_global_reset_switch,
965         .get_port_link = b53_port_get_link,
966 };
967
968 static const struct switch_dev_ops b53_switch_ops = {
969         .attr_global = {
970                 .attr = b53_global_ops,
971                 .n_attr = ARRAY_SIZE(b53_global_ops),
972         },
973         .attr_port = {
974                 .attr = b53_port_ops,
975                 .n_attr = ARRAY_SIZE(b53_port_ops),
976         },
977         .attr_vlan = {
978                 .attr = b53_no_ops,
979                 .n_attr = ARRAY_SIZE(b53_no_ops),
980         },
981
982         .get_vlan_ports = b53_vlan_get_ports,
983         .set_vlan_ports = b53_vlan_set_ports,
984         .get_port_pvid = b53_port_get_pvid,
985         .set_port_pvid = b53_port_set_pvid,
986         .apply_config = b53_global_apply_config,
987         .reset_switch = b53_global_reset_switch,
988         .get_port_link = b53_port_get_link,
989 };
990
991 struct b53_chip_data {
992         u32 chip_id;
993         const char *dev_name;
994         const char *alias;
995         u16 vlans;
996         u16 enabled_ports;
997         u8 cpu_port;
998         u8 vta_regs[3];
999         u8 duplex_reg;
1000         u8 jumbo_pm_reg;
1001         u8 jumbo_size_reg;
1002         const struct switch_dev_ops *sw_ops;
1003 };
1004
1005 #define B53_VTA_REGS    \
1006         { B53_VT_ACCESS, B53_VT_INDEX, B53_VT_ENTRY }
1007 #define B53_VTA_REGS_9798 \
1008         { B53_VT_ACCESS_9798, B53_VT_INDEX_9798, B53_VT_ENTRY_9798 }
1009 #define B53_VTA_REGS_63XX \
1010         { B53_VT_ACCESS_63XX, B53_VT_INDEX_63XX, B53_VT_ENTRY_63XX }
1011
1012 static const struct b53_chip_data b53_switch_chips[] = {
1013         {
1014                 .chip_id = BCM5325_DEVICE_ID,
1015                 .dev_name = "BCM5325",
1016                 .alias = "bcm5325",
1017                 .vlans = 16,
1018                 .enabled_ports = 0x1f,
1019                 .cpu_port = B53_CPU_PORT_25,
1020                 .duplex_reg = B53_DUPLEX_STAT_FE,
1021                 .sw_ops = &b53_switch_ops_25,
1022         },
1023         {
1024                 .chip_id = BCM5365_DEVICE_ID,
1025                 .dev_name = "BCM5365",
1026                 .alias = "bcm5365",
1027                 .vlans = 256,
1028                 .enabled_ports = 0x1f,
1029                 .cpu_port = B53_CPU_PORT_25,
1030                 .duplex_reg = B53_DUPLEX_STAT_FE,
1031                 .sw_ops = &b53_switch_ops_65,
1032         },
1033         {
1034                 .chip_id = BCM5395_DEVICE_ID,
1035                 .dev_name = "BCM5395",
1036                 .alias = "bcm5395",
1037                 .vlans = 4096,
1038                 .enabled_ports = 0x1f,
1039                 .cpu_port = B53_CPU_PORT,
1040                 .vta_regs = B53_VTA_REGS,
1041                 .duplex_reg = B53_DUPLEX_STAT_GE,
1042                 .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
1043                 .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
1044                 .sw_ops = &b53_switch_ops,
1045         },
1046         {
1047                 .chip_id = BCM5397_DEVICE_ID,
1048                 .dev_name = "BCM5397",
1049                 .alias = "bcm5397",
1050                 .vlans = 4096,
1051                 .enabled_ports = 0x1f,
1052                 .cpu_port = B53_CPU_PORT,
1053                 .vta_regs = B53_VTA_REGS_9798,
1054                 .duplex_reg = B53_DUPLEX_STAT_GE,
1055                 .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
1056                 .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
1057                 .sw_ops = &b53_switch_ops,
1058         },
1059         {
1060                 .chip_id = BCM5398_DEVICE_ID,
1061                 .dev_name = "BCM5398",
1062                 .alias = "bcm5398",
1063                 .vlans = 4096,
1064                 .enabled_ports = 0x7f,
1065                 .cpu_port = B53_CPU_PORT,
1066                 .vta_regs = B53_VTA_REGS_9798,
1067                 .duplex_reg = B53_DUPLEX_STAT_GE,
1068                 .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
1069                 .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
1070                 .sw_ops = &b53_switch_ops,
1071         },
1072         {
1073                 .chip_id = BCM53115_DEVICE_ID,
1074                 .dev_name = "BCM53115",
1075                 .alias = "bcm53115",
1076                 .vlans = 4096,
1077                 .enabled_ports = 0x1f,
1078                 .vta_regs = B53_VTA_REGS,
1079                 .cpu_port = B53_CPU_PORT,
1080                 .duplex_reg = B53_DUPLEX_STAT_GE,
1081                 .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
1082                 .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
1083                 .sw_ops = &b53_switch_ops,
1084         },
1085         {
1086                 .chip_id = BCM53125_DEVICE_ID,
1087                 .dev_name = "BCM53125",
1088                 .alias = "bcm53125",
1089                 .vlans = 4096,
1090                 .enabled_ports = 0x1f,
1091                 .cpu_port = B53_CPU_PORT,
1092                 .vta_regs = B53_VTA_REGS,
1093                 .duplex_reg = B53_DUPLEX_STAT_GE,
1094                 .jumbo_pm_reg = B53_JUMBO_PORT_MASK,
1095                 .jumbo_size_reg = B53_JUMBO_MAX_SIZE,
1096                 .sw_ops = &b53_switch_ops,
1097         },
1098         {
1099                 .chip_id = BCM63XX_DEVICE_ID,
1100                 .dev_name = "BCM63xx",
1101                 .alias = "bcm63xx",
1102                 .vlans = 4096,
1103                 .enabled_ports = 0, /* pdata must provide them */
1104                 .cpu_port = B53_CPU_PORT,
1105                 .vta_regs = B53_VTA_REGS_63XX,
1106                 .duplex_reg = B53_DUPLEX_STAT_63XX,
1107                 .jumbo_pm_reg = B53_JUMBO_PORT_MASK_63XX,
1108                 .jumbo_size_reg = B53_JUMBO_MAX_SIZE_63XX,
1109                 .sw_ops = &b53_switch_ops,
1110         },
1111 };
1112
1113 int b53_switch_init(struct b53_device *dev)
1114 {
1115         struct switch_dev *sw_dev = &dev->sw_dev;
1116         unsigned i;
1117
1118         for (i = 0; i < ARRAY_SIZE(b53_switch_chips); i++) {
1119                 const struct b53_chip_data *chip = &b53_switch_chips[i];
1120
1121                 if (chip->chip_id == dev->chip_id) {
1122                         sw_dev->name = chip->dev_name;
1123                         if (!sw_dev->alias)
1124                                 sw_dev->alias = chip->alias;
1125                         if (!dev->enabled_ports)
1126                                 dev->enabled_ports = chip->enabled_ports;
1127                         dev->duplex_reg = chip->duplex_reg;
1128                         dev->vta_regs[0] = chip->vta_regs[0];
1129                         dev->vta_regs[1] = chip->vta_regs[1];
1130                         dev->vta_regs[2] = chip->vta_regs[2];
1131                         dev->jumbo_pm_reg = chip->jumbo_pm_reg;
1132                         sw_dev->ops = chip->sw_ops;
1133                         sw_dev->cpu_port = chip->cpu_port;
1134                         sw_dev->vlans = chip->vlans;
1135                         break;
1136                 }
1137         }
1138
1139         if (!sw_dev->name)
1140                 return -EINVAL;
1141
1142         /* check which BCM5325x version we have */
1143         if (is5325(dev)) {
1144                 u8 vc4;
1145
1146                 b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL4_25, &vc4);
1147
1148                 /* check reserved bits */
1149                 switch (vc4 & 3) {
1150                 case 1:
1151                         /* BCM5325E */
1152                         break;
1153                 case 3:
1154                         /* BCM5325F - do not use port 4 */
1155                         dev->enabled_ports &= ~BIT(4);
1156                         break;
1157                 default:
1158                         /* BCM5325M */
1159                         return -EINVAL;
1160                 }
1161         } else if (dev->chip_id == BCM53115_DEVICE_ID) {
1162                 u64 strap_value;
1163
1164                 b53_read48(dev, B53_STAT_PAGE, B53_STRAP_VALUE, &strap_value);
1165                 /* use second IMP port if GMII is enabled */
1166                 if (strap_value & SV_GMII_CTRL_115)
1167                         sw_dev->cpu_port = 5;
1168         }
1169
1170         /* cpu port is always last */
1171         sw_dev->ports = sw_dev->cpu_port + 1;
1172         dev->enabled_ports |= BIT(sw_dev->cpu_port);
1173
1174         dev->ports = devm_kzalloc(dev->dev,
1175                                   sizeof(struct b53_port) * sw_dev->ports,
1176                                   GFP_KERNEL);
1177         if (!dev->ports)
1178                 return -ENOMEM;
1179
1180         dev->vlans = devm_kzalloc(dev->dev,
1181                                   sizeof(struct b53_vlan) * sw_dev->vlans,
1182                                   GFP_KERNEL);
1183         if (!dev->vlans)
1184                 return -ENOMEM;
1185
1186         dev->buf = devm_kzalloc(dev->dev, B53_BUF_SIZE, GFP_KERNEL);
1187         if (!dev->buf)
1188                 return -ENOMEM;
1189
1190         return b53_switch_reset(dev);
1191 }
1192
1193 struct b53_device *b53_switch_alloc(struct device *base, struct b53_io_ops *ops,
1194                                     void *priv)
1195 {
1196         struct b53_device *dev;
1197
1198         dev = devm_kzalloc(base, sizeof(*dev), GFP_KERNEL);
1199         if (!dev)
1200                 return NULL;
1201
1202         dev->dev = base;
1203         dev->ops = ops;
1204         dev->priv = priv;
1205         mutex_init(&dev->reg_mutex);
1206
1207         return dev;
1208 }
1209 EXPORT_SYMBOL(b53_switch_alloc);
1210
1211 int b53_switch_detect(struct b53_device *dev)
1212 {
1213         u32 id32;
1214         u16 tmp;
1215         u8 id8;
1216         int ret;
1217
1218         ret = b53_read8(dev, B53_MGMT_PAGE, B53_DEVICE_ID, &id8);
1219         if (ret)
1220                 return ret;
1221
1222         switch (id8) {
1223         case 0:
1224                 /*
1225                  * BCM5325 and BCM5365 do not have this register so reads
1226                  * return 0. But the read operation did succeed, so assume
1227                  * this is one of them.
1228                  *
1229                  * Next check if we can write to the 5325's VTA register; for
1230                  * 5365 it is read only.
1231                  */
1232
1233                 b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_TABLE_ACCESS_25, 0xf);
1234                 b53_read16(dev, B53_VLAN_PAGE, B53_VLAN_TABLE_ACCESS_25, &tmp);
1235
1236                 if (tmp == 0xf)
1237                         dev->chip_id = BCM5325_DEVICE_ID;
1238                 else
1239                         dev->chip_id = BCM5365_DEVICE_ID;
1240                 break;
1241         case BCM5395_DEVICE_ID:
1242         case BCM5397_DEVICE_ID:
1243         case BCM5398_DEVICE_ID:
1244                 dev->chip_id = id8;
1245                 break;
1246         default:
1247                 ret = b53_read32(dev, B53_MGMT_PAGE, B53_DEVICE_ID, &id32);
1248                 if (ret)
1249                         return ret;
1250
1251                 switch (id32) {
1252                 case BCM53115_DEVICE_ID:
1253                 case BCM53125_DEVICE_ID:
1254                         dev->chip_id = id32;
1255                         break;
1256                 default:
1257                         pr_err("unsupported switch detected (BCM53%02x/BCM%x)\n",
1258                                id8, id32);
1259                         return -ENODEV;
1260                 }
1261         }
1262
1263         return b53_read8(dev, B53_MGMT_PAGE, B53_REV_ID, &dev->core_rev);
1264 }
1265 EXPORT_SYMBOL(b53_switch_detect);
1266
1267 int b53_switch_register(struct b53_device *dev)
1268 {
1269         int ret;
1270
1271         if (dev->pdata) {
1272                 dev->chip_id = dev->pdata->chip_id;
1273                 dev->enabled_ports = dev->pdata->enabled_ports;
1274                 dev->sw_dev.alias = dev->pdata->alias;
1275         }
1276
1277         if (!dev->chip_id && b53_switch_detect(dev))
1278                 return -EINVAL;
1279
1280         ret = b53_switch_init(dev);
1281         if (ret)
1282                 return ret;
1283
1284         pr_info("found switch: %s, rev %i\n", dev->sw_dev.name, dev->core_rev);
1285
1286         return register_switch(&dev->sw_dev, NULL);
1287 }
1288 EXPORT_SYMBOL(b53_switch_register);
1289
1290 MODULE_AUTHOR("Jonas Gorski <jogo@openwrt.org>");
1291 MODULE_DESCRIPTION("B53 switch library");
1292 MODULE_LICENSE("Dual BSD/GPL");