1232809Sjmallett/***********************license start***************
2232809Sjmallett * Copyright (c) 2003-2010  Cavium Inc. (support@cavium.com). All rights
3232809Sjmallett * reserved.
4232809Sjmallett *
5232809Sjmallett *
6232809Sjmallett * Redistribution and use in source and binary forms, with or without
7232809Sjmallett * modification, are permitted provided that the following conditions are
8232809Sjmallett * met:
9232809Sjmallett *
10232809Sjmallett *   * Redistributions of source code must retain the above copyright
11232809Sjmallett *     notice, this list of conditions and the following disclaimer.
12232809Sjmallett *
13232809Sjmallett *   * Redistributions in binary form must reproduce the above
14232809Sjmallett *     copyright notice, this list of conditions and the following
15232809Sjmallett *     disclaimer in the documentation and/or other materials provided
16232809Sjmallett *     with the distribution.
17232809Sjmallett
18232809Sjmallett *   * Neither the name of Cavium Inc. nor the names of
19232809Sjmallett *     its contributors may be used to endorse or promote products
20232809Sjmallett *     derived from this software without specific prior written
21232809Sjmallett *     permission.
22232809Sjmallett
23232809Sjmallett * This Software, including technical data, may be subject to U.S. export  control
24232809Sjmallett * laws, including the U.S. Export Administration Act and its  associated
25232809Sjmallett * regulations, and may be subject to export or import  regulations in other
26232809Sjmallett * countries.
27232809Sjmallett
28232809Sjmallett * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
29232809Sjmallett * AND WITH ALL FAULTS AND CAVIUM INC. MAKES NO PROMISES, REPRESENTATIONS OR
30232809Sjmallett * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
31232809Sjmallett * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR
32232809Sjmallett * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM
33232809Sjmallett * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE,
34232809Sjmallett * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF
35232809Sjmallett * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
36232809Sjmallett * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE  RISK ARISING OUT OF USE OR
37232809Sjmallett * PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
38232809Sjmallett ***********************license end**************************************/
39232809Sjmallett
40232809Sjmallett
41232809Sjmallett
42232809Sjmallett
43232809Sjmallett
44232809Sjmallett
45232809Sjmallett
46232809Sjmallett/**
47232809Sjmallett * @file
48232809Sjmallett *
49232809Sjmallett * Helper Functions for the Configuration Framework
50232809Sjmallett *
51232809Sjmallett * <hr>$Revision: 0 $<hr>
52232809Sjmallett */
53232809Sjmallett#ifdef CVMX_BUILD_FOR_LINUX_KERNEL
54232809Sjmallett#include <linux/module.h>
55232809Sjmallett#include <asm/octeon/cvmx.h>
56232809Sjmallett#include <asm/octeon/cvmx-helper.h>
57232809Sjmallett#include <asm/octeon/cvmx-helper-util.h>
58232809Sjmallett#include <asm/octeon/cvmx-helper-cfg.h>
59232809Sjmallett#include <asm/octeon/cvmx-helper-ilk.h>
60232809Sjmallett#include <asm/octeon/cvmx-ilk.h>
61232809Sjmallett#include <asm/octeon/cvmx-config.h>
62232809Sjmallett#else
63232809Sjmallett#include "cvmx.h"
64232809Sjmallett#include "cvmx-bootmem.h"
65232809Sjmallett#include "cvmx-helper.h"
66232809Sjmallett#include "cvmx-helper-util.h"
67232809Sjmallett#include "cvmx-helper-cfg.h"
68232809Sjmallett#include "cvmx-ilk.h"
69232809Sjmallett#include "cvmx-helper-ilk.h"
70232812Sjmallett#if !defined(__FreeBSD__) || !defined(_KERNEL)
71232809Sjmallett#include "cvmx-config.h"
72232809Sjmallett#include "executive-config.h"
73232809Sjmallett#endif
74232812Sjmallett#endif
75232809Sjmallett
76232809Sjmallett#if defined(min)
77232809Sjmallett#else
78232809Sjmallett#define min( a, b ) ( ( a ) < ( b ) ) ? ( a ) : ( b )
79232809Sjmallett#endif
80232809Sjmallett
81232809Sjmallett/* #define CVMX_HELPER_CFG_DEBUG */
82232809Sjmallett
83232809Sjmallett/*
84232809Sjmallett * Per physical port
85232809Sjmallett */
86232809Sjmallettstruct cvmx_cfg_port_param {
87232809Sjmallett	int8_t	ccpp_pknd;
88232809Sjmallett	int8_t	ccpp_bpid;
89232809Sjmallett	int8_t	ccpp_pko_port_base;
90232809Sjmallett	int8_t	ccpp_pko_num_ports;
91232809Sjmallett	uint8_t	ccpp_pko_nqueues;	/*
92232809Sjmallett					 * When the user explicitly
93232809Sjmallett					 * assigns queues,
94232809Sjmallett					 * cvmx_cfg_pko_nqueue_pool[
95232809Sjmallett					 *     ccpp_pko_nqueues ...
96232809Sjmallett					 *     ccpp_pko_nqueues +
97232809Sjmallett					 *     ccpp_pko_num_ports - 1]
98232809Sjmallett					 * are the numbers of PKO queues
99232809Sjmallett					 * assigned to the PKO ports for
100232809Sjmallett					 * this physical port.
101232809Sjmallett					 */
102232809Sjmallett};
103232809Sjmallett
104232809Sjmallett/*
105232809Sjmallett * Per pko_port
106232809Sjmallett */
107232809Sjmallettstruct cvmx_cfg_pko_port_param {
108232809Sjmallett	int16_t	ccppp_queue_base;
109232809Sjmallett	int16_t	ccppp_num_queues;
110232809Sjmallett};
111232809Sjmallett
112232809Sjmallett/*
113232809Sjmallett * A map from pko_port to
114232809Sjmallett *     interface,
115232809Sjmallett *     index, and
116232809Sjmallett *     pko engine id
117232809Sjmallett */
118232809Sjmallettstruct cvmx_cfg_pko_port_map {
119232809Sjmallett	int16_t ccppl_interface;
120232809Sjmallett	int16_t ccppl_index;
121232809Sjmallett	int16_t ccppl_eid;
122232809Sjmallett};
123232809Sjmallett
124232809Sjmallett/*
125232809Sjmallett * This is for looking up pko_base_port and pko_nport for ipd_port
126232809Sjmallett */
127232809Sjmallettstruct cvmx_cfg_pko_port_pair {
128232809Sjmallett	int8_t ccppp_base_port;
129232809Sjmallett	int8_t ccppp_nports;
130232809Sjmallett};
131232809Sjmallett
132232809Sjmallettstatic CVMX_SHARED struct cvmx_cfg_port_param cvmx_cfg_port
133232809Sjmallett    [CVMX_HELPER_CFG_MAX_IFACE][CVMX_HELPER_CFG_MAX_PORT_PER_IFACE] =
134232809Sjmallett    {[0 ... CVMX_HELPER_CFG_MAX_IFACE - 1] =
135232809Sjmallett        {[0 ... CVMX_HELPER_CFG_MAX_PORT_PER_IFACE - 1] =
136232809Sjmallett            {CVMX_HELPER_CFG_INVALID_VALUE,
137232809Sjmallett    	     CVMX_HELPER_CFG_INVALID_VALUE,
138232809Sjmallett    	     CVMX_HELPER_CFG_INVALID_VALUE,
139232809Sjmallett    	     CVMX_HELPER_CFG_INVALID_VALUE,
140232809Sjmallett    	     CVMX_HELPER_CFG_INVALID_VALUE}}};
141232809Sjmallett
142232809Sjmallett/*
143232809Sjmallett * Indexed by the pko_port number
144232809Sjmallett */
145232809Sjmallettstatic CVMX_SHARED struct cvmx_cfg_pko_port_param cvmx_cfg_pko_port
146232809Sjmallett    [CVMX_HELPER_CFG_MAX_PKO_PORT] =
147232809Sjmallett    {[0 ... CVMX_HELPER_CFG_MAX_PKO_PORT - 1] =
148232809Sjmallett        {CVMX_HELPER_CFG_INVALID_VALUE,
149232809Sjmallett	 CVMX_HELPER_CFG_INVALID_VALUE}};
150232809Sjmallett
151232809Sjmallettstatic CVMX_SHARED struct cvmx_cfg_pko_port_map cvmx_cfg_pko_port_map
152232809Sjmallett    [CVMX_HELPER_CFG_MAX_PKO_PORT] =
153232809Sjmallett        {[0 ... CVMX_HELPER_CFG_MAX_PKO_PORT - 1] =
154232809Sjmallett            {CVMX_HELPER_CFG_INVALID_VALUE,
155232809Sjmallett	     CVMX_HELPER_CFG_INVALID_VALUE,
156232809Sjmallett             CVMX_HELPER_CFG_INVALID_VALUE}};
157232809Sjmallett
158232809Sjmallett#ifdef CVMX_ENABLE_PKO_FUNCTIONS
159232809Sjmallett/*
160232809Sjmallett * This array assists translation from ipd_port to pko_port.
161232809Sjmallett * The ``16'' is the rounded value for the 3rd 4-bit value of
162232809Sjmallett * ipd_port, used to differentiate ``interfaces.''
163232809Sjmallett */
164232809Sjmallettstatic CVMX_SHARED struct cvmx_cfg_pko_port_pair ipd2pko_port_cache[16]
165232809Sjmallett    [CVMX_HELPER_CFG_MAX_PORT_PER_IFACE] =
166232809Sjmallett    {[0 ... 15] =
167232809Sjmallett        {[0 ... CVMX_HELPER_CFG_MAX_PORT_PER_IFACE - 1] =
168232809Sjmallett	    {CVMX_HELPER_CFG_INVALID_VALUE,
169232809Sjmallett	     CVMX_HELPER_CFG_INVALID_VALUE}}};
170232809Sjmallett
171232809Sjmallett#ifdef CVMX_USER_DEFINED_HELPER_CONFIG_INIT
172232809Sjmallett
173232809Sjmallettstatic CVMX_SHARED int cvmx_cfg_default_pko_nqueues = 1;
174232809Sjmallett
175232809Sjmallett/*
176232809Sjmallett * A pool for holding the pko_nqueues for the pko_ports assigned to a
177232809Sjmallett * physical port.
178232809Sjmallett */
179232809Sjmallettstatic CVMX_SHARED uint8_t cvmx_cfg_pko_nqueue_pool
180232809Sjmallett    [CVMX_HELPER_CFG_MAX_PKO_QUEUES] =
181232809Sjmallett    {[0 ... CVMX_HELPER_CFG_MAX_PKO_QUEUES - 1] = 1};
182232809Sjmallett
183232809Sjmallett#endif
184232809Sjmallett#endif
185232809Sjmallett
186232809Sjmallett/*
187232809Sjmallett * Options
188232809Sjmallett *
189232809Sjmallett * Each array-elem's intial value is also the option's default value.
190232809Sjmallett */
191232809Sjmallettstatic CVMX_SHARED uint64_t cvmx_cfg_opts[CVMX_HELPER_CFG_OPT_MAX] =
192232809Sjmallett    {[0 ... CVMX_HELPER_CFG_OPT_MAX - 1] = 1};
193232809Sjmallett
194232809Sjmallett/*
195232809Sjmallett * MISC
196232809Sjmallett */
197232809Sjmallettstatic CVMX_SHARED int cvmx_cfg_max_pko_engines; /* # of PKO DMA engines
198232809Sjmallett						    allocated */
199232809Sjmallettint __cvmx_helper_cfg_pknd(int interface, int index)
200232809Sjmallett{
201232809Sjmallett    return cvmx_cfg_port[interface][index].ccpp_pknd;
202232809Sjmallett}
203232809Sjmallett
204232809Sjmallettint __cvmx_helper_cfg_bpid(int interface, int index)
205232809Sjmallett{
206232809Sjmallett    return cvmx_cfg_port[interface][index].ccpp_bpid;
207232809Sjmallett}
208232809Sjmallett
209232809Sjmallettint __cvmx_helper_cfg_pko_port_base(int interface, int index)
210232809Sjmallett{
211232809Sjmallett    return cvmx_cfg_port[interface][index].ccpp_pko_port_base;
212232809Sjmallett}
213232809Sjmallett
214232809Sjmallettint __cvmx_helper_cfg_pko_port_num(int interface, int index)
215232809Sjmallett{
216232809Sjmallett    return cvmx_cfg_port[interface][index].ccpp_pko_num_ports;
217232809Sjmallett}
218232809Sjmallett
219232809Sjmallettint __cvmx_helper_cfg_pko_queue_num(int pko_port)
220232809Sjmallett{
221232809Sjmallett    return cvmx_cfg_pko_port[pko_port].ccppp_num_queues;
222232809Sjmallett}
223232809Sjmallett
224232809Sjmallettint __cvmx_helper_cfg_pko_queue_base(int pko_port)
225232809Sjmallett{
226232809Sjmallett    return cvmx_cfg_pko_port[pko_port].ccppp_queue_base;
227232809Sjmallett}
228232809Sjmallett
229232809Sjmallettint __cvmx_helper_cfg_pko_max_queue(void)
230232809Sjmallett{
231232809Sjmallett    int i;
232232809Sjmallett
233232809Sjmallett    i = CVMX_HELPER_CFG_MAX_PKO_PORT - 1;
234232809Sjmallett
235232809Sjmallett    while (i >= 0)
236232809Sjmallett    {
237232809Sjmallett        if (cvmx_cfg_pko_port[i].ccppp_queue_base !=
238232809Sjmallett	    CVMX_HELPER_CFG_INVALID_VALUE)
239232809Sjmallett	{
240232809Sjmallett	    cvmx_helper_cfg_assert(cvmx_cfg_pko_port[i].ccppp_num_queues > 0);
241232809Sjmallett	    return (cvmx_cfg_pko_port[i].ccppp_queue_base +
242232809Sjmallett	        cvmx_cfg_pko_port[i].ccppp_num_queues);
243232809Sjmallett	}
244232809Sjmallett	i --;
245232809Sjmallett    }
246232809Sjmallett
247232809Sjmallett    cvmx_helper_cfg_assert(0); /* shouldn't get here */
248232809Sjmallett
249232809Sjmallett    return 0;
250232809Sjmallett}
251232809Sjmallett
252232809Sjmallettint __cvmx_helper_cfg_pko_max_engine(void)
253232809Sjmallett{
254232809Sjmallett    return cvmx_cfg_max_pko_engines;
255232809Sjmallett}
256232809Sjmallett
257232809Sjmallettint cvmx_helper_cfg_opt_set(cvmx_helper_cfg_option_t opt, uint64_t val)
258232809Sjmallett{
259232809Sjmallett    if (opt >= CVMX_HELPER_CFG_OPT_MAX)
260232809Sjmallett        return -1;
261232809Sjmallett
262232809Sjmallett    cvmx_cfg_opts[opt] = val;
263232809Sjmallett
264232809Sjmallett    return 0;
265232809Sjmallett}
266232809Sjmallett
267232809Sjmallettuint64_t cvmx_helper_cfg_opt_get(cvmx_helper_cfg_option_t opt)
268232809Sjmallett{
269232809Sjmallett    if (opt >= CVMX_HELPER_CFG_OPT_MAX)
270232809Sjmallett        return (uint64_t)CVMX_HELPER_CFG_INVALID_VALUE;
271232809Sjmallett
272232809Sjmallett    return cvmx_cfg_opts[opt];
273232809Sjmallett}
274232809Sjmallett
275232809Sjmallett#ifdef CVMX_BUILD_FOR_LINUX_KERNEL
276232809SjmallettEXPORT_SYMBOL(__cvmx_helper_cfg_init);
277232809SjmallettEXPORT_SYMBOL(__cvmx_helper_cfg_pknd);
278232809SjmallettEXPORT_SYMBOL(__cvmx_helper_cfg_bpid);
279232809SjmallettEXPORT_SYMBOL(__cvmx_helper_cfg_pko_port_base);
280232809SjmallettEXPORT_SYMBOL(__cvmx_helper_cfg_pko_port_num);
281232809SjmallettEXPORT_SYMBOL(__cvmx_helper_cfg_pko_queue_base);
282232809SjmallettEXPORT_SYMBOL(__cvmx_helper_cfg_pko_queue_num);
283232809SjmallettEXPORT_SYMBOL(__cvmx_helper_cfg_pko_max_queue);
284232809SjmallettEXPORT_SYMBOL(__cvmx_helper_cfg_pko_port_interface);
285232809SjmallettEXPORT_SYMBOL(__cvmx_helper_cfg_pko_port_index);
286232809SjmallettEXPORT_SYMBOL(__cvmx_helper_cfg_pko_port_eid);
287232809SjmallettEXPORT_SYMBOL(__cvmx_helper_cfg_pko_max_engine);
288232809SjmallettEXPORT_SYMBOL(cvmx_helper_cfg_opt_get);
289232809SjmallettEXPORT_SYMBOL(cvmx_helper_cfg_opt_set);
290232809SjmallettEXPORT_SYMBOL(cvmx_helper_cfg_ipd2pko_port_base);
291232809SjmallettEXPORT_SYMBOL(cvmx_helper_cfg_ipd2pko_port_num);
292232809Sjmallett#endif
293232809Sjmallett
294232809Sjmallett#ifdef CVMX_ENABLE_HELPER_FUNCTIONS
295232809Sjmallett
296232809Sjmallett#ifdef CVMX_HELPER_CFG_DEBUG
297232809Sjmallettvoid cvmx_helper_cfg_show_cfg(void)
298232809Sjmallett{
299232809Sjmallett    int i, j;
300232809Sjmallett
301232809Sjmallett    for (i = 0; i < cvmx_helper_get_number_of_interfaces(); i++)
302232809Sjmallett    {
303232809Sjmallett	cvmx_dprintf(
304232809Sjmallett	    "cvmx_helper_cfg_show_cfg: interface%d mode %10s nports%4d\n", i,
305232809Sjmallett	    cvmx_helper_interface_mode_to_string(cvmx_helper_interface_get_mode(i)),
306232809Sjmallett	    cvmx_helper_interface_enumerate(i));
307232809Sjmallett
308232809Sjmallett	for (j = 0; j < cvmx_helper_interface_enumerate(i); j++)
309232809Sjmallett	{
310232809Sjmallett	    cvmx_dprintf("\tpknd[%i][%d]%d", i, j,
311232809Sjmallett	        __cvmx_helper_cfg_pknd(i, j));
312232809Sjmallett	    cvmx_dprintf(" pko_port_base[%i][%d]%d", i, j,
313232809Sjmallett	        __cvmx_helper_cfg_pko_port_base(i, j));
314232809Sjmallett	    cvmx_dprintf(" pko_port_num[%i][%d]%d\n", i, j,
315232809Sjmallett	        __cvmx_helper_cfg_pko_port_num(i, j));
316232809Sjmallett	}
317232809Sjmallett    }
318232809Sjmallett
319232809Sjmallett    for (i = 0; i < CVMX_HELPER_CFG_MAX_PKO_PORT; i++)
320232809Sjmallett    {
321232809Sjmallett	if (__cvmx_helper_cfg_pko_queue_base(i) !=
322232809Sjmallett	    CVMX_HELPER_CFG_INVALID_VALUE)
323232809Sjmallett	{
324232809Sjmallett            cvmx_dprintf("cvmx_helper_cfg_show_cfg: pko_port%d qbase%d nqueues%d "
325232809Sjmallett	        "interface%d index%d\n", i,
326232809Sjmallett		__cvmx_helper_cfg_pko_queue_base(i),
327232809Sjmallett		__cvmx_helper_cfg_pko_queue_num(i),
328232809Sjmallett		__cvmx_helper_cfg_pko_port_interface(i),
329232809Sjmallett		__cvmx_helper_cfg_pko_port_index(i));
330232809Sjmallett        }
331232809Sjmallett    }
332232809Sjmallett}
333232809Sjmallett#endif
334232809Sjmallett
335232809Sjmallett/*
336232809Sjmallett * initialize cvmx_cfg_pko_port_map
337232809Sjmallett */
338232809Sjmallettstatic void cvmx_helper_cfg_init_pko_port_map(void)
339232809Sjmallett{
340232809Sjmallett    int i, j, k;
341232809Sjmallett    int pko_eid;
342232809Sjmallett    int pko_port_base, pko_port_max;
343232809Sjmallett    cvmx_helper_interface_mode_t mode;
344232809Sjmallett
345232809Sjmallett    /*
346232809Sjmallett     * one pko_eid is allocated to each port except for ILK, NPI, and
347232809Sjmallett     * LOOP. Each of the three has one eid.
348232809Sjmallett     */
349232809Sjmallett    pko_eid = 0;
350232809Sjmallett    for (i = 0; i < cvmx_helper_get_number_of_interfaces(); i++)
351232809Sjmallett    {
352232809Sjmallett	mode = cvmx_helper_interface_get_mode(i);
353232809Sjmallett        for (j = 0; j < cvmx_helper_interface_enumerate(i); j++)
354232809Sjmallett	{
355232809Sjmallett	    pko_port_base = cvmx_cfg_port[i][j].ccpp_pko_port_base;
356232809Sjmallett	    pko_port_max = pko_port_base +
357232809Sjmallett	        cvmx_cfg_port[i][j].ccpp_pko_num_ports;
358232809Sjmallett	    cvmx_helper_cfg_assert(pko_port_base !=
359232809Sjmallett	        CVMX_HELPER_CFG_INVALID_VALUE);
360232809Sjmallett	    cvmx_helper_cfg_assert(pko_port_max >= pko_port_base);
361232809Sjmallett	    for (k = pko_port_base; k < pko_port_max; k++)
362232809Sjmallett	    {
363232809Sjmallett	        cvmx_cfg_pko_port_map[k].ccppl_interface = i;
364232809Sjmallett	        cvmx_cfg_pko_port_map[k].ccppl_index = j;
365232809Sjmallett	        cvmx_cfg_pko_port_map[k].ccppl_eid = pko_eid;
366232809Sjmallett	    }
367232809Sjmallett
368232809Sjmallett#if 0
369232809Sjmallett	    /*
370232809Sjmallett	     * For a physical port that is not configured a PKO port,
371232809Sjmallett	     * pko_port_base here equals to pko_port_max. In this
372232809Sjmallett	     * case, the physical port does not take a DMA engine.
373232809Sjmallett	     */
374232809Sjmallett	    if (pko_port_base > pko_port_max)
375232809Sjmallett#endif
376232809Sjmallett	        if (!(mode == CVMX_HELPER_INTERFACE_MODE_NPI ||
377232809Sjmallett	            mode == CVMX_HELPER_INTERFACE_MODE_LOOP ||
378232809Sjmallett	            mode == CVMX_HELPER_INTERFACE_MODE_ILK))
379232809Sjmallett	            pko_eid ++;
380232809Sjmallett	}
381232809Sjmallett
382232809Sjmallett	if (mode == CVMX_HELPER_INTERFACE_MODE_NPI ||
383232809Sjmallett	    mode == CVMX_HELPER_INTERFACE_MODE_LOOP ||
384232809Sjmallett	    mode == CVMX_HELPER_INTERFACE_MODE_ILK)
385232809Sjmallett	        pko_eid ++;
386232809Sjmallett    }
387232809Sjmallett
388232809Sjmallett    /*
389232809Sjmallett     * Legal pko_eids [0, 0x13] should not be exhausted.
390232809Sjmallett     */
391232809Sjmallett    cvmx_helper_cfg_assert(pko_eid <= 0x14);
392232809Sjmallett
393232809Sjmallett    cvmx_cfg_max_pko_engines = pko_eid;
394232809Sjmallett}
395232809Sjmallett#endif
396232809Sjmallett
397232809Sjmallettint __cvmx_helper_cfg_pko_port_interface(int pko_port)
398232809Sjmallett{
399232809Sjmallett    return cvmx_cfg_pko_port_map[pko_port].ccppl_interface;
400232809Sjmallett}
401232809Sjmallett
402232809Sjmallettint __cvmx_helper_cfg_pko_port_index(int pko_port)
403232809Sjmallett{
404232809Sjmallett    return cvmx_cfg_pko_port_map[pko_port].ccppl_index;
405232809Sjmallett}
406232809Sjmallett
407232809Sjmallettint __cvmx_helper_cfg_pko_port_eid(int pko_port)
408232809Sjmallett{
409232809Sjmallett    return cvmx_cfg_pko_port_map[pko_port].ccppl_eid;
410232809Sjmallett}
411232809Sjmallett
412232809Sjmallett/**
413232809Sjmallett * Perform common init tasks for all chips.
414232809Sjmallett * @return 1 for the caller to continue init and 0 otherwise.
415232809Sjmallett *
416232809Sjmallett * Note: ``common'' means this function is executed regardless of
417232809Sjmallett * 	- chip, and
418232809Sjmallett * 	- CVMX_ENABLE_HELPER_FUNCTIONS.
419232809Sjmallett *
420232809Sjmallett * This function decides based on these conditions if the
421232809Sjmallett * configuration stage of the init process should continue.
422232809Sjmallett *
423232809Sjmallett * This is only meant to be called by __cvmx_helper_cfg_init().
424232809Sjmallett */
425232809Sjmallettstatic int __cvmx_helper_cfg_init_common(void)
426232809Sjmallett{
427232809Sjmallett    int val;
428232809Sjmallett
429232809Sjmallett#ifndef CVMX_ENABLE_HELPER_FUNCTIONS
430232809Sjmallett    val = 0;
431232809Sjmallett#else
432232809Sjmallett    val = (octeon_has_feature(OCTEON_FEATURE_PKND));
433232809Sjmallett#endif
434232809Sjmallett
435232809Sjmallett    return val;
436232809Sjmallett}
437232809Sjmallett
438232809Sjmallett#define IPD2PKO_CACHE_Y(ipd_port)	(ipd_port) >> 8
439232809Sjmallett#define IPD2PKO_CACHE_X(ipd_port)	(ipd_port) & 0xff
440232809Sjmallett
441232809Sjmallett#ifdef CVMX_ENABLE_PKO_FUNCTIONS
442232809Sjmallett/*
443232809Sjmallett * ipd_port to pko_port translation cache
444232809Sjmallett */
445232809Sjmallettstatic int __cvmx_helper_cfg_init_ipd2pko_cache(void)
446232809Sjmallett{
447232809Sjmallett    int i, j, n;
448232809Sjmallett    int ipd_y, ipd_x, ipd_port;
449232809Sjmallett
450232809Sjmallett    for (i = 0; i < cvmx_helper_get_number_of_interfaces(); i++)
451232809Sjmallett    {
452232809Sjmallett	n = cvmx_helper_interface_enumerate(i);
453232809Sjmallett
454232809Sjmallett        for (j = 0; j < n; j++)
455232809Sjmallett	{
456232809Sjmallett	    ipd_port = cvmx_helper_get_ipd_port(i, j);
457232809Sjmallett	    ipd_y = IPD2PKO_CACHE_Y(ipd_port);
458232809Sjmallett	    ipd_x = IPD2PKO_CACHE_X(ipd_port);
459232809Sjmallett	    ipd2pko_port_cache[ipd_y]
460232809Sjmallett	        [(ipd_port & 0x800) ? ((ipd_x >> 4) & 3) : ipd_x] =
461232809Sjmallett		(struct cvmx_cfg_pko_port_pair)
462232809Sjmallett		{__cvmx_helper_cfg_pko_port_base(i, j),
463232809Sjmallett		 __cvmx_helper_cfg_pko_port_num(i, j)};
464232809Sjmallett	}
465232809Sjmallett    }
466232809Sjmallett
467232809Sjmallett    return 0;
468232809Sjmallett}
469232809Sjmallett
470232809Sjmallettint cvmx_helper_cfg_ipd2pko_port_base(int ipd_port)
471232809Sjmallett{
472232809Sjmallett	int ipd_y, ipd_x;
473232809Sjmallett
474232809Sjmallett        ipd_y = IPD2PKO_CACHE_Y(ipd_port);
475232809Sjmallett	ipd_x = IPD2PKO_CACHE_X(ipd_port);
476232809Sjmallett
477232809Sjmallett        return ipd2pko_port_cache[ipd_y]
478232809Sjmallett	    [(ipd_port & 0x800) ? ((ipd_x >> 4) & 3) : ipd_x].ccppp_base_port;
479232809Sjmallett}
480232809Sjmallett
481232809Sjmallettint cvmx_helper_cfg_ipd2pko_port_num(int ipd_port)
482232809Sjmallett{
483232809Sjmallett	int ipd_y, ipd_x;
484232809Sjmallett
485232809Sjmallett        ipd_y = IPD2PKO_CACHE_Y(ipd_port);
486232809Sjmallett	ipd_x = IPD2PKO_CACHE_X(ipd_port);
487232809Sjmallett
488232809Sjmallett        return ipd2pko_port_cache[ipd_y]
489232809Sjmallett	    [(ipd_port & 0x800) ? ((ipd_x >> 4) & 3) : ipd_x].ccppp_nports;
490232809Sjmallett}
491232809Sjmallett#endif
492232809Sjmallett
493232809Sjmallett#ifdef CVMX_ENABLE_HELPER_FUNCTIONS
494232809Sjmallett#ifdef CVMX_USER_DEFINED_HELPER_CONFIG_INIT
495232809Sjmallett/**
496232809Sjmallett * Return the number of queues assigned to this pko_port by user
497232809Sjmallett *
498232809Sjmallett * @param pko_port
499232809Sjmallett * @return the number of queues for this pko_port
500232809Sjmallett *
501232809Sjmallett * Note: Called after the pko_port map is set up.
502232809Sjmallett */
503232809Sjmallettstatic int __cvmx_ucfg_nqueues(int pko_port)
504232809Sjmallett{
505232809Sjmallett    int interface, index;
506232809Sjmallett    int i, k;
507232809Sjmallett
508232809Sjmallett    interface = __cvmx_helper_cfg_pko_port_interface(pko_port);
509232809Sjmallett    index = __cvmx_helper_cfg_pko_port_index(pko_port);
510232809Sjmallett
511232809Sjmallett    /*
512232809Sjmallett     * pko_port belongs to no physical port,
513232809Sjmallett     * don't assign a queue to it.
514232809Sjmallett     */
515232809Sjmallett    if (interface == CVMX_HELPER_CFG_INVALID_VALUE ||
516232809Sjmallett        index == CVMX_HELPER_CFG_INVALID_VALUE)
517232809Sjmallett	return 0;
518232809Sjmallett
519232809Sjmallett    /*
520232809Sjmallett     * Assign the default number of queues to those pko_ports not
521232809Sjmallett     * assigned explicitly.
522232809Sjmallett     */
523232809Sjmallett    i = cvmx_cfg_port[interface][index].ccpp_pko_nqueues;
524232809Sjmallett    if (i == (uint8_t)CVMX_HELPER_CFG_INVALID_VALUE)
525232809Sjmallett        return cvmx_cfg_default_pko_nqueues;
526232809Sjmallett
527232809Sjmallett    /*
528232809Sjmallett     * The user has assigned nqueues to this pko_port,
529232809Sjmallett     * recorded in the pool.
530232809Sjmallett     */
531232809Sjmallett    k = pko_port - cvmx_cfg_port[interface][index].ccpp_pko_port_base;
532232809Sjmallett    cvmx_helper_cfg_assert(k <
533232809Sjmallett        cvmx_cfg_port[interface][index].ccpp_pko_num_ports);
534232809Sjmallett    return cvmx_cfg_pko_nqueue_pool[i + k];
535232809Sjmallett}
536232809Sjmallett
537232809Sjmallett#else
538232809Sjmallett
539232809Sjmallett/**
540232809Sjmallett * Return the number of queues to be assigned to this pko_port
541232809Sjmallett *
542232809Sjmallett * @param pko_port
543232809Sjmallett * @return the number of queues for this pko_port
544232809Sjmallett *
545232809Sjmallett * Note: This function exists for backward compatibility.
546232809Sjmallett * CVMX_PKO_QUEUES_PER_PORT_XXXX defines no of queues per HW port.
547232809Sjmallett * pko_port is equivalent in pre-o68 SDK.
548232809Sjmallett */
549232809Sjmallettstatic int cvmx_helper_cfg_dft_nqueues(int pko_port)
550232809Sjmallett{
551232809Sjmallett    cvmx_helper_interface_mode_t mode;
552232809Sjmallett    int interface;
553232809Sjmallett    int n;
554232809Sjmallett
555232809Sjmallett#ifndef CVMX_HELPER_PKO_QUEUES_PER_PORT_INTERFACE0
556232809Sjmallett#define CVMX_HELPER_PKO_QUEUES_PER_PORT_INTERFACE0 1
557232809Sjmallett#endif
558232809Sjmallett
559232809Sjmallett#ifndef CVMX_HELPER_PKO_QUEUES_PER_PORT_INTERFACE1
560232809Sjmallett#define CVMX_HELPER_PKO_QUEUES_PER_PORT_INTERFACE1 1
561232809Sjmallett#endif
562232809Sjmallett
563232809Sjmallett#ifndef CVMX_HELPER_PKO_QUEUES_PER_PORT_INTERFACE2
564232809Sjmallett#define CVMX_HELPER_PKO_QUEUES_PER_PORT_INTERFACE2 1
565232809Sjmallett#endif
566232809Sjmallett
567232809Sjmallett#ifndef CVMX_HELPER_PKO_QUEUES_PER_PORT_INTERFACE3
568232809Sjmallett#define CVMX_HELPER_PKO_QUEUES_PER_PORT_INTERFACE3 1
569232809Sjmallett#endif
570232809Sjmallett
571232809Sjmallett#ifndef CVMX_HELPER_PKO_QUEUES_PER_PORT_INTERFACE4
572232809Sjmallett#define CVMX_HELPER_PKO_QUEUES_PER_PORT_INTERFACE4 1
573232809Sjmallett#endif
574232809Sjmallett
575232809Sjmallett    n = 1;
576232809Sjmallett    interface = __cvmx_helper_cfg_pko_port_interface(pko_port);
577232809Sjmallett    if (interface == 0)
578232809Sjmallett    {
579232809Sjmallett#ifdef CVMX_PKO_QUEUES_PER_PORT_INTERFACE0
580232809Sjmallett	n = CVMX_PKO_QUEUES_PER_PORT_INTERFACE0;
581232809Sjmallett#endif
582232809Sjmallett    }
583232809Sjmallett    if (interface == 1)
584232809Sjmallett    {
585232809Sjmallett#ifdef CVMX_PKO_QUEUES_PER_PORT_INTERFACE1
586232809Sjmallett	n = CVMX_PKO_QUEUES_PER_PORT_INTERFACE1;
587232809Sjmallett#endif
588232809Sjmallett    }
589232809Sjmallett
590232809Sjmallett    if (interface == 2)
591232809Sjmallett    {
592232809Sjmallett#ifdef CVMX_PKO_QUEUES_PER_PORT_INTERFACE2
593232809Sjmallett	n = CVMX_PKO_QUEUES_PER_PORT_INTERFACE2;
594232809Sjmallett#endif
595232809Sjmallett    }
596232809Sjmallett    if (interface == 3)
597232809Sjmallett    {
598232809Sjmallett#ifdef CVMX_PKO_QUEUES_PER_PORT_INTERFACE3
599232809Sjmallett	n = CVMX_PKO_QUEUES_PER_PORT_INTERFACE3;
600232809Sjmallett#endif
601232809Sjmallett    }
602232809Sjmallett    if (interface == 4)
603232809Sjmallett    {
604232809Sjmallett#ifdef CVMX_PKO_QUEUES_PER_PORT_INTERFACE4
605232809Sjmallett	n = CVMX_PKO_QUEUES_PER_PORT_INTERFACE4;
606232809Sjmallett#endif
607232809Sjmallett    }
608232809Sjmallett
609232809Sjmallett    mode = cvmx_helper_interface_get_mode(interface);
610232809Sjmallett    if (mode == CVMX_HELPER_INTERFACE_MODE_LOOP)
611232809Sjmallett    {
612232809Sjmallett#ifdef CVMX_PKO_QUEUES_PER_PORT_LOOP
613232809Sjmallett	n = CVMX_PKO_QUEUES_PER_PORT_LOOP;
614232809Sjmallett#endif
615232809Sjmallett    }
616232809Sjmallett    if (mode == CVMX_HELPER_INTERFACE_MODE_NPI)
617232809Sjmallett    {
618232809Sjmallett#ifdef CVMX_PKO_QUEUES_PER_PORT_PCI
619232809Sjmallett	n = CVMX_PKO_QUEUES_PER_PORT_PCI;
620232809Sjmallett#endif
621232809Sjmallett    }
622232809Sjmallett
623232809Sjmallett    return n;
624232809Sjmallett}
625232809Sjmallett#endif /* CVMX_USER_DEFINED_HELPER_CONFIG_INIT */
626232809Sjmallett#endif /* CVMX_ENABLE_HELPER_FUNCTIONS */
627232809Sjmallett
628232809Sjmallettint __cvmx_helper_cfg_init(void)
629232809Sjmallett{
630232809Sjmallett#ifdef CVMX_ENABLE_HELPER_FUNCTIONS
631232809Sjmallett    struct cvmx_cfg_port_param *pport;
632232809Sjmallett    int cvmx_cfg_default_pko_nports;
633232809Sjmallett    int pknd, bpid, pko_port_base;
634232809Sjmallett    int qbase;
635232809Sjmallett    int i, j, n;
636232809Sjmallett
637232809Sjmallett    cvmx_cfg_default_pko_nports = 1;
638232809Sjmallett#endif
639232809Sjmallett
640232809Sjmallett    if (!__cvmx_helper_cfg_init_common())
641232809Sjmallett        return 0;
642232809Sjmallett
643232809Sjmallett#ifdef CVMX_ENABLE_HELPER_FUNCTIONS
644232809Sjmallett
645232809Sjmallett#ifdef CVMX_USER_DEFINED_HELPER_CONFIG_INIT
646232809Sjmallett{
647232809Sjmallett	int cvmx_ucfg_nq;
648232809Sjmallett	cvmx_ucfg_nq = 0;
649232809Sjmallett#include "cvmx-helper-cfg-init.c"
650232809Sjmallett}
651232809Sjmallett#endif
652232809Sjmallett
653232809Sjmallett    /*
654232809Sjmallett     * per-port parameters
655232809Sjmallett     */
656232809Sjmallett    pknd = 0;
657232809Sjmallett    bpid = 0;
658232809Sjmallett    pko_port_base = 0;
659232809Sjmallett
660232809Sjmallett    for (i = 0; i < cvmx_helper_get_number_of_interfaces(); i++)
661232809Sjmallett    {
662232809Sjmallett	n = cvmx_helper_interface_enumerate(i);
663232809Sjmallett
664232809Sjmallett        pport = cvmx_cfg_port[i];
665232809Sjmallett        for (j = 0; j < n; j++, pport++)
666232809Sjmallett	{
667232809Sjmallett	    int t;
668232809Sjmallett
669232809Sjmallett	    t = cvmx_cfg_default_pko_nports;
670232809Sjmallett	    if (pport->ccpp_pko_num_ports != CVMX_HELPER_CFG_INVALID_VALUE)
671232809Sjmallett	        t = pport->ccpp_pko_num_ports;
672232809Sjmallett
673232809Sjmallett            *pport = (struct cvmx_cfg_port_param) {
674232809Sjmallett		pknd++,
675232809Sjmallett		bpid++,
676232809Sjmallett		pko_port_base,
677232809Sjmallett		t,
678232809Sjmallett	        pport->ccpp_pko_nqueues};
679232809Sjmallett	    pko_port_base += t;
680232809Sjmallett	}
681232809Sjmallett    }
682232809Sjmallett
683232809Sjmallett    cvmx_helper_cfg_assert(pknd <= CVMX_HELPER_CFG_MAX_PIP_PKND);
684232809Sjmallett    cvmx_helper_cfg_assert(bpid <= CVMX_HELPER_CFG_MAX_PIP_BPID);
685232809Sjmallett    cvmx_helper_cfg_assert(pko_port_base <= CVMX_HELPER_CFG_MAX_PKO_PORT);
686232809Sjmallett
687232809Sjmallett    /*
688232809Sjmallett     * pko_port map
689232809Sjmallett     */
690232809Sjmallett    cvmx_helper_cfg_init_pko_port_map();
691232809Sjmallett
692232809Sjmallett    /*
693232809Sjmallett     * per-pko_port parameters
694232809Sjmallett     */
695232809Sjmallett    qbase = 0;
696232809Sjmallett    for (i = 0; i < pko_port_base; i++)
697232809Sjmallett    {
698232809Sjmallett#ifdef CVMX_USER_DEFINED_HELPER_CONFIG_INIT
699232809Sjmallett	n = __cvmx_ucfg_nqueues(i);
700232809Sjmallett#else
701232809Sjmallett	n = cvmx_helper_cfg_dft_nqueues(i);
702232809Sjmallett#endif
703232809Sjmallett	cvmx_cfg_pko_port[i] = (struct cvmx_cfg_pko_port_param) {qbase, n};
704232809Sjmallett	qbase += n;
705232809Sjmallett	cvmx_helper_cfg_assert(qbase <= CVMX_HELPER_CFG_MAX_PKO_QUEUES);
706232809Sjmallett    }
707232809Sjmallett
708232809Sjmallett#ifdef CVMX_ENABLE_PKO_FUNCTIONS
709232809Sjmallett    __cvmx_helper_cfg_init_ipd2pko_cache();
710232809Sjmallett#endif
711232809Sjmallett
712232809Sjmallett#ifdef CVMX_HELPER_CFG_DEBUG
713232809Sjmallett    cvmx_helper_cfg_show_cfg();
714232809Sjmallett#endif /* CVMX_HELPER_CFG_DEBUG */
715232809Sjmallett#endif
716232809Sjmallett    return 0;
717232809Sjmallett}
718