From a2dbba7674468ad03aa6cf4378ed0965f453e034 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Fri, 22 Aug 2014 18:55:42 -0700 Subject: net: phy: fixed: return an error for Clause 45 over 22 reads The fixed PHY driver does not properly emulate Clause 45 over Clause 22 MDIO reads, and as such, will return bogus values when we access such registers. Return an error when accessing these registers in order to prevent advertising bogus capabilities such as EEE support and such. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/phy/fixed.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers/net/phy/fixed.c') diff --git a/drivers/net/phy/fixed.c b/drivers/net/phy/fixed.c index d60d875cb44..5b19fbbda6d 100644 --- a/drivers/net/phy/fixed.c +++ b/drivers/net/phy/fixed.c @@ -124,6 +124,17 @@ static int fixed_mdio_read(struct mii_bus *bus, int phy_addr, int reg_num) if (reg_num >= MII_REGS_NUM) return -1; + /* We do not support emulating Clause 45 over Clause 22 register reads + * return an error instead of bogus data. + */ + switch (reg_num) { + case MII_MMD_CTRL: + case MII_MMD_DATA: + return -1; + default: + break; + } + list_for_each_entry(fp, &fmb->phys, node) { if (fp->addr == phy_addr) { /* Issue callback if user registered it. */ -- cgit v1.2.3-70-g09d2 From fd2ef0ba3071c92ac6272ab22ea3f2b16d88a4eb Mon Sep 17 00:00:00 2001 From: Petri Gynther Date: Mon, 6 Oct 2014 11:38:30 -0700 Subject: net: phy: adjust fixed_phy_register() return value Adjust fixed_phy_register() to return struct phy_device *, so that it becomes easy to use fixed PHYs without device tree support: phydev = fixed_phy_register(PHY_POLL, &fixed_phy_status, NULL); fixed_phy_set_link_update(phydev, fixed_phy_link_update); phy_connect_direct(netdev, phydev, handler_fn, phy_interface); This change is a prerequisite for modifying bcmgenet driver to work without a device tree on Broadcom's MIPS-based 7xxx platforms. Signed-off-by: Petri Gynther Signed-off-by: David S. Miller --- drivers/net/phy/fixed.c | 16 ++++++++-------- drivers/of/of_mdio.c | 7 +++++-- include/linux/phy_fixed.h | 14 +++++++------- 3 files changed, 20 insertions(+), 17 deletions(-) (limited to 'drivers/net/phy/fixed.c') diff --git a/drivers/net/phy/fixed.c b/drivers/net/phy/fixed.c index 5b19fbbda6d..47872caa008 100644 --- a/drivers/net/phy/fixed.c +++ b/drivers/net/phy/fixed.c @@ -233,9 +233,9 @@ EXPORT_SYMBOL_GPL(fixed_phy_del); static int phy_fixed_addr; static DEFINE_SPINLOCK(phy_fixed_addr_lock); -int fixed_phy_register(unsigned int irq, - struct fixed_phy_status *status, - struct device_node *np) +struct phy_device *fixed_phy_register(unsigned int irq, + struct fixed_phy_status *status, + struct device_node *np) { struct fixed_mdio_bus *fmb = &platform_fmb; struct phy_device *phy; @@ -246,19 +246,19 @@ int fixed_phy_register(unsigned int irq, spin_lock(&phy_fixed_addr_lock); if (phy_fixed_addr == PHY_MAX_ADDR) { spin_unlock(&phy_fixed_addr_lock); - return -ENOSPC; + return ERR_PTR(-ENOSPC); } phy_addr = phy_fixed_addr++; spin_unlock(&phy_fixed_addr_lock); ret = fixed_phy_add(PHY_POLL, phy_addr, status); if (ret < 0) - return ret; + return ERR_PTR(ret); phy = get_phy_device(fmb->mii_bus, phy_addr, false); if (!phy || IS_ERR(phy)) { fixed_phy_del(phy_addr); - return -EINVAL; + return ERR_PTR(-EINVAL); } of_node_get(np); @@ -269,10 +269,10 @@ int fixed_phy_register(unsigned int irq, phy_device_free(phy); of_node_put(np); fixed_phy_del(phy_addr); - return ret; + return ERR_PTR(ret); } - return 0; + return phy; } static int __init fixed_mdio_bus_init(void) diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c index a85d8001299..1bd43053b8c 100644 --- a/drivers/of/of_mdio.c +++ b/drivers/of/of_mdio.c @@ -286,6 +286,7 @@ int of_phy_register_fixed_link(struct device_node *np) struct device_node *fixed_link_node; const __be32 *fixed_link_prop; int len; + struct phy_device *phy; /* New binding */ fixed_link_node = of_get_child_by_name(np, "fixed-link"); @@ -299,7 +300,8 @@ int of_phy_register_fixed_link(struct device_node *np) status.asym_pause = of_property_read_bool(fixed_link_node, "asym-pause"); of_node_put(fixed_link_node); - return fixed_phy_register(PHY_POLL, &status, np); + phy = fixed_phy_register(PHY_POLL, &status, np); + return IS_ERR(phy) ? PTR_ERR(phy) : 0; } /* Old binding */ @@ -310,7 +312,8 @@ int of_phy_register_fixed_link(struct device_node *np) status.speed = be32_to_cpu(fixed_link_prop[2]); status.pause = be32_to_cpu(fixed_link_prop[3]); status.asym_pause = be32_to_cpu(fixed_link_prop[4]); - return fixed_phy_register(PHY_POLL, &status, np); + phy = fixed_phy_register(PHY_POLL, &status, np); + return IS_ERR(phy) ? PTR_ERR(phy) : 0; } return -ENODEV; diff --git a/include/linux/phy_fixed.h b/include/linux/phy_fixed.h index 941138664c1..f2ca1b45937 100644 --- a/include/linux/phy_fixed.h +++ b/include/linux/phy_fixed.h @@ -14,9 +14,9 @@ struct device_node; #ifdef CONFIG_FIXED_PHY extern int fixed_phy_add(unsigned int irq, int phy_id, struct fixed_phy_status *status); -extern int fixed_phy_register(unsigned int irq, - struct fixed_phy_status *status, - struct device_node *np); +extern struct phy_device *fixed_phy_register(unsigned int irq, + struct fixed_phy_status *status, + struct device_node *np); extern void fixed_phy_del(int phy_addr); extern int fixed_phy_set_link_update(struct phy_device *phydev, int (*link_update)(struct net_device *, @@ -27,11 +27,11 @@ static inline int fixed_phy_add(unsigned int irq, int phy_id, { return -ENODEV; } -static inline int fixed_phy_register(unsigned int irq, - struct fixed_phy_status *status, - struct device_node *np) +static inline struct phy_device *fixed_phy_register(unsigned int irq, + struct fixed_phy_status *status, + struct device_node *np) { - return -ENODEV; + return ERR_PTR(-ENODEV); } static inline int fixed_phy_del(int phy_addr) { -- cgit v1.2.3-70-g09d2