blob: b51032b8ff74913d93d98ed50a7d8126b33b5603 [file] [log] [blame]
/*
* FreeBSD OS Independent Layer
*
* Copyright (C) 2015, Broadcom Corporation
* All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation;
* the contents of this file may not be disclosed to third parties, copied
* or duplicated in any form, in whole or in part, without the prior
* written permission of Broadcom Corporation.
*
* $Id: fbsd_osl.h 542557 2015-03-20 05:23:54Z $
*/
#ifndef _bsd_osl_h_
#define _bsd_osl_h_
#include <typedefs.h>
#include <sys/malloc.h>
#include <sys/systm.h>
#include <machine/bus.h>
#include <sys/resource.h>
#include <machine/param.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#if !defined(__FreeBSD__) /* FreeBSD doesn't seem to use this file anymore */
#include <dev/pci/pcidevs.h>
#endif /* !defined ( __FreeBSD__) */
#include <sys/mbuf.h>
#if defined(__FreeBSD__)
#include <sys/kernel.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
#endif
#define OSL_ERR(args)
#define OSL_TRACE(args)
#define OSL_INFO(args)
#define OSL_DBGLOCK(args)
#if defined(__FreeBSD__)
/* Normally... We would expect the following to come from <sys/mbuf.h> but it's not present
* in the FreeBSD version of this header... Try this for now.
*/
#define M_GETCTX(m, t) ((t) (m)->m_pkthdr.rcvif + 0)
#define MCLISREFERENCED(m) ((m)->m_ext.ext_nextref != (m))
#define unlikely(x) (x)
#define likely(x) (x)
#define FREEBSD_PKTTAG (0x0114)
#define FREEBSD_PKTPRIO (0x0115)
#define OSL_PKTPRIO_SZ 4
#endif /* defined (__FreeBSD__) */
#define FBSD_MTX_DEBUG 0
#if FBSD_MTX_DEBUG
#define MTX_INIT(mutex, name, type, opts) ({ \
printf("init mtx from %s:%d\n", __FUNCTION__, __LINE__); \
mtx_init(mutex, name, type, opts); \
})
#define MTX_DESTROY(mutex) ({ \
printf("destroy mtx from %s:%d\n", __FUNCTION__, __LINE__); \
mtx_destroy(mutex); \
})
#define MTX_LOCK(mutex) ({ \
printf("lock mtx from %s:%d\n", __FUNCTION__, __LINE__); \
mtx_lock(mutex); \
})
#define MTX_UNLOCK(mutex) ({ \
printf("unlock mtx from %s:%d\n", __FUNCTION__, __LINE__); \
mtx_unlock(mutex); \
})
#define MTX_ASSERT(mutex, what) ({ \
printf("assert mtx from %s:%d\n", __FUNCTION__, __LINE__); \
mtx_assert(mutex, what); \
})
#else
#define MTX_INIT mtx_init
#define MTX_DESTROY mtx_destroy
#define MTX_LOCK mtx_lock
#define MTX_UNLOCK mtx_unlock
#define MTX_ASSERT mtx_assert
#endif /* FBSD_MTX_DEBUG */
/* The magic cookie */
#define OS_HANDLE_MAGIC 0x1234abcd /* Magic number for osl_t */
/* Assert */
extern void osl_assert(const char *exp, const char *file, int line);
#define ASSERT(exp) do {} while (0)
/* PCI configuration space access macros */
#define OSL_PCI_READ_CONFIG(osh, offset, size) \
osl_pci_read_config((osh), (offset), (size))
#define OSL_PCI_WRITE_CONFIG(osh, offset, size, val) \
osl_pci_write_config((osh), (offset), (size), (val))
extern uint32 osl_pci_read_config(osl_t *osh, uint size, uint offset);
extern void osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val);
/* PCMCIA attribute space access macros, not suppotred */
#define OSL_PCMCIA_READ_ATTR(osh, offset, buf, size) \
({ \
BCM_REFERENCE(osh); \
BCM_REFERENCE(buf); \
ASSERT(0); \
})
#define OSL_PCMCIA_WRITE_ATTR(osh, offset, buf, size) \
({ \
BCM_REFERENCE(osh); \
BCM_REFERENCE(buf); \
ASSERT(0); \
})
/* OSL initialization */
extern osl_t *osl_attach(void *pdev, const char *dev_name, bus_space_tag_t space,
bus_space_handle_t handle, uint8 *vaddr);
extern void osl_detach(osl_t *osh);
extern void osl_pktfree_cb_set(osl_t *osh, pktfree_cb_fn_t tx_fn, void *tx_ctx);
#define PKTFREESETCB(osh, tx_fn, tx_ctx) osl_pktfree_cb_set(osh, tx_fn, tx_ctx)
/* Host/bus architecture-specific byte swap */
#ifndef IL_BIGENDIAN
#define BUS_SWAP32(v) (v)
#else
#define BUS_SWAP32(v) htol32(v)
#endif
#ifndef bsd_osl_c
/* Undefine the generic BSD kernel MALLOC and MFREE macros to avoid clash
*
* Do this only if we are not in bsd_osl.c itself.
*/
#undef MALLOC
#undef MFREE
#define MALLOC(osh, size) osl_malloc((osh), (size))
#define MALLOCZ(osh, size) osl_mallocz((osh), (size))
#define MFREE(osh, addr, size) osl_mfree((osh), (addr), (size))
#define MALLOCED(osh) osl_malloced((osh))
#endif /* bsd_osl_c */
#define MALLOC_FAILED(osh) osl_malloc_failed((osh))
extern void *osl_debug_malloc(osl_t *osh, uint size, int line, const char* file);
extern void osl_debug_mfree(osl_t *osh, void *addr, uint size, int line, const char* file);
struct bcmstrbuf;
extern int osl_debug_memdump(osl_t *osh, struct bcmstrbuf *b);
extern void *osl_malloc(osl_t *osh, uint size);
extern void *osl_mallocz(osl_t *osh, uint size);
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);
/* Allocate/free shared (dma-able) consistent memory */
#define DMA_CONSISTENT_ALIGN PAGE_SIZE
#define DMA_ALLOC_CONSISTENT(osh, size, align, tot, pap, dmah) \
osl_dma_alloc_consistent((osh), (size), (align), (tot), (pap), (dmah))
#define DMA_FREE_CONSISTENT(osh, va, size, pa, dmah) \
osl_dma_free_consistent((osh), (void*)(va), (size), (pa), (dmah))
extern void *osl_dma_alloc_consistent(osl_t *osh, uint size, uint16 align, uint *tot,
ulong *pap, osldma_t **dmah);
/* Map/unmap direction */
#define DMA_TX 1 /* DMA TX flag */
#define DMA_RX 2 /* DMA RX flag */
/* Map/unmap shared (dma-able) memory */
#define DMA_MAP(osh, va, size, direction, p, dmah) \
osl_dma_map((osh), (va), (size), (direction), (dmah))
#define DMA_UNMAP(osh, pa, size, direction, p, dmah) \
osl_dma_unmap((osh), (pa), (size), (direction), (dmah))
extern uint osl_dma_map(osl_t *osh, void *va, uint size, int direction, osldma_t **dmah);
extern void osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction, osldma_t **dmah);
/* API for DMA addressing capability */
#define OSL_DMADDRWIDTH(osh, addrwidth) BCM_REFERENCE(osh)
/* map/unmap physical to virtual, not supported */
#define REG_MAP(pa, size) ((void *)NULL)
#define REG_UNMAP(va) ASSERT(0)
/* FreeBSD needs 2 handles the bus_space_tag at attach time
* and the bus_space_handle
*/
/* Pkttag flag should be part of public information */
struct osl_pubinfo {
bus_space_tag_t space;
bus_space_handle_t handle;
bool pkttag;
bool mmbus; /* Bus supports memory-mapped register accesses */
pktfree_cb_fn_t tx_fn; /* Callback function for PKTFREE */
void *tx_ctx; /* Context to the callback function */
uint8 *vaddr;
};
#define OSL_PUB(osh) ((struct osl_pubinfo *)(osh))
/* IO bus mapping routines */
#define rreg32(osh, r) bus_space_read_4(OSL_PUB(osh)->space, OSL_PUB(osh)->handle, \
(bus_size_t)(((uintptr)(r)) - \
((uintptr)(OSL_PUB(osh)->vaddr))))
#define rreg16(osh, r) bus_space_read_2(OSL_PUB(osh)->space, OSL_PUB(osh)->handle, \
(bus_size_t)(((uintptr)(r)) - \
((uintptr)(OSL_PUB(osh)->vaddr))))
#define rreg8(osh, r) bus_space_read_1(OSL_PUB(osh)->space, OSL_PUB(osh)->handle, \
(bus_size_t)(((uintptr)(r)) - \
((uintptr)(OSL_PUB(osh)->vaddr))))
#define wreg32(osh, r, v) bus_space_write_4(OSL_PUB(osh)->space, OSL_PUB(osh)->handle, \
(bus_size_t)((uintptr)(r) - \
((uintptr)(OSL_PUB(osh)->vaddr))), (uint32)(v))
#define wreg16(osh, r, v) bus_space_write_2(OSL_PUB(osh)->space, OSL_PUB(osh)->handle, \
(bus_size_t)((uintptr)(r) - \
((uintptr)(OSL_PUB(osh)->vaddr))), (uint16)(v))
#define wreg8(osh, r, v) bus_space_write_1(OSL_PUB(osh)->space, OSL_PUB(osh)->handle, \
(bus_size_t)((uintptr)(r) - \
((uintptr)(OSL_PUB(osh)->vaddr))), (uint8)(v))
#define R_REG(osh, r) ((sizeof *(r) == sizeof (uint32))? rreg32((osh), (r)):\
(uint32)((sizeof(*(r)) == sizeof(uint16))? rreg16((osh), (r)):\
rreg8((osh), (r))))
#define W_REG(osh, r, v) do {\
if (sizeof *(r) == sizeof (uint32)) \
wreg32((osh), (r), (v)); \
else if (sizeof *(r) == sizeof (uint16))\
wreg16((osh), (r), (v)); \
else \
wreg8((osh), (r), (v)); \
} while (0)
#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))
/* Shared memory access macros */
#define R_SM(a) *(a)
#define W_SM(a, v) (*(a) = (v))
#define BZERO_SM(a, len) bzero((char*)a, len)
/* Uncached/cached virtual address */
#define OSL_UNCACHED(va) ({BCM_REFERENCE(va); ASSERT(0);})
#define OSL_CACHED(va) ({BCM_REFERENCE(va); ASSERT(0);})
#define OSL_PREF_RANGE_LD(va, sz) ({BCM_REFERENCE(va); BCM_REFERENCE(sz);})
#define OSL_PREF_RANGE_ST(va, sz) ({BCM_REFERENCE(va); BCM_REFERENCE(sz);})
/* Get processor cycle count */
#ifdef __i386__
#define OSL_GETCYCLES(x) __asm__ __volatile__("rdtsc" : "=a" (x) : : "edx")
#endif /* #ifdef __i386__ */
/* dereference an address that may target abort */
#define BUSPROBE(val, addr) osl_busprobe(&(val), (addr))
extern int osl_busprobe(uint32 *val, uint32 addr);
/* Microsecond delay */
#define OSL_DELAY(usec) DELAY((usec))
static INLINE void *
osl_pktlink(void *m)
{
ASSERT(((struct mbuf *)(m))->m_flags & M_PKTHDR);
return ((struct mbuf *)(m))->m_nextpkt;
}
static INLINE void
osl_pktsetlink(void *m, void *x)
{
ASSERT(((struct mbuf *)(m))->m_flags & M_PKTHDR);
((struct mbuf *)(m))->m_nextpkt = (struct mbuf *)(x);
}
static INLINE void *
osl_pkttag(void *m)
{
#ifdef __FreeBSD__
struct m_tag *mtag;
mtag = m_tag_find((struct mbuf *)m, FREEBSD_PKTTAG, (struct m_tag *)NULL);
if (mtag == NULL) {
printf("Did not find FREEBSD_PKTTAG for mbuf %p?\n", m);
return NULL;
}
return ((void*)(mtag + 1));
#else
ASSERT(((struct mbuf *)(m))->m_flags & M_PKTHDR);
return (void *)M_GETCTX((struct mbuf *) m, struct mbuf *);
#endif
}
#define OSH_NULL NULL
#define MBUF_CHAINLEN(osh, m) ({BCM_REFERENCE(osh); m_length(m, NULL);})
#define PKTSUMNEEDED(skb) ({BCM_REFERENCE(skb); 1;})
#define PKTSETSUMGOOD(skb, x) ({ \
if (x) \
((struct mbuf *)(skb))->m_pkthdr.csum_flags |= (CSUM_IP_CHECKED | CSUM_IP_VALID); \
else \
((struct mbuf *)(skb))->m_pkthdr.csum_flags &= ~(CSUM_IP_CHECKED | CSUM_IP_VALID); \
})
/* Packet primitives */
#ifdef BCM_OBJECT_TRACE
#define PKTGET(osh, len, send) osl_pktget((osh), __LINE__, __FUNCTION__, (len), (send))
#define PKTFREE(osh, m, send) osl_pktfree((osh), __LINE__, __FUNCTION__, (m), (send))
#define PKTDUP(osh, m) osl_pktdup((osh), __LINE__, __FUNCTION__, (m))
#else
#define PKTGET(osh, len, send) osl_pktget((osh), (len), (send))
#define PKTFREE(osh, m, send) osl_pktfree((osh), (m), (send))
#define PKTDUP(osh, m) osl_pktdup((osh), (m))
#endif /* BCM_OBJECT_TRACE */
#ifdef __FreeBSD__
#define PKTDATA(osh, m) ({BCM_REFERENCE(osh); mtod((struct mbuf *)(m), char *);})
#else
#define PKTDATA(osh, m) ({BCM_REFERENCE(osh); ((struct mbuf *)(m))->m_data;})
#endif
#define PKTHEADROOM(osh, m) ({BCM_REFERENCE(osh); M_LEADINGSPACE((struct mbuf *)(m));})
#define PKTTAILROOM(osh, m) ({BCM_REFERENCE(osh); M_TRAILINGSPACE((struct mbuf *)(m));})
#define PKTSETNEXT(osh, m, x) osl_pktsetnext((osh), (m), (x))
#define PKTNEXT(osh, m) ({BCM_REFERENCE(osh); (((struct mbuf *)(m))->m_next);})
#ifdef __FreeBSD__
#define PKTPUSH(osh, m, bytes) osl_pktpush((osh), &(m), (bytes))
#define PKTSETLEN(osh, m, len) osl_pktsetlen((osh), (m), (len))
#define PKTPULL(osh, m, bytes) m_adj((struct mbuf*)(m), (bytes))
#define PKTLEN(osh, m) ({BCM_REFERENCE(osh); (((struct mbuf *)(m))->m_pkthdr.len);})
#else
#define PKTPUSH(osh, m, bytes) osl_pktpush((osh), (m), (bytes))
#define PKTSETLEN(osh, m, len) ({BCM_REFERENCE(osh); ((struct mbuf *)((m)))->m_len = (len);})
#define PKTPULL(osh, m, bytes) osl_pktpull((osh), (m), (bytes))
#define PKTLEN(osh, m) ({BCM_REFERENCE(osh); (((struct mbuf *)(m))->m_len);})
#endif
#define PKTTAG(m) osl_pkttag((m))
#define PKTLINK(m) osl_pktlink((m))
#define PKTSETLINK(m, x) osl_pktsetlink((m), (x))
#ifdef __FreeBSD__
#define PKTFRMNATIVE(osh, m) BCM_REFERENCE(osh)
#define PKTTONATIVE(osh, pkt) ({BCM_REFERENCE(osh); pkt;})
#else
#define PKTFRMNATIVE(osh, m) osl_pkt_frmnative((osh), (struct mbuf *)(m))
#define PKTTONATIVE(osh, p) osl_pkt_tonative((osh), (p))
#endif
#define PKTSHARED(p) MCLISREFERENCED((struct mbuf *)(p))
#define PKTALLOCED(osh) ({BCM_REFERENCE(osh); 0;})
#define PKTSETPOOL(osh, m, x, y) BCM_REFERENCE(osh)
#define PKTPOOL(osh, m) ({BCM_REFERENCE(osh); FALSE;})
#define PKTFREELIST(m) PKTLINK(m)
#define PKTSETFREELIST(m, x) PKTSETLINK((m), (x))
#define PKTPTR(m) (m)
#define PKTID(m) ({BCM_REFERENCE(m); 0;})
#define PKTSETID(m, id) ({BCM_REFERENCE(m); BCM_REFERENCE(id);})
#define PKTLIST_DUMP(osh, buf) BCM_REFERENCE(osh)
#define PKTSHRINK(osh, m) ({BCM_REFERENCE(osh); (m);})
#define PKTORPHAN(pkt) (pkt)
static INLINE uint
osl_pktprio(void *mbuf)
{
struct m_tag *mtag;
uint32_t *v;
mtag = m_tag_find((struct mbuf *)mbuf, FREEBSD_PKTPRIO, (struct m_tag *)NULL);
if (mtag == NULL) {
printf("Did not find FREEBSD_PKTPRIO tag to get for mbuf %p?\n", mbuf);
return 0;
}
v = (uint32_t *)(mtag + 1);
return *v;
}
static INLINE void
osl_pktsetprio(void *mbuf, uint x)
{
struct m_tag *mtag;
uint32_t *v;
mtag = m_tag_find((struct mbuf *)mbuf, FREEBSD_PKTPRIO, (struct m_tag *)NULL);
if (mtag == NULL) {
printf("Did not find FREEBSD_PKTPRIO tag to set for mbuf %p?\n", mbuf);
return;
}
v = (uint32_t *)(mtag + 1);
*v = x;
return;
}
#define PKTPRIO(m) osl_pktprio((m))
#define PKTSETPRIO(m, x) osl_pktsetprio((m), (x))
#define bcopy(src, dst, len) memcpy((void *) (dst), (void *) (src), (len))
extern void osl_delay(uint usec);
/* extern uint32_t osl_pktprio(void *p); */
extern void osl_setpktprio(void *p, uint32_t x);
extern void osl_pktsetlen(osl_t *osh, void *m, uint len);
/* OSL packet primitive functions */
extern void *osl_pktget(osl_t *osh,
#ifdef BCM_OBJECT_TRACE
int line, const char *caller,
#endif /* BCM_OBJECT_TRACE */
uint len, bool send);
extern void osl_pktfree(osl_t *osh,
#ifdef BCM_OBJECT_TRACE
int line, const char *caller,
#endif /* BCM_OBJECT_TRACE */
void *m, bool send);
extern void *osl_pktdup(osl_t *osh,
#ifdef BCM_OBJECT_TRACE
int line, const char *caller,
#endif /* BCM_OBJECT_TRACE */
void *m);
extern void *osl_pktpush(osl_t *osh, void **m, int bytes);
extern void *osl_pktpull(osl_t *osh, void *m, int bytes);
extern struct mbuf *osl_pkt_tonative(osl_t *osh, void *p);
extern void *osl_pkt_frmnative(osl_t *osh, struct mbuf *m);
#if !defined(__FreeBSD__) /* Not sure what this is doing here... It's defined as inline \
above? */
extern void osl_pktsetlink(void *m, void *x);
#endif
extern void osl_pktsetnext(osl_t *osh, void *m, void *x);
/* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */
#ifdef __FreeBSD__
#define PKTBUFSZ 2048 /* packet size */
#else
#define PKTBUFSZ MCLBYTES /* packet size */
#endif
/* PCI device bus # and slot # */
#define OSL_PCI_BUS(osh) osl_pci_bus(osh)
#define OSL_PCI_SLOT(osh) osl_pci_slot(osh)
extern uint osl_pci_bus(osl_t *osh);
extern uint osl_pci_slot(osl_t *osh);
#define OSL_PCIE_DOMAIN(osh) ({BCM_REFERENCE(osh); 0;})
#define OSL_PCIE_BUS(osh) ({BCM_REFERENCE(osh); 0;})
/* Translate bcmerrors into FreeBSD errors */
#define OSL_ERROR(bcmerror) osl_error(bcmerror)
extern int osl_error(int bcmerror);
extern uint32 g_assert_type;
/* get system up time in miliseconds */
#define OSL_SYSUPTIME() osl_sysuptime()
extern uint32 osl_sysuptime(void);
#endif /* _bsd_osl_h_ */