#include <linux/dmi.h>
/* These identify the driver base version and may not be removed. */
-static char version[] __devinitdata =
-KERN_INFO DRV_NAME ".c:v1.10-LK" DRV_VERSION " " DRV_RELDATE " Written by Donald Becker\n";
+static const char version[] __devinitconst =
+ KERN_INFO DRV_NAME ".c:v1.10-LK" DRV_VERSION " " DRV_RELDATE
+ " Written by Donald Becker\n";
/* This driver was written to use PCI memory space. Some early versions
of the Rhine may only work correctly with I/O space accesses. */
The driver runs as two independent, single-threaded flows of control. One
is the send-packet routine, which enforces single-threaded use by the
-dev->priv->lock spinlock. The other thread is the interrupt handler, which
-is single threaded by the hardware and interrupt handling software.
+netdev_priv(dev)->lock spinlock. The other thread is the interrupt handler,
+which is single threaded by the hardware and interrupt handling software.
The send packet thread has partial control over the Tx ring. It locks the
-dev->priv->lock whenever it's queuing a Tx packet. If the next slot in the ring
-is not available it stops the transmit queue by calling netif_stop_queue.
+netdev_priv(dev)->lock whenever it's queuing a Tx packet. If the next slot in
+the ring is not available it stops the transmit queue by
+calling netif_stop_queue.
The interrupt handler has exclusive control over the Rx ring and records stats
from the Tx ring. After reaping the stats, it marks the Tx queue entry as
long pioaddr;
struct net_device *dev;
struct napi_struct napi;
- struct net_device_stats stats;
spinlock_t lock;
/* Frequently used values: keep some adjacent for cache effect. */
static void mdio_write(struct net_device *dev, int phy_id, int location, int value);
static int rhine_open(struct net_device *dev);
static void rhine_tx_timeout(struct net_device *dev);
-static int rhine_start_tx(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t rhine_start_tx(struct sk_buff *skb,
+ struct net_device *dev);
static irqreturn_t rhine_interrupt(int irq, void *dev_instance);
static void rhine_tx(struct net_device *dev);
static int rhine_rx(struct net_device *dev, int limit);
work_done = rhine_rx(dev, budget);
if (work_done < budget) {
- netif_rx_complete(dev, napi);
+ napi_complete(napi);
iowrite16(IntrRxDone | IntrRxErr | IntrRxEmpty| IntrRxOverflow |
IntrRxDropped | IntrRxNoBuf | IntrTxAborted |
rhine_reload_eeprom(pioaddr, dev);
}
+static const struct net_device_ops rhine_netdev_ops = {
+ .ndo_open = rhine_open,
+ .ndo_stop = rhine_close,
+ .ndo_start_xmit = rhine_start_tx,
+ .ndo_get_stats = rhine_get_stats,
+ .ndo_set_multicast_list = rhine_set_rx_mode,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_do_ioctl = netdev_ioctl,
+ .ndo_tx_timeout = rhine_tx_timeout,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = rhine_poll,
+#endif
+};
+
static int __devinit rhine_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
#else
int bar = 0;
#endif
- DECLARE_MAC_BUF(mac);
/* when built into the kernel, we only print version if device is found */
#ifndef MODULE
goto err_out;
/* this should always be supported */
- rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (rc) {
printk(KERN_ERR "32-bit PCI DMA addresses not supported by "
"the card!?\n");
rp->mii_if.reg_num_mask = 0x1f;
/* The chip-specific entries in the device structure. */
- dev->open = rhine_open;
- dev->hard_start_xmit = rhine_start_tx;
- dev->stop = rhine_close;
- dev->get_stats = rhine_get_stats;
- dev->set_multicast_list = rhine_set_rx_mode;
- dev->do_ioctl = netdev_ioctl;
- dev->ethtool_ops = &netdev_ethtool_ops;
- dev->tx_timeout = rhine_tx_timeout;
+ dev->netdev_ops = &rhine_netdev_ops;
+ dev->ethtool_ops = &netdev_ethtool_ops,
dev->watchdog_timeo = TX_TIMEOUT;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = rhine_poll;
-#endif
+
netif_napi_add(dev, &rp->napi, rhine_napipoll, 64);
if (rp->quirks & rqRhineI)
if (rc)
goto err_out_unmap;
- printk(KERN_INFO "%s: VIA %s at 0x%lx, %s, IRQ %d.\n",
+ printk(KERN_INFO "%s: VIA %s at 0x%lx, %pM, IRQ %d.\n",
dev->name, name,
#ifdef USE_MMIO
memaddr,
#else
(long)ioaddr,
#endif
- print_mac(mac, dev->dev_addr), pdev->irq);
+ dev->dev_addr, pdev->irq);
pci_set_drvdata(pdev, dev);
enable_irq(rp->pdev->irq);
dev->trans_start = jiffies;
- rp->stats.tx_errors++;
+ dev->stats.tx_errors++;
netif_wake_queue(dev);
}
-static int rhine_start_tx(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t rhine_start_tx(struct sk_buff *skb,
+ struct net_device *dev)
{
struct rhine_private *rp = netdev_priv(dev);
void __iomem *ioaddr = rp->base;
unsigned entry;
+ unsigned long flags;
/* Caution: the write order is important here, set the field
with the "ownership" bits last. */
entry = rp->cur_tx % TX_RING_SIZE;
if (skb_padto(skb, ETH_ZLEN))
- return 0;
+ return NETDEV_TX_OK;
rp->tx_skbuff[entry] = skb;
/* packet too long, drop it */
dev_kfree_skb(skb);
rp->tx_skbuff[entry] = NULL;
- rp->stats.tx_dropped++;
- return 0;
+ dev->stats.tx_dropped++;
+ return NETDEV_TX_OK;
}
/* Padding is not copied and so must be redone. */
cpu_to_le32(TXDESC | (skb->len >= ETH_ZLEN ? skb->len : ETH_ZLEN));
/* lock eth irq */
- spin_lock_irq(&rp->lock);
+ spin_lock_irqsave(&rp->lock, flags);
wmb();
rp->tx_ring[entry].tx_status = cpu_to_le32(DescOwn);
wmb();
dev->trans_start = jiffies;
- spin_unlock_irq(&rp->lock);
+ spin_unlock_irqrestore(&rp->lock, flags);
if (debug > 4) {
printk(KERN_DEBUG "%s: Transmit frame #%d queued in slot %d.\n",
dev->name, rp->cur_tx-1, entry);
}
- return 0;
+ return NETDEV_TX_OK;
}
/* The interrupt handler does all of the Rx thread work and cleans up
IntrPCIErr | IntrStatsMax | IntrLinkChange,
ioaddr + IntrEnable);
- netif_rx_schedule(dev, &rp->napi);
+ napi_schedule(&rp->napi);
}
if (intr_status & (IntrTxErrSummary | IntrTxDone)) {
printk(KERN_DEBUG "%s: Transmit error, "
"Tx status %8.8x.\n",
dev->name, txstatus);
- rp->stats.tx_errors++;
- if (txstatus & 0x0400) rp->stats.tx_carrier_errors++;
- if (txstatus & 0x0200) rp->stats.tx_window_errors++;
- if (txstatus & 0x0100) rp->stats.tx_aborted_errors++;
- if (txstatus & 0x0080) rp->stats.tx_heartbeat_errors++;
+ dev->stats.tx_errors++;
+ if (txstatus & 0x0400)
+ dev->stats.tx_carrier_errors++;
+ if (txstatus & 0x0200)
+ dev->stats.tx_window_errors++;
+ if (txstatus & 0x0100)
+ dev->stats.tx_aborted_errors++;
+ if (txstatus & 0x0080)
+ dev->stats.tx_heartbeat_errors++;
if (((rp->quirks & rqRhineI) && txstatus & 0x0002) ||
(txstatus & 0x0800) || (txstatus & 0x1000)) {
- rp->stats.tx_fifo_errors++;
+ dev->stats.tx_fifo_errors++;
rp->tx_ring[entry].tx_status = cpu_to_le32(DescOwn);
break; /* Keep the skb - we try again */
}
/* Transmitter restarted in 'abnormal' handler. */
} else {
if (rp->quirks & rqRhineI)
- rp->stats.collisions += (txstatus >> 3) & 0x0F;
+ dev->stats.collisions += (txstatus >> 3) & 0x0F;
else
- rp->stats.collisions += txstatus & 0x0F;
+ dev->stats.collisions += txstatus & 0x0F;
if (debug > 6)
printk(KERN_DEBUG "collisions: %1.1x:%1.1x\n",
(txstatus >> 3) & 0xF,
txstatus & 0xF);
- rp->stats.tx_bytes += rp->tx_skbuff[entry]->len;
- rp->stats.tx_packets++;
+ dev->stats.tx_bytes += rp->tx_skbuff[entry]->len;
+ dev->stats.tx_packets++;
}
/* Free the original skb. */
if (rp->tx_skbuff_dma[entry]) {
printk(KERN_WARNING "%s: Oversized Ethernet "
"frame %p vs %p.\n", dev->name,
rp->rx_head_desc, &rp->rx_ring[entry]);
- rp->stats.rx_length_errors++;
+ dev->stats.rx_length_errors++;
} else if (desc_status & RxErr) {
/* There was a error. */
if (debug > 2)
printk(KERN_DEBUG "rhine_rx() Rx "
"error was %8.8x.\n",
desc_status);
- rp->stats.rx_errors++;
- if (desc_status & 0x0030) rp->stats.rx_length_errors++;
- if (desc_status & 0x0048) rp->stats.rx_fifo_errors++;
- if (desc_status & 0x0004) rp->stats.rx_frame_errors++;
+ dev->stats.rx_errors++;
+ if (desc_status & 0x0030)
+ dev->stats.rx_length_errors++;
+ if (desc_status & 0x0048)
+ dev->stats.rx_fifo_errors++;
+ if (desc_status & 0x0004)
+ dev->stats.rx_frame_errors++;
if (desc_status & 0x0002) {
/* this can also be updated outside the interrupt handler */
spin_lock(&rp->lock);
- rp->stats.rx_crc_errors++;
+ dev->stats.rx_crc_errors++;
spin_unlock(&rp->lock);
}
}
}
skb->protocol = eth_type_trans(skb, dev);
netif_receive_skb(skb);
- dev->last_rx = jiffies;
- rp->stats.rx_bytes += pkt_len;
- rp->stats.rx_packets++;
+ dev->stats.rx_bytes += pkt_len;
+ dev->stats.rx_packets++;
}
entry = (++rp->cur_rx) % RX_RING_SIZE;
rp->rx_head_desc = &rp->rx_ring[entry];
if (intr_status & IntrLinkChange)
rhine_check_media(dev, 0);
if (intr_status & IntrStatsMax) {
- rp->stats.rx_crc_errors += ioread16(ioaddr + RxCRCErrs);
- rp->stats.rx_missed_errors += ioread16(ioaddr + RxMissed);
+ dev->stats.rx_crc_errors += ioread16(ioaddr + RxCRCErrs);
+ dev->stats.rx_missed_errors += ioread16(ioaddr + RxMissed);
clear_tally_counters(ioaddr);
}
if (intr_status & IntrTxAborted) {
unsigned long flags;
spin_lock_irqsave(&rp->lock, flags);
- rp->stats.rx_crc_errors += ioread16(ioaddr + RxCRCErrs);
- rp->stats.rx_missed_errors += ioread16(ioaddr + RxMissed);
+ dev->stats.rx_crc_errors += ioread16(ioaddr + RxCRCErrs);
+ dev->stats.rx_missed_errors += ioread16(ioaddr + RxMissed);
clear_tally_counters(ioaddr);
spin_unlock_irqrestore(&rp->lock, flags);
- return &rp->stats;
+ return &dev->stats;
}
static void rhine_set_rx_mode(struct net_device *dev)