diff options
author | Felix Fietkau <nbd@openwrt.org> | 2015-07-15 08:17:28 +0000 |
---|---|---|
committer | Felix Fietkau <nbd@openwrt.org> | 2015-07-15 08:17:28 +0000 |
commit | 1abbabaceaef3b0bc877548f04ef7805cbd1c600 (patch) | |
tree | e740e006678384d12de814499b3377ded798302d /target/linux/generic/files/drivers/net | |
parent | 7598d1194406091a37a76601c84c9b4965d67a84 (diff) | |
download | master-187ad058-1abbabaceaef3b0bc877548f04ef7805cbd1c600.tar.gz master-187ad058-1abbabaceaef3b0bc877548f04ef7805cbd1c600.tar.bz2 master-187ad058-1abbabaceaef3b0bc877548f04ef7805cbd1c600.zip |
ar8216: add ARL table flushing per port
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>
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@46380 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/generic/files/drivers/net')
4 files changed, 47 insertions, 4 deletions
diff --git a/target/linux/generic/files/drivers/net/phy/ar8216.c b/target/linux/generic/files/drivers/net/phy/ar8216.c index 595f144ddb..f4c7b8d1e9 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 934a8b5cc1..5abbd55cc1 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 a6dd7d8e26..fd4a2626ed 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 29eeb6271d..8d1fb3b943 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 |