|
|
|
@ -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[] = {
|
|
|
|
|