From 7458d619f7336e745327c2ca2c4f4aebf468e472 Mon Sep 17 00:00:00 2001 From: Yousong Zhou Date: Fri, 6 Jul 2018 14:28:06 +0800 Subject: [PATCH] ag71xx: allow setting port state and storm control registers Signed-off-by: Yousong Zhou --- .../ethernet/atheros/ag71xx/ag71xx_ar7240.c | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar7240.c b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar7240.c index 3f2f64e2ae..3d5d55df58 100644 --- a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar7240.c +++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar7240.c @@ -138,6 +138,11 @@ #define AR7240_PORT_CTRL_MIRROR_TX BIT(16) #define AR7240_PORT_CTRL_MIRROR_RX BIT(17) +#define AR7240_REG_PORT_STORM_CTRL(_port) (AR7240_REG_PORT_BASE((_port)) + 0x14) +#define AR7240_STORM_CTRL_RES_M ((BITM(21) << 11) | (BITM(4) << 4)) +#define AR7240_STORM_CTRL_STORM_RATE_M BITM(4) +#define AR7240_STORM_CTRL_STORM_RATE_MAX 0xb + #define AR7240_REG_PORT_VLAN(_port) (AR7240_REG_PORT_BASE((_port)) + 0x08) #define AR7240_PORT_VLAN_DEFAULT_ID_S 0 @@ -1161,6 +1166,72 @@ static struct switch_attr ar7240_globals[] = { }, }; +static int ar7240_get_port_state(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 state; + + if (val->port_vlan > AR7240_NUM_PORTS) + return -EINVAL; + + state = ar7240sw_reg_read(mii, AR7240_REG_PORT_CTRL(val->port_vlan)); + val->value.i = state & AR7240_PORT_CTRL_STATE_M; + return 0; +} + +static int ar7240_set_port_state(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; + + if (val->port_vlan > AR7240_NUM_PORTS) + return -EINVAL; + + ar7240sw_reg_rmw(mii, AR7240_REG_PORT_CTRL(val->port_vlan), + AR7240_PORT_CTRL_STATE_M, val->value.i); + return 0; +} + +static int ar7240_get_port_storm_ctrl(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; + + if (val->port_vlan > AR7240_NUM_PORTS) + return -EINVAL; + + val->value.i = ar7240sw_reg_read(mii, AR7240_REG_PORT_STORM_CTRL(val->port_vlan)); + return 0; +} + +static int ar7240_set_port_storm_ctrl(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 i; + + if (val->port_vlan > AR7240_NUM_PORTS) + return -EINVAL; + + i = val->value.i; + if (i & AR7240_STORM_CTRL_RES_M) + return -EINVAL; + if ((i & AR7240_STORM_CTRL_STORM_RATE_M) > AR7240_STORM_CTRL_STORM_RATE_MAX) + return -EINVAL; + + ar7240sw_reg_write(mii, AR7240_REG_PORT_STORM_CTRL(val->port_vlan), i); + return 0; +} + static struct switch_attr ar7240_port[] = { { .type = SWITCH_TYPE_INT, @@ -1177,6 +1248,19 @@ static struct switch_attr ar7240_port[] = { .set = ar7240_set_mirror_tx, .get = ar7240_get_mirror_tx, .max = 1 + }, { + .name = "state", + .description = "Get/Set port state", + .max = 1, + .set = ar7240_set_port_state, + .get = ar7240_get_port_state, + }, { + .type = SWITCH_TYPE_INT, + .name = "storm_ctrl", + .description = "Get/Set port storm control registers", + .max = 1, + .set = ar7240_set_port_storm_ctrl, + .get = ar7240_get_port_storm_ctrl, }, }; -- 2.30.2