1 /******************************************************************************
3 * Copyright (c) 2020 Intel.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 *******************************************************************************/
20 * @brief This file has all definitions for the Ethernet Data Interface Layer
22 * @ingroup group_lte_source_auxlib
23 * @author Intel Corporation
32 #include <sys/queue.h>
36 #include <linux/limits.h>
37 #include <sys/types.h>
40 #include <immintrin.h>
41 #include <rte_config.h>
42 #include <rte_common.h>
44 #include <rte_memory.h>
45 #include <rte_memzone.h>
47 #include <rte_per_lcore.h>
48 #include <rte_launch.h>
49 #include <rte_atomic.h>
50 #include <rte_cycles.h>
51 #include <rte_prefetch.h>
52 #include <rte_lcore.h>
53 #include <rte_per_lcore.h>
54 #include <rte_branch_prediction.h>
55 #include <rte_interrupts.h>
57 #include <rte_debug.h>
58 #include <rte_ether.h>
59 #include <rte_ethdev.h>
61 #include <rte_mempool.h>
63 #include <rte_errno.h>
69 struct rte_mempool *_eth_mbuf_pool = NULL;
70 struct rte_mempool *_eth_mbuf_pool_indirect = NULL;
71 struct rte_mempool *_eth_mbuf_pool_rx = NULL;
72 struct rte_mempool *_eth_mbuf_pkt_gen = NULL;
74 struct rte_mempool *socket_direct_pool = NULL;
75 struct rte_mempool *socket_indirect_pool = NULL;
77 struct rte_mempool *_eth_mbuf_pool_vf_rx[16][RTE_MAX_QUEUES_PER_PORT] = {NULL};
78 struct rte_mempool *_eth_mbuf_pool_vf_small[16] = {NULL};
81 xran_init_mbuf_pool(uint32_t mtu)
83 uint16_t data_room_size = MBUF_POOL_ELEMENT;
84 printf("%s: socket %d\n",__FUNCTION__, rte_socket_id());
87 data_room_size = MBUF_POOL_ELM_SMALL;
90 /* Init the buffer pool */
91 if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
92 _eth_mbuf_pool = rte_pktmbuf_pool_create("mempool", NUM_MBUFS,
93 MBUF_CACHE, 0, data_room_size, rte_socket_id());
94 _eth_mbuf_pool_indirect = rte_pktmbuf_pool_create("mempool_indirect", NUM_MBUFS_VF,
95 MBUF_CACHE, 0, 0, rte_socket_id());
96 _eth_mbuf_pkt_gen = rte_pktmbuf_pool_create("mempool_pkt_gen",
97 NUM_MBUFS, MBUF_CACHE, 0, MBUF_POOL_PKT_GEN_ELM, rte_socket_id());
99 _eth_mbuf_pool = rte_mempool_lookup("mempool");
100 _eth_mbuf_pool_indirect = rte_mempool_lookup("mempool_indirect");
101 _eth_mbuf_pkt_gen = rte_mempool_lookup("mempool_pkt_gen");
104 if (_eth_mbuf_pool == NULL)
105 rte_panic("Cannot create mbuf pool: %s\n", rte_strerror(rte_errno));
106 if (_eth_mbuf_pool_indirect == NULL)
107 rte_panic("Cannot create mbuf pool: %s\n", rte_strerror(rte_errno));
108 if (_eth_mbuf_pkt_gen == NULL)
109 rte_panic("Cannot create packet gen pool: %s\n", rte_strerror(rte_errno));
111 if (socket_direct_pool == NULL)
112 socket_direct_pool = _eth_mbuf_pool;
114 if (socket_indirect_pool == NULL)
115 socket_indirect_pool = _eth_mbuf_pool_indirect;
118 /* Configure the Rx with optional split. */
120 rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
121 uint16_t nb_rx_desc, unsigned int socket_id,
122 struct rte_eth_rxconf *rx_conf, struct rte_mempool *mp)
124 unsigned int i, mp_n;
126 #ifndef RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT
127 #define RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT 0x00100000
129 if ((rx_conf->offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT) == 0) {
130 #if (RTE_VER_YEAR >= 21)
131 rx_conf->rx_seg = NULL;
132 rx_conf->rx_nseg = 0;
134 ret = rte_eth_rx_queue_setup(port_id, rx_queue_id,
135 nb_rx_desc, socket_id,
140 printf("rx_queue_setup error\n");
146 /* Init NIC port, then start the port */
147 void xran_init_port(int p_id, uint16_t num_rxq, uint32_t mtu)
149 static uint16_t nb_rxd = BURST_SIZE;
150 static uint16_t nb_txd = BURST_SIZE;
151 struct rte_ether_addr addr;
152 struct rte_eth_rxmode rxmode = {
154 .max_rx_pkt_len = MAX_RX_LEN,
155 .offloads = DEV_RX_OFFLOAD_JUMBO_FRAME
157 struct rte_eth_txmode txmode = {
158 .mq_mode = ETH_MQ_TX_NONE,
159 .offloads = DEV_TX_OFFLOAD_MULTI_SEGS
161 struct rte_eth_conf port_conf = {
165 struct rte_eth_rxconf rxq_conf;
166 struct rte_eth_txconf txq_conf;
169 struct rte_eth_dev_info dev_info;
170 const char *drv_name = "";
171 int sock_id = rte_eth_dev_socket_id(p_id);
172 char rx_pool_name[32] = "";
173 uint16_t data_room_size = MBUF_POOL_ELEMENT;
175 uint32_t num_mbufs = 0;
178 rxmode.offloads &= ~DEV_RX_OFFLOAD_JUMBO_FRAME;
179 rxmode.max_rx_pkt_len = RTE_ETHER_MAX_LEN;
180 data_room_size = MBUF_POOL_ELM_SMALL;
183 rte_eth_dev_info_get(p_id, &dev_info);
184 if (dev_info.driver_name)
185 drv_name = dev_info.driver_name;
186 printf("initializing port %d for TX, drv=%s\n", p_id, drv_name);
188 if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE){
189 printf("set DEV_TX_OFFLOAD_MBUF_FAST_FREE\n");
190 port_conf.txmode.offloads |=
191 DEV_TX_OFFLOAD_MBUF_FAST_FREE;
194 rte_eth_macaddr_get(p_id, &addr);
196 printf("Port %u MAC: %02"PRIx8" %02"PRIx8" %02"PRIx8
197 " %02"PRIx8" %02"PRIx8" %02"PRIx8"\n",
199 addr.addr_bytes[0], addr.addr_bytes[1], addr.addr_bytes[2],
200 addr.addr_bytes[3], addr.addr_bytes[4], addr.addr_bytes[5]);
204 num_mbufs = 2*nb_rxd-1;
207 num_mbufs = NUM_MBUFS;
211 ret = rte_eth_dev_configure(p_id, num_rxq, 1, &port_conf);
213 rte_panic("Cannot configure port %u (%d)\n", p_id, ret);
215 ret = rte_eth_dev_adjust_nb_rx_tx_desc(p_id, &nb_rxd,&nb_txd);
219 rte_exit(EXIT_FAILURE, "Cannot adjust number of "
220 "descriptors: err=%d, port=%d\n", ret, p_id);
222 printf("Port %u: nb_rxd %d nb_txd %d\n", p_id, nb_rxd, nb_txd);
224 for (qi = 0; qi < num_rxq; qi++) {
225 snprintf(rx_pool_name, RTE_DIM(rx_pool_name), "%s_p_%d_q_%d", "mp_rx_", p_id, qi);
226 printf("[%d] %s num blocks %d\n", p_id, rx_pool_name, num_mbufs);
227 _eth_mbuf_pool_vf_rx[p_id][qi] = rte_pktmbuf_pool_create(rx_pool_name, num_mbufs,
228 MBUF_CACHE, 0, data_room_size, rte_socket_id());
230 if (_eth_mbuf_pool_vf_rx[p_id][qi] == NULL)
231 rte_panic("Cannot create mbuf pool: %s\n", rte_strerror(rte_errno));
234 snprintf(rx_pool_name, RTE_DIM(rx_pool_name), "%s_%d", "mempool_small_", p_id);
235 printf("[%d] %s\n", p_id, rx_pool_name);
236 _eth_mbuf_pool_vf_small[p_id] = rte_pktmbuf_pool_create(rx_pool_name, NUM_MBUFS_VF,
237 MBUF_CACHE, 0, MBUF_POOL_ELM_SMALL_INDIRECT, rte_socket_id());
239 if (_eth_mbuf_pool_vf_small[p_id] == NULL)
240 rte_panic("Cannot create mbuf pool: %s\n", rte_strerror(rte_errno));
244 rxq_conf = dev_info.default_rxconf;
246 for (qi = 0; qi < num_rxq; qi++) {
247 ret = rx_queue_setup(p_id, qi, nb_rxd,
248 sock_id, &rxq_conf, _eth_mbuf_pool_vf_rx[p_id][qi]);
252 rte_panic("Cannot init RX for port %u (%d)\n",
257 txq_conf = dev_info.default_txconf;
259 ret = rte_eth_tx_queue_setup(p_id, 0, nb_txd, sock_id, &txq_conf);
261 rte_panic("Cannot init TX for port %u (%d)\n",
264 ret = rte_eth_dev_set_ptypes(p_id, RTE_PTYPE_UNKNOWN, NULL, 0);
266 rte_panic("Port %d: Failed to disable Ptype parsing\n", p_id);
269 ret = rte_eth_dev_start(p_id);
271 rte_panic("Cannot start port %u (%d)\n", p_id, ret);
274 void xran_init_port_mempool(int p_id, uint32_t mtu)
277 int sock_id = rte_eth_dev_socket_id(p_id);
278 char rx_pool_name[32] = "";
279 uint16_t data_room_size = MBUF_POOL_ELEMENT;
282 data_room_size = MBUF_POOL_ELM_SMALL;
285 snprintf(rx_pool_name, RTE_DIM(rx_pool_name), "%s_%d", "mempool_small_", p_id);
286 printf("[%d] %s\n", p_id, rx_pool_name);
287 _eth_mbuf_pool_vf_small[p_id] = rte_pktmbuf_pool_create(rx_pool_name, NUM_MBUFS_VF,
288 MBUF_CACHE, 0, MBUF_POOL_ELM_SMALL, rte_socket_id());
290 if (_eth_mbuf_pool_vf_small[p_id] == NULL)
291 rte_panic("Cannot create mbuf pool: %s\n", rte_strerror(rte_errno));
296 /* Prepend ethernet header, possibly vlan tag. */
297 void xran_add_eth_hdr_vlan(struct rte_ether_addr *dst, uint16_t ethertype, struct rte_mbuf *mb)
299 /* add in the ethernet header */
300 struct rte_ether_hdr *h = (struct rte_ether_hdr *)rte_pktmbuf_mtod(mb, struct rte_ether_hdr*);
302 PANIC_ON(h == NULL, "mbuf prepend of ether_hdr failed");
304 /* Fill in the ethernet header. */
305 rte_eth_macaddr_get(mb->port, &h->s_addr); /* set source addr */
306 h->d_addr = *dst; /* set dst addr */
307 h->ether_type = rte_cpu_to_be_16(ethertype); /* ethertype too */
309 #if defined(DPDKIO_DEBUG) && DPDKIO_DEBUG > 1
311 char dst[RTE_ETHER_ADDR_FMT_SIZE] = "(empty)";
312 char src[RTE_ETHER_ADDR_FMT_SIZE] = "(empty)";
314 printf("*** packet for TX below (len %d) ***", rte_pktmbuf_pkt_len(mb));
315 rte_ether_format_addr(src, sizeof(src), &h->s_addr);
316 rte_ether_format_addr(dst, sizeof(dst), &h->d_addr);
317 printf("src: %s dst: %s ethertype: %.4X", src, dst, ethertype);