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>
15 #include <linux/property.h>
22 int mv88e6xxx_port_read(struct mv88e6xxx_chip
*chip
, int port
, int reg
,
25 int addr
= chip
->info
->port_base_addr
+ port
;
27 return mv88e6xxx_read(chip
, addr
, reg
, val
);
30 int mv88e6xxx_port_wait_bit(struct mv88e6xxx_chip
*chip
, int port
, int reg
,
33 int addr
= chip
->info
->port_base_addr
+ port
;
35 return mv88e6xxx_wait_bit(chip
, addr
, reg
, bit
, val
);
38 int mv88e6xxx_port_write(struct mv88e6xxx_chip
*chip
, int port
, int reg
,
41 int addr
= chip
->info
->port_base_addr
+ port
;
43 return mv88e6xxx_write(chip
, addr
, reg
, val
);
46 /* Offset 0x00: MAC (or PCS or Physical) Status Register
48 * For most devices, this is read only. However the 6185 has the MyPause
51 int mv88e6185_port_set_pause(struct mv88e6xxx_chip
*chip
, int port
,
57 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_STS
, ®
);
62 reg
|= MV88E6XXX_PORT_STS_MY_PAUSE
;
64 reg
&= ~MV88E6XXX_PORT_STS_MY_PAUSE
;
66 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_STS
, reg
);
69 /* Offset 0x01: MAC (or PCS or Physical) Control Register
71 * Link, Duplex and Flow Control have one force bit, one value bit.
73 * For port's MAC speed, ForceSpd (or SpdValue) bits 1:0 program the value.
74 * Alternative values require the 200BASE (or AltSpeed) bit 12 set.
75 * Newer chips need a ForcedSpd bit 13 set to consider the value.
78 static int mv88e6xxx_port_set_rgmii_delay(struct mv88e6xxx_chip
*chip
, int port
,
84 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_MAC_CTL
, ®
);
88 reg
&= ~(MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK
|
89 MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK
);
92 case PHY_INTERFACE_MODE_RGMII_RXID
:
93 reg
|= MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK
;
95 case PHY_INTERFACE_MODE_RGMII_TXID
:
96 reg
|= MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK
;
98 case PHY_INTERFACE_MODE_RGMII_ID
:
99 reg
|= MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK
|
100 MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK
;
102 case PHY_INTERFACE_MODE_RGMII
:
108 err
= mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_MAC_CTL
, reg
);
112 dev_dbg(chip
->dev
, "p%d: delay RXCLK %s, TXCLK %s\n", port
,
113 reg
& MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK
? "yes" : "no",
114 reg
& MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK
? "yes" : "no");
119 int mv88e6352_port_set_rgmii_delay(struct mv88e6xxx_chip
*chip
, int port
,
120 phy_interface_t mode
)
125 return mv88e6xxx_port_set_rgmii_delay(chip
, port
, mode
);
128 int mv88e6390_port_set_rgmii_delay(struct mv88e6xxx_chip
*chip
, int port
,
129 phy_interface_t mode
)
134 return mv88e6xxx_port_set_rgmii_delay(chip
, port
, mode
);
137 int mv88e6320_port_set_rgmii_delay(struct mv88e6xxx_chip
*chip
, int port
,
138 phy_interface_t mode
)
140 if (port
!= 2 && port
!= 5 && port
!= 6)
143 return mv88e6xxx_port_set_rgmii_delay(chip
, port
, mode
);
146 int mv88e6xxx_port_set_link(struct mv88e6xxx_chip
*chip
, int port
, int link
)
151 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_MAC_CTL
, ®
);
155 reg
&= ~(MV88E6XXX_PORT_MAC_CTL_FORCE_LINK
|
156 MV88E6XXX_PORT_MAC_CTL_LINK_UP
);
159 case LINK_FORCED_DOWN
:
160 reg
|= MV88E6XXX_PORT_MAC_CTL_FORCE_LINK
;
163 reg
|= MV88E6XXX_PORT_MAC_CTL_FORCE_LINK
|
164 MV88E6XXX_PORT_MAC_CTL_LINK_UP
;
167 /* normal link detection */
173 err
= mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_MAC_CTL
, reg
);
177 dev_dbg(chip
->dev
, "p%d: %s link %s\n", port
,
178 reg
& MV88E6XXX_PORT_MAC_CTL_FORCE_LINK
? "Force" : "Unforce",
179 reg
& MV88E6XXX_PORT_MAC_CTL_LINK_UP
? "up" : "down");
184 int mv88e6xxx_port_sync_link(struct mv88e6xxx_chip
*chip
, int port
, unsigned int mode
, bool isup
)
186 const struct mv88e6xxx_ops
*ops
= chip
->info
->ops
;
191 link
= LINK_FORCED_UP
;
193 link
= LINK_FORCED_DOWN
;
195 if (ops
->port_set_link
)
196 err
= ops
->port_set_link(chip
, port
, link
);
201 int mv88e6185_port_sync_link(struct mv88e6xxx_chip
*chip
, int port
, unsigned int mode
, bool isup
)
203 const struct mv88e6xxx_ops
*ops
= chip
->info
->ops
;
207 if (mode
== MLO_AN_INBAND
)
208 link
= LINK_UNFORCED
;
210 link
= LINK_FORCED_UP
;
212 link
= LINK_FORCED_DOWN
;
214 if (ops
->port_set_link
)
215 err
= ops
->port_set_link(chip
, port
, link
);
220 static int mv88e6xxx_port_set_speed_duplex(struct mv88e6xxx_chip
*chip
,
221 int port
, int speed
, bool alt_bit
,
222 bool force_bit
, int duplex
)
229 ctrl
= MV88E6XXX_PORT_MAC_CTL_SPEED_10
;
232 ctrl
= MV88E6XXX_PORT_MAC_CTL_SPEED_100
;
236 ctrl
= MV88E6XXX_PORT_MAC_CTL_SPEED_100
|
237 MV88E6390_PORT_MAC_CTL_ALTSPEED
;
239 ctrl
= MV88E6065_PORT_MAC_CTL_SPEED_200
;
242 ctrl
= MV88E6XXX_PORT_MAC_CTL_SPEED_1000
;
246 ctrl
= MV88E6390_PORT_MAC_CTL_SPEED_10000
|
247 MV88E6390_PORT_MAC_CTL_ALTSPEED
;
249 ctrl
= MV88E6390_PORT_MAC_CTL_SPEED_10000
;
252 /* all bits set, fall through... */
254 ctrl
= MV88E6XXX_PORT_MAC_CTL_SPEED_UNFORCED
;
262 ctrl
|= MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX
;
265 ctrl
|= MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX
|
266 MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL
;
268 case DUPLEX_UNFORCED
:
269 /* normal duplex detection */
275 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_MAC_CTL
, ®
);
279 reg
&= ~(MV88E6XXX_PORT_MAC_CTL_SPEED_MASK
|
280 MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX
|
281 MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL
);
284 reg
&= ~MV88E6390_PORT_MAC_CTL_ALTSPEED
;
286 reg
&= ~MV88E6390_PORT_MAC_CTL_FORCE_SPEED
;
287 if (speed
!= SPEED_UNFORCED
)
288 ctrl
|= MV88E6390_PORT_MAC_CTL_FORCE_SPEED
;
292 err
= mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_MAC_CTL
, reg
);
296 if (speed
!= SPEED_UNFORCED
)
297 dev_dbg(chip
->dev
, "p%d: Speed set to %d Mbps\n", port
, speed
);
299 dev_dbg(chip
->dev
, "p%d: Speed unforced\n", port
);
300 dev_dbg(chip
->dev
, "p%d: %s %s duplex\n", port
,
301 reg
& MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX
? "Force" : "Unforce",
302 reg
& MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL
? "full" : "half");
307 /* Support 10, 100, 1000 Mbps (e.g. 88E6185 family) */
308 int mv88e6185_port_set_speed_duplex(struct mv88e6xxx_chip
*chip
, int port
,
309 int speed
, int duplex
)
311 if (speed
== 200 || speed
> 1000)
314 return mv88e6xxx_port_set_speed_duplex(chip
, port
, speed
, false, false,
318 /* Support 10, 100 Mbps (e.g. 88E6250 family) */
319 int mv88e6250_port_set_speed_duplex(struct mv88e6xxx_chip
*chip
, int port
,
320 int speed
, int duplex
)
325 return mv88e6xxx_port_set_speed_duplex(chip
, port
, speed
, false, false,
329 /* Support 10, 100, 200, 1000, 2500 Mbps (e.g. 88E6341) */
330 int mv88e6341_port_set_speed_duplex(struct mv88e6xxx_chip
*chip
, int port
,
331 int speed
, int duplex
)
336 if (speed
== 200 && port
!= 0)
339 if (speed
== 2500 && port
< 5)
342 return mv88e6xxx_port_set_speed_duplex(chip
, port
, speed
, !port
, true,
346 phy_interface_t
mv88e6341_port_max_speed_mode(struct mv88e6xxx_chip
*chip
,
350 return PHY_INTERFACE_MODE_2500BASEX
;
352 return PHY_INTERFACE_MODE_NA
;
355 /* Support 10, 100, 200, 1000 Mbps (e.g. 88E6352 family) */
356 int mv88e6352_port_set_speed_duplex(struct mv88e6xxx_chip
*chip
, int port
,
357 int speed
, int duplex
)
362 if (speed
== 200 && port
< 5)
365 return mv88e6xxx_port_set_speed_duplex(chip
, port
, speed
, true, false,
369 /* Support 10, 100, 200, 1000, 2500 Mbps (e.g. 88E6390) */
370 int mv88e6390_port_set_speed_duplex(struct mv88e6xxx_chip
*chip
, int port
,
371 int speed
, int duplex
)
376 if (speed
== 200 && port
!= 0)
379 if (speed
== 2500 && port
< 9)
382 return mv88e6xxx_port_set_speed_duplex(chip
, port
, speed
, true, true,
386 phy_interface_t
mv88e6390_port_max_speed_mode(struct mv88e6xxx_chip
*chip
,
389 if (port
== 9 || port
== 10)
390 return PHY_INTERFACE_MODE_2500BASEX
;
392 return PHY_INTERFACE_MODE_NA
;
395 /* Support 10, 100, 200, 1000, 2500, 10000 Mbps (e.g. 88E6190X) */
396 int mv88e6390x_port_set_speed_duplex(struct mv88e6xxx_chip
*chip
, int port
,
397 int speed
, int duplex
)
399 if (speed
== 200 && port
!= 0)
402 if (speed
>= 2500 && port
< 9)
405 return mv88e6xxx_port_set_speed_duplex(chip
, port
, speed
, true, true,
409 phy_interface_t
mv88e6390x_port_max_speed_mode(struct mv88e6xxx_chip
*chip
,
412 if (port
== 9 || port
== 10)
413 return PHY_INTERFACE_MODE_XAUI
;
415 return PHY_INTERFACE_MODE_NA
;
418 /* Support 10, 100, 200, 1000, 2500, 5000, 10000 Mbps (e.g. 88E6393X)
419 * Function mv88e6xxx_port_set_speed_duplex() can't be used as the register
420 * values for speeds 2500 & 5000 conflict.
422 int mv88e6393x_port_set_speed_duplex(struct mv88e6xxx_chip
*chip
, int port
,
423 int speed
, int duplex
)
428 if (chip
->info
->prod_num
== MV88E6XXX_PORT_SWITCH_ID_PROD_6361
&&
432 if (speed
== 200 && port
!= 0)
435 if (speed
>= 2500 && port
> 0 && port
< 9)
440 ctrl
= MV88E6XXX_PORT_MAC_CTL_SPEED_10
;
443 ctrl
= MV88E6XXX_PORT_MAC_CTL_SPEED_100
;
446 ctrl
= MV88E6XXX_PORT_MAC_CTL_SPEED_100
|
447 MV88E6390_PORT_MAC_CTL_ALTSPEED
;
450 ctrl
= MV88E6XXX_PORT_MAC_CTL_SPEED_1000
;
453 ctrl
= MV88E6XXX_PORT_MAC_CTL_SPEED_1000
|
454 MV88E6390_PORT_MAC_CTL_ALTSPEED
;
457 ctrl
= MV88E6390_PORT_MAC_CTL_SPEED_10000
|
458 MV88E6390_PORT_MAC_CTL_ALTSPEED
;
462 ctrl
= MV88E6XXX_PORT_MAC_CTL_SPEED_UNFORCED
;
470 ctrl
|= MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX
;
473 ctrl
|= MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX
|
474 MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL
;
476 case DUPLEX_UNFORCED
:
477 /* normal duplex detection */
483 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_MAC_CTL
, ®
);
487 reg
&= ~(MV88E6XXX_PORT_MAC_CTL_SPEED_MASK
|
488 MV88E6390_PORT_MAC_CTL_ALTSPEED
|
489 MV88E6390_PORT_MAC_CTL_FORCE_SPEED
);
491 if (speed
!= SPEED_UNFORCED
)
492 reg
|= MV88E6390_PORT_MAC_CTL_FORCE_SPEED
;
496 err
= mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_MAC_CTL
, reg
);
500 if (speed
!= SPEED_UNFORCED
)
501 dev_dbg(chip
->dev
, "p%d: Speed set to %d Mbps\n", port
, speed
);
503 dev_dbg(chip
->dev
, "p%d: Speed unforced\n", port
);
504 dev_dbg(chip
->dev
, "p%d: %s %s duplex\n", port
,
505 reg
& MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX
? "Force" : "Unforce",
506 reg
& MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL
? "full" : "half");
511 phy_interface_t
mv88e6393x_port_max_speed_mode(struct mv88e6xxx_chip
*chip
,
515 if (port
!= 0 && port
!= 9 && port
!= 10)
516 return PHY_INTERFACE_MODE_NA
;
518 if (chip
->info
->prod_num
== MV88E6XXX_PORT_SWITCH_ID_PROD_6361
)
519 return PHY_INTERFACE_MODE_2500BASEX
;
521 return PHY_INTERFACE_MODE_10GBASER
;
524 static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip
*chip
, int port
,
525 phy_interface_t mode
, bool force
)
531 /* Default to a slow mode, so freeing up SERDES interfaces for
532 * other ports which might use them for SFPs.
534 if (mode
== PHY_INTERFACE_MODE_NA
)
535 mode
= PHY_INTERFACE_MODE_1000BASEX
;
538 case PHY_INTERFACE_MODE_RMII
:
539 cmode
= MV88E6XXX_PORT_STS_CMODE_RMII
;
541 case PHY_INTERFACE_MODE_RGMII
:
542 case PHY_INTERFACE_MODE_RGMII_ID
:
543 case PHY_INTERFACE_MODE_RGMII_RXID
:
544 case PHY_INTERFACE_MODE_RGMII_TXID
:
545 cmode
= MV88E6XXX_PORT_STS_CMODE_RGMII
;
547 case PHY_INTERFACE_MODE_1000BASEX
:
548 cmode
= MV88E6XXX_PORT_STS_CMODE_1000BASEX
;
550 case PHY_INTERFACE_MODE_SGMII
:
551 cmode
= MV88E6XXX_PORT_STS_CMODE_SGMII
;
553 case PHY_INTERFACE_MODE_2500BASEX
:
554 cmode
= MV88E6XXX_PORT_STS_CMODE_2500BASEX
;
556 case PHY_INTERFACE_MODE_5GBASER
:
557 cmode
= MV88E6393X_PORT_STS_CMODE_5GBASER
;
559 case PHY_INTERFACE_MODE_XGMII
:
560 case PHY_INTERFACE_MODE_XAUI
:
561 cmode
= MV88E6XXX_PORT_STS_CMODE_XAUI
;
563 case PHY_INTERFACE_MODE_RXAUI
:
564 cmode
= MV88E6XXX_PORT_STS_CMODE_RXAUI
;
566 case PHY_INTERFACE_MODE_10GBASER
:
567 cmode
= MV88E6393X_PORT_STS_CMODE_10GBASER
;
569 case PHY_INTERFACE_MODE_USXGMII
:
570 cmode
= MV88E6393X_PORT_STS_CMODE_USXGMII
;
576 /* cmode doesn't change, nothing to do for us unless forced */
577 if (cmode
== chip
->ports
[port
].cmode
&& !force
)
580 chip
->ports
[port
].cmode
= 0;
583 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_STS
, ®
);
587 reg
&= ~MV88E6XXX_PORT_STS_CMODE_MASK
;
590 err
= mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_STS
, reg
);
594 chip
->ports
[port
].cmode
= cmode
;
600 int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip
*chip
, int port
,
601 phy_interface_t mode
)
603 if (port
!= 9 && port
!= 10)
606 return mv88e6xxx_port_set_cmode(chip
, port
, mode
, false);
609 int mv88e6390_port_set_cmode(struct mv88e6xxx_chip
*chip
, int port
,
610 phy_interface_t mode
)
612 if (port
!= 9 && port
!= 10)
616 case PHY_INTERFACE_MODE_NA
:
618 case PHY_INTERFACE_MODE_XGMII
:
619 case PHY_INTERFACE_MODE_XAUI
:
620 case PHY_INTERFACE_MODE_RXAUI
:
626 return mv88e6xxx_port_set_cmode(chip
, port
, mode
, false);
629 int mv88e6393x_port_set_cmode(struct mv88e6xxx_chip
*chip
, int port
,
630 phy_interface_t mode
)
635 if (port
!= 0 && port
!= 9 && port
!= 10)
638 if (port
== 9 || port
== 10) {
640 case PHY_INTERFACE_MODE_RMII
:
641 case PHY_INTERFACE_MODE_RGMII
:
642 case PHY_INTERFACE_MODE_RGMII_ID
:
643 case PHY_INTERFACE_MODE_RGMII_RXID
:
644 case PHY_INTERFACE_MODE_RGMII_TXID
:
651 /* mv88e6393x errata 4.5: EEE should be disabled on SERDES ports */
652 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_MAC_CTL
, ®
);
656 reg
&= ~MV88E6XXX_PORT_MAC_CTL_EEE
;
657 reg
|= MV88E6XXX_PORT_MAC_CTL_FORCE_EEE
;
658 err
= mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_MAC_CTL
, reg
);
662 return mv88e6xxx_port_set_cmode(chip
, port
, mode
, false);
665 static int mv88e6341_port_set_cmode_writable(struct mv88e6xxx_chip
*chip
,
674 addr
= chip
->info
->port_base_addr
+ port
;
676 err
= mv88e6xxx_port_hidden_read(chip
, 0x7, addr
, 0, ®
);
680 bits
= MV88E6341_PORT_RESERVED_1A_FORCE_CMODE
|
681 MV88E6341_PORT_RESERVED_1A_SGMII_AN
;
683 if ((reg
& bits
) == bits
)
687 return mv88e6xxx_port_hidden_write(chip
, 0x7, addr
, 0, reg
);
690 int mv88e6341_port_set_cmode(struct mv88e6xxx_chip
*chip
, int port
,
691 phy_interface_t mode
)
699 case PHY_INTERFACE_MODE_NA
:
701 case PHY_INTERFACE_MODE_XGMII
:
702 case PHY_INTERFACE_MODE_XAUI
:
703 case PHY_INTERFACE_MODE_RXAUI
:
709 err
= mv88e6341_port_set_cmode_writable(chip
, port
);
713 return mv88e6xxx_port_set_cmode(chip
, port
, mode
, true);
716 int mv88e6185_port_get_cmode(struct mv88e6xxx_chip
*chip
, int port
, u8
*cmode
)
721 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_STS
, ®
);
725 *cmode
= reg
& MV88E6185_PORT_STS_CMODE_MASK
;
730 int mv88e6352_port_get_cmode(struct mv88e6xxx_chip
*chip
, int port
, u8
*cmode
)
735 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_STS
, ®
);
739 *cmode
= reg
& MV88E6XXX_PORT_STS_CMODE_MASK
;
744 /* Offset 0x02: Jamming Control
746 * Do not limit the period of time that this port can be paused for by
747 * the remote end or the period of time that this port can pause the
750 int mv88e6097_port_pause_limit(struct mv88e6xxx_chip
*chip
, int port
, u8 in
,
753 return mv88e6xxx_port_write(chip
, port
, MV88E6097_PORT_JAM_CTL
,
757 int mv88e6390_port_pause_limit(struct mv88e6xxx_chip
*chip
, int port
, u8 in
,
762 err
= mv88e6xxx_port_write(chip
, port
, MV88E6390_PORT_FLOW_CTL
,
763 MV88E6390_PORT_FLOW_CTL_UPDATE
|
764 MV88E6390_PORT_FLOW_CTL_LIMIT_IN
| in
);
768 return mv88e6xxx_port_write(chip
, port
, MV88E6390_PORT_FLOW_CTL
,
769 MV88E6390_PORT_FLOW_CTL_UPDATE
|
770 MV88E6390_PORT_FLOW_CTL_LIMIT_OUT
| out
);
773 /* Offset 0x04: Port Control Register */
775 static const char * const mv88e6xxx_port_state_names
[] = {
776 [MV88E6XXX_PORT_CTL0_STATE_DISABLED
] = "Disabled",
777 [MV88E6XXX_PORT_CTL0_STATE_BLOCKING
] = "Blocking/Listening",
778 [MV88E6XXX_PORT_CTL0_STATE_LEARNING
] = "Learning",
779 [MV88E6XXX_PORT_CTL0_STATE_FORWARDING
] = "Forwarding",
782 int mv88e6xxx_port_set_state(struct mv88e6xxx_chip
*chip
, int port
, u8 state
)
787 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL0
, ®
);
791 reg
&= ~MV88E6XXX_PORT_CTL0_STATE_MASK
;
794 case BR_STATE_DISABLED
:
795 state
= MV88E6XXX_PORT_CTL0_STATE_DISABLED
;
797 case BR_STATE_BLOCKING
:
798 case BR_STATE_LISTENING
:
799 state
= MV88E6XXX_PORT_CTL0_STATE_BLOCKING
;
801 case BR_STATE_LEARNING
:
802 state
= MV88E6XXX_PORT_CTL0_STATE_LEARNING
;
804 case BR_STATE_FORWARDING
:
805 state
= MV88E6XXX_PORT_CTL0_STATE_FORWARDING
;
813 err
= mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_CTL0
, reg
);
817 dev_dbg(chip
->dev
, "p%d: PortState set to %s\n", port
,
818 mv88e6xxx_port_state_names
[state
]);
823 int mv88e6xxx_port_set_egress_mode(struct mv88e6xxx_chip
*chip
, int port
,
824 enum mv88e6xxx_egress_mode mode
)
829 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL0
, ®
);
833 reg
&= ~MV88E6XXX_PORT_CTL0_EGRESS_MODE_MASK
;
836 case MV88E6XXX_EGRESS_MODE_UNMODIFIED
:
837 reg
|= MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNMODIFIED
;
839 case MV88E6XXX_EGRESS_MODE_UNTAGGED
:
840 reg
|= MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNTAGGED
;
842 case MV88E6XXX_EGRESS_MODE_TAGGED
:
843 reg
|= MV88E6XXX_PORT_CTL0_EGRESS_MODE_TAGGED
;
845 case MV88E6XXX_EGRESS_MODE_ETHERTYPE
:
846 reg
|= MV88E6XXX_PORT_CTL0_EGRESS_MODE_ETHER_TYPE_DSA
;
852 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_CTL0
, reg
);
855 int mv88e6085_port_set_frame_mode(struct mv88e6xxx_chip
*chip
, int port
,
856 enum mv88e6xxx_frame_mode mode
)
861 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL0
, ®
);
865 reg
&= ~MV88E6XXX_PORT_CTL0_FRAME_MODE_MASK
;
868 case MV88E6XXX_FRAME_MODE_NORMAL
:
869 reg
|= MV88E6XXX_PORT_CTL0_FRAME_MODE_NORMAL
;
871 case MV88E6XXX_FRAME_MODE_DSA
:
872 reg
|= MV88E6XXX_PORT_CTL0_FRAME_MODE_DSA
;
878 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_CTL0
, reg
);
881 int mv88e6351_port_set_frame_mode(struct mv88e6xxx_chip
*chip
, int port
,
882 enum mv88e6xxx_frame_mode mode
)
887 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL0
, ®
);
891 reg
&= ~MV88E6XXX_PORT_CTL0_FRAME_MODE_MASK
;
894 case MV88E6XXX_FRAME_MODE_NORMAL
:
895 reg
|= MV88E6XXX_PORT_CTL0_FRAME_MODE_NORMAL
;
897 case MV88E6XXX_FRAME_MODE_DSA
:
898 reg
|= MV88E6XXX_PORT_CTL0_FRAME_MODE_DSA
;
900 case MV88E6XXX_FRAME_MODE_PROVIDER
:
901 reg
|= MV88E6XXX_PORT_CTL0_FRAME_MODE_PROVIDER
;
903 case MV88E6XXX_FRAME_MODE_ETHERTYPE
:
904 reg
|= MV88E6XXX_PORT_CTL0_FRAME_MODE_ETHER_TYPE_DSA
;
910 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_CTL0
, reg
);
913 int mv88e6185_port_set_forward_unknown(struct mv88e6xxx_chip
*chip
,
914 int port
, bool unicast
)
919 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL0
, ®
);
924 reg
|= MV88E6185_PORT_CTL0_FORWARD_UNKNOWN
;
926 reg
&= ~MV88E6185_PORT_CTL0_FORWARD_UNKNOWN
;
928 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_CTL0
, reg
);
931 int mv88e6352_port_set_ucast_flood(struct mv88e6xxx_chip
*chip
, int port
,
937 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL0
, ®
);
942 reg
|= MV88E6352_PORT_CTL0_EGRESS_FLOODS_UC
;
944 reg
&= ~MV88E6352_PORT_CTL0_EGRESS_FLOODS_UC
;
946 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_CTL0
, reg
);
949 int mv88e6352_port_set_mcast_flood(struct mv88e6xxx_chip
*chip
, int port
,
955 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL0
, ®
);
960 reg
|= MV88E6352_PORT_CTL0_EGRESS_FLOODS_MC
;
962 reg
&= ~MV88E6352_PORT_CTL0_EGRESS_FLOODS_MC
;
964 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_CTL0
, reg
);
967 /* Offset 0x05: Port Control 1 */
969 int mv88e6xxx_port_set_message_port(struct mv88e6xxx_chip
*chip
, int port
,
975 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL1
, &val
);
980 val
|= MV88E6XXX_PORT_CTL1_MESSAGE_PORT
;
982 val
&= ~MV88E6XXX_PORT_CTL1_MESSAGE_PORT
;
984 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_CTL1
, val
);
987 int mv88e6xxx_port_set_trunk(struct mv88e6xxx_chip
*chip
, int port
,
993 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL1
, &val
);
997 val
&= ~MV88E6XXX_PORT_CTL1_TRUNK_ID_MASK
;
1000 val
|= MV88E6XXX_PORT_CTL1_TRUNK_PORT
|
1001 (id
<< MV88E6XXX_PORT_CTL1_TRUNK_ID_SHIFT
);
1003 val
&= ~MV88E6XXX_PORT_CTL1_TRUNK_PORT
;
1005 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_CTL1
, val
);
1008 /* Offset 0x06: Port Based VLAN Map */
1010 int mv88e6xxx_port_set_vlan_map(struct mv88e6xxx_chip
*chip
, int port
, u16 map
)
1012 const u16 mask
= mv88e6xxx_port_mask(chip
);
1016 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_BASE_VLAN
, ®
);
1023 err
= mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_BASE_VLAN
, reg
);
1027 dev_dbg(chip
->dev
, "p%d: VLANTable set to %.3x\n", port
, map
);
1032 int mv88e6xxx_port_get_fid(struct mv88e6xxx_chip
*chip
, int port
, u16
*fid
)
1034 const u16 upper_mask
= (mv88e6xxx_num_databases(chip
) - 1) >> 4;
1038 /* Port's default FID lower 4 bits are located in reg 0x06, offset 12 */
1039 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_BASE_VLAN
, ®
);
1043 *fid
= (reg
& 0xf000) >> 12;
1045 /* Port's default FID upper bits are located in reg 0x05, offset 0 */
1047 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL1
,
1052 *fid
|= (reg
& upper_mask
) << 4;
1058 int mv88e6xxx_port_set_fid(struct mv88e6xxx_chip
*chip
, int port
, u16 fid
)
1060 const u16 upper_mask
= (mv88e6xxx_num_databases(chip
) - 1) >> 4;
1064 if (fid
>= mv88e6xxx_num_databases(chip
))
1067 /* Port's default FID lower 4 bits are located in reg 0x06, offset 12 */
1068 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_BASE_VLAN
, ®
);
1073 reg
|= (fid
& 0x000f) << 12;
1075 err
= mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_BASE_VLAN
, reg
);
1079 /* Port's default FID upper bits are located in reg 0x05, offset 0 */
1081 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL1
,
1087 reg
|= (fid
>> 4) & upper_mask
;
1089 err
= mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_CTL1
,
1095 dev_dbg(chip
->dev
, "p%d: FID set to %u\n", port
, fid
);
1100 /* Offset 0x07: Default Port VLAN ID & Priority */
1102 int mv88e6xxx_port_get_pvid(struct mv88e6xxx_chip
*chip
, int port
, u16
*pvid
)
1107 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_DEFAULT_VLAN
,
1112 *pvid
= reg
& MV88E6XXX_PORT_DEFAULT_VLAN_MASK
;
1117 int mv88e6xxx_port_set_pvid(struct mv88e6xxx_chip
*chip
, int port
, u16 pvid
)
1122 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_DEFAULT_VLAN
,
1127 reg
&= ~MV88E6XXX_PORT_DEFAULT_VLAN_MASK
;
1128 reg
|= pvid
& MV88E6XXX_PORT_DEFAULT_VLAN_MASK
;
1130 err
= mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_DEFAULT_VLAN
,
1135 dev_dbg(chip
->dev
, "p%d: DefaultVID set to %u\n", port
, pvid
);
1140 /* Offset 0x08: Port Control 2 Register */
1142 static const char * const mv88e6xxx_port_8021q_mode_names
[] = {
1143 [MV88E6XXX_PORT_CTL2_8021Q_MODE_DISABLED
] = "Disabled",
1144 [MV88E6XXX_PORT_CTL2_8021Q_MODE_FALLBACK
] = "Fallback",
1145 [MV88E6XXX_PORT_CTL2_8021Q_MODE_CHECK
] = "Check",
1146 [MV88E6XXX_PORT_CTL2_8021Q_MODE_SECURE
] = "Secure",
1149 int mv88e6185_port_set_default_forward(struct mv88e6xxx_chip
*chip
,
1150 int port
, bool multicast
)
1155 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL2
, ®
);
1160 reg
|= MV88E6XXX_PORT_CTL2_DEFAULT_FORWARD
;
1162 reg
&= ~MV88E6XXX_PORT_CTL2_DEFAULT_FORWARD
;
1164 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_CTL2
, reg
);
1167 int mv88e6095_port_set_upstream_port(struct mv88e6xxx_chip
*chip
, int port
,
1173 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL2
, ®
);
1177 reg
&= ~MV88E6095_PORT_CTL2_CPU_PORT_MASK
;
1178 reg
|= upstream_port
;
1180 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_CTL2
, reg
);
1183 int mv88e6xxx_port_set_mirror(struct mv88e6xxx_chip
*chip
, int port
,
1184 enum mv88e6xxx_egress_direction direction
,
1192 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL2
, ®
);
1196 switch (direction
) {
1197 case MV88E6XXX_EGRESS_DIR_INGRESS
:
1198 bit
= MV88E6XXX_PORT_CTL2_INGRESS_MONITOR
;
1199 mirror_port
= &chip
->ports
[port
].mirror_ingress
;
1201 case MV88E6XXX_EGRESS_DIR_EGRESS
:
1202 bit
= MV88E6XXX_PORT_CTL2_EGRESS_MONITOR
;
1203 mirror_port
= &chip
->ports
[port
].mirror_egress
;
1213 err
= mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_CTL2
, reg
);
1215 *mirror_port
= mirror
;
1220 int mv88e6xxx_port_set_lock(struct mv88e6xxx_chip
*chip
, int port
,
1226 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL0
, ®
);
1230 reg
&= ~MV88E6XXX_PORT_CTL0_SA_FILT_MASK
;
1232 reg
|= MV88E6XXX_PORT_CTL0_SA_FILT_DROP_ON_LOCK
;
1234 err
= mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_CTL0
, reg
);
1238 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_ASSOC_VECTOR
, ®
);
1242 reg
&= ~MV88E6XXX_PORT_ASSOC_VECTOR_LOCKED_PORT
;
1244 reg
|= MV88E6XXX_PORT_ASSOC_VECTOR_LOCKED_PORT
;
1246 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_ASSOC_VECTOR
, reg
);
1249 int mv88e6xxx_port_set_8021q_mode(struct mv88e6xxx_chip
*chip
, int port
,
1255 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL2
, ®
);
1259 reg
&= ~MV88E6XXX_PORT_CTL2_8021Q_MODE_MASK
;
1260 reg
|= mode
& MV88E6XXX_PORT_CTL2_8021Q_MODE_MASK
;
1262 err
= mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_CTL2
, reg
);
1266 dev_dbg(chip
->dev
, "p%d: 802.1QMode set to %s\n", port
,
1267 mv88e6xxx_port_8021q_mode_names
[mode
]);
1272 int mv88e6xxx_port_drop_untagged(struct mv88e6xxx_chip
*chip
, int port
,
1278 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL2
, &old
);
1283 new = old
| MV88E6XXX_PORT_CTL2_DISCARD_UNTAGGED
;
1285 new = old
& ~MV88E6XXX_PORT_CTL2_DISCARD_UNTAGGED
;
1290 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_CTL2
, new);
1293 int mv88e6xxx_port_set_map_da(struct mv88e6xxx_chip
*chip
, int port
, bool map
)
1298 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL2
, ®
);
1303 reg
|= MV88E6XXX_PORT_CTL2_MAP_DA
;
1305 reg
&= ~MV88E6XXX_PORT_CTL2_MAP_DA
;
1307 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_CTL2
, reg
);
1310 int mv88e6165_port_set_jumbo_size(struct mv88e6xxx_chip
*chip
, int port
,
1316 size
+= VLAN_ETH_HLEN
+ ETH_FCS_LEN
;
1318 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_CTL2
, ®
);
1322 reg
&= ~MV88E6XXX_PORT_CTL2_JUMBO_MODE_MASK
;
1325 reg
|= MV88E6XXX_PORT_CTL2_JUMBO_MODE_1522
;
1326 else if (size
<= 2048)
1327 reg
|= MV88E6XXX_PORT_CTL2_JUMBO_MODE_2048
;
1328 else if (size
<= 10240)
1329 reg
|= MV88E6XXX_PORT_CTL2_JUMBO_MODE_10240
;
1333 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_CTL2
, reg
);
1336 /* Offset 0x09: Port Rate Control */
1338 int mv88e6095_port_egress_rate_limiting(struct mv88e6xxx_chip
*chip
, int port
)
1340 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_EGRESS_RATE_CTL1
,
1344 int mv88e6097_port_egress_rate_limiting(struct mv88e6xxx_chip
*chip
, int port
)
1346 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_EGRESS_RATE_CTL1
,
1350 /* Offset 0x0B: Port Association Vector */
1352 int mv88e6xxx_port_set_assoc_vector(struct mv88e6xxx_chip
*chip
, int port
,
1358 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_ASSOC_VECTOR
,
1363 mask
= mv88e6xxx_port_mask(chip
);
1367 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_ASSOC_VECTOR
,
1371 /* Offset 0x0C: Port ATU Control */
1373 int mv88e6xxx_port_disable_learn_limit(struct mv88e6xxx_chip
*chip
, int port
)
1375 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_ATU_CTL
, 0);
1378 /* Offset 0x0D: (Priority) Override Register */
1380 int mv88e6xxx_port_disable_pri_override(struct mv88e6xxx_chip
*chip
, int port
)
1382 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_PRI_OVERRIDE
, 0);
1385 /* Offset 0x0E: Policy & MGMT Control Register for FAMILY 6191X 6193X 6393X */
1387 static int mv88e6393x_port_policy_read(struct mv88e6xxx_chip
*chip
, int port
,
1388 u16 pointer
, u8
*data
)
1393 err
= mv88e6xxx_port_write(chip
, port
, MV88E6393X_PORT_POLICY_MGMT_CTL
,
1398 err
= mv88e6xxx_port_read(chip
, port
, MV88E6393X_PORT_POLICY_MGMT_CTL
,
1408 static int mv88e6393x_port_policy_write(struct mv88e6xxx_chip
*chip
, int port
,
1409 u16 pointer
, u8 data
)
1413 reg
= MV88E6393X_PORT_POLICY_MGMT_CTL_UPDATE
| pointer
| data
;
1415 return mv88e6xxx_port_write(chip
, port
, MV88E6393X_PORT_POLICY_MGMT_CTL
,
1419 static int mv88e6393x_port_policy_write_all(struct mv88e6xxx_chip
*chip
,
1420 u16 pointer
, u8 data
)
1424 for (port
= 0; port
< mv88e6xxx_num_ports(chip
); port
++) {
1425 if (dsa_is_unused_port(chip
->ds
, port
))
1428 err
= mv88e6393x_port_policy_write(chip
, port
, pointer
, data
);
1436 int mv88e6393x_set_egress_port(struct mv88e6xxx_chip
*chip
,
1437 enum mv88e6xxx_egress_direction direction
,
1443 switch (direction
) {
1444 case MV88E6XXX_EGRESS_DIR_INGRESS
:
1445 ptr
= MV88E6393X_PORT_POLICY_MGMT_CTL_PTR_INGRESS_DEST
;
1446 err
= mv88e6393x_port_policy_write_all(chip
, ptr
, port
);
1450 case MV88E6XXX_EGRESS_DIR_EGRESS
:
1451 ptr
= MV88E6393X_G2_EGRESS_MONITOR_DEST
;
1452 err
= mv88e6xxx_g2_write(chip
, ptr
, port
);
1461 int mv88e6393x_port_set_upstream_port(struct mv88e6xxx_chip
*chip
, int port
,
1464 u16 ptr
= MV88E6393X_PORT_POLICY_MGMT_CTL_PTR_CPU_DEST
;
1465 u8 data
= MV88E6393X_PORT_POLICY_MGMT_CTL_CPU_DEST_MGMTPRI
|
1468 return mv88e6393x_port_policy_write(chip
, port
, ptr
, data
);
1471 int mv88e6393x_port_mgmt_rsvd2cpu(struct mv88e6xxx_chip
*chip
)
1476 /* Consider the frames with reserved multicast destination
1477 * addresses matching 01:80:c2:00:00:00 and
1478 * 01:80:c2:00:00:02 as MGMT.
1480 ptr
= MV88E6393X_PORT_POLICY_MGMT_CTL_PTR_01C280000000XLO
;
1481 err
= mv88e6393x_port_policy_write_all(chip
, ptr
, 0xff);
1485 ptr
= MV88E6393X_PORT_POLICY_MGMT_CTL_PTR_01C280000000XHI
;
1486 err
= mv88e6393x_port_policy_write_all(chip
, ptr
, 0xff);
1490 ptr
= MV88E6393X_PORT_POLICY_MGMT_CTL_PTR_01C280000002XLO
;
1491 err
= mv88e6393x_port_policy_write_all(chip
, ptr
, 0xff);
1495 ptr
= MV88E6393X_PORT_POLICY_MGMT_CTL_PTR_01C280000002XHI
;
1496 err
= mv88e6393x_port_policy_write_all(chip
, ptr
, 0xff);
1503 /* Offset 0x10 & 0x11: EPC */
1505 static int mv88e6393x_port_epc_wait_ready(struct mv88e6xxx_chip
*chip
, int port
)
1507 int bit
= __bf_shf(MV88E6393X_PORT_EPC_CMD_BUSY
);
1509 return mv88e6xxx_port_wait_bit(chip
, port
, MV88E6393X_PORT_EPC_CMD
, bit
, 0);
1512 /* Port Ether type for 6393X family */
1514 int mv88e6393x_port_set_ether_type(struct mv88e6xxx_chip
*chip
, int port
,
1520 err
= mv88e6393x_port_epc_wait_ready(chip
, port
);
1524 err
= mv88e6xxx_port_write(chip
, port
, MV88E6393X_PORT_EPC_DATA
, etype
);
1528 val
= MV88E6393X_PORT_EPC_CMD_BUSY
|
1529 MV88E6393X_PORT_EPC_CMD_WRITE
|
1530 MV88E6393X_PORT_EPC_INDEX_PORT_ETYPE
;
1532 return mv88e6xxx_port_write(chip
, port
, MV88E6393X_PORT_EPC_CMD
, val
);
1535 /* Offset 0x0f: Port Ether type */
1537 int mv88e6351_port_set_ether_type(struct mv88e6xxx_chip
*chip
, int port
,
1540 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_ETH_TYPE
, etype
);
1543 /* Offset 0x18: Port IEEE Priority Remapping Registers [0-3]
1544 * Offset 0x19: Port IEEE Priority Remapping Registers [4-7]
1547 int mv88e6095_port_tag_remap(struct mv88e6xxx_chip
*chip
, int port
)
1551 /* Use a direct priority mapping for all IEEE tagged frames */
1552 err
= mv88e6xxx_port_write(chip
, port
,
1553 MV88E6095_PORT_IEEE_PRIO_REMAP_0123
,
1558 return mv88e6xxx_port_write(chip
, port
,
1559 MV88E6095_PORT_IEEE_PRIO_REMAP_4567
,
1563 static int mv88e6xxx_port_ieeepmt_write(struct mv88e6xxx_chip
*chip
,
1564 int port
, u16 table
, u8 ptr
, u16 data
)
1568 reg
= MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_UPDATE
| table
|
1569 (ptr
<< __bf_shf(MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_PTR_MASK
)) |
1570 (data
& MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_DATA_MASK
);
1572 return mv88e6xxx_port_write(chip
, port
,
1573 MV88E6390_PORT_IEEE_PRIO_MAP_TABLE
, reg
);
1576 int mv88e6390_port_tag_remap(struct mv88e6xxx_chip
*chip
, int port
)
1581 for (i
= 0; i
<= 7; i
++) {
1582 table
= MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_INGRESS_PCP
;
1583 err
= mv88e6xxx_port_ieeepmt_write(chip
, port
, table
, i
,
1588 table
= MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_GREEN_PCP
;
1589 err
= mv88e6xxx_port_ieeepmt_write(chip
, port
, table
, i
, i
);
1593 table
= MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_YELLOW_PCP
;
1594 err
= mv88e6xxx_port_ieeepmt_write(chip
, port
, table
, i
, i
);
1598 table
= MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_AVB_PCP
;
1599 err
= mv88e6xxx_port_ieeepmt_write(chip
, port
, table
, i
, i
);
1607 /* Offset 0x0E: Policy Control Register */
1610 mv88e6xxx_port_policy_mapping_get_pos(enum mv88e6xxx_policy_mapping mapping
,
1611 enum mv88e6xxx_policy_action action
,
1612 u16
*mask
, u16
*val
, int *shift
)
1615 case MV88E6XXX_POLICY_MAPPING_DA
:
1616 *shift
= __bf_shf(MV88E6XXX_PORT_POLICY_CTL_DA_MASK
);
1617 *mask
= MV88E6XXX_PORT_POLICY_CTL_DA_MASK
;
1619 case MV88E6XXX_POLICY_MAPPING_SA
:
1620 *shift
= __bf_shf(MV88E6XXX_PORT_POLICY_CTL_SA_MASK
);
1621 *mask
= MV88E6XXX_PORT_POLICY_CTL_SA_MASK
;
1623 case MV88E6XXX_POLICY_MAPPING_VTU
:
1624 *shift
= __bf_shf(MV88E6XXX_PORT_POLICY_CTL_VTU_MASK
);
1625 *mask
= MV88E6XXX_PORT_POLICY_CTL_VTU_MASK
;
1627 case MV88E6XXX_POLICY_MAPPING_ETYPE
:
1628 *shift
= __bf_shf(MV88E6XXX_PORT_POLICY_CTL_ETYPE_MASK
);
1629 *mask
= MV88E6XXX_PORT_POLICY_CTL_ETYPE_MASK
;
1631 case MV88E6XXX_POLICY_MAPPING_PPPOE
:
1632 *shift
= __bf_shf(MV88E6XXX_PORT_POLICY_CTL_PPPOE_MASK
);
1633 *mask
= MV88E6XXX_PORT_POLICY_CTL_PPPOE_MASK
;
1635 case MV88E6XXX_POLICY_MAPPING_VBAS
:
1636 *shift
= __bf_shf(MV88E6XXX_PORT_POLICY_CTL_VBAS_MASK
);
1637 *mask
= MV88E6XXX_PORT_POLICY_CTL_VBAS_MASK
;
1639 case MV88E6XXX_POLICY_MAPPING_OPT82
:
1640 *shift
= __bf_shf(MV88E6XXX_PORT_POLICY_CTL_OPT82_MASK
);
1641 *mask
= MV88E6XXX_PORT_POLICY_CTL_OPT82_MASK
;
1643 case MV88E6XXX_POLICY_MAPPING_UDP
:
1644 *shift
= __bf_shf(MV88E6XXX_PORT_POLICY_CTL_UDP_MASK
);
1645 *mask
= MV88E6XXX_PORT_POLICY_CTL_UDP_MASK
;
1652 case MV88E6XXX_POLICY_ACTION_NORMAL
:
1653 *val
= MV88E6XXX_PORT_POLICY_CTL_NORMAL
;
1655 case MV88E6XXX_POLICY_ACTION_MIRROR
:
1656 *val
= MV88E6XXX_PORT_POLICY_CTL_MIRROR
;
1658 case MV88E6XXX_POLICY_ACTION_TRAP
:
1659 *val
= MV88E6XXX_PORT_POLICY_CTL_TRAP
;
1661 case MV88E6XXX_POLICY_ACTION_DISCARD
:
1662 *val
= MV88E6XXX_PORT_POLICY_CTL_DISCARD
;
1671 int mv88e6352_port_set_policy(struct mv88e6xxx_chip
*chip
, int port
,
1672 enum mv88e6xxx_policy_mapping mapping
,
1673 enum mv88e6xxx_policy_action action
)
1679 err
= mv88e6xxx_port_policy_mapping_get_pos(mapping
, action
, &mask
,
1684 err
= mv88e6xxx_port_read(chip
, port
, MV88E6XXX_PORT_POLICY_CTL
, ®
);
1689 reg
|= (val
<< shift
) & mask
;
1691 return mv88e6xxx_port_write(chip
, port
, MV88E6XXX_PORT_POLICY_CTL
, reg
);
1694 int mv88e6393x_port_set_policy(struct mv88e6xxx_chip
*chip
, int port
,
1695 enum mv88e6xxx_policy_mapping mapping
,
1696 enum mv88e6xxx_policy_action action
)
1704 err
= mv88e6xxx_port_policy_mapping_get_pos(mapping
, action
, &mask
,
1709 /* The 16-bit Port Policy CTL register from older chips is on 6393x
1710 * changed to Port Policy MGMT CTL, which can access more data, but
1711 * indirectly. The original 16-bit value is divided into two 8-bit
1719 err
= mv88e6393x_port_policy_read(chip
, port
, ptr
, ®
);
1724 reg
|= (val
<< shift
) & mask
;
1726 return mv88e6393x_port_policy_write(chip
, port
, ptr
, reg
);