summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuiz Souza <luiz@netgate.com>2018-03-12 17:06:18 -0300
committerLuiz Souza <luiz@netgate.com>2018-03-12 12:16:48 -0500
commit606d357e808d47170ca3c3d00af4bd29272bd56c (patch)
treef163b22ac8832b1a4b591893d9b2a3c5913d1d48
parent67ff878b5e5dabfe5f9c7d93f77f18a87d2a995b (diff)
downloadFreeBSD-src-606d357e808d47170ca3c3d00af4bd29272bd56c.zip
FreeBSD-src-606d357e808d47170ca3c3d00af4bd29272bd56c.tar.gz
Allow setting the port state on Marvel e6000 series switches.
(cherry picked from commit f3f1d1d3a10e7394b0f22f634562e46b05e694be)
-rw-r--r--sys/dev/etherswitch/e6000sw/e6000sw.c58
-rw-r--r--sys/dev/etherswitch/e6000sw/e6000swreg.h6
2 files changed, 55 insertions, 9 deletions
diff --git a/sys/dev/etherswitch/e6000sw/e6000sw.c b/sys/dev/etherswitch/e6000sw/e6000sw.c
index dcf253b..6f2e94d 100644
--- a/sys/dev/etherswitch/e6000sw/e6000sw.c
+++ b/sys/dev/etherswitch/e6000sw/e6000sw.c
@@ -110,7 +110,8 @@ static etherswitch_info_t etherswitch_info = {
.es_nports = 0,
.es_nvlangroups = 0,
.es_vlan_caps = ETHERSWITCH_VLAN_PORT | ETHERSWITCH_VLAN_DOT1Q,
- .es_switch_caps = ETHERSWITCH_CAPS_PORTS_MASK,
+ .es_switch_caps = ETHERSWITCH_CAPS_PORTS_MASK |
+ ETHERSWITCH_CAPS_PSTATE,
.es_name = "Marvell 6000 series switch"
};
@@ -220,6 +221,9 @@ static SYSCTL_NODE(_hw, OID_AUTO, e6000sw, CTLFLAG_RD, 0,
static int e6000sw_eeprom_wp = TRUE;
SYSCTL_INT(_hw_e6000sw, OID_AUTO, eeprom_wp, CTLFLAG_RDTUN, &e6000sw_eeprom_wp,
0, "Enable eeprom write protect.");
+static int e6000sw_default_disabled = FALSE;
+SYSCTL_INT(_hw_e6000sw, OID_AUTO, default_disabled, CTLFLAG_RDTUN,
+ &e6000sw_default_disabled, 0, "Keep ports disabled at boot.");
#undef E6000SW_DEBUG
#if defined(E6000SW_DEBUG)
@@ -1010,6 +1014,22 @@ e6000sw_getport(device_t dev, etherswitch_port_t *p)
E6000SW_LOCK(sc);
e6000sw_get_pvid(sc, p->es_port, &p->es_pvid);
+ /* Port state. */
+ reg = e6000sw_readreg(sc, REG_PORT(sc, p->es_port), PORT_CONTROL);
+ switch (reg & PORT_CONTROL_ENABLE) {
+ case PORT_CONTROL_BLOCKING:
+ p->es_state = ETHERSWITCH_PSTATE_BLOCKING;
+ break;
+ case PORT_CONTROL_LEARNING:
+ p->es_state = ETHERSWITCH_PSTATE_LEARNING;
+ break;
+ case PORT_CONTROL_FORWARDING:
+ p->es_state = ETHERSWITCH_PSTATE_FORWARDING;
+ break;
+ default:
+ p->es_state = ETHERSWITCH_PSTATE_DISABLED;
+ }
+
/* Port flags. */
reg = e6000sw_readreg(sc, REG_PORT(sc, p->es_port), PORT_CONTROL2);
if (reg & PORT_CONTROL2_DISC_TAGGED)
@@ -1059,6 +1079,26 @@ e6000sw_setport(device_t dev, etherswitch_port_t *p)
err = 0;
E6000SW_LOCK(sc);
+
+ /* Port state. */
+ reg = e6000sw_readreg(sc, REG_PORT(sc, p->es_port), PORT_CONTROL);
+ reg &= ~PORT_CONTROL_ENABLE;
+ switch (p->es_state) {
+ case ETHERSWITCH_PSTATE_BLOCKING:
+ reg |= PORT_CONTROL_BLOCKING;
+ break;
+ case ETHERSWITCH_PSTATE_LEARNING:
+ reg |= PORT_CONTROL_LEARNING;
+ break;
+ case ETHERSWITCH_PSTATE_FORWARDING:
+ reg |= PORT_CONTROL_FORWARDING;
+ break;
+ default:
+ reg |= PORT_CONTROL_DISABLED;
+ }
+ e6000sw_writereg(sc, REG_PORT(sc, p->es_port), PORT_CONTROL, reg);
+
+ /* Port flags. */
reg = e6000sw_readreg(sc, REG_PORT(sc, p->es_port), PORT_CONTROL2);
if (p->es_flags & ETHERSWITCH_PORT_DROPTAGGED)
reg |= PORT_CONTROL2_DISC_TAGGED;
@@ -1175,13 +1215,15 @@ e6000sw_init_vlan(struct e6000sw_softc *sc)
e6000sw_vtu_update(sc, 0, sc->vlans[0], 1, 0, sc->ports_mask);
}
- /* Enable all ports */
- for (port = 0; port < sc->num_ports; port++) {
- if (!e6000sw_is_portenabled(sc, port))
- continue;
- ret = e6000sw_readreg(sc, REG_PORT(sc, port), PORT_CONTROL);
- e6000sw_writereg(sc, REG_PORT(sc, port), PORT_CONTROL,
- (ret | PORT_CONTROL_ENABLE));
+ if (e6000sw_default_disabled == false) {
+ /* Enable all ports */
+ for (port = 0; port < sc->num_ports; port++) {
+ if (!e6000sw_is_portenabled(sc, port))
+ continue;
+ ret = e6000sw_readreg(sc, REG_PORT(sc, port), PORT_CONTROL);
+ e6000sw_writereg(sc, REG_PORT(sc, port), PORT_CONTROL,
+ (ret | PORT_CONTROL_ENABLE));
+ }
}
#if defined(E6000SW_DEBUG)
diff --git a/sys/dev/etherswitch/e6000sw/e6000swreg.h b/sys/dev/etherswitch/e6000sw/e6000swreg.h
index 74b73c1..4f25547 100644
--- a/sys/dev/etherswitch/e6000sw/e6000swreg.h
+++ b/sys/dev/etherswitch/e6000sw/e6000swreg.h
@@ -103,7 +103,11 @@ struct atu_opt {
#define PORT_VID_DEF_VID_MASK 0xfff
#define PORT_VID_PRIORITY_MASK 0xc00
-#define PORT_CONTROL_ENABLE 0x0003
+#define PORT_CONTROL_DISABLED 0
+#define PORT_CONTROL_BLOCKING 1
+#define PORT_CONTROL_LEARNING 2
+#define PORT_CONTROL_FORWARDING 3
+#define PORT_CONTROL_ENABLE 3
#define PORT_CONTROL_FRAME 0x0300
#define PORT_CONTROL_EGRESS 0x3000
#define PORT_CONTROL2_DOT1Q 0x0c00
OpenPOWER on IntegriCloud