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, 200, 1000, 2500 Mbps (e.g. 88E6341) */
294 int mv88e6341_port_set_speed(struct mv88e6xxx_chip
*chip
, int port
, int speed
)
296 if (speed
== SPEED_MAX
)
297 speed
= port
< 5 ? 1000 : 2500;
302 if (speed
== 200 && port
!= 0)
305 if (speed
== 2500 && port
< 5)
308 return mv88e6xxx_port_set_speed(chip
, port
, speed
, !port
, true);
311 phy_interface_t
mv88e6341_port_max_speed_mode(int port
)
314 return PHY_INTERFACE_MODE_2500BASEX
;
316 return PHY_INTERFACE_MODE_NA
;
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
)
322 if (speed
== SPEED_MAX
)
328 if (speed
== 200 && port
< 5)
331 return mv88e6xxx_port_set_speed(chip
, port
, speed
, true, false);
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
)
337 if (speed
== SPEED_MAX
)
338 speed
= port
< 9 ? 1000 : 2500;
343 if (speed
== 200 && port
!= 0)
346 if (speed
== 2500 && port
< 9)
349 return mv88e6xxx_port_set_speed(chip
, port
, speed
, true, true);
352 phy_interface_t
mv88e6390_port_max_speed_mode(int port
)
354 if (port
== 9 || port
== 10)
355 return PHY_INTERFACE_MODE_2500BASEX
;
357 return PHY_INTERFACE_MODE_NA
;
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
)
363 if (speed
== SPEED_MAX
)
364 speed
= port
< 9 ? 1000 : 10000;
366 if (speed
== 200 && port
!= 0)
369 if (speed
>= 2500 && port
< 9)
372 return mv88e6xxx_port_set_speed(chip
, port
, speed
, true, true);
375 phy_interface_t
mv88e6390x_port_max_speed_mode(int port
)
377 if (port
== 9 || port
== 10)
378 return PHY_INTERFACE_MODE_XAUI
;
380 return PHY_INTERFACE_MODE_NA
;
383 int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip
*chip
, int port
,
384 phy_interface_t mode
)
391 if (port
!= 9 && port
!= 10)
394 /* Default to a slow mode, so freeing up SERDES interfaces for
395 * other ports which might use them for SFPs.
397 if (mode
== PHY_INTERFACE_MODE_NA
)
398 mode
= PHY_INTERFACE_MODE_1000BASEX
;
401 case PHY_INTERFACE_MODE_1000BASEX
:
402 cmode
= MV88E6XXX_PORT_STS_CMODE_1000BASE_X
;
404 case PHY_INTERFACE_MODE_SGMII
:
405 cmode
= MV88E6XXX_PORT_STS_CMODE_SGMII
;
407 case PHY_INTERFACE_MODE_2500BASEX
:
408 cmode
= MV88E6XXX_PORT_STS_CMODE_2500BASEX
;
410 case PHY_INTERFACE_MODE_XGMII
:
411 case PHY_INTERFACE_MODE_XAUI
:
412 cmode
= MV88E6XXX_PORT_STS_CMODE_XAUI
;
414 case PHY_INTERFACE_MODE_RXAUI
:
415 cmode
= MV88E6XXX_PORT_STS_CMODE_RXAUI
;
421 /* cmode doesn't change, nothing to do for us */
422 if (cmode
== chip
->ports
[port
].cmode
)
425 lane
= mv88e6390x_serdes_get_lane(chip
, port
);
426 if (lane
< 0 && lane
!= -ENODEV
)
430 if (chip
->ports
[port
].serdes_irq
) {
431 err
= mv88e6390_serdes_irq_disable(chip
, port
, lane
);
436 err
= mv88e6390x_serdes_power(chip
, port
, false);
441 chip
->ports
[port
].cmode
= 0;
444 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_STS
, ®
);
448 reg
&= ~MV88E6XXX_PORT_STS_CMODE_MASK
;
451 err
= mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_STS
, reg
);
455 chip
->ports
[port
].cmode
= cmode
;
457 lane
= mv88e6390x_serdes_get_lane(chip
, port
);
461 err
= mv88e6390x_serdes_power(chip
, port
, true);
465 if (chip
->ports
[port
].serdes_irq
) {
466 err
= mv88e6390_serdes_irq_enable(chip
, port
, lane
);
475 int mv88e6390_port_set_cmode(struct mv88e6xxx_chip
*chip
, int port
,
476 phy_interface_t mode
)
479 case PHY_INTERFACE_MODE_NA
:
481 case PHY_INTERFACE_MODE_XGMII
:
482 case PHY_INTERFACE_MODE_XAUI
:
483 case PHY_INTERFACE_MODE_RXAUI
:
489 return mv88e6390x_port_set_cmode(chip
, port
, mode
);
492 int mv88e6185_port_get_cmode(struct mv88e6xxx_chip
*chip
, int port
, u8
*cmode
)
497 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_STS
, ®
);
501 *cmode
= reg
& MV88E6185_PORT_STS_CMODE_MASK
;
506 int mv88e6352_port_get_cmode(struct mv88e6xxx_chip
*chip
, int port
, u8
*cmode
)
511 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_STS
, ®
);
515 *cmode
= reg
& MV88E6XXX_PORT_STS_CMODE_MASK
;
520 int mv88e6352_port_link_state(struct mv88e6xxx_chip
*chip
, int port
,
521 struct phylink_link_state
*state
)
526 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_STS
, ®
);
530 switch (reg
& MV88E6XXX_PORT_STS_SPEED_MASK
) {
531 case MV88E6XXX_PORT_STS_SPEED_10
:
532 state
->speed
= SPEED_10
;
534 case MV88E6XXX_PORT_STS_SPEED_100
:
535 state
->speed
= SPEED_100
;
537 case MV88E6XXX_PORT_STS_SPEED_1000
:
538 state
->speed
= SPEED_1000
;
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
;
545 state
->speed
= SPEED_10000
;
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
;
558 int mv88e6185_port_link_state(struct mv88e6xxx_chip
*chip
, int port
,
559 struct phylink_link_state
*state
)
561 if (state
->interface
== PHY_INTERFACE_MODE_1000BASEX
) {
562 u8 cmode
= chip
->ports
[port
].cmode
;
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.)
569 if (cmode
== MV88E6185_PORT_STS_CMODE_SERDES
) {
573 err
= mv88e6xxx_port_read(chip
, port
,
574 MV88E6XXX_PORT_MAC_CTL
, &mac
);
578 state
->link
= !!(mac
& MV88E6185_PORT_MAC_CTL_SYNC_OK
);
579 state
->an_enabled
= 1;
581 !!(mac
& MV88E6185_PORT_MAC_CTL_AN_DONE
);
583 state
->link
? DUPLEX_FULL
: DUPLEX_UNKNOWN
;
585 state
->link
? SPEED_1000
: SPEED_UNKNOWN
;
591 return mv88e6352_port_link_state(chip
, port
, state
);
594 /* Offset 0x02: Jamming Control
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
600 int mv88e6097_port_pause_limit(struct mv88e6xxx_chip
*chip
, int port
, u8 in
,
603 return mv88e6xxx_port_write(chip
, port
, MV88E6097_PORT_JAM_CTL
,
607 int mv88e6390_port_pause_limit(struct mv88e6xxx_chip
*chip
, int port
, u8 in
,
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
);
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
);
623 /* Offset 0x04: Port Control Register */
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",
632 int mv88e6xxx_port_set_state(struct mv88e6xxx_chip
*chip
, int port
, u8 state
)
637 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL0
, ®
);
641 reg
&= ~MV88E6XXX_PORT_CTL0_STATE_MASK
;
644 case BR_STATE_DISABLED
:
645 state
= MV88E6XXX_PORT_CTL0_STATE_DISABLED
;
647 case BR_STATE_BLOCKING
:
648 case BR_STATE_LISTENING
:
649 state
= MV88E6XXX_PORT_CTL0_STATE_BLOCKING
;
651 case BR_STATE_LEARNING
:
652 state
= MV88E6XXX_PORT_CTL0_STATE_LEARNING
;
654 case BR_STATE_FORWARDING
:
655 state
= MV88E6XXX_PORT_CTL0_STATE_FORWARDING
;
663 err
= mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_CTL0
, reg
);
667 dev_dbg(chip
->dev
, "p%d: PortState set to %s\n", port
,
668 mv88e6xxx_port_state_names
[state
]);
673 int mv88e6xxx_port_set_egress_mode(struct mv88e6xxx_chip
*chip
, int port
,
674 enum mv88e6xxx_egress_mode mode
)
679 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL0
, ®
);
683 reg
&= ~MV88E6XXX_PORT_CTL0_EGRESS_MODE_MASK
;
686 case MV88E6XXX_EGRESS_MODE_UNMODIFIED
:
687 reg
|= MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNMODIFIED
;
689 case MV88E6XXX_EGRESS_MODE_UNTAGGED
:
690 reg
|= MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNTAGGED
;
692 case MV88E6XXX_EGRESS_MODE_TAGGED
:
693 reg
|= MV88E6XXX_PORT_CTL0_EGRESS_MODE_TAGGED
;
695 case MV88E6XXX_EGRESS_MODE_ETHERTYPE
:
696 reg
|= MV88E6XXX_PORT_CTL0_EGRESS_MODE_ETHER_TYPE_DSA
;
702 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_CTL0
, reg
);
705 int mv88e6085_port_set_frame_mode(struct mv88e6xxx_chip
*chip
, int port
,
706 enum mv88e6xxx_frame_mode mode
)
711 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL0
, ®
);
715 reg
&= ~MV88E6XXX_PORT_CTL0_FRAME_MODE_MASK
;
718 case MV88E6XXX_FRAME_MODE_NORMAL
:
719 reg
|= MV88E6XXX_PORT_CTL0_FRAME_MODE_NORMAL
;
721 case MV88E6XXX_FRAME_MODE_DSA
:
722 reg
|= MV88E6XXX_PORT_CTL0_FRAME_MODE_DSA
;
728 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_CTL0
, reg
);
731 int mv88e6351_port_set_frame_mode(struct mv88e6xxx_chip
*chip
, int port
,
732 enum mv88e6xxx_frame_mode mode
)
737 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL0
, ®
);
741 reg
&= ~MV88E6XXX_PORT_CTL0_FRAME_MODE_MASK
;
744 case MV88E6XXX_FRAME_MODE_NORMAL
:
745 reg
|= MV88E6XXX_PORT_CTL0_FRAME_MODE_NORMAL
;
747 case MV88E6XXX_FRAME_MODE_DSA
:
748 reg
|= MV88E6XXX_PORT_CTL0_FRAME_MODE_DSA
;
750 case MV88E6XXX_FRAME_MODE_PROVIDER
:
751 reg
|= MV88E6XXX_PORT_CTL0_FRAME_MODE_PROVIDER
;
753 case MV88E6XXX_FRAME_MODE_ETHERTYPE
:
754 reg
|= MV88E6XXX_PORT_CTL0_FRAME_MODE_ETHER_TYPE_DSA
;
760 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_CTL0
, reg
);
763 static int mv88e6185_port_set_forward_unknown(struct mv88e6xxx_chip
*chip
,
764 int port
, bool unicast
)
769 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL0
, ®
);
774 reg
|= MV88E6185_PORT_CTL0_FORWARD_UNKNOWN
;
776 reg
&= ~MV88E6185_PORT_CTL0_FORWARD_UNKNOWN
;
778 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_CTL0
, reg
);
781 int mv88e6352_port_set_egress_floods(struct mv88e6xxx_chip
*chip
, int port
,
782 bool unicast
, bool multicast
)
787 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL0
, ®
);
791 reg
&= ~MV88E6352_PORT_CTL0_EGRESS_FLOODS_MASK
;
793 if (unicast
&& multicast
)
794 reg
|= MV88E6352_PORT_CTL0_EGRESS_FLOODS_ALL_UNKNOWN_DA
;
796 reg
|= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_MC_DA
;
798 reg
|= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_UC_DA
;
800 reg
|= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_DA
;
802 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_CTL0
, reg
);
805 /* Offset 0x05: Port Control 1 */
807 int mv88e6xxx_port_set_message_port(struct mv88e6xxx_chip
*chip
, int port
,
813 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL1
, &val
);
818 val
|= MV88E6XXX_PORT_CTL1_MESSAGE_PORT
;
820 val
&= ~MV88E6XXX_PORT_CTL1_MESSAGE_PORT
;
822 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_CTL1
, val
);
825 /* Offset 0x06: Port Based VLAN Map */
827 int mv88e6xxx_port_set_vlan_map(struct mv88e6xxx_chip
*chip
, int port
, u16 map
)
829 const u16 mask
= mv88e6xxx_port_mask(chip
);
833 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_BASE_VLAN
, ®
);
840 err
= mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_BASE_VLAN
, reg
);
844 dev_dbg(chip
->dev
, "p%d: VLANTable set to %.3x\n", port
, map
);
849 int mv88e6xxx_port_get_fid(struct mv88e6xxx_chip
*chip
, int port
, u16
*fid
)
851 const u16 upper_mask
= (mv88e6xxx_num_databases(chip
) - 1) >> 4;
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
, ®
);
860 *fid
= (reg
& 0xf000) >> 12;
862 /* Port's default FID upper bits are located in reg 0x05, offset 0 */
864 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL1
,
869 *fid
|= (reg
& upper_mask
) << 4;
875 int mv88e6xxx_port_set_fid(struct mv88e6xxx_chip
*chip
, int port
, u16 fid
)
877 const u16 upper_mask
= (mv88e6xxx_num_databases(chip
) - 1) >> 4;
881 if (fid
>= mv88e6xxx_num_databases(chip
))
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
, ®
);
890 reg
|= (fid
& 0x000f) << 12;
892 err
= mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_BASE_VLAN
, reg
);
896 /* Port's default FID upper bits are located in reg 0x05, offset 0 */
898 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL1
,
904 reg
|= (fid
>> 4) & upper_mask
;
906 err
= mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_CTL1
,
912 dev_dbg(chip
->dev
, "p%d: FID set to %u\n", port
, fid
);
917 /* Offset 0x07: Default Port VLAN ID & Priority */
919 int mv88e6xxx_port_get_pvid(struct mv88e6xxx_chip
*chip
, int port
, u16
*pvid
)
924 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_DEFAULT_VLAN
,
929 *pvid
= reg
& MV88E6XXX_PORT_DEFAULT_VLAN_MASK
;
934 int mv88e6xxx_port_set_pvid(struct mv88e6xxx_chip
*chip
, int port
, u16 pvid
)
939 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_DEFAULT_VLAN
,
944 reg
&= ~MV88E6XXX_PORT_DEFAULT_VLAN_MASK
;
945 reg
|= pvid
& MV88E6XXX_PORT_DEFAULT_VLAN_MASK
;
947 err
= mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_DEFAULT_VLAN
,
952 dev_dbg(chip
->dev
, "p%d: DefaultVID set to %u\n", port
, pvid
);
957 /* Offset 0x08: Port Control 2 Register */
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",
966 static int mv88e6185_port_set_default_forward(struct mv88e6xxx_chip
*chip
,
967 int port
, bool multicast
)
972 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL2
, ®
);
977 reg
|= MV88E6XXX_PORT_CTL2_DEFAULT_FORWARD
;
979 reg
&= ~MV88E6XXX_PORT_CTL2_DEFAULT_FORWARD
;
981 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_CTL2
, reg
);
984 int mv88e6185_port_set_egress_floods(struct mv88e6xxx_chip
*chip
, int port
,
985 bool unicast
, bool multicast
)
989 err
= mv88e6185_port_set_forward_unknown(chip
, port
, unicast
);
993 return mv88e6185_port_set_default_forward(chip
, port
, multicast
);
996 int mv88e6095_port_set_upstream_port(struct mv88e6xxx_chip
*chip
, int port
,
1002 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL2
, ®
);
1006 reg
&= ~MV88E6095_PORT_CTL2_CPU_PORT_MASK
;
1007 reg
|= upstream_port
;
1009 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_CTL2
, reg
);
1012 int mv88e6xxx_port_set_8021q_mode(struct mv88e6xxx_chip
*chip
, int port
,
1018 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL2
, ®
);
1022 reg
&= ~MV88E6XXX_PORT_CTL2_8021Q_MODE_MASK
;
1023 reg
|= mode
& MV88E6XXX_PORT_CTL2_8021Q_MODE_MASK
;
1025 err
= mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_CTL2
, reg
);
1029 dev_dbg(chip
->dev
, "p%d: 802.1QMode set to %s\n", port
,
1030 mv88e6xxx_port_8021q_mode_names
[mode
]);
1035 int mv88e6xxx_port_set_map_da(struct mv88e6xxx_chip
*chip
, int port
)
1040 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL2
, ®
);
1044 reg
|= MV88E6XXX_PORT_CTL2_MAP_DA
;
1046 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_CTL2
, reg
);
1049 int mv88e6165_port_set_jumbo_size(struct mv88e6xxx_chip
*chip
, int port
,
1055 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL2
, ®
);
1059 reg
&= ~MV88E6XXX_PORT_CTL2_JUMBO_MODE_MASK
;
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
;
1070 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_CTL2
, reg
);
1073 /* Offset 0x09: Port Rate Control */
1075 int mv88e6095_port_egress_rate_limiting(struct mv88e6xxx_chip
*chip
, int port
)
1077 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_EGRESS_RATE_CTL1
,
1081 int mv88e6097_port_egress_rate_limiting(struct mv88e6xxx_chip
*chip
, int port
)
1083 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_EGRESS_RATE_CTL1
,
1087 /* Offset 0x0C: Port ATU Control */
1089 int mv88e6xxx_port_disable_learn_limit(struct mv88e6xxx_chip
*chip
, int port
)
1091 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_ATU_CTL
, 0);
1094 /* Offset 0x0D: (Priority) Override Register */
1096 int mv88e6xxx_port_disable_pri_override(struct mv88e6xxx_chip
*chip
, int port
)
1098 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_PRI_OVERRIDE
, 0);
1101 /* Offset 0x0f: Port Ether type */
1103 int mv88e6351_port_set_ether_type(struct mv88e6xxx_chip
*chip
, int port
,
1106 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_ETH_TYPE
, etype
);
1109 /* Offset 0x18: Port IEEE Priority Remapping Registers [0-3]
1110 * Offset 0x19: Port IEEE Priority Remapping Registers [4-7]
1113 int mv88e6095_port_tag_remap(struct mv88e6xxx_chip
*chip
, int port
)
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
,
1124 return mv88e6xxx_port_write(chip
, port
,
1125 MV88E6095_PORT_IEEE_PRIO_REMAP_4567
,
1129 static int mv88e6xxx_port_ieeepmt_write(struct mv88e6xxx_chip
*chip
,
1130 int port
, u16 table
, u8 ptr
, u16 data
)
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
);
1138 return mv88e6xxx_port_write(chip
, port
,
1139 MV88E6390_PORT_IEEE_PRIO_MAP_TABLE
, reg
);
1142 int mv88e6390_port_tag_remap(struct mv88e6xxx_chip
*chip
, int port
)
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
,
1154 table
= MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_GREEN_PCP
;
1155 err
= mv88e6xxx_port_ieeepmt_write(chip
, port
, table
, i
, i
);
1159 table
= MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_YELLOW_PCP
;
1160 err
= mv88e6xxx_port_ieeepmt_write(chip
, port
, table
, i
, i
);
1164 table
= MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_AVB_PCP
;
1165 err
= mv88e6xxx_port_ieeepmt_write(chip
, port
, table
, i
, i
);