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 uint32_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 t_Error 287 XX_Call(uint32_t qid, t_Error (* f)(t_Handle), t_Handle id, t_Handle appId, uint16_t flags ) 288 { 289 /* Not referenced */ 290 printf("NetCommSW: Unimplemented function %s() called!\n", __func__); 291 return (E_OK); 292 } 293 294 static bool 295 XX_IsPortalIntr(int irq) 296 { 297 int cpu, type; 298 /* Check interrupt numbers of all available portals */ 299 for (cpu = 0, type = 0; XX_PInfo.portal_intr[type][cpu] != 0; cpu++) { 300 if (irq == XX_PInfo.portal_intr[type][cpu]) { 301 /* Found it! */ 302 return (1); 303 } 304 if (XX_PInfo.portal_intr[type][cpu + 1] == 0) { 305 type++; 306 cpu = 0; 307 } 308 } 309 310 return (0); 311 } 312 313 void 314 XX_FmanFixIntr(int irq) 315 { 316 317 XX_IntrInfo[irq].flags |= XX_INTR_FLAG_FMAN_FIX; 318 } 319 320 static bool 321 XX_FmanNeedsIntrFix(int irq) 322 { 323 324 if (XX_IntrInfo[irq].flags & XX_INTR_FLAG_FMAN_FIX) 325 return (1); 326 327 return (0); 328 } 329 330 static void 331 XX_Dispatch(void *arg) 332 { 333 struct XX_IntrInfo *info; 334 335 info = arg; 336 337 /* Bind this thread to proper CPU when SMP has been already started. */ 338 if ((info->flags & XX_INTR_FLAG_BOUND) == 0 && smp_started && 339 info->cpu >= 0) { 340 thread_lock(curthread); 341 sched_bind(curthread, info->cpu); 342 thread_unlock(curthread); 343 344 info->flags |= XX_INTR_FLAG_BOUND; 345 } 346 347 if (info->handler == NULL) { 348 printf("%s(): IRQ handler is NULL!\n", __func__); 349 return; 350 } 351 352 info->handler(info->arg); 353 } 354 355 t_Error 356 XX_PreallocAndBindIntr(uintptr_t irq, unsigned int cpu) 357 { 358 struct resource *r; 359 unsigned int inum; 360 t_Error error; 361 362 r = (struct resource *)irq; 363 inum = rman_get_start(r); 364 365 error = XX_SetIntr(irq, XX_Dispatch, &XX_IntrInfo[inum]); 366 if (error != 0) 367 return (error); 368 369 XX_IntrInfo[inum].flags = XX_INTR_FLAG_PREALLOCATED; 370 XX_IntrInfo[inum].cpu = cpu; 371 372 return (E_OK); 373 } 374 375 t_Error 376 XX_DeallocIntr(uintptr_t irq) 377 { 378 struct resource *r; 379 unsigned int inum; 380 381 r = (struct resource *)irq; 382 inum = rman_get_start(r); 383 384 if ((XX_IntrInfo[inum].flags & XX_INTR_FLAG_PREALLOCATED) == 0) 385 return (E_INVALID_STATE); 386 387 XX_IntrInfo[inum].flags = 0; 388 return (XX_FreeIntr(irq)); 389 } 390 391 t_Error 392 XX_SetIntr(uintptr_t irq, t_Isr *f_Isr, t_Handle handle) 393 { 394 device_t dev; 395 struct resource *r; 396 unsigned int flags; 397 int err; 398 399 r = (struct resource *)irq; 400 dev = rman_get_device(r); 401 irq = rman_get_start(r); 402 403 /* Handle preallocated interrupts */ 404 if (XX_IntrInfo[irq].flags & XX_INTR_FLAG_PREALLOCATED) { 405 if (XX_IntrInfo[irq].handler != NULL) 406 return (E_BUSY); 407 408 XX_IntrInfo[irq].handler = f_Isr; 409 XX_IntrInfo[irq].arg = handle; 410 411 return (E_OK); 412 } 413 414 flags = INTR_TYPE_NET | INTR_MPSAFE; 415 416 /* BMAN/QMAN Portal interrupts must be exlusive */ 417 if (XX_IsPortalIntr(irq)) 418 flags |= INTR_EXCL; 419 420 err = bus_setup_intr(dev, r, flags, NULL, f_Isr, handle, 421 &XX_IntrInfo[irq].cookie); 422 if (err) 423 goto finish; 424 425 /* 426 * XXX: Bind FMan IRQ to CPU0. Current interrupt subsystem directs each 427 * interrupt to all CPUs. Race between an interrupt assertion and 428 * masking may occur and interrupt handler may be called multiple times 429 * per one interrupt. FMan doesn't support such a situation. Workaround 430 * is to bind FMan interrupt to one CPU0 only. 431 */ 432 #ifdef SMP 433 if (XX_FmanNeedsIntrFix(irq)) 434 err = powerpc_bind_intr(irq, 0); 435 #endif 436 finish: 437 return (err); 438 } 439 440 t_Error 441 XX_FreeIntr(uintptr_t irq) 442 { 443 device_t dev; 444 struct resource *r; 445 446 r = (struct resource *)irq; 447 dev = rman_get_device(r); 448 irq = rman_get_start(r); 449 450 /* Handle preallocated interrupts */ 451 if (XX_IntrInfo[irq].flags & XX_INTR_FLAG_PREALLOCATED) { 452 if (XX_IntrInfo[irq].handler == NULL) 453 return (E_INVALID_STATE); 454 455 XX_IntrInfo[irq].handler = NULL; 456 XX_IntrInfo[irq].arg = NULL; 457 458 return (E_OK); 459 } 460 461 return (bus_teardown_intr(dev, r, XX_IntrInfo[irq].cookie)); 462 } 463 464 t_Error 465 XX_EnableIntr(uintptr_t irq) 466 { 467 struct resource *r; 468 469 r = (struct resource *)irq; 470 irq = rman_get_start(r); 471 472 powerpc_intr_unmask(irq); 473 474 return (E_OK); 475 } 476 477 t_Error 478 XX_DisableIntr(uintptr_t irq) 479 { 480 struct resource *r; 481 482 r = (struct resource *)irq; 483 irq = rman_get_start(r); 484 485 powerpc_intr_mask(irq); 486 487 return (E_OK); 488 } 489 490 t_TaskletHandle 491 XX_InitTasklet (void (*routine)(void *), void *data) 492 { 493 /* Not referenced */ 494 printf("NetCommSW: Unimplemented function %s() called!\n", __func__); 495 return (NULL); 496 } 497 498 499 void 500 XX_FreeTasklet (t_TaskletHandle h_Tasklet) 501 { 502 /* Not referenced */ 503 printf("NetCommSW: Unimplemented function %s() called!\n", __func__); 504 } 505 506 int 507 XX_ScheduleTask(t_TaskletHandle h_Tasklet, int immediate) 508 { 509 /* Not referenced */ 510 printf("NetCommSW: Unimplemented function %s() called!\n", __func__); 511 return (0); 512 } 513 514 void 515 XX_FlushScheduledTasks(void) 516 { 517 /* Not referenced */ 518 printf("NetCommSW: Unimplemented function %s() called!\n", __func__); 519 } 520 521 int 522 XX_TaskletIsQueued(t_TaskletHandle h_Tasklet) 523 { 524 /* Not referenced */ 525 printf("NetCommSW: Unimplemented function %s() called!\n", __func__); 526 return (0); 527 } 528 529 void 530 XX_SetTaskletData(t_TaskletHandle h_Tasklet, t_Handle data) 531 { 532 /* Not referenced */ 533 printf("NetCommSW: Unimplemented function %s() called!\n", __func__); 534 } 535 536 t_Handle 537 XX_GetTaskletData(t_TaskletHandle h_Tasklet) 538 { 539 /* Not referenced */ 540 printf("NetCommSW: Unimplemented function %s() called!\n", __func__); 541 return (NULL); 542 } 543 544 t_Handle 545 XX_InitSpinlock(void) 546 { 547 struct mtx *m; 548 549 m = malloc(sizeof(*m), M_NETCOMMSW, M_NOWAIT | M_ZERO); 550 if (!m) 551 return (0); 552 553 mtx_init(m, "NetCommSW Lock", NULL, MTX_DEF | MTX_DUPOK); 554 555 return (m); 556 } 557 558 void 559 XX_FreeSpinlock(t_Handle h_Spinlock) 560 { 561 struct mtx *m; 562 563 m = h_Spinlock; 564 565 mtx_destroy(m); 566 free(m, M_NETCOMMSW); 567 } 568 569 void 570 XX_LockSpinlock(t_Handle h_Spinlock) 571 { 572 struct mtx *m; 573 574 m = h_Spinlock; 575 mtx_lock(m); 576 } 577 578 void 579 XX_UnlockSpinlock(t_Handle h_Spinlock) 580 { 581 struct mtx *m; 582 583 m = h_Spinlock; 584 mtx_unlock(m); 585 } 586 587 uint32_t 588 XX_LockIntrSpinlock(t_Handle h_Spinlock) 589 { 590 591 XX_LockSpinlock(h_Spinlock); 592 return (0); 593 } 594 595 void 596 XX_UnlockIntrSpinlock(t_Handle h_Spinlock, uint32_t intrFlags) 597 { 598 599 XX_UnlockSpinlock(h_Spinlock); 600 } 601 602 uint32_t 603 XX_CurrentTime(void) 604 { 605 /* Not referenced */ 606 printf("NetCommSW: Unimplemented function %s() called!\n", __func__); 607 return (0); 608 } 609 610 611 t_Handle 612 XX_CreateTimer(void) 613 { 614 /* Not referenced */ 615 printf("NetCommSW: Unimplemented function %s() called!\n", __func__); 616 return (NULL); 617 } 618 619 void 620 XX_FreeTimer(t_Handle h_Timer) 621 { 622 /* Not referenced */ 623 printf("NetCommSW: Unimplemented function %s() called!\n", __func__); 624 } 625 626 void 627 XX_StartTimer(t_Handle h_Timer, 628 uint32_t msecs, 629 bool periodic, 630 void (*f_TimerExpired)(t_Handle), 631 t_Handle h_Arg) 632 { 633 /* Not referenced */ 634 printf("NetCommSW: Unimplemented function %s() called!\n", __func__); 635 } 636 637 uint32_t 638 XX_GetExpirationTime(t_Handle h_Timer) 639 { 640 /* Not referenced */ 641 printf("NetCommSW: Unimplemented function %s() called!\n", __func__); 642 return (0); 643 } 644 645 void 646 XX_StopTimer(t_Handle h_Timer) 647 { 648 /* Not referenced */ 649 printf("NetCommSW: Unimplemented function %s() called!\n", __func__); 650 } 651 652 void 653 XX_ModTimer(t_Handle h_Timer, uint32_t msecs) 654 { 655 /* Not referenced */ 656 printf("NetCommSW: Unimplemented function %s() called!\n", __func__); 657 } 658 659 int 660 XX_TimerIsActive(t_Handle h_Timer) 661 { 662 /* Not referenced */ 663 printf("NetCommSW: Unimplemented function %s() called!\n", __func__); 664 return (0); 665 } 666 667 uint32_t 668 XX_Sleep(uint32_t msecs) 669 { 670 671 XX_UDelay(1000 * msecs); 672 return (0); 673 } 674 675 void 676 XX_UDelay(uint32_t usecs) 677 { 678 DELAY(usecs); 679 } 680 681 t_Error 682 XX_IpcRegisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH], 683 t_IpcMsgHandler *f_MsgHandler, t_Handle h_Module, uint32_t replyLength) 684 { 685 686 /* 687 * This function returns fake E_OK status and does nothing 688 * as NetCommSW IPC is not used by FreeBSD drivers. 689 */ 690 return (E_OK); 691 } 692 693 t_Error 694 XX_IpcUnregisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH]) 695 { 696 /* 697 * This function returns fake E_OK status and does nothing 698 * as NetCommSW IPC is not used by FreeBSD drivers. 699 */ 700 return (E_OK); 701 } 702 703 704 t_Error 705 XX_IpcSendMessage(t_Handle h_Session, 706 uint8_t *p_Msg, uint32_t msgLength, uint8_t *p_Reply, 707 uint32_t *p_ReplyLength, t_IpcMsgCompletion *f_Completion, t_Handle h_Arg) 708 { 709 710 /* Should not be called */ 711 printf("NetCommSW: Unimplemented function %s() called!\n", __func__); 712 return (E_OK); 713 } 714 715 t_Handle 716 XX_IpcInitSession(char destAddr[XX_IPC_MAX_ADDR_NAME_LENGTH], 717 char srcAddr[XX_IPC_MAX_ADDR_NAME_LENGTH]) 718 { 719 720 /* Should not be called */ 721 printf("NetCommSW: Unimplemented function %s() called!\n", __func__); 722 return (E_OK); 723 } 724 725 t_Error 726 XX_IpcFreeSession(t_Handle h_Session) 727 { 728 729 /* Should not be called */ 730 printf("NetCommSW: Unimplemented function %s() called!\n", __func__); 731 return (E_OK); 732 } 733 734 physAddress_t 735 XX_VirtToPhys(void *addr) 736 { 737 vm_paddr_t paddr; 738 int cpu; 739 740 cpu = PCPU_GET(cpuid); 741 742 /* Handle NULL address */ 743 if (addr == NULL) 744 return (-1); 745 746 /* Check CCSR */ 747 if ((vm_offset_t)addr >= ccsrbar_va && 748 (vm_offset_t)addr < ccsrbar_va + ccsrbar_size) 749 return (((vm_offset_t)addr - ccsrbar_va) + ccsrbar_pa); 750 751 /* Handle BMAN mappings */ 752 if (((vm_offset_t)addr >= XX_PInfo.portal_ce_va[BM_PORTAL]) && 753 ((vm_offset_t)addr < XX_PInfo.portal_ce_va[BM_PORTAL] + 754 XX_PInfo.portal_ce_size[BM_PORTAL][cpu])) 755 return (XX_PInfo.portal_ce_pa[BM_PORTAL][cpu] + 756 (vm_offset_t)addr - XX_PInfo.portal_ce_va[BM_PORTAL]); 757 758 if (((vm_offset_t)addr >= XX_PInfo.portal_ci_va[BM_PORTAL]) && 759 ((vm_offset_t)addr < XX_PInfo.portal_ci_va[BM_PORTAL] + 760 XX_PInfo.portal_ci_size[BM_PORTAL][cpu])) 761 return (XX_PInfo.portal_ci_pa[BM_PORTAL][cpu] + 762 (vm_offset_t)addr - XX_PInfo.portal_ci_va[BM_PORTAL]); 763 764 /* Handle QMAN mappings */ 765 if (((vm_offset_t)addr >= XX_PInfo.portal_ce_va[QM_PORTAL]) && 766 ((vm_offset_t)addr < XX_PInfo.portal_ce_va[QM_PORTAL] + 767 XX_PInfo.portal_ce_size[QM_PORTAL][cpu])) 768 return (XX_PInfo.portal_ce_pa[QM_PORTAL][cpu] + 769 (vm_offset_t)addr - XX_PInfo.portal_ce_va[QM_PORTAL]); 770 771 if (((vm_offset_t)addr >= XX_PInfo.portal_ci_va[QM_PORTAL]) && 772 ((vm_offset_t)addr < XX_PInfo.portal_ci_va[QM_PORTAL] + 773 XX_PInfo.portal_ci_size[QM_PORTAL][cpu])) 774 return (XX_PInfo.portal_ci_pa[QM_PORTAL][cpu] + 775 (vm_offset_t)addr - XX_PInfo.portal_ci_va[QM_PORTAL]); 776 777 paddr = pmap_kextract((vm_offset_t)addr); 778 if (paddr == 0) 779 printf("NetCommSW: " 780 "Unable to translate virtual address 0x%08X!\n", addr); 781 else 782 pmap_track_page(kernel_pmap, (vm_offset_t)addr); 783 784 return (paddr); 785 } 786 787 void * 788 XX_PhysToVirt(physAddress_t addr) 789 { 790 struct pv_entry *pv; 791 vm_page_t page; 792 int cpu; 793 794 /* Check CCSR */ 795 if (addr >= ccsrbar_pa && addr < ccsrbar_pa + ccsrbar_size) 796 return ((void *)((vm_offset_t)(addr - ccsrbar_pa) + 797 ccsrbar_va)); 798 799 cpu = PCPU_GET(cpuid); 800 801 /* Handle BMAN mappings */ 802 if ((addr >= XX_PInfo.portal_ce_pa[BM_PORTAL][cpu]) && 803 (addr < XX_PInfo.portal_ce_pa[BM_PORTAL][cpu] + 804 XX_PInfo.portal_ce_size[BM_PORTAL][cpu])) 805 return ((void *)(XX_PInfo.portal_ci_va[BM_PORTAL] + 806 (vm_offset_t)(addr - XX_PInfo.portal_ci_pa[BM_PORTAL][cpu]))); 807 808 if ((addr >= XX_PInfo.portal_ci_pa[BM_PORTAL][cpu]) && 809 (addr < XX_PInfo.portal_ci_pa[BM_PORTAL][cpu] + 810 XX_PInfo.portal_ci_size[BM_PORTAL][cpu])) 811 return ((void *)(XX_PInfo.portal_ci_va[BM_PORTAL] + 812 (vm_offset_t)(addr - XX_PInfo.portal_ci_pa[BM_PORTAL][cpu]))); 813 814 /* Handle QMAN mappings */ 815 if ((addr >= XX_PInfo.portal_ce_pa[QM_PORTAL][cpu]) && 816 (addr < XX_PInfo.portal_ce_pa[QM_PORTAL][cpu] + 817 XX_PInfo.portal_ce_size[QM_PORTAL][cpu])) 818 return ((void *)(XX_PInfo.portal_ce_va[QM_PORTAL] + 819 (vm_offset_t)(addr - XX_PInfo.portal_ce_pa[QM_PORTAL][cpu]))); 820 821 if ((addr >= XX_PInfo.portal_ci_pa[QM_PORTAL][cpu]) && 822 (addr < XX_PInfo.portal_ci_pa[QM_PORTAL][cpu] + 823 XX_PInfo.portal_ci_size[QM_PORTAL][cpu])) 824 return ((void *)(XX_PInfo.portal_ci_va[QM_PORTAL] + 825 (vm_offset_t)(addr - XX_PInfo.portal_ci_pa[QM_PORTAL][cpu]))); 826 827 page = PHYS_TO_VM_PAGE(addr); 828 pv = TAILQ_FIRST(&page->md.pv_list); 829 830 if (pv != NULL) 831 return ((void *)(pv->pv_va + ((vm_offset_t)addr & PAGE_MASK))); 832 833 printf("NetCommSW: " 834 "Unable to translate physical address 0x%08llX!\n", addr); 835 836 return (NULL); 837 } 838 839 void 840 XX_PortalSetInfo(device_t dev) 841 { 842 char *dev_name; 843 struct dpaa_portals_softc *sc; 844 int i, type, len; 845 846 dev_name = malloc(sizeof(*dev_name), M_TEMP, M_WAITOK | 847 M_ZERO); 848 849 len = strlen("bman-portals"); 850 851 strncpy(dev_name, device_get_name(dev), len); 852 853 if (strncmp(dev_name, "bman-portals", len) && strncmp(dev_name, 854 "qman-portals", len)) 855 goto end; 856 857 if (strncmp(dev_name, "bman-portals", len) == 0) 858 type = BM_PORTAL; 859 else 860 type = QM_PORTAL; 861 862 sc = device_get_softc(dev); 863 864 for (i = 0; sc->sc_dp[i].dp_ce_pa != 0; i++) { 865 XX_PInfo.portal_ce_pa[type][i] = sc->sc_dp[i].dp_ce_pa; 866 XX_PInfo.portal_ci_pa[type][i] = sc->sc_dp[i].dp_ci_pa; 867 XX_PInfo.portal_ce_size[type][i] = sc->sc_dp[i].dp_ce_size; 868 XX_PInfo.portal_ci_size[type][i] = sc->sc_dp[i].dp_ci_size; 869 XX_PInfo.portal_intr[type][i] = sc->sc_dp[i].dp_intr_num; 870 } 871 872 XX_PInfo.portal_ce_va[type] = rman_get_bushandle(sc->sc_rres[0]); 873 XX_PInfo.portal_ci_va[type] = rman_get_bushandle(sc->sc_rres[1]); 874 end: 875 free(dev_name, M_TEMP); 876 } 877