1 /* 2 * Linux OS Independent Layer 3 * 4 * Copyright (C) 2020, Broadcom. 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 * 21 * <<Broadcom-WL-IPTag/Dual:>> 22 */ 23 24 #ifndef _linux_osl_h_ 25 #define _linux_osl_h_ 26 27 #include <typedefs.h> 28 #define DECLSPEC_ALIGN(x) __attribute__ ((aligned(x))) 29 30 /* Linux Kernel: File Operations: start */ 31 extern void * osl_os_open_image(char * filename); 32 extern int osl_os_get_image_block(char * buf, int len, void * image); 33 extern void osl_os_close_image(void * image); 34 extern int osl_os_image_size(void *image); 35 /* Linux Kernel: File Operations: end */ 36 37 #ifdef BCMDRIVER 38 39 /* OSL initialization */ 40 #ifdef SHARED_OSL_CMN 41 extern osl_t *osl_attach(void *pdev, uint bustype, bool pkttag, void **osh_cmn); 42 #else 43 extern osl_t *osl_attach(void *pdev, uint bustype, bool pkttag); 44 #endif /* SHARED_OSL_CMN */ 45 46 extern void osl_detach(osl_t *osh); 47 extern int osl_static_mem_init(osl_t *osh, void *adapter); 48 extern int osl_static_mem_deinit(osl_t *osh, void *adapter); 49 extern void osl_set_bus_handle(osl_t *osh, void *bus_handle); 50 extern void* osl_get_bus_handle(osl_t *osh); 51 #ifdef DHD_MAP_LOGGING 52 extern void osl_dma_map_dump(osl_t *osh); 53 #define OSL_DMA_MAP_DUMP(osh) osl_dma_map_dump(osh) 54 #else 55 #define OSL_DMA_MAP_DUMP(osh) do {} while (0) 56 #endif /* DHD_MAP_LOGGING */ 57 58 /* Global ASSERT type */ 59 extern uint32 g_assert_type; 60 61 #ifdef CONFIG_PHYS_ADDR_T_64BIT 62 #define PRI_FMT_x "llx" 63 #define PRI_FMT_X "llX" 64 #define PRI_FMT_o "llo" 65 #define PRI_FMT_d "lld" 66 #else 67 #define PRI_FMT_x "x" 68 #define PRI_FMT_X "X" 69 #define PRI_FMT_o "o" 70 #define PRI_FMT_d "d" 71 #endif /* CONFIG_PHYS_ADDR_T_64BIT */ 72 /* ASSERT */ 73 #ifndef ASSERT 74 #if (defined(BCMDBG_ASSERT) || defined(BCMASSERT_LOG)) && !defined(BINCMP) 75 #define ASSERT(exp) \ 76 do { if (!(exp)) osl_assert(#exp, __FILE__, __LINE__); } while (0) 77 extern void osl_assert(const char *exp, const char *file, int line); 78 #else 79 #ifdef __GNUC__ 80 #define GCC_VERSION \ 81 (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) 82 #if GCC_VERSION > 30100 83 #define ASSERT(exp) do {} while (0) 84 #else 85 /* ASSERT could cause segmentation fault on GCC3.1, use empty instead */ 86 #define ASSERT(exp) 87 #endif /* GCC_VERSION > 30100 */ 88 #endif /* __GNUC__ */ 89 #endif /* (BCMDBG_ASSERT || BCMASSERT_LOG) && !BINCMP */ 90 #endif /* ASSERT */ 91 92 #define ASSERT_FP(exp) ASSERT(exp) 93 94 /* microsecond delay */ 95 #define OSL_DELAY(usec) osl_delay(usec) 96 extern void osl_delay(uint usec); 97 98 #define OSL_SLEEP(ms) osl_sleep(ms) 99 extern void osl_sleep(uint ms); 100 101 /* PCI configuration space access macros */ 102 #define OSL_PCI_READ_CONFIG(osh, offset, size) \ 103 osl_pci_read_config((osh), (offset), (size)) 104 #define OSL_PCI_WRITE_CONFIG(osh, offset, size, val) \ 105 osl_pci_write_config((osh), (offset), (size), (val)) 106 extern uint32 osl_pci_read_config(osl_t *osh, uint offset, uint size); 107 extern void osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val); 108 109 /* PCI device bus # and slot # */ 110 #define OSL_PCI_BUS(osh) osl_pci_bus(osh) 111 #define OSL_PCI_SLOT(osh) osl_pci_slot(osh) 112 #define OSL_PCIE_DOMAIN(osh) osl_pcie_domain(osh) 113 #define OSL_PCIE_BUS(osh) osl_pcie_bus(osh) 114 extern uint osl_pci_bus(osl_t *osh); 115 extern uint osl_pci_slot(osl_t *osh); 116 extern uint osl_pcie_domain(osl_t *osh); 117 extern uint osl_pcie_bus(osl_t *osh); 118 extern struct pci_dev *osl_pci_device(osl_t *osh); 119 120 /* precommit failed when this is removed */ 121 /* BLAZAR_BRANCH_101_10_DHD_003/build/dhd/linux-fc30/brix-brcm */ 122 /* TBD: Revisit later */ 123 #if defined(BCMINTERNAL) 124 /* Flags that can be used to handle OSL specifcs */ 125 #define OSL_PHYS_MEM_LESS_THAN_16MB (1<<0L) 126 #endif /* BCMINTERNAL */ 127 128 #define OSL_ACP_COHERENCE (1<<1L) 129 #define OSL_FWDERBUF (1<<2L) 130 131 /* Pkttag flag should be part of public information */ 132 typedef struct { 133 bool pkttag; 134 bool mmbus; /**< Bus supports memory-mapped register accesses */ 135 pktfree_cb_fn_t tx_fn; /**< Callback function for PKTFREE */ 136 void *tx_ctx; /**< Context to the callback function */ 137 #ifdef OSLREGOPS 138 osl_rreg_fn_t rreg_fn; /**< Read Register function */ 139 osl_wreg_fn_t wreg_fn; /**< Write Register function */ 140 void *reg_ctx; /**< Context to the reg callback functions */ 141 #else 142 void *unused[3]; /**< temp fix for USBAP cftpool handle currption */ 143 #endif 144 void (*rx_fn)(void *rx_ctx, void *p); 145 void *rx_ctx; 146 } osl_pubinfo_t; 147 148 extern void osl_flag_set(osl_t *osh, uint32 mask); 149 extern void osl_flag_clr(osl_t *osh, uint32 mask); 150 extern bool osl_is_flag_set(osl_t *osh, uint32 mask); 151 152 #define PKTFREESETCB(osh, _tx_fn, _tx_ctx) \ 153 do { \ 154 ((osl_pubinfo_t*)osh)->tx_fn = _tx_fn; \ 155 ((osl_pubinfo_t*)osh)->tx_ctx = _tx_ctx; \ 156 } while (0) 157 158 #define PKTFREESETRXCB(osh, _rx_fn, _rx_ctx) \ 159 do { \ 160 ((osl_pubinfo_t*)osh)->rx_fn = _rx_fn; \ 161 ((osl_pubinfo_t*)osh)->rx_ctx = _rx_ctx; \ 162 } while (0) 163 164 #ifdef OSLREGOPS 165 #define REGOPSSET(osh, rreg, wreg, ctx) \ 166 do { \ 167 ((osl_pubinfo_t*)osh)->rreg_fn = rreg; \ 168 ((osl_pubinfo_t*)osh)->wreg_fn = wreg; \ 169 ((osl_pubinfo_t*)osh)->reg_ctx = ctx; \ 170 } while (0) 171 #endif /* OSLREGOPS */ 172 173 /* host/bus architecture-specific byte swap */ 174 #define BUS_SWAP32(v) (v) 175 176 #if defined(BCMDBG_MEM) && !defined(BINCMP) 177 #define MALLOC(osh, size) osl_debug_malloc((osh), (size), __LINE__, __FILE__) 178 #define MALLOCZ(osh, size) osl_debug_mallocz((osh), (size), __LINE__, __FILE__) 179 #define MFREE(osh, addr, size) \ 180 ({osl_debug_mfree((osh), ((void *)addr), (size), __LINE__, __FILE__);(addr) = NULL;}) 181 #define VMALLOC(osh, size) osl_debug_vmalloc((osh), (size), __LINE__, __FILE__) 182 #define VMALLOCZ(osh, size) osl_debug_vmallocz((osh), (size), __LINE__, __FILE__) 183 #define VMFREE(osh, addr, size) osl_debug_vmfree((osh), (addr), (size), __LINE__, __FILE__) 184 #define MALLOCED(osh) osl_malloced((osh)) 185 #define MEMORY_LEFTOVER(osh) osl_check_memleak(osh) 186 #define MALLOC_DUMP(osh, b) osl_debug_memdump((osh), (b)) 187 extern void *osl_debug_malloc(osl_t *osh, uint size, int line, const char* file); 188 extern void *osl_debug_mallocz(osl_t *osh, uint size, int line, const char* file); 189 extern void osl_debug_mfree(osl_t *osh, void *addr, uint size, int line, const char* file); 190 extern void *osl_debug_vmalloc(osl_t *osh, uint size, int line, const char* file); 191 extern void *osl_debug_vmallocz(osl_t *osh, uint size, int line, const char* file); 192 extern void osl_debug_vmfree(osl_t *osh, void *addr, uint size, int line, const char* file); 193 extern uint osl_malloced(osl_t *osh); 194 struct bcmstrbuf; 195 extern int osl_debug_memdump(osl_t *osh, struct bcmstrbuf *b); 196 extern uint osl_check_memleak(osl_t *osh); 197 #else /* BCMDBG_MEM && !BINCMP */ 198 #define MALLOC(osh, size) osl_malloc((osh), (size)) 199 #define MALLOCZ(osh, size) osl_mallocz((osh), (size)) 200 #define MALLOC_RA(osh, size, callsite) osl_mallocz((osh), (size)) 201 #define MFREE(osh, addr, size) ({osl_mfree((osh), ((void *)addr), (size));(addr) = NULL;}) 202 #define VMALLOC(osh, size) osl_vmalloc((osh), (size)) 203 #define VMALLOCZ(osh, size) osl_vmallocz((osh), (size)) 204 #define VMFREE(osh, addr, size) osl_vmfree((osh), (addr), (size)) 205 #define MALLOCED(osh) osl_malloced((osh)) 206 #define MEMORY_LEFTOVER(osh) osl_check_memleak(osh) 207 extern void *osl_malloc(osl_t *osh, uint size); 208 extern void *osl_mallocz(osl_t *osh, uint size); 209 extern void osl_mfree(osl_t *osh, void *addr, uint size); 210 extern void *osl_vmalloc(osl_t *osh, uint size); 211 extern void *osl_vmallocz(osl_t *osh, uint size); 212 extern void osl_vmfree(osl_t *osh, void *addr, uint size); 213 extern uint osl_malloced(osl_t *osh); 214 extern uint osl_check_memleak(osl_t *osh); 215 #endif /* BCMDBG_MEM && !BINCMP */ 216 217 extern int memcpy_s(void *dest, size_t destsz, const void *src, size_t n); 218 extern int memset_s(void *dest, size_t destsz, int c, size_t n); 219 #define MALLOC_FAILED(osh) osl_malloc_failed((osh)) 220 extern uint osl_malloc_failed(osl_t *osh); 221 222 /* allocate/free shared (dma-able) consistent memory */ 223 #define DMA_CONSISTENT_ALIGN osl_dma_consistent_align() 224 #define DMA_ALLOC_CONSISTENT(osh, size, align, tot, pap, dmah) \ 225 osl_dma_alloc_consistent((osh), (size), (align), (tot), (pap)) 226 #define DMA_FREE_CONSISTENT(osh, va, size, pa, dmah) \ 227 osl_dma_free_consistent((osh), (void*)(va), (size), (pa)) 228 229 #define DMA_ALLOC_CONSISTENT_FORCE32(osh, size, align, tot, pap, dmah) \ 230 osl_dma_alloc_consistent((osh), (size), (align), (tot), (pap)) 231 #define DMA_FREE_CONSISTENT_FORCE32(osh, va, size, pa, dmah) \ 232 osl_dma_free_consistent((osh), (void*)(va), (size), (pa)) 233 234 extern uint osl_dma_consistent_align(void); 235 extern void *osl_dma_alloc_consistent(osl_t *osh, uint size, uint16 align, 236 uint *tot, dmaaddr_t *pap); 237 extern void osl_dma_free_consistent(osl_t *osh, void *va, uint size, dmaaddr_t pa); 238 239 /* map/unmap direction */ 240 #define DMA_NO 0 /* Used to skip cache op */ 241 #define DMA_TX 1 /* TX direction for DMA */ 242 #define DMA_RX 2 /* RX direction for DMA */ 243 244 /* map/unmap shared (dma-able) memory */ 245 #define DMA_UNMAP(osh, pa, size, direction, p, dmah) \ 246 osl_dma_unmap((osh), (pa), (size), (direction)) 247 extern void osl_dma_flush(osl_t *osh, void *va, uint size, int direction, void *p, 248 hnddma_seg_map_t *txp_dmah); 249 extern dmaaddr_t osl_dma_map(osl_t *osh, void *va, uint size, int direction, void *p, 250 hnddma_seg_map_t *txp_dmah); 251 extern void osl_dma_unmap(osl_t *osh, dmaaddr_t pa, uint size, int direction); 252 253 #ifndef PHYS_TO_VIRT 254 #define PHYS_TO_VIRT(pa) osl_phys_to_virt(pa) 255 #endif 256 #ifndef VIRT_TO_PHYS 257 #define VIRT_TO_PHYS(va) osl_virt_to_phys(va) 258 #endif 259 extern void * osl_phys_to_virt(void * pa); 260 extern void * osl_virt_to_phys(void * va); 261 262 /* API for DMA addressing capability */ 263 #define OSL_DMADDRWIDTH(osh, addrwidth) ({BCM_REFERENCE(osh); BCM_REFERENCE(addrwidth);}) 264 265 #define OSL_SMP_WMB() smp_wmb() 266 267 /* API for CPU relax */ 268 extern void osl_cpu_relax(void); 269 #define OSL_CPU_RELAX() osl_cpu_relax() 270 271 extern void osl_preempt_disable(osl_t *osh); 272 extern void osl_preempt_enable(osl_t *osh); 273 #define OSL_DISABLE_PREEMPTION(osh) osl_preempt_disable(osh) 274 #define OSL_ENABLE_PREEMPTION(osh) osl_preempt_enable(osh) 275 276 #if (!defined(DHD_USE_COHERENT_MEM_FOR_RING) && defined(__ARM_ARCH_7A__)) 277 278 extern void osl_cache_flush(void *va, uint size); 279 extern void osl_cache_inv(void *va, uint size); 280 extern void osl_prefetch(const void *ptr); 281 #define OSL_CACHE_FLUSH(va, len) osl_cache_flush((void *)(va), len) 282 #define OSL_CACHE_INV(va, len) osl_cache_inv((void *)(va), len) 283 #define OSL_PREFETCH(ptr) osl_prefetch(ptr) 284 #else /* !__ARM_ARCH_7A__ */ 285 #define OSL_CACHE_FLUSH(va, len) BCM_REFERENCE(va) 286 #define OSL_CACHE_INV(va, len) BCM_REFERENCE(va) 287 #define OSL_PREFETCH(ptr) BCM_REFERENCE(ptr) 288 #endif /* !__ARM_ARCH_7A__ */ 289 290 #ifdef AXI_TIMEOUTS_NIC 291 extern void osl_set_bpt_cb(osl_t *osh, void *bpt_cb, void *bpt_ctx); 292 extern void osl_bpt_rreg(osl_t *osh, ulong addr, volatile void *v, uint size); 293 #endif /* AXI_TIMEOUTS_NIC */ 294 295 /* register access macros */ 296 #if defined(BCMSDIO) 297 #include <bcmsdh.h> 298 #define OSL_WRITE_REG(osh, r, v) (bcmsdh_reg_write(osl_get_bus_handle(osh), \ 299 (uintptr)(r), sizeof(*(r)), (v))) 300 #define OSL_READ_REG(osh, r) (bcmsdh_reg_read(osl_get_bus_handle(osh), \ 301 (uintptr)(r), sizeof(*(r)))) 302 #elif defined(AXI_TIMEOUTS_NIC) 303 #define OSL_READ_REG(osh, r) \ 304 ({\ 305 __typeof(*(r)) __osl_v; \ 306 osl_bpt_rreg(osh, (uintptr)(r), &__osl_v, sizeof(*(r))); \ 307 __osl_v; \ 308 }) 309 #endif 310 311 #if defined(AXI_TIMEOUTS_NIC) 312 #define SELECT_BUS_WRITE(osh, mmap_op, bus_op) ({BCM_REFERENCE(osh); mmap_op;}) 313 #define SELECT_BUS_READ(osh, mmap_op, bus_op) ({BCM_REFERENCE(osh); bus_op;}) 314 #else /* !AXI_TIMEOUTS_NIC */ 315 #if defined(BCMSDIO) 316 #define SELECT_BUS_WRITE(osh, mmap_op, bus_op) if (((osl_pubinfo_t*)(osh))->mmbus) \ 317 mmap_op else bus_op 318 #define SELECT_BUS_READ(osh, mmap_op, bus_op) (((osl_pubinfo_t*)(osh))->mmbus) ? \ 319 mmap_op : bus_op 320 #else 321 #define SELECT_BUS_WRITE(osh, mmap_op, bus_op) ({BCM_REFERENCE(osh); mmap_op;}) 322 #define SELECT_BUS_READ(osh, mmap_op, bus_op) ({BCM_REFERENCE(osh); mmap_op;}) 323 #endif /* defined(BCMSDIO) */ 324 #endif /* AXI_TIMEOUTS_NIC */ 325 326 #define OSL_ERROR(bcmerror) osl_error(bcmerror) 327 extern int osl_error(int bcmerror); 328 329 /* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */ 330 #define PKTBUFSZ 2048 /* largest reasonable packet buffer, driver uses for ethernet MTU */ 331 332 #define OSH_NULL NULL 333 334 /* 335 * BINOSL selects the slightly slower function-call-based binary compatible osl. 336 * Macros expand to calls to functions defined in linux_osl.c . 337 */ 338 #ifndef BINOSL 339 #include <linuxver.h> /* use current 2.4.x calling conventions */ 340 #include <linux/kernel.h> /* for vsn/printf's */ 341 #include <linux/string.h> /* for mem*, str* */ 342 extern uint64 osl_sysuptime_us(void); 343 #define OSL_SYSUPTIME() ((uint32)jiffies_to_msecs(jiffies)) 344 #define OSL_SYSUPTIME_US() osl_sysuptime_us() 345 extern uint64 osl_localtime_ns(void); 346 extern void osl_get_localtime(uint64 *sec, uint64 *usec); 347 extern uint64 osl_systztime_us(void); 348 #define OSL_LOCALTIME_NS() osl_localtime_ns() 349 #define OSL_GET_LOCALTIME(sec, usec) osl_get_localtime((sec), (usec)) 350 #define OSL_SYSTZTIME_US() osl_systztime_us() 351 #define printf(fmt, args...) printk(DHD_LOG_PREFIXS fmt , ## args) 352 #include <linux/kernel.h> /* for vsn/printf's */ 353 #include <linux/string.h> /* for mem*, str* */ 354 /* bcopy's: Linux kernel doesn't provide these (anymore) */ 355 #define bcopy_hw(src, dst, len) memcpy((dst), (src), (len)) 356 #define bcopy_hw_async(src, dst, len) memcpy((dst), (src), (len)) 357 #define bcopy_hw_poll_for_completion() 358 #define bcopy(src, dst, len) memcpy((dst), (src), (len)) 359 #define bcmp(b1, b2, len) memcmp((b1), (b2), (len)) 360 #define bzero(b, len) memset((b), '\0', (len)) 361 362 #if defined(CONFIG_SOC_EXYNOS9810) || defined(CONFIG_SOC_EXYNOS9820) || \ 363 defined(CONFIG_SOC_EXYNOS9830) || defined(CONFIG_SOC_GS101) 364 extern int pcie_ch_num; 365 extern int exynos_pcie_l1_exit(int ch_num); 366 #endif /* CONFIG_SOC_EXYNOS9810 || CONFIG_SOC_EXYNOS9820 367 * CONFIG_SOC_EXYNOS9830 || CONFIG_SOC_GS101 368 */ 369 370 /* register access macros */ 371 #if defined(OSLREGOPS) 372 #define R_REG(osh, r) (\ 373 sizeof(*(r)) == sizeof(uint8) ? osl_readb((osh), (volatile uint8*)(r)) : \ 374 sizeof(*(r)) == sizeof(uint16) ? osl_readw((osh), (volatile uint16*)(r)) : \ 375 sizeof(*(r)) == sizeof(uint32) ? osl_readl((osh), (volatile uint32*)(r)) : \ 376 osl_readq((osh), (volatile uint64*)(r)) \ 377 ) 378 379 #define W_REG(osh, r, v) do { \ 380 switch (sizeof(*(r))) { \ 381 case sizeof(uint8): osl_writeb((osh), (volatile uint8*)(r), (uint8)(v)); break; \ 382 case sizeof(uint16): osl_writew((osh), (volatile uint16*)(r), (uint16)(v)); break; \ 383 case sizeof(uint32): osl_writel((osh), (volatile uint32*)(r), (uint32)(v)); break; \ 384 case sizeof(uint64): osl_writeq((osh), (volatile uint64*)(r), (uint64)(v)); break; \ 385 } \ 386 } while (0) 387 388 extern uint8 osl_readb(osl_t *osh, volatile uint8 *r); 389 extern uint16 osl_readw(osl_t *osh, volatile uint16 *r); 390 extern uint32 osl_readl(osl_t *osh, volatile uint32 *r); 391 extern uint32 osl_readq(osl_t *osh, volatile uint64 *r); 392 extern void osl_writeb(osl_t *osh, volatile uint8 *r, uint8 v); 393 extern void osl_writew(osl_t *osh, volatile uint16 *r, uint16 v); 394 extern void osl_writel(osl_t *osh, volatile uint32 *r, uint32 v); 395 extern void osl_writeq(osl_t *osh, volatile uint64 *r, uint64 v); 396 397 #else /* OSLREGOPS */ 398 399 #ifndef IL_BIGENDIAN 400 #ifdef CONFIG_64BIT 401 /* readq is defined only for 64 bit platform */ 402 #if defined(CONFIG_SOC_EXYNOS9810) || defined(CONFIG_SOC_EXYNOS9820) || \ 403 defined(CONFIG_SOC_EXYNOS9830) || defined(CONFIG_SOC_GS101) 404 #define R_REG(osh, r) (\ 405 SELECT_BUS_READ(osh, \ 406 ({ \ 407 __typeof(*(r)) __osl_v = 0; \ 408 exynos_pcie_l1_exit(pcie_ch_num); \ 409 BCM_REFERENCE(osh); \ 410 switch (sizeof(*(r))) { \ 411 case sizeof(uint8): __osl_v = \ 412 readb((volatile uint8*)(r)); break; \ 413 case sizeof(uint16): __osl_v = \ 414 readw((volatile uint16*)(r)); break; \ 415 case sizeof(uint32): __osl_v = \ 416 readl((volatile uint32*)(r)); break; \ 417 case sizeof(uint64): __osl_v = \ 418 readq((volatile uint64*)(r)); break; \ 419 } \ 420 __osl_v; \ 421 }), \ 422 OSL_READ_REG(osh, r)) \ 423 ) 424 #else 425 #define R_REG(osh, r) (\ 426 SELECT_BUS_READ(osh, \ 427 ({ \ 428 __typeof(*(r)) __osl_v = 0; \ 429 BCM_REFERENCE(osh); \ 430 switch (sizeof(*(r))) { \ 431 case sizeof(uint8): __osl_v = \ 432 readb((volatile uint8*)(r)); break; \ 433 case sizeof(uint16): __osl_v = \ 434 readw((volatile uint16*)(r)); break; \ 435 case sizeof(uint32): __osl_v = \ 436 readl((volatile uint32*)(r)); break; \ 437 case sizeof(uint64): __osl_v = \ 438 readq((volatile uint64*)(r)); break; \ 439 } \ 440 __osl_v; \ 441 }), \ 442 OSL_READ_REG(osh, r)) \ 443 ) 444 #endif /* CONFIG_SOC_EXYNOS9810 || CONFIG_SOC_EXYNOS9820 445 * CONFIG_SOC_EXYNOS9830 || CONFIG_SOC_GS101 446 */ 447 #else /* !CONFIG_64BIT */ 448 #define R_REG(osh, r) (\ 449 SELECT_BUS_READ(osh, \ 450 ({ \ 451 __typeof(*(r)) __osl_v = 0; \ 452 switch (sizeof(*(r))) { \ 453 case sizeof(uint8): __osl_v = \ 454 readb((volatile uint8*)(r)); break; \ 455 case sizeof(uint16): __osl_v = \ 456 readw((volatile uint16*)(r)); break; \ 457 case sizeof(uint32): __osl_v = \ 458 readl((volatile uint32*)(r)); break; \ 459 } \ 460 __osl_v; \ 461 }), \ 462 OSL_READ_REG(osh, r)) \ 463 ) 464 #endif /* CONFIG_64BIT */ 465 466 #ifdef CONFIG_64BIT 467 /* writeq is defined only for 64 bit platform */ 468 #if defined(CONFIG_SOC_EXYNOS9810) || defined(CONFIG_SOC_EXYNOS9820) || \ 469 defined(CONFIG_SOC_EXYNOS9830) || defined(CONFIG_SOC_GS101) 470 #define W_REG(osh, r, v) do { \ 471 SELECT_BUS_WRITE(osh, \ 472 ({ \ 473 exynos_pcie_l1_exit(pcie_ch_num); \ 474 switch (sizeof(*(r))) { \ 475 case sizeof(uint8): writeb((uint8)(v), \ 476 (volatile uint8*)(r)); break; \ 477 case sizeof(uint16): writew((uint16)(v), \ 478 (volatile uint16*)(r)); break; \ 479 case sizeof(uint32): writel((uint32)(v), \ 480 (volatile uint32*)(r)); break; \ 481 case sizeof(uint64): writeq((uint64)(v), \ 482 (volatile uint64*)(r)); break; \ 483 } \ 484 }), \ 485 (OSL_WRITE_REG(osh, r, v))); \ 486 } while (0) 487 #else 488 #define W_REG(osh, r, v) do { \ 489 SELECT_BUS_WRITE(osh, \ 490 switch (sizeof(*(r))) { \ 491 case sizeof(uint8): writeb((uint8)(v), (volatile uint8*)(r)); break; \ 492 case sizeof(uint16): writew((uint16)(v), (volatile uint16*)(r)); break; \ 493 case sizeof(uint32): writel((uint32)(v), (volatile uint32*)(r)); break; \ 494 case sizeof(uint64): writeq((uint64)(v), (volatile uint64*)(r)); break; \ 495 }, \ 496 (OSL_WRITE_REG(osh, r, v))); \ 497 } while (0) 498 #endif /* CONFIG_SOC_EXYNOS9810 || CONFIG_SOC_EXYNOS9820 499 * CONFIG_SOC_EXYNOS9830 || CONFIG_SOC_GS101 500 */ 501 #else /* !CONFIG_64BIT */ 502 #define W_REG(osh, r, v) do { \ 503 SELECT_BUS_WRITE(osh, \ 504 switch (sizeof(*(r))) { \ 505 case sizeof(uint8): writeb((uint8)(v), (volatile uint8*)(r)); break; \ 506 case sizeof(uint16): writew((uint16)(v), (volatile uint16*)(r)); break; \ 507 case sizeof(uint32): writel((uint32)(v), (volatile uint32*)(r)); break; \ 508 }, \ 509 (OSL_WRITE_REG(osh, r, v))); \ 510 } while (0) 511 #endif /* CONFIG_64BIT */ 512 513 #else /* IL_BIGENDIAN */ 514 515 #ifdef CONFIG_64BIT 516 /* readq and writeq is defined only for 64 bit platform */ 517 #define R_REG(osh, r) (\ 518 SELECT_BUS_READ(osh, \ 519 ({ \ 520 __typeof(*(r)) __osl_v = 0; \ 521 switch (sizeof(*(r))) { \ 522 case sizeof(uint8): __osl_v = \ 523 readb((volatile uint8*)((uintptr)(r)^3)); break; \ 524 case sizeof(uint16): __osl_v = \ 525 readw((volatile uint16*)((uintptr)(r)^2)); break; \ 526 case sizeof(uint32): __osl_v = \ 527 readl((volatile uint32*)(r)); break; \ 528 case sizeof(uint64): __osl_v = \ 529 readq((volatile uint64*)(r)); break; \ 530 } \ 531 __osl_v; \ 532 }), \ 533 OSL_READ_REG(osh, r)) \ 534 ) 535 #define W_REG(osh, r, v) do { \ 536 SELECT_BUS_WRITE(osh, \ 537 switch (sizeof(*(r))) { \ 538 case sizeof(uint8): writeb((uint8)(v), \ 539 (volatile uint8*)((uintptr)(r)^3)); break; \ 540 case sizeof(uint16): writew((uint16)(v), \ 541 (volatile uint16*)((uintptr)(r)^2)); break; \ 542 case sizeof(uint32): writel((uint32)(v), \ 543 (volatile uint32*)(r)); break; \ 544 case sizeof(uint64): writeq((uint64)(v), \ 545 (volatile uint64*)(r)); break; \ 546 }, \ 547 (OSL_WRITE_REG(osh, r, v))); \ 548 } while (0) 549 550 #else /* !CONFIG_64BIT */ 551 #define R_REG(osh, r) (\ 552 SELECT_BUS_READ(osh, \ 553 ({ \ 554 __typeof(*(r)) __osl_v = 0; \ 555 switch (sizeof(*(r))) { \ 556 case sizeof(uint8): __osl_v = \ 557 readb((volatile uint8*)((uintptr)(r)^3)); break; \ 558 case sizeof(uint16): __osl_v = \ 559 readw((volatile uint16*)((uintptr)(r)^2)); break; \ 560 case sizeof(uint32): __osl_v = \ 561 readl((volatile uint32*)(r)); break; \ 562 } \ 563 __osl_v; \ 564 }), \ 565 OSL_READ_REG(osh, r)) \ 566 ) 567 #define W_REG(osh, r, v) do { \ 568 SELECT_BUS_WRITE(osh, \ 569 switch (sizeof(*(r))) { \ 570 case sizeof(uint8): writeb((uint8)(v), \ 571 (volatile uint8*)((uintptr)(r)^3)); break; \ 572 case sizeof(uint16): writew((uint16)(v), \ 573 (volatile uint16*)((uintptr)(r)^2)); break; \ 574 case sizeof(uint32): writel((uint32)(v), \ 575 (volatile uint32*)(r)); break; \ 576 }, \ 577 (OSL_WRITE_REG(osh, r, v))); \ 578 } while (0) 579 #endif /* CONFIG_64BIT */ 580 #endif /* IL_BIGENDIAN */ 581 582 #endif /* OSLREGOPS */ 583 584 #define AND_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) & (v)) 585 #define OR_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) | (v)) 586 587 /* bcopy, bcmp, and bzero functions */ 588 #define bcopy(src, dst, len) memcpy((dst), (src), (len)) 589 #define bcmp(b1, b2, len) memcmp((b1), (b2), (len)) 590 #define bzero(b, len) memset((b), '\0', (len)) 591 592 /* uncached/cached virtual address */ 593 #define OSL_UNCACHED(va) ((void *)va) 594 #define OSL_CACHED(va) ((void *)va) 595 596 #define OSL_PREF_RANGE_LD(va, sz) BCM_REFERENCE(va) 597 #define OSL_PREF_RANGE_ST(va, sz) BCM_REFERENCE(va) 598 599 /* get processor cycle count */ 600 #if defined(__i386__) 601 #define OSL_GETCYCLES(x) rdtscl((x)) 602 #else 603 #define OSL_GETCYCLES(x) ((x) = 0) 604 #endif /* __i386__ */ 605 606 /* dereference an address that may cause a bus exception */ 607 #define BUSPROBE(val, addr) ({ (val) = R_REG(NULL, (addr)); 0; }) 608 609 /* map/unmap physical to virtual I/O */ 610 #if !defined(CONFIG_MMC_MSM7X00A) 611 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)) 612 #define REG_MAP(pa, size) ioremap((unsigned long)(pa), (unsigned long)(size)) 613 #else 614 #define REG_MAP(pa, size) ioremap_nocache((unsigned long)(pa), (unsigned long)(size)) 615 #endif 616 #else 617 #define REG_MAP(pa, size) (void *)(0) 618 #endif /* !defined(CONFIG_MMC_MSM7X00A */ 619 #define REG_UNMAP(va) iounmap((va)) 620 621 /* shared (dma-able) memory access macros */ 622 #define R_SM(r) *(r) 623 #define W_SM(r, v) (*(r) = (v)) 624 #define OR_SM(r, v) (*(r) |= (v)) 625 #define BZERO_SM(r, len) memset((r), '\0', (len)) 626 627 /* Because the non BINOSL implemenation of the PKT OSL routines are macros (for 628 * performance reasons), we need the Linux headers. 629 */ 630 #include <linuxver.h> /* use current 2.4.x calling conventions */ 631 632 #else /* BINOSL */ 633 634 /* Where to get the declarations for mem, str, printf, bcopy's? Two basic approaches. 635 * 636 * First, use the Linux header files and the C standard library replacmenent versions 637 * built-in to the kernel. Use this approach when compiling non hybrid code or compling 638 * the OS port files. The second approach is to use our own defines/prototypes and 639 * functions we have provided in the Linux OSL, i.e. linux_osl.c. Use this approach when 640 * compiling the files that make up the hybrid binary. We are ensuring we 641 * don't directly link to the kernel replacement routines from the hybrid binary. 642 * 643 * NOTE: The issue we are trying to avoid is any questioning of whether the 644 * hybrid binary is derived from Linux. The wireless common code (wlc) is designed 645 * to be OS independent through the use of the OSL API and thus the hybrid binary doesn't 646 * derive from the Linux kernel at all. But since we defined our OSL API to include 647 * a small collection of standard C library routines and these routines are provided in 648 * the kernel we want to avoid even the appearance of deriving at all even though clearly 649 * usage of a C standard library API doesn't represent a derivation from Linux. Lastly 650 * note at the time of this checkin 4 references to memcpy/memset could not be eliminated 651 * from the binary because they are created internally by GCC as part of things like 652 * structure assignment. I don't think the compiler should be doing this but there is 653 * no options to disable it on Intel architectures (there is for MIPS so somebody must 654 * agree with me). I may be able to even remove these references eventually with 655 * a GNU binutil such as objcopy via a symbol rename (i.e. memcpy to osl_memcpy). 656 */ 657 #define printf(fmt, args...) printk(fmt , ## args) 658 #include <linux/kernel.h> /* for vsn/printf's */ 659 #include <linux/string.h> /* for mem*, str* */ 660 /* bcopy's: Linux kernel doesn't provide these (anymore) */ 661 #define bcopy(src, dst, len) memcpy((dst), (src), (len)) 662 #define bcmp(b1, b2, len) memcmp((b1), (b2), (len)) 663 #define bzero(b, len) memset((b), '\0', (len)) 664 665 /* These are provided only because when compiling linux_osl.c there 666 * must be an explicit prototype (separate from the definition) because 667 * we are compiling with GCC option -Wstrict-prototypes. Conversely 668 * these could be placed directly in linux_osl.c. 669 */ 670 extern int osl_printf(const char *format, ...); 671 extern int osl_sprintf(char *buf, const char *format, ...); 672 extern int osl_snprintf(char *buf, size_t n, const char *format, ...); 673 extern int osl_vsprintf(char *buf, const char *format, va_list ap); 674 extern int osl_vsnprintf(char *buf, size_t n, const char *format, va_list ap); 675 extern int osl_strcmp(const char *s1, const char *s2); 676 extern int osl_strncmp(const char *s1, const char *s2, uint n); 677 extern int osl_strlen(const char *s); 678 extern char* osl_strcpy(char *d, const char *s); 679 extern char* osl_strncpy(char *d, const char *s, uint n); 680 extern char* osl_strchr(const char *s, int c); 681 extern char* osl_strrchr(const char *s, int c); 682 extern void *osl_memset(void *d, int c, size_t n); 683 extern void *osl_memcpy(void *d, const void *s, size_t n); 684 extern void *osl_memmove(void *d, const void *s, size_t n); 685 extern int osl_memcmp(const void *s1, const void *s2, size_t n); 686 687 /* register access macros */ 688 #if !defined(BCMSDIO) 689 #define R_REG(osh, r) \ 690 ({ \ 691 BCM_REFERENCE(osh); \ 692 sizeof(*(r)) == sizeof(uint8) ? osl_readb((volatile uint8*)(r)) : \ 693 sizeof(*(r)) == sizeof(uint16) ? osl_readw((volatile uint16*)(r)) : \ 694 sizeof(*(r)) == sizeof(uint32) ? osl_readl((volatile uint32*)(r)) : \ 695 osl_readq((volatile uint64*)(r)); \ 696 }) 697 #define W_REG(osh, r, v) do { \ 698 BCM_REFERENCE(osh); \ 699 switch (sizeof(*(r))) { \ 700 case sizeof(uint8): osl_writeb((uint8)(v), (volatile uint8*)(r)); break; \ 701 case sizeof(uint16): osl_writew((uint16)(v), (volatile uint16*)(r)); break; \ 702 case sizeof(uint32): osl_writel((uint32)(v), (volatile uint32*)(r)); break; \ 703 case sizeof(uint64): osl_writeq((uint64)(v), (volatile uint64*)(r)); break; \ 704 } \ 705 } while (0) 706 707 #else 708 #define R_REG(osh, r) OSL_READ_REG(osh, r) 709 #define W_REG(osh, r, v) do { OSL_WRITE_REG(osh, r, v); } while (0) 710 #endif /* !defined(BCMSDIO) */ 711 712 #define AND_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) & (v)) 713 #define OR_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) | (v)) 714 extern uint8 osl_readb(volatile uint8 *r); 715 extern uint16 osl_readw(volatile uint16 *r); 716 extern uint32 osl_readl(volatile uint32 *r); 717 extern uint64 osl_readq(volatile uint64 *r); 718 extern void osl_writeb(uint8 v, volatile uint8 *r); 719 extern void osl_writew(uint16 v, volatile uint16 *r); 720 extern void osl_writel(uint32 v, volatile uint32 *r); 721 extern void osl_writeq(uint64 v, volatile uint64 *r); 722 723 /* system up time in ms */ 724 #define OSL_SYSUPTIME() osl_sysuptime() 725 extern uint32 osl_sysuptime(void); 726 727 /* uncached/cached virtual address */ 728 #define OSL_UNCACHED(va) osl_uncached((va)) 729 extern void *osl_uncached(void *va); 730 #define OSL_CACHED(va) osl_cached((va)) 731 extern void *osl_cached(void *va); 732 733 #define OSL_PREF_RANGE_LD(va, sz) 734 #define OSL_PREF_RANGE_ST(va, sz) 735 736 /* get processor cycle count */ 737 #define OSL_GETCYCLES(x) ((x) = osl_getcycles()) 738 extern uint osl_getcycles(void); 739 740 /* dereference an address that may target abort */ 741 #define BUSPROBE(val, addr) osl_busprobe(&(val), (addr)) 742 extern int osl_busprobe(uint32 *val, uint32 addr); 743 744 /* map/unmap physical to virtual */ 745 #define REG_MAP(pa, size) osl_reg_map((pa), (size)) 746 #define REG_UNMAP(va) osl_reg_unmap((va)) 747 extern void *osl_reg_map(uint32 pa, uint size); 748 extern void osl_reg_unmap(void *va); 749 750 /* shared (dma-able) memory access macros */ 751 #define R_SM(r) *(r) 752 #define W_SM(r, v) (*(r) = (v)) 753 #define OR_SM(r, v) (*(r) |= (v)) 754 #define BZERO_SM(r, len) bzero((r), (len)) 755 756 #endif /* BINOSL */ 757 758 #define OSL_RAND() osl_rand() 759 extern uint32 osl_rand(void); 760 761 #define DMA_FLUSH(osh, va, size, direction, p, dmah) \ 762 osl_dma_flush((osh), (va), (size), (direction), (p), (dmah)) 763 #define DMA_MAP(osh, va, size, direction, p, dmah) \ 764 osl_dma_map((osh), (va), (size), (direction), (p), (dmah)) 765 766 #else /* ! BCMDRIVER */ 767 768 /* ASSERT */ 769 #ifdef BCMDBG_ASSERT 770 #include <assert.h> 771 #define ASSERT assert 772 #else /* BCMDBG_ASSERT */ 773 #define ASSERT(exp) do {} while (0) 774 #endif /* BCMDBG_ASSERT */ 775 776 #define ASSERT_FP(exp) ASSERT(exp) 777 778 /* MALLOC and MFREE */ 779 #define MALLOC(o, l) malloc(l) 780 #define MFREE(o, p, l) free(p) 781 #include <stdlib.h> 782 783 /* str* and mem* functions */ 784 #include <string.h> 785 786 /* *printf functions */ 787 #include <stdio.h> 788 789 /* bcopy, bcmp, and bzero */ 790 extern void bcopy(const void *src, void *dst, size_t len); 791 extern int bcmp(const void *b1, const void *b2, size_t len); 792 extern void bzero(void *b, size_t len); 793 #endif /* ! BCMDRIVER */ 794 795 typedef struct sk_buff_head PKT_LIST; 796 #define PKTLIST_INIT(x) skb_queue_head_init((x)) 797 #define PKTLIST_ENQ(x, y) skb_queue_head((struct sk_buff_head *)(x), (struct sk_buff *)(y)) 798 #define PKTLIST_DEQ(x) skb_dequeue((struct sk_buff_head *)(x)) 799 #define PKTLIST_UNLINK(x, y) skb_unlink((struct sk_buff *)(y), (struct sk_buff_head *)(x)) 800 #define PKTLIST_FINI(x) skb_queue_purge((struct sk_buff_head *)(x)) 801 802 #ifndef _linuxver_h_ 803 typedef struct timer_list_compat timer_list_compat_t; 804 #endif /* _linuxver_h_ */ 805 typedef struct osl_timer { 806 timer_list_compat_t *timer; 807 bool set; 808 #ifdef BCMDBG 809 char *name; /* Desription of the timer */ 810 #endif 811 } osl_timer_t; 812 813 typedef void (*linux_timer_fn)(ulong arg); 814 815 extern osl_timer_t * osl_timer_init(osl_t *osh, const char *name, void (*fn)(void *arg), void *arg); 816 extern void osl_timer_add(osl_t *osh, osl_timer_t *t, uint32 ms, bool periodic); 817 extern void osl_timer_update(osl_t *osh, osl_timer_t *t, uint32 ms, bool periodic); 818 extern bool osl_timer_del(osl_t *osh, osl_timer_t *t); 819 820 #ifdef BCMDRIVER 821 typedef atomic_t osl_atomic_t; 822 #define OSL_ATOMIC_SET(osh, v, x) atomic_set(v, x) 823 #define OSL_ATOMIC_INIT(osh, v) atomic_set(v, 0) 824 #define OSL_ATOMIC_INC(osh, v) atomic_inc(v) 825 #define OSL_ATOMIC_INC_RETURN(osh, v) atomic_inc_return(v) 826 #define OSL_ATOMIC_DEC(osh, v) atomic_dec(v) 827 #define OSL_ATOMIC_DEC_RETURN(osh, v) atomic_dec_return(v) 828 #define OSL_ATOMIC_READ(osh, v) atomic_read(v) 829 #define OSL_ATOMIC_ADD(osh, v, x) atomic_add(v, x) 830 831 #ifndef atomic_set_mask 832 #define OSL_ATOMIC_OR(osh, v, x) atomic_or(x, v) 833 #define OSL_ATOMIC_AND(osh, v, x) atomic_and(x, v) 834 #else 835 #define OSL_ATOMIC_OR(osh, v, x) atomic_set_mask(x, v) 836 #define OSL_ATOMIC_AND(osh, v, x) atomic_clear_mask(~x, v) 837 #endif 838 #endif /* BCMDRIVER */ 839 840 extern void *osl_spin_lock_init(osl_t *osh); 841 extern void osl_spin_lock_deinit(osl_t *osh, void *lock); 842 extern unsigned long osl_spin_lock(void *lock); 843 extern void osl_spin_unlock(void *lock, unsigned long flags); 844 extern unsigned long osl_spin_lock_irq(void *lock); 845 extern void osl_spin_unlock_irq(void *lock, unsigned long flags); 846 extern unsigned long osl_spin_lock_bh(void *lock); 847 extern void osl_spin_unlock_bh(void *lock, unsigned long flags); 848 849 extern void *osl_mutex_lock_init(osl_t *osh); 850 extern void osl_mutex_lock_deinit(osl_t *osh, void *lock); 851 extern unsigned long osl_mutex_lock(void *lock); 852 void osl_mutex_unlock(void *lock, unsigned long flags); 853 854 typedef struct osl_timespec { 855 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)) 856 __kernel_old_time_t tv_sec; /* seconds */ 857 #else 858 __kernel_time_t tv_sec; /* seconds */ 859 #endif 860 __kernel_suseconds_t tv_usec; /* microseconds */ 861 long tv_nsec; /* nanoseconds */ 862 } osl_timespec_t; 863 extern void osl_do_gettimeofday(struct osl_timespec *ts); 864 extern void osl_get_monotonic_boottime(struct osl_timespec *ts); 865 extern uint32 osl_do_gettimediff(struct osl_timespec *cur_ts, struct osl_timespec *old_ts); 866 #endif /* _linux_osl_h_ */ 867