1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Marvell 88E6xxx Switch Port Registers support
5 * Copyright (c) 2008 Marvell Semiconductor
7 * Copyright (c) 2016-2017 Savoir-faire Linux Inc.
8 * Vivien Didelot <vivien.didelot@savoirfairelinux.com>
11 #include <linux/bitfield.h>
12 #include <linux/if_bridge.h>
13 #include <linux/phy.h>
14 #include <linux/phylink.h>
20 int mv88e6xxx_port_read(struct mv88e6xxx_chip
*chip
, int port
, int reg
,
23 int addr
= chip
->info
->port_base_addr
+ port
;
25 return mv88e6xxx_read(chip
, addr
, reg
, val
);
28 int mv88e6xxx_port_write(struct mv88e6xxx_chip
*chip
, int port
, int reg
,
31 int addr
= chip
->info
->port_base_addr
+ port
;
33 return mv88e6xxx_write(chip
, addr
, reg
, val
);
36 /* Offset 0x00: MAC (or PCS or Physical) Status Register
38 * For most devices, this is read only. However the 6185 has the MyPause
41 int mv88e6185_port_set_pause(struct mv88e6xxx_chip
*chip
, int port
,
47 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_STS
, ®
);
52 reg
|= MV88E6XXX_PORT_STS_MY_PAUSE
;
54 reg
&= ~MV88E6XXX_PORT_STS_MY_PAUSE
;
56 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_STS
, reg
);
59 /* Offset 0x01: MAC (or PCS or Physical) Control Register
61 * Link, Duplex and Flow Control have one force bit, one value bit.
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.
68 static int mv88e6xxx_port_set_rgmii_delay(struct mv88e6xxx_chip
*chip
, int port
,
74 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_MAC_CTL
, ®
);
78 reg
&= ~(MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK
|
79 MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK
);
82 case PHY_INTERFACE_MODE_RGMII_RXID
:
83 reg
|= MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK
;
85 case PHY_INTERFACE_MODE_RGMII_TXID
:
86 reg
|= MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK
;
88 case PHY_INTERFACE_MODE_RGMII_ID
:
89 reg
|= MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK
|
90 MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK
;
92 case PHY_INTERFACE_MODE_RGMII
:
98 err
= mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_MAC_CTL
, reg
);
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");
109 int mv88e6352_port_set_rgmii_delay(struct mv88e6xxx_chip
*chip
, int port
,
110 phy_interface_t mode
)
115 return mv88e6xxx_port_set_rgmii_delay(chip
, port
, mode
);
118 int mv88e6390_port_set_rgmii_delay(struct mv88e6xxx_chip
*chip
, int port
,
119 phy_interface_t mode
)
124 return mv88e6xxx_port_set_rgmii_delay(chip
, port
, mode
);
127 int mv88e6xxx_port_set_link(struct mv88e6xxx_chip
*chip
, int port
, int link
)
132 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_MAC_CTL
, ®
);
136 reg
&= ~(MV88E6XXX_PORT_MAC_CTL_FORCE_LINK
|
137 MV88E6XXX_PORT_MAC_CTL_LINK_UP
);
140 case LINK_FORCED_DOWN
:
141 reg
|= MV88E6XXX_PORT_MAC_CTL_FORCE_LINK
;
144 reg
|= MV88E6XXX_PORT_MAC_CTL_FORCE_LINK
|
145 MV88E6XXX_PORT_MAC_CTL_LINK_UP
;
148 /* normal link detection */
154 err
= mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_MAC_CTL
, reg
);
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");
165 int mv88e6xxx_port_set_duplex(struct mv88e6xxx_chip
*chip
, int port
, int dup
)
170 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_MAC_CTL
, ®
);
174 reg
&= ~(MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX
|
175 MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL
);
179 reg
|= MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX
;
182 reg
|= MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX
|
183 MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL
;
185 case DUPLEX_UNFORCED
:
186 /* normal duplex detection */
192 err
= mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_MAC_CTL
, reg
);
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");
203 static int mv88e6xxx_port_set_speed(struct mv88e6xxx_chip
*chip
, int port
,
204 int speed
, bool alt_bit
, bool force_bit
)
211 ctrl
= MV88E6XXX_PORT_MAC_CTL_SPEED_10
;
214 ctrl
= MV88E6XXX_PORT_MAC_CTL_SPEED_100
;
218 ctrl
= MV88E6XXX_PORT_MAC_CTL_SPEED_100
|
219 MV88E6390_PORT_MAC_CTL_ALTSPEED
;
221 ctrl
= MV88E6065_PORT_MAC_CTL_SPEED_200
;
224 ctrl
= MV88E6XXX_PORT_MAC_CTL_SPEED_1000
;
228 ctrl
= MV88E6390_PORT_MAC_CTL_SPEED_10000
|
229 MV88E6390_PORT_MAC_CTL_ALTSPEED
;
231 ctrl
= MV88E6390_PORT_MAC_CTL_SPEED_10000
;
234 /* all bits set, fall through... */
236 ctrl
= MV88E6XXX_PORT_MAC_CTL_SPEED_UNFORCED
;
242 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_MAC_CTL
, ®
);
246 reg
&= ~MV88E6XXX_PORT_MAC_CTL_SPEED_MASK
;
248 reg
&= ~MV88E6390_PORT_MAC_CTL_ALTSPEED
;
250 reg
&= ~MV88E6390_PORT_MAC_CTL_FORCE_SPEED
;
251 if (speed
!= SPEED_UNFORCED
)
252 ctrl
|= MV88E6390_PORT_MAC_CTL_FORCE_SPEED
;
256 err
= mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_MAC_CTL
, reg
);
261 dev_dbg(chip
->dev
, "p%d: Speed set to %d Mbps\n", port
, speed
);
263 dev_dbg(chip
->dev
, "p%d: Speed unforced\n", port
);
268 /* Support 10, 100, 200 Mbps (e.g. 88E6065 family) */
269 int mv88e6065_port_set_speed(struct mv88e6xxx_chip
*chip
, int port
, int speed
)
271 if (speed
== SPEED_MAX
)
277 /* Setting 200 Mbps on port 0 to 3 selects 100 Mbps */
278 return mv88e6xxx_port_set_speed(chip
, port
, speed
, false, false);
281 /* Support 10, 100, 1000 Mbps (e.g. 88E6185 family) */
282 int mv88e6185_port_set_speed(struct mv88e6xxx_chip
*chip
, int port
, int speed
)
284 if (speed
== SPEED_MAX
)
287 if (speed
== 200 || speed
> 1000)
290 return mv88e6xxx_port_set_speed(chip
, port
, speed
, false, false);
293 /* Support 10, 100 Mbps (e.g. 88E6250 family) */
294 int mv88e6250_port_set_speed(struct mv88e6xxx_chip
*chip
, int port
, int speed
)
296 if (speed
== SPEED_MAX
)
302 return mv88e6xxx_port_set_speed(chip
, port
, speed
, false, false);
305 /* Support 10, 100, 200, 1000, 2500 Mbps (e.g. 88E6341) */
306 int mv88e6341_port_set_speed(struct mv88e6xxx_chip
*chip
, int port
, int speed
)
308 if (speed
== SPEED_MAX
)
309 speed
= port
< 5 ? 1000 : 2500;
314 if (speed
== 200 && port
!= 0)
317 if (speed
== 2500 && port
< 5)
320 return mv88e6xxx_port_set_speed(chip
, port
, speed
, !port
, true);
323 phy_interface_t
mv88e6341_port_max_speed_mode(int port
)
326 return PHY_INTERFACE_MODE_2500BASEX
;
328 return PHY_INTERFACE_MODE_NA
;
331 /* Support 10, 100, 200, 1000 Mbps (e.g. 88E6352 family) */
332 int mv88e6352_port_set_speed(struct mv88e6xxx_chip
*chip
, int port
, int speed
)
334 if (speed
== SPEED_MAX
)
340 if (speed
== 200 && port
< 5)
343 return mv88e6xxx_port_set_speed(chip
, port
, speed
, true, false);
346 /* Support 10, 100, 200, 1000, 2500 Mbps (e.g. 88E6390) */
347 int mv88e6390_port_set_speed(struct mv88e6xxx_chip
*chip
, int port
, int speed
)
349 if (speed
== SPEED_MAX
)
350 speed
= port
< 9 ? 1000 : 2500;
355 if (speed
== 200 && port
!= 0)
358 if (speed
== 2500 && port
< 9)
361 return mv88e6xxx_port_set_speed(chip
, port
, speed
, true, true);
364 phy_interface_t
mv88e6390_port_max_speed_mode(int port
)
366 if (port
== 9 || port
== 10)
367 return PHY_INTERFACE_MODE_2500BASEX
;
369 return PHY_INTERFACE_MODE_NA
;
372 /* Support 10, 100, 200, 1000, 2500, 10000 Mbps (e.g. 88E6190X) */
373 int mv88e6390x_port_set_speed(struct mv88e6xxx_chip
*chip
, int port
, int speed
)
375 if (speed
== SPEED_MAX
)
376 speed
= port
< 9 ? 1000 : 10000;
378 if (speed
== 200 && port
!= 0)
381 if (speed
>= 2500 && port
< 9)
384 return mv88e6xxx_port_set_speed(chip
, port
, speed
, true, true);
387 phy_interface_t
mv88e6390x_port_max_speed_mode(int port
)
389 if (port
== 9 || port
== 10)
390 return PHY_INTERFACE_MODE_XAUI
;
392 return PHY_INTERFACE_MODE_NA
;
395 static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip
*chip
, int port
,
396 phy_interface_t mode
, bool force
)
403 /* Default to a slow mode, so freeing up SERDES interfaces for
404 * other ports which might use them for SFPs.
406 if (mode
== PHY_INTERFACE_MODE_NA
)
407 mode
= PHY_INTERFACE_MODE_1000BASEX
;
410 case PHY_INTERFACE_MODE_1000BASEX
:
411 cmode
= MV88E6XXX_PORT_STS_CMODE_1000BASEX
;
413 case PHY_INTERFACE_MODE_SGMII
:
414 cmode
= MV88E6XXX_PORT_STS_CMODE_SGMII
;
416 case PHY_INTERFACE_MODE_2500BASEX
:
417 cmode
= MV88E6XXX_PORT_STS_CMODE_2500BASEX
;
419 case PHY_INTERFACE_MODE_XGMII
:
420 case PHY_INTERFACE_MODE_XAUI
:
421 cmode
= MV88E6XXX_PORT_STS_CMODE_XAUI
;
423 case PHY_INTERFACE_MODE_RXAUI
:
424 cmode
= MV88E6XXX_PORT_STS_CMODE_RXAUI
;
430 /* cmode doesn't change, nothing to do for us unless forced */
431 if (cmode
== chip
->ports
[port
].cmode
&& !force
)
434 lane
= mv88e6xxx_serdes_get_lane(chip
, port
);
436 if (chip
->ports
[port
].serdes_irq
) {
437 err
= mv88e6xxx_serdes_irq_disable(chip
, port
, lane
);
442 err
= mv88e6xxx_serdes_power_down(chip
, port
, lane
);
447 chip
->ports
[port
].cmode
= 0;
450 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_STS
, ®
);
454 reg
&= ~MV88E6XXX_PORT_STS_CMODE_MASK
;
457 err
= mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_STS
, reg
);
461 chip
->ports
[port
].cmode
= cmode
;
463 lane
= mv88e6xxx_serdes_get_lane(chip
, port
);
467 err
= mv88e6xxx_serdes_power_up(chip
, port
, lane
);
471 if (chip
->ports
[port
].serdes_irq
) {
472 err
= mv88e6xxx_serdes_irq_enable(chip
, port
, lane
);
481 int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip
*chip
, int port
,
482 phy_interface_t mode
)
484 if (port
!= 9 && port
!= 10)
487 return mv88e6xxx_port_set_cmode(chip
, port
, mode
, false);
490 int mv88e6390_port_set_cmode(struct mv88e6xxx_chip
*chip
, int port
,
491 phy_interface_t mode
)
493 if (port
!= 9 && port
!= 10)
497 case PHY_INTERFACE_MODE_NA
:
499 case PHY_INTERFACE_MODE_XGMII
:
500 case PHY_INTERFACE_MODE_XAUI
:
501 case PHY_INTERFACE_MODE_RXAUI
:
507 return mv88e6xxx_port_set_cmode(chip
, port
, mode
, false);
510 static int mv88e6341_port_set_cmode_writable(struct mv88e6xxx_chip
*chip
,
519 addr
= chip
->info
->port_base_addr
+ port
;
521 err
= mv88e6xxx_port_hidden_read(chip
, 0x7, addr
, 0, ®
);
525 bits
= MV88E6341_PORT_RESERVED_1A_FORCE_CMODE
|
526 MV88E6341_PORT_RESERVED_1A_SGMII_AN
;
528 if ((reg
& bits
) == bits
)
532 return mv88e6xxx_port_hidden_write(chip
, 0x7, addr
, 0, reg
);
535 int mv88e6341_port_set_cmode(struct mv88e6xxx_chip
*chip
, int port
,
536 phy_interface_t mode
)
544 case PHY_INTERFACE_MODE_NA
:
546 case PHY_INTERFACE_MODE_XGMII
:
547 case PHY_INTERFACE_MODE_XAUI
:
548 case PHY_INTERFACE_MODE_RXAUI
:
554 err
= mv88e6341_port_set_cmode_writable(chip
, port
);
558 return mv88e6xxx_port_set_cmode(chip
, port
, mode
, true);
561 int mv88e6185_port_get_cmode(struct mv88e6xxx_chip
*chip
, int port
, u8
*cmode
)
566 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_STS
, ®
);
570 *cmode
= reg
& MV88E6185_PORT_STS_CMODE_MASK
;
575 int mv88e6352_port_get_cmode(struct mv88e6xxx_chip
*chip
, int port
, u8
*cmode
)
580 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_STS
, ®
);
584 *cmode
= reg
& MV88E6XXX_PORT_STS_CMODE_MASK
;
589 int mv88e6250_port_link_state(struct mv88e6xxx_chip
*chip
, int port
,
590 struct phylink_link_state
*state
)
595 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_STS
, ®
);
600 switch (reg
& MV88E6250_PORT_STS_PORTMODE_MASK
) {
601 case MV88E6250_PORT_STS_PORTMODE_PHY_10_HALF
:
602 state
->speed
= SPEED_10
;
603 state
->duplex
= DUPLEX_HALF
;
605 case MV88E6250_PORT_STS_PORTMODE_PHY_100_HALF
:
606 state
->speed
= SPEED_100
;
607 state
->duplex
= DUPLEX_HALF
;
609 case MV88E6250_PORT_STS_PORTMODE_PHY_10_FULL
:
610 state
->speed
= SPEED_10
;
611 state
->duplex
= DUPLEX_FULL
;
613 case MV88E6250_PORT_STS_PORTMODE_PHY_100_FULL
:
614 state
->speed
= SPEED_100
;
615 state
->duplex
= DUPLEX_FULL
;
618 state
->speed
= SPEED_UNKNOWN
;
619 state
->duplex
= DUPLEX_UNKNOWN
;
623 switch (reg
& MV88E6250_PORT_STS_PORTMODE_MASK
) {
624 case MV88E6250_PORT_STS_PORTMODE_MII_10_HALF
:
625 state
->speed
= SPEED_10
;
626 state
->duplex
= DUPLEX_HALF
;
628 case MV88E6250_PORT_STS_PORTMODE_MII_100_HALF
:
629 state
->speed
= SPEED_100
;
630 state
->duplex
= DUPLEX_HALF
;
632 case MV88E6250_PORT_STS_PORTMODE_MII_10_FULL
:
633 state
->speed
= SPEED_10
;
634 state
->duplex
= DUPLEX_FULL
;
636 case MV88E6250_PORT_STS_PORTMODE_MII_100_FULL
:
637 state
->speed
= SPEED_100
;
638 state
->duplex
= DUPLEX_FULL
;
641 state
->speed
= SPEED_UNKNOWN
;
642 state
->duplex
= DUPLEX_UNKNOWN
;
647 state
->link
= !!(reg
& MV88E6250_PORT_STS_LINK
);
648 state
->an_enabled
= 1;
649 state
->an_complete
= state
->link
;
650 state
->interface
= PHY_INTERFACE_MODE_NA
;
655 int mv88e6352_port_link_state(struct mv88e6xxx_chip
*chip
, int port
,
656 struct phylink_link_state
*state
)
661 switch (chip
->ports
[port
].cmode
) {
662 case MV88E6XXX_PORT_STS_CMODE_RGMII
:
663 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_MAC_CTL
,
668 if ((reg
& MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK
) &&
669 (reg
& MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK
))
670 state
->interface
= PHY_INTERFACE_MODE_RGMII_ID
;
671 else if (reg
& MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK
)
672 state
->interface
= PHY_INTERFACE_MODE_RGMII_RXID
;
673 else if (reg
& MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK
)
674 state
->interface
= PHY_INTERFACE_MODE_RGMII_TXID
;
676 state
->interface
= PHY_INTERFACE_MODE_RGMII
;
678 case MV88E6XXX_PORT_STS_CMODE_1000BASEX
:
679 state
->interface
= PHY_INTERFACE_MODE_1000BASEX
;
681 case MV88E6XXX_PORT_STS_CMODE_SGMII
:
682 state
->interface
= PHY_INTERFACE_MODE_SGMII
;
684 case MV88E6XXX_PORT_STS_CMODE_2500BASEX
:
685 state
->interface
= PHY_INTERFACE_MODE_2500BASEX
;
687 case MV88E6XXX_PORT_STS_CMODE_XAUI
:
688 state
->interface
= PHY_INTERFACE_MODE_XAUI
;
690 case MV88E6XXX_PORT_STS_CMODE_RXAUI
:
691 state
->interface
= PHY_INTERFACE_MODE_RXAUI
;
694 /* we do not support other cmode values here */
695 state
->interface
= PHY_INTERFACE_MODE_NA
;
698 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_STS
, ®
);
702 switch (reg
& MV88E6XXX_PORT_STS_SPEED_MASK
) {
703 case MV88E6XXX_PORT_STS_SPEED_10
:
704 state
->speed
= SPEED_10
;
706 case MV88E6XXX_PORT_STS_SPEED_100
:
707 state
->speed
= SPEED_100
;
709 case MV88E6XXX_PORT_STS_SPEED_1000
:
710 state
->speed
= SPEED_1000
;
712 case MV88E6XXX_PORT_STS_SPEED_10000
:
713 if ((reg
& MV88E6XXX_PORT_STS_CMODE_MASK
) ==
714 MV88E6XXX_PORT_STS_CMODE_2500BASEX
)
715 state
->speed
= SPEED_2500
;
717 state
->speed
= SPEED_10000
;
721 state
->duplex
= reg
& MV88E6XXX_PORT_STS_DUPLEX
?
722 DUPLEX_FULL
: DUPLEX_HALF
;
723 state
->link
= !!(reg
& MV88E6XXX_PORT_STS_LINK
);
724 state
->an_enabled
= 1;
725 state
->an_complete
= state
->link
;
730 int mv88e6185_port_link_state(struct mv88e6xxx_chip
*chip
, int port
,
731 struct phylink_link_state
*state
)
733 if (state
->interface
== PHY_INTERFACE_MODE_1000BASEX
) {
734 u8 cmode
= chip
->ports
[port
].cmode
;
736 /* When a port is in "Cross-chip serdes" mode, it uses
737 * 1000Base-X full duplex mode, but there is no automatic
738 * link detection. Use the sync OK status for link (as it
739 * would do for 1000Base-X mode.)
741 if (cmode
== MV88E6185_PORT_STS_CMODE_SERDES
) {
745 err
= mv88e6xxx_port_read(chip
, port
,
746 MV88E6XXX_PORT_MAC_CTL
, &mac
);
750 state
->link
= !!(mac
& MV88E6185_PORT_MAC_CTL_SYNC_OK
);
751 state
->an_enabled
= 1;
753 !!(mac
& MV88E6185_PORT_MAC_CTL_AN_DONE
);
755 state
->link
? DUPLEX_FULL
: DUPLEX_UNKNOWN
;
757 state
->link
? SPEED_1000
: SPEED_UNKNOWN
;
763 return mv88e6352_port_link_state(chip
, port
, state
);
766 /* Offset 0x02: Jamming Control
768 * Do not limit the period of time that this port can be paused for by
769 * the remote end or the period of time that this port can pause the
772 int mv88e6097_port_pause_limit(struct mv88e6xxx_chip
*chip
, int port
, u8 in
,
775 return mv88e6xxx_port_write(chip
, port
, MV88E6097_PORT_JAM_CTL
,
779 int mv88e6390_port_pause_limit(struct mv88e6xxx_chip
*chip
, int port
, u8 in
,
784 err
= mv88e6xxx_port_write(chip
, port
, MV88E6390_PORT_FLOW_CTL
,
785 MV88E6390_PORT_FLOW_CTL_UPDATE
|
786 MV88E6390_PORT_FLOW_CTL_LIMIT_IN
| in
);
790 return mv88e6xxx_port_write(chip
, port
, MV88E6390_PORT_FLOW_CTL
,
791 MV88E6390_PORT_FLOW_CTL_UPDATE
|
792 MV88E6390_PORT_FLOW_CTL_LIMIT_OUT
| out
);
795 /* Offset 0x04: Port Control Register */
797 static const char * const mv88e6xxx_port_state_names
[] = {
798 [MV88E6XXX_PORT_CTL0_STATE_DISABLED
] = "Disabled",
799 [MV88E6XXX_PORT_CTL0_STATE_BLOCKING
] = "Blocking/Listening",
800 [MV88E6XXX_PORT_CTL0_STATE_LEARNING
] = "Learning",
801 [MV88E6XXX_PORT_CTL0_STATE_FORWARDING
] = "Forwarding",
804 int mv88e6xxx_port_set_state(struct mv88e6xxx_chip
*chip
, int port
, u8 state
)
809 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL0
, ®
);
813 reg
&= ~MV88E6XXX_PORT_CTL0_STATE_MASK
;
816 case BR_STATE_DISABLED
:
817 state
= MV88E6XXX_PORT_CTL0_STATE_DISABLED
;
819 case BR_STATE_BLOCKING
:
820 case BR_STATE_LISTENING
:
821 state
= MV88E6XXX_PORT_CTL0_STATE_BLOCKING
;
823 case BR_STATE_LEARNING
:
824 state
= MV88E6XXX_PORT_CTL0_STATE_LEARNING
;
826 case BR_STATE_FORWARDING
:
827 state
= MV88E6XXX_PORT_CTL0_STATE_FORWARDING
;
835 err
= mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_CTL0
, reg
);
839 dev_dbg(chip
->dev
, "p%d: PortState set to %s\n", port
,
840 mv88e6xxx_port_state_names
[state
]);
845 int mv88e6xxx_port_set_egress_mode(struct mv88e6xxx_chip
*chip
, int port
,
846 enum mv88e6xxx_egress_mode mode
)
851 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL0
, ®
);
855 reg
&= ~MV88E6XXX_PORT_CTL0_EGRESS_MODE_MASK
;
858 case MV88E6XXX_EGRESS_MODE_UNMODIFIED
:
859 reg
|= MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNMODIFIED
;
861 case MV88E6XXX_EGRESS_MODE_UNTAGGED
:
862 reg
|= MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNTAGGED
;
864 case MV88E6XXX_EGRESS_MODE_TAGGED
:
865 reg
|= MV88E6XXX_PORT_CTL0_EGRESS_MODE_TAGGED
;
867 case MV88E6XXX_EGRESS_MODE_ETHERTYPE
:
868 reg
|= MV88E6XXX_PORT_CTL0_EGRESS_MODE_ETHER_TYPE_DSA
;
874 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_CTL0
, reg
);
877 int mv88e6085_port_set_frame_mode(struct mv88e6xxx_chip
*chip
, int port
,
878 enum mv88e6xxx_frame_mode mode
)
883 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL0
, ®
);
887 reg
&= ~MV88E6XXX_PORT_CTL0_FRAME_MODE_MASK
;
890 case MV88E6XXX_FRAME_MODE_NORMAL
:
891 reg
|= MV88E6XXX_PORT_CTL0_FRAME_MODE_NORMAL
;
893 case MV88E6XXX_FRAME_MODE_DSA
:
894 reg
|= MV88E6XXX_PORT_CTL0_FRAME_MODE_DSA
;
900 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_CTL0
, reg
);
903 int mv88e6351_port_set_frame_mode(struct mv88e6xxx_chip
*chip
, int port
,
904 enum mv88e6xxx_frame_mode mode
)
909 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL0
, ®
);
913 reg
&= ~MV88E6XXX_PORT_CTL0_FRAME_MODE_MASK
;
916 case MV88E6XXX_FRAME_MODE_NORMAL
:
917 reg
|= MV88E6XXX_PORT_CTL0_FRAME_MODE_NORMAL
;
919 case MV88E6XXX_FRAME_MODE_DSA
:
920 reg
|= MV88E6XXX_PORT_CTL0_FRAME_MODE_DSA
;
922 case MV88E6XXX_FRAME_MODE_PROVIDER
:
923 reg
|= MV88E6XXX_PORT_CTL0_FRAME_MODE_PROVIDER
;
925 case MV88E6XXX_FRAME_MODE_ETHERTYPE
:
926 reg
|= MV88E6XXX_PORT_CTL0_FRAME_MODE_ETHER_TYPE_DSA
;
932 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_CTL0
, reg
);
935 static int mv88e6185_port_set_forward_unknown(struct mv88e6xxx_chip
*chip
,
936 int port
, bool unicast
)
941 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL0
, ®
);
946 reg
|= MV88E6185_PORT_CTL0_FORWARD_UNKNOWN
;
948 reg
&= ~MV88E6185_PORT_CTL0_FORWARD_UNKNOWN
;
950 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_CTL0
, reg
);
953 int mv88e6352_port_set_egress_floods(struct mv88e6xxx_chip
*chip
, int port
,
954 bool unicast
, bool multicast
)
959 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL0
, ®
);
963 reg
&= ~MV88E6352_PORT_CTL0_EGRESS_FLOODS_MASK
;
965 if (unicast
&& multicast
)
966 reg
|= MV88E6352_PORT_CTL0_EGRESS_FLOODS_ALL_UNKNOWN_DA
;
968 reg
|= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_MC_DA
;
970 reg
|= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_UC_DA
;
972 reg
|= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_DA
;
974 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_CTL0
, reg
);
977 /* Offset 0x05: Port Control 1 */
979 int mv88e6xxx_port_set_message_port(struct mv88e6xxx_chip
*chip
, int port
,
985 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL1
, &val
);
990 val
|= MV88E6XXX_PORT_CTL1_MESSAGE_PORT
;
992 val
&= ~MV88E6XXX_PORT_CTL1_MESSAGE_PORT
;
994 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_CTL1
, val
);
997 /* Offset 0x06: Port Based VLAN Map */
999 int mv88e6xxx_port_set_vlan_map(struct mv88e6xxx_chip
*chip
, int port
, u16 map
)
1001 const u16 mask
= mv88e6xxx_port_mask(chip
);
1005 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_BASE_VLAN
, ®
);
1012 err
= mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_BASE_VLAN
, reg
);
1016 dev_dbg(chip
->dev
, "p%d: VLANTable set to %.3x\n", port
, map
);
1021 int mv88e6xxx_port_get_fid(struct mv88e6xxx_chip
*chip
, int port
, u16
*fid
)
1023 const u16 upper_mask
= (mv88e6xxx_num_databases(chip
) - 1) >> 4;
1027 /* Port's default FID lower 4 bits are located in reg 0x06, offset 12 */
1028 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_BASE_VLAN
, ®
);
1032 *fid
= (reg
& 0xf000) >> 12;
1034 /* Port's default FID upper bits are located in reg 0x05, offset 0 */
1036 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL1
,
1041 *fid
|= (reg
& upper_mask
) << 4;
1047 int mv88e6xxx_port_set_fid(struct mv88e6xxx_chip
*chip
, int port
, u16 fid
)
1049 const u16 upper_mask
= (mv88e6xxx_num_databases(chip
) - 1) >> 4;
1053 if (fid
>= mv88e6xxx_num_databases(chip
))
1056 /* Port's default FID lower 4 bits are located in reg 0x06, offset 12 */
1057 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_BASE_VLAN
, ®
);
1062 reg
|= (fid
& 0x000f) << 12;
1064 err
= mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_BASE_VLAN
, reg
);
1068 /* Port's default FID upper bits are located in reg 0x05, offset 0 */
1070 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL1
,
1076 reg
|= (fid
>> 4) & upper_mask
;
1078 err
= mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_CTL1
,
1084 dev_dbg(chip
->dev
, "p%d: FID set to %u\n", port
, fid
);
1089 /* Offset 0x07: Default Port VLAN ID & Priority */
1091 int mv88e6xxx_port_get_pvid(struct mv88e6xxx_chip
*chip
, int port
, u16
*pvid
)
1096 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_DEFAULT_VLAN
,
1101 *pvid
= reg
& MV88E6XXX_PORT_DEFAULT_VLAN_MASK
;
1106 int mv88e6xxx_port_set_pvid(struct mv88e6xxx_chip
*chip
, int port
, u16 pvid
)
1111 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_DEFAULT_VLAN
,
1116 reg
&= ~MV88E6XXX_PORT_DEFAULT_VLAN_MASK
;
1117 reg
|= pvid
& MV88E6XXX_PORT_DEFAULT_VLAN_MASK
;
1119 err
= mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_DEFAULT_VLAN
,
1124 dev_dbg(chip
->dev
, "p%d: DefaultVID set to %u\n", port
, pvid
);
1129 /* Offset 0x08: Port Control 2 Register */
1131 static const char * const mv88e6xxx_port_8021q_mode_names
[] = {
1132 [MV88E6XXX_PORT_CTL2_8021Q_MODE_DISABLED
] = "Disabled",
1133 [MV88E6XXX_PORT_CTL2_8021Q_MODE_FALLBACK
] = "Fallback",
1134 [MV88E6XXX_PORT_CTL2_8021Q_MODE_CHECK
] = "Check",
1135 [MV88E6XXX_PORT_CTL2_8021Q_MODE_SECURE
] = "Secure",
1138 static int mv88e6185_port_set_default_forward(struct mv88e6xxx_chip
*chip
,
1139 int port
, bool multicast
)
1144 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL2
, ®
);
1149 reg
|= MV88E6XXX_PORT_CTL2_DEFAULT_FORWARD
;
1151 reg
&= ~MV88E6XXX_PORT_CTL2_DEFAULT_FORWARD
;
1153 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_CTL2
, reg
);
1156 int mv88e6185_port_set_egress_floods(struct mv88e6xxx_chip
*chip
, int port
,
1157 bool unicast
, bool multicast
)
1161 err
= mv88e6185_port_set_forward_unknown(chip
, port
, unicast
);
1165 return mv88e6185_port_set_default_forward(chip
, port
, multicast
);
1168 int mv88e6095_port_set_upstream_port(struct mv88e6xxx_chip
*chip
, int port
,
1174 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL2
, ®
);
1178 reg
&= ~MV88E6095_PORT_CTL2_CPU_PORT_MASK
;
1179 reg
|= upstream_port
;
1181 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_CTL2
, reg
);
1184 int mv88e6xxx_port_set_mirror(struct mv88e6xxx_chip
*chip
, int port
,
1185 enum mv88e6xxx_egress_direction direction
,
1193 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL2
, ®
);
1197 switch (direction
) {
1198 case MV88E6XXX_EGRESS_DIR_INGRESS
:
1199 bit
= MV88E6XXX_PORT_CTL2_INGRESS_MONITOR
;
1200 mirror_port
= &chip
->ports
[port
].mirror_ingress
;
1202 case MV88E6XXX_EGRESS_DIR_EGRESS
:
1203 bit
= MV88E6XXX_PORT_CTL2_EGRESS_MONITOR
;
1204 mirror_port
= &chip
->ports
[port
].mirror_egress
;
1214 err
= mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_CTL2
, reg
);
1216 *mirror_port
= mirror
;
1221 int mv88e6xxx_port_set_8021q_mode(struct mv88e6xxx_chip
*chip
, int port
,
1227 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL2
, ®
);
1231 reg
&= ~MV88E6XXX_PORT_CTL2_8021Q_MODE_MASK
;
1232 reg
|= mode
& MV88E6XXX_PORT_CTL2_8021Q_MODE_MASK
;
1234 err
= mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_CTL2
, reg
);
1238 dev_dbg(chip
->dev
, "p%d: 802.1QMode set to %s\n", port
,
1239 mv88e6xxx_port_8021q_mode_names
[mode
]);
1244 int mv88e6xxx_port_set_map_da(struct mv88e6xxx_chip
*chip
, int port
)
1249 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL2
, ®
);
1253 reg
|= MV88E6XXX_PORT_CTL2_MAP_DA
;
1255 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_CTL2
, reg
);
1258 int mv88e6165_port_set_jumbo_size(struct mv88e6xxx_chip
*chip
, int port
,
1264 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL2
, ®
);
1268 reg
&= ~MV88E6XXX_PORT_CTL2_JUMBO_MODE_MASK
;
1271 reg
|= MV88E6XXX_PORT_CTL2_JUMBO_MODE_1522
;
1272 else if (size
<= 2048)
1273 reg
|= MV88E6XXX_PORT_CTL2_JUMBO_MODE_2048
;
1274 else if (size
<= 10240)
1275 reg
|= MV88E6XXX_PORT_CTL2_JUMBO_MODE_10240
;
1279 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_CTL2
, reg
);
1282 /* Offset 0x09: Port Rate Control */
1284 int mv88e6095_port_egress_rate_limiting(struct mv88e6xxx_chip
*chip
, int port
)
1286 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_EGRESS_RATE_CTL1
,
1290 int mv88e6097_port_egress_rate_limiting(struct mv88e6xxx_chip
*chip
, int port
)
1292 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_EGRESS_RATE_CTL1
,
1296 /* Offset 0x0C: Port ATU Control */
1298 int mv88e6xxx_port_disable_learn_limit(struct mv88e6xxx_chip
*chip
, int port
)
1300 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_ATU_CTL
, 0);
1303 /* Offset 0x0D: (Priority) Override Register */
1305 int mv88e6xxx_port_disable_pri_override(struct mv88e6xxx_chip
*chip
, int port
)
1307 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_PRI_OVERRIDE
, 0);
1310 /* Offset 0x0f: Port Ether type */
1312 int mv88e6351_port_set_ether_type(struct mv88e6xxx_chip
*chip
, int port
,
1315 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_ETH_TYPE
, etype
);
1318 /* Offset 0x18: Port IEEE Priority Remapping Registers [0-3]
1319 * Offset 0x19: Port IEEE Priority Remapping Registers [4-7]
1322 int mv88e6095_port_tag_remap(struct mv88e6xxx_chip
*chip
, int port
)
1326 /* Use a direct priority mapping for all IEEE tagged frames */
1327 err
= mv88e6xxx_port_write(chip
, port
,
1328 MV88E6095_PORT_IEEE_PRIO_REMAP_0123
,
1333 return mv88e6xxx_port_write(chip
, port
,
1334 MV88E6095_PORT_IEEE_PRIO_REMAP_4567
,
1338 static int mv88e6xxx_port_ieeepmt_write(struct mv88e6xxx_chip
*chip
,
1339 int port
, u16 table
, u8 ptr
, u16 data
)
1343 reg
= MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_UPDATE
| table
|
1344 (ptr
<< __bf_shf(MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_PTR_MASK
)) |
1345 (data
& MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_DATA_MASK
);
1347 return mv88e6xxx_port_write(chip
, port
,
1348 MV88E6390_PORT_IEEE_PRIO_MAP_TABLE
, reg
);
1351 int mv88e6390_port_tag_remap(struct mv88e6xxx_chip
*chip
, int port
)
1356 for (i
= 0; i
<= 7; i
++) {
1357 table
= MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_INGRESS_PCP
;
1358 err
= mv88e6xxx_port_ieeepmt_write(chip
, port
, table
, i
,
1363 table
= MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_GREEN_PCP
;
1364 err
= mv88e6xxx_port_ieeepmt_write(chip
, port
, table
, i
, i
);
1368 table
= MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_YELLOW_PCP
;
1369 err
= mv88e6xxx_port_ieeepmt_write(chip
, port
, table
, i
, i
);
1373 table
= MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_AVB_PCP
;
1374 err
= mv88e6xxx_port_ieeepmt_write(chip
, port
, table
, i
, i
);
1382 /* Offset 0x0E: Policy Control Register */
1384 int mv88e6352_port_set_policy(struct mv88e6xxx_chip
*chip
, int port
,
1385 enum mv88e6xxx_policy_mapping mapping
,
1386 enum mv88e6xxx_policy_action action
)
1393 case MV88E6XXX_POLICY_MAPPING_DA
:
1394 shift
= __bf_shf(MV88E6XXX_PORT_POLICY_CTL_DA_MASK
);
1395 mask
= MV88E6XXX_PORT_POLICY_CTL_DA_MASK
;
1397 case MV88E6XXX_POLICY_MAPPING_SA
:
1398 shift
= __bf_shf(MV88E6XXX_PORT_POLICY_CTL_SA_MASK
);
1399 mask
= MV88E6XXX_PORT_POLICY_CTL_SA_MASK
;
1401 case MV88E6XXX_POLICY_MAPPING_VTU
:
1402 shift
= __bf_shf(MV88E6XXX_PORT_POLICY_CTL_VTU_MASK
);
1403 mask
= MV88E6XXX_PORT_POLICY_CTL_VTU_MASK
;
1405 case MV88E6XXX_POLICY_MAPPING_ETYPE
:
1406 shift
= __bf_shf(MV88E6XXX_PORT_POLICY_CTL_ETYPE_MASK
);
1407 mask
= MV88E6XXX_PORT_POLICY_CTL_ETYPE_MASK
;
1409 case MV88E6XXX_POLICY_MAPPING_PPPOE
:
1410 shift
= __bf_shf(MV88E6XXX_PORT_POLICY_CTL_PPPOE_MASK
);
1411 mask
= MV88E6XXX_PORT_POLICY_CTL_PPPOE_MASK
;
1413 case MV88E6XXX_POLICY_MAPPING_VBAS
:
1414 shift
= __bf_shf(MV88E6XXX_PORT_POLICY_CTL_VBAS_MASK
);
1415 mask
= MV88E6XXX_PORT_POLICY_CTL_VBAS_MASK
;
1417 case MV88E6XXX_POLICY_MAPPING_OPT82
:
1418 shift
= __bf_shf(MV88E6XXX_PORT_POLICY_CTL_OPT82_MASK
);
1419 mask
= MV88E6XXX_PORT_POLICY_CTL_OPT82_MASK
;
1421 case MV88E6XXX_POLICY_MAPPING_UDP
:
1422 shift
= __bf_shf(MV88E6XXX_PORT_POLICY_CTL_UDP_MASK
);
1423 mask
= MV88E6XXX_PORT_POLICY_CTL_UDP_MASK
;
1430 case MV88E6XXX_POLICY_ACTION_NORMAL
:
1431 val
= MV88E6XXX_PORT_POLICY_CTL_NORMAL
;
1433 case MV88E6XXX_POLICY_ACTION_MIRROR
:
1434 val
= MV88E6XXX_PORT_POLICY_CTL_MIRROR
;
1436 case MV88E6XXX_POLICY_ACTION_TRAP
:
1437 val
= MV88E6XXX_PORT_POLICY_CTL_TRAP
;
1439 case MV88E6XXX_POLICY_ACTION_DISCARD
:
1440 val
= MV88E6XXX_PORT_POLICY_CTL_DISCARD
;
1446 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_POLICY_CTL
, ®
);
1451 reg
|= (val
<< shift
) & mask
;
1453 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_POLICY_CTL
, reg
);