1/***********************license start***************
2 * Copyright (c) 2003-2010  Cavium Inc. (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 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 */
86struct 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 */
107struct 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 */
118struct 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 */
127struct cvmx_cfg_pko_port_pair {
128	int8_t ccppp_base_port;
129	int8_t ccppp_nports;
130};
131
132static 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 */
145static 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
151static 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 */
164static 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
173static 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 */
179static 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 */
191static 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 */
197static CVMX_SHARED int cvmx_cfg_max_pko_engines; /* # of PKO DMA engines
198						    allocated */
199int __cvmx_helper_cfg_pknd(int interface, int index)
200{
201    return cvmx_cfg_port[interface][index].ccpp_pknd;
202}
203
204int __cvmx_helper_cfg_bpid(int interface, int index)
205{
206    return cvmx_cfg_port[interface][index].ccpp_bpid;
207}
208
209int __cvmx_helper_cfg_pko_port_base(int interface, int index)
210{
211    return cvmx_cfg_port[interface][index].ccpp_pko_port_base;
212}
213
214int __cvmx_helper_cfg_pko_port_num(int interface, int index)
215{
216    return cvmx_cfg_port[interface][index].ccpp_pko_num_ports;
217}
218
219int __cvmx_helper_cfg_pko_queue_num(int pko_port)
220{
221    return cvmx_cfg_pko_port[pko_port].ccppp_num_queues;
222}
223
224int __cvmx_helper_cfg_pko_queue_base(int pko_port)
225{
226    return cvmx_cfg_pko_port[pko_port].ccppp_queue_base;
227}
228
229int __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
252int __cvmx_helper_cfg_pko_max_engine(void)
253{
254    return cvmx_cfg_max_pko_engines;
255}
256
257int 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
267uint64_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
276EXPORT_SYMBOL(__cvmx_helper_cfg_init);
277EXPORT_SYMBOL(__cvmx_helper_cfg_pknd);
278EXPORT_SYMBOL(__cvmx_helper_cfg_bpid);
279EXPORT_SYMBOL(__cvmx_helper_cfg_pko_port_base);
280EXPORT_SYMBOL(__cvmx_helper_cfg_pko_port_num);
281EXPORT_SYMBOL(__cvmx_helper_cfg_pko_queue_base);
282EXPORT_SYMBOL(__cvmx_helper_cfg_pko_queue_num);
283EXPORT_SYMBOL(__cvmx_helper_cfg_pko_max_queue);
284EXPORT_SYMBOL(__cvmx_helper_cfg_pko_port_interface);
285EXPORT_SYMBOL(__cvmx_helper_cfg_pko_port_index);
286EXPORT_SYMBOL(__cvmx_helper_cfg_pko_port_eid);
287EXPORT_SYMBOL(__cvmx_helper_cfg_pko_max_engine);
288EXPORT_SYMBOL(cvmx_helper_cfg_opt_get);
289EXPORT_SYMBOL(cvmx_helper_cfg_opt_set);
290EXPORT_SYMBOL(cvmx_helper_cfg_ipd2pko_port_base);
291EXPORT_SYMBOL(cvmx_helper_cfg_ipd2pko_port_num);
292#endif
293
294#ifdef CVMX_ENABLE_HELPER_FUNCTIONS
295
296#ifdef CVMX_HELPER_CFG_DEBUG
297void 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 */
338static 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
397int __cvmx_helper_cfg_pko_port_interface(int pko_port)
398{
399    return cvmx_cfg_pko_port_map[pko_port].ccppl_interface;
400}
401
402int __cvmx_helper_cfg_pko_port_index(int pko_port)
403{
404    return cvmx_cfg_pko_port_map[pko_port].ccppl_index;
405}
406
407int __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 */
425static 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 */
445static 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
470int 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
481int 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 */
503static 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 */
549static 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
628int __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