4 * Copyright (C) Cavium Inc. 2017. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
16 * * Neither the name of Cavium networks nor the names of its
17 * contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 #include <rte_alarm.h>
40 #include <rte_branch_prediction.h>
41 #include <rte_debug.h>
42 #include <rte_devargs.h>
44 #include <rte_kvargs.h>
45 #include <rte_malloc.h>
46 #include <rte_prefetch.h>
49 #include "octeontx_ethdev.h"
50 #include "octeontx_logs.h"
52 struct octeontx_vdev_init_params {
56 /* Parse integer from integer argument */
58 parse_integer_arg(const char *key __rte_unused,
59 const char *value, void *extra_args)
61 int *i = (int *)extra_args;
65 octeontx_log_err("argument has to be positive.");
73 octeontx_parse_vdev_init_params(struct octeontx_vdev_init_params *params,
74 struct rte_vdev_device *dev)
76 struct rte_kvargs *kvlist = NULL;
79 static const char * const octeontx_vdev_valid_params[] = {
80 OCTEONTX_VDEV_NR_PORT_ARG,
84 const char *input_args = rte_vdev_device_args(dev);
90 kvlist = rte_kvargs_parse(input_args,
91 octeontx_vdev_valid_params);
95 ret = rte_kvargs_process(kvlist,
96 OCTEONTX_VDEV_NR_PORT_ARG,
104 rte_kvargs_free(kvlist);
109 devconf_set_default_sane_values(struct rte_event_dev_config *dev_conf,
110 struct rte_event_dev_info *info)
112 memset(dev_conf, 0, sizeof(struct rte_event_dev_config));
113 dev_conf->dequeue_timeout_ns = info->min_dequeue_timeout_ns;
115 dev_conf->nb_event_ports = info->max_event_ports;
116 dev_conf->nb_event_queues = info->max_event_queues;
118 dev_conf->nb_event_queue_flows = info->max_event_queue_flows;
119 dev_conf->nb_event_port_dequeue_depth =
120 info->max_event_port_dequeue_depth;
121 dev_conf->nb_event_port_enqueue_depth =
122 info->max_event_port_enqueue_depth;
123 dev_conf->nb_event_port_enqueue_depth =
124 info->max_event_port_enqueue_depth;
125 dev_conf->nb_events_limit =
126 info->max_num_events;
129 /* Create Ethdev interface per BGX LMAC ports */
131 octeontx_create(struct rte_vdev_device *dev, int port, uint8_t evdev,
137 RTE_SET_USED(socket_id);
142 /* Un initialize octeontx device */
144 octeontx_remove(struct rte_vdev_device *dev)
146 char octtx_name[OCTEONTX_MAX_NAME_LEN];
147 struct rte_eth_dev *eth_dev = NULL;
148 struct octeontx_nic *nic = NULL;
154 for (i = 0; i < OCTEONTX_VDEV_DEFAULT_MAX_NR_PORT; i++) {
155 sprintf(octtx_name, "eth_octeontx_%d", i);
157 /* reserve an ethdev entry */
158 eth_dev = rte_eth_dev_allocated(octtx_name);
162 nic = octeontx_pmd_priv(eth_dev);
163 rte_event_dev_stop(nic->evdev);
164 PMD_INIT_LOG(INFO, "Closing octeontx device %s", octtx_name);
166 rte_free(eth_dev->data->mac_addrs);
167 rte_free(eth_dev->data->dev_private);
168 rte_free(eth_dev->data);
169 rte_eth_dev_release_port(eth_dev);
170 rte_event_dev_close(nic->evdev);
173 /* Free FC resource */
174 octeontx_pko_fc_free();
179 /* Initialize octeontx device */
181 octeontx_probe(struct rte_vdev_device *dev)
183 const char *dev_name;
184 static int probe_once;
185 uint8_t socket_id, qlist;
186 int tx_vfcnt, port_id, evdev, qnum, pnum, res, i;
187 struct rte_event_dev_config dev_conf;
188 const char *eventdev_name = "event_octeontx";
189 struct rte_event_dev_info info;
191 struct octeontx_vdev_init_params init_params = {
192 OCTEONTX_VDEV_DEFAULT_MAX_NR_PORT
195 dev_name = rte_vdev_device_name(dev);
196 res = octeontx_parse_vdev_init_params(&init_params, dev);
200 if (init_params.nr_port > OCTEONTX_VDEV_DEFAULT_MAX_NR_PORT) {
201 octeontx_log_err("nr_port (%d) > max (%d)", init_params.nr_port,
202 OCTEONTX_VDEV_DEFAULT_MAX_NR_PORT);
206 PMD_INIT_LOG(DEBUG, "initializing %s pmd", dev_name);
208 socket_id = rte_socket_id();
210 tx_vfcnt = octeontx_pko_vf_count();
212 if (tx_vfcnt < init_params.nr_port) {
213 octeontx_log_err("not enough PKO (%d) for port number (%d)",
214 tx_vfcnt, init_params.nr_port);
217 evdev = rte_event_dev_get_dev_id(eventdev_name);
219 octeontx_log_err("eventdev %s not found", eventdev_name);
223 res = rte_event_dev_info_get(evdev, &info);
225 octeontx_log_err("failed to eventdev info %d", res);
229 PMD_INIT_LOG(DEBUG, "max_queue %d max_port %d",
230 info.max_event_queues, info.max_event_ports);
232 if (octeontx_pko_init_fc(tx_vfcnt))
235 devconf_set_default_sane_values(&dev_conf, &info);
236 res = rte_event_dev_configure(evdev, &dev_conf);
240 rte_event_dev_attr_get(evdev, RTE_EVENT_DEV_ATTR_PORT_COUNT,
242 rte_event_dev_attr_get(evdev, RTE_EVENT_DEV_ATTR_QUEUE_COUNT,
245 octeontx_log_err("too few event ports (%d) for event_q(%d)",
252 * We don't poll on event ports
253 * that do not have any queues assigned.
257 "reducing number of active event ports to %d", pnum);
259 for (i = 0; i < qnum; i++) {
260 res = rte_event_queue_setup(evdev, i, NULL);
262 octeontx_log_err("failed to setup event_q(%d): res %d",
268 for (i = 0; i < pnum; i++) {
269 res = rte_event_port_setup(evdev, i, NULL);
272 octeontx_log_err("failed to setup ev port(%d) res=%d",
276 /* Link one queue to one event port */
278 res = rte_event_port_link(evdev, i, &qlist, NULL, 1);
281 octeontx_log_err("failed to link port (%d): res=%d",
287 /* Create ethdev interface */
288 for (i = 0; i < init_params.nr_port; i++) {
289 port_id = octeontx_create(dev, i, evdev, socket_id);
291 octeontx_log_err("failed to create device %s",
297 PMD_INIT_LOG(INFO, "created ethdev %s for port %d", dev_name,
302 octeontx_log_err("interface %s not supported", dev_name);
303 octeontx_remove(dev);
312 octeontx_pko_fc_free();
316 static struct rte_vdev_driver octeontx_pmd_drv = {
317 .probe = octeontx_probe,
318 .remove = octeontx_remove,
321 RTE_PMD_REGISTER_VDEV(OCTEONTX_PMD, octeontx_pmd_drv);
322 RTE_PMD_REGISTER_ALIAS(OCTEONTX_PMD, eth_octeontx);
323 RTE_PMD_REGISTER_PARAM_STRING(OCTEONTX_PMD, "nr_port=<int> ");