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 #include <rte_ethdev.h> 12 13 /**********************************************************/ 14 15 struct cmd_help_result { 16 cmdline_fixed_string_t help; 17 }; 18 19 static void cmd_help_parsed(__attribute__((unused)) void *parsed_result, 20 struct cmdline *cl, 21 __attribute__((unused)) void *data) 22 { 23 cmdline_printf(cl, 24 "commands:\n" 25 "- attach <devargs>\n" 26 "- detach <devargs>\n" 27 "- list\n\n"); 28 } 29 30 cmdline_parse_token_string_t cmd_help_help = 31 TOKEN_STRING_INITIALIZER(struct cmd_help_result, help, "help"); 32 33 cmdline_parse_inst_t cmd_help = { 34 .f = cmd_help_parsed, /* function to call */ 35 .data = NULL, /* 2nd arg of func */ 36 .help_str = "show help", 37 .tokens = { /* token list, NULL terminated */ 38 (void *)&cmd_help_help, 39 NULL, 40 }, 41 }; 42 43 /**********************************************************/ 44 45 struct cmd_quit_result { 46 cmdline_fixed_string_t quit; 47 }; 48 49 static void cmd_quit_parsed(__attribute__((unused)) void *parsed_result, 50 struct cmdline *cl, 51 __attribute__((unused)) void *data) 52 { 53 cmdline_quit(cl); 54 } 55 56 cmdline_parse_token_string_t cmd_quit_quit = 57 TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit, "quit"); 58 59 cmdline_parse_inst_t cmd_quit = { 60 .f = cmd_quit_parsed, /* function to call */ 61 .data = NULL, /* 2nd arg of func */ 62 .help_str = "quit", 63 .tokens = { /* token list, NULL terminated */ 64 (void *)&cmd_quit_quit, 65 NULL, 66 }, 67 }; 68 69 /**********************************************************/ 70 71 struct cmd_list_result { 72 cmdline_fixed_string_t list; 73 }; 74 75 static void cmd_list_parsed(__attribute__((unused)) void *parsed_result, 76 struct cmdline *cl, 77 __attribute__((unused)) void *data) 78 { 79 uint16_t port_id; 80 char dev_name[RTE_DEV_NAME_MAX_LEN]; 81 82 cmdline_printf(cl, "list all etherdev\n"); 83 84 RTE_ETH_FOREACH_DEV(port_id) { 85 rte_eth_dev_get_name_by_port(port_id, dev_name); 86 if (strlen(dev_name) > 0) 87 cmdline_printf(cl, "%d\t%s\n", port_id, dev_name); 88 else 89 printf("empty dev_name is not expected!\n"); 90 } 91 } 92 93 cmdline_parse_token_string_t cmd_list_list = 94 TOKEN_STRING_INITIALIZER(struct cmd_list_result, list, "list"); 95 96 cmdline_parse_inst_t cmd_list = { 97 .f = cmd_list_parsed, /* function to call */ 98 .data = NULL, /* 2nd arg of func */ 99 .help_str = "list all devices", 100 .tokens = { /* token list, NULL terminated */ 101 (void *)&cmd_list_list, 102 NULL, 103 }, 104 }; 105 106 /**********************************************************/ 107 108 struct cmd_dev_attach_result { 109 cmdline_fixed_string_t attach; 110 cmdline_fixed_string_t devargs; 111 }; 112 113 static void cmd_dev_attach_parsed(void *parsed_result, 114 struct cmdline *cl, 115 __attribute__((unused)) void *data) 116 { 117 struct cmd_dev_attach_result *res = parsed_result; 118 struct rte_devargs da; 119 120 memset(&da, 0, sizeof(da)); 121 122 if (rte_devargs_parsef(&da, "%s", res->devargs)) { 123 cmdline_printf(cl, "cannot parse devargs\n"); 124 if (da.args) 125 free(da.args); 126 return; 127 } 128 129 if (!rte_eal_hotplug_add(da.bus->name, 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 } 135 136 cmdline_parse_token_string_t cmd_dev_attach_attach = 137 TOKEN_STRING_INITIALIZER(struct cmd_dev_attach_result, attach, 138 "attach"); 139 cmdline_parse_token_string_t cmd_dev_attach_devargs = 140 TOKEN_STRING_INITIALIZER(struct cmd_dev_attach_result, devargs, NULL); 141 142 cmdline_parse_inst_t cmd_attach_device = { 143 .f = cmd_dev_attach_parsed, /* function to call */ 144 .data = NULL, /* 2nd arg of func */ 145 .help_str = "attach a device", 146 .tokens = { /* token list, NULL terminated */ 147 (void *)&cmd_dev_attach_attach, 148 (void *)&cmd_dev_attach_devargs, 149 NULL, 150 }, 151 }; 152 153 /**********************************************************/ 154 155 struct cmd_dev_detach_result { 156 cmdline_fixed_string_t detach; 157 cmdline_fixed_string_t devargs; 158 }; 159 160 static void cmd_dev_detach_parsed(void *parsed_result, 161 struct cmdline *cl, 162 __attribute__((unused)) void *data) 163 { 164 struct cmd_dev_detach_result *res = parsed_result; 165 struct rte_devargs da; 166 167 memset(&da, 0, sizeof(da)); 168 169 if (rte_devargs_parsef(&da, "%s", res->devargs)) { 170 cmdline_printf(cl, "cannot parse devargs\n"); 171 if (da.args) 172 free(da.args); 173 return; 174 } 175 176 printf("detaching...\n"); 177 if (!rte_eal_hotplug_remove(da.bus->name, da.name)) 178 cmdline_printf(cl, "detached device %s\n", 179 da.name); 180 else 181 cmdline_printf(cl, "failed to dettach device %s\n", 182 da.name); 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