1 /***********************license start***************
2  * Copyright (c) 2003-2010  Cavium Inc. ([email protected]). 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 Inc. 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  * This Software, including technical data, may be subject to U.S. export  control
24  * laws, including the U.S. Export Administration Act and its  associated
25  * regulations, and may be subject to export or import  regulations in other
26  * countries.
27 
28  * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
29  * AND WITH ALL FAULTS AND CAVIUM INC. MAKES NO PROMISES, REPRESENTATIONS OR
30  * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
31  * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR
32  * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM
33  * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE,
34  * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF
35  * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
36  * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE  RISK ARISING OUT OF USE OR
37  * PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
38  ***********************license end**************************************/
39 
40 
41 
42 
43 
44 
45 
46 /**
47  * @file
48  *
49  * Helper Functions for the Configuration Framework
50  *
51  * <hr>$Revision: 0 $<hr>
52  */
53 #ifdef CVMX_BUILD_FOR_LINUX_KERNEL
54 #include <linux/module.h>
55 #include <asm/octeon/cvmx.h>
56 #include <asm/octeon/cvmx-helper.h>
57 #include <asm/octeon/cvmx-helper-util.h>
58 #include <asm/octeon/cvmx-helper-cfg.h>
59 #include <asm/octeon/cvmx-helper-ilk.h>
60 #include <asm/octeon/cvmx-ilk.h>
61 #include <asm/octeon/cvmx-config.h>
62 #else
63 #include "cvmx.h"
64 #include "cvmx-bootmem.h"
65 #include "cvmx-helper.h"
66 #include "cvmx-helper-util.h"
67 #include "cvmx-helper-cfg.h"
68 #include "cvmx-ilk.h"
69 #include "cvmx-helper-ilk.h"
70 #if !defined(__FreeBSD__) || !defined(_KERNEL)
71 #include "cvmx-config.h"
72 #include "executive-config.h"
73 #endif
74 #endif
75 
76 #if defined(min)
77 #else
78 #define min( a, b ) ( ( a ) < ( b ) ) ? ( a ) : ( b )
79 #endif
80 
81 /* #define CVMX_HELPER_CFG_DEBUG */
82 
83 /*
84  * Per physical port
85  */
86 struct cvmx_cfg_port_param {
87 	int8_t	ccpp_pknd;
88 	int8_t	ccpp_bpid;
89 	int8_t	ccpp_pko_port_base;
90 	int8_t	ccpp_pko_num_ports;
91 	uint8_t	ccpp_pko_nqueues;	/*
92 					 * When the user explicitly
93 					 * assigns queues,
94 					 * cvmx_cfg_pko_nqueue_pool[
95 					 *     ccpp_pko_nqueues ...
96 					 *     ccpp_pko_nqueues +
97 					 *     ccpp_pko_num_ports - 1]
98 					 * are the numbers of PKO queues
99 					 * assigned to the PKO ports for
100 					 * this physical port.
101 					 */
102 };
103 
104 /*
105  * Per pko_port
106  */
107 struct cvmx_cfg_pko_port_param {
108 	int16_t	ccppp_queue_base;
109 	int16_t	ccppp_num_queues;
110 };
111 
112 /*
113  * A map from pko_port to
114  *     interface,
115  *     index, and
116  *     pko engine id
117  */
118 struct cvmx_cfg_pko_port_map {
119 	int16_t ccppl_interface;
120 	int16_t ccppl_index;
121 	int16_t ccppl_eid;
122 };
123 
124 /*
125  * This is for looking up pko_base_port and pko_nport for ipd_port
126  */
127 struct cvmx_cfg_pko_port_pair {
128 	int8_t ccppp_base_port;
129 	int8_t ccppp_nports;
130 };
131 
132 static CVMX_SHARED struct cvmx_cfg_port_param cvmx_cfg_port
133     [CVMX_HELPER_CFG_MAX_IFACE][CVMX_HELPER_CFG_MAX_PORT_PER_IFACE] =
134     {[0 ... CVMX_HELPER_CFG_MAX_IFACE - 1] =
135         {[0 ... CVMX_HELPER_CFG_MAX_PORT_PER_IFACE - 1] =
136             {CVMX_HELPER_CFG_INVALID_VALUE,
137     	     CVMX_HELPER_CFG_INVALID_VALUE,
138     	     CVMX_HELPER_CFG_INVALID_VALUE,
139     	     CVMX_HELPER_CFG_INVALID_VALUE,
140     	     CVMX_HELPER_CFG_INVALID_VALUE}}};
141 
142 /*
143  * Indexed by the pko_port number
144  */
145 static CVMX_SHARED struct cvmx_cfg_pko_port_param cvmx_cfg_pko_port
146     [CVMX_HELPER_CFG_MAX_PKO_PORT] =
147     {[0 ... CVMX_HELPER_CFG_MAX_PKO_PORT - 1] =
148         {CVMX_HELPER_CFG_INVALID_VALUE,
149 	 CVMX_HELPER_CFG_INVALID_VALUE}};
150 
151 static CVMX_SHARED struct cvmx_cfg_pko_port_map cvmx_cfg_pko_port_map
152     [CVMX_HELPER_CFG_MAX_PKO_PORT] =
153         {[0 ... CVMX_HELPER_CFG_MAX_PKO_PORT - 1] =
154             {CVMX_HELPER_CFG_INVALID_VALUE,
155 	     CVMX_HELPER_CFG_INVALID_VALUE,
156              CVMX_HELPER_CFG_INVALID_VALUE}};
157 
158 #ifdef CVMX_ENABLE_PKO_FUNCTIONS
159 /*
160  * This array assists translation from ipd_port to pko_port.
161  * The ``16'' is the rounded value for the 3rd 4-bit value of
162  * ipd_port, used to differentiate ``interfaces.''
163  */
164 static CVMX_SHARED struct cvmx_cfg_pko_port_pair ipd2pko_port_cache[16]
165     [CVMX_HELPER_CFG_MAX_PORT_PER_IFACE] =
166     {[0 ... 15] =
167         {[0 ... CVMX_HELPER_CFG_MAX_PORT_PER_IFACE - 1] =
168 	    {CVMX_HELPER_CFG_INVALID_VALUE,
169 	     CVMX_HELPER_CFG_INVALID_VALUE}}};
170 
171 #ifdef CVMX_USER_DEFINED_HELPER_CONFIG_INIT
172 
173 static CVMX_SHARED int cvmx_cfg_default_pko_nqueues = 1;
174 
175 /*
176  * A pool for holding the pko_nqueues for the pko_ports assigned to a
177  * physical port.
178  */
179 static CVMX_SHARED uint8_t cvmx_cfg_pko_nqueue_pool
180     [CVMX_HELPER_CFG_MAX_PKO_QUEUES] =
181     {[0 ... CVMX_HELPER_CFG_MAX_PKO_QUEUES - 1] = 1};
182 
183 #endif
184 #endif
185 
186 /*
187  * Options
188  *
189  * Each array-elem's intial value is also the option's default value.
190  */
191 static CVMX_SHARED uint64_t cvmx_cfg_opts[CVMX_HELPER_CFG_OPT_MAX] =
192     {[0 ... CVMX_HELPER_CFG_OPT_MAX - 1] = 1};
193 
194 /*
195  * MISC
196  */
197 static CVMX_SHARED int cvmx_cfg_max_pko_engines; /* # of PKO DMA engines
198 						    allocated */
__cvmx_helper_cfg_pknd(int interface,int index)199 int __cvmx_helper_cfg_pknd(int interface, int index)
200 {
201     return cvmx_cfg_port[interface][index].ccpp_pknd;
202 }
203 
__cvmx_helper_cfg_bpid(int interface,int index)204 int __cvmx_helper_cfg_bpid(int interface, int index)
205 {
206     return cvmx_cfg_port[interface][index].ccpp_bpid;
207 }
208 
__cvmx_helper_cfg_pko_port_base(int interface,int index)209 int __cvmx_helper_cfg_pko_port_base(int interface, int index)
210 {
211     return cvmx_cfg_port[interface][index].ccpp_pko_port_base;
212 }
213 
__cvmx_helper_cfg_pko_port_num(int interface,int index)214 int __cvmx_helper_cfg_pko_port_num(int interface, int index)
215 {
216     return cvmx_cfg_port[interface][index].ccpp_pko_num_ports;
217 }
218 
__cvmx_helper_cfg_pko_queue_num(int pko_port)219 int __cvmx_helper_cfg_pko_queue_num(int pko_port)
220 {
221     return cvmx_cfg_pko_port[pko_port].ccppp_num_queues;
222 }
223 
__cvmx_helper_cfg_pko_queue_base(int pko_port)224 int __cvmx_helper_cfg_pko_queue_base(int pko_port)
225 {
226     return cvmx_cfg_pko_port[pko_port].ccppp_queue_base;
227 }
228 
__cvmx_helper_cfg_pko_max_queue(void)229 int __cvmx_helper_cfg_pko_max_queue(void)
230 {
231     int i;
232 
233     i = CVMX_HELPER_CFG_MAX_PKO_PORT - 1;
234 
235     while (i >= 0)
236     {
237         if (cvmx_cfg_pko_port[i].ccppp_queue_base !=
238 	    CVMX_HELPER_CFG_INVALID_VALUE)
239 	{
240 	    cvmx_helper_cfg_assert(cvmx_cfg_pko_port[i].ccppp_num_queues > 0);
241 	    return (cvmx_cfg_pko_port[i].ccppp_queue_base +
242 	        cvmx_cfg_pko_port[i].ccppp_num_queues);
243 	}
244 	i --;
245     }
246 
247     cvmx_helper_cfg_assert(0); /* shouldn't get here */
248 
249     return 0;
250 }
251 
__cvmx_helper_cfg_pko_max_engine(void)252 int __cvmx_helper_cfg_pko_max_engine(void)
253 {
254     return cvmx_cfg_max_pko_engines;
255 }
256 
cvmx_helper_cfg_opt_set(cvmx_helper_cfg_option_t opt,uint64_t val)257 int cvmx_helper_cfg_opt_set(cvmx_helper_cfg_option_t opt, uint64_t val)
258 {
259     if (opt >= CVMX_HELPER_CFG_OPT_MAX)
260         return -1;
261 
262     cvmx_cfg_opts[opt] = val;
263 
264     return 0;
265 }
266 
cvmx_helper_cfg_opt_get(cvmx_helper_cfg_option_t opt)267 uint64_t cvmx_helper_cfg_opt_get(cvmx_helper_cfg_option_t opt)
268 {
269     if (opt >= CVMX_HELPER_CFG_OPT_MAX)
270         return (uint64_t)CVMX_HELPER_CFG_INVALID_VALUE;
271 
272     return cvmx_cfg_opts[opt];
273 }
274 
275 #ifdef CVMX_BUILD_FOR_LINUX_KERNEL
276 EXPORT_SYMBOL(__cvmx_helper_cfg_init);
277 EXPORT_SYMBOL(__cvmx_helper_cfg_pknd);
278 EXPORT_SYMBOL(__cvmx_helper_cfg_bpid);
279 EXPORT_SYMBOL(__cvmx_helper_cfg_pko_port_base);
280 EXPORT_SYMBOL(__cvmx_helper_cfg_pko_port_num);
281 EXPORT_SYMBOL(__cvmx_helper_cfg_pko_queue_base);
282 EXPORT_SYMBOL(__cvmx_helper_cfg_pko_queue_num);
283 EXPORT_SYMBOL(__cvmx_helper_cfg_pko_max_queue);
284 EXPORT_SYMBOL(__cvmx_helper_cfg_pko_port_interface);
285 EXPORT_SYMBOL(__cvmx_helper_cfg_pko_port_index);
286 EXPORT_SYMBOL(__cvmx_helper_cfg_pko_port_eid);
287 EXPORT_SYMBOL(__cvmx_helper_cfg_pko_max_engine);
288 EXPORT_SYMBOL(cvmx_helper_cfg_opt_get);
289 EXPORT_SYMBOL(cvmx_helper_cfg_opt_set);
290 EXPORT_SYMBOL(cvmx_helper_cfg_ipd2pko_port_base);
291 EXPORT_SYMBOL(cvmx_helper_cfg_ipd2pko_port_num);
292 #endif
293 
294 #ifdef CVMX_ENABLE_HELPER_FUNCTIONS
295 
296 #ifdef CVMX_HELPER_CFG_DEBUG
cvmx_helper_cfg_show_cfg(void)297 void cvmx_helper_cfg_show_cfg(void)
298 {
299     int i, j;
300 
301     for (i = 0; i < cvmx_helper_get_number_of_interfaces(); i++)
302     {
303 	cvmx_dprintf(
304 	    "cvmx_helper_cfg_show_cfg: interface%d mode %10s nports%4d\n", i,
305 	    cvmx_helper_interface_mode_to_string(cvmx_helper_interface_get_mode(i)),
306 	    cvmx_helper_interface_enumerate(i));
307 
308 	for (j = 0; j < cvmx_helper_interface_enumerate(i); j++)
309 	{
310 	    cvmx_dprintf("\tpknd[%i][%d]%d", i, j,
311 	        __cvmx_helper_cfg_pknd(i, j));
312 	    cvmx_dprintf(" pko_port_base[%i][%d]%d", i, j,
313 	        __cvmx_helper_cfg_pko_port_base(i, j));
314 	    cvmx_dprintf(" pko_port_num[%i][%d]%d\n", i, j,
315 	        __cvmx_helper_cfg_pko_port_num(i, j));
316 	}
317     }
318 
319     for (i = 0; i < CVMX_HELPER_CFG_MAX_PKO_PORT; i++)
320     {
321 	if (__cvmx_helper_cfg_pko_queue_base(i) !=
322 	    CVMX_HELPER_CFG_INVALID_VALUE)
323 	{
324             cvmx_dprintf("cvmx_helper_cfg_show_cfg: pko_port%d qbase%d nqueues%d "
325 	        "interface%d index%d\n", i,
326 		__cvmx_helper_cfg_pko_queue_base(i),
327 		__cvmx_helper_cfg_pko_queue_num(i),
328 		__cvmx_helper_cfg_pko_port_interface(i),
329 		__cvmx_helper_cfg_pko_port_index(i));
330         }
331     }
332 }
333 #endif
334 
335 /*
336  * initialize cvmx_cfg_pko_port_map
337  */
cvmx_helper_cfg_init_pko_port_map(void)338 static void cvmx_helper_cfg_init_pko_port_map(void)
339 {
340     int i, j, k;
341     int pko_eid;
342     int pko_port_base, pko_port_max;
343     cvmx_helper_interface_mode_t mode;
344 
345     /*
346      * one pko_eid is allocated to each port except for ILK, NPI, and
347      * LOOP. Each of the three has one eid.
348      */
349     pko_eid = 0;
350     for (i = 0; i < cvmx_helper_get_number_of_interfaces(); i++)
351     {
352 	mode = cvmx_helper_interface_get_mode(i);
353         for (j = 0; j < cvmx_helper_interface_enumerate(i); j++)
354 	{
355 	    pko_port_base = cvmx_cfg_port[i][j].ccpp_pko_port_base;
356 	    pko_port_max = pko_port_base +
357 	        cvmx_cfg_port[i][j].ccpp_pko_num_ports;
358 	    cvmx_helper_cfg_assert(pko_port_base !=
359 	        CVMX_HELPER_CFG_INVALID_VALUE);
360 	    cvmx_helper_cfg_assert(pko_port_max >= pko_port_base);
361 	    for (k = pko_port_base; k < pko_port_max; k++)
362 	    {
363 	        cvmx_cfg_pko_port_map[k].ccppl_interface = i;
364 	        cvmx_cfg_pko_port_map[k].ccppl_index = j;
365 	        cvmx_cfg_pko_port_map[k].ccppl_eid = pko_eid;
366 	    }
367 
368 #if 0
369 	    /*
370 	     * For a physical port that is not configured a PKO port,
371 	     * pko_port_base here equals to pko_port_max. In this
372 	     * case, the physical port does not take a DMA engine.
373 	     */
374 	    if (pko_port_base > pko_port_max)
375 #endif
376 	        if (!(mode == CVMX_HELPER_INTERFACE_MODE_NPI ||
377 	            mode == CVMX_HELPER_INTERFACE_MODE_LOOP ||
378 	            mode == CVMX_HELPER_INTERFACE_MODE_ILK))
379 	            pko_eid ++;
380 	}
381 
382 	if (mode == CVMX_HELPER_INTERFACE_MODE_NPI ||
383 	    mode == CVMX_HELPER_INTERFACE_MODE_LOOP ||
384 	    mode == CVMX_HELPER_INTERFACE_MODE_ILK)
385 	        pko_eid ++;
386     }
387 
388     /*
389      * Legal pko_eids [0, 0x13] should not be exhausted.
390      */
391     cvmx_helper_cfg_assert(pko_eid <= 0x14);
392 
393     cvmx_cfg_max_pko_engines = pko_eid;
394 }
395 #endif
396 
__cvmx_helper_cfg_pko_port_interface(int pko_port)397 int __cvmx_helper_cfg_pko_port_interface(int pko_port)
398 {
399     return cvmx_cfg_pko_port_map[pko_port].ccppl_interface;
400 }
401 
__cvmx_helper_cfg_pko_port_index(int pko_port)402 int __cvmx_helper_cfg_pko_port_index(int pko_port)
403 {
404     return cvmx_cfg_pko_port_map[pko_port].ccppl_index;
405 }
406 
__cvmx_helper_cfg_pko_port_eid(int pko_port)407 int __cvmx_helper_cfg_pko_port_eid(int pko_port)
408 {
409     return cvmx_cfg_pko_port_map[pko_port].ccppl_eid;
410 }
411 
412 /**
413  * Perform common init tasks for all chips.
414  * @return 1 for the caller to continue init and 0 otherwise.
415  *
416  * Note: ``common'' means this function is executed regardless of
417  * 	- chip, and
418  * 	- CVMX_ENABLE_HELPER_FUNCTIONS.
419  *
420  * This function decides based on these conditions if the
421  * configuration stage of the init process should continue.
422  *
423  * This is only meant to be called by __cvmx_helper_cfg_init().
424  */
__cvmx_helper_cfg_init_common(void)425 static int __cvmx_helper_cfg_init_common(void)
426 {
427     int val;
428 
429 #ifndef CVMX_ENABLE_HELPER_FUNCTIONS
430     val = 0;
431 #else
432     val = (octeon_has_feature(OCTEON_FEATURE_PKND));
433 #endif
434 
435     return val;
436 }
437 
438 #define IPD2PKO_CACHE_Y(ipd_port)	(ipd_port) >> 8
439 #define IPD2PKO_CACHE_X(ipd_port)	(ipd_port) & 0xff
440 
441 #ifdef CVMX_ENABLE_PKO_FUNCTIONS
442 /*
443  * ipd_port to pko_port translation cache
444  */
__cvmx_helper_cfg_init_ipd2pko_cache(void)445 static int __cvmx_helper_cfg_init_ipd2pko_cache(void)
446 {
447     int i, j, n;
448     int ipd_y, ipd_x, ipd_port;
449 
450     for (i = 0; i < cvmx_helper_get_number_of_interfaces(); i++)
451     {
452 	n = cvmx_helper_interface_enumerate(i);
453 
454         for (j = 0; j < n; j++)
455 	{
456 	    ipd_port = cvmx_helper_get_ipd_port(i, j);
457 	    ipd_y = IPD2PKO_CACHE_Y(ipd_port);
458 	    ipd_x = IPD2PKO_CACHE_X(ipd_port);
459 	    ipd2pko_port_cache[ipd_y]
460 	        [(ipd_port & 0x800) ? ((ipd_x >> 4) & 3) : ipd_x] =
461 		(struct cvmx_cfg_pko_port_pair)
462 		{__cvmx_helper_cfg_pko_port_base(i, j),
463 		 __cvmx_helper_cfg_pko_port_num(i, j)};
464 	}
465     }
466 
467     return 0;
468 }
469 
cvmx_helper_cfg_ipd2pko_port_base(int ipd_port)470 int cvmx_helper_cfg_ipd2pko_port_base(int ipd_port)
471 {
472 	int ipd_y, ipd_x;
473 
474         ipd_y = IPD2PKO_CACHE_Y(ipd_port);
475 	ipd_x = IPD2PKO_CACHE_X(ipd_port);
476 
477         return ipd2pko_port_cache[ipd_y]
478 	    [(ipd_port & 0x800) ? ((ipd_x >> 4) & 3) : ipd_x].ccppp_base_port;
479 }
480 
cvmx_helper_cfg_ipd2pko_port_num(int ipd_port)481 int cvmx_helper_cfg_ipd2pko_port_num(int ipd_port)
482 {
483 	int ipd_y, ipd_x;
484 
485         ipd_y = IPD2PKO_CACHE_Y(ipd_port);
486 	ipd_x = IPD2PKO_CACHE_X(ipd_port);
487 
488         return ipd2pko_port_cache[ipd_y]
489 	    [(ipd_port & 0x800) ? ((ipd_x >> 4) & 3) : ipd_x].ccppp_nports;
490 }
491 #endif
492 
493 #ifdef CVMX_ENABLE_HELPER_FUNCTIONS
494 #ifdef CVMX_USER_DEFINED_HELPER_CONFIG_INIT
495 /**
496  * Return the number of queues assigned to this pko_port by user
497  *
498  * @param pko_port
499  * @return the number of queues for this pko_port
500  *
501  * Note: Called after the pko_port map is set up.
502  */
__cvmx_ucfg_nqueues(int pko_port)503 static int __cvmx_ucfg_nqueues(int pko_port)
504 {
505     int interface, index;
506     int i, k;
507 
508     interface = __cvmx_helper_cfg_pko_port_interface(pko_port);
509     index = __cvmx_helper_cfg_pko_port_index(pko_port);
510 
511     /*
512      * pko_port belongs to no physical port,
513      * don't assign a queue to it.
514      */
515     if (interface == CVMX_HELPER_CFG_INVALID_VALUE ||
516         index == CVMX_HELPER_CFG_INVALID_VALUE)
517 	return 0;
518 
519     /*
520      * Assign the default number of queues to those pko_ports not
521      * assigned explicitly.
522      */
523     i = cvmx_cfg_port[interface][index].ccpp_pko_nqueues;
524     if (i == (uint8_t)CVMX_HELPER_CFG_INVALID_VALUE)
525         return cvmx_cfg_default_pko_nqueues;
526 
527     /*
528      * The user has assigned nqueues to this pko_port,
529      * recorded in the pool.
530      */
531     k = pko_port - cvmx_cfg_port[interface][index].ccpp_pko_port_base;
532     cvmx_helper_cfg_assert(k <
533         cvmx_cfg_port[interface][index].ccpp_pko_num_ports);
534     return cvmx_cfg_pko_nqueue_pool[i + k];
535 }
536 
537 #else
538 
539 /**
540  * Return the number of queues to be assigned to this pko_port
541  *
542  * @param pko_port
543  * @return the number of queues for this pko_port
544  *
545  * Note: This function exists for backward compatibility.
546  * CVMX_PKO_QUEUES_PER_PORT_XXXX defines no of queues per HW port.
547  * pko_port is equivalent in pre-o68 SDK.
548  */
cvmx_helper_cfg_dft_nqueues(int pko_port)549 static int cvmx_helper_cfg_dft_nqueues(int pko_port)
550 {
551     cvmx_helper_interface_mode_t mode;
552     int interface;
553     int n;
554 
555 #ifndef CVMX_HELPER_PKO_QUEUES_PER_PORT_INTERFACE0
556 #define CVMX_HELPER_PKO_QUEUES_PER_PORT_INTERFACE0 1
557 #endif
558 
559 #ifndef CVMX_HELPER_PKO_QUEUES_PER_PORT_INTERFACE1
560 #define CVMX_HELPER_PKO_QUEUES_PER_PORT_INTERFACE1 1
561 #endif
562 
563 #ifndef CVMX_HELPER_PKO_QUEUES_PER_PORT_INTERFACE2
564 #define CVMX_HELPER_PKO_QUEUES_PER_PORT_INTERFACE2 1
565 #endif
566 
567 #ifndef CVMX_HELPER_PKO_QUEUES_PER_PORT_INTERFACE3
568 #define CVMX_HELPER_PKO_QUEUES_PER_PORT_INTERFACE3 1
569 #endif
570 
571 #ifndef CVMX_HELPER_PKO_QUEUES_PER_PORT_INTERFACE4
572 #define CVMX_HELPER_PKO_QUEUES_PER_PORT_INTERFACE4 1
573 #endif
574 
575     n = 1;
576     interface = __cvmx_helper_cfg_pko_port_interface(pko_port);
577     if (interface == 0)
578     {
579 #ifdef CVMX_PKO_QUEUES_PER_PORT_INTERFACE0
580 	n = CVMX_PKO_QUEUES_PER_PORT_INTERFACE0;
581 #endif
582     }
583     if (interface == 1)
584     {
585 #ifdef CVMX_PKO_QUEUES_PER_PORT_INTERFACE1
586 	n = CVMX_PKO_QUEUES_PER_PORT_INTERFACE1;
587 #endif
588     }
589 
590     if (interface == 2)
591     {
592 #ifdef CVMX_PKO_QUEUES_PER_PORT_INTERFACE2
593 	n = CVMX_PKO_QUEUES_PER_PORT_INTERFACE2;
594 #endif
595     }
596     if (interface == 3)
597     {
598 #ifdef CVMX_PKO_QUEUES_PER_PORT_INTERFACE3
599 	n = CVMX_PKO_QUEUES_PER_PORT_INTERFACE3;
600 #endif
601     }
602     if (interface == 4)
603     {
604 #ifdef CVMX_PKO_QUEUES_PER_PORT_INTERFACE4
605 	n = CVMX_PKO_QUEUES_PER_PORT_INTERFACE4;
606 #endif
607     }
608 
609     mode = cvmx_helper_interface_get_mode(interface);
610     if (mode == CVMX_HELPER_INTERFACE_MODE_LOOP)
611     {
612 #ifdef CVMX_PKO_QUEUES_PER_PORT_LOOP
613 	n = CVMX_PKO_QUEUES_PER_PORT_LOOP;
614 #endif
615     }
616     if (mode == CVMX_HELPER_INTERFACE_MODE_NPI)
617     {
618 #ifdef CVMX_PKO_QUEUES_PER_PORT_PCI
619 	n = CVMX_PKO_QUEUES_PER_PORT_PCI;
620 #endif
621     }
622 
623     return n;
624 }
625 #endif /* CVMX_USER_DEFINED_HELPER_CONFIG_INIT */
626 #endif /* CVMX_ENABLE_HELPER_FUNCTIONS */
627 
__cvmx_helper_cfg_init(void)628 int __cvmx_helper_cfg_init(void)
629 {
630 #ifdef CVMX_ENABLE_HELPER_FUNCTIONS
631     struct cvmx_cfg_port_param *pport;
632     int cvmx_cfg_default_pko_nports;
633     int pknd, bpid, pko_port_base;
634     int qbase;
635     int i, j, n;
636 
637     cvmx_cfg_default_pko_nports = 1;
638 #endif
639 
640     if (!__cvmx_helper_cfg_init_common())
641         return 0;
642 
643 #ifdef CVMX_ENABLE_HELPER_FUNCTIONS
644 
645 #ifdef CVMX_USER_DEFINED_HELPER_CONFIG_INIT
646 {
647 	int cvmx_ucfg_nq;
648 	cvmx_ucfg_nq = 0;
649 #include "cvmx-helper-cfg-init.c"
650 }
651 #endif
652 
653     /*
654      * per-port parameters
655      */
656     pknd = 0;
657     bpid = 0;
658     pko_port_base = 0;
659 
660     for (i = 0; i < cvmx_helper_get_number_of_interfaces(); i++)
661     {
662 	n = cvmx_helper_interface_enumerate(i);
663 
664         pport = cvmx_cfg_port[i];
665         for (j = 0; j < n; j++, pport++)
666 	{
667 	    int t;
668 
669 	    t = cvmx_cfg_default_pko_nports;
670 	    if (pport->ccpp_pko_num_ports != CVMX_HELPER_CFG_INVALID_VALUE)
671 	        t = pport->ccpp_pko_num_ports;
672 
673             *pport = (struct cvmx_cfg_port_param) {
674 		pknd++,
675 		bpid++,
676 		pko_port_base,
677 		t,
678 	        pport->ccpp_pko_nqueues};
679 	    pko_port_base += t;
680 	}
681     }
682 
683     cvmx_helper_cfg_assert(pknd <= CVMX_HELPER_CFG_MAX_PIP_PKND);
684     cvmx_helper_cfg_assert(bpid <= CVMX_HELPER_CFG_MAX_PIP_BPID);
685     cvmx_helper_cfg_assert(pko_port_base <= CVMX_HELPER_CFG_MAX_PKO_PORT);
686 
687     /*
688      * pko_port map
689      */
690     cvmx_helper_cfg_init_pko_port_map();
691 
692     /*
693      * per-pko_port parameters
694      */
695     qbase = 0;
696     for (i = 0; i < pko_port_base; i++)
697     {
698 #ifdef CVMX_USER_DEFINED_HELPER_CONFIG_INIT
699 	n = __cvmx_ucfg_nqueues(i);
700 #else
701 	n = cvmx_helper_cfg_dft_nqueues(i);
702 #endif
703 	cvmx_cfg_pko_port[i] = (struct cvmx_cfg_pko_port_param) {qbase, n};
704 	qbase += n;
705 	cvmx_helper_cfg_assert(qbase <= CVMX_HELPER_CFG_MAX_PKO_QUEUES);
706     }
707 
708 #ifdef CVMX_ENABLE_PKO_FUNCTIONS
709     __cvmx_helper_cfg_init_ipd2pko_cache();
710 #endif
711 
712 #ifdef CVMX_HELPER_CFG_DEBUG
713     cvmx_helper_cfg_show_cfg();
714 #endif /* CVMX_HELPER_CFG_DEBUG */
715 #endif
716     return 0;
717 }
718