ethdev: remove old offload API
[dpdk.git] / examples / vm_power_manager / main.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2014 Intel Corporation
3  */
4
5 #include <stdio.h>
6 #include <string.h>
7 #include <stdint.h>
8 #include <sys/epoll.h>
9 #include <fcntl.h>
10 #include <unistd.h>
11 #include <stdlib.h>
12 #include <signal.h>
13 #include <errno.h>
14
15 #include <sys/queue.h>
16
17 #include <rte_common.h>
18 #include <rte_eal.h>
19 #include <rte_launch.h>
20 #include <rte_log.h>
21 #include <rte_per_lcore.h>
22 #include <rte_lcore.h>
23 #include <rte_ethdev.h>
24 #include <getopt.h>
25 #include <rte_cycles.h>
26 #include <rte_debug.h>
27
28 #include "channel_manager.h"
29 #include "channel_monitor.h"
30 #include "power_manager.h"
31 #include "vm_power_cli.h"
32 #include <rte_pmd_ixgbe.h>
33 #include <rte_pmd_i40e.h>
34 #include <rte_pmd_bnxt.h>
35
36 #define RX_RING_SIZE 1024
37 #define TX_RING_SIZE 1024
38
39 #define NUM_MBUFS 8191
40 #define MBUF_CACHE_SIZE 250
41 #define BURST_SIZE 32
42
43 static uint32_t enabled_port_mask;
44 static volatile bool force_quit;
45
46 /****************/
47 static const struct rte_eth_conf port_conf_default = {
48         .rxmode = {
49                 .max_rx_pkt_len = ETHER_MAX_LEN,
50         },
51 };
52
53 static inline int
54 port_init(uint16_t port, struct rte_mempool *mbuf_pool)
55 {
56         struct rte_eth_conf port_conf = port_conf_default;
57         const uint16_t rx_rings = 1, tx_rings = 1;
58         int retval;
59         uint16_t q;
60         struct rte_eth_dev_info dev_info;
61         struct rte_eth_txconf txq_conf;
62
63         if (!rte_eth_dev_is_valid_port(port))
64                 return -1;
65
66         rte_eth_dev_info_get(port, &dev_info);
67         if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
68                 port_conf.txmode.offloads |=
69                         DEV_TX_OFFLOAD_MBUF_FAST_FREE;
70
71         /* Configure the Ethernet device. */
72         retval = rte_eth_dev_configure(port, rx_rings, tx_rings, &port_conf);
73         if (retval != 0)
74                 return retval;
75
76         /* Allocate and set up 1 RX queue per Ethernet port. */
77         for (q = 0; q < rx_rings; q++) {
78                 retval = rte_eth_rx_queue_setup(port, q, RX_RING_SIZE,
79                                 rte_eth_dev_socket_id(port), NULL, mbuf_pool);
80                 if (retval < 0)
81                         return retval;
82         }
83
84         txq_conf = dev_info.default_txconf;
85         txq_conf.offloads = port_conf.txmode.offloads;
86         /* Allocate and set up 1 TX queue per Ethernet port. */
87         for (q = 0; q < tx_rings; q++) {
88                 retval = rte_eth_tx_queue_setup(port, q, TX_RING_SIZE,
89                                 rte_eth_dev_socket_id(port), &txq_conf);
90                 if (retval < 0)
91                         return retval;
92         }
93
94         /* Start the Ethernet port. */
95         retval = rte_eth_dev_start(port);
96         if (retval < 0)
97                 return retval;
98
99         /* Display the port MAC address. */
100         struct ether_addr addr;
101         rte_eth_macaddr_get(port, &addr);
102         printf("Port %u MAC: %02" PRIx8 " %02" PRIx8 " %02" PRIx8
103                            " %02" PRIx8 " %02" PRIx8 " %02" PRIx8 "\n",
104                         (unsigned int)port,
105                         addr.addr_bytes[0], addr.addr_bytes[1],
106                         addr.addr_bytes[2], addr.addr_bytes[3],
107                         addr.addr_bytes[4], addr.addr_bytes[5]);
108
109         /* Enable RX in promiscuous mode for the Ethernet device. */
110         rte_eth_promiscuous_enable(port);
111
112
113         return 0;
114 }
115
116 static int
117 parse_portmask(const char *portmask)
118 {
119         char *end = NULL;
120         unsigned long pm;
121
122         /* parse hexadecimal string */
123         pm = strtoul(portmask, &end, 16);
124         if ((portmask[0] == '\0') || (end == NULL) || (*end != '\0'))
125                 return -1;
126
127         if (pm == 0)
128                 return -1;
129
130         return pm;
131 }
132 /* Parse the argument given in the command line of the application */
133 static int
134 parse_args(int argc, char **argv)
135 {
136         int opt, ret;
137         char **argvopt;
138         int option_index;
139         char *prgname = argv[0];
140         static struct option lgopts[] = {
141                 { "mac-updating", no_argument, 0, 1},
142                 { "no-mac-updating", no_argument, 0, 0},
143                 {NULL, 0, 0, 0}
144         };
145         argvopt = argv;
146
147         while ((opt = getopt_long(argc, argvopt, "p:q:T:",
148                                   lgopts, &option_index)) != EOF) {
149
150                 switch (opt) {
151                 /* portmask */
152                 case 'p':
153                         enabled_port_mask = parse_portmask(optarg);
154                         if (enabled_port_mask == 0) {
155                                 printf("invalid portmask\n");
156                                 return -1;
157                         }
158                         break;
159                 /* long options */
160                 case 0:
161                         break;
162
163                 default:
164                         return -1;
165                 }
166         }
167
168         if (optind >= 0)
169                 argv[optind-1] = prgname;
170
171         ret = optind-1;
172         optind = 0; /* reset getopt lib */
173         return ret;
174 }
175
176 static void
177 check_all_ports_link_status(uint32_t port_mask)
178 {
179 #define CHECK_INTERVAL 100 /* 100ms */
180 #define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */
181         uint16_t portid, count, all_ports_up, print_flag = 0;
182         struct rte_eth_link link;
183
184         printf("\nChecking link status");
185         fflush(stdout);
186         for (count = 0; count <= MAX_CHECK_TIME; count++) {
187                 if (force_quit)
188                         return;
189                 all_ports_up = 1;
190                 RTE_ETH_FOREACH_DEV(portid) {
191                         if (force_quit)
192                                 return;
193                         if ((port_mask & (1 << portid)) == 0)
194                                 continue;
195                         memset(&link, 0, sizeof(link));
196                         rte_eth_link_get_nowait(portid, &link);
197                         /* print link status if flag set */
198                         if (print_flag == 1) {
199                                 if (link.link_status)
200                                         printf("Port %d Link Up - speed %u "
201                                                 "Mbps - %s\n", (uint16_t)portid,
202                                                 (unsigned int)link.link_speed,
203                                 (link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
204                                         ("full-duplex") : ("half-duplex\n"));
205                                 else
206                                         printf("Port %d Link Down\n",
207                                                 (uint16_t)portid);
208                                 continue;
209                         }
210                        /* clear all_ports_up flag if any link down */
211                         if (link.link_status == ETH_LINK_DOWN) {
212                                 all_ports_up = 0;
213                                 break;
214                         }
215                 }
216                 /* after finally printing all link status, get out */
217                 if (print_flag == 1)
218                         break;
219
220                 if (all_ports_up == 0) {
221                         printf(".");
222                         fflush(stdout);
223                         rte_delay_ms(CHECK_INTERVAL);
224                 }
225
226                 /* set the print_flag if all ports up or timeout */
227                 if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) {
228                         print_flag = 1;
229                         printf("done\n");
230                 }
231         }
232 }
233 static int
234 run_monitor(__attribute__((unused)) void *arg)
235 {
236         if (channel_monitor_init() < 0) {
237                 printf("Unable to initialize channel monitor\n");
238                 return -1;
239         }
240         run_channel_monitor();
241         return 0;
242 }
243
244 static void
245 sig_handler(int signo)
246 {
247         printf("Received signal %d, exiting...\n", signo);
248         channel_monitor_exit();
249         channel_manager_exit();
250         power_manager_exit();
251
252 }
253
254 int
255 main(int argc, char **argv)
256 {
257         int ret;
258         unsigned lcore_id;
259         unsigned int nb_ports;
260         struct rte_mempool *mbuf_pool;
261         uint16_t portid;
262
263
264         ret = rte_eal_init(argc, argv);
265         if (ret < 0)
266                 rte_panic("Cannot init EAL\n");
267
268         signal(SIGINT, sig_handler);
269         signal(SIGTERM, sig_handler);
270
271         argc -= ret;
272         argv += ret;
273
274         /* parse application arguments (after the EAL ones) */
275         ret = parse_args(argc, argv);
276         if (ret < 0)
277                 rte_exit(EXIT_FAILURE, "Invalid arguments\n");
278
279         nb_ports = rte_eth_dev_count_avail();
280
281         mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL", NUM_MBUFS * nb_ports,
282                 MBUF_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
283
284         if (mbuf_pool == NULL)
285                 rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
286
287         /* Initialize ports. */
288         RTE_ETH_FOREACH_DEV(portid) {
289                 struct ether_addr eth;
290                 int w, j;
291                 int ret;
292
293                 if ((enabled_port_mask & (1 << portid)) == 0)
294                         continue;
295
296                 eth.addr_bytes[0] = 0xe0;
297                 eth.addr_bytes[1] = 0xe0;
298                 eth.addr_bytes[2] = 0xe0;
299                 eth.addr_bytes[3] = 0xe0;
300                 eth.addr_bytes[4] = portid + 0xf0;
301
302                 if (port_init(portid, mbuf_pool) != 0)
303                         rte_exit(EXIT_FAILURE, "Cannot init port %"PRIu8 "\n",
304                                         portid);
305
306                 for (w = 0; w < MAX_VFS; w++) {
307                         eth.addr_bytes[5] = w + 0xf0;
308
309                         ret = rte_pmd_ixgbe_set_vf_mac_addr(portid,
310                                                 w, &eth);
311                         if (ret == -ENOTSUP)
312                                 ret = rte_pmd_i40e_set_vf_mac_addr(portid,
313                                                 w, &eth);
314                         if (ret == -ENOTSUP)
315                                 ret = rte_pmd_bnxt_set_vf_mac_addr(portid,
316                                                 w, &eth);
317
318                         switch (ret) {
319                         case 0:
320                                 printf("Port %d VF %d MAC: ",
321                                                 portid, w);
322                                 for (j = 0; j < 6; j++) {
323                                         printf("%02x", eth.addr_bytes[j]);
324                                         if (j < 5)
325                                                 printf(":");
326                                 }
327                                 printf("\n");
328                                 break;
329                         }
330                 }
331         }
332
333         lcore_id = rte_get_next_lcore(-1, 1, 0);
334         if (lcore_id == RTE_MAX_LCORE) {
335                 RTE_LOG(ERR, EAL, "A minimum of two cores are required to run "
336                                 "application\n");
337                 return 0;
338         }
339
340         check_all_ports_link_status(enabled_port_mask);
341         rte_eal_remote_launch(run_monitor, NULL, lcore_id);
342
343         if (power_manager_init() < 0) {
344                 printf("Unable to initialize power manager\n");
345                 return -1;
346         }
347         if (channel_manager_init(CHANNEL_MGR_DEFAULT_HV_PATH) < 0) {
348                 printf("Unable to initialize channel manager\n");
349                 return -1;
350         }
351         run_cli(NULL);
352
353         rte_eal_mp_wait_lcore();
354         return 0;
355 }