mirror of
https://github.com/Ysurac/openmptcprouter.git
synced 2025-02-13 20:01:55 +00:00
151 lines
3.7 KiB
Diff
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
|
|
|