From 67b3c39a059129bc32c1db59ffc5b11f76bf91e6 Mon Sep 17 00:00:00 2001 From: =?utf8?q?G=C3=BCnther=20Kelleter?= Date: Mon, 26 Nov 2018 15:44:31 +0100 Subject: [PATCH] kernel: ar8xxx: get_arl_table now shows all ports of an entry MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Multicast ARL entries can have multiple destination ports. Get and dump all destination ports of each entry, not just the lowest. Signed-off-by: Günther Kelleter (backported from 33878b0a40707a53920ec72a92430ab420b0893f) --- .../generic/files/drivers/net/phy/ar8216.c | 18 ++++++++---------- .../generic/files/drivers/net/phy/ar8216.h | 3 ++- .../generic/files/drivers/net/phy/ar8327.c | 10 ++-------- .../generic/files/drivers/net/phy/ar8327.h | 1 + 4 files changed, 13 insertions(+), 19 deletions(-) diff --git a/target/linux/generic/files/drivers/net/phy/ar8216.c b/target/linux/generic/files/drivers/net/phy/ar8216.c index 6869e1ff19..68754e6096 100644 --- a/target/linux/generic/files/drivers/net/phy/ar8216.c +++ b/target/linux/generic/files/drivers/net/phy/ar8216.c @@ -749,7 +749,6 @@ static void ar8216_get_arl_entry(struct ar8xxx_priv *priv, u16 r2, page; u16 r1_func0, r1_func1, r1_func2; u32 t, val0, val1, val2; - int i; split_addr(AR8216_REG_ATU_FUNC0, &r1_func0, &r2, &page); r2 |= 0x10; @@ -785,12 +784,7 @@ static void ar8216_get_arl_entry(struct ar8xxx_priv *priv, if (!*status) break; - i = 0; - t = AR8216_ATU_PORT0; - while (!(val2 & t) && ++i < priv->dev.ports) - t <<= 1; - - a->port = i; + a->portmap = (val2 & AR8216_ATU_PORTS) >> AR8216_ATU_PORTS_S; a->mac[0] = (val0 & AR8216_ATU_ADDR5) >> AR8216_ATU_ADDR5_S; a->mac[1] = (val0 & AR8216_ATU_ADDR4) >> AR8216_ATU_ADDR4_S; a->mac[2] = (val1 & AR8216_ATU_ADDR3) >> AR8216_ATU_ADDR3_S; @@ -1516,8 +1510,12 @@ ar8xxx_sw_get_arl_table(struct switch_dev *dev, */ for (j = 0; j < i; ++j) { a1 = &priv->arl_table[j]; - if (a->port == a1->port && !memcmp(a->mac, a1->mac, sizeof(a->mac))) - goto duplicate; + if (!memcmp(a->mac, a1->mac, sizeof(a->mac))) { + /* ignore ports already seen in former entry */ + a->portmap &= ~a1->portmap; + if (!a->portmap) + goto duplicate; + } } } @@ -1534,7 +1532,7 @@ ar8xxx_sw_get_arl_table(struct switch_dev *dev, for (j = 0; j < priv->dev.ports; ++j) { for (k = 0; k < i; ++k) { a = &priv->arl_table[k]; - if (a->port != j) + if (!(a->portmap & BIT(j))) continue; len += snprintf(buf + len, sizeof(priv->arl_buf) - len, "Port %d: MAC %02x:%02x:%02x:%02x:%02x:%02x\n", diff --git a/target/linux/generic/files/drivers/net/phy/ar8216.h b/target/linux/generic/files/drivers/net/phy/ar8216.h index ba0e0ddccd..509818c50d 100644 --- a/target/linux/generic/files/drivers/net/phy/ar8216.h +++ b/target/linux/generic/files/drivers/net/phy/ar8216.h @@ -112,6 +112,7 @@ #define AR8216_REG_ATU_FUNC2 0x0058 #define AR8216_ATU_PORTS BITS(0, 6) +#define AR8216_ATU_PORTS_S 0 #define AR8216_ATU_PORT0 BIT(0) #define AR8216_ATU_PORT1 BIT(1) #define AR8216_ATU_PORT2 BIT(2) @@ -367,7 +368,7 @@ enum arl_op { }; struct arl_entry { - u8 port; + u16 portmap; u8 mac[6]; }; diff --git a/target/linux/generic/files/drivers/net/phy/ar8327.c b/target/linux/generic/files/drivers/net/phy/ar8327.c index 74f0a08d76..803fb3d49f 100644 --- a/target/linux/generic/files/drivers/net/phy/ar8327.c +++ b/target/linux/generic/files/drivers/net/phy/ar8327.c @@ -1057,8 +1057,7 @@ static void ar8327_get_arl_entry(struct ar8xxx_priv *priv, struct mii_bus *bus = priv->mii_bus; u16 r2, page; u16 r1_data0, r1_data1, r1_data2, r1_func; - u32 t, val0, val1, val2; - int i; + u32 val0, val1, val2; split_addr(AR8327_REG_ATU_DATA0, &r1_data0, &r2, &page); r2 |= 0x10; @@ -1095,12 +1094,7 @@ static void ar8327_get_arl_entry(struct ar8xxx_priv *priv, if (!*status) break; - i = 0; - t = AR8327_ATU_PORT0; - while (!(val1 & t) && ++i < AR8327_NUM_PORTS) - t <<= 1; - - a->port = i; + a->portmap = (val1 & AR8327_ATU_PORTS) >> AR8327_ATU_PORTS_S; a->mac[0] = (val0 & AR8327_ATU_ADDR0) >> AR8327_ATU_ADDR0_S; a->mac[1] = (val0 & AR8327_ATU_ADDR1) >> AR8327_ATU_ADDR1_S; a->mac[2] = (val0 & AR8327_ATU_ADDR2) >> AR8327_ATU_ADDR2_S; diff --git a/target/linux/generic/files/drivers/net/phy/ar8327.h b/target/linux/generic/files/drivers/net/phy/ar8327.h index d53ef885b1..38e33ea57e 100644 --- a/target/linux/generic/files/drivers/net/phy/ar8327.h +++ b/target/linux/generic/files/drivers/net/phy/ar8327.h @@ -199,6 +199,7 @@ #define AR8327_ATU_ADDR5 BITS(8, 8) #define AR8327_ATU_ADDR5_S 8 #define AR8327_ATU_PORTS BITS(16, 7) +#define AR8327_ATU_PORTS_S 16 #define AR8327_ATU_PORT0 BIT(16) #define AR8327_ATU_PORT1 BIT(17) #define AR8327_ATU_PORT2 BIT(18) -- 2.30.2