]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/net/dsa/mv88e6xxx.c
net: dsa: mv88e6xxx: pass compatible info
[mirror_ubuntu-artful-kernel.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 *
b8fee957
VD
5 * Copyright (c) 2015 CMC Electronics, Inc.
6 * Added support for VLAN Table Unit operations
7 *
14c7b3c3
AL
8 * Copyright (c) 2016 Andrew Lunn <andrew@lunn.ch>
9 *
91da11f8
LB
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 */
15
19b2f97e 16#include <linux/delay.h>
defb05b9 17#include <linux/etherdevice.h>
dea87024 18#include <linux/ethtool.h>
facd95b2 19#include <linux/if_bridge.h>
19b2f97e 20#include <linux/jiffies.h>
91da11f8 21#include <linux/list.h>
14c7b3c3 22#include <linux/mdio.h>
2bbba277 23#include <linux/module.h>
caac8545 24#include <linux/of_device.h>
b516d453 25#include <linux/of_mdio.h>
91da11f8 26#include <linux/netdevice.h>
c8c1b39a 27#include <linux/gpio/consumer.h>
91da11f8 28#include <linux/phy.h>
c8f0b869 29#include <net/dsa.h>
1f36faf2 30#include <net/switchdev.h>
91da11f8
LB
31#include "mv88e6xxx.h"
32
9f8b3ee1 33static void assert_reg_lock(struct mv88e6xxx_priv_state *ps)
3996a4ff 34{
9f8b3ee1
VD
35 if (unlikely(!mutex_is_locked(&ps->reg_lock))) {
36 dev_err(ps->dev, "Switch registers lock not held!\n");
3996a4ff
VD
37 dump_stack();
38 }
39}
40
3675c8d7 41/* If the switch's ADDR[4:0] strap pins are strapped to zero, it will
91da11f8
LB
42 * use all 32 SMI bus addresses on its SMI bus, and all switch registers
43 * will be directly accessible on some {device address,register address}
44 * pair. If the ADDR[4:0] pins are not strapped to zero, the switch
45 * will only respond to SMI transactions to that specific address, and
46 * an indirect addressing mechanism needs to be used to access its
47 * registers.
48 */
49static int mv88e6xxx_reg_wait_ready(struct mii_bus *bus, int sw_addr)
50{
51 int ret;
52 int i;
53
54 for (i = 0; i < 16; i++) {
6e899e6c 55 ret = mdiobus_read_nested(bus, sw_addr, SMI_CMD);
91da11f8
LB
56 if (ret < 0)
57 return ret;
58
cca8b133 59 if ((ret & SMI_CMD_BUSY) == 0)
91da11f8
LB
60 return 0;
61 }
62
63 return -ETIMEDOUT;
64}
65
b9b37713
VD
66static int __mv88e6xxx_reg_read(struct mii_bus *bus, int sw_addr, int addr,
67 int reg)
91da11f8
LB
68{
69 int ret;
70
71 if (sw_addr == 0)
6e899e6c 72 return mdiobus_read_nested(bus, addr, reg);
91da11f8 73
3675c8d7 74 /* Wait for the bus to become free. */
91da11f8
LB
75 ret = mv88e6xxx_reg_wait_ready(bus, sw_addr);
76 if (ret < 0)
77 return ret;
78
3675c8d7 79 /* Transmit the read command. */
6e899e6c
NA
80 ret = mdiobus_write_nested(bus, sw_addr, SMI_CMD,
81 SMI_CMD_OP_22_READ | (addr << 5) | reg);
91da11f8
LB
82 if (ret < 0)
83 return ret;
84
3675c8d7 85 /* Wait for the read command to complete. */
91da11f8
LB
86 ret = mv88e6xxx_reg_wait_ready(bus, sw_addr);
87 if (ret < 0)
88 return ret;
89
3675c8d7 90 /* Read the data. */
6e899e6c 91 ret = mdiobus_read_nested(bus, sw_addr, SMI_DATA);
91da11f8
LB
92 if (ret < 0)
93 return ret;
94
95 return ret & 0xffff;
96}
97
158bc065
AL
98static int _mv88e6xxx_reg_read(struct mv88e6xxx_priv_state *ps,
99 int addr, int reg)
91da11f8 100{
91da11f8
LB
101 int ret;
102
9f8b3ee1 103 assert_reg_lock(ps);
3996a4ff 104
a77d43f1 105 ret = __mv88e6xxx_reg_read(ps->bus, ps->sw_addr, addr, reg);
bb92ea5e
VD
106 if (ret < 0)
107 return ret;
108
158bc065 109 dev_dbg(ps->dev, "<- addr: 0x%.2x reg: 0x%.2x val: 0x%.4x\n",
bb92ea5e
VD
110 addr, reg, ret);
111
91da11f8
LB
112 return ret;
113}
114
57d32310
VD
115static int mv88e6xxx_reg_read(struct mv88e6xxx_priv_state *ps, int addr,
116 int reg)
8d6d09e7 117{
8d6d09e7
GR
118 int ret;
119
9f8b3ee1 120 mutex_lock(&ps->reg_lock);
158bc065 121 ret = _mv88e6xxx_reg_read(ps, addr, reg);
9f8b3ee1 122 mutex_unlock(&ps->reg_lock);
8d6d09e7
GR
123
124 return ret;
125}
126
b9b37713
VD
127static int __mv88e6xxx_reg_write(struct mii_bus *bus, int sw_addr, int addr,
128 int reg, u16 val)
91da11f8
LB
129{
130 int ret;
131
132 if (sw_addr == 0)
6e899e6c 133 return mdiobus_write_nested(bus, addr, reg, val);
91da11f8 134
3675c8d7 135 /* Wait for the bus to become free. */
91da11f8
LB
136 ret = mv88e6xxx_reg_wait_ready(bus, sw_addr);
137 if (ret < 0)
138 return ret;
139
3675c8d7 140 /* Transmit the data to write. */
6e899e6c 141 ret = mdiobus_write_nested(bus, sw_addr, SMI_DATA, val);
91da11f8
LB
142 if (ret < 0)
143 return ret;
144
3675c8d7 145 /* Transmit the write command. */
6e899e6c
NA
146 ret = mdiobus_write_nested(bus, sw_addr, SMI_CMD,
147 SMI_CMD_OP_22_WRITE | (addr << 5) | reg);
91da11f8
LB
148 if (ret < 0)
149 return ret;
150
3675c8d7 151 /* Wait for the write command to complete. */
91da11f8
LB
152 ret = mv88e6xxx_reg_wait_ready(bus, sw_addr);
153 if (ret < 0)
154 return ret;
155
156 return 0;
157}
158
158bc065
AL
159static int _mv88e6xxx_reg_write(struct mv88e6xxx_priv_state *ps, int addr,
160 int reg, u16 val)
91da11f8 161{
9f8b3ee1 162 assert_reg_lock(ps);
91da11f8 163
158bc065 164 dev_dbg(ps->dev, "-> addr: 0x%.2x reg: 0x%.2x val: 0x%.4x\n",
bb92ea5e
VD
165 addr, reg, val);
166
a77d43f1 167 return __mv88e6xxx_reg_write(ps->bus, ps->sw_addr, addr, reg, val);
8d6d09e7
GR
168}
169
57d32310
VD
170static int mv88e6xxx_reg_write(struct mv88e6xxx_priv_state *ps, int addr,
171 int reg, u16 val)
8d6d09e7 172{
8d6d09e7
GR
173 int ret;
174
9f8b3ee1 175 mutex_lock(&ps->reg_lock);
158bc065 176 ret = _mv88e6xxx_reg_write(ps, addr, reg, val);
9f8b3ee1 177 mutex_unlock(&ps->reg_lock);
91da11f8
LB
178
179 return ret;
180}
181
1d13a06e 182static int mv88e6xxx_set_addr_direct(struct dsa_switch *ds, u8 *addr)
2e5f0320 183{
158bc065 184 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
48ace4ef 185 int err;
2e5f0320 186
158bc065 187 err = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_MAC_01,
48ace4ef
AL
188 (addr[0] << 8) | addr[1]);
189 if (err)
190 return err;
191
158bc065 192 err = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_MAC_23,
48ace4ef
AL
193 (addr[2] << 8) | addr[3]);
194 if (err)
195 return err;
196
158bc065 197 return mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_MAC_45,
48ace4ef 198 (addr[4] << 8) | addr[5]);
2e5f0320
LB
199}
200
1d13a06e 201static int mv88e6xxx_set_addr_indirect(struct dsa_switch *ds, u8 *addr)
91da11f8 202{
158bc065 203 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
91da11f8 204 int ret;
48ace4ef 205 int i;
91da11f8
LB
206
207 for (i = 0; i < 6; i++) {
208 int j;
209
3675c8d7 210 /* Write the MAC address byte. */
158bc065 211 ret = mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_SWITCH_MAC,
48ace4ef
AL
212 GLOBAL2_SWITCH_MAC_BUSY |
213 (i << 8) | addr[i]);
214 if (ret)
215 return ret;
91da11f8 216
3675c8d7 217 /* Wait for the write to complete. */
91da11f8 218 for (j = 0; j < 16; j++) {
158bc065 219 ret = mv88e6xxx_reg_read(ps, REG_GLOBAL2,
48ace4ef
AL
220 GLOBAL2_SWITCH_MAC);
221 if (ret < 0)
222 return ret;
223
cca8b133 224 if ((ret & GLOBAL2_SWITCH_MAC_BUSY) == 0)
91da11f8
LB
225 break;
226 }
227 if (j == 16)
228 return -ETIMEDOUT;
229 }
230
231 return 0;
232}
233
57d32310 234static int mv88e6xxx_set_addr(struct dsa_switch *ds, u8 *addr)
1d13a06e
VD
235{
236 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
237
238 if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_SWITCH_MAC))
239 return mv88e6xxx_set_addr_indirect(ds, addr);
240 else
241 return mv88e6xxx_set_addr_direct(ds, addr);
242}
243
03a4a540
AL
244static int mv88e6xxx_mdio_read_direct(struct mv88e6xxx_priv_state *ps,
245 int addr, int regnum)
91da11f8
LB
246{
247 if (addr >= 0)
158bc065 248 return _mv88e6xxx_reg_read(ps, addr, regnum);
91da11f8
LB
249 return 0xffff;
250}
251
03a4a540
AL
252static int mv88e6xxx_mdio_write_direct(struct mv88e6xxx_priv_state *ps,
253 int addr, int regnum, u16 val)
91da11f8
LB
254{
255 if (addr >= 0)
158bc065 256 return _mv88e6xxx_reg_write(ps, addr, regnum, val);
91da11f8
LB
257 return 0;
258}
259
158bc065 260static int mv88e6xxx_ppu_disable(struct mv88e6xxx_priv_state *ps)
2e5f0320
LB
261{
262 int ret;
19b2f97e 263 unsigned long timeout;
2e5f0320 264
8c9983a2 265 ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL, GLOBAL_CONTROL);
48ace4ef
AL
266 if (ret < 0)
267 return ret;
268
8c9983a2
VD
269 ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL,
270 ret & ~GLOBAL_CONTROL_PPU_ENABLE);
48ace4ef
AL
271 if (ret)
272 return ret;
2e5f0320 273
19b2f97e
BG
274 timeout = jiffies + 1 * HZ;
275 while (time_before(jiffies, timeout)) {
8c9983a2 276 ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL, GLOBAL_STATUS);
48ace4ef
AL
277 if (ret < 0)
278 return ret;
279
19b2f97e 280 usleep_range(1000, 2000);
cca8b133
AL
281 if ((ret & GLOBAL_STATUS_PPU_MASK) !=
282 GLOBAL_STATUS_PPU_POLLING)
85686581 283 return 0;
2e5f0320
LB
284 }
285
286 return -ETIMEDOUT;
287}
288
158bc065 289static int mv88e6xxx_ppu_enable(struct mv88e6xxx_priv_state *ps)
2e5f0320 290{
48ace4ef 291 int ret, err;
19b2f97e 292 unsigned long timeout;
2e5f0320 293
762eb67b 294 ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL, GLOBAL_CONTROL);
48ace4ef
AL
295 if (ret < 0)
296 return ret;
297
762eb67b
VD
298 err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL,
299 ret | GLOBAL_CONTROL_PPU_ENABLE);
48ace4ef
AL
300 if (err)
301 return err;
2e5f0320 302
19b2f97e
BG
303 timeout = jiffies + 1 * HZ;
304 while (time_before(jiffies, timeout)) {
762eb67b 305 ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL, GLOBAL_STATUS);
48ace4ef
AL
306 if (ret < 0)
307 return ret;
308
19b2f97e 309 usleep_range(1000, 2000);
cca8b133
AL
310 if ((ret & GLOBAL_STATUS_PPU_MASK) ==
311 GLOBAL_STATUS_PPU_POLLING)
85686581 312 return 0;
2e5f0320
LB
313 }
314
315 return -ETIMEDOUT;
316}
317
318static void mv88e6xxx_ppu_reenable_work(struct work_struct *ugly)
319{
320 struct mv88e6xxx_priv_state *ps;
321
322 ps = container_of(ugly, struct mv88e6xxx_priv_state, ppu_work);
762eb67b 323
9f8b3ee1 324 mutex_lock(&ps->reg_lock);
762eb67b 325
2e5f0320 326 if (mutex_trylock(&ps->ppu_mutex)) {
158bc065 327 if (mv88e6xxx_ppu_enable(ps) == 0)
85686581
BG
328 ps->ppu_disabled = 0;
329 mutex_unlock(&ps->ppu_mutex);
2e5f0320 330 }
762eb67b 331
9f8b3ee1 332 mutex_unlock(&ps->reg_lock);
2e5f0320
LB
333}
334
335static void mv88e6xxx_ppu_reenable_timer(unsigned long _ps)
336{
337 struct mv88e6xxx_priv_state *ps = (void *)_ps;
338
339 schedule_work(&ps->ppu_work);
340}
341
158bc065 342static int mv88e6xxx_ppu_access_get(struct mv88e6xxx_priv_state *ps)
2e5f0320 343{
2e5f0320
LB
344 int ret;
345
346 mutex_lock(&ps->ppu_mutex);
347
3675c8d7 348 /* If the PHY polling unit is enabled, disable it so that
2e5f0320
LB
349 * we can access the PHY registers. If it was already
350 * disabled, cancel the timer that is going to re-enable
351 * it.
352 */
353 if (!ps->ppu_disabled) {
158bc065 354 ret = mv88e6xxx_ppu_disable(ps);
85686581
BG
355 if (ret < 0) {
356 mutex_unlock(&ps->ppu_mutex);
357 return ret;
358 }
359 ps->ppu_disabled = 1;
2e5f0320 360 } else {
85686581
BG
361 del_timer(&ps->ppu_timer);
362 ret = 0;
2e5f0320
LB
363 }
364
365 return ret;
366}
367
158bc065 368static void mv88e6xxx_ppu_access_put(struct mv88e6xxx_priv_state *ps)
2e5f0320 369{
3675c8d7 370 /* Schedule a timer to re-enable the PHY polling unit. */
2e5f0320
LB
371 mod_timer(&ps->ppu_timer, jiffies + msecs_to_jiffies(10));
372 mutex_unlock(&ps->ppu_mutex);
373}
374
57d32310 375static void mv88e6xxx_ppu_state_init(struct mv88e6xxx_priv_state *ps)
2e5f0320 376{
2e5f0320
LB
377 mutex_init(&ps->ppu_mutex);
378 INIT_WORK(&ps->ppu_work, mv88e6xxx_ppu_reenable_work);
379 init_timer(&ps->ppu_timer);
380 ps->ppu_timer.data = (unsigned long)ps;
381 ps->ppu_timer.function = mv88e6xxx_ppu_reenable_timer;
382}
383
03a4a540
AL
384static int mv88e6xxx_mdio_read_ppu(struct mv88e6xxx_priv_state *ps, int addr,
385 int regnum)
2e5f0320
LB
386{
387 int ret;
388
158bc065 389 ret = mv88e6xxx_ppu_access_get(ps);
2e5f0320 390 if (ret >= 0) {
8c9983a2 391 ret = _mv88e6xxx_reg_read(ps, addr, regnum);
158bc065 392 mv88e6xxx_ppu_access_put(ps);
2e5f0320
LB
393 }
394
395 return ret;
396}
397
03a4a540
AL
398static int mv88e6xxx_mdio_write_ppu(struct mv88e6xxx_priv_state *ps, int addr,
399 int regnum, u16 val)
2e5f0320
LB
400{
401 int ret;
402
158bc065 403 ret = mv88e6xxx_ppu_access_get(ps);
2e5f0320 404 if (ret >= 0) {
8c9983a2 405 ret = _mv88e6xxx_reg_write(ps, addr, regnum, val);
158bc065 406 mv88e6xxx_ppu_access_put(ps);
2e5f0320
LB
407 }
408
409 return ret;
410}
2e5f0320 411
158bc065 412static bool mv88e6xxx_6065_family(struct mv88e6xxx_priv_state *ps)
54d792f2 413{
22356476 414 return ps->info->family == MV88E6XXX_FAMILY_6065;
54d792f2
AL
415}
416
158bc065 417static bool mv88e6xxx_6095_family(struct mv88e6xxx_priv_state *ps)
54d792f2 418{
22356476 419 return ps->info->family == MV88E6XXX_FAMILY_6095;
54d792f2
AL
420}
421
158bc065 422static bool mv88e6xxx_6097_family(struct mv88e6xxx_priv_state *ps)
54d792f2 423{
22356476 424 return ps->info->family == MV88E6XXX_FAMILY_6097;
54d792f2
AL
425}
426
158bc065 427static bool mv88e6xxx_6165_family(struct mv88e6xxx_priv_state *ps)
54d792f2 428{
22356476 429 return ps->info->family == MV88E6XXX_FAMILY_6165;
54d792f2
AL
430}
431
158bc065 432static bool mv88e6xxx_6185_family(struct mv88e6xxx_priv_state *ps)
54d792f2 433{
22356476 434 return ps->info->family == MV88E6XXX_FAMILY_6185;
54d792f2
AL
435}
436
158bc065 437static bool mv88e6xxx_6320_family(struct mv88e6xxx_priv_state *ps)
7c3d0d67 438{
22356476 439 return ps->info->family == MV88E6XXX_FAMILY_6320;
7c3d0d67
AK
440}
441
158bc065 442static bool mv88e6xxx_6351_family(struct mv88e6xxx_priv_state *ps)
54d792f2 443{
22356476 444 return ps->info->family == MV88E6XXX_FAMILY_6351;
54d792f2
AL
445}
446
158bc065 447static bool mv88e6xxx_6352_family(struct mv88e6xxx_priv_state *ps)
f3a8b6b6 448{
22356476 449 return ps->info->family == MV88E6XXX_FAMILY_6352;
f3a8b6b6
AL
450}
451
158bc065 452static unsigned int mv88e6xxx_num_databases(struct mv88e6xxx_priv_state *ps)
f74df0be 453{
cd5a2c82 454 return ps->info->num_databases;
f74df0be
VD
455}
456
158bc065 457static bool mv88e6xxx_has_fid_reg(struct mv88e6xxx_priv_state *ps)
b426e5f7
VD
458{
459 /* Does the device have dedicated FID registers for ATU and VTU ops? */
158bc065
AL
460 if (mv88e6xxx_6097_family(ps) || mv88e6xxx_6165_family(ps) ||
461 mv88e6xxx_6351_family(ps) || mv88e6xxx_6352_family(ps))
b426e5f7
VD
462 return true;
463
464 return false;
465}
466
dea87024
AL
467/* We expect the switch to perform auto negotiation if there is a real
468 * phy. However, in the case of a fixed link phy, we force the port
469 * settings from the fixed link settings.
470 */
f81ec90f
VD
471static void mv88e6xxx_adjust_link(struct dsa_switch *ds, int port,
472 struct phy_device *phydev)
dea87024
AL
473{
474 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
49052871
AL
475 u32 reg;
476 int ret;
dea87024
AL
477
478 if (!phy_is_pseudo_fixed_link(phydev))
479 return;
480
9f8b3ee1 481 mutex_lock(&ps->reg_lock);
dea87024 482
158bc065 483 ret = _mv88e6xxx_reg_read(ps, REG_PORT(port), PORT_PCS_CTRL);
dea87024
AL
484 if (ret < 0)
485 goto out;
486
487 reg = ret & ~(PORT_PCS_CTRL_LINK_UP |
488 PORT_PCS_CTRL_FORCE_LINK |
489 PORT_PCS_CTRL_DUPLEX_FULL |
490 PORT_PCS_CTRL_FORCE_DUPLEX |
491 PORT_PCS_CTRL_UNFORCED);
492
493 reg |= PORT_PCS_CTRL_FORCE_LINK;
494 if (phydev->link)
57d32310 495 reg |= PORT_PCS_CTRL_LINK_UP;
dea87024 496
158bc065 497 if (mv88e6xxx_6065_family(ps) && phydev->speed > SPEED_100)
dea87024
AL
498 goto out;
499
500 switch (phydev->speed) {
501 case SPEED_1000:
502 reg |= PORT_PCS_CTRL_1000;
503 break;
504 case SPEED_100:
505 reg |= PORT_PCS_CTRL_100;
506 break;
507 case SPEED_10:
508 reg |= PORT_PCS_CTRL_10;
509 break;
510 default:
511 pr_info("Unknown speed");
512 goto out;
513 }
514
515 reg |= PORT_PCS_CTRL_FORCE_DUPLEX;
516 if (phydev->duplex == DUPLEX_FULL)
517 reg |= PORT_PCS_CTRL_DUPLEX_FULL;
518
158bc065 519 if ((mv88e6xxx_6352_family(ps) || mv88e6xxx_6351_family(ps)) &&
009a2b98 520 (port >= ps->info->num_ports - 2)) {
e7e72ac0
AL
521 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
522 reg |= PORT_PCS_CTRL_RGMII_DELAY_RXCLK;
523 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
524 reg |= PORT_PCS_CTRL_RGMII_DELAY_TXCLK;
525 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
526 reg |= (PORT_PCS_CTRL_RGMII_DELAY_RXCLK |
527 PORT_PCS_CTRL_RGMII_DELAY_TXCLK);
528 }
158bc065 529 _mv88e6xxx_reg_write(ps, REG_PORT(port), PORT_PCS_CTRL, reg);
dea87024
AL
530
531out:
9f8b3ee1 532 mutex_unlock(&ps->reg_lock);
dea87024
AL
533}
534
158bc065 535static int _mv88e6xxx_stats_wait(struct mv88e6xxx_priv_state *ps)
91da11f8
LB
536{
537 int ret;
538 int i;
539
540 for (i = 0; i < 10; i++) {
158bc065 541 ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL, GLOBAL_STATS_OP);
cca8b133 542 if ((ret & GLOBAL_STATS_OP_BUSY) == 0)
91da11f8
LB
543 return 0;
544 }
545
546 return -ETIMEDOUT;
547}
548
158bc065
AL
549static int _mv88e6xxx_stats_snapshot(struct mv88e6xxx_priv_state *ps,
550 int port)
91da11f8
LB
551{
552 int ret;
553
158bc065 554 if (mv88e6xxx_6320_family(ps) || mv88e6xxx_6352_family(ps))
f3a8b6b6
AL
555 port = (port + 1) << 5;
556
3675c8d7 557 /* Snapshot the hardware statistics counters for this port. */
158bc065 558 ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_STATS_OP,
31888234
AL
559 GLOBAL_STATS_OP_CAPTURE_PORT |
560 GLOBAL_STATS_OP_HIST_RX_TX | port);
561 if (ret < 0)
562 return ret;
91da11f8 563
3675c8d7 564 /* Wait for the snapshotting to complete. */
158bc065 565 ret = _mv88e6xxx_stats_wait(ps);
91da11f8
LB
566 if (ret < 0)
567 return ret;
568
569 return 0;
570}
571
158bc065
AL
572static void _mv88e6xxx_stats_read(struct mv88e6xxx_priv_state *ps,
573 int stat, u32 *val)
91da11f8
LB
574{
575 u32 _val;
576 int ret;
577
578 *val = 0;
579
158bc065 580 ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_STATS_OP,
31888234
AL
581 GLOBAL_STATS_OP_READ_CAPTURED |
582 GLOBAL_STATS_OP_HIST_RX_TX | stat);
91da11f8
LB
583 if (ret < 0)
584 return;
585
158bc065 586 ret = _mv88e6xxx_stats_wait(ps);
91da11f8
LB
587 if (ret < 0)
588 return;
589
158bc065 590 ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL, GLOBAL_STATS_COUNTER_32);
91da11f8
LB
591 if (ret < 0)
592 return;
593
594 _val = ret << 16;
595
158bc065 596 ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL, GLOBAL_STATS_COUNTER_01);
91da11f8
LB
597 if (ret < 0)
598 return;
599
600 *val = _val | ret;
601}
602
e413e7e1 603static struct mv88e6xxx_hw_stat mv88e6xxx_hw_stats[] = {
f5e2ed02
AL
604 { "in_good_octets", 8, 0x00, BANK0, },
605 { "in_bad_octets", 4, 0x02, BANK0, },
606 { "in_unicast", 4, 0x04, BANK0, },
607 { "in_broadcasts", 4, 0x06, BANK0, },
608 { "in_multicasts", 4, 0x07, BANK0, },
609 { "in_pause", 4, 0x16, BANK0, },
610 { "in_undersize", 4, 0x18, BANK0, },
611 { "in_fragments", 4, 0x19, BANK0, },
612 { "in_oversize", 4, 0x1a, BANK0, },
613 { "in_jabber", 4, 0x1b, BANK0, },
614 { "in_rx_error", 4, 0x1c, BANK0, },
615 { "in_fcs_error", 4, 0x1d, BANK0, },
616 { "out_octets", 8, 0x0e, BANK0, },
617 { "out_unicast", 4, 0x10, BANK0, },
618 { "out_broadcasts", 4, 0x13, BANK0, },
619 { "out_multicasts", 4, 0x12, BANK0, },
620 { "out_pause", 4, 0x15, BANK0, },
621 { "excessive", 4, 0x11, BANK0, },
622 { "collisions", 4, 0x1e, BANK0, },
623 { "deferred", 4, 0x05, BANK0, },
624 { "single", 4, 0x14, BANK0, },
625 { "multiple", 4, 0x17, BANK0, },
626 { "out_fcs_error", 4, 0x03, BANK0, },
627 { "late", 4, 0x1f, BANK0, },
628 { "hist_64bytes", 4, 0x08, BANK0, },
629 { "hist_65_127bytes", 4, 0x09, BANK0, },
630 { "hist_128_255bytes", 4, 0x0a, BANK0, },
631 { "hist_256_511bytes", 4, 0x0b, BANK0, },
632 { "hist_512_1023bytes", 4, 0x0c, BANK0, },
633 { "hist_1024_max_bytes", 4, 0x0d, BANK0, },
634 { "sw_in_discards", 4, 0x10, PORT, },
635 { "sw_in_filtered", 2, 0x12, PORT, },
636 { "sw_out_filtered", 2, 0x13, PORT, },
637 { "in_discards", 4, 0x00 | GLOBAL_STATS_OP_BANK_1, BANK1, },
638 { "in_filtered", 4, 0x01 | GLOBAL_STATS_OP_BANK_1, BANK1, },
639 { "in_accepted", 4, 0x02 | GLOBAL_STATS_OP_BANK_1, BANK1, },
640 { "in_bad_accepted", 4, 0x03 | GLOBAL_STATS_OP_BANK_1, BANK1, },
641 { "in_good_avb_class_a", 4, 0x04 | GLOBAL_STATS_OP_BANK_1, BANK1, },
642 { "in_good_avb_class_b", 4, 0x05 | GLOBAL_STATS_OP_BANK_1, BANK1, },
643 { "in_bad_avb_class_a", 4, 0x06 | GLOBAL_STATS_OP_BANK_1, BANK1, },
644 { "in_bad_avb_class_b", 4, 0x07 | GLOBAL_STATS_OP_BANK_1, BANK1, },
645 { "tcam_counter_0", 4, 0x08 | GLOBAL_STATS_OP_BANK_1, BANK1, },
646 { "tcam_counter_1", 4, 0x09 | GLOBAL_STATS_OP_BANK_1, BANK1, },
647 { "tcam_counter_2", 4, 0x0a | GLOBAL_STATS_OP_BANK_1, BANK1, },
648 { "tcam_counter_3", 4, 0x0b | GLOBAL_STATS_OP_BANK_1, BANK1, },
649 { "in_da_unknown", 4, 0x0e | GLOBAL_STATS_OP_BANK_1, BANK1, },
650 { "in_management", 4, 0x0f | GLOBAL_STATS_OP_BANK_1, BANK1, },
651 { "out_queue_0", 4, 0x10 | GLOBAL_STATS_OP_BANK_1, BANK1, },
652 { "out_queue_1", 4, 0x11 | GLOBAL_STATS_OP_BANK_1, BANK1, },
653 { "out_queue_2", 4, 0x12 | GLOBAL_STATS_OP_BANK_1, BANK1, },
654 { "out_queue_3", 4, 0x13 | GLOBAL_STATS_OP_BANK_1, BANK1, },
655 { "out_queue_4", 4, 0x14 | GLOBAL_STATS_OP_BANK_1, BANK1, },
656 { "out_queue_5", 4, 0x15 | GLOBAL_STATS_OP_BANK_1, BANK1, },
657 { "out_queue_6", 4, 0x16 | GLOBAL_STATS_OP_BANK_1, BANK1, },
658 { "out_queue_7", 4, 0x17 | GLOBAL_STATS_OP_BANK_1, BANK1, },
659 { "out_cut_through", 4, 0x18 | GLOBAL_STATS_OP_BANK_1, BANK1, },
660 { "out_octets_a", 4, 0x1a | GLOBAL_STATS_OP_BANK_1, BANK1, },
661 { "out_octets_b", 4, 0x1b | GLOBAL_STATS_OP_BANK_1, BANK1, },
662 { "out_management", 4, 0x1f | GLOBAL_STATS_OP_BANK_1, BANK1, },
e413e7e1
AL
663};
664
158bc065 665static bool mv88e6xxx_has_stat(struct mv88e6xxx_priv_state *ps,
f5e2ed02 666 struct mv88e6xxx_hw_stat *stat)
e413e7e1 667{
f5e2ed02
AL
668 switch (stat->type) {
669 case BANK0:
e413e7e1 670 return true;
f5e2ed02 671 case BANK1:
158bc065 672 return mv88e6xxx_6320_family(ps);
f5e2ed02 673 case PORT:
158bc065
AL
674 return mv88e6xxx_6095_family(ps) ||
675 mv88e6xxx_6185_family(ps) ||
676 mv88e6xxx_6097_family(ps) ||
677 mv88e6xxx_6165_family(ps) ||
678 mv88e6xxx_6351_family(ps) ||
679 mv88e6xxx_6352_family(ps);
91da11f8 680 }
f5e2ed02 681 return false;
91da11f8
LB
682}
683
158bc065 684static uint64_t _mv88e6xxx_get_ethtool_stat(struct mv88e6xxx_priv_state *ps,
f5e2ed02 685 struct mv88e6xxx_hw_stat *s,
80c4627b
AL
686 int port)
687{
80c4627b
AL
688 u32 low;
689 u32 high = 0;
690 int ret;
691 u64 value;
692
f5e2ed02
AL
693 switch (s->type) {
694 case PORT:
158bc065 695 ret = _mv88e6xxx_reg_read(ps, REG_PORT(port), s->reg);
80c4627b
AL
696 if (ret < 0)
697 return UINT64_MAX;
698
699 low = ret;
700 if (s->sizeof_stat == 4) {
158bc065 701 ret = _mv88e6xxx_reg_read(ps, REG_PORT(port),
f5e2ed02 702 s->reg + 1);
80c4627b
AL
703 if (ret < 0)
704 return UINT64_MAX;
705 high = ret;
706 }
f5e2ed02
AL
707 break;
708 case BANK0:
709 case BANK1:
158bc065 710 _mv88e6xxx_stats_read(ps, s->reg, &low);
80c4627b 711 if (s->sizeof_stat == 8)
158bc065 712 _mv88e6xxx_stats_read(ps, s->reg + 1, &high);
80c4627b
AL
713 }
714 value = (((u64)high) << 16) | low;
715 return value;
716}
717
f81ec90f
VD
718static void mv88e6xxx_get_strings(struct dsa_switch *ds, int port,
719 uint8_t *data)
91da11f8 720{
158bc065 721 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
f5e2ed02
AL
722 struct mv88e6xxx_hw_stat *stat;
723 int i, j;
91da11f8 724
f5e2ed02
AL
725 for (i = 0, j = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) {
726 stat = &mv88e6xxx_hw_stats[i];
158bc065 727 if (mv88e6xxx_has_stat(ps, stat)) {
f5e2ed02
AL
728 memcpy(data + j * ETH_GSTRING_LEN, stat->string,
729 ETH_GSTRING_LEN);
730 j++;
731 }
91da11f8 732 }
e413e7e1
AL
733}
734
f81ec90f 735static int mv88e6xxx_get_sset_count(struct dsa_switch *ds)
e413e7e1 736{
158bc065 737 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
f5e2ed02
AL
738 struct mv88e6xxx_hw_stat *stat;
739 int i, j;
740
741 for (i = 0, j = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) {
742 stat = &mv88e6xxx_hw_stats[i];
158bc065 743 if (mv88e6xxx_has_stat(ps, stat))
f5e2ed02
AL
744 j++;
745 }
746 return j;
e413e7e1
AL
747}
748
f81ec90f
VD
749static void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, int port,
750 uint64_t *data)
e413e7e1 751{
f5e2ed02
AL
752 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
753 struct mv88e6xxx_hw_stat *stat;
754 int ret;
755 int i, j;
756
9f8b3ee1 757 mutex_lock(&ps->reg_lock);
f5e2ed02 758
158bc065 759 ret = _mv88e6xxx_stats_snapshot(ps, port);
f5e2ed02 760 if (ret < 0) {
9f8b3ee1 761 mutex_unlock(&ps->reg_lock);
f5e2ed02
AL
762 return;
763 }
764 for (i = 0, j = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) {
765 stat = &mv88e6xxx_hw_stats[i];
158bc065
AL
766 if (mv88e6xxx_has_stat(ps, stat)) {
767 data[j] = _mv88e6xxx_get_ethtool_stat(ps, stat, port);
f5e2ed02
AL
768 j++;
769 }
770 }
771
9f8b3ee1 772 mutex_unlock(&ps->reg_lock);
e413e7e1
AL
773}
774
f81ec90f 775static int mv88e6xxx_get_regs_len(struct dsa_switch *ds, int port)
a1ab91f3
GR
776{
777 return 32 * sizeof(u16);
778}
779
f81ec90f
VD
780static void mv88e6xxx_get_regs(struct dsa_switch *ds, int port,
781 struct ethtool_regs *regs, void *_p)
a1ab91f3 782{
158bc065 783 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
a1ab91f3
GR
784 u16 *p = _p;
785 int i;
786
787 regs->version = 0;
788
789 memset(p, 0xff, 32 * sizeof(u16));
790
9f8b3ee1 791 mutex_lock(&ps->reg_lock);
23062513 792
a1ab91f3
GR
793 for (i = 0; i < 32; i++) {
794 int ret;
795
23062513 796 ret = _mv88e6xxx_reg_read(ps, REG_PORT(port), i);
a1ab91f3
GR
797 if (ret >= 0)
798 p[i] = ret;
799 }
23062513 800
9f8b3ee1 801 mutex_unlock(&ps->reg_lock);
a1ab91f3
GR
802}
803
158bc065 804static int _mv88e6xxx_wait(struct mv88e6xxx_priv_state *ps, int reg, int offset,
3898c148 805 u16 mask)
f3044683
AL
806{
807 unsigned long timeout = jiffies + HZ / 10;
808
809 while (time_before(jiffies, timeout)) {
810 int ret;
811
158bc065 812 ret = _mv88e6xxx_reg_read(ps, reg, offset);
3898c148
AL
813 if (ret < 0)
814 return ret;
f3044683
AL
815 if (!(ret & mask))
816 return 0;
817
818 usleep_range(1000, 2000);
819 }
820 return -ETIMEDOUT;
821}
822
158bc065
AL
823static int mv88e6xxx_wait(struct mv88e6xxx_priv_state *ps, int reg,
824 int offset, u16 mask)
3898c148 825{
3898c148
AL
826 int ret;
827
9f8b3ee1 828 mutex_lock(&ps->reg_lock);
158bc065 829 ret = _mv88e6xxx_wait(ps, reg, offset, mask);
9f8b3ee1 830 mutex_unlock(&ps->reg_lock);
3898c148
AL
831
832 return ret;
833}
834
03a4a540 835static int mv88e6xxx_mdio_wait(struct mv88e6xxx_priv_state *ps)
f3044683 836{
158bc065 837 return _mv88e6xxx_wait(ps, REG_GLOBAL2, GLOBAL2_SMI_OP,
3898c148 838 GLOBAL2_SMI_OP_BUSY);
f3044683
AL
839}
840
d24645be 841static int mv88e6xxx_eeprom_load_wait(struct dsa_switch *ds)
f3044683 842{
158bc065
AL
843 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
844
845 return mv88e6xxx_wait(ps, REG_GLOBAL2, GLOBAL2_EEPROM_OP,
cca8b133 846 GLOBAL2_EEPROM_OP_LOAD);
f3044683
AL
847}
848
d24645be 849static int mv88e6xxx_eeprom_busy_wait(struct dsa_switch *ds)
f3044683 850{
158bc065
AL
851 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
852
853 return mv88e6xxx_wait(ps, REG_GLOBAL2, GLOBAL2_EEPROM_OP,
cca8b133 854 GLOBAL2_EEPROM_OP_BUSY);
f3044683
AL
855}
856
d24645be
VD
857static int mv88e6xxx_read_eeprom_word(struct dsa_switch *ds, int addr)
858{
859 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
860 int ret;
861
862 mutex_lock(&ps->eeprom_mutex);
863
864 ret = mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_EEPROM_OP,
865 GLOBAL2_EEPROM_OP_READ |
866 (addr & GLOBAL2_EEPROM_OP_ADDR_MASK));
867 if (ret < 0)
868 goto error;
869
870 ret = mv88e6xxx_eeprom_busy_wait(ds);
871 if (ret < 0)
872 goto error;
873
874 ret = mv88e6xxx_reg_read(ps, REG_GLOBAL2, GLOBAL2_EEPROM_DATA);
875error:
876 mutex_unlock(&ps->eeprom_mutex);
877 return ret;
878}
879
f8cd8753
AL
880static int mv88e6xxx_get_eeprom_len(struct dsa_switch *ds)
881{
882 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
883
884 if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_EEPROM))
885 return ps->eeprom_len;
886
887 return 0;
888}
889
f81ec90f
VD
890static int mv88e6xxx_get_eeprom(struct dsa_switch *ds,
891 struct ethtool_eeprom *eeprom, u8 *data)
d24645be
VD
892{
893 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
894 int offset;
895 int len;
896 int ret;
897
898 if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_EEPROM))
899 return -EOPNOTSUPP;
900
901 offset = eeprom->offset;
902 len = eeprom->len;
903 eeprom->len = 0;
904
905 eeprom->magic = 0xc3ec4951;
906
907 ret = mv88e6xxx_eeprom_load_wait(ds);
908 if (ret < 0)
909 return ret;
910
911 if (offset & 1) {
912 int word;
913
914 word = mv88e6xxx_read_eeprom_word(ds, offset >> 1);
915 if (word < 0)
916 return word;
917
918 *data++ = (word >> 8) & 0xff;
919
920 offset++;
921 len--;
922 eeprom->len++;
923 }
924
925 while (len >= 2) {
926 int word;
927
928 word = mv88e6xxx_read_eeprom_word(ds, offset >> 1);
929 if (word < 0)
930 return word;
931
932 *data++ = word & 0xff;
933 *data++ = (word >> 8) & 0xff;
934
935 offset += 2;
936 len -= 2;
937 eeprom->len += 2;
938 }
939
940 if (len) {
941 int word;
942
943 word = mv88e6xxx_read_eeprom_word(ds, offset >> 1);
944 if (word < 0)
945 return word;
946
947 *data++ = word & 0xff;
948
949 offset++;
950 len--;
951 eeprom->len++;
952 }
953
954 return 0;
955}
956
957static int mv88e6xxx_eeprom_is_readonly(struct dsa_switch *ds)
958{
959 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
960 int ret;
961
962 ret = mv88e6xxx_reg_read(ps, REG_GLOBAL2, GLOBAL2_EEPROM_OP);
963 if (ret < 0)
964 return ret;
965
966 if (!(ret & GLOBAL2_EEPROM_OP_WRITE_EN))
967 return -EROFS;
968
969 return 0;
970}
971
972static int mv88e6xxx_write_eeprom_word(struct dsa_switch *ds, int addr,
973 u16 data)
974{
975 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
976 int ret;
977
978 mutex_lock(&ps->eeprom_mutex);
979
980 ret = mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_EEPROM_DATA, data);
981 if (ret < 0)
982 goto error;
983
984 ret = mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_EEPROM_OP,
985 GLOBAL2_EEPROM_OP_WRITE |
986 (addr & GLOBAL2_EEPROM_OP_ADDR_MASK));
987 if (ret < 0)
988 goto error;
989
990 ret = mv88e6xxx_eeprom_busy_wait(ds);
991error:
992 mutex_unlock(&ps->eeprom_mutex);
993 return ret;
994}
995
f81ec90f
VD
996static int mv88e6xxx_set_eeprom(struct dsa_switch *ds,
997 struct ethtool_eeprom *eeprom, u8 *data)
d24645be
VD
998{
999 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1000 int offset;
1001 int ret;
1002 int len;
1003
1004 if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_EEPROM))
1005 return -EOPNOTSUPP;
1006
1007 if (eeprom->magic != 0xc3ec4951)
1008 return -EINVAL;
1009
1010 ret = mv88e6xxx_eeprom_is_readonly(ds);
1011 if (ret)
1012 return ret;
1013
1014 offset = eeprom->offset;
1015 len = eeprom->len;
1016 eeprom->len = 0;
1017
1018 ret = mv88e6xxx_eeprom_load_wait(ds);
1019 if (ret < 0)
1020 return ret;
1021
1022 if (offset & 1) {
1023 int word;
1024
1025 word = mv88e6xxx_read_eeprom_word(ds, offset >> 1);
1026 if (word < 0)
1027 return word;
1028
1029 word = (*data++ << 8) | (word & 0xff);
1030
1031 ret = mv88e6xxx_write_eeprom_word(ds, offset >> 1, word);
1032 if (ret < 0)
1033 return ret;
1034
1035 offset++;
1036 len--;
1037 eeprom->len++;
1038 }
1039
1040 while (len >= 2) {
1041 int word;
1042
1043 word = *data++;
1044 word |= *data++ << 8;
1045
1046 ret = mv88e6xxx_write_eeprom_word(ds, offset >> 1, word);
1047 if (ret < 0)
1048 return ret;
1049
1050 offset += 2;
1051 len -= 2;
1052 eeprom->len += 2;
1053 }
1054
1055 if (len) {
1056 int word;
1057
1058 word = mv88e6xxx_read_eeprom_word(ds, offset >> 1);
1059 if (word < 0)
1060 return word;
1061
1062 word = (word & 0xff00) | *data++;
1063
1064 ret = mv88e6xxx_write_eeprom_word(ds, offset >> 1, word);
1065 if (ret < 0)
1066 return ret;
1067
1068 offset++;
1069 len--;
1070 eeprom->len++;
1071 }
1072
1073 return 0;
1074}
1075
158bc065 1076static int _mv88e6xxx_atu_wait(struct mv88e6xxx_priv_state *ps)
facd95b2 1077{
158bc065 1078 return _mv88e6xxx_wait(ps, REG_GLOBAL, GLOBAL_ATU_OP,
cca8b133 1079 GLOBAL_ATU_OP_BUSY);
facd95b2
GR
1080}
1081
03a4a540 1082static int mv88e6xxx_mdio_read_indirect(struct mv88e6xxx_priv_state *ps,
158bc065 1083 int addr, int regnum)
f3044683
AL
1084{
1085 int ret;
1086
158bc065 1087 ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_SMI_OP,
3898c148
AL
1088 GLOBAL2_SMI_OP_22_READ | (addr << 5) |
1089 regnum);
1090 if (ret < 0)
1091 return ret;
f3044683 1092
03a4a540 1093 ret = mv88e6xxx_mdio_wait(ps);
f3044683
AL
1094 if (ret < 0)
1095 return ret;
1096
158bc065
AL
1097 ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL2, GLOBAL2_SMI_DATA);
1098
1099 return ret;
f3044683
AL
1100}
1101
03a4a540 1102static int mv88e6xxx_mdio_write_indirect(struct mv88e6xxx_priv_state *ps,
158bc065 1103 int addr, int regnum, u16 val)
f3044683 1104{
3898c148
AL
1105 int ret;
1106
158bc065 1107 ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_SMI_DATA, val);
3898c148
AL
1108 if (ret < 0)
1109 return ret;
f3044683 1110
158bc065 1111 ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_SMI_OP,
3898c148
AL
1112 GLOBAL2_SMI_OP_22_WRITE | (addr << 5) |
1113 regnum);
1114
03a4a540 1115 return mv88e6xxx_mdio_wait(ps);
f3044683
AL
1116}
1117
f81ec90f
VD
1118static int mv88e6xxx_get_eee(struct dsa_switch *ds, int port,
1119 struct ethtool_eee *e)
11b3b45d 1120{
2f40c698 1121 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
11b3b45d
GR
1122 int reg;
1123
aadbdb8a
VD
1124 if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_EEE))
1125 return -EOPNOTSUPP;
1126
9f8b3ee1 1127 mutex_lock(&ps->reg_lock);
2f40c698 1128
03a4a540 1129 reg = mv88e6xxx_mdio_read_indirect(ps, port, 16);
11b3b45d 1130 if (reg < 0)
2f40c698 1131 goto out;
11b3b45d
GR
1132
1133 e->eee_enabled = !!(reg & 0x0200);
1134 e->tx_lpi_enabled = !!(reg & 0x0100);
1135
158bc065 1136 reg = _mv88e6xxx_reg_read(ps, REG_PORT(port), PORT_STATUS);
11b3b45d 1137 if (reg < 0)
2f40c698 1138 goto out;
11b3b45d 1139
cca8b133 1140 e->eee_active = !!(reg & PORT_STATUS_EEE);
2f40c698 1141 reg = 0;
11b3b45d 1142
2f40c698 1143out:
9f8b3ee1 1144 mutex_unlock(&ps->reg_lock);
2f40c698 1145 return reg;
11b3b45d
GR
1146}
1147
f81ec90f
VD
1148static int mv88e6xxx_set_eee(struct dsa_switch *ds, int port,
1149 struct phy_device *phydev, struct ethtool_eee *e)
11b3b45d 1150{
2f40c698
AL
1151 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1152 int reg;
11b3b45d
GR
1153 int ret;
1154
aadbdb8a
VD
1155 if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_EEE))
1156 return -EOPNOTSUPP;
1157
9f8b3ee1 1158 mutex_lock(&ps->reg_lock);
11b3b45d 1159
03a4a540 1160 ret = mv88e6xxx_mdio_read_indirect(ps, port, 16);
2f40c698
AL
1161 if (ret < 0)
1162 goto out;
1163
1164 reg = ret & ~0x0300;
1165 if (e->eee_enabled)
1166 reg |= 0x0200;
1167 if (e->tx_lpi_enabled)
1168 reg |= 0x0100;
1169
03a4a540 1170 ret = mv88e6xxx_mdio_write_indirect(ps, port, 16, reg);
2f40c698 1171out:
9f8b3ee1 1172 mutex_unlock(&ps->reg_lock);
2f40c698
AL
1173
1174 return ret;
11b3b45d
GR
1175}
1176
158bc065 1177static int _mv88e6xxx_atu_cmd(struct mv88e6xxx_priv_state *ps, u16 fid, u16 cmd)
facd95b2
GR
1178{
1179 int ret;
1180
158bc065
AL
1181 if (mv88e6xxx_has_fid_reg(ps)) {
1182 ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_ATU_FID, fid);
b426e5f7
VD
1183 if (ret < 0)
1184 return ret;
158bc065 1185 } else if (mv88e6xxx_num_databases(ps) == 256) {
11ea809f 1186 /* ATU DBNum[7:4] are located in ATU Control 15:12 */
158bc065 1187 ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL, GLOBAL_ATU_CONTROL);
11ea809f
VD
1188 if (ret < 0)
1189 return ret;
1190
158bc065 1191 ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_ATU_CONTROL,
11ea809f
VD
1192 (ret & 0xfff) |
1193 ((fid << 8) & 0xf000));
1194 if (ret < 0)
1195 return ret;
1196
1197 /* ATU DBNum[3:0] are located in ATU Operation 3:0 */
1198 cmd |= fid & 0xf;
b426e5f7
VD
1199 }
1200
158bc065 1201 ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_ATU_OP, cmd);
facd95b2
GR
1202 if (ret < 0)
1203 return ret;
1204
158bc065 1205 return _mv88e6xxx_atu_wait(ps);
facd95b2
GR
1206}
1207
158bc065 1208static int _mv88e6xxx_atu_data_write(struct mv88e6xxx_priv_state *ps,
37705b73
VD
1209 struct mv88e6xxx_atu_entry *entry)
1210{
1211 u16 data = entry->state & GLOBAL_ATU_DATA_STATE_MASK;
1212
1213 if (entry->state != GLOBAL_ATU_DATA_STATE_UNUSED) {
1214 unsigned int mask, shift;
1215
1216 if (entry->trunk) {
1217 data |= GLOBAL_ATU_DATA_TRUNK;
1218 mask = GLOBAL_ATU_DATA_TRUNK_ID_MASK;
1219 shift = GLOBAL_ATU_DATA_TRUNK_ID_SHIFT;
1220 } else {
1221 mask = GLOBAL_ATU_DATA_PORT_VECTOR_MASK;
1222 shift = GLOBAL_ATU_DATA_PORT_VECTOR_SHIFT;
1223 }
1224
1225 data |= (entry->portv_trunkid << shift) & mask;
1226 }
1227
158bc065 1228 return _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_ATU_DATA, data);
37705b73
VD
1229}
1230
158bc065 1231static int _mv88e6xxx_atu_flush_move(struct mv88e6xxx_priv_state *ps,
7fb5e755
VD
1232 struct mv88e6xxx_atu_entry *entry,
1233 bool static_too)
facd95b2 1234{
7fb5e755
VD
1235 int op;
1236 int err;
facd95b2 1237
158bc065 1238 err = _mv88e6xxx_atu_wait(ps);
7fb5e755
VD
1239 if (err)
1240 return err;
facd95b2 1241
158bc065 1242 err = _mv88e6xxx_atu_data_write(ps, entry);
7fb5e755
VD
1243 if (err)
1244 return err;
1245
1246 if (entry->fid) {
7fb5e755
VD
1247 op = static_too ? GLOBAL_ATU_OP_FLUSH_MOVE_ALL_DB :
1248 GLOBAL_ATU_OP_FLUSH_MOVE_NON_STATIC_DB;
1249 } else {
1250 op = static_too ? GLOBAL_ATU_OP_FLUSH_MOVE_ALL :
1251 GLOBAL_ATU_OP_FLUSH_MOVE_NON_STATIC;
1252 }
1253
158bc065 1254 return _mv88e6xxx_atu_cmd(ps, entry->fid, op);
7fb5e755
VD
1255}
1256
158bc065
AL
1257static int _mv88e6xxx_atu_flush(struct mv88e6xxx_priv_state *ps,
1258 u16 fid, bool static_too)
7fb5e755
VD
1259{
1260 struct mv88e6xxx_atu_entry entry = {
1261 .fid = fid,
1262 .state = 0, /* EntryState bits must be 0 */
1263 };
70cc99d1 1264
158bc065 1265 return _mv88e6xxx_atu_flush_move(ps, &entry, static_too);
7fb5e755
VD
1266}
1267
158bc065
AL
1268static int _mv88e6xxx_atu_move(struct mv88e6xxx_priv_state *ps, u16 fid,
1269 int from_port, int to_port, bool static_too)
9f4d55d2
VD
1270{
1271 struct mv88e6xxx_atu_entry entry = {
1272 .trunk = false,
1273 .fid = fid,
1274 };
1275
1276 /* EntryState bits must be 0xF */
1277 entry.state = GLOBAL_ATU_DATA_STATE_MASK;
1278
1279 /* ToPort and FromPort are respectively in PortVec bits 7:4 and 3:0 */
1280 entry.portv_trunkid = (to_port & 0x0f) << 4;
1281 entry.portv_trunkid |= from_port & 0x0f;
1282
158bc065 1283 return _mv88e6xxx_atu_flush_move(ps, &entry, static_too);
9f4d55d2
VD
1284}
1285
158bc065
AL
1286static int _mv88e6xxx_atu_remove(struct mv88e6xxx_priv_state *ps, u16 fid,
1287 int port, bool static_too)
9f4d55d2
VD
1288{
1289 /* Destination port 0xF means remove the entries */
158bc065 1290 return _mv88e6xxx_atu_move(ps, fid, port, 0x0f, static_too);
9f4d55d2
VD
1291}
1292
2d9deae4
VD
1293static const char * const mv88e6xxx_port_state_names[] = {
1294 [PORT_CONTROL_STATE_DISABLED] = "Disabled",
1295 [PORT_CONTROL_STATE_BLOCKING] = "Blocking/Listening",
1296 [PORT_CONTROL_STATE_LEARNING] = "Learning",
1297 [PORT_CONTROL_STATE_FORWARDING] = "Forwarding",
1298};
1299
158bc065
AL
1300static int _mv88e6xxx_port_state(struct mv88e6xxx_priv_state *ps, int port,
1301 u8 state)
facd95b2 1302{
158bc065 1303 struct dsa_switch *ds = ps->ds;
c3ffe6d2 1304 int reg, ret = 0;
facd95b2
GR
1305 u8 oldstate;
1306
158bc065 1307 reg = _mv88e6xxx_reg_read(ps, REG_PORT(port), PORT_CONTROL);
2d9deae4
VD
1308 if (reg < 0)
1309 return reg;
facd95b2 1310
cca8b133 1311 oldstate = reg & PORT_CONTROL_STATE_MASK;
2d9deae4 1312
facd95b2
GR
1313 if (oldstate != state) {
1314 /* Flush forwarding database if we're moving a port
1315 * from Learning or Forwarding state to Disabled or
1316 * Blocking or Listening state.
1317 */
2d9deae4 1318 if ((oldstate == PORT_CONTROL_STATE_LEARNING ||
57d32310
VD
1319 oldstate == PORT_CONTROL_STATE_FORWARDING) &&
1320 (state == PORT_CONTROL_STATE_DISABLED ||
1321 state == PORT_CONTROL_STATE_BLOCKING)) {
158bc065 1322 ret = _mv88e6xxx_atu_remove(ps, 0, port, false);
facd95b2 1323 if (ret)
2d9deae4 1324 return ret;
facd95b2 1325 }
2d9deae4 1326
cca8b133 1327 reg = (reg & ~PORT_CONTROL_STATE_MASK) | state;
158bc065 1328 ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), PORT_CONTROL,
cca8b133 1329 reg);
2d9deae4
VD
1330 if (ret)
1331 return ret;
1332
c8b09808 1333 netdev_dbg(ds->ports[port].netdev, "PortState %s (was %s)\n",
2d9deae4
VD
1334 mv88e6xxx_port_state_names[state],
1335 mv88e6xxx_port_state_names[oldstate]);
facd95b2
GR
1336 }
1337
facd95b2
GR
1338 return ret;
1339}
1340
158bc065
AL
1341static int _mv88e6xxx_port_based_vlan_map(struct mv88e6xxx_priv_state *ps,
1342 int port)
facd95b2 1343{
b7666efe 1344 struct net_device *bridge = ps->ports[port].bridge_dev;
009a2b98 1345 const u16 mask = (1 << ps->info->num_ports) - 1;
158bc065 1346 struct dsa_switch *ds = ps->ds;
b7666efe 1347 u16 output_ports = 0;
ede8098d 1348 int reg;
b7666efe
VD
1349 int i;
1350
1351 /* allow CPU port or DSA link(s) to send frames to every port */
1352 if (dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port)) {
1353 output_ports = mask;
1354 } else {
009a2b98 1355 for (i = 0; i < ps->info->num_ports; ++i) {
b7666efe
VD
1356 /* allow sending frames to every group member */
1357 if (bridge && ps->ports[i].bridge_dev == bridge)
1358 output_ports |= BIT(i);
1359
1360 /* allow sending frames to CPU port and DSA link(s) */
1361 if (dsa_is_cpu_port(ds, i) || dsa_is_dsa_port(ds, i))
1362 output_ports |= BIT(i);
1363 }
1364 }
1365
1366 /* prevent frames from going back out of the port they came in on */
1367 output_ports &= ~BIT(port);
facd95b2 1368
158bc065 1369 reg = _mv88e6xxx_reg_read(ps, REG_PORT(port), PORT_BASE_VLAN);
ede8098d
VD
1370 if (reg < 0)
1371 return reg;
facd95b2 1372
ede8098d
VD
1373 reg &= ~mask;
1374 reg |= output_ports & mask;
facd95b2 1375
158bc065 1376 return _mv88e6xxx_reg_write(ps, REG_PORT(port), PORT_BASE_VLAN, reg);
facd95b2
GR
1377}
1378
f81ec90f
VD
1379static void mv88e6xxx_port_stp_state_set(struct dsa_switch *ds, int port,
1380 u8 state)
facd95b2
GR
1381{
1382 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1383 int stp_state;
553eb544 1384 int err;
facd95b2 1385
936f234a
VD
1386 if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_PORTSTATE))
1387 return;
1388
facd95b2
GR
1389 switch (state) {
1390 case BR_STATE_DISABLED:
cca8b133 1391 stp_state = PORT_CONTROL_STATE_DISABLED;
facd95b2
GR
1392 break;
1393 case BR_STATE_BLOCKING:
1394 case BR_STATE_LISTENING:
cca8b133 1395 stp_state = PORT_CONTROL_STATE_BLOCKING;
facd95b2
GR
1396 break;
1397 case BR_STATE_LEARNING:
cca8b133 1398 stp_state = PORT_CONTROL_STATE_LEARNING;
facd95b2
GR
1399 break;
1400 case BR_STATE_FORWARDING:
1401 default:
cca8b133 1402 stp_state = PORT_CONTROL_STATE_FORWARDING;
facd95b2
GR
1403 break;
1404 }
1405
9f8b3ee1 1406 mutex_lock(&ps->reg_lock);
553eb544 1407 err = _mv88e6xxx_port_state(ps, port, stp_state);
9f8b3ee1 1408 mutex_unlock(&ps->reg_lock);
553eb544
VD
1409
1410 if (err)
c8b09808
AL
1411 netdev_err(ds->ports[port].netdev,
1412 "failed to update state to %s\n",
553eb544 1413 mv88e6xxx_port_state_names[stp_state]);
facd95b2
GR
1414}
1415
158bc065
AL
1416static int _mv88e6xxx_port_pvid(struct mv88e6xxx_priv_state *ps, int port,
1417 u16 *new, u16 *old)
76e398a6 1418{
158bc065 1419 struct dsa_switch *ds = ps->ds;
5da96031 1420 u16 pvid;
76e398a6
VD
1421 int ret;
1422
158bc065 1423 ret = _mv88e6xxx_reg_read(ps, REG_PORT(port), PORT_DEFAULT_VLAN);
76e398a6
VD
1424 if (ret < 0)
1425 return ret;
1426
5da96031
VD
1427 pvid = ret & PORT_DEFAULT_VLAN_MASK;
1428
1429 if (new) {
1430 ret &= ~PORT_DEFAULT_VLAN_MASK;
1431 ret |= *new & PORT_DEFAULT_VLAN_MASK;
1432
158bc065 1433 ret = _mv88e6xxx_reg_write(ps, REG_PORT(port),
5da96031
VD
1434 PORT_DEFAULT_VLAN, ret);
1435 if (ret < 0)
1436 return ret;
1437
c8b09808
AL
1438 netdev_dbg(ds->ports[port].netdev,
1439 "DefaultVID %d (was %d)\n", *new, pvid);
5da96031
VD
1440 }
1441
1442 if (old)
1443 *old = pvid;
76e398a6
VD
1444
1445 return 0;
1446}
1447
158bc065
AL
1448static int _mv88e6xxx_port_pvid_get(struct mv88e6xxx_priv_state *ps,
1449 int port, u16 *pvid)
5da96031 1450{
158bc065 1451 return _mv88e6xxx_port_pvid(ps, port, NULL, pvid);
5da96031
VD
1452}
1453
158bc065
AL
1454static int _mv88e6xxx_port_pvid_set(struct mv88e6xxx_priv_state *ps,
1455 int port, u16 pvid)
0d3b33e6 1456{
158bc065 1457 return _mv88e6xxx_port_pvid(ps, port, &pvid, NULL);
0d3b33e6
VD
1458}
1459
158bc065 1460static int _mv88e6xxx_vtu_wait(struct mv88e6xxx_priv_state *ps)
6b17e864 1461{
158bc065 1462 return _mv88e6xxx_wait(ps, REG_GLOBAL, GLOBAL_VTU_OP,
6b17e864
VD
1463 GLOBAL_VTU_OP_BUSY);
1464}
1465
158bc065 1466static int _mv88e6xxx_vtu_cmd(struct mv88e6xxx_priv_state *ps, u16 op)
6b17e864
VD
1467{
1468 int ret;
1469
158bc065 1470 ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_VTU_OP, op);
6b17e864
VD
1471 if (ret < 0)
1472 return ret;
1473
158bc065 1474 return _mv88e6xxx_vtu_wait(ps);
6b17e864
VD
1475}
1476
158bc065 1477static int _mv88e6xxx_vtu_stu_flush(struct mv88e6xxx_priv_state *ps)
6b17e864
VD
1478{
1479 int ret;
1480
158bc065 1481 ret = _mv88e6xxx_vtu_wait(ps);
6b17e864
VD
1482 if (ret < 0)
1483 return ret;
1484
158bc065 1485 return _mv88e6xxx_vtu_cmd(ps, GLOBAL_VTU_OP_FLUSH_ALL);
6b17e864
VD
1486}
1487
158bc065 1488static int _mv88e6xxx_vtu_stu_data_read(struct mv88e6xxx_priv_state *ps,
b8fee957
VD
1489 struct mv88e6xxx_vtu_stu_entry *entry,
1490 unsigned int nibble_offset)
1491{
b8fee957
VD
1492 u16 regs[3];
1493 int i;
1494 int ret;
1495
1496 for (i = 0; i < 3; ++i) {
158bc065 1497 ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL,
b8fee957
VD
1498 GLOBAL_VTU_DATA_0_3 + i);
1499 if (ret < 0)
1500 return ret;
1501
1502 regs[i] = ret;
1503 }
1504
009a2b98 1505 for (i = 0; i < ps->info->num_ports; ++i) {
b8fee957
VD
1506 unsigned int shift = (i % 4) * 4 + nibble_offset;
1507 u16 reg = regs[i / 4];
1508
1509 entry->data[i] = (reg >> shift) & GLOBAL_VTU_STU_DATA_MASK;
1510 }
1511
1512 return 0;
1513}
1514
15d7d7d4
VD
1515static int mv88e6xxx_vtu_data_read(struct mv88e6xxx_priv_state *ps,
1516 struct mv88e6xxx_vtu_stu_entry *entry)
1517{
1518 return _mv88e6xxx_vtu_stu_data_read(ps, entry, 0);
1519}
1520
1521static int mv88e6xxx_stu_data_read(struct mv88e6xxx_priv_state *ps,
1522 struct mv88e6xxx_vtu_stu_entry *entry)
1523{
1524 return _mv88e6xxx_vtu_stu_data_read(ps, entry, 2);
1525}
1526
158bc065 1527static int _mv88e6xxx_vtu_stu_data_write(struct mv88e6xxx_priv_state *ps,
7dad08d7
VD
1528 struct mv88e6xxx_vtu_stu_entry *entry,
1529 unsigned int nibble_offset)
1530{
7dad08d7
VD
1531 u16 regs[3] = { 0 };
1532 int i;
1533 int ret;
1534
009a2b98 1535 for (i = 0; i < ps->info->num_ports; ++i) {
7dad08d7
VD
1536 unsigned int shift = (i % 4) * 4 + nibble_offset;
1537 u8 data = entry->data[i];
1538
1539 regs[i / 4] |= (data & GLOBAL_VTU_STU_DATA_MASK) << shift;
1540 }
1541
1542 for (i = 0; i < 3; ++i) {
158bc065 1543 ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL,
7dad08d7
VD
1544 GLOBAL_VTU_DATA_0_3 + i, regs[i]);
1545 if (ret < 0)
1546 return ret;
1547 }
1548
1549 return 0;
1550}
1551
15d7d7d4
VD
1552static int mv88e6xxx_vtu_data_write(struct mv88e6xxx_priv_state *ps,
1553 struct mv88e6xxx_vtu_stu_entry *entry)
1554{
1555 return _mv88e6xxx_vtu_stu_data_write(ps, entry, 0);
1556}
1557
1558static int mv88e6xxx_stu_data_write(struct mv88e6xxx_priv_state *ps,
1559 struct mv88e6xxx_vtu_stu_entry *entry)
1560{
1561 return _mv88e6xxx_vtu_stu_data_write(ps, entry, 2);
1562}
1563
158bc065 1564static int _mv88e6xxx_vtu_vid_write(struct mv88e6xxx_priv_state *ps, u16 vid)
36d04ba1 1565{
158bc065 1566 return _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_VTU_VID,
36d04ba1
VD
1567 vid & GLOBAL_VTU_VID_MASK);
1568}
1569
158bc065 1570static int _mv88e6xxx_vtu_getnext(struct mv88e6xxx_priv_state *ps,
b8fee957
VD
1571 struct mv88e6xxx_vtu_stu_entry *entry)
1572{
1573 struct mv88e6xxx_vtu_stu_entry next = { 0 };
1574 int ret;
1575
158bc065 1576 ret = _mv88e6xxx_vtu_wait(ps);
b8fee957
VD
1577 if (ret < 0)
1578 return ret;
1579
158bc065 1580 ret = _mv88e6xxx_vtu_cmd(ps, GLOBAL_VTU_OP_VTU_GET_NEXT);
b8fee957
VD
1581 if (ret < 0)
1582 return ret;
1583
158bc065 1584 ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL, GLOBAL_VTU_VID);
b8fee957
VD
1585 if (ret < 0)
1586 return ret;
1587
1588 next.vid = ret & GLOBAL_VTU_VID_MASK;
1589 next.valid = !!(ret & GLOBAL_VTU_VID_VALID);
1590
1591 if (next.valid) {
15d7d7d4 1592 ret = mv88e6xxx_vtu_data_read(ps, &next);
b8fee957
VD
1593 if (ret < 0)
1594 return ret;
1595
158bc065
AL
1596 if (mv88e6xxx_has_fid_reg(ps)) {
1597 ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL,
b8fee957
VD
1598 GLOBAL_VTU_FID);
1599 if (ret < 0)
1600 return ret;
1601
1602 next.fid = ret & GLOBAL_VTU_FID_MASK;
158bc065 1603 } else if (mv88e6xxx_num_databases(ps) == 256) {
11ea809f
VD
1604 /* VTU DBNum[7:4] are located in VTU Operation 11:8, and
1605 * VTU DBNum[3:0] are located in VTU Operation 3:0
1606 */
158bc065 1607 ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL,
11ea809f
VD
1608 GLOBAL_VTU_OP);
1609 if (ret < 0)
1610 return ret;
1611
1612 next.fid = (ret & 0xf00) >> 4;
1613 next.fid |= ret & 0xf;
2e7bd5ef 1614 }
b8fee957 1615
cb9b9020 1616 if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_STU)) {
158bc065 1617 ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL,
b8fee957
VD
1618 GLOBAL_VTU_SID);
1619 if (ret < 0)
1620 return ret;
1621
1622 next.sid = ret & GLOBAL_VTU_SID_MASK;
1623 }
1624 }
1625
1626 *entry = next;
1627 return 0;
1628}
1629
f81ec90f
VD
1630static int mv88e6xxx_port_vlan_dump(struct dsa_switch *ds, int port,
1631 struct switchdev_obj_port_vlan *vlan,
1632 int (*cb)(struct switchdev_obj *obj))
ceff5eff
VD
1633{
1634 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1635 struct mv88e6xxx_vtu_stu_entry next;
1636 u16 pvid;
1637 int err;
1638
54d77b5b
VD
1639 if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_VTU))
1640 return -EOPNOTSUPP;
1641
9f8b3ee1 1642 mutex_lock(&ps->reg_lock);
ceff5eff 1643
158bc065 1644 err = _mv88e6xxx_port_pvid_get(ps, port, &pvid);
ceff5eff
VD
1645 if (err)
1646 goto unlock;
1647
158bc065 1648 err = _mv88e6xxx_vtu_vid_write(ps, GLOBAL_VTU_VID_MASK);
ceff5eff
VD
1649 if (err)
1650 goto unlock;
1651
1652 do {
158bc065 1653 err = _mv88e6xxx_vtu_getnext(ps, &next);
ceff5eff
VD
1654 if (err)
1655 break;
1656
1657 if (!next.valid)
1658 break;
1659
1660 if (next.data[port] == GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER)
1661 continue;
1662
1663 /* reinit and dump this VLAN obj */
57d32310
VD
1664 vlan->vid_begin = next.vid;
1665 vlan->vid_end = next.vid;
ceff5eff
VD
1666 vlan->flags = 0;
1667
1668 if (next.data[port] == GLOBAL_VTU_DATA_MEMBER_TAG_UNTAGGED)
1669 vlan->flags |= BRIDGE_VLAN_INFO_UNTAGGED;
1670
1671 if (next.vid == pvid)
1672 vlan->flags |= BRIDGE_VLAN_INFO_PVID;
1673
1674 err = cb(&vlan->obj);
1675 if (err)
1676 break;
1677 } while (next.vid < GLOBAL_VTU_VID_MASK);
1678
1679unlock:
9f8b3ee1 1680 mutex_unlock(&ps->reg_lock);
ceff5eff
VD
1681
1682 return err;
1683}
1684
158bc065 1685static int _mv88e6xxx_vtu_loadpurge(struct mv88e6xxx_priv_state *ps,
7dad08d7
VD
1686 struct mv88e6xxx_vtu_stu_entry *entry)
1687{
11ea809f 1688 u16 op = GLOBAL_VTU_OP_VTU_LOAD_PURGE;
7dad08d7
VD
1689 u16 reg = 0;
1690 int ret;
1691
158bc065 1692 ret = _mv88e6xxx_vtu_wait(ps);
7dad08d7
VD
1693 if (ret < 0)
1694 return ret;
1695
1696 if (!entry->valid)
1697 goto loadpurge;
1698
1699 /* Write port member tags */
15d7d7d4 1700 ret = mv88e6xxx_vtu_data_write(ps, entry);
7dad08d7
VD
1701 if (ret < 0)
1702 return ret;
1703
cb9b9020 1704 if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_STU)) {
7dad08d7 1705 reg = entry->sid & GLOBAL_VTU_SID_MASK;
158bc065 1706 ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_VTU_SID, reg);
7dad08d7
VD
1707 if (ret < 0)
1708 return ret;
b426e5f7 1709 }
7dad08d7 1710
158bc065 1711 if (mv88e6xxx_has_fid_reg(ps)) {
7dad08d7 1712 reg = entry->fid & GLOBAL_VTU_FID_MASK;
158bc065 1713 ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_VTU_FID, reg);
7dad08d7
VD
1714 if (ret < 0)
1715 return ret;
158bc065 1716 } else if (mv88e6xxx_num_databases(ps) == 256) {
11ea809f
VD
1717 /* VTU DBNum[7:4] are located in VTU Operation 11:8, and
1718 * VTU DBNum[3:0] are located in VTU Operation 3:0
1719 */
1720 op |= (entry->fid & 0xf0) << 8;
1721 op |= entry->fid & 0xf;
7dad08d7
VD
1722 }
1723
1724 reg = GLOBAL_VTU_VID_VALID;
1725loadpurge:
1726 reg |= entry->vid & GLOBAL_VTU_VID_MASK;
158bc065 1727 ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_VTU_VID, reg);
7dad08d7
VD
1728 if (ret < 0)
1729 return ret;
1730
158bc065 1731 return _mv88e6xxx_vtu_cmd(ps, op);
7dad08d7
VD
1732}
1733
158bc065 1734static int _mv88e6xxx_stu_getnext(struct mv88e6xxx_priv_state *ps, u8 sid,
0d3b33e6
VD
1735 struct mv88e6xxx_vtu_stu_entry *entry)
1736{
1737 struct mv88e6xxx_vtu_stu_entry next = { 0 };
1738 int ret;
1739
158bc065 1740 ret = _mv88e6xxx_vtu_wait(ps);
0d3b33e6
VD
1741 if (ret < 0)
1742 return ret;
1743
158bc065 1744 ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_VTU_SID,
0d3b33e6
VD
1745 sid & GLOBAL_VTU_SID_MASK);
1746 if (ret < 0)
1747 return ret;
1748
158bc065 1749 ret = _mv88e6xxx_vtu_cmd(ps, GLOBAL_VTU_OP_STU_GET_NEXT);
0d3b33e6
VD
1750 if (ret < 0)
1751 return ret;
1752
158bc065 1753 ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL, GLOBAL_VTU_SID);
0d3b33e6
VD
1754 if (ret < 0)
1755 return ret;
1756
1757 next.sid = ret & GLOBAL_VTU_SID_MASK;
1758
158bc065 1759 ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL, GLOBAL_VTU_VID);
0d3b33e6
VD
1760 if (ret < 0)
1761 return ret;
1762
1763 next.valid = !!(ret & GLOBAL_VTU_VID_VALID);
1764
1765 if (next.valid) {
15d7d7d4 1766 ret = mv88e6xxx_stu_data_read(ps, &next);
0d3b33e6
VD
1767 if (ret < 0)
1768 return ret;
1769 }
1770
1771 *entry = next;
1772 return 0;
1773}
1774
158bc065 1775static int _mv88e6xxx_stu_loadpurge(struct mv88e6xxx_priv_state *ps,
0d3b33e6
VD
1776 struct mv88e6xxx_vtu_stu_entry *entry)
1777{
1778 u16 reg = 0;
1779 int ret;
1780
158bc065 1781 ret = _mv88e6xxx_vtu_wait(ps);
0d3b33e6
VD
1782 if (ret < 0)
1783 return ret;
1784
1785 if (!entry->valid)
1786 goto loadpurge;
1787
1788 /* Write port states */
15d7d7d4 1789 ret = mv88e6xxx_stu_data_write(ps, entry);
0d3b33e6
VD
1790 if (ret < 0)
1791 return ret;
1792
1793 reg = GLOBAL_VTU_VID_VALID;
1794loadpurge:
158bc065 1795 ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_VTU_VID, reg);
0d3b33e6
VD
1796 if (ret < 0)
1797 return ret;
1798
1799 reg = entry->sid & GLOBAL_VTU_SID_MASK;
158bc065 1800 ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_VTU_SID, reg);
0d3b33e6
VD
1801 if (ret < 0)
1802 return ret;
1803
158bc065 1804 return _mv88e6xxx_vtu_cmd(ps, GLOBAL_VTU_OP_STU_LOAD_PURGE);
0d3b33e6
VD
1805}
1806
158bc065
AL
1807static int _mv88e6xxx_port_fid(struct mv88e6xxx_priv_state *ps, int port,
1808 u16 *new, u16 *old)
2db9ce1f 1809{
158bc065 1810 struct dsa_switch *ds = ps->ds;
f74df0be 1811 u16 upper_mask;
2db9ce1f
VD
1812 u16 fid;
1813 int ret;
1814
158bc065 1815 if (mv88e6xxx_num_databases(ps) == 4096)
f74df0be 1816 upper_mask = 0xff;
158bc065 1817 else if (mv88e6xxx_num_databases(ps) == 256)
11ea809f 1818 upper_mask = 0xf;
f74df0be
VD
1819 else
1820 return -EOPNOTSUPP;
1821
2db9ce1f 1822 /* Port's default FID bits 3:0 are located in reg 0x06, offset 12 */
158bc065 1823 ret = _mv88e6xxx_reg_read(ps, REG_PORT(port), PORT_BASE_VLAN);
2db9ce1f
VD
1824 if (ret < 0)
1825 return ret;
1826
1827 fid = (ret & PORT_BASE_VLAN_FID_3_0_MASK) >> 12;
1828
1829 if (new) {
1830 ret &= ~PORT_BASE_VLAN_FID_3_0_MASK;
1831 ret |= (*new << 12) & PORT_BASE_VLAN_FID_3_0_MASK;
1832
158bc065 1833 ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), PORT_BASE_VLAN,
2db9ce1f
VD
1834 ret);
1835 if (ret < 0)
1836 return ret;
1837 }
1838
1839 /* Port's default FID bits 11:4 are located in reg 0x05, offset 0 */
158bc065 1840 ret = _mv88e6xxx_reg_read(ps, REG_PORT(port), PORT_CONTROL_1);
2db9ce1f
VD
1841 if (ret < 0)
1842 return ret;
1843
f74df0be 1844 fid |= (ret & upper_mask) << 4;
2db9ce1f
VD
1845
1846 if (new) {
f74df0be
VD
1847 ret &= ~upper_mask;
1848 ret |= (*new >> 4) & upper_mask;
2db9ce1f 1849
158bc065 1850 ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), PORT_CONTROL_1,
2db9ce1f
VD
1851 ret);
1852 if (ret < 0)
1853 return ret;
1854
c8b09808
AL
1855 netdev_dbg(ds->ports[port].netdev,
1856 "FID %d (was %d)\n", *new, fid);
2db9ce1f
VD
1857 }
1858
1859 if (old)
1860 *old = fid;
1861
1862 return 0;
1863}
1864
158bc065
AL
1865static int _mv88e6xxx_port_fid_get(struct mv88e6xxx_priv_state *ps,
1866 int port, u16 *fid)
2db9ce1f 1867{
158bc065 1868 return _mv88e6xxx_port_fid(ps, port, NULL, fid);
2db9ce1f
VD
1869}
1870
158bc065
AL
1871static int _mv88e6xxx_port_fid_set(struct mv88e6xxx_priv_state *ps,
1872 int port, u16 fid)
2db9ce1f 1873{
158bc065 1874 return _mv88e6xxx_port_fid(ps, port, &fid, NULL);
2db9ce1f
VD
1875}
1876
158bc065 1877static int _mv88e6xxx_fid_new(struct mv88e6xxx_priv_state *ps, u16 *fid)
3285f9e8
VD
1878{
1879 DECLARE_BITMAP(fid_bitmap, MV88E6XXX_N_FID);
1880 struct mv88e6xxx_vtu_stu_entry vlan;
2db9ce1f 1881 int i, err;
3285f9e8
VD
1882
1883 bitmap_zero(fid_bitmap, MV88E6XXX_N_FID);
1884
2db9ce1f 1885 /* Set every FID bit used by the (un)bridged ports */
009a2b98 1886 for (i = 0; i < ps->info->num_ports; ++i) {
158bc065 1887 err = _mv88e6xxx_port_fid_get(ps, i, fid);
2db9ce1f
VD
1888 if (err)
1889 return err;
1890
1891 set_bit(*fid, fid_bitmap);
1892 }
1893
3285f9e8 1894 /* Set every FID bit used by the VLAN entries */
158bc065 1895 err = _mv88e6xxx_vtu_vid_write(ps, GLOBAL_VTU_VID_MASK);
3285f9e8
VD
1896 if (err)
1897 return err;
1898
1899 do {
158bc065 1900 err = _mv88e6xxx_vtu_getnext(ps, &vlan);
3285f9e8
VD
1901 if (err)
1902 return err;
1903
1904 if (!vlan.valid)
1905 break;
1906
1907 set_bit(vlan.fid, fid_bitmap);
1908 } while (vlan.vid < GLOBAL_VTU_VID_MASK);
1909
1910 /* The reset value 0x000 is used to indicate that multiple address
1911 * databases are not needed. Return the next positive available.
1912 */
1913 *fid = find_next_zero_bit(fid_bitmap, MV88E6XXX_N_FID, 1);
158bc065 1914 if (unlikely(*fid >= mv88e6xxx_num_databases(ps)))
3285f9e8
VD
1915 return -ENOSPC;
1916
1917 /* Clear the database */
158bc065 1918 return _mv88e6xxx_atu_flush(ps, *fid, true);
3285f9e8
VD
1919}
1920
158bc065 1921static int _mv88e6xxx_vtu_new(struct mv88e6xxx_priv_state *ps, u16 vid,
2fb5ef09 1922 struct mv88e6xxx_vtu_stu_entry *entry)
0d3b33e6 1923{
158bc065 1924 struct dsa_switch *ds = ps->ds;
0d3b33e6
VD
1925 struct mv88e6xxx_vtu_stu_entry vlan = {
1926 .valid = true,
1927 .vid = vid,
1928 };
3285f9e8
VD
1929 int i, err;
1930
158bc065 1931 err = _mv88e6xxx_fid_new(ps, &vlan.fid);
3285f9e8
VD
1932 if (err)
1933 return err;
0d3b33e6 1934
3d131f07 1935 /* exclude all ports except the CPU and DSA ports */
009a2b98 1936 for (i = 0; i < ps->info->num_ports; ++i)
3d131f07
VD
1937 vlan.data[i] = dsa_is_cpu_port(ds, i) || dsa_is_dsa_port(ds, i)
1938 ? GLOBAL_VTU_DATA_MEMBER_TAG_UNMODIFIED
1939 : GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER;
0d3b33e6 1940
158bc065
AL
1941 if (mv88e6xxx_6097_family(ps) || mv88e6xxx_6165_family(ps) ||
1942 mv88e6xxx_6351_family(ps) || mv88e6xxx_6352_family(ps)) {
0d3b33e6 1943 struct mv88e6xxx_vtu_stu_entry vstp;
0d3b33e6
VD
1944
1945 /* Adding a VTU entry requires a valid STU entry. As VSTP is not
1946 * implemented, only one STU entry is needed to cover all VTU
1947 * entries. Thus, validate the SID 0.
1948 */
1949 vlan.sid = 0;
158bc065 1950 err = _mv88e6xxx_stu_getnext(ps, GLOBAL_VTU_SID_MASK, &vstp);
0d3b33e6
VD
1951 if (err)
1952 return err;
1953
1954 if (vstp.sid != vlan.sid || !vstp.valid) {
1955 memset(&vstp, 0, sizeof(vstp));
1956 vstp.valid = true;
1957 vstp.sid = vlan.sid;
1958
158bc065 1959 err = _mv88e6xxx_stu_loadpurge(ps, &vstp);
0d3b33e6
VD
1960 if (err)
1961 return err;
1962 }
0d3b33e6
VD
1963 }
1964
1965 *entry = vlan;
1966 return 0;
1967}
1968
158bc065 1969static int _mv88e6xxx_vtu_get(struct mv88e6xxx_priv_state *ps, u16 vid,
2fb5ef09
VD
1970 struct mv88e6xxx_vtu_stu_entry *entry, bool creat)
1971{
1972 int err;
1973
1974 if (!vid)
1975 return -EINVAL;
1976
158bc065 1977 err = _mv88e6xxx_vtu_vid_write(ps, vid - 1);
2fb5ef09
VD
1978 if (err)
1979 return err;
1980
158bc065 1981 err = _mv88e6xxx_vtu_getnext(ps, entry);
2fb5ef09
VD
1982 if (err)
1983 return err;
1984
1985 if (entry->vid != vid || !entry->valid) {
1986 if (!creat)
1987 return -EOPNOTSUPP;
1988 /* -ENOENT would've been more appropriate, but switchdev expects
1989 * -EOPNOTSUPP to inform bridge about an eventual software VLAN.
1990 */
1991
158bc065 1992 err = _mv88e6xxx_vtu_new(ps, vid, entry);
2fb5ef09
VD
1993 }
1994
1995 return err;
1996}
1997
da9c359e
VD
1998static int mv88e6xxx_port_check_hw_vlan(struct dsa_switch *ds, int port,
1999 u16 vid_begin, u16 vid_end)
2000{
2001 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
2002 struct mv88e6xxx_vtu_stu_entry vlan;
2003 int i, err;
2004
2005 if (!vid_begin)
2006 return -EOPNOTSUPP;
2007
9f8b3ee1 2008 mutex_lock(&ps->reg_lock);
da9c359e 2009
158bc065 2010 err = _mv88e6xxx_vtu_vid_write(ps, vid_begin - 1);
da9c359e
VD
2011 if (err)
2012 goto unlock;
2013
2014 do {
158bc065 2015 err = _mv88e6xxx_vtu_getnext(ps, &vlan);
da9c359e
VD
2016 if (err)
2017 goto unlock;
2018
2019 if (!vlan.valid)
2020 break;
2021
2022 if (vlan.vid > vid_end)
2023 break;
2024
009a2b98 2025 for (i = 0; i < ps->info->num_ports; ++i) {
da9c359e
VD
2026 if (dsa_is_dsa_port(ds, i) || dsa_is_cpu_port(ds, i))
2027 continue;
2028
2029 if (vlan.data[i] ==
2030 GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER)
2031 continue;
2032
2033 if (ps->ports[i].bridge_dev ==
2034 ps->ports[port].bridge_dev)
2035 break; /* same bridge, check next VLAN */
2036
c8b09808 2037 netdev_warn(ds->ports[port].netdev,
da9c359e
VD
2038 "hardware VLAN %d already used by %s\n",
2039 vlan.vid,
2040 netdev_name(ps->ports[i].bridge_dev));
2041 err = -EOPNOTSUPP;
2042 goto unlock;
2043 }
2044 } while (vlan.vid < vid_end);
2045
2046unlock:
9f8b3ee1 2047 mutex_unlock(&ps->reg_lock);
da9c359e
VD
2048
2049 return err;
2050}
2051
214cdb99
VD
2052static const char * const mv88e6xxx_port_8021q_mode_names[] = {
2053 [PORT_CONTROL_2_8021Q_DISABLED] = "Disabled",
2054 [PORT_CONTROL_2_8021Q_FALLBACK] = "Fallback",
2055 [PORT_CONTROL_2_8021Q_CHECK] = "Check",
2056 [PORT_CONTROL_2_8021Q_SECURE] = "Secure",
2057};
2058
f81ec90f
VD
2059static int mv88e6xxx_port_vlan_filtering(struct dsa_switch *ds, int port,
2060 bool vlan_filtering)
214cdb99
VD
2061{
2062 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
2063 u16 old, new = vlan_filtering ? PORT_CONTROL_2_8021Q_SECURE :
2064 PORT_CONTROL_2_8021Q_DISABLED;
2065 int ret;
2066
54d77b5b
VD
2067 if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_VTU))
2068 return -EOPNOTSUPP;
2069
9f8b3ee1 2070 mutex_lock(&ps->reg_lock);
214cdb99 2071
158bc065 2072 ret = _mv88e6xxx_reg_read(ps, REG_PORT(port), PORT_CONTROL_2);
214cdb99
VD
2073 if (ret < 0)
2074 goto unlock;
2075
2076 old = ret & PORT_CONTROL_2_8021Q_MASK;
2077
5220ef1e
VD
2078 if (new != old) {
2079 ret &= ~PORT_CONTROL_2_8021Q_MASK;
2080 ret |= new & PORT_CONTROL_2_8021Q_MASK;
214cdb99 2081
158bc065 2082 ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), PORT_CONTROL_2,
5220ef1e
VD
2083 ret);
2084 if (ret < 0)
2085 goto unlock;
2086
c8b09808 2087 netdev_dbg(ds->ports[port].netdev, "802.1Q Mode %s (was %s)\n",
5220ef1e
VD
2088 mv88e6xxx_port_8021q_mode_names[new],
2089 mv88e6xxx_port_8021q_mode_names[old]);
2090 }
214cdb99 2091
5220ef1e 2092 ret = 0;
214cdb99 2093unlock:
9f8b3ee1 2094 mutex_unlock(&ps->reg_lock);
214cdb99
VD
2095
2096 return ret;
2097}
2098
57d32310
VD
2099static int
2100mv88e6xxx_port_vlan_prepare(struct dsa_switch *ds, int port,
2101 const struct switchdev_obj_port_vlan *vlan,
2102 struct switchdev_trans *trans)
76e398a6 2103{
54d77b5b 2104 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
da9c359e
VD
2105 int err;
2106
54d77b5b
VD
2107 if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_VTU))
2108 return -EOPNOTSUPP;
2109
da9c359e
VD
2110 /* If the requested port doesn't belong to the same bridge as the VLAN
2111 * members, do not support it (yet) and fallback to software VLAN.
2112 */
2113 err = mv88e6xxx_port_check_hw_vlan(ds, port, vlan->vid_begin,
2114 vlan->vid_end);
2115 if (err)
2116 return err;
2117
76e398a6
VD
2118 /* We don't need any dynamic resource from the kernel (yet),
2119 * so skip the prepare phase.
2120 */
2121 return 0;
2122}
2123
158bc065
AL
2124static int _mv88e6xxx_port_vlan_add(struct mv88e6xxx_priv_state *ps, int port,
2125 u16 vid, bool untagged)
0d3b33e6 2126{
0d3b33e6
VD
2127 struct mv88e6xxx_vtu_stu_entry vlan;
2128 int err;
2129
158bc065 2130 err = _mv88e6xxx_vtu_get(ps, vid, &vlan, true);
0d3b33e6 2131 if (err)
76e398a6 2132 return err;
0d3b33e6 2133
0d3b33e6
VD
2134 vlan.data[port] = untagged ?
2135 GLOBAL_VTU_DATA_MEMBER_TAG_UNTAGGED :
2136 GLOBAL_VTU_DATA_MEMBER_TAG_TAGGED;
2137
158bc065 2138 return _mv88e6xxx_vtu_loadpurge(ps, &vlan);
76e398a6
VD
2139}
2140
f81ec90f
VD
2141static void mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port,
2142 const struct switchdev_obj_port_vlan *vlan,
2143 struct switchdev_trans *trans)
76e398a6
VD
2144{
2145 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
2146 bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
2147 bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
2148 u16 vid;
76e398a6 2149
54d77b5b
VD
2150 if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_VTU))
2151 return;
2152
9f8b3ee1 2153 mutex_lock(&ps->reg_lock);
76e398a6 2154
4d5770b3 2155 for (vid = vlan->vid_begin; vid <= vlan->vid_end; ++vid)
158bc065 2156 if (_mv88e6xxx_port_vlan_add(ps, port, vid, untagged))
c8b09808
AL
2157 netdev_err(ds->ports[port].netdev,
2158 "failed to add VLAN %d%c\n",
4d5770b3 2159 vid, untagged ? 'u' : 't');
76e398a6 2160
158bc065 2161 if (pvid && _mv88e6xxx_port_pvid_set(ps, port, vlan->vid_end))
c8b09808 2162 netdev_err(ds->ports[port].netdev, "failed to set PVID %d\n",
4d5770b3 2163 vlan->vid_end);
0d3b33e6 2164
9f8b3ee1 2165 mutex_unlock(&ps->reg_lock);
0d3b33e6
VD
2166}
2167
158bc065
AL
2168static int _mv88e6xxx_port_vlan_del(struct mv88e6xxx_priv_state *ps,
2169 int port, u16 vid)
7dad08d7 2170{
158bc065 2171 struct dsa_switch *ds = ps->ds;
7dad08d7 2172 struct mv88e6xxx_vtu_stu_entry vlan;
7dad08d7
VD
2173 int i, err;
2174
158bc065 2175 err = _mv88e6xxx_vtu_get(ps, vid, &vlan, false);
7dad08d7 2176 if (err)
76e398a6 2177 return err;
7dad08d7 2178
2fb5ef09
VD
2179 /* Tell switchdev if this VLAN is handled in software */
2180 if (vlan.data[port] == GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER)
3c06f08b 2181 return -EOPNOTSUPP;
7dad08d7
VD
2182
2183 vlan.data[port] = GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER;
2184
2185 /* keep the VLAN unless all ports are excluded */
f02bdffc 2186 vlan.valid = false;
009a2b98 2187 for (i = 0; i < ps->info->num_ports; ++i) {
3d131f07 2188 if (dsa_is_cpu_port(ds, i) || dsa_is_dsa_port(ds, i))
7dad08d7
VD
2189 continue;
2190
2191 if (vlan.data[i] != GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER) {
f02bdffc 2192 vlan.valid = true;
7dad08d7
VD
2193 break;
2194 }
2195 }
2196
158bc065 2197 err = _mv88e6xxx_vtu_loadpurge(ps, &vlan);
76e398a6
VD
2198 if (err)
2199 return err;
2200
158bc065 2201 return _mv88e6xxx_atu_remove(ps, vlan.fid, port, false);
76e398a6
VD
2202}
2203
f81ec90f
VD
2204static int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port,
2205 const struct switchdev_obj_port_vlan *vlan)
76e398a6
VD
2206{
2207 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
2208 u16 pvid, vid;
2209 int err = 0;
2210
54d77b5b
VD
2211 if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_VTU))
2212 return -EOPNOTSUPP;
2213
9f8b3ee1 2214 mutex_lock(&ps->reg_lock);
76e398a6 2215
158bc065 2216 err = _mv88e6xxx_port_pvid_get(ps, port, &pvid);
7dad08d7
VD
2217 if (err)
2218 goto unlock;
2219
76e398a6 2220 for (vid = vlan->vid_begin; vid <= vlan->vid_end; ++vid) {
158bc065 2221 err = _mv88e6xxx_port_vlan_del(ps, port, vid);
76e398a6
VD
2222 if (err)
2223 goto unlock;
2224
2225 if (vid == pvid) {
158bc065 2226 err = _mv88e6xxx_port_pvid_set(ps, port, 0);
76e398a6
VD
2227 if (err)
2228 goto unlock;
2229 }
2230 }
2231
7dad08d7 2232unlock:
9f8b3ee1 2233 mutex_unlock(&ps->reg_lock);
7dad08d7
VD
2234
2235 return err;
2236}
2237
158bc065 2238static int _mv88e6xxx_atu_mac_write(struct mv88e6xxx_priv_state *ps,
c5723ac5 2239 const unsigned char *addr)
defb05b9
GR
2240{
2241 int i, ret;
2242
2243 for (i = 0; i < 3; i++) {
cca8b133 2244 ret = _mv88e6xxx_reg_write(
158bc065 2245 ps, REG_GLOBAL, GLOBAL_ATU_MAC_01 + i,
cca8b133 2246 (addr[i * 2] << 8) | addr[i * 2 + 1]);
defb05b9
GR
2247 if (ret < 0)
2248 return ret;
2249 }
2250
2251 return 0;
2252}
2253
158bc065
AL
2254static int _mv88e6xxx_atu_mac_read(struct mv88e6xxx_priv_state *ps,
2255 unsigned char *addr)
defb05b9
GR
2256{
2257 int i, ret;
2258
2259 for (i = 0; i < 3; i++) {
158bc065 2260 ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL,
cca8b133 2261 GLOBAL_ATU_MAC_01 + i);
defb05b9
GR
2262 if (ret < 0)
2263 return ret;
2264 addr[i * 2] = ret >> 8;
2265 addr[i * 2 + 1] = ret & 0xff;
2266 }
2267
2268 return 0;
2269}
2270
158bc065 2271static int _mv88e6xxx_atu_load(struct mv88e6xxx_priv_state *ps,
fd231c82 2272 struct mv88e6xxx_atu_entry *entry)
defb05b9 2273{
6630e236
VD
2274 int ret;
2275
158bc065 2276 ret = _mv88e6xxx_atu_wait(ps);
defb05b9
GR
2277 if (ret < 0)
2278 return ret;
2279
158bc065 2280 ret = _mv88e6xxx_atu_mac_write(ps, entry->mac);
defb05b9
GR
2281 if (ret < 0)
2282 return ret;
2283
158bc065 2284 ret = _mv88e6xxx_atu_data_write(ps, entry);
fd231c82 2285 if (ret < 0)
87820510
VD
2286 return ret;
2287
158bc065 2288 return _mv88e6xxx_atu_cmd(ps, entry->fid, GLOBAL_ATU_OP_LOAD_DB);
fd231c82 2289}
87820510 2290
158bc065 2291static int _mv88e6xxx_port_fdb_load(struct mv88e6xxx_priv_state *ps, int port,
fd231c82
VD
2292 const unsigned char *addr, u16 vid,
2293 u8 state)
2294{
2295 struct mv88e6xxx_atu_entry entry = { 0 };
3285f9e8
VD
2296 struct mv88e6xxx_vtu_stu_entry vlan;
2297 int err;
2298
2db9ce1f
VD
2299 /* Null VLAN ID corresponds to the port private database */
2300 if (vid == 0)
158bc065 2301 err = _mv88e6xxx_port_fid_get(ps, port, &vlan.fid);
2db9ce1f 2302 else
158bc065 2303 err = _mv88e6xxx_vtu_get(ps, vid, &vlan, false);
3285f9e8
VD
2304 if (err)
2305 return err;
fd231c82 2306
3285f9e8 2307 entry.fid = vlan.fid;
fd231c82
VD
2308 entry.state = state;
2309 ether_addr_copy(entry.mac, addr);
2310 if (state != GLOBAL_ATU_DATA_STATE_UNUSED) {
2311 entry.trunk = false;
2312 entry.portv_trunkid = BIT(port);
2313 }
2314
158bc065 2315 return _mv88e6xxx_atu_load(ps, &entry);
87820510
VD
2316}
2317
f81ec90f
VD
2318static int mv88e6xxx_port_fdb_prepare(struct dsa_switch *ds, int port,
2319 const struct switchdev_obj_port_fdb *fdb,
2320 struct switchdev_trans *trans)
146a3206 2321{
2672f825
VD
2322 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
2323
2324 if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_ATU))
2325 return -EOPNOTSUPP;
2326
146a3206
VD
2327 /* We don't need any dynamic resource from the kernel (yet),
2328 * so skip the prepare phase.
2329 */
2330 return 0;
2331}
2332
f81ec90f
VD
2333static void mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port,
2334 const struct switchdev_obj_port_fdb *fdb,
2335 struct switchdev_trans *trans)
87820510 2336{
1f36faf2 2337 int state = is_multicast_ether_addr(fdb->addr) ?
87820510
VD
2338 GLOBAL_ATU_DATA_STATE_MC_STATIC :
2339 GLOBAL_ATU_DATA_STATE_UC_STATIC;
cdf09697 2340 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
87820510 2341
2672f825
VD
2342 if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_ATU))
2343 return;
2344
9f8b3ee1 2345 mutex_lock(&ps->reg_lock);
158bc065 2346 if (_mv88e6xxx_port_fdb_load(ps, port, fdb->addr, fdb->vid, state))
c8b09808
AL
2347 netdev_err(ds->ports[port].netdev,
2348 "failed to load MAC address\n");
9f8b3ee1 2349 mutex_unlock(&ps->reg_lock);
87820510
VD
2350}
2351
f81ec90f
VD
2352static int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port,
2353 const struct switchdev_obj_port_fdb *fdb)
87820510
VD
2354{
2355 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
87820510
VD
2356 int ret;
2357
2672f825
VD
2358 if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_ATU))
2359 return -EOPNOTSUPP;
2360
9f8b3ee1 2361 mutex_lock(&ps->reg_lock);
158bc065 2362 ret = _mv88e6xxx_port_fdb_load(ps, port, fdb->addr, fdb->vid,
cdf09697 2363 GLOBAL_ATU_DATA_STATE_UNUSED);
9f8b3ee1 2364 mutex_unlock(&ps->reg_lock);
87820510
VD
2365
2366 return ret;
2367}
2368
158bc065 2369static int _mv88e6xxx_atu_getnext(struct mv88e6xxx_priv_state *ps, u16 fid,
1d194046 2370 struct mv88e6xxx_atu_entry *entry)
6630e236 2371{
1d194046
VD
2372 struct mv88e6xxx_atu_entry next = { 0 };
2373 int ret;
2374
2375 next.fid = fid;
defb05b9 2376
158bc065 2377 ret = _mv88e6xxx_atu_wait(ps);
cdf09697
DM
2378 if (ret < 0)
2379 return ret;
6630e236 2380
158bc065 2381 ret = _mv88e6xxx_atu_cmd(ps, fid, GLOBAL_ATU_OP_GET_NEXT_DB);
1d194046
VD
2382 if (ret < 0)
2383 return ret;
6630e236 2384
158bc065 2385 ret = _mv88e6xxx_atu_mac_read(ps, next.mac);
1d194046
VD
2386 if (ret < 0)
2387 return ret;
6630e236 2388
158bc065 2389 ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL, GLOBAL_ATU_DATA);
cdf09697
DM
2390 if (ret < 0)
2391 return ret;
6630e236 2392
1d194046
VD
2393 next.state = ret & GLOBAL_ATU_DATA_STATE_MASK;
2394 if (next.state != GLOBAL_ATU_DATA_STATE_UNUSED) {
2395 unsigned int mask, shift;
2396
2397 if (ret & GLOBAL_ATU_DATA_TRUNK) {
2398 next.trunk = true;
2399 mask = GLOBAL_ATU_DATA_TRUNK_ID_MASK;
2400 shift = GLOBAL_ATU_DATA_TRUNK_ID_SHIFT;
2401 } else {
2402 next.trunk = false;
2403 mask = GLOBAL_ATU_DATA_PORT_VECTOR_MASK;
2404 shift = GLOBAL_ATU_DATA_PORT_VECTOR_SHIFT;
2405 }
2406
2407 next.portv_trunkid = (ret & mask) >> shift;
2408 }
cdf09697 2409
1d194046 2410 *entry = next;
cdf09697
DM
2411 return 0;
2412}
2413
158bc065
AL
2414static int _mv88e6xxx_port_fdb_dump_one(struct mv88e6xxx_priv_state *ps,
2415 u16 fid, u16 vid, int port,
74b6ba0d
VD
2416 struct switchdev_obj_port_fdb *fdb,
2417 int (*cb)(struct switchdev_obj *obj))
2418{
2419 struct mv88e6xxx_atu_entry addr = {
2420 .mac = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
2421 };
2422 int err;
2423
158bc065 2424 err = _mv88e6xxx_atu_mac_write(ps, addr.mac);
74b6ba0d
VD
2425 if (err)
2426 return err;
2427
2428 do {
158bc065 2429 err = _mv88e6xxx_atu_getnext(ps, fid, &addr);
74b6ba0d
VD
2430 if (err)
2431 break;
2432
2433 if (addr.state == GLOBAL_ATU_DATA_STATE_UNUSED)
2434 break;
2435
2436 if (!addr.trunk && addr.portv_trunkid & BIT(port)) {
2437 bool is_static = addr.state ==
2438 (is_multicast_ether_addr(addr.mac) ?
2439 GLOBAL_ATU_DATA_STATE_MC_STATIC :
2440 GLOBAL_ATU_DATA_STATE_UC_STATIC);
2441
2442 fdb->vid = vid;
2443 ether_addr_copy(fdb->addr, addr.mac);
2444 fdb->ndm_state = is_static ? NUD_NOARP : NUD_REACHABLE;
2445
2446 err = cb(&fdb->obj);
2447 if (err)
2448 break;
2449 }
2450 } while (!is_broadcast_ether_addr(addr.mac));
2451
2452 return err;
2453}
2454
f81ec90f
VD
2455static int mv88e6xxx_port_fdb_dump(struct dsa_switch *ds, int port,
2456 struct switchdev_obj_port_fdb *fdb,
2457 int (*cb)(struct switchdev_obj *obj))
f33475bd
VD
2458{
2459 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
2460 struct mv88e6xxx_vtu_stu_entry vlan = {
2461 .vid = GLOBAL_VTU_VID_MASK, /* all ones */
2462 };
2db9ce1f 2463 u16 fid;
f33475bd
VD
2464 int err;
2465
2672f825
VD
2466 if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_ATU))
2467 return -EOPNOTSUPP;
2468
9f8b3ee1 2469 mutex_lock(&ps->reg_lock);
f33475bd 2470
2db9ce1f 2471 /* Dump port's default Filtering Information Database (VLAN ID 0) */
158bc065 2472 err = _mv88e6xxx_port_fid_get(ps, port, &fid);
2db9ce1f
VD
2473 if (err)
2474 goto unlock;
2475
158bc065 2476 err = _mv88e6xxx_port_fdb_dump_one(ps, fid, 0, port, fdb, cb);
2db9ce1f
VD
2477 if (err)
2478 goto unlock;
2479
74b6ba0d 2480 /* Dump VLANs' Filtering Information Databases */
158bc065 2481 err = _mv88e6xxx_vtu_vid_write(ps, vlan.vid);
f33475bd
VD
2482 if (err)
2483 goto unlock;
2484
2485 do {
158bc065 2486 err = _mv88e6xxx_vtu_getnext(ps, &vlan);
f33475bd 2487 if (err)
74b6ba0d 2488 break;
f33475bd
VD
2489
2490 if (!vlan.valid)
2491 break;
2492
158bc065 2493 err = _mv88e6xxx_port_fdb_dump_one(ps, vlan.fid, vlan.vid, port,
74b6ba0d 2494 fdb, cb);
f33475bd 2495 if (err)
74b6ba0d 2496 break;
f33475bd
VD
2497 } while (vlan.vid < GLOBAL_VTU_VID_MASK);
2498
2499unlock:
9f8b3ee1 2500 mutex_unlock(&ps->reg_lock);
f33475bd
VD
2501
2502 return err;
2503}
2504
f81ec90f
VD
2505static int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port,
2506 struct net_device *bridge)
e79a8bcb 2507{
a6692754 2508 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1d9619d5 2509 int i, err = 0;
466dfa07 2510
936f234a
VD
2511 if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_VLANTABLE))
2512 return -EOPNOTSUPP;
2513
9f8b3ee1 2514 mutex_lock(&ps->reg_lock);
466dfa07 2515
b7666efe 2516 /* Assign the bridge and remap each port's VLANTable */
a6692754 2517 ps->ports[port].bridge_dev = bridge;
b7666efe 2518
009a2b98 2519 for (i = 0; i < ps->info->num_ports; ++i) {
b7666efe 2520 if (ps->ports[i].bridge_dev == bridge) {
158bc065 2521 err = _mv88e6xxx_port_based_vlan_map(ps, i);
b7666efe
VD
2522 if (err)
2523 break;
2524 }
2525 }
2526
9f8b3ee1 2527 mutex_unlock(&ps->reg_lock);
a6692754 2528
466dfa07 2529 return err;
e79a8bcb
VD
2530}
2531
f81ec90f 2532static void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port)
66d9cd0f 2533{
a6692754 2534 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
b7666efe 2535 struct net_device *bridge = ps->ports[port].bridge_dev;
16bfa702 2536 int i;
466dfa07 2537
936f234a
VD
2538 if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_VLANTABLE))
2539 return;
2540
9f8b3ee1 2541 mutex_lock(&ps->reg_lock);
466dfa07 2542
b7666efe 2543 /* Unassign the bridge and remap each port's VLANTable */
a6692754 2544 ps->ports[port].bridge_dev = NULL;
b7666efe 2545
009a2b98 2546 for (i = 0; i < ps->info->num_ports; ++i)
16bfa702 2547 if (i == port || ps->ports[i].bridge_dev == bridge)
158bc065 2548 if (_mv88e6xxx_port_based_vlan_map(ps, i))
c8b09808
AL
2549 netdev_warn(ds->ports[i].netdev,
2550 "failed to remap\n");
b7666efe 2551
9f8b3ee1 2552 mutex_unlock(&ps->reg_lock);
66d9cd0f
VD
2553}
2554
03a4a540
AL
2555static int _mv88e6xxx_mdio_page_write(struct mv88e6xxx_priv_state *ps,
2556 int port, int page, int reg, int val)
75baacf0
PU
2557{
2558 int ret;
2559
03a4a540 2560 ret = mv88e6xxx_mdio_write_indirect(ps, port, 0x16, page);
75baacf0
PU
2561 if (ret < 0)
2562 goto restore_page_0;
2563
03a4a540 2564 ret = mv88e6xxx_mdio_write_indirect(ps, port, reg, val);
75baacf0 2565restore_page_0:
03a4a540 2566 mv88e6xxx_mdio_write_indirect(ps, port, 0x16, 0x0);
75baacf0
PU
2567
2568 return ret;
2569}
2570
03a4a540
AL
2571static int _mv88e6xxx_mdio_page_read(struct mv88e6xxx_priv_state *ps,
2572 int port, int page, int reg)
75baacf0
PU
2573{
2574 int ret;
2575
03a4a540 2576 ret = mv88e6xxx_mdio_write_indirect(ps, port, 0x16, page);
75baacf0
PU
2577 if (ret < 0)
2578 goto restore_page_0;
2579
03a4a540 2580 ret = mv88e6xxx_mdio_read_indirect(ps, port, reg);
75baacf0 2581restore_page_0:
03a4a540 2582 mv88e6xxx_mdio_write_indirect(ps, port, 0x16, 0x0);
75baacf0
PU
2583
2584 return ret;
2585}
2586
552238b5
VD
2587static int mv88e6xxx_switch_reset(struct mv88e6xxx_priv_state *ps)
2588{
2589 bool ppu_active = mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU_ACTIVE);
2590 u16 is_reset = (ppu_active ? 0x8800 : 0xc800);
52638f71 2591 struct gpio_desc *gpiod = ps->reset;
552238b5
VD
2592 unsigned long timeout;
2593 int ret;
2594 int i;
2595
2596 /* Set all ports to the disabled state. */
2597 for (i = 0; i < ps->info->num_ports; i++) {
2598 ret = _mv88e6xxx_reg_read(ps, REG_PORT(i), PORT_CONTROL);
2599 if (ret < 0)
2600 return ret;
2601
2602 ret = _mv88e6xxx_reg_write(ps, REG_PORT(i), PORT_CONTROL,
2603 ret & 0xfffc);
2604 if (ret)
2605 return ret;
2606 }
2607
2608 /* Wait for transmit queues to drain. */
2609 usleep_range(2000, 4000);
2610
2611 /* If there is a gpio connected to the reset pin, toggle it */
2612 if (gpiod) {
2613 gpiod_set_value_cansleep(gpiod, 1);
2614 usleep_range(10000, 20000);
2615 gpiod_set_value_cansleep(gpiod, 0);
2616 usleep_range(10000, 20000);
2617 }
2618
2619 /* Reset the switch. Keep the PPU active if requested. The PPU
2620 * needs to be active to support indirect phy register access
2621 * through global registers 0x18 and 0x19.
2622 */
2623 if (ppu_active)
2624 ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL, 0x04, 0xc000);
2625 else
2626 ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL, 0x04, 0xc400);
2627 if (ret)
2628 return ret;
2629
2630 /* Wait up to one second for reset to complete. */
2631 timeout = jiffies + 1 * HZ;
2632 while (time_before(jiffies, timeout)) {
2633 ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL, 0x00);
2634 if (ret < 0)
2635 return ret;
2636
2637 if ((ret & is_reset) == is_reset)
2638 break;
2639 usleep_range(1000, 2000);
2640 }
2641 if (time_after(jiffies, timeout))
2642 ret = -ETIMEDOUT;
2643 else
2644 ret = 0;
2645
2646 return ret;
2647}
2648
158bc065 2649static int mv88e6xxx_power_on_serdes(struct mv88e6xxx_priv_state *ps)
13a7ebb3
PU
2650{
2651 int ret;
2652
03a4a540
AL
2653 ret = _mv88e6xxx_mdio_page_read(ps, REG_FIBER_SERDES,
2654 PAGE_FIBER_SERDES, MII_BMCR);
13a7ebb3
PU
2655 if (ret < 0)
2656 return ret;
2657
2658 if (ret & BMCR_PDOWN) {
2659 ret &= ~BMCR_PDOWN;
03a4a540
AL
2660 ret = _mv88e6xxx_mdio_page_write(ps, REG_FIBER_SERDES,
2661 PAGE_FIBER_SERDES, MII_BMCR,
2662 ret);
13a7ebb3
PU
2663 }
2664
2665 return ret;
2666}
2667
a1a6a4d1 2668static int mv88e6xxx_setup_port(struct mv88e6xxx_priv_state *ps, int port)
d827e88a 2669{
a1a6a4d1 2670 struct dsa_switch *ds = ps->ds;
f02bdffc 2671 int ret;
54d792f2 2672 u16 reg;
d827e88a 2673
158bc065
AL
2674 if (mv88e6xxx_6352_family(ps) || mv88e6xxx_6351_family(ps) ||
2675 mv88e6xxx_6165_family(ps) || mv88e6xxx_6097_family(ps) ||
2676 mv88e6xxx_6185_family(ps) || mv88e6xxx_6095_family(ps) ||
2677 mv88e6xxx_6065_family(ps) || mv88e6xxx_6320_family(ps)) {
54d792f2
AL
2678 /* MAC Forcing register: don't force link, speed,
2679 * duplex or flow control state to any particular
2680 * values on physical ports, but force the CPU port
2681 * and all DSA ports to their maximum bandwidth and
2682 * full duplex.
2683 */
158bc065 2684 reg = _mv88e6xxx_reg_read(ps, REG_PORT(port), PORT_PCS_CTRL);
60045cbf 2685 if (dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port)) {
53adc9e8 2686 reg &= ~PORT_PCS_CTRL_UNFORCED;
54d792f2
AL
2687 reg |= PORT_PCS_CTRL_FORCE_LINK |
2688 PORT_PCS_CTRL_LINK_UP |
2689 PORT_PCS_CTRL_DUPLEX_FULL |
2690 PORT_PCS_CTRL_FORCE_DUPLEX;
158bc065 2691 if (mv88e6xxx_6065_family(ps))
54d792f2
AL
2692 reg |= PORT_PCS_CTRL_100;
2693 else
2694 reg |= PORT_PCS_CTRL_1000;
2695 } else {
2696 reg |= PORT_PCS_CTRL_UNFORCED;
2697 }
2698
158bc065 2699 ret = _mv88e6xxx_reg_write(ps, REG_PORT(port),
54d792f2
AL
2700 PORT_PCS_CTRL, reg);
2701 if (ret)
a1a6a4d1 2702 return ret;
54d792f2
AL
2703 }
2704
2705 /* Port Control: disable Drop-on-Unlock, disable Drop-on-Lock,
2706 * disable Header mode, enable IGMP/MLD snooping, disable VLAN
2707 * tunneling, determine priority by looking at 802.1p and IP
2708 * priority fields (IP prio has precedence), and set STP state
2709 * to Forwarding.
2710 *
2711 * If this is the CPU link, use DSA or EDSA tagging depending
2712 * on which tagging mode was configured.
2713 *
2714 * If this is a link to another switch, use DSA tagging mode.
2715 *
2716 * If this is the upstream port for this switch, enable
2717 * forwarding of unknown unicasts and multicasts.
2718 */
2719 reg = 0;
158bc065
AL
2720 if (mv88e6xxx_6352_family(ps) || mv88e6xxx_6351_family(ps) ||
2721 mv88e6xxx_6165_family(ps) || mv88e6xxx_6097_family(ps) ||
2722 mv88e6xxx_6095_family(ps) || mv88e6xxx_6065_family(ps) ||
2723 mv88e6xxx_6185_family(ps) || mv88e6xxx_6320_family(ps))
54d792f2
AL
2724 reg = PORT_CONTROL_IGMP_MLD_SNOOP |
2725 PORT_CONTROL_USE_TAG | PORT_CONTROL_USE_IP |
2726 PORT_CONTROL_STATE_FORWARDING;
2727 if (dsa_is_cpu_port(ds, port)) {
158bc065 2728 if (mv88e6xxx_6095_family(ps) || mv88e6xxx_6185_family(ps))
54d792f2 2729 reg |= PORT_CONTROL_DSA_TAG;
158bc065
AL
2730 if (mv88e6xxx_6352_family(ps) || mv88e6xxx_6351_family(ps) ||
2731 mv88e6xxx_6165_family(ps) || mv88e6xxx_6097_family(ps) ||
2732 mv88e6xxx_6320_family(ps)) {
5377b802
AL
2733 reg |= PORT_CONTROL_FRAME_ETHER_TYPE_DSA |
2734 PORT_CONTROL_FORWARD_UNKNOWN |
c047a1f9 2735 PORT_CONTROL_FORWARD_UNKNOWN_MC;
54d792f2
AL
2736 }
2737
158bc065
AL
2738 if (mv88e6xxx_6352_family(ps) || mv88e6xxx_6351_family(ps) ||
2739 mv88e6xxx_6165_family(ps) || mv88e6xxx_6097_family(ps) ||
2740 mv88e6xxx_6095_family(ps) || mv88e6xxx_6065_family(ps) ||
2741 mv88e6xxx_6185_family(ps) || mv88e6xxx_6320_family(ps)) {
57d32310 2742 reg |= PORT_CONTROL_EGRESS_ADD_TAG;
54d792f2
AL
2743 }
2744 }
6083ce71 2745 if (dsa_is_dsa_port(ds, port)) {
158bc065 2746 if (mv88e6xxx_6095_family(ps) || mv88e6xxx_6185_family(ps))
6083ce71 2747 reg |= PORT_CONTROL_DSA_TAG;
158bc065
AL
2748 if (mv88e6xxx_6352_family(ps) || mv88e6xxx_6351_family(ps) ||
2749 mv88e6xxx_6165_family(ps) || mv88e6xxx_6097_family(ps) ||
2750 mv88e6xxx_6320_family(ps)) {
54d792f2 2751 reg |= PORT_CONTROL_FRAME_MODE_DSA;
6083ce71
AL
2752 }
2753
54d792f2
AL
2754 if (port == dsa_upstream_port(ds))
2755 reg |= PORT_CONTROL_FORWARD_UNKNOWN |
2756 PORT_CONTROL_FORWARD_UNKNOWN_MC;
2757 }
2758 if (reg) {
158bc065 2759 ret = _mv88e6xxx_reg_write(ps, REG_PORT(port),
54d792f2
AL
2760 PORT_CONTROL, reg);
2761 if (ret)
a1a6a4d1 2762 return ret;
54d792f2
AL
2763 }
2764
13a7ebb3
PU
2765 /* If this port is connected to a SerDes, make sure the SerDes is not
2766 * powered down.
2767 */
158bc065
AL
2768 if (mv88e6xxx_6352_family(ps)) {
2769 ret = _mv88e6xxx_reg_read(ps, REG_PORT(port), PORT_STATUS);
13a7ebb3 2770 if (ret < 0)
a1a6a4d1 2771 return ret;
13a7ebb3
PU
2772 ret &= PORT_STATUS_CMODE_MASK;
2773 if ((ret == PORT_STATUS_CMODE_100BASE_X) ||
2774 (ret == PORT_STATUS_CMODE_1000BASE_X) ||
2775 (ret == PORT_STATUS_CMODE_SGMII)) {
158bc065 2776 ret = mv88e6xxx_power_on_serdes(ps);
13a7ebb3 2777 if (ret < 0)
a1a6a4d1 2778 return ret;
13a7ebb3
PU
2779 }
2780 }
2781
8efdda4a 2782 /* Port Control 2: don't force a good FCS, set the maximum frame size to
46fbe5e5 2783 * 10240 bytes, disable 802.1q tags checking, don't discard tagged or
8efdda4a
VD
2784 * untagged frames on this port, do a destination address lookup on all
2785 * received packets as usual, disable ARP mirroring and don't send a
2786 * copy of all transmitted/received frames on this port to the CPU.
54d792f2
AL
2787 */
2788 reg = 0;
158bc065
AL
2789 if (mv88e6xxx_6352_family(ps) || mv88e6xxx_6351_family(ps) ||
2790 mv88e6xxx_6165_family(ps) || mv88e6xxx_6097_family(ps) ||
2791 mv88e6xxx_6095_family(ps) || mv88e6xxx_6320_family(ps) ||
2792 mv88e6xxx_6185_family(ps))
54d792f2
AL
2793 reg = PORT_CONTROL_2_MAP_DA;
2794
158bc065
AL
2795 if (mv88e6xxx_6352_family(ps) || mv88e6xxx_6351_family(ps) ||
2796 mv88e6xxx_6165_family(ps) || mv88e6xxx_6320_family(ps))
54d792f2
AL
2797 reg |= PORT_CONTROL_2_JUMBO_10240;
2798
158bc065 2799 if (mv88e6xxx_6095_family(ps) || mv88e6xxx_6185_family(ps)) {
54d792f2
AL
2800 /* Set the upstream port this port should use */
2801 reg |= dsa_upstream_port(ds);
2802 /* enable forwarding of unknown multicast addresses to
2803 * the upstream port
2804 */
2805 if (port == dsa_upstream_port(ds))
2806 reg |= PORT_CONTROL_2_FORWARD_UNKNOWN;
2807 }
2808
46fbe5e5 2809 reg |= PORT_CONTROL_2_8021Q_DISABLED;
8efdda4a 2810
54d792f2 2811 if (reg) {
158bc065 2812 ret = _mv88e6xxx_reg_write(ps, REG_PORT(port),
54d792f2
AL
2813 PORT_CONTROL_2, reg);
2814 if (ret)
a1a6a4d1 2815 return ret;
54d792f2
AL
2816 }
2817
2818 /* Port Association Vector: when learning source addresses
2819 * of packets, add the address to the address database using
2820 * a port bitmap that has only the bit for this port set and
2821 * the other bits clear.
2822 */
4c7ea3c0 2823 reg = 1 << port;
996ecb82
VD
2824 /* Disable learning for CPU port */
2825 if (dsa_is_cpu_port(ds, port))
65fa4027 2826 reg = 0;
4c7ea3c0 2827
158bc065 2828 ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), PORT_ASSOC_VECTOR, reg);
54d792f2 2829 if (ret)
a1a6a4d1 2830 return ret;
54d792f2
AL
2831
2832 /* Egress rate control 2: disable egress rate control. */
158bc065 2833 ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), PORT_RATE_CONTROL_2,
54d792f2
AL
2834 0x0000);
2835 if (ret)
a1a6a4d1 2836 return ret;
54d792f2 2837
158bc065
AL
2838 if (mv88e6xxx_6352_family(ps) || mv88e6xxx_6351_family(ps) ||
2839 mv88e6xxx_6165_family(ps) || mv88e6xxx_6097_family(ps) ||
2840 mv88e6xxx_6320_family(ps)) {
54d792f2
AL
2841 /* Do not limit the period of time that this port can
2842 * be paused for by the remote end or the period of
2843 * time that this port can pause the remote end.
2844 */
158bc065 2845 ret = _mv88e6xxx_reg_write(ps, REG_PORT(port),
54d792f2
AL
2846 PORT_PAUSE_CTRL, 0x0000);
2847 if (ret)
a1a6a4d1 2848 return ret;
54d792f2
AL
2849
2850 /* Port ATU control: disable limiting the number of
2851 * address database entries that this port is allowed
2852 * to use.
2853 */
158bc065 2854 ret = _mv88e6xxx_reg_write(ps, REG_PORT(port),
54d792f2
AL
2855 PORT_ATU_CONTROL, 0x0000);
2856 /* Priority Override: disable DA, SA and VTU priority
2857 * override.
2858 */
158bc065 2859 ret = _mv88e6xxx_reg_write(ps, REG_PORT(port),
54d792f2
AL
2860 PORT_PRI_OVERRIDE, 0x0000);
2861 if (ret)
a1a6a4d1 2862 return ret;
54d792f2
AL
2863
2864 /* Port Ethertype: use the Ethertype DSA Ethertype
2865 * value.
2866 */
158bc065 2867 ret = _mv88e6xxx_reg_write(ps, REG_PORT(port),
54d792f2
AL
2868 PORT_ETH_TYPE, ETH_P_EDSA);
2869 if (ret)
a1a6a4d1 2870 return ret;
54d792f2
AL
2871 /* Tag Remap: use an identity 802.1p prio -> switch
2872 * prio mapping.
2873 */
158bc065 2874 ret = _mv88e6xxx_reg_write(ps, REG_PORT(port),
54d792f2
AL
2875 PORT_TAG_REGMAP_0123, 0x3210);
2876 if (ret)
a1a6a4d1 2877 return ret;
54d792f2
AL
2878
2879 /* Tag Remap 2: use an identity 802.1p prio -> switch
2880 * prio mapping.
2881 */
158bc065 2882 ret = _mv88e6xxx_reg_write(ps, REG_PORT(port),
54d792f2
AL
2883 PORT_TAG_REGMAP_4567, 0x7654);
2884 if (ret)
a1a6a4d1 2885 return ret;
54d792f2
AL
2886 }
2887
158bc065
AL
2888 if (mv88e6xxx_6352_family(ps) || mv88e6xxx_6351_family(ps) ||
2889 mv88e6xxx_6165_family(ps) || mv88e6xxx_6097_family(ps) ||
2890 mv88e6xxx_6185_family(ps) || mv88e6xxx_6095_family(ps) ||
2891 mv88e6xxx_6320_family(ps)) {
54d792f2 2892 /* Rate Control: disable ingress rate limiting. */
158bc065 2893 ret = _mv88e6xxx_reg_write(ps, REG_PORT(port),
54d792f2
AL
2894 PORT_RATE_CONTROL, 0x0001);
2895 if (ret)
a1a6a4d1 2896 return ret;
54d792f2
AL
2897 }
2898
366f0a0f
GR
2899 /* Port Control 1: disable trunking, disable sending
2900 * learning messages to this port.
d827e88a 2901 */
158bc065 2902 ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), PORT_CONTROL_1, 0x0000);
d827e88a 2903 if (ret)
a1a6a4d1 2904 return ret;
d827e88a 2905
207afda1 2906 /* Port based VLAN map: give each port the same default address
b7666efe
VD
2907 * database, and allow bidirectional communication between the
2908 * CPU and DSA port(s), and the other ports.
d827e88a 2909 */
158bc065 2910 ret = _mv88e6xxx_port_fid_set(ps, port, 0);
2db9ce1f 2911 if (ret)
a1a6a4d1 2912 return ret;
2db9ce1f 2913
158bc065 2914 ret = _mv88e6xxx_port_based_vlan_map(ps, port);
d827e88a 2915 if (ret)
a1a6a4d1 2916 return ret;
d827e88a
GR
2917
2918 /* Default VLAN ID and priority: don't set a default VLAN
2919 * ID, and set the default packet priority to zero.
2920 */
158bc065 2921 ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), PORT_DEFAULT_VLAN,
47cf1e65 2922 0x0000);
a1a6a4d1
VD
2923 if (ret)
2924 return ret;
dbde9e66 2925
dbde9e66
AL
2926 return 0;
2927}
2928
08a01261 2929static int mv88e6xxx_setup_global(struct mv88e6xxx_priv_state *ps)
acdaffcc 2930{
b0745e87
VD
2931 struct dsa_switch *ds = ps->ds;
2932 u32 upstream_port = dsa_upstream_port(ds);
119477bd 2933 u16 reg;
552238b5 2934 int err;
54d792f2
AL
2935 int i;
2936
119477bd
VD
2937 /* Enable the PHY Polling Unit if present, don't discard any packets,
2938 * and mask all interrupt sources.
2939 */
2940 reg = 0;
2941 if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU) ||
2942 mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU_ACTIVE))
2943 reg |= GLOBAL_CONTROL_PPU_ENABLE;
2944
2945 err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL, reg);
2946 if (err)
2947 return err;
2948
b0745e87
VD
2949 /* Configure the upstream port, and configure it as the port to which
2950 * ingress and egress and ARP monitor frames are to be sent.
2951 */
2952 reg = upstream_port << GLOBAL_MONITOR_CONTROL_INGRESS_SHIFT |
2953 upstream_port << GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT |
2954 upstream_port << GLOBAL_MONITOR_CONTROL_ARP_SHIFT;
2955 err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_MONITOR_CONTROL, reg);
2956 if (err)
2957 return err;
2958
50484ff4
VD
2959 /* Disable remote management, and set the switch's DSA device number. */
2960 err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL_2,
2961 GLOBAL_CONTROL_2_MULTIPLE_CASCADE |
2962 (ds->index & 0x1f));
2963 if (err)
2964 return err;
2965
54d792f2
AL
2966 /* Set the default address aging time to 5 minutes, and
2967 * enable address learn messages to be sent to all message
2968 * ports.
2969 */
158bc065 2970 err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_ATU_CONTROL,
48ace4ef
AL
2971 0x0140 | GLOBAL_ATU_CONTROL_LEARN2ALL);
2972 if (err)
08a01261 2973 return err;
54d792f2
AL
2974
2975 /* Configure the IP ToS mapping registers. */
158bc065 2976 err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_0, 0x0000);
48ace4ef 2977 if (err)
08a01261 2978 return err;
158bc065 2979 err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_1, 0x0000);
48ace4ef 2980 if (err)
08a01261 2981 return err;
158bc065 2982 err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_2, 0x5555);
48ace4ef 2983 if (err)
08a01261 2984 return err;
158bc065 2985 err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_3, 0x5555);
48ace4ef 2986 if (err)
08a01261 2987 return err;
158bc065 2988 err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_4, 0xaaaa);
48ace4ef 2989 if (err)
08a01261 2990 return err;
158bc065 2991 err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_5, 0xaaaa);
48ace4ef 2992 if (err)
08a01261 2993 return err;
158bc065 2994 err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_6, 0xffff);
48ace4ef 2995 if (err)
08a01261 2996 return err;
158bc065 2997 err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_7, 0xffff);
48ace4ef 2998 if (err)
08a01261 2999 return err;
54d792f2
AL
3000
3001 /* Configure the IEEE 802.1p priority mapping register. */
158bc065 3002 err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IEEE_PRI, 0xfa41);
48ace4ef 3003 if (err)
08a01261 3004 return err;
54d792f2
AL
3005
3006 /* Send all frames with destination addresses matching
3007 * 01:80:c2:00:00:0x to the CPU port.
3008 */
158bc065 3009 err = _mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_MGMT_EN_0X, 0xffff);
48ace4ef 3010 if (err)
08a01261 3011 return err;
54d792f2
AL
3012
3013 /* Ignore removed tag data on doubly tagged packets, disable
3014 * flow control messages, force flow control priority to the
3015 * highest, and send all special multicast frames to the CPU
3016 * port at the highest priority.
3017 */
158bc065 3018 err = _mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_SWITCH_MGMT,
48ace4ef
AL
3019 0x7 | GLOBAL2_SWITCH_MGMT_RSVD2CPU | 0x70 |
3020 GLOBAL2_SWITCH_MGMT_FORCE_FLOW_CTRL_PRI);
3021 if (err)
08a01261 3022 return err;
54d792f2
AL
3023
3024 /* Program the DSA routing table. */
3025 for (i = 0; i < 32; i++) {
3026 int nexthop = 0x1f;
3027
66472fc0
AL
3028 if (i != ds->index && i < DSA_MAX_SWITCHES)
3029 nexthop = ds->rtable[i] & 0x1f;
54d792f2 3030
48ace4ef 3031 err = _mv88e6xxx_reg_write(
158bc065 3032 ps, REG_GLOBAL2,
48ace4ef
AL
3033 GLOBAL2_DEVICE_MAPPING,
3034 GLOBAL2_DEVICE_MAPPING_UPDATE |
3035 (i << GLOBAL2_DEVICE_MAPPING_TARGET_SHIFT) | nexthop);
3036 if (err)
08a01261 3037 return err;
54d792f2
AL
3038 }
3039
3040 /* Clear all trunk masks. */
48ace4ef 3041 for (i = 0; i < 8; i++) {
158bc065 3042 err = _mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_TRUNK_MASK,
48ace4ef
AL
3043 0x8000 |
3044 (i << GLOBAL2_TRUNK_MASK_NUM_SHIFT) |
009a2b98 3045 ((1 << ps->info->num_ports) - 1));
48ace4ef 3046 if (err)
08a01261 3047 return err;
48ace4ef 3048 }
54d792f2
AL
3049
3050 /* Clear all trunk mappings. */
48ace4ef
AL
3051 for (i = 0; i < 16; i++) {
3052 err = _mv88e6xxx_reg_write(
158bc065 3053 ps, REG_GLOBAL2,
48ace4ef
AL
3054 GLOBAL2_TRUNK_MAPPING,
3055 GLOBAL2_TRUNK_MAPPING_UPDATE |
3056 (i << GLOBAL2_TRUNK_MAPPING_ID_SHIFT));
3057 if (err)
08a01261 3058 return err;
48ace4ef 3059 }
54d792f2 3060
158bc065
AL
3061 if (mv88e6xxx_6352_family(ps) || mv88e6xxx_6351_family(ps) ||
3062 mv88e6xxx_6165_family(ps) || mv88e6xxx_6097_family(ps) ||
3063 mv88e6xxx_6320_family(ps)) {
54d792f2
AL
3064 /* Send all frames with destination addresses matching
3065 * 01:80:c2:00:00:2x to the CPU port.
3066 */
158bc065 3067 err = _mv88e6xxx_reg_write(ps, REG_GLOBAL2,
48ace4ef
AL
3068 GLOBAL2_MGMT_EN_2X, 0xffff);
3069 if (err)
08a01261 3070 return err;
54d792f2
AL
3071
3072 /* Initialise cross-chip port VLAN table to reset
3073 * defaults.
3074 */
158bc065 3075 err = _mv88e6xxx_reg_write(ps, REG_GLOBAL2,
48ace4ef
AL
3076 GLOBAL2_PVT_ADDR, 0x9000);
3077 if (err)
08a01261 3078 return err;
54d792f2
AL
3079
3080 /* Clear the priority override table. */
48ace4ef 3081 for (i = 0; i < 16; i++) {
158bc065 3082 err = _mv88e6xxx_reg_write(ps, REG_GLOBAL2,
48ace4ef
AL
3083 GLOBAL2_PRIO_OVERRIDE,
3084 0x8000 | (i << 8));
3085 if (err)
08a01261 3086 return err;
48ace4ef 3087 }
54d792f2
AL
3088 }
3089
158bc065
AL
3090 if (mv88e6xxx_6352_family(ps) || mv88e6xxx_6351_family(ps) ||
3091 mv88e6xxx_6165_family(ps) || mv88e6xxx_6097_family(ps) ||
3092 mv88e6xxx_6185_family(ps) || mv88e6xxx_6095_family(ps) ||
3093 mv88e6xxx_6320_family(ps)) {
54d792f2
AL
3094 /* Disable ingress rate limiting by resetting all
3095 * ingress rate limit registers to their initial
3096 * state.
3097 */
009a2b98 3098 for (i = 0; i < ps->info->num_ports; i++) {
158bc065 3099 err = _mv88e6xxx_reg_write(ps, REG_GLOBAL2,
48ace4ef
AL
3100 GLOBAL2_INGRESS_OP,
3101 0x9000 | (i << 8));
3102 if (err)
08a01261 3103 return err;
48ace4ef 3104 }
54d792f2
AL
3105 }
3106
db687a56 3107 /* Clear the statistics counters for all ports */
158bc065 3108 err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_STATS_OP,
48ace4ef
AL
3109 GLOBAL_STATS_OP_FLUSH_ALL);
3110 if (err)
08a01261 3111 return err;
db687a56
AL
3112
3113 /* Wait for the flush to complete. */
158bc065 3114 err = _mv88e6xxx_stats_wait(ps);
08a01261
VD
3115 if (err)
3116 return err;
6b17e864 3117
c161d0a5 3118 /* Clear all ATU entries */
158bc065 3119 err = _mv88e6xxx_atu_flush(ps, 0, true);
08a01261
VD
3120 if (err)
3121 return err;
c161d0a5 3122
6b17e864 3123 /* Clear all the VTU and STU entries */
158bc065 3124 err = _mv88e6xxx_vtu_stu_flush(ps);
08a01261
VD
3125 if (err < 0)
3126 return err;
3127
3128 return err;
3129}
3130
f81ec90f 3131static int mv88e6xxx_setup(struct dsa_switch *ds)
08a01261 3132{
a1a6a4d1 3133 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
08a01261 3134 int err;
a1a6a4d1
VD
3135 int i;
3136
3137 ps->ds = ds;
b516d453 3138 ds->slave_mii_bus = ps->mdio_bus;
08a01261 3139
08a01261
VD
3140 if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_EEPROM))
3141 mutex_init(&ps->eeprom_mutex);
3142
9f8b3ee1 3143 mutex_lock(&ps->reg_lock);
08a01261
VD
3144
3145 err = mv88e6xxx_switch_reset(ps);
3146 if (err)
3147 goto unlock;
3148
3149 err = mv88e6xxx_setup_global(ps);
a1a6a4d1
VD
3150 if (err)
3151 goto unlock;
3152
3153 for (i = 0; i < ps->info->num_ports; i++) {
3154 err = mv88e6xxx_setup_port(ps, i);
3155 if (err)
3156 goto unlock;
3157 }
08a01261 3158
6b17e864 3159unlock:
9f8b3ee1 3160 mutex_unlock(&ps->reg_lock);
db687a56 3161
48ace4ef 3162 return err;
54d792f2
AL
3163}
3164
57d32310
VD
3165static int mv88e6xxx_mdio_page_read(struct dsa_switch *ds, int port, int page,
3166 int reg)
49143585
AL
3167{
3168 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
3169 int ret;
3170
9f8b3ee1 3171 mutex_lock(&ps->reg_lock);
03a4a540 3172 ret = _mv88e6xxx_mdio_page_read(ps, port, page, reg);
9f8b3ee1 3173 mutex_unlock(&ps->reg_lock);
75baacf0 3174
49143585
AL
3175 return ret;
3176}
3177
57d32310
VD
3178static int mv88e6xxx_mdio_page_write(struct dsa_switch *ds, int port, int page,
3179 int reg, int val)
49143585
AL
3180{
3181 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
3182 int ret;
3183
9f8b3ee1 3184 mutex_lock(&ps->reg_lock);
03a4a540 3185 ret = _mv88e6xxx_mdio_page_write(ps, port, page, reg, val);
9f8b3ee1 3186 mutex_unlock(&ps->reg_lock);
75baacf0 3187
fd3a0ee4
AL
3188 return ret;
3189}
3190
03a4a540
AL
3191static int mv88e6xxx_port_to_mdio_addr(struct mv88e6xxx_priv_state *ps,
3192 int port)
fd3a0ee4 3193{
009a2b98 3194 if (port >= 0 && port < ps->info->num_ports)
fd3a0ee4
AL
3195 return port;
3196 return -EINVAL;
3197}
3198
b516d453 3199static int mv88e6xxx_mdio_read(struct mii_bus *bus, int port, int regnum)
fd3a0ee4 3200{
b516d453 3201 struct mv88e6xxx_priv_state *ps = bus->priv;
03a4a540 3202 int addr = mv88e6xxx_port_to_mdio_addr(ps, port);
fd3a0ee4
AL
3203 int ret;
3204
3205 if (addr < 0)
158bc065 3206 return 0xffff;
fd3a0ee4 3207
9f8b3ee1 3208 mutex_lock(&ps->reg_lock);
8c9983a2
VD
3209
3210 if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU))
03a4a540 3211 ret = mv88e6xxx_mdio_read_ppu(ps, addr, regnum);
6d5834a1 3212 else if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_SMI_PHY))
03a4a540 3213 ret = mv88e6xxx_mdio_read_indirect(ps, addr, regnum);
8c9983a2 3214 else
03a4a540 3215 ret = mv88e6xxx_mdio_read_direct(ps, addr, regnum);
8c9983a2 3216
9f8b3ee1 3217 mutex_unlock(&ps->reg_lock);
fd3a0ee4
AL
3218 return ret;
3219}
3220
b516d453 3221static int mv88e6xxx_mdio_write(struct mii_bus *bus, int port, int regnum,
03a4a540 3222 u16 val)
fd3a0ee4 3223{
b516d453 3224 struct mv88e6xxx_priv_state *ps = bus->priv;
03a4a540 3225 int addr = mv88e6xxx_port_to_mdio_addr(ps, port);
fd3a0ee4
AL
3226 int ret;
3227
3228 if (addr < 0)
158bc065 3229 return 0xffff;
fd3a0ee4 3230
9f8b3ee1 3231 mutex_lock(&ps->reg_lock);
8c9983a2
VD
3232
3233 if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU))
03a4a540 3234 ret = mv88e6xxx_mdio_write_ppu(ps, addr, regnum, val);
6d5834a1 3235 else if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_SMI_PHY))
03a4a540 3236 ret = mv88e6xxx_mdio_write_indirect(ps, addr, regnum, val);
8c9983a2 3237 else
03a4a540 3238 ret = mv88e6xxx_mdio_write_direct(ps, addr, regnum, val);
8c9983a2 3239
9f8b3ee1 3240 mutex_unlock(&ps->reg_lock);
fd3a0ee4
AL
3241 return ret;
3242}
3243
b516d453
AL
3244static int mv88e6xxx_mdio_register(struct mv88e6xxx_priv_state *ps,
3245 struct device_node *np)
3246{
3247 static int index;
3248 struct mii_bus *bus;
3249 int err;
3250
3251 if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU))
3252 mv88e6xxx_ppu_state_init(ps);
3253
3254 if (np)
3255 ps->mdio_np = of_get_child_by_name(np, "mdio");
3256
3257 bus = devm_mdiobus_alloc(ps->dev);
3258 if (!bus)
3259 return -ENOMEM;
3260
3261 bus->priv = (void *)ps;
3262 if (np) {
3263 bus->name = np->full_name;
3264 snprintf(bus->id, MII_BUS_ID_SIZE, "%s", np->full_name);
3265 } else {
3266 bus->name = "mv88e6xxx SMI";
3267 snprintf(bus->id, MII_BUS_ID_SIZE, "mv88e6xxx-%d", index++);
3268 }
3269
3270 bus->read = mv88e6xxx_mdio_read;
3271 bus->write = mv88e6xxx_mdio_write;
3272 bus->parent = ps->dev;
3273
3274 if (ps->mdio_np)
3275 err = of_mdiobus_register(bus, ps->mdio_np);
3276 else
3277 err = mdiobus_register(bus);
3278 if (err) {
3279 dev_err(ps->dev, "Cannot register MDIO bus (%d)\n", err);
3280 goto out;
3281 }
3282 ps->mdio_bus = bus;
3283
3284 return 0;
3285
3286out:
3287 if (ps->mdio_np)
3288 of_node_put(ps->mdio_np);
3289
3290 return err;
3291}
3292
3293static void mv88e6xxx_mdio_unregister(struct mv88e6xxx_priv_state *ps)
3294
3295{
3296 struct mii_bus *bus = ps->mdio_bus;
3297
3298 mdiobus_unregister(bus);
3299
3300 if (ps->mdio_np)
3301 of_node_put(ps->mdio_np);
3302}
3303
c22995c5
GR
3304#ifdef CONFIG_NET_DSA_HWMON
3305
3306static int mv88e61xx_get_temp(struct dsa_switch *ds, int *temp)
3307{
3308 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
3309 int ret;
3310 int val;
3311
3312 *temp = 0;
3313
9f8b3ee1 3314 mutex_lock(&ps->reg_lock);
c22995c5 3315
03a4a540 3316 ret = mv88e6xxx_mdio_write_direct(ps, 0x0, 0x16, 0x6);
c22995c5
GR
3317 if (ret < 0)
3318 goto error;
3319
3320 /* Enable temperature sensor */
03a4a540 3321 ret = mv88e6xxx_mdio_read_direct(ps, 0x0, 0x1a);
c22995c5
GR
3322 if (ret < 0)
3323 goto error;
3324
03a4a540 3325 ret = mv88e6xxx_mdio_write_direct(ps, 0x0, 0x1a, ret | (1 << 5));
c22995c5
GR
3326 if (ret < 0)
3327 goto error;
3328
3329 /* Wait for temperature to stabilize */
3330 usleep_range(10000, 12000);
3331
03a4a540 3332 val = mv88e6xxx_mdio_read_direct(ps, 0x0, 0x1a);
c22995c5
GR
3333 if (val < 0) {
3334 ret = val;
3335 goto error;
3336 }
3337
3338 /* Disable temperature sensor */
03a4a540 3339 ret = mv88e6xxx_mdio_write_direct(ps, 0x0, 0x1a, ret & ~(1 << 5));
c22995c5
GR
3340 if (ret < 0)
3341 goto error;
3342
3343 *temp = ((val & 0x1f) - 5) * 5;
3344
3345error:
03a4a540 3346 mv88e6xxx_mdio_write_direct(ps, 0x0, 0x16, 0x0);
9f8b3ee1 3347 mutex_unlock(&ps->reg_lock);
c22995c5
GR
3348 return ret;
3349}
3350
3351static int mv88e63xx_get_temp(struct dsa_switch *ds, int *temp)
3352{
158bc065
AL
3353 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
3354 int phy = mv88e6xxx_6320_family(ps) ? 3 : 0;
c22995c5
GR
3355 int ret;
3356
3357 *temp = 0;
3358
03a4a540 3359 ret = mv88e6xxx_mdio_page_read(ds, phy, 6, 27);
c22995c5
GR
3360 if (ret < 0)
3361 return ret;
3362
3363 *temp = (ret & 0xff) - 25;
3364
3365 return 0;
3366}
3367
f81ec90f 3368static int mv88e6xxx_get_temp(struct dsa_switch *ds, int *temp)
c22995c5 3369{
158bc065
AL
3370 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
3371
6594f615
VD
3372 if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_TEMP))
3373 return -EOPNOTSUPP;
3374
158bc065 3375 if (mv88e6xxx_6320_family(ps) || mv88e6xxx_6352_family(ps))
c22995c5
GR
3376 return mv88e63xx_get_temp(ds, temp);
3377
3378 return mv88e61xx_get_temp(ds, temp);
3379}
3380
f81ec90f 3381static int mv88e6xxx_get_temp_limit(struct dsa_switch *ds, int *temp)
c22995c5 3382{
158bc065
AL
3383 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
3384 int phy = mv88e6xxx_6320_family(ps) ? 3 : 0;
c22995c5
GR
3385 int ret;
3386
6594f615 3387 if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_TEMP_LIMIT))
c22995c5
GR
3388 return -EOPNOTSUPP;
3389
3390 *temp = 0;
3391
03a4a540 3392 ret = mv88e6xxx_mdio_page_read(ds, phy, 6, 26);
c22995c5
GR
3393 if (ret < 0)
3394 return ret;
3395
3396 *temp = (((ret >> 8) & 0x1f) * 5) - 25;
3397
3398 return 0;
3399}
3400
f81ec90f 3401static int mv88e6xxx_set_temp_limit(struct dsa_switch *ds, int temp)
c22995c5 3402{
158bc065
AL
3403 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
3404 int phy = mv88e6xxx_6320_family(ps) ? 3 : 0;
c22995c5
GR
3405 int ret;
3406
6594f615 3407 if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_TEMP_LIMIT))
c22995c5
GR
3408 return -EOPNOTSUPP;
3409
03a4a540 3410 ret = mv88e6xxx_mdio_page_read(ds, phy, 6, 26);
c22995c5
GR
3411 if (ret < 0)
3412 return ret;
3413 temp = clamp_val(DIV_ROUND_CLOSEST(temp, 5) + 5, 0, 0x1f);
03a4a540
AL
3414 return mv88e6xxx_mdio_page_write(ds, phy, 6, 26,
3415 (ret & 0xe0ff) | (temp << 8));
c22995c5
GR
3416}
3417
f81ec90f 3418static int mv88e6xxx_get_temp_alarm(struct dsa_switch *ds, bool *alarm)
c22995c5 3419{
158bc065
AL
3420 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
3421 int phy = mv88e6xxx_6320_family(ps) ? 3 : 0;
c22995c5
GR
3422 int ret;
3423
6594f615 3424 if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_TEMP_LIMIT))
c22995c5
GR
3425 return -EOPNOTSUPP;
3426
3427 *alarm = false;
3428
03a4a540 3429 ret = mv88e6xxx_mdio_page_read(ds, phy, 6, 26);
c22995c5
GR
3430 if (ret < 0)
3431 return ret;
3432
3433 *alarm = !!(ret & 0x40);
3434
3435 return 0;
3436}
3437#endif /* CONFIG_NET_DSA_HWMON */
3438
f81ec90f
VD
3439static const struct mv88e6xxx_info mv88e6xxx_table[] = {
3440 [MV88E6085] = {
3441 .prod_num = PORT_SWITCH_ID_PROD_NUM_6085,
3442 .family = MV88E6XXX_FAMILY_6097,
3443 .name = "Marvell 88E6085",
3444 .num_databases = 4096,
3445 .num_ports = 10,
3446 .flags = MV88E6XXX_FLAGS_FAMILY_6097,
3447 },
3448
3449 [MV88E6095] = {
3450 .prod_num = PORT_SWITCH_ID_PROD_NUM_6095,
3451 .family = MV88E6XXX_FAMILY_6095,
3452 .name = "Marvell 88E6095/88E6095F",
3453 .num_databases = 256,
3454 .num_ports = 11,
3455 .flags = MV88E6XXX_FLAGS_FAMILY_6095,
3456 },
3457
3458 [MV88E6123] = {
3459 .prod_num = PORT_SWITCH_ID_PROD_NUM_6123,
3460 .family = MV88E6XXX_FAMILY_6165,
3461 .name = "Marvell 88E6123",
3462 .num_databases = 4096,
3463 .num_ports = 3,
3464 .flags = MV88E6XXX_FLAGS_FAMILY_6165,
3465 },
3466
3467 [MV88E6131] = {
3468 .prod_num = PORT_SWITCH_ID_PROD_NUM_6131,
3469 .family = MV88E6XXX_FAMILY_6185,
3470 .name = "Marvell 88E6131",
3471 .num_databases = 256,
3472 .num_ports = 8,
3473 .flags = MV88E6XXX_FLAGS_FAMILY_6185,
3474 },
3475
3476 [MV88E6161] = {
3477 .prod_num = PORT_SWITCH_ID_PROD_NUM_6161,
3478 .family = MV88E6XXX_FAMILY_6165,
3479 .name = "Marvell 88E6161",
3480 .num_databases = 4096,
3481 .num_ports = 6,
3482 .flags = MV88E6XXX_FLAGS_FAMILY_6165,
3483 },
3484
3485 [MV88E6165] = {
3486 .prod_num = PORT_SWITCH_ID_PROD_NUM_6165,
3487 .family = MV88E6XXX_FAMILY_6165,
3488 .name = "Marvell 88E6165",
3489 .num_databases = 4096,
3490 .num_ports = 6,
3491 .flags = MV88E6XXX_FLAGS_FAMILY_6165,
3492 },
3493
3494 [MV88E6171] = {
3495 .prod_num = PORT_SWITCH_ID_PROD_NUM_6171,
3496 .family = MV88E6XXX_FAMILY_6351,
3497 .name = "Marvell 88E6171",
3498 .num_databases = 4096,
3499 .num_ports = 7,
3500 .flags = MV88E6XXX_FLAGS_FAMILY_6351,
3501 },
3502
3503 [MV88E6172] = {
3504 .prod_num = PORT_SWITCH_ID_PROD_NUM_6172,
3505 .family = MV88E6XXX_FAMILY_6352,
3506 .name = "Marvell 88E6172",
3507 .num_databases = 4096,
3508 .num_ports = 7,
3509 .flags = MV88E6XXX_FLAGS_FAMILY_6352,
3510 },
3511
3512 [MV88E6175] = {
3513 .prod_num = PORT_SWITCH_ID_PROD_NUM_6175,
3514 .family = MV88E6XXX_FAMILY_6351,
3515 .name = "Marvell 88E6175",
3516 .num_databases = 4096,
3517 .num_ports = 7,
3518 .flags = MV88E6XXX_FLAGS_FAMILY_6351,
3519 },
3520
3521 [MV88E6176] = {
3522 .prod_num = PORT_SWITCH_ID_PROD_NUM_6176,
3523 .family = MV88E6XXX_FAMILY_6352,
3524 .name = "Marvell 88E6176",
3525 .num_databases = 4096,
3526 .num_ports = 7,
3527 .flags = MV88E6XXX_FLAGS_FAMILY_6352,
3528 },
3529
3530 [MV88E6185] = {
3531 .prod_num = PORT_SWITCH_ID_PROD_NUM_6185,
3532 .family = MV88E6XXX_FAMILY_6185,
3533 .name = "Marvell 88E6185",
3534 .num_databases = 256,
3535 .num_ports = 10,
3536 .flags = MV88E6XXX_FLAGS_FAMILY_6185,
3537 },
3538
3539 [MV88E6240] = {
3540 .prod_num = PORT_SWITCH_ID_PROD_NUM_6240,
3541 .family = MV88E6XXX_FAMILY_6352,
3542 .name = "Marvell 88E6240",
3543 .num_databases = 4096,
3544 .num_ports = 7,
3545 .flags = MV88E6XXX_FLAGS_FAMILY_6352,
3546 },
3547
3548 [MV88E6320] = {
3549 .prod_num = PORT_SWITCH_ID_PROD_NUM_6320,
3550 .family = MV88E6XXX_FAMILY_6320,
3551 .name = "Marvell 88E6320",
3552 .num_databases = 4096,
3553 .num_ports = 7,
3554 .flags = MV88E6XXX_FLAGS_FAMILY_6320,
3555 },
3556
3557 [MV88E6321] = {
3558 .prod_num = PORT_SWITCH_ID_PROD_NUM_6321,
3559 .family = MV88E6XXX_FAMILY_6320,
3560 .name = "Marvell 88E6321",
3561 .num_databases = 4096,
3562 .num_ports = 7,
3563 .flags = MV88E6XXX_FLAGS_FAMILY_6320,
3564 },
3565
3566 [MV88E6350] = {
3567 .prod_num = PORT_SWITCH_ID_PROD_NUM_6350,
3568 .family = MV88E6XXX_FAMILY_6351,
3569 .name = "Marvell 88E6350",
3570 .num_databases = 4096,
3571 .num_ports = 7,
3572 .flags = MV88E6XXX_FLAGS_FAMILY_6351,
3573 },
3574
3575 [MV88E6351] = {
3576 .prod_num = PORT_SWITCH_ID_PROD_NUM_6351,
3577 .family = MV88E6XXX_FAMILY_6351,
3578 .name = "Marvell 88E6351",
3579 .num_databases = 4096,
3580 .num_ports = 7,
3581 .flags = MV88E6XXX_FLAGS_FAMILY_6351,
3582 },
3583
3584 [MV88E6352] = {
3585 .prod_num = PORT_SWITCH_ID_PROD_NUM_6352,
3586 .family = MV88E6XXX_FAMILY_6352,
3587 .name = "Marvell 88E6352",
3588 .num_databases = 4096,
3589 .num_ports = 7,
3590 .flags = MV88E6XXX_FLAGS_FAMILY_6352,
3591 },
3592};
3593
5f7c0367 3594static const struct mv88e6xxx_info *mv88e6xxx_lookup_info(unsigned int prod_num)
b9b37713 3595{
a439c061 3596 int i;
b9b37713 3597
5f7c0367
VD
3598 for (i = 0; i < ARRAY_SIZE(mv88e6xxx_table); ++i)
3599 if (mv88e6xxx_table[i].prod_num == prod_num)
3600 return &mv88e6xxx_table[i];
b9b37713 3601
b9b37713
VD
3602 return NULL;
3603}
3604
bc46a3d5
VD
3605static int mv88e6xxx_detect(struct mv88e6xxx_priv_state *ps)
3606{
3607 const struct mv88e6xxx_info *info;
3608 int id, prod_num, rev;
3609
3610 id = mv88e6xxx_reg_read(ps, REG_PORT(0), PORT_SWITCH_ID);
3611 if (id < 0)
3612 return id;
3613
3614 prod_num = (id & 0xfff0) >> 4;
3615 rev = id & 0x000f;
3616
3617 info = mv88e6xxx_lookup_info(prod_num);
3618 if (!info)
3619 return -ENODEV;
3620
caac8545 3621 /* Update the compatible info with the probed one */
bc46a3d5
VD
3622 ps->info = info;
3623
3624 dev_info(ps->dev, "switch 0x%x detected: %s, revision %u\n",
3625 ps->info->prod_num, ps->info->name, rev);
3626
3627 return 0;
3628}
3629
469d729f
VD
3630static struct mv88e6xxx_priv_state *mv88e6xxx_alloc_chip(struct device *dev)
3631{
3632 struct mv88e6xxx_priv_state *ps;
3633
3634 ps = devm_kzalloc(dev, sizeof(*ps), GFP_KERNEL);
3635 if (!ps)
3636 return NULL;
3637
3638 ps->dev = dev;
3639
3640 mutex_init(&ps->reg_lock);
3641
3642 return ps;
3643}
3644
4a70c4ab
VD
3645static int mv88e6xxx_smi_init(struct mv88e6xxx_priv_state *ps,
3646 struct mii_bus *bus, int sw_addr)
3647{
3648 /* ADDR[0] pin is unavailable externally and considered zero */
3649 if (sw_addr & 0x1)
3650 return -EINVAL;
3651
3652 ps->bus = bus;
3653 ps->sw_addr = sw_addr;
3654
3655 return 0;
3656}
3657
fcdce7d0
AL
3658static const char *mv88e6xxx_drv_probe(struct device *dsa_dev,
3659 struct device *host_dev, int sw_addr,
3660 void **priv)
a77d43f1
AL
3661{
3662 struct mv88e6xxx_priv_state *ps;
a439c061 3663 struct mii_bus *bus;
b516d453 3664 int err;
a77d43f1 3665
a439c061 3666 bus = dsa_host_dev_to_mii_bus(host_dev);
c156913b
AL
3667 if (!bus)
3668 return NULL;
3669
469d729f
VD
3670 ps = mv88e6xxx_alloc_chip(dsa_dev);
3671 if (!ps)
3672 return NULL;
3673
caac8545
VD
3674 /* Legacy SMI probing will only support chips similar to 88E6085 */
3675 ps->info = &mv88e6xxx_table[MV88E6085];
3676
4a70c4ab
VD
3677 err = mv88e6xxx_smi_init(ps, bus, sw_addr);
3678 if (err)
3679 goto free;
3680
bc46a3d5
VD
3681 err = mv88e6xxx_detect(ps);
3682 if (err)
469d729f 3683 goto free;
a439c061 3684
b516d453
AL
3685 err = mv88e6xxx_mdio_register(ps, NULL);
3686 if (err)
469d729f 3687 goto free;
b516d453 3688
a439c061
VD
3689 *priv = ps;
3690
bc46a3d5 3691 return ps->info->name;
469d729f
VD
3692free:
3693 devm_kfree(dsa_dev, ps);
3694
3695 return NULL;
a77d43f1
AL
3696}
3697
57d32310 3698static struct dsa_switch_driver mv88e6xxx_switch_driver = {
f81ec90f 3699 .tag_protocol = DSA_TAG_PROTO_EDSA,
fcdce7d0 3700 .probe = mv88e6xxx_drv_probe,
f81ec90f
VD
3701 .setup = mv88e6xxx_setup,
3702 .set_addr = mv88e6xxx_set_addr,
f81ec90f
VD
3703 .adjust_link = mv88e6xxx_adjust_link,
3704 .get_strings = mv88e6xxx_get_strings,
3705 .get_ethtool_stats = mv88e6xxx_get_ethtool_stats,
3706 .get_sset_count = mv88e6xxx_get_sset_count,
3707 .set_eee = mv88e6xxx_set_eee,
3708 .get_eee = mv88e6xxx_get_eee,
3709#ifdef CONFIG_NET_DSA_HWMON
3710 .get_temp = mv88e6xxx_get_temp,
3711 .get_temp_limit = mv88e6xxx_get_temp_limit,
3712 .set_temp_limit = mv88e6xxx_set_temp_limit,
3713 .get_temp_alarm = mv88e6xxx_get_temp_alarm,
3714#endif
f8cd8753 3715 .get_eeprom_len = mv88e6xxx_get_eeprom_len,
f81ec90f
VD
3716 .get_eeprom = mv88e6xxx_get_eeprom,
3717 .set_eeprom = mv88e6xxx_set_eeprom,
3718 .get_regs_len = mv88e6xxx_get_regs_len,
3719 .get_regs = mv88e6xxx_get_regs,
3720 .port_bridge_join = mv88e6xxx_port_bridge_join,
3721 .port_bridge_leave = mv88e6xxx_port_bridge_leave,
3722 .port_stp_state_set = mv88e6xxx_port_stp_state_set,
3723 .port_vlan_filtering = mv88e6xxx_port_vlan_filtering,
3724 .port_vlan_prepare = mv88e6xxx_port_vlan_prepare,
3725 .port_vlan_add = mv88e6xxx_port_vlan_add,
3726 .port_vlan_del = mv88e6xxx_port_vlan_del,
3727 .port_vlan_dump = mv88e6xxx_port_vlan_dump,
3728 .port_fdb_prepare = mv88e6xxx_port_fdb_prepare,
3729 .port_fdb_add = mv88e6xxx_port_fdb_add,
3730 .port_fdb_del = mv88e6xxx_port_fdb_del,
3731 .port_fdb_dump = mv88e6xxx_port_fdb_dump,
3732};
3733
b7e66a5f
VD
3734static int mv88e6xxx_register_switch(struct mv88e6xxx_priv_state *ps,
3735 struct device_node *np)
3736{
3737 struct device *dev = ps->dev;
3738 struct dsa_switch *ds;
3739
3740 ds = devm_kzalloc(dev, sizeof(*ds), GFP_KERNEL);
3741 if (!ds)
3742 return -ENOMEM;
3743
3744 ds->dev = dev;
3745 ds->priv = ps;
3746 ds->drv = &mv88e6xxx_switch_driver;
3747
3748 dev_set_drvdata(dev, ds);
3749
3750 return dsa_register_switch(ds, np);
3751}
3752
3753static void mv88e6xxx_unregister_switch(struct mv88e6xxx_priv_state *ps)
3754{
3755 dsa_unregister_switch(ps->ds);
3756}
3757
57d32310 3758static int mv88e6xxx_probe(struct mdio_device *mdiodev)
98e67308 3759{
14c7b3c3 3760 struct device *dev = &mdiodev->dev;
f8cd8753 3761 struct device_node *np = dev->of_node;
caac8545 3762 const struct mv88e6xxx_info *compat_info;
14c7b3c3 3763 struct mv88e6xxx_priv_state *ps;
f8cd8753 3764 u32 eeprom_len;
52638f71 3765 int err;
14c7b3c3 3766
caac8545
VD
3767 compat_info = of_device_get_match_data(dev);
3768 if (!compat_info)
3769 return -EINVAL;
3770
469d729f 3771 ps = mv88e6xxx_alloc_chip(dev);
b7e66a5f 3772 if (!ps)
14c7b3c3
AL
3773 return -ENOMEM;
3774
caac8545
VD
3775 ps->info = compat_info;
3776
4a70c4ab
VD
3777 err = mv88e6xxx_smi_init(ps, mdiodev->bus, mdiodev->addr);
3778 if (err)
3779 return err;
14c7b3c3 3780
bc46a3d5
VD
3781 err = mv88e6xxx_detect(ps);
3782 if (err)
3783 return err;
14c7b3c3 3784
c6d19ab6
VD
3785 ps->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_ASIS);
3786 if (IS_ERR(ps->reset))
3787 return PTR_ERR(ps->reset);
52638f71 3788
f8cd8753
AL
3789 if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_EEPROM) &&
3790 !of_property_read_u32(np, "eeprom-length", &eeprom_len))
3791 ps->eeprom_len = eeprom_len;
3792
aa8ac396 3793 err = mv88e6xxx_mdio_register(ps, np);
b516d453
AL
3794 if (err)
3795 return err;
3796
b7e66a5f 3797 err = mv88e6xxx_register_switch(ps, np);
83c0afae
AL
3798 if (err) {
3799 mv88e6xxx_mdio_unregister(ps);
3800 return err;
3801 }
3802
98e67308
BH
3803 return 0;
3804}
14c7b3c3
AL
3805
3806static void mv88e6xxx_remove(struct mdio_device *mdiodev)
3807{
3808 struct dsa_switch *ds = dev_get_drvdata(&mdiodev->dev);
3809 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
3810
b7e66a5f 3811 mv88e6xxx_unregister_switch(ps);
b516d453 3812 mv88e6xxx_mdio_unregister(ps);
14c7b3c3
AL
3813}
3814
3815static const struct of_device_id mv88e6xxx_of_match[] = {
caac8545
VD
3816 {
3817 .compatible = "marvell,mv88e6085",
3818 .data = &mv88e6xxx_table[MV88E6085],
3819 },
14c7b3c3
AL
3820 { /* sentinel */ },
3821};
3822
3823MODULE_DEVICE_TABLE(of, mv88e6xxx_of_match);
3824
3825static struct mdio_driver mv88e6xxx_driver = {
3826 .probe = mv88e6xxx_probe,
3827 .remove = mv88e6xxx_remove,
3828 .mdiodrv.driver = {
3829 .name = "mv88e6085",
3830 .of_match_table = mv88e6xxx_of_match,
3831 },
3832};
3833
3834static int __init mv88e6xxx_init(void)
3835{
3836 register_switch_driver(&mv88e6xxx_switch_driver);
3837 return mdio_driver_register(&mv88e6xxx_driver);
3838}
98e67308
BH
3839module_init(mv88e6xxx_init);
3840
3841static void __exit mv88e6xxx_cleanup(void)
3842{
14c7b3c3 3843 mdio_driver_unregister(&mv88e6xxx_driver);
f81ec90f 3844 unregister_switch_driver(&mv88e6xxx_switch_driver);
98e67308
BH
3845}
3846module_exit(mv88e6xxx_cleanup);
3d825ede
BH
3847
3848MODULE_AUTHOR("Lennert Buytenhek <buytenh@wantstofly.org>");
3849MODULE_DESCRIPTION("Driver for Marvell 88E6XXX ethernet switch chips");
3850MODULE_LICENSE("GPL");