176404edcSAsim Jamshed /* for io_module_func def'ns */ 276404edcSAsim Jamshed #include "io_module.h" 376404edcSAsim Jamshed /* for mtcp related def'ns */ 476404edcSAsim Jamshed #include "mtcp.h" 576404edcSAsim Jamshed /* for errno */ 676404edcSAsim Jamshed #include <errno.h> 7dcdbbb98SAsim Jamshed /* for close/optind */ 8dcdbbb98SAsim Jamshed #include <unistd.h> 976404edcSAsim Jamshed /* for logging */ 1076404edcSAsim Jamshed #include "debug.h" 1176404edcSAsim Jamshed /* for num_devices_* */ 1276404edcSAsim Jamshed #include "config.h" 1376404edcSAsim Jamshed /* for rte_max_eth_ports */ 1476404edcSAsim Jamshed #include <rte_common.h> 1576404edcSAsim Jamshed /* for rte_eth_rxconf */ 1676404edcSAsim Jamshed #include <rte_ethdev.h> 1776404edcSAsim Jamshed /* for delay funcs */ 1876404edcSAsim Jamshed #include <rte_cycles.h> 1976404edcSAsim Jamshed /* for ip pesudo-chksum */ 2076404edcSAsim Jamshed #include <rte_ip.h> 2176404edcSAsim Jamshed #define ENABLE_STATS_IOCTL 1 2276404edcSAsim Jamshed #ifdef ENABLE_STATS_IOCTL 2376404edcSAsim Jamshed /* for open */ 2476404edcSAsim Jamshed #include <fcntl.h> 2576404edcSAsim Jamshed /* for ioctl */ 2676404edcSAsim Jamshed #include <sys/ioctl.h> 2776404edcSAsim Jamshed #endif /* !ENABLE_STATS_IOCTL */ 2876404edcSAsim Jamshed /*----------------------------------------------------------------------------*/ 2976404edcSAsim Jamshed /* Essential macros */ 3076404edcSAsim Jamshed #define MAX_RX_QUEUE_PER_LCORE MAX_CPUS 3176404edcSAsim Jamshed #define MAX_TX_QUEUE_PER_PORT MAX_CPUS 3276404edcSAsim Jamshed 3376404edcSAsim Jamshed #define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM) 3476404edcSAsim Jamshed #define NB_MBUF 8192 3576404edcSAsim Jamshed #define MEMPOOL_CACHE_SIZE 256 36a5e1a556SAsim Jamshed //#define RX_IDLE_ENABLE 1 37a5e1a556SAsim Jamshed #define RX_IDLE_TIMEOUT 1 /* in micro-seconds */ 38a5e1a556SAsim Jamshed #define RX_IDLE_THRESH 64 3976404edcSAsim Jamshed 4076404edcSAsim Jamshed /* 4176404edcSAsim Jamshed * RX and TX Prefetch, Host, and Write-back threshold values should be 4276404edcSAsim Jamshed * carefully set for optimal performance. Consult the network 4376404edcSAsim Jamshed * controller's datasheet and supporting DPDK documentation for guidance 4476404edcSAsim Jamshed * on how these parameters should be set. 4576404edcSAsim Jamshed */ 4676404edcSAsim Jamshed #define RX_PTHRESH 8 /**< Default values of RX prefetch threshold reg. */ 4776404edcSAsim Jamshed #define RX_HTHRESH 8 /**< Default values of RX host threshold reg. */ 4876404edcSAsim Jamshed #define RX_WTHRESH 4 /**< Default values of RX write-back threshold reg. */ 4976404edcSAsim Jamshed 5076404edcSAsim Jamshed /* 5176404edcSAsim Jamshed * These default values are optimized for use with the Intel(R) 82599 10 GbE 5276404edcSAsim Jamshed * Controller and the DPDK ixgbe PMD. Consider using other values for other 5376404edcSAsim Jamshed * network controllers and/or network drivers. 5476404edcSAsim Jamshed */ 5576404edcSAsim Jamshed #define TX_PTHRESH 36 /**< Default values of TX prefetch threshold reg. */ 5676404edcSAsim Jamshed #define TX_HTHRESH 0 /**< Default values of TX host threshold reg. */ 5776404edcSAsim Jamshed #define TX_WTHRESH 0 /**< Default values of TX write-back threshold reg. */ 5876404edcSAsim Jamshed 5976404edcSAsim Jamshed #define MAX_PKT_BURST /*32*/64/*128*//*32*/ 6076404edcSAsim Jamshed 6176404edcSAsim Jamshed /* 6276404edcSAsim Jamshed * Configurable number of RX/TX ring descriptors 6376404edcSAsim Jamshed */ 6476404edcSAsim Jamshed #define RTE_TEST_RX_DESC_DEFAULT 128 6576404edcSAsim Jamshed #define RTE_TEST_TX_DESC_DEFAULT 512 6676404edcSAsim Jamshed 6776404edcSAsim Jamshed static uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; 6876404edcSAsim Jamshed static uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; 6976404edcSAsim Jamshed /*----------------------------------------------------------------------------*/ 7076404edcSAsim Jamshed /* packet memory pools for storing packet bufs */ 7176404edcSAsim Jamshed static struct rte_mempool *pktmbuf_pool[MAX_CPUS] = {NULL}; 7276404edcSAsim Jamshed static uint8_t cpu_qid_map[RTE_MAX_ETHPORTS][MAX_CPUS] = {{0}}; 7376404edcSAsim Jamshed 7476404edcSAsim Jamshed //#define DEBUG 1 7576404edcSAsim Jamshed #ifdef DEBUG 7676404edcSAsim Jamshed /* ethernet addresses of ports */ 7776404edcSAsim Jamshed static struct ether_addr ports_eth_addr[RTE_MAX_ETHPORTS]; 7876404edcSAsim Jamshed #endif 7976404edcSAsim Jamshed 80b88bd7d2SAsim Jamshed static struct rte_eth_dev_info dev_info[RTE_MAX_ETHPORTS]; 81b88bd7d2SAsim Jamshed 8276404edcSAsim Jamshed static struct rte_eth_conf port_conf = { 8376404edcSAsim Jamshed .rxmode = { 8476404edcSAsim Jamshed .mq_mode = ETH_MQ_RX_RSS, 8576404edcSAsim Jamshed .max_rx_pkt_len = ETHER_MAX_LEN, 8676404edcSAsim Jamshed .split_hdr_size = 0, 8776404edcSAsim Jamshed .header_split = 0, /**< Header Split disabled */ 8876404edcSAsim Jamshed .hw_ip_checksum = 1, /**< IP checksum offload enabled */ 8976404edcSAsim Jamshed .hw_vlan_filter = 0, /**< VLAN filtering disabled */ 9076404edcSAsim Jamshed .jumbo_frame = 0, /**< Jumbo Frame Support disabled */ 9176404edcSAsim Jamshed .hw_strip_crc = 1, /**< CRC stripped by hardware */ 9276404edcSAsim Jamshed }, 9376404edcSAsim Jamshed .rx_adv_conf = { 9476404edcSAsim Jamshed .rss_conf = { 9576404edcSAsim Jamshed .rss_key = NULL, 96b2b18834SAsim Jamshed .rss_hf = ETH_RSS_TCP | ETH_RSS_UDP | 97b2b18834SAsim Jamshed ETH_RSS_IP | ETH_RSS_L2_PAYLOAD 9876404edcSAsim Jamshed }, 9976404edcSAsim Jamshed }, 10076404edcSAsim Jamshed .txmode = { 10176404edcSAsim Jamshed .mq_mode = ETH_MQ_TX_NONE, 10276404edcSAsim Jamshed }, 10376404edcSAsim Jamshed }; 10476404edcSAsim Jamshed 10576404edcSAsim Jamshed static const struct rte_eth_rxconf rx_conf = { 10676404edcSAsim Jamshed .rx_thresh = { 10776404edcSAsim Jamshed .pthresh = RX_PTHRESH, /* RX prefetch threshold reg */ 10876404edcSAsim Jamshed .hthresh = RX_HTHRESH, /* RX host threshold reg */ 10976404edcSAsim Jamshed .wthresh = RX_WTHRESH, /* RX write-back threshold reg */ 11076404edcSAsim Jamshed }, 11176404edcSAsim Jamshed .rx_free_thresh = 32, 11276404edcSAsim Jamshed }; 11376404edcSAsim Jamshed 11476404edcSAsim Jamshed static const struct rte_eth_txconf tx_conf = { 11576404edcSAsim Jamshed .tx_thresh = { 11676404edcSAsim Jamshed .pthresh = TX_PTHRESH, /* TX prefetch threshold reg */ 11776404edcSAsim Jamshed .hthresh = TX_HTHRESH, /* TX host threshold reg */ 11876404edcSAsim Jamshed .wthresh = TX_WTHRESH, /* TX write-back threshold reg */ 11976404edcSAsim Jamshed }, 12076404edcSAsim Jamshed .tx_free_thresh = 0, /* Use PMD default values */ 12176404edcSAsim Jamshed .tx_rs_thresh = 0, /* Use PMD default values */ 12276404edcSAsim Jamshed /* 12376404edcSAsim Jamshed * As the example won't handle mult-segments and offload cases, 12476404edcSAsim Jamshed * set the flag by default. 12576404edcSAsim Jamshed */ 12676404edcSAsim Jamshed .txq_flags = 0x0, 12776404edcSAsim Jamshed }; 12876404edcSAsim Jamshed 12976404edcSAsim Jamshed struct mbuf_table { 13076404edcSAsim Jamshed unsigned len; /* length of queued packets */ 13176404edcSAsim Jamshed struct rte_mbuf *m_table[MAX_PKT_BURST]; 13276404edcSAsim Jamshed }; 13376404edcSAsim Jamshed 13476404edcSAsim Jamshed struct dpdk_private_context { 13576404edcSAsim Jamshed struct mbuf_table rmbufs[RTE_MAX_ETHPORTS]; 13676404edcSAsim Jamshed struct mbuf_table wmbufs[RTE_MAX_ETHPORTS]; 13776404edcSAsim Jamshed struct rte_mempool *pktmbuf_pool; 13876404edcSAsim Jamshed struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; 139a5e1a556SAsim Jamshed #ifdef RX_IDLE_ENABLE 140a5e1a556SAsim Jamshed uint8_t rx_idle; 141a5e1a556SAsim Jamshed #endif 14276404edcSAsim Jamshed #ifdef ENABLE_STATS_IOCTL 14376404edcSAsim Jamshed int fd; 14476404edcSAsim Jamshed #endif /* !ENABLE_STATS_IOCTL */ 14576404edcSAsim Jamshed } __rte_cache_aligned; 14676404edcSAsim Jamshed 14776404edcSAsim Jamshed #ifdef ENABLE_STATS_IOCTL 14876404edcSAsim Jamshed /** 14976404edcSAsim Jamshed * stats struct passed on from user space to the driver 15076404edcSAsim Jamshed */ 15176404edcSAsim Jamshed struct stats_struct { 15276404edcSAsim Jamshed uint64_t tx_bytes; 15376404edcSAsim Jamshed uint64_t tx_pkts; 15476404edcSAsim Jamshed uint64_t rx_bytes; 15576404edcSAsim Jamshed uint64_t rx_pkts; 15676404edcSAsim Jamshed uint8_t qid; 15776404edcSAsim Jamshed uint8_t dev; 15876404edcSAsim Jamshed }; 15976404edcSAsim Jamshed #endif /* !ENABLE_STATS_IOCTL */ 16076404edcSAsim Jamshed /*----------------------------------------------------------------------------*/ 16176404edcSAsim Jamshed void 16276404edcSAsim Jamshed dpdk_init_handle(struct mtcp_thread_context *ctxt) 16376404edcSAsim Jamshed { 16476404edcSAsim Jamshed struct dpdk_private_context *dpc; 16576404edcSAsim Jamshed int i, j; 16676404edcSAsim Jamshed char mempool_name[20]; 16776404edcSAsim Jamshed 16876404edcSAsim Jamshed /* create and initialize private I/O module context */ 16976404edcSAsim Jamshed ctxt->io_private_context = calloc(1, sizeof(struct dpdk_private_context)); 17076404edcSAsim Jamshed if (ctxt->io_private_context == NULL) { 17176404edcSAsim Jamshed TRACE_ERROR("Failed to initialize ctxt->io_private_context: " 17276404edcSAsim Jamshed "Can't allocate memory\n"); 17376404edcSAsim Jamshed exit(EXIT_FAILURE); 17476404edcSAsim Jamshed } 17576404edcSAsim Jamshed 17676404edcSAsim Jamshed sprintf(mempool_name, "mbuf_pool-%d", ctxt->cpu); 17776404edcSAsim Jamshed dpc = (struct dpdk_private_context *)ctxt->io_private_context; 17876404edcSAsim Jamshed dpc->pktmbuf_pool = pktmbuf_pool[ctxt->cpu]; 17976404edcSAsim Jamshed 18076404edcSAsim Jamshed /* set wmbufs correctly */ 18176404edcSAsim Jamshed for (j = 0; j < g_config.mos->netdev_table->num; j++) { 18276404edcSAsim Jamshed /* Allocate wmbufs for each registered port */ 18376404edcSAsim Jamshed for (i = 0; i < MAX_PKT_BURST; i++) { 18476404edcSAsim Jamshed dpc->wmbufs[j].m_table[i] = rte_pktmbuf_alloc(pktmbuf_pool[ctxt->cpu]); 18576404edcSAsim Jamshed if (dpc->wmbufs[j].m_table[i] == NULL) { 18676404edcSAsim Jamshed TRACE_ERROR("Failed to allocate %d:wmbuf[%d] on device %d!\n", 18776404edcSAsim Jamshed ctxt->cpu, i, j); 18876404edcSAsim Jamshed exit(EXIT_FAILURE); 18976404edcSAsim Jamshed } 19076404edcSAsim Jamshed } 19176404edcSAsim Jamshed /* set mbufs queue length to 0 to begin with */ 19276404edcSAsim Jamshed dpc->wmbufs[j].len = 0; 19376404edcSAsim Jamshed } 19476404edcSAsim Jamshed 19576404edcSAsim Jamshed #ifdef ENABLE_STATS_IOCTL 19676404edcSAsim Jamshed dpc->fd = open("/dev/dpdk-iface", O_RDWR); 19776404edcSAsim Jamshed if (dpc->fd == -1) { 198c789f6daSAsim Jamshed TRACE_ERROR("Can't open /dev/dpdk-iface for context->cpu: %d! " 199c789f6daSAsim Jamshed "Are you using mlx4/mlx5 driver?\n", 20076404edcSAsim Jamshed ctxt->cpu); 20176404edcSAsim Jamshed } 20276404edcSAsim Jamshed #endif /* !ENABLE_STATS_IOCTL */ 20376404edcSAsim Jamshed } 20476404edcSAsim Jamshed /*----------------------------------------------------------------------------*/ 20576404edcSAsim Jamshed int 20676404edcSAsim Jamshed dpdk_send_pkts(struct mtcp_thread_context *ctxt, int nif) 20776404edcSAsim Jamshed { 20876404edcSAsim Jamshed struct dpdk_private_context *dpc; 20976404edcSAsim Jamshed mtcp_manager_t mtcp; 21076404edcSAsim Jamshed int ret; 21176404edcSAsim Jamshed int qid; 21276404edcSAsim Jamshed 21376404edcSAsim Jamshed dpc = (struct dpdk_private_context *)ctxt->io_private_context; 21476404edcSAsim Jamshed mtcp = ctxt->mtcp_manager; 21576404edcSAsim Jamshed ret = 0; 21676404edcSAsim Jamshed qid = cpu_qid_map[nif][ctxt->cpu]; 21776404edcSAsim Jamshed 21876404edcSAsim Jamshed /* if queue is unassigned, skip it.. */ 21976404edcSAsim Jamshed if (unlikely(qid == 0xFF)) 22076404edcSAsim Jamshed return 0; 22176404edcSAsim Jamshed 22276404edcSAsim Jamshed /* if there are packets in the queue... flush them out to the wire */ 22376404edcSAsim Jamshed if (dpc->wmbufs[nif].len >/*= MAX_PKT_BURST*/ 0) { 22476404edcSAsim Jamshed struct rte_mbuf **pkts; 22576404edcSAsim Jamshed #ifdef ENABLE_STATS_IOCTL 22676404edcSAsim Jamshed struct stats_struct ss; 22776404edcSAsim Jamshed #endif /* !ENABLE_STATS_IOCTL */ 22876404edcSAsim Jamshed int cnt = dpc->wmbufs[nif].len; 22976404edcSAsim Jamshed pkts = dpc->wmbufs[nif].m_table; 23076404edcSAsim Jamshed #ifdef NETSTAT 23176404edcSAsim Jamshed mtcp->nstat.tx_packets[nif] += cnt; 23276404edcSAsim Jamshed #ifdef ENABLE_STATS_IOCTL 233c789f6daSAsim Jamshed if (likely(dpc->fd) >= 0) { 23476404edcSAsim Jamshed ss.tx_pkts = mtcp->nstat.tx_packets[nif]; 23576404edcSAsim Jamshed ss.tx_bytes = mtcp->nstat.tx_bytes[nif]; 23676404edcSAsim Jamshed ss.rx_pkts = mtcp->nstat.rx_packets[nif]; 23776404edcSAsim Jamshed ss.rx_bytes = mtcp->nstat.rx_bytes[nif]; 23876404edcSAsim Jamshed ss.qid = ctxt->cpu; 23976404edcSAsim Jamshed ss.dev = nif; 24076404edcSAsim Jamshed ioctl(dpc->fd, 0, &ss); 241c789f6daSAsim Jamshed } 24276404edcSAsim Jamshed #endif /* !ENABLE_STATS_IOCTL */ 24376404edcSAsim Jamshed #endif 24476404edcSAsim Jamshed do { 24576404edcSAsim Jamshed /* tx cnt # of packets */ 24676404edcSAsim Jamshed ret = rte_eth_tx_burst(nif, qid, 24776404edcSAsim Jamshed pkts, cnt); 24876404edcSAsim Jamshed pkts += ret; 24976404edcSAsim Jamshed cnt -= ret; 25076404edcSAsim Jamshed /* if not all pkts were sent... then repeat the cycle */ 25176404edcSAsim Jamshed } while (cnt > 0); 25276404edcSAsim Jamshed 25376404edcSAsim Jamshed #ifndef SHARE_IO_BUFFER 25476404edcSAsim Jamshed int i; 25576404edcSAsim Jamshed /* time to allocate fresh mbufs for the queue */ 25676404edcSAsim Jamshed for (i = 0; i < dpc->wmbufs[nif].len; i++) { 25776404edcSAsim Jamshed dpc->wmbufs[nif].m_table[i] = rte_pktmbuf_alloc(pktmbuf_pool[ctxt->cpu]); 25876404edcSAsim Jamshed /* error checking */ 25976404edcSAsim Jamshed if (unlikely(dpc->wmbufs[nif].m_table[i] == NULL)) { 26076404edcSAsim Jamshed TRACE_ERROR("Failed to allocate %d:wmbuf[%d] on device %d!\n", 26176404edcSAsim Jamshed ctxt->cpu, i, nif); 26276404edcSAsim Jamshed exit(EXIT_FAILURE); 26376404edcSAsim Jamshed } 26476404edcSAsim Jamshed } 26576404edcSAsim Jamshed #endif 26676404edcSAsim Jamshed /* reset the len of mbufs var after flushing of packets */ 26776404edcSAsim Jamshed dpc->wmbufs[nif].len = 0; 26876404edcSAsim Jamshed } 26976404edcSAsim Jamshed 27076404edcSAsim Jamshed return ret; 27176404edcSAsim Jamshed } 27276404edcSAsim Jamshed /*----------------------------------------------------------------------------*/ 27376404edcSAsim Jamshed uint8_t * 27476404edcSAsim Jamshed dpdk_get_wptr(struct mtcp_thread_context *ctxt, int nif, uint16_t pktsize) 27576404edcSAsim Jamshed { 27676404edcSAsim Jamshed struct dpdk_private_context *dpc; 27776404edcSAsim Jamshed mtcp_manager_t mtcp; 27876404edcSAsim Jamshed struct rte_mbuf *m; 27976404edcSAsim Jamshed uint8_t *ptr; 28076404edcSAsim Jamshed int len_of_mbuf; 28176404edcSAsim Jamshed 28276404edcSAsim Jamshed dpc = (struct dpdk_private_context *) ctxt->io_private_context; 28376404edcSAsim Jamshed mtcp = ctxt->mtcp_manager; 28476404edcSAsim Jamshed 28576404edcSAsim Jamshed /* sanity check */ 28676404edcSAsim Jamshed if (unlikely(dpc->wmbufs[nif].len == MAX_PKT_BURST)) 28776404edcSAsim Jamshed return NULL; 28876404edcSAsim Jamshed 28976404edcSAsim Jamshed len_of_mbuf = dpc->wmbufs[nif].len; 29076404edcSAsim Jamshed m = dpc->wmbufs[nif].m_table[len_of_mbuf]; 29176404edcSAsim Jamshed 29276404edcSAsim Jamshed /* retrieve the right write offset */ 29376404edcSAsim Jamshed ptr = (void *)rte_pktmbuf_mtod(m, struct ether_hdr *); 29476404edcSAsim Jamshed m->pkt_len = m->data_len = pktsize; 29576404edcSAsim Jamshed m->nb_segs = 1; 29676404edcSAsim Jamshed m->next = NULL; 29776404edcSAsim Jamshed 29876404edcSAsim Jamshed #ifdef NETSTAT 299a834ea89SAsim Jamshed mtcp->nstat.tx_bytes[nif] += pktsize + ETHER_OVR; 30076404edcSAsim Jamshed #endif 30176404edcSAsim Jamshed 30276404edcSAsim Jamshed /* increment the len_of_mbuf var */ 30376404edcSAsim Jamshed dpc->wmbufs[nif].len = len_of_mbuf + 1; 30476404edcSAsim Jamshed 30576404edcSAsim Jamshed return (uint8_t *)ptr; 30676404edcSAsim Jamshed } 30776404edcSAsim Jamshed /*----------------------------------------------------------------------------*/ 30876404edcSAsim Jamshed void 30976404edcSAsim Jamshed dpdk_set_wptr(struct mtcp_thread_context *ctxt, int out_nif, int in_nif, int index) 31076404edcSAsim Jamshed { 31176404edcSAsim Jamshed struct dpdk_private_context *dpc; 31276404edcSAsim Jamshed mtcp_manager_t mtcp; 31376404edcSAsim Jamshed int len_of_mbuf; 31476404edcSAsim Jamshed 31576404edcSAsim Jamshed dpc = (struct dpdk_private_context *) ctxt->io_private_context; 31676404edcSAsim Jamshed mtcp = ctxt->mtcp_manager; 31776404edcSAsim Jamshed 31876404edcSAsim Jamshed /* sanity check */ 31976404edcSAsim Jamshed if (unlikely(dpc->wmbufs[out_nif].len == MAX_PKT_BURST)) 32076404edcSAsim Jamshed return; 32176404edcSAsim Jamshed 32276404edcSAsim Jamshed len_of_mbuf = dpc->wmbufs[out_nif].len; 32376404edcSAsim Jamshed dpc->wmbufs[out_nif].m_table[len_of_mbuf] = 32476404edcSAsim Jamshed dpc->rmbufs[in_nif].m_table[index]; 32576404edcSAsim Jamshed 32676404edcSAsim Jamshed dpc->wmbufs[out_nif].m_table[len_of_mbuf]->udata64 = 0; 32776404edcSAsim Jamshed 32876404edcSAsim Jamshed #ifdef NETSTAT 329a834ea89SAsim Jamshed mtcp->nstat.tx_bytes[out_nif] += dpc->rmbufs[in_nif].m_table[index]->pkt_len + ETHER_OVR; 33076404edcSAsim Jamshed #endif 33176404edcSAsim Jamshed 33276404edcSAsim Jamshed /* increment the len_of_mbuf var */ 33376404edcSAsim Jamshed dpc->wmbufs[out_nif].len = len_of_mbuf + 1; 33476404edcSAsim Jamshed 33576404edcSAsim Jamshed return; 33676404edcSAsim Jamshed } 33776404edcSAsim Jamshed /*----------------------------------------------------------------------------*/ 33876404edcSAsim Jamshed static inline void 33976404edcSAsim Jamshed free_pkts(struct rte_mbuf **mtable, unsigned len) 34076404edcSAsim Jamshed { 34176404edcSAsim Jamshed int i; 34276404edcSAsim Jamshed 34376404edcSAsim Jamshed /* free the freaking packets */ 34476404edcSAsim Jamshed for (i = 0; i < len; i++) { 34576404edcSAsim Jamshed if (mtable[i]->udata64 == 1) { 34676404edcSAsim Jamshed rte_pktmbuf_free_seg(mtable[i]); 34776404edcSAsim Jamshed RTE_MBUF_PREFETCH_TO_FREE(mtable[i+1]); 34876404edcSAsim Jamshed } 34976404edcSAsim Jamshed } 35076404edcSAsim Jamshed } 35176404edcSAsim Jamshed /*----------------------------------------------------------------------------*/ 35276404edcSAsim Jamshed int32_t 35376404edcSAsim Jamshed dpdk_recv_pkts(struct mtcp_thread_context *ctxt, int ifidx) 35476404edcSAsim Jamshed { 35576404edcSAsim Jamshed struct dpdk_private_context *dpc; 35676404edcSAsim Jamshed int ret; 35776404edcSAsim Jamshed uint8_t qid; 35876404edcSAsim Jamshed 35976404edcSAsim Jamshed dpc = (struct dpdk_private_context *) ctxt->io_private_context; 36076404edcSAsim Jamshed qid = cpu_qid_map[ifidx][ctxt->cpu]; 36176404edcSAsim Jamshed 36276404edcSAsim Jamshed /* if queue is unassigned, skip it.. */ 36376404edcSAsim Jamshed if (qid == 0xFF) 36476404edcSAsim Jamshed return 0; 36576404edcSAsim Jamshed 36676404edcSAsim Jamshed if (dpc->rmbufs[ifidx].len != 0) { 36776404edcSAsim Jamshed free_pkts(dpc->rmbufs[ifidx].m_table, dpc->rmbufs[ifidx].len); 36876404edcSAsim Jamshed dpc->rmbufs[ifidx].len = 0; 36976404edcSAsim Jamshed } 37076404edcSAsim Jamshed 37176404edcSAsim Jamshed ret = rte_eth_rx_burst((uint8_t)ifidx, qid, 37276404edcSAsim Jamshed dpc->pkts_burst, MAX_PKT_BURST); 373a5e1a556SAsim Jamshed #ifdef RX_IDLE_ENABLE 374a5e1a556SAsim Jamshed dpc->rx_idle = (likely(ret != 0)) ? 0 : dpc->rx_idle + 1; 375a5e1a556SAsim Jamshed #endif 37676404edcSAsim Jamshed dpc->rmbufs[ifidx].len = ret; 37776404edcSAsim Jamshed 37876404edcSAsim Jamshed return ret; 37976404edcSAsim Jamshed } 38076404edcSAsim Jamshed /*----------------------------------------------------------------------------*/ 38176404edcSAsim Jamshed uint8_t * 38276404edcSAsim Jamshed dpdk_get_rptr(struct mtcp_thread_context *ctxt, int ifidx, int index, uint16_t *len) 38376404edcSAsim Jamshed { 38476404edcSAsim Jamshed struct dpdk_private_context *dpc; 38576404edcSAsim Jamshed struct rte_mbuf *m; 38676404edcSAsim Jamshed uint8_t *pktbuf; 38776404edcSAsim Jamshed 38876404edcSAsim Jamshed dpc = (struct dpdk_private_context *) ctxt->io_private_context; 38976404edcSAsim Jamshed 39076404edcSAsim Jamshed 39176404edcSAsim Jamshed m = dpc->pkts_burst[index]; 39276404edcSAsim Jamshed /* tag to check if the packet is a local or a forwarded pkt */ 39376404edcSAsim Jamshed m->udata64 = 1; 39476404edcSAsim Jamshed /* don't enable pre-fetching... performance goes down */ 39576404edcSAsim Jamshed //rte_prefetch0(rte_pktmbuf_mtod(m, void *)); 39676404edcSAsim Jamshed *len = m->pkt_len; 39776404edcSAsim Jamshed pktbuf = rte_pktmbuf_mtod(m, uint8_t *); 39876404edcSAsim Jamshed 39976404edcSAsim Jamshed /* enqueue the pkt ptr in mbuf */ 40076404edcSAsim Jamshed dpc->rmbufs[ifidx].m_table[index] = m; 40176404edcSAsim Jamshed 40276404edcSAsim Jamshed return pktbuf; 40376404edcSAsim Jamshed } 40476404edcSAsim Jamshed /*----------------------------------------------------------------------------*/ 40576404edcSAsim Jamshed int 40676404edcSAsim Jamshed dpdk_get_nif(struct ifreq *ifr) 40776404edcSAsim Jamshed { 40876404edcSAsim Jamshed int i; 40976404edcSAsim Jamshed static int num_dev = -1; 41076404edcSAsim Jamshed static struct ether_addr ports_eth_addr[RTE_MAX_ETHPORTS]; 41176404edcSAsim Jamshed /* get mac addr entries of 'detected' dpdk ports */ 41276404edcSAsim Jamshed if (num_dev < 0) { 41376404edcSAsim Jamshed num_dev = rte_eth_dev_count(); 41476404edcSAsim Jamshed for (i = 0; i < num_dev; i++) 41576404edcSAsim Jamshed rte_eth_macaddr_get(i, &ports_eth_addr[i]); 41676404edcSAsim Jamshed } 41776404edcSAsim Jamshed 41876404edcSAsim Jamshed for (i = 0; i < num_dev; i++) 41976404edcSAsim Jamshed if (!memcmp(&ifr->ifr_addr.sa_data[0], &ports_eth_addr[i], ETH_ALEN)) 42076404edcSAsim Jamshed return i; 42176404edcSAsim Jamshed 42276404edcSAsim Jamshed return -1; 42376404edcSAsim Jamshed } 42476404edcSAsim Jamshed /*----------------------------------------------------------------------------*/ 425a5e1a556SAsim Jamshed int32_t 426a5e1a556SAsim Jamshed dpdk_select(struct mtcp_thread_context *ctxt) 427a5e1a556SAsim Jamshed { 428a5e1a556SAsim Jamshed #ifdef RX_IDLE_ENABLE 429a5e1a556SAsim Jamshed struct dpdk_private_context *dpc; 430a5e1a556SAsim Jamshed 431a5e1a556SAsim Jamshed dpc = (struct dpdk_private_context *) ctxt->io_private_context; 432a5e1a556SAsim Jamshed if (dpc->rx_idle > RX_IDLE_THRESH) { 433a5e1a556SAsim Jamshed dpc->rx_idle = 0; 434a5e1a556SAsim Jamshed usleep(RX_IDLE_TIMEOUT); 435a5e1a556SAsim Jamshed } 436a5e1a556SAsim Jamshed #endif 437a5e1a556SAsim Jamshed return 0; 438a5e1a556SAsim Jamshed } 439a5e1a556SAsim Jamshed /*----------------------------------------------------------------------------*/ 44076404edcSAsim Jamshed void 44176404edcSAsim Jamshed dpdk_destroy_handle(struct mtcp_thread_context *ctxt) 44276404edcSAsim Jamshed { 44376404edcSAsim Jamshed struct dpdk_private_context *dpc; 44476404edcSAsim Jamshed int i; 44576404edcSAsim Jamshed 44676404edcSAsim Jamshed dpc = (struct dpdk_private_context *) ctxt->io_private_context; 44776404edcSAsim Jamshed 44876404edcSAsim Jamshed /* free wmbufs */ 44976404edcSAsim Jamshed for (i = 0; i < g_config.mos->netdev_table->num; i++) 45076404edcSAsim Jamshed free_pkts(dpc->wmbufs[i].m_table, MAX_PKT_BURST); 45176404edcSAsim Jamshed 45276404edcSAsim Jamshed #ifdef ENABLE_STATS_IOCTL 45376404edcSAsim Jamshed /* free fd */ 454c789f6daSAsim Jamshed if (dpc->fd >= 0) 45576404edcSAsim Jamshed close(dpc->fd); 45676404edcSAsim Jamshed #endif /* !ENABLE_STATS_IOCTL */ 45776404edcSAsim Jamshed 45876404edcSAsim Jamshed /* free it all up */ 45976404edcSAsim Jamshed free(dpc); 46076404edcSAsim Jamshed } 46176404edcSAsim Jamshed /*----------------------------------------------------------------------------*/ 46276404edcSAsim Jamshed static void 46376404edcSAsim Jamshed check_all_ports_link_status(uint8_t port_num, uint32_t port_mask) 46476404edcSAsim Jamshed { 46576404edcSAsim Jamshed #define CHECK_INTERVAL 100 /* 100ms */ 46676404edcSAsim Jamshed #define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */ 46776404edcSAsim Jamshed 46876404edcSAsim Jamshed uint8_t portid, count, all_ports_up, print_flag = 0; 46976404edcSAsim Jamshed struct rte_eth_link link; 47076404edcSAsim Jamshed 47176404edcSAsim Jamshed printf("\nChecking link status"); 47276404edcSAsim Jamshed fflush(stdout); 47376404edcSAsim Jamshed for (count = 0; count <= MAX_CHECK_TIME; count++) { 47476404edcSAsim Jamshed all_ports_up = 1; 47576404edcSAsim Jamshed for (portid = 0; portid < port_num; portid++) { 47676404edcSAsim Jamshed if ((port_mask & (1 << portid)) == 0) 47776404edcSAsim Jamshed continue; 47876404edcSAsim Jamshed memset(&link, 0, sizeof(link)); 47976404edcSAsim Jamshed rte_eth_link_get_nowait(portid, &link); 48076404edcSAsim Jamshed /* print link status if flag set */ 48176404edcSAsim Jamshed if (print_flag == 1) { 48276404edcSAsim Jamshed if (link.link_status) 48376404edcSAsim Jamshed printf("Port %d Link Up - speed %u " 48476404edcSAsim Jamshed "Mbps - %s\n", (uint8_t)portid, 48576404edcSAsim Jamshed (unsigned)link.link_speed, 48676404edcSAsim Jamshed (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? 48776404edcSAsim Jamshed ("full-duplex") : ("half-duplex\n")); 48876404edcSAsim Jamshed else 48976404edcSAsim Jamshed printf("Port %d Link Down\n", 49076404edcSAsim Jamshed (uint8_t)portid); 49176404edcSAsim Jamshed continue; 49276404edcSAsim Jamshed } 49376404edcSAsim Jamshed /* clear all_ports_up flag if any link down */ 49476404edcSAsim Jamshed if (link.link_status == 0) { 49576404edcSAsim Jamshed all_ports_up = 0; 49676404edcSAsim Jamshed break; 49776404edcSAsim Jamshed } 49876404edcSAsim Jamshed } 49976404edcSAsim Jamshed /* after finally printing all link status, get out */ 50076404edcSAsim Jamshed if (print_flag == 1) 50176404edcSAsim Jamshed break; 50276404edcSAsim Jamshed 50376404edcSAsim Jamshed if (all_ports_up == 0) { 50476404edcSAsim Jamshed printf("."); 50576404edcSAsim Jamshed fflush(stdout); 50676404edcSAsim Jamshed rte_delay_ms(CHECK_INTERVAL); 50776404edcSAsim Jamshed } 50876404edcSAsim Jamshed 50976404edcSAsim Jamshed /* set the print_flag if all ports up or timeout */ 51076404edcSAsim Jamshed if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) { 51176404edcSAsim Jamshed print_flag = 1; 51276404edcSAsim Jamshed printf("done\n"); 51376404edcSAsim Jamshed } 51476404edcSAsim Jamshed } 51576404edcSAsim Jamshed } 51676404edcSAsim Jamshed /*----------------------------------------------------------------------------*/ 51776404edcSAsim Jamshed int32_t 51876404edcSAsim Jamshed dpdk_dev_ioctl(struct mtcp_thread_context *ctx, int nif, int cmd, void *argp) 51976404edcSAsim Jamshed { 52076404edcSAsim Jamshed struct dpdk_private_context *dpc; 52176404edcSAsim Jamshed struct rte_mbuf *m; 52276404edcSAsim Jamshed int len_of_mbuf; 52376404edcSAsim Jamshed struct iphdr *iph; 52476404edcSAsim Jamshed struct tcphdr *tcph; 52576404edcSAsim Jamshed RssInfo *rss_i; 526b88bd7d2SAsim Jamshed void **argpptr = (void **)argp; 527b88bd7d2SAsim Jamshed 528b88bd7d2SAsim Jamshed if (cmd == DRV_NAME) { 529b88bd7d2SAsim Jamshed *argpptr = (void *)dev_info->driver_name; 530b88bd7d2SAsim Jamshed return 0; 531b88bd7d2SAsim Jamshed } 53276404edcSAsim Jamshed 53376404edcSAsim Jamshed iph = (struct iphdr *)argp; 53476404edcSAsim Jamshed dpc = (struct dpdk_private_context *)ctx->io_private_context; 53576404edcSAsim Jamshed len_of_mbuf = dpc->wmbufs[nif].len; 53676404edcSAsim Jamshed rss_i = NULL; 53776404edcSAsim Jamshed 53876404edcSAsim Jamshed switch (cmd) { 53976404edcSAsim Jamshed case PKT_TX_IP_CSUM: 54076404edcSAsim Jamshed m = dpc->wmbufs[nif].m_table[len_of_mbuf - 1]; 541522d5c66SAsim Jamshed m->ol_flags = PKT_TX_IP_CKSUM | PKT_TX_IPV4; 54276404edcSAsim Jamshed m->l2_len = sizeof(struct ether_hdr); 54376404edcSAsim Jamshed m->l3_len = (iph->ihl<<2); 54476404edcSAsim Jamshed break; 54576404edcSAsim Jamshed case PKT_TX_TCP_CSUM: 54676404edcSAsim Jamshed m = dpc->wmbufs[nif].m_table[len_of_mbuf - 1]; 54776404edcSAsim Jamshed tcph = (struct tcphdr *)((unsigned char *)iph + (iph->ihl<<2)); 54876404edcSAsim Jamshed m->ol_flags |= PKT_TX_TCP_CKSUM; 54976404edcSAsim Jamshed tcph->check = rte_ipv4_phdr_cksum((struct ipv4_hdr *)iph, m->ol_flags); 55076404edcSAsim Jamshed break; 55176404edcSAsim Jamshed case PKT_RX_RSS: 55276404edcSAsim Jamshed rss_i = (RssInfo *)argp; 55376404edcSAsim Jamshed m = dpc->pkts_burst[rss_i->pktidx]; 55476404edcSAsim Jamshed rss_i->hash_value = m->hash.rss; 55576404edcSAsim Jamshed break; 55676404edcSAsim Jamshed default: 55776404edcSAsim Jamshed goto dev_ioctl_err; 55876404edcSAsim Jamshed } 55976404edcSAsim Jamshed 56076404edcSAsim Jamshed return 0; 56176404edcSAsim Jamshed dev_ioctl_err: 56276404edcSAsim Jamshed return -1; 56376404edcSAsim Jamshed } 56476404edcSAsim Jamshed /*----------------------------------------------------------------------------*/ 56576404edcSAsim Jamshed void 56676404edcSAsim Jamshed dpdk_load_module_upper_half(void) 56776404edcSAsim Jamshed { 56876404edcSAsim Jamshed int cpu = g_config.mos->num_cores, ret; 56976404edcSAsim Jamshed uint32_t cpumask = 0; 57076404edcSAsim Jamshed char cpumaskbuf[10]; 57176404edcSAsim Jamshed char mem_channels[5]; 57276404edcSAsim Jamshed 57376404edcSAsim Jamshed /* set the log level */ 574*0be44444SAsim Jamshed #if 0 57576404edcSAsim Jamshed rte_set_log_type(RTE_LOGTYPE_PMD, 0); 57676404edcSAsim Jamshed rte_set_log_type(RTE_LOGTYPE_MALLOC, 0); 57776404edcSAsim Jamshed rte_set_log_type(RTE_LOGTYPE_MEMPOOL, 0); 57876404edcSAsim Jamshed rte_set_log_type(RTE_LOGTYPE_RING, 0); 57976404edcSAsim Jamshed rte_set_log_level(RTE_LOG_WARNING); 580*0be44444SAsim Jamshed #else 581*0be44444SAsim Jamshed rte_log_set_level(RTE_LOGTYPE_PMD, 0); 582*0be44444SAsim Jamshed rte_log_set_level(RTE_LOGTYPE_MALLOC, 0); 583*0be44444SAsim Jamshed rte_log_set_level(RTE_LOGTYPE_MEMPOOL, 0); 584*0be44444SAsim Jamshed rte_log_set_level(RTE_LOGTYPE_RING, 0); 585*0be44444SAsim Jamshed rte_log_set_level(RTE_LOG_WARNING, 0); 586*0be44444SAsim Jamshed #endif 58776404edcSAsim Jamshed /* get the cpu mask */ 58876404edcSAsim Jamshed for (ret = 0; ret < cpu; ret++) 58976404edcSAsim Jamshed cpumask = (cpumask | (1 << ret)); 59076404edcSAsim Jamshed sprintf(cpumaskbuf, "%X", cpumask); 59176404edcSAsim Jamshed 59276404edcSAsim Jamshed /* get the mem channels per socket */ 59376404edcSAsim Jamshed if (g_config.mos->nb_mem_channels == 0) { 59476404edcSAsim Jamshed TRACE_ERROR("DPDK module requires # of memory channels " 59576404edcSAsim Jamshed "per socket parameter!\n"); 59676404edcSAsim Jamshed exit(EXIT_FAILURE); 59776404edcSAsim Jamshed } 59876404edcSAsim Jamshed sprintf(mem_channels, "%d", g_config.mos->nb_mem_channels); 59976404edcSAsim Jamshed 60076404edcSAsim Jamshed /* initialize the rte env first, what a waste of implementation effort! */ 60176404edcSAsim Jamshed char *argv[] = {"", 60276404edcSAsim Jamshed "-c", 60376404edcSAsim Jamshed cpumaskbuf, 60476404edcSAsim Jamshed "-n", 60576404edcSAsim Jamshed mem_channels, 60676404edcSAsim Jamshed "--proc-type=auto", 60776404edcSAsim Jamshed "" 60876404edcSAsim Jamshed }; 60976404edcSAsim Jamshed const int argc = 6; 61076404edcSAsim Jamshed 61176404edcSAsim Jamshed /* 61276404edcSAsim Jamshed * re-set getopt extern variable optind. 61376404edcSAsim Jamshed * this issue was a bitch to debug 61476404edcSAsim Jamshed * rte_eal_init() internally uses getopt() syscall 61576404edcSAsim Jamshed * mtcp applications that also use an `external' getopt 61676404edcSAsim Jamshed * will cause a violent crash if optind is not reset to zero 61776404edcSAsim Jamshed * prior to calling the func below... 61876404edcSAsim Jamshed * see man getopt(3) for more details 61976404edcSAsim Jamshed */ 62076404edcSAsim Jamshed optind = 0; 62176404edcSAsim Jamshed 62276404edcSAsim Jamshed /* initialize the dpdk eal env */ 62376404edcSAsim Jamshed ret = rte_eal_init(argc, argv); 62476404edcSAsim Jamshed if (ret < 0) 62576404edcSAsim Jamshed rte_exit(EXIT_FAILURE, "Invalid EAL args!\n"); 62676404edcSAsim Jamshed 62776404edcSAsim Jamshed } 62876404edcSAsim Jamshed /*----------------------------------------------------------------------------*/ 62976404edcSAsim Jamshed void 63076404edcSAsim Jamshed dpdk_load_module_lower_half(void) 63176404edcSAsim Jamshed { 63276404edcSAsim Jamshed int portid, rxlcore_id, ret; 63376404edcSAsim Jamshed struct rte_eth_fc_conf fc_conf; /* for Ethernet flow control settings */ 63476404edcSAsim Jamshed /* setting the rss key */ 63576404edcSAsim Jamshed static const uint8_t key[] = { 63676404edcSAsim Jamshed 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 63776404edcSAsim Jamshed 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 63876404edcSAsim Jamshed 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 639b88bd7d2SAsim Jamshed 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 640b88bd7d2SAsim Jamshed 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 641b88bd7d2SAsim Jamshed 0x05, 0x05 64276404edcSAsim Jamshed }; 64376404edcSAsim Jamshed 64476404edcSAsim Jamshed port_conf.rx_adv_conf.rss_conf.rss_key = (uint8_t *)&key; 64576404edcSAsim Jamshed port_conf.rx_adv_conf.rss_conf.rss_key_len = sizeof(key); 64676404edcSAsim Jamshed 64776404edcSAsim Jamshed /* resetting cpu_qid mapping */ 64876404edcSAsim Jamshed memset(cpu_qid_map, 0xFF, sizeof(cpu_qid_map)); 64976404edcSAsim Jamshed 65076404edcSAsim Jamshed if (!g_config.mos->multiprocess 65176404edcSAsim Jamshed || (g_config.mos->multiprocess && g_config.mos->multiprocess_is_master)) { 65276404edcSAsim Jamshed for (rxlcore_id = 0; rxlcore_id < g_config.mos->num_cores; rxlcore_id++) { 65376404edcSAsim Jamshed char name[20]; 65476404edcSAsim Jamshed sprintf(name, "mbuf_pool-%d", rxlcore_id); 65576404edcSAsim Jamshed /* create the mbuf pools */ 65676404edcSAsim Jamshed pktmbuf_pool[rxlcore_id] = 65776404edcSAsim Jamshed rte_mempool_create(name, NB_MBUF, 65876404edcSAsim Jamshed MBUF_SIZE, MEMPOOL_CACHE_SIZE, 65976404edcSAsim Jamshed sizeof(struct rte_pktmbuf_pool_private), 66076404edcSAsim Jamshed rte_pktmbuf_pool_init, NULL, 66176404edcSAsim Jamshed rte_pktmbuf_init, NULL, 66276404edcSAsim Jamshed rte_lcore_to_socket_id(rxlcore_id), 0); 66376404edcSAsim Jamshed if (pktmbuf_pool[rxlcore_id] == NULL) 66476404edcSAsim Jamshed rte_exit(EXIT_FAILURE, "Cannot init mbuf pool\n"); 66576404edcSAsim Jamshed } 66676404edcSAsim Jamshed 66776404edcSAsim Jamshed /* Initialise each port */ 66876404edcSAsim Jamshed for (portid = 0; portid < g_config.mos->netdev_table->num; portid++) { 66976404edcSAsim Jamshed int num_queue = 0, eth_idx, i, queue_id; 67076404edcSAsim Jamshed for (eth_idx = 0; eth_idx < g_config.mos->netdev_table->num; eth_idx++) 67176404edcSAsim Jamshed if (portid == g_config.mos->netdev_table->ent[eth_idx]->ifindex) 67276404edcSAsim Jamshed break; 67376404edcSAsim Jamshed if (eth_idx == g_config.mos->netdev_table->num) 67476404edcSAsim Jamshed continue; 67576404edcSAsim Jamshed for (i = 0; i < sizeof(uint64_t) * 8; i++) 67676404edcSAsim Jamshed if (g_config.mos->netdev_table->ent[eth_idx]->cpu_mask & (1L << i)) 67776404edcSAsim Jamshed num_queue++; 67876404edcSAsim Jamshed 67976404edcSAsim Jamshed /* set 'num_queues' (used for GetRSSCPUCore() in util.c) */ 68076404edcSAsim Jamshed num_queues = num_queue; 68176404edcSAsim Jamshed 68276404edcSAsim Jamshed /* init port */ 68376404edcSAsim Jamshed printf("Initializing port %u... ", (unsigned) portid); 68476404edcSAsim Jamshed fflush(stdout); 68576404edcSAsim Jamshed ret = rte_eth_dev_configure(portid, num_queue, num_queue, 68676404edcSAsim Jamshed &port_conf); 68776404edcSAsim Jamshed if (ret < 0) 68876404edcSAsim Jamshed rte_exit(EXIT_FAILURE, "Cannot configure device:" 68976404edcSAsim Jamshed "err=%d, port=%u\n", 69076404edcSAsim Jamshed ret, (unsigned) portid); 69176404edcSAsim Jamshed 69276404edcSAsim Jamshed /* init one RX queue per CPU */ 69376404edcSAsim Jamshed fflush(stdout); 69476404edcSAsim Jamshed #ifdef DEBUG 69576404edcSAsim Jamshed rte_eth_macaddr_get(portid, &ports_eth_addr[portid]); 69676404edcSAsim Jamshed #endif 697b88bd7d2SAsim Jamshed /* check port capabilities */ 698b88bd7d2SAsim Jamshed rte_eth_dev_info_get(portid, &dev_info[portid]); 699b88bd7d2SAsim Jamshed 70076404edcSAsim Jamshed queue_id = 0; 70176404edcSAsim Jamshed for (rxlcore_id = 0; rxlcore_id < g_config.mos->num_cores; rxlcore_id++) { 70276404edcSAsim Jamshed if (!(g_config.mos->netdev_table->ent[eth_idx]->cpu_mask & (1L << rxlcore_id))) 70376404edcSAsim Jamshed continue; 70476404edcSAsim Jamshed ret = rte_eth_rx_queue_setup(portid, queue_id, nb_rxd, 70576404edcSAsim Jamshed rte_eth_dev_socket_id(portid), &rx_conf, 70676404edcSAsim Jamshed pktmbuf_pool[rxlcore_id]); 70776404edcSAsim Jamshed if (ret < 0) 70876404edcSAsim Jamshed rte_exit(EXIT_FAILURE, "rte_eth_rx_queue_setup:" 70976404edcSAsim Jamshed "err=%d, port=%u, queueid: %d\n", 71076404edcSAsim Jamshed ret, (unsigned) portid, rxlcore_id); 71176404edcSAsim Jamshed cpu_qid_map[portid][rxlcore_id] = queue_id++; 71276404edcSAsim Jamshed } 71376404edcSAsim Jamshed 71476404edcSAsim Jamshed /* init one TX queue on each port per CPU (this is redundant for 71576404edcSAsim Jamshed * this app) */ 71676404edcSAsim Jamshed fflush(stdout); 71776404edcSAsim Jamshed queue_id = 0; 71876404edcSAsim Jamshed for (rxlcore_id = 0; rxlcore_id < g_config.mos->num_cores; rxlcore_id++) { 71976404edcSAsim Jamshed if (!(g_config.mos->netdev_table->ent[eth_idx]->cpu_mask & (1L << rxlcore_id))) 72076404edcSAsim Jamshed continue; 72176404edcSAsim Jamshed ret = rte_eth_tx_queue_setup(portid, queue_id++, nb_txd, 72276404edcSAsim Jamshed rte_eth_dev_socket_id(portid), &tx_conf); 72376404edcSAsim Jamshed if (ret < 0) 72476404edcSAsim Jamshed rte_exit(EXIT_FAILURE, "rte_eth_tx_queue_setup:" 72576404edcSAsim Jamshed "err=%d, port=%u, queueid: %d\n", 72676404edcSAsim Jamshed ret, (unsigned) portid, rxlcore_id); 72776404edcSAsim Jamshed } 72876404edcSAsim Jamshed 72976404edcSAsim Jamshed /* Start device */ 73076404edcSAsim Jamshed ret = rte_eth_dev_start(portid); 73176404edcSAsim Jamshed if (ret < 0) 73276404edcSAsim Jamshed rte_exit(EXIT_FAILURE, "rte_eth_dev_start:err=%d, port=%u\n", 73376404edcSAsim Jamshed ret, (unsigned) portid); 73476404edcSAsim Jamshed 73576404edcSAsim Jamshed printf("done: \n"); 73676404edcSAsim Jamshed rte_eth_promiscuous_enable(portid); 73776404edcSAsim Jamshed 73876404edcSAsim Jamshed /* retrieve current flow control settings per port */ 73976404edcSAsim Jamshed memset(&fc_conf, 0, sizeof(fc_conf)); 74076404edcSAsim Jamshed ret = rte_eth_dev_flow_ctrl_get(portid, &fc_conf); 74176404edcSAsim Jamshed if (ret != 0) { 74276404edcSAsim Jamshed rte_exit(EXIT_FAILURE, "Failed to get flow control info!\n"); 74376404edcSAsim Jamshed } 74476404edcSAsim Jamshed 74576404edcSAsim Jamshed /* and just disable the rx/tx flow control */ 74676404edcSAsim Jamshed fc_conf.mode = RTE_FC_NONE; 74776404edcSAsim Jamshed ret = rte_eth_dev_flow_ctrl_set(portid, &fc_conf); 74876404edcSAsim Jamshed if (ret != 0) { 74976404edcSAsim Jamshed rte_exit(EXIT_FAILURE, "Failed to set flow control info!: errno: %d\n", 75076404edcSAsim Jamshed ret); 75176404edcSAsim Jamshed } 75276404edcSAsim Jamshed 75376404edcSAsim Jamshed #ifdef DEBUG 75476404edcSAsim Jamshed printf("Port %u, MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n\n", 75576404edcSAsim Jamshed (unsigned) portid, 75676404edcSAsim Jamshed ports_eth_addr[portid].addr_bytes[0], 75776404edcSAsim Jamshed ports_eth_addr[portid].addr_bytes[1], 75876404edcSAsim Jamshed ports_eth_addr[portid].addr_bytes[2], 75976404edcSAsim Jamshed ports_eth_addr[portid].addr_bytes[3], 76076404edcSAsim Jamshed ports_eth_addr[portid].addr_bytes[4], 76176404edcSAsim Jamshed ports_eth_addr[portid].addr_bytes[5]); 76276404edcSAsim Jamshed #endif 7633ae9e016SAsim Jamshed /* only check for link status if the thread is master */ 7643ae9e016SAsim Jamshed check_all_ports_link_status(g_config.mos->netdev_table->num, 0xFFFFFFFF); 76576404edcSAsim Jamshed } 76676404edcSAsim Jamshed } else { /* g_config.mos->multiprocess && !g_config.mos->multiprocess_is_master */ 76776404edcSAsim Jamshed for (rxlcore_id = 0; rxlcore_id < g_config.mos->num_cores; rxlcore_id++) { 76876404edcSAsim Jamshed char name[20]; 76976404edcSAsim Jamshed sprintf(name, "mbuf_pool-%d", rxlcore_id); 77076404edcSAsim Jamshed /* initialize the mbuf pools */ 77176404edcSAsim Jamshed pktmbuf_pool[rxlcore_id] = 77276404edcSAsim Jamshed rte_mempool_lookup(name); 77376404edcSAsim Jamshed if (pktmbuf_pool[rxlcore_id] == NULL) 77476404edcSAsim Jamshed rte_exit(EXIT_FAILURE, "Cannot init mbuf pool\n"); 7753ae9e016SAsim Jamshed for (portid = 0; portid < g_config.mos->netdev_table->num; portid++) 7763ae9e016SAsim Jamshed cpu_qid_map[portid][rxlcore_id] = rxlcore_id; 77776404edcSAsim Jamshed } 7783ae9e016SAsim Jamshed /* set 'num_queues' (used for GetRSSCPUCore() in util.c) */ 7793ae9e016SAsim Jamshed num_queues = g_config.mos->num_cores; 78076404edcSAsim Jamshed } 78176404edcSAsim Jamshed 78276404edcSAsim Jamshed } 78376404edcSAsim Jamshed /*----------------------------------------------------------------------------*/ 78476404edcSAsim Jamshed io_module_func dpdk_module_func = { 78576404edcSAsim Jamshed .load_module_upper_half = dpdk_load_module_upper_half, 78676404edcSAsim Jamshed .load_module_lower_half = dpdk_load_module_lower_half, 78776404edcSAsim Jamshed .init_handle = dpdk_init_handle, 78876404edcSAsim Jamshed .link_devices = NULL, 78976404edcSAsim Jamshed .release_pkt = NULL, 79076404edcSAsim Jamshed .send_pkts = dpdk_send_pkts, 79176404edcSAsim Jamshed .get_wptr = dpdk_get_wptr, 79276404edcSAsim Jamshed .recv_pkts = dpdk_recv_pkts, 79376404edcSAsim Jamshed .get_rptr = dpdk_get_rptr, 79476404edcSAsim Jamshed .get_nif = dpdk_get_nif, 795a5e1a556SAsim Jamshed .select = dpdk_select, 79676404edcSAsim Jamshed .destroy_handle = dpdk_destroy_handle, 79776404edcSAsim Jamshed .dev_ioctl = dpdk_dev_ioctl, 79876404edcSAsim Jamshed .set_wptr = dpdk_set_wptr, 79976404edcSAsim Jamshed }; 80076404edcSAsim Jamshed /*----------------------------------------------------------------------------*/ 80176404edcSAsim Jamshed 802