diff options
Diffstat (limited to 'package/broadcom-wl/src/driver/linux_osl.h')
-rw-r--r-- | package/broadcom-wl/src/driver/linux_osl.h | 322 |
1 files changed, 267 insertions, 55 deletions
diff --git a/package/broadcom-wl/src/driver/linux_osl.h b/package/broadcom-wl/src/driver/linux_osl.h index d9c5533b85..f65c85966b 100644 --- a/package/broadcom-wl/src/driver/linux_osl.h +++ b/package/broadcom-wl/src/driver/linux_osl.h @@ -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_ @@ -19,17 +19,25 @@ #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); |