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