diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c index eaa4bb80f1c9..25ced96750bf 100644 --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c @@ -3396,7 +3396,8 @@ static void mvneta_set_eee(struct mvneta_port *pp, bool enable) mvreg_write(pp, MVNETA_LPI_CTRL_1, lpi_ctl1); } -static void mvneta_mac_link_down(struct net_device *ndev, unsigned int mode) +static void mvneta_mac_link_down(struct net_device *ndev, unsigned int mode, + phy_interface_t interface) { struct mvneta_port *pp = netdev_priv(ndev); u32 val; @@ -3415,6 +3416,7 @@ static void mvneta_mac_link_down(struct net_device *ndev, unsigned int mode) } static void mvneta_mac_link_up(struct net_device *ndev, unsigned int mode, + phy_interface_t interface, struct phy_device *phy) { struct mvneta_port *pp = netdev_priv(ndev); @@ -4073,22 +4075,6 @@ static int mvneta_ethtool_set_wol(struct net_device *dev, return ret; } -static int mvneta_ethtool_get_module_info(struct net_device *dev, - struct ethtool_modinfo *modinfo) -{ - struct mvneta_port *pp = netdev_priv(dev); - - return phylink_ethtool_get_module_info(pp->phylink, modinfo); -} - -static int mvneta_ethtool_get_module_eeprom(struct net_device *dev, - struct ethtool_eeprom *ee, u8 *buf) -{ - struct mvneta_port *pp = netdev_priv(dev); - - return phylink_ethtool_get_module_eeprom(pp->phylink, ee, buf); -} - static int mvneta_ethtool_get_eee(struct net_device *dev, struct ethtool_eee *eee) { @@ -4163,8 +4149,6 @@ static const struct ethtool_ops mvneta_eth_tool_ops = { .set_link_ksettings = mvneta_ethtool_set_link_ksettings, .get_wol = mvneta_ethtool_get_wol, .set_wol = mvneta_ethtool_set_wol, - .get_module_info = mvneta_ethtool_get_module_info, - .get_module_eeprom = mvneta_ethtool_get_module_eeprom, .get_eee = mvneta_ethtool_get_eee, .set_eee = mvneta_ethtool_set_eee, }; diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c index 51a011a349fe..c582b2d7546c 100644 --- a/drivers/net/phy/phylink.c +++ b/drivers/net/phy/phylink.c @@ -470,10 +470,12 @@ static void phylink_resolve(struct work_struct *w) if (link_state.link != netif_carrier_ok(ndev)) { if (!link_state.link) { netif_carrier_off(ndev); - pl->ops->mac_link_down(ndev, pl->link_an_mode); + pl->ops->mac_link_down(ndev, pl->link_an_mode, + pl->phy_state.interface); netdev_info(ndev, "Link is Down\n"); } else { pl->ops->mac_link_up(ndev, pl->link_an_mode, + pl->phy_state.interface, pl->phydev); netif_carrier_on(ndev); @@ -1248,34 +1250,6 @@ int phylink_ethtool_set_pauseparam(struct phylink *pl, } EXPORT_SYMBOL_GPL(phylink_ethtool_set_pauseparam); -int phylink_ethtool_get_module_info(struct phylink *pl, - struct ethtool_modinfo *modinfo) -{ - int ret = -EOPNOTSUPP; - - WARN_ON(!lockdep_rtnl_is_held()); - - if (pl->sfp_bus) - ret = sfp_get_module_info(pl->sfp_bus, modinfo); - - return ret; -} -EXPORT_SYMBOL_GPL(phylink_ethtool_get_module_info); - -int phylink_ethtool_get_module_eeprom(struct phylink *pl, - struct ethtool_eeprom *ee, u8 *buf) -{ - int ret = -EOPNOTSUPP; - - WARN_ON(!lockdep_rtnl_is_held()); - - if (pl->sfp_bus) - ret = sfp_get_module_eeprom(pl->sfp_bus, ee, buf); - - return ret; -} -EXPORT_SYMBOL_GPL(phylink_ethtool_get_module_eeprom); - /** * phylink_ethtool_get_eee_err() - read the energy efficient ethernet error * counter diff --git a/drivers/net/phy/sfp-bus.c b/drivers/net/phy/sfp-bus.c index 3d4ff5d0d2a6..0381da78d228 100644 --- a/drivers/net/phy/sfp-bus.c +++ b/drivers/net/phy/sfp-bus.c @@ -342,6 +342,7 @@ static int sfp_register_bus(struct sfp_bus *bus) } if (bus->started) bus->socket_ops->start(bus->sfp); + bus->netdev->sfp_bus = bus; bus->registered = true; return 0; } @@ -356,6 +357,7 @@ static void sfp_unregister_bus(struct sfp_bus *bus) if (bus->phydev && ops && ops->disconnect_phy) ops->disconnect_phy(bus->upstream); } + bus->netdev->sfp_bus = NULL; bus->registered = false; } @@ -371,8 +373,6 @@ static void sfp_unregister_bus(struct sfp_bus *bus) */ int sfp_get_module_info(struct sfp_bus *bus, struct ethtool_modinfo *modinfo) { - if (!bus->registered) - return -ENOIOCTLCMD; return bus->socket_ops->module_info(bus->sfp, modinfo); } EXPORT_SYMBOL_GPL(sfp_get_module_info); @@ -391,8 +391,6 @@ EXPORT_SYMBOL_GPL(sfp_get_module_info); int sfp_get_module_eeprom(struct sfp_bus *bus, struct ethtool_eeprom *ee, u8 *data) { - if (!bus->registered) - return -ENOIOCTLCMD; return bus->socket_ops->module_eeprom(bus->sfp, ee, data); } EXPORT_SYMBOL_GPL(sfp_get_module_eeprom); diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index da44dab492e3..cf44503ea81a 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -58,6 +58,7 @@ struct device; struct phy_device; struct dsa_port; +struct sfp_bus; /* 802.11 specific */ struct wireless_dev; /* 802.15.4 specific */ @@ -1662,6 +1663,7 @@ enum netdev_priv_flags { * @priomap: XXX: need comments on this one * @phydev: Physical device may attach itself * for hardware timestamping + * @sfp_bus: attached &struct sfp_bus structure. * * @qdisc_tx_busylock: lockdep class annotating Qdisc->busylock spinlock * @qdisc_running_key: lockdep class annotating Qdisc->running seqcount @@ -1945,6 +1947,7 @@ struct net_device { struct netprio_map __rcu *priomap; #endif struct phy_device *phydev; + struct sfp_bus *sfp_bus; struct lock_class_key *qdisc_tx_busylock; struct lock_class_key *qdisc_running_key; bool proto_down; diff --git a/include/linux/phylink.h b/include/linux/phylink.h index bd137c273d38..50eeae025f1e 100644 --- a/include/linux/phylink.h +++ b/include/linux/phylink.h @@ -73,8 +73,10 @@ struct phylink_mac_ops { void (*mac_config)(struct net_device *ndev, unsigned int mode, const struct phylink_link_state *state); void (*mac_an_restart)(struct net_device *ndev); - void (*mac_link_down)(struct net_device *ndev, unsigned int mode); + void (*mac_link_down)(struct net_device *ndev, unsigned int mode, + phy_interface_t interface); void (*mac_link_up)(struct net_device *ndev, unsigned int mode, + phy_interface_t interface, struct phy_device *phy); }; @@ -161,25 +163,31 @@ void mac_an_restart(struct net_device *ndev); * mac_link_down() - take the link down * @ndev: a pointer to a &struct net_device for the MAC. * @mode: link autonegotiation mode + * @interface: link &typedef phy_interface_t mode * * If @mode is not an in-band negotiation mode (as defined by * phylink_autoneg_inband()), force the link down and disable any - * Energy Efficient Ethernet MAC configuration. + * Energy Efficient Ethernet MAC configuration. Interface type + * selection must be done in mac_config(). */ -void mac_link_down(struct net_device *ndev, unsigned int mode); +void mac_link_down(struct net_device *ndev, unsigned int mode, + phy_interface_t interface); /** * mac_link_up() - allow the link to come up * @ndev: a pointer to a &struct net_device for the MAC. * @mode: link autonegotiation mode + * @interface: link &typedef phy_interface_t mode * @phy: any attached phy * * If @mode is not an in-band negotiation mode (as defined by * phylink_autoneg_inband()), allow the link to come up. If @phy * is non-%NULL, configure Energy Efficient Ethernet by calling * phy_init_eee() and perform appropriate MAC configuration for EEE. + * Interface type selection must be done in mac_config(). */ void mac_link_up(struct net_device *ndev, unsigned int mode, + phy_interface_t interface, struct phy_device *phy); #endif @@ -211,9 +219,6 @@ void phylink_ethtool_get_pauseparam(struct phylink *, struct ethtool_pauseparam *); int phylink_ethtool_set_pauseparam(struct phylink *, struct ethtool_pauseparam *); -int phylink_ethtool_get_module_info(struct phylink *, struct ethtool_modinfo *); -int phylink_ethtool_get_module_eeprom(struct phylink *, - struct ethtool_eeprom *, u8 *); int phylink_get_eee_err(struct phylink *); int phylink_ethtool_get_eee(struct phylink *, struct ethtool_eee *); int phylink_ethtool_set_eee(struct phylink *, struct ethtool_eee *); diff --git a/net/core/ethtool.c b/net/core/ethtool.c index bb6e498c6e3d..eb55252ca1fb 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -2245,6 +2246,9 @@ static int __ethtool_get_module_info(struct net_device *dev, const struct ethtool_ops *ops = dev->ethtool_ops; struct phy_device *phydev = dev->phydev; + if (dev->sfp_bus) + return sfp_get_module_info(dev->sfp_bus, modinfo); + if (phydev && phydev->drv && phydev->drv->module_info) return phydev->drv->module_info(phydev, modinfo); @@ -2279,6 +2283,9 @@ static int __ethtool_get_module_eeprom(struct net_device *dev, const struct ethtool_ops *ops = dev->ethtool_ops; struct phy_device *phydev = dev->phydev; + if (dev->sfp_bus) + return sfp_get_module_eeprom(dev->sfp_bus, ee, data); + if (phydev && phydev->drv && phydev->drv->module_eeprom) return phydev->drv->module_eeprom(phydev, ee, data);