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 #define XX_INTR_FLAG_BOUND (1 << 1) 99 #define XX_INTR_FLAG_FMAN_FIX (1 << 2) 100 101 struct XX_IntrInfo { 102 driver_intr_t *handler; 103 void *arg; 104 int cpu; 105 int flags; 106 void *cookie; 107 }; 108 109 static struct XX_IntrInfo XX_IntrInfo[INTR_VECTORS]; 110 /* Portal type identifiers */ 111 enum XX_PortalIdent{ 112 BM_PORTAL = 0, 113 QM_PORTAL, 114 }; 115 /* Structure to store portals' properties */ 116 struct XX_PortalInfo { 117 vm_paddr_t portal_ce_pa[2][MAXCPU]; 118 vm_paddr_t portal_ci_pa[2][MAXCPU]; 119 uint32_t portal_ce_size[2][MAXCPU]; 120 uint32_t portal_ci_size[2][MAXCPU]; 121 vm_offset_t portal_ce_va[2]; 122 vm_offset_t portal_ci_va[2]; 123 uintptr_t portal_intr[2][MAXCPU]; 124 }; 125 126 static struct XX_PortalInfo XX_PInfo; 127 128 void 129 XX_Exit(int status) 130 { 131 132 panic("NetCommSW: Exit called with status %i", status); 133 } 134 135 void 136 XX_Print(char *str, ...) 137 { 138 va_list ap; 139 140 va_start(ap, str); 141 vprintf(str, ap); 142 va_end(ap); 143 } 144 145 void * 146 XX_Malloc(uint32_t size) 147 { 148 void *p = (malloc(size, M_NETCOMMSW, M_NOWAIT)); 149 150 return (p); 151 } 152 153 static int 154 XX_MallocSmartMapCheck(unsigned int start, unsigned int slices) 155 { 156 unsigned int i; 157 158 mtx_assert(&XX_MallocSmartLock, MA_OWNED); 159 for (i = start; i < start + slices; i++) 160 if (XX_MallocSmartMap[i]) 161 return (FALSE); 162 return (TRUE); 163 } 164 165 static void 166 XX_MallocSmartMapSet(unsigned int start, unsigned int slices) 167 { 168 unsigned int i; 169 170 mtx_assert(&XX_MallocSmartLock, MA_OWNED); 171 172 for (i = start; i < start + slices; i++) 173 XX_MallocSmartMap[i] = ((i == start) ? slices : -1); 174 } 175 176 static void 177 XX_MallocSmartMapClear(unsigned int start, unsigned int slices) 178 { 179 unsigned int i; 180 181 mtx_assert(&XX_MallocSmartLock, MA_OWNED); 182 183 for (i = start; i < start + slices; i++) 184 XX_MallocSmartMap[i] = 0; 185 } 186 187 int 188 XX_MallocSmartInit(void) 189 { 190 int error; 191 192 error = E_OK; 193 mtx_lock(&XX_MallocSmartLock); 194 195 if (XX_MallocSmartPool) 196 goto out; 197 198 /* Allocate MallocSmart pool */ 199 XX_MallocSmartPool = contigmalloc(MALLOCSMART_POOL_SIZE, M_NETCOMMSW, 200 M_NOWAIT, 0, 0xFFFFFFFFFull, MALLOCSMART_POOL_SIZE, 0); 201 if (!XX_MallocSmartPool) { 202 error = E_NO_MEMORY; 203 goto out; 204 } 205 206 out: 207 mtx_unlock(&XX_MallocSmartLock); 208 return (error); 209 } 210 211 void * 212 XX_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment) 213 { 214 unsigned int i; 215 vm_offset_t addr; 216 217 addr = 0; 218 219 /* Convert alignment and size to number of slices */ 220 alignment = MALLOCSMART_SIZE_TO_SLICE(alignment); 221 size = MALLOCSMART_SIZE_TO_SLICE(size); 222 223 /* Lock resources */ 224 mtx_lock(&XX_MallocSmartLock); 225 226 /* Allocate region */ 227 for (i = 0; i + size <= MALLOCSMART_SLICES; i += alignment) { 228 if (XX_MallocSmartMapCheck(i, size)) { 229 XX_MallocSmartMapSet(i, size); 230 addr = (vm_offset_t)XX_MallocSmartPool + 231 (i * MALLOCSMART_SLICE_SIZE); 232 break; 233 } 234 } 235 236 /* Unlock resources */ 237 mtx_unlock(&XX_MallocSmartLock); 238 239 return ((void *)addr); 240 } 241 242 void 243 XX_FreeSmart(void *p) 244 { 245 unsigned int start, slices; 246 247 /* Calculate first slice of region */ 248 start = MALLOCSMART_SIZE_TO_SLICE((vm_offset_t)(p) - 249 (vm_offset_t)XX_MallocSmartPool); 250 251 /* Lock resources */ 252 mtx_lock(&XX_MallocSmartLock); 253 254 KASSERT(XX_MallocSmartMap[start] > 0, 255 ("XX_FreeSmart: Double or mid-block free!\n")); 256 257 /* Free region */ 258 slices = XX_MallocSmartMap[start]; 259 XX_MallocSmartMapClear(start, slices); 260 261 /* Unlock resources */ 262 mtx_unlock(&XX_MallocSmartLock); 263 } 264 265 void 266 XX_Free(void *p) 267 { 268 269 free(p, M_NETCOMMSW); 270 } 271 272 uint32_t 273 XX_DisableAllIntr(void) 274 { 275 276 return (intr_disable()); 277 } 278 279 void 280 XX_RestoreAllIntr(uint32_t flags) 281 { 282 283 intr_restore(flags); 284 } 285 286 static bool 287 XX_IsPortalIntr(uintptr_t irq) 288 { 289 int cpu, type; 290 /* Check interrupt numbers of all available portals */ 291 for (cpu = 0, type = 0; XX_PInfo.portal_intr[type][cpu] != 0; cpu++) { 292 if (irq == XX_PInfo.portal_intr[type][cpu]) { 293 /* Found it! */ 294 return (1); 295 } 296 if (XX_PInfo.portal_intr[type][cpu + 1] == 0) { 297 type++; 298 cpu = 0; 299 } 300 } 301 302 return (0); 303 } 304 305 void 306 XX_FmanFixIntr(int irq) 307 { 308 309 XX_IntrInfo[irq].flags |= XX_INTR_FLAG_FMAN_FIX; 310 } 311 312 static bool 313 XX_FmanNeedsIntrFix(int irq) 314 { 315 316 if (XX_IntrInfo[irq].flags & XX_INTR_FLAG_FMAN_FIX) 317 return (1); 318 319 return (0); 320 } 321 322 static void 323 XX_Dispatch(void *arg) 324 { 325 struct XX_IntrInfo *info; 326 327 info = arg; 328 329 /* Bind this thread to proper CPU when SMP has been already started. */ 330 if ((info->flags & XX_INTR_FLAG_BOUND) == 0 && smp_started && 331 info->cpu >= 0) { 332 thread_lock(curthread); 333 sched_bind(curthread, info->cpu); 334 thread_unlock(curthread); 335 336 info->flags |= XX_INTR_FLAG_BOUND; 337 } 338 339 if (info->handler == NULL) { 340 printf("%s(): IRQ handler is NULL!\n", __func__); 341 return; 342 } 343 344 info->handler(info->arg); 345 } 346 347 t_Error 348 XX_PreallocAndBindIntr(uintptr_t irq, unsigned int cpu) 349 { 350 struct resource *r; 351 unsigned int inum; 352 t_Error error; 353 354 r = (struct resource *)irq; 355 inum = rman_get_start(r); 356 357 error = XX_SetIntr(irq, XX_Dispatch, &XX_IntrInfo[inum]); 358 if (error != 0) 359 return (error); 360 361 XX_IntrInfo[inum].flags = XX_INTR_FLAG_PREALLOCATED; 362 XX_IntrInfo[inum].cpu = cpu; 363 364 return (E_OK); 365 } 366 367 t_Error 368 XX_DeallocIntr(uintptr_t irq) 369 { 370 struct resource *r; 371 unsigned int inum; 372 373 r = (struct resource *)irq; 374 inum = rman_get_start(r); 375 376 if ((XX_IntrInfo[inum].flags & XX_INTR_FLAG_PREALLOCATED) == 0) 377 return (E_INVALID_STATE); 378 379 XX_IntrInfo[inum].flags = 0; 380 return (XX_FreeIntr(irq)); 381 } 382 383 t_Error 384 XX_SetIntr(uintptr_t irq, t_Isr *f_Isr, t_Handle handle) 385 { 386 device_t dev; 387 struct resource *r; 388 unsigned int flags; 389 int err; 390 391 r = (struct resource *)irq; 392 dev = rman_get_device(r); 393 irq = rman_get_start(r); 394 395 /* Handle preallocated interrupts */ 396 if (XX_IntrInfo[irq].flags & XX_INTR_FLAG_PREALLOCATED) { 397 if (XX_IntrInfo[irq].handler != NULL) 398 return (E_BUSY); 399 400 XX_IntrInfo[irq].handler = f_Isr; 401 XX_IntrInfo[irq].arg = handle; 402 403 return (E_OK); 404 } 405 406 flags = INTR_TYPE_NET | INTR_MPSAFE; 407 408 /* BMAN/QMAN Portal interrupts must be exlusive */ 409 if (XX_IsPortalIntr(irq)) 410 flags |= INTR_EXCL; 411 412 err = bus_setup_intr(dev, r, flags, NULL, f_Isr, handle, 413 &XX_IntrInfo[irq].cookie); 414 if (err) 415 goto finish; 416 417 /* 418 * XXX: Bind FMan IRQ to CPU0. Current interrupt subsystem directs each 419 * interrupt to all CPUs. Race between an interrupt assertion and 420 * masking may occur and interrupt handler may be called multiple times 421 * per one interrupt. FMan doesn't support such a situation. Workaround 422 * is to bind FMan interrupt to one CPU0 only. 423 */ 424 #ifdef SMP 425 if (XX_FmanNeedsIntrFix(irq)) 426 err = powerpc_bind_intr(irq, 0); 427 #endif 428 finish: 429 return (err); 430 } 431 432 t_Error 433 XX_FreeIntr(uintptr_t irq) 434 { 435 device_t dev; 436 struct resource *r; 437 438 r = (struct resource *)irq; 439 dev = rman_get_device(r); 440 irq = rman_get_start(r); 441 442 /* Handle preallocated interrupts */ 443 if (XX_IntrInfo[irq].flags & XX_INTR_FLAG_PREALLOCATED) { 444 if (XX_IntrInfo[irq].handler == NULL) 445 return (E_INVALID_STATE); 446 447 XX_IntrInfo[irq].handler = NULL; 448 XX_IntrInfo[irq].arg = NULL; 449 450 return (E_OK); 451 } 452 453 return (bus_teardown_intr(dev, r, XX_IntrInfo[irq].cookie)); 454 } 455 456 t_Error 457 XX_EnableIntr(uintptr_t irq) 458 { 459 struct resource *r; 460 461 r = (struct resource *)irq; 462 irq = rman_get_start(r); 463 464 powerpc_intr_unmask(irq); 465 466 return (E_OK); 467 } 468 469 t_Error 470 XX_DisableIntr(uintptr_t irq) 471 { 472 struct resource *r; 473 474 r = (struct resource *)irq; 475 irq = rman_get_start(r); 476 477 powerpc_intr_mask(irq); 478 479 return (E_OK); 480 } 481 482 t_TaskletHandle 483 XX_InitTasklet (void (*routine)(void *), void *data) 484 { 485 /* Not referenced */ 486 printf("NetCommSW: Unimplemented function %s() called!\n", __func__); 487 return (NULL); 488 } 489 490 491 void 492 XX_FreeTasklet (t_TaskletHandle h_Tasklet) 493 { 494 /* Not referenced */ 495 printf("NetCommSW: Unimplemented function %s() called!\n", __func__); 496 } 497 498 int 499 XX_ScheduleTask(t_TaskletHandle h_Tasklet, int immediate) 500 { 501 /* Not referenced */ 502 printf("NetCommSW: Unimplemented function %s() called!\n", __func__); 503 return (0); 504 } 505 506 void 507 XX_FlushScheduledTasks(void) 508 { 509 /* Not referenced */ 510 printf("NetCommSW: Unimplemented function %s() called!\n", __func__); 511 } 512 513 int 514 XX_TaskletIsQueued(t_TaskletHandle h_Tasklet) 515 { 516 /* Not referenced */ 517 printf("NetCommSW: Unimplemented function %s() called!\n", __func__); 518 return (0); 519 } 520 521 void 522 XX_SetTaskletData(t_TaskletHandle h_Tasklet, t_Handle data) 523 { 524 /* Not referenced */ 525 printf("NetCommSW: Unimplemented function %s() called!\n", __func__); 526 } 527 528 t_Handle 529 XX_GetTaskletData(t_TaskletHandle h_Tasklet) 530 { 531 /* Not referenced */ 532 printf("NetCommSW: Unimplemented function %s() called!\n", __func__); 533 return (NULL); 534 } 535 536 t_Handle 537 XX_InitSpinlock(void) 538 { 539 struct mtx *m; 540 541 m = malloc(sizeof(*m), M_NETCOMMSW, M_NOWAIT | M_ZERO); 542 if (!m) 543 return (0); 544 545 mtx_init(m, "NetCommSW Lock", NULL, MTX_DEF | MTX_DUPOK); 546 547 return (m); 548 } 549 550 void 551 XX_FreeSpinlock(t_Handle h_Spinlock) 552 { 553 struct mtx *m; 554 555 m = h_Spinlock; 556 557 mtx_destroy(m); 558 free(m, M_NETCOMMSW); 559 } 560 561 void 562 XX_LockSpinlock(t_Handle h_Spinlock) 563 { 564 struct mtx *m; 565 566 m = h_Spinlock; 567 mtx_lock(m); 568 } 569 570 void 571 XX_UnlockSpinlock(t_Handle h_Spinlock) 572 { 573 struct mtx *m; 574 575 m = h_Spinlock; 576 mtx_unlock(m); 577 } 578 579 uint32_t 580 XX_LockIntrSpinlock(t_Handle h_Spinlock) 581 { 582 583 XX_LockSpinlock(h_Spinlock); 584 return (0); 585 } 586 587 void 588 XX_UnlockIntrSpinlock(t_Handle h_Spinlock, uint32_t intrFlags) 589 { 590 591 XX_UnlockSpinlock(h_Spinlock); 592 } 593 594 uint32_t 595 XX_Sleep(uint32_t msecs) 596 { 597 598 XX_UDelay(1000 * msecs); 599 return (0); 600 } 601 602 void 603 XX_UDelay(uint32_t usecs) 604 { 605 DELAY(usecs); 606 } 607 608 t_Error 609 XX_IpcRegisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH], 610 t_IpcMsgHandler *f_MsgHandler, t_Handle h_Module, uint32_t replyLength) 611 { 612 613 /* 614 * This function returns fake E_OK status and does nothing 615 * as NetCommSW IPC is not used by FreeBSD drivers. 616 */ 617 return (E_OK); 618 } 619 620 t_Error 621 XX_IpcUnregisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH]) 622 { 623 /* 624 * This function returns fake E_OK status and does nothing 625 * as NetCommSW IPC is not used by FreeBSD drivers. 626 */ 627 return (E_OK); 628 } 629 630 631 t_Error 632 XX_IpcSendMessage(t_Handle h_Session, 633 uint8_t *p_Msg, uint32_t msgLength, uint8_t *p_Reply, 634 uint32_t *p_ReplyLength, t_IpcMsgCompletion *f_Completion, t_Handle h_Arg) 635 { 636 637 /* Should not be called */ 638 printf("NetCommSW: Unimplemented function %s() called!\n", __func__); 639 return (E_OK); 640 } 641 642 t_Handle 643 XX_IpcInitSession(char destAddr[XX_IPC_MAX_ADDR_NAME_LENGTH], 644 char srcAddr[XX_IPC_MAX_ADDR_NAME_LENGTH]) 645 { 646 647 /* Should not be called */ 648 printf("NetCommSW: Unimplemented function %s() called!\n", __func__); 649 return (E_OK); 650 } 651 652 t_Error 653 XX_IpcFreeSession(t_Handle h_Session) 654 { 655 656 /* Should not be called */ 657 printf("NetCommSW: Unimplemented function %s() called!\n", __func__); 658 return (E_OK); 659 } 660 661 physAddress_t 662 XX_VirtToPhys(void *addr) 663 { 664 vm_paddr_t paddr; 665 int cpu; 666 667 cpu = PCPU_GET(cpuid); 668 669 /* Handle NULL address */ 670 if (addr == NULL) 671 return (-1); 672 673 /* Check CCSR */ 674 if ((vm_offset_t)addr >= ccsrbar_va && 675 (vm_offset_t)addr < ccsrbar_va + ccsrbar_size) 676 return (((vm_offset_t)addr - ccsrbar_va) + ccsrbar_pa); 677 678 /* Handle BMAN mappings */ 679 if (((vm_offset_t)addr >= XX_PInfo.portal_ce_va[BM_PORTAL]) && 680 ((vm_offset_t)addr < XX_PInfo.portal_ce_va[BM_PORTAL] + 681 XX_PInfo.portal_ce_size[BM_PORTAL][cpu])) 682 return (XX_PInfo.portal_ce_pa[BM_PORTAL][cpu] + 683 (vm_offset_t)addr - XX_PInfo.portal_ce_va[BM_PORTAL]); 684 685 if (((vm_offset_t)addr >= XX_PInfo.portal_ci_va[BM_PORTAL]) && 686 ((vm_offset_t)addr < XX_PInfo.portal_ci_va[BM_PORTAL] + 687 XX_PInfo.portal_ci_size[BM_PORTAL][cpu])) 688 return (XX_PInfo.portal_ci_pa[BM_PORTAL][cpu] + 689 (vm_offset_t)addr - XX_PInfo.portal_ci_va[BM_PORTAL]); 690 691 /* Handle QMAN mappings */ 692 if (((vm_offset_t)addr >= XX_PInfo.portal_ce_va[QM_PORTAL]) && 693 ((vm_offset_t)addr < XX_PInfo.portal_ce_va[QM_PORTAL] + 694 XX_PInfo.portal_ce_size[QM_PORTAL][cpu])) 695 return (XX_PInfo.portal_ce_pa[QM_PORTAL][cpu] + 696 (vm_offset_t)addr - XX_PInfo.portal_ce_va[QM_PORTAL]); 697 698 if (((vm_offset_t)addr >= XX_PInfo.portal_ci_va[QM_PORTAL]) && 699 ((vm_offset_t)addr < XX_PInfo.portal_ci_va[QM_PORTAL] + 700 XX_PInfo.portal_ci_size[QM_PORTAL][cpu])) 701 return (XX_PInfo.portal_ci_pa[QM_PORTAL][cpu] + 702 (vm_offset_t)addr - XX_PInfo.portal_ci_va[QM_PORTAL]); 703 704 if (PMAP_HAS_DMAP && (vm_offset_t)addr >= DMAP_BASE_ADDRESS && 705 (vm_offset_t)addr <= DMAP_MAX_ADDRESS) 706 return (DMAP_TO_PHYS((vm_offset_t)addr)); 707 else 708 paddr = pmap_kextract((vm_offset_t)addr); 709 710 if (paddr == 0) 711 printf("NetCommSW: " 712 "Unable to translate virtual address %p!\n", addr); 713 else 714 pmap_track_page(kernel_pmap, (vm_offset_t)addr); 715 716 return (paddr); 717 } 718 719 void * 720 XX_PhysToVirt(physAddress_t addr) 721 { 722 struct pv_entry *pv; 723 vm_page_t page; 724 int cpu; 725 726 /* Check CCSR */ 727 if (addr >= ccsrbar_pa && addr < ccsrbar_pa + ccsrbar_size) 728 return ((void *)((vm_offset_t)(addr - ccsrbar_pa) + 729 ccsrbar_va)); 730 731 cpu = PCPU_GET(cpuid); 732 733 /* Handle BMAN mappings */ 734 if ((addr >= XX_PInfo.portal_ce_pa[BM_PORTAL][cpu]) && 735 (addr < XX_PInfo.portal_ce_pa[BM_PORTAL][cpu] + 736 XX_PInfo.portal_ce_size[BM_PORTAL][cpu])) 737 return ((void *)(XX_PInfo.portal_ci_va[BM_PORTAL] + 738 (vm_offset_t)(addr - XX_PInfo.portal_ci_pa[BM_PORTAL][cpu]))); 739 740 if ((addr >= XX_PInfo.portal_ci_pa[BM_PORTAL][cpu]) && 741 (addr < XX_PInfo.portal_ci_pa[BM_PORTAL][cpu] + 742 XX_PInfo.portal_ci_size[BM_PORTAL][cpu])) 743 return ((void *)(XX_PInfo.portal_ci_va[BM_PORTAL] + 744 (vm_offset_t)(addr - XX_PInfo.portal_ci_pa[BM_PORTAL][cpu]))); 745 746 /* Handle QMAN mappings */ 747 if ((addr >= XX_PInfo.portal_ce_pa[QM_PORTAL][cpu]) && 748 (addr < XX_PInfo.portal_ce_pa[QM_PORTAL][cpu] + 749 XX_PInfo.portal_ce_size[QM_PORTAL][cpu])) 750 return ((void *)(XX_PInfo.portal_ce_va[QM_PORTAL] + 751 (vm_offset_t)(addr - XX_PInfo.portal_ce_pa[QM_PORTAL][cpu]))); 752 753 if ((addr >= XX_PInfo.portal_ci_pa[QM_PORTAL][cpu]) && 754 (addr < XX_PInfo.portal_ci_pa[QM_PORTAL][cpu] + 755 XX_PInfo.portal_ci_size[QM_PORTAL][cpu])) 756 return ((void *)(XX_PInfo.portal_ci_va[QM_PORTAL] + 757 (vm_offset_t)(addr - XX_PInfo.portal_ci_pa[QM_PORTAL][cpu]))); 758 759 page = PHYS_TO_VM_PAGE(addr); 760 pv = TAILQ_FIRST(&page->md.pv_list); 761 762 if (pv != NULL) 763 return ((void *)(pv->pv_va + ((vm_offset_t)addr & PAGE_MASK))); 764 765 if (PMAP_HAS_DMAP) 766 return ((void *)(uintptr_t)PHYS_TO_DMAP(addr)); 767 768 printf("NetCommSW: " 769 "Unable to translate physical address 0x%09jx!\n", (uintmax_t)addr); 770 771 return (NULL); 772 } 773 774 void 775 XX_PortalSetInfo(device_t dev) 776 { 777 char *dev_name; 778 struct dpaa_portals_softc *sc; 779 int i, type, len; 780 781 dev_name = malloc(sizeof(*dev_name), M_TEMP, M_WAITOK | 782 M_ZERO); 783 784 len = strlen("bman-portals"); 785 786 strncpy(dev_name, device_get_name(dev), len); 787 788 if (strncmp(dev_name, "bman-portals", len) && strncmp(dev_name, 789 "qman-portals", len)) 790 goto end; 791 792 if (strncmp(dev_name, "bman-portals", len) == 0) 793 type = BM_PORTAL; 794 else 795 type = QM_PORTAL; 796 797 sc = device_get_softc(dev); 798 799 for (i = 0; sc->sc_dp[i].dp_ce_pa != 0; i++) { 800 XX_PInfo.portal_ce_pa[type][i] = sc->sc_dp[i].dp_ce_pa; 801 XX_PInfo.portal_ci_pa[type][i] = sc->sc_dp[i].dp_ci_pa; 802 XX_PInfo.portal_ce_size[type][i] = sc->sc_dp[i].dp_ce_size; 803 XX_PInfo.portal_ci_size[type][i] = sc->sc_dp[i].dp_ci_size; 804 XX_PInfo.portal_intr[type][i] = sc->sc_dp[i].dp_intr_num; 805 } 806 807 XX_PInfo.portal_ce_va[type] = rman_get_bushandle(sc->sc_rres[0]); 808 XX_PInfo.portal_ci_va[type] = rman_get_bushandle(sc->sc_rres[1]); 809 end: 810 free(dev_name, M_TEMP); 811 } 812