2 * Marvell 88E6xxx Switch Port Registers support
4 * Copyright (c) 2008 Marvell Semiconductor
6 * Copyright (c) 2016-2017 Savoir-faire Linux Inc.
7 * Vivien Didelot <vivien.didelot@savoirfairelinux.com>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
15 #include <linux/bitfield.h>
16 #include <linux/if_bridge.h>
17 #include <linux/phy.h>
18 #include <linux/phylink.h>
23 int mv88e6xxx_port_read(struct mv88e6xxx_chip *chip, int port, int reg,
26 int addr = chip->info->port_base_addr + port;
28 return mv88e6xxx_read(chip, addr, reg, val);
31 int mv88e6xxx_port_write(struct mv88e6xxx_chip *chip, int port, int reg,
34 int addr = chip->info->port_base_addr + port;
36 return mv88e6xxx_write(chip, addr, reg, val);
39 /* Offset 0x00: MAC (or PCS or Physical) Status Register
41 * For most devices, this is read only. However the 6185 has the MyPause
44 int mv88e6185_port_set_pause(struct mv88e6xxx_chip *chip, int port,
50 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®);
55 reg |= MV88E6XXX_PORT_STS_MY_PAUSE;
57 reg &= ~MV88E6XXX_PORT_STS_MY_PAUSE;
59 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_STS, reg);
62 /* Offset 0x01: MAC (or PCS or Physical) Control Register
64 * Link, Duplex and Flow Control have one force bit, one value bit.
66 * For port's MAC speed, ForceSpd (or SpdValue) bits 1:0 program the value.
67 * Alternative values require the 200BASE (or AltSpeed) bit 12 set.
68 * Newer chips need a ForcedSpd bit 13 set to consider the value.
71 static int mv88e6xxx_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,
77 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, ®);
81 reg &= ~(MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK |
82 MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK);
85 case PHY_INTERFACE_MODE_RGMII_RXID:
86 reg |= MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK;
88 case PHY_INTERFACE_MODE_RGMII_TXID:
89 reg |= MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK;
91 case PHY_INTERFACE_MODE_RGMII_ID:
92 reg |= MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK |
93 MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK;
95 case PHY_INTERFACE_MODE_RGMII:
101 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg);
105 dev_dbg(chip->dev, "p%d: delay RXCLK %s, TXCLK %s\n", port,
106 reg & MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK ? "yes" : "no",
107 reg & MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK ? "yes" : "no");
112 int mv88e6352_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,
113 phy_interface_t mode)
118 return mv88e6xxx_port_set_rgmii_delay(chip, port, mode);
121 int mv88e6390_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,
122 phy_interface_t mode)
127 return mv88e6xxx_port_set_rgmii_delay(chip, port, mode);
130 int mv88e6xxx_port_set_link(struct mv88e6xxx_chip *chip, int port, int link)
135 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, ®);
139 reg &= ~(MV88E6XXX_PORT_MAC_CTL_FORCE_LINK |
140 MV88E6XXX_PORT_MAC_CTL_LINK_UP);
143 case LINK_FORCED_DOWN:
144 reg |= MV88E6XXX_PORT_MAC_CTL_FORCE_LINK;
147 reg |= MV88E6XXX_PORT_MAC_CTL_FORCE_LINK |
148 MV88E6XXX_PORT_MAC_CTL_LINK_UP;
151 /* normal link detection */
157 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg);
161 dev_dbg(chip->dev, "p%d: %s link %s\n", port,
162 reg & MV88E6XXX_PORT_MAC_CTL_FORCE_LINK ? "Force" : "Unforce",
163 reg & MV88E6XXX_PORT_MAC_CTL_LINK_UP ? "up" : "down");
168 int mv88e6xxx_port_set_duplex(struct mv88e6xxx_chip *chip, int port, int dup)
173 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, ®);
177 reg &= ~(MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX |
178 MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL);
182 reg |= MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX;
185 reg |= MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX |
186 MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL;
188 case DUPLEX_UNFORCED:
189 /* normal duplex detection */
195 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg);
199 dev_dbg(chip->dev, "p%d: %s %s duplex\n", port,
200 reg & MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX ? "Force" : "Unforce",
201 reg & MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL ? "full" : "half");
206 static int mv88e6xxx_port_set_speed(struct mv88e6xxx_chip *chip, int port,
207 int speed, bool alt_bit, bool force_bit)
214 ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_10;
217 ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_100;
221 ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_100 |
222 MV88E6390_PORT_MAC_CTL_ALTSPEED;
224 ctrl = MV88E6065_PORT_MAC_CTL_SPEED_200;
227 ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_1000;
230 ctrl = MV88E6390_PORT_MAC_CTL_SPEED_10000 |
231 MV88E6390_PORT_MAC_CTL_ALTSPEED;
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 Mbps (e.g. 88E6352 family) */
294 int mv88e6352_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
296 if (speed == SPEED_MAX)
302 if (speed == 200 && port < 5)
305 return mv88e6xxx_port_set_speed(chip, port, speed, true, false);
308 /* Support 10, 100, 200, 1000, 2500 Mbps (e.g. 88E6390) */
309 int mv88e6390_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
311 if (speed == SPEED_MAX)
312 speed = port < 9 ? 1000 : 2500;
317 if (speed == 200 && port != 0)
320 if (speed == 2500 && port < 9)
323 return mv88e6xxx_port_set_speed(chip, port, speed, true, true);
326 /* Support 10, 100, 200, 1000, 2500, 10000 Mbps (e.g. 88E6190X) */
327 int mv88e6390x_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
329 if (speed == SPEED_MAX)
330 speed = port < 9 ? 1000 : 10000;
332 if (speed == 200 && port != 0)
335 if (speed >= 2500 && port < 9)
338 return mv88e6xxx_port_set_speed(chip, port, speed, true, true);
341 int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
342 phy_interface_t mode)
348 if (mode == PHY_INTERFACE_MODE_NA)
351 if (port != 9 && port != 10)
355 case PHY_INTERFACE_MODE_1000BASEX:
356 cmode = MV88E6XXX_PORT_STS_CMODE_1000BASE_X;
358 case PHY_INTERFACE_MODE_SGMII:
359 cmode = MV88E6XXX_PORT_STS_CMODE_SGMII;
361 case PHY_INTERFACE_MODE_2500BASEX:
362 cmode = MV88E6XXX_PORT_STS_CMODE_2500BASEX;
364 case PHY_INTERFACE_MODE_XGMII:
365 case PHY_INTERFACE_MODE_XAUI:
366 cmode = MV88E6XXX_PORT_STS_CMODE_XAUI;
368 case PHY_INTERFACE_MODE_RXAUI:
369 cmode = MV88E6XXX_PORT_STS_CMODE_RXAUI;
376 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®);
380 reg &= ~MV88E6XXX_PORT_STS_CMODE_MASK;
383 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_STS, reg);
388 chip->ports[port].cmode = cmode;
393 int mv88e6185_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode)
398 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®);
402 *cmode = reg & MV88E6185_PORT_STS_CMODE_MASK;
407 int mv88e6352_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode)
412 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®);
416 *cmode = reg & MV88E6XXX_PORT_STS_CMODE_MASK;
421 int mv88e6352_port_link_state(struct mv88e6xxx_chip *chip, int port,
422 struct phylink_link_state *state)
427 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®);
431 switch (reg & MV88E6XXX_PORT_STS_SPEED_MASK) {
432 case MV88E6XXX_PORT_STS_SPEED_10:
433 state->speed = SPEED_10;
435 case MV88E6XXX_PORT_STS_SPEED_100:
436 state->speed = SPEED_100;
438 case MV88E6XXX_PORT_STS_SPEED_1000:
439 state->speed = SPEED_1000;
441 case MV88E6XXX_PORT_STS_SPEED_10000:
442 if ((reg & MV88E6XXX_PORT_STS_CMODE_MASK) ==
443 MV88E6XXX_PORT_STS_CMODE_2500BASEX)
444 state->speed = SPEED_2500;
446 state->speed = SPEED_10000;
450 state->duplex = reg & MV88E6XXX_PORT_STS_DUPLEX ?
451 DUPLEX_FULL : DUPLEX_HALF;
452 state->link = !!(reg & MV88E6XXX_PORT_STS_LINK);
453 state->an_enabled = 1;
454 state->an_complete = state->link;
459 int mv88e6185_port_link_state(struct mv88e6xxx_chip *chip, int port,
460 struct phylink_link_state *state)
462 if (state->interface == PHY_INTERFACE_MODE_1000BASEX) {
463 u8 cmode = chip->ports[port].cmode;
465 /* When a port is in "Cross-chip serdes" mode, it uses
466 * 1000Base-X full duplex mode, but there is no automatic
467 * link detection. Use the sync OK status for link (as it
468 * would do for 1000Base-X mode.)
470 if (cmode == MV88E6185_PORT_STS_CMODE_SERDES) {
474 err = mv88e6xxx_port_read(chip, port,
475 MV88E6XXX_PORT_MAC_CTL, &mac);
479 state->link = !!(mac & MV88E6185_PORT_MAC_CTL_SYNC_OK);
480 state->an_enabled = 1;
482 !!(mac & MV88E6185_PORT_MAC_CTL_AN_DONE);
484 state->link ? DUPLEX_FULL : DUPLEX_UNKNOWN;
486 state->link ? SPEED_1000 : SPEED_UNKNOWN;
492 return mv88e6352_port_link_state(chip, port, state);
495 /* Offset 0x02: Jamming Control
497 * Do not limit the period of time that this port can be paused for by
498 * the remote end or the period of time that this port can pause the
501 int mv88e6097_port_pause_limit(struct mv88e6xxx_chip *chip, int port, u8 in,
504 return mv88e6xxx_port_write(chip, port, MV88E6097_PORT_JAM_CTL,
508 int mv88e6390_port_pause_limit(struct mv88e6xxx_chip *chip, int port, u8 in,
513 err = mv88e6xxx_port_write(chip, port, MV88E6390_PORT_FLOW_CTL,
514 MV88E6390_PORT_FLOW_CTL_UPDATE |
515 MV88E6390_PORT_FLOW_CTL_LIMIT_IN | in);
519 return mv88e6xxx_port_write(chip, port, MV88E6390_PORT_FLOW_CTL,
520 MV88E6390_PORT_FLOW_CTL_UPDATE |
521 MV88E6390_PORT_FLOW_CTL_LIMIT_OUT | out);
524 /* Offset 0x04: Port Control Register */
526 static const char * const mv88e6xxx_port_state_names[] = {
527 [MV88E6XXX_PORT_CTL0_STATE_DISABLED] = "Disabled",
528 [MV88E6XXX_PORT_CTL0_STATE_BLOCKING] = "Blocking/Listening",
529 [MV88E6XXX_PORT_CTL0_STATE_LEARNING] = "Learning",
530 [MV88E6XXX_PORT_CTL0_STATE_FORWARDING] = "Forwarding",
533 int mv88e6xxx_port_set_state(struct mv88e6xxx_chip *chip, int port, u8 state)
538 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®);
542 reg &= ~MV88E6XXX_PORT_CTL0_STATE_MASK;
545 case BR_STATE_DISABLED:
546 state = MV88E6XXX_PORT_CTL0_STATE_DISABLED;
548 case BR_STATE_BLOCKING:
549 case BR_STATE_LISTENING:
550 state = MV88E6XXX_PORT_CTL0_STATE_BLOCKING;
552 case BR_STATE_LEARNING:
553 state = MV88E6XXX_PORT_CTL0_STATE_LEARNING;
555 case BR_STATE_FORWARDING:
556 state = MV88E6XXX_PORT_CTL0_STATE_FORWARDING;
564 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
568 dev_dbg(chip->dev, "p%d: PortState set to %s\n", port,
569 mv88e6xxx_port_state_names[state]);
574 int mv88e6xxx_port_set_egress_mode(struct mv88e6xxx_chip *chip, int port,
575 enum mv88e6xxx_egress_mode mode)
580 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®);
584 reg &= ~MV88E6XXX_PORT_CTL0_EGRESS_MODE_MASK;
587 case MV88E6XXX_EGRESS_MODE_UNMODIFIED:
588 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNMODIFIED;
590 case MV88E6XXX_EGRESS_MODE_UNTAGGED:
591 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNTAGGED;
593 case MV88E6XXX_EGRESS_MODE_TAGGED:
594 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_TAGGED;
596 case MV88E6XXX_EGRESS_MODE_ETHERTYPE:
597 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_ETHER_TYPE_DSA;
603 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
606 int mv88e6085_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port,
607 enum mv88e6xxx_frame_mode mode)
612 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®);
616 reg &= ~MV88E6XXX_PORT_CTL0_FRAME_MODE_MASK;
619 case MV88E6XXX_FRAME_MODE_NORMAL:
620 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_NORMAL;
622 case MV88E6XXX_FRAME_MODE_DSA:
623 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_DSA;
629 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
632 int mv88e6351_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port,
633 enum mv88e6xxx_frame_mode mode)
638 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®);
642 reg &= ~MV88E6XXX_PORT_CTL0_FRAME_MODE_MASK;
645 case MV88E6XXX_FRAME_MODE_NORMAL:
646 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_NORMAL;
648 case MV88E6XXX_FRAME_MODE_DSA:
649 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_DSA;
651 case MV88E6XXX_FRAME_MODE_PROVIDER:
652 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_PROVIDER;
654 case MV88E6XXX_FRAME_MODE_ETHERTYPE:
655 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_ETHER_TYPE_DSA;
661 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
664 static int mv88e6185_port_set_forward_unknown(struct mv88e6xxx_chip *chip,
665 int port, bool unicast)
670 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®);
675 reg |= MV88E6185_PORT_CTL0_FORWARD_UNKNOWN;
677 reg &= ~MV88E6185_PORT_CTL0_FORWARD_UNKNOWN;
679 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
682 int mv88e6352_port_set_egress_floods(struct mv88e6xxx_chip *chip, int port,
683 bool unicast, bool multicast)
688 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®);
692 reg &= ~MV88E6352_PORT_CTL0_EGRESS_FLOODS_MASK;
694 if (unicast && multicast)
695 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_ALL_UNKNOWN_DA;
697 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_MC_DA;
699 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_UC_DA;
701 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_DA;
703 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
706 /* Offset 0x05: Port Control 1 */
708 int mv88e6xxx_port_set_message_port(struct mv88e6xxx_chip *chip, int port,
714 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1, &val);
719 val |= MV88E6XXX_PORT_CTL1_MESSAGE_PORT;
721 val &= ~MV88E6XXX_PORT_CTL1_MESSAGE_PORT;
723 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL1, val);
726 /* Offset 0x06: Port Based VLAN Map */
728 int mv88e6xxx_port_set_vlan_map(struct mv88e6xxx_chip *chip, int port, u16 map)
730 const u16 mask = mv88e6xxx_port_mask(chip);
734 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, ®);
741 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_BASE_VLAN, reg);
745 dev_dbg(chip->dev, "p%d: VLANTable set to %.3x\n", port, map);
750 int mv88e6xxx_port_get_fid(struct mv88e6xxx_chip *chip, int port, u16 *fid)
752 const u16 upper_mask = (mv88e6xxx_num_databases(chip) - 1) >> 4;
756 /* Port's default FID lower 4 bits are located in reg 0x06, offset 12 */
757 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, ®);
761 *fid = (reg & 0xf000) >> 12;
763 /* Port's default FID upper bits are located in reg 0x05, offset 0 */
765 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1,
770 *fid |= (reg & upper_mask) << 4;
776 int mv88e6xxx_port_set_fid(struct mv88e6xxx_chip *chip, int port, u16 fid)
778 const u16 upper_mask = (mv88e6xxx_num_databases(chip) - 1) >> 4;
782 if (fid >= mv88e6xxx_num_databases(chip))
785 /* Port's default FID lower 4 bits are located in reg 0x06, offset 12 */
786 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, ®);
791 reg |= (fid & 0x000f) << 12;
793 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_BASE_VLAN, reg);
797 /* Port's default FID upper bits are located in reg 0x05, offset 0 */
799 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1,
805 reg |= (fid >> 4) & upper_mask;
807 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL1,
813 dev_dbg(chip->dev, "p%d: FID set to %u\n", port, fid);
818 /* Offset 0x07: Default Port VLAN ID & Priority */
820 int mv88e6xxx_port_get_pvid(struct mv88e6xxx_chip *chip, int port, u16 *pvid)
825 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN,
830 *pvid = reg & MV88E6XXX_PORT_DEFAULT_VLAN_MASK;
835 int mv88e6xxx_port_set_pvid(struct mv88e6xxx_chip *chip, int port, u16 pvid)
840 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN,
845 reg &= ~MV88E6XXX_PORT_DEFAULT_VLAN_MASK;
846 reg |= pvid & MV88E6XXX_PORT_DEFAULT_VLAN_MASK;
848 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN,
853 dev_dbg(chip->dev, "p%d: DefaultVID set to %u\n", port, pvid);
858 /* Offset 0x08: Port Control 2 Register */
860 static const char * const mv88e6xxx_port_8021q_mode_names[] = {
861 [MV88E6XXX_PORT_CTL2_8021Q_MODE_DISABLED] = "Disabled",
862 [MV88E6XXX_PORT_CTL2_8021Q_MODE_FALLBACK] = "Fallback",
863 [MV88E6XXX_PORT_CTL2_8021Q_MODE_CHECK] = "Check",
864 [MV88E6XXX_PORT_CTL2_8021Q_MODE_SECURE] = "Secure",
867 static int mv88e6185_port_set_default_forward(struct mv88e6xxx_chip *chip,
868 int port, bool multicast)
873 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®);
878 reg |= MV88E6XXX_PORT_CTL2_DEFAULT_FORWARD;
880 reg &= ~MV88E6XXX_PORT_CTL2_DEFAULT_FORWARD;
882 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
885 int mv88e6185_port_set_egress_floods(struct mv88e6xxx_chip *chip, int port,
886 bool unicast, bool multicast)
890 err = mv88e6185_port_set_forward_unknown(chip, port, unicast);
894 return mv88e6185_port_set_default_forward(chip, port, multicast);
897 int mv88e6095_port_set_upstream_port(struct mv88e6xxx_chip *chip, int port,
903 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®);
907 reg &= ~MV88E6095_PORT_CTL2_CPU_PORT_MASK;
908 reg |= upstream_port;
910 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
913 int mv88e6xxx_port_set_8021q_mode(struct mv88e6xxx_chip *chip, int port,
919 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®);
923 reg &= ~MV88E6XXX_PORT_CTL2_8021Q_MODE_MASK;
924 reg |= mode & MV88E6XXX_PORT_CTL2_8021Q_MODE_MASK;
926 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
930 dev_dbg(chip->dev, "p%d: 802.1QMode set to %s\n", port,
931 mv88e6xxx_port_8021q_mode_names[mode]);
936 int mv88e6xxx_port_set_map_da(struct mv88e6xxx_chip *chip, int port)
941 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®);
945 reg |= MV88E6XXX_PORT_CTL2_MAP_DA;
947 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
950 int mv88e6165_port_set_jumbo_size(struct mv88e6xxx_chip *chip, int port,
956 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®);
960 reg &= ~MV88E6XXX_PORT_CTL2_JUMBO_MODE_MASK;
963 reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_1522;
964 else if (size <= 2048)
965 reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_2048;
966 else if (size <= 10240)
967 reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_10240;
971 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
974 /* Offset 0x09: Port Rate Control */
976 int mv88e6095_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port)
978 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_EGRESS_RATE_CTL1,
982 int mv88e6097_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port)
984 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_EGRESS_RATE_CTL1,
988 /* Offset 0x0C: Port ATU Control */
990 int mv88e6xxx_port_disable_learn_limit(struct mv88e6xxx_chip *chip, int port)
992 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ATU_CTL, 0);
995 /* Offset 0x0D: (Priority) Override Register */
997 int mv88e6xxx_port_disable_pri_override(struct mv88e6xxx_chip *chip, int port)
999 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_PRI_OVERRIDE, 0);
1002 /* Offset 0x0f: Port Ether type */
1004 int mv88e6351_port_set_ether_type(struct mv88e6xxx_chip *chip, int port,
1007 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ETH_TYPE, etype);
1010 /* Offset 0x18: Port IEEE Priority Remapping Registers [0-3]
1011 * Offset 0x19: Port IEEE Priority Remapping Registers [4-7]
1014 int mv88e6095_port_tag_remap(struct mv88e6xxx_chip *chip, int port)
1018 /* Use a direct priority mapping for all IEEE tagged frames */
1019 err = mv88e6xxx_port_write(chip, port,
1020 MV88E6095_PORT_IEEE_PRIO_REMAP_0123,
1025 return mv88e6xxx_port_write(chip, port,
1026 MV88E6095_PORT_IEEE_PRIO_REMAP_4567,
1030 static int mv88e6xxx_port_ieeepmt_write(struct mv88e6xxx_chip *chip,
1031 int port, u16 table, u8 ptr, u16 data)
1035 reg = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_UPDATE | table |
1036 (ptr << __bf_shf(MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_PTR_MASK)) |
1037 (data & MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_DATA_MASK);
1039 return mv88e6xxx_port_write(chip, port,
1040 MV88E6390_PORT_IEEE_PRIO_MAP_TABLE, reg);
1043 int mv88e6390_port_tag_remap(struct mv88e6xxx_chip *chip, int port)
1048 for (i = 0; i <= 7; i++) {
1049 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_INGRESS_PCP;
1050 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i,
1055 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_GREEN_PCP;
1056 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i);
1060 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_YELLOW_PCP;
1061 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i);
1065 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_AVB_PCP;
1066 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i);