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 */
81MALLOC_DEFINE(M_NETCOMMSW, "NetCommSW", "NetCommSW software stack");
82MALLOC_DEFINE(M_NETCOMMSW_MT, "NetCommSWTrack",
83    "NetCommSW software allocation tracker");
84
85/* MallocSmart data structures */
86static void *XX_MallocSmartPool;
87static int XX_MallocSmartMap[MALLOCSMART_SLICES];
88
89static struct mtx XX_MallocSmartLock;
90static struct mtx XX_MallocTrackLock;
91MTX_SYSINIT(XX_MallocSmartLockInit, &XX_MallocSmartLock,
92    "NetCommSW MallocSmart Lock", MTX_DEF);
93MTX_SYSINIT(XX_MallocTrackLockInit, &XX_MallocTrackLock,
94    "NetCommSW MallocTrack Lock", MTX_DEF);
95
96/* Interrupt info */
97#define XX_INTR_FLAG_PREALLOCATED	(1 << 0)
98
99struct XX_IntrInfo {
100	driver_intr_t	*handler;
101	void		*arg;
102	int		cpu;
103	int		flags;
104	void		*cookie;
105};
106
107static struct XX_IntrInfo XX_IntrInfo[INTR_VECTORS];
108/* Portal type identifiers */
109enum XX_PortalIdent{
110	BM_PORTAL = 0,
111	QM_PORTAL,
112};
113/* Structure to store portals' properties */
114struct 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
124static struct XX_PortalInfo XX_PInfo;
125
126void
127XX_Exit(int status)
128{
129
130	panic("NetCommSW: Exit called with status %i", status);
131}
132
133void
134XX_Print(char *str, ...)
135{
136	va_list ap;
137
138	va_start(ap, str);
139	vprintf(str, ap);
140	va_end(ap);
141}
142
143void *
144XX_Malloc(uint32_t size)
145{
146	void *p = (malloc(size, M_NETCOMMSW, M_NOWAIT));
147
148	return (p);
149}
150
151static int
152XX_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
163static void
164XX_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
174static void
175XX_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
185int
186XX_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
204out:
205	mtx_unlock(&XX_MallocSmartLock);
206	return (error);
207}
208
209void *
210XX_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
240void
241XX_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
263void
264XX_Free(void *p)
265{
266
267	free(p, M_NETCOMMSW);
268}
269
270uint32_t
271XX_DisableAllIntr(void)
272{
273
274	return (intr_disable());
275}
276
277void
278XX_RestoreAllIntr(uint32_t flags)
279{
280
281	intr_restore(flags);
282}
283
284static bool
285XX_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
297static void
298XX_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
312t_Error
313XX_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
336t_Error
337XX_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
352t_Error
353XX_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
387t_Error
388XX_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
411t_Error
412XX_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
424t_Error
425XX_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
437t_TaskletHandle
438XX_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
446void
447XX_FreeTasklet (t_TaskletHandle h_Tasklet)
448{
449	/* Not referenced */
450	printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
451}
452
453int
454XX_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
461void
462XX_FlushScheduledTasks(void)
463{
464	/* Not referenced */
465	printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
466}
467
468int
469XX_TaskletIsQueued(t_TaskletHandle h_Tasklet)
470{
471	/* Not referenced */
472	printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
473	return (0);
474}
475
476void
477XX_SetTaskletData(t_TaskletHandle h_Tasklet, t_Handle data)
478{
479	/* Not referenced */
480	printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
481}
482
483t_Handle
484XX_GetTaskletData(t_TaskletHandle h_Tasklet)
485{
486	/* Not referenced */
487	printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
488	return (NULL);
489}
490
491t_Handle
492XX_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
505void
506XX_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
516void
517XX_LockSpinlock(t_Handle h_Spinlock)
518{
519	struct mtx *m;
520
521	m = h_Spinlock;
522	mtx_lock(m);
523}
524
525void
526XX_UnlockSpinlock(t_Handle h_Spinlock)
527{
528	struct mtx *m;
529
530	m = h_Spinlock;
531	mtx_unlock(m);
532}
533
534uint32_t
535XX_LockIntrSpinlock(t_Handle h_Spinlock)
536{
537
538	XX_LockSpinlock(h_Spinlock);
539	return (0);
540}
541
542void
543XX_UnlockIntrSpinlock(t_Handle h_Spinlock, uint32_t intrFlags)
544{
545
546	XX_UnlockSpinlock(h_Spinlock);
547}
548
549uint32_t
550XX_Sleep(uint32_t msecs)
551{
552
553	XX_UDelay(1000 * msecs);
554	return (0);
555}
556
557void
558XX_UDelay(uint32_t usecs)
559{
560	DELAY(usecs);
561}
562
563t_Error
564XX_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
575t_Error
576XX_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
586t_Error
587XX_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
597t_Handle
598XX_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
607t_Error
608XX_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
616physAddress_t
617XX_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
674void *
675XX_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
729void
730XX_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]);
764end:
765	free(dev_name, M_TEMP);
766}
767