On Wed, 2018-12-12 at 15:51 +0100, Andrew Lunn wrote: > CAUTION: This email originated from outside of the organization. Do not click > links or open attachments unless you recognize the sender and know the > content is safe. > > > > fast check, would you be happy with this in fixed PHY: > > --- a/drivers/net/phy/fixed_phy.c > > +++ b/drivers/net/phy/fixed_phy.c > > @@ -25,6 +25,7 @@ > > #include <linux/gpio.h> > > #include <linux/seqlock.h> > > #include <linux/idr.h> > > +#include <linux/netdevice.h> > > > > #include "swphy.h" > > > > @@ -38,6 +39,7 @@ struct fixed_phy { > > struct phy_device *phydev; > > seqcount_t seqcount; > > struct fixed_phy_status status; > > + bool no_carrier; > > int (*link_update)(struct net_device *, struct fixed_phy_status *); > > struct list_head node; > > int link_gpio; > > @@ -48,6 +50,24 @@ static struct fixed_mdio_bus platform_fmb = { > > .phys = LIST_HEAD_INIT(platform_fmb.phys), > > }; > > > > +int > > +fixed_phy_change_carrier(struct net_device *dev, bool new_carrier) > > +{ > > + struct fixed_mdio_bus *fmb = &platform_fmb; > > + struct phy_device *phydev = dev->phydev; > > + struct fixed_phy *fp; > > + > > + if (!phydev || !phydev->mdio.bus) > > + return -EINVAL; > > + > > + list_for_each_entry(fp, &fmb->phys, node) { > > + if (fp->addr == phydev->mdio.addr) { > > + fp->no_carrier = !new_carrier; > > Why is no_carrier needed? You can directly change fp->status.link, so > long as you take care of locking.
I to remember it for the gpio control of link state, see below. > > > + return 0; > > + } > > + } > > + return -EINVAL; > > +} > > You need to export the function. Yes, it was not a complete patch. Below is what I have now and is happy with: diff --git a/drivers/net/phy/fixed_phy.c b/drivers/net/phy/fixed_phy.c index eb5167210681..aedebc251997 100644 --- a/drivers/net/phy/fixed_phy.c +++ b/drivers/net/phy/fixed_phy.c @@ -25,6 +25,7 @@ #include <linux/gpio.h> #include <linux/seqlock.h> #include <linux/idr.h> +#include <linux/netdevice.h> #include "swphy.h" @@ -38,6 +39,7 @@ struct fixed_phy { struct phy_device *phydev; seqcount_t seqcount; struct fixed_phy_status status; + bool no_carrier; int (*link_update)(struct net_device *, struct fixed_phy_status *); struct list_head node; int link_gpio; @@ -48,9 +50,27 @@ static struct fixed_mdio_bus platform_fmb = { .phys = LIST_HEAD_INIT(platform_fmb.phys), }; +int +fixed_phy_change_carrier(struct net_device *dev, bool new_carrier) +{ + struct fixed_mdio_bus *fmb = &platform_fmb; + struct phy_device *phydev = dev->phydev; + struct fixed_phy *fp; + + if (!phydev || !phydev->mdio.bus) + return -EINVAL; + + list_for_each_entry(fp, &fmb->phys, node) { + if (fp->addr == phydev->mdio.addr) { + fp->no_carrier = !new_carrier; + return 0; + } + } + return -EINVAL; +} static void fixed_phy_update(struct fixed_phy *fp) { - if (gpio_is_valid(fp->link_gpio)) + if (!fp->no_carrier && gpio_is_valid(fp->link_gpio)) fp->status.link = !!gpio_get_value_cansleep(fp->link_gpio); } @@ -66,6 +86,7 @@ static int fixed_mdio_read(struct mii_bus *bus, int phy_addr, int reg_num) do { s = read_seqcount_begin(&fp->seqcount); + fp->status.link = !fp->no_carrier; /* Issue callback if user registered it. */ if (fp->link_update) { fp->link_update(fp->phydev->attached_dev, diff --git a/include/linux/phy_fixed.h b/include/linux/phy_fixed.h index cf6392de6eb0..09d7e613cffc 100644 --- a/include/linux/phy_fixed.h +++ b/include/linux/phy_fixed.h @@ -27,6 +27,7 @@ extern int fixed_phy_set_link_update(struct phy_device *phydev, extern int fixed_phy_update_state(struct phy_device *phydev, const struct fixed_phy_status *status, const struct fixed_phy_status *changed); +extern int fixed_phy_change_carrier(struct net_device *dev, bool new_carrier); #else static inline int fixed_phy_add(unsigned int irq, int phy_id, struct fixed_phy_status *status, @@ -56,6 +57,10 @@ static inline int fixed_phy_update_state(struct phy_device *phydev, { return -ENODEV; } +static inline int fixed_phy_change_carrier(struct net_device *dev, bool new_carrier) +{ + return -EINVAL; +} #endif /* CONFIG_FIXED_PHY */ #endif /* __PHY_FIXED_H */ -- 2.18.1