diff options
Diffstat (limited to 'drivers/net/wireless/bcm4329/linux_osl.c')
| -rw-r--r-- | drivers/net/wireless/bcm4329/linux_osl.c | 625 |
1 files changed, 625 insertions, 0 deletions
diff --git a/drivers/net/wireless/bcm4329/linux_osl.c b/drivers/net/wireless/bcm4329/linux_osl.c new file mode 100644 index 00000000000..cf72a077bd9 --- /dev/null +++ b/drivers/net/wireless/bcm4329/linux_osl.c | |||
| @@ -0,0 +1,625 @@ | |||
| 1 | /* | ||
| 2 | * Linux OS Independent Layer | ||
| 3 | * | ||
| 4 | * Copyright (C) 1999-2010, Broadcom Corporation | ||
| 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 | * $Id: linux_osl.c,v 1.125.12.3.8.7 2010/05/04 21:10:04 Exp $ | ||
| 25 | */ | ||
| 26 | |||
| 27 | |||
| 28 | #define LINUX_OSL | ||
| 29 | |||
| 30 | #include <typedefs.h> | ||
| 31 | #include <bcmendian.h> | ||
| 32 | #include <linuxver.h> | ||
| 33 | #include <bcmdefs.h> | ||
| 34 | #include <osl.h> | ||
| 35 | #include <bcmutils.h> | ||
| 36 | #include <linux/delay.h> | ||
| 37 | #include <pcicfg.h> | ||
| 38 | #include <linux/mutex.h> | ||
| 39 | |||
| 40 | #define PCI_CFG_RETRY 10 | ||
| 41 | |||
| 42 | #define OS_HANDLE_MAGIC 0x1234abcd | ||
| 43 | #define BCM_MEM_FILENAME_LEN 24 | ||
| 44 | |||
| 45 | #ifdef DHD_USE_STATIC_BUF | ||
| 46 | #define MAX_STATIC_BUF_NUM 16 | ||
| 47 | #define STATIC_BUF_SIZE (PAGE_SIZE*2) | ||
| 48 | #define STATIC_BUF_TOTAL_LEN (MAX_STATIC_BUF_NUM*STATIC_BUF_SIZE) | ||
| 49 | typedef struct bcm_static_buf { | ||
| 50 | struct mutex static_sem; | ||
| 51 | unsigned char *buf_ptr; | ||
| 52 | unsigned char buf_use[MAX_STATIC_BUF_NUM]; | ||
| 53 | } bcm_static_buf_t; | ||
| 54 | |||
| 55 | static bcm_static_buf_t *bcm_static_buf = 0; | ||
| 56 | |||
| 57 | #define MAX_STATIC_PKT_NUM 8 | ||
| 58 | typedef struct bcm_static_pkt { | ||
| 59 | struct sk_buff *skb_4k[MAX_STATIC_PKT_NUM]; | ||
| 60 | struct sk_buff *skb_8k[MAX_STATIC_PKT_NUM]; | ||
| 61 | struct mutex osl_pkt_sem; | ||
| 62 | unsigned char pkt_use[MAX_STATIC_PKT_NUM*2]; | ||
| 63 | } bcm_static_pkt_t; | ||
| 64 | static bcm_static_pkt_t *bcm_static_skb = 0; | ||
| 65 | |||
| 66 | #endif | ||
| 67 | typedef struct bcm_mem_link { | ||
| 68 | struct bcm_mem_link *prev; | ||
| 69 | struct bcm_mem_link *next; | ||
| 70 | uint size; | ||
| 71 | int line; | ||
| 72 | char file[BCM_MEM_FILENAME_LEN]; | ||
| 73 | } bcm_mem_link_t; | ||
| 74 | |||
| 75 | struct osl_info { | ||
| 76 | osl_pubinfo_t pub; | ||
| 77 | uint magic; | ||
| 78 | void *pdev; | ||
| 79 | uint malloced; | ||
| 80 | uint failed; | ||
| 81 | uint bustype; | ||
| 82 | bcm_mem_link_t *dbgmem_list; | ||
| 83 | }; | ||
| 84 | |||
| 85 | static int16 linuxbcmerrormap[] = | ||
| 86 | { 0, | ||
| 87 | -EINVAL, | ||
| 88 | -EINVAL, | ||
| 89 | -EINVAL, | ||
| 90 | -EINVAL, | ||
| 91 | -EINVAL, | ||
| 92 | -EINVAL, | ||
| 93 | -EINVAL, | ||
| 94 | -EINVAL, | ||
| 95 | -EINVAL, | ||
| 96 | -EINVAL, | ||
| 97 | -EINVAL, | ||
| 98 | -EINVAL, | ||
| 99 | -EINVAL, | ||
| 100 | -E2BIG, | ||
| 101 | -E2BIG, | ||
| 102 | -EBUSY, | ||
| 103 | -EINVAL, | ||
| 104 | -EINVAL, | ||
| 105 | -EINVAL, | ||
| 106 | -EINVAL, | ||
| 107 | -EFAULT, | ||
| 108 | -ENOMEM, | ||
| 109 | -EOPNOTSUPP, | ||
| 110 | -EMSGSIZE, | ||
| 111 | -EINVAL, | ||
| 112 | -EPERM, | ||
| 113 | -ENOMEM, | ||
| 114 | -EINVAL, | ||
| 115 | -ERANGE, | ||
| 116 | -EINVAL, | ||
| 117 | -EINVAL, | ||
| 118 | -EINVAL, | ||
| 119 | -EINVAL, | ||
| 120 | -EINVAL, | ||
| 121 | -EIO, | ||
| 122 | -ENODEV, | ||
| 123 | -EINVAL, | ||
| 124 | -EIO, | ||
| 125 | -EIO, | ||
| 126 | -EINVAL, | ||
| 127 | -EINVAL, | ||
| 128 | |||
| 129 | |||
| 130 | |||
| 131 | #if BCME_LAST != -41 | ||
| 132 | #error "You need to add a OS error translation in the linuxbcmerrormap \ | ||
| 133 | for new error code defined in bcmutils.h" | ||
| 134 | #endif | ||
| 135 | }; | ||
| 136 | |||
| 137 | |||
| 138 | int | ||
| 139 | osl_error(int bcmerror) | ||
| 140 | { | ||
| 141 | if (bcmerror > 0) | ||
| 142 | bcmerror = 0; | ||
| 143 | else if (bcmerror < BCME_LAST) | ||
| 144 | bcmerror = BCME_ERROR; | ||
| 145 | |||
| 146 | |||
| 147 | return linuxbcmerrormap[-bcmerror]; | ||
| 148 | } | ||
| 149 | |||
| 150 | void * dhd_os_prealloc(int section, unsigned long size); | ||
| 151 | osl_t * | ||
| 152 | osl_attach(void *pdev, uint bustype, bool pkttag) | ||
| 153 | { | ||
| 154 | osl_t *osh; | ||
| 155 | gfp_t flags; | ||
| 156 | |||
| 157 | flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL; | ||
| 158 | osh = kmalloc(sizeof(osl_t), flags); | ||
| 159 | ASSERT(osh); | ||
| 160 | |||
| 161 | bzero(osh, sizeof(osl_t)); | ||
| 162 | |||
| 163 | |||
| 164 | ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(linuxbcmerrormap) - 1)); | ||
| 165 | |||
| 166 | osh->magic = OS_HANDLE_MAGIC; | ||
| 167 | osh->malloced = 0; | ||
| 168 | osh->failed = 0; | ||
| 169 | osh->dbgmem_list = NULL; | ||
| 170 | osh->pdev = pdev; | ||
| 171 | osh->pub.pkttag = pkttag; | ||
| 172 | osh->bustype = bustype; | ||
| 173 | |||
| 174 | switch (bustype) { | ||
| 175 | case PCI_BUS: | ||
| 176 | case SI_BUS: | ||
| 177 | case PCMCIA_BUS: | ||
| 178 | osh->pub.mmbus = TRUE; | ||
| 179 | break; | ||
| 180 | case JTAG_BUS: | ||
| 181 | case SDIO_BUS: | ||
| 182 | case USB_BUS: | ||
| 183 | case SPI_BUS: | ||
| 184 | osh->pub.mmbus = FALSE; | ||
| 185 | break; | ||
| 186 | default: | ||
| 187 | ASSERT(FALSE); | ||
| 188 | break; | ||
| 189 | } | ||
| 190 | |||
| 191 | #ifdef DHD_USE_STATIC_BUF | ||
| 192 | |||
| 193 | |||
| 194 | if (!bcm_static_buf) { | ||
| 195 | if (!(bcm_static_buf = (bcm_static_buf_t *)dhd_os_prealloc(3, STATIC_BUF_SIZE+ | ||
| 196 | STATIC_BUF_TOTAL_LEN))) { | ||
| 197 | printk("can not alloc static buf!\n"); | ||
| 198 | } | ||
| 199 | else { | ||
| 200 | /* printk("alloc static buf at %x!\n", (unsigned int)bcm_static_buf); */ | ||
| 201 | } | ||
| 202 | |||
| 203 | mutex_init(&bcm_static_buf->static_sem); | ||
| 204 | |||
| 205 | |||
| 206 | bcm_static_buf->buf_ptr = (unsigned char *)bcm_static_buf + STATIC_BUF_SIZE; | ||
| 207 | |||
| 208 | } | ||
| 209 | |||
| 210 | if (!bcm_static_skb) | ||
| 211 | { | ||
| 212 | int i; | ||
| 213 | void *skb_buff_ptr = 0; | ||
| 214 | bcm_static_skb = (bcm_static_pkt_t *)((char *)bcm_static_buf + 2048); | ||
| 215 | skb_buff_ptr = dhd_os_prealloc(4, 0); | ||
| 216 | |||
| 217 | bcopy(skb_buff_ptr, bcm_static_skb, sizeof(struct sk_buff *)*16); | ||
| 218 | for (i = 0; i < MAX_STATIC_PKT_NUM*2; i++) | ||
| 219 | bcm_static_skb->pkt_use[i] = 0; | ||
| 220 | |||
| 221 | mutex_init(&bcm_static_skb->osl_pkt_sem); | ||
| 222 | } | ||
| 223 | #endif | ||
| 224 | return osh; | ||
| 225 | } | ||
| 226 | |||
| 227 | void | ||
| 228 | osl_detach(osl_t *osh) | ||
| 229 | { | ||
| 230 | if (osh == NULL) | ||
| 231 | return; | ||
| 232 | |||
| 233 | #ifdef DHD_USE_STATIC_BUF | ||
| 234 | if (bcm_static_buf) { | ||
| 235 | bcm_static_buf = 0; | ||
| 236 | } | ||
| 237 | if (bcm_static_skb) { | ||
| 238 | bcm_static_skb = 0; | ||
| 239 | } | ||
| 240 | #endif | ||
| 241 | ASSERT(osh->magic == OS_HANDLE_MAGIC); | ||
| 242 | kfree(osh); | ||
| 243 | } | ||
| 244 | |||
| 245 | |||
| 246 | void* | ||
| 247 | osl_pktget(osl_t *osh, uint len) | ||
| 248 | { | ||
| 249 | struct sk_buff *skb; | ||
| 250 | gfp_t flags; | ||
| 251 | |||
| 252 | flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL; | ||
| 253 | if ((skb = __dev_alloc_skb(len, flags))) { | ||
| 254 | skb_put(skb, len); | ||
| 255 | skb->priority = 0; | ||
| 256 | |||
| 257 | |||
| 258 | osh->pub.pktalloced++; | ||
| 259 | } | ||
| 260 | |||
| 261 | return ((void*) skb); | ||
| 262 | } | ||
| 263 | |||
| 264 | |||
| 265 | void | ||
| 266 | osl_pktfree(osl_t *osh, void *p, bool send) | ||
| 267 | { | ||
| 268 | struct sk_buff *skb, *nskb; | ||
| 269 | |||
| 270 | skb = (struct sk_buff*) p; | ||
| 271 | |||
| 272 | if (send && osh->pub.tx_fn) | ||
| 273 | osh->pub.tx_fn(osh->pub.tx_ctx, p, 0); | ||
| 274 | |||
| 275 | |||
| 276 | while (skb) { | ||
| 277 | nskb = skb->next; | ||
| 278 | skb->next = NULL; | ||
| 279 | |||
| 280 | |||
| 281 | if (skb->destructor) { | ||
| 282 | |||
| 283 | dev_kfree_skb_any(skb); | ||
| 284 | } else { | ||
| 285 | |||
| 286 | dev_kfree_skb(skb); | ||
| 287 | } | ||
| 288 | |||
| 289 | osh->pub.pktalloced--; | ||
| 290 | |||
| 291 | skb = nskb; | ||
| 292 | } | ||
| 293 | } | ||
| 294 | |||
| 295 | #ifdef DHD_USE_STATIC_BUF | ||
| 296 | void* | ||
| 297 | osl_pktget_static(osl_t *osh, uint len) | ||
| 298 | { | ||
| 299 | int i = 0; | ||
| 300 | struct sk_buff *skb; | ||
| 301 | |||
| 302 | |||
| 303 | if (len > (PAGE_SIZE*2)) | ||
| 304 | { | ||
| 305 | printk("Do we really need this big skb??\n"); | ||
| 306 | return osl_pktget(osh, len); | ||
| 307 | } | ||
| 308 | |||
| 309 | |||
| 310 | mutex_lock(&bcm_static_skb->osl_pkt_sem); | ||
| 311 | if (len <= PAGE_SIZE) | ||
| 312 | { | ||
| 313 | |||
| 314 | for (i = 0; i < MAX_STATIC_PKT_NUM; i++) | ||
| 315 | { | ||
| 316 | if (bcm_static_skb->pkt_use[i] == 0) | ||
| 317 | break; | ||
| 318 | } | ||
| 319 | |||
| 320 | if (i != MAX_STATIC_PKT_NUM) | ||
| 321 | { | ||
| 322 | bcm_static_skb->pkt_use[i] = 1; | ||
| 323 | mutex_unlock(&bcm_static_skb->osl_pkt_sem); | ||
| 324 | |||
| 325 | skb = bcm_static_skb->skb_4k[i]; | ||
| 326 | skb->tail = skb->data + len; | ||
| 327 | skb->len = len; | ||
| 328 | |||
| 329 | return skb; | ||
| 330 | } | ||
| 331 | } | ||
| 332 | |||
| 333 | |||
| 334 | for (i = 0; i < MAX_STATIC_PKT_NUM; i++) | ||
| 335 | { | ||
| 336 | if (bcm_static_skb->pkt_use[i+MAX_STATIC_PKT_NUM] == 0) | ||
| 337 | break; | ||
| 338 | } | ||
| 339 | |||
| 340 | if (i != MAX_STATIC_PKT_NUM) | ||
| 341 | { | ||
| 342 | bcm_static_skb->pkt_use[i+MAX_STATIC_PKT_NUM] = 1; | ||
| 343 | mutex_unlock(&bcm_static_skb->osl_pkt_sem); | ||
| 344 | skb = bcm_static_skb->skb_8k[i]; | ||
| 345 | skb->tail = skb->data + len; | ||
| 346 | skb->len = len; | ||
| 347 | |||
| 348 | return skb; | ||
| 349 | } | ||
| 350 | |||
| 351 | |||
| 352 | |||
| 353 | mutex_unlock(&bcm_static_skb->osl_pkt_sem); | ||
| 354 | printk("all static pkt in use!\n"); | ||
| 355 | return osl_pktget(osh, len); | ||
| 356 | } | ||
| 357 | |||
| 358 | |||
| 359 | void | ||
| 360 | osl_pktfree_static(osl_t *osh, void *p, bool send) | ||
| 361 | { | ||
| 362 | int i; | ||
| 363 | |||
| 364 | for (i = 0; i < MAX_STATIC_PKT_NUM*2; i++) | ||
| 365 | { | ||
| 366 | if (p == bcm_static_skb->skb_4k[i]) | ||
| 367 | { | ||
| 368 | mutex_lock(&bcm_static_skb->osl_pkt_sem); | ||
| 369 | bcm_static_skb->pkt_use[i] = 0; | ||
| 370 | mutex_unlock(&bcm_static_skb->osl_pkt_sem); | ||
| 371 | |||
| 372 | |||
| 373 | return; | ||
| 374 | } | ||
| 375 | } | ||
| 376 | return osl_pktfree(osh, p, send); | ||
| 377 | } | ||
| 378 | #endif | ||
| 379 | uint32 | ||
| 380 | osl_pci_read_config(osl_t *osh, uint offset, uint size) | ||
| 381 | { | ||
| 382 | uint val = 0; | ||
| 383 | uint retry = PCI_CFG_RETRY; | ||
| 384 | |||
| 385 | ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); | ||
| 386 | |||
| 387 | |||
| 388 | ASSERT(size == 4); | ||
| 389 | |||
| 390 | do { | ||
| 391 | pci_read_config_dword(osh->pdev, offset, &val); | ||
| 392 | if (val != 0xffffffff) | ||
| 393 | break; | ||
| 394 | } while (retry--); | ||
| 395 | |||
| 396 | |||
| 397 | return (val); | ||
| 398 | } | ||
| 399 | |||
| 400 | void | ||
| 401 | osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val) | ||
| 402 | { | ||
| 403 | uint retry = PCI_CFG_RETRY; | ||
| 404 | |||
| 405 | ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); | ||
| 406 | |||
| 407 | |||
| 408 | ASSERT(size == 4); | ||
| 409 | |||
| 410 | do { | ||
| 411 | pci_write_config_dword(osh->pdev, offset, val); | ||
| 412 | if (offset != PCI_BAR0_WIN) | ||
| 413 | break; | ||
| 414 | if (osl_pci_read_config(osh, offset, size) == val) | ||
| 415 | break; | ||
| 416 | } while (retry--); | ||
| 417 | |||
| 418 | } | ||
| 419 | |||
| 420 | |||
| 421 | uint | ||
| 422 | osl_pci_bus(osl_t *osh) | ||
| 423 | { | ||
| 424 | ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev); | ||
| 425 | |||
| 426 | return ((struct pci_dev *)osh->pdev)->bus->number; | ||
| 427 | } | ||
| 428 | |||
| 429 | |||
| 430 | uint | ||
| 431 | osl_pci_slot(osl_t *osh) | ||
| 432 | { | ||
| 433 | ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev); | ||
| 434 | |||
| 435 | return PCI_SLOT(((struct pci_dev *)osh->pdev)->devfn); | ||
| 436 | } | ||
| 437 | |||
| 438 | static void | ||
| 439 | osl_pcmcia_attr(osl_t *osh, uint offset, char *buf, int size, bool write) | ||
| 440 | { | ||
| 441 | } | ||
| 442 | |||
| 443 | void | ||
| 444 | osl_pcmcia_read_attr(osl_t *osh, uint offset, void *buf, int size) | ||
| 445 | { | ||
| 446 | osl_pcmcia_attr(osh, offset, (char *) buf, size, FALSE); | ||
| 447 | } | ||
| 448 | |||
| 449 | void | ||
| 450 | osl_pcmcia_write_attr(osl_t *osh, uint offset, void *buf, int size) | ||
| 451 | { | ||
| 452 | osl_pcmcia_attr(osh, offset, (char *) buf, size, TRUE); | ||
| 453 | } | ||
| 454 | |||
| 455 | |||
| 456 | |||
| 457 | void* | ||
| 458 | osl_malloc(osl_t *osh, uint size) | ||
| 459 | { | ||
| 460 | void *addr; | ||
| 461 | gfp_t flags; | ||
| 462 | |||
| 463 | if (osh) | ||
| 464 | ASSERT(osh->magic == OS_HANDLE_MAGIC); | ||
| 465 | |||
| 466 | #ifdef DHD_USE_STATIC_BUF | ||
| 467 | if (bcm_static_buf) | ||
| 468 | { | ||
| 469 | int i = 0; | ||
| 470 | if ((size >= PAGE_SIZE)&&(size <= STATIC_BUF_SIZE)) | ||
| 471 | { | ||
| 472 | mutex_lock(&bcm_static_buf->static_sem); | ||
| 473 | |||
| 474 | for (i = 0; i < MAX_STATIC_BUF_NUM; i++) | ||
| 475 | { | ||
| 476 | if (bcm_static_buf->buf_use[i] == 0) | ||
| 477 | break; | ||
| 478 | } | ||
| 479 | |||
| 480 | if (i == MAX_STATIC_BUF_NUM) | ||
| 481 | { | ||
| 482 | mutex_unlock(&bcm_static_buf->static_sem); | ||
| 483 | printk("all static buff in use!\n"); | ||
| 484 | goto original; | ||
| 485 | } | ||
| 486 | |||
| 487 | bcm_static_buf->buf_use[i] = 1; | ||
| 488 | mutex_unlock(&bcm_static_buf->static_sem); | ||
| 489 | |||
| 490 | bzero(bcm_static_buf->buf_ptr+STATIC_BUF_SIZE*i, size); | ||
| 491 | if (osh) | ||
| 492 | osh->malloced += size; | ||
| 493 | |||
| 494 | return ((void *)(bcm_static_buf->buf_ptr+STATIC_BUF_SIZE*i)); | ||
| 495 | } | ||
| 496 | } | ||
| 497 | original: | ||
| 498 | #endif | ||
| 499 | flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL; | ||
| 500 | if ((addr = kmalloc(size, flags)) == NULL) { | ||
| 501 | if (osh) | ||
| 502 | osh->failed++; | ||
| 503 | return (NULL); | ||
| 504 | } | ||
| 505 | if (osh) | ||
| 506 | osh->malloced += size; | ||
| 507 | |||
| 508 | return (addr); | ||
| 509 | } | ||
| 510 | |||
| 511 | void | ||
| 512 | osl_mfree(osl_t *osh, void *addr, uint size) | ||
| 513 | { | ||
| 514 | #ifdef DHD_USE_STATIC_BUF | ||
| 515 | if (bcm_static_buf) | ||
| 516 | { | ||
| 517 | if ((addr > (void *)bcm_static_buf) && ((unsigned char *)addr | ||
| 518 | <= ((unsigned char *)bcm_static_buf + STATIC_BUF_TOTAL_LEN))) | ||
| 519 | { | ||
| 520 | int buf_idx = 0; | ||
| 521 | |||
| 522 | buf_idx = ((unsigned char *)addr - bcm_static_buf->buf_ptr)/STATIC_BUF_SIZE; | ||
| 523 | |||
| 524 | mutex_lock(&bcm_static_buf->static_sem); | ||
| 525 | bcm_static_buf->buf_use[buf_idx] = 0; | ||
| 526 | mutex_unlock(&bcm_static_buf->static_sem); | ||
| 527 | |||
| 528 | if (osh) { | ||
| 529 | ASSERT(osh->magic == OS_HANDLE_MAGIC); | ||
| 530 | osh->malloced -= size; | ||
| 531 | } | ||
| 532 | return; | ||
| 533 | } | ||
| 534 | } | ||
| 535 | #endif | ||
| 536 | if (osh) { | ||
| 537 | ASSERT(osh->magic == OS_HANDLE_MAGIC); | ||
| 538 | osh->malloced -= size; | ||
| 539 | } | ||
| 540 | kfree(addr); | ||
| 541 | } | ||
| 542 | |||
| 543 | uint | ||
| 544 | osl_malloced(osl_t *osh) | ||
| 545 | { | ||
| 546 | ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); | ||
| 547 | return (osh->malloced); | ||
| 548 | } | ||
| 549 | |||
| 550 | uint | ||
| 551 | osl_malloc_failed(osl_t *osh) | ||
| 552 | { | ||
| 553 | ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); | ||
| 554 | return (osh->failed); | ||
| 555 | } | ||
| 556 | |||
| 557 | void* | ||
| 558 | osl_dma_alloc_consistent(osl_t *osh, uint size, ulong *pap) | ||
| 559 | { | ||
| 560 | ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); | ||
| 561 | |||
| 562 | return (pci_alloc_consistent(osh->pdev, size, (dma_addr_t*)pap)); | ||
| 563 | } | ||
| 564 | |||
| 565 | void | ||
| 566 | osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa) | ||
| 567 | { | ||
| 568 | ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); | ||
| 569 | |||
| 570 | pci_free_consistent(osh->pdev, size, va, (dma_addr_t)pa); | ||
| 571 | } | ||
| 572 | |||
| 573 | uint | ||
| 574 | osl_dma_map(osl_t *osh, void *va, uint size, int direction) | ||
| 575 | { | ||
| 576 | int dir; | ||
| 577 | |||
| 578 | ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); | ||
| 579 | dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE; | ||
| 580 | return (pci_map_single(osh->pdev, va, size, dir)); | ||
| 581 | } | ||
| 582 | |||
| 583 | void | ||
| 584 | osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction) | ||
| 585 | { | ||
| 586 | int dir; | ||
| 587 | |||
| 588 | ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); | ||
| 589 | dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE; | ||
| 590 | pci_unmap_single(osh->pdev, (uint32)pa, size, dir); | ||
| 591 | } | ||
| 592 | |||
| 593 | |||
| 594 | void | ||
| 595 | osl_delay(uint usec) | ||
| 596 | { | ||
| 597 | uint d; | ||
| 598 | |||
| 599 | while (usec > 0) { | ||
| 600 | d = MIN(usec, 1000); | ||
| 601 | udelay(d); | ||
| 602 | usec -= d; | ||
| 603 | } | ||
| 604 | } | ||
| 605 | |||
| 606 | |||
| 607 | |||
| 608 | void * | ||
| 609 | osl_pktdup(osl_t *osh, void *skb) | ||
| 610 | { | ||
| 611 | void * p; | ||
| 612 | gfp_t flags; | ||
| 613 | |||
| 614 | flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL; | ||
| 615 | if ((p = skb_clone((struct sk_buff*)skb, flags)) == NULL) | ||
| 616 | return NULL; | ||
| 617 | |||
| 618 | |||
| 619 | if (osh->pub.pkttag) | ||
| 620 | bzero((void*)((struct sk_buff *)p)->cb, OSL_PKTTAG_SZ); | ||
| 621 | |||
| 622 | |||
| 623 | osh->pub.pktalloced++; | ||
| 624 | return (p); | ||
| 625 | } | ||
