Loading drivers/net/ns83820.c +148 −3 Original line number Diff line number Diff line #define VERSION "0.22" #define VERSION "0.23" /* ns83820.c by Benjamin LaHaise with contributions. * * Questions/comments/discussion to linux-ns83820@kvack.org. Loading Loading @@ -1247,6 +1247,149 @@ static struct net_device_stats *ns83820_get_stats(struct net_device *ndev) return &dev->stats; } /* Let ethtool retrieve info */ static int ns83820_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd) { struct ns83820 *dev = PRIV(ndev); u32 cfg, tanar, tbicr; int have_optical = 0; int fullduplex = 0; /* * Here's the list of available ethtool commands from other drivers: * cmd->advertising = * cmd->speed = * cmd->duplex = * cmd->port = 0; * cmd->phy_address = * cmd->transceiver = 0; * cmd->autoneg = * cmd->maxtxpkt = 0; * cmd->maxrxpkt = 0; */ /* read current configuration */ cfg = readl(dev->base + CFG) ^ SPDSTS_POLARITY; tanar = readl(dev->base + TANAR); tbicr = readl(dev->base + TBICR); if (dev->CFG_cache & CFG_TBI_EN) { /* we have an optical interface */ have_optical = 1; fullduplex = (cfg & CFG_DUPSTS) ? 1 : 0; } else { /* We have copper */ fullduplex = (cfg & CFG_DUPSTS) ? 1 : 0; } cmd->supported = SUPPORTED_Autoneg; /* we have optical interface */ if (dev->CFG_cache & CFG_TBI_EN) { cmd->supported |= SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full | SUPPORTED_FIBRE; cmd->port = PORT_FIBRE; } /* TODO: else copper related support */ cmd->duplex = fullduplex ? DUPLEX_FULL : DUPLEX_HALF; switch (cfg / CFG_SPDSTS0 & 3) { case 2: cmd->speed = SPEED_1000; break; case 1: cmd->speed = SPEED_100; break; default: cmd->speed = SPEED_10; break; } cmd->autoneg = (tbicr & TBICR_MR_AN_ENABLE) ? 1: 0; return 0; } /* Let ethool change settings*/ static int ns83820_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd) { struct ns83820 *dev = PRIV(ndev); u32 cfg, tanar; int have_optical = 0; int fullduplex = 0; /* read current configuration */ cfg = readl(dev->base + CFG) ^ SPDSTS_POLARITY; tanar = readl(dev->base + TANAR); if (dev->CFG_cache & CFG_TBI_EN) { /* we have optical */ have_optical = 1; fullduplex = (tanar & TANAR_FULL_DUP); } else { /* we have copper */ fullduplex = cfg & CFG_DUPSTS; } spin_lock_irq(&dev->misc_lock); spin_lock(&dev->tx_lock); /* Set duplex */ if (cmd->duplex != fullduplex) { if (have_optical) { /*set full duplex*/ if (cmd->duplex == DUPLEX_FULL) { /* force full duplex */ writel(readl(dev->base + TXCFG) | TXCFG_CSI | TXCFG_HBI | TXCFG_ATP, dev->base + TXCFG); writel(readl(dev->base + RXCFG) | RXCFG_RX_FD, dev->base + RXCFG); /* Light up full duplex LED */ writel(readl(dev->base + GPIOR) | GPIOR_GP1_OUT, dev->base + GPIOR); } else { /*TODO: set half duplex */ } } else { /*we have copper*/ /* TODO: Set duplex for copper cards */ } printk(KERN_INFO "%s: Duplex set via ethtool\n", ndev->name); } /* Set autonegotiation */ if (1) { if (cmd->autoneg == AUTONEG_ENABLE) { /* restart auto negotiation */ writel(TBICR_MR_AN_ENABLE | TBICR_MR_RESTART_AN, dev->base + TBICR); writel(TBICR_MR_AN_ENABLE, dev->base + TBICR); dev->linkstate = LINK_AUTONEGOTIATE; printk(KERN_INFO "%s: autoneg enabled via ethtool\n", ndev->name); } else { /* disable auto negotiation */ writel(0x00000000, dev->base + TBICR); } printk(KERN_INFO "%s: autoneg %s via ethtool\n", ndev->name, cmd->autoneg ? "ENABLED" : "DISABLED"); } phy_intr(ndev); spin_unlock(&dev->tx_lock); spin_unlock_irq(&dev->misc_lock); return 0; } /* end ethtool get/set support -df */ static void ns83820_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo *info) { struct ns83820 *dev = PRIV(ndev); Loading @@ -1263,6 +1406,8 @@ static u32 ns83820_get_link(struct net_device *ndev) } static const struct ethtool_ops ops = { .get_settings = ns83820_get_settings, .set_settings = ns83820_set_settings, .get_drvinfo = ns83820_get_drvinfo, .get_link = ns83820_get_link }; Loading Loading
drivers/net/ns83820.c +148 −3 Original line number Diff line number Diff line #define VERSION "0.22" #define VERSION "0.23" /* ns83820.c by Benjamin LaHaise with contributions. * * Questions/comments/discussion to linux-ns83820@kvack.org. Loading Loading @@ -1247,6 +1247,149 @@ static struct net_device_stats *ns83820_get_stats(struct net_device *ndev) return &dev->stats; } /* Let ethtool retrieve info */ static int ns83820_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd) { struct ns83820 *dev = PRIV(ndev); u32 cfg, tanar, tbicr; int have_optical = 0; int fullduplex = 0; /* * Here's the list of available ethtool commands from other drivers: * cmd->advertising = * cmd->speed = * cmd->duplex = * cmd->port = 0; * cmd->phy_address = * cmd->transceiver = 0; * cmd->autoneg = * cmd->maxtxpkt = 0; * cmd->maxrxpkt = 0; */ /* read current configuration */ cfg = readl(dev->base + CFG) ^ SPDSTS_POLARITY; tanar = readl(dev->base + TANAR); tbicr = readl(dev->base + TBICR); if (dev->CFG_cache & CFG_TBI_EN) { /* we have an optical interface */ have_optical = 1; fullduplex = (cfg & CFG_DUPSTS) ? 1 : 0; } else { /* We have copper */ fullduplex = (cfg & CFG_DUPSTS) ? 1 : 0; } cmd->supported = SUPPORTED_Autoneg; /* we have optical interface */ if (dev->CFG_cache & CFG_TBI_EN) { cmd->supported |= SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full | SUPPORTED_FIBRE; cmd->port = PORT_FIBRE; } /* TODO: else copper related support */ cmd->duplex = fullduplex ? DUPLEX_FULL : DUPLEX_HALF; switch (cfg / CFG_SPDSTS0 & 3) { case 2: cmd->speed = SPEED_1000; break; case 1: cmd->speed = SPEED_100; break; default: cmd->speed = SPEED_10; break; } cmd->autoneg = (tbicr & TBICR_MR_AN_ENABLE) ? 1: 0; return 0; } /* Let ethool change settings*/ static int ns83820_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd) { struct ns83820 *dev = PRIV(ndev); u32 cfg, tanar; int have_optical = 0; int fullduplex = 0; /* read current configuration */ cfg = readl(dev->base + CFG) ^ SPDSTS_POLARITY; tanar = readl(dev->base + TANAR); if (dev->CFG_cache & CFG_TBI_EN) { /* we have optical */ have_optical = 1; fullduplex = (tanar & TANAR_FULL_DUP); } else { /* we have copper */ fullduplex = cfg & CFG_DUPSTS; } spin_lock_irq(&dev->misc_lock); spin_lock(&dev->tx_lock); /* Set duplex */ if (cmd->duplex != fullduplex) { if (have_optical) { /*set full duplex*/ if (cmd->duplex == DUPLEX_FULL) { /* force full duplex */ writel(readl(dev->base + TXCFG) | TXCFG_CSI | TXCFG_HBI | TXCFG_ATP, dev->base + TXCFG); writel(readl(dev->base + RXCFG) | RXCFG_RX_FD, dev->base + RXCFG); /* Light up full duplex LED */ writel(readl(dev->base + GPIOR) | GPIOR_GP1_OUT, dev->base + GPIOR); } else { /*TODO: set half duplex */ } } else { /*we have copper*/ /* TODO: Set duplex for copper cards */ } printk(KERN_INFO "%s: Duplex set via ethtool\n", ndev->name); } /* Set autonegotiation */ if (1) { if (cmd->autoneg == AUTONEG_ENABLE) { /* restart auto negotiation */ writel(TBICR_MR_AN_ENABLE | TBICR_MR_RESTART_AN, dev->base + TBICR); writel(TBICR_MR_AN_ENABLE, dev->base + TBICR); dev->linkstate = LINK_AUTONEGOTIATE; printk(KERN_INFO "%s: autoneg enabled via ethtool\n", ndev->name); } else { /* disable auto negotiation */ writel(0x00000000, dev->base + TBICR); } printk(KERN_INFO "%s: autoneg %s via ethtool\n", ndev->name, cmd->autoneg ? "ENABLED" : "DISABLED"); } phy_intr(ndev); spin_unlock(&dev->tx_lock); spin_unlock_irq(&dev->misc_lock); return 0; } /* end ethtool get/set support -df */ static void ns83820_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo *info) { struct ns83820 *dev = PRIV(ndev); Loading @@ -1263,6 +1406,8 @@ static u32 ns83820_get_link(struct net_device *ndev) } static const struct ethtool_ops ops = { .get_settings = ns83820_get_settings, .set_settings = ns83820_set_settings, .get_drvinfo = ns83820_get_drvinfo, .get_link = ns83820_get_link }; Loading