diff options
Diffstat (limited to 'drivers/net/ethernet/smsc')
-rw-r--r-- | drivers/net/ethernet/smsc/epic100.c | 16 | ||||
-rw-r--r-- | drivers/net/ethernet/smsc/smc911x.c | 51 | ||||
-rw-r--r-- | drivers/net/ethernet/smsc/smc91c92_cs.c | 98 | ||||
-rw-r--r-- | drivers/net/ethernet/smsc/smsc911x.c | 49 | ||||
-rw-r--r-- | drivers/net/ethernet/smsc/smsc911x.h | 19 |
5 files changed, 137 insertions, 96 deletions
diff --git a/drivers/net/ethernet/smsc/epic100.c b/drivers/net/ethernet/smsc/epic100.c index 5f2737189c72..db6dcb06193d 100644 --- a/drivers/net/ethernet/smsc/epic100.c +++ b/drivers/net/ethernet/smsc/epic100.c @@ -1387,25 +1387,27 @@ static void netdev_get_drvinfo (struct net_device *dev, struct ethtool_drvinfo * strlcpy(info->bus_info, pci_name(np->pci_dev), sizeof(info->bus_info)); } -static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +static int netdev_get_link_ksettings(struct net_device *dev, + struct ethtool_link_ksettings *cmd) { struct epic_private *np = netdev_priv(dev); int rc; spin_lock_irq(&np->lock); - rc = mii_ethtool_gset(&np->mii, cmd); + rc = mii_ethtool_get_link_ksettings(&np->mii, cmd); spin_unlock_irq(&np->lock); return rc; } -static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) +static int netdev_set_link_ksettings(struct net_device *dev, + const struct ethtool_link_ksettings *cmd) { struct epic_private *np = netdev_priv(dev); int rc; spin_lock_irq(&np->lock); - rc = mii_ethtool_sset(&np->mii, cmd); + rc = mii_ethtool_set_link_ksettings(&np->mii, cmd); spin_unlock_irq(&np->lock); return rc; @@ -1460,14 +1462,14 @@ static void ethtool_complete(struct net_device *dev) static const struct ethtool_ops netdev_ethtool_ops = { .get_drvinfo = netdev_get_drvinfo, - .get_settings = netdev_get_settings, - .set_settings = netdev_set_settings, .nway_reset = netdev_nway_reset, .get_link = netdev_get_link, .get_msglevel = netdev_get_msglevel, .set_msglevel = netdev_set_msglevel, .begin = ethtool_begin, - .complete = ethtool_complete + .complete = ethtool_complete, + .get_link_ksettings = netdev_get_link_ksettings, + .set_link_ksettings = netdev_set_link_ksettings, }; static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) diff --git a/drivers/net/ethernet/smsc/smc911x.c b/drivers/net/ethernet/smsc/smc911x.c index 4f19c6166182..36307d34f641 100644 --- a/drivers/net/ethernet/smsc/smc911x.c +++ b/drivers/net/ethernet/smsc/smc911x.c @@ -1446,40 +1446,40 @@ static int smc911x_close(struct net_device *dev) * Ethtool support */ static int -smc911x_ethtool_getsettings(struct net_device *dev, struct ethtool_cmd *cmd) +smc911x_ethtool_get_link_ksettings(struct net_device *dev, + struct ethtool_link_ksettings *cmd) { struct smc911x_local *lp = netdev_priv(dev); int ret, status; unsigned long flags; + u32 supported; DBG(SMC_DEBUG_FUNC, dev, "--> %s\n", __func__); - cmd->maxtxpkt = 1; - cmd->maxrxpkt = 1; if (lp->phy_type != 0) { spin_lock_irqsave(&lp->lock, flags); - ret = mii_ethtool_gset(&lp->mii, cmd); + ret = mii_ethtool_get_link_ksettings(&lp->mii, cmd); spin_unlock_irqrestore(&lp->lock, flags); } else { - cmd->supported = SUPPORTED_10baseT_Half | + supported = SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_TP | SUPPORTED_AUI; if (lp->ctl_rspeed == 10) - ethtool_cmd_speed_set(cmd, SPEED_10); + cmd->base.speed = SPEED_10; else if (lp->ctl_rspeed == 100) - ethtool_cmd_speed_set(cmd, SPEED_100); - - cmd->autoneg = AUTONEG_DISABLE; - if (lp->mii.phy_id==1) - cmd->transceiver = XCVR_INTERNAL; - else - cmd->transceiver = XCVR_EXTERNAL; - cmd->port = 0; + cmd->base.speed = SPEED_100; + + cmd->base.autoneg = AUTONEG_DISABLE; + cmd->base.port = 0; SMC_GET_PHY_SPECIAL(lp, lp->mii.phy_id, status); - cmd->duplex = + cmd->base.duplex = (status & (PHY_SPECIAL_SPD_10FULL_ | PHY_SPECIAL_SPD_100FULL_)) ? DUPLEX_FULL : DUPLEX_HALF; + + ethtool_convert_legacy_u32_to_link_mode( + cmd->link_modes.supported, supported); + ret = 0; } @@ -1487,7 +1487,8 @@ smc911x_ethtool_getsettings(struct net_device *dev, struct ethtool_cmd *cmd) } static int -smc911x_ethtool_setsettings(struct net_device *dev, struct ethtool_cmd *cmd) +smc911x_ethtool_set_link_ksettings(struct net_device *dev, + const struct ethtool_link_ksettings *cmd) { struct smc911x_local *lp = netdev_priv(dev); int ret; @@ -1495,16 +1496,18 @@ smc911x_ethtool_setsettings(struct net_device *dev, struct ethtool_cmd *cmd) if (lp->phy_type != 0) { spin_lock_irqsave(&lp->lock, flags); - ret = mii_ethtool_sset(&lp->mii, cmd); + ret = mii_ethtool_set_link_ksettings(&lp->mii, cmd); spin_unlock_irqrestore(&lp->lock, flags); } else { - if (cmd->autoneg != AUTONEG_DISABLE || - cmd->speed != SPEED_10 || - (cmd->duplex != DUPLEX_HALF && cmd->duplex != DUPLEX_FULL) || - (cmd->port != PORT_TP && cmd->port != PORT_AUI)) + if (cmd->base.autoneg != AUTONEG_DISABLE || + cmd->base.speed != SPEED_10 || + (cmd->base.duplex != DUPLEX_HALF && + cmd->base.duplex != DUPLEX_FULL) || + (cmd->base.port != PORT_TP && + cmd->base.port != PORT_AUI)) return -EINVAL; - lp->ctl_rfduplx = cmd->duplex == DUPLEX_FULL; + lp->ctl_rfduplx = cmd->base.duplex == DUPLEX_FULL; ret = 0; } @@ -1686,8 +1689,6 @@ static int smc911x_ethtool_geteeprom_len(struct net_device *dev) } static const struct ethtool_ops smc911x_ethtool_ops = { - .get_settings = smc911x_ethtool_getsettings, - .set_settings = smc911x_ethtool_setsettings, .get_drvinfo = smc911x_ethtool_getdrvinfo, .get_msglevel = smc911x_ethtool_getmsglevel, .set_msglevel = smc911x_ethtool_setmsglevel, @@ -1698,6 +1699,8 @@ static const struct ethtool_ops smc911x_ethtool_ops = { .get_eeprom_len = smc911x_ethtool_geteeprom_len, .get_eeprom = smc911x_ethtool_geteeprom, .set_eeprom = smc911x_ethtool_seteeprom, + .get_link_ksettings = smc911x_ethtool_get_link_ksettings, + .set_link_ksettings = smc911x_ethtool_set_link_ksettings, }; /* diff --git a/drivers/net/ethernet/smsc/smc91c92_cs.c b/drivers/net/ethernet/smsc/smc91c92_cs.c index 97280daba27f..976aa876789a 100644 --- a/drivers/net/ethernet/smsc/smc91c92_cs.c +++ b/drivers/net/ethernet/smsc/smc91c92_cs.c @@ -1843,56 +1843,60 @@ static int smc_link_ok(struct net_device *dev) } } -static int smc_netdev_get_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd) +static int smc_netdev_get_ecmd(struct net_device *dev, + struct ethtool_link_ksettings *ecmd) { - u16 tmp; - unsigned int ioaddr = dev->base_addr; + u16 tmp; + unsigned int ioaddr = dev->base_addr; + u32 supported; - ecmd->supported = (SUPPORTED_TP | SUPPORTED_AUI | - SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full); - - SMC_SELECT_BANK(1); - tmp = inw(ioaddr + CONFIG); - ecmd->port = (tmp & CFG_AUI_SELECT) ? PORT_AUI : PORT_TP; - ecmd->transceiver = XCVR_INTERNAL; - ethtool_cmd_speed_set(ecmd, SPEED_10); - ecmd->phy_address = ioaddr + MGMT; + supported = (SUPPORTED_TP | SUPPORTED_AUI | + SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full); - SMC_SELECT_BANK(0); - tmp = inw(ioaddr + TCR); - ecmd->duplex = (tmp & TCR_FDUPLX) ? DUPLEX_FULL : DUPLEX_HALF; + SMC_SELECT_BANK(1); + tmp = inw(ioaddr + CONFIG); + ecmd->base.port = (tmp & CFG_AUI_SELECT) ? PORT_AUI : PORT_TP; + ecmd->base.speed = SPEED_10; + ecmd->base.phy_address = ioaddr + MGMT; - return 0; + SMC_SELECT_BANK(0); + tmp = inw(ioaddr + TCR); + ecmd->base.duplex = (tmp & TCR_FDUPLX) ? DUPLEX_FULL : DUPLEX_HALF; + + ethtool_convert_legacy_u32_to_link_mode(ecmd->link_modes.supported, + supported); + + return 0; } -static int smc_netdev_set_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd) +static int smc_netdev_set_ecmd(struct net_device *dev, + const struct ethtool_link_ksettings *ecmd) { - u16 tmp; - unsigned int ioaddr = dev->base_addr; + u16 tmp; + unsigned int ioaddr = dev->base_addr; - if (ethtool_cmd_speed(ecmd) != SPEED_10) - return -EINVAL; - if (ecmd->duplex != DUPLEX_HALF && ecmd->duplex != DUPLEX_FULL) - return -EINVAL; - if (ecmd->port != PORT_TP && ecmd->port != PORT_AUI) - return -EINVAL; - if (ecmd->transceiver != XCVR_INTERNAL) - return -EINVAL; + if (ecmd->base.speed != SPEED_10) + return -EINVAL; + if (ecmd->base.duplex != DUPLEX_HALF && + ecmd->base.duplex != DUPLEX_FULL) + return -EINVAL; + if (ecmd->base.port != PORT_TP && ecmd->base.port != PORT_AUI) + return -EINVAL; - if (ecmd->port == PORT_AUI) - smc_set_xcvr(dev, 1); - else - smc_set_xcvr(dev, 0); + if (ecmd->base.port == PORT_AUI) + smc_set_xcvr(dev, 1); + else + smc_set_xcvr(dev, 0); - SMC_SELECT_BANK(0); - tmp = inw(ioaddr + TCR); - if (ecmd->duplex == DUPLEX_FULL) - tmp |= TCR_FDUPLX; - else - tmp &= ~TCR_FDUPLX; - outw(tmp, ioaddr + TCR); - - return 0; + SMC_SELECT_BANK(0); + tmp = inw(ioaddr + TCR); + if (ecmd->base.duplex == DUPLEX_FULL) + tmp |= TCR_FDUPLX; + else + tmp &= ~TCR_FDUPLX; + outw(tmp, ioaddr + TCR); + + return 0; } static int check_if_running(struct net_device *dev) @@ -1908,7 +1912,8 @@ static void smc_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info strlcpy(info->version, DRV_VERSION, sizeof(info->version)); } -static int smc_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) +static int smc_get_link_ksettings(struct net_device *dev, + struct ethtool_link_ksettings *ecmd) { struct smc_private *smc = netdev_priv(dev); unsigned int ioaddr = dev->base_addr; @@ -1919,7 +1924,7 @@ static int smc_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) spin_lock_irqsave(&smc->lock, flags); SMC_SELECT_BANK(3); if (smc->cfg & CFG_MII_SELECT) - ret = mii_ethtool_gset(&smc->mii_if, ecmd); + ret = mii_ethtool_get_link_ksettings(&smc->mii_if, ecmd); else ret = smc_netdev_get_ecmd(dev, ecmd); SMC_SELECT_BANK(saved_bank); @@ -1927,7 +1932,8 @@ static int smc_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) return ret; } -static int smc_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) +static int smc_set_link_ksettings(struct net_device *dev, + const struct ethtool_link_ksettings *ecmd) { struct smc_private *smc = netdev_priv(dev); unsigned int ioaddr = dev->base_addr; @@ -1938,7 +1944,7 @@ static int smc_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) spin_lock_irqsave(&smc->lock, flags); SMC_SELECT_BANK(3); if (smc->cfg & CFG_MII_SELECT) - ret = mii_ethtool_sset(&smc->mii_if, ecmd); + ret = mii_ethtool_set_link_ksettings(&smc->mii_if, ecmd); else ret = smc_netdev_set_ecmd(dev, ecmd); SMC_SELECT_BANK(saved_bank); @@ -1982,10 +1988,10 @@ static int smc_nway_reset(struct net_device *dev) static const struct ethtool_ops ethtool_ops = { .begin = check_if_running, .get_drvinfo = smc_get_drvinfo, - .get_settings = smc_get_settings, - .set_settings = smc_set_settings, .get_link = smc_get_link, .nway_reset = smc_nway_reset, + .get_link_ksettings = smc_get_link_ksettings, + .set_link_ksettings = smc_set_link_ksettings, }; static int smc_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c index fa5ca0992be6..ea1bbc355b4d 100644 --- a/drivers/net/ethernet/smsc/smsc911x.c +++ b/drivers/net/ethernet/smsc/smsc911x.c @@ -25,7 +25,7 @@ * LAN9215, LAN9216, LAN9217, LAN9218 * LAN9210, LAN9211 * LAN9220, LAN9221 - * LAN89218 + * LAN89218,LAN9250 * */ @@ -1450,6 +1450,8 @@ static int smsc911x_soft_reset(struct smsc911x_data *pdata) unsigned int timeout; unsigned int temp; int ret; + unsigned int reset_offset = HW_CFG; + unsigned int reset_mask = HW_CFG_SRST_; /* * Make sure to power-up the PHY chip before doing a reset, otherwise @@ -1476,15 +1478,23 @@ static int smsc911x_soft_reset(struct smsc911x_data *pdata) } } + if ((pdata->idrev & 0xFFFF0000) == LAN9250) { + /* special reset for LAN9250 */ + reset_offset = RESET_CTL; + reset_mask = RESET_CTL_DIGITAL_RST_; + } + /* Reset the LAN911x */ - smsc911x_reg_write(pdata, HW_CFG, HW_CFG_SRST_); + smsc911x_reg_write(pdata, reset_offset, reset_mask); + + /* verify reset bit is cleared */ timeout = 10; do { udelay(10); - temp = smsc911x_reg_read(pdata, HW_CFG); - } while ((--timeout) && (temp & HW_CFG_SRST_)); + temp = smsc911x_reg_read(pdata, reset_offset); + } while ((--timeout) && (temp & reset_mask)); - if (unlikely(temp & HW_CFG_SRST_)) { + if (unlikely(temp & reset_mask)) { SMSC_WARN(pdata, drv, "Failed to complete reset"); return -EIO; } @@ -2253,28 +2263,29 @@ static int smsc911x_init(struct net_device *dev) pdata->idrev = smsc911x_reg_read(pdata, ID_REV); switch (pdata->idrev & 0xFFFF0000) { - case 0x01180000: - case 0x01170000: - case 0x01160000: - case 0x01150000: - case 0x218A0000: + case LAN9118: + case LAN9117: + case LAN9116: + case LAN9115: + case LAN89218: /* LAN911[5678] family */ pdata->generation = pdata->idrev & 0x0000FFFF; break; - case 0x118A0000: - case 0x117A0000: - case 0x116A0000: - case 0x115A0000: + case LAN9218: + case LAN9217: + case LAN9216: + case LAN9215: /* LAN921[5678] family */ pdata->generation = 3; break; - case 0x92100000: - case 0x92110000: - case 0x92200000: - case 0x92210000: - /* LAN9210/LAN9211/LAN9220/LAN9221 */ + case LAN9210: + case LAN9211: + case LAN9220: + case LAN9221: + case LAN9250: + /* LAN9210/LAN9211/LAN9220/LAN9221/LAN9250 */ pdata->generation = 4; break; diff --git a/drivers/net/ethernet/smsc/smsc911x.h b/drivers/net/ethernet/smsc/smsc911x.h index 54d648920a1b..8d75508acd2b 100644 --- a/drivers/net/ethernet/smsc/smsc911x.h +++ b/drivers/net/ethernet/smsc/smsc911x.h @@ -20,6 +20,22 @@ #ifndef __SMSC911X_H__ #define __SMSC911X_H__ +/*Chip ID*/ +#define LAN9115 0x01150000 +#define LAN9116 0x01160000 +#define LAN9117 0x01170000 +#define LAN9118 0x01180000 +#define LAN9215 0x115A0000 +#define LAN9216 0x116A0000 +#define LAN9217 0x117A0000 +#define LAN9218 0x118A0000 +#define LAN9210 0x92100000 +#define LAN9211 0x92110000 +#define LAN9220 0x92200000 +#define LAN9221 0x92210000 +#define LAN9250 0x92500000 +#define LAN89218 0x218A0000 + #define TX_FIFO_LOW_THRESHOLD ((u32)1600) #define SMSC911X_EEPROM_SIZE ((u32)128) #define USE_DEBUG 0 @@ -303,6 +319,9 @@ #define E2P_DATA_EEPROM_DATA_ 0x000000FF #define LAN_REGISTER_EXTENT 0x00000100 +#define RESET_CTL 0x1F8 +#define RESET_CTL_DIGITAL_RST_ 0x00000001 + /* * MAC Control and Status Register (Indirect Address) * Offset (through the MAC_CSR CMD and DATA port) |