xref: /freebsd/sys/contrib/ncsw/user/env/xx.c (revision 13464e4a44fc58490a03bb8bfc7e3c972e9c30b2)
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