[OpenWrt-Devel,2/4] ar8216: add ARL table flushing per port
diff mbox

Message ID 54CCA02D.3040905@gmail.com
State Accepted
Delegated to: Felix Fietkau
Headers show

Commit Message

Heiner Kallweit Jan. 31, 2015, 9:28 a.m. UTC
Adds functions for flushing ARL table entries per port.

Successfully tested on AR8327. Implementation for AR8216/AR8236/AR8316
is based on the AR8236 datasheet and assumes that the three chips
share a common ATU register layout.
Compile-tested only for AR8216/AR8236/AR8316.

Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
---
 target/linux/generic/files/drivers/net/phy/ar8216.c | 19 +++++++++++++++++++
 target/linux/generic/files/drivers/net/phy/ar8216.h |  6 ++++--
 target/linux/generic/files/drivers/net/phy/ar8327.c | 20 ++++++++++++++++++++
 target/linux/generic/files/drivers/net/phy/ar8327.h |  6 ++++--
 4 files changed, 47 insertions(+), 4 deletions(-)

Patch
diff mbox

diff --git a/target/linux/generic/files/drivers/net/phy/ar8216.c b/target/linux/generic/files/drivers/net/phy/ar8216.c
index 595f144..f4c7b8d 100644
--- a/target/linux/generic/files/drivers/net/phy/ar8216.c
+++ b/target/linux/generic/files/drivers/net/phy/ar8216.c
@@ -606,6 +606,22 @@  ar8216_atu_flush(struct ar8xxx_priv *priv)
 	return ret;
 }
 
+static int
+ar8216_atu_flush_port(struct ar8xxx_priv *priv, int port)
+{
+	u32 t;
+	int ret;
+
+	ret = ar8216_wait_bit(priv, AR8216_REG_ATU_FUNC0, AR8216_ATU_ACTIVE, 0);
+	if (!ret) {
+		t = (port << AR8216_ATU_PORT_NUM_S) | AR8216_ATU_OP_FLUSH_PORT;
+		t |= AR8216_ATU_ACTIVE;
+		ar8xxx_write(priv, AR8216_REG_ATU_FUNC0, t);
+	}
+
+	return ret;
+}
+
 static u32
 ar8216_read_port_status(struct ar8xxx_priv *priv, int port)
 {
@@ -1542,6 +1558,7 @@  static const struct ar8xxx_chip ar8216_chip = {
 	.setup_port = ar8216_setup_port,
 	.read_port_status = ar8216_read_port_status,
 	.atu_flush = ar8216_atu_flush,
+	.atu_flush_port = ar8216_atu_flush_port,
 	.vtu_flush = ar8216_vtu_flush,
 	.vtu_load_vlan = ar8216_vtu_load_vlan,
 	.set_mirror_regs = ar8216_set_mirror_regs,
@@ -1570,6 +1587,7 @@  static const struct ar8xxx_chip ar8236_chip = {
 	.setup_port = ar8236_setup_port,
 	.read_port_status = ar8216_read_port_status,
 	.atu_flush = ar8216_atu_flush,
+	.atu_flush_port = ar8216_atu_flush_port,
 	.vtu_flush = ar8216_vtu_flush,
 	.vtu_load_vlan = ar8216_vtu_load_vlan,
 	.set_mirror_regs = ar8216_set_mirror_regs,
@@ -1598,6 +1616,7 @@  static const struct ar8xxx_chip ar8316_chip = {
 	.setup_port = ar8216_setup_port,
 	.read_port_status = ar8216_read_port_status,
 	.atu_flush = ar8216_atu_flush,
+	.atu_flush_port = ar8216_atu_flush_port,
 	.vtu_flush = ar8216_vtu_flush,
 	.vtu_load_vlan = ar8216_vtu_load_vlan,
 	.set_mirror_regs = ar8216_set_mirror_regs,
diff --git a/target/linux/generic/files/drivers/net/phy/ar8216.h b/target/linux/generic/files/drivers/net/phy/ar8216.h
index 934a8b5..5abbd55 100644
--- a/target/linux/generic/files/drivers/net/phy/ar8216.h
+++ b/target/linux/generic/files/drivers/net/phy/ar8216.h
@@ -85,11 +85,12 @@ 
 #define   AR8216_ATU_OP_FLUSH		0x1
 #define   AR8216_ATU_OP_LOAD		0x2
 #define   AR8216_ATU_OP_PURGE		0x3
-#define   AR8216_ATU_OP_FLUSH_LOCKED	0x4
-#define   AR8216_ATU_OP_FLUSH_UNICAST	0x5
+#define   AR8216_ATU_OP_FLUSH_UNLOCKED	0x4
+#define   AR8216_ATU_OP_FLUSH_PORT	0x5
 #define   AR8216_ATU_OP_GET_NEXT	0x6
 #define   AR8216_ATU_ACTIVE		BIT(3)
 #define   AR8216_ATU_PORT_NUM		BITS(8, 4)
+#define   AR8216_ATU_PORT_NUM_S		8
 #define   AR8216_ATU_FULL_VIO		BIT(12)
 #define   AR8216_ATU_ADDR5		BITS(16, 8)
 #define   AR8216_ATU_ADDR5_S		16
@@ -397,6 +398,7 @@  struct ar8xxx_chip {
 	u32 (*read_port_status)(struct ar8xxx_priv *priv, int port);
 	u32 (*read_port_eee_status)(struct ar8xxx_priv *priv, int port);
 	int (*atu_flush)(struct ar8xxx_priv *priv);
+	int (*atu_flush_port)(struct ar8xxx_priv *priv, int port);
 	void (*vtu_flush)(struct ar8xxx_priv *priv);
 	void (*vtu_load_vlan)(struct ar8xxx_priv *priv, u32 vid, u32 port_mask);
 	void (*phy_fixup)(struct ar8xxx_priv *priv, int phy);
diff --git a/target/linux/generic/files/drivers/net/phy/ar8327.c b/target/linux/generic/files/drivers/net/phy/ar8327.c
index 07e837e..a8d33a8 100644
--- a/target/linux/generic/files/drivers/net/phy/ar8327.c
+++ b/target/linux/generic/files/drivers/net/phy/ar8327.c
@@ -765,6 +765,24 @@  ar8327_atu_flush(struct ar8xxx_priv *priv)
 	return ret;
 }
 
+static int
+ar8327_atu_flush_port(struct ar8xxx_priv *priv, int port)
+{
+	u32 t;
+	int ret;
+
+	ret = ar8216_wait_bit(priv, AR8327_REG_ATU_FUNC,
+			      AR8327_ATU_FUNC_BUSY, 0);
+	if (!ret) {
+		t = (port << AR8327_ATU_PORT_NUM_S);
+		t |= AR8327_ATU_FUNC_OP_FLUSH_PORT;
+		t |= AR8327_ATU_FUNC_BUSY;
+		ar8xxx_write(priv, AR8327_REG_ATU_FUNC, t);
+	}
+
+	return ret;
+}
+
 static void
 ar8327_vtu_op(struct ar8xxx_priv *priv, u32 op, u32 val)
 {
@@ -1189,6 +1207,7 @@  const struct ar8xxx_chip ar8327_chip = {
 	.read_port_status = ar8327_read_port_status,
 	.read_port_eee_status = ar8327_read_port_eee_status,
 	.atu_flush = ar8327_atu_flush,
+	.atu_flush_port = ar8327_atu_flush_port,
 	.vtu_flush = ar8327_vtu_flush,
 	.vtu_load_vlan = ar8327_vtu_load_vlan,
 	.phy_fixup = ar8327_phy_fixup,
@@ -1222,6 +1241,7 @@  const struct ar8xxx_chip ar8337_chip = {
 	.read_port_status = ar8327_read_port_status,
 	.read_port_eee_status = ar8327_read_port_eee_status,
 	.atu_flush = ar8327_atu_flush,
+	.atu_flush_port = ar8327_atu_flush_port,
 	.vtu_flush = ar8327_vtu_flush,
 	.vtu_load_vlan = ar8327_vtu_load_vlan,
 	.phy_fixup = ar8327_phy_fixup,
diff --git a/target/linux/generic/files/drivers/net/phy/ar8327.h b/target/linux/generic/files/drivers/net/phy/ar8327.h
index 29eeb62..8d1fb3b 100644
--- a/target/linux/generic/files/drivers/net/phy/ar8327.h
+++ b/target/linux/generic/files/drivers/net/phy/ar8327.h
@@ -144,11 +144,13 @@ 
 #define   AR8327_ATU_FUNC_OP_FLUSH		0x1
 #define   AR8327_ATU_FUNC_OP_LOAD		0x2
 #define   AR8327_ATU_FUNC_OP_PURGE		0x3
-#define   AR8327_ATU_FUNC_OP_FLUSH_LOCKED	0x4
-#define   AR8327_ATU_FUNC_OP_FLUSH_UNICAST	0x5
+#define   AR8327_ATU_FUNC_OP_FLUSH_UNLOCKED	0x4
+#define   AR8327_ATU_FUNC_OP_FLUSH_PORT		0x5
 #define   AR8327_ATU_FUNC_OP_GET_NEXT		0x6
 #define   AR8327_ATU_FUNC_OP_SEARCH_MAC		0x7
 #define   AR8327_ATU_FUNC_OP_CHANGE_TRUNK	0x8
+#define   AR8327_ATU_PORT_NUM			BITS(8, 4)
+#define   AR8327_ATU_PORT_NUM_S			8
 #define   AR8327_ATU_FUNC_BUSY			BIT(31)
 
 #define AR8327_REG_VTU_FUNC0			0x0610