]> CyberLeo.Net >> Repos - FreeBSD/releng/8.2.git/blob - sys/mips/cavium/dev/rgmii/octeon_fpa.c
Copy stable/8 to releng/8.2 in preparation for FreeBSD-8.2 release.
[FreeBSD/releng/8.2.git] / sys / mips / cavium / dev / rgmii / octeon_fpa.c
1 /***********************license start***************
2  *  Copyright (c) 2003-2008 Cavium Networks (support@cavium.com). All rights
3  *  reserved.
4  *
5  *
6  *  Redistribution and use in source and binary forms, with or without
7  *  modification, are permitted provided that the following conditions are
8  *  met:
9  *
10  *      * Redistributions of source code must retain the above copyright
11  *        notice, this list of conditions and the following disclaimer.
12  *
13  *      * Redistributions in binary form must reproduce the above
14  *        copyright notice, this list of conditions and the following
15  *        disclaimer in the documentation and/or other materials provided
16  *        with the distribution.
17  *
18  *      * Neither the name of Cavium Networks nor the names of
19  *        its contributors may be used to endorse or promote products
20  *        derived from this software without specific prior written
21  *        permission.
22  *
23  *  TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
24  *  AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS
25  *  OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH
26  *  RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY
27  *  REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT
28  *  DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES
29  *  OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR
30  *  PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET
31  *  POSSESSION OR CORRESPONDENCE TO DESCRIPTION.  THE ENTIRE RISK ARISING OUT
32  *  OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
33  *
34  *
35  *  For any questions regarding licensing please contact marketing@caviumnetworks.com
36  *
37  ***********************license end**************************************/
38
39 /*------------------------------------------------------------------
40  * octeon_fpa.c        Free Pool Allocator
41  *
42  *------------------------------------------------------------------
43  */
44
45 #include <sys/cdefs.h>
46 __FBSDID("$FreeBSD$");
47
48 #include <sys/param.h>
49 #include <sys/systm.h>
50 #include <sys/malloc.h>
51 #include <vm/vm.h>
52 #include <vm/pmap.h>
53
54
55 #include <mips/cavium/octeon_pcmap_regs.h>
56 #include "octeon_fpa.h"
57
58
59 #define FPA_DEBUG 1
60
61 /*
62  * octeon_dump_fpa
63  *
64  */
65 void octeon_dump_fpa (void)
66 {
67     int i;
68     octeon_fpa_ctl_status_t status;
69     octeon_fpa_queue_available_t q_avail;
70
71     status.word64 = oct_read64(OCTEON_FPA_CTL_STATUS);
72     if (!status.bits.enb) {
73         printf("\n  FPA Disabled");
74         /*
75          * No dumping if disabled
76          */
77         return;
78     }
79     printf(" FPA  Ctrl-Status-reg 0x%llX := 0x%llX  EN %X  M1_E %X  M0_E %X\n",
80            OCTEON_FPA_CTL_STATUS, (unsigned long long)status.word64,
81            status.bits.enb, status.bits.mem1_err, status.bits.mem0_err);
82     for (i = 0; i < OCTEON_FPA_QUEUES; i++) {
83         printf("   Pool: %d\n", i);
84
85         q_avail.word64 = oct_read64((OCTEON_FPA_QUEUE_AVAILABLE + (i)*8ull));
86         printf("   Avail-reg 0x%llX :=   Size: 0x%X\n",
87                (OCTEON_FPA_QUEUE_AVAILABLE + (i)*8ull), q_avail.bits.queue_size);
88     }
89 }
90
91 void octeon_dump_fpa_pool (u_int pool)
92 {
93     octeon_fpa_ctl_status_t status;
94     octeon_fpa_queue_available_t q_avail;
95
96     status.word64 = oct_read64(OCTEON_FPA_CTL_STATUS);
97     if (!status.bits.enb) {
98         printf("\n  FPA Disabled");
99         /*
100          * No dumping if disabled
101          */
102         return;
103     }
104     printf(" FPA  Ctrl-Status-reg 0x%llX := 0x%llX  EN %X  M1_E %X  M0_E %X\n",
105            OCTEON_FPA_CTL_STATUS, (unsigned long long)status.word64,
106            status.bits.enb, status.bits.mem1_err, status.bits.mem0_err);
107     q_avail.word64 = oct_read64((OCTEON_FPA_QUEUE_AVAILABLE + (pool)*8ull));
108     printf("   FPA Pool: %u   Avail-reg 0x%llX :=   Size: 0x%X\n", pool,
109            (OCTEON_FPA_QUEUE_AVAILABLE + (pool)*8ull), q_avail.bits.queue_size);
110 }
111
112
113 u_int octeon_fpa_pool_size (u_int pool)
114 {
115     octeon_fpa_queue_available_t q_avail;
116     u_int size = 0;
117
118     if (pool < 7) {
119             q_avail.word64 = oct_read64((OCTEON_FPA_QUEUE_AVAILABLE + (pool)*8ull));
120             size = q_avail.bits.queue_size;
121     }
122     return (size);
123 }
124
125
126 /*
127  * octeon_enable_fpa
128  *
129  * configure fpa with defaults and then mark it enabled.
130  */
131 void octeon_enable_fpa (void)
132 {
133     int i;
134     octeon_fpa_ctl_status_t status;
135     octeon_fpa_fpf_marks_t marks;
136
137     for (i = 0; i < OCTEON_FPA_QUEUES; i++) {
138         marks.word64 = oct_read64((OCTEON_FPA_FPF_MARKS + (i)*8ull));
139
140         marks.bits.fpf_wr = 0xe0;
141         oct_write64((OCTEON_FPA_FPF_MARKS + (i)*8ull), marks.word64);
142     }
143
144     /* Enforce a 10 cycle delay between config and enable */
145     octeon_wait(10);
146
147     status.word64 = 0;
148     status.bits.enb = 1;
149     oct_write64(OCTEON_FPA_CTL_STATUS, status.word64);
150 }
151
152
153 #define FPA_DEBUG_TERSE 1
154
155 /*
156  * octeon_fpa_fill_pool_mem
157  *
158  * Fill the specified FPA pool with elem_num number of
159  * elements of size elem_size_words * 8
160  */
161 void octeon_fpa_fill_pool_mem (u_int pool, u_int elem_size_words, u_int elem_num)
162 {
163     void *memory;
164     u_int bytes, elem_size_bytes;
165     u_int block_size;
166
167 #ifdef FPA_DEBUG
168     u_int elems = elem_num;
169     printf(" FPA fill: Pool %u  elem_size_words %u   Num: %u\n", pool, elem_size_words, elem_num);
170 #endif
171     elem_size_bytes = elem_size_words * sizeof(uint64_t);
172     block_size = OCTEON_ALIGN(elem_size_bytes);
173
174 //    block_size = ((elem_size_bytes / OCTEON_FPA_POOL_ALIGNMENT) + 1) * OCTEON_FPA_POOL_ALIGNMENT;
175
176     bytes = (elem_num * block_size);
177
178 #ifdef FPA_DEBUG
179     printf(" elem_size_bytes = words * 8 = %u;  block_size %u\n", elem_size_bytes, block_size);
180 #endif
181
182
183 #ifdef FPA_DEBUG
184     int block = 0;
185
186     printf(" %% Filling Pool %u  with %u blocks of %u bytes  %u words\n",
187            pool, elem_num, elem_size_bytes, elem_size_words);
188 #endif
189
190 //    memory = malloc(bytes, M_DEVBUF, M_NOWAIT | M_ZERO);
191     memory = contigmalloc(bytes, M_DEVBUF, M_NOWAIT | M_ZERO,
192                           0, 0x20000000,
193                           OCTEON_FPA_POOL_ALIGNMENT, 0);
194
195     if (memory == NULL) {
196         printf(" %% FPA pool %u could not be filled with %u bytes\n",
197                pool, bytes);
198         return;
199     }
200
201     /*
202      * Forward Align allocated mem to needed alignment. Don't worry about growth, we
203      * already preallocated extra
204      */
205 #ifdef FPA_DEBUG
206     printf(" %% Huge MemBlock  %p   Bytes %u\n", memory, bytes);
207 #endif
208
209     memory = (void *) OCTEON_ALIGN(memory);
210
211 #ifdef FPA_DEBUG_TERSE
212     printf("FPA fill: %u  Count: %u  SizeBytes: %u  SizeBytesAligned: %u  1st: %p = %p\n",
213            pool, elem_num, elem_size_bytes, block_size, memory,
214            (void *)(intptr_t)OCTEON_PTR2PHYS(memory));
215 #endif
216
217 //    memory = (void *) ((((u_int) memory / OCTEON_FPA_POOL_ALIGNMENT) + 1) * OCTEON_FPA_POOL_ALIGNMENT);
218
219     while (elem_num--) {
220 #ifdef FPA_DEBUG
221         if (((elems - elem_num) < 4) || (elem_num < 4))
222         printf(" %% Block %d:  %p  Phys %p   Bytes %u\n", block, memory,
223           (void *)(intptr_t)OCTEON_PTR2PHYS(memory), elem_size_bytes);
224         block++;
225 #endif
226         octeon_fpa_free(memory, pool, 0);
227         memory = (void *) (((u_long) memory) + block_size);
228     }
229 }
230