linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / drivers / net / yellowfin.c
index 8459a18..1c25065 100644 (file)
 
        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    "2.0"
-#define DRV_RELDATE    "Jun 27, 2006"
+#define DRV_VERSION    "1.05+LK1.1.6"
+#define DRV_RELDATE    "Feb 11, 2002"
 
 #define PFX DRV_NAME ": "
 
@@ -45,8 +69,8 @@ static int fifo_cfg = 0x0020;                         /* Bypass external Tx FIFO. */
 static int dma_ctrl = 0x00CAC277;                      /* Override when loading module! */
 static int fifo_cfg = 0x0028;
 #else
-static const int dma_ctrl = 0x004A0263;                        /* Constrained by errata */
-static const int fifo_cfg = 0x0020;                            /* Bypass external Tx FIFO. */
+static int dma_ctrl = 0x004A0263;                      /* Constrained by errata */
+static int fifo_cfg = 0x0020;                          /* Bypass external Tx FIFO. */
 #endif
 
 /* Set the copy breakpoint for the copy-only-tiny-frames scheme.
@@ -210,16 +234,26 @@ See Packet Engines confidential appendix (prototype chips only).
 
 \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. */
-enum {
-       YELLOWFIN_SIZE  = 0x100,
-};
+#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
 
 struct pci_id_info {
         const char *name;
@@ -227,21 +261,24 @@ struct pci_id_info {
                 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 const struct pci_id_info pci_id_tbl[] = {
+static 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},
-         HasMII | DontUseEeprom },
-       { }
+        PCI_IOTYPE, YELLOWFIN_SIZE, HasMII | DontUseEeprom },
+       {NULL,},
 };
 
-static const struct pci_device_id yellowfin_pci_tbl[] = {
+static 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);
 
@@ -579,7 +616,7 @@ static int yellowfin_open(struct net_device *dev)
        /* Reset the chip. */
        iowrite32(0x80000000, ioaddr + DMACtrl);
 
-       i = request_irq(dev->irq, &yellowfin_interrupt, IRQF_SHARED, dev->name, dev);
+       i = request_irq(dev->irq, &yellowfin_interrupt, SA_SHIRQ, dev->name, dev);
        if (i) return i;
 
        if (yellowfin_debug > 1)
@@ -825,11 +862,13 @@ static int yellowfin_start_xmit(struct sk_buff *skb, struct net_device *dev)
                /* Fix GX chipset errata. */
                if (cacheline_end > 24  || cacheline_end == 0) {
                        len = skb->len + 32 - cacheline_end + 1;
-                       if (skb_padto(skb, len)) {
-                               yp->tx_skbuff[entry] = NULL;
-                               netif_wake_queue(dev);
-                               return 0;
-                       }
+                       if (len != skb->len)
+                               skb = skb_padto(skb, len);
+               }
+               if (skb == NULL) {
+                       yp->tx_skbuff[entry] = NULL;
+                       netif_wake_queue(dev);
+                       return 0;
                }
        }
        yp->tx_skbuff[entry] = skb;
@@ -1402,7 +1441,8 @@ static void __devexit yellowfin_remove_one (struct pci_dev *pdev)
        struct net_device *dev = pci_get_drvdata(pdev);
        struct yellowfin_private *np;
 
-       BUG_ON(!dev);
+       if (!dev)
+               BUG();
        np = netdev_priv(dev);
 
         pci_free_consistent(pdev, STATUS_TOTAL_SIZE, np->tx_status,