aboutsummaryrefslogtreecommitdiffstats
path: root/cvmx-helper-cfg.c
diff options
context:
space:
mode:
Diffstat (limited to 'cvmx-helper-cfg.c')
-rw-r--r--cvmx-helper-cfg.c715
1 files changed, 715 insertions, 0 deletions
diff --git a/cvmx-helper-cfg.c b/cvmx-helper-cfg.c
new file mode 100644
index 000000000000..66e416c6757a
--- /dev/null
+++ b/cvmx-helper-cfg.c
@@ -0,0 +1,715 @@
+/***********************license start***************
+ * Copyright (c) 2003-2010 Cavium Inc. (support@cavium.com). All rights
+ * reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+
+ * * Neither the name of Cavium Inc. nor the names of
+ * its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+
+ * This Software, including technical data, may be subject to U.S. export control
+ * laws, including the U.S. Export Administration Act and its associated
+ * regulations, and may be subject to export or import regulations in other
+ * countries.
+
+ * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
+ * AND WITH ALL FAULTS AND CAVIUM INC. MAKES NO PROMISES, REPRESENTATIONS OR
+ * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
+ * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR
+ * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM
+ * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE,
+ * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF
+ * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
+ * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR
+ * PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
+ ***********************license end**************************************/
+
+
+
+
+
+
+
+/**
+ * @file
+ *
+ * Helper Functions for the Configuration Framework
+ *
+ * <hr>$Revision: 0 $<hr>
+ */
+#ifdef CVMX_BUILD_FOR_LINUX_KERNEL
+#include <linux/module.h>
+#include <asm/octeon/cvmx.h>
+#include <asm/octeon/cvmx-helper.h>
+#include <asm/octeon/cvmx-helper-util.h>
+#include <asm/octeon/cvmx-helper-cfg.h>
+#include <asm/octeon/cvmx-helper-ilk.h>
+#include <asm/octeon/cvmx-ilk.h>
+#include <asm/octeon/cvmx-config.h>
+#else
+#include "cvmx.h"
+#include "cvmx-bootmem.h"
+#include "cvmx-helper.h"
+#include "cvmx-helper-util.h"
+#include "cvmx-helper-cfg.h"
+#include "cvmx-ilk.h"
+#include "cvmx-helper-ilk.h"
+#include "cvmx-config.h"
+#include "executive-config.h"
+#endif
+
+#if defined(min)
+#else
+#define min( a, b ) ( ( a ) < ( b ) ) ? ( a ) : ( b )
+#endif
+
+/* #define CVMX_HELPER_CFG_DEBUG */
+
+/*
+ * Per physical port
+ */
+struct cvmx_cfg_port_param {
+ int8_t ccpp_pknd;
+ int8_t ccpp_bpid;
+ int8_t ccpp_pko_port_base;
+ int8_t ccpp_pko_num_ports;
+ uint8_t ccpp_pko_nqueues; /*
+ * When the user explicitly
+ * assigns queues,
+ * cvmx_cfg_pko_nqueue_pool[
+ * ccpp_pko_nqueues ...
+ * ccpp_pko_nqueues +
+ * ccpp_pko_num_ports - 1]
+ * are the numbers of PKO queues
+ * assigned to the PKO ports for
+ * this physical port.
+ */
+};
+
+/*
+ * Per pko_port
+ */
+struct cvmx_cfg_pko_port_param {
+ int16_t ccppp_queue_base;
+ int16_t ccppp_num_queues;
+};
+
+/*
+ * A map from pko_port to
+ * interface,
+ * index, and
+ * pko engine id
+ */
+struct cvmx_cfg_pko_port_map {
+ int16_t ccppl_interface;
+ int16_t ccppl_index;
+ int16_t ccppl_eid;
+};
+
+/*
+ * This is for looking up pko_base_port and pko_nport for ipd_port
+ */
+struct cvmx_cfg_pko_port_pair {
+ int8_t ccppp_base_port;
+ int8_t ccppp_nports;
+};
+
+static CVMX_SHARED struct cvmx_cfg_port_param cvmx_cfg_port
+ [CVMX_HELPER_CFG_MAX_IFACE][CVMX_HELPER_CFG_MAX_PORT_PER_IFACE] =
+ {[0 ... CVMX_HELPER_CFG_MAX_IFACE - 1] =
+ {[0 ... CVMX_HELPER_CFG_MAX_PORT_PER_IFACE - 1] =
+ {CVMX_HELPER_CFG_INVALID_VALUE,
+ CVMX_HELPER_CFG_INVALID_VALUE,
+ CVMX_HELPER_CFG_INVALID_VALUE,
+ CVMX_HELPER_CFG_INVALID_VALUE,
+ CVMX_HELPER_CFG_INVALID_VALUE}}};
+
+/*
+ * Indexed by the pko_port number
+ */
+static CVMX_SHARED struct cvmx_cfg_pko_port_param cvmx_cfg_pko_port
+ [CVMX_HELPER_CFG_MAX_PKO_PORT] =
+ {[0 ... CVMX_HELPER_CFG_MAX_PKO_PORT - 1] =
+ {CVMX_HELPER_CFG_INVALID_VALUE,
+ CVMX_HELPER_CFG_INVALID_VALUE}};
+
+static CVMX_SHARED struct cvmx_cfg_pko_port_map cvmx_cfg_pko_port_map
+ [CVMX_HELPER_CFG_MAX_PKO_PORT] =
+ {[0 ... CVMX_HELPER_CFG_MAX_PKO_PORT - 1] =
+ {CVMX_HELPER_CFG_INVALID_VALUE,
+ CVMX_HELPER_CFG_INVALID_VALUE,
+ CVMX_HELPER_CFG_INVALID_VALUE}};
+
+#ifdef CVMX_ENABLE_PKO_FUNCTIONS
+/*
+ * This array assists translation from ipd_port to pko_port.
+ * The ``16'' is the rounded value for the 3rd 4-bit value of
+ * ipd_port, used to differentiate ``interfaces.''
+ */
+static CVMX_SHARED struct cvmx_cfg_pko_port_pair ipd2pko_port_cache[16]
+ [CVMX_HELPER_CFG_MAX_PORT_PER_IFACE] =
+ {[0 ... 15] =
+ {[0 ... CVMX_HELPER_CFG_MAX_PORT_PER_IFACE - 1] =
+ {CVMX_HELPER_CFG_INVALID_VALUE,
+ CVMX_HELPER_CFG_INVALID_VALUE}}};
+
+#ifdef CVMX_USER_DEFINED_HELPER_CONFIG_INIT
+
+static CVMX_SHARED int cvmx_cfg_default_pko_nqueues = 1;
+
+/*
+ * A pool for holding the pko_nqueues for the pko_ports assigned to a
+ * physical port.
+ */
+static CVMX_SHARED uint8_t cvmx_cfg_pko_nqueue_pool
+ [CVMX_HELPER_CFG_MAX_PKO_QUEUES] =
+ {[0 ... CVMX_HELPER_CFG_MAX_PKO_QUEUES - 1] = 1};
+
+#endif
+#endif
+
+/*
+ * Options
+ *
+ * Each array-elem's intial value is also the option's default value.
+ */
+static CVMX_SHARED uint64_t cvmx_cfg_opts[CVMX_HELPER_CFG_OPT_MAX] =
+ {[0 ... CVMX_HELPER_CFG_OPT_MAX - 1] = 1};
+
+/*
+ * MISC
+ */
+static CVMX_SHARED int cvmx_cfg_max_pko_engines; /* # of PKO DMA engines
+ allocated */
+int __cvmx_helper_cfg_pknd(int interface, int index)
+{
+ return cvmx_cfg_port[interface][index].ccpp_pknd;
+}
+
+int __cvmx_helper_cfg_bpid(int interface, int index)
+{
+ return cvmx_cfg_port[interface][index].ccpp_bpid;
+}
+
+int __cvmx_helper_cfg_pko_port_base(int interface, int index)
+{
+ return cvmx_cfg_port[interface][index].ccpp_pko_port_base;
+}
+
+int __cvmx_helper_cfg_pko_port_num(int interface, int index)
+{
+ return cvmx_cfg_port[interface][index].ccpp_pko_num_ports;
+}
+
+int __cvmx_helper_cfg_pko_queue_num(int pko_port)
+{
+ return cvmx_cfg_pko_port[pko_port].ccppp_num_queues;
+}
+
+int __cvmx_helper_cfg_pko_queue_base(int pko_port)
+{
+ return cvmx_cfg_pko_port[pko_port].ccppp_queue_base;
+}
+
+int __cvmx_helper_cfg_pko_max_queue(void)
+{
+ int i;
+
+ i = CVMX_HELPER_CFG_MAX_PKO_PORT - 1;
+
+ while (i >= 0)
+ {
+ if (cvmx_cfg_pko_port[i].ccppp_queue_base !=
+ CVMX_HELPER_CFG_INVALID_VALUE)
+ {
+ cvmx_helper_cfg_assert(cvmx_cfg_pko_port[i].ccppp_num_queues > 0);
+ return (cvmx_cfg_pko_port[i].ccppp_queue_base +
+ cvmx_cfg_pko_port[i].ccppp_num_queues);
+ }
+ i --;
+ }
+
+ cvmx_helper_cfg_assert(0); /* shouldn't get here */
+
+ return 0;
+}
+
+int __cvmx_helper_cfg_pko_max_engine(void)
+{
+ return cvmx_cfg_max_pko_engines;
+}
+
+int cvmx_helper_cfg_opt_set(cvmx_helper_cfg_option_t opt, uint64_t val)
+{
+ if (opt >= CVMX_HELPER_CFG_OPT_MAX)
+ return -1;
+
+ cvmx_cfg_opts[opt] = val;
+
+ return 0;
+}
+
+uint64_t cvmx_helper_cfg_opt_get(cvmx_helper_cfg_option_t opt)
+{
+ if (opt >= CVMX_HELPER_CFG_OPT_MAX)
+ return (uint64_t)CVMX_HELPER_CFG_INVALID_VALUE;
+
+ return cvmx_cfg_opts[opt];
+}
+
+#ifdef CVMX_BUILD_FOR_LINUX_KERNEL
+EXPORT_SYMBOL(__cvmx_helper_cfg_init);
+EXPORT_SYMBOL(__cvmx_helper_cfg_pknd);
+EXPORT_SYMBOL(__cvmx_helper_cfg_bpid);
+EXPORT_SYMBOL(__cvmx_helper_cfg_pko_port_base);
+EXPORT_SYMBOL(__cvmx_helper_cfg_pko_port_num);
+EXPORT_SYMBOL(__cvmx_helper_cfg_pko_queue_base);
+EXPORT_SYMBOL(__cvmx_helper_cfg_pko_queue_num);
+EXPORT_SYMBOL(__cvmx_helper_cfg_pko_max_queue);
+EXPORT_SYMBOL(__cvmx_helper_cfg_pko_port_interface);
+EXPORT_SYMBOL(__cvmx_helper_cfg_pko_port_index);
+EXPORT_SYMBOL(__cvmx_helper_cfg_pko_port_eid);
+EXPORT_SYMBOL(__cvmx_helper_cfg_pko_max_engine);
+EXPORT_SYMBOL(cvmx_helper_cfg_opt_get);
+EXPORT_SYMBOL(cvmx_helper_cfg_opt_set);
+EXPORT_SYMBOL(cvmx_helper_cfg_ipd2pko_port_base);
+EXPORT_SYMBOL(cvmx_helper_cfg_ipd2pko_port_num);
+#endif
+
+#ifdef CVMX_ENABLE_HELPER_FUNCTIONS
+
+#ifdef CVMX_HELPER_CFG_DEBUG
+void cvmx_helper_cfg_show_cfg(void)
+{
+ int i, j;
+
+ for (i = 0; i < cvmx_helper_get_number_of_interfaces(); i++)
+ {
+ cvmx_dprintf(
+ "cvmx_helper_cfg_show_cfg: interface%d mode %10s nports%4d\n", i,
+ cvmx_helper_interface_mode_to_string(cvmx_helper_interface_get_mode(i)),
+ cvmx_helper_interface_enumerate(i));
+
+ for (j = 0; j < cvmx_helper_interface_enumerate(i); j++)
+ {
+ cvmx_dprintf("\tpknd[%i][%d]%d", i, j,
+ __cvmx_helper_cfg_pknd(i, j));
+ cvmx_dprintf(" pko_port_base[%i][%d]%d", i, j,
+ __cvmx_helper_cfg_pko_port_base(i, j));
+ cvmx_dprintf(" pko_port_num[%i][%d]%d\n", i, j,
+ __cvmx_helper_cfg_pko_port_num(i, j));
+ }
+ }
+
+ for (i = 0; i < CVMX_HELPER_CFG_MAX_PKO_PORT; i++)
+ {
+ if (__cvmx_helper_cfg_pko_queue_base(i) !=
+ CVMX_HELPER_CFG_INVALID_VALUE)
+ {
+ cvmx_dprintf("cvmx_helper_cfg_show_cfg: pko_port%d qbase%d nqueues%d "
+ "interface%d index%d\n", i,
+ __cvmx_helper_cfg_pko_queue_base(i),
+ __cvmx_helper_cfg_pko_queue_num(i),
+ __cvmx_helper_cfg_pko_port_interface(i),
+ __cvmx_helper_cfg_pko_port_index(i));
+ }
+ }
+}
+#endif
+
+/*
+ * initialize cvmx_cfg_pko_port_map
+ */
+static void cvmx_helper_cfg_init_pko_port_map(void)
+{
+ int i, j, k;
+ int pko_eid;
+ int pko_port_base, pko_port_max;
+ cvmx_helper_interface_mode_t mode;
+
+ /*
+ * one pko_eid is allocated to each port except for ILK, NPI, and
+ * LOOP. Each of the three has one eid.
+ */
+ pko_eid = 0;
+ for (i = 0; i < cvmx_helper_get_number_of_interfaces(); i++)
+ {
+ mode = cvmx_helper_interface_get_mode(i);
+ for (j = 0; j < cvmx_helper_interface_enumerate(i); j++)
+ {
+ pko_port_base = cvmx_cfg_port[i][j].ccpp_pko_port_base;
+ pko_port_max = pko_port_base +
+ cvmx_cfg_port[i][j].ccpp_pko_num_ports;
+ cvmx_helper_cfg_assert(pko_port_base !=
+ CVMX_HELPER_CFG_INVALID_VALUE);
+ cvmx_helper_cfg_assert(pko_port_max >= pko_port_base);
+ for (k = pko_port_base; k < pko_port_max; k++)
+ {
+ cvmx_cfg_pko_port_map[k].ccppl_interface = i;
+ cvmx_cfg_pko_port_map[k].ccppl_index = j;
+ cvmx_cfg_pko_port_map[k].ccppl_eid = pko_eid;
+ }
+
+#if 0
+ /*
+ * For a physical port that is not configured a PKO port,
+ * pko_port_base here equals to pko_port_max. In this
+ * case, the physical port does not take a DMA engine.
+ */
+ if (pko_port_base > pko_port_max)
+#endif
+ if (!(mode == CVMX_HELPER_INTERFACE_MODE_NPI ||
+ mode == CVMX_HELPER_INTERFACE_MODE_LOOP ||
+ mode == CVMX_HELPER_INTERFACE_MODE_ILK))
+ pko_eid ++;
+ }
+
+ if (mode == CVMX_HELPER_INTERFACE_MODE_NPI ||
+ mode == CVMX_HELPER_INTERFACE_MODE_LOOP ||
+ mode == CVMX_HELPER_INTERFACE_MODE_ILK)
+ pko_eid ++;
+ }
+
+ /*
+ * Legal pko_eids [0, 0x13] should not be exhausted.
+ */
+ cvmx_helper_cfg_assert(pko_eid <= 0x14);
+
+ cvmx_cfg_max_pko_engines = pko_eid;
+}
+#endif
+
+int __cvmx_helper_cfg_pko_port_interface(int pko_port)
+{
+ return cvmx_cfg_pko_port_map[pko_port].ccppl_interface;
+}
+
+int __cvmx_helper_cfg_pko_port_index(int pko_port)
+{
+ return cvmx_cfg_pko_port_map[pko_port].ccppl_index;
+}
+
+int __cvmx_helper_cfg_pko_port_eid(int pko_port)
+{
+ return cvmx_cfg_pko_port_map[pko_port].ccppl_eid;
+}
+
+/**
+ * Perform common init tasks for all chips.
+ * @return 1 for the caller to continue init and 0 otherwise.
+ *
+ * Note: ``common'' means this function is executed regardless of
+ * - chip, and
+ * - CVMX_ENABLE_HELPER_FUNCTIONS.
+ *
+ * This function decides based on these conditions if the
+ * configuration stage of the init process should continue.
+ *
+ * This is only meant to be called by __cvmx_helper_cfg_init().
+ */
+static int __cvmx_helper_cfg_init_common(void)
+{
+ int val;
+
+#ifndef CVMX_ENABLE_HELPER_FUNCTIONS
+ val = 0;
+#else
+ val = (octeon_has_feature(OCTEON_FEATURE_PKND));
+#endif
+
+ return val;
+}
+
+#define IPD2PKO_CACHE_Y(ipd_port) (ipd_port) >> 8
+#define IPD2PKO_CACHE_X(ipd_port) (ipd_port) & 0xff
+
+#ifdef CVMX_ENABLE_PKO_FUNCTIONS
+/*
+ * ipd_port to pko_port translation cache
+ */
+static int __cvmx_helper_cfg_init_ipd2pko_cache(void)
+{
+ int i, j, n;
+ int ipd_y, ipd_x, ipd_port;
+
+ for (i = 0; i < cvmx_helper_get_number_of_interfaces(); i++)
+ {
+ n = cvmx_helper_interface_enumerate(i);
+
+ for (j = 0; j < n; j++)
+ {
+ ipd_port = cvmx_helper_get_ipd_port(i, j);
+ ipd_y = IPD2PKO_CACHE_Y(ipd_port);
+ ipd_x = IPD2PKO_CACHE_X(ipd_port);
+ ipd2pko_port_cache[ipd_y]
+ [(ipd_port & 0x800) ? ((ipd_x >> 4) & 3) : ipd_x] =
+ (struct cvmx_cfg_pko_port_pair)
+ {__cvmx_helper_cfg_pko_port_base(i, j),
+ __cvmx_helper_cfg_pko_port_num(i, j)};
+ }
+ }
+
+ return 0;
+}
+
+int cvmx_helper_cfg_ipd2pko_port_base(int ipd_port)
+{
+ int ipd_y, ipd_x;
+
+ ipd_y = IPD2PKO_CACHE_Y(ipd_port);
+ ipd_x = IPD2PKO_CACHE_X(ipd_port);
+
+ return ipd2pko_port_cache[ipd_y]
+ [(ipd_port & 0x800) ? ((ipd_x >> 4) & 3) : ipd_x].ccppp_base_port;
+}
+
+int cvmx_helper_cfg_ipd2pko_port_num(int ipd_port)
+{
+ int ipd_y, ipd_x;
+
+ ipd_y = IPD2PKO_CACHE_Y(ipd_port);
+ ipd_x = IPD2PKO_CACHE_X(ipd_port);
+
+ return ipd2pko_port_cache[ipd_y]
+ [(ipd_port & 0x800) ? ((ipd_x >> 4) & 3) : ipd_x].ccppp_nports;
+}
+#endif
+
+#ifdef CVMX_ENABLE_HELPER_FUNCTIONS
+#ifdef CVMX_USER_DEFINED_HELPER_CONFIG_INIT
+/**
+ * Return the number of queues assigned to this pko_port by user
+ *
+ * @param pko_port
+ * @return the number of queues for this pko_port
+ *
+ * Note: Called after the pko_port map is set up.
+ */
+static int __cvmx_ucfg_nqueues(int pko_port)
+{
+ int interface, index;
+ int i, k;
+
+ interface = __cvmx_helper_cfg_pko_port_interface(pko_port);
+ index = __cvmx_helper_cfg_pko_port_index(pko_port);
+
+ /*
+ * pko_port belongs to no physical port,
+ * don't assign a queue to it.
+ */
+ if (interface == CVMX_HELPER_CFG_INVALID_VALUE ||
+ index == CVMX_HELPER_CFG_INVALID_VALUE)
+ return 0;
+
+ /*
+ * Assign the default number of queues to those pko_ports not
+ * assigned explicitly.
+ */
+ i = cvmx_cfg_port[interface][index].ccpp_pko_nqueues;
+ if (i == (uint8_t)CVMX_HELPER_CFG_INVALID_VALUE)
+ return cvmx_cfg_default_pko_nqueues;
+
+ /*
+ * The user has assigned nqueues to this pko_port,
+ * recorded in the pool.
+ */
+ k = pko_port - cvmx_cfg_port[interface][index].ccpp_pko_port_base;
+ cvmx_helper_cfg_assert(k <
+ cvmx_cfg_port[interface][index].ccpp_pko_num_ports);
+ return cvmx_cfg_pko_nqueue_pool[i + k];
+}
+
+#else
+
+/**
+ * Return the number of queues to be assigned to this pko_port
+ *
+ * @param pko_port
+ * @return the number of queues for this pko_port
+ *
+ * Note: This function exists for backward compatibility.
+ * CVMX_PKO_QUEUES_PER_PORT_XXXX defines no of queues per HW port.
+ * pko_port is equivalent in pre-o68 SDK.
+ */
+static int cvmx_helper_cfg_dft_nqueues(int pko_port)
+{
+ cvmx_helper_interface_mode_t mode;
+ int interface;
+ int n;
+
+#ifndef CVMX_HELPER_PKO_QUEUES_PER_PORT_INTERFACE0
+#define CVMX_HELPER_PKO_QUEUES_PER_PORT_INTERFACE0 1
+#endif
+
+#ifndef CVMX_HELPER_PKO_QUEUES_PER_PORT_INTERFACE1
+#define CVMX_HELPER_PKO_QUEUES_PER_PORT_INTERFACE1 1
+#endif
+
+#ifndef CVMX_HELPER_PKO_QUEUES_PER_PORT_INTERFACE2
+#define CVMX_HELPER_PKO_QUEUES_PER_PORT_INTERFACE2 1
+#endif
+
+#ifndef CVMX_HELPER_PKO_QUEUES_PER_PORT_INTERFACE3
+#define CVMX_HELPER_PKO_QUEUES_PER_PORT_INTERFACE3 1
+#endif
+
+#ifndef CVMX_HELPER_PKO_QUEUES_PER_PORT_INTERFACE4
+#define CVMX_HELPER_PKO_QUEUES_PER_PORT_INTERFACE4 1
+#endif
+
+ n = 1;
+ interface = __cvmx_helper_cfg_pko_port_interface(pko_port);
+ if (interface == 0)
+ {
+#ifdef CVMX_PKO_QUEUES_PER_PORT_INTERFACE0
+ n = CVMX_PKO_QUEUES_PER_PORT_INTERFACE0;
+#endif
+ }
+ if (interface == 1)
+ {
+#ifdef CVMX_PKO_QUEUES_PER_PORT_INTERFACE1
+ n = CVMX_PKO_QUEUES_PER_PORT_INTERFACE1;
+#endif
+ }
+
+ if (interface == 2)
+ {
+#ifdef CVMX_PKO_QUEUES_PER_PORT_INTERFACE2
+ n = CVMX_PKO_QUEUES_PER_PORT_INTERFACE2;
+#endif
+ }
+ if (interface == 3)
+ {
+#ifdef CVMX_PKO_QUEUES_PER_PORT_INTERFACE3
+ n = CVMX_PKO_QUEUES_PER_PORT_INTERFACE3;
+#endif
+ }
+ if (interface == 4)
+ {
+#ifdef CVMX_PKO_QUEUES_PER_PORT_INTERFACE4
+ n = CVMX_PKO_QUEUES_PER_PORT_INTERFACE4;
+#endif
+ }
+
+ mode = cvmx_helper_interface_get_mode(interface);
+ if (mode == CVMX_HELPER_INTERFACE_MODE_LOOP)
+ {
+#ifdef CVMX_PKO_QUEUES_PER_PORT_LOOP
+ n = CVMX_PKO_QUEUES_PER_PORT_LOOP;
+#endif
+ }
+ if (mode == CVMX_HELPER_INTERFACE_MODE_NPI)
+ {
+#ifdef CVMX_PKO_QUEUES_PER_PORT_PCI
+ n = CVMX_PKO_QUEUES_PER_PORT_PCI;
+#endif
+ }
+
+ return n;
+}
+#endif /* CVMX_USER_DEFINED_HELPER_CONFIG_INIT */
+#endif /* CVMX_ENABLE_HELPER_FUNCTIONS */
+
+int __cvmx_helper_cfg_init(void)
+{
+#ifdef CVMX_ENABLE_HELPER_FUNCTIONS
+ struct cvmx_cfg_port_param *pport;
+ int cvmx_cfg_default_pko_nports;
+ int pknd, bpid, pko_port_base;
+ int qbase;
+ int i, j, n;
+
+ cvmx_cfg_default_pko_nports = 1;
+#endif
+
+ if (!__cvmx_helper_cfg_init_common())
+ return 0;
+
+#ifdef CVMX_ENABLE_HELPER_FUNCTIONS
+
+#ifdef CVMX_USER_DEFINED_HELPER_CONFIG_INIT
+{
+ int cvmx_ucfg_nq;
+ cvmx_ucfg_nq = 0;
+#include "cvmx-helper-cfg-init.c"
+}
+#endif
+
+ /*
+ * per-port parameters
+ */
+ pknd = 0;
+ bpid = 0;
+ pko_port_base = 0;
+
+ for (i = 0; i < cvmx_helper_get_number_of_interfaces(); i++)
+ {
+ n = cvmx_helper_interface_enumerate(i);
+
+ pport = cvmx_cfg_port[i];
+ for (j = 0; j < n; j++, pport++)
+ {
+ int t;
+
+ t = cvmx_cfg_default_pko_nports;
+ if (pport->ccpp_pko_num_ports != CVMX_HELPER_CFG_INVALID_VALUE)
+ t = pport->ccpp_pko_num_ports;
+
+ *pport = (struct cvmx_cfg_port_param) {
+ pknd++,
+ bpid++,
+ pko_port_base,
+ t,
+ pport->ccpp_pko_nqueues};
+ pko_port_base += t;
+ }
+ }
+
+ cvmx_helper_cfg_assert(pknd <= CVMX_HELPER_CFG_MAX_PIP_PKND);
+ cvmx_helper_cfg_assert(bpid <= CVMX_HELPER_CFG_MAX_PIP_BPID);
+ cvmx_helper_cfg_assert(pko_port_base <= CVMX_HELPER_CFG_MAX_PKO_PORT);
+
+ /*
+ * pko_port map
+ */
+ cvmx_helper_cfg_init_pko_port_map();
+
+ /*
+ * per-pko_port parameters
+ */
+ qbase = 0;
+ for (i = 0; i < pko_port_base; i++)
+ {
+#ifdef CVMX_USER_DEFINED_HELPER_CONFIG_INIT
+ n = __cvmx_ucfg_nqueues(i);
+#else
+ n = cvmx_helper_cfg_dft_nqueues(i);
+#endif
+ cvmx_cfg_pko_port[i] = (struct cvmx_cfg_pko_port_param) {qbase, n};
+ qbase += n;
+ cvmx_helper_cfg_assert(qbase <= CVMX_HELPER_CFG_MAX_PKO_QUEUES);
+ }
+
+#ifdef CVMX_ENABLE_PKO_FUNCTIONS
+ __cvmx_helper_cfg_init_ipd2pko_cache();
+#endif
+
+#ifdef CVMX_HELPER_CFG_DEBUG
+ cvmx_helper_cfg_show_cfg();
+#endif /* CVMX_HELPER_CFG_DEBUG */
+#endif
+ return 0;
+}