mirror of
https://github.com/hanwckf/immortalwrt-mt798x.git
synced 2025-01-09 18:59:13 +08:00
ramips: add arl_table support for MT7530
Use switch.h API to expose MT7530's ARL table to user space. Signed-off-by: Salvatore Mesoraca <salvatore@samknows.com>
This commit is contained in:
parent
cc66580293
commit
2a43ab4a18
@ -31,6 +31,7 @@
|
|||||||
#include <linux/lockdep.h>
|
#include <linux/lockdep.h>
|
||||||
#include <linux/workqueue.h>
|
#include <linux/workqueue.h>
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
|
#include <asm/byteorder.h>
|
||||||
|
|
||||||
#include "mt7530.h"
|
#include "mt7530.h"
|
||||||
|
|
||||||
@ -43,6 +44,8 @@
|
|||||||
#endif
|
#endif
|
||||||
#define MT7530_MAX_VID 4095
|
#define MT7530_MAX_VID 4095
|
||||||
#define MT7530_MIN_VID 0
|
#define MT7530_MIN_VID 0
|
||||||
|
#define MT7530_NUM_ARL_RECORDS 2048
|
||||||
|
#define ARL_LINE_LENGTH 30
|
||||||
|
|
||||||
#define MT7530_PORT_MIB_TXB_ID 2 /* TxGOC */
|
#define MT7530_PORT_MIB_TXB_ID 2 /* TxGOC */
|
||||||
#define MT7530_PORT_MIB_RXB_ID 6 /* RxGOC */
|
#define MT7530_PORT_MIB_RXB_ID 6 /* RxGOC */
|
||||||
@ -61,6 +64,20 @@
|
|||||||
#define REG_ESW_VLAN_VAWD2 0x98
|
#define REG_ESW_VLAN_VAWD2 0x98
|
||||||
#define REG_ESW_VLAN_VTIM(x) (0x100 + 4 * ((x) / 2))
|
#define REG_ESW_VLAN_VTIM(x) (0x100 + 4 * ((x) / 2))
|
||||||
|
|
||||||
|
#define REG_ESW_WT_MAC_ATC 0x80
|
||||||
|
#define REG_ESW_TABLE_ATRD 0x8C
|
||||||
|
#define REG_ESW_TABLE_TSRA1 0x84
|
||||||
|
#define REG_ESW_TABLE_TSRA2 0x88
|
||||||
|
|
||||||
|
#define REG_MAC_ATC_START 0x8004
|
||||||
|
#define REG_MAC_ATC_NEXT 0x8005
|
||||||
|
|
||||||
|
#define REG_MAC_ATC_BUSY 0x8000U
|
||||||
|
#define REG_MAC_ATC_SRCH_HIT 0x2000U
|
||||||
|
#define REG_MAC_ATC_SRCH_END 0x4000U
|
||||||
|
#define REG_ATRD_VALID 0xff000000U
|
||||||
|
#define REG_ATRD_PORT_MASK 0xff0U
|
||||||
|
|
||||||
#define REG_ESW_VLAN_VAWD1_IVL_MAC BIT(30)
|
#define REG_ESW_VLAN_VAWD1_IVL_MAC BIT(30)
|
||||||
#define REG_ESW_VLAN_VAWD1_VTAG_EN BIT(28)
|
#define REG_ESW_VLAN_VAWD1_VTAG_EN BIT(28)
|
||||||
#define REG_ESW_VLAN_VAWD1_VALID BIT(0)
|
#define REG_ESW_VLAN_VAWD1_VALID BIT(0)
|
||||||
@ -212,6 +229,7 @@ struct mt7530_priv {
|
|||||||
bool global_vlan_enable;
|
bool global_vlan_enable;
|
||||||
struct mt7530_vlan_entry vlan_entries[MT7530_NUM_VLANS];
|
struct mt7530_vlan_entry vlan_entries[MT7530_NUM_VLANS];
|
||||||
struct mt7530_port_entry port_entries[MT7530_NUM_PORTS];
|
struct mt7530_port_entry port_entries[MT7530_NUM_PORTS];
|
||||||
|
char arl_buf[MT7530_NUM_ARL_RECORDS * ARL_LINE_LENGTH + 1];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mt7530_mapping {
|
struct mt7530_mapping {
|
||||||
@ -865,6 +883,100 @@ static int mt7530_sw_get_mib(struct switch_dev *dev,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *mt7530_print_arl_table_row(u32 atrd,
|
||||||
|
u32 mac1,
|
||||||
|
u32 mac2,
|
||||||
|
char *buf,
|
||||||
|
size_t *size)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
size_t port;
|
||||||
|
size_t i;
|
||||||
|
u8 port_map;
|
||||||
|
u8 mac[ETH_ALEN];
|
||||||
|
|
||||||
|
mac1 = ntohl(mac1);
|
||||||
|
mac2 = ntohl(mac2);
|
||||||
|
port_map = (u8)((atrd & REG_ATRD_PORT_MASK) >> 4);
|
||||||
|
memcpy(mac, &mac1, sizeof(mac1));
|
||||||
|
memcpy(mac + sizeof(mac1), &mac2, sizeof(mac) - sizeof(mac1));
|
||||||
|
for (port = 0, i = 1; port < MT7530_NUM_PORTS; ++port, i <<= 1) {
|
||||||
|
if (port_map & i) {
|
||||||
|
ret = snprintf(buf, *size, "Port %d: MAC %pM\n", port, mac);
|
||||||
|
if (ret >= *size || ret <= 0) {
|
||||||
|
*buf = 0;
|
||||||
|
buf = NULL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
buf += ret;
|
||||||
|
*size = *size - ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mt7530_get_arl_table(struct switch_dev *dev,
|
||||||
|
const struct switch_attr *attr,
|
||||||
|
struct switch_val *val)
|
||||||
|
{
|
||||||
|
struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
|
||||||
|
char *buf = priv->arl_buf;
|
||||||
|
size_t size = sizeof(priv->arl_buf);
|
||||||
|
size_t count = 0;
|
||||||
|
size_t retry_times = 100;
|
||||||
|
int ret;
|
||||||
|
u32 atc;
|
||||||
|
|
||||||
|
ret = snprintf(buf, size, "address resolution table\n");
|
||||||
|
if (ret >= size || ret <= 0) {
|
||||||
|
priv->arl_buf[0] = 0;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
buf += ret;
|
||||||
|
size = size - ret;
|
||||||
|
|
||||||
|
mt7530_w32(priv, REG_ESW_WT_MAC_ATC, REG_MAC_ATC_START);
|
||||||
|
|
||||||
|
do {
|
||||||
|
atc = mt7530_r32(priv, REG_ESW_WT_MAC_ATC);
|
||||||
|
if (atc & REG_MAC_ATC_SRCH_HIT && !(atc & REG_MAC_ATC_BUSY)) {
|
||||||
|
u32 atrd;
|
||||||
|
|
||||||
|
++count;
|
||||||
|
atrd = mt7530_r32(priv, REG_ESW_TABLE_ATRD);
|
||||||
|
if (atrd & REG_ATRD_VALID) {
|
||||||
|
u32 mac1;
|
||||||
|
u32 mac2;
|
||||||
|
|
||||||
|
mac1 = mt7530_r32(priv, REG_ESW_TABLE_TSRA1);
|
||||||
|
mac2 = mt7530_r32(priv, REG_ESW_TABLE_TSRA2);
|
||||||
|
|
||||||
|
if (!(atc & REG_MAC_ATC_SRCH_END))
|
||||||
|
mt7530_w32(priv, REG_ESW_WT_MAC_ATC, REG_MAC_ATC_NEXT);
|
||||||
|
|
||||||
|
buf = mt7530_print_arl_table_row(atrd, mac1, mac2, buf, &size);
|
||||||
|
if (!buf) {
|
||||||
|
pr_warn("%s: too many addresses\n", __func__);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
} else if (!(atc & REG_MAC_ATC_SRCH_END)) {
|
||||||
|
mt7530_w32(priv, REG_ESW_WT_MAC_ATC, REG_MAC_ATC_NEXT);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
--retry_times;
|
||||||
|
usleep_range(1000, 5000);
|
||||||
|
}
|
||||||
|
} while (!(atc & REG_MAC_ATC_SRCH_END) &&
|
||||||
|
count < MT7530_NUM_ARL_RECORDS &&
|
||||||
|
retry_times > 0);
|
||||||
|
out:
|
||||||
|
val->value.s = priv->arl_buf;
|
||||||
|
val->len = strlen(priv->arl_buf);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int mt7530_sw_get_port_mib(struct switch_dev *dev,
|
static int mt7530_sw_get_port_mib(struct switch_dev *dev,
|
||||||
const struct switch_attr *attr,
|
const struct switch_attr *attr,
|
||||||
struct switch_val *val)
|
struct switch_val *val)
|
||||||
@ -944,6 +1056,13 @@ static const struct switch_attr mt7530_global[] = {
|
|||||||
.get = mt7530_get_mirror_monitor_port,
|
.get = mt7530_get_mirror_monitor_port,
|
||||||
.max = MT7530_NUM_PORTS - 1
|
.max = MT7530_NUM_PORTS - 1
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.type = SWITCH_TYPE_STRING,
|
||||||
|
.name = "arl_table",
|
||||||
|
.description = "Get ARL table",
|
||||||
|
.set = NULL,
|
||||||
|
.get = mt7530_get_arl_table,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct switch_attr mt7621_port[] = {
|
static const struct switch_attr mt7621_port[] = {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user