1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2018 Intel Corporation. 3 */ 4 5 #include <cmdline_rdline.h> 6 #include <cmdline_parse.h> 7 #include <cmdline_parse_ipaddr.h> 8 #include <cmdline_parse_num.h> 9 #include <cmdline_parse_string.h> 10 #include <cmdline.h> 11 12 #include <rte_bus.h> 13 #include <rte_ethdev.h> 14 15 /**********************************************************/ 16 17 struct cmd_help_result { 18 cmdline_fixed_string_t help; 19 }; 20 21 static void cmd_help_parsed(__rte_unused void *parsed_result, 22 struct cmdline *cl, 23 __rte_unused void *data) 24 { 25 cmdline_printf(cl, 26 "commands:\n" 27 "- attach <devargs>\n" 28 "- detach <devargs>\n" 29 "- list\n\n"); 30 } 31 32 cmdline_parse_token_string_t cmd_help_help = 33 TOKEN_STRING_INITIALIZER(struct cmd_help_result, help, "help"); 34 35 cmdline_parse_inst_t cmd_help = { 36 .f = cmd_help_parsed, /* function to call */ 37 .data = NULL, /* 2nd arg of func */ 38 .help_str = "show help", 39 .tokens = { /* token list, NULL terminated */ 40 (void *)&cmd_help_help, 41 NULL, 42 }, 43 }; 44 45 /**********************************************************/ 46 47 struct cmd_quit_result { 48 cmdline_fixed_string_t quit; 49 }; 50 51 static void cmd_quit_parsed(__rte_unused void *parsed_result, 52 struct cmdline *cl, 53 __rte_unused void *data) 54 { 55 cmdline_quit(cl); 56 } 57 58 cmdline_parse_token_string_t cmd_quit_quit = 59 TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit, "quit"); 60 61 cmdline_parse_inst_t cmd_quit = { 62 .f = cmd_quit_parsed, /* function to call */ 63 .data = NULL, /* 2nd arg of func */ 64 .help_str = "quit", 65 .tokens = { /* token list, NULL terminated */ 66 (void *)&cmd_quit_quit, 67 NULL, 68 }, 69 }; 70 71 /**********************************************************/ 72 73 struct cmd_list_result { 74 cmdline_fixed_string_t list; 75 }; 76 77 static void cmd_list_parsed(__rte_unused void *parsed_result, 78 struct cmdline *cl, 79 __rte_unused void *data) 80 { 81 uint16_t port_id; 82 char dev_name[RTE_DEV_NAME_MAX_LEN]; 83 84 cmdline_printf(cl, "list all etherdev\n"); 85 86 RTE_ETH_FOREACH_DEV(port_id) { 87 rte_eth_dev_get_name_by_port(port_id, dev_name); 88 if (strlen(dev_name) > 0) 89 cmdline_printf(cl, "%d\t%s\n", port_id, dev_name); 90 else 91 printf("empty dev_name is not expected!\n"); 92 } 93 } 94 95 cmdline_parse_token_string_t cmd_list_list = 96 TOKEN_STRING_INITIALIZER(struct cmd_list_result, list, "list"); 97 98 cmdline_parse_inst_t cmd_list = { 99 .f = cmd_list_parsed, /* function to call */ 100 .data = NULL, /* 2nd arg of func */ 101 .help_str = "list all devices", 102 .tokens = { /* token list, NULL terminated */ 103 (void *)&cmd_list_list, 104 NULL, 105 }, 106 }; 107 108 /**********************************************************/ 109 110 struct cmd_dev_attach_result { 111 cmdline_fixed_string_t attach; 112 cmdline_fixed_string_t devargs; 113 }; 114 115 static void cmd_dev_attach_parsed(void *parsed_result, 116 struct cmdline *cl, 117 __rte_unused void *data) 118 { 119 struct cmd_dev_attach_result *res = parsed_result; 120 struct rte_devargs da; 121 122 memset(&da, 0, sizeof(da)); 123 124 if (rte_devargs_parsef(&da, "%s", res->devargs)) { 125 cmdline_printf(cl, "cannot parse devargs\n"); 126 return; 127 } 128 129 if (!rte_eal_hotplug_add(rte_bus_name(da.bus), da.name, da.args)) 130 cmdline_printf(cl, "attached device %s\n", da.name); 131 else 132 cmdline_printf(cl, "failed to attached device %s\n", 133 da.name); 134 rte_devargs_reset(&da); 135 } 136 137 cmdline_parse_token_string_t cmd_dev_attach_attach = 138 TOKEN_STRING_INITIALIZER(struct cmd_dev_attach_result, attach, 139 "attach"); 140 cmdline_parse_token_string_t cmd_dev_attach_devargs = 141 TOKEN_STRING_INITIALIZER(struct cmd_dev_attach_result, devargs, NULL); 142 143 cmdline_parse_inst_t cmd_attach_device = { 144 .f = cmd_dev_attach_parsed, /* function to call */ 145 .data = NULL, /* 2nd arg of func */ 146 .help_str = "attach a device", 147 .tokens = { /* token list, NULL terminated */ 148 (void *)&cmd_dev_attach_attach, 149 (void *)&cmd_dev_attach_devargs, 150 NULL, 151 }, 152 }; 153 154 /**********************************************************/ 155 156 struct cmd_dev_detach_result { 157 cmdline_fixed_string_t detach; 158 cmdline_fixed_string_t devargs; 159 }; 160 161 static void cmd_dev_detach_parsed(void *parsed_result, 162 struct cmdline *cl, 163 __rte_unused void *data) 164 { 165 struct cmd_dev_detach_result *res = parsed_result; 166 struct rte_devargs da; 167 168 memset(&da, 0, sizeof(da)); 169 170 if (rte_devargs_parsef(&da, "%s", res->devargs)) { 171 cmdline_printf(cl, "cannot parse devargs\n"); 172 return; 173 } 174 175 printf("detaching...\n"); 176 if (!rte_eal_hotplug_remove(rte_bus_name(da.bus), da.name)) 177 cmdline_printf(cl, "detached device %s\n", 178 da.name); 179 else 180 cmdline_printf(cl, "failed to detach device %s\n", 181 da.name); 182 rte_devargs_reset(&da); 183 } 184 185 cmdline_parse_token_string_t cmd_dev_detach_detach = 186 TOKEN_STRING_INITIALIZER(struct cmd_dev_detach_result, detach, 187 "detach"); 188 189 cmdline_parse_token_string_t cmd_dev_detach_devargs = 190 TOKEN_STRING_INITIALIZER(struct cmd_dev_detach_result, devargs, NULL); 191 192 cmdline_parse_inst_t cmd_detach_device = { 193 .f = cmd_dev_detach_parsed, /* function to call */ 194 .data = NULL, /* 2nd arg of func */ 195 .help_str = "detach a device", 196 .tokens = { /* token list, NULL terminated */ 197 (void *)&cmd_dev_detach_detach, 198 (void *)&cmd_dev_detach_devargs, 199 NULL, 200 }, 201 }; 202 203 /**********************************************************/ 204 /**********************************************************/ 205 /****** CONTEXT (list of instruction) */ 206 207 cmdline_parse_ctx_t main_ctx[] = { 208 (cmdline_parse_inst_t *)&cmd_help, 209 (cmdline_parse_inst_t *)&cmd_quit, 210 (cmdline_parse_inst_t *)&cmd_list, 211 (cmdline_parse_inst_t *)&cmd_attach_device, 212 (cmdline_parse_inst_t *)&cmd_detach_device, 213 NULL, 214 }; 215