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
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)
{
.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,
.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,
.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,
#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
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);
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)
{
.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,
.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,
#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