diff mbox

[OpenWrt-Devel,1/3] b53: add swconfig logic to enable/disable management

Message ID 1424877864-30726-1-git-send-email-ardeleanalex@gmail.com
State Rejected
Delegated to: Jonas Gorski
Headers show

Commit Message

Alexandru Ardelean Feb. 25, 2015, 3:24 p.m. UTC
Feature implemented and tested on BCM53128.

This enables the Managed Mode of the b53 switch.
Two things need setup after the managed mode bit is set.
 - The CPU port needs to be explicitly enabled.
   CPU ports seems disabled by default when managed mode is enabled
 - The Broadcom Tag/Header needs to be explicitly disabled.
   When managed mode is enabled, frames seem to include tag bytes
   when sent to the CPU, because the tag is enabled by default.

After it's enabled, it will behave like unmanaged modei
plus some extra behaviour.
In unmanaged mode, the switch chip tries to be smart about
dropping some frames based on IEEE standards.
Specifically regarding reserved multicast addresses that
get dropped in unmanaged mode.

Signed-off-by: Alexandru Ardelean <ardeleanalex@gmail.com>
---
 .../generic/files/drivers/net/phy/b53/b53_common.c | 55 ++++++++++++++++++++++
 .../generic/files/drivers/net/phy/b53/b53_priv.h   |  1 +
 .../generic/files/drivers/net/phy/b53/b53_regs.h   |  4 ++
 3 files changed, 60 insertions(+)
diff mbox

Patch

diff --git a/target/linux/generic/files/drivers/net/phy/b53/b53_common.c b/target/linux/generic/files/drivers/net/phy/b53/b53_common.c
index fd1e78a..a7093ee 100644
--- a/target/linux/generic/files/drivers/net/phy/b53/b53_common.c
+++ b/target/linux/generic/files/drivers/net/phy/b53/b53_common.c
@@ -317,6 +317,29 @@  static void b53_enable_vlan(struct b53_device *dev, int enable)
 	b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, mgmt);
 }
 
+static void b53_enable_management(struct b53_device *dev)
+{
+	u8 mgmt, gc;
+	u8 brcm_hdr_ctrl;
+
+	/* Management has been disabled by by clearing the SM_SW_FWD_MODE bit
+	 * in b53_enable_vlan() or b53_reset_switch() */
+	if (!dev->enable_management)
+		return;
+	b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, &mgmt);
+	b53_read8(dev, B53_MGMT_PAGE, B53_GLOBAL_CONFIG, &gc);
+	b53_read8(dev, B53_MGMT_PAGE, B53_BRCM_HDR_CTRL, &brcm_hdr_ctrl);
+
+	mgmt |= SM_SW_FWD_MODE;
+	gc |= GC_FRM_MGMT_PORT_MII;
+	/* Chip inserts tag in frame when managed mode is on; not needed yet */
+	brcm_hdr_ctrl &= ~B53_BRCM_HDR_EN;
+
+	b53_write8(dev, B53_CTRL_PAGE, B53_BRCM_HDR_CTRL, brcm_hdr_ctrl);
+	b53_write8(dev, B53_MGMT_PAGE, B53_GLOBAL_CONFIG, gc);
+	b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, mgmt);
+}
+
 static int b53_set_jumbo(struct b53_device *dev, int enable, int allow_10_100)
 {
 	u32 port_mask = 0;
@@ -669,6 +692,7 @@  static int b53_apply(struct b53_device *dev)
 
 	if (!is5325(dev) && !is5365(dev))
 		b53_set_jumbo(dev, dev->enable_jumbo, 1);
+	b53_enable_management(dev);
 
 	return 0;
 }
@@ -1320,6 +1344,28 @@  static int b53_port_get_link(struct switch_dev *dev, int port,
 
 }
 
+static int b53_global_get_management(struct switch_dev *dev,
+			const struct switch_attr *attr,
+			struct switch_val *val)
+{
+	struct b53_device *priv = sw_to_b53(dev);
+
+	val->value.i = priv->enable_management;
+
+	return 0;
+}
+
+static int b53_global_set_management(struct switch_dev *dev,
+			const struct switch_attr *attr,
+			struct switch_val *val)
+{
+	struct b53_device *priv = sw_to_b53(dev);
+
+	priv->enable_management = val->value.i;
+
+	return 0;
+}
+
 static int b53_global_reset_switch(struct switch_dev *dev)
 {
 	struct b53_device *priv = sw_to_b53(dev);
@@ -1328,6 +1374,7 @@  static int b53_global_reset_switch(struct switch_dev *dev)
 	priv->enable_vlan = 0;
 	priv->enable_jumbo = 0;
 	priv->allow_vid_4095 = 0;
+	priv->enable_management = 0;
 
 	memset(priv->vlans, 0, sizeof(priv->vlans) * dev->vlans);
 	memset(priv->ports, 0, sizeof(priv->ports) * dev->ports);
@@ -1495,6 +1542,14 @@  static struct switch_attr b53_global_ops[] = {
 		.get = b53_global_get_4095_enable,
 		.max = 1,
 	},
+	{
+		.type = SWITCH_TYPE_INT,
+		.name = "enable_management",
+		.description = "Enable Management",
+		.set = b53_global_set_management,
+		.get = b53_global_get_management,
+		.max = 1,
+	},
 #ifdef CONFIG_B53_HW_DEBUG_FEATURES
 	{
 		.type = SWITCH_TYPE_STRING,
diff --git a/target/linux/generic/files/drivers/net/phy/b53/b53_priv.h b/target/linux/generic/files/drivers/net/phy/b53/b53_priv.h
index 395a76c..15df201 100644
--- a/target/linux/generic/files/drivers/net/phy/b53/b53_priv.h
+++ b/target/linux/generic/files/drivers/net/phy/b53/b53_priv.h
@@ -130,6 +130,7 @@  struct b53_device {
 	unsigned enable_vlan:1;
 	unsigned enable_jumbo:1;
 	unsigned allow_vid_4095:1;
+	unsigned enable_management:1;
 #ifdef CONFIG_B53_HW_DEBUG_FEATURES
 	struct {
 		unsigned enable:1;
diff --git a/target/linux/generic/files/drivers/net/phy/b53/b53_regs.h b/target/linux/generic/files/drivers/net/phy/b53/b53_regs.h
index 33a763c..c429fd3 100644
--- a/target/linux/generic/files/drivers/net/phy/b53/b53_regs.h
+++ b/target/linux/generic/files/drivers/net/phy/b53/b53_regs.h
@@ -166,6 +166,10 @@  static inline u64 b53_mac_array_to_u64(const u8 *u8_arr) {
 #define   GC_FRM_MGMT_PORT_04		0x00
 #define   GC_FRM_MGMT_PORT_MII		0x80
 
+/* Broadcom Header Control Register (8 bit) */
+#define B53_BRCM_HDR_CTRL		0x03
+#define   B53_BRCM_HDR_EN		BIT(0)
+
 /* Mirror Capture Control Register (16 bit) */
 #define B53_MIRROR_CTRL			0x10
 #define   B53_CAP_PORT_SET(r,p)		(r = (r & ~0x0f) | (p & 0x0f))