linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / drivers / net / smc91x.h
index cf74b74..e0efd19 100644 (file)
  * Define your architecture specific bus configuration parameters here.
  */
 
-#if    defined(CONFIG_SA1100_GRAPHICSCLIENT) || \
-       defined(CONFIG_SA1100_PFS168) || \
-       defined(CONFIG_SA1100_FLEXANET) || \
-       defined(CONFIG_SA1100_GRAPHICSMASTER) || \
-       defined(CONFIG_ARCH_LUBBOCK)
+#if    defined(CONFIG_ARCH_LUBBOCK)
 
 /* We can only do 16-bit reads and writes in the static memory space. */
 #define SMC_CAN_USE_8BIT       0
                        __l--;                                          \
                }                                                       \
        } while (0)
-#define set_irq_type(irq, type)
+#define SMC_IRQ_FLAGS          (0)
+
+#elif defined(CONFIG_SA1100_PLEB)
+/* We can only do 16-bit reads and writes in the static memory space. */
+#define SMC_CAN_USE_8BIT       1
+#define SMC_CAN_USE_16BIT      1
+#define SMC_CAN_USE_32BIT      0
+#define SMC_IO_SHIFT           0
+#define SMC_NOWAIT             1
+
+#define SMC_inb(a, r)          readb((a) + (r))
+#define SMC_insb(a, r, p, l)   readsb((a) + (r), p, (l))
+#define SMC_inw(a, r)          readw((a) + (r))
+#define SMC_insw(a, r, p, l)   readsw((a) + (r), p, l)
+#define SMC_outb(v, a, r)      writeb(v, (a) + (r))
+#define SMC_outsb(a, r, p, l)  writesb((a) + (r), p, (l))
+#define SMC_outw(v, a, r)      writew(v, (a) + (r))
+#define SMC_outsw(a, r, p, l)  writesw((a) + (r), p, l)
+
+#define SMC_IRQ_FLAGS          (0)
 
 #elif defined(CONFIG_SA1100_ASSABET)
 
 
 /* We actually can't write halfwords properly if not word aligned */
 static inline void
-SMC_outw(u16 val, unsigned long ioaddr, int reg)
+SMC_outw(u16 val, void __iomem *ioaddr, int reg)
 {
        if (reg & 2) {
                unsigned int v = val << 16;
@@ -147,6 +162,55 @@ SMC_outw(u16 val, unsigned long ioaddr, int reg)
        }
 }
 
+#elif  defined(CONFIG_ARCH_OMAP)
+
+/* We can only do 16-bit reads and writes in the static memory space. */
+#define SMC_CAN_USE_8BIT       0
+#define SMC_CAN_USE_16BIT      1
+#define SMC_CAN_USE_32BIT      0
+#define SMC_IO_SHIFT           0
+#define SMC_NOWAIT             1
+
+#define SMC_inb(a, r)          readb((a) + (r))
+#define SMC_outb(v, a, r)      writeb(v, (a) + (r))
+#define SMC_inw(a, r)          readw((a) + (r))
+#define SMC_outw(v, a, r)      writew(v, (a) + (r))
+#define SMC_insw(a, r, p, l)   readsw((a) + (r), p, l)
+#define SMC_outsw(a, r, p, l)  writesw((a) + (r), p, l)
+#define SMC_inl(a, r)          readl((a) + (r))
+#define SMC_outl(v, a, r)      writel(v, (a) + (r))
+#define SMC_insl(a, r, p, l)   readsl((a) + (r), p, l)
+#define SMC_outsl(a, r, p, l)  writesl((a) + (r), p, l)
+
+#include <asm/mach-types.h>
+#include <asm/arch/cpu.h>
+
+#define        SMC_IRQ_FLAGS (( \
+                  machine_is_omap_h2() \
+               || machine_is_omap_h3() \
+               || (machine_is_omap_innovator() && !cpu_is_omap1510()) \
+       ) ? SA_TRIGGER_FALLING : SA_TRIGGER_RISING)
+
+
+#elif  defined(CONFIG_SH_SH4202_MICRODEV)
+
+#define SMC_CAN_USE_8BIT       0
+#define SMC_CAN_USE_16BIT      1
+#define SMC_CAN_USE_32BIT      0
+
+#define SMC_inb(a, r)          inb((a) + (r) - 0xa0000000)
+#define SMC_inw(a, r)          inw((a) + (r) - 0xa0000000)
+#define SMC_inl(a, r)          inl((a) + (r) - 0xa0000000)
+#define SMC_outb(v, a, r)      outb(v, (a) + (r) - 0xa0000000)
+#define SMC_outw(v, a, r)      outw(v, (a) + (r) - 0xa0000000)
+#define SMC_outl(v, a, r)      outl(v, (a) + (r) - 0xa0000000)
+#define SMC_insl(a, r, p, l)   insl((a) + (r) - 0xa0000000, p, l)
+#define SMC_outsl(a, r, p, l)  outsl((a) + (r) - 0xa0000000, p, l)
+#define SMC_insw(a, r, p, l)   insw((a) + (r) - 0xa0000000, p, l)
+#define SMC_outsw(a, r, p, l)  outsw((a) + (r) - 0xa0000000, p, l)
+
+#define SMC_IRQ_FLAGS          (0)
+
 #elif  defined(CONFIG_ISA)
 
 #define SMC_CAN_USE_8BIT       1
@@ -166,12 +230,96 @@ SMC_outw(u16 val, unsigned long ioaddr, int reg)
 #define SMC_CAN_USE_16BIT      1
 #define SMC_CAN_USE_32BIT      0
 
-#define SMC_inb(a, r)          inb((a) + (r) - 0xa0000000)
-#define SMC_inw(a, r)          inw((a) + (r) - 0xa0000000)
-#define SMC_outb(v, a, r)      outb(v, (a) + (r) - 0xa0000000)
-#define SMC_outw(v, a, r)      outw(v, (a) + (r) - 0xa0000000)
-#define SMC_insw(a, r, p, l)   insw((a) + (r) - 0xa0000000, p, l)
-#define SMC_outsw(a, r, p, l)  outsw((a) + (r) - 0xa0000000, p, l)
+#define SMC_inb(a, r)          inb((u32)a) + (r))
+#define SMC_inw(a, r)          inw(((u32)a) + (r))
+#define SMC_outb(v, a, r)      outb(v, ((u32)a) + (r))
+#define SMC_outw(v, a, r)      outw(v, ((u32)a) + (r))
+#define SMC_insw(a, r, p, l)   insw(((u32)a) + (r), p, l)
+#define SMC_outsw(a, r, p, l)  outsw(((u32)a) + (r), p, l)
+
+#define SMC_IRQ_FLAGS          (0)
+
+#define RPC_LSA_DEFAULT                RPC_LED_TX_RX
+#define RPC_LSB_DEFAULT                RPC_LED_100_10
+
+#elif  defined(CONFIG_MACH_LPD7A400) || defined(CONFIG_MACH_LPD7A404)
+
+/* The LPD7A40X_IOBARRIER is necessary to overcome a mismatch between
+ * the way that the CPU handles chip selects and the way that the SMC
+ * chip expects the chip select to operate.  Refer to
+ * Documentation/arm/Sharp-LH/IOBarrier for details.  The read from
+ * IOBARRIER is a byte as a least-common denominator of possible
+ * regions to use as the barrier.  It would be wasteful to read 32
+ * bits from a byte oriented region.
+ *
+ * There is no explicit protection against interrupts intervening
+ * between the writew and the IOBARRIER.  In SMC ISR there is a
+ * preamble that performs an IOBARRIER in the extremely unlikely event
+ * that the driver interrupts itself between a writew to the chip an
+ * the IOBARRIER that follows *and* the cache is large enough that the
+ * first off-chip access while handing the interrupt is to the SMC
+ * chip.  Other devices in the same address space as the SMC chip must
+ * be aware of the potential for trouble and perform a similar
+ * IOBARRIER on entry to their ISR.
+ */
+
+#include <asm/arch/constants.h>        /* IOBARRIER_VIRT */
+
+#define SMC_CAN_USE_8BIT       0
+#define SMC_CAN_USE_16BIT      1
+#define SMC_CAN_USE_32BIT      0
+#define SMC_NOWAIT             0
+#define LPD7A40X_IOBARRIER     readb (IOBARRIER_VIRT)
+
+#define SMC_inw(a,r)           readw ((void*) ((a) + (r)))
+#define SMC_insw(a,r,p,l)      readsw ((void*) ((a) + (r)), p, l)
+#define SMC_outw(v,a,r)             ({ writew ((v), (a) + (r)); LPD7A40X_IOBARRIER; })
+
+static inline void SMC_outsw (unsigned long a, int r, unsigned char* p, int l)
+{
+       unsigned short* ps = (unsigned short*) p;
+       while (l-- > 0) {
+               writew (*ps++, a + r);
+               LPD7A40X_IOBARRIER;
+       }
+}
+
+#define SMC_INTERRUPT_PREAMBLE LPD7A40X_IOBARRIER
+
+#define RPC_LSA_DEFAULT                RPC_LED_TX_RX
+#define RPC_LSB_DEFAULT                RPC_LED_100_10
+
+#elif defined(CONFIG_SOC_AU1X00)
+
+#include <au1xxx.h>
+
+/* We can only do 16-bit reads and writes in the static memory space. */
+#define SMC_CAN_USE_8BIT       0
+#define SMC_CAN_USE_16BIT      1
+#define SMC_CAN_USE_32BIT      0
+#define SMC_IO_SHIFT           0
+#define SMC_NOWAIT             1
+
+#define SMC_inw(a, r)          au_readw((unsigned long)((a) + (r)))
+#define SMC_insw(a, r, p, l)   \
+       do {    \
+               unsigned long _a = (unsigned long)((a) + (r)); \
+               int _l = (l); \
+               u16 *_p = (u16 *)(p); \
+               while (_l-- > 0) \
+                       *_p++ = au_readw(_a); \
+       } while(0)
+#define SMC_outw(v, a, r)      au_writew(v, (unsigned long)((a) + (r)))
+#define SMC_outsw(a, r, p, l)  \
+       do {    \
+               unsigned long _a = (unsigned long)((a) + (r)); \
+               int _l = (l); \
+               const u16 *_p = (const u16 *)(p); \
+               while (_l-- > 0) \
+                       au_writew(*_p++ , _a); \
+       } while(0)
+
+#define SMC_IRQ_FLAGS          (0)
 
 #else
 
@@ -194,6 +342,9 @@ SMC_outw(u16 val, unsigned long ioaddr, int reg)
 
 #endif
 
+#ifndef        SMC_IRQ_FLAGS
+#define        SMC_IRQ_FLAGS           SA_TRIGGER_RISING
+#endif
 
 #ifdef SMC_USE_PXA_DMA
 /*
@@ -202,15 +353,16 @@ SMC_outw(u16 val, unsigned long ioaddr, int reg)
  * different and probably not worth it for that reason, and not as critical
  * as RX which can overrun memory and lose packets.
  */
-#include <linux/pci.h>
+#include <linux/dma-mapping.h>
 #include <asm/dma.h>
+#include <asm/arch/pxa-regs.h>
 
 #ifdef SMC_insl
 #undef SMC_insl
 #define SMC_insl(a, r, p, l) \
        smc_pxa_dma_insl(a, lp->physaddr, r, dev->dma, p, l)
 static inline void
-smc_pxa_dma_insl(u_long ioaddr, u_long physaddr, int reg, int dma,
+smc_pxa_dma_insl(void __iomem *ioaddr, u_long physaddr, int reg, int dma,
                 u_char *buf, int len)
 {
        dma_addr_t dmabuf;
@@ -223,21 +375,23 @@ smc_pxa_dma_insl(u_long ioaddr, u_long physaddr, int reg, int dma,
 
        /* 64 bit alignment is required for memory to memory DMA */
        if ((long)buf & 4) {
-               *((u32 *)buf)++ = SMC_inl(ioaddr, reg);
+               *((u32 *)buf) = SMC_inl(ioaddr, reg);
+               buf += 4;
                len--;
        }
 
        len *= 4;
-       dmabuf = dma_map_single(NULL, buf, len, PCI_DMA_FROMDEVICE);
+       dmabuf = dma_map_single(NULL, buf, len, DMA_FROM_DEVICE);
        DCSR(dma) = DCSR_NODESC;
        DTADR(dma) = dmabuf;
        DSADR(dma) = physaddr + reg;
        DCMD(dma) = (DCMD_INCTRGADDR | DCMD_BURST32 |
                     DCMD_WIDTH4 | (DCMD_LENGTH & len));
        DCSR(dma) = DCSR_NODESC | DCSR_RUN;
-       while (!(DCSR(dma) & DCSR_STOPSTATE));
+       while (!(DCSR(dma) & DCSR_STOPSTATE))
+               cpu_relax();
        DCSR(dma) = 0;
-       dma_unmap_single(NULL, dmabuf, len, PCI_DMA_FROMDEVICE);
+       dma_unmap_single(NULL, dmabuf, len, DMA_FROM_DEVICE);
 }
 #endif
 
@@ -246,7 +400,7 @@ smc_pxa_dma_insl(u_long ioaddr, u_long physaddr, int reg, int dma,
 #define SMC_insw(a, r, p, l) \
        smc_pxa_dma_insw(a, lp->physaddr, r, dev->dma, p, l)
 static inline void
-smc_pxa_dma_insw(u_long ioaddr, u_long physaddr, int reg, int dma,
+smc_pxa_dma_insw(void __iomem *ioaddr, u_long physaddr, int reg, int dma,
                 u_char *buf, int len)
 {
        dma_addr_t dmabuf;
@@ -259,21 +413,23 @@ smc_pxa_dma_insw(u_long ioaddr, u_long physaddr, int reg, int dma,
 
        /* 64 bit alignment is required for memory to memory DMA */
        while ((long)buf & 6) {
-               *((u16 *)buf)++ = SMC_inw(ioaddr, reg);
+               *((u16 *)buf) = SMC_inw(ioaddr, reg);
+               buf += 2;
                len--;
        }
 
        len *= 2;
-       dmabuf = dma_map_single(NULL, buf, len, PCI_DMA_FROMDEVICE);
+       dmabuf = dma_map_single(NULL, buf, len, DMA_FROM_DEVICE);
        DCSR(dma) = DCSR_NODESC;
        DTADR(dma) = dmabuf;
        DSADR(dma) = physaddr + reg;
        DCMD(dma) = (DCMD_INCTRGADDR | DCMD_BURST32 |
                     DCMD_WIDTH2 | (DCMD_LENGTH & len));
        DCSR(dma) = DCSR_NODESC | DCSR_RUN;
-       while (!(DCSR(dma) & DCSR_STOPSTATE));
+       while (!(DCSR(dma) & DCSR_STOPSTATE))
+               cpu_relax();
        DCSR(dma) = 0;
-       dma_unmap_single(NULL, dmabuf, len, PCI_DMA_FROMDEVICE);
+       dma_unmap_single(NULL, dmabuf, len, DMA_FROM_DEVICE);
 }
 #endif
 
@@ -290,7 +446,7 @@ smc_pxa_dma_irq(int dma, void *dummy, struct pt_regs *regs)
 #define SMC_IO_SHIFT   0
 #endif
 #define SMC_IO_EXTENT  (16 << SMC_IO_SHIFT)
-
+#define SMC_DATA_EXTENT (4)
 
 /*
  . Bank Select Register:
@@ -569,14 +725,6 @@ static const char * chip_ids[ 16 ] =  {
        NULL, NULL, NULL};
 
 
-/*
- . Transmit status bits
-*/
-#define TS_SUCCESS 0x0001
-#define TS_LOSTCAR 0x0400
-#define TS_LATCOL  0x0200
-#define TS_16COL   0x0010
-
 /*
  . Receive status bits
 */
@@ -734,6 +882,7 @@ static const char * chip_ids[ 16 ] =  {
 #define SMC_GET_FIFO()         SMC_inw( ioaddr, FIFO_REG )
 #define SMC_GET_PTR()          SMC_inw( ioaddr, PTR_REG )
 #define SMC_SET_PTR(x)         SMC_outw( x, ioaddr, PTR_REG )
+#define SMC_GET_EPH_STATUS()   SMC_inw( ioaddr, EPH_STATUS_REG )
 #define SMC_GET_RCR()          SMC_inw( ioaddr, RCR_REG )
 #define SMC_SET_RCR(x)         SMC_outw( x, ioaddr, RCR_REG )
 #define SMC_GET_REV()          SMC_inw( ioaddr, REV_REG )
@@ -762,16 +911,9 @@ static const char * chip_ids[ 16 ] =  {
                SMC_outw( addr[4]|(addr[5] << 8), ioaddr, ADDR2_REG );  \
        } while (0)
 
-#define SMC_CLEAR_MCAST()                                              \
-       do {                                                            \
-               SMC_outw( 0, ioaddr, MCAST_REG1 );                      \
-               SMC_outw( 0, ioaddr, MCAST_REG2 );                      \
-               SMC_outw( 0, ioaddr, MCAST_REG3 );                      \
-               SMC_outw( 0, ioaddr, MCAST_REG4 );                      \
-       } while (0)
 #define SMC_SET_MCAST(x)                                               \
        do {                                                            \
-               unsigned char *mt = (x);                                \
+               const unsigned char *mt = (x);                          \
                SMC_outw( mt[0] | (mt[1] << 8), ioaddr, MCAST_REG1 );   \
                SMC_outw( mt[2] | (mt[3] << 8), ioaddr, MCAST_REG2 );   \
                SMC_outw( mt[4] | (mt[5] << 8), ioaddr, MCAST_REG3 );   \
@@ -818,7 +960,7 @@ static const char * chip_ids[ 16 ] =  {
 #endif
 
 #if SMC_CAN_USE_32BIT
-#define SMC_PUSH_DATA(p, l)                                            \
+#define _SMC_PUSH_DATA(p, l)                                           \
        do {                                                            \
                char *__ptr = (p);                                      \
                int __len = (l);                                        \
@@ -833,7 +975,7 @@ static const char * chip_ids[ 16 ] =  {
                        SMC_outw( *((u16 *)__ptr), ioaddr, DATA_REG );  \
                }                                                       \
        } while (0)
-#define SMC_PULL_DATA(p, l)                                            \
+#define _SMC_PULL_DATA(p, l)                                           \
        do {                                                            \
                char *__ptr = (p);                                      \
                int __len = (l);                                        \
@@ -853,11 +995,11 @@ static const char * chip_ids[ 16 ] =  {
                SMC_insl( ioaddr, DATA_REG, __ptr, __len >> 2);         \
        } while (0)
 #elif SMC_CAN_USE_16BIT
-#define SMC_PUSH_DATA(p, l)    SMC_outsw( ioaddr, DATA_REG, p, (l) >> 1 )
-#define SMC_PULL_DATA(p, l)    SMC_insw ( ioaddr, DATA_REG, p, (l) >> 1 )
+#define _SMC_PUSH_DATA(p, l)   SMC_outsw( ioaddr, DATA_REG, p, (l) >> 1 )
+#define _SMC_PULL_DATA(p, l)   SMC_insw ( ioaddr, DATA_REG, p, (l) >> 1 )
 #elif SMC_CAN_USE_8BIT
-#define SMC_PUSH_DATA(p, l)    SMC_outsb( ioaddr, DATA_REG, p, l )
-#define SMC_PULL_DATA(p, l)    SMC_insb ( ioaddr, DATA_REG, p, l )
+#define _SMC_PUSH_DATA(p, l)   SMC_outsb( ioaddr, DATA_REG, p, l )
+#define _SMC_PULL_DATA(p, l)   SMC_insb ( ioaddr, DATA_REG, p, l )
 #endif
 
 #if ! SMC_CAN_USE_16BIT
@@ -876,5 +1018,53 @@ static const char * chip_ids[ 16 ] =  {
        })
 #endif
 
+#ifdef SMC_CAN_USE_DATACS
+#define SMC_PUSH_DATA(p, l)                                            \
+       if ( lp->datacs ) {                                             \
+               unsigned char *__ptr = (p);                             \
+               int __len = (l);                                        \
+               if (__len >= 2 && (unsigned long)__ptr & 2) {           \
+                       __len -= 2;                                     \
+                       SMC_outw( *((u16 *)__ptr), ioaddr, DATA_REG );  \
+                       __ptr += 2;                                     \
+               }                                                       \
+               outsl(lp->datacs, __ptr, __len >> 2);                   \
+               if (__len & 2) {                                        \
+                       __ptr += (__len & ~3);                          \
+                       SMC_outw( *((u16 *)__ptr), ioaddr, DATA_REG );  \
+               }                                                       \
+       } else {                                                        \
+               _SMC_PUSH_DATA(p, l);                                   \
+       }
+
+#define SMC_PULL_DATA(p, l)                                            \
+       if ( lp->datacs ) {                                             \
+               unsigned char *__ptr = (p);                             \
+               int __len = (l);                                        \
+               if ((unsigned long)__ptr & 2) {                         \
+                       /*                                              \
+                        * We want 32bit alignment here.                \
+                        * Since some buses perform a full 32bit        \
+                        * fetch even for 16bit data we can't use       \
+                        * SMC_inw() here.  Back both source (on chip   \
+                        * and destination) pointers of 2 bytes.        \
+                        */                                             \
+                       __ptr -= 2;                                     \
+                       __len += 2;                                     \
+                       SMC_SET_PTR( 2|PTR_READ|PTR_RCV|PTR_AUTOINC );  \
+               }                                                       \
+               __len += 2;                                             \
+               insl( lp->datacs, __ptr, __len >> 2);                   \
+       } else {                                                        \
+               _SMC_PULL_DATA(p, l);                                   \
+       }
+#else
+#define SMC_PUSH_DATA(p, l) _SMC_PUSH_DATA(p, l)
+#define SMC_PULL_DATA(p, l) _SMC_PULL_DATA(p, l)
+#endif
+
+#if !defined (SMC_INTERRUPT_PREAMBLE)
+# define SMC_INTERRUPT_PREAMBLE
+#endif
 
 #endif  /* _SMC91X_H_ */