xref: /dpdk/examples/l2fwd-event/l2fwd_common.c (revision aae4f5e0)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2019 Marvell International Ltd.
3  */
4 
5 #include "l2fwd_common.h"
6 
7 int
l2fwd_event_init_ports(struct l2fwd_resources * rsrc)8 l2fwd_event_init_ports(struct l2fwd_resources *rsrc)
9 {
10 	uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT;
11 	uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT;
12 	struct rte_eth_conf port_conf = {
13 		.rxmode = {
14 			.split_hdr_size = 0,
15 		},
16 		.txmode = {
17 			.mq_mode = RTE_ETH_MQ_TX_NONE,
18 		},
19 	};
20 	uint16_t nb_ports_available = 0;
21 	uint16_t port_id;
22 	int ret;
23 
24 	if (rsrc->event_mode) {
25 		port_conf.rxmode.mq_mode = RTE_ETH_MQ_RX_RSS;
26 		port_conf.rx_adv_conf.rss_conf.rss_key = NULL;
27 		port_conf.rx_adv_conf.rss_conf.rss_hf = RTE_ETH_RSS_IP;
28 	}
29 
30 	/* Initialise each port */
31 	RTE_ETH_FOREACH_DEV(port_id) {
32 		struct rte_eth_conf local_port_conf = port_conf;
33 		struct rte_eth_dev_info dev_info;
34 		struct rte_eth_rxconf rxq_conf;
35 		struct rte_eth_txconf txq_conf;
36 
37 		/* skip ports that are not enabled */
38 		if ((rsrc->enabled_port_mask & (1 << port_id)) == 0) {
39 			printf("Skipping disabled port %u\n", port_id);
40 			continue;
41 		}
42 		nb_ports_available++;
43 
44 		/* init port */
45 		printf("Initializing port %u... ", port_id);
46 		fflush(stdout);
47 
48 		ret = rte_eth_dev_info_get(port_id, &dev_info);
49 		if (ret != 0)
50 			rte_panic("Error during getting device (port %u) info: %s\n",
51 				  port_id, strerror(-ret));
52 		local_port_conf.rx_adv_conf.rss_conf.rss_hf &=
53 			dev_info.flow_type_rss_offloads;
54 		if (local_port_conf.rx_adv_conf.rss_conf.rss_hf !=
55 				port_conf.rx_adv_conf.rss_conf.rss_hf) {
56 			printf("Port %u modified RSS hash function based on hardware support,"
57 			       "requested:%#"PRIx64" configured:%#"PRIx64"",
58 				port_id,
59 				port_conf.rx_adv_conf.rss_conf.rss_hf,
60 				local_port_conf.rx_adv_conf.rss_conf.rss_hf);
61 		}
62 
63 		if (dev_info.tx_offload_capa & RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE)
64 			local_port_conf.txmode.offloads |=
65 				RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE;
66 		/* Configure RX and TX queue. 8< */
67 		ret = rte_eth_dev_configure(port_id, 1, 1, &local_port_conf);
68 		if (ret < 0)
69 			rte_panic("Cannot configure device: err=%d, port=%u\n",
70 				  ret, port_id);
71 		/* >8 End of configuration RX and TX queue. */
72 
73 		ret = rte_eth_dev_adjust_nb_rx_tx_desc(port_id, &nb_rxd,
74 						       &nb_txd);
75 		if (ret < 0)
76 			rte_panic("Cannot adjust number of descriptors: err=%d, port=%u\n",
77 				  ret, port_id);
78 
79 		rte_eth_macaddr_get(port_id, &rsrc->eth_addr[port_id]);
80 
81 		/* init one RX queue */
82 		fflush(stdout);
83 		rxq_conf = dev_info.default_rxconf;
84 		rxq_conf.offloads = local_port_conf.rxmode.offloads;
85 		/* Using lcore to poll one or several ports. 8< */
86 		ret = rte_eth_rx_queue_setup(port_id, 0, nb_rxd,
87 					     rte_eth_dev_socket_id(port_id),
88 					     &rxq_conf,
89 					     rsrc->pktmbuf_pool);
90 		if (ret < 0)
91 			rte_panic("rte_eth_rx_queue_setup:err=%d, port=%u\n",
92 				  ret, port_id);
93 
94 		/* >8 End of using lcore to poll one or several ports. */
95 
96 		/* Init one TX queue on each port. 8< */
97 		fflush(stdout);
98 		txq_conf = dev_info.default_txconf;
99 		txq_conf.offloads = local_port_conf.txmode.offloads;
100 		ret = rte_eth_tx_queue_setup(port_id, 0, nb_txd,
101 				rte_eth_dev_socket_id(port_id),
102 				&txq_conf);
103 		if (ret < 0)
104 			rte_panic("rte_eth_tx_queue_setup:err=%d, port=%u\n",
105 				  ret, port_id);
106 		/* >8 End of init one TX queue on each port. */
107 
108 		rte_eth_promiscuous_enable(port_id);
109 
110 		printf("Port %u,MAC address: " RTE_ETHER_ADDR_PRT_FMT "\n\n",
111 			port_id,
112 			RTE_ETHER_ADDR_BYTES(&rsrc->eth_addr[port_id]));
113 	}
114 
115 	return nb_ports_available;
116 }
117 
118 static void
l2fwd_event_vector_array_free(struct rte_event events[],uint16_t num)119 l2fwd_event_vector_array_free(struct rte_event events[], uint16_t num)
120 {
121 	uint16_t i;
122 
123 	for (i = 0; i < num; i++) {
124 		rte_pktmbuf_free_bulk(events[i].vec->mbufs,
125 				      events[i].vec->nb_elem);
126 		rte_mempool_put(rte_mempool_from_obj(events[i].vec),
127 				events[i].vec);
128 	}
129 }
130 
131 static void
l2fwd_event_port_flush(uint8_t event_d_id __rte_unused,struct rte_event ev,void * args __rte_unused)132 l2fwd_event_port_flush(uint8_t event_d_id __rte_unused, struct rte_event ev,
133 		       void *args __rte_unused)
134 {
135 	if (ev.event_type & RTE_EVENT_TYPE_VECTOR)
136 		l2fwd_event_vector_array_free(&ev, 1);
137 	else
138 		rte_pktmbuf_free(ev.mbuf);
139 }
140 
141 void
l2fwd_event_worker_cleanup(uint8_t event_d_id,uint8_t port_id,struct rte_event events[],uint16_t nb_enq,uint16_t nb_deq,uint8_t is_vector)142 l2fwd_event_worker_cleanup(uint8_t event_d_id, uint8_t port_id,
143 			   struct rte_event events[], uint16_t nb_enq,
144 			   uint16_t nb_deq, uint8_t is_vector)
145 {
146 	int i;
147 
148 	if (nb_deq) {
149 		if (is_vector)
150 			l2fwd_event_vector_array_free(events + nb_enq,
151 						      nb_deq - nb_enq);
152 		else
153 			for (i = nb_enq; i < nb_deq; i++)
154 				rte_pktmbuf_free(events[i].mbuf);
155 
156 		for (i = 0; i < nb_deq; i++)
157 			events[i].op = RTE_EVENT_OP_RELEASE;
158 		rte_event_enqueue_burst(event_d_id, port_id, events, nb_deq);
159 	}
160 
161 	rte_event_port_quiesce(event_d_id, port_id, l2fwd_event_port_flush,
162 			       NULL);
163 }
164