Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 66517
b: refs/heads/master
c: 1009697
h: refs/heads/master
i:
  66515: f071966
v: v3
  • Loading branch information
Jeff Garzik authored and David S. Miller committed Oct 10, 2007
1 parent 9dec4bb commit 87f2dde
Show file tree
Hide file tree
Showing 2 changed files with 149 additions and 4 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 2808d2e83f9b48c2f68930b6746fed8efabc41e9
refs/heads/master: 10096974adb6d62b9f8cf65c266632ea73040936
151 changes: 148 additions & 3 deletions trunk/drivers/net/ns83820.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#define VERSION "0.22"
#define VERSION "0.23"
/* ns83820.c by Benjamin LaHaise with contributions.
*
* Questions/comments/discussion to linux-ns83820@kvack.org.
Expand Down Expand Up @@ -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);
Expand All @@ -1263,8 +1406,10 @@ static u32 ns83820_get_link(struct net_device *ndev)
}

static const struct ethtool_ops ops = {
.get_drvinfo = ns83820_get_drvinfo,
.get_link = ns83820_get_link
.get_settings = ns83820_get_settings,
.set_settings = ns83820_set_settings,
.get_drvinfo = ns83820_get_drvinfo,
.get_link = ns83820_get_link
};

/* this function is called in irq context from the ISR */
Expand Down

0 comments on commit 87f2dde

Please sign in to comment.