Pekka Enberg wrote:
On Sat, 2006-04-29 at 14:21 +0200, David Gómez wrote:
I already had it modified, just needed to create the patch... Anyway,
have you submitted it to netdev?

On Sat, 2006-04-29 at 23:35 +0300, Pekka Enberg wrote:
No, I haven't. I don't have the hardware, so I can't test the driver.
Furthermore, there's plenty of stuff to fix before it's in any shape for
submission. If someone wants to give this patch a spin, I would love to
hear the results.

Thanks for doing this Pekka. I've fixed up some stuff and given it some brief testing on a 100BaseT network and it seems to work now.

Subject: [PATCH] IP1000 Gigabit Ethernet device driver

This is a cleaned up fork of the IP1000A device driver:

  <http://www.icplus.com.tw/driver-pp-IP1000A.html>

Open issues include but are not limited to:

  - ipg_probe() looks really fishy and doesn't handle all errors
    (e.g. ioremap failing).
  - ipg_nic_do_ioctl() is playing games with user-space pointer.
    We should use ethtool ioctl instead as suggested by Arjan.

Still pending.  Also:

    - something (PHY reset/auto negotiation?) takes 2-3 seconds and
      appears to be done with interrupts disabled.

  - For multiple devices, the driver uses a global root_dev and
    ipg_remove() play some tricks which look fishy.

Killed this.  It was broke and ugly as hell.

Attached is patch with some more changes:

- Remove changelogs
- Remove ether_crc_le() -- use crc32_le() instead.
- No more nonsense with root_dev -- ipg_remove() now works.
- Move PHY and MAC address initialization into the ipg_probe().  It was
  previously filling in the MAC address on open which breaks some user
  space.
- Folded ipg_nic_init into ipg_probe since it was broke otherwise.

Signed-off-by: David Vrabel <[EMAIL PROTECTED]>
Index: linux-source-2.6.16/drivers/net/ipg.c
===================================================================
--- linux-source-2.6.16.orig/drivers/net/ipg.c  2006-04-30 22:26:05.788013667 
+0100
+++ linux-source-2.6.16/drivers/net/ipg.c       2006-05-01 00:23:28.358641581 
+0100
@@ -13,149 +13,14 @@
  * 408 873 4117
  * www.sundanceti.com
  * [EMAIL PROTECTED]
- *
- * Rev  Date     Description
- * --------------------------------------------------------------
- * 0.1  11/8/99  Initial revision work begins.
- *
- * 0.2  11/12/99  Basic operation achieved, continuing work.
- *
- * 0.3  11/19/99  MAC Loop Back for sync problem testing.
- *
- * 0.4  12/22/99  ioctl for diagnotic program 'hunter' support.
- *
- * 0.5  4/13/00   Updates to
- *
- * 0.6  6/14/00   Slight correction to handling TFDDONE, and
- *                preservation of PHYCTRL polarity bits.
- *
- * 0.7  7/27/00   Modifications to accomodate triple speed
- *                autonegotiation. Also change to ioctl routine
- *                to handle unknown PHY address.
- *
- * 0.8  8/11/00   Added change_mtu function.
- *
- * 0.9  8/15/00   Corrected autonegotiation resolution.
- *
- * 0.10 8/30/00   Changed constants to use IPG in place
- *                of RIO. Also, removed most of debug
- *                code in preparation for production release.
- *
- * 0.11 8/31/00   Utilize 64 bit data types where appropriate.
- *
- * 0.12 9/1/00    Move some constants to include file and utilize
- *                RxDMAInt register.
- *
- * 0.13 10/31/00  Several minor modifications to improve stability.
- *
- * 0.14 11/28/00  Added call to nic_tx_free if TFD not available.
- *
- * 0.15 12/5/00   Corrected problem with receive errors, always set
- *                receive buffer address to NULL. Release RX buffers
- *                on errors.
- *
- * 0.16 12/20/00  Corrected autoneg resolution issue, must detect
- *                speed via PHYCTRL register. Also, perform only 1
- *                loop in the nic_txcleanup routine.
- *
- * 0.17 2/7/01    Changed all references of ST2021 to IPG.
- *                When next TFD not available, return -ENOMEM instead
- *                of 0. Removed references to RUBICON.
- *
- * 0.18 2/14/01   Corrected problem when unexpected jumbo frames are
- *                received (now dropped properly.) Changed
- *                "DROP_ON_ERRORS" breaking out Ethernet errors and
- *                TCP/IP errors serparately. Corrected Gigabit
- *                copper PAUSE autonegotiation.
- *
- * 0.19 2/22/01   Changed interrupt handling of RFD_LIST_END,
- *                INT_REQUESTED, and RX_DMA_COMPLETE. Masked off
- *                RMON statistics and unused MIB statistics.
- *                Make sure *all* statistics are accounted for
- *                (either masked or read in get_stats) to avoid
- *                perpetual UpdateStats interrupt from causing
- *                driver to crash.
- *
- * 0.20 3/2/01    Corrected error in nic_stop. Need to set
- *                TxBuff[] = NULL after freeing TxBuff and
- *                RxBuff[] = NULL after freeing RxBuff.
- *
- * 0.21 3/5/01    Correct 10/100Mbit PAUSE autonegotiation.
- *
- * 0.22 3/16/01   Used TxDMAIndicate for 100/1000Mbps modes. Add
- *                "TFD unavailable" and "RFD list end" counters
- *                to assist with performance measurement. Added
- *                check for maxtfdcnt != 0 to while loop within
- *                txcleanup.
- *
- * 0.23 3/22/01   Set the CurrentTxFrameID to 1 upon detecting
- *                a TxDMAComplete to reduce the number of TxDMAComplete.
- *                Also, indicate IP/TCP/UDP checksum is unneseccary
- *                if IPG indicates checksum validates.
- *
- * 0.24 3/23/01   Changed the txfree routine, eliminating the margin
- *                between the last freed TFD and the current TFD.
- *
- * 0.25 4/3/01    Corrected errors in config_autoneg to deal with
- *                fiber flag properly.
- *
- * 0.26 5/1/01    Port for operation with Linux 2.2 or 2.4 kernel.
- *
- * 0.27 5/22/01   Cleaned up some extraneous comments.
- *
- * 0.28 6/20/01   Added auto IP, TCP, and UDP checksum addition
- *                on transmit based on compilation option.
- *
- * 0.29 7/26/01   Comment out #include <asm/spinlock.h> from ipg.h
- *                for compatibility with RedHat 7.1. Unkown reason.
- *
- * 0.30 8/10/01   Added debug message to each function, print function
- *                name when entered. Added DEBUGCTRL register bit 5 for
- *                Rx DMA Poll Now bug work around. Added ifdef IPG_DEBUG
- *                flags to IPG_TFDlistunabvail and IPG_RFDlistend
- *                counters. Removed clearing of sp->stat struct from
- *                nic_open and added check in get_stats to make sure
- *                NIC is initialized before reading statistic registers.
- *                Corrected erroneous MACCTRL setting for Fiber based
- *                10/100 boards. Corrected storage of phyctrlpolarity
- *                variable.
- *
- * 0.31 8/13/01   Incorporate STI or TMI fiber based NIC detection.
- *                Corrected problem with _pciremove_linux2_4 routine.
- *                Corrected setting of IP/TCP/UDP checksumming on receive
- *                and transmit.
- *
- * 0.32 8/15/01   Changed the tmi_fiber_detect routine.
- *
- * 0.33 8/16/01   Changed PHY reset method in nic_open routine. Added
- *                a chip reset in nic_stop to shut down the IPG.
- *
- * 0.34 9/5/01    Corrected some misuage of dev_kfree_skb.
- *
- * 0.35 10/30/01  Unmap register space (IO or memory) in the nic_stop
- *                routine instead of in the cleanup or remove routines.
- *                Corrects driver up/down/up problem when using IO
- *                register mapping.
- *
- * 0.36 10/31/01  Modify the constant IPG_FRAMESBETWEENTXDMACOMPLETES
- *               from 0x10 to 1.
- * 0.37 11/05/03  Modify the IPG_PHY_1000BASETCONTROL
- *                               in IP1000A this register is without 1000BPS 
Ability by default
- *                               so enable 1000BPS ability before PHY 
RESET/RESTART_AN
- * 0.38 11/05/03  update ipg_config_autoneg routine
- * 0.39 11/05/03  add Vendor_ID=13F0/Device_ID=1023 into support_cards
- * 2.05 10/16/04  Remove IPG_IE_RFD_LIST_END for pass SmartBit test.
- *                (see 20041019Jesse_For_SmartBit.)
- * 2.06 10/27/04 Support for kernel 2.6.x
- * 2.06a 11/03/04 remove some compile warring message.
- * 2.09b 06/03/05 Support 4k jumbo  (IC Plus, Jesse)
- * 2.09d 06/22/05 Support 10k jumbo, more than 4k will using copy mode (IC 
Plus, Jesse)
  */
 #define JUMBO_FRAME_4k_ONLY
 enum {
        netdev_io_size = 128
 };
 
+#include <linux/crc32.h>
+
 #include "ipg.h"
 #define DRV_NAME       "ipg"
 
@@ -214,14 +79,12 @@
 static int ipg_nic_hard_start_xmit(struct sk_buff *, struct net_device *);
 static struct net_device_stats *ipg_nic_get_stats(struct net_device *);
 static void ipg_nic_set_multicast_list(struct net_device *);
-static int ipg_nic_init(struct net_device *);
 static int ipg_nic_rx(struct net_device *);
 static int ipg_nic_rxrestore(struct net_device *);
 static int init_rfdlist(struct net_device *);
 static int init_tfdlist(struct net_device *);
 static int ipg_get_rxbuff(struct net_device *, int);
 static int ipg_config_autoneg(struct net_device *);
-static unsigned ether_crc_le(int, unsigned char *);
 static int ipg_nic_do_ioctl(struct net_device *, struct ifreq *, int);
 static int ipg_nic_change_mtu(struct net_device *, int);
 
@@ -1637,60 +1500,12 @@
         * by ifconfig.
         */
 
-       int phyaddr = 0;
        int error = 0;
-       int i;
        void __iomem *ioaddr = ipg_ioaddr(dev);
-       u8 revisionid = 0;
        struct ipg_nic_private *sp = netdev_priv(dev);
 
        IPG_DEBUG_MSG("_nic_open\n");
 
-       /* Reset all functions within the IPG. Do not assert
-        * RST_OUT as not compatible with some PHYs.
-        */
-       i = IPG_AC_GLOBAL_RESET | IPG_AC_RX_RESET |
-           IPG_AC_TX_RESET | IPG_AC_DMA |
-           IPG_AC_FIFO | IPG_AC_NETWORK | IPG_AC_HOST | IPG_AC_AUTO_INIT;
-       /* Read/Write and Reset EEPROM Value Jesse20040128EEPROM_VALUE */
-       /* Read LED Mode Configuration from EEPROM */
-       sp->LED_Mode = read_eeprom(dev, 6);
-
-       error = ipg_reset(dev, i);
-       if (error < 0) {
-               return error;
-       }
-
-       /* Reset PHY. */
-       phyaddr = ipg_find_phyaddr(dev);
-
-       if (phyaddr != -1) {
-               u16 mii_phyctrl, mii_1000cr;
-               mii_1000cr = read_phy_register(dev,
-                                              phyaddr,
-                                              GMII_PHY_1000BASETCONTROL);
-               write_phy_register(dev, phyaddr,
-                                  GMII_PHY_1000BASETCONTROL,
-                                  mii_1000cr |
-                                  GMII_PHY_1000BASETCONTROL_FULL_DUPLEX |
-                                  GMII_PHY_1000BASETCONTROL_HALF_DUPLEX |
-                                  GMII_PHY_1000BASETCONTROL_PreferMaster);
-
-               mii_phyctrl = read_phy_register(dev, phyaddr, GMII_PHY_CONTROL);
-               /* Set default phyparam */
-               pci_read_config_byte(sp->pdev, PCI_REVISION_ID, &revisionid);
-               ipg_set_phy_default_param(revisionid, dev, phyaddr);
-
-               /* reset Phy */
-               write_phy_register(dev,
-                                  phyaddr, GMII_PHY_CONTROL,
-                                  (mii_phyctrl | GMII_PHY_CONTROL_RESET |
-                                   MII_PHY_CONTROL_RESTARTAN));
-
-       }
-
-       spin_lock_init(&sp->lock);
-
        /* Check for interrupt line conflicts, and request interrupt
         * line for IPG.
         *
@@ -1743,26 +1558,6 @@
                return error;
        }
 
-       /* Read MAC Address from EERPOM Jesse20040128EEPROM_VALUE */
-       sp->StationAddr0 = read_eeprom(dev, 16);
-       sp->StationAddr1 = read_eeprom(dev, 17);
-       sp->StationAddr2 = read_eeprom(dev, 18);
-       /* Write MAC Address to Station Address */
-       iowrite16(sp->StationAddr0, ioaddr + IPG_STATIONADDRESS0);
-       iowrite16(sp->StationAddr1, ioaddr + IPG_STATIONADDRESS1);
-       iowrite16(sp->StationAddr2, ioaddr + IPG_STATIONADDRESS2);
-
-       /* Set station address in ethernet_device structure. */
-       dev->dev_addr[0] = ioread16(ioaddr + IPG_STATIONADDRESS0) & 0x00FF;
-       dev->dev_addr[1] =
-           (ioread16(ioaddr + IPG_STATIONADDRESS0) & 0xFF00) >> 8;
-       dev->dev_addr[2] = ioread16(ioaddr + IPG_STATIONADDRESS1) & 0x00FF;
-       dev->dev_addr[3] =
-           (ioread16(ioaddr + IPG_STATIONADDRESS1) & 0xFF00) >> 8;
-       dev->dev_addr[4] = ioread16(ioaddr + IPG_STATIONADDRESS2) & 0x00FF;
-       dev->dev_addr[5] =
-           (ioread16(ioaddr + IPG_STATIONADDRESS2) & 0xFF00) >> 8;
-
        /* Configure IPG I/O registers. */
        error = ipg_io_config(dev);
        if (error < 0) {
@@ -2860,7 +2655,8 @@
        for (mc_list_ptr = dev->mc_list;
             mc_list_ptr != NULL; mc_list_ptr = mc_list_ptr->next) {
                /* Calculate CRC result for each multicast address. */
-               hashindex = ether_crc_le(ETH_ALEN, mc_list_ptr->dmi_addr);
+               hashindex = crc32_le(0xffffffff, mc_list_ptr->dmi_addr,
+                                    ETH_ALEN);
 
                /* Use only the least significant 6 bits. */
                hashindex = hashindex & 0x3F;
@@ -2883,86 +2679,79 @@
                      ioread8(ioaddr + IPG_RECEIVEMODE));
 }
 
-/*
- * The following code fragment was authored by Donald Becker.
- */
-
-/* The little-endian AUTODIN II ethernet CRC calculations.
-   A big-endian version is also available.
-   This is slow but compact code.  Do not use this routine for bulk data,
-   use a table-based routine instead.
-   This is common code and should be moved to net/core/crc.c.
-   Chips may use the upper or lower CRC bits, and may reverse and/or invert
-   them.  Select the endian-ness that results in minimal calculations.
-*/
-static unsigned const ethernet_polynomial_le = 0xedb88320U;
-static unsigned ether_crc_le(int length, unsigned char *data)
+static int ipg_hw_init(struct net_device *dev)
 {
-       unsigned int crc = 0xffffffff;  /* Initial value. */
-       while (--length >= 0) {
-               unsigned char current_octet = *data++;
-               int bit;
-               for (bit = 8; --bit >= 0; current_octet >>= 1) {
-                       if ((crc ^ current_octet) & 1) {
-                               crc >>= 1;
-                               crc ^= ethernet_polynomial_le;
-                       } else
-                               crc >>= 1;
-               }
-       }
-       return crc;
-}
+       int phyaddr = 0;
+       int error = 0;
+       int i;
+       void __iomem *ioaddr = ipg_ioaddr(dev);
+       u8 revisionid = 0;
+       struct ipg_nic_private *sp = netdev_priv(dev);
 
-/*
- * End of code fragment authored by Donald Becker.
- */
+       /* Reset all functions within the IPG. Do not assert
+        * RST_OUT as not compatible with some PHYs.
+        */
+       i = IPG_AC_GLOBAL_RESET | IPG_AC_RX_RESET |
+           IPG_AC_TX_RESET | IPG_AC_DMA |
+           IPG_AC_FIFO | IPG_AC_NETWORK | IPG_AC_HOST | IPG_AC_AUTO_INIT;
+       /* Read/Write and Reset EEPROM Value Jesse20040128EEPROM_VALUE */
+       /* Read LED Mode Configuration from EEPROM */
+       sp->LED_Mode = read_eeprom(dev, 6);
 
-static int ipg_nic_init(struct net_device *dev)
-{
-       /* Initialize IPG NIC. */
+       error = ipg_reset(dev, i);
+       if (error < 0) {
+               return error;
+       }
 
-       struct ipg_nic_private *sp = NULL;
+       ioaddr = ipg_ioaddr(dev);
 
-       IPG_DEBUG_MSG("_nic_init\n");
+       /* Reset PHY. */
+       phyaddr = ipg_find_phyaddr(dev);
 
-       /* Register the IPG NIC in the list of Ethernet devices. */
-       dev = alloc_etherdev(sizeof(struct ipg_nic_private));
+       if (phyaddr != -1) {
+               u16 mii_phyctrl, mii_1000cr;
+               mii_1000cr = read_phy_register(dev,
+                                              phyaddr,
+                                              GMII_PHY_1000BASETCONTROL);
+               write_phy_register(dev, phyaddr,
+                                  GMII_PHY_1000BASETCONTROL,
+                                  mii_1000cr |
+                                  GMII_PHY_1000BASETCONTROL_FULL_DUPLEX |
+                                  GMII_PHY_1000BASETCONTROL_HALF_DUPLEX |
+                                  GMII_PHY_1000BASETCONTROL_PreferMaster);
 
-       if (dev == NULL) {
-               printk(KERN_INFO "Could not initialize IP1000 based NIC.\n");
-               return -ENODEV;
-       }
+               mii_phyctrl = read_phy_register(dev, phyaddr, GMII_PHY_CONTROL);
+               /* Set default phyparam */
+               pci_read_config_byte(sp->pdev, PCI_REVISION_ID, &revisionid);
+               ipg_set_phy_default_param(revisionid, dev, phyaddr);
 
-       /* Reserve memory for ipg_nic_private structure. */
-       sp = kmalloc(sizeof(struct ipg_nic_private), GFP_KERNEL);
+               /* reset Phy */
+               write_phy_register(dev,
+                                  phyaddr, GMII_PHY_CONTROL,
+                                  (mii_phyctrl | GMII_PHY_CONTROL_RESET |
+                                   MII_PHY_CONTROL_RESTARTAN));
 
-       if (sp == NULL) {
-               printk(KERN_INFO
-                      "%s: No memory available for IP1000 private 
strucutre.\n",
-                      dev->name);
-               return -ENOMEM;
-       } else {
-               /* Fill the allocated memory space with 0s.
-                * Essentially sets all ipg_nic_private
-                * structure fields to 0.
-                */
-               memset(sp, 0, sizeof(*sp));
-               dev->priv = sp;
        }
 
-       /* Assign the new device to the list of IPG Ethernet devices. */
-       sp->next_dev = root_dev;
-       root_dev = dev;
+       /* Read MAC Address from EERPOM Jesse20040128EEPROM_VALUE */
+       sp->StationAddr0 = read_eeprom(dev, 16);
+       sp->StationAddr1 = read_eeprom(dev, 17);
+       sp->StationAddr2 = read_eeprom(dev, 18);
+       /* Write MAC Address to Station Address */
+       iowrite16(sp->StationAddr0, ioaddr + IPG_STATIONADDRESS0);
+       iowrite16(sp->StationAddr1, ioaddr + IPG_STATIONADDRESS1);
+       iowrite16(sp->StationAddr2, ioaddr + IPG_STATIONADDRESS2);
 
-       /* Declare IPG NIC functions for Ethernet device methods.
-        */
-       dev->open = &ipg_nic_open;
-       dev->stop = &ipg_nic_stop;
-       dev->hard_start_xmit = &ipg_nic_hard_start_xmit;
-       dev->get_stats = &ipg_nic_get_stats;
-       dev->set_multicast_list = &ipg_nic_set_multicast_list;
-       dev->do_ioctl = &ipg_nic_do_ioctl;
-       dev->change_mtu = &ipg_nic_change_mtu;
+       /* Set station address in ethernet_device structure. */
+       dev->dev_addr[0] = ioread16(ioaddr + IPG_STATIONADDRESS0) & 0x00FF;
+       dev->dev_addr[1] =
+           (ioread16(ioaddr + IPG_STATIONADDRESS0) & 0xFF00) >> 8;
+       dev->dev_addr[2] = ioread16(ioaddr + IPG_STATIONADDRESS1) & 0x00FF;
+       dev->dev_addr[3] =
+           (ioread16(ioaddr + IPG_STATIONADDRESS1) & 0xFF00) >> 8;
+       dev->dev_addr[4] = ioread16(ioaddr + IPG_STATIONADDRESS2) & 0x00FF;
+       dev->dev_addr[5] =
+           (ioread16(ioaddr + IPG_STATIONADDRESS2) & 0xFF00) >> 8;
 
        return 0;
 }
@@ -3144,99 +2933,23 @@
 
 static void ipg_remove(struct pci_dev *pdev)
 {
-       /* Remove function called when a IPG device is
-        * to be shut down.
-        */
-
-       struct net_device *prev_dev = NULL;
-       struct net_device *dev = NULL;
-       struct net_device *dev_to_remove = NULL;
-       struct ipg_nic_private *prev_sp = NULL;
-       struct ipg_nic_private *sp = NULL;
-       struct ipg_nic_private *sp_to_remove = NULL;
-
-       IPG_DEBUG_MSG("_pciremove_linux2_4\n");
-
-       dev = root_dev;
-
-       /* Move through list of Ethernet devices looking for
-        * a match.
-        */
-       while (dev) {
-               sp = netdev_priv(dev);
-
-               if (sp->pdev == pdev) {
-                       /* Save the pointer to the previous Ethernet
-                        * device.
-                        */
-                       dev_to_remove = dev;
-
-                       sp_to_remove = sp;
-
-                       break;
-               }
-
-               /* Save the "previous" device in the list. */
-               prev_dev = dev;
-
-               /* Retrieve next Ethernet device to be
-                * released.
-                */
-               dev = sp->next_dev;
-       }
-
-       /* Check if there is a device to remove. */
-       if (dev_to_remove == NULL) {
-               /* There are no Ethernet devices to remove. */
-               printk(KERN_INFO
-                      "A device remove request does not match with any 
Ethernet devices.\n");
-
-               return;
-       }
-
-       /* Check to see if we are removing the root device in the list. */
-       if (root_dev == dev_to_remove) {
-               /* Change the root Ethernet device to the next device to be
-                * released.
-                */
-               root_dev = sp_to_remove->next_dev;
-       } else if (sp_to_remove->next_dev != NULL)
-               /* Check if we need to re-link the list of devices. */
-       {
-               /* If the "previous" Ethernet device is NULL,
-                * the device is at the head of the list, and
-                * no re-linking is needed.
-                */
-               prev_sp = netdev_priv(prev_dev);
-
-               prev_sp->next_dev = sp_to_remove->next_dev;
-       }
-
-       /* Free memory associated with Ethernet device's
-        * private data structure.
-        */
-       if (sp_to_remove) {
-               kfree(sp_to_remove);
-       }
+       struct net_device *dev = pci_get_drvdata(pdev);
+       struct ipg_nic_private *sp = netdev_priv(dev);
 
-       printk(KERN_INFO "Un-registering Ethernet device %s\n",
-              dev_to_remove->name);
+       IPG_DEBUG_MSG("_remove\n");
 
        /* Un-register Ethernet device. */
-       unregister_netdev(dev_to_remove);
+       unregister_netdev(dev);
 
 #ifdef USE_IO_OPS
        ioport_unmap(ioaddr);
 #else
        iounmap(sp->ioaddr);
 #endif
-
        pci_release_regions(pdev);
 
-       /* Free memory associated with Ethernet device. */
-       if (dev_to_remove) {
-               kfree(dev_to_remove);
-       }
+       free_netdev(dev);
+       pci_disable_device(pdev);
        pci_set_drvdata(pdev, NULL);
 }
 
@@ -3269,13 +2982,31 @@
                goto out;
        }
 
-       err = ipg_nic_init(dev);
-       if (err) {
-               printk(KERN_INFO "Could not intialize IP1000 based NIC.\n");
+       /*
+        * Initialize net device.
+        */
+       dev = alloc_etherdev(sizeof(struct ipg_nic_private));
+       if (!dev) {
+               printk(KERN_ERR "ipg: alloc_etherdev failed\n");
+               err = -ENOMEM;
                goto out;
        }
-       dev = root_dev;
+
+       sp = netdev_priv(dev);
+       spin_lock_init(&sp->lock);
+
+       /* Declare IPG NIC functions for Ethernet device methods.
+        */
+       dev->open = &ipg_nic_open;
+       dev->stop = &ipg_nic_stop;
+       dev->hard_start_xmit = &ipg_nic_hard_start_xmit;
+       dev->get_stats = &ipg_nic_get_stats;
+       dev->set_multicast_list = &ipg_nic_set_multicast_list;
+       dev->do_ioctl = &ipg_nic_do_ioctl;
+       dev->change_mtu = &ipg_nic_change_mtu;
+
        SET_MODULE_OWNER(dev);
+       SET_NETDEV_DEV(dev, &pdev->dev);
 
        err = pci_request_regions(pdev, DRV_NAME);
        if (err)
@@ -3300,13 +3031,17 @@
                goto out;
        }
 #endif
-       sp = netdev_priv(root_dev);
+       sp = netdev_priv(dev);
        /* Save the pointer to the PCI device information. */
        sp->ioaddr = ioaddr;
        sp->pdev = pdev;
 
        pci_set_drvdata(pdev, dev);
 
+       err = ipg_hw_init(dev);
+       if (err)
+               goto out;
+
        err = register_netdev(dev);
        if (err)
                goto out;
Index: linux-source-2.6.16/drivers/net/ipg.h
===================================================================
--- linux-source-2.6.16.orig/drivers/net/ipg.h  2006-04-30 23:02:09.861345105 
+0100
+++ linux-source-2.6.16/drivers/net/ipg.h       2006-05-01 00:11:14.974349454 
+0100
@@ -15,85 +15,6 @@
  * 408 873 4117
  * www.sundanceti.com
  * [EMAIL PROTECTED]
- *
- * Rev  Date     Description
- * --------------------------------------------------------------
- * 0.1  11/8/99  Initial revision work begins
- *
- * 0.2  12/1/99  Minor update to modversions.h inclusion.
- *
- * 0.3  12/30/99 Updates to fully comply with IPG spec.
- *
- * 0.4  4/24/00  Updates to allow for removal of FCS generation
- *               and verification.
- * 0.5  8/15/00  Updates for MII PHY registers and fields.
- *
- * 0.6  8/31/00  Updates to change to using 64 bit data types
- *
- * 0.7  10/31/00 Added DDEBUG_MSG to allow for easy activation of
- *               individual DEBUG_MSGs.
- *
- * 0.8  11/06/00 Changed LastFreedRxBuff to LastRestoredRxBuff for
- *               clarity.
- *
- * 0.9  11/10/00 Changed Sundance DeviceID to 0x9020
- *
- * 0.10 2/14/01  Changed "DROP_ON_ERRORS", breaking out Ethernet from
- *               TCP/IP errors.
- *
- * 0.11 3/16/01  Changed "IPG_FRAMESBETWEENTXCOMPLETES" to
- *               "IPG_FRAMESBETWEENTXDMACOMPLETES" since will
- *               be using TxDMAIndicate instead of TxIndicate to
- *               improve performance. Added TFDunavailCount and
- *               RFDlistendCount to aid in performance improvement.
- *
- * 0.12 3/22/01  Removed IPG_DROP_ON_RX_TCPIP_ERRORS.
- *
- * 0.13 3/23/01  Removed IPG_TXQUEUE_MARGIN.
- *
- * 0.14 3/30/01  Broke out sections into multiple files and added
- *               OS version specific detection and settings.
- */
-
-/*
- * Linux header utilization:
- *
- * config.h     For PCI support, namely CONFIG_PCI macro.
- *
- * version.h   For Linux kernel version detection.
- *
- * module.h    For modularized driver support.
- *
- * kernel.h     For 'printk'.
- *
- * pci.h        PCI support, including ID, VENDOR, and CLASS
- *              standard definitions; PCI specific structures,
- *              including pci_dev struct.
- *
- * ioport.h     I/O ports, check_region, request_region,
- *              release_region.
- *
- * errno.h      Standard error numbers, e.g. ENODEV.
- *
- * asm/io.h     For reading/writing I/O ports, and for virt_to_bus
- *             function.
- *
- * delay.h      For milisecond delays.
- *
- * types.h      For specific typedefs (i.e. u32, u16, u8).
- *
- * netdevice.h  For device structure needed for network support.
- *
- * etherdevice.h       For ethernet device support.
- *
- * init.h       For __initfunc.
- *
- * skbuff.h    Socket buffer (skbuff) definition.
- *
- * asm/bitops.h        For test_and_set_bit, clear_bit functions.
- *
- * asm/spinlock.h For spin_lock_irqsave, spin_lock_irqrestore functions.
- *
  */
 #ifndef __LINUX_IPG_H
 #define __LINUX_IPG_H
@@ -1000,9 +921,6 @@
  * End miscellaneous macros.
  */
 
-/* IPG Ethernet device structure, used for removing module. */
-struct net_device *root_dev = NULL;
-
 /* Transmit Frame Descriptor. The IPG supports 15 fragments,
  * however Linux requires only a single fragment. Note, each
  * TFD field is 64 bits wide.
@@ -1054,7 +972,6 @@
        int RxBuffNotReady;
        struct pci_dev *pdev;
        struct net_device_stats stats;
-       struct net_device *next_dev;
        spinlock_t lock;
        int tenmbpsmode;
 

Reply via email to