Commit | Line | Data |
---|---|---|
d2839953 RC |
1 | /* |
2 | * Linux OS Independent Layer | |
3 | * | |
965f77c4 | 4 | * Copyright (C) 1999-2019, Broadcom. |
d2839953 RC |
5 | * |
6 | * Unless you and Broadcom execute a separate written software license | |
7 | * agreement governing use of this software, this software is licensed to you | |
8 | * under the terms of the GNU General Public License version 2 (the "GPL"), | |
9 | * available at http://www.broadcom.com/licenses/GPLv2.php, with the | |
10 | * following added to such license: | |
11 | * | |
12 | * As a special exception, the copyright holders of this software give you | |
13 | * permission to link this software with independent modules, and to copy and | |
14 | * distribute the resulting executable under terms of your choice, provided that | |
15 | * you also meet, for each linked independent module, the terms and conditions of | |
16 | * the license of that module. An independent module is a module which is not | |
17 | * derived from this software. The special exception does not apply to any | |
18 | * modifications of the software. | |
19 | * | |
20 | * Notwithstanding the above, under no circumstances may you combine this | |
21 | * software in any way with any other Broadcom software provided under a license | |
22 | * other than the GPL, without Broadcom's express prior written consent. | |
23 | * | |
24 | * | |
25 | * <<Broadcom-WL-IPTag/Open:>> | |
26 | * | |
965f77c4 | 27 | * $Id: linux_osl.h 815919 2019-04-22 09:06:50Z $ |
d2839953 RC |
28 | */ |
29 | ||
30 | #ifndef _linux_osl_h_ | |
31 | #define _linux_osl_h_ | |
32 | ||
33 | #include <typedefs.h> | |
34 | #define DECLSPEC_ALIGN(x) __attribute__ ((aligned(x))) | |
35 | ||
36 | /* Linux Kernel: File Operations: start */ | |
37 | extern void * osl_os_open_image(char * filename); | |
38 | extern int osl_os_get_image_block(char * buf, int len, void * image); | |
39 | extern void osl_os_close_image(void * image); | |
40 | extern int osl_os_image_size(void *image); | |
41 | /* Linux Kernel: File Operations: end */ | |
42 | ||
43 | #ifdef BCMDRIVER | |
44 | ||
45 | /* OSL initialization */ | |
46 | extern osl_t *osl_attach(void *pdev, uint bustype, bool pkttag); | |
47 | ||
48 | extern void osl_detach(osl_t *osh); | |
49 | extern int osl_static_mem_init(osl_t *osh, void *adapter); | |
50 | extern int osl_static_mem_deinit(osl_t *osh, void *adapter); | |
51 | extern void osl_set_bus_handle(osl_t *osh, void *bus_handle); | |
52 | extern void* osl_get_bus_handle(osl_t *osh); | |
53 | #ifdef DHD_MAP_LOGGING | |
965f77c4 RC |
54 | extern void osl_dma_map_dump(osl_t *osh); |
55 | #define OSL_DMA_MAP_DUMP(osh) osl_dma_map_dump(osh) | |
56 | #else | |
57 | #define OSL_DMA_MAP_DUMP(osh) do {} while (0) | |
d2839953 RC |
58 | #endif /* DHD_MAP_LOGGING */ |
59 | ||
60 | /* Global ASSERT type */ | |
61 | extern uint32 g_assert_type; | |
62 | ||
63 | #ifdef CONFIG_PHYS_ADDR_T_64BIT | |
64 | #define PRI_FMT_x "llx" | |
65 | #define PRI_FMT_X "llX" | |
66 | #define PRI_FMT_o "llo" | |
67 | #define PRI_FMT_d "lld" | |
68 | #else | |
69 | #define PRI_FMT_x "x" | |
70 | #define PRI_FMT_X "X" | |
71 | #define PRI_FMT_o "o" | |
72 | #define PRI_FMT_d "d" | |
73 | #endif /* CONFIG_PHYS_ADDR_T_64BIT */ | |
74 | /* ASSERT */ | |
75 | #ifndef ASSERT | |
76 | #if defined(BCMASSERT_LOG) | |
77 | #define ASSERT(exp) \ | |
78 | do { if (!(exp)) osl_assert(#exp, __FILE__, __LINE__); } while (0) | |
79 | extern void osl_assert(const char *exp, const char *file, int line); | |
80 | #else | |
81 | #ifdef __GNUC__ | |
82 | #define GCC_VERSION \ | |
83 | (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) | |
84 | #if GCC_VERSION > 30100 | |
85 | #define ASSERT(exp) do {} while (0) | |
86 | #else | |
87 | /* ASSERT could cause segmentation fault on GCC3.1, use empty instead */ | |
88 | #define ASSERT(exp) | |
89 | #endif /* GCC_VERSION > 30100 */ | |
90 | #endif /* __GNUC__ */ | |
91 | #endif // endif | |
92 | #endif /* ASSERT */ | |
93 | ||
94 | /* bcm_prefetch_32B */ | |
95 | static inline void bcm_prefetch_32B(const uint8 *addr, const int cachelines_32B) | |
96 | { | |
97 | #if (defined(STB) && defined(__arm__)) && (__LINUX_ARM_ARCH__ >= 5) | |
98 | switch (cachelines_32B) { | |
99 | case 4: __asm__ __volatile__("pld\t%a0" :: "p"(addr + 96) : "cc"); | |
100 | case 3: __asm__ __volatile__("pld\t%a0" :: "p"(addr + 64) : "cc"); | |
101 | case 2: __asm__ __volatile__("pld\t%a0" :: "p"(addr + 32) : "cc"); | |
102 | case 1: __asm__ __volatile__("pld\t%a0" :: "p"(addr + 0) : "cc"); | |
103 | } | |
104 | #endif // endif | |
105 | } | |
106 | ||
107 | /* microsecond delay */ | |
108 | #define OSL_DELAY(usec) osl_delay(usec) | |
109 | extern void osl_delay(uint usec); | |
110 | ||
111 | #define OSL_SLEEP(ms) osl_sleep(ms) | |
112 | extern void osl_sleep(uint ms); | |
113 | ||
114 | #define OSL_PCMCIA_READ_ATTR(osh, offset, buf, size) \ | |
115 | osl_pcmcia_read_attr((osh), (offset), (buf), (size)) | |
116 | #define OSL_PCMCIA_WRITE_ATTR(osh, offset, buf, size) \ | |
117 | osl_pcmcia_write_attr((osh), (offset), (buf), (size)) | |
118 | extern void osl_pcmcia_read_attr(osl_t *osh, uint offset, void *buf, int size); | |
119 | extern void osl_pcmcia_write_attr(osl_t *osh, uint offset, void *buf, int size); | |
120 | ||
121 | /* PCI configuration space access macros */ | |
122 | #define OSL_PCI_READ_CONFIG(osh, offset, size) \ | |
123 | osl_pci_read_config((osh), (offset), (size)) | |
124 | #define OSL_PCI_WRITE_CONFIG(osh, offset, size, val) \ | |
125 | osl_pci_write_config((osh), (offset), (size), (val)) | |
126 | extern uint32 osl_pci_read_config(osl_t *osh, uint offset, uint size); | |
127 | extern void osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val); | |
128 | ||
129 | /* PCI device bus # and slot # */ | |
130 | #define OSL_PCI_BUS(osh) osl_pci_bus(osh) | |
131 | #define OSL_PCI_SLOT(osh) osl_pci_slot(osh) | |
132 | #define OSL_PCIE_DOMAIN(osh) osl_pcie_domain(osh) | |
133 | #define OSL_PCIE_BUS(osh) osl_pcie_bus(osh) | |
134 | extern uint osl_pci_bus(osl_t *osh); | |
135 | extern uint osl_pci_slot(osl_t *osh); | |
136 | extern uint osl_pcie_domain(osl_t *osh); | |
137 | extern uint osl_pcie_bus(osl_t *osh); | |
138 | extern struct pci_dev *osl_pci_device(osl_t *osh); | |
139 | ||
140 | #define OSL_ACP_COHERENCE (1<<1L) | |
141 | #define OSL_FWDERBUF (1<<2L) | |
142 | ||
143 | /* Pkttag flag should be part of public information */ | |
144 | typedef struct { | |
145 | bool pkttag; | |
146 | bool mmbus; /**< Bus supports memory-mapped register accesses */ | |
147 | pktfree_cb_fn_t tx_fn; /**< Callback function for PKTFREE */ | |
148 | void *tx_ctx; /**< Context to the callback function */ | |
149 | void *unused[3]; | |
150 | void (*rx_fn)(void *rx_ctx, void *p); | |
151 | void *rx_ctx; | |
152 | } osl_pubinfo_t; | |
153 | ||
154 | extern void osl_flag_set(osl_t *osh, uint32 mask); | |
155 | extern void osl_flag_clr(osl_t *osh, uint32 mask); | |
156 | extern bool osl_is_flag_set(osl_t *osh, uint32 mask); | |
157 | ||
158 | #define PKTFREESETCB(osh, _tx_fn, _tx_ctx) \ | |
159 | do { \ | |
160 | ((osl_pubinfo_t*)osh)->tx_fn = _tx_fn; \ | |
161 | ((osl_pubinfo_t*)osh)->tx_ctx = _tx_ctx; \ | |
162 | } while (0) | |
163 | ||
164 | #define PKTFREESETRXCB(osh, _rx_fn, _rx_ctx) \ | |
165 | do { \ | |
166 | ((osl_pubinfo_t*)osh)->rx_fn = _rx_fn; \ | |
167 | ((osl_pubinfo_t*)osh)->rx_ctx = _rx_ctx; \ | |
168 | } while (0) | |
169 | ||
170 | /* host/bus architecture-specific byte swap */ | |
171 | #define BUS_SWAP32(v) (v) | |
172 | #define MALLOC(osh, size) osl_malloc((osh), (size)) | |
173 | #define MALLOCZ(osh, size) osl_mallocz((osh), (size)) | |
174 | #define MFREE(osh, addr, size) osl_mfree((osh), (addr), (size)) | |
175 | #define VMALLOC(osh, size) osl_vmalloc((osh), (size)) | |
176 | #define VMALLOCZ(osh, size) osl_vmallocz((osh), (size)) | |
177 | #define VMFREE(osh, addr, size) osl_vmfree((osh), (addr), (size)) | |
178 | #define MALLOCED(osh) osl_malloced((osh)) | |
179 | #define MEMORY_LEFTOVER(osh) osl_check_memleak(osh) | |
180 | extern void *osl_malloc(osl_t *osh, uint size); | |
181 | extern void *osl_mallocz(osl_t *osh, uint size); | |
182 | extern void osl_mfree(osl_t *osh, void *addr, uint size); | |
183 | extern void *osl_vmalloc(osl_t *osh, uint size); | |
184 | extern void *osl_vmallocz(osl_t *osh, uint size); | |
185 | extern void osl_vmfree(osl_t *osh, void *addr, uint size); | |
186 | extern uint osl_malloced(osl_t *osh); | |
187 | extern uint osl_check_memleak(osl_t *osh); | |
188 | ||
189 | #define MALLOC_FAILED(osh) osl_malloc_failed((osh)) | |
190 | extern uint osl_malloc_failed(osl_t *osh); | |
191 | ||
192 | /* allocate/free shared (dma-able) consistent memory */ | |
193 | #define DMA_CONSISTENT_ALIGN osl_dma_consistent_align() | |
194 | #define DMA_ALLOC_CONSISTENT(osh, size, align, tot, pap, dmah) \ | |
195 | osl_dma_alloc_consistent((osh), (size), (align), (tot), (pap)) | |
196 | #define DMA_FREE_CONSISTENT(osh, va, size, pa, dmah) \ | |
197 | osl_dma_free_consistent((osh), (void*)(va), (size), (pa)) | |
198 | ||
199 | #define DMA_ALLOC_CONSISTENT_FORCE32(osh, size, align, tot, pap, dmah) \ | |
200 | osl_dma_alloc_consistent((osh), (size), (align), (tot), (pap)) | |
201 | #define DMA_FREE_CONSISTENT_FORCE32(osh, va, size, pa, dmah) \ | |
202 | osl_dma_free_consistent((osh), (void*)(va), (size), (pa)) | |
203 | ||
204 | extern uint osl_dma_consistent_align(void); | |
205 | extern void *osl_dma_alloc_consistent(osl_t *osh, uint size, uint16 align, | |
206 | uint *tot, dmaaddr_t *pap); | |
207 | extern void osl_dma_free_consistent(osl_t *osh, void *va, uint size, dmaaddr_t pa); | |
208 | ||
209 | /* map/unmap direction */ | |
210 | #define DMA_NO 0 /* Used to skip cache op */ | |
211 | #define DMA_TX 1 /* TX direction for DMA */ | |
212 | #define DMA_RX 2 /* RX direction for DMA */ | |
213 | ||
214 | /* map/unmap shared (dma-able) memory */ | |
215 | #define DMA_UNMAP(osh, pa, size, direction, p, dmah) \ | |
216 | osl_dma_unmap((osh), (pa), (size), (direction)) | |
217 | extern void osl_dma_flush(osl_t *osh, void *va, uint size, int direction, void *p, | |
218 | hnddma_seg_map_t *txp_dmah); | |
219 | extern dmaaddr_t osl_dma_map(osl_t *osh, void *va, uint size, int direction, void *p, | |
220 | hnddma_seg_map_t *txp_dmah); | |
221 | extern void osl_dma_unmap(osl_t *osh, dmaaddr_t pa, uint size, int direction); | |
222 | ||
223 | #ifndef PHYS_TO_VIRT | |
224 | #define PHYS_TO_VIRT(pa) osl_phys_to_virt(pa) | |
225 | #endif // endif | |
226 | #ifndef VIRT_TO_PHYS | |
227 | #define VIRT_TO_PHYS(va) osl_virt_to_phys(va) | |
228 | #endif // endif | |
229 | extern void * osl_phys_to_virt(void * pa); | |
230 | extern void * osl_virt_to_phys(void * va); | |
231 | ||
232 | /* API for DMA addressing capability */ | |
233 | #define OSL_DMADDRWIDTH(osh, addrwidth) ({BCM_REFERENCE(osh); BCM_REFERENCE(addrwidth);}) | |
234 | ||
235 | #define OSL_SMP_WMB() smp_wmb() | |
236 | ||
237 | /* API for CPU relax */ | |
238 | extern void osl_cpu_relax(void); | |
239 | #define OSL_CPU_RELAX() osl_cpu_relax() | |
240 | ||
241 | extern void osl_preempt_disable(osl_t *osh); | |
242 | extern void osl_preempt_enable(osl_t *osh); | |
243 | #define OSL_DISABLE_PREEMPTION(osh) osl_preempt_disable(osh) | |
244 | #define OSL_ENABLE_PREEMPTION(osh) osl_preempt_enable(osh) | |
245 | ||
246 | #if (!defined(DHD_USE_COHERENT_MEM_FOR_RING) && defined(__ARM_ARCH_7A__)) || \ | |
247 | defined(STB_SOC_WIFI) | |
248 | extern void osl_cache_flush(void *va, uint size); | |
249 | extern void osl_cache_inv(void *va, uint size); | |
250 | extern void osl_prefetch(const void *ptr); | |
251 | #define OSL_CACHE_FLUSH(va, len) osl_cache_flush((void *)(va), len) | |
252 | #define OSL_CACHE_INV(va, len) osl_cache_inv((void *)(va), len) | |
253 | #define OSL_PREFETCH(ptr) osl_prefetch(ptr) | |
254 | #if defined(__ARM_ARCH_7A__) || defined(STB_SOC_WIFI) | |
255 | extern int osl_arch_is_coherent(void); | |
256 | #define OSL_ARCH_IS_COHERENT() osl_arch_is_coherent() | |
257 | extern int osl_acp_war_enab(void); | |
258 | #define OSL_ACP_WAR_ENAB() osl_acp_war_enab() | |
259 | #else /* !__ARM_ARCH_7A__ */ | |
260 | #define OSL_ARCH_IS_COHERENT() NULL | |
261 | #define OSL_ACP_WAR_ENAB() NULL | |
262 | #endif /* !__ARM_ARCH_7A__ */ | |
263 | #else /* !__mips__ && !__ARM_ARCH_7A__ */ | |
264 | #define OSL_CACHE_FLUSH(va, len) BCM_REFERENCE(va) | |
265 | #define OSL_CACHE_INV(va, len) BCM_REFERENCE(va) | |
266 | #define OSL_PREFETCH(ptr) BCM_REFERENCE(ptr) | |
267 | ||
268 | #define OSL_ARCH_IS_COHERENT() NULL | |
269 | #define OSL_ACP_WAR_ENAB() NULL | |
270 | #endif // endif | |
271 | ||
272 | #ifdef BCM_BACKPLANE_TIMEOUT | |
273 | extern void osl_set_bpt_cb(osl_t *osh, void *bpt_cb, void *bpt_ctx); | |
274 | extern void osl_bpt_rreg(osl_t *osh, ulong addr, volatile void *v, uint size); | |
275 | #endif /* BCM_BACKPLANE_TIMEOUT */ | |
276 | ||
277 | #if (defined(STB) && defined(__arm__)) | |
278 | extern void osl_pcie_rreg(osl_t *osh, ulong addr, volatile void *v, uint size); | |
279 | #endif // endif | |
280 | ||
281 | /* register access macros */ | |
282 | #if defined(BCMSDIO) | |
283 | #include <bcmsdh.h> | |
284 | #define OSL_WRITE_REG(osh, r, v) (bcmsdh_reg_write(osl_get_bus_handle(osh), \ | |
285 | (uintptr)(r), sizeof(*(r)), (v))) | |
286 | #define OSL_READ_REG(osh, r) (bcmsdh_reg_read(osl_get_bus_handle(osh), \ | |
287 | (uintptr)(r), sizeof(*(r)))) | |
288 | #elif defined(BCM_BACKPLANE_TIMEOUT) | |
289 | #define OSL_READ_REG(osh, r) \ | |
290 | ({\ | |
291 | __typeof(*(r)) __osl_v; \ | |
292 | osl_bpt_rreg(osh, (uintptr)(r), &__osl_v, sizeof(*(r))); \ | |
293 | __osl_v; \ | |
294 | }) | |
295 | #elif (defined(STB) && defined(__arm__)) | |
296 | #define OSL_READ_REG(osh, r) \ | |
297 | ({\ | |
298 | __typeof(*(r)) __osl_v; \ | |
299 | osl_pcie_rreg(osh, (uintptr)(r), &__osl_v, sizeof(*(r))); \ | |
300 | __osl_v; \ | |
301 | }) | |
302 | #endif // endif | |
303 | ||
304 | #if defined(BCM_BACKPLANE_TIMEOUT) || (defined(STB) && defined(__arm__)) | |
305 | #define SELECT_BUS_WRITE(osh, mmap_op, bus_op) ({BCM_REFERENCE(osh); mmap_op;}) | |
306 | #define SELECT_BUS_READ(osh, mmap_op, bus_op) ({BCM_REFERENCE(osh); bus_op;}) | |
307 | #else /* !BCM47XX_CA9 && !BCM_BACKPLANE_TIMEOUT && !(STB && __arm__) */ | |
308 | #if defined(BCMSDIO) | |
309 | #define SELECT_BUS_WRITE(osh, mmap_op, bus_op) if (((osl_pubinfo_t*)(osh))->mmbus) \ | |
310 | mmap_op else bus_op | |
311 | #define SELECT_BUS_READ(osh, mmap_op, bus_op) (((osl_pubinfo_t*)(osh))->mmbus) ? \ | |
312 | mmap_op : bus_op | |
313 | #else | |
314 | #define SELECT_BUS_WRITE(osh, mmap_op, bus_op) ({BCM_REFERENCE(osh); mmap_op;}) | |
315 | #define SELECT_BUS_READ(osh, mmap_op, bus_op) ({BCM_REFERENCE(osh); mmap_op;}) | |
316 | #endif // endif | |
317 | #endif // endif | |
318 | ||
319 | #define OSL_ERROR(bcmerror) osl_error(bcmerror) | |
320 | extern int osl_error(int bcmerror); | |
321 | ||
322 | /* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */ | |
323 | #define PKTBUFSZ 2048 /* largest reasonable packet buffer, driver uses for ethernet MTU */ | |
324 | ||
325 | #define OSH_NULL NULL | |
326 | ||
327 | /* | |
328 | * BINOSL selects the slightly slower function-call-based binary compatible osl. | |
329 | * Macros expand to calls to functions defined in linux_osl.c . | |
330 | */ | |
331 | #include <linuxver.h> /* use current 2.4.x calling conventions */ | |
332 | #include <linux/kernel.h> /* for vsn/printf's */ | |
333 | #include <linux/string.h> /* for mem*, str* */ | |
d2839953 RC |
334 | extern uint64 osl_sysuptime_us(void); |
335 | #define OSL_SYSUPTIME() ((uint32)jiffies_to_msecs(jiffies)) | |
336 | #define OSL_SYSUPTIME_US() osl_sysuptime_us() | |
965f77c4 RC |
337 | extern uint64 osl_localtime_ns(void); |
338 | extern void osl_get_localtime(uint64 *sec, uint64 *usec); | |
339 | extern uint64 osl_systztime_us(void); | |
340 | #define OSL_LOCALTIME_NS() osl_localtime_ns() | |
341 | #define OSL_GET_LOCALTIME(sec, usec) osl_get_localtime((sec), (usec)) | |
342 | #define OSL_SYSTZTIME_US() osl_systztime_us() | |
3910ce8e | 343 | #define printf(fmt, args...) printk("[dhd] " fmt , ## args) |
d2839953 RC |
344 | #include <linux/kernel.h> /* for vsn/printf's */ |
345 | #include <linux/string.h> /* for mem*, str* */ | |
346 | /* bcopy's: Linux kernel doesn't provide these (anymore) */ | |
347 | #define bcopy_hw(src, dst, len) memcpy((dst), (src), (len)) | |
348 | #define bcopy_hw_async(src, dst, len) memcpy((dst), (src), (len)) | |
349 | #define bcopy_hw_poll_for_completion() | |
350 | #define bcopy(src, dst, len) memcpy((dst), (src), (len)) | |
351 | #define bcmp(b1, b2, len) memcmp((b1), (b2), (len)) | |
352 | #define bzero(b, len) memset((b), '\0', (len)) | |
353 | ||
354 | /* register access macros */ | |
355 | ||
356 | #ifdef CONFIG_64BIT | |
357 | /* readq is defined only for 64 bit platform */ | |
358 | #define R_REG(osh, r) (\ | |
359 | SELECT_BUS_READ(osh, \ | |
360 | ({ \ | |
361 | __typeof(*(r)) __osl_v = 0; \ | |
362 | BCM_REFERENCE(osh); \ | |
363 | switch (sizeof(*(r))) { \ | |
364 | case sizeof(uint8): __osl_v = \ | |
365 | readb((volatile uint8*)(r)); break; \ | |
366 | case sizeof(uint16): __osl_v = \ | |
367 | readw((volatile uint16*)(r)); break; \ | |
368 | case sizeof(uint32): __osl_v = \ | |
369 | readl((volatile uint32*)(r)); break; \ | |
370 | case sizeof(uint64): __osl_v = \ | |
371 | readq((volatile uint64*)(r)); break; \ | |
372 | } \ | |
373 | __osl_v; \ | |
374 | }), \ | |
375 | OSL_READ_REG(osh, r)) \ | |
376 | ) | |
377 | #else /* !CONFIG_64BIT */ | |
378 | #define R_REG(osh, r) (\ | |
379 | SELECT_BUS_READ(osh, \ | |
380 | ({ \ | |
381 | __typeof(*(r)) __osl_v = 0; \ | |
382 | switch (sizeof(*(r))) { \ | |
383 | case sizeof(uint8): __osl_v = \ | |
384 | readb((volatile uint8*)(r)); break; \ | |
385 | case sizeof(uint16): __osl_v = \ | |
386 | readw((volatile uint16*)(r)); break; \ | |
387 | case sizeof(uint32): __osl_v = \ | |
388 | readl((volatile uint32*)(r)); break; \ | |
389 | } \ | |
390 | __osl_v; \ | |
391 | }), \ | |
392 | OSL_READ_REG(osh, r)) \ | |
393 | ) | |
394 | #endif /* CONFIG_64BIT */ | |
395 | ||
396 | #ifdef CONFIG_64BIT | |
397 | /* writeq is defined only for 64 bit platform */ | |
398 | #define W_REG(osh, r, v) do { \ | |
399 | SELECT_BUS_WRITE(osh, \ | |
400 | switch (sizeof(*(r))) { \ | |
401 | case sizeof(uint8): writeb((uint8)(v), (volatile uint8*)(r)); break; \ | |
402 | case sizeof(uint16): writew((uint16)(v), (volatile uint16*)(r)); break; \ | |
403 | case sizeof(uint32): writel((uint32)(v), (volatile uint32*)(r)); break; \ | |
404 | case sizeof(uint64): writeq((uint64)(v), (volatile uint64*)(r)); break; \ | |
405 | }, \ | |
406 | (OSL_WRITE_REG(osh, r, v))); \ | |
407 | } while (0) | |
408 | ||
409 | #else /* !CONFIG_64BIT */ | |
410 | #define W_REG(osh, r, v) do { \ | |
411 | SELECT_BUS_WRITE(osh, \ | |
412 | switch (sizeof(*(r))) { \ | |
413 | case sizeof(uint8): writeb((uint8)(v), (volatile uint8*)(r)); break; \ | |
414 | case sizeof(uint16): writew((uint16)(v), (volatile uint16*)(r)); break; \ | |
415 | case sizeof(uint32): writel((uint32)(v), (volatile uint32*)(r)); break; \ | |
416 | }, \ | |
417 | (OSL_WRITE_REG(osh, r, v))); \ | |
418 | } while (0) | |
419 | #endif /* CONFIG_64BIT */ | |
420 | ||
421 | #define AND_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) & (v)) | |
422 | #define OR_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) | (v)) | |
423 | ||
424 | /* bcopy, bcmp, and bzero functions */ | |
425 | #define bcopy(src, dst, len) memcpy((dst), (src), (len)) | |
426 | #define bcmp(b1, b2, len) memcmp((b1), (b2), (len)) | |
427 | #define bzero(b, len) memset((b), '\0', (len)) | |
428 | ||
429 | /* uncached/cached virtual address */ | |
430 | #define OSL_UNCACHED(va) ((void *)va) | |
431 | #define OSL_CACHED(va) ((void *)va) | |
432 | ||
433 | #define OSL_PREF_RANGE_LD(va, sz) BCM_REFERENCE(va) | |
434 | #define OSL_PREF_RANGE_ST(va, sz) BCM_REFERENCE(va) | |
435 | ||
436 | /* get processor cycle count */ | |
437 | #if defined(__i386__) | |
438 | #define OSL_GETCYCLES(x) rdtscl((x)) | |
439 | #else | |
440 | #define OSL_GETCYCLES(x) ((x) = 0) | |
441 | #endif // endif | |
442 | ||
443 | /* dereference an address that may cause a bus exception */ | |
444 | #define BUSPROBE(val, addr) ({ (val) = R_REG(NULL, (addr)); 0; }) | |
445 | ||
446 | /* map/unmap physical to virtual I/O */ | |
447 | #if !defined(CONFIG_MMC_MSM7X00A) | |
3910ce8e LJ |
448 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)) |
449 | #define REG_MAP(pa, size) ioremap((unsigned long)(pa), (unsigned long)(size)) | |
450 | #else | |
d2839953 | 451 | #define REG_MAP(pa, size) ioremap_nocache((unsigned long)(pa), (unsigned long)(size)) |
3910ce8e | 452 | #endif |
d2839953 RC |
453 | #else |
454 | #define REG_MAP(pa, size) (void *)(0) | |
455 | #endif /* !defined(CONFIG_MMC_MSM7X00A */ | |
456 | #define REG_UNMAP(va) iounmap((va)) | |
457 | ||
458 | /* shared (dma-able) memory access macros */ | |
459 | #define R_SM(r) *(r) | |
460 | #define W_SM(r, v) (*(r) = (v)) | |
461 | #define BZERO_SM(r, len) memset((r), '\0', (len)) | |
462 | ||
463 | /* Because the non BINOSL implemenation of the PKT OSL routines are macros (for | |
464 | * performance reasons), we need the Linux headers. | |
465 | */ | |
466 | #include <linuxver.h> /* use current 2.4.x calling conventions */ | |
467 | ||
468 | #define OSL_RAND() osl_rand() | |
469 | extern uint32 osl_rand(void); | |
470 | ||
471 | #define DMA_FLUSH(osh, va, size, direction, p, dmah) \ | |
472 | osl_dma_flush((osh), (va), (size), (direction), (p), (dmah)) | |
473 | #if !defined(BCM_SECURE_DMA) | |
474 | #define DMA_MAP(osh, va, size, direction, p, dmah) \ | |
475 | osl_dma_map((osh), (va), (size), (direction), (p), (dmah)) | |
476 | #endif /* !(defined(BCM_SECURE_DMA)) */ | |
477 | ||
478 | #else /* ! BCMDRIVER */ | |
479 | ||
480 | /* ASSERT */ | |
481 | #define ASSERT(exp) do {} while (0) | |
482 | ||
483 | /* MALLOC and MFREE */ | |
484 | #define MALLOC(o, l) malloc(l) | |
485 | #define MFREE(o, p, l) free(p) | |
486 | #include <stdlib.h> | |
487 | ||
488 | /* str* and mem* functions */ | |
489 | #include <string.h> | |
490 | ||
491 | /* *printf functions */ | |
492 | #include <stdio.h> | |
493 | ||
494 | /* bcopy, bcmp, and bzero */ | |
495 | extern void bcopy(const void *src, void *dst, size_t len); | |
496 | extern int bcmp(const void *b1, const void *b2, size_t len); | |
497 | extern void bzero(void *b, size_t len); | |
498 | #endif /* ! BCMDRIVER */ | |
499 | ||
500 | /* Current STB 7445D1 doesn't use ACP and it is non-coherrent. | |
501 | * Adding these dummy values for build apss only | |
502 | * When we revisit need to change these. | |
503 | */ | |
504 | ||
505 | #ifdef BCM_SECURE_DMA | |
506 | ||
507 | #define SECURE_DMA_MAP(osh, va, size, direction, p, dmah, pcma, offset) \ | |
508 | osl_sec_dma_map((osh), (va), (size), (direction), (p), (dmah), (pcma), (offset)) | |
509 | #define SECURE_DMA_DD_MAP(osh, va, size, direction, p, dmah) \ | |
510 | osl_sec_dma_dd_map((osh), (va), (size), (direction), (p), (dmah)) | |
511 | #define SECURE_DMA_MAP_TXMETA(osh, va, size, direction, p, dmah, pcma) \ | |
512 | osl_sec_dma_map_txmeta((osh), (va), (size), (direction), (p), (dmah), (pcma)) | |
513 | #define SECURE_DMA_UNMAP(osh, pa, size, direction, p, dmah, pcma, offset) \ | |
514 | osl_sec_dma_unmap((osh), (pa), (size), (direction), (p), (dmah), (pcma), (offset)) | |
515 | #define SECURE_DMA_UNMAP_ALL(osh, pcma) \ | |
516 | osl_sec_dma_unmap_all((osh), (pcma)) | |
517 | ||
518 | #define DMA_MAP(osh, va, size, direction, p, dmah) | |
519 | ||
520 | typedef struct sec_cma_info { | |
521 | struct sec_mem_elem *sec_alloc_list; | |
522 | struct sec_mem_elem *sec_alloc_list_tail; | |
523 | } sec_cma_info_t; | |
524 | ||
525 | #if defined(__ARM_ARCH_7A__) | |
526 | #define CMA_BUFSIZE_4K 4096 | |
527 | #define CMA_BUFSIZE_2K 2048 | |
528 | #define CMA_BUFSIZE_512 512 | |
529 | ||
530 | #define CMA_BUFNUM 2048 | |
531 | #define SEC_CMA_COHERENT_BLK 0x8000 /* 32768 */ | |
532 | #define SEC_CMA_COHERENT_MAX 278 | |
533 | #define CMA_DMA_DESC_MEMBLOCK (SEC_CMA_COHERENT_BLK * SEC_CMA_COHERENT_MAX) | |
534 | #define CMA_DMA_DATA_MEMBLOCK (CMA_BUFSIZE_4K*CMA_BUFNUM) | |
535 | #define CMA_MEMBLOCK (CMA_DMA_DESC_MEMBLOCK + CMA_DMA_DATA_MEMBLOCK) | |
536 | #define CONT_REGION 0x02 /* Region CMA */ | |
537 | #else | |
538 | #define CONT_REGION 0x00 /* To access the MIPs mem, Not yet... */ | |
539 | #endif /* !defined __ARM_ARCH_7A__ */ | |
540 | ||
541 | #define SEC_DMA_ALIGN (1<<16) | |
542 | typedef struct sec_mem_elem { | |
543 | size_t size; | |
544 | int direction; | |
545 | phys_addr_t pa_cma; /**< physical address */ | |
546 | void *va; /**< virtual address of driver pkt */ | |
547 | dma_addr_t dma_handle; /**< bus address assign by linux */ | |
548 | void *vac; /**< virtual address of cma buffer */ | |
549 | struct page *pa_cma_page; /* phys to page address */ | |
550 | struct sec_mem_elem *next; | |
551 | } sec_mem_elem_t; | |
552 | ||
553 | extern dma_addr_t osl_sec_dma_map(osl_t *osh, void *va, uint size, int direction, void *p, | |
554 | hnddma_seg_map_t *dmah, void *ptr_cma_info, uint offset); | |
555 | extern dma_addr_t osl_sec_dma_dd_map(osl_t *osh, void *va, uint size, int direction, void *p, | |
556 | hnddma_seg_map_t *dmah); | |
557 | extern dma_addr_t osl_sec_dma_map_txmeta(osl_t *osh, void *va, uint size, | |
558 | int direction, void *p, hnddma_seg_map_t *dmah, void *ptr_cma_info); | |
559 | extern void osl_sec_dma_unmap(osl_t *osh, dma_addr_t dma_handle, uint size, int direction, | |
560 | void *p, hnddma_seg_map_t *map, void *ptr_cma_info, uint offset); | |
561 | extern void osl_sec_dma_unmap_all(osl_t *osh, void *ptr_cma_info); | |
562 | ||
563 | #endif /* BCM_SECURE_DMA */ | |
564 | ||
565 | typedef struct sk_buff_head PKT_LIST; | |
566 | #define PKTLIST_INIT(x) skb_queue_head_init((x)) | |
567 | #define PKTLIST_ENQ(x, y) skb_queue_head((struct sk_buff_head *)(x), (struct sk_buff *)(y)) | |
568 | #define PKTLIST_DEQ(x) skb_dequeue((struct sk_buff_head *)(x)) | |
569 | #define PKTLIST_UNLINK(x, y) skb_unlink((struct sk_buff *)(y), (struct sk_buff_head *)(x)) | |
570 | #define PKTLIST_FINI(x) skb_queue_purge((struct sk_buff_head *)(x)) | |
571 | ||
965f77c4 RC |
572 | #ifndef _linuxver_h_ |
573 | typedef struct timer_list_compat timer_list_compat_t; | |
574 | #endif /* _linuxver_h_ */ | |
d2839953 | 575 | typedef struct osl_timer { |
965f77c4 | 576 | timer_list_compat_t *timer; |
d2839953 RC |
577 | bool set; |
578 | } osl_timer_t; | |
579 | ||
580 | typedef void (*linux_timer_fn)(ulong arg); | |
581 | ||
582 | extern osl_timer_t * osl_timer_init(osl_t *osh, const char *name, void (*fn)(void *arg), void *arg); | |
583 | extern void osl_timer_add(osl_t *osh, osl_timer_t *t, uint32 ms, bool periodic); | |
584 | extern void osl_timer_update(osl_t *osh, osl_timer_t *t, uint32 ms, bool periodic); | |
585 | extern bool osl_timer_del(osl_t *osh, osl_timer_t *t); | |
d2839953 RC |
586 | |
587 | typedef atomic_t osl_atomic_t; | |
588 | #define OSL_ATOMIC_SET(osh, v, x) atomic_set(v, x) | |
589 | #define OSL_ATOMIC_INIT(osh, v) atomic_set(v, 0) | |
590 | #define OSL_ATOMIC_INC(osh, v) atomic_inc(v) | |
591 | #define OSL_ATOMIC_INC_RETURN(osh, v) atomic_inc_return(v) | |
592 | #define OSL_ATOMIC_DEC(osh, v) atomic_dec(v) | |
593 | #define OSL_ATOMIC_DEC_RETURN(osh, v) atomic_dec_return(v) | |
594 | #define OSL_ATOMIC_READ(osh, v) atomic_read(v) | |
595 | #define OSL_ATOMIC_ADD(osh, v, x) atomic_add(v, x) | |
596 | ||
965f77c4 RC |
597 | #ifndef atomic_set_mask |
598 | #define OSL_ATOMIC_OR(osh, v, x) atomic_or(x, v) | |
599 | #define OSL_ATOMIC_AND(osh, v, x) atomic_and(x, v) | |
600 | #else | |
601 | #define OSL_ATOMIC_OR(osh, v, x) atomic_set_mask(x, v) | |
602 | #define OSL_ATOMIC_AND(osh, v, x) atomic_clear_mask(~x, v) | |
603 | #endif // endif | |
604 | ||
605 | #include <linux/rbtree.h> | |
606 | ||
607 | typedef struct rb_node osl_rb_node_t; | |
608 | typedef struct rb_root osl_rb_root_t; | |
609 | ||
610 | #define OSL_RB_ENTRY(ptr, type, member) rb_entry(ptr, type, member) | |
611 | #define OSL_RB_INSERT_COLOR(root, node) rb_insert_color(root, node) | |
612 | #define OSL_RB_ERASE(node, root) rb_erase(node, root) | |
613 | #define OSL_RB_FIRST(root) rb_first(root) | |
614 | #define OSL_RB_LAST(root) rb_last(root) | |
615 | #define OSL_RB_LINK_NODE(node, parent, rb_link) \ | |
616 | rb_link_node(node, parent, rb_link) | |
617 | ||
618 | extern void *osl_spin_lock_init(osl_t *osh); | |
619 | extern void osl_spin_lock_deinit(osl_t *osh, void *lock); | |
620 | extern unsigned long osl_spin_lock(void *lock); | |
621 | extern void osl_spin_unlock(void *lock, unsigned long flags); | |
622 | ||
623 | typedef struct osl_timespec { | |
3910ce8e LJ |
624 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)) |
625 | __kernel_old_time_t tv_sec; /* seconds */ | |
626 | #else | |
965f77c4 | 627 | __kernel_time_t tv_sec; /* seconds */ |
3910ce8e | 628 | #endif |
965f77c4 RC |
629 | __kernel_suseconds_t tv_usec; /* microseconds */ |
630 | long tv_nsec; /* nanoseconds */ | |
631 | } osl_timespec_t; | |
632 | extern void osl_do_gettimeofday(struct osl_timespec *ts); | |
633 | extern void osl_get_monotonic_boottime(struct osl_timespec *ts); | |
d2839953 | 634 | #endif /* _linux_osl_h_ */ |