net: dsa: Centralise global and port setup code into mv88e6xxx.
[deliverable/linux.git] / drivers / net / dsa / mv88e6xxx.c
CommitLineData
91da11f8
LB
1/*
2 * net/dsa/mv88e6xxx.c - Marvell 88e6xxx switch chip support
3 * Copyright (c) 2008 Marvell Semiconductor
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 */
10
19b2f97e 11#include <linux/delay.h>
defb05b9 12#include <linux/etherdevice.h>
facd95b2 13#include <linux/if_bridge.h>
19b2f97e 14#include <linux/jiffies.h>
91da11f8 15#include <linux/list.h>
2bbba277 16#include <linux/module.h>
91da11f8
LB
17#include <linux/netdevice.h>
18#include <linux/phy.h>
c8f0b869 19#include <net/dsa.h>
91da11f8
LB
20#include "mv88e6xxx.h"
21
3675c8d7 22/* If the switch's ADDR[4:0] strap pins are strapped to zero, it will
91da11f8
LB
23 * use all 32 SMI bus addresses on its SMI bus, and all switch registers
24 * will be directly accessible on some {device address,register address}
25 * pair. If the ADDR[4:0] pins are not strapped to zero, the switch
26 * will only respond to SMI transactions to that specific address, and
27 * an indirect addressing mechanism needs to be used to access its
28 * registers.
29 */
30static int mv88e6xxx_reg_wait_ready(struct mii_bus *bus, int sw_addr)
31{
32 int ret;
33 int i;
34
35 for (i = 0; i < 16; i++) {
cca8b133 36 ret = mdiobus_read(bus, sw_addr, SMI_CMD);
91da11f8
LB
37 if (ret < 0)
38 return ret;
39
cca8b133 40 if ((ret & SMI_CMD_BUSY) == 0)
91da11f8
LB
41 return 0;
42 }
43
44 return -ETIMEDOUT;
45}
46
47int __mv88e6xxx_reg_read(struct mii_bus *bus, int sw_addr, int addr, int reg)
48{
49 int ret;
50
51 if (sw_addr == 0)
52 return mdiobus_read(bus, addr, reg);
53
3675c8d7 54 /* Wait for the bus to become free. */
91da11f8
LB
55 ret = mv88e6xxx_reg_wait_ready(bus, sw_addr);
56 if (ret < 0)
57 return ret;
58
3675c8d7 59 /* Transmit the read command. */
cca8b133
AL
60 ret = mdiobus_write(bus, sw_addr, SMI_CMD,
61 SMI_CMD_OP_22_READ | (addr << 5) | reg);
91da11f8
LB
62 if (ret < 0)
63 return ret;
64
3675c8d7 65 /* Wait for the read command to complete. */
91da11f8
LB
66 ret = mv88e6xxx_reg_wait_ready(bus, sw_addr);
67 if (ret < 0)
68 return ret;
69
3675c8d7 70 /* Read the data. */
cca8b133 71 ret = mdiobus_read(bus, sw_addr, SMI_DATA);
91da11f8
LB
72 if (ret < 0)
73 return ret;
74
75 return ret & 0xffff;
76}
77
8d6d09e7
GR
78/* Must be called with SMI mutex held */
79static int _mv88e6xxx_reg_read(struct dsa_switch *ds, int addr, int reg)
91da11f8 80{
b184e497 81 struct mii_bus *bus = dsa_host_dev_to_mii_bus(ds->master_dev);
91da11f8
LB
82 int ret;
83
b184e497
GR
84 if (bus == NULL)
85 return -EINVAL;
86
b184e497 87 ret = __mv88e6xxx_reg_read(bus, ds->pd->sw_addr, addr, reg);
bb92ea5e
VD
88 if (ret < 0)
89 return ret;
90
91 dev_dbg(ds->master_dev, "<- addr: 0x%.2x reg: 0x%.2x val: 0x%.4x\n",
92 addr, reg, ret);
93
91da11f8
LB
94 return ret;
95}
96
8d6d09e7
GR
97int mv88e6xxx_reg_read(struct dsa_switch *ds, int addr, int reg)
98{
99 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
100 int ret;
101
102 mutex_lock(&ps->smi_mutex);
103 ret = _mv88e6xxx_reg_read(ds, addr, reg);
104 mutex_unlock(&ps->smi_mutex);
105
106 return ret;
107}
108
91da11f8
LB
109int __mv88e6xxx_reg_write(struct mii_bus *bus, int sw_addr, int addr,
110 int reg, u16 val)
111{
112 int ret;
113
114 if (sw_addr == 0)
115 return mdiobus_write(bus, addr, reg, val);
116
3675c8d7 117 /* Wait for the bus to become free. */
91da11f8
LB
118 ret = mv88e6xxx_reg_wait_ready(bus, sw_addr);
119 if (ret < 0)
120 return ret;
121
3675c8d7 122 /* Transmit the data to write. */
cca8b133 123 ret = mdiobus_write(bus, sw_addr, SMI_DATA, val);
91da11f8
LB
124 if (ret < 0)
125 return ret;
126
3675c8d7 127 /* Transmit the write command. */
cca8b133
AL
128 ret = mdiobus_write(bus, sw_addr, SMI_CMD,
129 SMI_CMD_OP_22_WRITE | (addr << 5) | reg);
91da11f8
LB
130 if (ret < 0)
131 return ret;
132
3675c8d7 133 /* Wait for the write command to complete. */
91da11f8
LB
134 ret = mv88e6xxx_reg_wait_ready(bus, sw_addr);
135 if (ret < 0)
136 return ret;
137
138 return 0;
139}
140
8d6d09e7
GR
141/* Must be called with SMI mutex held */
142static int _mv88e6xxx_reg_write(struct dsa_switch *ds, int addr, int reg,
143 u16 val)
91da11f8 144{
b184e497 145 struct mii_bus *bus = dsa_host_dev_to_mii_bus(ds->master_dev);
91da11f8 146
b184e497
GR
147 if (bus == NULL)
148 return -EINVAL;
149
bb92ea5e
VD
150 dev_dbg(ds->master_dev, "-> addr: 0x%.2x reg: 0x%.2x val: 0x%.4x\n",
151 addr, reg, val);
152
8d6d09e7
GR
153 return __mv88e6xxx_reg_write(bus, ds->pd->sw_addr, addr, reg, val);
154}
155
156int mv88e6xxx_reg_write(struct dsa_switch *ds, int addr, int reg, u16 val)
157{
158 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
159 int ret;
160
91da11f8 161 mutex_lock(&ps->smi_mutex);
8d6d09e7 162 ret = _mv88e6xxx_reg_write(ds, addr, reg, val);
91da11f8
LB
163 mutex_unlock(&ps->smi_mutex);
164
165 return ret;
166}
167
2e5f0320
LB
168int mv88e6xxx_set_addr_direct(struct dsa_switch *ds, u8 *addr)
169{
cca8b133
AL
170 REG_WRITE(REG_GLOBAL, GLOBAL_MAC_01, (addr[0] << 8) | addr[1]);
171 REG_WRITE(REG_GLOBAL, GLOBAL_MAC_23, (addr[2] << 8) | addr[3]);
172 REG_WRITE(REG_GLOBAL, GLOBAL_MAC_45, (addr[4] << 8) | addr[5]);
2e5f0320
LB
173
174 return 0;
175}
176
91da11f8
LB
177int mv88e6xxx_set_addr_indirect(struct dsa_switch *ds, u8 *addr)
178{
179 int i;
180 int ret;
181
182 for (i = 0; i < 6; i++) {
183 int j;
184
3675c8d7 185 /* Write the MAC address byte. */
cca8b133
AL
186 REG_WRITE(REG_GLOBAL2, GLOBAL2_SWITCH_MAC,
187 GLOBAL2_SWITCH_MAC_BUSY | (i << 8) | addr[i]);
91da11f8 188
3675c8d7 189 /* Wait for the write to complete. */
91da11f8 190 for (j = 0; j < 16; j++) {
cca8b133
AL
191 ret = REG_READ(REG_GLOBAL2, GLOBAL2_SWITCH_MAC);
192 if ((ret & GLOBAL2_SWITCH_MAC_BUSY) == 0)
91da11f8
LB
193 break;
194 }
195 if (j == 16)
196 return -ETIMEDOUT;
197 }
198
199 return 0;
200}
201
fd3a0ee4
AL
202/* Must be called with phy mutex held */
203static int _mv88e6xxx_phy_read(struct dsa_switch *ds, int addr, int regnum)
91da11f8
LB
204{
205 if (addr >= 0)
206 return mv88e6xxx_reg_read(ds, addr, regnum);
207 return 0xffff;
208}
209
fd3a0ee4
AL
210/* Must be called with phy mutex held */
211static int _mv88e6xxx_phy_write(struct dsa_switch *ds, int addr, int regnum,
212 u16 val)
91da11f8
LB
213{
214 if (addr >= 0)
215 return mv88e6xxx_reg_write(ds, addr, regnum, val);
216 return 0;
217}
218
2e5f0320
LB
219#ifdef CONFIG_NET_DSA_MV88E6XXX_NEED_PPU
220static int mv88e6xxx_ppu_disable(struct dsa_switch *ds)
221{
222 int ret;
19b2f97e 223 unsigned long timeout;
2e5f0320 224
cca8b133
AL
225 ret = REG_READ(REG_GLOBAL, GLOBAL_CONTROL);
226 REG_WRITE(REG_GLOBAL, GLOBAL_CONTROL,
227 ret & ~GLOBAL_CONTROL_PPU_ENABLE);
2e5f0320 228
19b2f97e
BG
229 timeout = jiffies + 1 * HZ;
230 while (time_before(jiffies, timeout)) {
cca8b133 231 ret = REG_READ(REG_GLOBAL, GLOBAL_STATUS);
19b2f97e 232 usleep_range(1000, 2000);
cca8b133
AL
233 if ((ret & GLOBAL_STATUS_PPU_MASK) !=
234 GLOBAL_STATUS_PPU_POLLING)
85686581 235 return 0;
2e5f0320
LB
236 }
237
238 return -ETIMEDOUT;
239}
240
241static int mv88e6xxx_ppu_enable(struct dsa_switch *ds)
242{
243 int ret;
19b2f97e 244 unsigned long timeout;
2e5f0320 245
cca8b133
AL
246 ret = REG_READ(REG_GLOBAL, GLOBAL_CONTROL);
247 REG_WRITE(REG_GLOBAL, GLOBAL_CONTROL, ret | GLOBAL_CONTROL_PPU_ENABLE);
2e5f0320 248
19b2f97e
BG
249 timeout = jiffies + 1 * HZ;
250 while (time_before(jiffies, timeout)) {
cca8b133 251 ret = REG_READ(REG_GLOBAL, GLOBAL_STATUS);
19b2f97e 252 usleep_range(1000, 2000);
cca8b133
AL
253 if ((ret & GLOBAL_STATUS_PPU_MASK) ==
254 GLOBAL_STATUS_PPU_POLLING)
85686581 255 return 0;
2e5f0320
LB
256 }
257
258 return -ETIMEDOUT;
259}
260
261static void mv88e6xxx_ppu_reenable_work(struct work_struct *ugly)
262{
263 struct mv88e6xxx_priv_state *ps;
264
265 ps = container_of(ugly, struct mv88e6xxx_priv_state, ppu_work);
266 if (mutex_trylock(&ps->ppu_mutex)) {
85686581 267 struct dsa_switch *ds = ((struct dsa_switch *)ps) - 1;
2e5f0320 268
85686581
BG
269 if (mv88e6xxx_ppu_enable(ds) == 0)
270 ps->ppu_disabled = 0;
271 mutex_unlock(&ps->ppu_mutex);
2e5f0320
LB
272 }
273}
274
275static void mv88e6xxx_ppu_reenable_timer(unsigned long _ps)
276{
277 struct mv88e6xxx_priv_state *ps = (void *)_ps;
278
279 schedule_work(&ps->ppu_work);
280}
281
282static int mv88e6xxx_ppu_access_get(struct dsa_switch *ds)
283{
a22adce5 284 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
2e5f0320
LB
285 int ret;
286
287 mutex_lock(&ps->ppu_mutex);
288
3675c8d7 289 /* If the PHY polling unit is enabled, disable it so that
2e5f0320
LB
290 * we can access the PHY registers. If it was already
291 * disabled, cancel the timer that is going to re-enable
292 * it.
293 */
294 if (!ps->ppu_disabled) {
85686581
BG
295 ret = mv88e6xxx_ppu_disable(ds);
296 if (ret < 0) {
297 mutex_unlock(&ps->ppu_mutex);
298 return ret;
299 }
300 ps->ppu_disabled = 1;
2e5f0320 301 } else {
85686581
BG
302 del_timer(&ps->ppu_timer);
303 ret = 0;
2e5f0320
LB
304 }
305
306 return ret;
307}
308
309static void mv88e6xxx_ppu_access_put(struct dsa_switch *ds)
310{
a22adce5 311 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
2e5f0320 312
3675c8d7 313 /* Schedule a timer to re-enable the PHY polling unit. */
2e5f0320
LB
314 mod_timer(&ps->ppu_timer, jiffies + msecs_to_jiffies(10));
315 mutex_unlock(&ps->ppu_mutex);
316}
317
318void mv88e6xxx_ppu_state_init(struct dsa_switch *ds)
319{
a22adce5 320 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
2e5f0320
LB
321
322 mutex_init(&ps->ppu_mutex);
323 INIT_WORK(&ps->ppu_work, mv88e6xxx_ppu_reenable_work);
324 init_timer(&ps->ppu_timer);
325 ps->ppu_timer.data = (unsigned long)ps;
326 ps->ppu_timer.function = mv88e6xxx_ppu_reenable_timer;
327}
328
329int mv88e6xxx_phy_read_ppu(struct dsa_switch *ds, int addr, int regnum)
330{
331 int ret;
332
333 ret = mv88e6xxx_ppu_access_get(ds);
334 if (ret >= 0) {
85686581
BG
335 ret = mv88e6xxx_reg_read(ds, addr, regnum);
336 mv88e6xxx_ppu_access_put(ds);
2e5f0320
LB
337 }
338
339 return ret;
340}
341
342int mv88e6xxx_phy_write_ppu(struct dsa_switch *ds, int addr,
343 int regnum, u16 val)
344{
345 int ret;
346
347 ret = mv88e6xxx_ppu_access_get(ds);
348 if (ret >= 0) {
85686581
BG
349 ret = mv88e6xxx_reg_write(ds, addr, regnum, val);
350 mv88e6xxx_ppu_access_put(ds);
2e5f0320
LB
351 }
352
353 return ret;
354}
355#endif
356
91da11f8
LB
357void mv88e6xxx_poll_link(struct dsa_switch *ds)
358{
359 int i;
360
361 for (i = 0; i < DSA_MAX_PORTS; i++) {
362 struct net_device *dev;
2a9e7978 363 int uninitialized_var(port_status);
91da11f8
LB
364 int link;
365 int speed;
366 int duplex;
367 int fc;
368
369 dev = ds->ports[i];
370 if (dev == NULL)
371 continue;
372
373 link = 0;
374 if (dev->flags & IFF_UP) {
cca8b133
AL
375 port_status = mv88e6xxx_reg_read(ds, REG_PORT(i),
376 PORT_STATUS);
91da11f8
LB
377 if (port_status < 0)
378 continue;
379
cca8b133 380 link = !!(port_status & PORT_STATUS_LINK);
91da11f8
LB
381 }
382
383 if (!link) {
384 if (netif_carrier_ok(dev)) {
ab381a93 385 netdev_info(dev, "link down\n");
91da11f8
LB
386 netif_carrier_off(dev);
387 }
388 continue;
389 }
390
cca8b133
AL
391 switch (port_status & PORT_STATUS_SPEED_MASK) {
392 case PORT_STATUS_SPEED_10:
91da11f8
LB
393 speed = 10;
394 break;
cca8b133 395 case PORT_STATUS_SPEED_100:
91da11f8
LB
396 speed = 100;
397 break;
cca8b133 398 case PORT_STATUS_SPEED_1000:
91da11f8
LB
399 speed = 1000;
400 break;
401 default:
402 speed = -1;
403 break;
404 }
cca8b133
AL
405 duplex = (port_status & PORT_STATUS_DUPLEX) ? 1 : 0;
406 fc = (port_status & PORT_STATUS_PAUSE_EN) ? 1 : 0;
91da11f8
LB
407
408 if (!netif_carrier_ok(dev)) {
ab381a93
BG
409 netdev_info(dev,
410 "link up, %d Mb/s, %s duplex, flow control %sabled\n",
411 speed,
412 duplex ? "full" : "half",
413 fc ? "en" : "dis");
91da11f8
LB
414 netif_carrier_on(dev);
415 }
416 }
417}
418
54d792f2
AL
419static bool mv88e6xxx_6065_family(struct dsa_switch *ds)
420{
421 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
422
423 switch (ps->id) {
424 case PORT_SWITCH_ID_6031:
425 case PORT_SWITCH_ID_6061:
426 case PORT_SWITCH_ID_6035:
427 case PORT_SWITCH_ID_6065:
428 return true;
429 }
430 return false;
431}
432
433static bool mv88e6xxx_6095_family(struct dsa_switch *ds)
434{
435 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
436
437 switch (ps->id) {
438 case PORT_SWITCH_ID_6092:
439 case PORT_SWITCH_ID_6095:
440 return true;
441 }
442 return false;
443}
444
445static bool mv88e6xxx_6097_family(struct dsa_switch *ds)
446{
447 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
448
449 switch (ps->id) {
450 case PORT_SWITCH_ID_6046:
451 case PORT_SWITCH_ID_6085:
452 case PORT_SWITCH_ID_6096:
453 case PORT_SWITCH_ID_6097:
454 return true;
455 }
456 return false;
457}
458
459static bool mv88e6xxx_6165_family(struct dsa_switch *ds)
460{
461 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
462
463 switch (ps->id) {
464 case PORT_SWITCH_ID_6123:
465 case PORT_SWITCH_ID_6161:
466 case PORT_SWITCH_ID_6165:
467 return true;
468 }
469 return false;
470}
471
472static bool mv88e6xxx_6185_family(struct dsa_switch *ds)
473{
474 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
475
476 switch (ps->id) {
477 case PORT_SWITCH_ID_6121:
478 case PORT_SWITCH_ID_6122:
479 case PORT_SWITCH_ID_6152:
480 case PORT_SWITCH_ID_6155:
481 case PORT_SWITCH_ID_6182:
482 case PORT_SWITCH_ID_6185:
483 case PORT_SWITCH_ID_6108:
484 case PORT_SWITCH_ID_6131:
485 return true;
486 }
487 return false;
488}
489
490static bool mv88e6xxx_6351_family(struct dsa_switch *ds)
491{
492 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
493
494 switch (ps->id) {
495 case PORT_SWITCH_ID_6171:
496 case PORT_SWITCH_ID_6175:
497 case PORT_SWITCH_ID_6350:
498 case PORT_SWITCH_ID_6351:
499 return true;
500 }
501 return false;
502}
503
f3a8b6b6
AL
504static bool mv88e6xxx_6352_family(struct dsa_switch *ds)
505{
506 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
507
508 switch (ps->id) {
f3a8b6b6
AL
509 case PORT_SWITCH_ID_6172:
510 case PORT_SWITCH_ID_6176:
54d792f2
AL
511 case PORT_SWITCH_ID_6240:
512 case PORT_SWITCH_ID_6352:
f3a8b6b6
AL
513 return true;
514 }
515 return false;
516}
517
91da11f8
LB
518static int mv88e6xxx_stats_wait(struct dsa_switch *ds)
519{
520 int ret;
521 int i;
522
523 for (i = 0; i < 10; i++) {
cca8b133
AL
524 ret = REG_READ(REG_GLOBAL, GLOBAL_STATS_OP);
525 if ((ret & GLOBAL_STATS_OP_BUSY) == 0)
91da11f8
LB
526 return 0;
527 }
528
529 return -ETIMEDOUT;
530}
531
532static int mv88e6xxx_stats_snapshot(struct dsa_switch *ds, int port)
533{
534 int ret;
535
f3a8b6b6
AL
536 if (mv88e6xxx_6352_family(ds))
537 port = (port + 1) << 5;
538
3675c8d7 539 /* Snapshot the hardware statistics counters for this port. */
cca8b133
AL
540 REG_WRITE(REG_GLOBAL, GLOBAL_STATS_OP,
541 GLOBAL_STATS_OP_CAPTURE_PORT |
542 GLOBAL_STATS_OP_HIST_RX_TX | port);
91da11f8 543
3675c8d7 544 /* Wait for the snapshotting to complete. */
91da11f8
LB
545 ret = mv88e6xxx_stats_wait(ds);
546 if (ret < 0)
547 return ret;
548
549 return 0;
550}
551
552static void mv88e6xxx_stats_read(struct dsa_switch *ds, int stat, u32 *val)
553{
554 u32 _val;
555 int ret;
556
557 *val = 0;
558
cca8b133
AL
559 ret = mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_STATS_OP,
560 GLOBAL_STATS_OP_READ_CAPTURED |
561 GLOBAL_STATS_OP_HIST_RX_TX | stat);
91da11f8
LB
562 if (ret < 0)
563 return;
564
565 ret = mv88e6xxx_stats_wait(ds);
566 if (ret < 0)
567 return;
568
cca8b133 569 ret = mv88e6xxx_reg_read(ds, REG_GLOBAL, GLOBAL_STATS_COUNTER_32);
91da11f8
LB
570 if (ret < 0)
571 return;
572
573 _val = ret << 16;
574
cca8b133 575 ret = mv88e6xxx_reg_read(ds, REG_GLOBAL, GLOBAL_STATS_COUNTER_01);
91da11f8
LB
576 if (ret < 0)
577 return;
578
579 *val = _val | ret;
580}
581
e413e7e1
AL
582static struct mv88e6xxx_hw_stat mv88e6xxx_hw_stats[] = {
583 { "in_good_octets", 8, 0x00, },
584 { "in_bad_octets", 4, 0x02, },
585 { "in_unicast", 4, 0x04, },
586 { "in_broadcasts", 4, 0x06, },
587 { "in_multicasts", 4, 0x07, },
588 { "in_pause", 4, 0x16, },
589 { "in_undersize", 4, 0x18, },
590 { "in_fragments", 4, 0x19, },
591 { "in_oversize", 4, 0x1a, },
592 { "in_jabber", 4, 0x1b, },
593 { "in_rx_error", 4, 0x1c, },
594 { "in_fcs_error", 4, 0x1d, },
595 { "out_octets", 8, 0x0e, },
596 { "out_unicast", 4, 0x10, },
597 { "out_broadcasts", 4, 0x13, },
598 { "out_multicasts", 4, 0x12, },
599 { "out_pause", 4, 0x15, },
600 { "excessive", 4, 0x11, },
601 { "collisions", 4, 0x1e, },
602 { "deferred", 4, 0x05, },
603 { "single", 4, 0x14, },
604 { "multiple", 4, 0x17, },
605 { "out_fcs_error", 4, 0x03, },
606 { "late", 4, 0x1f, },
607 { "hist_64bytes", 4, 0x08, },
608 { "hist_65_127bytes", 4, 0x09, },
609 { "hist_128_255bytes", 4, 0x0a, },
610 { "hist_256_511bytes", 4, 0x0b, },
611 { "hist_512_1023bytes", 4, 0x0c, },
612 { "hist_1024_max_bytes", 4, 0x0d, },
613 /* Not all devices have the following counters */
614 { "sw_in_discards", 4, 0x110, },
615 { "sw_in_filtered", 2, 0x112, },
616 { "sw_out_filtered", 2, 0x113, },
617
618};
619
620static bool have_sw_in_discards(struct dsa_switch *ds)
621{
622 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
623
624 switch (ps->id) {
cca8b133
AL
625 case PORT_SWITCH_ID_6095: case PORT_SWITCH_ID_6161:
626 case PORT_SWITCH_ID_6165: case PORT_SWITCH_ID_6171:
627 case PORT_SWITCH_ID_6172: case PORT_SWITCH_ID_6176:
628 case PORT_SWITCH_ID_6182: case PORT_SWITCH_ID_6185:
629 case PORT_SWITCH_ID_6352:
e413e7e1
AL
630 return true;
631 default:
632 return false;
633 }
634}
635
636static void _mv88e6xxx_get_strings(struct dsa_switch *ds,
637 int nr_stats,
638 struct mv88e6xxx_hw_stat *stats,
639 int port, uint8_t *data)
91da11f8
LB
640{
641 int i;
642
643 for (i = 0; i < nr_stats; i++) {
644 memcpy(data + i * ETH_GSTRING_LEN,
645 stats[i].string, ETH_GSTRING_LEN);
646 }
647}
648
e413e7e1
AL
649static void _mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds,
650 int nr_stats,
651 struct mv88e6xxx_hw_stat *stats,
652 int port, uint64_t *data)
91da11f8 653{
a22adce5 654 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
91da11f8
LB
655 int ret;
656 int i;
657
658 mutex_lock(&ps->stats_mutex);
659
660 ret = mv88e6xxx_stats_snapshot(ds, port);
661 if (ret < 0) {
662 mutex_unlock(&ps->stats_mutex);
663 return;
664 }
665
3675c8d7 666 /* Read each of the counters. */
91da11f8
LB
667 for (i = 0; i < nr_stats; i++) {
668 struct mv88e6xxx_hw_stat *s = stats + i;
669 u32 low;
17ee3e04
GR
670 u32 high = 0;
671
672 if (s->reg >= 0x100) {
17ee3e04
GR
673 ret = mv88e6xxx_reg_read(ds, REG_PORT(port),
674 s->reg - 0x100);
675 if (ret < 0)
676 goto error;
677 low = ret;
678 if (s->sizeof_stat == 4) {
679 ret = mv88e6xxx_reg_read(ds, REG_PORT(port),
680 s->reg - 0x100 + 1);
681 if (ret < 0)
682 goto error;
683 high = ret;
684 }
685 data[i] = (((u64)high) << 16) | low;
686 continue;
687 }
91da11f8
LB
688 mv88e6xxx_stats_read(ds, s->reg, &low);
689 if (s->sizeof_stat == 8)
690 mv88e6xxx_stats_read(ds, s->reg + 1, &high);
91da11f8
LB
691
692 data[i] = (((u64)high) << 32) | low;
693 }
17ee3e04 694error:
91da11f8
LB
695 mutex_unlock(&ps->stats_mutex);
696}
98e67308 697
e413e7e1
AL
698/* All the statistics in the table */
699void
700mv88e6xxx_get_strings(struct dsa_switch *ds, int port, uint8_t *data)
701{
702 if (have_sw_in_discards(ds))
703 _mv88e6xxx_get_strings(ds, ARRAY_SIZE(mv88e6xxx_hw_stats),
704 mv88e6xxx_hw_stats, port, data);
705 else
706 _mv88e6xxx_get_strings(ds, ARRAY_SIZE(mv88e6xxx_hw_stats) - 3,
707 mv88e6xxx_hw_stats, port, data);
708}
709
710int mv88e6xxx_get_sset_count(struct dsa_switch *ds)
711{
712 if (have_sw_in_discards(ds))
713 return ARRAY_SIZE(mv88e6xxx_hw_stats);
714 return ARRAY_SIZE(mv88e6xxx_hw_stats) - 3;
715}
716
717void
718mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds,
719 int port, uint64_t *data)
720{
721 if (have_sw_in_discards(ds))
722 _mv88e6xxx_get_ethtool_stats(
723 ds, ARRAY_SIZE(mv88e6xxx_hw_stats),
724 mv88e6xxx_hw_stats, port, data);
725 else
726 _mv88e6xxx_get_ethtool_stats(
727 ds, ARRAY_SIZE(mv88e6xxx_hw_stats) - 3,
728 mv88e6xxx_hw_stats, port, data);
729}
730
a1ab91f3
GR
731int mv88e6xxx_get_regs_len(struct dsa_switch *ds, int port)
732{
733 return 32 * sizeof(u16);
734}
735
736void mv88e6xxx_get_regs(struct dsa_switch *ds, int port,
737 struct ethtool_regs *regs, void *_p)
738{
739 u16 *p = _p;
740 int i;
741
742 regs->version = 0;
743
744 memset(p, 0xff, 32 * sizeof(u16));
745
746 for (i = 0; i < 32; i++) {
747 int ret;
748
749 ret = mv88e6xxx_reg_read(ds, REG_PORT(port), i);
750 if (ret >= 0)
751 p[i] = ret;
752 }
753}
754
eaa23765
AL
755#ifdef CONFIG_NET_DSA_HWMON
756
757int mv88e6xxx_get_temp(struct dsa_switch *ds, int *temp)
758{
759 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
760 int ret;
761 int val;
762
763 *temp = 0;
764
765 mutex_lock(&ps->phy_mutex);
766
fd3a0ee4 767 ret = _mv88e6xxx_phy_write(ds, 0x0, 0x16, 0x6);
eaa23765
AL
768 if (ret < 0)
769 goto error;
770
771 /* Enable temperature sensor */
fd3a0ee4 772 ret = _mv88e6xxx_phy_read(ds, 0x0, 0x1a);
eaa23765
AL
773 if (ret < 0)
774 goto error;
775
fd3a0ee4 776 ret = _mv88e6xxx_phy_write(ds, 0x0, 0x1a, ret | (1 << 5));
eaa23765
AL
777 if (ret < 0)
778 goto error;
779
780 /* Wait for temperature to stabilize */
781 usleep_range(10000, 12000);
782
fd3a0ee4 783 val = _mv88e6xxx_phy_read(ds, 0x0, 0x1a);
eaa23765
AL
784 if (val < 0) {
785 ret = val;
786 goto error;
787 }
788
789 /* Disable temperature sensor */
fd3a0ee4 790 ret = _mv88e6xxx_phy_write(ds, 0x0, 0x1a, ret & ~(1 << 5));
eaa23765
AL
791 if (ret < 0)
792 goto error;
793
794 *temp = ((val & 0x1f) - 5) * 5;
795
796error:
fd3a0ee4 797 _mv88e6xxx_phy_write(ds, 0x0, 0x16, 0x0);
eaa23765
AL
798 mutex_unlock(&ps->phy_mutex);
799 return ret;
800}
801#endif /* CONFIG_NET_DSA_HWMON */
802
f3044683
AL
803static int mv88e6xxx_wait(struct dsa_switch *ds, int reg, int offset, u16 mask)
804{
805 unsigned long timeout = jiffies + HZ / 10;
806
807 while (time_before(jiffies, timeout)) {
808 int ret;
809
810 ret = REG_READ(reg, offset);
811 if (!(ret & mask))
812 return 0;
813
814 usleep_range(1000, 2000);
815 }
816 return -ETIMEDOUT;
817}
818
819int mv88e6xxx_phy_wait(struct dsa_switch *ds)
820{
cca8b133
AL
821 return mv88e6xxx_wait(ds, REG_GLOBAL2, GLOBAL2_SMI_OP,
822 GLOBAL2_SMI_OP_BUSY);
f3044683
AL
823}
824
825int mv88e6xxx_eeprom_load_wait(struct dsa_switch *ds)
826{
cca8b133
AL
827 return mv88e6xxx_wait(ds, REG_GLOBAL2, GLOBAL2_EEPROM_OP,
828 GLOBAL2_EEPROM_OP_LOAD);
f3044683
AL
829}
830
831int mv88e6xxx_eeprom_busy_wait(struct dsa_switch *ds)
832{
cca8b133
AL
833 return mv88e6xxx_wait(ds, REG_GLOBAL2, GLOBAL2_EEPROM_OP,
834 GLOBAL2_EEPROM_OP_BUSY);
f3044683
AL
835}
836
facd95b2
GR
837/* Must be called with SMI lock held */
838static int _mv88e6xxx_wait(struct dsa_switch *ds, int reg, int offset, u16 mask)
839{
840 unsigned long timeout = jiffies + HZ / 10;
841
842 while (time_before(jiffies, timeout)) {
843 int ret;
844
845 ret = _mv88e6xxx_reg_read(ds, reg, offset);
846 if (ret < 0)
847 return ret;
848 if (!(ret & mask))
849 return 0;
850
851 usleep_range(1000, 2000);
852 }
853 return -ETIMEDOUT;
854}
855
856/* Must be called with SMI lock held */
857static int _mv88e6xxx_atu_wait(struct dsa_switch *ds)
858{
cca8b133
AL
859 return _mv88e6xxx_wait(ds, REG_GLOBAL, GLOBAL_ATU_OP,
860 GLOBAL_ATU_OP_BUSY);
facd95b2
GR
861}
862
fd3a0ee4
AL
863/* Must be called with phy mutex held */
864static int _mv88e6xxx_phy_read_indirect(struct dsa_switch *ds, int addr,
865 int regnum)
f3044683
AL
866{
867 int ret;
868
cca8b133
AL
869 REG_WRITE(REG_GLOBAL2, GLOBAL2_SMI_OP,
870 GLOBAL2_SMI_OP_22_READ | (addr << 5) | regnum);
f3044683
AL
871
872 ret = mv88e6xxx_phy_wait(ds);
873 if (ret < 0)
874 return ret;
875
cca8b133 876 return REG_READ(REG_GLOBAL2, GLOBAL2_SMI_DATA);
f3044683
AL
877}
878
fd3a0ee4
AL
879/* Must be called with phy mutex held */
880static int _mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int addr,
881 int regnum, u16 val)
f3044683 882{
cca8b133
AL
883 REG_WRITE(REG_GLOBAL2, GLOBAL2_SMI_DATA, val);
884 REG_WRITE(REG_GLOBAL2, GLOBAL2_SMI_OP,
885 GLOBAL2_SMI_OP_22_WRITE | (addr << 5) | regnum);
f3044683
AL
886
887 return mv88e6xxx_phy_wait(ds);
888}
889
11b3b45d
GR
890int mv88e6xxx_get_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e)
891{
2f40c698 892 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
11b3b45d
GR
893 int reg;
894
2f40c698
AL
895 mutex_lock(&ps->phy_mutex);
896
897 reg = _mv88e6xxx_phy_read_indirect(ds, port, 16);
11b3b45d 898 if (reg < 0)
2f40c698 899 goto out;
11b3b45d
GR
900
901 e->eee_enabled = !!(reg & 0x0200);
902 e->tx_lpi_enabled = !!(reg & 0x0100);
903
cca8b133 904 reg = mv88e6xxx_reg_read(ds, REG_PORT(port), PORT_STATUS);
11b3b45d 905 if (reg < 0)
2f40c698 906 goto out;
11b3b45d 907
cca8b133 908 e->eee_active = !!(reg & PORT_STATUS_EEE);
2f40c698 909 reg = 0;
11b3b45d 910
2f40c698
AL
911out:
912 mutex_unlock(&ps->phy_mutex);
913 return reg;
11b3b45d
GR
914}
915
916int mv88e6xxx_set_eee(struct dsa_switch *ds, int port,
917 struct phy_device *phydev, struct ethtool_eee *e)
918{
2f40c698
AL
919 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
920 int reg;
11b3b45d
GR
921 int ret;
922
2f40c698 923 mutex_lock(&ps->phy_mutex);
11b3b45d 924
2f40c698
AL
925 ret = _mv88e6xxx_phy_read_indirect(ds, port, 16);
926 if (ret < 0)
927 goto out;
928
929 reg = ret & ~0x0300;
930 if (e->eee_enabled)
931 reg |= 0x0200;
932 if (e->tx_lpi_enabled)
933 reg |= 0x0100;
934
935 ret = _mv88e6xxx_phy_write_indirect(ds, port, 16, reg);
936out:
937 mutex_unlock(&ps->phy_mutex);
938
939 return ret;
11b3b45d
GR
940}
941
facd95b2
GR
942static int _mv88e6xxx_atu_cmd(struct dsa_switch *ds, int fid, u16 cmd)
943{
944 int ret;
945
946 ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, 0x01, fid);
947 if (ret < 0)
948 return ret;
949
cca8b133 950 ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_ATU_OP, cmd);
facd95b2
GR
951 if (ret < 0)
952 return ret;
953
954 return _mv88e6xxx_atu_wait(ds);
955}
956
957static int _mv88e6xxx_flush_fid(struct dsa_switch *ds, int fid)
958{
959 int ret;
960
961 ret = _mv88e6xxx_atu_wait(ds);
962 if (ret < 0)
963 return ret;
964
cca8b133 965 return _mv88e6xxx_atu_cmd(ds, fid, GLOBAL_ATU_OP_FLUSH_NON_STATIC_DB);
facd95b2
GR
966}
967
968static int mv88e6xxx_set_port_state(struct dsa_switch *ds, int port, u8 state)
969{
970 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
c3ffe6d2 971 int reg, ret = 0;
facd95b2
GR
972 u8 oldstate;
973
974 mutex_lock(&ps->smi_mutex);
975
cca8b133 976 reg = _mv88e6xxx_reg_read(ds, REG_PORT(port), PORT_CONTROL);
538cc282
GR
977 if (reg < 0) {
978 ret = reg;
facd95b2 979 goto abort;
538cc282 980 }
facd95b2 981
cca8b133 982 oldstate = reg & PORT_CONTROL_STATE_MASK;
facd95b2
GR
983 if (oldstate != state) {
984 /* Flush forwarding database if we're moving a port
985 * from Learning or Forwarding state to Disabled or
986 * Blocking or Listening state.
987 */
cca8b133
AL
988 if (oldstate >= PORT_CONTROL_STATE_LEARNING &&
989 state <= PORT_CONTROL_STATE_BLOCKING) {
facd95b2
GR
990 ret = _mv88e6xxx_flush_fid(ds, ps->fid[port]);
991 if (ret)
992 goto abort;
993 }
cca8b133
AL
994 reg = (reg & ~PORT_CONTROL_STATE_MASK) | state;
995 ret = _mv88e6xxx_reg_write(ds, REG_PORT(port), PORT_CONTROL,
996 reg);
facd95b2
GR
997 }
998
999abort:
1000 mutex_unlock(&ps->smi_mutex);
1001 return ret;
1002}
1003
1004/* Must be called with smi lock held */
1005static int _mv88e6xxx_update_port_config(struct dsa_switch *ds, int port)
1006{
1007 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1008 u8 fid = ps->fid[port];
1009 u16 reg = fid << 12;
1010
1011 if (dsa_is_cpu_port(ds, port))
1012 reg |= ds->phys_port_mask;
1013 else
1014 reg |= (ps->bridge_mask[fid] |
1015 (1 << dsa_upstream_port(ds))) & ~(1 << port);
1016
cca8b133 1017 return _mv88e6xxx_reg_write(ds, REG_PORT(port), PORT_BASE_VLAN, reg);
facd95b2
GR
1018}
1019
1020/* Must be called with smi lock held */
1021static int _mv88e6xxx_update_bridge_config(struct dsa_switch *ds, int fid)
1022{
1023 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1024 int port;
1025 u32 mask;
1026 int ret;
1027
1028 mask = ds->phys_port_mask;
1029 while (mask) {
1030 port = __ffs(mask);
1031 mask &= ~(1 << port);
1032 if (ps->fid[port] != fid)
1033 continue;
1034
1035 ret = _mv88e6xxx_update_port_config(ds, port);
1036 if (ret)
1037 return ret;
1038 }
1039
1040 return _mv88e6xxx_flush_fid(ds, fid);
1041}
1042
1043/* Bridge handling functions */
1044
1045int mv88e6xxx_join_bridge(struct dsa_switch *ds, int port, u32 br_port_mask)
1046{
1047 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1048 int ret = 0;
1049 u32 nmask;
1050 int fid;
1051
1052 /* If the bridge group is not empty, join that group.
1053 * Otherwise create a new group.
1054 */
1055 fid = ps->fid[port];
1056 nmask = br_port_mask & ~(1 << port);
1057 if (nmask)
1058 fid = ps->fid[__ffs(nmask)];
1059
1060 nmask = ps->bridge_mask[fid] | (1 << port);
1061 if (nmask != br_port_mask) {
1062 netdev_err(ds->ports[port],
1063 "join: Bridge port mask mismatch fid=%d mask=0x%x expected 0x%x\n",
1064 fid, br_port_mask, nmask);
1065 return -EINVAL;
1066 }
1067
1068 mutex_lock(&ps->smi_mutex);
1069
1070 ps->bridge_mask[fid] = br_port_mask;
1071
1072 if (fid != ps->fid[port]) {
1073 ps->fid_mask |= 1 << ps->fid[port];
1074 ps->fid[port] = fid;
1075 ret = _mv88e6xxx_update_bridge_config(ds, fid);
1076 }
1077
1078 mutex_unlock(&ps->smi_mutex);
1079
1080 return ret;
1081}
1082
1083int mv88e6xxx_leave_bridge(struct dsa_switch *ds, int port, u32 br_port_mask)
1084{
1085 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1086 u8 fid, newfid;
1087 int ret;
1088
1089 fid = ps->fid[port];
1090
1091 if (ps->bridge_mask[fid] != br_port_mask) {
1092 netdev_err(ds->ports[port],
1093 "leave: Bridge port mask mismatch fid=%d mask=0x%x expected 0x%x\n",
1094 fid, br_port_mask, ps->bridge_mask[fid]);
1095 return -EINVAL;
1096 }
1097
1098 /* If the port was the last port of a bridge, we are done.
1099 * Otherwise assign a new fid to the port, and fix up
1100 * the bridge configuration.
1101 */
1102 if (br_port_mask == (1 << port))
1103 return 0;
1104
1105 mutex_lock(&ps->smi_mutex);
1106
1107 newfid = __ffs(ps->fid_mask);
1108 ps->fid[port] = newfid;
1109 ps->fid_mask &= (1 << newfid);
1110 ps->bridge_mask[fid] &= ~(1 << port);
1111 ps->bridge_mask[newfid] = 1 << port;
1112
1113 ret = _mv88e6xxx_update_bridge_config(ds, fid);
1114 if (!ret)
1115 ret = _mv88e6xxx_update_bridge_config(ds, newfid);
1116
1117 mutex_unlock(&ps->smi_mutex);
1118
1119 return ret;
1120}
1121
1122int mv88e6xxx_port_stp_update(struct dsa_switch *ds, int port, u8 state)
1123{
1124 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1125 int stp_state;
1126
1127 switch (state) {
1128 case BR_STATE_DISABLED:
cca8b133 1129 stp_state = PORT_CONTROL_STATE_DISABLED;
facd95b2
GR
1130 break;
1131 case BR_STATE_BLOCKING:
1132 case BR_STATE_LISTENING:
cca8b133 1133 stp_state = PORT_CONTROL_STATE_BLOCKING;
facd95b2
GR
1134 break;
1135 case BR_STATE_LEARNING:
cca8b133 1136 stp_state = PORT_CONTROL_STATE_LEARNING;
facd95b2
GR
1137 break;
1138 case BR_STATE_FORWARDING:
1139 default:
cca8b133 1140 stp_state = PORT_CONTROL_STATE_FORWARDING;
facd95b2
GR
1141 break;
1142 }
1143
1144 netdev_dbg(ds->ports[port], "port state %d [%d]\n", state, stp_state);
1145
1146 /* mv88e6xxx_port_stp_update may be called with softirqs disabled,
1147 * so we can not update the port state directly but need to schedule it.
1148 */
1149 ps->port_state[port] = stp_state;
1150 set_bit(port, &ps->port_state_update_mask);
1151 schedule_work(&ps->bridge_work);
1152
1153 return 0;
1154}
1155
defb05b9
GR
1156static int __mv88e6xxx_write_addr(struct dsa_switch *ds,
1157 const unsigned char *addr)
1158{
1159 int i, ret;
1160
1161 for (i = 0; i < 3; i++) {
cca8b133
AL
1162 ret = _mv88e6xxx_reg_write(
1163 ds, REG_GLOBAL, GLOBAL_ATU_MAC_01 + i,
1164 (addr[i * 2] << 8) | addr[i * 2 + 1]);
defb05b9
GR
1165 if (ret < 0)
1166 return ret;
1167 }
1168
1169 return 0;
1170}
1171
1172static int __mv88e6xxx_read_addr(struct dsa_switch *ds, unsigned char *addr)
1173{
1174 int i, ret;
1175
1176 for (i = 0; i < 3; i++) {
cca8b133
AL
1177 ret = _mv88e6xxx_reg_read(ds, REG_GLOBAL,
1178 GLOBAL_ATU_MAC_01 + i);
defb05b9
GR
1179 if (ret < 0)
1180 return ret;
1181 addr[i * 2] = ret >> 8;
1182 addr[i * 2 + 1] = ret & 0xff;
1183 }
1184
1185 return 0;
1186}
1187
1188static int __mv88e6xxx_port_fdb_cmd(struct dsa_switch *ds, int port,
1189 const unsigned char *addr, int state)
1190{
1191 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1192 u8 fid = ps->fid[port];
1193 int ret;
1194
1195 ret = _mv88e6xxx_atu_wait(ds);
1196 if (ret < 0)
1197 return ret;
1198
1199 ret = __mv88e6xxx_write_addr(ds, addr);
1200 if (ret < 0)
1201 return ret;
1202
cca8b133 1203 ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_ATU_DATA,
defb05b9
GR
1204 (0x10 << port) | state);
1205 if (ret)
1206 return ret;
1207
cca8b133 1208 ret = _mv88e6xxx_atu_cmd(ds, fid, GLOBAL_ATU_OP_LOAD_DB);
defb05b9
GR
1209
1210 return ret;
1211}
1212
1213int mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port,
1214 const unsigned char *addr, u16 vid)
1215{
1216 int state = is_multicast_ether_addr(addr) ?
cca8b133
AL
1217 GLOBAL_ATU_DATA_STATE_MC_STATIC :
1218 GLOBAL_ATU_DATA_STATE_UC_STATIC;
defb05b9
GR
1219 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1220 int ret;
1221
1222 mutex_lock(&ps->smi_mutex);
1223 ret = __mv88e6xxx_port_fdb_cmd(ds, port, addr, state);
1224 mutex_unlock(&ps->smi_mutex);
1225
1226 return ret;
1227}
1228
1229int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port,
1230 const unsigned char *addr, u16 vid)
1231{
1232 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1233 int ret;
1234
1235 mutex_lock(&ps->smi_mutex);
cca8b133
AL
1236 ret = __mv88e6xxx_port_fdb_cmd(ds, port, addr,
1237 GLOBAL_ATU_DATA_STATE_UNUSED);
defb05b9
GR
1238 mutex_unlock(&ps->smi_mutex);
1239
1240 return ret;
1241}
1242
1243static int __mv88e6xxx_port_getnext(struct dsa_switch *ds, int port,
1244 unsigned char *addr, bool *is_static)
1245{
1246 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1247 u8 fid = ps->fid[port];
1248 int ret, state;
1249
1250 ret = _mv88e6xxx_atu_wait(ds);
1251 if (ret < 0)
1252 return ret;
1253
1254 ret = __mv88e6xxx_write_addr(ds, addr);
1255 if (ret < 0)
1256 return ret;
1257
1258 do {
cca8b133 1259 ret = _mv88e6xxx_atu_cmd(ds, fid, GLOBAL_ATU_OP_GET_NEXT_DB);
defb05b9
GR
1260 if (ret < 0)
1261 return ret;
1262
cca8b133 1263 ret = _mv88e6xxx_reg_read(ds, REG_GLOBAL, GLOBAL_ATU_DATA);
defb05b9
GR
1264 if (ret < 0)
1265 return ret;
cca8b133
AL
1266 state = ret & GLOBAL_ATU_DATA_STATE_MASK;
1267 if (state == GLOBAL_ATU_DATA_STATE_UNUSED)
defb05b9
GR
1268 return -ENOENT;
1269 } while (!(((ret >> 4) & 0xff) & (1 << port)));
1270
1271 ret = __mv88e6xxx_read_addr(ds, addr);
1272 if (ret < 0)
1273 return ret;
1274
1275 *is_static = state == (is_multicast_ether_addr(addr) ?
cca8b133
AL
1276 GLOBAL_ATU_DATA_STATE_MC_STATIC :
1277 GLOBAL_ATU_DATA_STATE_UC_STATIC);
defb05b9
GR
1278
1279 return 0;
1280}
1281
1282/* get next entry for port */
1283int mv88e6xxx_port_fdb_getnext(struct dsa_switch *ds, int port,
1284 unsigned char *addr, bool *is_static)
1285{
1286 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1287 int ret;
1288
1289 mutex_lock(&ps->smi_mutex);
1290 ret = __mv88e6xxx_port_getnext(ds, port, addr, is_static);
1291 mutex_unlock(&ps->smi_mutex);
1292
1293 return ret;
1294}
1295
facd95b2
GR
1296static void mv88e6xxx_bridge_work(struct work_struct *work)
1297{
1298 struct mv88e6xxx_priv_state *ps;
1299 struct dsa_switch *ds;
1300 int port;
1301
1302 ps = container_of(work, struct mv88e6xxx_priv_state, bridge_work);
1303 ds = ((struct dsa_switch *)ps) - 1;
1304
1305 while (ps->port_state_update_mask) {
1306 port = __ffs(ps->port_state_update_mask);
1307 clear_bit(port, &ps->port_state_update_mask);
1308 mv88e6xxx_set_port_state(ds, port, ps->port_state[port]);
1309 }
1310}
1311
54d792f2 1312int mv88e6xxx_setup_port(struct dsa_switch *ds, int port)
d827e88a
GR
1313{
1314 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
facd95b2 1315 int ret, fid;
54d792f2 1316 u16 reg;
d827e88a
GR
1317
1318 mutex_lock(&ps->smi_mutex);
1319
54d792f2
AL
1320 if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) ||
1321 mv88e6xxx_6165_family(ds) || mv88e6xxx_6097_family(ds) ||
1322 mv88e6xxx_6185_family(ds) || mv88e6xxx_6095_family(ds) ||
1323 mv88e6xxx_6065_family(ds)) {
1324 /* MAC Forcing register: don't force link, speed,
1325 * duplex or flow control state to any particular
1326 * values on physical ports, but force the CPU port
1327 * and all DSA ports to their maximum bandwidth and
1328 * full duplex.
1329 */
1330 reg = _mv88e6xxx_reg_read(ds, REG_PORT(port), PORT_PCS_CTRL);
1331 if (dsa_is_cpu_port(ds, port) ||
1332 ds->dsa_port_mask & (1 << port)) {
1333 reg |= PORT_PCS_CTRL_FORCE_LINK |
1334 PORT_PCS_CTRL_LINK_UP |
1335 PORT_PCS_CTRL_DUPLEX_FULL |
1336 PORT_PCS_CTRL_FORCE_DUPLEX;
1337 if (mv88e6xxx_6065_family(ds))
1338 reg |= PORT_PCS_CTRL_100;
1339 else
1340 reg |= PORT_PCS_CTRL_1000;
1341 } else {
1342 reg |= PORT_PCS_CTRL_UNFORCED;
1343 }
1344
1345 ret = _mv88e6xxx_reg_write(ds, REG_PORT(port),
1346 PORT_PCS_CTRL, reg);
1347 if (ret)
1348 goto abort;
1349 }
1350
1351 /* Port Control: disable Drop-on-Unlock, disable Drop-on-Lock,
1352 * disable Header mode, enable IGMP/MLD snooping, disable VLAN
1353 * tunneling, determine priority by looking at 802.1p and IP
1354 * priority fields (IP prio has precedence), and set STP state
1355 * to Forwarding.
1356 *
1357 * If this is the CPU link, use DSA or EDSA tagging depending
1358 * on which tagging mode was configured.
1359 *
1360 * If this is a link to another switch, use DSA tagging mode.
1361 *
1362 * If this is the upstream port for this switch, enable
1363 * forwarding of unknown unicasts and multicasts.
1364 */
1365 reg = 0;
1366 if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) ||
1367 mv88e6xxx_6165_family(ds) || mv88e6xxx_6097_family(ds) ||
1368 mv88e6xxx_6095_family(ds) || mv88e6xxx_6065_family(ds) ||
1369 mv88e6xxx_6185_family(ds))
1370 reg = PORT_CONTROL_IGMP_MLD_SNOOP |
1371 PORT_CONTROL_USE_TAG | PORT_CONTROL_USE_IP |
1372 PORT_CONTROL_STATE_FORWARDING;
1373 if (dsa_is_cpu_port(ds, port)) {
1374 if (mv88e6xxx_6095_family(ds) || mv88e6xxx_6185_family(ds))
1375 reg |= PORT_CONTROL_DSA_TAG;
1376 if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) ||
1377 mv88e6xxx_6165_family(ds) || mv88e6xxx_6097_family(ds)) {
1378 if (ds->dst->tag_protocol == DSA_TAG_PROTO_EDSA)
1379 reg |= PORT_CONTROL_FRAME_ETHER_TYPE_DSA;
1380 else
1381 reg |= PORT_CONTROL_FRAME_MODE_DSA;
1382 }
1383
1384 if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) ||
1385 mv88e6xxx_6165_family(ds) || mv88e6xxx_6097_family(ds) ||
1386 mv88e6xxx_6095_family(ds) || mv88e6xxx_6065_family(ds) ||
1387 mv88e6xxx_6185_family(ds)) {
1388 if (ds->dst->tag_protocol == DSA_TAG_PROTO_EDSA)
1389 reg |= PORT_CONTROL_EGRESS_ADD_TAG;
1390 }
1391 }
1392 if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) ||
1393 mv88e6xxx_6165_family(ds) || mv88e6xxx_6097_family(ds) ||
1394 mv88e6xxx_6095_family(ds) || mv88e6xxx_6065_family(ds)) {
1395 if (ds->dsa_port_mask & (1 << port))
1396 reg |= PORT_CONTROL_FRAME_MODE_DSA;
1397 if (port == dsa_upstream_port(ds))
1398 reg |= PORT_CONTROL_FORWARD_UNKNOWN |
1399 PORT_CONTROL_FORWARD_UNKNOWN_MC;
1400 }
1401 if (reg) {
1402 ret = _mv88e6xxx_reg_write(ds, REG_PORT(port),
1403 PORT_CONTROL, reg);
1404 if (ret)
1405 goto abort;
1406 }
1407
1408 /* Port Control 2: don't force a good FCS, set the maximum
1409 * frame size to 10240 bytes, don't let the switch add or
1410 * strip 802.1q tags, don't discard tagged or untagged frames
1411 * on this port, do a destination address lookup on all
1412 * received packets as usual, disable ARP mirroring and don't
1413 * send a copy of all transmitted/received frames on this port
1414 * to the CPU.
1415 */
1416 reg = 0;
1417 if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) ||
1418 mv88e6xxx_6165_family(ds) || mv88e6xxx_6097_family(ds) ||
1419 mv88e6xxx_6095_family(ds))
1420 reg = PORT_CONTROL_2_MAP_DA;
1421
1422 if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) ||
1423 mv88e6xxx_6165_family(ds))
1424 reg |= PORT_CONTROL_2_JUMBO_10240;
1425
1426 if (mv88e6xxx_6095_family(ds) || mv88e6xxx_6185_family(ds)) {
1427 /* Set the upstream port this port should use */
1428 reg |= dsa_upstream_port(ds);
1429 /* enable forwarding of unknown multicast addresses to
1430 * the upstream port
1431 */
1432 if (port == dsa_upstream_port(ds))
1433 reg |= PORT_CONTROL_2_FORWARD_UNKNOWN;
1434 }
1435
1436 if (reg) {
1437 ret = _mv88e6xxx_reg_write(ds, REG_PORT(port),
1438 PORT_CONTROL_2, reg);
1439 if (ret)
1440 goto abort;
1441 }
1442
1443 /* Port Association Vector: when learning source addresses
1444 * of packets, add the address to the address database using
1445 * a port bitmap that has only the bit for this port set and
1446 * the other bits clear.
1447 */
1448 ret = _mv88e6xxx_reg_write(ds, REG_PORT(port), PORT_ASSOC_VECTOR,
1449 1 << port);
1450 if (ret)
1451 goto abort;
1452
1453 /* Egress rate control 2: disable egress rate control. */
1454 ret = _mv88e6xxx_reg_write(ds, REG_PORT(port), PORT_RATE_CONTROL_2,
1455 0x0000);
1456 if (ret)
1457 goto abort;
1458
1459 if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) ||
1460 mv88e6xxx_6165_family(ds) || mv88e6xxx_6097_family(ds)) {
1461 /* Do not limit the period of time that this port can
1462 * be paused for by the remote end or the period of
1463 * time that this port can pause the remote end.
1464 */
1465 ret = _mv88e6xxx_reg_write(ds, REG_PORT(port),
1466 PORT_PAUSE_CTRL, 0x0000);
1467 if (ret)
1468 goto abort;
1469
1470 /* Port ATU control: disable limiting the number of
1471 * address database entries that this port is allowed
1472 * to use.
1473 */
1474 ret = _mv88e6xxx_reg_write(ds, REG_PORT(port),
1475 PORT_ATU_CONTROL, 0x0000);
1476 /* Priority Override: disable DA, SA and VTU priority
1477 * override.
1478 */
1479 ret = _mv88e6xxx_reg_write(ds, REG_PORT(port),
1480 PORT_PRI_OVERRIDE, 0x0000);
1481 if (ret)
1482 goto abort;
1483
1484 /* Port Ethertype: use the Ethertype DSA Ethertype
1485 * value.
1486 */
1487 ret = _mv88e6xxx_reg_write(ds, REG_PORT(port),
1488 PORT_ETH_TYPE, ETH_P_EDSA);
1489 if (ret)
1490 goto abort;
1491 /* Tag Remap: use an identity 802.1p prio -> switch
1492 * prio mapping.
1493 */
1494 ret = _mv88e6xxx_reg_write(ds, REG_PORT(port),
1495 PORT_TAG_REGMAP_0123, 0x3210);
1496 if (ret)
1497 goto abort;
1498
1499 /* Tag Remap 2: use an identity 802.1p prio -> switch
1500 * prio mapping.
1501 */
1502 ret = _mv88e6xxx_reg_write(ds, REG_PORT(port),
1503 PORT_TAG_REGMAP_4567, 0x7654);
1504 if (ret)
1505 goto abort;
1506 }
1507
1508 if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) ||
1509 mv88e6xxx_6165_family(ds) || mv88e6xxx_6097_family(ds) ||
1510 mv88e6xxx_6185_family(ds) || mv88e6xxx_6095_family(ds)) {
1511 /* Rate Control: disable ingress rate limiting. */
1512 ret = _mv88e6xxx_reg_write(ds, REG_PORT(port),
1513 PORT_RATE_CONTROL, 0x0001);
1514 if (ret)
1515 goto abort;
1516 }
1517
366f0a0f
GR
1518 /* Port Control 1: disable trunking, disable sending
1519 * learning messages to this port.
d827e88a 1520 */
614f03fc 1521 ret = _mv88e6xxx_reg_write(ds, REG_PORT(port), PORT_CONTROL_1, 0x0000);
d827e88a
GR
1522 if (ret)
1523 goto abort;
1524
1525 /* Port based VLAN map: give each port its own address
1526 * database, allow the CPU port to talk to each of the 'real'
1527 * ports, and allow each of the 'real' ports to only talk to
1528 * the upstream port.
1529 */
facd95b2
GR
1530 fid = __ffs(ps->fid_mask);
1531 ps->fid[port] = fid;
1532 ps->fid_mask &= ~(1 << fid);
1533
1534 if (!dsa_is_cpu_port(ds, port))
1535 ps->bridge_mask[fid] = 1 << port;
d827e88a 1536
facd95b2 1537 ret = _mv88e6xxx_update_port_config(ds, port);
d827e88a
GR
1538 if (ret)
1539 goto abort;
1540
1541 /* Default VLAN ID and priority: don't set a default VLAN
1542 * ID, and set the default packet priority to zero.
1543 */
47cf1e65
VD
1544 ret = _mv88e6xxx_reg_write(ds, REG_PORT(port), PORT_DEFAULT_VLAN,
1545 0x0000);
d827e88a
GR
1546abort:
1547 mutex_unlock(&ps->smi_mutex);
1548 return ret;
1549}
1550
acdaffcc
GR
1551int mv88e6xxx_setup_common(struct dsa_switch *ds)
1552{
1553 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1554
1555 mutex_init(&ps->smi_mutex);
1556 mutex_init(&ps->stats_mutex);
1557 mutex_init(&ps->phy_mutex);
1558
cca8b133 1559 ps->id = REG_READ(REG_PORT(0), PORT_SWITCH_ID) & 0xfff0;
a8f064c6 1560
facd95b2
GR
1561 ps->fid_mask = (1 << DSA_MAX_PORTS) - 1;
1562
1563 INIT_WORK(&ps->bridge_work, mv88e6xxx_bridge_work);
1564
acdaffcc
GR
1565 return 0;
1566}
1567
54d792f2
AL
1568int mv88e6xxx_setup_global(struct dsa_switch *ds)
1569{
1570 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1571 int i;
1572
1573 /* Set the default address aging time to 5 minutes, and
1574 * enable address learn messages to be sent to all message
1575 * ports.
1576 */
1577 REG_WRITE(REG_GLOBAL, GLOBAL_ATU_CONTROL,
1578 0x0140 | GLOBAL_ATU_CONTROL_LEARN2ALL);
1579
1580 /* Configure the IP ToS mapping registers. */
1581 REG_WRITE(REG_GLOBAL, GLOBAL_IP_PRI_0, 0x0000);
1582 REG_WRITE(REG_GLOBAL, GLOBAL_IP_PRI_1, 0x0000);
1583 REG_WRITE(REG_GLOBAL, GLOBAL_IP_PRI_2, 0x5555);
1584 REG_WRITE(REG_GLOBAL, GLOBAL_IP_PRI_3, 0x5555);
1585 REG_WRITE(REG_GLOBAL, GLOBAL_IP_PRI_4, 0xaaaa);
1586 REG_WRITE(REG_GLOBAL, GLOBAL_IP_PRI_5, 0xaaaa);
1587 REG_WRITE(REG_GLOBAL, GLOBAL_IP_PRI_6, 0xffff);
1588 REG_WRITE(REG_GLOBAL, GLOBAL_IP_PRI_7, 0xffff);
1589
1590 /* Configure the IEEE 802.1p priority mapping register. */
1591 REG_WRITE(REG_GLOBAL, GLOBAL_IEEE_PRI, 0xfa41);
1592
1593 /* Send all frames with destination addresses matching
1594 * 01:80:c2:00:00:0x to the CPU port.
1595 */
1596 REG_WRITE(REG_GLOBAL2, GLOBAL2_MGMT_EN_0X, 0xffff);
1597
1598 /* Ignore removed tag data on doubly tagged packets, disable
1599 * flow control messages, force flow control priority to the
1600 * highest, and send all special multicast frames to the CPU
1601 * port at the highest priority.
1602 */
1603 REG_WRITE(REG_GLOBAL2, GLOBAL2_SWITCH_MGMT,
1604 0x7 | GLOBAL2_SWITCH_MGMT_RSVD2CPU | 0x70 |
1605 GLOBAL2_SWITCH_MGMT_FORCE_FLOW_CTRL_PRI);
1606
1607 /* Program the DSA routing table. */
1608 for (i = 0; i < 32; i++) {
1609 int nexthop = 0x1f;
1610
1611 if (ds->pd->rtable &&
1612 i != ds->index && i < ds->dst->pd->nr_chips)
1613 nexthop = ds->pd->rtable[i] & 0x1f;
1614
1615 REG_WRITE(REG_GLOBAL2, GLOBAL2_DEVICE_MAPPING,
1616 GLOBAL2_DEVICE_MAPPING_UPDATE |
1617 (i << GLOBAL2_DEVICE_MAPPING_TARGET_SHIFT) |
1618 nexthop);
1619 }
1620
1621 /* Clear all trunk masks. */
1622 for (i = 0; i < 8; i++)
1623 REG_WRITE(REG_GLOBAL2, GLOBAL2_TRUNK_MASK,
1624 0x8000 | (i << GLOBAL2_TRUNK_MASK_NUM_SHIFT) |
1625 ((1 << ps->num_ports) - 1));
1626
1627 /* Clear all trunk mappings. */
1628 for (i = 0; i < 16; i++)
1629 REG_WRITE(REG_GLOBAL2, GLOBAL2_TRUNK_MAPPING,
1630 GLOBAL2_TRUNK_MAPPING_UPDATE |
1631 (i << GLOBAL2_TRUNK_MAPPING_ID_SHIFT));
1632
1633 if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) ||
1634 mv88e6xxx_6165_family(ds) || mv88e6xxx_6097_family(ds)) {
1635 /* Send all frames with destination addresses matching
1636 * 01:80:c2:00:00:2x to the CPU port.
1637 */
1638 REG_WRITE(REG_GLOBAL2, GLOBAL2_MGMT_EN_2X, 0xffff);
1639
1640 /* Initialise cross-chip port VLAN table to reset
1641 * defaults.
1642 */
1643 REG_WRITE(REG_GLOBAL2, GLOBAL2_PVT_ADDR, 0x9000);
1644
1645 /* Clear the priority override table. */
1646 for (i = 0; i < 16; i++)
1647 REG_WRITE(REG_GLOBAL2, GLOBAL2_PRIO_OVERRIDE,
1648 0x8000 | (i << 8));
1649 }
1650
1651 if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) ||
1652 mv88e6xxx_6165_family(ds) || mv88e6xxx_6097_family(ds) ||
1653 mv88e6xxx_6185_family(ds) || mv88e6xxx_6095_family(ds)) {
1654 /* Disable ingress rate limiting by resetting all
1655 * ingress rate limit registers to their initial
1656 * state.
1657 */
1658 for (i = 0; i < ps->num_ports; i++)
1659 REG_WRITE(REG_GLOBAL2, GLOBAL2_INGRESS_OP,
1660 0x9000 | (i << 8));
1661 }
1662
1663 return 0;
1664}
1665
143a8307
AL
1666int mv88e6xxx_switch_reset(struct dsa_switch *ds, bool ppu_active)
1667{
1668 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1669 u16 is_reset = (ppu_active ? 0x8800 : 0xc800);
1670 unsigned long timeout;
1671 int ret;
1672 int i;
1673
1674 /* Set all ports to the disabled state. */
1675 for (i = 0; i < ps->num_ports; i++) {
cca8b133
AL
1676 ret = REG_READ(REG_PORT(i), PORT_CONTROL);
1677 REG_WRITE(REG_PORT(i), PORT_CONTROL, ret & 0xfffc);
143a8307
AL
1678 }
1679
1680 /* Wait for transmit queues to drain. */
1681 usleep_range(2000, 4000);
1682
1683 /* Reset the switch. Keep the PPU active if requested. The PPU
1684 * needs to be active to support indirect phy register access
1685 * through global registers 0x18 and 0x19.
1686 */
1687 if (ppu_active)
1688 REG_WRITE(REG_GLOBAL, 0x04, 0xc000);
1689 else
1690 REG_WRITE(REG_GLOBAL, 0x04, 0xc400);
1691
1692 /* Wait up to one second for reset to complete. */
1693 timeout = jiffies + 1 * HZ;
1694 while (time_before(jiffies, timeout)) {
1695 ret = REG_READ(REG_GLOBAL, 0x00);
1696 if ((ret & is_reset) == is_reset)
1697 break;
1698 usleep_range(1000, 2000);
1699 }
1700 if (time_after(jiffies, timeout))
1701 return -ETIMEDOUT;
1702
1703 return 0;
1704}
1705
49143585
AL
1706int mv88e6xxx_phy_page_read(struct dsa_switch *ds, int port, int page, int reg)
1707{
1708 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1709 int ret;
1710
1711 mutex_lock(&ps->phy_mutex);
fd3a0ee4 1712 ret = _mv88e6xxx_phy_write_indirect(ds, port, 0x16, page);
49143585
AL
1713 if (ret < 0)
1714 goto error;
fd3a0ee4 1715 ret = _mv88e6xxx_phy_read_indirect(ds, port, reg);
49143585 1716error:
fd3a0ee4 1717 _mv88e6xxx_phy_write_indirect(ds, port, 0x16, 0x0);
49143585
AL
1718 mutex_unlock(&ps->phy_mutex);
1719 return ret;
1720}
1721
1722int mv88e6xxx_phy_page_write(struct dsa_switch *ds, int port, int page,
1723 int reg, int val)
1724{
1725 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1726 int ret;
1727
1728 mutex_lock(&ps->phy_mutex);
fd3a0ee4 1729 ret = _mv88e6xxx_phy_write_indirect(ds, port, 0x16, page);
49143585
AL
1730 if (ret < 0)
1731 goto error;
1732
fd3a0ee4 1733 ret = _mv88e6xxx_phy_write_indirect(ds, port, reg, val);
49143585 1734error:
fd3a0ee4
AL
1735 _mv88e6xxx_phy_write_indirect(ds, port, 0x16, 0x0);
1736 mutex_unlock(&ps->phy_mutex);
1737 return ret;
1738}
1739
1740static int mv88e6xxx_port_to_phy_addr(struct dsa_switch *ds, int port)
1741{
1742 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1743
1744 if (port >= 0 && port < ps->num_ports)
1745 return port;
1746 return -EINVAL;
1747}
1748
1749int
1750mv88e6xxx_phy_read(struct dsa_switch *ds, int port, int regnum)
1751{
1752 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1753 int addr = mv88e6xxx_port_to_phy_addr(ds, port);
1754 int ret;
1755
1756 if (addr < 0)
1757 return addr;
1758
1759 mutex_lock(&ps->phy_mutex);
1760 ret = _mv88e6xxx_phy_read(ds, addr, regnum);
1761 mutex_unlock(&ps->phy_mutex);
1762 return ret;
1763}
1764
1765int
1766mv88e6xxx_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val)
1767{
1768 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1769 int addr = mv88e6xxx_port_to_phy_addr(ds, port);
1770 int ret;
1771
1772 if (addr < 0)
1773 return addr;
1774
1775 mutex_lock(&ps->phy_mutex);
1776 ret = _mv88e6xxx_phy_write(ds, addr, regnum, val);
1777 mutex_unlock(&ps->phy_mutex);
1778 return ret;
1779}
1780
1781int
1782mv88e6xxx_phy_read_indirect(struct dsa_switch *ds, int port, int regnum)
1783{
1784 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1785 int addr = mv88e6xxx_port_to_phy_addr(ds, port);
1786 int ret;
1787
1788 if (addr < 0)
1789 return addr;
1790
1791 mutex_lock(&ps->phy_mutex);
1792 ret = _mv88e6xxx_phy_read_indirect(ds, addr, regnum);
1793 mutex_unlock(&ps->phy_mutex);
1794 return ret;
1795}
1796
1797int
1798mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int port, int regnum,
1799 u16 val)
1800{
1801 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1802 int addr = mv88e6xxx_port_to_phy_addr(ds, port);
1803 int ret;
1804
1805 if (addr < 0)
1806 return addr;
1807
1808 mutex_lock(&ps->phy_mutex);
1809 ret = _mv88e6xxx_phy_write_indirect(ds, addr, regnum, val);
49143585
AL
1810 mutex_unlock(&ps->phy_mutex);
1811 return ret;
1812}
1813
98e67308
BH
1814static int __init mv88e6xxx_init(void)
1815{
1816#if IS_ENABLED(CONFIG_NET_DSA_MV88E6131)
1817 register_switch_driver(&mv88e6131_switch_driver);
1818#endif
1819#if IS_ENABLED(CONFIG_NET_DSA_MV88E6123_61_65)
1820 register_switch_driver(&mv88e6123_61_65_switch_driver);
42f27253 1821#endif
3ad50cca
GR
1822#if IS_ENABLED(CONFIG_NET_DSA_MV88E6352)
1823 register_switch_driver(&mv88e6352_switch_driver);
1824#endif
42f27253
AL
1825#if IS_ENABLED(CONFIG_NET_DSA_MV88E6171)
1826 register_switch_driver(&mv88e6171_switch_driver);
98e67308
BH
1827#endif
1828 return 0;
1829}
1830module_init(mv88e6xxx_init);
1831
1832static void __exit mv88e6xxx_cleanup(void)
1833{
42f27253
AL
1834#if IS_ENABLED(CONFIG_NET_DSA_MV88E6171)
1835 unregister_switch_driver(&mv88e6171_switch_driver);
1836#endif
98e67308
BH
1837#if IS_ENABLED(CONFIG_NET_DSA_MV88E6123_61_65)
1838 unregister_switch_driver(&mv88e6123_61_65_switch_driver);
1839#endif
1840#if IS_ENABLED(CONFIG_NET_DSA_MV88E6131)
1841 unregister_switch_driver(&mv88e6131_switch_driver);
1842#endif
1843}
1844module_exit(mv88e6xxx_cleanup);
3d825ede
BH
1845
1846MODULE_AUTHOR("Lennert Buytenhek <buytenh@wantstofly.org>");
1847MODULE_DESCRIPTION("Driver for Marvell 88E6XXX ethernet switch chips");
1848MODULE_LICENSE("GPL");
This page took 0.634899 seconds and 5 git commands to generate.