struct net_device *next;
struct mii_if_info mii_if;
struct timer_list watchdog_timer;
- struct timer_list blink_timer;
u32 msg_enable; /* debug message level */
/* each bit indicates an available PHY */
u32 phymask;
unsigned short chip_version; /* which variant this is */
+
+ /* saved registers during ethtool blink */
+ u16 save_regs[4];
};
static int pcnet32_probe_pci(struct pci_dev *, const struct pci_device_id *);
static void pcnet32_ethtool_test(struct net_device *dev,
struct ethtool_test *eth_test, u64 * data);
static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1);
-static int pcnet32_phys_id(struct net_device *dev, u32 data);
-static void pcnet32_led_blink_callback(struct net_device *dev);
static int pcnet32_get_regs_len(struct net_device *dev);
static void pcnet32_get_regs(struct net_device *dev, struct ethtool_regs *regs,
void *ptr);
return rc;
} /* end pcnet32_loopback_test */
-static void pcnet32_led_blink_callback(struct net_device *dev)
+static int pcnet32_set_phys_id(struct net_device *dev,
+ enum ethtool_phys_id_state state)
{
struct pcnet32_private *lp = netdev_priv(dev);
struct pcnet32_access *a = &lp->a;
unsigned long flags;
int i;
- spin_lock_irqsave(&lp->lock, flags);
- for (i = 4; i < 8; i++)
- a->write_bcr(ioaddr, i, a->read_bcr(ioaddr, i) ^ 0x4000);
- spin_unlock_irqrestore(&lp->lock, flags);
-
- mod_timer(&lp->blink_timer, PCNET32_BLINK_TIMEOUT);
-}
+ switch (state) {
+ case ETHTOOL_ID_ACTIVE:
+ /* Save the current value of the bcrs */
+ spin_lock_irqsave(&lp->lock, flags);
+ for (i = 4; i < 8; i++)
+ lp->save_regs[i - 4] = a->read_bcr(ioaddr, i);
+ spin_unlock_irqrestore(&lp->lock, flags);
+ return 2; /* cycle on/off twice per second */
-static int pcnet32_phys_id(struct net_device *dev, u32 data)
-{
- struct pcnet32_private *lp = netdev_priv(dev);
- struct pcnet32_access *a = &lp->a;
- ulong ioaddr = dev->base_addr;
- unsigned long flags;
- int i, regs[4];
+ case ETHTOOL_ID_ON:
+ case ETHTOOL_ID_OFF:
+ /* Blink the led */
+ spin_lock_irqsave(&lp->lock, flags);
+ for (i = 4; i < 8; i++)
+ a->write_bcr(ioaddr, i, a->read_bcr(ioaddr, i) ^ 0x4000);
+ spin_unlock_irqrestore(&lp->lock, flags);
+ break;
- if (!lp->blink_timer.function) {
- init_timer(&lp->blink_timer);
- lp->blink_timer.function = (void *)pcnet32_led_blink_callback;
- lp->blink_timer.data = (unsigned long)dev;
+ case ETHTOOL_ID_INACTIVE:
+ /* Restore the original value of the bcrs */
+ spin_lock_irqsave(&lp->lock, flags);
+ for (i = 4; i < 8; i++)
+ a->write_bcr(ioaddr, i, lp->save_regs[i - 4]);
+ spin_unlock_irqrestore(&lp->lock, flags);
}
-
- /* Save the current value of the bcrs */
- spin_lock_irqsave(&lp->lock, flags);
- for (i = 4; i < 8; i++)
- regs[i - 4] = a->read_bcr(ioaddr, i);
- spin_unlock_irqrestore(&lp->lock, flags);
-
- mod_timer(&lp->blink_timer, jiffies);
- set_current_state(TASK_INTERRUPTIBLE);
-
- /* AV: the limit here makes no sense whatsoever */
- if ((!data) || (data > (u32) (MAX_SCHEDULE_TIMEOUT / HZ)))
- data = (u32) (MAX_SCHEDULE_TIMEOUT / HZ);
-
- msleep_interruptible(data * 1000);
- del_timer_sync(&lp->blink_timer);
-
- /* Restore the original value of the bcrs */
- spin_lock_irqsave(&lp->lock, flags);
- for (i = 4; i < 8; i++)
- a->write_bcr(ioaddr, i, regs[i - 4]);
- spin_unlock_irqrestore(&lp->lock, flags);
-
return 0;
}
.set_ringparam = pcnet32_set_ringparam,
.get_strings = pcnet32_get_strings,
.self_test = pcnet32_ethtool_test,
- .phys_id = pcnet32_phys_id,
+ .set_phys_id = pcnet32_set_phys_id,
.get_regs_len = pcnet32_get_regs_len,
.get_regs = pcnet32_get_regs,
.get_sset_count = pcnet32_get_sset_count,
/*
* On selected chips turn on the BCR18:NOUFLO bit. This stops transmit
* starting until the packet is loaded. Strike one for reliability, lose
- * one for latency - although on PCI this isnt a big loss. Older chips
+ * one for latency - although on PCI this isn't a big loss. Older chips
* have FIFO's smaller than a packet, so you can't do this.
* Turn on BCR18:BurstRdEn and BCR18:BurstWrEn.
*/
int first_phy = -1;
u16 bmcr;
u32 bcr9;
- struct ethtool_cmd ecmd;
+ struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
/*
* There is really no good other way to handle multiple PHYs
ecmd.port = PORT_MII;
ecmd.transceiver = XCVR_INTERNAL;
ecmd.autoneg = AUTONEG_DISABLE;
- ecmd.speed =
- lp->
- options & PCNET32_PORT_100 ? SPEED_100 : SPEED_10;
+ ethtool_cmd_speed_set(&ecmd,
+ (lp->options & PCNET32_PORT_100) ?
+ SPEED_100 : SPEED_10);
bcr9 = lp->a.read_bcr(ioaddr, 9);
if (lp->options & PCNET32_PORT_FD) {
netif_carrier_on(dev);
if (lp->mii) {
if (netif_msg_link(lp)) {
- struct ethtool_cmd ecmd;
+ struct ethtool_cmd ecmd = {
+ .cmd = ETHTOOL_GSET };
mii_ethtool_gset(&lp->mii_if, &ecmd);
- netdev_info(dev, "link up, %sMbps, %s-duplex\n",
- (ecmd.speed == SPEED_100)
- ? "100" : "10",
+ netdev_info(dev, "link up, %uMbps, %s-duplex\n",
+ ethtool_cmd_speed(&ecmd),
(ecmd.duplex == DUPLEX_FULL)
? "full" : "half");
}