net/bnxt: fail init when mbuf allocation fails
[dpdk.git] / drivers / net / softnic / rte_eth_softnic.c
index 0fd264e..8c098ca 100644 (file)
@@ -6,8 +6,8 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include <rte_ethdev_driver.h>
-#include <rte_ethdev_vdev.h>
+#include <ethdev_driver.h>
+#include <ethdev_vdev.h>
 #include <rte_malloc.h>
 #include <rte_bus_vdev.h>
 #include <rte_kvargs.h>
 #define PMD_PARAM_FIRMWARE                                 "firmware"
 #define PMD_PARAM_CONN_PORT                                "conn_port"
 #define PMD_PARAM_CPU_ID                                   "cpu_id"
+#define PMD_PARAM_SC                                       "sc"
 #define PMD_PARAM_TM_N_QUEUES                              "tm_n_queues"
 #define PMD_PARAM_TM_QSIZE0                                "tm_qsize0"
 #define PMD_PARAM_TM_QSIZE1                                "tm_qsize1"
 #define PMD_PARAM_TM_QSIZE2                                "tm_qsize2"
 #define PMD_PARAM_TM_QSIZE3                                "tm_qsize3"
-
-static const char *pmd_valid_args[] = {
+#define PMD_PARAM_TM_QSIZE4                                "tm_qsize4"
+#define PMD_PARAM_TM_QSIZE5                                "tm_qsize5"
+#define PMD_PARAM_TM_QSIZE6                                "tm_qsize6"
+#define PMD_PARAM_TM_QSIZE7                                "tm_qsize7"
+#define PMD_PARAM_TM_QSIZE8                                "tm_qsize8"
+#define PMD_PARAM_TM_QSIZE9                                "tm_qsize9"
+#define PMD_PARAM_TM_QSIZE10                               "tm_qsize10"
+#define PMD_PARAM_TM_QSIZE11                               "tm_qsize11"
+#define PMD_PARAM_TM_QSIZE12                               "tm_qsize12"
+
+
+static const char * const pmd_valid_args[] = {
        PMD_PARAM_FIRMWARE,
        PMD_PARAM_CONN_PORT,
        PMD_PARAM_CPU_ID,
+       PMD_PARAM_SC,
        PMD_PARAM_TM_N_QUEUES,
        PMD_PARAM_TM_QSIZE0,
        PMD_PARAM_TM_QSIZE1,
        PMD_PARAM_TM_QSIZE2,
        PMD_PARAM_TM_QSIZE3,
+       PMD_PARAM_TM_QSIZE4,
+       PMD_PARAM_TM_QSIZE5,
+       PMD_PARAM_TM_QSIZE6,
+       PMD_PARAM_TM_QSIZE7,
+       PMD_PARAM_TM_QSIZE8,
+       PMD_PARAM_TM_QSIZE9,
+       PMD_PARAM_TM_QSIZE10,
+       PMD_PARAM_TM_QSIZE11,
+       PMD_PARAM_TM_QSIZE12,
        NULL
 };
 
@@ -47,7 +68,7 @@ static const char welcome[] =
 
 static const char prompt[] = "softnic> ";
 
-struct softnic_conn_params conn_params_default = {
+static const struct softnic_conn_params conn_params_default = {
        .welcome = welcome,
        .prompt = prompt,
        .addr = "0.0.0.0",
@@ -59,34 +80,22 @@ struct softnic_conn_params conn_params_default = {
        .msg_handle_arg = NULL,
 };
 
-static const struct rte_eth_dev_info pmd_dev_info = {
-       .min_rx_bufsize = 0,
-       .max_rx_pktlen = UINT32_MAX,
-       .max_rx_queues = UINT16_MAX,
-       .max_tx_queues = UINT16_MAX,
-       .rx_desc_lim = {
-               .nb_max = UINT16_MAX,
-               .nb_min = 0,
-               .nb_align = 1,
-       },
-       .tx_desc_lim = {
-               .nb_max = UINT16_MAX,
-               .nb_min = 0,
-               .nb_align = 1,
-       },
-};
-
-static int pmd_softnic_logtype;
+RTE_LOG_REGISTER_DEFAULT(pmd_softnic_logtype, NOTICE);
 
 #define PMD_LOG(level, fmt, args...) \
        rte_log(RTE_LOG_ ## level, pmd_softnic_logtype, \
                "%s(): " fmt "\n", __func__, ##args)
 
-static void
+static int
 pmd_dev_infos_get(struct rte_eth_dev *dev __rte_unused,
        struct rte_eth_dev_info *dev_info)
 {
-       memcpy(dev_info, &pmd_dev_info, sizeof(*dev_info));
+       dev_info->max_rx_pktlen = UINT32_MAX;
+       dev_info->max_rx_queues = UINT16_MAX;
+       dev_info->max_tx_queues = UINT16_MAX;
+       dev_info->dev_capa &= ~RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP;
+
+       return 0;
 }
 
 static int
@@ -165,18 +174,18 @@ pmd_dev_start(struct rte_eth_dev *dev)
                return status;
 
        /* Link UP */
-       dev->data->dev_link.link_status = ETH_LINK_UP;
+       dev->data->dev_link.link_status = RTE_ETH_LINK_UP;
 
        return 0;
 }
 
-static void
+static int
 pmd_dev_stop(struct rte_eth_dev *dev)
 {
        struct pmd_internals *p = dev->data->dev_private;
 
        /* Link DOWN */
-       dev->data->dev_link.link_status = ETH_LINK_DOWN;
+       dev->data->dev_link.link_status = RTE_ETH_LINK_DOWN;
 
        /* Firmware */
        softnic_pipeline_disable_all(p);
@@ -191,12 +200,45 @@ pmd_dev_stop(struct rte_eth_dev *dev)
 
        tm_hierarchy_free(p);
        softnic_mtr_free(p);
+
+       return 0;
 }
 
 static void
-pmd_dev_close(struct rte_eth_dev *dev __rte_unused)
+pmd_free(struct pmd_internals *p)
 {
-       return;
+       if (p == NULL)
+               return;
+
+       if (p->params.conn_port)
+               softnic_conn_free(p->conn);
+
+       softnic_thread_free(p);
+       softnic_pipeline_free(p);
+       softnic_table_action_profile_free(p);
+       softnic_port_in_action_profile_free(p);
+       softnic_tap_free(p);
+       softnic_tmgr_free(p);
+       softnic_link_free(p);
+       softnic_swq_free(p);
+       softnic_mempool_free(p);
+
+       tm_hierarchy_free(p);
+       softnic_mtr_free(p);
+
+       rte_free(p);
+}
+
+static int
+pmd_dev_close(struct rte_eth_dev *dev)
+{
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return 0;
+
+       pmd_free(dev->data->dev_private);
+       dev->data->dev_private = NULL; /* already freed */
+       dev->data->mac_addrs = NULL; /* statically allocated */
+       return 0;
 }
 
 static int
@@ -207,18 +249,11 @@ pmd_link_update(struct rte_eth_dev *dev __rte_unused,
 }
 
 static int
-pmd_filter_ctrl(struct rte_eth_dev *dev __rte_unused,
-               enum rte_filter_type filter_type,
-               enum rte_filter_op filter_op,
-               void *arg)
+pmd_flow_ops_get(struct rte_eth_dev *dev __rte_unused,
+                const struct rte_flow_ops **ops)
 {
-       if (filter_type == RTE_ETH_FILTER_GENERIC &&
-                       filter_op == RTE_ETH_FILTER_GET) {
-               *(const void **)arg = &pmd_flow_ops;
-               return 0;
-       }
-
-       return -ENOTSUP;
+       *ops = &pmd_flow_ops;
+       return 0;
 }
 
 static int
@@ -246,7 +281,7 @@ static const struct eth_dev_ops pmd_ops = {
        .dev_infos_get = pmd_dev_infos_get,
        .rx_queue_setup = pmd_rx_queue_setup,
        .tx_queue_setup = pmd_tx_queue_setup,
-       .filter_ctrl = pmd_filter_ctrl,
+       .flow_ops_get = pmd_flow_ops_get,
        .tm_ops_get = pmd_tm_ops_get,
        .mtr_ops_get = pmd_mtr_ops_get,
 };
@@ -298,6 +333,7 @@ pmd_init(struct pmd_params *params)
        softnic_link_init(p);
        softnic_tmgr_init(p);
        softnic_tap_init(p);
+       softnic_cryptodev_init(p);
        softnic_port_in_action_profile_init(p);
        softnic_table_action_profile_init(p);
        softnic_pipeline_init(p);
@@ -326,32 +362,7 @@ pmd_init(struct pmd_params *params)
        return p;
 }
 
-static void
-pmd_free(struct pmd_internals *p)
-{
-       if (p == NULL)
-               return;
-
-       if (p->params.conn_port)
-               softnic_conn_free(p->conn);
-
-       softnic_thread_free(p);
-       softnic_pipeline_free(p);
-       softnic_table_action_profile_free(p);
-       softnic_port_in_action_profile_free(p);
-       softnic_tap_free(p);
-       softnic_tmgr_free(p);
-       softnic_link_free(p);
-       softnic_swq_free(p);
-       softnic_mempool_free(p);
-
-       tm_hierarchy_free(p);
-       softnic_mtr_free(p);
-
-       rte_free(p);
-}
-
-static struct ether_addr eth_addr = {
+static struct rte_ether_addr eth_addr = {
        .addr_bytes = {0},
 };
 
@@ -376,13 +387,12 @@ pmd_ethdev_register(struct rte_vdev_device *vdev,
 
        /* dev->data */
        dev->data->dev_private = dev_private;
-       dev->data->dev_link.link_speed = ETH_SPEED_NUM_100G;
-       dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;
-       dev->data->dev_link.link_autoneg = ETH_LINK_FIXED;
-       dev->data->dev_link.link_status = ETH_LINK_DOWN;
+       dev->data->dev_link.link_speed = RTE_ETH_SPEED_NUM_100G;
+       dev->data->dev_link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
+       dev->data->dev_link.link_autoneg = RTE_ETH_LINK_FIXED;
+       dev->data->dev_link.link_status = RTE_ETH_LINK_DOWN;
        dev->data->mac_addrs = &eth_addr;
        dev->data->promiscuous = 1;
-       dev->data->kdrv = RTE_KDRV_NONE;
        dev->data->numa_node = params->cpu_id;
 
        rte_eth_dev_probing_finish(dev);
@@ -431,6 +441,7 @@ pmd_parse_args(struct pmd_params *p, const char *params)
 {
        struct rte_kvargs *kvlist;
        int ret = 0;
+       char *firmware = NULL;
 
        kvlist = rte_kvargs_parse(params, pmd_valid_args);
        if (kvlist == NULL)
@@ -438,22 +449,50 @@ pmd_parse_args(struct pmd_params *p, const char *params)
 
        /* Set default values */
        memset(p, 0, sizeof(*p));
-       p->firmware = SOFTNIC_FIRMWARE;
+       if (rte_strscpy(p->firmware, SOFTNIC_FIRMWARE,
+                       sizeof(p->firmware)) < 0) {
+               PMD_LOG(WARNING,
+                       "\"%s\": firmware path should be shorter than %zu",
+                       SOFTNIC_FIRMWARE, sizeof(p->firmware));
+               ret = -EINVAL;
+               goto out_free;
+       }
        p->cpu_id = SOFTNIC_CPU_ID;
+       p->sc = SOFTNIC_SC;
        p->tm.n_queues = SOFTNIC_TM_N_QUEUES;
        p->tm.qsize[0] = SOFTNIC_TM_QUEUE_SIZE;
        p->tm.qsize[1] = SOFTNIC_TM_QUEUE_SIZE;
        p->tm.qsize[2] = SOFTNIC_TM_QUEUE_SIZE;
        p->tm.qsize[3] = SOFTNIC_TM_QUEUE_SIZE;
+       p->tm.qsize[4] = SOFTNIC_TM_QUEUE_SIZE;
+       p->tm.qsize[5] = SOFTNIC_TM_QUEUE_SIZE;
+       p->tm.qsize[6] = SOFTNIC_TM_QUEUE_SIZE;
+       p->tm.qsize[7] = SOFTNIC_TM_QUEUE_SIZE;
+       p->tm.qsize[8] = SOFTNIC_TM_QUEUE_SIZE;
+       p->tm.qsize[9] = SOFTNIC_TM_QUEUE_SIZE;
+       p->tm.qsize[10] = SOFTNIC_TM_QUEUE_SIZE;
+       p->tm.qsize[11] = SOFTNIC_TM_QUEUE_SIZE;
+       p->tm.qsize[12] = SOFTNIC_TM_QUEUE_SIZE;
 
        /* Firmware script (optional) */
        if (rte_kvargs_count(kvlist, PMD_PARAM_FIRMWARE) == 1) {
                ret = rte_kvargs_process(kvlist, PMD_PARAM_FIRMWARE,
-                       &get_string, &p->firmware);
+                       &get_string, &firmware);
                if (ret < 0)
                        goto out_free;
-       }
 
+               if (rte_strscpy(p->firmware, firmware,
+                               sizeof(p->firmware)) < 0) {
+                       PMD_LOG(WARNING,
+                               "\"%s\": "
+                               "firmware path should be shorter than %zu",
+                               firmware, sizeof(p->firmware));
+                       free(firmware);
+                       ret = -EINVAL;
+                       goto out_free;
+               }
+               free(firmware);
+       }
        /* Connection listening port (optional) */
        if (rte_kvargs_count(kvlist, PMD_PARAM_CONN_PORT) == 1) {
                ret = rte_kvargs_process(kvlist, PMD_PARAM_CONN_PORT,
@@ -470,6 +509,14 @@ pmd_parse_args(struct pmd_params *p, const char *params)
                        goto out_free;
        }
 
+       /* Service cores (optional) */
+       if (rte_kvargs_count(kvlist, PMD_PARAM_SC) == 1) {
+               ret = rte_kvargs_process(kvlist, PMD_PARAM_SC,
+                       &get_uint32, &p->sc);
+               if (ret < 0)
+                       goto out_free;
+       }
+
        /* TM number of queues (optional) */
        if (rte_kvargs_count(kvlist, PMD_PARAM_TM_N_QUEUES) == 1) {
                ret = rte_kvargs_process(kvlist, PMD_PARAM_TM_N_QUEUES,
@@ -507,6 +554,67 @@ pmd_parse_args(struct pmd_params *p, const char *params)
                        goto out_free;
        }
 
+       if (rte_kvargs_count(kvlist, PMD_PARAM_TM_QSIZE4) == 1) {
+               ret = rte_kvargs_process(kvlist, PMD_PARAM_TM_QSIZE4,
+                       &get_uint32, &p->tm.qsize[4]);
+               if (ret < 0)
+                       goto out_free;
+       }
+
+       if (rte_kvargs_count(kvlist, PMD_PARAM_TM_QSIZE5) == 1) {
+               ret = rte_kvargs_process(kvlist, PMD_PARAM_TM_QSIZE5,
+                       &get_uint32, &p->tm.qsize[5]);
+               if (ret < 0)
+                       goto out_free;
+       }
+
+       if (rte_kvargs_count(kvlist, PMD_PARAM_TM_QSIZE6) == 1) {
+               ret = rte_kvargs_process(kvlist, PMD_PARAM_TM_QSIZE6,
+                       &get_uint32, &p->tm.qsize[6]);
+               if (ret < 0)
+                       goto out_free;
+       }
+
+       if (rte_kvargs_count(kvlist, PMD_PARAM_TM_QSIZE7) == 1) {
+               ret = rte_kvargs_process(kvlist, PMD_PARAM_TM_QSIZE7,
+                       &get_uint32, &p->tm.qsize[7]);
+               if (ret < 0)
+                       goto out_free;
+       }
+       if (rte_kvargs_count(kvlist, PMD_PARAM_TM_QSIZE8) == 1) {
+               ret = rte_kvargs_process(kvlist, PMD_PARAM_TM_QSIZE8,
+                       &get_uint32, &p->tm.qsize[8]);
+               if (ret < 0)
+                       goto out_free;
+       }
+       if (rte_kvargs_count(kvlist, PMD_PARAM_TM_QSIZE9) == 1) {
+               ret = rte_kvargs_process(kvlist, PMD_PARAM_TM_QSIZE9,
+                       &get_uint32, &p->tm.qsize[9]);
+               if (ret < 0)
+                       goto out_free;
+       }
+
+       if (rte_kvargs_count(kvlist, PMD_PARAM_TM_QSIZE10) == 1) {
+               ret = rte_kvargs_process(kvlist, PMD_PARAM_TM_QSIZE10,
+                       &get_uint32, &p->tm.qsize[10]);
+               if (ret < 0)
+                       goto out_free;
+       }
+
+       if (rte_kvargs_count(kvlist, PMD_PARAM_TM_QSIZE11) == 1) {
+               ret = rte_kvargs_process(kvlist, PMD_PARAM_TM_QSIZE11,
+                       &get_uint32, &p->tm.qsize[11]);
+               if (ret < 0)
+                       goto out_free;
+       }
+
+       if (rte_kvargs_count(kvlist, PMD_PARAM_TM_QSIZE12) == 1) {
+               ret = rte_kvargs_process(kvlist, PMD_PARAM_TM_QSIZE12,
+                       &get_uint32, &p->tm.qsize[12]);
+               if (ret < 0)
+                       goto out_free;
+       }
+
 out_free:
        rte_kvargs_free(kvlist);
        return ret;
@@ -533,7 +641,12 @@ pmd_probe(struct rte_vdev_device *vdev)
        if (status)
                return status;
 
-       p.name = name;
+       if (rte_strscpy(p.name, name, sizeof(p.name)) < 0) {
+               PMD_LOG(WARNING,
+                       "\"%s\": device name should be shorter than %zu",
+                       name, sizeof(p.name));
+               return -EINVAL;
+       }
 
        /* Allocate and initialize soft ethdev private data */
        dev_private = pmd_init(&p);
@@ -556,7 +669,6 @@ static int
 pmd_remove(struct rte_vdev_device *vdev)
 {
        struct rte_eth_dev *dev = NULL;
-       struct pmd_internals *p;
 
        if (!vdev)
                return -EINVAL;
@@ -566,13 +678,10 @@ pmd_remove(struct rte_vdev_device *vdev)
        /* Find the ethdev entry */
        dev = rte_eth_dev_allocated(rte_vdev_device_name(vdev));
        if (dev == NULL)
-               return -ENODEV;
-       p = dev->data->dev_private;
+               return 0; /* port already released */
 
-       /* Free device data structures*/
-       rte_free(dev->data);
+       pmd_dev_close(dev);
        rte_eth_dev_release_port(dev);
-       pmd_free(p);
 
        return 0;
 }
@@ -592,16 +701,17 @@ RTE_PMD_REGISTER_PARAM_STRING(net_softnic,
        PMD_PARAM_TM_QSIZE1 "=<uint32> "
        PMD_PARAM_TM_QSIZE2 "=<uint32> "
        PMD_PARAM_TM_QSIZE3 "=<uint32>"
+       PMD_PARAM_TM_QSIZE4 "=<uint32> "
+       PMD_PARAM_TM_QSIZE5 "=<uint32> "
+       PMD_PARAM_TM_QSIZE6 "=<uint32> "
+       PMD_PARAM_TM_QSIZE7 "=<uint32> "
+       PMD_PARAM_TM_QSIZE8 "=<uint32> "
+       PMD_PARAM_TM_QSIZE9 "=<uint32> "
+       PMD_PARAM_TM_QSIZE10 "=<uint32> "
+       PMD_PARAM_TM_QSIZE11 "=<uint32>"
+       PMD_PARAM_TM_QSIZE12 "=<uint32>"
 );
 
-
-RTE_INIT(pmd_softnic_init_log)
-{
-       pmd_softnic_logtype = rte_log_register("pmd.net.softnic");
-       if (pmd_softnic_logtype >= 0)
-               rte_log_set_level(pmd_softnic_logtype, RTE_LOG_NOTICE);
-}
-
 int
 rte_pmd_softnic_manage(uint16_t port_id)
 {