diff options
author | Chuanhong Guo <gch981213@gmail.com> | 2019-04-09 21:32:32 +0800 |
---|---|---|
committer | Petr Štetiar <ynezz@true.cz> | 2019-05-20 21:17:45 +0200 |
commit | 107dc4326ccfaff27bd1e698b8bc7fb942233559 (patch) | |
tree | 03bac9ce58d91967a902011e8d2a64e4cf1925d7 /target/linux/generic/files/drivers | |
parent | df6e8c8771d5457048a5cb1e510c6bc73bd4c173 (diff) | |
download | upstream-107dc4326ccfaff27bd1e698b8bc7fb942233559.tar.gz upstream-107dc4326ccfaff27bd1e698b8bc7fb942233559.tar.bz2 upstream-107dc4326ccfaff27bd1e698b8bc7fb942233559.zip |
generic: ar8216: add mib_poll_interval switch attribute
This allows specifying interval of polling MIB counters from userspace
and allow completely turning off MIB counter support by setting
mib_poll_interval to 0.
Since MIB counter polling is a heavy CPU load for GPIO emulated MDIO
bus, disable this behavior by default. Those who wants to use swconfig
LEDs can enable them with qca,mib-poll-interval dts property or with
swconfig command.
Fixes: FS#2230 ("kworker spikes 100% cpu every 2 second.")
Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
Diffstat (limited to 'target/linux/generic/files/drivers')
-rw-r--r-- | target/linux/generic/files/drivers/net/phy/ar8216.c | 56 | ||||
-rw-r--r-- | target/linux/generic/files/drivers/net/phy/ar8216.h | 8 | ||||
-rw-r--r-- | target/linux/generic/files/drivers/net/phy/ar8327.c | 7 |
3 files changed, 63 insertions, 8 deletions
diff --git a/target/linux/generic/files/drivers/net/phy/ar8216.c b/target/linux/generic/files/drivers/net/phy/ar8216.c index a2c42d18e6..748a626070 100644 --- a/target/linux/generic/files/drivers/net/phy/ar8216.c +++ b/target/linux/generic/files/drivers/net/phy/ar8216.c @@ -42,8 +42,6 @@ extern const struct ar8xxx_chip ar8327_chip; extern const struct ar8xxx_chip ar8337_chip; -#define AR8XXX_MIB_WORK_DELAY 2000 /* msecs */ - #define MIB_DESC(_s , _o, _n) \ { \ .size = (_s), \ @@ -136,6 +134,11 @@ const struct ar8xxx_mib_desc ar8236_mibs[39] = { static DEFINE_MUTEX(ar8xxx_dev_list_lock); static LIST_HEAD(ar8xxx_dev_list); +static void +ar8xxx_mib_start(struct ar8xxx_priv *priv); +static void +ar8xxx_mib_stop(struct ar8xxx_priv *priv); + /* inspired by phy_poll_reset in drivers/net/phy/phy_device.c */ static int ar8xxx_phy_poll_reset(struct mii_bus *bus) @@ -1445,6 +1448,36 @@ unlock: } int +ar8xxx_sw_set_mib_poll_interval(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); + + if (!ar8xxx_has_mib_counters(priv)) + return -EOPNOTSUPP; + + ar8xxx_mib_stop(priv); + priv->mib_poll_interval = val->value.i; + ar8xxx_mib_start(priv); + + return 0; +} + +int +ar8xxx_sw_get_mib_poll_interval(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); + + if (!ar8xxx_has_mib_counters(priv)) + return -EOPNOTSUPP; + val->value.i = priv->mib_poll_interval; + return 0; +} + +int ar8xxx_sw_set_mirror_rx_enable(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) @@ -1615,7 +1648,7 @@ ar8xxx_sw_get_port_mib(struct switch_dev *dev, int i, len = 0; bool mib_stats_empty = true; - if (!ar8xxx_has_mib_counters(priv)) + if (!ar8xxx_has_mib_counters(priv) || !priv->mib_poll_interval) return -EOPNOTSUPP; port = val->port_vlan; @@ -1807,7 +1840,7 @@ ar8xxx_sw_get_port_stats(struct switch_dev *dev, int port, struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev); u64 *mib_stats; - if (!ar8xxx_has_mib_counters(priv)) + if (!ar8xxx_has_mib_counters(priv) || !priv->mib_poll_interval) return -EOPNOTSUPP; if (!(priv->chip->mib_rxb_id || priv->chip->mib_txb_id)) @@ -1859,6 +1892,13 @@ static const struct switch_attr ar8xxx_sw_attr_globals[] = { }, { .type = SWITCH_TYPE_INT, + .name = "ar8xxx_mib_poll_interval", + .description = "MIB polling interval in msecs (0 to disable)", + .set = ar8xxx_sw_set_mib_poll_interval, + .get = ar8xxx_sw_get_mib_poll_interval + }, + { + .type = SWITCH_TYPE_INT, .name = "enable_mirror_rx", .description = "Enable mirroring of RX packets", .set = ar8xxx_sw_set_mirror_rx_enable, @@ -2234,7 +2274,7 @@ ar8xxx_mib_init(struct ar8xxx_priv *priv) static void ar8xxx_mib_start(struct ar8xxx_priv *priv) { - if (!ar8xxx_has_mib_counters(priv)) + if (!ar8xxx_has_mib_counters(priv) || !priv->mib_poll_interval) return; schedule_delayed_work(&priv->mib_work, @@ -2244,7 +2284,7 @@ ar8xxx_mib_start(struct ar8xxx_priv *priv) static void ar8xxx_mib_stop(struct ar8xxx_priv *priv) { - if (!ar8xxx_has_mib_counters(priv)) + if (!ar8xxx_has_mib_counters(priv) || !priv->mib_poll_interval) return; cancel_delayed_work_sync(&priv->mib_work); @@ -2516,7 +2556,7 @@ ar8xxx_phy_probe(struct phy_device *phydev) ret = of_property_read_u32(priv->pdev->of_node, "qca,mib-poll-interval", &priv->mib_poll_interval); if (ret) - priv->mib_poll_interval = AR8XXX_MIB_WORK_DELAY; + priv->mib_poll_interval = 0; ret = ar8xxx_id_chip(priv); if (ret) @@ -2688,7 +2728,7 @@ ar8xxx_mdiodev_probe(struct mdio_device *mdiodev) ret = of_property_read_u32(priv->pdev->of_node, "qca,mib-poll-interval", &priv->mib_poll_interval); if (ret) - priv->mib_poll_interval = AR8XXX_MIB_WORK_DELAY; + priv->mib_poll_interval = 0; ret = ar8xxx_read_id(priv); if (ret) diff --git a/target/linux/generic/files/drivers/net/phy/ar8216.h b/target/linux/generic/files/drivers/net/phy/ar8216.h index 35274b480a..8f77c916c0 100644 --- a/target/linux/generic/files/drivers/net/phy/ar8216.h +++ b/target/linux/generic/files/drivers/net/phy/ar8216.h @@ -544,6 +544,14 @@ ar8xxx_sw_set_reset_mibs(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val); int +ar8xxx_sw_set_mib_poll_interval(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val); +int +ar8xxx_sw_get_mib_poll_interval(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val); +int ar8xxx_sw_set_mirror_rx_enable(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val); diff --git a/target/linux/generic/files/drivers/net/phy/ar8327.c b/target/linux/generic/files/drivers/net/phy/ar8327.c index b0da346314..c2964169eb 100644 --- a/target/linux/generic/files/drivers/net/phy/ar8327.c +++ b/target/linux/generic/files/drivers/net/phy/ar8327.c @@ -1323,6 +1323,13 @@ static const struct switch_attr ar8327_sw_attr_globals[] = { }, { .type = SWITCH_TYPE_INT, + .name = "ar8xxx_mib_poll_interval", + .description = "MIB polling interval in msecs (0 to disable)", + .set = ar8xxx_sw_set_mib_poll_interval, + .get = ar8xxx_sw_get_mib_poll_interval + }, + { + .type = SWITCH_TYPE_INT, .name = "enable_mirror_rx", .description = "Enable mirroring of RX packets", .set = ar8xxx_sw_set_mirror_rx_enable, |