update brcm-2.4 to 2.4.35.4, integrate new broadcom system code, update broadcom...
[openwrt/staging/yousong.git] / package / broadcom-wl / src / driver / linux_osl.h
index d9c5533b85eb9fba74764b6339798defe9e866d1..f65c85966b7a23c1f069e825024bff0cde38f9cd 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Linux OS Independent Layer
  *
- * Copyright 2006, Broadcom Corporation
+ * Copyright 2007, Broadcom Corporation
  * All Rights Reserved.
  * 
  * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
@@ -9,7 +9,7 @@
  * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
  * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
  *
- * $Id: linux_osl.h,v 1.1.1.13 2006/04/08 06:13:39 honor Exp $
+ * $Id$
  */
 
 #ifndef _linux_osl_h_
 #include <linuxver.h>
 #include <osl.h>
 
-#define OSL_PKTTAG_SZ     32 /* Size of PktTag */
+#define OSL_PKTTAG_SZ      32 /* Size of PktTag */
 
-/* osl handle type forward declaration */
-typedef struct osl_dmainfo osldma_t;
+/* microsecond delay */
+extern void osl_delay(uint usec);
 
 /* OSL initialization */
-extern osl_t *osl_attach(void *pdev, bool pkttag);
+extern osl_t *osl_attach(void *pdev, uint bustype, bool pkttag);
 extern void osl_detach(osl_t *osh);
 
+#define PKTFREESETCB(osh, _tx_fn, _tx_ctx) \
+       do { \
+          ((osl_pubinfo_t*)osh)->tx_fn = _tx_fn; \
+          ((osl_pubinfo_t*)osh)->tx_ctx = _tx_ctx; \
+       } while (0)
+
 /* host/bus architecture-specific byte swap */
 #define BUS_SWAP32(v)          (v)
+
+
 #define        MALLOC_FAILED(osh)      osl_malloc_failed((osh))
 
 extern void *osl_malloc(osl_t *osh, uint size);
@@ -37,61 +45,110 @@ extern void osl_mfree(osl_t *osh, void *addr, uint size);
 extern uint osl_malloced(osl_t *osh);
 extern uint osl_malloc_failed(osl_t *osh);
 
-/* API for DMA addressing capability */
-#define        DMA_MAP(osh, va, size, direction, p) \
-       osl_dma_map((osh), (va), (size), (direction))
-#define        DMA_UNMAP(osh, pa, size, direction, p) \
-       osl_dma_unmap((osh), (pa), (size), (direction))
-static inline uint
-osl_dma_map(void *osh, void *va, uint size, int direction)
-{
-       int dir;
-       struct pci_dev *dev;
-
-       dev = (osh == NULL ? NULL : ((osl_t *)osh)->pdev);
-       dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE;
-       return (pci_map_single(dev, va, size, dir));
-}
-
-static inline void
-osl_dma_unmap(void *osh, uint pa, uint size, int direction)
-{
-       int dir;
-       struct pci_dev *dev;
-
-       dev = (osh == NULL ? NULL : ((osl_t *)osh)->pdev);
-       dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE;
-       pci_unmap_single(dev, (uint32)pa, size, dir);
-}
-
-#define OSL_DMADDRWIDTH(osh, addrwidth) do {} while (0)
+/* allocate/free shared (dma-able) consistent memory */
 #define        DMA_CONSISTENT_ALIGN    PAGE_SIZE
 #define        DMA_ALLOC_CONSISTENT(osh, size, pap, dmah) \
        osl_dma_alloc_consistent((osh), (size), (pap))
 #define        DMA_FREE_CONSISTENT(osh, va, size, pa, dmah) \
        osl_dma_free_consistent((osh), (void*)(va), (size), (pa))
-static inline void*
-osl_dma_alloc_consistent(osl_t *osh, uint size, ulong *pap)
-{
-       return (pci_alloc_consistent(osh->pdev, size, (dma_addr_t*)pap));
-}
+extern void *osl_dma_alloc_consistent(osl_t *osh, uint size, ulong *pap);
+extern void osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa);
 
-static inline void
-osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa)
-{
-       pci_free_consistent(osh->pdev, size, va, (dma_addr_t)pa);
-}
+/* map/unmap direction */
+#define        DMA_TX  1       /* TX direction for DMA */
+#define        DMA_RX  2       /* RX direction for DMA */
+
+/* map/unmap shared (dma-able) memory */
+#define        DMA_MAP(osh, va, size, direction, p, dmah) \
+       osl_dma_map((osh), (va), (size), (direction))
+#define        DMA_UNMAP(osh, pa, size, direction, p, dmah) \
+       osl_dma_unmap((osh), (pa), (size), (direction))
+extern uint osl_dma_map(osl_t *osh, void *va, uint size, int direction);
+extern void osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction);
 
+/* API for DMA addressing capability */
+#define OSL_DMADDRWIDTH(osh, addrwidth) do {} while (0)
 
 /* register access macros */
 #if defined(BCMJTAG)
 #include <bcmjtag.h>
-#define        R_REG(osh, r)   bcmjtag_read(NULL, (uint32)(r), sizeof(*(r)))
-#define        W_REG(osh, r, v)        bcmjtag_write(NULL, (uint32)(r), (uint32)(v), sizeof(*(r)))
-#endif /* defined(BCMSDIO) */
+#define OSL_WRITE_REG(osh, r, v) (bcmjtag_write(NULL, (uintptr)(r), (v), sizeof(*(r))))
+#define OSL_READ_REG(osh, r) (bcmjtag_read(NULL, (uintptr)(r), sizeof(*(r))))
+#endif
+
+#if defined(BCMJTAG)
+#define SELECT_BUS_WRITE(osh, mmap_op, bus_op) if (((osl_pubinfo_t*)(osh))->mmbus) \
+       mmap_op else bus_op
+#define SELECT_BUS_READ(osh, mmap_op, bus_op) (((osl_pubinfo_t*)(osh))->mmbus) ? \
+       mmap_op : bus_op
+#else
+#define SELECT_BUS_WRITE(osh, mmap_op, bus_op) mmap_op
+#define SELECT_BUS_READ(osh, mmap_op, bus_op) mmap_op
+#endif 
+
+/*
+ * BINOSL selects the slightly slower function-call-based binary compatible osl.
+ * Macros expand to calls to functions defined in linux_osl.c .
+ */
+#ifndef BINOSL
+
+/* string library, kernel mode */
+#ifndef printf
+#define        printf(fmt, args...)    printk(fmt, ## args)
+#endif /* printf */
+#include <linux/kernel.h>
+#include <linux/string.h>
+
+/* register access macros */
+#define        AND_REG(osh, r, v)              W_REG(osh, (r), R_REG(osh, r) & (v))
+#define        OR_REG(osh, r, v)               W_REG(osh, (r), R_REG(osh, r) | (v))
+
+/* bcopy, bcmp, and bzero */
+#define        bcopy(src, dst, len)    memcpy((dst), (src), (len))
+#define        bcmp(b1, b2, len)       memcmp((b1), (b2), (len))
+#define        bzero(b, len)           memset((b), '\0', (len))
+
+/* uncached virtual address */
+#ifdef mips
+#define OSL_UNCACHED(va)       KSEG1ADDR((va))
+#include <asm/addrspace.h>
+#else
+#define OSL_UNCACHED(va)       (va)
+#endif /* mips */
+
+/* get processor cycle count */
+#if defined(mips)
+#define        OSL_GETCYCLES(x)        ((x) = read_c0_count() * 2)
+#elif defined(__i386__)
+#define        OSL_GETCYCLES(x)        rdtscl((x))
+#else
+#define OSL_GETCYCLES(x)       ((x) = 0)
+#endif /* defined(mips) */
+
+/* dereference an address that may cause a bus exception */
+#ifdef mips
+#if defined(MODULE) && (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 17))
+#define BUSPROBE(val, addr)    panic("get_dbe() will not fixup a bus exception when compiled into"\
+                                       " a module")
+#else
+#define        BUSPROBE(val, addr)     get_dbe((val), (addr))
+#include <asm/paccess.h>
+#endif /* defined(MODULE) && (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 17)) */
+#else
+#define        BUSPROBE(val, addr)     ({ (val) = R_REG(NULL, (addr)); 0; })
+#endif /* mips */
+
+/* map/unmap physical to virtual I/O */
+#define        REG_MAP(pa, size)       ioremap_nocache((unsigned long)(pa), (unsigned long)(size))
+#define        REG_UNMAP(va)           iounmap((void *)(va))
+
+/* shared (dma-able) memory access macros */
+#define        R_SM(r)                 *(r)
+#define        W_SM(r, v)              (*(r) = (v))
+#define        BZERO_SM(r, len)        memset((r), '\0', (len))
 
 /* packet primitives */
-#define        PKTGET(osh, len, send)          osl_pktget((osh), (len), (send))
+#define        PKTGET(osh, len, send)          osl_pktget((osh), (len))
 #define        PKTFREE(osh, skb, send)         osl_pktfree((osh), (skb), (send))
 #define        PKTDATA(osh, skb)               (((struct sk_buff*)(skb))->data)
 #define        PKTLEN(osh, skb)                (((struct sk_buff*)(skb))->len)
@@ -104,15 +161,25 @@ osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa)
 #define        PKTPULL(osh, skb, bytes)        skb_pull((struct sk_buff*)(skb), (bytes))
 #define        PKTDUP(osh, skb)                osl_pktdup((osh), (skb))
 #define        PKTTAG(skb)                     ((void*)(((struct sk_buff*)(skb))->cb))
-#define PKTALLOCED(osh)                        osl_pktalloced((osh))
+#define PKTALLOCED(osh)                        ((osl_pubinfo_t *)(osh))->pktalloced
+#ifdef BCMDBG_PKT     /* pkt logging for debugging */
+#define PKTLIST_DUMP(osh, buf)                 osl_pktlist_dump(osh, buf)
+#else /* BCMDBG_PKT */
 #define PKTLIST_DUMP(osh, buf)
+#endif /* BCMDBG_PKT */
+
+#ifdef BCMDBG_PKT     /* pkt logging for debugging */
+extern void osl_pktlist_add(osl_t *osh, void *p);
+extern void osl_pktlist_remove(osl_t *osh, void *p);
+extern char *osl_pktlist_dump(osl_t *osh, char *buf);
+#endif /* BCMDBG_PKT */
 
 /* Convert a native(OS) packet to driver packet.
  * In the process, native packet is destroyed, there is no copying
  * Also, a packettag is zeroed out
  */
 static INLINE void *
-osl_pkt_frmnative(osl_pubinfo_t*osh, struct sk_buff *skb)
+osl_pkt_frmnative(osl_pubinfo_t *osh, struct sk_buff *skb)
 {
        struct sk_buff *nskb;
 
@@ -121,13 +188,15 @@ osl_pkt_frmnative(osl_pubinfo_t*osh, struct sk_buff *skb)
 
        /* Increment the packet counter */
        for (nskb = skb; nskb; nskb = nskb->next) {
+#ifdef BCMDBG_PKT
+               osl_pktlist_add((osl_t *)osh, (void *) nskb);
+#endif  /* BCMDBG_PKT */
                osh->pktalloced++;
        }
 
        return (void *)skb;
 }
-#define PKTFRMNATIVE(osh, skb) osl_pkt_frmnative(((osl_pubinfo_t*)osh), \
-                                                       (struct sk_buff*)(skb))
+#define PKTFRMNATIVE(osh, skb) osl_pkt_frmnative(((osl_pubinfo_t *)osh), (struct sk_buff*)(skb))
 
 /* Convert a driver packet to native(OS) packet
  * In the process, packettag is zeroed out before sending up
@@ -135,7 +204,7 @@ osl_pkt_frmnative(osl_pubinfo_t*osh, struct sk_buff *skb)
  * In our case, that means it should be 0
  */
 static INLINE struct sk_buff *
-osl_pkt_tonative(osl_pubinfo_t*osh, void *pkt)
+osl_pkt_tonative(osl_pubinfo_t *osh, void *pkt)
 {
        struct sk_buff *nskb;
 
@@ -144,24 +213,167 @@ osl_pkt_tonative(osl_pubinfo_t*osh, void *pkt)
 
        /* Decrement the packet counter */
        for (nskb = (struct sk_buff *)pkt; nskb; nskb = nskb->next) {
+#ifdef BCMDBG_PKT
+               osl_pktlist_remove((osl_t *)osh, (void *) nskb);
+#endif  /* BCMDBG_PKT */
                osh->pktalloced--;
        }
 
        return (struct sk_buff *)pkt;
 }
-#define PKTTONATIVE(osh, pkt)          osl_pkt_tonative((osl_pubinfo_t*)(osh), (pkt))
+#define PKTTONATIVE(osh, pkt)          osl_pkt_tonative((osl_pubinfo_t *)(osh), (pkt))
 
 #define        PKTLINK(skb)                    (((struct sk_buff*)(skb))->prev)
 #define        PKTSETLINK(skb, x)              (((struct sk_buff*)(skb))->prev = (struct sk_buff*)(x))
 #define        PKTPRIO(skb)                    (((struct sk_buff*)(skb))->priority)
 #define        PKTSETPRIO(skb, x)              (((struct sk_buff*)(skb))->priority = (x))
+#define PKTSUMNEEDED(skb)              (((struct sk_buff*)(skb))->ip_summed == CHECKSUM_HW)
+#define PKTSETSUMGOOD(skb, x)          (((struct sk_buff*)(skb))->ip_summed = \
+                                               ((x) ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE))
+/* PKTSETSUMNEEDED and PKTSUMGOOD are not possible because skb->ip_summed is overloaded */
 #define PKTSHARED(skb)                  (((struct sk_buff*)(skb))->cloned)
 
-extern void *osl_pktget(osl_t *osh, uint len, bool send);
+extern void *osl_pktget(osl_t *osh, uint len);
+extern void osl_pktfree(osl_t *osh, void *skb, bool send);
+extern void *osl_pktdup(osl_t *osh, void *skb);
+#else  /* BINOSL */
+
+/* string library */
+#ifndef LINUX_OSL
+#undef printf
+#define        printf(fmt, args...)            osl_printf((fmt), ## args)
+#undef sprintf
+#define sprintf(buf, fmt, args...)     osl_sprintf((buf), (fmt), ## args)
+#undef strcmp
+#define        strcmp(s1, s2)                  osl_strcmp((s1), (s2))
+#undef strncmp
+#define        strncmp(s1, s2, n)              osl_strncmp((s1), (s2), (n))
+#undef strlen
+#define strlen(s)                      osl_strlen((s))
+#undef strcpy
+#define        strcpy(d, s)                    osl_strcpy((d), (s))
+#undef strncpy
+#define        strncpy(d, s, n)                osl_strncpy((d), (s), (n))
+#endif /* LINUX_OSL */
+extern int osl_printf(const char *format, ...);
+extern int osl_sprintf(char *buf, const char *format, ...);
+extern int osl_strcmp(const char *s1, const char *s2);
+extern int osl_strncmp(const char *s1, const char *s2, uint n);
+extern int osl_strlen(const char *s);
+extern char* osl_strcpy(char *d, const char *s);
+extern char* osl_strncpy(char *d, const char *s, uint n);
+
+/* register access macros */
+#if !defined(BCMJTAG)
+#define R_REG(osh, r) (\
+       sizeof(*(r)) == sizeof(uint8) ? osl_readb((volatile uint8*)(r)) : \
+       sizeof(*(r)) == sizeof(uint16) ? osl_readw((volatile uint16*)(r)) : \
+       osl_readl((volatile uint32*)(r)) \
+)
+#define W_REG(osh, r, v) do { \
+       switch (sizeof(*(r))) { \
+       case sizeof(uint8):     osl_writeb((uint8)(v), (volatile uint8*)(r)); break; \
+       case sizeof(uint16):    osl_writew((uint16)(v), (volatile uint16*)(r)); break; \
+       case sizeof(uint32):    osl_writel((uint32)(v), (volatile uint32*)(r)); break; \
+       } \
+} while (0)
+#endif 
+
+#define        AND_REG(osh, r, v)              W_REG(osh, (r), R_REG(osh, r) & (v))
+#define        OR_REG(osh, r, v)               W_REG(osh, (r), R_REG(osh, r) | (v))
+extern uint8 osl_readb(volatile uint8 *r);
+extern uint16 osl_readw(volatile uint16 *r);
+extern uint32 osl_readl(volatile uint32 *r);
+extern void osl_writeb(uint8 v, volatile uint8 *r);
+extern void osl_writew(uint16 v, volatile uint16 *r);
+extern void osl_writel(uint32 v, volatile uint32 *r);
+
+/* bcopy, bcmp, and bzero */
+extern void bcopy(const void *src, void *dst, int len);
+extern int bcmp(const void *b1, const void *b2, int len);
+extern void bzero(void *b, int len);
+
+/* uncached virtual address */
+#define OSL_UNCACHED(va)       osl_uncached((va))
+extern void *osl_uncached(void *va);
+
+/* get processor cycle count */
+#define OSL_GETCYCLES(x)       ((x) = osl_getcycles())
+extern uint osl_getcycles(void);
+
+/* dereference an address that may target abort */
+#define        BUSPROBE(val, addr)     osl_busprobe(&(val), (addr))
+extern int osl_busprobe(uint32 *val, uint32 addr);
+
+/* map/unmap physical to virtual */
+#define        REG_MAP(pa, size)       osl_reg_map((pa), (size))
+#define        REG_UNMAP(va)           osl_reg_unmap((va))
+extern void *osl_reg_map(uint32 pa, uint size);
+extern void osl_reg_unmap(void *va);
+
+/* shared (dma-able) memory access macros */
+#define        R_SM(r)                 *(r)
+#define        W_SM(r, v)              (*(r) = (v))
+#define        BZERO_SM(r, len)        bzero((r), (len))
+
+/* packet primitives */
+#define        PKTGET(osh, len, send)          osl_pktget((osh), (len))
+#define        PKTFREE(osh, skb, send)         osl_pktfree((osh), (skb), (send))
+#define        PKTDATA(osh, skb)               osl_pktdata((osh), (skb))
+#define        PKTLEN(osh, skb)                osl_pktlen((osh), (skb))
+#define PKTHEADROOM(osh, skb)          osl_pktheadroom((osh), (skb))
+#define PKTTAILROOM(osh, skb)          osl_pkttailroom((osh), (skb))
+#define        PKTNEXT(osh, skb)               osl_pktnext((osh), (skb))
+#define        PKTSETNEXT(osh, skb, x)         osl_pktsetnext((skb), (x))
+#define        PKTSETLEN(osh, skb, len)        osl_pktsetlen((osh), (skb), (len))
+#define        PKTPUSH(osh, skb, bytes)        osl_pktpush((osh), (skb), (bytes))
+#define        PKTPULL(osh, skb, bytes)        osl_pktpull((osh), (skb), (bytes))
+#define        PKTDUP(osh, skb)                osl_pktdup((osh), (skb))
+#define PKTTAG(skb)                    osl_pkttag((skb))
+#define PKTFRMNATIVE(osh, skb)         osl_pkt_frmnative((osh), (struct sk_buff*)(skb))
+#define PKTTONATIVE(osh, pkt)          osl_pkt_tonative((osh), (pkt))
+#define        PKTLINK(skb)                    osl_pktlink((skb))
+#define        PKTSETLINK(skb, x)              osl_pktsetlink((skb), (x))
+#define        PKTPRIO(skb)                    osl_pktprio((skb))
+#define        PKTSETPRIO(skb, x)              osl_pktsetprio((skb), (x))
+#define PKTSHARED(skb)                  osl_pktshared((skb))
+#define PKTALLOCED(osh)                        osl_pktalloced((osh))
+#ifdef BCMDBG_PKT
+#define PKTLIST_DUMP(osh, buf)                 osl_pktlist_dump(osh, buf)
+#else /* BCMDBG_PKT */
+#define PKTLIST_DUMP(osh, buf)
+#endif /* BCMDBG_PKT */
+
+extern void *osl_pktget(osl_t *osh, uint len);
 extern void osl_pktfree(osl_t *osh, void *skb, bool send);
+extern uchar *osl_pktdata(osl_t *osh, void *skb);
+extern uint osl_pktlen(osl_t *osh, void *skb);
+extern uint osl_pktheadroom(osl_t *osh, void *skb);
+extern uint osl_pkttailroom(osl_t *osh, void *skb);
+extern void *osl_pktnext(osl_t *osh, void *skb);
+extern void osl_pktsetnext(void *skb, void *x);
+extern void osl_pktsetlen(osl_t *osh, void *skb, uint len);
+extern uchar *osl_pktpush(osl_t *osh, void *skb, int bytes);
+extern uchar *osl_pktpull(osl_t *osh, void *skb, int bytes);
 extern void *osl_pktdup(osl_t *osh, void *skb);
+extern void *osl_pkttag(void *skb);
+extern void *osl_pktlink(void *skb);
+extern void osl_pktsetlink(void *skb, void *x);
+extern uint osl_pktprio(void *skb);
+extern void osl_pktsetprio(void *skb, uint x);
+extern void *osl_pkt_frmnative(osl_t *osh, struct sk_buff *skb);
+extern struct sk_buff *osl_pkt_tonative(osl_t *osh, void *pkt);
+extern bool osl_pktshared(void *skb);
 extern uint osl_pktalloced(osl_t *osh);
 
+#ifdef BCMDBG_PKT     /* pkt logging for debugging */
+extern char *osl_pktlist_dump(osl_t *osh, char *buf);
+extern void osl_pktlist_add(osl_t *osh, void *p);
+extern void osl_pktlist_remove(osl_t *osh, void *p);
+#endif /* BCMDBG_PKT */
+
+#endif /* BINOSL */
+
 #define OSL_ERROR(bcmerror)    osl_error(bcmerror)
 extern int osl_error(int bcmerror);