ag71xx: add support for port mirroring
This exposes hardware port mirroring in ag71xx driver (e.g. TL-WR841ND) via swconfig API. Signed-off-by: Milan Krstić <milan.krstic@gmail.com>
This commit is contained in:
parent
d0f6a514b1
commit
4c1ce83548
1 changed files with 153 additions and 0 deletions
|
@ -77,6 +77,7 @@
|
||||||
|
|
||||||
#define AR7240_REG_CPU_PORT 0x78
|
#define AR7240_REG_CPU_PORT 0x78
|
||||||
#define AR7240_MIRROR_PORT_S 4
|
#define AR7240_MIRROR_PORT_S 4
|
||||||
|
#define AR7240_MIRROR_PORT_M BITM(4)
|
||||||
#define AR7240_CPU_PORT_EN BIT(8)
|
#define AR7240_CPU_PORT_EN BIT(8)
|
||||||
|
|
||||||
#define AR7240_REG_MIB_FUNCTION0 0x80
|
#define AR7240_REG_MIB_FUNCTION0 0x80
|
||||||
|
@ -1013,6 +1014,134 @@ ar7240_get_port_stats(struct switch_dev *dev, int port,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ar7240_set_mirror_monitor_port(struct switch_dev *dev,
|
||||||
|
const struct switch_attr *attr,
|
||||||
|
struct switch_val *val)
|
||||||
|
{
|
||||||
|
struct ar7240sw *as = sw_to_ar7240(dev);
|
||||||
|
struct mii_bus *mii = as->mii_bus;
|
||||||
|
|
||||||
|
int port = val->value.i;
|
||||||
|
|
||||||
|
if (port > 15)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
ar7240sw_reg_rmw(mii, AR7240_REG_CPU_PORT,
|
||||||
|
AR7240_MIRROR_PORT_M << AR7240_MIRROR_PORT_S,
|
||||||
|
port << AR7240_MIRROR_PORT_S);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ar7240_get_mirror_monitor_port(struct switch_dev *dev,
|
||||||
|
const struct switch_attr *attr,
|
||||||
|
struct switch_val *val)
|
||||||
|
{
|
||||||
|
struct ar7240sw *as = sw_to_ar7240(dev);
|
||||||
|
struct mii_bus *mii = as->mii_bus;
|
||||||
|
|
||||||
|
u32 ret;
|
||||||
|
|
||||||
|
ret = ar7240sw_reg_read(mii, AR7240_REG_CPU_PORT);
|
||||||
|
val->value.i = (ret >> AR7240_MIRROR_PORT_S) & AR7240_MIRROR_PORT_M;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ar7240_set_mirror_rx(struct switch_dev *dev, const struct switch_attr *attr,
|
||||||
|
struct switch_val *val)
|
||||||
|
{
|
||||||
|
struct ar7240sw *as = sw_to_ar7240(dev);
|
||||||
|
struct mii_bus *mii = as->mii_bus;
|
||||||
|
|
||||||
|
int port = val->port_vlan;
|
||||||
|
|
||||||
|
if (port >= dev->ports)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (val && val->value.i == 1)
|
||||||
|
ar7240sw_reg_set(mii, AR7240_REG_PORT_CTRL(port),
|
||||||
|
AR7240_PORT_CTRL_MIRROR_RX);
|
||||||
|
else
|
||||||
|
ar7240sw_reg_rmw(mii, AR7240_REG_PORT_CTRL(port),
|
||||||
|
AR7240_PORT_CTRL_MIRROR_RX, 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ar7240_get_mirror_rx(struct switch_dev *dev, const struct switch_attr *attr,
|
||||||
|
struct switch_val *val)
|
||||||
|
{
|
||||||
|
struct ar7240sw *as = sw_to_ar7240(dev);
|
||||||
|
struct mii_bus *mii = as->mii_bus;
|
||||||
|
|
||||||
|
u32 ctrl;
|
||||||
|
|
||||||
|
int port = val->port_vlan;
|
||||||
|
|
||||||
|
if (port >= dev->ports)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
ctrl = ar7240sw_reg_read(mii, AR7240_REG_PORT_CTRL(port));
|
||||||
|
|
||||||
|
if ((ctrl & AR7240_PORT_CTRL_MIRROR_RX) == AR7240_PORT_CTRL_MIRROR_RX)
|
||||||
|
val->value.i = 1;
|
||||||
|
else
|
||||||
|
val->value.i = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ar7240_set_mirror_tx(struct switch_dev *dev, const struct switch_attr *attr,
|
||||||
|
struct switch_val *val)
|
||||||
|
{
|
||||||
|
struct ar7240sw *as = sw_to_ar7240(dev);
|
||||||
|
struct mii_bus *mii = as->mii_bus;
|
||||||
|
|
||||||
|
int port = val->port_vlan;
|
||||||
|
|
||||||
|
if (port >= dev->ports)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (val && val->value.i == 1)
|
||||||
|
ar7240sw_reg_set(mii, AR7240_REG_PORT_CTRL(port),
|
||||||
|
AR7240_PORT_CTRL_MIRROR_TX);
|
||||||
|
else
|
||||||
|
ar7240sw_reg_rmw(mii, AR7240_REG_PORT_CTRL(port),
|
||||||
|
AR7240_PORT_CTRL_MIRROR_TX, 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ar7240_get_mirror_tx(struct switch_dev *dev, const struct switch_attr *attr,
|
||||||
|
struct switch_val *val)
|
||||||
|
{
|
||||||
|
struct ar7240sw *as = sw_to_ar7240(dev);
|
||||||
|
struct mii_bus *mii = as->mii_bus;
|
||||||
|
|
||||||
|
u32 ctrl;
|
||||||
|
|
||||||
|
int port = val->port_vlan;
|
||||||
|
|
||||||
|
if (port >= dev->ports)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
ctrl = ar7240sw_reg_read(mii, AR7240_REG_PORT_CTRL(port));
|
||||||
|
|
||||||
|
if ((ctrl & AR7240_PORT_CTRL_MIRROR_TX) == AR7240_PORT_CTRL_MIRROR_TX)
|
||||||
|
val->value.i = 1;
|
||||||
|
else
|
||||||
|
val->value.i = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static struct switch_attr ar7240_globals[] = {
|
static struct switch_attr ar7240_globals[] = {
|
||||||
{
|
{
|
||||||
.type = SWITCH_TYPE_INT,
|
.type = SWITCH_TYPE_INT,
|
||||||
|
@ -1022,9 +1151,33 @@ static struct switch_attr ar7240_globals[] = {
|
||||||
.get = ar7240_get_vlan,
|
.get = ar7240_get_vlan,
|
||||||
.max = 1
|
.max = 1
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.type = SWITCH_TYPE_INT,
|
||||||
|
.name = "mirror_monitor_port",
|
||||||
|
.description = "Mirror monitor port",
|
||||||
|
.set = ar7240_set_mirror_monitor_port,
|
||||||
|
.get = ar7240_get_mirror_monitor_port,
|
||||||
|
.max = 15
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct switch_attr ar7240_port[] = {
|
static struct switch_attr ar7240_port[] = {
|
||||||
|
{
|
||||||
|
.type = SWITCH_TYPE_INT,
|
||||||
|
.name = "enable_mirror_rx",
|
||||||
|
.description = "Enable mirroring of RX packets",
|
||||||
|
.set = ar7240_set_mirror_rx,
|
||||||
|
.get = ar7240_get_mirror_rx,
|
||||||
|
.max = 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.type = SWITCH_TYPE_INT,
|
||||||
|
.name = "enable_mirror_tx",
|
||||||
|
.description = "Enable mirroring of TX packets",
|
||||||
|
.set = ar7240_set_mirror_tx,
|
||||||
|
.get = ar7240_get_mirror_tx,
|
||||||
|
.max = 1
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct switch_attr ar7240_vlan[] = {
|
static struct switch_attr ar7240_vlan[] = {
|
||||||
|
|
Loading…
Reference in a new issue