Support and updates available at
http://www.scyld.com/network/yellowfin.html
+ [link no longer provides useful info -jgarzik]
-
- Linux kernel changelog:
- -----------------------
-
- LK1.1.1 (jgarzik): Port to 2.4 kernel
-
- LK1.1.2 (jgarzik):
- * Merge in becker version 1.05
-
- LK1.1.3 (jgarzik):
- * Various cleanups
- * Update yellowfin_timer to correctly calculate duplex.
- (suggested by Manfred Spraul)
-
- LK1.1.4 (val@nmt.edu):
- * Fix three endian-ness bugs
- * Support dual function SYM53C885E ethernet chip
-
- LK1.1.5 (val@nmt.edu):
- * Fix forced full-duplex bug I introduced
-
- LK1.1.6 (val@nmt.edu):
- * Only print warning on truly "oversized" packets
- * Fix theoretical bug on gigabit cards - return to 1.1.3 behavior
-
*/
#define DRV_NAME "yellowfin"
-#define DRV_VERSION "1.05+LK1.1.6"
-#define DRV_RELDATE "Feb 11, 2002"
+#define DRV_VERSION "2.0"
+#define DRV_RELDATE "Jun 27, 2006"
#define PFX DRV_NAME ": "
static int bogus_rx;
static int dma_ctrl = 0x004A0263; /* Constrained by errata */
static int fifo_cfg = 0x0020; /* Bypass external Tx FIFO. */
-#elif YF_NEW /* A future perfect board :->. */
+#elif defined(YF_NEW) /* A future perfect board :->. */
static int dma_ctrl = 0x00CAC277; /* Override when loading module! */
static int fifo_cfg = 0x0028;
#else
-static int dma_ctrl = 0x004A0263; /* Constrained by errata */
-static int fifo_cfg = 0x0020; /* Bypass external Tx FIFO. */
+static const int dma_ctrl = 0x004A0263; /* Constrained by errata */
+static const int fifo_cfg = 0x0020; /* Bypass external Tx FIFO. */
#endif
/* Set the copy breakpoint for the copy-only-tiny-frames scheme.
#define yellowfin_debug debug
-#if !defined(__OPTIMIZE__)
-#warning You must compile this file with the correct options!
-#warning See the last lines of the source file.
-#error You must compile this driver with "-O".
-#endif
-
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/skbuff.h>
#include <linux/ethtool.h>
#include <linux/crc32.h>
+#include <linux/bitops.h>
#include <asm/uaccess.h>
#include <asm/processor.h> /* Processor type for cache alignment. */
#include <asm/unaligned.h>
-#include <asm/bitops.h>
#include <asm/io.h>
/* These identify the driver base version and may not be removed. */
KERN_INFO " http://www.scyld.com/network/yellowfin.html\n"
KERN_INFO " (unofficial 2.4.x port, " DRV_VERSION ", " DRV_RELDATE ")\n";
-#ifndef USE_IO_OPS
-#undef inb
-#undef inw
-#undef inl
-#undef outb
-#undef outw
-#undef outl
-#define inb readb
-#define inw readw
-#define inl readl
-#define outb writeb
-#define outw writew
-#define outl writel
-#endif /* !USE_IO_OPS */
MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
MODULE_DESCRIPTION("Packet Engines Yellowfin G-NIC Gigabit Ethernet driver");
MODULE_LICENSE("GPL");
-MODULE_PARM(max_interrupt_work, "i");
-MODULE_PARM(mtu, "i");
-MODULE_PARM(debug, "i");
-MODULE_PARM(rx_copybreak, "i");
-MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
-MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
-MODULE_PARM(gx_fix, "i");
+module_param(max_interrupt_work, int, 0);
+module_param(mtu, int, 0);
+module_param(debug, int, 0);
+module_param(rx_copybreak, int, 0);
+module_param_array(options, int, NULL, 0);
+module_param_array(full_duplex, int, NULL, 0);
+module_param(gx_fix, int, 0);
MODULE_PARM_DESC(max_interrupt_work, "G-NIC maximum events handled per interrupt");
MODULE_PARM_DESC(mtu, "G-NIC MTU (all boards)");
MODULE_PARM_DESC(debug, "G-NIC debug level (0-7)");
\f
-enum pci_id_flags_bits {
- /* Set PCI command register bits before calling probe1(). */
- PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4,
- /* Read and map the single following PCI BAR. */
- PCI_ADDR0=0<<4, PCI_ADDR1=1<<4, PCI_ADDR2=2<<4, PCI_ADDR3=3<<4,
- PCI_ADDR_64BITS=0x100, PCI_NO_ACPI_WAKE=0x200, PCI_NO_MIN_LATENCY=0x400,
- PCI_UNUSED_IRQ=0x800,
-};
enum capability_flags {
HasMII=1, FullTxStatus=2, IsGigabit=4, HasMulticastBug=8, FullRxStatus=16,
HasMACAddrBug=32, /* Only on early revs. */
DontUseEeprom=64, /* Don't read the MAC from the EEPROm. */
};
+
/* The PCI I/O space extent. */
-#define YELLOWFIN_SIZE 0x100
-#ifdef USE_IO_OPS
-#define PCI_IOTYPE (PCI_USES_MASTER | PCI_USES_IO | PCI_ADDR0)
-#else
-#define PCI_IOTYPE (PCI_USES_MASTER | PCI_USES_MEM | PCI_ADDR1)
-#endif
+enum {
+ YELLOWFIN_SIZE = 0x100,
+};
struct pci_id_info {
const char *name;
int pci, pci_mask, subsystem, subsystem_mask;
int revision, revision_mask; /* Only 8 bits. */
} id;
- enum pci_id_flags_bits pci_flags;
- int io_size; /* Needed for I/O region check or ioremap(). */
int drv_flags; /* Driver use, intended as capability flags. */
};
-static struct pci_id_info pci_id_tbl[] = {
+static const struct pci_id_info pci_id_tbl[] = {
{"Yellowfin G-NIC Gigabit Ethernet", { 0x07021000, 0xffffffff},
- PCI_IOTYPE, YELLOWFIN_SIZE,
FullTxStatus | IsGigabit | HasMulticastBug | HasMACAddrBug | DontUseEeprom},
{"Symbios SYM83C885", { 0x07011000, 0xffffffff},
- PCI_IOTYPE, YELLOWFIN_SIZE, HasMII | DontUseEeprom },
- {0,},
+ HasMII | DontUseEeprom },
+ { }
};
-static struct pci_device_id yellowfin_pci_tbl[] = {
+static const struct pci_device_id yellowfin_pci_tbl[] = {
{ 0x1000, 0x0702, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
{ 0x1000, 0x0701, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 },
- { 0, }
+ { }
};
MODULE_DEVICE_TABLE (pci, yellowfin_pci_tbl);
u16 advertising; /* NWay media advertisement */
unsigned char phys[MII_CNT]; /* MII device addresses, only first one used */
spinlock_t lock;
+ void __iomem *base;
};
-static int read_eeprom(long ioaddr, int location);
-static int mdio_read(long ioaddr, int phy_id, int location);
-static void mdio_write(long ioaddr, int phy_id, int location, int value);
+static int read_eeprom(void __iomem *ioaddr, int location);
+static int mdio_read(void __iomem *ioaddr, int phy_id, int location);
+static void mdio_write(void __iomem *ioaddr, int phy_id, int location, int value);
static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
static int yellowfin_open(struct net_device *dev);
static void yellowfin_timer(unsigned long data);
static int yellowfin_close(struct net_device *dev);
static struct net_device_stats *yellowfin_get_stats(struct net_device *dev);
static void set_rx_mode(struct net_device *dev);
+static struct ethtool_ops ethtool_ops;
static int __devinit yellowfin_init_one(struct pci_dev *pdev,
int irq;
int chip_idx = ent->driver_data;
static int find_cnt;
- long ioaddr, real_ioaddr;
+ void __iomem *ioaddr;
int i, option = find_cnt < MAX_UNITS ? options[find_cnt] : 0;
int drv_flags = pci_id_tbl[chip_idx].drv_flags;
void *ring_space;
dma_addr_t ring_dma;
+#ifdef USE_IO_OPS
+ int bar = 0;
+#else
+ int bar = 1;
+#endif
/* when built into the kernel, we only print version if device is found */
#ifndef MODULE
SET_MODULE_OWNER(dev);
SET_NETDEV_DEV(dev, &pdev->dev);
- np = dev->priv;
+ np = netdev_priv(dev);
- if (pci_request_regions(pdev, dev->name))
+ if (pci_request_regions(pdev, DRV_NAME))
goto err_out_free_netdev;
pci_set_master (pdev);
-#ifdef USE_IO_OPS
- real_ioaddr = ioaddr = pci_resource_start (pdev, 0);
-#else
- real_ioaddr = ioaddr = pci_resource_start (pdev, 1);
- ioaddr = (long) ioremap(ioaddr, YELLOWFIN_SIZE);
+ ioaddr = pci_iomap(pdev, bar, YELLOWFIN_SIZE);
if (!ioaddr)
goto err_out_free_res;
-#endif
+
irq = pdev->irq;
if (drv_flags & DontUseEeprom)
for (i = 0; i < 6; i++)
- dev->dev_addr[i] = inb(ioaddr + StnAddr + i);
+ dev->dev_addr[i] = ioread8(ioaddr + StnAddr + i);
else {
int ee_offset = (read_eeprom(ioaddr, 6) == 0xff ? 0x100 : 0);
for (i = 0; i < 6; i++)
}
/* Reset the chip. */
- outl(0x80000000, ioaddr + DMACtrl);
+ iowrite32(0x80000000, ioaddr + DMACtrl);
- dev->base_addr = ioaddr;
+ dev->base_addr = (unsigned long)ioaddr;
dev->irq = irq;
pci_set_drvdata(pdev, dev);
np->pci_dev = pdev;
np->chip_id = chip_idx;
np->drv_flags = drv_flags;
+ np->base = ioaddr;
ring_space = pci_alloc_consistent(pdev, TX_TOTAL_SIZE, &ring_dma);
if (!ring_space)
dev->get_stats = &yellowfin_get_stats;
dev->set_multicast_list = &set_rx_mode;
dev->do_ioctl = &netdev_ioctl;
+ SET_ETHTOOL_OPS(dev, ðtool_ops);
dev->tx_timeout = yellowfin_tx_timeout;
dev->watchdog_timeo = TX_TIMEOUT;
if (i)
goto err_out_unmap_status;
- printk(KERN_INFO "%s: %s type %8x at 0x%lx, ",
- dev->name, pci_id_tbl[chip_idx].name, inl(ioaddr + ChipRev), ioaddr);
+ printk(KERN_INFO "%s: %s type %8x at %p, ",
+ dev->name, pci_id_tbl[chip_idx].name,
+ ioread32(ioaddr + ChipRev), ioaddr);
for (i = 0; i < 5; i++)
printk("%2.2x:", dev->dev_addr[i]);
printk("%2.2x, IRQ %d.\n", dev->dev_addr[i], irq);
pci_free_consistent(pdev, TX_TOTAL_SIZE, np->tx_ring, np->tx_ring_dma);
err_out_cleardev:
pci_set_drvdata(pdev, NULL);
-#ifndef USE_IO_OPS
- iounmap((void *)ioaddr);
+ pci_iounmap(pdev, ioaddr);
err_out_free_res:
-#endif
pci_release_regions(pdev);
err_out_free_netdev:
free_netdev (dev);
return -ENODEV;
}
-static int __devinit read_eeprom(long ioaddr, int location)
+static int __devinit read_eeprom(void __iomem *ioaddr, int location)
{
int bogus_cnt = 10000; /* Typical 33Mhz: 1050 ticks */
- outb(location, ioaddr + EEAddr);
- outb(0x30 | ((location >> 8) & 7), ioaddr + EECtrl);
- while ((inb(ioaddr + EEStatus) & 0x80) && --bogus_cnt > 0)
+ iowrite8(location, ioaddr + EEAddr);
+ iowrite8(0x30 | ((location >> 8) & 7), ioaddr + EECtrl);
+ while ((ioread8(ioaddr + EEStatus) & 0x80) && --bogus_cnt > 0)
;
- return inb(ioaddr + EERead);
+ return ioread8(ioaddr + EERead);
}
/* MII Managemen Data I/O accesses.
These routines assume the MDIO controller is idle, and do not exit until
the command is finished. */
-static int mdio_read(long ioaddr, int phy_id, int location)
+static int mdio_read(void __iomem *ioaddr, int phy_id, int location)
{
int i;
- outw((phy_id<<8) + location, ioaddr + MII_Addr);
- outw(1, ioaddr + MII_Cmd);
+ iowrite16((phy_id<<8) + location, ioaddr + MII_Addr);
+ iowrite16(1, ioaddr + MII_Cmd);
for (i = 10000; i >= 0; i--)
- if ((inw(ioaddr + MII_Status) & 1) == 0)
+ if ((ioread16(ioaddr + MII_Status) & 1) == 0)
break;
- return inw(ioaddr + MII_Rd_Data);
+ return ioread16(ioaddr + MII_Rd_Data);
}
-static void mdio_write(long ioaddr, int phy_id, int location, int value)
+static void mdio_write(void __iomem *ioaddr, int phy_id, int location, int value)
{
int i;
- outw((phy_id<<8) + location, ioaddr + MII_Addr);
- outw(value, ioaddr + MII_Wr_Data);
+ iowrite16((phy_id<<8) + location, ioaddr + MII_Addr);
+ iowrite16(value, ioaddr + MII_Wr_Data);
/* Wait for the command to finish. */
for (i = 10000; i >= 0; i--)
- if ((inw(ioaddr + MII_Status) & 1) == 0)
+ if ((ioread16(ioaddr + MII_Status) & 1) == 0)
break;
return;
}
\f
static int yellowfin_open(struct net_device *dev)
{
- struct yellowfin_private *yp = dev->priv;
- long ioaddr = dev->base_addr;
+ struct yellowfin_private *yp = netdev_priv(dev);
+ void __iomem *ioaddr = yp->base;
int i;
/* Reset the chip. */
- outl(0x80000000, ioaddr + DMACtrl);
+ iowrite32(0x80000000, ioaddr + DMACtrl);
- i = request_irq(dev->irq, &yellowfin_interrupt, SA_SHIRQ, dev->name, dev);
+ i = request_irq(dev->irq, &yellowfin_interrupt, IRQF_SHARED, dev->name, dev);
if (i) return i;
if (yellowfin_debug > 1)
yellowfin_init_ring(dev);
- outl(yp->rx_ring_dma, ioaddr + RxPtr);
- outl(yp->tx_ring_dma, ioaddr + TxPtr);
+ iowrite32(yp->rx_ring_dma, ioaddr + RxPtr);
+ iowrite32(yp->tx_ring_dma, ioaddr + TxPtr);
for (i = 0; i < 6; i++)
- outb(dev->dev_addr[i], ioaddr + StnAddr + i);
+ iowrite8(dev->dev_addr[i], ioaddr + StnAddr + i);
/* Set up various condition 'select' registers.
There are no options here. */
- outl(0x00800080, ioaddr + TxIntrSel); /* Interrupt on Tx abort */
- outl(0x00800080, ioaddr + TxBranchSel); /* Branch on Tx abort */
- outl(0x00400040, ioaddr + TxWaitSel); /* Wait on Tx status */
- outl(0x00400040, ioaddr + RxIntrSel); /* Interrupt on Rx done */
- outl(0x00400040, ioaddr + RxBranchSel); /* Branch on Rx error */
- outl(0x00400040, ioaddr + RxWaitSel); /* Wait on Rx done */
+ iowrite32(0x00800080, ioaddr + TxIntrSel); /* Interrupt on Tx abort */
+ iowrite32(0x00800080, ioaddr + TxBranchSel); /* Branch on Tx abort */
+ iowrite32(0x00400040, ioaddr + TxWaitSel); /* Wait on Tx status */
+ iowrite32(0x00400040, ioaddr + RxIntrSel); /* Interrupt on Rx done */
+ iowrite32(0x00400040, ioaddr + RxBranchSel); /* Branch on Rx error */
+ iowrite32(0x00400040, ioaddr + RxWaitSel); /* Wait on Rx done */
/* Initialize other registers: with so many this eventually this will
converted to an offset/value list. */
- outl(dma_ctrl, ioaddr + DMACtrl);
- outw(fifo_cfg, ioaddr + FIFOcfg);
+ iowrite32(dma_ctrl, ioaddr + DMACtrl);
+ iowrite16(fifo_cfg, ioaddr + FIFOcfg);
/* Enable automatic generation of flow control frames, period 0xffff. */
- outl(0x0030FFFF, ioaddr + FlowCtrl);
+ iowrite32(0x0030FFFF, ioaddr + FlowCtrl);
yp->tx_threshold = 32;
- outl(yp->tx_threshold, ioaddr + TxThreshold);
+ iowrite32(yp->tx_threshold, ioaddr + TxThreshold);
if (dev->if_port == 0)
dev->if_port = yp->default_port;
if (yp->drv_flags & IsGigabit) {
/* We are always in full-duplex mode with gigabit! */
yp->full_duplex = 1;
- outw(0x01CF, ioaddr + Cnfg);
+ iowrite16(0x01CF, ioaddr + Cnfg);
} else {
- outw(0x0018, ioaddr + FrameGap0); /* 0060/4060 for non-MII 10baseT */
- outw(0x1018, ioaddr + FrameGap1);
- outw(0x101C | (yp->full_duplex ? 2 : 0), ioaddr + Cnfg);
+ iowrite16(0x0018, ioaddr + FrameGap0); /* 0060/4060 for non-MII 10baseT */
+ iowrite16(0x1018, ioaddr + FrameGap1);
+ iowrite16(0x101C | (yp->full_duplex ? 2 : 0), ioaddr + Cnfg);
}
set_rx_mode(dev);
/* Enable interrupts by setting the interrupt mask. */
- outw(0x81ff, ioaddr + IntrEnb); /* See enum intr_status_bits */
- outw(0x0000, ioaddr + EventStatus); /* Clear non-interrupting events */
- outl(0x80008000, ioaddr + RxCtrl); /* Start Rx and Tx channels. */
- outl(0x80008000, ioaddr + TxCtrl);
+ iowrite16(0x81ff, ioaddr + IntrEnb); /* See enum intr_status_bits */
+ iowrite16(0x0000, ioaddr + EventStatus); /* Clear non-interrupting events */
+ iowrite32(0x80008000, ioaddr + RxCtrl); /* Start Rx and Tx channels. */
+ iowrite32(0x80008000, ioaddr + TxCtrl);
if (yellowfin_debug > 2) {
printk(KERN_DEBUG "%s: Done yellowfin_open().\n",
static void yellowfin_timer(unsigned long data)
{
struct net_device *dev = (struct net_device *)data;
- struct yellowfin_private *yp = dev->priv;
- long ioaddr = dev->base_addr;
+ struct yellowfin_private *yp = netdev_priv(dev);
+ void __iomem *ioaddr = yp->base;
int next_tick = 60*HZ;
if (yellowfin_debug > 3) {
printk(KERN_DEBUG "%s: Yellowfin timer tick, status %8.8x.\n",
- dev->name, inw(ioaddr + IntrStatus));
+ dev->name, ioread16(ioaddr + IntrStatus));
}
if (yp->mii_cnt) {
yp->full_duplex = mii_duplex(yp->duplex_lock, negotiated);
- outw(0x101C | (yp->full_duplex ? 2 : 0), ioaddr + Cnfg);
+ iowrite16(0x101C | (yp->full_duplex ? 2 : 0), ioaddr + Cnfg);
if (bmsr & BMSR_LSTATUS)
next_tick = 60*HZ;
static void yellowfin_tx_timeout(struct net_device *dev)
{
- struct yellowfin_private *yp = dev->priv;
- long ioaddr = dev->base_addr;
+ struct yellowfin_private *yp = netdev_priv(dev);
+ void __iomem *ioaddr = yp->base;
printk(KERN_WARNING "%s: Yellowfin transmit timed out at %d/%d Tx "
"status %4.4x, Rx status %4.4x, resetting...\n",
dev->name, yp->cur_tx, yp->dirty_tx,
- inl(ioaddr + TxStatus), inl(ioaddr + RxStatus));
+ ioread32(ioaddr + TxStatus), ioread32(ioaddr + RxStatus));
/* Note: these should be KERN_DEBUG. */
if (yellowfin_debug) {
dev->if_port = 0;
/* Wake the potentially-idle transmit channel. */
- outl(0x10001000, dev->base_addr + TxCtrl);
+ iowrite32(0x10001000, yp->base + TxCtrl);
if (yp->cur_tx - yp->dirty_tx < TX_QUEUE_SIZE)
netif_wake_queue (dev); /* Typical path */
/* Initialize the Rx and Tx rings, along with various 'dev' bits. */
static void yellowfin_init_ring(struct net_device *dev)
{
- struct yellowfin_private *yp = dev->priv;
+ struct yellowfin_private *yp = netdev_priv(dev);
int i;
yp->tx_full = 0;
skb->dev = dev; /* Mark as being used by this device. */
skb_reserve(skb, 2); /* 16 byte align the IP header. */
yp->rx_ring[i].addr = cpu_to_le32(pci_map_single(yp->pci_dev,
- skb->tail, yp->rx_buf_sz, PCI_DMA_FROMDEVICE));
+ skb->data, yp->rx_buf_sz, PCI_DMA_FROMDEVICE));
}
yp->rx_ring[i-1].dbdma_cmd = cpu_to_le32(CMD_STOP);
yp->dirty_rx = (unsigned int)(i - RX_RING_SIZE);
#ifdef NO_TXSTATS
/* In this mode the Tx ring needs only a single descriptor. */
for (i = 0; i < TX_RING_SIZE; i++) {
- yp->tx_skbuff[i] = 0;
+ yp->tx_skbuff[i] = NULL;
yp->tx_ring[i].dbdma_cmd = cpu_to_le32(CMD_STOP);
yp->tx_ring[i].branch_addr = cpu_to_le32(yp->tx_ring_dma +
((i+1)%TX_RING_SIZE)*sizeof(struct yellowfin_desc));
static int yellowfin_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
- struct yellowfin_private *yp = dev->priv;
+ struct yellowfin_private *yp = netdev_priv(dev);
unsigned entry;
int len = skb->len;
/* Fix GX chipset errata. */
if (cacheline_end > 24 || cacheline_end == 0) {
len = skb->len + 32 - cacheline_end + 1;
- if (len != skb->len)
- skb = skb_padto(skb, len);
- }
- if (skb == NULL) {
- yp->tx_skbuff[entry] = NULL;
- netif_wake_queue(dev);
- return 0;
+ if (skb_padto(skb, len)) {
+ yp->tx_skbuff[entry] = NULL;
+ netif_wake_queue(dev);
+ return 0;
+ }
}
}
yp->tx_skbuff[entry] = skb;
/* Non-x86 Todo: explicitly flush cache lines here. */
/* Wake the potentially-idle transmit channel. */
- outl(0x10001000, dev->base_addr + TxCtrl);
+ iowrite32(0x10001000, yp->base + TxCtrl);
if (yp->cur_tx - yp->dirty_tx < TX_QUEUE_SIZE)
netif_start_queue (dev); /* Typical path */
{
struct net_device *dev = dev_instance;
struct yellowfin_private *yp;
- long ioaddr;
+ void __iomem *ioaddr;
int boguscnt = max_interrupt_work;
unsigned int handled = 0;
}
#endif
- ioaddr = dev->base_addr;
- yp = dev->priv;
+ yp = netdev_priv(dev);
+ ioaddr = yp->base;
spin_lock (&yp->lock);
do {
- u16 intr_status = inw(ioaddr + IntrClear);
+ u16 intr_status = ioread16(ioaddr + IntrClear);
if (yellowfin_debug > 4)
printk(KERN_DEBUG "%s: Yellowfin interrupt, status %4.4x.\n",
if (intr_status & (IntrRxDone | IntrEarlyRx)) {
yellowfin_rx(dev);
- outl(0x10001000, ioaddr + RxCtrl); /* Wake Rx engine. */
+ iowrite32(0x10001000, ioaddr + RxCtrl); /* Wake Rx engine. */
}
#ifdef NO_TXSTATS
pci_unmap_single(yp->pci_dev, yp->tx_ring[entry].addr,
skb->len, PCI_DMA_TODEVICE);
dev_kfree_skb_irq(skb);
- yp->tx_skbuff[entry] = 0;
+ yp->tx_skbuff[entry] = NULL;
}
if (yp->tx_full
&& yp->cur_tx - yp->dirty_tx < TX_QUEUE_SIZE - 4) {
if (yellowfin_debug > 3)
printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n",
- dev->name, inw(ioaddr + IntrStatus));
+ dev->name, ioread16(ioaddr + IntrStatus));
spin_unlock (&yp->lock);
return IRQ_RETVAL(handled);
for clarity and better register allocation. */
static int yellowfin_rx(struct net_device *dev)
{
- struct yellowfin_private *yp = dev->priv;
+ struct yellowfin_private *yp = netdev_priv(dev);
int entry = yp->cur_rx % RX_RING_SIZE;
int boguscnt = yp->dirty_rx + RX_RING_SIZE - yp->cur_rx;
pci_dma_sync_single_for_cpu(yp->pci_dev, desc->addr,
yp->rx_buf_sz, PCI_DMA_FROMDEVICE);
desc_status = le32_to_cpu(desc->result_status) >> 16;
- buf_addr = rx_skb->tail;
+ buf_addr = rx_skb->data;
data_size = (le32_to_cpu(desc->dbdma_cmd) -
le32_to_cpu(desc->result_status)) & 0xffff;
frame_status = le16_to_cpu(get_unaligned((s16*)&(buf_addr[data_size - 2])));
break;
skb->dev = dev;
skb_reserve(skb, 2); /* 16 byte align the IP header */
-#if HAS_IP_COPYSUM
- eth_copy_and_sum(skb, rx_skb->tail, pkt_len, 0);
+ eth_copy_and_sum(skb, rx_skb->data, pkt_len, 0);
skb_put(skb, pkt_len);
-#else
- memcpy(skb_put(skb, pkt_len),
- rx_skb->tail, pkt_len);
-#endif
pci_dma_sync_single_for_device(yp->pci_dev, desc->addr,
yp->rx_buf_sz,
PCI_DMA_FROMDEVICE);
skb->dev = dev; /* Mark as being used by this device. */
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
yp->rx_ring[entry].addr = cpu_to_le32(pci_map_single(yp->pci_dev,
- skb->tail, yp->rx_buf_sz, PCI_DMA_FROMDEVICE));
+ skb->data, yp->rx_buf_sz, PCI_DMA_FROMDEVICE));
}
yp->rx_ring[entry].dbdma_cmd = cpu_to_le32(CMD_STOP);
yp->rx_ring[entry].result_status = 0; /* Clear complete bit. */
static void yellowfin_error(struct net_device *dev, int intr_status)
{
- struct yellowfin_private *yp = dev->priv;
+ struct yellowfin_private *yp = netdev_priv(dev);
printk(KERN_ERR "%s: Something Wicked happened! %4.4x.\n",
dev->name, intr_status);
static int yellowfin_close(struct net_device *dev)
{
- long ioaddr = dev->base_addr;
- struct yellowfin_private *yp = dev->priv;
+ struct yellowfin_private *yp = netdev_priv(dev);
+ void __iomem *ioaddr = yp->base;
int i;
netif_stop_queue (dev);
if (yellowfin_debug > 1) {
printk(KERN_DEBUG "%s: Shutting down ethercard, status was Tx %4.4x "
"Rx %4.4x Int %2.2x.\n",
- dev->name, inw(ioaddr + TxStatus),
- inw(ioaddr + RxStatus), inw(ioaddr + IntrStatus));
+ dev->name, ioread16(ioaddr + TxStatus),
+ ioread16(ioaddr + RxStatus),
+ ioread16(ioaddr + IntrStatus));
printk(KERN_DEBUG "%s: Queue pointers were Tx %d / %d, Rx %d / %d.\n",
dev->name, yp->cur_tx, yp->dirty_tx, yp->cur_rx, yp->dirty_rx);
}
/* Disable interrupts by clearing the interrupt mask. */
- outw(0x0000, ioaddr + IntrEnb);
+ iowrite16(0x0000, ioaddr + IntrEnb);
/* Stop the chip's Tx and Rx processes. */
- outl(0x80000000, ioaddr + RxCtrl);
- outl(0x80000000, ioaddr + TxCtrl);
+ iowrite32(0x80000000, ioaddr + RxCtrl);
+ iowrite32(0x80000000, ioaddr + TxCtrl);
del_timer(&yp->timer);
(unsigned long long)yp->tx_ring_dma);
for (i = 0; i < TX_RING_SIZE*2; i++)
printk(" %c #%d desc. %8.8x %8.8x %8.8x %8.8x.\n",
- inl(ioaddr + TxPtr) == (long)&yp->tx_ring[i] ? '>' : ' ',
+ ioread32(ioaddr + TxPtr) == (long)&yp->tx_ring[i] ? '>' : ' ',
i, yp->tx_ring[i].dbdma_cmd, yp->tx_ring[i].addr,
yp->tx_ring[i].branch_addr, yp->tx_ring[i].result_status);
printk(KERN_DEBUG " Tx status %p:\n", yp->tx_status);
(unsigned long long)yp->rx_ring_dma);
for (i = 0; i < RX_RING_SIZE; i++) {
printk(KERN_DEBUG " %c #%d desc. %8.8x %8.8x %8.8x\n",
- inl(ioaddr + RxPtr) == (long)&yp->rx_ring[i] ? '>' : ' ',
+ ioread32(ioaddr + RxPtr) == (long)&yp->rx_ring[i] ? '>' : ' ',
i, yp->rx_ring[i].dbdma_cmd, yp->rx_ring[i].addr,
yp->rx_ring[i].result_status);
if (yellowfin_debug > 6) {
if (yp->rx_skbuff[i]) {
dev_kfree_skb(yp->rx_skbuff[i]);
}
- yp->rx_skbuff[i] = 0;
+ yp->rx_skbuff[i] = NULL;
}
for (i = 0; i < TX_RING_SIZE; i++) {
if (yp->tx_skbuff[i])
dev_kfree_skb(yp->tx_skbuff[i]);
- yp->tx_skbuff[i] = 0;
+ yp->tx_skbuff[i] = NULL;
}
#ifdef YF_PROTOTYPE /* Support for prototype hardware errata. */
static struct net_device_stats *yellowfin_get_stats(struct net_device *dev)
{
- struct yellowfin_private *yp = dev->priv;
+ struct yellowfin_private *yp = netdev_priv(dev);
return &yp->stats;
}
static void set_rx_mode(struct net_device *dev)
{
- struct yellowfin_private *yp = dev->priv;
- long ioaddr = dev->base_addr;
- u16 cfg_value = inw(ioaddr + Cnfg);
+ struct yellowfin_private *yp = netdev_priv(dev);
+ void __iomem *ioaddr = yp->base;
+ u16 cfg_value = ioread16(ioaddr + Cnfg);
/* Stop the Rx process to change any value. */
- outw(cfg_value & ~0x1000, ioaddr + Cnfg);
+ iowrite16(cfg_value & ~0x1000, ioaddr + Cnfg);
if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */
/* Unconditionally log net taps. */
printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name);
- outw(0x000F, ioaddr + AddrMode);
+ iowrite16(0x000F, ioaddr + AddrMode);
} else if ((dev->mc_count > 64) || (dev->flags & IFF_ALLMULTI)) {
/* Too many to filter well, or accept all multicasts. */
- outw(0x000B, ioaddr + AddrMode);
+ iowrite16(0x000B, ioaddr + AddrMode);
} else if (dev->mc_count > 0) { /* Must use the multicast hash table. */
struct dev_mc_list *mclist;
u16 hash_table[4];
}
/* Copy the hash table to the chip. */
for (i = 0; i < 4; i++)
- outw(hash_table[i], ioaddr + HashTbl + i*2);
- outw(0x0003, ioaddr + AddrMode);
+ iowrite16(hash_table[i], ioaddr + HashTbl + i*2);
+ iowrite16(0x0003, ioaddr + AddrMode);
} else { /* Normal, unicast/broadcast-only mode. */
- outw(0x0001, ioaddr + AddrMode);
+ iowrite16(0x0001, ioaddr + AddrMode);
}
/* Restart the Rx process. */
- outw(cfg_value | 0x1000, ioaddr + Cnfg);
+ iowrite16(cfg_value | 0x1000, ioaddr + Cnfg);
}
-static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
+static void yellowfin_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
- struct yellowfin_private *np = dev->priv;
- u32 ethcmd;
-
- if (copy_from_user(ðcmd, useraddr, sizeof(ethcmd)))
- return -EFAULT;
-
- switch (ethcmd) {
- case ETHTOOL_GDRVINFO: {
- struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
- strcpy(info.driver, DRV_NAME);
- strcpy(info.version, DRV_VERSION);
- strcpy(info.bus_info, pci_name(np->pci_dev));
- if (copy_to_user(useraddr, &info, sizeof(info)))
- return -EFAULT;
- return 0;
- }
-
- }
-
- return -EOPNOTSUPP;
+ struct yellowfin_private *np = netdev_priv(dev);
+ strcpy(info->driver, DRV_NAME);
+ strcpy(info->version, DRV_VERSION);
+ strcpy(info->bus_info, pci_name(np->pci_dev));
}
+static struct ethtool_ops ethtool_ops = {
+ .get_drvinfo = yellowfin_get_drvinfo
+};
+
static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
- struct yellowfin_private *np = dev->priv;
- long ioaddr = dev->base_addr;
- struct mii_ioctl_data *data = (struct mii_ioctl_data *)&rq->ifr_data;
+ struct yellowfin_private *np = netdev_priv(dev);
+ void __iomem *ioaddr = np->base;
+ struct mii_ioctl_data *data = if_mii(rq);
switch(cmd) {
- case SIOCETHTOOL:
- return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
case SIOCGMIIPHY: /* Get address of MII PHY in use. */
data->phy_id = np->phys[0] & 0x1f;
/* Fall Through */
struct net_device *dev = pci_get_drvdata(pdev);
struct yellowfin_private *np;
- if (!dev)
- BUG();
- np = dev->priv;
+ BUG_ON(!dev);
+ np = netdev_priv(dev);
pci_free_consistent(pdev, STATUS_TOTAL_SIZE, np->tx_status,
np->tx_status_dma);
pci_free_consistent(pdev, TX_TOTAL_SIZE, np->tx_ring, np->tx_ring_dma);
unregister_netdev (dev);
- pci_release_regions (pdev);
+ pci_iounmap(pdev, np->base);
-#ifndef USE_IO_OPS
- iounmap ((void *) dev->base_addr);
-#endif
+ pci_release_regions (pdev);
free_netdev (dev);
pci_set_drvdata(pdev, NULL);