+}
+
+static void get_max_link_speed(struct prox_port_cfg *port_cfg)
+{
+ port_cfg->max_link_speed = UINT32_MAX;
+
+#if RTE_VERSION >= RTE_VERSION_NUM(16,4,0,0)
+ // virtio and vmxnet3 reports fake max_link_speed
+ if (strcmp(port_cfg->short_name, "vmxnet3") && strcmp(port_cfg->short_name, "virtio")) {
+ // Get link_speed from highest capability from the port
+ // This will be used by gen and lat for extrapolation purposes
+ // The negotiated link_speed (as reported by rte_eth_link_get
+ // or rte_eth_link_get_nowait) might be reported too late
+ // and might result in wrong exrapolation, and hence should not be used
+ // for extrapolation purposes
+ if (port_cfg->dev_info.speed_capa & ETH_LINK_SPEED_100G)
+ port_cfg->max_link_speed = ETH_SPEED_NUM_100G;
+ else if (port_cfg->dev_info.speed_capa & ETH_LINK_SPEED_56G)
+ port_cfg->max_link_speed = ETH_SPEED_NUM_56G;
+ else if (port_cfg->dev_info.speed_capa & ETH_LINK_SPEED_50G)
+ port_cfg->max_link_speed = ETH_SPEED_NUM_50G;
+ else if (port_cfg->dev_info.speed_capa & ETH_LINK_SPEED_40G)
+ port_cfg->max_link_speed = ETH_SPEED_NUM_40G;
+ else if (port_cfg->dev_info.speed_capa & ETH_LINK_SPEED_25G)
+ port_cfg->max_link_speed = ETH_SPEED_NUM_25G;
+ else if (port_cfg->dev_info.speed_capa & ETH_LINK_SPEED_20G)
+ port_cfg->max_link_speed = ETH_SPEED_NUM_20G;
+ else if (port_cfg->dev_info.speed_capa & ETH_LINK_SPEED_10G)
+ port_cfg->max_link_speed = ETH_SPEED_NUM_10G;
+ else if (port_cfg->dev_info.speed_capa & ETH_LINK_SPEED_5G)
+ port_cfg->max_link_speed = ETH_SPEED_NUM_5G;
+ else if (port_cfg->dev_info.speed_capa & ETH_LINK_SPEED_2_5G)
+ port_cfg->max_link_speed = ETH_SPEED_NUM_2_5G;
+ else if (port_cfg->dev_info.speed_capa & ETH_LINK_SPEED_1G)
+ port_cfg->max_link_speed = ETH_SPEED_NUM_1G;
+ else if (port_cfg->dev_info.speed_capa & (ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M))
+ port_cfg->max_link_speed = ETH_SPEED_NUM_100M;
+ else if (port_cfg->dev_info.speed_capa & (ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M))
+ port_cfg->max_link_speed = ETH_SPEED_NUM_10M;
+
+ }
+#endif
+}
+
+static void init_port(struct prox_port_cfg *port_cfg)
+{
+ static char dummy_pool_name[] = "0_dummy";
+ struct rte_eth_link link;
+ uint8_t port_id;
+ int ret;
+
+ get_max_link_speed(port_cfg);
+ print_port_capa(port_cfg);
+ port_id = port_cfg - prox_port_cfg;
+ PROX_PANIC(port_cfg->n_rxq == 0 && port_cfg->n_txq == 0,
+ "\t\t port %u is enabled but no RX or TX queues have been configured", port_id);
+
+ if (port_cfg->n_rxq == 0) {
+ /* not receiving on this port */
+ plog_info("\t\tPort %u had no RX queues, setting to 1\n", port_id);
+ port_cfg->n_rxq = 1;
+ uint32_t mbuf_size = TX_MBUF_SIZE;
+ plog_info("\t\tAllocating dummy memory pool on socket %u with %u elements of size %u\n",
+ port_cfg->socket, port_cfg->n_rxd, mbuf_size);
+ port_cfg->pool[0] = rte_mempool_create(dummy_pool_name, port_cfg->n_rxd, mbuf_size,
+ 0,
+ sizeof(struct rte_pktmbuf_pool_private),
+ rte_pktmbuf_pool_init, NULL,
+ prox_pktmbuf_init, 0,
+ port_cfg->socket, 0);
+ PROX_PANIC(port_cfg->pool[0] == NULL, "Failed to allocate dummy memory pool on socket %u with %u elements\n",
+ port_cfg->socket, port_cfg->n_rxd);
+ dummy_pool_name[0]++;
+ } else {
+ // Most pmd should now support setting mtu
+ if (port_cfg->mtu + ETHER_HDR_LEN + ETHER_CRC_LEN > port_cfg->max_rx_pkt_len) {
+ plog_info("\t\tMTU is too big for the port, reducing MTU from %d to %d\n", port_cfg->mtu, port_cfg->max_rx_pkt_len);
+ port_cfg->mtu = port_cfg->max_rx_pkt_len;
+ }
+ plog_info("\t\tSetting MTU size to %u for port %u ...\n", port_cfg->mtu, port_id);
+ ret = rte_eth_dev_set_mtu(port_id, port_cfg->mtu);
+ if (ret)
+ plog_err("\t\t\trte_eth_dev_set_mtu() failed on port %u: error %d\n", port_id, ret);
+
+ if (port_cfg->n_txq == 0) {
+ /* not sending on this port */
+ plog_info("\t\tPort %u had no TX queues, setting to 1\n", port_id);
+ port_cfg->n_txq = 1;
+ }
+ }
+
+ if (port_cfg->n_rxq > 1) {
+ // Enable RSS if multiple receive queues
+ port_cfg->port_conf.rxmode.mq_mode |= ETH_MQ_RX_RSS;
+ port_cfg->port_conf.rx_adv_conf.rss_conf.rss_key = toeplitz_init_key;
+ port_cfg->port_conf.rx_adv_conf.rss_conf.rss_key_len = TOEPLITZ_KEY_LEN;
+#if RTE_VERSION >= RTE_VERSION_NUM(2,0,0,0)
+ port_cfg->port_conf.rx_adv_conf.rss_conf.rss_hf = ETH_RSS_IP|ETH_RSS_UDP;
+#else
+ port_cfg->port_conf.rx_adv_conf.rss_conf.rss_hf = ETH_RSS_IPV4|ETH_RSS_NONF_IPV4_UDP;
+#endif
+ }
+
+ // Make sure that the requested RSS offload is supported by the PMD
+#if RTE_VERSION >= RTE_VERSION_NUM(2,0,0,0)
+ port_cfg->port_conf.rx_adv_conf.rss_conf.rss_hf &= port_cfg->dev_info.flow_type_rss_offloads;
+#endif
+ plog_info("\t\t Enabling RSS rss_hf = 0x%lx (requested 0x%llx)\n", port_cfg->port_conf.rx_adv_conf.rss_conf.rss_hf, ETH_RSS_IP|ETH_RSS_UDP);