From 1b86f702f80de32d555519e2c4c61385faeab710 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Tue, 16 May 2017 18:29:11 +0200 Subject: net: phy: Remove residual magic from PHY drivers commit fa8cddaf903c ("net phylib: Remove unnecessary condition check in phy") removed the only place where the PHY flag PHY_HAS_MAGICANEG was checked. But it left the flag being set in the drivers. Remove the flag. Signed-off-by: Andrew Lunn Signed-off-by: David S. Miller --- drivers/net/phy/smsc.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/net/phy/smsc.c') diff --git a/drivers/net/phy/smsc.c b/drivers/net/phy/smsc.c index cef6967b0396..67c9f2b26c8e 100644 --- a/drivers/net/phy/smsc.c +++ b/drivers/net/phy/smsc.c @@ -170,7 +170,7 @@ static struct phy_driver smsc_phy_driver[] = { .name = "SMSC LAN83C185", .features = PHY_BASIC_FEATURES, - .flags = PHY_HAS_INTERRUPT | PHY_HAS_MAGICANEG, + .flags = PHY_HAS_INTERRUPT, .probe = smsc_phy_probe, @@ -192,7 +192,7 @@ static struct phy_driver smsc_phy_driver[] = { .name = "SMSC LAN8187", .features = PHY_BASIC_FEATURES, - .flags = PHY_HAS_INTERRUPT | PHY_HAS_MAGICANEG, + .flags = PHY_HAS_INTERRUPT, .probe = smsc_phy_probe, @@ -214,7 +214,7 @@ static struct phy_driver smsc_phy_driver[] = { .name = "SMSC LAN8700", .features = PHY_BASIC_FEATURES, - .flags = PHY_HAS_INTERRUPT | PHY_HAS_MAGICANEG, + .flags = PHY_HAS_INTERRUPT, .probe = smsc_phy_probe, @@ -236,7 +236,7 @@ static struct phy_driver smsc_phy_driver[] = { .name = "SMSC LAN911x Internal PHY", .features = PHY_BASIC_FEATURES, - .flags = PHY_HAS_INTERRUPT | PHY_HAS_MAGICANEG, + .flags = PHY_HAS_INTERRUPT, .probe = smsc_phy_probe, @@ -257,7 +257,7 @@ static struct phy_driver smsc_phy_driver[] = { .name = "SMSC LAN8710/LAN8720", .features = PHY_BASIC_FEATURES, - .flags = PHY_HAS_INTERRUPT | PHY_HAS_MAGICANEG, + .flags = PHY_HAS_INTERRUPT, .probe = smsc_phy_probe, @@ -279,7 +279,7 @@ static struct phy_driver smsc_phy_driver[] = { .name = "SMSC LAN8740", .features = PHY_BASIC_FEATURES, - .flags = PHY_HAS_INTERRUPT | PHY_HAS_MAGICANEG, + .flags = PHY_HAS_INTERRUPT, .probe = smsc_phy_probe, -- cgit v1.2.3 From 030a89028db07a7987f1f3bd6ee43114e36f5060 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Sat, 3 Jun 2017 20:00:36 +0200 Subject: net: phy: smsc: Implement PHY statistics Most of the PHYs supported by the SMSC driver have a counter of symbol errors. This is 16 bit wide and wraps around when it reaches its maximum value. Signed-off-by: Andrew Lunn Reviewed-by: Florian Fainelli Reviewed-By: Woojung Huh Signed-off-by: David S. Miller --- drivers/net/phy/smsc.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) (limited to 'drivers/net/phy/smsc.c') diff --git a/drivers/net/phy/smsc.c b/drivers/net/phy/smsc.c index 67c9f2b26c8e..1b8204be064c 100644 --- a/drivers/net/phy/smsc.c +++ b/drivers/net/phy/smsc.c @@ -25,6 +25,16 @@ #include #include +struct smsc_hw_stat { + const char *string; + u8 reg; + u8 bits; +}; + +static struct smsc_hw_stat smsc_hw_stats[] = { + { "phy_symbol_errors", 26, 16}, +}; + struct smsc_phy_priv { bool energy_enable; }; @@ -143,6 +153,48 @@ static int lan87xx_read_status(struct phy_device *phydev) return err; } +static int smsc_get_sset_count(struct phy_device *phydev) +{ + return ARRAY_SIZE(smsc_hw_stats); +} + +static void smsc_get_strings(struct phy_device *phydev, u8 *data) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(smsc_hw_stats); i++) { + memcpy(data + i * ETH_GSTRING_LEN, + smsc_hw_stats[i].string, ETH_GSTRING_LEN); + } +} + +#ifndef UINT64_MAX +#define UINT64_MAX (u64)(~((u64)0)) +#endif +static u64 smsc_get_stat(struct phy_device *phydev, int i) +{ + struct smsc_hw_stat stat = smsc_hw_stats[i]; + int val; + u64 ret; + + val = phy_read(phydev, stat.reg); + if (val < 0) + ret = UINT64_MAX; + else + ret = val; + + return ret; +} + +static void smsc_get_stats(struct phy_device *phydev, + struct ethtool_stats *stats, u64 *data) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(smsc_hw_stats); i++) + data[i] = smsc_get_stat(phydev, i); +} + static int smsc_phy_probe(struct phy_device *phydev) { struct device *dev = &phydev->mdio.dev; @@ -206,6 +258,11 @@ static struct phy_driver smsc_phy_driver[] = { .ack_interrupt = smsc_phy_ack_interrupt, .config_intr = smsc_phy_config_intr, + /* Statistics */ + .get_sset_count = smsc_get_sset_count, + .get_strings = smsc_get_strings, + .get_stats = smsc_get_stats, + .suspend = genphy_suspend, .resume = genphy_resume, }, { @@ -228,6 +285,11 @@ static struct phy_driver smsc_phy_driver[] = { .ack_interrupt = smsc_phy_ack_interrupt, .config_intr = smsc_phy_config_intr, + /* Statistics */ + .get_sset_count = smsc_get_sset_count, + .get_strings = smsc_get_strings, + .get_stats = smsc_get_stats, + .suspend = genphy_suspend, .resume = genphy_resume, }, { @@ -271,6 +333,11 @@ static struct phy_driver smsc_phy_driver[] = { .ack_interrupt = smsc_phy_ack_interrupt, .config_intr = smsc_phy_config_intr, + /* Statistics */ + .get_sset_count = smsc_get_sset_count, + .get_strings = smsc_get_strings, + .get_stats = smsc_get_stats, + .suspend = genphy_suspend, .resume = genphy_resume, }, { @@ -293,6 +360,11 @@ static struct phy_driver smsc_phy_driver[] = { .ack_interrupt = smsc_phy_ack_interrupt, .config_intr = smsc_phy_config_intr, + /* Statistics */ + .get_sset_count = smsc_get_sset_count, + .get_strings = smsc_get_strings, + .get_stats = smsc_get_stats, + .suspend = genphy_suspend, .resume = genphy_resume, } }; -- cgit v1.2.3 From 2da55390a96ad2245edfaca77669c10088523d39 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 Jun 2017 22:40:46 +0200 Subject: net: phy: smsc: fix buffer overflow in memcpy The memcpy annotation triggers for a fixed-length buffer copy: In file included from /git/arm-soc/arch/arm64/include/asm/processor.h:30:0, from /git/arm-soc/arch/arm64/include/asm/spinlock.h:21, from /git/arm-soc/include/linux/spinlock.h:87, from /git/arm-soc/include/linux/seqlock.h:35, from /git/arm-soc/include/linux/time.h:5, from /git/arm-soc/include/linux/stat.h:21, from /git/arm-soc/include/linux/module.h:10, from /git/arm-soc/drivers/net/phy/smsc.c:20: In function 'memcpy', inlined from 'smsc_get_strings' at /git/arm-soc/drivers/net/phy/smsc.c:166:3: /git/arm-soc/include/linux/string.h:309:4: error: call to '__read_overflow2' declared with attribute error: detected read beyond size of object passed as 2nd parameter Using strncpy instead of memcpy should do the right thing here. Fixes: 030a89028db0 ("net: phy: smsc: Implement PHY statistics") Signed-off-by: Arnd Bergmann Signed-off-by: David S. Miller --- drivers/net/phy/smsc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/phy/smsc.c') diff --git a/drivers/net/phy/smsc.c b/drivers/net/phy/smsc.c index 1b8204be064c..2306bfae057f 100644 --- a/drivers/net/phy/smsc.c +++ b/drivers/net/phy/smsc.c @@ -163,7 +163,7 @@ static void smsc_get_strings(struct phy_device *phydev, u8 *data) int i; for (i = 0; i < ARRAY_SIZE(smsc_hw_stats); i++) { - memcpy(data + i * ETH_GSTRING_LEN, + strncpy(data + i * ETH_GSTRING_LEN, smsc_hw_stats[i].string, ETH_GSTRING_LEN); } } -- cgit v1.2.3