1f7be70e5SJerin Jacob /* 2f7be70e5SJerin Jacob * BSD LICENSE 3f7be70e5SJerin Jacob * 4f7be70e5SJerin Jacob * Copyright (C) Cavium Inc. 2017. All rights reserved. 5f7be70e5SJerin Jacob * 6f7be70e5SJerin Jacob * Redistribution and use in source and binary forms, with or without 7f7be70e5SJerin Jacob * modification, are permitted provided that the following conditions 8f7be70e5SJerin Jacob * are met: 9f7be70e5SJerin Jacob * 10f7be70e5SJerin Jacob * * Redistributions of source code must retain the above copyright 11f7be70e5SJerin Jacob * notice, this list of conditions and the following disclaimer. 12f7be70e5SJerin Jacob * * Redistributions in binary form must reproduce the above copyright 13f7be70e5SJerin Jacob * notice, this list of conditions and the following disclaimer in 14f7be70e5SJerin Jacob * the documentation and/or other materials provided with the 15f7be70e5SJerin Jacob * distribution. 16f7be70e5SJerin Jacob * * Neither the name of Cavium networks nor the names of its 17f7be70e5SJerin Jacob * contributors may be used to endorse or promote products derived 18f7be70e5SJerin Jacob * from this software without specific prior written permission. 19f7be70e5SJerin Jacob * 20f7be70e5SJerin Jacob * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21f7be70e5SJerin Jacob * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22f7be70e5SJerin Jacob * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23f7be70e5SJerin Jacob * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24f7be70e5SJerin Jacob * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25f7be70e5SJerin Jacob * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26f7be70e5SJerin Jacob * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27f7be70e5SJerin Jacob * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28f7be70e5SJerin Jacob * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29f7be70e5SJerin Jacob * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30f7be70e5SJerin Jacob * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31f7be70e5SJerin Jacob */ 32f7be70e5SJerin Jacob #include <stdio.h> 33f7be70e5SJerin Jacob #include <stdarg.h> 34f7be70e5SJerin Jacob #include <stdbool.h> 35f7be70e5SJerin Jacob #include <stdint.h> 36f7be70e5SJerin Jacob #include <string.h> 37f7be70e5SJerin Jacob #include <unistd.h> 38f7be70e5SJerin Jacob 39f7be70e5SJerin Jacob #include <rte_alarm.h> 40f7be70e5SJerin Jacob #include <rte_branch_prediction.h> 41f7be70e5SJerin Jacob #include <rte_debug.h> 42f7be70e5SJerin Jacob #include <rte_devargs.h> 43f7be70e5SJerin Jacob #include <rte_dev.h> 44f7be70e5SJerin Jacob #include <rte_kvargs.h> 45f7be70e5SJerin Jacob #include <rte_malloc.h> 46f7be70e5SJerin Jacob #include <rte_prefetch.h> 47f7be70e5SJerin Jacob #include <rte_vdev.h> 48f7be70e5SJerin Jacob 49f7be70e5SJerin Jacob #include "octeontx_ethdev.h" 50f7be70e5SJerin Jacob #include "octeontx_logs.h" 51f7be70e5SJerin Jacob 52f7be70e5SJerin Jacob struct octeontx_vdev_init_params { 53f7be70e5SJerin Jacob uint8_t nr_port; 54f7be70e5SJerin Jacob }; 55f7be70e5SJerin Jacob 56f7be70e5SJerin Jacob /* Parse integer from integer argument */ 57f7be70e5SJerin Jacob static int 58f7be70e5SJerin Jacob parse_integer_arg(const char *key __rte_unused, 59f7be70e5SJerin Jacob const char *value, void *extra_args) 60f7be70e5SJerin Jacob { 61f7be70e5SJerin Jacob int *i = (int *)extra_args; 62f7be70e5SJerin Jacob 63f7be70e5SJerin Jacob *i = atoi(value); 64f7be70e5SJerin Jacob if (*i < 0) { 65f7be70e5SJerin Jacob octeontx_log_err("argument has to be positive."); 66f7be70e5SJerin Jacob return -1; 67f7be70e5SJerin Jacob } 68f7be70e5SJerin Jacob 69f7be70e5SJerin Jacob return 0; 70f7be70e5SJerin Jacob } 71f7be70e5SJerin Jacob 72f7be70e5SJerin Jacob static int 73f7be70e5SJerin Jacob octeontx_parse_vdev_init_params(struct octeontx_vdev_init_params *params, 74f7be70e5SJerin Jacob struct rte_vdev_device *dev) 75f7be70e5SJerin Jacob { 76f7be70e5SJerin Jacob struct rte_kvargs *kvlist = NULL; 77f7be70e5SJerin Jacob int ret = 0; 78f7be70e5SJerin Jacob 79f7be70e5SJerin Jacob static const char * const octeontx_vdev_valid_params[] = { 80f7be70e5SJerin Jacob OCTEONTX_VDEV_NR_PORT_ARG, 81f7be70e5SJerin Jacob NULL 82f7be70e5SJerin Jacob }; 83f7be70e5SJerin Jacob 84f7be70e5SJerin Jacob const char *input_args = rte_vdev_device_args(dev); 85f7be70e5SJerin Jacob if (params == NULL) 86f7be70e5SJerin Jacob return -EINVAL; 87f7be70e5SJerin Jacob 88f7be70e5SJerin Jacob 89f7be70e5SJerin Jacob if (input_args) { 90f7be70e5SJerin Jacob kvlist = rte_kvargs_parse(input_args, 91f7be70e5SJerin Jacob octeontx_vdev_valid_params); 92f7be70e5SJerin Jacob if (kvlist == NULL) 93f7be70e5SJerin Jacob return -1; 94f7be70e5SJerin Jacob 95f7be70e5SJerin Jacob ret = rte_kvargs_process(kvlist, 96f7be70e5SJerin Jacob OCTEONTX_VDEV_NR_PORT_ARG, 97f7be70e5SJerin Jacob &parse_integer_arg, 98f7be70e5SJerin Jacob ¶ms->nr_port); 99f7be70e5SJerin Jacob if (ret < 0) 100f7be70e5SJerin Jacob goto free_kvlist; 101f7be70e5SJerin Jacob } 102f7be70e5SJerin Jacob 103f7be70e5SJerin Jacob free_kvlist: 104f7be70e5SJerin Jacob rte_kvargs_free(kvlist); 105f7be70e5SJerin Jacob return ret; 106f7be70e5SJerin Jacob } 107f7be70e5SJerin Jacob 108*f18b146cSJerin Jacob static int 109*f18b146cSJerin Jacob octeontx_port_open(struct octeontx_nic *nic) 110*f18b146cSJerin Jacob { 111*f18b146cSJerin Jacob octeontx_mbox_bgx_port_conf_t bgx_port_conf; 112*f18b146cSJerin Jacob int res; 113*f18b146cSJerin Jacob 114*f18b146cSJerin Jacob res = 0; 115*f18b146cSJerin Jacob 116*f18b146cSJerin Jacob PMD_INIT_FUNC_TRACE(); 117*f18b146cSJerin Jacob 118*f18b146cSJerin Jacob res = octeontx_bgx_port_open(nic->port_id, &bgx_port_conf); 119*f18b146cSJerin Jacob if (res < 0) { 120*f18b146cSJerin Jacob octeontx_log_err("failed to open port %d", res); 121*f18b146cSJerin Jacob return res; 122*f18b146cSJerin Jacob } 123*f18b146cSJerin Jacob 124*f18b146cSJerin Jacob nic->node = bgx_port_conf.node; 125*f18b146cSJerin Jacob nic->port_ena = bgx_port_conf.enable; 126*f18b146cSJerin Jacob nic->base_ichan = bgx_port_conf.base_chan; 127*f18b146cSJerin Jacob nic->base_ochan = bgx_port_conf.base_chan; 128*f18b146cSJerin Jacob nic->num_ichans = bgx_port_conf.num_chans; 129*f18b146cSJerin Jacob nic->num_ochans = bgx_port_conf.num_chans; 130*f18b146cSJerin Jacob nic->mtu = bgx_port_conf.mtu; 131*f18b146cSJerin Jacob nic->bpen = bgx_port_conf.bpen; 132*f18b146cSJerin Jacob nic->fcs_strip = bgx_port_conf.fcs_strip; 133*f18b146cSJerin Jacob nic->bcast_mode = bgx_port_conf.bcast_mode; 134*f18b146cSJerin Jacob nic->mcast_mode = bgx_port_conf.mcast_mode; 135*f18b146cSJerin Jacob nic->speed = bgx_port_conf.mode; 136*f18b146cSJerin Jacob 137*f18b146cSJerin Jacob memcpy(&nic->mac_addr[0], &bgx_port_conf.macaddr[0], ETHER_ADDR_LEN); 138*f18b146cSJerin Jacob 139*f18b146cSJerin Jacob octeontx_log_dbg("port opened %d", nic->port_id); 140*f18b146cSJerin Jacob return res; 141*f18b146cSJerin Jacob } 142*f18b146cSJerin Jacob 143*f18b146cSJerin Jacob static void 144*f18b146cSJerin Jacob octeontx_port_close(struct octeontx_nic *nic) 145*f18b146cSJerin Jacob { 146*f18b146cSJerin Jacob PMD_INIT_FUNC_TRACE(); 147*f18b146cSJerin Jacob 148*f18b146cSJerin Jacob octeontx_bgx_port_close(nic->port_id); 149*f18b146cSJerin Jacob octeontx_log_dbg("port closed %d", nic->port_id); 150*f18b146cSJerin Jacob } 151*f18b146cSJerin Jacob 152f7be70e5SJerin Jacob static inline void 153f7be70e5SJerin Jacob devconf_set_default_sane_values(struct rte_event_dev_config *dev_conf, 154f7be70e5SJerin Jacob struct rte_event_dev_info *info) 155f7be70e5SJerin Jacob { 156f7be70e5SJerin Jacob memset(dev_conf, 0, sizeof(struct rte_event_dev_config)); 157f7be70e5SJerin Jacob dev_conf->dequeue_timeout_ns = info->min_dequeue_timeout_ns; 158f7be70e5SJerin Jacob 159f7be70e5SJerin Jacob dev_conf->nb_event_ports = info->max_event_ports; 160f7be70e5SJerin Jacob dev_conf->nb_event_queues = info->max_event_queues; 161f7be70e5SJerin Jacob 162f7be70e5SJerin Jacob dev_conf->nb_event_queue_flows = info->max_event_queue_flows; 163f7be70e5SJerin Jacob dev_conf->nb_event_port_dequeue_depth = 164f7be70e5SJerin Jacob info->max_event_port_dequeue_depth; 165f7be70e5SJerin Jacob dev_conf->nb_event_port_enqueue_depth = 166f7be70e5SJerin Jacob info->max_event_port_enqueue_depth; 167f7be70e5SJerin Jacob dev_conf->nb_event_port_enqueue_depth = 168f7be70e5SJerin Jacob info->max_event_port_enqueue_depth; 169f7be70e5SJerin Jacob dev_conf->nb_events_limit = 170f7be70e5SJerin Jacob info->max_num_events; 171f7be70e5SJerin Jacob } 172f7be70e5SJerin Jacob 173*f18b146cSJerin Jacob /* Initialize and register driver with DPDK Application */ 174*f18b146cSJerin Jacob static const struct eth_dev_ops octeontx_dev_ops = { 175*f18b146cSJerin Jacob }; 176*f18b146cSJerin Jacob 177f7be70e5SJerin Jacob /* Create Ethdev interface per BGX LMAC ports */ 178f7be70e5SJerin Jacob static int 179f7be70e5SJerin Jacob octeontx_create(struct rte_vdev_device *dev, int port, uint8_t evdev, 180f7be70e5SJerin Jacob int socket_id) 181f7be70e5SJerin Jacob { 182*f18b146cSJerin Jacob int res; 183*f18b146cSJerin Jacob char octtx_name[OCTEONTX_MAX_NAME_LEN]; 184*f18b146cSJerin Jacob struct octeontx_nic *nic = NULL; 185*f18b146cSJerin Jacob struct rte_eth_dev *eth_dev = NULL; 186*f18b146cSJerin Jacob struct rte_eth_dev_data *data = NULL; 187*f18b146cSJerin Jacob const char *name = rte_vdev_device_name(dev); 188f7be70e5SJerin Jacob 189*f18b146cSJerin Jacob PMD_INIT_FUNC_TRACE(); 190*f18b146cSJerin Jacob 191*f18b146cSJerin Jacob sprintf(octtx_name, "%s_%d", name, port); 192*f18b146cSJerin Jacob if (rte_eal_process_type() != RTE_PROC_PRIMARY) { 193*f18b146cSJerin Jacob eth_dev = rte_eth_dev_attach_secondary(octtx_name); 194*f18b146cSJerin Jacob if (eth_dev == NULL) 195f7be70e5SJerin Jacob return -ENODEV; 196*f18b146cSJerin Jacob 197*f18b146cSJerin Jacob return 0; 198*f18b146cSJerin Jacob } 199*f18b146cSJerin Jacob 200*f18b146cSJerin Jacob data = rte_zmalloc_socket(octtx_name, sizeof(*data), 0, socket_id); 201*f18b146cSJerin Jacob if (data == NULL) { 202*f18b146cSJerin Jacob octeontx_log_err("failed to allocate devdata"); 203*f18b146cSJerin Jacob res = -ENOMEM; 204*f18b146cSJerin Jacob goto err; 205*f18b146cSJerin Jacob } 206*f18b146cSJerin Jacob 207*f18b146cSJerin Jacob nic = rte_zmalloc_socket(octtx_name, sizeof(*nic), 0, socket_id); 208*f18b146cSJerin Jacob if (nic == NULL) { 209*f18b146cSJerin Jacob octeontx_log_err("failed to allocate nic structure"); 210*f18b146cSJerin Jacob res = -ENOMEM; 211*f18b146cSJerin Jacob goto err; 212*f18b146cSJerin Jacob } 213*f18b146cSJerin Jacob 214*f18b146cSJerin Jacob nic->port_id = port; 215*f18b146cSJerin Jacob nic->evdev = evdev; 216*f18b146cSJerin Jacob 217*f18b146cSJerin Jacob res = octeontx_port_open(nic); 218*f18b146cSJerin Jacob if (res < 0) 219*f18b146cSJerin Jacob goto err; 220*f18b146cSJerin Jacob 221*f18b146cSJerin Jacob /* Rx side port configuration */ 222*f18b146cSJerin Jacob res = octeontx_pki_port_open(port); 223*f18b146cSJerin Jacob if (res != 0) { 224*f18b146cSJerin Jacob octeontx_log_err("failed to open PKI port %d", port); 225*f18b146cSJerin Jacob res = -ENODEV; 226*f18b146cSJerin Jacob goto err; 227*f18b146cSJerin Jacob } 228*f18b146cSJerin Jacob 229*f18b146cSJerin Jacob /* Reserve an ethdev entry */ 230*f18b146cSJerin Jacob eth_dev = rte_eth_dev_allocate(octtx_name); 231*f18b146cSJerin Jacob if (eth_dev == NULL) { 232*f18b146cSJerin Jacob octeontx_log_err("failed to allocate rte_eth_dev"); 233*f18b146cSJerin Jacob res = -ENOMEM; 234*f18b146cSJerin Jacob goto err; 235*f18b146cSJerin Jacob } 236*f18b146cSJerin Jacob 237*f18b146cSJerin Jacob eth_dev->device = &dev->device; 238*f18b146cSJerin Jacob eth_dev->intr_handle = NULL; 239*f18b146cSJerin Jacob eth_dev->data->kdrv = RTE_KDRV_NONE; 240*f18b146cSJerin Jacob eth_dev->data->numa_node = dev->device.numa_node; 241*f18b146cSJerin Jacob 242*f18b146cSJerin Jacob rte_memcpy(data, (eth_dev)->data, sizeof(*data)); 243*f18b146cSJerin Jacob data->dev_private = nic; 244*f18b146cSJerin Jacob 245*f18b146cSJerin Jacob data->port_id = eth_dev->data->port_id; 246*f18b146cSJerin Jacob snprintf(data->name, sizeof(data->name), "%s", eth_dev->data->name); 247*f18b146cSJerin Jacob 248*f18b146cSJerin Jacob nic->ev_queues = 1; 249*f18b146cSJerin Jacob nic->ev_ports = 1; 250*f18b146cSJerin Jacob 251*f18b146cSJerin Jacob data->dev_link.link_status = ETH_LINK_DOWN; 252*f18b146cSJerin Jacob data->dev_started = 0; 253*f18b146cSJerin Jacob data->promiscuous = 0; 254*f18b146cSJerin Jacob data->all_multicast = 0; 255*f18b146cSJerin Jacob data->scattered_rx = 0; 256*f18b146cSJerin Jacob 257*f18b146cSJerin Jacob data->mac_addrs = rte_zmalloc_socket(octtx_name, ETHER_ADDR_LEN, 0, 258*f18b146cSJerin Jacob socket_id); 259*f18b146cSJerin Jacob if (data->mac_addrs == NULL) { 260*f18b146cSJerin Jacob octeontx_log_err("failed to allocate memory for mac_addrs"); 261*f18b146cSJerin Jacob res = -ENOMEM; 262*f18b146cSJerin Jacob goto err; 263*f18b146cSJerin Jacob } 264*f18b146cSJerin Jacob 265*f18b146cSJerin Jacob eth_dev->data = data; 266*f18b146cSJerin Jacob eth_dev->dev_ops = &octeontx_dev_ops; 267*f18b146cSJerin Jacob 268*f18b146cSJerin Jacob /* Finally save ethdev pointer to the NIC structure */ 269*f18b146cSJerin Jacob nic->dev = eth_dev; 270*f18b146cSJerin Jacob 271*f18b146cSJerin Jacob if (nic->port_id != data->port_id) { 272*f18b146cSJerin Jacob octeontx_log_err("eth_dev->port_id (%d) is diff to orig (%d)", 273*f18b146cSJerin Jacob data->port_id, nic->port_id); 274*f18b146cSJerin Jacob res = -EINVAL; 275*f18b146cSJerin Jacob goto err; 276*f18b146cSJerin Jacob } 277*f18b146cSJerin Jacob 278*f18b146cSJerin Jacob /* Update port_id mac to eth_dev */ 279*f18b146cSJerin Jacob memcpy(data->mac_addrs, nic->mac_addr, ETHER_ADDR_LEN); 280*f18b146cSJerin Jacob 281*f18b146cSJerin Jacob PMD_INIT_LOG(DEBUG, "ethdev info: "); 282*f18b146cSJerin Jacob PMD_INIT_LOG(DEBUG, "port %d, port_ena %d ochan %d num_ochan %d tx_q %d", 283*f18b146cSJerin Jacob nic->port_id, nic->port_ena, 284*f18b146cSJerin Jacob nic->base_ochan, nic->num_ochans, 285*f18b146cSJerin Jacob nic->num_tx_queues); 286*f18b146cSJerin Jacob PMD_INIT_LOG(DEBUG, "speed %d mtu %d", nic->speed, nic->mtu); 287*f18b146cSJerin Jacob 288*f18b146cSJerin Jacob return data->port_id; 289*f18b146cSJerin Jacob 290*f18b146cSJerin Jacob err: 291*f18b146cSJerin Jacob if (port) 292*f18b146cSJerin Jacob octeontx_port_close(nic); 293*f18b146cSJerin Jacob 294*f18b146cSJerin Jacob if (eth_dev != NULL) { 295*f18b146cSJerin Jacob rte_free(eth_dev->data->mac_addrs); 296*f18b146cSJerin Jacob rte_free(data); 297*f18b146cSJerin Jacob rte_free(nic); 298*f18b146cSJerin Jacob rte_eth_dev_release_port(eth_dev); 299*f18b146cSJerin Jacob } 300*f18b146cSJerin Jacob 301*f18b146cSJerin Jacob return res; 302f7be70e5SJerin Jacob } 303f7be70e5SJerin Jacob 304f7be70e5SJerin Jacob /* Un initialize octeontx device */ 305f7be70e5SJerin Jacob static int 306f7be70e5SJerin Jacob octeontx_remove(struct rte_vdev_device *dev) 307f7be70e5SJerin Jacob { 308f7be70e5SJerin Jacob char octtx_name[OCTEONTX_MAX_NAME_LEN]; 309f7be70e5SJerin Jacob struct rte_eth_dev *eth_dev = NULL; 310f7be70e5SJerin Jacob struct octeontx_nic *nic = NULL; 311f7be70e5SJerin Jacob int i; 312f7be70e5SJerin Jacob 313f7be70e5SJerin Jacob if (dev == NULL) 314f7be70e5SJerin Jacob return -EINVAL; 315f7be70e5SJerin Jacob 316f7be70e5SJerin Jacob for (i = 0; i < OCTEONTX_VDEV_DEFAULT_MAX_NR_PORT; i++) { 317f7be70e5SJerin Jacob sprintf(octtx_name, "eth_octeontx_%d", i); 318f7be70e5SJerin Jacob 319f7be70e5SJerin Jacob /* reserve an ethdev entry */ 320f7be70e5SJerin Jacob eth_dev = rte_eth_dev_allocated(octtx_name); 321f7be70e5SJerin Jacob if (eth_dev == NULL) 322f7be70e5SJerin Jacob return -ENODEV; 323f7be70e5SJerin Jacob 324f7be70e5SJerin Jacob nic = octeontx_pmd_priv(eth_dev); 325f7be70e5SJerin Jacob rte_event_dev_stop(nic->evdev); 326f7be70e5SJerin Jacob PMD_INIT_LOG(INFO, "Closing octeontx device %s", octtx_name); 327f7be70e5SJerin Jacob 328f7be70e5SJerin Jacob rte_free(eth_dev->data->mac_addrs); 329f7be70e5SJerin Jacob rte_free(eth_dev->data->dev_private); 330f7be70e5SJerin Jacob rte_free(eth_dev->data); 331f7be70e5SJerin Jacob rte_eth_dev_release_port(eth_dev); 332f7be70e5SJerin Jacob rte_event_dev_close(nic->evdev); 333f7be70e5SJerin Jacob } 334f7be70e5SJerin Jacob 335f7be70e5SJerin Jacob /* Free FC resource */ 336f7be70e5SJerin Jacob octeontx_pko_fc_free(); 337f7be70e5SJerin Jacob 338f7be70e5SJerin Jacob return 0; 339f7be70e5SJerin Jacob } 340f7be70e5SJerin Jacob 341f7be70e5SJerin Jacob /* Initialize octeontx device */ 342f7be70e5SJerin Jacob static int 343f7be70e5SJerin Jacob octeontx_probe(struct rte_vdev_device *dev) 344f7be70e5SJerin Jacob { 345f7be70e5SJerin Jacob const char *dev_name; 346f7be70e5SJerin Jacob static int probe_once; 347f7be70e5SJerin Jacob uint8_t socket_id, qlist; 348f7be70e5SJerin Jacob int tx_vfcnt, port_id, evdev, qnum, pnum, res, i; 349f7be70e5SJerin Jacob struct rte_event_dev_config dev_conf; 350f7be70e5SJerin Jacob const char *eventdev_name = "event_octeontx"; 351f7be70e5SJerin Jacob struct rte_event_dev_info info; 352f7be70e5SJerin Jacob 353f7be70e5SJerin Jacob struct octeontx_vdev_init_params init_params = { 354f7be70e5SJerin Jacob OCTEONTX_VDEV_DEFAULT_MAX_NR_PORT 355f7be70e5SJerin Jacob }; 356f7be70e5SJerin Jacob 357f7be70e5SJerin Jacob dev_name = rte_vdev_device_name(dev); 358f7be70e5SJerin Jacob res = octeontx_parse_vdev_init_params(&init_params, dev); 359f7be70e5SJerin Jacob if (res < 0) 360f7be70e5SJerin Jacob return -EINVAL; 361f7be70e5SJerin Jacob 362f7be70e5SJerin Jacob if (init_params.nr_port > OCTEONTX_VDEV_DEFAULT_MAX_NR_PORT) { 363f7be70e5SJerin Jacob octeontx_log_err("nr_port (%d) > max (%d)", init_params.nr_port, 364f7be70e5SJerin Jacob OCTEONTX_VDEV_DEFAULT_MAX_NR_PORT); 365f7be70e5SJerin Jacob return -ENOTSUP; 366f7be70e5SJerin Jacob } 367f7be70e5SJerin Jacob 368f7be70e5SJerin Jacob PMD_INIT_LOG(DEBUG, "initializing %s pmd", dev_name); 369f7be70e5SJerin Jacob 370f7be70e5SJerin Jacob socket_id = rte_socket_id(); 371f7be70e5SJerin Jacob 372f7be70e5SJerin Jacob tx_vfcnt = octeontx_pko_vf_count(); 373f7be70e5SJerin Jacob 374f7be70e5SJerin Jacob if (tx_vfcnt < init_params.nr_port) { 375f7be70e5SJerin Jacob octeontx_log_err("not enough PKO (%d) for port number (%d)", 376f7be70e5SJerin Jacob tx_vfcnt, init_params.nr_port); 377f7be70e5SJerin Jacob return -EINVAL; 378f7be70e5SJerin Jacob } 379f7be70e5SJerin Jacob evdev = rte_event_dev_get_dev_id(eventdev_name); 380f7be70e5SJerin Jacob if (evdev < 0) { 381f7be70e5SJerin Jacob octeontx_log_err("eventdev %s not found", eventdev_name); 382f7be70e5SJerin Jacob return -ENODEV; 383f7be70e5SJerin Jacob } 384f7be70e5SJerin Jacob 385f7be70e5SJerin Jacob res = rte_event_dev_info_get(evdev, &info); 386f7be70e5SJerin Jacob if (res < 0) { 387f7be70e5SJerin Jacob octeontx_log_err("failed to eventdev info %d", res); 388f7be70e5SJerin Jacob return -EINVAL; 389f7be70e5SJerin Jacob } 390f7be70e5SJerin Jacob 391f7be70e5SJerin Jacob PMD_INIT_LOG(DEBUG, "max_queue %d max_port %d", 392f7be70e5SJerin Jacob info.max_event_queues, info.max_event_ports); 393f7be70e5SJerin Jacob 394f7be70e5SJerin Jacob if (octeontx_pko_init_fc(tx_vfcnt)) 395f7be70e5SJerin Jacob return -ENOMEM; 396f7be70e5SJerin Jacob 397f7be70e5SJerin Jacob devconf_set_default_sane_values(&dev_conf, &info); 398f7be70e5SJerin Jacob res = rte_event_dev_configure(evdev, &dev_conf); 399f7be70e5SJerin Jacob if (res < 0) 400f7be70e5SJerin Jacob goto parse_error; 401f7be70e5SJerin Jacob 402f7be70e5SJerin Jacob rte_event_dev_attr_get(evdev, RTE_EVENT_DEV_ATTR_PORT_COUNT, 403f7be70e5SJerin Jacob (uint32_t *)&pnum); 404f7be70e5SJerin Jacob rte_event_dev_attr_get(evdev, RTE_EVENT_DEV_ATTR_QUEUE_COUNT, 405f7be70e5SJerin Jacob (uint32_t *)&qnum); 406f7be70e5SJerin Jacob if (pnum < qnum) { 407f7be70e5SJerin Jacob octeontx_log_err("too few event ports (%d) for event_q(%d)", 408f7be70e5SJerin Jacob pnum, qnum); 409f7be70e5SJerin Jacob res = -EINVAL; 410f7be70e5SJerin Jacob goto parse_error; 411f7be70e5SJerin Jacob } 412f7be70e5SJerin Jacob if (pnum > qnum) { 413f7be70e5SJerin Jacob /* 414f7be70e5SJerin Jacob * We don't poll on event ports 415f7be70e5SJerin Jacob * that do not have any queues assigned. 416f7be70e5SJerin Jacob */ 417f7be70e5SJerin Jacob pnum = qnum; 418f7be70e5SJerin Jacob PMD_INIT_LOG(INFO, 419f7be70e5SJerin Jacob "reducing number of active event ports to %d", pnum); 420f7be70e5SJerin Jacob } 421f7be70e5SJerin Jacob for (i = 0; i < qnum; i++) { 422f7be70e5SJerin Jacob res = rte_event_queue_setup(evdev, i, NULL); 423f7be70e5SJerin Jacob if (res < 0) { 424f7be70e5SJerin Jacob octeontx_log_err("failed to setup event_q(%d): res %d", 425f7be70e5SJerin Jacob i, res); 426f7be70e5SJerin Jacob goto parse_error; 427f7be70e5SJerin Jacob } 428f7be70e5SJerin Jacob } 429f7be70e5SJerin Jacob 430f7be70e5SJerin Jacob for (i = 0; i < pnum; i++) { 431f7be70e5SJerin Jacob res = rte_event_port_setup(evdev, i, NULL); 432f7be70e5SJerin Jacob if (res < 0) { 433f7be70e5SJerin Jacob res = -ENODEV; 434f7be70e5SJerin Jacob octeontx_log_err("failed to setup ev port(%d) res=%d", 435f7be70e5SJerin Jacob i, res); 436f7be70e5SJerin Jacob goto parse_error; 437f7be70e5SJerin Jacob } 438f7be70e5SJerin Jacob /* Link one queue to one event port */ 439f7be70e5SJerin Jacob qlist = i; 440f7be70e5SJerin Jacob res = rte_event_port_link(evdev, i, &qlist, NULL, 1); 441f7be70e5SJerin Jacob if (res < 0) { 442f7be70e5SJerin Jacob res = -ENODEV; 443f7be70e5SJerin Jacob octeontx_log_err("failed to link port (%d): res=%d", 444f7be70e5SJerin Jacob i, res); 445f7be70e5SJerin Jacob goto parse_error; 446f7be70e5SJerin Jacob } 447f7be70e5SJerin Jacob } 448f7be70e5SJerin Jacob 449f7be70e5SJerin Jacob /* Create ethdev interface */ 450f7be70e5SJerin Jacob for (i = 0; i < init_params.nr_port; i++) { 451f7be70e5SJerin Jacob port_id = octeontx_create(dev, i, evdev, socket_id); 452f7be70e5SJerin Jacob if (port_id < 0) { 453f7be70e5SJerin Jacob octeontx_log_err("failed to create device %s", 454f7be70e5SJerin Jacob dev_name); 455f7be70e5SJerin Jacob res = -ENODEV; 456f7be70e5SJerin Jacob goto parse_error; 457f7be70e5SJerin Jacob } 458f7be70e5SJerin Jacob 459f7be70e5SJerin Jacob PMD_INIT_LOG(INFO, "created ethdev %s for port %d", dev_name, 460f7be70e5SJerin Jacob port_id); 461f7be70e5SJerin Jacob } 462f7be70e5SJerin Jacob 463f7be70e5SJerin Jacob if (probe_once) { 464f7be70e5SJerin Jacob octeontx_log_err("interface %s not supported", dev_name); 465f7be70e5SJerin Jacob octeontx_remove(dev); 466f7be70e5SJerin Jacob res = -ENOTSUP; 467f7be70e5SJerin Jacob goto parse_error; 468f7be70e5SJerin Jacob } 469f7be70e5SJerin Jacob probe_once = 1; 470f7be70e5SJerin Jacob 471f7be70e5SJerin Jacob return 0; 472f7be70e5SJerin Jacob 473f7be70e5SJerin Jacob parse_error: 474f7be70e5SJerin Jacob octeontx_pko_fc_free(); 475f7be70e5SJerin Jacob return res; 476f7be70e5SJerin Jacob } 477f7be70e5SJerin Jacob 478f7be70e5SJerin Jacob static struct rte_vdev_driver octeontx_pmd_drv = { 479f7be70e5SJerin Jacob .probe = octeontx_probe, 480f7be70e5SJerin Jacob .remove = octeontx_remove, 481f7be70e5SJerin Jacob }; 482f7be70e5SJerin Jacob 483f7be70e5SJerin Jacob RTE_PMD_REGISTER_VDEV(OCTEONTX_PMD, octeontx_pmd_drv); 484f7be70e5SJerin Jacob RTE_PMD_REGISTER_ALIAS(OCTEONTX_PMD, eth_octeontx); 485f7be70e5SJerin Jacob RTE_PMD_REGISTER_PARAM_STRING(OCTEONTX_PMD, "nr_port=<int> "); 486