1 /*- 2 * Copyright (c) 2011 Semihalf. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 #include <sys/param.h> 28 #include <sys/systm.h> 29 #include <sys/kernel.h> 30 #include <sys/malloc.h> 31 #include <sys/bus.h> 32 #include <sys/interrupt.h> 33 #include <sys/lock.h> 34 #include <sys/mutex.h> 35 #include <sys/proc.h> 36 #include <sys/queue.h> 37 #include <sys/rman.h> 38 #include <sys/sched.h> 39 #include <sys/smp.h> 40 41 #include <vm/vm.h> 42 #include <vm/vm_param.h> 43 #include <vm/vm_page.h> 44 45 #include <machine/cpufunc.h> 46 #include <machine/intr_machdep.h> 47 #include <machine/pmap.h> 48 #include <machine/stdarg.h> 49 50 #include <dev/dpaa/bman.h> 51 #include <dev/dpaa/qman.h> 52 #include <dev/dpaa/portals.h> 53 54 #include <powerpc/mpc85xx/mpc85xx.h> 55 #include "error_ext.h" 56 #include "std_ext.h" 57 #include "list_ext.h" 58 #include "mm_ext.h" 59 60 /* Configuration */ 61 62 /* Define the number of dTSEC ports active in system */ 63 #define MALLOCSMART_DTSEC_IN_USE 4 64 65 /* 66 * Calculate malloc's pool size for dTSEC's buffers. 67 * We reserve 1MB pool for each dTSEC port. 68 */ 69 #define MALLOCSMART_POOL_SIZE \ 70 (MALLOCSMART_DTSEC_IN_USE * 1024 * 1024) 71 72 #define MALLOCSMART_SLICE_SIZE (PAGE_SIZE / 2) /* 2kB */ 73 74 /* Defines */ 75 #define MALLOCSMART_SIZE_TO_SLICE(x) \ 76 (((x) + MALLOCSMART_SLICE_SIZE - 1) / MALLOCSMART_SLICE_SIZE) 77 #define MALLOCSMART_SLICES \ 78 MALLOCSMART_SIZE_TO_SLICE(MALLOCSMART_POOL_SIZE) 79 80 /* Malloc Pool for NetCommSW */ 81 MALLOC_DEFINE(M_NETCOMMSW, "NetCommSW", "NetCommSW software stack"); 82 MALLOC_DEFINE(M_NETCOMMSW_MT, "NetCommSWTrack", 83 "NetCommSW software allocation tracker"); 84 85 /* MallocSmart data structures */ 86 static void *XX_MallocSmartPool; 87 static int XX_MallocSmartMap[MALLOCSMART_SLICES]; 88 89 static struct mtx XX_MallocSmartLock; 90 static struct mtx XX_MallocTrackLock; 91 MTX_SYSINIT(XX_MallocSmartLockInit, &XX_MallocSmartLock, 92 "NetCommSW MallocSmart Lock", MTX_DEF); 93 MTX_SYSINIT(XX_MallocTrackLockInit, &XX_MallocTrackLock, 94 "NetCommSW MallocTrack Lock", MTX_DEF); 95 96 /* Interrupt info */ 97 #define XX_INTR_FLAG_PREALLOCATED (1 << 0) 98 99 struct XX_IntrInfo { 100 driver_intr_t *handler; 101 void *arg; 102 int cpu; 103 int flags; 104 void *cookie; 105 }; 106 107 static struct XX_IntrInfo XX_IntrInfo[INTR_VECTORS]; 108 /* Portal type identifiers */ 109 enum XX_PortalIdent{ 110 BM_PORTAL = 0, 111 QM_PORTAL, 112 }; 113 /* Structure to store portals' properties */ 114 struct XX_PortalInfo { 115 vm_paddr_t portal_ce_pa[2][MAXCPU]; 116 vm_paddr_t portal_ci_pa[2][MAXCPU]; 117 uint32_t portal_ce_size[2][MAXCPU]; 118 uint32_t portal_ci_size[2][MAXCPU]; 119 vm_offset_t portal_ce_va[2]; 120 vm_offset_t portal_ci_va[2]; 121 uintptr_t portal_intr[2][MAXCPU]; 122 }; 123 124 static struct XX_PortalInfo XX_PInfo; 125 126 void 127 XX_Exit(int status) 128 { 129 130 panic("NetCommSW: Exit called with status %i", status); 131 } 132 133 void 134 XX_Print(char *str, ...) 135 { 136 va_list ap; 137 138 va_start(ap, str); 139 vprintf(str, ap); 140 va_end(ap); 141 } 142 143 void * 144 XX_Malloc(uint32_t size) 145 { 146 void *p = (malloc(size, M_NETCOMMSW, M_NOWAIT)); 147 148 return (p); 149 } 150 151 static int 152 XX_MallocSmartMapCheck(unsigned int start, unsigned int slices) 153 { 154 unsigned int i; 155 156 mtx_assert(&XX_MallocSmartLock, MA_OWNED); 157 for (i = start; i < start + slices; i++) 158 if (XX_MallocSmartMap[i]) 159 return (FALSE); 160 return (TRUE); 161 } 162 163 static void 164 XX_MallocSmartMapSet(unsigned int start, unsigned int slices) 165 { 166 unsigned int i; 167 168 mtx_assert(&XX_MallocSmartLock, MA_OWNED); 169 170 for (i = start; i < start + slices; i++) 171 XX_MallocSmartMap[i] = ((i == start) ? slices : -1); 172 } 173 174 static void 175 XX_MallocSmartMapClear(unsigned int start, unsigned int slices) 176 { 177 unsigned int i; 178 179 mtx_assert(&XX_MallocSmartLock, MA_OWNED); 180 181 for (i = start; i < start + slices; i++) 182 XX_MallocSmartMap[i] = 0; 183 } 184 185 int 186 XX_MallocSmartInit(void) 187 { 188 int error; 189 190 error = E_OK; 191 mtx_lock(&XX_MallocSmartLock); 192 193 if (XX_MallocSmartPool) 194 goto out; 195 196 /* Allocate MallocSmart pool */ 197 XX_MallocSmartPool = contigmalloc(MALLOCSMART_POOL_SIZE, M_NETCOMMSW, 198 M_NOWAIT, 0, 0xFFFFFFFFFull, MALLOCSMART_POOL_SIZE, 0); 199 if (!XX_MallocSmartPool) { 200 error = E_NO_MEMORY; 201 goto out; 202 } 203 204 out: 205 mtx_unlock(&XX_MallocSmartLock); 206 return (error); 207 } 208 209 void * 210 XX_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment) 211 { 212 unsigned int i; 213 vm_offset_t addr; 214 215 addr = 0; 216 217 /* Convert alignment and size to number of slices */ 218 alignment = MALLOCSMART_SIZE_TO_SLICE(alignment); 219 size = MALLOCSMART_SIZE_TO_SLICE(size); 220 221 /* Lock resources */ 222 mtx_lock(&XX_MallocSmartLock); 223 224 /* Allocate region */ 225 for (i = 0; i + size <= MALLOCSMART_SLICES; i += alignment) { 226 if (XX_MallocSmartMapCheck(i, size)) { 227 XX_MallocSmartMapSet(i, size); 228 addr = (vm_offset_t)XX_MallocSmartPool + 229 (i * MALLOCSMART_SLICE_SIZE); 230 break; 231 } 232 } 233 234 /* Unlock resources */ 235 mtx_unlock(&XX_MallocSmartLock); 236 237 return ((void *)addr); 238 } 239 240 void 241 XX_FreeSmart(void *p) 242 { 243 unsigned int start, slices; 244 245 /* Calculate first slice of region */ 246 start = MALLOCSMART_SIZE_TO_SLICE((vm_offset_t)(p) - 247 (vm_offset_t)XX_MallocSmartPool); 248 249 /* Lock resources */ 250 mtx_lock(&XX_MallocSmartLock); 251 252 KASSERT(XX_MallocSmartMap[start] > 0, 253 ("XX_FreeSmart: Double or mid-block free!\n")); 254 255 /* Free region */ 256 slices = XX_MallocSmartMap[start]; 257 XX_MallocSmartMapClear(start, slices); 258 259 /* Unlock resources */ 260 mtx_unlock(&XX_MallocSmartLock); 261 } 262 263 void 264 XX_Free(void *p) 265 { 266 267 free(p, M_NETCOMMSW); 268 } 269 270 uint32_t 271 XX_DisableAllIntr(void) 272 { 273 274 return (intr_disable()); 275 } 276 277 void 278 XX_RestoreAllIntr(uint32_t flags) 279 { 280 281 intr_restore(flags); 282 } 283 284 static bool 285 XX_IsPortalIntr(uintptr_t irq) 286 { 287 int cpu, type; 288 /* Check interrupt numbers of all available portals */ 289 for (type = 0; type < 2; type++) 290 for (cpu = 0; cpu < MAXCPU; cpu++) 291 if (irq == XX_PInfo.portal_intr[type][cpu]) 292 return (1); 293 294 return (0); 295 } 296 297 static void 298 XX_Dispatch(void *arg) 299 { 300 struct XX_IntrInfo *info; 301 302 info = arg; 303 304 if (info->handler == NULL) { 305 printf("%s(): IRQ handler is NULL!\n", __func__); 306 return; 307 } 308 309 info->handler(info->arg); 310 } 311 312 t_Error 313 XX_PreallocAndBindIntr(device_t dev, uintptr_t irq, unsigned int cpu) 314 { 315 struct resource *r; 316 unsigned int inum; 317 t_Error error; 318 319 r = (struct resource *)irq; 320 inum = rman_get_start(r); 321 322 error = XX_SetIntr(irq, XX_Dispatch, &XX_IntrInfo[inum]); 323 if (error != 0) 324 return (error); 325 326 error = bus_bind_intr(dev, r, cpu); 327 if (error != 0) 328 return (error); 329 330 XX_IntrInfo[inum].flags = XX_INTR_FLAG_PREALLOCATED; 331 XX_IntrInfo[inum].cpu = cpu; 332 333 return (E_OK); 334 } 335 336 t_Error 337 XX_DeallocIntr(uintptr_t irq) 338 { 339 struct resource *r; 340 unsigned int inum; 341 342 r = (struct resource *)irq; 343 inum = rman_get_start(r); 344 345 if ((XX_IntrInfo[inum].flags & XX_INTR_FLAG_PREALLOCATED) == 0) 346 return (E_INVALID_STATE); 347 348 XX_IntrInfo[inum].flags = 0; 349 return (XX_FreeIntr(irq)); 350 } 351 352 t_Error 353 XX_SetIntr(uintptr_t irq, t_Isr *f_Isr, t_Handle handle) 354 { 355 device_t dev; 356 struct resource *r; 357 unsigned int flags; 358 int err; 359 360 r = (struct resource *)irq; 361 dev = rman_get_device(r); 362 irq = rman_get_start(r); 363 364 /* Handle preallocated interrupts */ 365 if (XX_IntrInfo[irq].flags & XX_INTR_FLAG_PREALLOCATED) { 366 if (XX_IntrInfo[irq].handler != NULL) 367 return (E_BUSY); 368 369 XX_IntrInfo[irq].handler = f_Isr; 370 XX_IntrInfo[irq].arg = handle; 371 372 return (E_OK); 373 } 374 375 flags = INTR_TYPE_NET | INTR_MPSAFE; 376 377 /* BMAN/QMAN Portal interrupts must be exlusive */ 378 if (XX_IsPortalIntr(irq)) 379 flags |= INTR_EXCL; 380 381 err = bus_setup_intr(dev, r, flags, NULL, f_Isr, handle, 382 &XX_IntrInfo[irq].cookie); 383 384 return (err); 385 } 386 387 t_Error 388 XX_FreeIntr(uintptr_t irq) 389 { 390 device_t dev; 391 struct resource *r; 392 393 r = (struct resource *)irq; 394 dev = rman_get_device(r); 395 irq = rman_get_start(r); 396 397 /* Handle preallocated interrupts */ 398 if (XX_IntrInfo[irq].flags & XX_INTR_FLAG_PREALLOCATED) { 399 if (XX_IntrInfo[irq].handler == NULL) 400 return (E_INVALID_STATE); 401 402 XX_IntrInfo[irq].handler = NULL; 403 XX_IntrInfo[irq].arg = NULL; 404 405 return (E_OK); 406 } 407 408 return (bus_teardown_intr(dev, r, XX_IntrInfo[irq].cookie)); 409 } 410 411 t_Error 412 XX_EnableIntr(uintptr_t irq) 413 { 414 struct resource *r; 415 416 r = (struct resource *)irq; 417 irq = rman_get_start(r); 418 419 powerpc_intr_unmask(irq); 420 421 return (E_OK); 422 } 423 424 t_Error 425 XX_DisableIntr(uintptr_t irq) 426 { 427 struct resource *r; 428 429 r = (struct resource *)irq; 430 irq = rman_get_start(r); 431 432 powerpc_intr_mask(irq); 433 434 return (E_OK); 435 } 436 437 t_TaskletHandle 438 XX_InitTasklet (void (*routine)(void *), void *data) 439 { 440 /* Not referenced */ 441 printf("NetCommSW: Unimplemented function %s() called!\n", __func__); 442 return (NULL); 443 } 444 445 446 void 447 XX_FreeTasklet (t_TaskletHandle h_Tasklet) 448 { 449 /* Not referenced */ 450 printf("NetCommSW: Unimplemented function %s() called!\n", __func__); 451 } 452 453 int 454 XX_ScheduleTask(t_TaskletHandle h_Tasklet, int immediate) 455 { 456 /* Not referenced */ 457 printf("NetCommSW: Unimplemented function %s() called!\n", __func__); 458 return (0); 459 } 460 461 void 462 XX_FlushScheduledTasks(void) 463 { 464 /* Not referenced */ 465 printf("NetCommSW: Unimplemented function %s() called!\n", __func__); 466 } 467 468 int 469 XX_TaskletIsQueued(t_TaskletHandle h_Tasklet) 470 { 471 /* Not referenced */ 472 printf("NetCommSW: Unimplemented function %s() called!\n", __func__); 473 return (0); 474 } 475 476 void 477 XX_SetTaskletData(t_TaskletHandle h_Tasklet, t_Handle data) 478 { 479 /* Not referenced */ 480 printf("NetCommSW: Unimplemented function %s() called!\n", __func__); 481 } 482 483 t_Handle 484 XX_GetTaskletData(t_TaskletHandle h_Tasklet) 485 { 486 /* Not referenced */ 487 printf("NetCommSW: Unimplemented function %s() called!\n", __func__); 488 return (NULL); 489 } 490 491 t_Handle 492 XX_InitSpinlock(void) 493 { 494 struct mtx *m; 495 496 m = malloc(sizeof(*m), M_NETCOMMSW, M_NOWAIT | M_ZERO); 497 if (!m) 498 return (0); 499 500 mtx_init(m, "NetCommSW Lock", NULL, MTX_DEF | MTX_DUPOK); 501 502 return (m); 503 } 504 505 void 506 XX_FreeSpinlock(t_Handle h_Spinlock) 507 { 508 struct mtx *m; 509 510 m = h_Spinlock; 511 512 mtx_destroy(m); 513 free(m, M_NETCOMMSW); 514 } 515 516 void 517 XX_LockSpinlock(t_Handle h_Spinlock) 518 { 519 struct mtx *m; 520 521 m = h_Spinlock; 522 mtx_lock(m); 523 } 524 525 void 526 XX_UnlockSpinlock(t_Handle h_Spinlock) 527 { 528 struct mtx *m; 529 530 m = h_Spinlock; 531 mtx_unlock(m); 532 } 533 534 uint32_t 535 XX_LockIntrSpinlock(t_Handle h_Spinlock) 536 { 537 538 XX_LockSpinlock(h_Spinlock); 539 return (0); 540 } 541 542 void 543 XX_UnlockIntrSpinlock(t_Handle h_Spinlock, uint32_t intrFlags) 544 { 545 546 XX_UnlockSpinlock(h_Spinlock); 547 } 548 549 uint32_t 550 XX_Sleep(uint32_t msecs) 551 { 552 553 XX_UDelay(1000 * msecs); 554 return (0); 555 } 556 557 void 558 XX_UDelay(uint32_t usecs) 559 { 560 DELAY(usecs); 561 } 562 563 t_Error 564 XX_IpcRegisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH], 565 t_IpcMsgHandler *f_MsgHandler, t_Handle h_Module, uint32_t replyLength) 566 { 567 568 /* 569 * This function returns fake E_OK status and does nothing 570 * as NetCommSW IPC is not used by FreeBSD drivers. 571 */ 572 return (E_OK); 573 } 574 575 t_Error 576 XX_IpcUnregisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH]) 577 { 578 /* 579 * This function returns fake E_OK status and does nothing 580 * as NetCommSW IPC is not used by FreeBSD drivers. 581 */ 582 return (E_OK); 583 } 584 585 586 t_Error 587 XX_IpcSendMessage(t_Handle h_Session, 588 uint8_t *p_Msg, uint32_t msgLength, uint8_t *p_Reply, 589 uint32_t *p_ReplyLength, t_IpcMsgCompletion *f_Completion, t_Handle h_Arg) 590 { 591 592 /* Should not be called */ 593 printf("NetCommSW: Unimplemented function %s() called!\n", __func__); 594 return (E_OK); 595 } 596 597 t_Handle 598 XX_IpcInitSession(char destAddr[XX_IPC_MAX_ADDR_NAME_LENGTH], 599 char srcAddr[XX_IPC_MAX_ADDR_NAME_LENGTH]) 600 { 601 602 /* Should not be called */ 603 printf("NetCommSW: Unimplemented function %s() called!\n", __func__); 604 return (NULL); 605 } 606 607 t_Error 608 XX_IpcFreeSession(t_Handle h_Session) 609 { 610 611 /* Should not be called */ 612 printf("NetCommSW: Unimplemented function %s() called!\n", __func__); 613 return (E_OK); 614 } 615 616 physAddress_t 617 XX_VirtToPhys(void *addr) 618 { 619 vm_paddr_t paddr; 620 int cpu; 621 622 cpu = PCPU_GET(cpuid); 623 624 /* Handle NULL address */ 625 if (addr == NULL) 626 return (-1); 627 628 /* Check CCSR */ 629 if ((vm_offset_t)addr >= ccsrbar_va && 630 (vm_offset_t)addr < ccsrbar_va + ccsrbar_size) 631 return (((vm_offset_t)addr - ccsrbar_va) + ccsrbar_pa); 632 633 /* Handle BMAN mappings */ 634 if (((vm_offset_t)addr >= XX_PInfo.portal_ce_va[BM_PORTAL]) && 635 ((vm_offset_t)addr < XX_PInfo.portal_ce_va[BM_PORTAL] + 636 XX_PInfo.portal_ce_size[BM_PORTAL][cpu])) 637 return (XX_PInfo.portal_ce_pa[BM_PORTAL][cpu] + 638 (vm_offset_t)addr - XX_PInfo.portal_ce_va[BM_PORTAL]); 639 640 if (((vm_offset_t)addr >= XX_PInfo.portal_ci_va[BM_PORTAL]) && 641 ((vm_offset_t)addr < XX_PInfo.portal_ci_va[BM_PORTAL] + 642 XX_PInfo.portal_ci_size[BM_PORTAL][cpu])) 643 return (XX_PInfo.portal_ci_pa[BM_PORTAL][cpu] + 644 (vm_offset_t)addr - XX_PInfo.portal_ci_va[BM_PORTAL]); 645 646 /* Handle QMAN mappings */ 647 if (((vm_offset_t)addr >= XX_PInfo.portal_ce_va[QM_PORTAL]) && 648 ((vm_offset_t)addr < XX_PInfo.portal_ce_va[QM_PORTAL] + 649 XX_PInfo.portal_ce_size[QM_PORTAL][cpu])) 650 return (XX_PInfo.portal_ce_pa[QM_PORTAL][cpu] + 651 (vm_offset_t)addr - XX_PInfo.portal_ce_va[QM_PORTAL]); 652 653 if (((vm_offset_t)addr >= XX_PInfo.portal_ci_va[QM_PORTAL]) && 654 ((vm_offset_t)addr < XX_PInfo.portal_ci_va[QM_PORTAL] + 655 XX_PInfo.portal_ci_size[QM_PORTAL][cpu])) 656 return (XX_PInfo.portal_ci_pa[QM_PORTAL][cpu] + 657 (vm_offset_t)addr - XX_PInfo.portal_ci_va[QM_PORTAL]); 658 659 if (PMAP_HAS_DMAP && (vm_offset_t)addr >= DMAP_BASE_ADDRESS && 660 (vm_offset_t)addr <= DMAP_MAX_ADDRESS) 661 return (DMAP_TO_PHYS((vm_offset_t)addr)); 662 else 663 paddr = pmap_kextract((vm_offset_t)addr); 664 665 if (paddr == 0) 666 printf("NetCommSW: " 667 "Unable to translate virtual address %p!\n", addr); 668 else 669 pmap_track_page(kernel_pmap, (vm_offset_t)addr); 670 671 return (paddr); 672 } 673 674 void * 675 XX_PhysToVirt(physAddress_t addr) 676 { 677 struct pv_entry *pv; 678 vm_page_t page; 679 int cpu; 680 681 /* Check CCSR */ 682 if (addr >= ccsrbar_pa && addr < ccsrbar_pa + ccsrbar_size) 683 return ((void *)((vm_offset_t)(addr - ccsrbar_pa) + 684 ccsrbar_va)); 685 686 cpu = PCPU_GET(cpuid); 687 688 /* Handle BMAN mappings */ 689 if ((addr >= XX_PInfo.portal_ce_pa[BM_PORTAL][cpu]) && 690 (addr < XX_PInfo.portal_ce_pa[BM_PORTAL][cpu] + 691 XX_PInfo.portal_ce_size[BM_PORTAL][cpu])) 692 return ((void *)(XX_PInfo.portal_ci_va[BM_PORTAL] + 693 (vm_offset_t)(addr - XX_PInfo.portal_ci_pa[BM_PORTAL][cpu]))); 694 695 if ((addr >= XX_PInfo.portal_ci_pa[BM_PORTAL][cpu]) && 696 (addr < XX_PInfo.portal_ci_pa[BM_PORTAL][cpu] + 697 XX_PInfo.portal_ci_size[BM_PORTAL][cpu])) 698 return ((void *)(XX_PInfo.portal_ci_va[BM_PORTAL] + 699 (vm_offset_t)(addr - XX_PInfo.portal_ci_pa[BM_PORTAL][cpu]))); 700 701 /* Handle QMAN mappings */ 702 if ((addr >= XX_PInfo.portal_ce_pa[QM_PORTAL][cpu]) && 703 (addr < XX_PInfo.portal_ce_pa[QM_PORTAL][cpu] + 704 XX_PInfo.portal_ce_size[QM_PORTAL][cpu])) 705 return ((void *)(XX_PInfo.portal_ce_va[QM_PORTAL] + 706 (vm_offset_t)(addr - XX_PInfo.portal_ce_pa[QM_PORTAL][cpu]))); 707 708 if ((addr >= XX_PInfo.portal_ci_pa[QM_PORTAL][cpu]) && 709 (addr < XX_PInfo.portal_ci_pa[QM_PORTAL][cpu] + 710 XX_PInfo.portal_ci_size[QM_PORTAL][cpu])) 711 return ((void *)(XX_PInfo.portal_ci_va[QM_PORTAL] + 712 (vm_offset_t)(addr - XX_PInfo.portal_ci_pa[QM_PORTAL][cpu]))); 713 714 page = PHYS_TO_VM_PAGE(addr); 715 pv = TAILQ_FIRST(&page->md.pv_list); 716 717 if (pv != NULL) 718 return ((void *)(pv->pv_va + ((vm_offset_t)addr & PAGE_MASK))); 719 720 if (PMAP_HAS_DMAP) 721 return ((void *)(uintptr_t)PHYS_TO_DMAP(addr)); 722 723 printf("NetCommSW: " 724 "Unable to translate physical address 0x%09jx!\n", (uintmax_t)addr); 725 726 return (NULL); 727 } 728 729 void 730 XX_PortalSetInfo(device_t dev) 731 { 732 char *dev_name; 733 struct dpaa_portals_softc *sc; 734 int i, type, len; 735 736 dev_name = malloc(sizeof(*dev_name), M_TEMP, M_WAITOK | 737 M_ZERO); 738 739 len = strlen("bman-portals"); 740 741 strncpy(dev_name, device_get_name(dev), len); 742 743 if (strncmp(dev_name, "bman-portals", len) && strncmp(dev_name, 744 "qman-portals", len)) 745 goto end; 746 747 if (strncmp(dev_name, "bman-portals", len) == 0) 748 type = BM_PORTAL; 749 else 750 type = QM_PORTAL; 751 752 sc = device_get_softc(dev); 753 754 for (i = 0; sc->sc_dp[i].dp_ce_pa != 0; i++) { 755 XX_PInfo.portal_ce_pa[type][i] = sc->sc_dp[i].dp_ce_pa; 756 XX_PInfo.portal_ci_pa[type][i] = sc->sc_dp[i].dp_ci_pa; 757 XX_PInfo.portal_ce_size[type][i] = sc->sc_dp[i].dp_ce_size; 758 XX_PInfo.portal_ci_size[type][i] = sc->sc_dp[i].dp_ci_size; 759 XX_PInfo.portal_intr[type][i] = sc->sc_dp[i].dp_intr_num; 760 } 761 762 XX_PInfo.portal_ce_va[type] = rman_get_bushandle(sc->sc_rres[0]); 763 XX_PInfo.portal_ci_va[type] = rman_get_bushandle(sc->sc_rres[1]); 764 end: 765 free(dev_name, M_TEMP); 766 } 767