1/*
2 * Linux OS Independent Layer
3 *
4 * Copyright (C) 2015, Broadcom Corporation. All Rights Reserved.
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
13 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
15 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
16 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 *
18 * $Id: linux_osl.h 532344 2015-02-05 19:21:37Z $
19 */
20
21#ifndef _linux_osl_h_
22#define _linux_osl_h_
23
24#include <typedefs.h>
25
26/* Linux Kernel: File Operations: start */
27extern void * osl_os_open_image(char * filename);
28extern int osl_os_get_image_block(char * buf, int len, void * image);
29extern void osl_os_close_image(void * image);
30extern int osl_os_image_size(void *image);
31/* Linux Kernel: File Operations: end */
32
33#ifdef BCMDRIVER
34
35/* OSL initialization */
36extern osl_t *osl_attach(void *pdev, uint bustype, bool pkttag);
37extern void osl_detach(osl_t *osh);
38
39/* Global ASSERT type */
40extern uint32 g_assert_type;
41
42/* ASSERT */
43	#ifdef __GNUC__
44		#define GCC_VERSION \
45			(__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
46		#if GCC_VERSION > 30100
47			#define ASSERT(exp)	do {} while (0)
48		#else
49			/* ASSERT could cause segmentation fault on GCC3.1, use empty instead */
50			#define ASSERT(exp)
51		#endif /* GCC_VERSION > 30100 */
52	#endif /* __GNUC__ */
53
54/* microsecond delay */
55#define	OSL_DELAY(usec)		osl_delay(usec)
56extern void osl_delay(uint usec);
57
58#define	OSL_PCMCIA_READ_ATTR(osh, offset, buf, size) \
59	osl_pcmcia_read_attr((osh), (offset), (buf), (size))
60#define	OSL_PCMCIA_WRITE_ATTR(osh, offset, buf, size) \
61	osl_pcmcia_write_attr((osh), (offset), (buf), (size))
62extern void osl_pcmcia_read_attr(osl_t *osh, uint offset, void *buf, int size);
63extern void osl_pcmcia_write_attr(osl_t *osh, uint offset, void *buf, int size);
64
65/* PCI configuration space access macros */
66#define	OSL_PCI_READ_CONFIG(osh, offset, size) \
67	osl_pci_read_config((osh), (offset), (size))
68#define	OSL_PCI_WRITE_CONFIG(osh, offset, size, val) \
69	osl_pci_write_config((osh), (offset), (size), (val))
70extern uint32 osl_pci_read_config(osl_t *osh, uint offset, uint size);
71extern void osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val);
72
73/* PCI device bus # and slot # */
74#define OSL_PCI_BUS(osh)	osl_pci_bus(osh)
75#define OSL_PCI_SLOT(osh)	osl_pci_slot(osh)
76#define OSL_PCIE_DOMAIN(osh)	osl_pcie_domain(osh)
77#define OSL_PCIE_BUS(osh)	osl_pcie_bus(osh)
78extern uint osl_pci_bus(osl_t *osh);
79extern uint osl_pci_slot(osl_t *osh);
80extern uint osl_pcie_domain(osl_t *osh);
81extern uint osl_pcie_bus(osl_t *osh);
82extern struct pci_dev *osl_pci_device(osl_t *osh);
83
84/* Pkttag flag should be part of public information */
85typedef struct {
86	bool pkttag;
87	bool mmbus;		/* Bus supports memory-mapped register accesses */
88	pktfree_cb_fn_t tx_fn;  /* Callback function for PKTFREE */
89	void *tx_ctx;		/* Context to the callback function */
90#ifdef OSLREGOPS
91	osl_rreg_fn_t rreg_fn;	/* Read Register function */
92	osl_wreg_fn_t wreg_fn;	/* Write Register function */
93	void *reg_ctx;		/* Context to the reg callback functions */
94#else
95	void	*unused[3];
96#endif
97} osl_pubinfo_t;
98
99#define PKTFREESETCB(osh, _tx_fn, _tx_ctx)		\
100	do {						\
101	   ((osl_pubinfo_t*)osh)->tx_fn = _tx_fn;	\
102	   ((osl_pubinfo_t*)osh)->tx_ctx = _tx_ctx;	\
103	} while (0)
104
105#ifdef OSLREGOPS
106#define REGOPSSET(osh, rreg, wreg, ctx)			\
107	do {						\
108	   ((osl_pubinfo_t*)osh)->rreg_fn = rreg;	\
109	   ((osl_pubinfo_t*)osh)->wreg_fn = wreg;	\
110	   ((osl_pubinfo_t*)osh)->reg_ctx = ctx;	\
111	} while (0)
112#endif /* OSLREGOPS */
113
114/* host/bus architecture-specific byte swap */
115#define BUS_SWAP32(v)		(v)
116
117	#define MALLOC(osh, size)	osl_malloc((osh), (size))
118	#define MFREE(osh, addr, size)	osl_mfree((osh), (addr), (size))
119	#define MALLOCED(osh)		osl_malloced((osh))
120	extern void *osl_malloc(osl_t *osh, uint size);
121	extern void osl_mfree(osl_t *osh, void *addr, uint size);
122	extern uint osl_malloced(osl_t *osh);
123
124#define NATIVE_MALLOC(osh, size)		kmalloc(size, GFP_ATOMIC)
125#define NATIVE_MFREE(osh, addr, size)	kfree(addr)
126#ifdef USBAP
127#include <linux/vmalloc.h>
128#define VMALLOC(osh, size)	vmalloc(size)
129#define VFREE(osh, addr, size)	vfree(addr)
130#endif /* USBAP */
131
132#define	MALLOC_FAILED(osh)	osl_malloc_failed((osh))
133extern uint osl_malloc_failed(osl_t *osh);
134
135/* allocate/free shared (dma-able) consistent memory */
136#define	DMA_CONSISTENT_ALIGN	osl_dma_consistent_align()
137#define	DMA_ALLOC_CONSISTENT(osh, size, align, tot, pap, dmah) \
138	osl_dma_alloc_consistent((osh), (size), (align), (tot), (pap))
139#define	DMA_FREE_CONSISTENT(osh, va, size, pa, dmah) \
140	osl_dma_free_consistent((osh), (void*)(va), (size), (pa))
141
142#define	DMA_ALLOC_CONSISTENT_FORCE32(osh, size, align, tot, pap, dmah) \
143	osl_dma_alloc_consistent((osh), (size), (align), (tot), (pap))
144#define	DMA_FREE_CONSISTENT_FORCE32(osh, va, size, pa, dmah) \
145	osl_dma_free_consistent((osh), (void*)(va), (size), (pa))
146
147extern uint osl_dma_consistent_align(void);
148extern void *osl_dma_alloc_consistent(osl_t *osh, uint size, uint16 align, uint *tot, ulong *pap);
149extern void osl_sec_cma_baseaddr_memsize(osl_t *osh, dma_addr_t *cma_baseaddr, uint32 *cma_memsize);
150extern void osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa);
151
152/* map/unmap direction */
153#define	DMA_TX	1	/* TX direction for DMA */
154#define	DMA_RX	2	/* RX direction for DMA */
155
156/* map/unmap shared (dma-able) memory */
157#define	DMA_UNMAP(osh, pa, size, direction, p, dmah) \
158	osl_dma_unmap((osh), (pa), (size), (direction))
159#define	SECURE_DMA_UNMAP(osh, pa, size, direction, p, dmah, pcma, offset) \
160	osl_sec_dma_unmap((osh), (pa), (size), (direction), (p), (dmah), (pcma), (offset))
161
162#define PHYS_TO_PAGE(pa) pfn_to_page(PFN_DOWN((u32)pa))
163
164extern uint osl_dma_map(osl_t *osh, void *va, uint size, int direction, void *p,
165	hnddma_seg_map_t *txp_dmah);
166extern void osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction);
167
168/* API for DMA addressing capability */
169#define OSL_DMADDRWIDTH(osh, addrwidth) do {} while (0)
170
171/* register access macros */
172#if defined(BCMJTAG)
173	#include <bcmjtag.h>
174	#define OSL_WRITE_REG(osh, r, v) (bcmjtag_write(NULL, (uintptr)(r), (v), sizeof(*(r))))
175	#define OSL_READ_REG(osh, r) (bcmjtag_read(NULL, (uintptr)(r), sizeof(*(r))))
176#endif
177
178#if defined(BCMJTAG)
179	#define SELECT_BUS_WRITE(osh, mmap_op, bus_op) if (((osl_pubinfo_t*)(osh))->mmbus) \
180		mmap_op else bus_op
181	#define SELECT_BUS_READ(osh, mmap_op, bus_op) (((osl_pubinfo_t*)(osh))->mmbus) ? \
182		mmap_op : bus_op
183#else
184	#define SELECT_BUS_WRITE(osh, mmap_op, bus_op) mmap_op
185	#define SELECT_BUS_READ(osh, mmap_op, bus_op) mmap_op
186#endif
187
188#define OSL_ERROR(bcmerror)	osl_error(bcmerror)
189extern int osl_error(int bcmerror);
190
191/* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */
192#define	PKTBUFSZ	2048   /* largest reasonable packet buffer, driver uses for ethernet MTU */
193
194/*
195 * BINOSL selects the slightly slower function-call-based binary compatible osl.
196 * Macros expand to calls to functions defined in linux_osl.c .
197 */
198#ifndef BINOSL
199#include <linuxver.h>           /* use current 2.4.x calling conventions */
200#include <linux/kernel.h>       /* for vsn/printf's */
201#include <linux/string.h>       /* for mem*, str* */
202
203#define OSL_SYSUPTIME()		((uint32)jiffies * (1000 / HZ))
204#define	printf(fmt, args...)	printk(fmt , ## args)
205#include <linux/kernel.h>	/* for vsn/printf's */
206#include <linux/string.h>	/* for mem*, str* */
207/* bcopy's: Linux kernel doesn't provide these (anymore) */
208#define	bcopy(src, dst, len)	memcpy((dst), (src), (len))
209#define	bcmp(b1, b2, len)	memcmp((b1), (b2), (len))
210#define	bzero(b, len)		memset((b), '\0', (len))
211
212/* register access macros */
213#if defined(OSLREGOPS)
214#define R_REG(osh, r) (\
215	sizeof(*(r)) == sizeof(uint8) ? osl_readb((osh), (volatile uint8*)(r)) : \
216	sizeof(*(r)) == sizeof(uint16) ? osl_readw((osh), (volatile uint16*)(r)) : \
217	osl_readl((osh), (volatile uint32*)(r)) \
218)
219#define W_REG(osh, r, v) do { \
220	switch (sizeof(*(r))) { \
221	case sizeof(uint8):	osl_writeb((osh), (volatile uint8*)(r), (uint8)(v)); break; \
222	case sizeof(uint16):	osl_writew((osh), (volatile uint16*)(r), (uint16)(v)); break; \
223	case sizeof(uint32):	osl_writel((osh), (volatile uint32*)(r), (uint32)(v)); break; \
224	} \
225} while (0)
226
227extern uint8 osl_readb(osl_t *osh, volatile uint8 *r);
228extern uint16 osl_readw(osl_t *osh, volatile uint16 *r);
229extern uint32 osl_readl(osl_t *osh, volatile uint32 *r);
230extern void osl_writeb(osl_t *osh, volatile uint8 *r, uint8 v);
231extern void osl_writew(osl_t *osh, volatile uint16 *r, uint16 v);
232extern void osl_writel(osl_t *osh, volatile uint32 *r, uint32 v);
233
234#else /* OSLREGOPS */
235
236#ifndef IL_BIGENDIAN
237#ifndef __mips__
238#define R_REG(osh, r) (\
239	SELECT_BUS_READ(osh, \
240		({ \
241			__typeof(*(r)) __osl_v; \
242			BCM_REFERENCE(osh);	\
243			switch (sizeof(*(r))) { \
244				case sizeof(uint8):	__osl_v = \
245					readb((volatile uint8*)(r)); break; \
246				case sizeof(uint16):	__osl_v = \
247					readw((volatile uint16*)(r)); break; \
248				case sizeof(uint32):	__osl_v = \
249					readl((volatile uint32*)(r)); break; \
250			} \
251			__osl_v; \
252		}), \
253		OSL_READ_REG(osh, r)) \
254)
255#else /* __mips__ */
256#define R_REG(osh, r) (\
257	SELECT_BUS_READ(osh, \
258		({ \
259			__typeof(*(r)) __osl_v; \
260			BCM_REFERENCE(osh);	\
261			__asm__ __volatile__("sync"); \
262			switch (sizeof(*(r))) { \
263				case sizeof(uint8):	__osl_v = \
264					readb((volatile uint8*)(r)); break; \
265				case sizeof(uint16):	__osl_v = \
266					readw((volatile uint16*)(r)); break; \
267				case sizeof(uint32):	__osl_v = \
268					readl((volatile uint32*)(r)); break; \
269			} \
270			__asm__ __volatile__("sync"); \
271			__osl_v; \
272		}), \
273		({ \
274			__typeof(*(r)) __osl_v; \
275			__asm__ __volatile__("sync"); \
276			__osl_v = OSL_READ_REG(osh, r); \
277			__asm__ __volatile__("sync"); \
278			__osl_v; \
279		})) \
280)
281#endif /* __mips__ */
282
283#define W_REG(osh, r, v) do { \
284	BCM_REFERENCE(osh);   \
285	SELECT_BUS_WRITE(osh, \
286		switch (sizeof(*(r))) { \
287			case sizeof(uint8):	writeb((uint8)(v), (volatile uint8*)(r)); break; \
288			case sizeof(uint16):	writew((uint16)(v), (volatile uint16*)(r)); break; \
289			case sizeof(uint32):	writel((uint32)(v), (volatile uint32*)(r)); break; \
290		}, \
291		(OSL_WRITE_REG(osh, r, v))); \
292	} while (0)
293#else	/* IL_BIGENDIAN */
294#define R_REG(osh, r) (\
295	SELECT_BUS_READ(osh, \
296		({ \
297			__typeof(*(r)) __osl_v; \
298			BCM_REFERENCE(osh);	\
299			switch (sizeof(*(r))) { \
300				case sizeof(uint8):	__osl_v = \
301					readb((volatile uint8*)((uintptr)(r)^3)); break; \
302				case sizeof(uint16):	__osl_v = \
303					readw((volatile uint16*)((uintptr)(r)^2)); break; \
304				case sizeof(uint32):	__osl_v = \
305					readl((volatile uint32*)(r)); break; \
306			} \
307			__osl_v; \
308		}), \
309		OSL_READ_REG(osh, r)) \
310)
311#define W_REG(osh, r, v) do { \
312	BCM_REFERENCE(osh);   \
313	SELECT_BUS_WRITE(osh, \
314		switch (sizeof(*(r))) { \
315			case sizeof(uint8):	writeb((uint8)(v), \
316					(volatile uint8*)((uintptr)(r)^3)); break; \
317			case sizeof(uint16):	writew((uint16)(v), \
318					(volatile uint16*)((uintptr)(r)^2)); break; \
319			case sizeof(uint32):	writel((uint32)(v), \
320					(volatile uint32*)(r)); break; \
321		}, \
322		(OSL_WRITE_REG(osh, r, v))); \
323	} while (0)
324#endif /* IL_BIGENDIAN */
325
326#endif /* OSLREGOPS */
327
328#define	AND_REG(osh, r, v)		W_REG(osh, (r), R_REG(osh, r) & (v))
329#define	OR_REG(osh, r, v)		W_REG(osh, (r), R_REG(osh, r) | (v))
330
331/* bcopy, bcmp, and bzero functions */
332#define	bcopy(src, dst, len)	memcpy((dst), (src), (len))
333#define	bcmp(b1, b2, len)	memcmp((b1), (b2), (len))
334#define	bzero(b, len)		memset((b), '\0', (len))
335
336/* uncached/cached virtual address */
337#ifdef __mips__
338#include <asm/addrspace.h>
339#define OSL_UNCACHED(va)	((void *)KSEG1ADDR((va)))
340#define OSL_CACHED(va)		((void *)KSEG0ADDR((va)))
341#else
342#define OSL_UNCACHED(va)	((void *)va)
343#define OSL_CACHED(va)		((void *)va)
344
345/* ARM NorthStar */
346#define OSL_CACHE_FLUSH(va, len)
347
348#endif /* mips */
349
350#ifdef __mips__
351#define OSL_PREF_RANGE_LD(va, sz) prefetch_range_PREF_LOAD_RETAINED(va, sz)
352#define OSL_PREF_RANGE_ST(va, sz) prefetch_range_PREF_STORE_RETAINED(va, sz)
353#else /* __mips__ */
354#define OSL_PREF_RANGE_LD(va, sz)
355#define OSL_PREF_RANGE_ST(va, sz)
356#endif /* __mips__ */
357
358/* get processor cycle count */
359#if defined(mips)
360#define	OSL_GETCYCLES(x)	((x) = read_c0_count() * 2)
361#elif defined(__i386__)
362#define	OSL_GETCYCLES(x)	rdtscl((x))
363#else
364#define OSL_GETCYCLES(x)	((x) = 0)
365#endif /* defined(mips) */
366
367/* dereference an address that may cause a bus exception */
368#ifdef mips
369#if defined(MODULE) && (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 17))
370#define BUSPROBE(val, addr)	panic("get_dbe() will not fixup a bus exception when compiled into"\
371					" a module")
372#else
373#define	BUSPROBE(val, addr)	get_dbe((val), (addr))
374#include <asm/paccess.h>
375#endif /* defined(MODULE) && (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 17)) */
376#else
377#define	BUSPROBE(val, addr)	({ (val) = R_REG(NULL, (addr)); 0; })
378#endif /* mips */
379
380/* map/unmap physical to virtual I/O */
381#if !defined(CONFIG_MMC_MSM7X00A)
382#define	REG_MAP(pa, size)	ioremap_nocache((unsigned long)(pa), (unsigned long)(size))
383#else
384#define REG_MAP(pa, size)       (void *)(0)
385#endif /* !defined(CONFIG_MMC_MSM7X00A */
386#define	REG_UNMAP(va)		iounmap((va))
387
388/* shared (dma-able) memory access macros */
389#define	R_SM(r)			*(r)
390#define	W_SM(r, v)		(*(r) = (v))
391#define	BZERO_SM(r, len)	memset((r), '\0', (len))
392
393/* Because the non BINOSL implemenation of the PKT OSL routines are macros (for
394 * performance reasons),  we need the Linux headers.
395 */
396#include <linuxver.h>		/* use current 2.4.x calling conventions */
397
398/* packet primitives */
399#ifdef BCMDBG_CTRACE
400#define	PKTGET(osh, len, send)		osl_pktget((osh), (len), __LINE__, __FILE__)
401#define	PKTDUP(osh, skb)		osl_pktdup((osh), (skb), __LINE__, __FILE__)
402#else
403#define	PKTGET(osh, len, send)		osl_pktget((osh), (len))
404#define	PKTDUP(osh, skb)		osl_pktdup((osh), (skb))
405#endif /* BCMDBG_CTRACE */
406#define PKTLIST_DUMP(osh, buf)
407#define PKTDBG_TRACE(osh, pkt, bit)
408#define	PKTFREE(osh, skb, send)		osl_pktfree((osh), (skb), (send))
409#ifdef DHD_USE_STATIC_BUF
410#define	PKTGET_STATIC(osh, len, send)		osl_pktget_static((osh), (len))
411#define	PKTFREE_STATIC(osh, skb, send)		osl_pktfree_static((osh), (skb), (send))
412#endif /* DHD_USE_STATIC_BUF */
413#define	PKTDATA(osh, skb)		(((struct sk_buff*)(skb))->data)
414#define	PKTLEN(osh, skb)		(((struct sk_buff*)(skb))->len)
415#define PKTHEADROOM(osh, skb)		(PKTDATA(osh, skb)-(((struct sk_buff*)(skb))->head))
416#define PKTEXPHEADROOM(osh, skb, b)	skb_realloc_headroom((struct sk_buff*)(skb), (b))
417#define PKTTAILROOM(osh, skb)		skb_tailroom((struct sk_buff*)(skb))
418#define	PKTNEXT(osh, skb)		(((struct sk_buff*)(skb))->next)
419#define	PKTSETNEXT(osh, skb, x)		(((struct sk_buff*)(skb))->next = (struct sk_buff*)(x))
420#define	PKTSETLEN(osh, skb, len)	__skb_trim((struct sk_buff*)(skb), (len))
421#define	PKTPUSH(osh, skb, bytes)	skb_push((struct sk_buff*)(skb), (bytes))
422#define	PKTPULL(osh, skb, bytes)	skb_pull((struct sk_buff*)(skb), (bytes))
423#define	PKTTAG(skb)			((void*)(((struct sk_buff*)(skb))->cb))
424#define PKTSETPOOL(osh, skb, x, y)	do {} while (0)
425#define PKTPOOL(osh, skb)		FALSE
426#define PKTSHRINK(osh, m)		(m)
427
428#ifdef BCMDBG_CTRACE
429#define	DEL_CTRACE(zosh, zskb) { \
430	unsigned long zflags; \
431	spin_lock_irqsave(&(zosh)->ctrace_lock, zflags); \
432	list_del(&(zskb)->ctrace_list); \
433	(zosh)->ctrace_num--; \
434	(zskb)->ctrace_start = 0; \
435	(zskb)->ctrace_count = 0; \
436	spin_unlock_irqrestore(&(zosh)->ctrace_lock, zflags); \
437}
438
439#define	UPDATE_CTRACE(zskb, zfile, zline) { \
440	struct sk_buff *_zskb = (struct sk_buff *)(zskb); \
441	if (_zskb->ctrace_count < CTRACE_NUM) { \
442		_zskb->func[_zskb->ctrace_count] = zfile; \
443		_zskb->line[_zskb->ctrace_count] = zline; \
444		_zskb->ctrace_count++; \
445	} \
446	else { \
447		_zskb->func[_zskb->ctrace_start] = zfile; \
448		_zskb->line[_zskb->ctrace_start] = zline; \
449		_zskb->ctrace_start++; \
450		if (_zskb->ctrace_start >= CTRACE_NUM) \
451			_zskb->ctrace_start = 0; \
452	} \
453}
454
455#define	ADD_CTRACE(zosh, zskb, zfile, zline) { \
456	unsigned long zflags; \
457	spin_lock_irqsave(&(zosh)->ctrace_lock, zflags); \
458	list_add(&(zskb)->ctrace_list, &(zosh)->ctrace_list); \
459	(zosh)->ctrace_num++; \
460	UPDATE_CTRACE(zskb, zfile, zline); \
461	spin_unlock_irqrestore(&(zosh)->ctrace_lock, zflags); \
462}
463
464#define PKTCALLER(zskb)	UPDATE_CTRACE((struct sk_buff *)zskb, (char *)__FUNCTION__, __LINE__)
465#endif /* BCMDBG_CTRACE */
466
467#ifdef CTFPOOL
468#define	CTFPOOL_REFILL_THRESH	3
469typedef struct ctfpool {
470	void		*head;
471#if defined(CTF_PPTP) || defined(CTF_L2TP)
472	void            *tail;
473#endif
474	spinlock_t	lock;
475	uint		max_obj;
476	uint		curr_obj;
477	uint		obj_size;
478	uint		refills;
479	uint		fast_allocs;
480	uint 		fast_frees;
481	uint 		slow_allocs;
482} ctfpool_t;
483#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22)
484
485#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
486#define	FASTBUF	(1 << 0)
487#define	CTFBUF	(1 << 1)
488#define	PKTSETFAST(osh, skb)	((((struct sk_buff*)(skb))->pktc_flags) |= FASTBUF)
489#define	PKTCLRFAST(osh, skb)	((((struct sk_buff*)(skb))->pktc_flags) &= (~FASTBUF))
490#define	PKTSETCTF(osh, skb)	((((struct sk_buff*)(skb))->pktc_flags) |= CTFBUF)
491#define	PKTCLRCTF(osh, skb)	((((struct sk_buff*)(skb))->pktc_flags) &= (~CTFBUF))
492#define	PKTISFAST(osh, skb)	((((struct sk_buff*)(skb))->pktc_flags) & FASTBUF)
493#define	PKTISCTF(osh, skb)	((((struct sk_buff*)(skb))->pktc_flags) & CTFBUF)
494#define	PKTFAST(osh, skb)	(((struct sk_buff*)(skb))->pktc_flags)
495#else
496#define	FASTBUF	(1 << 16)
497#define	CTFBUF	(1 << 17)
498#define	PKTSETFAST(osh, skb)	((((struct sk_buff*)(skb))->mac_len) |= FASTBUF)
499#define	PKTCLRFAST(osh, skb)	((((struct sk_buff*)(skb))->mac_len) &= (~FASTBUF))
500#define	PKTSETCTF(osh, skb)	((((struct sk_buff*)(skb))->mac_len) |= CTFBUF)
501#define	PKTCLRCTF(osh, skb)	((((struct sk_buff*)(skb))->mac_len) &= (~CTFBUF))
502#define	PKTISFAST(osh, skb)	((((struct sk_buff*)(skb))->mac_len) & FASTBUF)
503#define	PKTISCTF(osh, skb)	((((struct sk_buff*)(skb))->mac_len) & CTFBUF)
504#define	PKTFAST(osh, skb)	(((struct sk_buff*)(skb))->mac_len)
505#endif /* 2.6.36 */
506#else
507#define	FASTBUF	(1 << 0)
508#define	CTFBUF	(1 << 1)
509#define	PKTSETFAST(osh, skb)	((((struct sk_buff*)(skb))->__unused) |= FASTBUF)
510#define	PKTCLRFAST(osh, skb)	((((struct sk_buff*)(skb))->__unused) &= (~FASTBUF))
511#define	PKTSETCTF(osh, skb)	((((struct sk_buff*)(skb))->__unused) |= CTFBUF)
512#define	PKTCLRCTF(osh, skb)	((((struct sk_buff*)(skb))->__unused) &= (~CTFBUF))
513#define	PKTISFAST(osh, skb)	((((struct sk_buff*)(skb))->__unused) & FASTBUF)
514#define	PKTISCTF(osh, skb)	((((struct sk_buff*)(skb))->__unused) & CTFBUF)
515#define	PKTFAST(osh, skb)	(((struct sk_buff*)(skb))->__unused)
516#endif /* 2.6.22 */
517
518#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
519#define	CTFPOOLPTR(osh, skb)	(((struct sk_buff*)(skb))->ctfpool)
520#define	CTFPOOLHEAD(osh, skb)	(((ctfpool_t *)((struct sk_buff*)(skb))->ctfpool)->head)
521#else
522#define	CTFPOOLPTR(osh, skb)	(((struct sk_buff*)(skb))->sk)
523#define	CTFPOOLHEAD(osh, skb)	(((ctfpool_t *)((struct sk_buff*)(skb))->sk)->head)
524#endif
525
526extern void *osl_ctfpool_add(osl_t *osh);
527extern void osl_ctfpool_replenish(osl_t *osh, uint thresh);
528extern int32 osl_ctfpool_init(osl_t *osh, uint numobj, uint size);
529extern void osl_ctfpool_cleanup(osl_t *osh);
530extern void osl_ctfpool_stats(osl_t *osh, void *b);
531
532#if defined(CTF_PPTP) || defined(CTF_L2TP)
533extern void osl_ctfpool_direction(int tail);
534#endif
535#endif /* CTFPOOL */
536
537#ifdef CTFMAP
538
539#if defined(__mips__)
540#define CACHE_LINE_SIZE		32
541#elif defined(__ARM_ARCH_7A__)
542#define CACHE_LINE_SIZE		32
543#else
544#error "CACHE_LINE_SIZE define needed!"
545#endif
546
547#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14)
548#define CTFMAPPTR(osh, skb)	(((struct sk_buff*)(skb))->sp)
549#else /* 2.6.14 */
550#define CTFMAPPTR(osh, skb)	(((struct sk_buff*)(skb))->list)
551#endif /* 2.6.14 */
552
553#define PKTCTFMAP(osh, p) \
554do { \
555	if (PKTISCTF(osh, p)) { \
556		int32 sz; \
557		sz = (uint32)(((struct sk_buff *)p)->end) - \
558		     (uint32)CTFMAPPTR(osh, p); \
559		/* map the remaining unmapped area */ \
560		if (sz > 0) { \
561			sz = (sz + CACHE_LINE_SIZE - 1) & ~(CACHE_LINE_SIZE - 1); \
562			_DMA_MAP(osh, (void *)CTFMAPPTR(osh, p), \
563			         sz, DMA_RX, p, NULL); \
564		} \
565		/* clear ctf buf flag */ \
566		PKTCLRCTF(osh, p); \
567		CTFMAPPTR(osh, p) = NULL; \
568	} \
569} while (0)
570#endif /* CTFMAP */
571
572#ifdef HNDCTF
573#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22)
574
575#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
576#define	SKIPCT	(1 << 2)
577#define	CHAINED	(1 << 3)
578#define	TOBR	(1 << 5)	/* Sync with other branch */
579#define	PKTSETSKIPCT(osh, skb)	(((struct sk_buff*)(skb))->pktc_flags |= SKIPCT)
580#define	PKTCLRSKIPCT(osh, skb)	(((struct sk_buff*)(skb))->pktc_flags &= (~SKIPCT))
581#define	PKTSKIPCT(osh, skb)	(((struct sk_buff*)(skb))->pktc_flags & SKIPCT)
582#define	PKTSETCHAINED(osh, skb)	(((struct sk_buff*)(skb))->pktc_flags |= CHAINED)
583#define	PKTCLRCHAINED(osh, skb)	(((struct sk_buff*)(skb))->pktc_flags &= (~CHAINED))
584#define	PKTISCHAINED(skb)	(((struct sk_buff*)(skb))->pktc_flags & CHAINED)
585#define	PKTSETTOBR(osh, skb)	(((struct sk_buff*)(skb))->pktc_flags |= TOBR)
586#define	PKTCLRTOBR(osh, skb)	(((struct sk_buff*)(skb))->pktc_flags &= (~TOBR))
587#define	PKTISTOBR(skb)		(((struct sk_buff*)(skb))->pktc_flags & TOBR)
588#define	PKTSETCTFIPCTXIF(skb, ifp)	(((struct sk_buff*)(skb))->ctf_ipc_txif = ifp)
589#else
590#define	SKIPCT	(1 << 18)
591#define	CHAINED	(1 << 19)
592#define	PKTSETSKIPCT(osh, skb)	(((struct sk_buff*)(skb))->mac_len |= SKIPCT)
593#define	PKTCLRSKIPCT(osh, skb)	(((struct sk_buff*)(skb))->mac_len &= (~SKIPCT))
594#define	PKTSKIPCT(osh, skb)	(((struct sk_buff*)(skb))->mac_len & SKIPCT)
595#define	PKTSETCHAINED(osh, skb)	(((struct sk_buff*)(skb))->mac_len |= CHAINED)
596#define	PKTCLRCHAINED(osh, skb)	(((struct sk_buff*)(skb))->mac_len &= (~CHAINED))
597#define	PKTISCHAINED(skb)	(((struct sk_buff*)(skb))->mac_len & CHAINED)
598#define	PKTSETCTFIPCTXIF(skb, ifp)
599#define	PKTSETTOBR(osh, skb)
600#define	PKTCLRTOBR(osh, skb)
601#define	PKTISTOBR(skb)	FALSE
602#endif /* 2.6.36 */
603#else /* 2.6.22 */
604#define	SKIPCT	(1 << 2)
605#define	CHAINED	(1 << 3)
606#define	PKTSETSKIPCT(osh, skb)	(((struct sk_buff*)(skb))->__unused |= SKIPCT)
607#define	PKTCLRSKIPCT(osh, skb)	(((struct sk_buff*)(skb))->__unused &= (~SKIPCT))
608#define	PKTSKIPCT(osh, skb)	(((struct sk_buff*)(skb))->__unused & SKIPCT)
609#define	PKTSETCHAINED(osh, skb)	(((struct sk_buff*)(skb))->__unused |= CHAINED)
610#define	PKTCLRCHAINED(osh, skb)	(((struct sk_buff*)(skb))->__unused &= (~CHAINED))
611#define	PKTISCHAINED(skb)	(((struct sk_buff*)(skb))->__unused & CHAINED)
612#define	PKTSETCTFIPCTXIF(skb, ifp)
613#define	PKTSETTOBR(osh, skb)
614#define	PKTCLRTOBR(osh, skb)
615#define	PKTISTOBR(skb)	FALSE
616#endif /* 2.6.22 */
617typedef struct ctf_mark {
618	uint32	value;
619}	ctf_mark_t;
620#define CTF_MARK(m)				(m.value)
621#else /* HNDCTF */
622#define	PKTSETSKIPCT(osh, skb)
623#define	PKTCLRSKIPCT(osh, skb)
624#define	PKTSKIPCT(osh, skb)
625#define CTF_MARK(m)				0
626#endif /* HNDCTF */
627
628#ifdef BCMFA
629#ifdef BCMFA_HW_HASH
630#define PKTSETFAHIDX(skb, idx)	(((struct sk_buff*)(skb))->napt_idx = idx)
631#else
632#define PKTSETFAHIDX(skb, idx)
633#endif /* BCMFA_SW_HASH */
634#define PKTGETFAHIDX(skb)	(((struct sk_buff*)(skb))->napt_idx)
635#define PKTSETFADEV(skb, imp)	(((struct sk_buff*)(skb))->dev = imp)
636#define PKTSETRXDEV(skb)	(((struct sk_buff*)(skb))->rxdev = ((struct sk_buff*)(skb))->dev)
637
638#define	AUX_TCP_FIN_RST	(1 << 0)
639#define	AUX_FREED	(1 << 1)
640#define PKTSETFAAUX(skb)	(((struct sk_buff*)(skb))->napt_flags |= AUX_TCP_FIN_RST)
641#define	PKTCLRFAAUX(skb)	(((struct sk_buff*)(skb))->napt_flags &= (~AUX_TCP_FIN_RST))
642#define	PKTISFAAUX(skb)		(((struct sk_buff*)(skb))->napt_flags & AUX_TCP_FIN_RST)
643#define PKTSETFAFREED(skb)	(((struct sk_buff*)(skb))->napt_flags |= AUX_FREED)
644#define	PKTCLRFAFREED(skb)	(((struct sk_buff*)(skb))->napt_flags &= (~AUX_FREED))
645#define	PKTISFAFREED(skb)	(((struct sk_buff*)(skb))->napt_flags & AUX_FREED)
646#define	PKTISFABRIDGED(skb)	PKTISFAAUX(skb)
647#else
648#define	PKTISFAAUX(skb)		(FALSE)
649#define	PKTISFABRIDGED(skb)	(FALSE)
650#define	PKTISFAFREED(skb)	(FALSE)
651
652#define	PKTCLRFAAUX(skb)
653#define PKTSETFAFREED(skb)
654#define	PKTCLRFAFREED(skb)
655#endif /* BCMFA */
656
657extern void osl_pktfree(osl_t *osh, void *skb, bool send);
658extern void *osl_pktget_static(osl_t *osh, uint len);
659extern void osl_pktfree_static(osl_t *osh, void *skb, bool send);
660
661#ifdef BCMDBG_CTRACE
662#define PKT_CTRACE_DUMP(osh, b)	osl_ctrace_dump((osh), (b))
663extern void *osl_pktget(osl_t *osh, uint len, int line, char *file);
664extern void *osl_pkt_frmnative(osl_t *osh, void *skb, int line, char *file);
665extern int osl_pkt_is_frmnative(osl_t *osh, struct sk_buff *pkt);
666extern void *osl_pktdup(osl_t *osh, void *skb, int line, char *file);
667struct bcmstrbuf;
668extern void osl_ctrace_dump(osl_t *osh, struct bcmstrbuf *b);
669#else
670extern void *osl_pkt_frmnative(osl_t *osh, void *skb);
671extern void *osl_pktget(osl_t *osh, uint len);
672extern void *osl_pktdup(osl_t *osh, void *skb);
673#endif /* BCMDBG_CTRACE */
674extern struct sk_buff *osl_pkt_tonative(osl_t *osh, void *pkt);
675#ifdef BCMDBG_CTRACE
676#define PKTFRMNATIVE(osh, skb)  osl_pkt_frmnative(((osl_t *)osh), \
677				(struct sk_buff*)(skb), __LINE__, __FILE__)
678#define	PKTISFRMNATIVE(osh, skb) osl_pkt_is_frmnative((osl_t *)(osh), (struct sk_buff *)(skb))
679#else
680#define PKTFRMNATIVE(osh, skb)	osl_pkt_frmnative(((osl_t *)osh), (struct sk_buff*)(skb))
681#endif /* BCMDBG_CTRACE */
682#define PKTTONATIVE(osh, pkt)		osl_pkt_tonative((osl_t *)(osh), (pkt))
683
684#define	PKTLINK(skb)			(((struct sk_buff*)(skb))->prev)
685#define	PKTSETLINK(skb, x)		(((struct sk_buff*)(skb))->prev = (struct sk_buff*)(x))
686#define	PKTPRIO(skb)			(((struct sk_buff*)(skb))->priority)
687#define	PKTSETPRIO(skb, x)		(((struct sk_buff*)(skb))->priority = (x))
688#define PKTSUMNEEDED(skb)		(((struct sk_buff*)(skb))->ip_summed == CHECKSUM_HW)
689#define PKTSETSUMGOOD(skb, x)		(((struct sk_buff*)(skb))->ip_summed = \
690						((x) ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE))
691/* PKTSETSUMNEEDED and PKTSUMGOOD are not possible because skb->ip_summed is overloaded */
692#define PKTSHARED(skb)                  (((struct sk_buff*)(skb))->cloned)
693
694#if defined(CTF_PPTP) || defined(CTF_L2TP)
695#define DEVMTU(dev)                  (((struct net_device*)(dev))->mtu)
696#define DEVIFINDEX(dev)                  (((struct net_device*)(dev))->ifindex)
697#endif
698
699#ifdef CONFIG_NF_CONNTRACK_MARK
700#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
701#define PKTMARK(p)                     (((struct sk_buff *)(p))->mark)
702#define PKTSETMARK(p, m)               ((struct sk_buff *)(p))->mark = (m)
703#else /* !2.6.0 */
704#define PKTMARK(p)                     (((struct sk_buff *)(p))->nfmark)
705#define PKTSETMARK(p, m)               ((struct sk_buff *)(p))->nfmark = (m)
706#endif /* 2.6.0 */
707#else /* CONFIG_NF_CONNTRACK_MARK */
708#define PKTMARK(p)                     0
709#define PKTSETMARK(p, m)
710#endif /* CONFIG_NF_CONNTRACK_MARK */
711
712#else	/* BINOSL */
713
714/* Where to get the declarations for mem, str, printf, bcopy's? Two basic approaches.
715 *
716 * First, use the Linux header files and the C standard library replacmenent versions
717 * built-in to the kernel.  Use this approach when compiling non hybrid code or compling
718 * the OS port files.  The second approach is to use our own defines/prototypes and
719 * functions we have provided in the Linux OSL, i.e. linux_osl.c.  Use this approach when
720 * compiling the files that make up the hybrid binary.  We are ensuring we
721 * don't directly link to the kernel replacement routines from the hybrid binary.
722 *
723 * NOTE: The issue we are trying to avoid is any questioning of whether the
724 * hybrid binary is derived from Linux.  The wireless common code (wlc) is designed
725 * to be OS independent through the use of the OSL API and thus the hybrid binary doesn't
726 * derive from the Linux kernel at all.  But since we defined our OSL API to include
727 * a small collection of standard C library routines and these routines are provided in
728 * the kernel we want to avoid even the appearance of deriving at all even though clearly
729 * usage of a C standard library API doesn't represent a derivation from Linux.  Lastly
730 * note at the time of this checkin 4 references to memcpy/memset could not be eliminated
731 * from the binary because they are created internally by GCC as part of things like
732 * structure assignment.  I don't think the compiler should be doing this but there is
733 * no options to disable it on Intel architectures (there is for MIPS so somebody must
734 * agree with me).  I may be able to even remove these references eventually with
735 * a GNU binutil such as objcopy via a symbol rename (i.e. memcpy to osl_memcpy).
736 */
737#if !defined(LINUX_HYBRID) || defined(LINUX_PORT)
738	#define	printf(fmt, args...)	printk(fmt , ## args)
739	#include <linux/kernel.h>	/* for vsn/printf's */
740	#include <linux/string.h>	/* for mem*, str* */
741	/* bcopy's: Linux kernel doesn't provide these (anymore) */
742	#define	bcopy(src, dst, len)	memcpy((dst), (src), (len))
743	#define	bcmp(b1, b2, len)	memcmp((b1), (b2), (len))
744	#define	bzero(b, len)		memset((b), '\0', (len))
745
746	/* These are provided only because when compiling linux_osl.c there
747	 * must be an explicit prototype (separate from the definition) because
748	 * we are compiling with GCC option -Wstrict-prototypes.  Conversely
749	 * these could be placed directly in linux_osl.c.
750	 */
751	extern int osl_printf(const char *format, ...);
752	extern int osl_sprintf(char *buf, const char *format, ...);
753	extern int osl_snprintf(char *buf, size_t n, const char *format, ...);
754	extern int osl_vsprintf(char *buf, const char *format, va_list ap);
755	extern int osl_vsnprintf(char *buf, size_t n, const char *format, va_list ap);
756	extern int osl_strcmp(const char *s1, const char *s2);
757	extern int osl_strncmp(const char *s1, const char *s2, uint n);
758	extern int osl_strlen(const char *s);
759	extern char* osl_strcpy(char *d, const char *s);
760	extern char* osl_strncpy(char *d, const char *s, uint n);
761	extern char* osl_strchr(const char *s, int c);
762	extern char* osl_strrchr(const char *s, int c);
763	extern void *osl_memset(void *d, int c, size_t n);
764	extern void *osl_memcpy(void *d, const void *s, size_t n);
765	extern void *osl_memmove(void *d, const void *s, size_t n);
766	extern int osl_memcmp(const void *s1, const void *s2, size_t n);
767#else
768
769	/* In the below defines we undefine the macro first in case it is
770	 * defined.  This shouldn't happen because we are not using Linux
771	 * header files but because our Linux 2.4 make includes modversions.h
772	 * through a GCC -include compile option, they get defined to point
773	 * at the appropriate versioned symbol name.  Note this doesn't
774	 * happen with our Linux 2.6 makes.
775	 */
776
777	/* *printf functions */
778	#include <stdarg.h>			/* va_list needed for v*printf */
779	#include <stddef.h>			/* size_t needed for *nprintf */
780	#undef printf
781	#undef sprintf
782	#undef snprintf
783	#undef vsprintf
784	#undef vsnprintf
785	#define	printf(fmt, args...)		osl_printf((fmt) , ## args)
786	#define sprintf(buf, fmt, args...)	osl_sprintf((buf), (fmt) , ## args)
787	#define snprintf(buf, n, fmt, args...)	osl_snprintf((buf), (n), (fmt) , ## args)
788	#define vsprintf(buf, fmt, ap)		osl_vsprintf((buf), (fmt), (ap))
789	#define vsnprintf(buf, n, fmt, ap)	osl_vsnprintf((buf), (n), (fmt), (ap))
790	extern int osl_printf(const char *format, ...);
791	extern int osl_sprintf(char *buf, const char *format, ...);
792	extern int osl_snprintf(char *buf, size_t n, const char *format, ...);
793	extern int osl_vsprintf(char *buf, const char *format, va_list ap);
794	extern int osl_vsnprintf(char *buf, size_t n, const char *format, va_list ap);
795
796	/* str* functions */
797	#undef strcmp
798	#undef strncmp
799	#undef strlen
800	#undef strcpy
801	#undef strncpy
802	#undef strchr
803	#undef strrchr
804	#define	strcmp(s1, s2)			osl_strcmp((s1), (s2))
805	#define	strncmp(s1, s2, n)		osl_strncmp((s1), (s2), (n))
806	#define strlen(s)			osl_strlen((s))
807	#define	strcpy(d, s)			osl_strcpy((d), (s))
808	#define	strncpy(d, s, n)		osl_strncpy((d), (s), (n))
809	#define	strchr(s, c)			osl_strchr((s), (c))
810	#define	strrchr(s, c)			osl_strrchr((s), (c))
811	extern int osl_strcmp(const char *s1, const char *s2);
812	extern int osl_strncmp(const char *s1, const char *s2, uint n);
813	extern int osl_strlen(const char *s);
814	extern char* osl_strcpy(char *d, const char *s);
815	extern char* osl_strncpy(char *d, const char *s, uint n);
816	extern char* osl_strchr(const char *s, int c);
817	extern char* osl_strrchr(const char *s, int c);
818
819	/* mem* functions */
820	#undef memset
821	#undef memcpy
822	#undef memcmp
823	#define	memset(d, c, n)		osl_memset((d), (c), (n))
824	#define	memcpy(d, s, n)		osl_memcpy((d), (s), (n))
825	#define	memmove(d, s, n)	osl_memmove((d), (s), (n))
826	#define	memcmp(s1, s2, n)	osl_memcmp((s1), (s2), (n))
827	extern void *osl_memset(void *d, int c, size_t n);
828	extern void *osl_memcpy(void *d, const void *s, size_t n);
829	extern void *osl_memmove(void *d, const void *s, size_t n);
830	extern int osl_memcmp(const void *s1, const void *s2, size_t n);
831
832	/* bcopy, bcmp, and bzero functions */
833	#undef bcopy
834	#undef bcmp
835	#undef bzero
836	#define	bcopy(src, dst, len)	osl_memcpy((dst), (src), (len))
837	#define	bcmp(b1, b2, len)	osl_memcmp((b1), (b2), (len))
838	#define	bzero(b, len)		osl_memset((b), '\0', (len))
839#endif /* !defined(LINUX_HYBRID) || defined(LINUX_PORT) */
840
841/* register access macros */
842#if !defined(BCMJTAG)
843#define R_REG(osh, r) (\
844	sizeof(*(r)) == sizeof(uint8) ? osl_readb((volatile uint8*)(r)) : \
845	sizeof(*(r)) == sizeof(uint16) ? osl_readw((volatile uint16*)(r)) : \
846	osl_readl((volatile uint32*)(r)) \
847)
848#define W_REG(osh, r, v) do { \
849	switch (sizeof(*(r))) { \
850	case sizeof(uint8):	osl_writeb((uint8)(v), (volatile uint8*)(r)); break; \
851	case sizeof(uint16):	osl_writew((uint16)(v), (volatile uint16*)(r)); break; \
852	case sizeof(uint32):	osl_writel((uint32)(v), (volatile uint32*)(r)); break; \
853	} \
854} while (0)
855
856/* else added by johnvb to make sdio and jtag work with BINOSL, at least compile ... UNTESTED */
857#else
858#define R_REG(osh, r) OSL_READ_REG(osh, r)
859#define W_REG(osh, r, v) do { OSL_WRITE_REG(osh, r, v); } while (0)
860#endif
861
862#define	AND_REG(osh, r, v)		W_REG(osh, (r), R_REG(osh, r) & (v))
863#define	OR_REG(osh, r, v)		W_REG(osh, (r), R_REG(osh, r) | (v))
864extern uint8 osl_readb(volatile uint8 *r);
865extern uint16 osl_readw(volatile uint16 *r);
866extern uint32 osl_readl(volatile uint32 *r);
867extern void osl_writeb(uint8 v, volatile uint8 *r);
868extern void osl_writew(uint16 v, volatile uint16 *r);
869extern void osl_writel(uint32 v, volatile uint32 *r);
870
871/* system up time in ms */
872#define OSL_SYSUPTIME()		osl_sysuptime()
873extern uint32 osl_sysuptime(void);
874
875/* uncached/cached virtual address */
876#define OSL_UNCACHED(va)	osl_uncached((va))
877extern void *osl_uncached(void *va);
878#define OSL_CACHED(va)		osl_cached((va))
879extern void *osl_cached(void *va);
880
881#define OSL_PREF_RANGE_LD(va, sz)
882#define OSL_PREF_RANGE_ST(va, sz)
883
884/* get processor cycle count */
885#define OSL_GETCYCLES(x)	((x) = osl_getcycles())
886extern uint osl_getcycles(void);
887
888/* dereference an address that may target abort */
889#define	BUSPROBE(val, addr)	osl_busprobe(&(val), (addr))
890extern int osl_busprobe(uint32 *val, uint32 addr);
891
892/* map/unmap physical to virtual */
893#define	REG_MAP(pa, size)	osl_reg_map((pa), (size))
894#define	REG_UNMAP(va)		osl_reg_unmap((va))
895extern void *osl_reg_map(uint32 pa, uint size);
896extern void osl_reg_unmap(void *va);
897
898/* shared (dma-able) memory access macros */
899#define	R_SM(r)			*(r)
900#define	W_SM(r, v)		(*(r) = (v))
901#define	BZERO_SM(r, len)	bzero((r), (len))
902
903/* packet primitives */
904#ifdef BCMDBG_CTRACE
905#define	PKTGET(osh, len, send)		osl_pktget((osh), (len), __LINE__, __FILE__)
906#define	PKTDUP(osh, skb)		osl_pktdup((osh), (skb), __LINE__, __FILE__)
907#define PKTFRMNATIVE(osh, skb)		osl_pkt_frmnative((osh), (skb), __LINE__, __FILE__)
908#else
909#define	PKTGET(osh, len, send)		osl_pktget((osh), (len))
910#define	PKTDUP(osh, skb)		osl_pktdup((osh), (skb))
911#define PKTFRMNATIVE(osh, skb)		osl_pkt_frmnative((osh), (skb))
912#endif /* BCMDBG_CTRACE */
913#define PKTLIST_DUMP(osh, buf)
914#define PKTDBG_TRACE(osh, pkt, bit)
915#define	PKTFREE(osh, skb, send)		osl_pktfree((osh), (skb), (send))
916#define	PKTDATA(osh, skb)		osl_pktdata((osh), (skb))
917#define	PKTLEN(osh, skb)		osl_pktlen((osh), (skb))
918#define PKTHEADROOM(osh, skb)		osl_pktheadroom((osh), (skb))
919#define PKTTAILROOM(osh, skb)		osl_pkttailroom((osh), (skb))
920#define	PKTNEXT(osh, skb)		osl_pktnext((osh), (skb))
921#define	PKTSETNEXT(osh, skb, x)		osl_pktsetnext((skb), (x))
922#define	PKTSETLEN(osh, skb, len)	osl_pktsetlen((osh), (skb), (len))
923#define	PKTPUSH(osh, skb, bytes)	osl_pktpush((osh), (skb), (bytes))
924#define	PKTPULL(osh, skb, bytes)	osl_pktpull((osh), (skb), (bytes))
925#define PKTTAG(skb)			osl_pkttag((skb))
926#define PKTTONATIVE(osh, pkt)		osl_pkt_tonative((osh), (pkt))
927#define	PKTLINK(skb)			osl_pktlink((skb))
928#define	PKTSETLINK(skb, x)		osl_pktsetlink((skb), (x))
929#define	PKTPRIO(skb)			osl_pktprio((skb))
930#define	PKTSETPRIO(skb, x)		osl_pktsetprio((skb), (x))
931#define PKTSHARED(skb)                  osl_pktshared((skb))
932#define PKTSETPOOL(osh, skb, x, y)	do {} while (0)
933#define PKTPOOL(osh, skb)		FALSE
934
935extern void *osl_pktget(osl_t *osh, uint len);
936extern void *osl_pktdup(osl_t *osh, void *skb);
937extern void *osl_pkt_frmnative(osl_t *osh, void *skb);
938extern void osl_pktfree(osl_t *osh, void *skb, bool send);
939extern uchar *osl_pktdata(osl_t *osh, void *skb);
940extern uint osl_pktlen(osl_t *osh, void *skb);
941extern uint osl_pktheadroom(osl_t *osh, void *skb);
942extern uint osl_pkttailroom(osl_t *osh, void *skb);
943extern void *osl_pktnext(osl_t *osh, void *skb);
944extern void osl_pktsetnext(void *skb, void *x);
945extern void osl_pktsetlen(osl_t *osh, void *skb, uint len);
946extern uchar *osl_pktpush(osl_t *osh, void *skb, int bytes);
947extern uchar *osl_pktpull(osl_t *osh, void *skb, int bytes);
948extern void *osl_pkttag(void *skb);
949extern void *osl_pktlink(void *skb);
950extern void osl_pktsetlink(void *skb, void *x);
951extern uint osl_pktprio(void *skb);
952extern void osl_pktsetprio(void *skb, uint x);
953extern struct sk_buff *osl_pkt_tonative(osl_t *osh, void *pkt);
954extern bool osl_pktshared(void *skb);
955
956
957#endif	/* BINOSL */
958
959#define PKTALLOCED(osh)		osl_pktalloced(osh)
960extern uint osl_pktalloced(osl_t *osh);
961
962#ifdef CTFMAP
963#include <ctf/hndctf.h>
964#define	CTFMAPSZ	320
965#define	DMA_MAP(osh, va, size, direction, p, dmah) \
966({ \
967	typeof(size) sz = (size); \
968	if (p && PKTISCTF((osh), (p))) { \
969		sz = CTFMAPSZ; \
970		CTFMAPPTR((osh), (p)) = (void *)(((uint8 *)(va)) + CTFMAPSZ); \
971	} \
972	osl_dma_map((osh), (va), sz, (direction), (p), (dmah)); \
973})
974#define	SECURE_DMA_MAP(osh, va, size, direction, p, dmah, pcma, offset) \
975	osl_sec_dma_map((osh), (va), (size), (direction), (p), (dmah), (pcma), (offset))
976#define	SECURE_DMA_DD_MAP(osh, va, size, direction, p, dmah) \
977	osl_sec_dma_dd_map((osh), (va), (size), (direction), (p), (dmah))
978
979#if defined(__mips__)
980#define	_DMA_MAP(osh, va, size, direction, p, dmah) \
981	dma_cache_inv((uint)(va), (size))
982#elif defined(__ARM_ARCH_7A__)
983#include <asm/cacheflush.h>
984#define	_DMA_MAP(osh, va, size, direction, p, dmah) \
985	osl_dma_map((osh), (va), (size), (direction), (p), (dmah))
986#else
987#define	_DMA_MAP(osh, va, size, direction, p, dmah)
988#endif
989
990#else /* CTFMAP */
991#define	DMA_MAP(osh, va, size, direction, p, dmah) \
992	osl_dma_map((osh), (va), (size), (direction), (p), (dmah))
993#define	SECURE_DMA_MAP(osh, va, size, direction, p, dmah, pcma, offset) \
994		osl_sec_dma_map((osh), (va), (size), (direction), (p), (dmah), (pcma), (offset))
995#define	SECURE_DMA_DD_MAP(osh, va, size, direction, p, dmah) \
996	osl_sec_dma_dd_map((osh), (va), (size), (direction), (p), (dmah))
997#endif /* CTFMAP */
998
999#ifdef PKTC
1000/* Use 8 bytes of skb tstamp field to store below info */
1001struct chain_node {
1002	struct sk_buff	*link;
1003	unsigned int	flags:3, pkts:9, bytes:20;
1004};
1005
1006#define CHAIN_NODE(skb)		((struct chain_node*)(((struct sk_buff*)skb)->pktc_cb))
1007
1008#define	PKTCSETATTR(s, f, p, b)	({CHAIN_NODE(s)->flags = (f); CHAIN_NODE(s)->pkts = (p); \
1009	                         CHAIN_NODE(s)->bytes = (b);})
1010#define	PKTCCLRATTR(s)		({CHAIN_NODE(s)->flags = CHAIN_NODE(s)->pkts = \
1011	                         CHAIN_NODE(s)->bytes = 0;})
1012#define	PKTCGETATTR(s)		(CHAIN_NODE(s)->flags << 29 | CHAIN_NODE(s)->pkts << 20 | \
1013	                         CHAIN_NODE(s)->bytes)
1014#define	PKTCCNT(skb)		(CHAIN_NODE(skb)->pkts)
1015#define	PKTCLEN(skb)		(CHAIN_NODE(skb)->bytes)
1016#define	PKTCGETFLAGS(skb)	(CHAIN_NODE(skb)->flags)
1017#define	PKTCSETFLAGS(skb, f)	(CHAIN_NODE(skb)->flags = (f))
1018#define	PKTCCLRFLAGS(skb)	(CHAIN_NODE(skb)->flags = 0)
1019#define	PKTCFLAGS(skb)		(CHAIN_NODE(skb)->flags)
1020#define	PKTCSETCNT(skb, c)	(CHAIN_NODE(skb)->pkts = (c))
1021#define	PKTCINCRCNT(skb)	(CHAIN_NODE(skb)->pkts++)
1022#define	PKTCADDCNT(skb, c)	(CHAIN_NODE(skb)->pkts += (c))
1023#define	PKTCSETLEN(skb, l)	(CHAIN_NODE(skb)->bytes = (l))
1024#define	PKTCADDLEN(skb, l)	(CHAIN_NODE(skb)->bytes += (l))
1025#define	PKTCSETFLAG(skb, fb)	(CHAIN_NODE(skb)->flags |= (fb))
1026#define	PKTCCLRFLAG(skb, fb)	(CHAIN_NODE(skb)->flags &= ~(fb))
1027#define	PKTCLINK(skb)		(CHAIN_NODE(skb)->link)
1028#define	PKTSETCLINK(skb, x)	(CHAIN_NODE(skb)->link = (struct sk_buff*)(x))
1029#define FOREACH_CHAINED_PKT(skb, nskb) \
1030	for (; (skb) != NULL; (skb) = (nskb)) \
1031		if ((nskb) = (PKTISCHAINED(skb) ? PKTCLINK(skb) : NULL), \
1032		    PKTSETCLINK((skb), NULL), 1)
1033#define	PKTCFREE(osh, skb, send) \
1034do { \
1035	void *nskb; \
1036	ASSERT((skb) != NULL); \
1037	FOREACH_CHAINED_PKT((skb), nskb) { \
1038		PKTCLRCHAINED((osh), (skb)); \
1039		PKTCCLRFLAGS((skb)); \
1040		PKTFREE((osh), (skb), (send)); \
1041	} \
1042} while (0)
1043#define PKTCENQTAIL(h, t, p) \
1044do { \
1045	if ((t) == NULL) { \
1046		(h) = (t) = (p); \
1047	} else { \
1048		PKTSETCLINK((t), (p)); \
1049		(t) = (p); \
1050	} \
1051} while (0)
1052#endif /* PKTC */
1053
1054#else /* ! BCMDRIVER */
1055
1056
1057/* ASSERT */
1058	#define ASSERT(exp)	do {} while (0)
1059
1060/* MALLOC and MFREE */
1061#define MALLOC(o, l) malloc(l)
1062#define MFREE(o, p, l) free(p)
1063#include <stdlib.h>
1064
1065/* str* and mem* functions */
1066#include <string.h>
1067
1068/* *printf functions */
1069#include <stdio.h>
1070
1071/* bcopy, bcmp, and bzero */
1072extern void bcopy(const void *src, void *dst, size_t len);
1073extern int bcmp(const void *b1, const void *b2, size_t len);
1074extern void bzero(void *b, size_t len);
1075#endif /* ! BCMDRIVER */
1076
1077#ifdef BCM_SECURE_DMA
1078
1079#define CMA_BUFSIZE_4K	4096
1080#define CMA_BUFSIZE_2K	2048
1081#define CMA_BUFSIZE_512	512
1082
1083#define	CMA_BUFNUM		2048
1084#define CMA_DMA_DESC_MEMBLOCK	(0x80000)	/* 512K bytes */
1085#define CMA_DMA_DATA_MEMBLOCK	(CMA_BUFSIZE_4K*CMA_BUFNUM)		/* 2048 page size buffers */
1086#define	CMA_MEMBLOCK		(CMA_DMA_DESC_MEMBLOCK + CMA_DMA_DATA_MEMBLOCK)
1087#if defined(__ARM_ARCH_7A__)
1088#define CONT_ARMREGION	0x02		/* Region CMA */
1089#else
1090#define CONT_MIPREGION	0x00		/* To access the MIPs mem, Not yet... */
1091#endif
1092
1093#define SEC_DMA_ALIGN	(1<<16)
1094typedef struct sec_mem_elem {
1095	size_t			size;
1096	int				direction;
1097	phys_addr_t		pa_cma; 	/* physical  address */
1098	void			*va;     	/* virtual address of driver pkt */
1099	dma_addr_t		dma_handle; /* bus address assign by linux */
1100	void			*vac;       /* virtual address of cma buffer */
1101	struct	sec_mem_elem	*next;
1102} sec_mem_elem_t;
1103
1104typedef struct sec_cma_info {
1105	struct sec_mem_elem *sec_alloc_list;
1106	struct sec_mem_elem *sec_alloc_list_tail;
1107} sec_cma_info_t;
1108
1109extern void osl_sec_dma_setup_contig_mem(osl_t *osh, unsigned long memsize, int regn);
1110extern int osl_sec_dma_alloc_contig_mem(osl_t *osh, unsigned long memsize, int regn);
1111extern int osl_sec_dma_alloc_mips_contig_mem(osl_t *osh, unsigned long memsize, int regn);
1112extern void osl_sec_dma_init_elem_mem_block(osl_t *osh, size_t mbsize, int max,
1113	sec_mem_elem_t **list);
1114extern sec_mem_elem_t *osl_sec_dma_alloc_mem_elem(osl_t *osh, void *va, uint size,
1115	int direction, struct sec_cma_info *ptr_cma_info, uint offset);
1116extern void osl_sec_dma_free_mem_elem(osl_t *osh, sec_mem_elem_t *sec_mem_elem);
1117extern sec_mem_elem_t *osl_sec_dma_find_elem(osl_t *osh, struct sec_cma_info *ptr_cma_info,
1118	void *va);
1119extern sec_mem_elem_t *osl_sec_dma_find_rem_elem(osl_t *osh, struct sec_cma_info *ptr_cma_info,
1120	dma_addr_t dma_handle);
1121extern dma_addr_t osl_sec_dma_map(osl_t *osh, void *va, uint size, int direction, void *p,
1122	hnddma_seg_map_t *dmah, void *ptr_cma_info, uint offset);
1123extern dma_addr_t osl_sec_dma_dd_map(osl_t *osh, void *va, uint size, int direction, void *p,
1124	hnddma_seg_map_t *dmah);
1125extern void osl_sec_dma_unmap(osl_t *osh, dma_addr_t dma_handle, uint size, int direction,
1126	void *p, hnddma_seg_map_t *map, void *ptr_cma_info, uint offset);
1127extern void *osl_sec_dma_ioremap(osl_t *osh, struct page *page, size_t size, bool iscache,
1128	bool isdecr);
1129extern void osl_sec_dma_deinit_elem_mem_block(osl_t *osh, size_t mbsize, int max,
1130	void *sec_list_base);
1131extern void osl_sec_dma_free_contig_mem(osl_t *osh, u32 memsize, int regn);
1132extern void osl_sec_dma_iounmap(osl_t *osh, void *contig_base_va, size_t size);
1133extern void *osl_sec_dma_alloc_consistent(osl_t *osh, uint size, uint16 align_bits, ulong *pap);
1134
1135#endif /* BCM_SECURE_DMA */
1136#endif	/* _linux_osl_h_ */
1137