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