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_MIRROR_PORT_S 4
|
||||
#define AR7240_MIRROR_PORT_M BITM(4)
|
||||
#define AR7240_CPU_PORT_EN BIT(8)
|
||||
|
||||
#define AR7240_REG_MIB_FUNCTION0 0x80
|
||||
|
@ -1013,6 +1014,134 @@ ar7240_get_port_stats(struct switch_dev *dev, int port,
|
|||
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[] = {
|
||||
{
|
||||
.type = SWITCH_TYPE_INT,
|
||||
|
@ -1022,9 +1151,33 @@ static struct switch_attr ar7240_globals[] = {
|
|||
.get = ar7240_get_vlan,
|
||||
.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[] = {
|
||||
{
|
||||
.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[] = {
|
||||
|
|
Loading…
Reference in a new issue