net/octeontx: add net device probe and remove
An octeontx ethdev device consists of multiple PKO VF devices, a PKI VF device and multiple SSOVF devices which shared between eventdev. This patch adds a vdev based device called "eth_octeontx" which will create multiple ethernet ports based on "nr_port" or maximum physical ports are available in the system. Signed-off-by: Jerin Jacob <jerin.jacob@caviumnetworks.com> Signed-off-by: Santosh Shukla <santosh.shukla@caviumnetworks.com>
This commit is contained in:
parent
3813a10af5
commit
f7be70e513
@ -53,6 +53,7 @@ VPATH += $(SRCDIR)/base
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_OCTEONTX_PMD) += octeontx_pkovf.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_OCTEONTX_PMD) += octeontx_pkivf.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_OCTEONTX_PMD) += octeontx_bgx.c
|
||||
SRCS-$(CONFIG_RTE_LIBRTE_OCTEONTX_PMD) += octeontx_ethdev.c
|
||||
|
||||
LDLIBS += -lrte_eventdev
|
||||
LDLIBS += -lrte_pmd_octeontx_ssovf
|
||||
|
323
drivers/net/octeontx/octeontx_ethdev.c
Normal file
323
drivers/net/octeontx/octeontx_ethdev.c
Normal file
@ -0,0 +1,323 @@
|
||||
/*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright (C) Cavium Inc. 2017. 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 networks 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 IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <rte_alarm.h>
|
||||
#include <rte_branch_prediction.h>
|
||||
#include <rte_debug.h>
|
||||
#include <rte_devargs.h>
|
||||
#include <rte_dev.h>
|
||||
#include <rte_kvargs.h>
|
||||
#include <rte_malloc.h>
|
||||
#include <rte_prefetch.h>
|
||||
#include <rte_vdev.h>
|
||||
|
||||
#include "octeontx_ethdev.h"
|
||||
#include "octeontx_logs.h"
|
||||
|
||||
struct octeontx_vdev_init_params {
|
||||
uint8_t nr_port;
|
||||
};
|
||||
|
||||
/* Parse integer from integer argument */
|
||||
static int
|
||||
parse_integer_arg(const char *key __rte_unused,
|
||||
const char *value, void *extra_args)
|
||||
{
|
||||
int *i = (int *)extra_args;
|
||||
|
||||
*i = atoi(value);
|
||||
if (*i < 0) {
|
||||
octeontx_log_err("argument has to be positive.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
octeontx_parse_vdev_init_params(struct octeontx_vdev_init_params *params,
|
||||
struct rte_vdev_device *dev)
|
||||
{
|
||||
struct rte_kvargs *kvlist = NULL;
|
||||
int ret = 0;
|
||||
|
||||
static const char * const octeontx_vdev_valid_params[] = {
|
||||
OCTEONTX_VDEV_NR_PORT_ARG,
|
||||
NULL
|
||||
};
|
||||
|
||||
const char *input_args = rte_vdev_device_args(dev);
|
||||
if (params == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
if (input_args) {
|
||||
kvlist = rte_kvargs_parse(input_args,
|
||||
octeontx_vdev_valid_params);
|
||||
if (kvlist == NULL)
|
||||
return -1;
|
||||
|
||||
ret = rte_kvargs_process(kvlist,
|
||||
OCTEONTX_VDEV_NR_PORT_ARG,
|
||||
&parse_integer_arg,
|
||||
¶ms->nr_port);
|
||||
if (ret < 0)
|
||||
goto free_kvlist;
|
||||
}
|
||||
|
||||
free_kvlist:
|
||||
rte_kvargs_free(kvlist);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void
|
||||
devconf_set_default_sane_values(struct rte_event_dev_config *dev_conf,
|
||||
struct rte_event_dev_info *info)
|
||||
{
|
||||
memset(dev_conf, 0, sizeof(struct rte_event_dev_config));
|
||||
dev_conf->dequeue_timeout_ns = info->min_dequeue_timeout_ns;
|
||||
|
||||
dev_conf->nb_event_ports = info->max_event_ports;
|
||||
dev_conf->nb_event_queues = info->max_event_queues;
|
||||
|
||||
dev_conf->nb_event_queue_flows = info->max_event_queue_flows;
|
||||
dev_conf->nb_event_port_dequeue_depth =
|
||||
info->max_event_port_dequeue_depth;
|
||||
dev_conf->nb_event_port_enqueue_depth =
|
||||
info->max_event_port_enqueue_depth;
|
||||
dev_conf->nb_event_port_enqueue_depth =
|
||||
info->max_event_port_enqueue_depth;
|
||||
dev_conf->nb_events_limit =
|
||||
info->max_num_events;
|
||||
}
|
||||
|
||||
/* Create Ethdev interface per BGX LMAC ports */
|
||||
static int
|
||||
octeontx_create(struct rte_vdev_device *dev, int port, uint8_t evdev,
|
||||
int socket_id)
|
||||
{
|
||||
RTE_SET_USED(dev);
|
||||
RTE_SET_USED(port);
|
||||
RTE_SET_USED(evdev);
|
||||
RTE_SET_USED(socket_id);
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Un initialize octeontx device */
|
||||
static int
|
||||
octeontx_remove(struct rte_vdev_device *dev)
|
||||
{
|
||||
char octtx_name[OCTEONTX_MAX_NAME_LEN];
|
||||
struct rte_eth_dev *eth_dev = NULL;
|
||||
struct octeontx_nic *nic = NULL;
|
||||
int i;
|
||||
|
||||
if (dev == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < OCTEONTX_VDEV_DEFAULT_MAX_NR_PORT; i++) {
|
||||
sprintf(octtx_name, "eth_octeontx_%d", i);
|
||||
|
||||
/* reserve an ethdev entry */
|
||||
eth_dev = rte_eth_dev_allocated(octtx_name);
|
||||
if (eth_dev == NULL)
|
||||
return -ENODEV;
|
||||
|
||||
nic = octeontx_pmd_priv(eth_dev);
|
||||
rte_event_dev_stop(nic->evdev);
|
||||
PMD_INIT_LOG(INFO, "Closing octeontx device %s", octtx_name);
|
||||
|
||||
rte_free(eth_dev->data->mac_addrs);
|
||||
rte_free(eth_dev->data->dev_private);
|
||||
rte_free(eth_dev->data);
|
||||
rte_eth_dev_release_port(eth_dev);
|
||||
rte_event_dev_close(nic->evdev);
|
||||
}
|
||||
|
||||
/* Free FC resource */
|
||||
octeontx_pko_fc_free();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Initialize octeontx device */
|
||||
static int
|
||||
octeontx_probe(struct rte_vdev_device *dev)
|
||||
{
|
||||
const char *dev_name;
|
||||
static int probe_once;
|
||||
uint8_t socket_id, qlist;
|
||||
int tx_vfcnt, port_id, evdev, qnum, pnum, res, i;
|
||||
struct rte_event_dev_config dev_conf;
|
||||
const char *eventdev_name = "event_octeontx";
|
||||
struct rte_event_dev_info info;
|
||||
|
||||
struct octeontx_vdev_init_params init_params = {
|
||||
OCTEONTX_VDEV_DEFAULT_MAX_NR_PORT
|
||||
};
|
||||
|
||||
dev_name = rte_vdev_device_name(dev);
|
||||
res = octeontx_parse_vdev_init_params(&init_params, dev);
|
||||
if (res < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (init_params.nr_port > OCTEONTX_VDEV_DEFAULT_MAX_NR_PORT) {
|
||||
octeontx_log_err("nr_port (%d) > max (%d)", init_params.nr_port,
|
||||
OCTEONTX_VDEV_DEFAULT_MAX_NR_PORT);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
PMD_INIT_LOG(DEBUG, "initializing %s pmd", dev_name);
|
||||
|
||||
socket_id = rte_socket_id();
|
||||
|
||||
tx_vfcnt = octeontx_pko_vf_count();
|
||||
|
||||
if (tx_vfcnt < init_params.nr_port) {
|
||||
octeontx_log_err("not enough PKO (%d) for port number (%d)",
|
||||
tx_vfcnt, init_params.nr_port);
|
||||
return -EINVAL;
|
||||
}
|
||||
evdev = rte_event_dev_get_dev_id(eventdev_name);
|
||||
if (evdev < 0) {
|
||||
octeontx_log_err("eventdev %s not found", eventdev_name);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
res = rte_event_dev_info_get(evdev, &info);
|
||||
if (res < 0) {
|
||||
octeontx_log_err("failed to eventdev info %d", res);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
PMD_INIT_LOG(DEBUG, "max_queue %d max_port %d",
|
||||
info.max_event_queues, info.max_event_ports);
|
||||
|
||||
if (octeontx_pko_init_fc(tx_vfcnt))
|
||||
return -ENOMEM;
|
||||
|
||||
devconf_set_default_sane_values(&dev_conf, &info);
|
||||
res = rte_event_dev_configure(evdev, &dev_conf);
|
||||
if (res < 0)
|
||||
goto parse_error;
|
||||
|
||||
rte_event_dev_attr_get(evdev, RTE_EVENT_DEV_ATTR_PORT_COUNT,
|
||||
(uint32_t *)&pnum);
|
||||
rte_event_dev_attr_get(evdev, RTE_EVENT_DEV_ATTR_QUEUE_COUNT,
|
||||
(uint32_t *)&qnum);
|
||||
if (pnum < qnum) {
|
||||
octeontx_log_err("too few event ports (%d) for event_q(%d)",
|
||||
pnum, qnum);
|
||||
res = -EINVAL;
|
||||
goto parse_error;
|
||||
}
|
||||
if (pnum > qnum) {
|
||||
/*
|
||||
* We don't poll on event ports
|
||||
* that do not have any queues assigned.
|
||||
*/
|
||||
pnum = qnum;
|
||||
PMD_INIT_LOG(INFO,
|
||||
"reducing number of active event ports to %d", pnum);
|
||||
}
|
||||
for (i = 0; i < qnum; i++) {
|
||||
res = rte_event_queue_setup(evdev, i, NULL);
|
||||
if (res < 0) {
|
||||
octeontx_log_err("failed to setup event_q(%d): res %d",
|
||||
i, res);
|
||||
goto parse_error;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < pnum; i++) {
|
||||
res = rte_event_port_setup(evdev, i, NULL);
|
||||
if (res < 0) {
|
||||
res = -ENODEV;
|
||||
octeontx_log_err("failed to setup ev port(%d) res=%d",
|
||||
i, res);
|
||||
goto parse_error;
|
||||
}
|
||||
/* Link one queue to one event port */
|
||||
qlist = i;
|
||||
res = rte_event_port_link(evdev, i, &qlist, NULL, 1);
|
||||
if (res < 0) {
|
||||
res = -ENODEV;
|
||||
octeontx_log_err("failed to link port (%d): res=%d",
|
||||
i, res);
|
||||
goto parse_error;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create ethdev interface */
|
||||
for (i = 0; i < init_params.nr_port; i++) {
|
||||
port_id = octeontx_create(dev, i, evdev, socket_id);
|
||||
if (port_id < 0) {
|
||||
octeontx_log_err("failed to create device %s",
|
||||
dev_name);
|
||||
res = -ENODEV;
|
||||
goto parse_error;
|
||||
}
|
||||
|
||||
PMD_INIT_LOG(INFO, "created ethdev %s for port %d", dev_name,
|
||||
port_id);
|
||||
}
|
||||
|
||||
if (probe_once) {
|
||||
octeontx_log_err("interface %s not supported", dev_name);
|
||||
octeontx_remove(dev);
|
||||
res = -ENOTSUP;
|
||||
goto parse_error;
|
||||
}
|
||||
probe_once = 1;
|
||||
|
||||
return 0;
|
||||
|
||||
parse_error:
|
||||
octeontx_pko_fc_free();
|
||||
return res;
|
||||
}
|
||||
|
||||
static struct rte_vdev_driver octeontx_pmd_drv = {
|
||||
.probe = octeontx_probe,
|
||||
.remove = octeontx_remove,
|
||||
};
|
||||
|
||||
RTE_PMD_REGISTER_VDEV(OCTEONTX_PMD, octeontx_pmd_drv);
|
||||
RTE_PMD_REGISTER_ALIAS(OCTEONTX_PMD, eth_octeontx);
|
||||
RTE_PMD_REGISTER_PARAM_STRING(OCTEONTX_PMD, "nr_port=<int> ");
|
94
drivers/net/octeontx/octeontx_ethdev.h
Normal file
94
drivers/net/octeontx/octeontx_ethdev.h
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright (C) Cavium Inc. 2017. 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 networks 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 IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef __OCTEONTX_ETHDEV_H__
|
||||
#define __OCTEONTX_ETHDEV_H__
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <rte_common.h>
|
||||
#include <rte_ethdev.h>
|
||||
#include <rte_eventdev.h>
|
||||
#include <rte_mempool.h>
|
||||
#include <rte_memory.h>
|
||||
|
||||
#include <octeontx_fpavf.h>
|
||||
|
||||
#include "base/octeontx_bgx.h"
|
||||
#include "base/octeontx_pki_var.h"
|
||||
#include "base/octeontx_pkivf.h"
|
||||
#include "base/octeontx_pkovf.h"
|
||||
#include "base/octeontx_io.h"
|
||||
|
||||
#define OCTEONTX_VDEV_DEFAULT_MAX_NR_PORT 12
|
||||
#define OCTEONTX_VDEV_NR_PORT_ARG ("nr_port")
|
||||
#define OCTEONTX_MAX_NAME_LEN 32
|
||||
|
||||
static inline struct octeontx_nic *
|
||||
octeontx_pmd_priv(struct rte_eth_dev *dev)
|
||||
{
|
||||
return dev->data->dev_private;
|
||||
}
|
||||
|
||||
/* Octeontx ethdev nic */
|
||||
struct octeontx_nic {
|
||||
struct rte_eth_dev *dev;
|
||||
int node;
|
||||
int port_id;
|
||||
int port_ena;
|
||||
int base_ichan;
|
||||
int num_ichans;
|
||||
int base_ochan;
|
||||
int num_ochans;
|
||||
uint8_t evdev;
|
||||
uint8_t bpen;
|
||||
uint8_t fcs_strip;
|
||||
uint8_t bcast_mode;
|
||||
uint8_t mcast_mode;
|
||||
uint16_t num_tx_queues;
|
||||
uint64_t hwcap;
|
||||
uint8_t link_up;
|
||||
uint8_t duplex;
|
||||
uint8_t speed;
|
||||
uint16_t mtu;
|
||||
uint8_t mac_addr[ETHER_ADDR_LEN];
|
||||
/* Rx port parameters */
|
||||
struct {
|
||||
bool classifier_enable;
|
||||
bool hash_enable;
|
||||
bool initialized;
|
||||
} pki;
|
||||
|
||||
uint16_t ev_queues;
|
||||
uint16_t ev_ports;
|
||||
} __rte_cache_aligned;
|
||||
|
||||
#endif /* __OCTEONTX_ETHDEV_H__ */
|
Loading…
x
Reference in New Issue
Block a user