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);
391 int mv88e6xxx_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode)
396 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®);
400 *cmode = reg & MV88E6XXX_PORT_STS_CMODE_MASK;
405 int mv88e6xxx_port_link_state(struct mv88e6xxx_chip *chip, int port,
406 struct phylink_link_state *state)
411 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®);
415 switch (reg & MV88E6XXX_PORT_STS_SPEED_MASK) {
416 case MV88E6XXX_PORT_STS_SPEED_10:
417 state->speed = SPEED_10;
419 case MV88E6XXX_PORT_STS_SPEED_100:
420 state->speed = SPEED_100;
422 case MV88E6XXX_PORT_STS_SPEED_1000:
423 state->speed = SPEED_1000;
425 case MV88E6XXX_PORT_STS_SPEED_10000:
426 if ((reg &MV88E6XXX_PORT_STS_CMODE_MASK) ==
427 MV88E6XXX_PORT_STS_CMODE_2500BASEX)
428 state->speed = SPEED_2500;
430 state->speed = SPEED_10000;
434 state->duplex = reg & MV88E6XXX_PORT_STS_DUPLEX ?
435 DUPLEX_FULL : DUPLEX_HALF;
436 state->link = !!(reg & MV88E6XXX_PORT_STS_LINK);
437 state->an_enabled = 1;
438 state->an_complete = state->link;
443 /* Offset 0x02: Jamming Control
445 * Do not limit the period of time that this port can be paused for by
446 * the remote end or the period of time that this port can pause the
449 int mv88e6097_port_pause_limit(struct mv88e6xxx_chip *chip, int port, u8 in,
452 return mv88e6xxx_port_write(chip, port, MV88E6097_PORT_JAM_CTL,
456 int mv88e6390_port_pause_limit(struct mv88e6xxx_chip *chip, int port, u8 in,
461 err = mv88e6xxx_port_write(chip, port, MV88E6390_PORT_FLOW_CTL,
462 MV88E6390_PORT_FLOW_CTL_UPDATE |
463 MV88E6390_PORT_FLOW_CTL_LIMIT_IN | in);
467 return mv88e6xxx_port_write(chip, port, MV88E6390_PORT_FLOW_CTL,
468 MV88E6390_PORT_FLOW_CTL_UPDATE |
469 MV88E6390_PORT_FLOW_CTL_LIMIT_OUT | out);
472 /* Offset 0x04: Port Control Register */
474 static const char * const mv88e6xxx_port_state_names[] = {
475 [MV88E6XXX_PORT_CTL0_STATE_DISABLED] = "Disabled",
476 [MV88E6XXX_PORT_CTL0_STATE_BLOCKING] = "Blocking/Listening",
477 [MV88E6XXX_PORT_CTL0_STATE_LEARNING] = "Learning",
478 [MV88E6XXX_PORT_CTL0_STATE_FORWARDING] = "Forwarding",
481 int mv88e6xxx_port_set_state(struct mv88e6xxx_chip *chip, int port, u8 state)
486 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®);
490 reg &= ~MV88E6XXX_PORT_CTL0_STATE_MASK;
493 case BR_STATE_DISABLED:
494 state = MV88E6XXX_PORT_CTL0_STATE_DISABLED;
496 case BR_STATE_BLOCKING:
497 case BR_STATE_LISTENING:
498 state = MV88E6XXX_PORT_CTL0_STATE_BLOCKING;
500 case BR_STATE_LEARNING:
501 state = MV88E6XXX_PORT_CTL0_STATE_LEARNING;
503 case BR_STATE_FORWARDING:
504 state = MV88E6XXX_PORT_CTL0_STATE_FORWARDING;
512 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
516 dev_dbg(chip->dev, "p%d: PortState set to %s\n", port,
517 mv88e6xxx_port_state_names[state]);
522 int mv88e6xxx_port_set_egress_mode(struct mv88e6xxx_chip *chip, int port,
523 enum mv88e6xxx_egress_mode mode)
528 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®);
532 reg &= ~MV88E6XXX_PORT_CTL0_EGRESS_MODE_MASK;
535 case MV88E6XXX_EGRESS_MODE_UNMODIFIED:
536 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNMODIFIED;
538 case MV88E6XXX_EGRESS_MODE_UNTAGGED:
539 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNTAGGED;
541 case MV88E6XXX_EGRESS_MODE_TAGGED:
542 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_TAGGED;
544 case MV88E6XXX_EGRESS_MODE_ETHERTYPE:
545 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_ETHER_TYPE_DSA;
551 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
554 int mv88e6085_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port,
555 enum mv88e6xxx_frame_mode mode)
560 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®);
564 reg &= ~MV88E6XXX_PORT_CTL0_FRAME_MODE_MASK;
567 case MV88E6XXX_FRAME_MODE_NORMAL:
568 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_NORMAL;
570 case MV88E6XXX_FRAME_MODE_DSA:
571 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_DSA;
577 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
580 int mv88e6351_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port,
581 enum mv88e6xxx_frame_mode mode)
586 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®);
590 reg &= ~MV88E6XXX_PORT_CTL0_FRAME_MODE_MASK;
593 case MV88E6XXX_FRAME_MODE_NORMAL:
594 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_NORMAL;
596 case MV88E6XXX_FRAME_MODE_DSA:
597 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_DSA;
599 case MV88E6XXX_FRAME_MODE_PROVIDER:
600 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_PROVIDER;
602 case MV88E6XXX_FRAME_MODE_ETHERTYPE:
603 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_ETHER_TYPE_DSA;
609 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
612 static int mv88e6185_port_set_forward_unknown(struct mv88e6xxx_chip *chip,
613 int port, bool unicast)
618 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®);
623 reg |= MV88E6185_PORT_CTL0_FORWARD_UNKNOWN;
625 reg &= ~MV88E6185_PORT_CTL0_FORWARD_UNKNOWN;
627 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
630 int mv88e6352_port_set_egress_floods(struct mv88e6xxx_chip *chip, int port,
631 bool unicast, bool multicast)
636 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®);
640 reg &= ~MV88E6352_PORT_CTL0_EGRESS_FLOODS_MASK;
642 if (unicast && multicast)
643 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_ALL_UNKNOWN_DA;
645 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_MC_DA;
647 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_UC_DA;
649 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_DA;
651 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
654 /* Offset 0x05: Port Control 1 */
656 int mv88e6xxx_port_set_message_port(struct mv88e6xxx_chip *chip, int port,
662 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1, &val);
667 val |= MV88E6XXX_PORT_CTL1_MESSAGE_PORT;
669 val &= ~MV88E6XXX_PORT_CTL1_MESSAGE_PORT;
671 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL1, val);
674 /* Offset 0x06: Port Based VLAN Map */
676 int mv88e6xxx_port_set_vlan_map(struct mv88e6xxx_chip *chip, int port, u16 map)
678 const u16 mask = mv88e6xxx_port_mask(chip);
682 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, ®);
689 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_BASE_VLAN, reg);
693 dev_dbg(chip->dev, "p%d: VLANTable set to %.3x\n", port, map);
698 int mv88e6xxx_port_get_fid(struct mv88e6xxx_chip *chip, int port, u16 *fid)
700 const u16 upper_mask = (mv88e6xxx_num_databases(chip) - 1) >> 4;
704 /* Port's default FID lower 4 bits are located in reg 0x06, offset 12 */
705 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, ®);
709 *fid = (reg & 0xf000) >> 12;
711 /* Port's default FID upper bits are located in reg 0x05, offset 0 */
713 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1,
718 *fid |= (reg & upper_mask) << 4;
724 int mv88e6xxx_port_set_fid(struct mv88e6xxx_chip *chip, int port, u16 fid)
726 const u16 upper_mask = (mv88e6xxx_num_databases(chip) - 1) >> 4;
730 if (fid >= mv88e6xxx_num_databases(chip))
733 /* Port's default FID lower 4 bits are located in reg 0x06, offset 12 */
734 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, ®);
739 reg |= (fid & 0x000f) << 12;
741 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_BASE_VLAN, reg);
745 /* Port's default FID upper bits are located in reg 0x05, offset 0 */
747 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1,
753 reg |= (fid >> 4) & upper_mask;
755 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL1,
761 dev_dbg(chip->dev, "p%d: FID set to %u\n", port, fid);
766 /* Offset 0x07: Default Port VLAN ID & Priority */
768 int mv88e6xxx_port_get_pvid(struct mv88e6xxx_chip *chip, int port, u16 *pvid)
773 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN,
778 *pvid = reg & MV88E6XXX_PORT_DEFAULT_VLAN_MASK;
783 int mv88e6xxx_port_set_pvid(struct mv88e6xxx_chip *chip, int port, u16 pvid)
788 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN,
793 reg &= ~MV88E6XXX_PORT_DEFAULT_VLAN_MASK;
794 reg |= pvid & MV88E6XXX_PORT_DEFAULT_VLAN_MASK;
796 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN,
801 dev_dbg(chip->dev, "p%d: DefaultVID set to %u\n", port, pvid);
806 /* Offset 0x08: Port Control 2 Register */
808 static const char * const mv88e6xxx_port_8021q_mode_names[] = {
809 [MV88E6XXX_PORT_CTL2_8021Q_MODE_DISABLED] = "Disabled",
810 [MV88E6XXX_PORT_CTL2_8021Q_MODE_FALLBACK] = "Fallback",
811 [MV88E6XXX_PORT_CTL2_8021Q_MODE_CHECK] = "Check",
812 [MV88E6XXX_PORT_CTL2_8021Q_MODE_SECURE] = "Secure",
815 static int mv88e6185_port_set_default_forward(struct mv88e6xxx_chip *chip,
816 int port, bool multicast)
821 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®);
826 reg |= MV88E6XXX_PORT_CTL2_DEFAULT_FORWARD;
828 reg &= ~MV88E6XXX_PORT_CTL2_DEFAULT_FORWARD;
830 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
833 int mv88e6185_port_set_egress_floods(struct mv88e6xxx_chip *chip, int port,
834 bool unicast, bool multicast)
838 err = mv88e6185_port_set_forward_unknown(chip, port, unicast);
842 return mv88e6185_port_set_default_forward(chip, port, multicast);
845 int mv88e6095_port_set_upstream_port(struct mv88e6xxx_chip *chip, int port,
851 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®);
855 reg &= ~MV88E6095_PORT_CTL2_CPU_PORT_MASK;
856 reg |= upstream_port;
858 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
861 int mv88e6xxx_port_set_8021q_mode(struct mv88e6xxx_chip *chip, int port,
867 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®);
871 reg &= ~MV88E6XXX_PORT_CTL2_8021Q_MODE_MASK;
872 reg |= mode & MV88E6XXX_PORT_CTL2_8021Q_MODE_MASK;
874 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
878 dev_dbg(chip->dev, "p%d: 802.1QMode set to %s\n", port,
879 mv88e6xxx_port_8021q_mode_names[mode]);
884 int mv88e6xxx_port_set_map_da(struct mv88e6xxx_chip *chip, int port)
889 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®);
893 reg |= MV88E6XXX_PORT_CTL2_MAP_DA;
895 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
898 int mv88e6165_port_set_jumbo_size(struct mv88e6xxx_chip *chip, int port,
904 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®);
908 reg &= ~MV88E6XXX_PORT_CTL2_JUMBO_MODE_MASK;
911 reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_1522;
912 else if (size <= 2048)
913 reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_2048;
914 else if (size <= 10240)
915 reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_10240;
919 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
922 /* Offset 0x09: Port Rate Control */
924 int mv88e6095_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port)
926 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_EGRESS_RATE_CTL1,
930 int mv88e6097_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port)
932 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_EGRESS_RATE_CTL1,
936 /* Offset 0x0C: Port ATU Control */
938 int mv88e6xxx_port_disable_learn_limit(struct mv88e6xxx_chip *chip, int port)
940 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ATU_CTL, 0);
943 /* Offset 0x0D: (Priority) Override Register */
945 int mv88e6xxx_port_disable_pri_override(struct mv88e6xxx_chip *chip, int port)
947 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_PRI_OVERRIDE, 0);
950 /* Offset 0x0f: Port Ether type */
952 int mv88e6351_port_set_ether_type(struct mv88e6xxx_chip *chip, int port,
955 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ETH_TYPE, etype);
958 /* Offset 0x18: Port IEEE Priority Remapping Registers [0-3]
959 * Offset 0x19: Port IEEE Priority Remapping Registers [4-7]
962 int mv88e6095_port_tag_remap(struct mv88e6xxx_chip *chip, int port)
966 /* Use a direct priority mapping for all IEEE tagged frames */
967 err = mv88e6xxx_port_write(chip, port,
968 MV88E6095_PORT_IEEE_PRIO_REMAP_0123,
973 return mv88e6xxx_port_write(chip, port,
974 MV88E6095_PORT_IEEE_PRIO_REMAP_4567,
978 static int mv88e6xxx_port_ieeepmt_write(struct mv88e6xxx_chip *chip,
979 int port, u16 table, u8 ptr, u16 data)
983 reg = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_UPDATE | table |
984 (ptr << __bf_shf(MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_PTR_MASK)) |
985 (data & MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_DATA_MASK);
987 return mv88e6xxx_port_write(chip, port,
988 MV88E6390_PORT_IEEE_PRIO_MAP_TABLE, reg);
991 int mv88e6390_port_tag_remap(struct mv88e6xxx_chip *chip, int port)
996 for (i = 0; i <= 7; i++) {
997 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_INGRESS_PCP;
998 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i,
1003 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_GREEN_PCP;
1004 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i);
1008 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_YELLOW_PCP;
1009 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i);
1013 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_AVB_PCP;
1014 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i);