diff options
Diffstat (limited to 'target/linux')
4 files changed, 122 insertions, 17 deletions
diff --git a/target/linux/generic/files/drivers/net/phy/ar8216.c b/target/linux/generic/files/drivers/net/phy/ar8216.c index 2fd44253c8..99d0e8220f 100644 --- a/target/linux/generic/files/drivers/net/phy/ar8216.c +++ b/target/linux/generic/files/drivers/net/phy/ar8216.c @@ -1041,6 +1041,7 @@ int ar8xxx_sw_reset_switch(struct switch_dev *dev) { struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); + const struct ar8xxx_chip *chip = priv->chip; int i; mutex_lock(&priv->reg_mutex); @@ -1052,18 +1053,18 @@ ar8xxx_sw_reset_switch(struct switch_dev *dev) /* Configure all ports */ for (i = 0; i < dev->ports; i++) - priv->chip->init_port(priv, i); + chip->init_port(priv, i); priv->mirror_rx = false; priv->mirror_tx = false; priv->source_port = 0; priv->monitor_port = 0; - priv->chip->init_globals(priv); + chip->init_globals(priv); mutex_unlock(&priv->reg_mutex); - return ar8xxx_sw_hw_apply(dev); + return chip->sw_hw_apply(dev); } int @@ -1194,7 +1195,7 @@ ar8xxx_sw_get_mirror_source_port(struct switch_dev *dev, return 0; } -static int +int ar8xxx_sw_set_port_reset_mib(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) @@ -1224,7 +1225,7 @@ unlock: return ret; } -static int +int ar8xxx_sw_get_port_mib(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) @@ -1390,6 +1391,7 @@ static const struct ar8xxx_chip ar8216_chip = { .vtu_flush = ar8216_vtu_flush, .vtu_load_vlan = ar8216_vtu_load_vlan, .set_mirror_regs = ar8216_set_mirror_regs, + .sw_hw_apply = ar8xxx_sw_hw_apply, .num_mibs = ARRAY_SIZE(ar8216_mibs), .mib_decs = ar8216_mibs, @@ -1416,6 +1418,7 @@ static const struct ar8xxx_chip ar8236_chip = { .vtu_flush = ar8216_vtu_flush, .vtu_load_vlan = ar8216_vtu_load_vlan, .set_mirror_regs = ar8216_set_mirror_regs, + .sw_hw_apply = ar8xxx_sw_hw_apply, .num_mibs = ARRAY_SIZE(ar8236_mibs), .mib_decs = ar8236_mibs, @@ -1442,6 +1445,7 @@ static const struct ar8xxx_chip ar8316_chip = { .vtu_flush = ar8216_vtu_flush, .vtu_load_vlan = ar8216_vtu_load_vlan, .set_mirror_regs = ar8216_set_mirror_regs, + .sw_hw_apply = ar8xxx_sw_hw_apply, .num_mibs = ARRAY_SIZE(ar8236_mibs), .mib_decs = ar8236_mibs, diff --git a/target/linux/generic/files/drivers/net/phy/ar8216.h b/target/linux/generic/files/drivers/net/phy/ar8216.h index d3d044324e..4089a17059 100644 --- a/target/linux/generic/files/drivers/net/phy/ar8216.h +++ b/target/linux/generic/files/drivers/net/phy/ar8216.h @@ -371,6 +371,7 @@ struct ar8xxx_chip { void (*vtu_load_vlan)(struct ar8xxx_priv *priv, u32 vid, u32 port_mask); void (*phy_fixup)(struct ar8xxx_priv *priv, int phy); void (*set_mirror_regs)(struct ar8xxx_priv *priv); + int (*sw_hw_apply)(struct switch_dev *dev); const struct ar8xxx_mib_desc *mib_decs; unsigned num_mibs; @@ -487,6 +488,14 @@ int ar8xxx_sw_get_port_link(struct switch_dev *dev, int port, struct switch_port_link *link); int +ar8xxx_sw_set_port_reset_mib(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val); +int +ar8xxx_sw_get_port_mib(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val); +int ar8216_wait_bit(struct ar8xxx_priv *priv, int reg, u32 mask, u32 val); static inline struct ar8xxx_priv * diff --git a/target/linux/generic/files/drivers/net/phy/ar8327.c b/target/linux/generic/files/drivers/net/phy/ar8327.c index f6d07c1982..0971f80d50 100644 --- a/target/linux/generic/files/drivers/net/phy/ar8327.c +++ b/target/linux/generic/files/drivers/net/phy/ar8327.c @@ -30,7 +30,6 @@ #include "ar8327.h" extern const struct ar8xxx_mib_desc ar8236_mibs[39]; -extern const struct switch_attr ar8xxx_sw_attr_port[2]; extern const struct switch_attr ar8xxx_sw_attr_vlan[1]; static u32 @@ -651,7 +650,9 @@ ar8327_cleanup(struct ar8xxx_priv *priv) static void ar8327_init_globals(struct ar8xxx_priv *priv) { + struct ar8327_data *data = priv->chip_data; u32 t; + int i; /* enable CPU port and disable mirror port */ t = AR8327_FWD_CTRL0_CPU_PORT_EN | @@ -672,14 +673,9 @@ ar8327_init_globals(struct ar8xxx_priv *priv) ar8xxx_reg_set(priv, AR8327_REG_MODULE_EN, AR8327_MODULE_EN_MIB); - /* Disable EEE on all ports due to stability issues */ - t = ar8xxx_read(priv, AR8327_REG_EEE_CTRL); - t |= AR8327_EEE_CTRL_DISABLE_PHY(0) | - AR8327_EEE_CTRL_DISABLE_PHY(1) | - AR8327_EEE_CTRL_DISABLE_PHY(2) | - AR8327_EEE_CTRL_DISABLE_PHY(3) | - AR8327_EEE_CTRL_DISABLE_PHY(4); - ar8xxx_write(priv, AR8327_REG_EEE_CTRL, t); + /* Disable EEE on all phy's due to stability issues */ + for (i = 0; i < AR8XXX_NUM_PHYS; i++) + data->eee[i] = false; } static void @@ -892,6 +888,73 @@ ar8327_set_mirror_regs(struct ar8xxx_priv *priv) AR8327_PORT_HOL_CTRL1_EG_MIRROR_EN); } +static int +ar8327_sw_set_eee(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); + struct ar8327_data *data = priv->chip_data; + int port = val->port_vlan; + int phy; + + if (port >= dev->ports) + return -EINVAL; + if (port == 0 || port == 6) + return -EOPNOTSUPP; + + phy = port - 1; + + data->eee[phy] = !!(val->value.i); + + return 0; +} + +static int +ar8327_sw_get_eee(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); + const struct ar8327_data *data = priv->chip_data; + int port = val->port_vlan; + int phy; + + if (port >= dev->ports) + return -EINVAL; + if (port == 0 || port == 6) + return -EOPNOTSUPP; + + phy = port - 1; + + val->value.i = data->eee[phy]; + + return 0; +} + +static int +ar8327_sw_hw_apply(struct switch_dev *dev) +{ + struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); + const struct ar8327_data *data = priv->chip_data; + int ret, i; + + ret = ar8xxx_sw_hw_apply(dev); + if (ret) + return ret; + + for (i=0; i < AR8XXX_NUM_PHYS; i++) { + if (data->eee[i]) + ar8xxx_reg_clear(priv, AR8327_REG_EEE_CTRL, + AR8327_EEE_CTRL_DISABLE_PHY(i)); + else + ar8xxx_reg_set(priv, AR8327_REG_EEE_CTRL, + AR8327_EEE_CTRL_DISABLE_PHY(i)); + } + + return 0; +} + static const struct switch_attr ar8327_sw_attr_globals[] = { { .type = SWITCH_TYPE_INT, @@ -941,14 +1004,38 @@ static const struct switch_attr ar8327_sw_attr_globals[] = { }, }; +static const struct switch_attr ar8327_sw_attr_port[] = { + { + .type = SWITCH_TYPE_NOVAL, + .name = "reset_mib", + .description = "Reset single port MIB counters", + .set = ar8xxx_sw_set_port_reset_mib, + }, + { + .type = SWITCH_TYPE_STRING, + .name = "mib", + .description = "Get port's MIB counters", + .set = NULL, + .get = ar8xxx_sw_get_port_mib, + }, + { + .type = SWITCH_TYPE_INT, + .name = "enable_eee", + .description = "Enable EEE PHY sleep mode", + .set = ar8327_sw_set_eee, + .get = ar8327_sw_get_eee, + .max = 1, + }, +}; + static const struct switch_dev_ops ar8327_sw_ops = { .attr_global = { .attr = ar8327_sw_attr_globals, .n_attr = ARRAY_SIZE(ar8327_sw_attr_globals), }, .attr_port = { - .attr = ar8xxx_sw_attr_port, - .n_attr = ARRAY_SIZE(ar8xxx_sw_attr_port), + .attr = ar8327_sw_attr_port, + .n_attr = ARRAY_SIZE(ar8327_sw_attr_port), }, .attr_vlan = { .attr = ar8xxx_sw_attr_vlan, @@ -958,7 +1045,7 @@ static const struct switch_dev_ops ar8327_sw_ops = { .set_port_pvid = ar8xxx_sw_set_pvid, .get_vlan_ports = ar8327_sw_get_ports, .set_vlan_ports = ar8327_sw_set_ports, - .apply_config = ar8xxx_sw_hw_apply, + .apply_config = ar8327_sw_hw_apply, .reset_switch = ar8xxx_sw_reset_switch, .get_port_link = ar8xxx_sw_get_port_link, }; @@ -987,6 +1074,7 @@ const struct ar8xxx_chip ar8327_chip = { .vtu_load_vlan = ar8327_vtu_load_vlan, .phy_fixup = ar8327_phy_fixup, .set_mirror_regs = ar8327_set_mirror_regs, + .sw_hw_apply = ar8327_sw_hw_apply, .num_mibs = ARRAY_SIZE(ar8236_mibs), .mib_decs = ar8236_mibs, @@ -1017,6 +1105,7 @@ const struct ar8xxx_chip ar8337_chip = { .vtu_load_vlan = ar8327_vtu_load_vlan, .phy_fixup = ar8327_phy_fixup, .set_mirror_regs = ar8327_set_mirror_regs, + .sw_hw_apply = ar8327_sw_hw_apply, .num_mibs = ARRAY_SIZE(ar8236_mibs), .mib_decs = ar8236_mibs, diff --git a/target/linux/generic/files/drivers/net/phy/ar8327.h b/target/linux/generic/files/drivers/net/phy/ar8327.h index c606972a04..1877f00c97 100644 --- a/target/linux/generic/files/drivers/net/phy/ar8327.h +++ b/target/linux/generic/files/drivers/net/phy/ar8327.h @@ -219,6 +219,9 @@ struct ar8327_data { struct ar8327_led **leds; unsigned int num_leds; + + /* all fields below are cleared on reset */ + bool eee[AR8XXX_NUM_PHYS]; }; #endif |