Use phy lib for the phy. This is needed to get the switch connected to the phy and driven by b53 working. Signed-off-by: Hauke Mehrtens --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -1252,27 +1252,14 @@ static int bgmac_set_mac_address(struct static int bgmac_ioctl(struct net_device *net_dev, struct ifreq *ifr, int cmd) { struct bgmac *bgmac = netdev_priv(net_dev); - struct mii_ioctl_data *data = if_mii(ifr); - switch (cmd) { - case SIOCGMIIPHY: - data->phy_id = bgmac->phyaddr; - /* fallthru */ - case SIOCGMIIREG: - if (!netif_running(net_dev)) - return -EAGAIN; - data->val_out = bgmac_phy_read(bgmac, data->phy_id, - data->reg_num & 0x1f); - return 0; - case SIOCSMIIREG: - if (!netif_running(net_dev)) - return -EAGAIN; - bgmac_phy_write(bgmac, data->phy_id, data->reg_num & 0x1f, - data->val_in); - return 0; - default: - return -EOPNOTSUPP; - } + if (!netif_running(net_dev)) + return -EINVAL; + + if (!bgmac->phydev) + return -EINVAL; + + return phy_mii_ioctl(bgmac->phydev, ifr, cmd); } static const struct net_device_ops bgmac_netdev_ops = { @@ -1294,61 +1281,16 @@ static int bgmac_get_settings(struct net { struct bgmac *bgmac = netdev_priv(net_dev); - cmd->supported = SUPPORTED_10baseT_Half | - SUPPORTED_10baseT_Full | - SUPPORTED_100baseT_Half | - SUPPORTED_100baseT_Full | - SUPPORTED_1000baseT_Half | - SUPPORTED_1000baseT_Full | - SUPPORTED_Autoneg; - - if (bgmac->autoneg) { - WARN_ON(cmd->advertising); - if (bgmac->full_duplex) { - if (bgmac->speed & BGMAC_SPEED_10) - cmd->advertising |= ADVERTISED_10baseT_Full; - if (bgmac->speed & BGMAC_SPEED_100) - cmd->advertising |= ADVERTISED_100baseT_Full; - if (bgmac->speed & BGMAC_SPEED_1000) - cmd->advertising |= ADVERTISED_1000baseT_Full; - } else { - if (bgmac->speed & BGMAC_SPEED_10) - cmd->advertising |= ADVERTISED_10baseT_Half; - if (bgmac->speed & BGMAC_SPEED_100) - cmd->advertising |= ADVERTISED_100baseT_Half; - if (bgmac->speed & BGMAC_SPEED_1000) - cmd->advertising |= ADVERTISED_1000baseT_Half; - } - } else { - switch (bgmac->speed) { - case BGMAC_SPEED_10: - ethtool_cmd_speed_set(cmd, SPEED_10); - break; - case BGMAC_SPEED_100: - ethtool_cmd_speed_set(cmd, SPEED_100); - break; - case BGMAC_SPEED_1000: - ethtool_cmd_speed_set(cmd, SPEED_1000); - break; - } - } - - cmd->duplex = bgmac->full_duplex ? DUPLEX_FULL : DUPLEX_HALF; - - cmd->autoneg = bgmac->autoneg; - - return 0; + return phy_ethtool_gset(bgmac->phydev, cmd); } -#if 0 static int bgmac_set_settings(struct net_device *net_dev, struct ethtool_cmd *cmd) { struct bgmac *bgmac = netdev_priv(net_dev); - return -1; + return phy_ethtool_sset(bgmac->phydev, cmd); } -#endif static void bgmac_get_drvinfo(struct net_device *net_dev, struct ethtool_drvinfo *info) @@ -1359,6 +1301,7 @@ static void bgmac_get_drvinfo(struct net static const struct ethtool_ops bgmac_ethtool_ops = { .get_settings = bgmac_get_settings, + .set_settings = bgmac_set_settings, .get_drvinfo = bgmac_get_drvinfo, }; @@ -1377,10 +1320,36 @@ static int bgmac_mii_write(struct mii_bu return bgmac_phy_write(bus->priv, mii_id, regnum, value); } +static void bgmac_adjust_link(struct net_device *dev) +{ + struct bgmac *bgmac = netdev_priv(dev); + struct phy_device *phydev = bgmac->phydev; + bool status_changed = 0; + + BUG_ON(!phydev); + + if (bgmac->old_link != phydev->link) { + status_changed = 1; + bgmac->old_link = phydev->link; + } + + /* reflect duplex change */ + if (phydev->link && (bgmac->old_duplex != phydev->duplex)) { + status_changed = 1; + bgmac->old_duplex = phydev->duplex; + } + + if (status_changed) + phy_print_status(phydev); +} + static int bgmac_mii_register(struct bgmac *bgmac) { struct mii_bus *mii_bus; int i, err = 0; + struct phy_device *phydev = NULL; + char phy_id[MII_BUS_ID_SIZE + 3]; + struct net_device *net_dev = bgmac->net_dev; mii_bus = mdiobus_alloc(); if (!mii_bus) @@ -1411,7 +1380,28 @@ static int bgmac_mii_register(struct bgm bgmac->mii_bus = mii_bus; - return err; + /* connect to PHY */ + snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT, + mii_bus->id, bgmac->phyaddr); + + phydev = phy_connect(net_dev, phy_id, &bgmac_adjust_link, + PHY_INTERFACE_MODE_MII); + + if (IS_ERR(phydev)) { + netdev_err(net_dev, "could not attach PHY: %s\n", phy_id); + bgmac->phyaddr = BGMAC_PHY_NOREGS; + return PTR_ERR(phydev); + } + + bgmac->phydev = phydev; + bgmac->old_link = 0; + bgmac->old_duplex = -1; + bgmac->phyaddr = phydev->addr; + + netdev_info(net_dev, "attached PHY driver [%s] (mii_bus:phy_addr=%s)\n", + phydev->drv->name, dev_name(&phydev->dev)); + + return 0; err_free_irq: kfree(mii_bus->irq); --- a/drivers/net/ethernet/broadcom/bgmac.h +++ b/drivers/net/ethernet/broadcom/bgmac.h @@ -401,7 +401,10 @@ struct bgmac { struct bcma_device *cmn; /* Reference to CMN core for BCM4706 */ struct net_device *net_dev; struct napi_struct napi; + struct phy_device *phydev; struct mii_bus *mii_bus; + int old_link; + int old_duplex; /* DMA */ struct bgmac_dma_ring tx_ring[BGMAC_MAX_TX_RINGS];