1
0
Fork 0
mirror of https://github.com/Ysurac/openmptcprouter.git synced 2025-02-13 20:01:55 +00:00
openmptcprouter/root/target/linux/ipq40xx/patches-5.4/717-ar40xx-dump-arl-support.patch
Ycarus (Yannick Chabanois) 0b14e36374 Fix RUTX support
2022-03-07 20:21:35 +01:00

151 lines
3.7 KiB
Diff

--- a/drivers/net/phy/ar40xx.c
+++ b/drivers/net/phy/ar40xx.c
@@ -82,6 +82,13 @@
MIB_DESC(1, AR40XX_STATS_TXLATECOL, "TxLateCol"),
};
+static int
+ar40xx_atu_flush(struct ar40xx_priv *);
+
+static int
+ar40xx_atu_dump(struct ar40xx_priv *);
+
+
static u32
ar40xx_read(struct ar40xx_priv *priv, int reg)
{
@@ -810,6 +817,35 @@
}
ar40xx_phy_poll_reset(priv);
+
+ return 0;
+}
+
+static int
+ar40xx_sw_atu_flush(struct switch_dev *dev,
+ const struct switch_attr *attr,
+ struct switch_val *val)
+{
+ struct ar40xx_priv *priv = swdev_to_ar40xx(dev);
+
+ return ar40xx_atu_flush(priv);
+}
+
+static int
+ar40xx_sw_atu_dump(struct switch_dev *dev,
+ const struct switch_attr *attr,
+ struct switch_val *val)
+{
+ struct ar40xx_priv *priv = swdev_to_ar40xx(dev);
+ int len=0;
+
+ len = ar40xx_atu_dump(priv);
+ if(len >= 0){
+ val->value.s = priv->buf;
+ val->len = len;
+ } else {
+ val->len = -1;
+ }
return 0;
}
@@ -868,6 +904,18 @@
.max = AR40XX_NUM_PORTS - 1
},
{
+ .type = SWITCH_TYPE_NOVAL,
+ .name = "flush_arl",
+ .description = "Flush ARL table",
+ .set = ar40xx_sw_atu_flush,
+ },
+ {
+ .type = SWITCH_TYPE_STRING,
+ .name = "dump_arl",
+ .description = "Dump ARL table with mac and port map",
+ .get = ar40xx_sw_atu_dump,
+ },
+ {
.type = SWITCH_TYPE_INT,
.name = "linkdown",
.description = "Link down all the PHYs",
@@ -925,6 +973,65 @@
pr_err("ar40xx: timeout for reg %08x: %08x & %08x != %08x\n",
(unsigned int)reg, t, mask, val);
return -ETIMEDOUT;
+}
+
+static int
+ar40xx_atu_dump(struct ar40xx_priv *priv)
+{
+ u32 ret;
+ u32 i = 0, len = 0, entry_len = 0;
+ volatile u32 reg[4] = {0,0,0,0};
+ u8 addr[ETH_ALEN] = { 0 };
+ char *buf;
+
+ buf = priv->buf;
+ memset(priv->buf, 0, sizeof(priv->buf));
+ do {
+ ret = ar40xx_wait_bit(priv, AR40XX_REG_ATU_FUNC,
+ AR40XX_ATU_FUNC_BUSY, 0);
+ if(ret != 0)
+ return -ETIMEDOUT;
+
+ reg[3] = AR40XX_ATU_FUNC_BUSY | AR40XX_ATU_FUNC_OP_GET_NEXT;
+ ar40xx_write(priv, AR40XX_REG_ATU_DATA0, reg[0]);
+ ar40xx_write(priv, AR40XX_REG_ATU_DATA1, reg[1]);
+ ar40xx_write(priv, AR40XX_REG_ATU_DATA2, reg[2]);
+ ar40xx_write(priv, AR40XX_REG_ATU_FUNC, reg[3]);
+
+ ret = ar40xx_wait_bit(priv, AR40XX_REG_ATU_FUNC,
+ AR40XX_ATU_FUNC_BUSY, 0);
+ if(ret != 0)
+ return -ETIMEDOUT;
+
+ reg[0] = ar40xx_read(priv, AR40XX_REG_ATU_DATA0);
+ reg[1] = ar40xx_read(priv, AR40XX_REG_ATU_DATA1);
+ reg[2] = ar40xx_read(priv, AR40XX_REG_ATU_DATA2);
+ reg[3] = ar40xx_read(priv, AR40XX_REG_ATU_FUNC);
+
+ if((reg[2] & 0xf) == 0)
+ break;
+
+ for(i=2; i<6; i++)
+ addr[i] = (reg[0] >> ((5 - i) << 3)) & 0xff;
+ for(i=0; i<2; i++)
+ addr[i] = (reg[1] >> ((1 - i) << 3)) & 0xff;
+
+ len += snprintf(buf + len, sizeof(priv->buf) - len, "MAC: %02x:%02x:%02x:%02x:%02x:%02x ",
+ addr[0],addr[1],addr[2],addr[3],addr[4],addr[5]);
+ len += snprintf(buf + len, sizeof(priv->buf) - len, "PORTMAP: 0x%02x ", ((reg[1] >> 16) & 0x7f));
+
+ len += snprintf(buf + len, sizeof(priv->buf) - len, "VID: 0x%x ", ((reg[2] >> 8) & 0xfff));
+
+ len += snprintf(buf + len, sizeof(priv->buf) - len, "STATUS: 0x%x\n", ((reg[2] & 0xf) == 0xf ? 1 : 0));
+
+ if (!entry_len)
+ entry_len = len;
+
+ if (sizeof(priv->buf) - len <= entry_len)
+ break;
+ } while(1);
+
+ return len;
}
static int
--- a/drivers/net/phy/ar40xx.h
+++ b/drivers/net/phy/ar40xx.h
@@ -243,6 +243,10 @@
#define AR40XX_PORT_LOOKUP_LOOPBACK BIT(21)
#define AR40XX_PORT_LOOKUP_ING_MIRROR_EN BIT(25)
+#define AR40XX_REG_ATU_DATA0 0x600
+#define AR40XX_REG_ATU_DATA1 0x604
+#define AR40XX_REG_ATU_DATA2 0x608
+
#define AR40XX_REG_ATU_FUNC 0x60c
#define AR40XX_ATU_FUNC_OP BITS(0, 4)
#define AR40XX_ATU_FUNC_OP_NOOP 0x0