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 | 00e599b0b7ff50c78a1b6ac2f2db1478f6bca358 (patch) | |
tree | 023aaced6bddb939dd27edae4d5b234993b9d74a /target | |
parent | 2666403c3a850088a440d65f1a49004f1e9d926c (diff) | |
download | mtk-20170518-00e599b0b7ff50c78a1b6ac2f2db1478f6bca358.zip mtk-20170518-00e599b0b7ff50c78a1b6ac2f2db1478f6bca358.tar.gz mtk-20170518-00e599b0b7ff50c78a1b6ac2f2db1478f6bca358.tar.bz2 |
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>
SVN-Revision: 46380
Diffstat (limited to 'target')
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 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 a6dd7d8..fd4a262 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 |