patch-2.4.3 linux/drivers/net/pci-skeleton.c
Next file: linux/drivers/net/pcmcia/3c574_cs.c
Previous file: linux/drivers/net/oaknet.c
Back to the patch index
Back to the overall index
- Lines: 555
- Date:
Sun Mar 25 18:24:31 2001
- Orig file:
v2.4.2/linux/drivers/net/pci-skeleton.c
- Orig date:
Wed Feb 21 18:20:28 2001
diff -u --recursive --new-file v2.4.2/linux/drivers/net/pci-skeleton.c linux/drivers/net/pci-skeleton.c
@@ -504,7 +504,7 @@
static void netdrv_interrupt (int irq, void *dev_instance,
struct pt_regs *regs);
static int netdrv_close (struct net_device *dev);
-static int mii_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
+static int netdrv_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
static struct net_device_stats *netdrv_get_stats (struct net_device *dev);
static inline u32 ether_crc (int length, unsigned char *data);
static void netdrv_set_rx_mode (struct net_device *dev);
@@ -600,7 +600,7 @@
*dev_out = NULL;
/* dev zeroed in init_etherdev */
- dev = init_etherdev (NULL, sizeof (*tp));
+ dev = alloc_etherdev (sizeof (*tp));
if (dev == NULL) {
printk (KERN_ERR PFX "unable to alloc new ethernet\n");
DPRINTK ("EXIT, returning -ENOMEM\n");
@@ -609,6 +609,11 @@
SET_MODULE_OWNER(dev);
tp = dev->priv;
+ /* enable device (incl. PCI PM wakeup), and bus-mastering */
+ rc = pci_enable_device (pdev);
+ if (rc)
+ goto err_out;
+
pio_start = pci_resource_start (pdev, 0);
pio_end = pci_resource_end (pdev, 0);
pio_flags = pci_resource_flags (pdev, 0);
@@ -623,8 +628,6 @@
* we talk to the chip directly */
DPRINTK("PIO region size == 0x%02X\n", pio_len);
DPRINTK("MMIO region size == 0x%02lX\n", mmio_len);
- if (pio_len == RTL8139B_IO_SIZE)
- tp->chipset = CH_8139B;
/* make sure PCI base addr 0 is PIO */
if (!(pio_flags & IORESOURCE_IO)) {
@@ -648,24 +651,9 @@
goto err_out;
}
- /* make sure our PIO region in PCI space is available */
- if (!request_region (pio_start, pio_len, dev->name)) {
- printk (KERN_ERR PFX "no I/O resource available, aborting\n");
- rc = -EBUSY;
- goto err_out;
- }
-
- /* make sure our MMIO region in PCI space is available */
- if (!request_mem_region (mmio_start, mmio_len, dev->name)) {
- printk (KERN_ERR PFX "no mem resource available, aborting\n");
- rc = -EBUSY;
- goto err_out_free_pio;
- }
-
- /* enable device (incl. PCI PM wakeup), and bus-mastering */
- rc = pci_enable_device (pdev);
+ rc = pci_request_regions (pdev, "pci-skeleton");
if (rc)
- goto err_out_free_mmio;
+ goto err_out;
pci_set_master (pdev);
@@ -677,7 +665,7 @@
if (ioaddr == NULL) {
printk (KERN_ERR PFX "cannot remap MMIO, aborting\n");
rc = -EIO;
- goto err_out_free_mmio;
+ goto err_out_free_res;
}
#endif /* USE_IO_OPS */
@@ -692,14 +680,7 @@
udelay (10);
/* Bring the chip out of low-power mode. */
- if (tp->chipset == CH_8139B) {
- NETDRV_W8 (Config1, NETDRV_R8 (Config1) & ~(1<<4));
- NETDRV_W8 (Config4, NETDRV_R8 (Config4) & ~(1<<2));
- } else {
- /* handle RTL8139A and RTL8139 cases */
- /* XXX from becker driver. is this right?? */
- NETDRV_W8 (Config1, 0);
- }
+ /* <insert device-specific code here> */
#ifndef USE_IO_OPS
/* sanity checks -- ensure PIO and MMIO registers agree */
@@ -709,19 +690,6 @@
assert (inb (pio_start+RxConfig) == readb (ioaddr+RxConfig));
#endif /* !USE_IO_OPS */
- /* make sure chip thinks PIO and MMIO are enabled */
- tmp8 = NETDRV_R8 (Config1);
- if ((tmp8 & Cfg1_PIO) == 0) {
- printk (KERN_ERR PFX "PIO not enabled, Cfg1=%02X, aborting\n", tmp8);
- rc = -EIO;
- goto err_out_iounmap;
- }
- if ((tmp8 & Cfg1_MMIO) == 0) {
- printk (KERN_ERR PFX "MMIO not enabled, Cfg1=%02X, aborting\n", tmp8);
- rc = -EIO;
- goto err_out_iounmap;
- }
-
/* identify chip attached to board */
tmp = NETDRV_R8 (ChipVersion);
for (i = ARRAY_SIZE (rtl_chip_info) - 1; i >= 0; i--)
@@ -742,22 +710,22 @@
tp->chipset,
rtl_chip_info[tp->chipset].name);
+ i = register_netdev (dev);
+ if (i)
+ goto err_out_unmap;
+
DPRINTK ("EXIT, returning 0\n");
*ioaddr_out = ioaddr;
*dev_out = dev;
return 0;
-err_out_iounmap:
- assert (ioaddr > 0);
+err_out_unmap:
#ifndef USE_IO_OPS
- iounmap (ioaddr);
-#endif /* !USE_IO_OPS */
-err_out_free_mmio:
- release_mem_region (mmio_start, mmio_len);
-err_out_free_pio:
- release_region (pio_start, pio_len);
+ iounmap(ioaddr);
+err_out_free_res:
+#endif
+ pci_release_regions (pdev);
err_out:
- unregister_netdev (dev);
kfree (dev);
DPRINTK ("EXIT, returning %d\n", rc);
return rc;
@@ -810,7 +778,7 @@
dev->stop = netdrv_close;
dev->get_stats = netdrv_get_stats;
dev->set_multicast_list = netdrv_set_rx_mode;
- dev->do_ioctl = mii_ioctl;
+ dev->do_ioctl = netdrv_ioctl;
dev->tx_timeout = netdrv_tx_timeout;
dev->watchdog_timeo = TX_TIMEOUT;
@@ -828,7 +796,7 @@
tp->mmio_addr = ioaddr;
tp->lock = SPIN_LOCK_UNLOCKED;
- pdev->driver_data = dev;
+ pci_set_drvdata(pdev, dev);
tp->phys[0] = 32;
@@ -849,12 +817,6 @@
/* Put the chip into low-power mode. */
NETDRV_W8_F (Cfg9346, Cfg9346_Unlock);
- tmp = NETDRV_R8 (Config1) & Config1Clear;
- tmp |= (tp->chipset == CH_8139B) ? 3 : 1; /* Enable PM/VPD */
- NETDRV_W8_F (Config1, tmp);
-
- NETDRV_W8_F (HltClk, 'H'); /* 'R' would leave the clock running. */
-
/* The lower four bits are the media type. */
option = (board_idx > 7) ? 0 : media[board_idx];
if (option > 0) {
@@ -879,14 +841,14 @@
static void __devexit netdrv_remove_one (struct pci_dev *pdev)
{
- struct net_device *dev = pdev->driver_data;
+ struct net_device *dev = pci_get_drvdata (pdev);
struct netdrv_private *np;
DPRINTK ("ENTER\n");
assert (dev != NULL);
- np = (struct netdrv_private *) (dev->priv);
+ np = dev->priv;
assert (np != NULL);
unregister_netdev (dev);
@@ -895,10 +857,7 @@
iounmap (np->mmio_addr);
#endif /* !USE_IO_OPS */
- release_region (pci_resource_start (pdev, 0),
- pci_resource_len (pdev, 0));
- release_mem_region (pci_resource_start (pdev, 1),
- pci_resource_len (pdev, 1));
+ pci_release_regions (pdev);
#ifndef NETDRV_NDEBUG
/* poison memory before freeing */
@@ -909,7 +868,7 @@
kfree (dev);
- pdev->driver_data = NULL;
+ pci_set_drvdata (pdev, NULL);
pci_power_off (pdev, -1);
@@ -1029,7 +988,7 @@
static int mdio_read (struct net_device *dev, int phy_id, int location)
{
- struct netdrv_private *tp = (struct netdrv_private *) dev->priv;
+ struct netdrv_private *tp = dev->priv;
void *mdio_addr = tp->mmio_addr + Config4;
int mii_cmd = (0xf6 << 10) | (phy_id << 5) | location;
int retval = 0;
@@ -1072,7 +1031,7 @@
static void mdio_write (struct net_device *dev, int phy_id, int location,
int value)
{
- struct netdrv_private *tp = (struct netdrv_private *) dev->priv;
+ struct netdrv_private *tp = dev->priv;
void *mdio_addr = tp->mmio_addr + Config4;
int mii_cmd =
(0x5002 << 16) | (phy_id << 23) | (location << 18) | value;
@@ -1115,7 +1074,7 @@
static int netdrv_open (struct net_device *dev)
{
- struct netdrv_private *tp = (struct netdrv_private *) dev->priv;
+ struct netdrv_private *tp = dev->priv;
int retval;
#ifdef NETDRV_DEBUG
void *ioaddr = tp->mmio_addr;
@@ -1176,7 +1135,7 @@
/* Start the hardware at open or resume. */
static void netdrv_hw_start (struct net_device *dev)
{
- struct netdrv_private *tp = (struct netdrv_private *) dev->priv;
+ struct netdrv_private *tp = dev->priv;
void *ioaddr = tp->mmio_addr;
u32 i;
u8 tmp;
@@ -1213,27 +1172,6 @@
tp->cur_rx = 0;
- if (tp->chipset >= CH_8139A) {
- tmp = NETDRV_R8 (Config1) & Config1Clear;
- tmp |= Cfg1_Driver_Load;
- tmp |= (tp->chipset == CH_8139B) ? 3 : 1; /* Enable PM/VPD */
- NETDRV_W8_F (Config1, tmp);
- } else {
- u8 foo = NETDRV_R8 (Config1) & Config1Clear;
- NETDRV_W8 (Config1, tp->full_duplex ? (foo|0x60) : (foo|0x20));
- }
-
- if (tp->chipset >= CH_8139B) {
- tmp = NETDRV_R8 (Config4) & ~(1<<2);
- /* chip will clear Rx FIFO overflow automatically */
- tmp |= (1<<7);
- NETDRV_W8 (Config4, tmp);
-
- /* disable magic packet scanning, which is enabled
- * when PM is enabled above (Config1) */
- NETDRV_W8 (Config3, NETDRV_R8 (Config3) & ~(1<<5));
- }
-
/* Lock Config[01234] and BMCR register writes */
NETDRV_W8_F (Cfg9346, Cfg9346_Lock);
udelay (10);
@@ -1268,7 +1206,7 @@
/* Initialize the Rx and Tx rings, along with various 'dev' bits. */
static void netdrv_init_ring (struct net_device *dev)
{
- struct netdrv_private *tp = (struct netdrv_private *) dev->priv;
+ struct netdrv_private *tp = dev->priv;
int i;
DPRINTK ("ENTER\n");
@@ -1287,104 +1225,10 @@
}
-#ifndef NETDRV_TUNE_TWISTER
-static inline void netdrv_tune_twister (struct net_device *dev,
- struct netdrv_private *tp) {}
-#else
-static void netdrv_tune_twister (struct net_device *dev,
- struct netdrv_private *tp)
-{
- int linkcase;
-
- DPRINTK ("ENTER\n");
-
- /* This is a complicated state machine to configure the "twister" for
- impedance/echos based on the cable length.
- All of this is magic and undocumented.
- */
- switch (tp->twistie) {
- case 1:
- if (NETDRV_R16 (CSCR) & CSCR_LinkOKBit) {
- /* We have link beat, let us tune the twister. */
- NETDRV_W16 (CSCR, CSCR_LinkDownOffCmd);
- tp->twistie = 2; /* Change to state 2. */
- next_tick = HZ / 10;
- } else {
- /* Just put in some reasonable defaults for when beat returns. */
- NETDRV_W16 (CSCR, CSCR_LinkDownCmd);
- NETDRV_W32 (FIFOTMS, 0x20); /* Turn on cable test mode. */
- NETDRV_W32 (PARA78, PARA78_default);
- NETDRV_W32 (PARA7c, PARA7c_default);
- tp->twistie = 0; /* Bail from future actions. */
- }
- break;
- case 2:
- /* Read how long it took to hear the echo. */
- linkcase = NETDRV_R16 (CSCR) & CSCR_LinkStatusBits;
- if (linkcase == 0x7000)
- tp->twist_row = 3;
- else if (linkcase == 0x3000)
- tp->twist_row = 2;
- else if (linkcase == 0x1000)
- tp->twist_row = 1;
- else
- tp->twist_row = 0;
- tp->twist_col = 0;
- tp->twistie = 3; /* Change to state 2. */
- next_tick = HZ / 10;
- break;
- case 3:
- /* Put out four tuning parameters, one per 100msec. */
- if (tp->twist_col == 0)
- NETDRV_W16 (FIFOTMS, 0);
- NETDRV_W32 (PARA7c, param[(int) tp->twist_row]
- [(int) tp->twist_col]);
- next_tick = HZ / 10;
- if (++tp->twist_col >= 4) {
- /* For short cables we are done.
- For long cables (row == 3) check for mistune. */
- tp->twistie =
- (tp->twist_row == 3) ? 4 : 0;
- }
- break;
- case 4:
- /* Special case for long cables: check for mistune. */
- if ((NETDRV_R16 (CSCR) &
- CSCR_LinkStatusBits) == 0x7000) {
- tp->twistie = 0;
- break;
- } else {
- NETDRV_W32 (PARA7c, 0xfb38de03);
- tp->twistie = 5;
- next_tick = HZ / 10;
- }
- break;
- case 5:
- /* Retune for shorter cable (column 2). */
- NETDRV_W32 (FIFOTMS, 0x20);
- NETDRV_W32 (PARA78, PARA78_default);
- NETDRV_W32 (PARA7c, PARA7c_default);
- NETDRV_W32 (FIFOTMS, 0x00);
- tp->twist_row = 2;
- tp->twist_col = 0;
- tp->twistie = 3;
- next_tick = HZ / 10;
- break;
-
- default:
- /* do nothing */
- break;
- }
-
- DPRINTK ("EXIT\n");
-}
-#endif /* NETDRV_TUNE_TWISTER */
-
-
static void netdrv_timer (unsigned long data)
{
struct net_device *dev = (struct net_device *) data;
- struct netdrv_private *tp = (struct netdrv_private *) dev->priv;
+ struct netdrv_private *tp = dev->priv;
void *ioaddr = tp->mmio_addr;
int next_tick = 60 * HZ;
int mii_reg5;
@@ -1407,8 +1251,6 @@
}
}
- netdrv_tune_twister (dev, tp);
-
DPRINTK ("%s: Media selection tick, Link partner %4.4x.\n",
dev->name, NETDRV_R16 (NWayLPAR));
DPRINTK ("%s: Other registers are IntMask %4.4x IntStatus %4.4x"
@@ -1451,7 +1293,7 @@
static void netdrv_tx_timeout (struct net_device *dev)
{
- struct netdrv_private *tp = (struct netdrv_private *) dev->priv;
+ struct netdrv_private *tp = dev->priv;
void *ioaddr = tp->mmio_addr;
int i;
u8 tmp8;
@@ -1498,7 +1340,7 @@
static int netdrv_start_xmit (struct sk_buff *skb, struct net_device *dev)
{
- struct netdrv_private *tp = (struct netdrv_private *) dev->priv;
+ struct netdrv_private *tp = dev->priv;
void *ioaddr = tp->mmio_addr;
int entry;
@@ -1713,18 +1555,6 @@
}
#endif
- /* E. Gill */
- /* Note from BSD driver:
- * Here's a totally undocumented fact for you. When the
- * RealTek chip is in the process of copying a packet into
- * RAM for you, the length will be 0xfff0. If you spot a
- * packet header with this value, you need to stop. The
- * datasheet makes absolutely no mention of this and
- * RealTek should be shot for this.
- */
- if (rx_size == 0xfff0)
- break;
-
/* If Rx err or invalid rx_size/rx_status received
* (which happens if we get lost in the ring),
* Rx process gets reset, so we abort any further
@@ -1839,7 +1669,7 @@
struct pt_regs *regs)
{
struct net_device *dev = (struct net_device *) dev_instance;
- struct netdrv_private *tp = (struct netdrv_private *) dev->priv;
+ struct netdrv_private *tp = dev->priv;
int boguscnt = max_interrupt_work;
void *ioaddr = tp->mmio_addr;
int status = 0, link_changed = 0; /* avoid bogus "uninit" warning */
@@ -1853,31 +1683,8 @@
if (status == 0xFFFF)
break;
- /* Acknowledge all of the current interrupt sources ASAP, but
- an first get an additional status bit from CSCR. */
- if (status & RxUnderrun)
- link_changed = NETDRV_R16 (CSCR) & CSCR_LinkChangeBit;
-
- /* E. Gill */
- /* In case of an RxFIFOOver we must also clear the RxOverflow
- bit to avoid dropping frames for ever. Believe me, I got a
- lot of troubles copying huge data (approximately 2 RxFIFOOver
- errors per 1GB data transfer).
- The following is written in the 'p-guide.pdf' file (RTL8139(A/B)
- Programming guide V0.1, from 1999/1/15) on page 9 from REALTEC.
- -----------------------------------------------------------
- 2. RxFIFOOvw handling:
- When RxFIFOOvw occurs, all incoming packets are discarded.
- Clear ISR(RxFIFOOvw) doesn't dismiss RxFIFOOvw event. To
- dismiss RxFIFOOvw event, the ISR(RxBufOvw) must be written
- with a '1'.
- -----------------------------------------------------------
- Unfortunately I was not able to find any reason for the
- RxFIFOOver error (I got the feeling this depends on the
- CPU speed, lower CPU speed --> more errors).
- After clearing the RxOverflow bit the transfer of the
- packet was repeated and all data are error free transfered */
- NETDRV_W16_F (IntrStatus, (status & RxFIFOOver) ? (status | RxOverflow) : status);
+ /* Acknowledge all of the current interrupt sources ASAP */
+ NETDRV_W16_F (IntrStatus, status);
DPRINTK ("%s: interrupt status=%#4.4x new intstat=%#4.4x.\n",
dev->name, status,
@@ -1922,7 +1729,7 @@
static int netdrv_close (struct net_device *dev)
{
- struct netdrv_private *tp = (struct netdrv_private *) dev->priv;
+ struct netdrv_private *tp = dev->priv;
void *ioaddr = tp->mmio_addr;
unsigned long flags;
@@ -1964,16 +1771,16 @@
/* Green! Put the chip in low-power mode. */
NETDRV_W8 (Cfg9346, Cfg9346_Unlock);
NETDRV_W8 (Config1, 0x03);
- NETDRV_W8 (HltClk, 'H'); /* 'R' would leave the clock running. */
+ NETDRV_W8 (Cfg9346, Cfg9346_Lock);
DPRINTK ("EXIT\n");
return 0;
}
-static int mii_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
+static int netdrv_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
{
- struct netdrv_private *tp = (struct netdrv_private *) dev->priv;
+ struct netdrv_private *tp = dev->priv;
u16 *data = (u16 *) & rq->ifr_data;
unsigned long flags;
int rc = 0;
@@ -2014,7 +1821,7 @@
static struct net_device_stats *netdrv_get_stats (struct net_device *dev)
{
- struct netdrv_private *tp = (struct netdrv_private *) dev->priv;
+ struct netdrv_private *tp = dev->priv;
void *ioaddr = tp->mmio_addr;
DPRINTK ("ENTER\n");
@@ -2062,7 +1869,7 @@
static void netdrv_set_rx_mode (struct net_device *dev)
{
- struct netdrv_private *tp = (struct netdrv_private *) dev->priv;
+ struct netdrv_private *tp = dev->priv;
void *ioaddr = tp->mmio_addr;
u32 mc_filter[2]; /* Multicast hash filter */
int i, rx_mode;
@@ -2117,11 +1924,13 @@
static void netdrv_suspend (struct pci_dev *pdev)
{
- struct net_device *dev = pdev->driver_data;
- struct netdrv_private *tp = (struct netdrv_private *) dev->priv;
+ struct net_device *dev = pci_get_drvdata (pdev);
+ struct netdrv_private *tp = dev->priv;
void *ioaddr = tp->mmio_addr;
unsigned long flags;
+ if (!netif_running(dev))
+ return;
netif_device_detach (dev);
spin_lock_irqsave (&tp->lock, flags);
@@ -2142,8 +1951,10 @@
static void netdrv_resume (struct pci_dev *pdev)
{
- struct net_device *dev = pdev->driver_data;
+ struct net_device *dev = pci_get_drvdata (pdev);
+ if (!netif_running(dev))
+ return;
pci_power_on (pdev);
netif_device_attach (dev);
netdrv_hw_start (dev);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)