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