1 /*
2 * Marvell 88E6xxx Switch Port Registers support
3 *
4 * Copyright (c) 2008 Marvell Semiconductor
5 *
6 * Copyright (c) 2016-2017 Savoir-faire Linux Inc.
7 * Vivien Didelot <vivien.didelot@savoirfairelinux.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 */
14
15 #include <linux/bitfield.h>
16 #include <linux/if_bridge.h>
17 #include <linux/phy.h>
18 #include <linux/phylink.h>
19
20 #include "chip.h"
21 #include "port.h"
22 #include "serdes.h"
23
mv88e6xxx_port_read(struct mv88e6xxx_chip * chip,int port,int reg,u16 * val)24 int mv88e6xxx_port_read(struct mv88e6xxx_chip *chip, int port, int reg,
25 u16 *val)
26 {
27 int addr = chip->info->port_base_addr + port;
28
29 return mv88e6xxx_read(chip, addr, reg, val);
30 }
31
mv88e6xxx_port_write(struct mv88e6xxx_chip * chip,int port,int reg,u16 val)32 int mv88e6xxx_port_write(struct mv88e6xxx_chip *chip, int port, int reg,
33 u16 val)
34 {
35 int addr = chip->info->port_base_addr + port;
36
37 return mv88e6xxx_write(chip, addr, reg, val);
38 }
39
40 /* Offset 0x00: MAC (or PCS or Physical) Status Register
41 *
42 * For most devices, this is read only. However the 6185 has the MyPause
43 * bit read/write.
44 */
mv88e6185_port_set_pause(struct mv88e6xxx_chip * chip,int port,int pause)45 int mv88e6185_port_set_pause(struct mv88e6xxx_chip *chip, int port,
46 int pause)
47 {
48 u16 reg;
49 int err;
50
51 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®);
52 if (err)
53 return err;
54
55 if (pause)
56 reg |= MV88E6XXX_PORT_STS_MY_PAUSE;
57 else
58 reg &= ~MV88E6XXX_PORT_STS_MY_PAUSE;
59
60 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_STS, reg);
61 }
62
63 /* Offset 0x01: MAC (or PCS or Physical) Control Register
64 *
65 * Link, Duplex and Flow Control have one force bit, one value bit.
66 *
67 * For port's MAC speed, ForceSpd (or SpdValue) bits 1:0 program the value.
68 * Alternative values require the 200BASE (or AltSpeed) bit 12 set.
69 * Newer chips need a ForcedSpd bit 13 set to consider the value.
70 */
71
mv88e6xxx_port_set_rgmii_delay(struct mv88e6xxx_chip * chip,int port,phy_interface_t mode)72 static int mv88e6xxx_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,
73 phy_interface_t mode)
74 {
75 u16 reg;
76 int err;
77
78 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, ®);
79 if (err)
80 return err;
81
82 reg &= ~(MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK |
83 MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK);
84
85 switch (mode) {
86 case PHY_INTERFACE_MODE_RGMII_RXID:
87 reg |= MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK;
88 break;
89 case PHY_INTERFACE_MODE_RGMII_TXID:
90 reg |= MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK;
91 break;
92 case PHY_INTERFACE_MODE_RGMII_ID:
93 reg |= MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK |
94 MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK;
95 break;
96 case PHY_INTERFACE_MODE_RGMII:
97 break;
98 default:
99 return 0;
100 }
101
102 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg);
103 if (err)
104 return err;
105
106 dev_dbg(chip->dev, "p%d: delay RXCLK %s, TXCLK %s\n", port,
107 reg & MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK ? "yes" : "no",
108 reg & MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK ? "yes" : "no");
109
110 return 0;
111 }
112
mv88e6352_port_set_rgmii_delay(struct mv88e6xxx_chip * chip,int port,phy_interface_t mode)113 int mv88e6352_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,
114 phy_interface_t mode)
115 {
116 if (port < 5)
117 return -EOPNOTSUPP;
118
119 return mv88e6xxx_port_set_rgmii_delay(chip, port, mode);
120 }
121
mv88e6390_port_set_rgmii_delay(struct mv88e6xxx_chip * chip,int port,phy_interface_t mode)122 int mv88e6390_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,
123 phy_interface_t mode)
124 {
125 if (port != 0)
126 return -EOPNOTSUPP;
127
128 return mv88e6xxx_port_set_rgmii_delay(chip, port, mode);
129 }
130
mv88e6xxx_port_set_link(struct mv88e6xxx_chip * chip,int port,int link)131 int mv88e6xxx_port_set_link(struct mv88e6xxx_chip *chip, int port, int link)
132 {
133 u16 reg;
134 int err;
135
136 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, ®);
137 if (err)
138 return err;
139
140 reg &= ~(MV88E6XXX_PORT_MAC_CTL_FORCE_LINK |
141 MV88E6XXX_PORT_MAC_CTL_LINK_UP);
142
143 switch (link) {
144 case LINK_FORCED_DOWN:
145 reg |= MV88E6XXX_PORT_MAC_CTL_FORCE_LINK;
146 break;
147 case LINK_FORCED_UP:
148 reg |= MV88E6XXX_PORT_MAC_CTL_FORCE_LINK |
149 MV88E6XXX_PORT_MAC_CTL_LINK_UP;
150 break;
151 case LINK_UNFORCED:
152 /* normal link detection */
153 break;
154 default:
155 return -EINVAL;
156 }
157
158 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg);
159 if (err)
160 return err;
161
162 dev_dbg(chip->dev, "p%d: %s link %s\n", port,
163 reg & MV88E6XXX_PORT_MAC_CTL_FORCE_LINK ? "Force" : "Unforce",
164 reg & MV88E6XXX_PORT_MAC_CTL_LINK_UP ? "up" : "down");
165
166 return 0;
167 }
168
mv88e6xxx_port_set_duplex(struct mv88e6xxx_chip * chip,int port,int dup)169 int mv88e6xxx_port_set_duplex(struct mv88e6xxx_chip *chip, int port, int dup)
170 {
171 u16 reg;
172 int err;
173
174 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, ®);
175 if (err)
176 return err;
177
178 reg &= ~(MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX |
179 MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL);
180
181 switch (dup) {
182 case DUPLEX_HALF:
183 reg |= MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX;
184 break;
185 case DUPLEX_FULL:
186 reg |= MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX |
187 MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL;
188 break;
189 case DUPLEX_UNFORCED:
190 /* normal duplex detection */
191 break;
192 default:
193 return -EOPNOTSUPP;
194 }
195
196 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg);
197 if (err)
198 return err;
199
200 dev_dbg(chip->dev, "p%d: %s %s duplex\n", port,
201 reg & MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX ? "Force" : "Unforce",
202 reg & MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL ? "full" : "half");
203
204 return 0;
205 }
206
mv88e6xxx_port_set_speed(struct mv88e6xxx_chip * chip,int port,int speed,bool alt_bit,bool force_bit)207 static int mv88e6xxx_port_set_speed(struct mv88e6xxx_chip *chip, int port,
208 int speed, bool alt_bit, bool force_bit)
209 {
210 u16 reg, ctrl;
211 int err;
212
213 switch (speed) {
214 case 10:
215 ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_10;
216 break;
217 case 100:
218 ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_100;
219 break;
220 case 200:
221 if (alt_bit)
222 ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_100 |
223 MV88E6390_PORT_MAC_CTL_ALTSPEED;
224 else
225 ctrl = MV88E6065_PORT_MAC_CTL_SPEED_200;
226 break;
227 case 1000:
228 ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_1000;
229 break;
230 case 2500:
231 if (alt_bit)
232 ctrl = MV88E6390_PORT_MAC_CTL_SPEED_10000 |
233 MV88E6390_PORT_MAC_CTL_ALTSPEED;
234 else
235 ctrl = MV88E6390_PORT_MAC_CTL_SPEED_10000;
236 break;
237 case 10000:
238 /* all bits set, fall through... */
239 case SPEED_UNFORCED:
240 ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_UNFORCED;
241 break;
242 default:
243 return -EOPNOTSUPP;
244 }
245
246 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, ®);
247 if (err)
248 return err;
249
250 reg &= ~MV88E6XXX_PORT_MAC_CTL_SPEED_MASK;
251 if (alt_bit)
252 reg &= ~MV88E6390_PORT_MAC_CTL_ALTSPEED;
253 if (force_bit) {
254 reg &= ~MV88E6390_PORT_MAC_CTL_FORCE_SPEED;
255 if (speed != SPEED_UNFORCED)
256 ctrl |= MV88E6390_PORT_MAC_CTL_FORCE_SPEED;
257 }
258 reg |= ctrl;
259
260 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg);
261 if (err)
262 return err;
263
264 if (speed)
265 dev_dbg(chip->dev, "p%d: Speed set to %d Mbps\n", port, speed);
266 else
267 dev_dbg(chip->dev, "p%d: Speed unforced\n", port);
268
269 return 0;
270 }
271
272 /* Support 10, 100, 200 Mbps (e.g. 88E6065 family) */
mv88e6065_port_set_speed(struct mv88e6xxx_chip * chip,int port,int speed)273 int mv88e6065_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
274 {
275 if (speed == SPEED_MAX)
276 speed = 200;
277
278 if (speed > 200)
279 return -EOPNOTSUPP;
280
281 /* Setting 200 Mbps on port 0 to 3 selects 100 Mbps */
282 return mv88e6xxx_port_set_speed(chip, port, speed, false, false);
283 }
284
285 /* Support 10, 100, 1000 Mbps (e.g. 88E6185 family) */
mv88e6185_port_set_speed(struct mv88e6xxx_chip * chip,int port,int speed)286 int mv88e6185_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
287 {
288 if (speed == SPEED_MAX)
289 speed = 1000;
290
291 if (speed == 200 || speed > 1000)
292 return -EOPNOTSUPP;
293
294 return mv88e6xxx_port_set_speed(chip, port, speed, false, false);
295 }
296
297 /* Support 10, 100, 200, 1000, 2500 Mbps (e.g. 88E6341) */
mv88e6341_port_set_speed(struct mv88e6xxx_chip * chip,int port,int speed)298 int mv88e6341_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
299 {
300 if (speed == SPEED_MAX)
301 speed = port < 5 ? 1000 : 2500;
302
303 if (speed > 2500)
304 return -EOPNOTSUPP;
305
306 if (speed == 200 && port != 0)
307 return -EOPNOTSUPP;
308
309 if (speed == 2500 && port < 5)
310 return -EOPNOTSUPP;
311
312 return mv88e6xxx_port_set_speed(chip, port, speed, !port, true);
313 }
314
315 /* Support 10, 100, 200, 1000 Mbps (e.g. 88E6352 family) */
mv88e6352_port_set_speed(struct mv88e6xxx_chip * chip,int port,int speed)316 int mv88e6352_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
317 {
318 if (speed == SPEED_MAX)
319 speed = 1000;
320
321 if (speed > 1000)
322 return -EOPNOTSUPP;
323
324 if (speed == 200 && port < 5)
325 return -EOPNOTSUPP;
326
327 return mv88e6xxx_port_set_speed(chip, port, speed, true, false);
328 }
329
330 /* Support 10, 100, 200, 1000, 2500 Mbps (e.g. 88E6390) */
mv88e6390_port_set_speed(struct mv88e6xxx_chip * chip,int port,int speed)331 int mv88e6390_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
332 {
333 if (speed == SPEED_MAX)
334 speed = port < 9 ? 1000 : 2500;
335
336 if (speed > 2500)
337 return -EOPNOTSUPP;
338
339 if (speed == 200 && port != 0)
340 return -EOPNOTSUPP;
341
342 if (speed == 2500 && port < 9)
343 return -EOPNOTSUPP;
344
345 return mv88e6xxx_port_set_speed(chip, port, speed, true, true);
346 }
347
348 /* Support 10, 100, 200, 1000, 2500, 10000 Mbps (e.g. 88E6190X) */
mv88e6390x_port_set_speed(struct mv88e6xxx_chip * chip,int port,int speed)349 int mv88e6390x_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
350 {
351 if (speed == SPEED_MAX)
352 speed = port < 9 ? 1000 : 10000;
353
354 if (speed == 200 && port != 0)
355 return -EOPNOTSUPP;
356
357 if (speed >= 2500 && port < 9)
358 return -EOPNOTSUPP;
359
360 return mv88e6xxx_port_set_speed(chip, port, speed, true, true);
361 }
362
mv88e6390x_port_set_cmode(struct mv88e6xxx_chip * chip,int port,phy_interface_t mode)363 int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
364 phy_interface_t mode)
365 {
366 int lane;
367 u16 cmode;
368 u16 reg;
369 int err;
370
371 if (mode == PHY_INTERFACE_MODE_NA)
372 return 0;
373
374 if (port != 9 && port != 10)
375 return -EOPNOTSUPP;
376
377 switch (mode) {
378 case PHY_INTERFACE_MODE_1000BASEX:
379 cmode = MV88E6XXX_PORT_STS_CMODE_1000BASE_X;
380 break;
381 case PHY_INTERFACE_MODE_SGMII:
382 cmode = MV88E6XXX_PORT_STS_CMODE_SGMII;
383 break;
384 case PHY_INTERFACE_MODE_2500BASEX:
385 cmode = MV88E6XXX_PORT_STS_CMODE_2500BASEX;
386 break;
387 case PHY_INTERFACE_MODE_XGMII:
388 case PHY_INTERFACE_MODE_XAUI:
389 cmode = MV88E6XXX_PORT_STS_CMODE_XAUI;
390 break;
391 case PHY_INTERFACE_MODE_RXAUI:
392 cmode = MV88E6XXX_PORT_STS_CMODE_RXAUI;
393 break;
394 default:
395 cmode = 0;
396 }
397
398 /* cmode doesn't change, nothing to do for us */
399 if (cmode == chip->ports[port].cmode)
400 return 0;
401
402 lane = mv88e6390x_serdes_get_lane(chip, port);
403 if (lane < 0 && lane != -ENODEV)
404 return lane;
405
406 if (lane >= 0) {
407 if (chip->ports[port].serdes_irq) {
408 err = mv88e6390_serdes_irq_disable(chip, port, lane);
409 if (err)
410 return err;
411 }
412
413 err = mv88e6390x_serdes_power(chip, port, false);
414 if (err)
415 return err;
416 }
417
418 chip->ports[port].cmode = 0;
419
420 if (cmode) {
421 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®);
422 if (err)
423 return err;
424
425 reg &= ~MV88E6XXX_PORT_STS_CMODE_MASK;
426 reg |= cmode;
427
428 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_STS, reg);
429 if (err)
430 return err;
431
432 chip->ports[port].cmode = cmode;
433
434 lane = mv88e6390x_serdes_get_lane(chip, port);
435 if (lane < 0)
436 return lane;
437
438 err = mv88e6390x_serdes_power(chip, port, true);
439 if (err)
440 return err;
441
442 if (chip->ports[port].serdes_irq) {
443 err = mv88e6390_serdes_irq_enable(chip, port, lane);
444 if (err)
445 return err;
446 }
447 }
448
449 return 0;
450 }
451
mv88e6185_port_get_cmode(struct mv88e6xxx_chip * chip,int port,u8 * cmode)452 int mv88e6185_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode)
453 {
454 int err;
455 u16 reg;
456
457 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®);
458 if (err)
459 return err;
460
461 *cmode = reg & MV88E6185_PORT_STS_CMODE_MASK;
462
463 return 0;
464 }
465
mv88e6352_port_get_cmode(struct mv88e6xxx_chip * chip,int port,u8 * cmode)466 int mv88e6352_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode)
467 {
468 int err;
469 u16 reg;
470
471 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®);
472 if (err)
473 return err;
474
475 *cmode = reg & MV88E6XXX_PORT_STS_CMODE_MASK;
476
477 return 0;
478 }
479
mv88e6352_port_link_state(struct mv88e6xxx_chip * chip,int port,struct phylink_link_state * state)480 int mv88e6352_port_link_state(struct mv88e6xxx_chip *chip, int port,
481 struct phylink_link_state *state)
482 {
483 int err;
484 u16 reg;
485
486 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®);
487 if (err)
488 return err;
489
490 switch (reg & MV88E6XXX_PORT_STS_SPEED_MASK) {
491 case MV88E6XXX_PORT_STS_SPEED_10:
492 state->speed = SPEED_10;
493 break;
494 case MV88E6XXX_PORT_STS_SPEED_100:
495 state->speed = SPEED_100;
496 break;
497 case MV88E6XXX_PORT_STS_SPEED_1000:
498 state->speed = SPEED_1000;
499 break;
500 case MV88E6XXX_PORT_STS_SPEED_10000:
501 if ((reg & MV88E6XXX_PORT_STS_CMODE_MASK) ==
502 MV88E6XXX_PORT_STS_CMODE_2500BASEX)
503 state->speed = SPEED_2500;
504 else
505 state->speed = SPEED_10000;
506 break;
507 }
508
509 state->duplex = reg & MV88E6XXX_PORT_STS_DUPLEX ?
510 DUPLEX_FULL : DUPLEX_HALF;
511 state->link = !!(reg & MV88E6XXX_PORT_STS_LINK);
512 state->an_enabled = 1;
513 state->an_complete = state->link;
514
515 return 0;
516 }
517
mv88e6185_port_link_state(struct mv88e6xxx_chip * chip,int port,struct phylink_link_state * state)518 int mv88e6185_port_link_state(struct mv88e6xxx_chip *chip, int port,
519 struct phylink_link_state *state)
520 {
521 if (state->interface == PHY_INTERFACE_MODE_1000BASEX) {
522 u8 cmode = chip->ports[port].cmode;
523
524 /* When a port is in "Cross-chip serdes" mode, it uses
525 * 1000Base-X full duplex mode, but there is no automatic
526 * link detection. Use the sync OK status for link (as it
527 * would do for 1000Base-X mode.)
528 */
529 if (cmode == MV88E6185_PORT_STS_CMODE_SERDES) {
530 u16 mac;
531 int err;
532
533 err = mv88e6xxx_port_read(chip, port,
534 MV88E6XXX_PORT_MAC_CTL, &mac);
535 if (err)
536 return err;
537
538 state->link = !!(mac & MV88E6185_PORT_MAC_CTL_SYNC_OK);
539 state->an_enabled = 1;
540 state->an_complete =
541 !!(mac & MV88E6185_PORT_MAC_CTL_AN_DONE);
542 state->duplex =
543 state->link ? DUPLEX_FULL : DUPLEX_UNKNOWN;
544 state->speed =
545 state->link ? SPEED_1000 : SPEED_UNKNOWN;
546
547 return 0;
548 }
549 }
550
551 return mv88e6352_port_link_state(chip, port, state);
552 }
553
554 /* Offset 0x02: Jamming Control
555 *
556 * Do not limit the period of time that this port can be paused for by
557 * the remote end or the period of time that this port can pause the
558 * remote end.
559 */
mv88e6097_port_pause_limit(struct mv88e6xxx_chip * chip,int port,u8 in,u8 out)560 int mv88e6097_port_pause_limit(struct mv88e6xxx_chip *chip, int port, u8 in,
561 u8 out)
562 {
563 return mv88e6xxx_port_write(chip, port, MV88E6097_PORT_JAM_CTL,
564 out << 8 | in);
565 }
566
mv88e6390_port_pause_limit(struct mv88e6xxx_chip * chip,int port,u8 in,u8 out)567 int mv88e6390_port_pause_limit(struct mv88e6xxx_chip *chip, int port, u8 in,
568 u8 out)
569 {
570 int err;
571
572 err = mv88e6xxx_port_write(chip, port, MV88E6390_PORT_FLOW_CTL,
573 MV88E6390_PORT_FLOW_CTL_UPDATE |
574 MV88E6390_PORT_FLOW_CTL_LIMIT_IN | in);
575 if (err)
576 return err;
577
578 return mv88e6xxx_port_write(chip, port, MV88E6390_PORT_FLOW_CTL,
579 MV88E6390_PORT_FLOW_CTL_UPDATE |
580 MV88E6390_PORT_FLOW_CTL_LIMIT_OUT | out);
581 }
582
583 /* Offset 0x04: Port Control Register */
584
585 static const char * const mv88e6xxx_port_state_names[] = {
586 [MV88E6XXX_PORT_CTL0_STATE_DISABLED] = "Disabled",
587 [MV88E6XXX_PORT_CTL0_STATE_BLOCKING] = "Blocking/Listening",
588 [MV88E6XXX_PORT_CTL0_STATE_LEARNING] = "Learning",
589 [MV88E6XXX_PORT_CTL0_STATE_FORWARDING] = "Forwarding",
590 };
591
mv88e6xxx_port_set_state(struct mv88e6xxx_chip * chip,int port,u8 state)592 int mv88e6xxx_port_set_state(struct mv88e6xxx_chip *chip, int port, u8 state)
593 {
594 u16 reg;
595 int err;
596
597 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®);
598 if (err)
599 return err;
600
601 reg &= ~MV88E6XXX_PORT_CTL0_STATE_MASK;
602
603 switch (state) {
604 case BR_STATE_DISABLED:
605 state = MV88E6XXX_PORT_CTL0_STATE_DISABLED;
606 break;
607 case BR_STATE_BLOCKING:
608 case BR_STATE_LISTENING:
609 state = MV88E6XXX_PORT_CTL0_STATE_BLOCKING;
610 break;
611 case BR_STATE_LEARNING:
612 state = MV88E6XXX_PORT_CTL0_STATE_LEARNING;
613 break;
614 case BR_STATE_FORWARDING:
615 state = MV88E6XXX_PORT_CTL0_STATE_FORWARDING;
616 break;
617 default:
618 return -EINVAL;
619 }
620
621 reg |= state;
622
623 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
624 if (err)
625 return err;
626
627 dev_dbg(chip->dev, "p%d: PortState set to %s\n", port,
628 mv88e6xxx_port_state_names[state]);
629
630 return 0;
631 }
632
mv88e6xxx_port_set_egress_mode(struct mv88e6xxx_chip * chip,int port,enum mv88e6xxx_egress_mode mode)633 int mv88e6xxx_port_set_egress_mode(struct mv88e6xxx_chip *chip, int port,
634 enum mv88e6xxx_egress_mode mode)
635 {
636 int err;
637 u16 reg;
638
639 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®);
640 if (err)
641 return err;
642
643 reg &= ~MV88E6XXX_PORT_CTL0_EGRESS_MODE_MASK;
644
645 switch (mode) {
646 case MV88E6XXX_EGRESS_MODE_UNMODIFIED:
647 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNMODIFIED;
648 break;
649 case MV88E6XXX_EGRESS_MODE_UNTAGGED:
650 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNTAGGED;
651 break;
652 case MV88E6XXX_EGRESS_MODE_TAGGED:
653 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_TAGGED;
654 break;
655 case MV88E6XXX_EGRESS_MODE_ETHERTYPE:
656 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_ETHER_TYPE_DSA;
657 break;
658 default:
659 return -EINVAL;
660 }
661
662 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
663 }
664
mv88e6085_port_set_frame_mode(struct mv88e6xxx_chip * chip,int port,enum mv88e6xxx_frame_mode mode)665 int mv88e6085_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port,
666 enum mv88e6xxx_frame_mode mode)
667 {
668 int err;
669 u16 reg;
670
671 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®);
672 if (err)
673 return err;
674
675 reg &= ~MV88E6XXX_PORT_CTL0_FRAME_MODE_MASK;
676
677 switch (mode) {
678 case MV88E6XXX_FRAME_MODE_NORMAL:
679 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_NORMAL;
680 break;
681 case MV88E6XXX_FRAME_MODE_DSA:
682 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_DSA;
683 break;
684 default:
685 return -EINVAL;
686 }
687
688 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
689 }
690
mv88e6351_port_set_frame_mode(struct mv88e6xxx_chip * chip,int port,enum mv88e6xxx_frame_mode mode)691 int mv88e6351_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port,
692 enum mv88e6xxx_frame_mode mode)
693 {
694 int err;
695 u16 reg;
696
697 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®);
698 if (err)
699 return err;
700
701 reg &= ~MV88E6XXX_PORT_CTL0_FRAME_MODE_MASK;
702
703 switch (mode) {
704 case MV88E6XXX_FRAME_MODE_NORMAL:
705 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_NORMAL;
706 break;
707 case MV88E6XXX_FRAME_MODE_DSA:
708 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_DSA;
709 break;
710 case MV88E6XXX_FRAME_MODE_PROVIDER:
711 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_PROVIDER;
712 break;
713 case MV88E6XXX_FRAME_MODE_ETHERTYPE:
714 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_ETHER_TYPE_DSA;
715 break;
716 default:
717 return -EINVAL;
718 }
719
720 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
721 }
722
mv88e6185_port_set_forward_unknown(struct mv88e6xxx_chip * chip,int port,bool unicast)723 static int mv88e6185_port_set_forward_unknown(struct mv88e6xxx_chip *chip,
724 int port, bool unicast)
725 {
726 int err;
727 u16 reg;
728
729 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®);
730 if (err)
731 return err;
732
733 if (unicast)
734 reg |= MV88E6185_PORT_CTL0_FORWARD_UNKNOWN;
735 else
736 reg &= ~MV88E6185_PORT_CTL0_FORWARD_UNKNOWN;
737
738 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
739 }
740
mv88e6352_port_set_egress_floods(struct mv88e6xxx_chip * chip,int port,bool unicast,bool multicast)741 int mv88e6352_port_set_egress_floods(struct mv88e6xxx_chip *chip, int port,
742 bool unicast, bool multicast)
743 {
744 int err;
745 u16 reg;
746
747 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®);
748 if (err)
749 return err;
750
751 reg &= ~MV88E6352_PORT_CTL0_EGRESS_FLOODS_MASK;
752
753 if (unicast && multicast)
754 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_ALL_UNKNOWN_DA;
755 else if (unicast)
756 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_MC_DA;
757 else if (multicast)
758 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_UC_DA;
759 else
760 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_DA;
761
762 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
763 }
764
765 /* Offset 0x05: Port Control 1 */
766
mv88e6xxx_port_set_message_port(struct mv88e6xxx_chip * chip,int port,bool message_port)767 int mv88e6xxx_port_set_message_port(struct mv88e6xxx_chip *chip, int port,
768 bool message_port)
769 {
770 u16 val;
771 int err;
772
773 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1, &val);
774 if (err)
775 return err;
776
777 if (message_port)
778 val |= MV88E6XXX_PORT_CTL1_MESSAGE_PORT;
779 else
780 val &= ~MV88E6XXX_PORT_CTL1_MESSAGE_PORT;
781
782 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL1, val);
783 }
784
785 /* Offset 0x06: Port Based VLAN Map */
786
mv88e6xxx_port_set_vlan_map(struct mv88e6xxx_chip * chip,int port,u16 map)787 int mv88e6xxx_port_set_vlan_map(struct mv88e6xxx_chip *chip, int port, u16 map)
788 {
789 const u16 mask = mv88e6xxx_port_mask(chip);
790 u16 reg;
791 int err;
792
793 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, ®);
794 if (err)
795 return err;
796
797 reg &= ~mask;
798 reg |= map & mask;
799
800 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_BASE_VLAN, reg);
801 if (err)
802 return err;
803
804 dev_dbg(chip->dev, "p%d: VLANTable set to %.3x\n", port, map);
805
806 return 0;
807 }
808
mv88e6xxx_port_get_fid(struct mv88e6xxx_chip * chip,int port,u16 * fid)809 int mv88e6xxx_port_get_fid(struct mv88e6xxx_chip *chip, int port, u16 *fid)
810 {
811 const u16 upper_mask = (mv88e6xxx_num_databases(chip) - 1) >> 4;
812 u16 reg;
813 int err;
814
815 /* Port's default FID lower 4 bits are located in reg 0x06, offset 12 */
816 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, ®);
817 if (err)
818 return err;
819
820 *fid = (reg & 0xf000) >> 12;
821
822 /* Port's default FID upper bits are located in reg 0x05, offset 0 */
823 if (upper_mask) {
824 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1,
825 ®);
826 if (err)
827 return err;
828
829 *fid |= (reg & upper_mask) << 4;
830 }
831
832 return 0;
833 }
834
mv88e6xxx_port_set_fid(struct mv88e6xxx_chip * chip,int port,u16 fid)835 int mv88e6xxx_port_set_fid(struct mv88e6xxx_chip *chip, int port, u16 fid)
836 {
837 const u16 upper_mask = (mv88e6xxx_num_databases(chip) - 1) >> 4;
838 u16 reg;
839 int err;
840
841 if (fid >= mv88e6xxx_num_databases(chip))
842 return -EINVAL;
843
844 /* Port's default FID lower 4 bits are located in reg 0x06, offset 12 */
845 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, ®);
846 if (err)
847 return err;
848
849 reg &= 0x0fff;
850 reg |= (fid & 0x000f) << 12;
851
852 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_BASE_VLAN, reg);
853 if (err)
854 return err;
855
856 /* Port's default FID upper bits are located in reg 0x05, offset 0 */
857 if (upper_mask) {
858 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1,
859 ®);
860 if (err)
861 return err;
862
863 reg &= ~upper_mask;
864 reg |= (fid >> 4) & upper_mask;
865
866 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL1,
867 reg);
868 if (err)
869 return err;
870 }
871
872 dev_dbg(chip->dev, "p%d: FID set to %u\n", port, fid);
873
874 return 0;
875 }
876
877 /* Offset 0x07: Default Port VLAN ID & Priority */
878
mv88e6xxx_port_get_pvid(struct mv88e6xxx_chip * chip,int port,u16 * pvid)879 int mv88e6xxx_port_get_pvid(struct mv88e6xxx_chip *chip, int port, u16 *pvid)
880 {
881 u16 reg;
882 int err;
883
884 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN,
885 ®);
886 if (err)
887 return err;
888
889 *pvid = reg & MV88E6XXX_PORT_DEFAULT_VLAN_MASK;
890
891 return 0;
892 }
893
mv88e6xxx_port_set_pvid(struct mv88e6xxx_chip * chip,int port,u16 pvid)894 int mv88e6xxx_port_set_pvid(struct mv88e6xxx_chip *chip, int port, u16 pvid)
895 {
896 u16 reg;
897 int err;
898
899 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN,
900 ®);
901 if (err)
902 return err;
903
904 reg &= ~MV88E6XXX_PORT_DEFAULT_VLAN_MASK;
905 reg |= pvid & MV88E6XXX_PORT_DEFAULT_VLAN_MASK;
906
907 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN,
908 reg);
909 if (err)
910 return err;
911
912 dev_dbg(chip->dev, "p%d: DefaultVID set to %u\n", port, pvid);
913
914 return 0;
915 }
916
917 /* Offset 0x08: Port Control 2 Register */
918
919 static const char * const mv88e6xxx_port_8021q_mode_names[] = {
920 [MV88E6XXX_PORT_CTL2_8021Q_MODE_DISABLED] = "Disabled",
921 [MV88E6XXX_PORT_CTL2_8021Q_MODE_FALLBACK] = "Fallback",
922 [MV88E6XXX_PORT_CTL2_8021Q_MODE_CHECK] = "Check",
923 [MV88E6XXX_PORT_CTL2_8021Q_MODE_SECURE] = "Secure",
924 };
925
mv88e6185_port_set_default_forward(struct mv88e6xxx_chip * chip,int port,bool multicast)926 static int mv88e6185_port_set_default_forward(struct mv88e6xxx_chip *chip,
927 int port, bool multicast)
928 {
929 int err;
930 u16 reg;
931
932 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®);
933 if (err)
934 return err;
935
936 if (multicast)
937 reg |= MV88E6XXX_PORT_CTL2_DEFAULT_FORWARD;
938 else
939 reg &= ~MV88E6XXX_PORT_CTL2_DEFAULT_FORWARD;
940
941 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
942 }
943
mv88e6185_port_set_egress_floods(struct mv88e6xxx_chip * chip,int port,bool unicast,bool multicast)944 int mv88e6185_port_set_egress_floods(struct mv88e6xxx_chip *chip, int port,
945 bool unicast, bool multicast)
946 {
947 int err;
948
949 err = mv88e6185_port_set_forward_unknown(chip, port, unicast);
950 if (err)
951 return err;
952
953 return mv88e6185_port_set_default_forward(chip, port, multicast);
954 }
955
mv88e6095_port_set_upstream_port(struct mv88e6xxx_chip * chip,int port,int upstream_port)956 int mv88e6095_port_set_upstream_port(struct mv88e6xxx_chip *chip, int port,
957 int upstream_port)
958 {
959 int err;
960 u16 reg;
961
962 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®);
963 if (err)
964 return err;
965
966 reg &= ~MV88E6095_PORT_CTL2_CPU_PORT_MASK;
967 reg |= upstream_port;
968
969 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
970 }
971
mv88e6xxx_port_set_8021q_mode(struct mv88e6xxx_chip * chip,int port,u16 mode)972 int mv88e6xxx_port_set_8021q_mode(struct mv88e6xxx_chip *chip, int port,
973 u16 mode)
974 {
975 u16 reg;
976 int err;
977
978 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®);
979 if (err)
980 return err;
981
982 reg &= ~MV88E6XXX_PORT_CTL2_8021Q_MODE_MASK;
983 reg |= mode & MV88E6XXX_PORT_CTL2_8021Q_MODE_MASK;
984
985 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
986 if (err)
987 return err;
988
989 dev_dbg(chip->dev, "p%d: 802.1QMode set to %s\n", port,
990 mv88e6xxx_port_8021q_mode_names[mode]);
991
992 return 0;
993 }
994
mv88e6xxx_port_set_map_da(struct mv88e6xxx_chip * chip,int port)995 int mv88e6xxx_port_set_map_da(struct mv88e6xxx_chip *chip, int port)
996 {
997 u16 reg;
998 int err;
999
1000 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®);
1001 if (err)
1002 return err;
1003
1004 reg |= MV88E6XXX_PORT_CTL2_MAP_DA;
1005
1006 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
1007 }
1008
mv88e6165_port_set_jumbo_size(struct mv88e6xxx_chip * chip,int port,size_t size)1009 int mv88e6165_port_set_jumbo_size(struct mv88e6xxx_chip *chip, int port,
1010 size_t size)
1011 {
1012 u16 reg;
1013 int err;
1014
1015 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®);
1016 if (err)
1017 return err;
1018
1019 reg &= ~MV88E6XXX_PORT_CTL2_JUMBO_MODE_MASK;
1020
1021 if (size <= 1522)
1022 reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_1522;
1023 else if (size <= 2048)
1024 reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_2048;
1025 else if (size <= 10240)
1026 reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_10240;
1027 else
1028 return -ERANGE;
1029
1030 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
1031 }
1032
1033 /* Offset 0x09: Port Rate Control */
1034
mv88e6095_port_egress_rate_limiting(struct mv88e6xxx_chip * chip,int port)1035 int mv88e6095_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port)
1036 {
1037 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_EGRESS_RATE_CTL1,
1038 0x0000);
1039 }
1040
mv88e6097_port_egress_rate_limiting(struct mv88e6xxx_chip * chip,int port)1041 int mv88e6097_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port)
1042 {
1043 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_EGRESS_RATE_CTL1,
1044 0x0001);
1045 }
1046
1047 /* Offset 0x0C: Port ATU Control */
1048
mv88e6xxx_port_disable_learn_limit(struct mv88e6xxx_chip * chip,int port)1049 int mv88e6xxx_port_disable_learn_limit(struct mv88e6xxx_chip *chip, int port)
1050 {
1051 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ATU_CTL, 0);
1052 }
1053
1054 /* Offset 0x0D: (Priority) Override Register */
1055
mv88e6xxx_port_disable_pri_override(struct mv88e6xxx_chip * chip,int port)1056 int mv88e6xxx_port_disable_pri_override(struct mv88e6xxx_chip *chip, int port)
1057 {
1058 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_PRI_OVERRIDE, 0);
1059 }
1060
1061 /* Offset 0x0f: Port Ether type */
1062
mv88e6351_port_set_ether_type(struct mv88e6xxx_chip * chip,int port,u16 etype)1063 int mv88e6351_port_set_ether_type(struct mv88e6xxx_chip *chip, int port,
1064 u16 etype)
1065 {
1066 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ETH_TYPE, etype);
1067 }
1068
1069 /* Offset 0x18: Port IEEE Priority Remapping Registers [0-3]
1070 * Offset 0x19: Port IEEE Priority Remapping Registers [4-7]
1071 */
1072
mv88e6095_port_tag_remap(struct mv88e6xxx_chip * chip,int port)1073 int mv88e6095_port_tag_remap(struct mv88e6xxx_chip *chip, int port)
1074 {
1075 int err;
1076
1077 /* Use a direct priority mapping for all IEEE tagged frames */
1078 err = mv88e6xxx_port_write(chip, port,
1079 MV88E6095_PORT_IEEE_PRIO_REMAP_0123,
1080 0x3210);
1081 if (err)
1082 return err;
1083
1084 return mv88e6xxx_port_write(chip, port,
1085 MV88E6095_PORT_IEEE_PRIO_REMAP_4567,
1086 0x7654);
1087 }
1088
mv88e6xxx_port_ieeepmt_write(struct mv88e6xxx_chip * chip,int port,u16 table,u8 ptr,u16 data)1089 static int mv88e6xxx_port_ieeepmt_write(struct mv88e6xxx_chip *chip,
1090 int port, u16 table, u8 ptr, u16 data)
1091 {
1092 u16 reg;
1093
1094 reg = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_UPDATE | table |
1095 (ptr << __bf_shf(MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_PTR_MASK)) |
1096 (data & MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_DATA_MASK);
1097
1098 return mv88e6xxx_port_write(chip, port,
1099 MV88E6390_PORT_IEEE_PRIO_MAP_TABLE, reg);
1100 }
1101
mv88e6390_port_tag_remap(struct mv88e6xxx_chip * chip,int port)1102 int mv88e6390_port_tag_remap(struct mv88e6xxx_chip *chip, int port)
1103 {
1104 int err, i;
1105 u16 table;
1106
1107 for (i = 0; i <= 7; i++) {
1108 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_INGRESS_PCP;
1109 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i,
1110 (i | i << 4));
1111 if (err)
1112 return err;
1113
1114 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_GREEN_PCP;
1115 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i);
1116 if (err)
1117 return err;
1118
1119 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_YELLOW_PCP;
1120 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i);
1121 if (err)
1122 return err;
1123
1124 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_AVB_PCP;
1125 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i);
1126 if (err)
1127 return err;
1128 }
1129
1130 return 0;
1131 }
1132