7199de0eb21b05b6afc76f8a5379bd73fdd7e044
[openwrt.git] / target / linux / generic / files / drivers / net / phy / mvsw61xx.c
1 /*
2  * Marvell 88E61xx switch driver
3  *
4  * Copyright (c) 2014 Claudio Leite <leitec@staticky.com>
5  *
6  * Based on code (c) 2008 Felix Fietkau <nbd@openwrt.org>
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License v2 as published by the
10  * Free Software Foundation
11  */
12
13 #include <linux/kernel.h>
14 #include <linux/module.h>
15 #include <linux/init.h>
16 #include <linux/list.h>
17 #include <linux/mii.h>
18 #include <linux/phy.h>
19 #include <linux/of.h>
20 #include <linux/of_mdio.h>
21 #include <linux/delay.h>
22 #include <linux/switch.h>
23 #include <linux/device.h>
24 #include <linux/platform_device.h>
25
26 #include "mvsw61xx.h"
27
28 MODULE_DESCRIPTION("Marvell 88E61xx Switch driver");
29 MODULE_AUTHOR("Claudio Leite <leitec@staticky.com>");
30 MODULE_LICENSE("GPL v2");
31 MODULE_ALIAS("platform:mvsw61xx");
32
33 /*
34  * Register access is done through direct or indirect addressing,
35  * depending on how the switch is physically connected.
36  *
37  * Direct addressing: all port and global registers directly
38  *   accessible via an address/register pair
39  *
40  * Indirect addressing: switch is mapped at a single address,
41  *   port and global registers accessible via a single command/data
42  *   register pair
43  */
44
45 static int
46 mvsw61xx_wait_mask_raw(struct mii_bus *bus, int addr,
47                 int reg, u16 mask, u16 val)
48 {
49         int i = 100;
50         u16 r;
51
52         do {
53                 r = bus->read(bus, addr, reg);
54                 if ((r & mask) == val)
55                         return 0;
56         } while (--i > 0);
57
58         return -ETIMEDOUT;
59 }
60
61 static u16
62 r16(struct mii_bus *bus, bool indirect, int base_addr, int addr, int reg)
63 {
64         u16 ind_addr;
65
66         if (!indirect)
67                 return bus->read(bus, addr, reg);
68
69         /* Indirect read: First, make sure switch is free */
70         mvsw61xx_wait_mask_raw(bus, base_addr, MV_INDIRECT_REG_CMD,
71                         MV_INDIRECT_INPROGRESS, 0);
72
73         /* Load address and request read */
74         ind_addr = MV_INDIRECT_READ | (addr << MV_INDIRECT_ADDR_S) | reg;
75         bus->write(bus, base_addr, MV_INDIRECT_REG_CMD,
76                         ind_addr);
77
78         /* Wait until it's ready */
79         mvsw61xx_wait_mask_raw(bus, base_addr, MV_INDIRECT_REG_CMD,
80                         MV_INDIRECT_INPROGRESS, 0);
81
82         /* Read the requested data */
83         return bus->read(bus, base_addr, MV_INDIRECT_REG_DATA);
84 }
85
86 static void
87 w16(struct mii_bus *bus, bool indirect, int base_addr, int addr,
88                 int reg, u16 val)
89 {
90         u16 ind_addr;
91
92         if (!indirect) {
93                 bus->write(bus, addr, reg, val);
94                 return;
95         }
96
97         /* Indirect write: First, make sure switch is free */
98         mvsw61xx_wait_mask_raw(bus, base_addr, MV_INDIRECT_REG_CMD,
99                         MV_INDIRECT_INPROGRESS, 0);
100
101         /* Load the data to be written */
102         bus->write(bus, base_addr, MV_INDIRECT_REG_DATA, val);
103
104         /* Wait again for switch to be free */
105         mvsw61xx_wait_mask_raw(bus, base_addr, MV_INDIRECT_REG_CMD,
106                         MV_INDIRECT_INPROGRESS, 0);
107
108         /* Load address, and issue write command */
109         ind_addr = MV_INDIRECT_WRITE | (addr << MV_INDIRECT_ADDR_S) | reg;
110         bus->write(bus, base_addr, MV_INDIRECT_REG_CMD,
111                         ind_addr);
112 }
113
114 /* swconfig support */
115
116 static inline u16
117 sr16(struct switch_dev *dev, int addr, int reg)
118 {
119         struct mvsw61xx_state *state = get_state(dev);
120
121         return r16(state->bus, state->is_indirect, state->base_addr, addr, reg);
122 }
123
124 static inline void
125 sw16(struct switch_dev *dev, int addr, int reg, u16 val)
126 {
127         struct mvsw61xx_state *state = get_state(dev);
128
129         w16(state->bus, state->is_indirect, state->base_addr, addr, reg, val);
130 }
131
132 static int
133 mvsw61xx_wait_mask_s(struct switch_dev *dev, int addr,
134                 int reg, u16 mask, u16 val)
135 {
136         int i = 100;
137         u16 r;
138
139         do {
140                 r = sr16(dev, addr, reg) & mask;
141                 if (r == val)
142                         return 0;
143         } while (--i > 0);
144
145         return -ETIMEDOUT;
146 }
147
148 static int
149 mvsw61xx_get_port_mask(struct switch_dev *dev,
150                 const struct switch_attr *attr, struct switch_val *val)
151 {
152         struct mvsw61xx_state *state = get_state(dev);
153         char *buf = state->buf;
154         int port, len, i;
155         u16 reg;
156
157         port = val->port_vlan;
158         reg = sr16(dev, MV_PORTREG(VLANMAP, port)) & MV_PORTS_MASK;
159
160         len = sprintf(buf, "0x%04x: ", reg);
161
162         for (i = 0; i < MV_PORTS; i++) {
163                 if (reg & (1 << i))
164                         len += sprintf(buf + len, "%d ", i);
165                 else if (i == port)
166                         len += sprintf(buf + len, "(%d) ", i);
167         }
168
169         val->value.s = buf;
170
171         return 0;
172 }
173
174 static int
175 mvsw61xx_get_port_qmode(struct switch_dev *dev,
176                 const struct switch_attr *attr, struct switch_val *val)
177 {
178         struct mvsw61xx_state *state = get_state(dev);
179
180         val->value.i = state->ports[val->port_vlan].qmode;
181
182         return 0;
183 }
184
185 static int
186 mvsw61xx_set_port_qmode(struct switch_dev *dev,
187                 const struct switch_attr *attr, struct switch_val *val)
188 {
189         struct mvsw61xx_state *state = get_state(dev);
190
191         state->ports[val->port_vlan].qmode = val->value.i;
192
193         return 0;
194 }
195
196 static int
197 mvsw61xx_get_pvid(struct switch_dev *dev, int port, int *val)
198 {
199         struct mvsw61xx_state *state = get_state(dev);
200
201         *val = state->ports[port].pvid;
202
203         return 0;
204 }
205
206 static int
207 mvsw61xx_set_pvid(struct switch_dev *dev, int port, int val)
208 {
209         struct mvsw61xx_state *state = get_state(dev);
210
211         if (val < 0 || val >= MV_VLANS)
212                 return -EINVAL;
213
214         state->ports[port].pvid = (u16)val;
215
216         return 0;
217 }
218
219 static int
220 mvsw61xx_get_port_status(struct switch_dev *dev,
221                 const struct switch_attr *attr, struct switch_val *val)
222 {
223         struct mvsw61xx_state *state = get_state(dev);
224         char *buf = state->buf;
225         u16 status, speed;
226         int len;
227
228         status = sr16(dev, MV_PORTREG(STATUS, val->port_vlan));
229         speed = (status & MV_PORT_STATUS_SPEED_MASK) >>
230                         MV_PORT_STATUS_SPEED_SHIFT;
231
232         len = sprintf(buf, "link: ");
233         if (status & MV_PORT_STATUS_LINK) {
234                 len += sprintf(buf + len, "up, speed: ");
235
236                 switch (speed) {
237                 case MV_PORT_STATUS_SPEED_10:
238                         len += sprintf(buf + len, "10");
239                         break;
240                 case MV_PORT_STATUS_SPEED_100:
241                         len += sprintf(buf + len, "100");
242                         break;
243                 case MV_PORT_STATUS_SPEED_1000:
244                         len += sprintf(buf + len, "1000");
245                         break;
246                 }
247
248                 len += sprintf(buf + len, " Mbps, duplex: ");
249
250                 if (status & MV_PORT_STATUS_FDX)
251                         len += sprintf(buf + len, "full");
252                 else
253                         len += sprintf(buf + len, "half");
254         } else {
255                 len += sprintf(buf + len, "down");
256         }
257
258         val->value.s = buf;
259
260         return 0;
261 }
262
263 static int
264 mvsw61xx_get_port_speed(struct switch_dev *dev,
265                 const struct switch_attr *attr, struct switch_val *val)
266 {
267         u16 status, speed;
268
269         status = sr16(dev, MV_PORTREG(STATUS, val->port_vlan));
270         speed = (status & MV_PORT_STATUS_SPEED_MASK) >>
271                         MV_PORT_STATUS_SPEED_SHIFT;
272
273         val->value.i = 0;
274
275         if (status & MV_PORT_STATUS_LINK) {
276                 switch (speed) {
277                 case MV_PORT_STATUS_SPEED_10:
278                         val->value.i = 10;
279                         break;
280                 case MV_PORT_STATUS_SPEED_100:
281                         val->value.i = 100;
282                         break;
283                 case MV_PORT_STATUS_SPEED_1000:
284                         val->value.i = 1000;
285                         break;
286                 }
287         }
288
289         return 0;
290 }
291
292 static int mvsw61xx_get_vlan_ports(struct switch_dev *dev,
293                 struct switch_val *val)
294 {
295         struct mvsw61xx_state *state = get_state(dev);
296         int i, j, mode, vno;
297
298         vno = val->port_vlan;
299
300         if (vno <= 0 || vno >= dev->vlans)
301                 return -EINVAL;
302
303         for (i = 0, j = 0; i < dev->ports; i++) {
304                 if (state->vlans[vno].mask & (1 << i)) {
305                         val->value.ports[j].id = i;
306
307                         mode = (state->vlans[vno].port_mode >> (i * 4)) & 0xf;
308                         if (mode == MV_VTUCTL_EGRESS_TAGGED)
309                                 val->value.ports[j].flags =
310                                         (1 << SWITCH_PORT_FLAG_TAGGED);
311                         else
312                                 val->value.ports[j].flags = 0;
313
314                         j++;
315                 }
316         }
317
318         val->len = j;
319
320         return 0;
321 }
322
323 static int mvsw61xx_set_vlan_ports(struct switch_dev *dev,
324                 struct switch_val *val)
325 {
326         struct mvsw61xx_state *state = get_state(dev);
327         int i, mode, pno, vno;
328
329         vno = val->port_vlan;
330
331         if (vno <= 0 || vno >= dev->vlans)
332                 return -EINVAL;
333
334         state->vlans[vno].mask = 0;
335         state->vlans[vno].port_mode = 0;
336
337         if(state->vlans[vno].vid == 0)
338                 state->vlans[vno].vid = vno;
339
340         for (i = 0; i < val->len; i++) {
341                 pno = val->value.ports[i].id;
342
343                 state->vlans[vno].mask |= (1 << pno);
344                 if (val->value.ports[i].flags &
345                                 (1 << SWITCH_PORT_FLAG_TAGGED))
346                         mode = MV_VTUCTL_EGRESS_TAGGED;
347                 else
348                         mode = MV_VTUCTL_EGRESS_UNTAGGED;
349
350                 state->vlans[vno].port_mode |= mode << (pno * 4);
351         }
352
353         /*
354          * DISCARD is nonzero, so it must be explicitly
355          * set on ports not in the VLAN.
356          */
357         for (i = 0; i < dev->ports; i++)
358                 if (!(state->vlans[vno].mask & (1 << i)))
359                         state->vlans[vno].port_mode |=
360                                 MV_VTUCTL_DISCARD << (i * 4);
361
362         return 0;
363 }
364
365 static int mvsw61xx_get_vlan_port_based(struct switch_dev *dev,
366                 const struct switch_attr *attr, struct switch_val *val)
367 {
368         struct mvsw61xx_state *state = get_state(dev);
369         int vno = val->port_vlan;
370
371         if (vno <= 0 || vno >= dev->vlans)
372                 return -EINVAL;
373
374         if (state->vlans[vno].port_based)
375                 val->value.i = 1;
376         else
377                 val->value.i = 0;
378
379         return 0;
380 }
381
382 static int mvsw61xx_set_vlan_port_based(struct switch_dev *dev,
383                 const struct switch_attr *attr, struct switch_val *val)
384 {
385         struct mvsw61xx_state *state = get_state(dev);
386         int vno = val->port_vlan;
387
388         if (vno <= 0 || vno >= dev->vlans)
389                 return -EINVAL;
390
391         if (val->value.i == 1)
392                 state->vlans[vno].port_based = true;
393         else
394                 state->vlans[vno].port_based = false;
395
396         return 0;
397 }
398
399 static int mvsw61xx_get_vid(struct switch_dev *dev,
400                 const struct switch_attr *attr, struct switch_val *val)
401 {
402         struct mvsw61xx_state *state = get_state(dev);
403         int vno = val->port_vlan;
404
405         if (vno <= 0 || vno >= dev->vlans)
406                 return -EINVAL;
407
408         val->value.i = state->vlans[vno].vid;
409
410         return 0;
411 }
412
413 static int mvsw61xx_set_vid(struct switch_dev *dev,
414                 const struct switch_attr *attr, struct switch_val *val)
415 {
416         struct mvsw61xx_state *state = get_state(dev);
417         int vno = val->port_vlan;
418
419         if (vno <= 0 || vno >= dev->vlans)
420                 return -EINVAL;
421
422         state->vlans[vno].vid = val->value.i;
423
424         return 0;
425 }
426
427 static int mvsw61xx_get_enable_vlan(struct switch_dev *dev,
428                 const struct switch_attr *attr, struct switch_val *val)
429 {
430         struct mvsw61xx_state *state = get_state(dev);
431
432         val->value.i = state->vlan_enabled;
433
434         return 0;
435 }
436
437 static int mvsw61xx_set_enable_vlan(struct switch_dev *dev,
438                 const struct switch_attr *attr, struct switch_val *val)
439 {
440         struct mvsw61xx_state *state = get_state(dev);
441
442         state->vlan_enabled = val->value.i;
443
444         return 0;
445 }
446
447 static int mvsw61xx_vtu_program(struct switch_dev *dev)
448 {
449         struct mvsw61xx_state *state = get_state(dev);
450         u16 v1, v2;
451         int i;
452
453         /* Flush */
454         mvsw61xx_wait_mask_s(dev, MV_GLOBALREG(VTU_OP),
455                         MV_VTUOP_INPROGRESS, 0);
456         sw16(dev, MV_GLOBALREG(VTU_OP),
457                         MV_VTUOP_INPROGRESS | MV_VTUOP_VALID);
458
459         /* Write VLAN table */
460         for (i = 1; i < dev->vlans; i++) {
461                 if (state->vlans[i].mask == 0 ||
462                                 state->vlans[i].vid == 0 ||
463                                 state->vlans[i].port_based == true)
464                         continue;
465
466                 mvsw61xx_wait_mask_s(dev, MV_GLOBALREG(VTU_OP),
467                                 MV_VTUOP_INPROGRESS, 0);
468
469                 sw16(dev, MV_GLOBALREG(VTU_VID),
470                                 MV_VTUOP_VALID | state->vlans[i].vid);
471
472                 v1 = (u16)(state->vlans[i].port_mode & 0xffff);
473                 v2 = (u16)((state->vlans[i].port_mode >> 16) & 0xffff);
474
475                 sw16(dev, MV_GLOBALREG(VTU_DATA1), v1);
476                 sw16(dev, MV_GLOBALREG(VTU_DATA2), v2);
477
478                 sw16(dev, MV_GLOBALREG(VTU_OP),
479                                 MV_VTUOP_INPROGRESS | MV_VTUOP_LOAD);
480                 mvsw61xx_wait_mask_s(dev, MV_GLOBALREG(VTU_OP),
481                                 MV_VTUOP_INPROGRESS, 0);
482         }
483
484         return 0;
485 }
486
487 static void mvsw61xx_vlan_port_config(struct switch_dev *dev, int vno)
488 {
489         struct mvsw61xx_state *state = get_state(dev);
490         int i, mode;
491
492         for (i = 0; i < dev->ports; i++) {
493                 if (!(state->vlans[vno].mask & (1 << i)))
494                         continue;
495
496                 mode = (state->vlans[vno].port_mode >> (i * 4)) & 0xf;
497
498                 if(mode != MV_VTUCTL_EGRESS_TAGGED)
499                         state->ports[i].pvid = state->vlans[vno].vid;
500
501                 if (state->vlans[vno].port_based)
502                         state->ports[i].mask |= state->vlans[vno].mask;
503                 else
504                         state->ports[i].qmode = MV_8021Q_MODE_SECURE;
505         }
506 }
507
508 static int mvsw61xx_update_state(struct switch_dev *dev)
509 {
510         struct mvsw61xx_state *state = get_state(dev);
511         int i;
512         u16 reg;
513
514         if (!state->registered)
515                 return -EINVAL;
516
517         mvsw61xx_vtu_program(dev);
518
519         /*
520          * Set 802.1q-only mode if vlan_enabled is true.
521          *
522          * Without this, even if 802.1q is enabled for
523          * a port/VLAN, it still depends on the port-based
524          * VLAN mask being set.
525          *
526          * With this setting, port-based VLANs are still
527          * functional, provided the VID is not in the VTU.
528          */
529         reg = sr16(dev, MV_GLOBAL2REG(SDET_POLARITY));
530
531         if (state->vlan_enabled)
532                 reg |= MV_8021Q_VLAN_ONLY;
533         else
534                 reg &= ~MV_8021Q_VLAN_ONLY;
535
536         sw16(dev, MV_GLOBAL2REG(SDET_POLARITY), reg);
537
538         /*
539          * Set port-based VLAN masks on each port
540          * based only on VLAN definitions known to
541          * the driver (i.e. in state).
542          *
543          * This means any pre-existing port mapping is
544          * wiped out once our driver is initialized.
545          */
546         for (i = 0; i < dev->ports; i++) {
547                 state->ports[i].mask = 0;
548                 state->ports[i].qmode = MV_8021Q_MODE_DISABLE;
549         }
550
551         for (i = 0; i < dev->vlans; i++)
552                 mvsw61xx_vlan_port_config(dev, i);
553
554         for (i = 0; i < dev->ports; i++) {
555                 reg = sr16(dev, MV_PORTREG(VLANID, i)) & ~MV_PVID_MASK;
556                 reg |= state->ports[i].pvid;
557                 sw16(dev, MV_PORTREG(VLANID, i), reg);
558
559                 state->ports[i].mask &= ~(1 << i);
560
561                 reg = sr16(dev, MV_PORTREG(VLANMAP, i)) & ~MV_PORTS_MASK;
562                 reg |= state->ports[i].mask;
563                 sw16(dev, MV_PORTREG(VLANMAP, i), reg);
564
565                 reg = sr16(dev, MV_PORTREG(CONTROL2, i)) &
566                         ~MV_8021Q_MODE_MASK;
567                 reg |= state->ports[i].qmode << MV_8021Q_MODE_SHIFT;
568                 sw16(dev, MV_PORTREG(CONTROL2, i), reg);
569         }
570
571         return 0;
572 }
573
574 static int mvsw61xx_apply(struct switch_dev *dev)
575 {
576         return mvsw61xx_update_state(dev);
577 }
578
579 static int mvsw61xx_reset(struct switch_dev *dev)
580 {
581         struct mvsw61xx_state *state = get_state(dev);
582         int i;
583         u16 reg;
584
585         /* Disable all ports before reset */
586         for (i = 0; i < dev->ports; i++) {
587                 reg = sr16(dev, MV_PORTREG(CONTROL, i)) &
588                         ~MV_PORTCTRL_ENABLED;
589                 sw16(dev, MV_PORTREG(CONTROL, i), reg);
590         }
591
592         reg = sr16(dev, MV_GLOBALREG(CONTROL)) | MV_CONTROL_RESET;
593
594         sw16(dev, MV_GLOBALREG(CONTROL), reg);
595         if (mvsw61xx_wait_mask_s(dev, MV_GLOBALREG(CONTROL),
596                                 MV_CONTROL_RESET, 0) < 0)
597                 return -ETIMEDOUT;
598
599         for (i = 0; i < dev->ports; i++) {
600                 state->ports[i].qmode = 0;
601                 state->ports[i].mask = 0;
602                 state->ports[i].pvid = 0;
603
604                 /* Force flow control off */
605                 reg = sr16(dev, MV_PORTREG(FORCE, i)) & ~MV_FORCE_FC_MASK;
606                 reg |= MV_FORCE_FC_DISABLE;
607                 sw16(dev, MV_PORTREG(FORCE, i), reg);
608
609                 /* Set port association vector */
610                 sw16(dev, MV_PORTREG(ASSOC, i), (1 << i));
611         }
612
613         for (i = 0; i < dev->vlans; i++) {
614                 state->vlans[i].port_based = false;
615                 state->vlans[i].mask = 0;
616                 state->vlans[i].vid = 0;
617                 state->vlans[i].port_mode = 0;
618         }
619
620         state->vlan_enabled = 0;
621
622         mvsw61xx_update_state(dev);
623
624         /* Re-enable ports */
625         for (i = 0; i < dev->ports; i++) {
626                 reg = sr16(dev, MV_PORTREG(CONTROL, i)) |
627                         MV_PORTCTRL_ENABLED;
628                 sw16(dev, MV_PORTREG(CONTROL, i), reg);
629         }
630
631         return 0;
632 }
633
634 enum {
635         MVSW61XX_ENABLE_VLAN,
636 };
637
638 enum {
639         MVSW61XX_VLAN_PORT_BASED,
640         MVSW61XX_VLAN_ID,
641 };
642
643 enum {
644         MVSW61XX_PORT_MASK,
645         MVSW61XX_PORT_QMODE,
646         MVSW61XX_PORT_STATUS,
647         MVSW61XX_PORT_LINK,
648 };
649
650 static const struct switch_attr mvsw61xx_global[] = {
651         [MVSW61XX_ENABLE_VLAN] = {
652                 .id = MVSW61XX_ENABLE_VLAN,
653                 .type = SWITCH_TYPE_INT,
654                 .name = "enable_vlan",
655                 .description = "Enable 802.1q VLAN support",
656                 .get = mvsw61xx_get_enable_vlan,
657                 .set = mvsw61xx_set_enable_vlan,
658         },
659 };
660
661 static const struct switch_attr mvsw61xx_vlan[] = {
662         [MVSW61XX_VLAN_PORT_BASED] = {
663                 .id = MVSW61XX_VLAN_PORT_BASED,
664                 .type = SWITCH_TYPE_INT,
665                 .name = "port_based",
666                 .description = "Use port-based (non-802.1q) VLAN only",
667                 .get = mvsw61xx_get_vlan_port_based,
668                 .set = mvsw61xx_set_vlan_port_based,
669         },
670         [MVSW61XX_VLAN_ID] = {
671                 .id = MVSW61XX_VLAN_ID,
672                 .type = SWITCH_TYPE_INT,
673                 .name = "vid",
674                 .description = "Get/set VLAN ID",
675                 .get = mvsw61xx_get_vid,
676                 .set = mvsw61xx_set_vid,
677         },
678 };
679
680 static const struct switch_attr mvsw61xx_port[] = {
681         [MVSW61XX_PORT_MASK] = {
682                 .id = MVSW61XX_PORT_MASK,
683                 .type = SWITCH_TYPE_STRING,
684                 .description = "Port-based VLAN mask",
685                 .name = "mask",
686                 .get = mvsw61xx_get_port_mask,
687                 .set = NULL,
688         },
689         [MVSW61XX_PORT_QMODE] = {
690                 .id = MVSW61XX_PORT_QMODE,
691                 .type = SWITCH_TYPE_INT,
692                 .description = "802.1q mode: 0=off/1=fallback/2=check/3=secure",
693                 .name = "qmode",
694                 .get = mvsw61xx_get_port_qmode,
695                 .set = mvsw61xx_set_port_qmode,
696         },
697         [MVSW61XX_PORT_STATUS] = {
698                 .id = MVSW61XX_PORT_STATUS,
699                 .type = SWITCH_TYPE_STRING,
700                 .description = "Return port status",
701                 .name = "status",
702                 .get = mvsw61xx_get_port_status,
703                 .set = NULL,
704         },
705         [MVSW61XX_PORT_LINK] = {
706                 .id = MVSW61XX_PORT_LINK,
707                 .type = SWITCH_TYPE_INT,
708                 .description = "Get link speed",
709                 .name = "link",
710                 .get = mvsw61xx_get_port_speed,
711                 .set = NULL,
712         },
713 };
714
715 static const struct switch_dev_ops mvsw61xx_ops = {
716         .attr_global = {
717                 .attr = mvsw61xx_global,
718                 .n_attr = ARRAY_SIZE(mvsw61xx_global),
719         },
720         .attr_vlan = {
721                 .attr = mvsw61xx_vlan,
722                 .n_attr = ARRAY_SIZE(mvsw61xx_vlan),
723         },
724         .attr_port = {
725                 .attr = mvsw61xx_port,
726                 .n_attr = ARRAY_SIZE(mvsw61xx_port),
727         },
728         .get_port_pvid = mvsw61xx_get_pvid,
729         .set_port_pvid = mvsw61xx_set_pvid,
730         .get_vlan_ports = mvsw61xx_get_vlan_ports,
731         .set_vlan_ports = mvsw61xx_set_vlan_ports,
732         .apply_config = mvsw61xx_apply,
733         .reset_switch = mvsw61xx_reset,
734 };
735
736 /* end swconfig stuff */
737
738 static int mvsw61xx_probe(struct platform_device *pdev)
739 {
740         struct mvsw61xx_state *state;
741         struct device_node *np = pdev->dev.of_node;
742         struct device_node *mdio;
743         u32 val;
744         u16 reg;
745         int err;
746
747         state = kzalloc(sizeof(*state), GFP_KERNEL);
748         if (!state)
749                 return -ENOMEM;
750
751         mdio = of_parse_phandle(np, "mii-bus", 0);
752         if (!mdio) {
753                 dev_err(&pdev->dev, "Couldn't get MII bus handle\n");
754                 err = -ENODEV;
755                 goto out_err;
756         }
757
758         state->bus = of_mdio_find_bus(mdio);
759         if (!state->bus) {
760                 dev_err(&pdev->dev, "Couldn't find MII bus from handle\n");
761                 err = -ENODEV;
762                 goto out_err;
763         }
764
765         state->is_indirect = of_property_read_bool(np, "is-indirect");
766
767         if (state->is_indirect) {
768                 if (of_property_read_u32(np, "reg", &val)) {
769                         dev_err(&pdev->dev, "Switch address not specified\n");
770                         err = -ENODEV;
771                         goto out_err;
772                 }
773
774                 state->base_addr = val;
775         } else {
776                 state->base_addr = MV_BASE;
777         }
778
779         reg = r16(state->bus, state->is_indirect, state->base_addr,
780                         MV_PORTREG(IDENT, 0)) & MV_IDENT_MASK;
781         if (reg != MV_IDENT_VALUE) {
782                 dev_err(&pdev->dev, "No switch found at 0x%02x\n",
783                                 state->base_addr);
784                 err = -ENODEV;
785                 goto out_err;
786         }
787
788         platform_set_drvdata(pdev, state);
789         dev_info(&pdev->dev, "Found %s at %s:%02x\n", MV_IDENT_STR,
790                         state->bus->id, state->base_addr);
791
792         dev_info(&pdev->dev, "Using %sdirect addressing\n",
793                         (state->is_indirect ? "in" : ""));
794
795         if (of_property_read_u32(np, "cpu-port-0", &val)) {
796                 dev_err(&pdev->dev, "CPU port not set\n");
797                 err = -ENODEV;
798                 goto out_err;
799         }
800
801         state->cpu_port0 = val;
802
803         if (!of_property_read_u32(np, "cpu-port-1", &val))
804                 state->cpu_port1 = val;
805         else
806                 state->cpu_port1 = -1;
807
808         state->dev.vlans = MV_VLANS;
809         state->dev.cpu_port = state->cpu_port0;
810         state->dev.ports = MV_PORTS;
811         state->dev.name = MV_IDENT_STR;
812         state->dev.ops = &mvsw61xx_ops;
813         state->dev.alias = dev_name(&pdev->dev);
814
815         err = register_switch(&state->dev, NULL);
816         if (err < 0)
817                 goto out_err;
818
819         state->registered = true;
820
821         return 0;
822 out_err:
823         kfree(state);
824         return err;
825 }
826
827 static int
828 mvsw61xx_remove(struct platform_device *pdev)
829 {
830         struct mvsw61xx_state *state = platform_get_drvdata(pdev);
831
832         if (state->registered)
833                 unregister_switch(&state->dev);
834
835         kfree(state);
836
837         return 0;
838 }
839
840 static const struct of_device_id mvsw61xx_match[] = {
841         { .compatible = "marvell,88e6171" },
842         { }
843 };
844 MODULE_DEVICE_TABLE(of, mvsw61xx_match);
845
846 static struct platform_driver mvsw61xx_driver = {
847         .probe = mvsw61xx_probe,
848         .remove = mvsw61xx_remove,
849         .driver = {
850                 .name = "mvsw61xx",
851                 .of_match_table = of_match_ptr(mvsw61xx_match),
852                 .owner = THIS_MODULE,
853         },
854 };
855
856 static int __init mvsw61xx_module_init(void)
857 {
858         return platform_driver_register(&mvsw61xx_driver);
859 }
860 late_initcall(mvsw61xx_module_init);
861
862 static void __exit mvsw61xx_module_exit(void)
863 {
864         platform_driver_unregister(&mvsw61xx_driver);
865 }
866 module_exit(mvsw61xx_module_exit);