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(__rte_unused void *parsed_result, 20 struct cmdline *cl, 21 __rte_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(__rte_unused void *parsed_result, 50 struct cmdline *cl, 51 __rte_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(__rte_unused void *parsed_result, 76 struct cmdline *cl, 77 __rte_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 __rte_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 return; 125 } 126 127 if (!rte_eal_hotplug_add(da.bus->name, da.name, da.args)) 128 cmdline_printf(cl, "attached device %s\n", da.name); 129 else 130 cmdline_printf(cl, "failed to attached device %s\n", 131 da.name); 132 rte_devargs_reset(&da); 133 } 134 135 cmdline_parse_token_string_t cmd_dev_attach_attach = 136 TOKEN_STRING_INITIALIZER(struct cmd_dev_attach_result, attach, 137 "attach"); 138 cmdline_parse_token_string_t cmd_dev_attach_devargs = 139 TOKEN_STRING_INITIALIZER(struct cmd_dev_attach_result, devargs, NULL); 140 141 cmdline_parse_inst_t cmd_attach_device = { 142 .f = cmd_dev_attach_parsed, /* function to call */ 143 .data = NULL, /* 2nd arg of func */ 144 .help_str = "attach a device", 145 .tokens = { /* token list, NULL terminated */ 146 (void *)&cmd_dev_attach_attach, 147 (void *)&cmd_dev_attach_devargs, 148 NULL, 149 }, 150 }; 151 152 /**********************************************************/ 153 154 struct cmd_dev_detach_result { 155 cmdline_fixed_string_t detach; 156 cmdline_fixed_string_t devargs; 157 }; 158 159 static void cmd_dev_detach_parsed(void *parsed_result, 160 struct cmdline *cl, 161 __rte_unused void *data) 162 { 163 struct cmd_dev_detach_result *res = parsed_result; 164 struct rte_devargs da; 165 166 memset(&da, 0, sizeof(da)); 167 168 if (rte_devargs_parsef(&da, "%s", res->devargs)) { 169 cmdline_printf(cl, "cannot parse devargs\n"); 170 return; 171 } 172 173 printf("detaching...\n"); 174 if (!rte_eal_hotplug_remove(da.bus->name, da.name)) 175 cmdline_printf(cl, "detached device %s\n", 176 da.name); 177 else 178 cmdline_printf(cl, "failed to dettach device %s\n", 179 da.name); 180 rte_devargs_reset(&da); 181 } 182 183 cmdline_parse_token_string_t cmd_dev_detach_detach = 184 TOKEN_STRING_INITIALIZER(struct cmd_dev_detach_result, detach, 185 "detach"); 186 187 cmdline_parse_token_string_t cmd_dev_detach_devargs = 188 TOKEN_STRING_INITIALIZER(struct cmd_dev_detach_result, devargs, NULL); 189 190 cmdline_parse_inst_t cmd_detach_device = { 191 .f = cmd_dev_detach_parsed, /* function to call */ 192 .data = NULL, /* 2nd arg of func */ 193 .help_str = "detach a device", 194 .tokens = { /* token list, NULL terminated */ 195 (void *)&cmd_dev_detach_detach, 196 (void *)&cmd_dev_detach_devargs, 197 NULL, 198 }, 199 }; 200 201 /**********************************************************/ 202 /**********************************************************/ 203 /****** CONTEXT (list of instruction) */ 204 205 cmdline_parse_ctx_t main_ctx[] = { 206 (cmdline_parse_inst_t *)&cmd_help, 207 (cmdline_parse_inst_t *)&cmd_quit, 208 (cmdline_parse_inst_t *)&cmd_list, 209 (cmdline_parse_inst_t *)&cmd_attach_device, 210 (cmdline_parse_inst_t *)&cmd_detach_device, 211 NULL, 212 }; 213