summaryrefslogtreecommitdiffstats
path: root/package/broadcom-wl/src/driver/linux_osl.h
blob: d9c5533b85eb9fba74764b6339798defe9e866d1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/*
 * Linux OS Independent Layer
 *
 * Copyright 2006, Broadcom Corporation
 * All Rights Reserved.
 * 
 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
 * 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 $
 */

#ifndef _linux_osl_h_
#define _linux_osl_h_

#include <typedefs.h>
#include <linuxver.h>
#include <osl.h>

#define OSL_PKTTAG_SZ     32 /* Size of PktTag */

/* osl handle type forward declaration */
typedef struct osl_dmainfo osldma_t;

/* OSL initialization */
extern osl_t *osl_attach(void *pdev, bool pkttag);
extern void osl_detach(osl_t *osh);

/* 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);
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)
#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));
}

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);
}


/* 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) */

/* packet primitives */
#define	PKTGET(osh, len, send)		osl_pktget((osh), (len), (send))
#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)
#define PKTHEADROOM(osh, skb)		(PKTDATA(osh, skb)-(((struct sk_buff*)(skb))->head))
#define PKTTAILROOM(osh, skb) ((((struct sk_buff*)(skb))->end)-(((struct sk_buff*)(skb))->tail))
#define	PKTNEXT(osh, skb)		(((struct sk_buff*)(skb))->next)
#define	PKTSETNEXT(osh, skb, x)		(((struct sk_buff*)(skb))->next = (struct sk_buff*)(x))
#define	PKTSETLEN(osh, skb, len)	__skb_trim((struct sk_buff*)(skb), (len))
#define	PKTPUSH(osh, skb, bytes)	skb_push((struct sk_buff*)(skb), (bytes))
#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 PKTLIST_DUMP(osh, buf)

/* 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)
{
	struct sk_buff *nskb;

	if (osh->pkttag)
		bzero((void*)skb->cb, OSL_PKTTAG_SZ);

	/* Increment the packet counter */
	for (nskb = skb; nskb; nskb = nskb->next) {
		osh->pktalloced++;
	}

	return (void *)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
 * IP code depends on skb->cb to be setup correctly with various options
 * In our case, that means it should be 0
 */
static INLINE struct sk_buff *
osl_pkt_tonative(osl_pubinfo_t*osh, void *pkt)
{
	struct sk_buff *nskb;

	if (osh->pkttag)
		bzero(((struct sk_buff*)pkt)->cb, OSL_PKTTAG_SZ);

	/* Decrement the packet counter */
	for (nskb = (struct sk_buff *)pkt; nskb; nskb = nskb->next) {
		osh->pktalloced--;
	}

	return (struct sk_buff *)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 PKTSHARED(skb)                  (((struct sk_buff*)(skb))->cloned)

extern void *osl_pktget(osl_t *osh, uint len, bool send);
extern void osl_pktfree(osl_t *osh, void *skb, bool send);
extern void *osl_pktdup(osl_t *osh, void *skb);
extern uint osl_pktalloced(osl_t *osh);

#define OSL_ERROR(bcmerror)	osl_error(bcmerror)
extern int osl_error(int bcmerror);

/* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */
#define	PKTBUFSZ	2048   /* largest reasonable packet buffer, driver uses for ethernet MTU */

#endif	/* _linux_osl_h_ */