X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=lib%2Flibrte_pmd_ring%2Frte_eth_ring.c;h=6832f01e2495912dde192c21d2f6e0ba77861e13;hb=4ae39dfa69ad9a1ae6174f52c60c187d2843402b;hp=5ddecc57be7b67cfe3fe4451cd8d5e221d93165b;hpb=e9d48c0072d36eb6423b45fba4ec49d0def6c36f;p=dpdk.git diff --git a/lib/librte_pmd_ring/rte_eth_ring.c b/lib/librte_pmd_ring/rte_eth_ring.c index 5ddecc57be..6832f01e24 100644 --- a/lib/librte_pmd_ring/rte_eth_ring.c +++ b/lib/librte_pmd_ring/rte_eth_ring.c @@ -1,13 +1,13 @@ /*- * BSD LICENSE - * + * * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. * 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 @@ -17,7 +17,7 @@ * * Neither the name of Intel Corporation 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 @@ -37,6 +37,19 @@ #include #include #include +#include +#include + +#define ETH_RING_NUMA_NODE_ACTION_ARG "nodeaction" +#define ETH_RING_ACTION_CREATE "CREATE" +#define ETH_RING_ACTION_ATTACH "ATTACH" + +static const char *ring_ethdev_driver_name = "Ring PMD"; + +static const char *valid_arguments[] = { + ETH_RING_NUMA_NODE_ACTION_ARG, + NULL +}; struct ring_queue { struct rte_ring *rng; @@ -51,10 +64,11 @@ struct pmd_internals { struct ring_queue rx_ring_queues[RTE_PMD_RING_MAX_RX_RINGS]; struct ring_queue tx_ring_queues[RTE_PMD_RING_MAX_TX_RINGS]; + + struct ether_addr address; }; -static struct ether_addr eth_addr = { .addr_bytes = {0} }; static const char *drivername = "Rings PMD"; static struct rte_eth_link pmd_link = { .link_speed = 10000, @@ -67,7 +81,7 @@ eth_ring_rx(void *q, struct rte_mbuf **bufs, uint16_t nb_bufs) { void **ptrs = (void *)&bufs[0]; struct ring_queue *r = q; - const uint16_t nb_rx = (uint16_t)rte_ring_dequeue_burst(r->rng, + const uint16_t nb_rx = (uint16_t)rte_ring_dequeue_burst(r->rng, ptrs, nb_bufs); if (r->rng->flags & RING_F_SC_DEQ) r->rx_pkts.cnt += nb_rx; @@ -81,7 +95,7 @@ eth_ring_tx(void *q, struct rte_mbuf **bufs, uint16_t nb_bufs) { void **ptrs = (void *)&bufs[0]; struct ring_queue *r = q; - const uint16_t nb_tx = (uint16_t)rte_ring_enqueue_burst(r->rng, + const uint16_t nb_tx = (uint16_t)rte_ring_enqueue_burst(r->rng, ptrs, nb_bufs); if (r->rng->flags & RING_F_SP_ENQ) { r->tx_pkts.cnt += nb_tx; @@ -109,6 +123,20 @@ eth_dev_stop(struct rte_eth_dev *dev) dev->data->dev_link.link_status = 0; } +static int +eth_dev_set_link_down(struct rte_eth_dev *dev) +{ + dev->data->dev_link.link_status = 0; + return 0; +} + +static int +eth_dev_set_link_up(struct rte_eth_dev *dev) +{ + dev->data->dev_link.link_status = 1; + return 0; +} + static int eth_rx_queue_setup(struct rte_eth_dev *dev,uint16_t rx_queue_id, uint16_t nb_rx_desc __rte_unused, @@ -154,7 +182,6 @@ eth_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *igb_stats) unsigned long rx_total = 0, tx_total = 0, tx_err_total = 0; const struct pmd_internals *internal = dev->data->dev_private; - memset(igb_stats, 0, sizeof(*igb_stats)); for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS && i < internal->nb_rx_queues; i++) { igb_stats->q_ipackets[i] = internal->rx_ring_queues[i].rx_pkts.cnt; @@ -187,28 +214,46 @@ eth_stats_reset(struct rte_eth_dev *dev) } } +static void +eth_mac_addr_remove(struct rte_eth_dev *dev __rte_unused, + uint32_t index __rte_unused) +{ +} + +static void +eth_mac_addr_add(struct rte_eth_dev *dev __rte_unused, + struct ether_addr *mac_addr __rte_unused, + uint32_t index __rte_unused, + uint32_t vmdq __rte_unused) +{ +} + static void eth_queue_release(void *q __rte_unused) { ; } static int eth_link_update(struct rte_eth_dev *dev __rte_unused, int wait_to_complete __rte_unused) { return 0; } -static struct eth_dev_ops ops = { - .dev_start = eth_dev_start, - .dev_stop = eth_dev_stop, - .dev_configure = eth_dev_configure, - .dev_infos_get = eth_dev_info, - .rx_queue_setup = eth_rx_queue_setup, - .tx_queue_setup = eth_tx_queue_setup, - .rx_queue_release = eth_queue_release, - .tx_queue_release = eth_queue_release, - .link_update = eth_link_update, - .stats_get = eth_stats_get, - .stats_reset = eth_stats_reset, +static const struct eth_dev_ops ops = { + .dev_start = eth_dev_start, + .dev_stop = eth_dev_stop, + .dev_set_link_up = eth_dev_set_link_up, + .dev_set_link_down = eth_dev_set_link_down, + .dev_configure = eth_dev_configure, + .dev_infos_get = eth_dev_info, + .rx_queue_setup = eth_rx_queue_setup, + .tx_queue_setup = eth_tx_queue_setup, + .rx_queue_release = eth_queue_release, + .tx_queue_release = eth_queue_release, + .link_update = eth_link_update, + .stats_get = eth_stats_get, + .stats_reset = eth_stats_reset, + .mac_addr_remove = eth_mac_addr_remove, + .mac_addr_add = eth_mac_addr_add, }; int -rte_eth_from_rings(struct rte_ring *const rx_queues[], +rte_eth_from_rings(const char *name, struct rte_ring *const rx_queues[], const unsigned nb_rx_queues, struct rte_ring *const tx_queues[], const unsigned nb_tx_queues, @@ -218,9 +263,12 @@ rte_eth_from_rings(struct rte_ring *const rx_queues[], struct rte_pci_device *pci_dev = NULL; struct pmd_internals *internals = NULL; struct rte_eth_dev *eth_dev = NULL; + struct eth_driver *eth_drv = NULL; + struct rte_pci_id *id_table = NULL; + unsigned i; - /* do some paramter checking */ + /* do some parameter checking */ if (rx_queues == NULL && nb_rx_queues > 0) goto error; if (tx_queues == NULL && nb_tx_queues > 0) @@ -232,23 +280,31 @@ rte_eth_from_rings(struct rte_ring *const rx_queues[], /* now do all data allocation - for eth_dev structure, dummy pci driver * and internal (private) data */ - data = rte_zmalloc_socket(NULL, sizeof(*data), 0, numa_node); + data = rte_zmalloc_socket(name, sizeof(*data), 0, numa_node); if (data == NULL) goto error; - pci_dev = rte_zmalloc_socket(NULL, sizeof(*pci_dev), 0, numa_node); + pci_dev = rte_zmalloc_socket(name, sizeof(*pci_dev), 0, numa_node); if (pci_dev == NULL) goto error; - internals = rte_zmalloc_socket(NULL, sizeof(*internals), 0, numa_node); + id_table = rte_zmalloc_socket(name, sizeof(*id_table), 0, numa_node); + if (id_table == NULL) + goto error; + + internals = rte_zmalloc_socket(name, sizeof(*internals), 0, numa_node); if (internals == NULL) goto error; /* reserve an ethdev entry */ - eth_dev = rte_eth_dev_allocate(); + eth_dev = rte_eth_dev_allocate(name, RTE_ETH_DEV_VIRTUAL); if (eth_dev == NULL) goto error; + eth_drv = rte_zmalloc_socket(name, sizeof(*eth_drv), 0, numa_node); + if (eth_drv == NULL) + goto error; + /* now put it all together * - store queue data in internals, * - store numa_node info in pci_driver @@ -267,18 +323,24 @@ rte_eth_from_rings(struct rte_ring *const rx_queues[], internals->tx_ring_queues[i].rng = tx_queues[i]; } + eth_drv->pci_drv.name = ring_ethdev_driver_name; + eth_drv->pci_drv.id_table = id_table; + pci_dev->numa_node = numa_node; + pci_dev->driver = ð_drv->pci_drv; data->dev_private = internals; data->port_id = eth_dev->data->port_id; data->nb_rx_queues = (uint16_t)nb_rx_queues; data->nb_tx_queues = (uint16_t)nb_tx_queues; data->dev_link = pmd_link; - data->mac_addrs = ð_addr; + data->mac_addrs = &internals->address; - eth_dev ->data = data; - eth_dev ->dev_ops = &ops; - eth_dev ->pci_dev = pci_dev; + eth_dev->data = data; + eth_dev->driver = eth_drv; + eth_dev->dev_ops = &ops; + eth_dev->pci_dev = pci_dev; + TAILQ_INIT(&(eth_dev->link_intr_cbs)); /* finally assign rx and tx ops */ eth_dev->rx_pkt_burst = eth_ring_rx; @@ -287,12 +349,10 @@ rte_eth_from_rings(struct rte_ring *const rx_queues[], return 0; error: - if (data) - rte_free(data); - if (pci_dev) - rte_free(pci_dev); - if (internals) - rte_free(internals); + rte_free(data); + rte_free(pci_dev); + rte_free(internals); + return -1; } @@ -315,7 +375,7 @@ eth_dev_ring_create(const char *name, const unsigned numa_node, RTE_PMD_RING_MAX_TX_RINGS); for (i = 0; i < num_rings; i++) { - rte_snprintf(rng_name, sizeof(rng_name), "ETH_RXTX%u_%s", i, name); + snprintf(rng_name, sizeof(rng_name), "ETH_RXTX%u_%s", i, name); rxtx[i] = (action == DEV_CREATE) ? rte_ring_create(rng_name, 1024, numa_node, RING_F_SP_ENQ|RING_F_SC_DEQ) : @@ -324,7 +384,7 @@ eth_dev_ring_create(const char *name, const unsigned numa_node, return -1; } - if (rte_eth_from_rings(rxtx, num_rings, rxtx, num_rings, numa_node)) + if (rte_eth_from_rings(name, rxtx, num_rings, rxtx, num_rings, numa_node)) return -1; return 0; @@ -341,29 +401,31 @@ eth_dev_ring_pair_create(const char *name, const unsigned numa_node, struct rte_ring *rx[RTE_PMD_RING_MAX_RX_RINGS]; struct rte_ring *tx[RTE_PMD_RING_MAX_TX_RINGS]; unsigned i; - char rng_name[RTE_RING_NAMESIZE]; + char rx_rng_name[RTE_RING_NAMESIZE]; + char tx_rng_name[RTE_RING_NAMESIZE]; unsigned num_rings = RTE_MIN(RTE_PMD_RING_MAX_RX_RINGS, RTE_PMD_RING_MAX_TX_RINGS); for (i = 0; i < num_rings; i++) { - rte_snprintf(rng_name, sizeof(rng_name), "ETH_RX%u_%s", i, name); + snprintf(rx_rng_name, sizeof(rx_rng_name), "ETH_RX%u_%s", i, name); rx[i] = (action == DEV_CREATE) ? - rte_ring_create(rng_name, 1024, numa_node, + rte_ring_create(rx_rng_name, 1024, numa_node, RING_F_SP_ENQ|RING_F_SC_DEQ) : - rte_ring_lookup(rng_name); + rte_ring_lookup(rx_rng_name); if (rx[i] == NULL) return -1; - rte_snprintf(rng_name, sizeof(rng_name), "ETH_TX%u_%s", i, name); + snprintf(tx_rng_name, sizeof(tx_rng_name), "ETH_TX%u_%s", i, name); tx[i] = (action == DEV_CREATE) ? - rte_ring_create(rng_name, 1024, numa_node, + rte_ring_create(tx_rng_name, 1024, numa_node, RING_F_SP_ENQ|RING_F_SC_DEQ): - rte_ring_lookup(rng_name); + rte_ring_lookup(tx_rng_name); if (tx[i] == NULL) return -1; } - if (rte_eth_from_rings(rx, num_rings, tx, num_rings, numa_node) || - rte_eth_from_rings(tx, num_rings, rx, num_rings, numa_node) ) + if (rte_eth_from_rings(rx_rng_name, rx, num_rings, tx, num_rings, + numa_node) || rte_eth_from_rings(tx_rng_name, tx, num_rings, rx, + num_rings, numa_node)) return -1; return 0; @@ -372,24 +434,146 @@ eth_dev_ring_pair_create(const char *name, const unsigned numa_node, int rte_eth_ring_pair_create(const char *name, const unsigned numa_node) { + RTE_LOG(WARNING, PMD, "rte_eth_ring_pair_create is deprecated\n"); return eth_dev_ring_pair_create(name, numa_node, DEV_CREATE); } int rte_eth_ring_pair_attach(const char *name, const unsigned numa_node) { + RTE_LOG(WARNING, PMD, "rte_eth_ring_pair_attach is deprecated\n"); return eth_dev_ring_pair_create(name, numa_node, DEV_ATTACH); } -int -rte_pmd_ring_init(const char *name, const char *params) +struct node_action_pair { + char name[PATH_MAX]; + unsigned node; + enum dev_action action; +}; + +struct node_action_list { + unsigned total; + unsigned count; + struct node_action_pair *list; +}; + +static int parse_kvlist (const char *key __rte_unused, const char *value, void *data) { - if (params == NULL) + struct node_action_list *info = data; + int ret; + char *name; + char *action; + char *node; + char *end; + + name = strdup(value); + + ret = -EINVAL; + + if (!name) { + RTE_LOG(WARNING, PMD, "command line paramter is empty for ring pmd!\n"); + goto out; + } + + node = strchr(name, ':'); + if (!node) { + RTE_LOG(WARNING, PMD, "could not parse node value from %s", name); + goto out; + } + + *node = '\0'; + node++; + + action = strchr(node, ':'); + if (!action) { + RTE_LOG(WARNING, PMD, "could not action value from %s", node); + goto out; + } + + *action = '\0'; + action++; + + /* + * Need to do some sanity checking here + */ + + if (strcmp(action, ETH_RING_ACTION_ATTACH) == 0) + info->list[info->count].action = DEV_ATTACH; + else if (strcmp(action, ETH_RING_ACTION_CREATE) == 0) + info->list[info->count].action = DEV_CREATE; + else + goto out; + + errno = 0; + info->list[info->count].node = strtol(node, &end, 10); + + if ((errno != 0) || (*end != '\0')) { + RTE_LOG(WARNING, PMD, "node value %s is unparseable as a number\n", node); + goto out; + } + + snprintf(info->list[info->count].name, sizeof(info->list[info->count].name), "%s", name); + + info->count++; + + ret = 0; +out: + free(name); + return ret; +} + +static int +rte_pmd_ring_devinit(const char *name, const char *params) +{ + struct rte_kvargs *kvlist = NULL; + int ret = 0; + struct node_action_list *info = NULL; + + RTE_LOG(INFO, PMD, "Initializing pmd_ring for %s\n", name); + + if (params == NULL || params[0] == '\0') eth_dev_ring_create(name, rte_socket_id(), DEV_CREATE); else { - RTE_LOG(INFO, PMD, "Ignoring unsupported parameters when creating" - " rings-backed ethernet device\n"); - eth_dev_ring_create(name, rte_socket_id(), DEV_CREATE); + kvlist = rte_kvargs_parse(params, valid_arguments); + + if (!kvlist) { + RTE_LOG(INFO, PMD, "Ignoring unsupported parameters when creating" + " rings-backed ethernet device\n"); + eth_dev_ring_create(name, rte_socket_id(), DEV_CREATE); + return 0; + } else { + ret = rte_kvargs_count(kvlist, ETH_RING_NUMA_NODE_ACTION_ARG); + info = rte_zmalloc("struct node_action_list", sizeof(struct node_action_list) + + (sizeof(struct node_action_pair) * ret), 0); + if (!info) + goto out_free; + + info->total = ret; + info->list = (struct node_action_pair*)(info + 1); + + ret = rte_kvargs_process(kvlist, ETH_RING_NUMA_NODE_ACTION_ARG, + parse_kvlist, info); + + if (ret < 0) + goto out_free; + + for (info->count = 0; info->count < info->total; info->count++) { + eth_dev_ring_create(name, info->list[info->count].node, + info->list[info->count].action); + } + } } - return 0; + +out_free: + rte_kvargs_free(kvlist); + rte_free(info); + return ret; } + +static struct rte_driver pmd_ring_drv = { + .name = "eth_ring", + .type = PMD_VDEV, + .init = rte_pmd_ring_devinit, +}; + +PMD_REGISTER_DRIVER(pmd_ring_drv);