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 "error_ext.h"
55 #include "std_ext.h"
56 #include "list_ext.h"
57 #include "mm_ext.h"
58
59 /* Configuration */
60
61 /* Define the number of dTSEC ports active in system */
62 #define MALLOCSMART_DTSEC_IN_USE 4
63
64 /*
65 * Calculate malloc's pool size for dTSEC's buffers.
66 * We reserve 1MB pool for each dTSEC port.
67 */
68 #define MALLOCSMART_POOL_SIZE \
69 (MALLOCSMART_DTSEC_IN_USE * 1024 * 1024)
70
71 #define MALLOCSMART_SLICE_SIZE (PAGE_SIZE / 2) /* 2kB */
72
73 /* Defines */
74 #define MALLOCSMART_SIZE_TO_SLICE(x) \
75 (((x) + MALLOCSMART_SLICE_SIZE - 1) / MALLOCSMART_SLICE_SIZE)
76 #define MALLOCSMART_SLICES \
77 MALLOCSMART_SIZE_TO_SLICE(MALLOCSMART_POOL_SIZE)
78
79 /* Malloc Pool for NetCommSW */
80 MALLOC_DEFINE(M_NETCOMMSW, "NetCommSW", "NetCommSW software stack");
81 MALLOC_DEFINE(M_NETCOMMSW_MT, "NetCommSWTrack",
82 "NetCommSW software allocation tracker");
83
84 /* MallocSmart data structures */
85 static void *XX_MallocSmartPool;
86 static int XX_MallocSmartMap[MALLOCSMART_SLICES];
87
88 static struct mtx XX_MallocSmartLock;
89 static struct mtx XX_MallocTrackLock;
90 MTX_SYSINIT(XX_MallocSmartLockInit, &XX_MallocSmartLock,
91 "NetCommSW MallocSmart Lock", MTX_DEF);
92 MTX_SYSINIT(XX_MallocTrackLockInit, &XX_MallocTrackLock,
93 "NetCommSW MallocTrack Lock", MTX_DEF);
94
95 /* Interrupt info */
96 #define XX_INTR_FLAG_PREALLOCATED (1 << 0)
97 #define XX_INTR_FLAG_BOUND (1 << 1)
98 #define XX_INTR_FLAG_FMAN_FIX (1 << 2)
99
100 struct XX_IntrInfo {
101 driver_intr_t *handler;
102 void *arg;
103 int cpu;
104 int flags;
105 void *cookie;
106 };
107
108 static struct XX_IntrInfo XX_IntrInfo[INTR_VECTORS];
109 /* Portal type identifiers */
110 enum XX_PortalIdent{
111 BM_PORTAL = 0,
112 QM_PORTAL,
113 };
114 /* Structure to store portals' properties */
115 struct XX_PortalInfo {
116 vm_paddr_t portal_ce_pa[2][MAXCPU];
117 vm_paddr_t portal_ci_pa[2][MAXCPU];
118 uint32_t portal_ce_size[2][MAXCPU];
119 uint32_t portal_ci_size[2][MAXCPU];
120 vm_offset_t portal_ce_va[2];
121 vm_offset_t portal_ci_va[2];
122 uint32_t portal_intr[2][MAXCPU];
123 };
124
125 static struct XX_PortalInfo XX_PInfo;
126
127 /* The lower 9 bits, through emprical testing, tend to be 0. */
128 #define XX_MALLOC_TRACK_SHIFT 9
129
130 typedef struct XX_MallocTrackStruct {
131 LIST_ENTRY(XX_MallocTrackStruct) entries;
132 physAddress_t pa;
133 void *va;
134 } XX_MallocTrackStruct;
135
136 LIST_HEAD(XX_MallocTrackerList, XX_MallocTrackStruct) *XX_MallocTracker;
137 u_long XX_MallocHashMask;
138 static XX_MallocTrackStruct * XX_FindTracker(physAddress_t pa);
139
140 void
XX_Exit(int status)141 XX_Exit(int status)
142 {
143
144 panic("NetCommSW: Exit called with status %i", status);
145 }
146
147 void
XX_Print(char * str,...)148 XX_Print(char *str, ...)
149 {
150 va_list ap;
151
152 va_start(ap, str);
153 vprintf(str, ap);
154 va_end(ap);
155 }
156
157 void *
XX_Malloc(uint32_t size)158 XX_Malloc(uint32_t size)
159 {
160 void *p = (malloc(size, M_NETCOMMSW, M_NOWAIT));
161
162 return (p);
163 }
164
165 static int
XX_MallocSmartMapCheck(unsigned int start,unsigned int slices)166 XX_MallocSmartMapCheck(unsigned int start, unsigned int slices)
167 {
168 unsigned int i;
169
170 mtx_assert(&XX_MallocSmartLock, MA_OWNED);
171 for (i = start; i < start + slices; i++)
172 if (XX_MallocSmartMap[i])
173 return (FALSE);
174 return (TRUE);
175 }
176
177 static void
XX_MallocSmartMapSet(unsigned int start,unsigned int slices)178 XX_MallocSmartMapSet(unsigned int start, unsigned int slices)
179 {
180 unsigned int i;
181
182 mtx_assert(&XX_MallocSmartLock, MA_OWNED);
183
184 for (i = start; i < start + slices; i++)
185 XX_MallocSmartMap[i] = ((i == start) ? slices : -1);
186 }
187
188 static void
XX_MallocSmartMapClear(unsigned int start,unsigned int slices)189 XX_MallocSmartMapClear(unsigned int start, unsigned int slices)
190 {
191 unsigned int i;
192
193 mtx_assert(&XX_MallocSmartLock, MA_OWNED);
194
195 for (i = start; i < start + slices; i++)
196 XX_MallocSmartMap[i] = 0;
197 }
198
199 int
XX_MallocSmartInit(void)200 XX_MallocSmartInit(void)
201 {
202 int error;
203
204 error = E_OK;
205 mtx_lock(&XX_MallocSmartLock);
206
207 if (XX_MallocSmartPool)
208 goto out;
209
210 /* Allocate MallocSmart pool */
211 XX_MallocSmartPool = contigmalloc(MALLOCSMART_POOL_SIZE, M_NETCOMMSW,
212 M_NOWAIT, 0, 0xFFFFFFFFFull, MALLOCSMART_POOL_SIZE, 0);
213 if (!XX_MallocSmartPool) {
214 error = E_NO_MEMORY;
215 goto out;
216 }
217
218 out:
219 mtx_unlock(&XX_MallocSmartLock);
220 return (error);
221 }
222
223 void *
XX_MallocSmart(uint32_t size,int memPartitionId,uint32_t alignment)224 XX_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment)
225 {
226 unsigned int i;
227 vm_offset_t addr;
228
229 addr = 0;
230
231 /* Convert alignment and size to number of slices */
232 alignment = MALLOCSMART_SIZE_TO_SLICE(alignment);
233 size = MALLOCSMART_SIZE_TO_SLICE(size);
234
235 /* Lock resources */
236 mtx_lock(&XX_MallocSmartLock);
237
238 /* Allocate region */
239 for (i = 0; i + size <= MALLOCSMART_SLICES; i += alignment) {
240 if (XX_MallocSmartMapCheck(i, size)) {
241 XX_MallocSmartMapSet(i, size);
242 addr = (vm_offset_t)XX_MallocSmartPool +
243 (i * MALLOCSMART_SLICE_SIZE);
244 break;
245 }
246 }
247
248 /* Unlock resources */
249 mtx_unlock(&XX_MallocSmartLock);
250
251 return ((void *)addr);
252 }
253
254 void
XX_FreeSmart(void * p)255 XX_FreeSmart(void *p)
256 {
257 unsigned int start, slices;
258
259 /* Calculate first slice of region */
260 start = MALLOCSMART_SIZE_TO_SLICE((vm_offset_t)(p) -
261 (vm_offset_t)XX_MallocSmartPool);
262
263 /* Lock resources */
264 mtx_lock(&XX_MallocSmartLock);
265
266 KASSERT(XX_MallocSmartMap[start] > 0,
267 ("XX_FreeSmart: Double or mid-block free!\n"));
268
269 XX_UntrackAddress(p);
270 /* Free region */
271 slices = XX_MallocSmartMap[start];
272 XX_MallocSmartMapClear(start, slices);
273
274 /* Unlock resources */
275 mtx_unlock(&XX_MallocSmartLock);
276 }
277
278 void
XX_Free(void * p)279 XX_Free(void *p)
280 {
281
282 if (p != NULL)
283 XX_UntrackAddress(p);
284 free(p, M_NETCOMMSW);
285 }
286
287 uint32_t
XX_DisableAllIntr(void)288 XX_DisableAllIntr(void)
289 {
290
291 return (intr_disable());
292 }
293
294 void
XX_RestoreAllIntr(uint32_t flags)295 XX_RestoreAllIntr(uint32_t flags)
296 {
297
298 intr_restore(flags);
299 }
300
301 t_Error
XX_Call(uint32_t qid,t_Error (* f)(t_Handle),t_Handle id,t_Handle appId,uint16_t flags)302 XX_Call(uint32_t qid, t_Error (* f)(t_Handle), t_Handle id, t_Handle appId, uint16_t flags )
303 {
304 /* Not referenced */
305 printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
306 return (E_OK);
307 }
308
309 static bool
XX_IsPortalIntr(int irq)310 XX_IsPortalIntr(int irq)
311 {
312 int cpu, type;
313 /* Check interrupt numbers of all available portals */
314 for (cpu = 0, type = 0; XX_PInfo.portal_intr[type][cpu] != 0; cpu++) {
315 if (irq == XX_PInfo.portal_intr[type][cpu]) {
316 /* Found it! */
317 return (1);
318 }
319 if (XX_PInfo.portal_intr[type][cpu + 1] == 0) {
320 type++;
321 cpu = 0;
322 }
323 }
324
325 return (0);
326 }
327
328 void
XX_FmanFixIntr(int irq)329 XX_FmanFixIntr(int irq)
330 {
331
332 XX_IntrInfo[irq].flags |= XX_INTR_FLAG_FMAN_FIX;
333 }
334
335 static bool
XX_FmanNeedsIntrFix(int irq)336 XX_FmanNeedsIntrFix(int irq)
337 {
338
339 if (XX_IntrInfo[irq].flags & XX_INTR_FLAG_FMAN_FIX)
340 return (1);
341
342 return (0);
343 }
344
345 static void
XX_Dispatch(void * arg)346 XX_Dispatch(void *arg)
347 {
348 struct XX_IntrInfo *info;
349
350 info = arg;
351
352 /* Bind this thread to proper CPU when SMP has been already started. */
353 if ((info->flags & XX_INTR_FLAG_BOUND) == 0 && smp_started &&
354 info->cpu >= 0) {
355 thread_lock(curthread);
356 sched_bind(curthread, info->cpu);
357 thread_unlock(curthread);
358
359 info->flags |= XX_INTR_FLAG_BOUND;
360 }
361
362 if (info->handler == NULL) {
363 printf("%s(): IRQ handler is NULL!\n", __func__);
364 return;
365 }
366
367 info->handler(info->arg);
368 }
369
370 t_Error
XX_PreallocAndBindIntr(int irq,unsigned int cpu)371 XX_PreallocAndBindIntr(int irq, unsigned int cpu)
372 {
373 struct resource *r;
374 unsigned int inum;
375 t_Error error;
376
377 r = (struct resource *)irq;
378 inum = rman_get_start(r);
379
380 error = XX_SetIntr(irq, XX_Dispatch, &XX_IntrInfo[inum]);
381 if (error != 0)
382 return (error);
383
384 XX_IntrInfo[inum].flags = XX_INTR_FLAG_PREALLOCATED;
385 XX_IntrInfo[inum].cpu = cpu;
386
387 return (E_OK);
388 }
389
390 t_Error
XX_DeallocIntr(int irq)391 XX_DeallocIntr(int irq)
392 {
393 struct resource *r;
394 unsigned int inum;
395
396 r = (struct resource *)irq;
397 inum = rman_get_start(r);
398
399 if ((XX_IntrInfo[inum].flags & XX_INTR_FLAG_PREALLOCATED) == 0)
400 return (E_INVALID_STATE);
401
402 XX_IntrInfo[inum].flags = 0;
403 return (XX_FreeIntr(irq));
404 }
405
406 t_Error
XX_SetIntr(int irq,t_Isr * f_Isr,t_Handle handle)407 XX_SetIntr(int irq, t_Isr *f_Isr, t_Handle handle)
408 {
409 struct device *dev;
410 struct resource *r;
411 unsigned int flags;
412 int err;
413
414 r = (struct resource *)irq;
415 dev = rman_get_device(r);
416 irq = rman_get_start(r);
417
418 /* Handle preallocated interrupts */
419 if (XX_IntrInfo[irq].flags & XX_INTR_FLAG_PREALLOCATED) {
420 if (XX_IntrInfo[irq].handler != NULL)
421 return (E_BUSY);
422
423 XX_IntrInfo[irq].handler = f_Isr;
424 XX_IntrInfo[irq].arg = handle;
425
426 return (E_OK);
427 }
428
429 flags = INTR_TYPE_NET | INTR_MPSAFE;
430
431 /* BMAN/QMAN Portal interrupts must be exlusive */
432 if (XX_IsPortalIntr(irq))
433 flags |= INTR_EXCL;
434
435 err = bus_setup_intr(dev, r, flags, NULL, f_Isr, handle,
436 &XX_IntrInfo[irq].cookie);
437 if (err)
438 goto finish;
439
440 /*
441 * XXX: Bind FMan IRQ to CPU0. Current interrupt subsystem directs each
442 * interrupt to all CPUs. Race between an interrupt assertion and
443 * masking may occur and interrupt handler may be called multiple times
444 * per one interrupt. FMan doesn't support such a situation. Workaround
445 * is to bind FMan interrupt to one CPU0 only.
446 */
447 #ifdef SMP
448 if (XX_FmanNeedsIntrFix(irq))
449 err = powerpc_bind_intr(irq, 0);
450 #endif
451 finish:
452 return (err);
453 }
454
455 t_Error
XX_FreeIntr(int irq)456 XX_FreeIntr(int irq)
457 {
458 struct device *dev;
459 struct resource *r;
460
461 r = (struct resource *)irq;
462 dev = rman_get_device(r);
463 irq = rman_get_start(r);
464
465 /* Handle preallocated interrupts */
466 if (XX_IntrInfo[irq].flags & XX_INTR_FLAG_PREALLOCATED) {
467 if (XX_IntrInfo[irq].handler == NULL)
468 return (E_INVALID_STATE);
469
470 XX_IntrInfo[irq].handler = NULL;
471 XX_IntrInfo[irq].arg = NULL;
472
473 return (E_OK);
474 }
475
476 return (bus_teardown_intr(dev, r, XX_IntrInfo[irq].cookie));
477 }
478
479 t_Error
XX_EnableIntr(int irq)480 XX_EnableIntr(int irq)
481 {
482 struct resource *r;
483
484 r = (struct resource *)irq;
485 irq = rman_get_start(r);
486
487 powerpc_intr_unmask(irq);
488
489 return (E_OK);
490 }
491
492 t_Error
XX_DisableIntr(int irq)493 XX_DisableIntr(int irq)
494 {
495 struct resource *r;
496
497 r = (struct resource *)irq;
498 irq = rman_get_start(r);
499
500 powerpc_intr_mask(irq);
501
502 return (E_OK);
503 }
504
505 t_TaskletHandle
XX_InitTasklet(void (* routine)(void *),void * data)506 XX_InitTasklet (void (*routine)(void *), void *data)
507 {
508 /* Not referenced */
509 printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
510 return (NULL);
511 }
512
513
514 void
XX_FreeTasklet(t_TaskletHandle h_Tasklet)515 XX_FreeTasklet (t_TaskletHandle h_Tasklet)
516 {
517 /* Not referenced */
518 printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
519 }
520
521 int
XX_ScheduleTask(t_TaskletHandle h_Tasklet,int immediate)522 XX_ScheduleTask(t_TaskletHandle h_Tasklet, int immediate)
523 {
524 /* Not referenced */
525 printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
526 return (0);
527 }
528
529 void
XX_FlushScheduledTasks(void)530 XX_FlushScheduledTasks(void)
531 {
532 /* Not referenced */
533 printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
534 }
535
536 int
XX_TaskletIsQueued(t_TaskletHandle h_Tasklet)537 XX_TaskletIsQueued(t_TaskletHandle h_Tasklet)
538 {
539 /* Not referenced */
540 printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
541 return (0);
542 }
543
544 void
XX_SetTaskletData(t_TaskletHandle h_Tasklet,t_Handle data)545 XX_SetTaskletData(t_TaskletHandle h_Tasklet, t_Handle data)
546 {
547 /* Not referenced */
548 printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
549 }
550
551 t_Handle
XX_GetTaskletData(t_TaskletHandle h_Tasklet)552 XX_GetTaskletData(t_TaskletHandle h_Tasklet)
553 {
554 /* Not referenced */
555 printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
556 return (NULL);
557 }
558
559 t_Handle
XX_InitSpinlock(void)560 XX_InitSpinlock(void)
561 {
562 struct mtx *m;
563
564 m = malloc(sizeof(*m), M_NETCOMMSW, M_NOWAIT | M_ZERO);
565 if (!m)
566 return (0);
567
568 mtx_init(m, "NetCommSW Lock", NULL, MTX_DEF | MTX_DUPOK);
569
570 return (m);
571 }
572
573 void
XX_FreeSpinlock(t_Handle h_Spinlock)574 XX_FreeSpinlock(t_Handle h_Spinlock)
575 {
576 struct mtx *m;
577
578 m = h_Spinlock;
579
580 mtx_destroy(m);
581 free(m, M_NETCOMMSW);
582 }
583
584 void
XX_LockSpinlock(t_Handle h_Spinlock)585 XX_LockSpinlock(t_Handle h_Spinlock)
586 {
587 struct mtx *m;
588
589 m = h_Spinlock;
590 mtx_lock(m);
591 }
592
593 void
XX_UnlockSpinlock(t_Handle h_Spinlock)594 XX_UnlockSpinlock(t_Handle h_Spinlock)
595 {
596 struct mtx *m;
597
598 m = h_Spinlock;
599 mtx_unlock(m);
600 }
601
602 uint32_t
XX_LockIntrSpinlock(t_Handle h_Spinlock)603 XX_LockIntrSpinlock(t_Handle h_Spinlock)
604 {
605
606 XX_LockSpinlock(h_Spinlock);
607 return (0);
608 }
609
610 void
XX_UnlockIntrSpinlock(t_Handle h_Spinlock,uint32_t intrFlags)611 XX_UnlockIntrSpinlock(t_Handle h_Spinlock, uint32_t intrFlags)
612 {
613
614 XX_UnlockSpinlock(h_Spinlock);
615 }
616
617 uint32_t
XX_CurrentTime(void)618 XX_CurrentTime(void)
619 {
620 /* Not referenced */
621 printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
622 return (0);
623 }
624
625
626 t_Handle
XX_CreateTimer(void)627 XX_CreateTimer(void)
628 {
629 /* Not referenced */
630 printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
631 return (NULL);
632 }
633
634 void
XX_FreeTimer(t_Handle h_Timer)635 XX_FreeTimer(t_Handle h_Timer)
636 {
637 /* Not referenced */
638 printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
639 }
640
641 void
XX_StartTimer(t_Handle h_Timer,uint32_t msecs,bool periodic,void (* f_TimerExpired)(t_Handle),t_Handle h_Arg)642 XX_StartTimer(t_Handle h_Timer,
643 uint32_t msecs,
644 bool periodic,
645 void (*f_TimerExpired)(t_Handle),
646 t_Handle h_Arg)
647 {
648 /* Not referenced */
649 printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
650 }
651
652 uint32_t
XX_GetExpirationTime(t_Handle h_Timer)653 XX_GetExpirationTime(t_Handle h_Timer)
654 {
655 /* Not referenced */
656 printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
657 return (0);
658 }
659
660 void
XX_StopTimer(t_Handle h_Timer)661 XX_StopTimer(t_Handle h_Timer)
662 {
663 /* Not referenced */
664 printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
665 }
666
667 void
XX_ModTimer(t_Handle h_Timer,uint32_t msecs)668 XX_ModTimer(t_Handle h_Timer, uint32_t msecs)
669 {
670 /* Not referenced */
671 printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
672 }
673
674 int
XX_TimerIsActive(t_Handle h_Timer)675 XX_TimerIsActive(t_Handle h_Timer)
676 {
677 /* Not referenced */
678 printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
679 return (0);
680 }
681
682 uint32_t
XX_Sleep(uint32_t msecs)683 XX_Sleep(uint32_t msecs)
684 {
685
686 XX_UDelay(1000 * msecs);
687 return (0);
688 }
689
690 void
XX_UDelay(uint32_t usecs)691 XX_UDelay(uint32_t usecs)
692 {
693 DELAY(usecs);
694 }
695
696 t_Error
XX_IpcRegisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH],t_IpcMsgHandler * f_MsgHandler,t_Handle h_Module,uint32_t replyLength)697 XX_IpcRegisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH],
698 t_IpcMsgHandler *f_MsgHandler, t_Handle h_Module, uint32_t replyLength)
699 {
700
701 /*
702 * This function returns fake E_OK status and does nothing
703 * as NetCommSW IPC is not used by FreeBSD drivers.
704 */
705 return (E_OK);
706 }
707
708 t_Error
XX_IpcUnregisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH])709 XX_IpcUnregisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH])
710 {
711 /*
712 * This function returns fake E_OK status and does nothing
713 * as NetCommSW IPC is not used by FreeBSD drivers.
714 */
715 return (E_OK);
716 }
717
718
719 t_Error
XX_IpcSendMessage(t_Handle h_Session,uint8_t * p_Msg,uint32_t msgLength,uint8_t * p_Reply,uint32_t * p_ReplyLength,t_IpcMsgCompletion * f_Completion,t_Handle h_Arg)720 XX_IpcSendMessage(t_Handle h_Session,
721 uint8_t *p_Msg, uint32_t msgLength, uint8_t *p_Reply,
722 uint32_t *p_ReplyLength, t_IpcMsgCompletion *f_Completion, t_Handle h_Arg)
723 {
724
725 /* Should not be called */
726 printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
727 return (E_OK);
728 }
729
730 t_Handle
XX_IpcInitSession(char destAddr[XX_IPC_MAX_ADDR_NAME_LENGTH],char srcAddr[XX_IPC_MAX_ADDR_NAME_LENGTH])731 XX_IpcInitSession(char destAddr[XX_IPC_MAX_ADDR_NAME_LENGTH],
732 char srcAddr[XX_IPC_MAX_ADDR_NAME_LENGTH])
733 {
734
735 /* Should not be called */
736 printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
737 return (E_OK);
738 }
739
740 t_Error
XX_IpcFreeSession(t_Handle h_Session)741 XX_IpcFreeSession(t_Handle h_Session)
742 {
743
744 /* Should not be called */
745 printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
746 return (E_OK);
747 }
748
749 extern void db_trace_self(void);
750 physAddress_t
XX_VirtToPhys(void * addr)751 XX_VirtToPhys(void *addr)
752 {
753 vm_paddr_t paddr;
754 int cpu;
755
756 cpu = PCPU_GET(cpuid);
757
758 /* Handle NULL address */
759 if (addr == NULL)
760 return (-1);
761
762 /* Handle BMAN mappings */
763 if (((vm_offset_t)addr >= XX_PInfo.portal_ce_va[BM_PORTAL]) &&
764 ((vm_offset_t)addr < XX_PInfo.portal_ce_va[BM_PORTAL] +
765 XX_PInfo.portal_ce_size[BM_PORTAL][cpu]))
766 return (XX_PInfo.portal_ce_pa[BM_PORTAL][cpu] +
767 (vm_offset_t)addr - XX_PInfo.portal_ce_va[BM_PORTAL]);
768
769 if (((vm_offset_t)addr >= XX_PInfo.portal_ci_va[BM_PORTAL]) &&
770 ((vm_offset_t)addr < XX_PInfo.portal_ci_va[BM_PORTAL] +
771 XX_PInfo.portal_ci_size[BM_PORTAL][cpu]))
772 return (XX_PInfo.portal_ci_pa[BM_PORTAL][cpu] +
773 (vm_offset_t)addr - XX_PInfo.portal_ci_va[BM_PORTAL]);
774
775 /* Handle QMAN mappings */
776 if (((vm_offset_t)addr >= XX_PInfo.portal_ce_va[QM_PORTAL]) &&
777 ((vm_offset_t)addr < XX_PInfo.portal_ce_va[QM_PORTAL] +
778 XX_PInfo.portal_ce_size[QM_PORTAL][cpu]))
779 return (XX_PInfo.portal_ce_pa[QM_PORTAL][cpu] +
780 (vm_offset_t)addr - XX_PInfo.portal_ce_va[QM_PORTAL]);
781
782 if (((vm_offset_t)addr >= XX_PInfo.portal_ci_va[QM_PORTAL]) &&
783 ((vm_offset_t)addr < XX_PInfo.portal_ci_va[QM_PORTAL] +
784 XX_PInfo.portal_ci_size[QM_PORTAL][cpu]))
785 return (XX_PInfo.portal_ci_pa[QM_PORTAL][cpu] +
786 (vm_offset_t)addr - XX_PInfo.portal_ci_va[QM_PORTAL]);
787
788 paddr = pmap_kextract((vm_offset_t)addr);
789 if (!paddr)
790 printf("NetCommSW: "
791 "Unable to translate virtual address 0x%08X!\n", addr);
792 else
793 XX_TrackAddress(addr);
794
795 return (paddr);
796 }
797
798 void *
XX_PhysToVirt(physAddress_t addr)799 XX_PhysToVirt(physAddress_t addr)
800 {
801 XX_MallocTrackStruct *ts;
802 int cpu;
803
804 cpu = PCPU_GET(cpuid);
805
806 /* Handle BMAN mappings */
807 if ((addr >= XX_PInfo.portal_ce_pa[BM_PORTAL][cpu]) &&
808 (addr < XX_PInfo.portal_ce_pa[BM_PORTAL][cpu] +
809 XX_PInfo.portal_ce_size[BM_PORTAL][cpu]))
810 return ((void *)(XX_PInfo.portal_ci_va[BM_PORTAL] +
811 (vm_offset_t)(addr - XX_PInfo.portal_ci_pa[BM_PORTAL][cpu])));
812
813 if ((addr >= XX_PInfo.portal_ci_pa[BM_PORTAL][cpu]) &&
814 (addr < XX_PInfo.portal_ci_pa[BM_PORTAL][cpu] +
815 XX_PInfo.portal_ci_size[BM_PORTAL][cpu]))
816 return ((void *)(XX_PInfo.portal_ci_va[BM_PORTAL] +
817 (vm_offset_t)(addr - XX_PInfo.portal_ci_pa[BM_PORTAL][cpu])));
818
819 /* Handle QMAN mappings */
820 if ((addr >= XX_PInfo.portal_ce_pa[QM_PORTAL][cpu]) &&
821 (addr < XX_PInfo.portal_ce_pa[QM_PORTAL][cpu] +
822 XX_PInfo.portal_ce_size[QM_PORTAL][cpu]))
823 return ((void *)(XX_PInfo.portal_ce_va[QM_PORTAL] +
824 (vm_offset_t)(addr - XX_PInfo.portal_ce_pa[QM_PORTAL][cpu])));
825
826 if ((addr >= XX_PInfo.portal_ci_pa[QM_PORTAL][cpu]) &&
827 (addr < XX_PInfo.portal_ci_pa[QM_PORTAL][cpu] +
828 XX_PInfo.portal_ci_size[QM_PORTAL][cpu]))
829 return ((void *)(XX_PInfo.portal_ci_va[QM_PORTAL] +
830 (vm_offset_t)(addr - XX_PInfo.portal_ci_pa[QM_PORTAL][cpu])));
831
832 mtx_lock(&XX_MallocTrackLock);
833 ts = XX_FindTracker(addr);
834 mtx_unlock(&XX_MallocTrackLock);
835
836 if (ts != NULL)
837 return ts->va;
838
839 printf("NetCommSW: "
840 "Unable to translate physical address 0x%08llX!\n", addr);
841
842 return (NULL);
843 }
844
845 void
XX_PortalSetInfo(device_t dev)846 XX_PortalSetInfo(device_t dev)
847 {
848 char *dev_name;
849 struct dpaa_portals_softc *sc;
850 int i, type, len;
851
852 dev_name = malloc(sizeof(*dev_name), M_TEMP, M_WAITOK |
853 M_ZERO);
854
855 len = strlen("bman-portals");
856
857 strncpy(dev_name, device_get_name(dev), len);
858
859 if (strncmp(dev_name, "bman-portals", len) && strncmp(dev_name,
860 "qman-portals", len))
861 goto end;
862
863 if (strncmp(dev_name, "bman-portals", len) == 0)
864 type = BM_PORTAL;
865 else
866 type = QM_PORTAL;
867
868 sc = device_get_softc(dev);
869
870 for (i = 0; sc->sc_dp[i].dp_ce_pa != 0; i++) {
871 XX_PInfo.portal_ce_pa[type][i] = sc->sc_dp[i].dp_ce_pa;
872 XX_PInfo.portal_ci_pa[type][i] = sc->sc_dp[i].dp_ci_pa;
873 XX_PInfo.portal_ce_size[type][i] = sc->sc_dp[i].dp_ce_size;
874 XX_PInfo.portal_ci_size[type][i] = sc->sc_dp[i].dp_ci_size;
875 XX_PInfo.portal_intr[type][i] = sc->sc_dp[i].dp_intr_num;
876 }
877
878 XX_PInfo.portal_ce_va[type] = rman_get_bushandle(sc->sc_rres[0]);
879 XX_PInfo.portal_ci_va[type] = rman_get_bushandle(sc->sc_rres[1]);
880 end:
881 free(dev_name, M_TEMP);
882 }
883
884 static XX_MallocTrackStruct *
XX_FindTracker(physAddress_t pa)885 XX_FindTracker(physAddress_t pa)
886 {
887 struct XX_MallocTrackerList *l;
888 XX_MallocTrackStruct *tp;
889
890 l = &XX_MallocTracker[(pa >> XX_MALLOC_TRACK_SHIFT) & XX_MallocHashMask];
891
892 LIST_FOREACH(tp, l, entries) {
893 if (tp->pa == pa)
894 return tp;
895 }
896
897 return NULL;
898 }
899
900 void
XX_TrackInit(void)901 XX_TrackInit(void)
902 {
903 if (XX_MallocTracker == NULL) {
904 XX_MallocTracker = hashinit(64, M_NETCOMMSW_MT,
905 &XX_MallocHashMask);
906 }
907 }
908
909 void
XX_TrackAddress(void * addr)910 XX_TrackAddress(void *addr)
911 {
912 physAddress_t pa;
913 struct XX_MallocTrackerList *l;
914 XX_MallocTrackStruct *ts;
915
916 pa = pmap_kextract((vm_offset_t)addr);
917
918 ts = malloc(sizeof(*ts), M_NETCOMMSW_MT, M_NOWAIT);
919 ts->va = addr;
920 ts->pa = pa;
921
922 l = &XX_MallocTracker[(pa >> XX_MALLOC_TRACK_SHIFT) & XX_MallocHashMask];
923
924 mtx_lock(&XX_MallocTrackLock);
925 if (XX_FindTracker(pa) != NULL)
926 free(ts, M_NETCOMMSW_MT);
927 else
928 LIST_INSERT_HEAD(l, ts, entries);
929 mtx_unlock(&XX_MallocTrackLock);
930 }
931
932 void
XX_UntrackAddress(void * addr)933 XX_UntrackAddress(void *addr)
934 {
935 physAddress_t pa;
936 XX_MallocTrackStruct *ts;
937
938 pa = pmap_kextract((vm_offset_t)addr);
939
940 KASSERT(XX_MallocTracker != NULL,
941 ("Untracking an address before it's even initialized!\n"));
942
943 mtx_lock(&XX_MallocTrackLock);
944 ts = XX_FindTracker(pa);
945 if (ts != NULL)
946 LIST_REMOVE(ts, entries);
947 mtx_unlock(&XX_MallocTrackLock);
948 free(ts, M_NETCOMMSW_MT);
949 }
950