static int init_port()

in metron-sensors/fastcapa/src/nic.c [59:152]


static int init_port(
    const uint8_t port_id,
    struct rte_mempool* mem_pool,
    const uint16_t nb_rx_queue,
    const uint16_t nb_rx_desc)
{
    struct rte_eth_conf rx_conf = rx_conf_default;
    struct rte_eth_txconf tx_conf = tx_conf_default;
    int retval;
    uint16_t q;
    int retry = 5;
    const uint16_t tx_queues = 1;
    int socket;
    struct rte_eth_dev_info dev_info;

    if (port_id >= rte_eth_dev_count()) {
        rte_exit(EXIT_FAILURE, "Port does not exist; port=%u \n", port_id);
        return -1;
    }

    // check that the number of RX queues does not exceed what is supported by the device
    rte_eth_dev_info_get(port_id, &dev_info);
    if (nb_rx_queue > dev_info.max_rx_queues) {
        rte_exit(EXIT_FAILURE, "Too many RX queues for device; port=%u, rx_queues=%u, max_queues=%u \n",
            port_id, nb_rx_queue, dev_info.max_rx_queues);
        return -EINVAL;
    }

    // check that the number of TX queues does not exceed what is supported by the device
    if (tx_queues > dev_info.max_tx_queues) {
        rte_exit(EXIT_FAILURE, "Too many TX queues for device; port=%u, tx_queues=%u, max_queues=%u \n",
            port_id, tx_queues, dev_info.max_tx_queues);
        return -EINVAL;
    }

    retval = rte_eth_dev_configure(port_id, nb_rx_queue, tx_queues, &rx_conf);
    if (retval != 0) {
        rte_exit(EXIT_FAILURE, "Cannot configure device; port=%u, err=%s \n", port_id, strerror(-retval));
        return retval;
    }

    // create the receive queues
    socket = rte_eth_dev_socket_id(port_id);
    for (q = 0; q < nb_rx_queue; q++) {
        retval = rte_eth_rx_queue_setup(port_id, q, nb_rx_desc, socket, NULL, mem_pool);
        if (retval != 0) {
            rte_exit(EXIT_FAILURE, "Cannot setup RX queue; port=%u, err=%s \n", port_id, strerror(-retval));
            return retval;
        }
    }

    // create the transmit queues - at least one TX queue must be setup even though we don't use it
    for (q = 0; q < tx_queues; q++) {
        retval = rte_eth_tx_queue_setup(port_id, q, TX_QUEUE_SIZE, socket, &tx_conf);
        if (retval != 0) {
            rte_exit(EXIT_FAILURE, "Cannot setup TX queue; port=%u, err=%s \n", port_id, strerror(-retval));
            return retval;
        }
    }

    // start the receive and transmit units on the device
    retval = rte_eth_dev_start(port_id);
    if (retval < 0) {
        rte_exit(EXIT_FAILURE, "Cannot start device; port=%u, err=%s \n", port_id, strerror(-retval));
        return retval;
    }

    // retrieve information about the device
    struct rte_eth_link link;
    do {
        rte_eth_link_get_nowait(port_id, &link);

    } while (retry-- > 0 && !link.link_status && !sleep(1));

    // if still no link information, must be down
    if (!link.link_status) {
        rte_exit(EXIT_FAILURE, "Link down; port=%u \n", port_id);
        return 0;
    }

    // enable promisc mode
    rte_eth_promiscuous_enable(port_id);

    // print diagnostics
    struct ether_addr addr;
    rte_eth_macaddr_get(port_id, &addr);
    LOG_INFO(USER1, "Device setup successfully; port=%u, mac=%02" PRIx8 " %02" PRIx8 " %02" PRIx8 " %02" PRIx8 " %02" PRIx8 " %02" PRIx8 "\n",
        (unsigned int) port_id,
        addr.addr_bytes[0], addr.addr_bytes[1],
        addr.addr_bytes[2], addr.addr_bytes[3],
        addr.addr_bytes[4], addr.addr_bytes[5]);

    return 0;
}