I am looking for a way to induce carrier state from user space, primarily for Fixed PHYs as these are always up. ifplugd/dhcp etc. does not behave properly if the link is up when it really isn't.
I came up with a new 'phy_carrier' attribute in /sys/class/net/eth0/phydev where I can induce carrier state: diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index a1e7ea4d4b16..f82beeabdd75 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -612,10 +612,39 @@ phy_has_fixups_show(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR_RO(phy_has_fixups); +static ssize_t +phy_carrier_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct phy_device *phydev = to_phy_device(dev); + struct net_device *netdev = phydev->attached_dev; + + return sprintf(buf, "%d\n", netif_carrier_ok(netdev)); +} + +static ssize_t phy_carrier_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t len) +{ + struct phy_device *phydev = to_phy_device(dev); + struct net_device *netdev = phydev->attached_dev; + bool enable; + + if (strtobool(buf, &enable)) + return -EINVAL; + + if (enable) + netif_carrier_on(netdev); + else + netif_carrier_off(netdev); + return len; +} +static DEVICE_ATTR_RW(phy_carrier); + static struct attribute *phy_dev_attrs[] = { &dev_attr_phy_id.attr, &dev_attr_phy_interface.attr, &dev_attr_phy_has_fixups.attr, + &dev_attr_phy_carrier.attr, NULL, }; ATTRIBUTE_GROUPS(phy_dev); I would like to know if this acceptable for linux proper or if there is a better way to do this? Jocke