net: dsa: mv88e6xxx: Replace stats mutex with SMI mutex
[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
3898c148 202/* Must be called with SMI mutex held */
fd3a0ee4 203static int _mv88e6xxx_phy_read(struct dsa_switch *ds, int addr, int regnum)
91da11f8
LB
204{
205 if (addr >= 0)
3898c148 206 return _mv88e6xxx_reg_read(ds, addr, regnum);
91da11f8
LB
207 return 0xffff;
208}
209
3898c148 210/* Must be called with SMI mutex held */
fd3a0ee4
AL
211static int _mv88e6xxx_phy_write(struct dsa_switch *ds, int addr, int regnum,
212 u16 val)
91da11f8
LB
213{
214 if (addr >= 0)
3898c148 215 return _mv88e6xxx_reg_write(ds, addr, regnum, val);
91da11f8
LB
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
31888234
AL
518/* Must be called with SMI mutex held */
519static int _mv88e6xxx_stats_wait(struct dsa_switch *ds)
91da11f8
LB
520{
521 int ret;
522 int i;
523
524 for (i = 0; i < 10; i++) {
31888234 525 ret = _mv88e6xxx_reg_read(ds, REG_GLOBAL, GLOBAL_STATS_OP);
cca8b133 526 if ((ret & GLOBAL_STATS_OP_BUSY) == 0)
91da11f8
LB
527 return 0;
528 }
529
530 return -ETIMEDOUT;
531}
532
31888234
AL
533/* Must be called with SMI mutex held */
534static int _mv88e6xxx_stats_snapshot(struct dsa_switch *ds, int port)
91da11f8
LB
535{
536 int ret;
537
f3a8b6b6
AL
538 if (mv88e6xxx_6352_family(ds))
539 port = (port + 1) << 5;
540
3675c8d7 541 /* Snapshot the hardware statistics counters for this port. */
31888234
AL
542 ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_STATS_OP,
543 GLOBAL_STATS_OP_CAPTURE_PORT |
544 GLOBAL_STATS_OP_HIST_RX_TX | port);
545 if (ret < 0)
546 return ret;
91da11f8 547
3675c8d7 548 /* Wait for the snapshotting to complete. */
31888234 549 ret = _mv88e6xxx_stats_wait(ds);
91da11f8
LB
550 if (ret < 0)
551 return ret;
552
553 return 0;
554}
555
31888234
AL
556/* Must be called with SMI mutex held */
557static void _mv88e6xxx_stats_read(struct dsa_switch *ds, int stat, u32 *val)
91da11f8
LB
558{
559 u32 _val;
560 int ret;
561
562 *val = 0;
563
31888234
AL
564 ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_STATS_OP,
565 GLOBAL_STATS_OP_READ_CAPTURED |
566 GLOBAL_STATS_OP_HIST_RX_TX | stat);
91da11f8
LB
567 if (ret < 0)
568 return;
569
31888234 570 ret = _mv88e6xxx_stats_wait(ds);
91da11f8
LB
571 if (ret < 0)
572 return;
573
31888234 574 ret = _mv88e6xxx_reg_read(ds, REG_GLOBAL, GLOBAL_STATS_COUNTER_32);
91da11f8
LB
575 if (ret < 0)
576 return;
577
578 _val = ret << 16;
579
31888234 580 ret = _mv88e6xxx_reg_read(ds, REG_GLOBAL, GLOBAL_STATS_COUNTER_01);
91da11f8
LB
581 if (ret < 0)
582 return;
583
584 *val = _val | ret;
585}
586
e413e7e1
AL
587static struct mv88e6xxx_hw_stat mv88e6xxx_hw_stats[] = {
588 { "in_good_octets", 8, 0x00, },
589 { "in_bad_octets", 4, 0x02, },
590 { "in_unicast", 4, 0x04, },
591 { "in_broadcasts", 4, 0x06, },
592 { "in_multicasts", 4, 0x07, },
593 { "in_pause", 4, 0x16, },
594 { "in_undersize", 4, 0x18, },
595 { "in_fragments", 4, 0x19, },
596 { "in_oversize", 4, 0x1a, },
597 { "in_jabber", 4, 0x1b, },
598 { "in_rx_error", 4, 0x1c, },
599 { "in_fcs_error", 4, 0x1d, },
600 { "out_octets", 8, 0x0e, },
601 { "out_unicast", 4, 0x10, },
602 { "out_broadcasts", 4, 0x13, },
603 { "out_multicasts", 4, 0x12, },
604 { "out_pause", 4, 0x15, },
605 { "excessive", 4, 0x11, },
606 { "collisions", 4, 0x1e, },
607 { "deferred", 4, 0x05, },
608 { "single", 4, 0x14, },
609 { "multiple", 4, 0x17, },
610 { "out_fcs_error", 4, 0x03, },
611 { "late", 4, 0x1f, },
612 { "hist_64bytes", 4, 0x08, },
613 { "hist_65_127bytes", 4, 0x09, },
614 { "hist_128_255bytes", 4, 0x0a, },
615 { "hist_256_511bytes", 4, 0x0b, },
616 { "hist_512_1023bytes", 4, 0x0c, },
617 { "hist_1024_max_bytes", 4, 0x0d, },
618 /* Not all devices have the following counters */
619 { "sw_in_discards", 4, 0x110, },
620 { "sw_in_filtered", 2, 0x112, },
621 { "sw_out_filtered", 2, 0x113, },
622
623};
624
625static bool have_sw_in_discards(struct dsa_switch *ds)
626{
627 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
628
629 switch (ps->id) {
cca8b133
AL
630 case PORT_SWITCH_ID_6095: case PORT_SWITCH_ID_6161:
631 case PORT_SWITCH_ID_6165: case PORT_SWITCH_ID_6171:
632 case PORT_SWITCH_ID_6172: case PORT_SWITCH_ID_6176:
633 case PORT_SWITCH_ID_6182: case PORT_SWITCH_ID_6185:
634 case PORT_SWITCH_ID_6352:
e413e7e1
AL
635 return true;
636 default:
637 return false;
638 }
639}
640
641static void _mv88e6xxx_get_strings(struct dsa_switch *ds,
642 int nr_stats,
643 struct mv88e6xxx_hw_stat *stats,
644 int port, uint8_t *data)
91da11f8
LB
645{
646 int i;
647
648 for (i = 0; i < nr_stats; i++) {
649 memcpy(data + i * ETH_GSTRING_LEN,
650 stats[i].string, ETH_GSTRING_LEN);
651 }
652}
653
e413e7e1
AL
654static void _mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds,
655 int nr_stats,
656 struct mv88e6xxx_hw_stat *stats,
657 int port, uint64_t *data)
91da11f8 658{
a22adce5 659 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
91da11f8
LB
660 int ret;
661 int i;
662
31888234 663 mutex_lock(&ps->smi_mutex);
91da11f8 664
31888234 665 ret = _mv88e6xxx_stats_snapshot(ds, port);
91da11f8 666 if (ret < 0) {
31888234 667 mutex_unlock(&ps->smi_mutex);
91da11f8
LB
668 return;
669 }
670
3675c8d7 671 /* Read each of the counters. */
91da11f8
LB
672 for (i = 0; i < nr_stats; i++) {
673 struct mv88e6xxx_hw_stat *s = stats + i;
674 u32 low;
17ee3e04
GR
675 u32 high = 0;
676
677 if (s->reg >= 0x100) {
17ee3e04
GR
678 ret = mv88e6xxx_reg_read(ds, REG_PORT(port),
679 s->reg - 0x100);
680 if (ret < 0)
681 goto error;
682 low = ret;
683 if (s->sizeof_stat == 4) {
31888234
AL
684 ret = _mv88e6xxx_reg_read(ds, REG_PORT(port),
685 s->reg - 0x100 + 1);
17ee3e04
GR
686 if (ret < 0)
687 goto error;
688 high = ret;
689 }
690 data[i] = (((u64)high) << 16) | low;
691 continue;
692 }
31888234 693 _mv88e6xxx_stats_read(ds, s->reg, &low);
91da11f8 694 if (s->sizeof_stat == 8)
31888234 695 _mv88e6xxx_stats_read(ds, s->reg + 1, &high);
91da11f8
LB
696
697 data[i] = (((u64)high) << 32) | low;
698 }
17ee3e04 699error:
31888234 700 mutex_unlock(&ps->smi_mutex);
91da11f8 701}
98e67308 702
e413e7e1
AL
703/* All the statistics in the table */
704void
705mv88e6xxx_get_strings(struct dsa_switch *ds, int port, uint8_t *data)
706{
707 if (have_sw_in_discards(ds))
708 _mv88e6xxx_get_strings(ds, ARRAY_SIZE(mv88e6xxx_hw_stats),
709 mv88e6xxx_hw_stats, port, data);
710 else
711 _mv88e6xxx_get_strings(ds, ARRAY_SIZE(mv88e6xxx_hw_stats) - 3,
712 mv88e6xxx_hw_stats, port, data);
713}
714
715int mv88e6xxx_get_sset_count(struct dsa_switch *ds)
716{
717 if (have_sw_in_discards(ds))
718 return ARRAY_SIZE(mv88e6xxx_hw_stats);
719 return ARRAY_SIZE(mv88e6xxx_hw_stats) - 3;
720}
721
722void
723mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds,
724 int port, uint64_t *data)
725{
726 if (have_sw_in_discards(ds))
727 _mv88e6xxx_get_ethtool_stats(
728 ds, ARRAY_SIZE(mv88e6xxx_hw_stats),
729 mv88e6xxx_hw_stats, port, data);
730 else
731 _mv88e6xxx_get_ethtool_stats(
732 ds, ARRAY_SIZE(mv88e6xxx_hw_stats) - 3,
733 mv88e6xxx_hw_stats, port, data);
734}
735
a1ab91f3
GR
736int mv88e6xxx_get_regs_len(struct dsa_switch *ds, int port)
737{
738 return 32 * sizeof(u16);
739}
740
741void mv88e6xxx_get_regs(struct dsa_switch *ds, int port,
742 struct ethtool_regs *regs, void *_p)
743{
744 u16 *p = _p;
745 int i;
746
747 regs->version = 0;
748
749 memset(p, 0xff, 32 * sizeof(u16));
750
751 for (i = 0; i < 32; i++) {
752 int ret;
753
754 ret = mv88e6xxx_reg_read(ds, REG_PORT(port), i);
755 if (ret >= 0)
756 p[i] = ret;
757 }
758}
759
eaa23765
AL
760#ifdef CONFIG_NET_DSA_HWMON
761
762int mv88e6xxx_get_temp(struct dsa_switch *ds, int *temp)
763{
764 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
765 int ret;
766 int val;
767
768 *temp = 0;
769
3898c148 770 mutex_lock(&ps->smi_mutex);
eaa23765 771
fd3a0ee4 772 ret = _mv88e6xxx_phy_write(ds, 0x0, 0x16, 0x6);
eaa23765
AL
773 if (ret < 0)
774 goto error;
775
776 /* Enable temperature sensor */
fd3a0ee4 777 ret = _mv88e6xxx_phy_read(ds, 0x0, 0x1a);
eaa23765
AL
778 if (ret < 0)
779 goto error;
780
fd3a0ee4 781 ret = _mv88e6xxx_phy_write(ds, 0x0, 0x1a, ret | (1 << 5));
eaa23765
AL
782 if (ret < 0)
783 goto error;
784
785 /* Wait for temperature to stabilize */
786 usleep_range(10000, 12000);
787
fd3a0ee4 788 val = _mv88e6xxx_phy_read(ds, 0x0, 0x1a);
eaa23765
AL
789 if (val < 0) {
790 ret = val;
791 goto error;
792 }
793
794 /* Disable temperature sensor */
fd3a0ee4 795 ret = _mv88e6xxx_phy_write(ds, 0x0, 0x1a, ret & ~(1 << 5));
eaa23765
AL
796 if (ret < 0)
797 goto error;
798
799 *temp = ((val & 0x1f) - 5) * 5;
800
801error:
fd3a0ee4 802 _mv88e6xxx_phy_write(ds, 0x0, 0x16, 0x0);
3898c148 803 mutex_unlock(&ps->smi_mutex);
eaa23765
AL
804 return ret;
805}
806#endif /* CONFIG_NET_DSA_HWMON */
807
3898c148
AL
808/* Must be called with SMI lock held */
809static int _mv88e6xxx_wait(struct dsa_switch *ds, int reg, int offset,
810 u16 mask)
f3044683
AL
811{
812 unsigned long timeout = jiffies + HZ / 10;
813
814 while (time_before(jiffies, timeout)) {
815 int ret;
816
3898c148
AL
817 ret = _mv88e6xxx_reg_read(ds, reg, offset);
818 if (ret < 0)
819 return ret;
f3044683
AL
820 if (!(ret & mask))
821 return 0;
822
823 usleep_range(1000, 2000);
824 }
825 return -ETIMEDOUT;
826}
827
3898c148
AL
828static int mv88e6xxx_wait(struct dsa_switch *ds, int reg, int offset, u16 mask)
829{
830 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
831 int ret;
832
833 mutex_lock(&ps->smi_mutex);
834 ret = _mv88e6xxx_wait(ds, reg, offset, mask);
835 mutex_unlock(&ps->smi_mutex);
836
837 return ret;
838}
839
840static int _mv88e6xxx_phy_wait(struct dsa_switch *ds)
f3044683 841{
3898c148
AL
842 return _mv88e6xxx_wait(ds, REG_GLOBAL2, GLOBAL2_SMI_OP,
843 GLOBAL2_SMI_OP_BUSY);
f3044683
AL
844}
845
846int mv88e6xxx_eeprom_load_wait(struct dsa_switch *ds)
847{
cca8b133
AL
848 return mv88e6xxx_wait(ds, REG_GLOBAL2, GLOBAL2_EEPROM_OP,
849 GLOBAL2_EEPROM_OP_LOAD);
f3044683
AL
850}
851
852int mv88e6xxx_eeprom_busy_wait(struct dsa_switch *ds)
853{
cca8b133
AL
854 return mv88e6xxx_wait(ds, REG_GLOBAL2, GLOBAL2_EEPROM_OP,
855 GLOBAL2_EEPROM_OP_BUSY);
f3044683
AL
856}
857
facd95b2
GR
858/* Must be called with SMI lock held */
859static int _mv88e6xxx_atu_wait(struct dsa_switch *ds)
860{
cca8b133
AL
861 return _mv88e6xxx_wait(ds, REG_GLOBAL, GLOBAL_ATU_OP,
862 GLOBAL_ATU_OP_BUSY);
facd95b2
GR
863}
864
3898c148 865/* Must be called with SMI mutex held */
fd3a0ee4
AL
866static int _mv88e6xxx_phy_read_indirect(struct dsa_switch *ds, int addr,
867 int regnum)
f3044683
AL
868{
869 int ret;
870
3898c148
AL
871 ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL2, GLOBAL2_SMI_OP,
872 GLOBAL2_SMI_OP_22_READ | (addr << 5) |
873 regnum);
874 if (ret < 0)
875 return ret;
f3044683 876
3898c148 877 ret = _mv88e6xxx_phy_wait(ds);
f3044683
AL
878 if (ret < 0)
879 return ret;
880
3898c148 881 return _mv88e6xxx_reg_read(ds, REG_GLOBAL2, GLOBAL2_SMI_DATA);
f3044683
AL
882}
883
3898c148 884/* Must be called with SMI mutex held */
fd3a0ee4
AL
885static int _mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int addr,
886 int regnum, u16 val)
f3044683 887{
3898c148
AL
888 int ret;
889
890 ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL2, GLOBAL2_SMI_DATA, val);
891 if (ret < 0)
892 return ret;
f3044683 893
3898c148
AL
894 ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL2, GLOBAL2_SMI_OP,
895 GLOBAL2_SMI_OP_22_WRITE | (addr << 5) |
896 regnum);
897
898 return _mv88e6xxx_phy_wait(ds);
f3044683
AL
899}
900
11b3b45d
GR
901int mv88e6xxx_get_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e)
902{
2f40c698 903 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
11b3b45d
GR
904 int reg;
905
3898c148 906 mutex_lock(&ps->smi_mutex);
2f40c698
AL
907
908 reg = _mv88e6xxx_phy_read_indirect(ds, port, 16);
11b3b45d 909 if (reg < 0)
2f40c698 910 goto out;
11b3b45d
GR
911
912 e->eee_enabled = !!(reg & 0x0200);
913 e->tx_lpi_enabled = !!(reg & 0x0100);
914
3898c148 915 reg = _mv88e6xxx_reg_read(ds, REG_PORT(port), PORT_STATUS);
11b3b45d 916 if (reg < 0)
2f40c698 917 goto out;
11b3b45d 918
cca8b133 919 e->eee_active = !!(reg & PORT_STATUS_EEE);
2f40c698 920 reg = 0;
11b3b45d 921
2f40c698 922out:
3898c148 923 mutex_unlock(&ps->smi_mutex);
2f40c698 924 return reg;
11b3b45d
GR
925}
926
927int mv88e6xxx_set_eee(struct dsa_switch *ds, int port,
928 struct phy_device *phydev, struct ethtool_eee *e)
929{
2f40c698
AL
930 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
931 int reg;
11b3b45d
GR
932 int ret;
933
3898c148 934 mutex_lock(&ps->smi_mutex);
11b3b45d 935
2f40c698
AL
936 ret = _mv88e6xxx_phy_read_indirect(ds, port, 16);
937 if (ret < 0)
938 goto out;
939
940 reg = ret & ~0x0300;
941 if (e->eee_enabled)
942 reg |= 0x0200;
943 if (e->tx_lpi_enabled)
944 reg |= 0x0100;
945
946 ret = _mv88e6xxx_phy_write_indirect(ds, port, 16, reg);
947out:
3898c148 948 mutex_unlock(&ps->smi_mutex);
2f40c698
AL
949
950 return ret;
11b3b45d
GR
951}
952
facd95b2
GR
953static int _mv88e6xxx_atu_cmd(struct dsa_switch *ds, int fid, u16 cmd)
954{
955 int ret;
956
957 ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, 0x01, fid);
958 if (ret < 0)
959 return ret;
960
cca8b133 961 ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_ATU_OP, cmd);
facd95b2
GR
962 if (ret < 0)
963 return ret;
964
965 return _mv88e6xxx_atu_wait(ds);
966}
967
968static int _mv88e6xxx_flush_fid(struct dsa_switch *ds, int fid)
969{
970 int ret;
971
972 ret = _mv88e6xxx_atu_wait(ds);
973 if (ret < 0)
974 return ret;
975
cca8b133 976 return _mv88e6xxx_atu_cmd(ds, fid, GLOBAL_ATU_OP_FLUSH_NON_STATIC_DB);
facd95b2
GR
977}
978
979static int mv88e6xxx_set_port_state(struct dsa_switch *ds, int port, u8 state)
980{
981 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
c3ffe6d2 982 int reg, ret = 0;
facd95b2
GR
983 u8 oldstate;
984
985 mutex_lock(&ps->smi_mutex);
986
cca8b133 987 reg = _mv88e6xxx_reg_read(ds, REG_PORT(port), PORT_CONTROL);
538cc282
GR
988 if (reg < 0) {
989 ret = reg;
facd95b2 990 goto abort;
538cc282 991 }
facd95b2 992
cca8b133 993 oldstate = reg & PORT_CONTROL_STATE_MASK;
facd95b2
GR
994 if (oldstate != state) {
995 /* Flush forwarding database if we're moving a port
996 * from Learning or Forwarding state to Disabled or
997 * Blocking or Listening state.
998 */
cca8b133
AL
999 if (oldstate >= PORT_CONTROL_STATE_LEARNING &&
1000 state <= PORT_CONTROL_STATE_BLOCKING) {
facd95b2
GR
1001 ret = _mv88e6xxx_flush_fid(ds, ps->fid[port]);
1002 if (ret)
1003 goto abort;
1004 }
cca8b133
AL
1005 reg = (reg & ~PORT_CONTROL_STATE_MASK) | state;
1006 ret = _mv88e6xxx_reg_write(ds, REG_PORT(port), PORT_CONTROL,
1007 reg);
facd95b2
GR
1008 }
1009
1010abort:
1011 mutex_unlock(&ps->smi_mutex);
1012 return ret;
1013}
1014
1015/* Must be called with smi lock held */
1016static int _mv88e6xxx_update_port_config(struct dsa_switch *ds, int port)
1017{
1018 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1019 u8 fid = ps->fid[port];
1020 u16 reg = fid << 12;
1021
1022 if (dsa_is_cpu_port(ds, port))
1023 reg |= ds->phys_port_mask;
1024 else
1025 reg |= (ps->bridge_mask[fid] |
1026 (1 << dsa_upstream_port(ds))) & ~(1 << port);
1027
cca8b133 1028 return _mv88e6xxx_reg_write(ds, REG_PORT(port), PORT_BASE_VLAN, reg);
facd95b2
GR
1029}
1030
1031/* Must be called with smi lock held */
1032static int _mv88e6xxx_update_bridge_config(struct dsa_switch *ds, int fid)
1033{
1034 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1035 int port;
1036 u32 mask;
1037 int ret;
1038
1039 mask = ds->phys_port_mask;
1040 while (mask) {
1041 port = __ffs(mask);
1042 mask &= ~(1 << port);
1043 if (ps->fid[port] != fid)
1044 continue;
1045
1046 ret = _mv88e6xxx_update_port_config(ds, port);
1047 if (ret)
1048 return ret;
1049 }
1050
1051 return _mv88e6xxx_flush_fid(ds, fid);
1052}
1053
1054/* Bridge handling functions */
1055
1056int mv88e6xxx_join_bridge(struct dsa_switch *ds, int port, u32 br_port_mask)
1057{
1058 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1059 int ret = 0;
1060 u32 nmask;
1061 int fid;
1062
1063 /* If the bridge group is not empty, join that group.
1064 * Otherwise create a new group.
1065 */
1066 fid = ps->fid[port];
1067 nmask = br_port_mask & ~(1 << port);
1068 if (nmask)
1069 fid = ps->fid[__ffs(nmask)];
1070
1071 nmask = ps->bridge_mask[fid] | (1 << port);
1072 if (nmask != br_port_mask) {
1073 netdev_err(ds->ports[port],
1074 "join: Bridge port mask mismatch fid=%d mask=0x%x expected 0x%x\n",
1075 fid, br_port_mask, nmask);
1076 return -EINVAL;
1077 }
1078
1079 mutex_lock(&ps->smi_mutex);
1080
1081 ps->bridge_mask[fid] = br_port_mask;
1082
1083 if (fid != ps->fid[port]) {
1084 ps->fid_mask |= 1 << ps->fid[port];
1085 ps->fid[port] = fid;
1086 ret = _mv88e6xxx_update_bridge_config(ds, fid);
1087 }
1088
1089 mutex_unlock(&ps->smi_mutex);
1090
1091 return ret;
1092}
1093
1094int mv88e6xxx_leave_bridge(struct dsa_switch *ds, int port, u32 br_port_mask)
1095{
1096 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1097 u8 fid, newfid;
1098 int ret;
1099
1100 fid = ps->fid[port];
1101
1102 if (ps->bridge_mask[fid] != br_port_mask) {
1103 netdev_err(ds->ports[port],
1104 "leave: Bridge port mask mismatch fid=%d mask=0x%x expected 0x%x\n",
1105 fid, br_port_mask, ps->bridge_mask[fid]);
1106 return -EINVAL;
1107 }
1108
1109 /* If the port was the last port of a bridge, we are done.
1110 * Otherwise assign a new fid to the port, and fix up
1111 * the bridge configuration.
1112 */
1113 if (br_port_mask == (1 << port))
1114 return 0;
1115
1116 mutex_lock(&ps->smi_mutex);
1117
1118 newfid = __ffs(ps->fid_mask);
1119 ps->fid[port] = newfid;
1120 ps->fid_mask &= (1 << newfid);
1121 ps->bridge_mask[fid] &= ~(1 << port);
1122 ps->bridge_mask[newfid] = 1 << port;
1123
1124 ret = _mv88e6xxx_update_bridge_config(ds, fid);
1125 if (!ret)
1126 ret = _mv88e6xxx_update_bridge_config(ds, newfid);
1127
1128 mutex_unlock(&ps->smi_mutex);
1129
1130 return ret;
1131}
1132
1133int mv88e6xxx_port_stp_update(struct dsa_switch *ds, int port, u8 state)
1134{
1135 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1136 int stp_state;
1137
1138 switch (state) {
1139 case BR_STATE_DISABLED:
cca8b133 1140 stp_state = PORT_CONTROL_STATE_DISABLED;
facd95b2
GR
1141 break;
1142 case BR_STATE_BLOCKING:
1143 case BR_STATE_LISTENING:
cca8b133 1144 stp_state = PORT_CONTROL_STATE_BLOCKING;
facd95b2
GR
1145 break;
1146 case BR_STATE_LEARNING:
cca8b133 1147 stp_state = PORT_CONTROL_STATE_LEARNING;
facd95b2
GR
1148 break;
1149 case BR_STATE_FORWARDING:
1150 default:
cca8b133 1151 stp_state = PORT_CONTROL_STATE_FORWARDING;
facd95b2
GR
1152 break;
1153 }
1154
1155 netdev_dbg(ds->ports[port], "port state %d [%d]\n", state, stp_state);
1156
1157 /* mv88e6xxx_port_stp_update may be called with softirqs disabled,
1158 * so we can not update the port state directly but need to schedule it.
1159 */
1160 ps->port_state[port] = stp_state;
1161 set_bit(port, &ps->port_state_update_mask);
1162 schedule_work(&ps->bridge_work);
1163
1164 return 0;
1165}
1166
defb05b9
GR
1167static int __mv88e6xxx_write_addr(struct dsa_switch *ds,
1168 const unsigned char *addr)
1169{
1170 int i, ret;
1171
1172 for (i = 0; i < 3; i++) {
cca8b133
AL
1173 ret = _mv88e6xxx_reg_write(
1174 ds, REG_GLOBAL, GLOBAL_ATU_MAC_01 + i,
1175 (addr[i * 2] << 8) | addr[i * 2 + 1]);
defb05b9
GR
1176 if (ret < 0)
1177 return ret;
1178 }
1179
1180 return 0;
1181}
1182
1183static int __mv88e6xxx_read_addr(struct dsa_switch *ds, unsigned char *addr)
1184{
1185 int i, ret;
1186
1187 for (i = 0; i < 3; i++) {
cca8b133
AL
1188 ret = _mv88e6xxx_reg_read(ds, REG_GLOBAL,
1189 GLOBAL_ATU_MAC_01 + i);
defb05b9
GR
1190 if (ret < 0)
1191 return ret;
1192 addr[i * 2] = ret >> 8;
1193 addr[i * 2 + 1] = ret & 0xff;
1194 }
1195
1196 return 0;
1197}
1198
1199static int __mv88e6xxx_port_fdb_cmd(struct dsa_switch *ds, int port,
1200 const unsigned char *addr, int state)
1201{
1202 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1203 u8 fid = ps->fid[port];
1204 int ret;
1205
1206 ret = _mv88e6xxx_atu_wait(ds);
1207 if (ret < 0)
1208 return ret;
1209
1210 ret = __mv88e6xxx_write_addr(ds, addr);
1211 if (ret < 0)
1212 return ret;
1213
cca8b133 1214 ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_ATU_DATA,
defb05b9
GR
1215 (0x10 << port) | state);
1216 if (ret)
1217 return ret;
1218
cca8b133 1219 ret = _mv88e6xxx_atu_cmd(ds, fid, GLOBAL_ATU_OP_LOAD_DB);
defb05b9
GR
1220
1221 return ret;
1222}
1223
1224int mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port,
1225 const unsigned char *addr, u16 vid)
1226{
1227 int state = is_multicast_ether_addr(addr) ?
cca8b133
AL
1228 GLOBAL_ATU_DATA_STATE_MC_STATIC :
1229 GLOBAL_ATU_DATA_STATE_UC_STATIC;
defb05b9
GR
1230 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1231 int ret;
1232
1233 mutex_lock(&ps->smi_mutex);
1234 ret = __mv88e6xxx_port_fdb_cmd(ds, port, addr, state);
1235 mutex_unlock(&ps->smi_mutex);
1236
1237 return ret;
1238}
1239
1240int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port,
1241 const unsigned char *addr, u16 vid)
1242{
1243 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1244 int ret;
1245
1246 mutex_lock(&ps->smi_mutex);
cca8b133
AL
1247 ret = __mv88e6xxx_port_fdb_cmd(ds, port, addr,
1248 GLOBAL_ATU_DATA_STATE_UNUSED);
defb05b9
GR
1249 mutex_unlock(&ps->smi_mutex);
1250
1251 return ret;
1252}
1253
1254static int __mv88e6xxx_port_getnext(struct dsa_switch *ds, int port,
1255 unsigned char *addr, bool *is_static)
1256{
1257 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1258 u8 fid = ps->fid[port];
1259 int ret, state;
1260
1261 ret = _mv88e6xxx_atu_wait(ds);
1262 if (ret < 0)
1263 return ret;
1264
1265 ret = __mv88e6xxx_write_addr(ds, addr);
1266 if (ret < 0)
1267 return ret;
1268
1269 do {
cca8b133 1270 ret = _mv88e6xxx_atu_cmd(ds, fid, GLOBAL_ATU_OP_GET_NEXT_DB);
defb05b9
GR
1271 if (ret < 0)
1272 return ret;
1273
cca8b133 1274 ret = _mv88e6xxx_reg_read(ds, REG_GLOBAL, GLOBAL_ATU_DATA);
defb05b9
GR
1275 if (ret < 0)
1276 return ret;
cca8b133
AL
1277 state = ret & GLOBAL_ATU_DATA_STATE_MASK;
1278 if (state == GLOBAL_ATU_DATA_STATE_UNUSED)
defb05b9
GR
1279 return -ENOENT;
1280 } while (!(((ret >> 4) & 0xff) & (1 << port)));
1281
1282 ret = __mv88e6xxx_read_addr(ds, addr);
1283 if (ret < 0)
1284 return ret;
1285
1286 *is_static = state == (is_multicast_ether_addr(addr) ?
cca8b133
AL
1287 GLOBAL_ATU_DATA_STATE_MC_STATIC :
1288 GLOBAL_ATU_DATA_STATE_UC_STATIC);
defb05b9
GR
1289
1290 return 0;
1291}
1292
1293/* get next entry for port */
1294int mv88e6xxx_port_fdb_getnext(struct dsa_switch *ds, int port,
1295 unsigned char *addr, bool *is_static)
1296{
1297 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1298 int ret;
1299
1300 mutex_lock(&ps->smi_mutex);
1301 ret = __mv88e6xxx_port_getnext(ds, port, addr, is_static);
1302 mutex_unlock(&ps->smi_mutex);
1303
1304 return ret;
1305}
1306
facd95b2
GR
1307static void mv88e6xxx_bridge_work(struct work_struct *work)
1308{
1309 struct mv88e6xxx_priv_state *ps;
1310 struct dsa_switch *ds;
1311 int port;
1312
1313 ps = container_of(work, struct mv88e6xxx_priv_state, bridge_work);
1314 ds = ((struct dsa_switch *)ps) - 1;
1315
1316 while (ps->port_state_update_mask) {
1317 port = __ffs(ps->port_state_update_mask);
1318 clear_bit(port, &ps->port_state_update_mask);
1319 mv88e6xxx_set_port_state(ds, port, ps->port_state[port]);
1320 }
1321}
1322
dbde9e66 1323static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port)
d827e88a
GR
1324{
1325 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
facd95b2 1326 int ret, fid;
54d792f2 1327 u16 reg;
d827e88a
GR
1328
1329 mutex_lock(&ps->smi_mutex);
1330
54d792f2
AL
1331 if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) ||
1332 mv88e6xxx_6165_family(ds) || mv88e6xxx_6097_family(ds) ||
1333 mv88e6xxx_6185_family(ds) || mv88e6xxx_6095_family(ds) ||
1334 mv88e6xxx_6065_family(ds)) {
1335 /* MAC Forcing register: don't force link, speed,
1336 * duplex or flow control state to any particular
1337 * values on physical ports, but force the CPU port
1338 * and all DSA ports to their maximum bandwidth and
1339 * full duplex.
1340 */
1341 reg = _mv88e6xxx_reg_read(ds, REG_PORT(port), PORT_PCS_CTRL);
1342 if (dsa_is_cpu_port(ds, port) ||
1343 ds->dsa_port_mask & (1 << port)) {
1344 reg |= PORT_PCS_CTRL_FORCE_LINK |
1345 PORT_PCS_CTRL_LINK_UP |
1346 PORT_PCS_CTRL_DUPLEX_FULL |
1347 PORT_PCS_CTRL_FORCE_DUPLEX;
1348 if (mv88e6xxx_6065_family(ds))
1349 reg |= PORT_PCS_CTRL_100;
1350 else
1351 reg |= PORT_PCS_CTRL_1000;
1352 } else {
1353 reg |= PORT_PCS_CTRL_UNFORCED;
1354 }
1355
1356 ret = _mv88e6xxx_reg_write(ds, REG_PORT(port),
1357 PORT_PCS_CTRL, reg);
1358 if (ret)
1359 goto abort;
1360 }
1361
1362 /* Port Control: disable Drop-on-Unlock, disable Drop-on-Lock,
1363 * disable Header mode, enable IGMP/MLD snooping, disable VLAN
1364 * tunneling, determine priority by looking at 802.1p and IP
1365 * priority fields (IP prio has precedence), and set STP state
1366 * to Forwarding.
1367 *
1368 * If this is the CPU link, use DSA or EDSA tagging depending
1369 * on which tagging mode was configured.
1370 *
1371 * If this is a link to another switch, use DSA tagging mode.
1372 *
1373 * If this is the upstream port for this switch, enable
1374 * forwarding of unknown unicasts and multicasts.
1375 */
1376 reg = 0;
1377 if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) ||
1378 mv88e6xxx_6165_family(ds) || mv88e6xxx_6097_family(ds) ||
1379 mv88e6xxx_6095_family(ds) || mv88e6xxx_6065_family(ds) ||
1380 mv88e6xxx_6185_family(ds))
1381 reg = PORT_CONTROL_IGMP_MLD_SNOOP |
1382 PORT_CONTROL_USE_TAG | PORT_CONTROL_USE_IP |
1383 PORT_CONTROL_STATE_FORWARDING;
1384 if (dsa_is_cpu_port(ds, port)) {
1385 if (mv88e6xxx_6095_family(ds) || mv88e6xxx_6185_family(ds))
1386 reg |= PORT_CONTROL_DSA_TAG;
1387 if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) ||
1388 mv88e6xxx_6165_family(ds) || mv88e6xxx_6097_family(ds)) {
1389 if (ds->dst->tag_protocol == DSA_TAG_PROTO_EDSA)
1390 reg |= PORT_CONTROL_FRAME_ETHER_TYPE_DSA;
1391 else
1392 reg |= PORT_CONTROL_FRAME_MODE_DSA;
1393 }
1394
1395 if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) ||
1396 mv88e6xxx_6165_family(ds) || mv88e6xxx_6097_family(ds) ||
1397 mv88e6xxx_6095_family(ds) || mv88e6xxx_6065_family(ds) ||
1398 mv88e6xxx_6185_family(ds)) {
1399 if (ds->dst->tag_protocol == DSA_TAG_PROTO_EDSA)
1400 reg |= PORT_CONTROL_EGRESS_ADD_TAG;
1401 }
1402 }
1403 if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) ||
1404 mv88e6xxx_6165_family(ds) || mv88e6xxx_6097_family(ds) ||
1405 mv88e6xxx_6095_family(ds) || mv88e6xxx_6065_family(ds)) {
1406 if (ds->dsa_port_mask & (1 << port))
1407 reg |= PORT_CONTROL_FRAME_MODE_DSA;
1408 if (port == dsa_upstream_port(ds))
1409 reg |= PORT_CONTROL_FORWARD_UNKNOWN |
1410 PORT_CONTROL_FORWARD_UNKNOWN_MC;
1411 }
1412 if (reg) {
1413 ret = _mv88e6xxx_reg_write(ds, REG_PORT(port),
1414 PORT_CONTROL, reg);
1415 if (ret)
1416 goto abort;
1417 }
1418
1419 /* Port Control 2: don't force a good FCS, set the maximum
1420 * frame size to 10240 bytes, don't let the switch add or
1421 * strip 802.1q tags, don't discard tagged or untagged frames
1422 * on this port, do a destination address lookup on all
1423 * received packets as usual, disable ARP mirroring and don't
1424 * send a copy of all transmitted/received frames on this port
1425 * to the CPU.
1426 */
1427 reg = 0;
1428 if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) ||
1429 mv88e6xxx_6165_family(ds) || mv88e6xxx_6097_family(ds) ||
1430 mv88e6xxx_6095_family(ds))
1431 reg = PORT_CONTROL_2_MAP_DA;
1432
1433 if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) ||
1434 mv88e6xxx_6165_family(ds))
1435 reg |= PORT_CONTROL_2_JUMBO_10240;
1436
1437 if (mv88e6xxx_6095_family(ds) || mv88e6xxx_6185_family(ds)) {
1438 /* Set the upstream port this port should use */
1439 reg |= dsa_upstream_port(ds);
1440 /* enable forwarding of unknown multicast addresses to
1441 * the upstream port
1442 */
1443 if (port == dsa_upstream_port(ds))
1444 reg |= PORT_CONTROL_2_FORWARD_UNKNOWN;
1445 }
1446
1447 if (reg) {
1448 ret = _mv88e6xxx_reg_write(ds, REG_PORT(port),
1449 PORT_CONTROL_2, reg);
1450 if (ret)
1451 goto abort;
1452 }
1453
1454 /* Port Association Vector: when learning source addresses
1455 * of packets, add the address to the address database using
1456 * a port bitmap that has only the bit for this port set and
1457 * the other bits clear.
1458 */
1459 ret = _mv88e6xxx_reg_write(ds, REG_PORT(port), PORT_ASSOC_VECTOR,
1460 1 << port);
1461 if (ret)
1462 goto abort;
1463
1464 /* Egress rate control 2: disable egress rate control. */
1465 ret = _mv88e6xxx_reg_write(ds, REG_PORT(port), PORT_RATE_CONTROL_2,
1466 0x0000);
1467 if (ret)
1468 goto abort;
1469
1470 if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) ||
1471 mv88e6xxx_6165_family(ds) || mv88e6xxx_6097_family(ds)) {
1472 /* Do not limit the period of time that this port can
1473 * be paused for by the remote end or the period of
1474 * time that this port can pause the remote end.
1475 */
1476 ret = _mv88e6xxx_reg_write(ds, REG_PORT(port),
1477 PORT_PAUSE_CTRL, 0x0000);
1478 if (ret)
1479 goto abort;
1480
1481 /* Port ATU control: disable limiting the number of
1482 * address database entries that this port is allowed
1483 * to use.
1484 */
1485 ret = _mv88e6xxx_reg_write(ds, REG_PORT(port),
1486 PORT_ATU_CONTROL, 0x0000);
1487 /* Priority Override: disable DA, SA and VTU priority
1488 * override.
1489 */
1490 ret = _mv88e6xxx_reg_write(ds, REG_PORT(port),
1491 PORT_PRI_OVERRIDE, 0x0000);
1492 if (ret)
1493 goto abort;
1494
1495 /* Port Ethertype: use the Ethertype DSA Ethertype
1496 * value.
1497 */
1498 ret = _mv88e6xxx_reg_write(ds, REG_PORT(port),
1499 PORT_ETH_TYPE, ETH_P_EDSA);
1500 if (ret)
1501 goto abort;
1502 /* Tag Remap: use an identity 802.1p prio -> switch
1503 * prio mapping.
1504 */
1505 ret = _mv88e6xxx_reg_write(ds, REG_PORT(port),
1506 PORT_TAG_REGMAP_0123, 0x3210);
1507 if (ret)
1508 goto abort;
1509
1510 /* Tag Remap 2: use an identity 802.1p prio -> switch
1511 * prio mapping.
1512 */
1513 ret = _mv88e6xxx_reg_write(ds, REG_PORT(port),
1514 PORT_TAG_REGMAP_4567, 0x7654);
1515 if (ret)
1516 goto abort;
1517 }
1518
1519 if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) ||
1520 mv88e6xxx_6165_family(ds) || mv88e6xxx_6097_family(ds) ||
1521 mv88e6xxx_6185_family(ds) || mv88e6xxx_6095_family(ds)) {
1522 /* Rate Control: disable ingress rate limiting. */
1523 ret = _mv88e6xxx_reg_write(ds, REG_PORT(port),
1524 PORT_RATE_CONTROL, 0x0001);
1525 if (ret)
1526 goto abort;
1527 }
1528
366f0a0f
GR
1529 /* Port Control 1: disable trunking, disable sending
1530 * learning messages to this port.
d827e88a 1531 */
614f03fc 1532 ret = _mv88e6xxx_reg_write(ds, REG_PORT(port), PORT_CONTROL_1, 0x0000);
d827e88a
GR
1533 if (ret)
1534 goto abort;
1535
1536 /* Port based VLAN map: give each port its own address
1537 * database, allow the CPU port to talk to each of the 'real'
1538 * ports, and allow each of the 'real' ports to only talk to
1539 * the upstream port.
1540 */
facd95b2
GR
1541 fid = __ffs(ps->fid_mask);
1542 ps->fid[port] = fid;
1543 ps->fid_mask &= ~(1 << fid);
1544
1545 if (!dsa_is_cpu_port(ds, port))
1546 ps->bridge_mask[fid] = 1 << port;
d827e88a 1547
facd95b2 1548 ret = _mv88e6xxx_update_port_config(ds, port);
d827e88a
GR
1549 if (ret)
1550 goto abort;
1551
1552 /* Default VLAN ID and priority: don't set a default VLAN
1553 * ID, and set the default packet priority to zero.
1554 */
47cf1e65
VD
1555 ret = _mv88e6xxx_reg_write(ds, REG_PORT(port), PORT_DEFAULT_VLAN,
1556 0x0000);
d827e88a
GR
1557abort:
1558 mutex_unlock(&ps->smi_mutex);
1559 return ret;
1560}
1561
dbde9e66
AL
1562int mv88e6xxx_setup_ports(struct dsa_switch *ds)
1563{
1564 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1565 int ret;
1566 int i;
1567
1568 for (i = 0; i < ps->num_ports; i++) {
1569 ret = mv88e6xxx_setup_port(ds, i);
1570 if (ret < 0)
1571 return ret;
1572 }
1573 return 0;
1574}
1575
acdaffcc
GR
1576int mv88e6xxx_setup_common(struct dsa_switch *ds)
1577{
1578 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1579
1580 mutex_init(&ps->smi_mutex);
acdaffcc 1581
cca8b133 1582 ps->id = REG_READ(REG_PORT(0), PORT_SWITCH_ID) & 0xfff0;
a8f064c6 1583
facd95b2
GR
1584 ps->fid_mask = (1 << DSA_MAX_PORTS) - 1;
1585
1586 INIT_WORK(&ps->bridge_work, mv88e6xxx_bridge_work);
1587
acdaffcc
GR
1588 return 0;
1589}
1590
54d792f2
AL
1591int mv88e6xxx_setup_global(struct dsa_switch *ds)
1592{
1593 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1594 int i;
1595
1596 /* Set the default address aging time to 5 minutes, and
1597 * enable address learn messages to be sent to all message
1598 * ports.
1599 */
1600 REG_WRITE(REG_GLOBAL, GLOBAL_ATU_CONTROL,
1601 0x0140 | GLOBAL_ATU_CONTROL_LEARN2ALL);
1602
1603 /* Configure the IP ToS mapping registers. */
1604 REG_WRITE(REG_GLOBAL, GLOBAL_IP_PRI_0, 0x0000);
1605 REG_WRITE(REG_GLOBAL, GLOBAL_IP_PRI_1, 0x0000);
1606 REG_WRITE(REG_GLOBAL, GLOBAL_IP_PRI_2, 0x5555);
1607 REG_WRITE(REG_GLOBAL, GLOBAL_IP_PRI_3, 0x5555);
1608 REG_WRITE(REG_GLOBAL, GLOBAL_IP_PRI_4, 0xaaaa);
1609 REG_WRITE(REG_GLOBAL, GLOBAL_IP_PRI_5, 0xaaaa);
1610 REG_WRITE(REG_GLOBAL, GLOBAL_IP_PRI_6, 0xffff);
1611 REG_WRITE(REG_GLOBAL, GLOBAL_IP_PRI_7, 0xffff);
1612
1613 /* Configure the IEEE 802.1p priority mapping register. */
1614 REG_WRITE(REG_GLOBAL, GLOBAL_IEEE_PRI, 0xfa41);
1615
1616 /* Send all frames with destination addresses matching
1617 * 01:80:c2:00:00:0x to the CPU port.
1618 */
1619 REG_WRITE(REG_GLOBAL2, GLOBAL2_MGMT_EN_0X, 0xffff);
1620
1621 /* Ignore removed tag data on doubly tagged packets, disable
1622 * flow control messages, force flow control priority to the
1623 * highest, and send all special multicast frames to the CPU
1624 * port at the highest priority.
1625 */
1626 REG_WRITE(REG_GLOBAL2, GLOBAL2_SWITCH_MGMT,
1627 0x7 | GLOBAL2_SWITCH_MGMT_RSVD2CPU | 0x70 |
1628 GLOBAL2_SWITCH_MGMT_FORCE_FLOW_CTRL_PRI);
1629
1630 /* Program the DSA routing table. */
1631 for (i = 0; i < 32; i++) {
1632 int nexthop = 0x1f;
1633
1634 if (ds->pd->rtable &&
1635 i != ds->index && i < ds->dst->pd->nr_chips)
1636 nexthop = ds->pd->rtable[i] & 0x1f;
1637
1638 REG_WRITE(REG_GLOBAL2, GLOBAL2_DEVICE_MAPPING,
1639 GLOBAL2_DEVICE_MAPPING_UPDATE |
1640 (i << GLOBAL2_DEVICE_MAPPING_TARGET_SHIFT) |
1641 nexthop);
1642 }
1643
1644 /* Clear all trunk masks. */
1645 for (i = 0; i < 8; i++)
1646 REG_WRITE(REG_GLOBAL2, GLOBAL2_TRUNK_MASK,
1647 0x8000 | (i << GLOBAL2_TRUNK_MASK_NUM_SHIFT) |
1648 ((1 << ps->num_ports) - 1));
1649
1650 /* Clear all trunk mappings. */
1651 for (i = 0; i < 16; i++)
1652 REG_WRITE(REG_GLOBAL2, GLOBAL2_TRUNK_MAPPING,
1653 GLOBAL2_TRUNK_MAPPING_UPDATE |
1654 (i << GLOBAL2_TRUNK_MAPPING_ID_SHIFT));
1655
1656 if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) ||
1657 mv88e6xxx_6165_family(ds) || mv88e6xxx_6097_family(ds)) {
1658 /* Send all frames with destination addresses matching
1659 * 01:80:c2:00:00:2x to the CPU port.
1660 */
1661 REG_WRITE(REG_GLOBAL2, GLOBAL2_MGMT_EN_2X, 0xffff);
1662
1663 /* Initialise cross-chip port VLAN table to reset
1664 * defaults.
1665 */
1666 REG_WRITE(REG_GLOBAL2, GLOBAL2_PVT_ADDR, 0x9000);
1667
1668 /* Clear the priority override table. */
1669 for (i = 0; i < 16; i++)
1670 REG_WRITE(REG_GLOBAL2, GLOBAL2_PRIO_OVERRIDE,
1671 0x8000 | (i << 8));
1672 }
1673
1674 if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) ||
1675 mv88e6xxx_6165_family(ds) || mv88e6xxx_6097_family(ds) ||
1676 mv88e6xxx_6185_family(ds) || mv88e6xxx_6095_family(ds)) {
1677 /* Disable ingress rate limiting by resetting all
1678 * ingress rate limit registers to their initial
1679 * state.
1680 */
1681 for (i = 0; i < ps->num_ports; i++)
1682 REG_WRITE(REG_GLOBAL2, GLOBAL2_INGRESS_OP,
1683 0x9000 | (i << 8));
1684 }
1685
1686 return 0;
1687}
1688
143a8307
AL
1689int mv88e6xxx_switch_reset(struct dsa_switch *ds, bool ppu_active)
1690{
1691 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1692 u16 is_reset = (ppu_active ? 0x8800 : 0xc800);
1693 unsigned long timeout;
1694 int ret;
1695 int i;
1696
1697 /* Set all ports to the disabled state. */
1698 for (i = 0; i < ps->num_ports; i++) {
cca8b133
AL
1699 ret = REG_READ(REG_PORT(i), PORT_CONTROL);
1700 REG_WRITE(REG_PORT(i), PORT_CONTROL, ret & 0xfffc);
143a8307
AL
1701 }
1702
1703 /* Wait for transmit queues to drain. */
1704 usleep_range(2000, 4000);
1705
1706 /* Reset the switch. Keep the PPU active if requested. The PPU
1707 * needs to be active to support indirect phy register access
1708 * through global registers 0x18 and 0x19.
1709 */
1710 if (ppu_active)
1711 REG_WRITE(REG_GLOBAL, 0x04, 0xc000);
1712 else
1713 REG_WRITE(REG_GLOBAL, 0x04, 0xc400);
1714
1715 /* Wait up to one second for reset to complete. */
1716 timeout = jiffies + 1 * HZ;
1717 while (time_before(jiffies, timeout)) {
1718 ret = REG_READ(REG_GLOBAL, 0x00);
1719 if ((ret & is_reset) == is_reset)
1720 break;
1721 usleep_range(1000, 2000);
1722 }
1723 if (time_after(jiffies, timeout))
1724 return -ETIMEDOUT;
1725
1726 return 0;
1727}
1728
49143585
AL
1729int mv88e6xxx_phy_page_read(struct dsa_switch *ds, int port, int page, int reg)
1730{
1731 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1732 int ret;
1733
3898c148 1734 mutex_lock(&ps->smi_mutex);
fd3a0ee4 1735 ret = _mv88e6xxx_phy_write_indirect(ds, port, 0x16, page);
49143585
AL
1736 if (ret < 0)
1737 goto error;
fd3a0ee4 1738 ret = _mv88e6xxx_phy_read_indirect(ds, port, reg);
49143585 1739error:
fd3a0ee4 1740 _mv88e6xxx_phy_write_indirect(ds, port, 0x16, 0x0);
3898c148 1741 mutex_unlock(&ps->smi_mutex);
49143585
AL
1742 return ret;
1743}
1744
1745int mv88e6xxx_phy_page_write(struct dsa_switch *ds, int port, int page,
1746 int reg, int val)
1747{
1748 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1749 int ret;
1750
3898c148 1751 mutex_lock(&ps->smi_mutex);
fd3a0ee4 1752 ret = _mv88e6xxx_phy_write_indirect(ds, port, 0x16, page);
49143585
AL
1753 if (ret < 0)
1754 goto error;
1755
fd3a0ee4 1756 ret = _mv88e6xxx_phy_write_indirect(ds, port, reg, val);
49143585 1757error:
fd3a0ee4 1758 _mv88e6xxx_phy_write_indirect(ds, port, 0x16, 0x0);
3898c148 1759 mutex_unlock(&ps->smi_mutex);
fd3a0ee4
AL
1760 return ret;
1761}
1762
1763static int mv88e6xxx_port_to_phy_addr(struct dsa_switch *ds, int port)
1764{
1765 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1766
1767 if (port >= 0 && port < ps->num_ports)
1768 return port;
1769 return -EINVAL;
1770}
1771
1772int
1773mv88e6xxx_phy_read(struct dsa_switch *ds, int port, int regnum)
1774{
1775 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1776 int addr = mv88e6xxx_port_to_phy_addr(ds, port);
1777 int ret;
1778
1779 if (addr < 0)
1780 return addr;
1781
3898c148 1782 mutex_lock(&ps->smi_mutex);
fd3a0ee4 1783 ret = _mv88e6xxx_phy_read(ds, addr, regnum);
3898c148 1784 mutex_unlock(&ps->smi_mutex);
fd3a0ee4
AL
1785 return ret;
1786}
1787
1788int
1789mv88e6xxx_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val)
1790{
1791 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1792 int addr = mv88e6xxx_port_to_phy_addr(ds, port);
1793 int ret;
1794
1795 if (addr < 0)
1796 return addr;
1797
3898c148 1798 mutex_lock(&ps->smi_mutex);
fd3a0ee4 1799 ret = _mv88e6xxx_phy_write(ds, addr, regnum, val);
3898c148 1800 mutex_unlock(&ps->smi_mutex);
fd3a0ee4
AL
1801 return ret;
1802}
1803
1804int
1805mv88e6xxx_phy_read_indirect(struct dsa_switch *ds, int port, int regnum)
1806{
1807 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1808 int addr = mv88e6xxx_port_to_phy_addr(ds, port);
1809 int ret;
1810
1811 if (addr < 0)
1812 return addr;
1813
3898c148 1814 mutex_lock(&ps->smi_mutex);
fd3a0ee4 1815 ret = _mv88e6xxx_phy_read_indirect(ds, addr, regnum);
3898c148 1816 mutex_unlock(&ps->smi_mutex);
fd3a0ee4
AL
1817 return ret;
1818}
1819
1820int
1821mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int port, int regnum,
1822 u16 val)
1823{
1824 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1825 int addr = mv88e6xxx_port_to_phy_addr(ds, port);
1826 int ret;
1827
1828 if (addr < 0)
1829 return addr;
1830
3898c148 1831 mutex_lock(&ps->smi_mutex);
fd3a0ee4 1832 ret = _mv88e6xxx_phy_write_indirect(ds, addr, regnum, val);
3898c148 1833 mutex_unlock(&ps->smi_mutex);
49143585
AL
1834 return ret;
1835}
1836
98e67308
BH
1837static int __init mv88e6xxx_init(void)
1838{
1839#if IS_ENABLED(CONFIG_NET_DSA_MV88E6131)
1840 register_switch_driver(&mv88e6131_switch_driver);
1841#endif
1842#if IS_ENABLED(CONFIG_NET_DSA_MV88E6123_61_65)
1843 register_switch_driver(&mv88e6123_61_65_switch_driver);
42f27253 1844#endif
3ad50cca
GR
1845#if IS_ENABLED(CONFIG_NET_DSA_MV88E6352)
1846 register_switch_driver(&mv88e6352_switch_driver);
1847#endif
42f27253
AL
1848#if IS_ENABLED(CONFIG_NET_DSA_MV88E6171)
1849 register_switch_driver(&mv88e6171_switch_driver);
98e67308
BH
1850#endif
1851 return 0;
1852}
1853module_init(mv88e6xxx_init);
1854
1855static void __exit mv88e6xxx_cleanup(void)
1856{
42f27253
AL
1857#if IS_ENABLED(CONFIG_NET_DSA_MV88E6171)
1858 unregister_switch_driver(&mv88e6171_switch_driver);
1859#endif
98e67308
BH
1860#if IS_ENABLED(CONFIG_NET_DSA_MV88E6123_61_65)
1861 unregister_switch_driver(&mv88e6123_61_65_switch_driver);
1862#endif
1863#if IS_ENABLED(CONFIG_NET_DSA_MV88E6131)
1864 unregister_switch_driver(&mv88e6131_switch_driver);
1865#endif
1866}
1867module_exit(mv88e6xxx_cleanup);
3d825ede
BH
1868
1869MODULE_AUTHOR("Lennert Buytenhek <buytenh@wantstofly.org>");
1870MODULE_DESCRIPTION("Driver for Marvell 88E6XXX ethernet switch chips");
1871MODULE_LICENSE("GPL");
This page took 0.579908 seconds and 5 git commands to generate.