Preparations to caching root in path_walk()
[safe/jmp/linux-2.6] / drivers / net / tulip / tulip.h
index 20346d8..0afa2d4 100644 (file)
@@ -8,34 +8,34 @@
        of the GNU General Public License, incorporated herein by reference.
 
        Please refer to Documentation/DocBook/tulip-user.{pdf,ps,html}
-       for more information on this driver, or visit the project
-       Web page at http://sourceforge.net/projects/tulip/
+       for more information on this driver.
 
+       Please submit bugs to http://bugzilla.kernel.org/ .
 */
 
 #ifndef __NET_TULIP_H__
 #define __NET_TULIP_H__
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/spinlock.h>
 #include <linux/netdevice.h>
 #include <linux/timer.h>
 #include <linux/delay.h>
+#include <linux/pci.h>
 #include <asm/io.h>
 #include <asm/irq.h>
+#include <asm/unaligned.h>
 
 
 
 /* undefine, or define to various debugging levels (>4 == obscene levels) */
 #define TULIP_DEBUG 1
 
-/* undefine USE_IO_OPS for MMIO, define for PIO */
 #ifdef CONFIG_TULIP_MMIO
-# undef USE_IO_OPS
+#define TULIP_BAR      1       /* CBMA */
 #else
-# define USE_IO_OPS 1
+#define TULIP_BAR      0       /* CBIO */
 #endif
 
 
@@ -45,7 +45,8 @@ struct tulip_chip_table {
        int io_size;
        int valid_intrs;        /* CSR7 interrupt enable settings */
        int flags;
-       void (*media_timer) (unsigned long data);
+       void (*media_timer) (unsigned long);
+       work_func_t media_task;
 };
 
 
@@ -88,7 +89,6 @@ enum chips {
        I21145,
        DM910X,
        CONEXANT,
-       ULI526X
 };
 
 
@@ -134,7 +134,7 @@ enum pci_cfg_driver_reg {
 /* The bits in the CSR5 status registers, mostly interrupt sources. */
 enum status_bits {
        TimerInt = 0x800,
-       SytemError = 0x2000,
+       SystemError = 0x2000,
        TPLnkFail = 0x1000,
        TPLnkPass = 0x10,
        NormalIntr = 0x10000,
@@ -144,6 +144,7 @@ enum status_bits {
        RxNoBuf = 0x80,
        RxIntr = 0x40,
        TxFIFOUnderflow = 0x20,
+       RxErrIntr = 0x10,
        TxJabber = 0x08,
        TxNoBuf = 0x04,
        TxDied = 0x02,
@@ -178,25 +179,60 @@ enum tulip_busconfig_bits {
 
 /* The Tulip Rx and Tx buffer descriptors. */
 struct tulip_rx_desc {
-       s32 status;
-       s32 length;
-       u32 buffer1;
-       u32 buffer2;
+       __le32 status;
+       __le32 length;
+       __le32 buffer1;
+       __le32 buffer2;
 };
 
 
 struct tulip_tx_desc {
-       s32 status;
-       s32 length;
-       u32 buffer1;
-       u32 buffer2;            /* We use only buffer 1.  */
+       __le32 status;
+       __le32 length;
+       __le32 buffer1;
+       __le32 buffer2;         /* We use only buffer 1.  */
 };
 
 
 enum desc_status_bits {
-       DescOwned = 0x80000000,
-       RxDescFatalErr = 0x8000,
-       RxWholePkt = 0x0300,
+       DescOwned    = 0x80000000,
+       DescWholePkt = 0x60000000,
+       DescEndPkt   = 0x40000000,
+       DescStartPkt = 0x20000000,
+       DescEndRing  = 0x02000000,
+       DescUseLink  = 0x01000000,
+
+       /*
+        * Error summary flag is logical or of 'CRC Error', 'Collision Seen',
+        * 'Frame Too Long', 'Runt' and 'Descriptor Error' flags generated
+        * within tulip chip.
+        */
+       RxDescErrorSummary = 0x8000,
+       RxDescCRCError = 0x0002,
+       RxDescCollisionSeen = 0x0040,
+
+       /*
+        * 'Frame Too Long' flag is set if packet length including CRC exceeds
+        * 1518.  However, a full sized VLAN tagged frame is 1522 bytes
+        * including CRC.
+        *
+        * The tulip chip does not block oversized frames, and if this flag is
+        * set on a receive descriptor it does not indicate the frame has been
+        * truncated.  The receive descriptor also includes the actual length.
+        * Therefore we can safety ignore this flag and check the length
+        * ourselves.
+        */
+       RxDescFrameTooLong = 0x0080,
+       RxDescRunt = 0x0800,
+       RxDescDescErr = 0x4000,
+       RxWholePkt   = 0x00000300,
+       /*
+        * Top three bits of 14 bit frame length (status bits 27-29) should
+        * never be set as that would make frame over 2047 bytes. The Receive
+        * Watchdog flag (bit 4) may indicate the length is over 2048 and the
+        * length field is invalid.
+        */
+       RxLengthOver2047 = 0x38000010
 };
 
 
@@ -260,10 +296,15 @@ enum t21143_csr6_bits {
    There are no ill effects from too-large receive rings. */
 
 #define TX_RING_SIZE   32
-#define RX_RING_SIZE   128 
+#define RX_RING_SIZE   128
 #define MEDIA_MASK     31
 
-#define PKT_BUF_SZ             1536    /* Size of each temporary Rx buffer. */
+/* The receiver on the DC21143 rev 65 can fail to close the last
+ * receive descriptor in certain circumstances (see errata) when
+ * using MWI. This can only occur if the receive buffer ends on
+ * a cache line boundary, so the "+ 4" below ensures it doesn't.
+ */
+#define PKT_BUF_SZ     (1536 + 4)      /* Size of each temporary Rx buffer. */
 
 #define TULIP_MIN_CACHE_LINE   8       /* in units of 32-bit words */
 
@@ -294,11 +335,7 @@ enum t21143_csr6_bits {
 
 #define RUN_AT(x) (jiffies + (x))
 
-#if defined(__i386__)                  /* AKA get_unaligned() */
-#define get_u16(ptr) (*(u16 *)(ptr))
-#else
-#define get_u16(ptr) (((u8*)(ptr))[0] + (((u8*)(ptr))[1]<<8))
-#endif
+#define get_u16(ptr) get_unaligned_le16((ptr))
 
 struct medialeaf {
        u8 type;
@@ -348,6 +385,7 @@ struct tulip_private {
        int chip_id;
        int revision;
        int flags;
+       struct napi_struct napi;
        struct net_device_stats stats;
        struct timer_list timer;        /* Media selection timer. */
        struct timer_list oom_timer;    /* Out of memory timer. */
@@ -368,6 +406,7 @@ struct tulip_private {
        unsigned int medialock:1;       /* Don't sense media type. */
        unsigned int mediasense:1;      /* Media sensing in progress. */
        unsigned int nway:1, nwayset:1;         /* 21143 internal NWay. */
+       unsigned int timeout_recovery:1;
        unsigned int csr0;      /* CSR0 setting. */
        unsigned int csr6;      /* Current CSR6 control settings. */
        unsigned char eeprom[EEPROM_SIZE];      /* Serial EEPROM contents. */
@@ -386,6 +425,8 @@ struct tulip_private {
        void __iomem *base_addr;
        int csr12_shadow;
        int pad0;               /* Used for 8-byte alignment */
+       struct work_struct media_work;
+       struct net_device *dev;
 };
 
 
@@ -400,7 +441,7 @@ struct eeprom_fixup {
 
 /* 21142.c */
 extern u16 t21142_csr14[];
-void t21142_timer(unsigned long data);
+void t21142_media_task(struct work_struct *work);
 void t21142_start_nway(struct net_device *dev);
 void t21142_lnk_change(struct net_device *dev, int csr5);
 
@@ -418,10 +459,10 @@ int tulip_read_eeprom(struct net_device *dev, int location, int addr_len);
 /* interrupt.c */
 extern unsigned int tulip_max_interrupt_work;
 extern int tulip_rx_copybreak;
-irqreturn_t tulip_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
+irqreturn_t tulip_interrupt(int irq, void *dev_instance);
 int tulip_refill_rx(struct net_device *dev);
 #ifdef CONFIG_TULIP_NAPI
-int tulip_poll(struct net_device *dev, int *budget);
+int tulip_poll(struct napi_struct *napi, int budget);
 #endif
 
 
@@ -438,7 +479,7 @@ void pnic_lnk_change(struct net_device *dev, int csr5);
 void pnic_timer(unsigned long data);
 
 /* timer.c */
-void tulip_timer(unsigned long data);
+void tulip_media_task(struct work_struct *work);
 void mxic_timer(unsigned long data);
 void comet_timer(unsigned long data);
 
@@ -475,19 +516,29 @@ static inline void tulip_stop_rxtx(struct tulip_private *tp)
                        udelay(10);
 
                if (!i)
-                       printk(KERN_DEBUG "%s: tulip_stop_rxtx() failed\n",
-                                       pci_name(tp->pdev));
+                       printk(KERN_DEBUG "%s: tulip_stop_rxtx() failed"
+                                       " (CSR5 0x%x CSR6 0x%x)\n",
+                                       pci_name(tp->pdev),
+                                       ioread32(ioaddr + CSR5),
+                                       ioread32(ioaddr + CSR6));
        }
 }
 
 static inline void tulip_restart_rxtx(struct tulip_private *tp)
 {
-       if(!(tp->chip_id == ULI526X && 
-               (tp->revision == 0x40 || tp->revision == 0x50))) {
-               tulip_stop_rxtx(tp);
-               udelay(5);
-       }
+       tulip_stop_rxtx(tp);
+       udelay(5);
        tulip_start_rxtx(tp);
 }
 
+static inline void tulip_tx_timeout_complete(struct tulip_private *tp, void __iomem *ioaddr)
+{
+       /* Stop and restart the chip's Tx processes. */
+       tulip_restart_rxtx(tp);
+       /* Trigger an immediate transmit demand. */
+       iowrite32(0, ioaddr + CSR1);
+
+       tp->stats.tx_errors++;
+}
+
 #endif /* __NET_TULIP_H__ */