Line data Source code
1 : /*
2 : *------------------------------------------------------------------
3 : * Copyright (c) 2018 Cisco and/or its affiliates.
4 : * Licensed under the Apache License, Version 2.0 (the "License");
5 : * you may not use this file except in compliance with the License.
6 : * You may obtain a copy of the License at:
7 : *
8 : * http://www.apache.org/licenses/LICENSE-2.0
9 : *
10 : * Unless required by applicable law or agreed to in writing, software
11 : * distributed under the License is distributed on an "AS IS" BASIS,
12 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 : * See the License for the specific language governing permissions and
14 : * limitations under the License.
15 : *------------------------------------------------------------------
16 : */
17 : #include <vlib/vlib.h>
18 : #include <vlib/unix/unix.h>
19 : #include <vlib/pci/pci.h>
20 : #include <vnet/ethernet/ethernet.h>
21 : #include <vnet/ip/ip4_packet.h>
22 : #include <vnet/ip/ip6_packet.h>
23 : #include <vnet/devices/virtio/virtio.h>
24 : #include <vnet/devices/virtio/pci.h>
25 :
26 : static clib_error_t *
27 0 : virtio_pci_create_command_fn (vlib_main_t * vm, unformat_input_t * input,
28 : vlib_cli_command_t * cmd)
29 : {
30 0 : unformat_input_t _line_input, *line_input = &_line_input;
31 : virtio_pci_create_if_args_t args;
32 0 : u64 feature_mask = (u64) ~ (0ULL);
33 0 : u32 buffering_size = 0;
34 :
35 : /* Get a line of input. */
36 0 : if (!unformat_user (input, unformat_line_input, line_input))
37 0 : return 0;
38 :
39 0 : memset (&args, 0, sizeof (args));
40 0 : while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
41 : {
42 0 : if (unformat (line_input, "%U", unformat_vlib_pci_addr, &args.addr))
43 : ;
44 0 : else if (unformat (line_input, "feature-mask 0x%llx", &feature_mask))
45 0 : args.features = feature_mask;
46 0 : else if (unformat (line_input, "gso-enabled"))
47 0 : args.gso_enabled = 1;
48 0 : else if (unformat (line_input, "csum-enabled"))
49 0 : args.checksum_offload_enabled = 1;
50 0 : else if (unformat (line_input, "buffering"))
51 : {
52 0 : args.virtio_flags |= VIRTIO_FLAG_BUFFERING;
53 0 : if (unformat (line_input, "size %u", &buffering_size))
54 0 : args.buffering_size = buffering_size;
55 : }
56 0 : else if (unformat (line_input, "packed"))
57 0 : args.virtio_flags |= VIRTIO_FLAG_PACKED;
58 0 : else if (unformat (line_input, "bind force"))
59 0 : args.bind = VIRTIO_BIND_FORCE;
60 0 : else if (unformat (line_input, "bind"))
61 0 : args.bind = VIRTIO_BIND_DEFAULT;
62 : else
63 0 : return clib_error_return (0, "unknown input `%U'",
64 : format_unformat_error, input);
65 : }
66 0 : unformat_free (line_input);
67 :
68 0 : virtio_pci_create_if (vm, &args);
69 :
70 0 : return args.error;
71 : }
72 :
73 : /* *INDENT-OFF* */
74 272887 : VLIB_CLI_COMMAND (virtio_pci_create_command, static) = {
75 : .path = "create interface virtio",
76 : .short_help = "create interface virtio <pci-address> "
77 : "[feature-mask <hex-mask>] [gso-enabled] [csum-enabled] "
78 : "[buffering [size <buffering-szie>]] [packed] [bind [force]]",
79 : .function = virtio_pci_create_command_fn,
80 : };
81 : /* *INDENT-ON* */
82 :
83 : static clib_error_t *
84 0 : virtio_pci_delete_command_fn (vlib_main_t * vm, unformat_input_t * input,
85 : vlib_cli_command_t * cmd)
86 : {
87 0 : unformat_input_t _line_input, *line_input = &_line_input;
88 0 : u32 sw_if_index = ~0;
89 : vnet_hw_interface_t *hw;
90 0 : virtio_main_t *vim = &virtio_main;
91 : virtio_if_t *vif;
92 0 : vnet_main_t *vnm = vnet_get_main ();
93 :
94 : /* Get a line of input. */
95 0 : if (!unformat_user (input, unformat_line_input, line_input))
96 0 : return 0;
97 :
98 0 : while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
99 : {
100 0 : if (unformat (line_input, "sw_if_index %d", &sw_if_index))
101 : ;
102 0 : else if (unformat (line_input, "%U", unformat_vnet_sw_interface,
103 : vnm, &sw_if_index))
104 : ;
105 : else
106 0 : return clib_error_return (0, "unknown input `%U'",
107 : format_unformat_error, input);
108 : }
109 0 : unformat_free (line_input);
110 :
111 0 : if (sw_if_index == ~0)
112 0 : return clib_error_return (0,
113 : "please specify interface name or sw_if_index");
114 :
115 0 : hw = vnet_get_sup_hw_interface_api_visible_or_null (vnm, sw_if_index);
116 0 : if (hw == NULL || virtio_device_class.index != hw->dev_class_index)
117 0 : return clib_error_return (0, "not a virtio interface");
118 :
119 0 : vif = pool_elt_at_index (vim->interfaces, hw->dev_instance);
120 :
121 0 : if (virtio_pci_delete_if (vm, vif) < 0)
122 0 : return clib_error_return (0, "not a virtio pci interface");
123 :
124 0 : return 0;
125 : }
126 :
127 : /* *INDENT-OFF* */
128 272887 : VLIB_CLI_COMMAND (virtio_pci_delete_command, static) = {
129 : .path = "delete interface virtio",
130 : .short_help = "delete interface virtio "
131 : "{<interface> | sw_if_index <sw_idx>}",
132 : .function = virtio_pci_delete_command_fn,
133 : };
134 : /* *INDENT-ON* */
135 :
136 : static clib_error_t *
137 0 : virtio_pci_enable_command_fn (vlib_main_t * vm, unformat_input_t * input,
138 : vlib_cli_command_t * cmd)
139 : {
140 0 : unformat_input_t _line_input, *line_input = &_line_input;
141 0 : u32 sw_if_index = ~0;
142 : vnet_hw_interface_t *hw;
143 0 : virtio_main_t *vim = &virtio_main;
144 : virtio_if_t *vif;
145 0 : vnet_main_t *vnm = vnet_get_main ();
146 0 : int gso_enabled = 0, checksum_offload_enabled = 0;
147 0 : int offloads_disabled = 0;
148 :
149 : /* Get a line of input. */
150 0 : if (!unformat_user (input, unformat_line_input, line_input))
151 0 : return 0;
152 :
153 0 : while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
154 : {
155 0 : if (unformat (line_input, "sw_if_index %d", &sw_if_index))
156 : ;
157 0 : else if (unformat (line_input, "%U", unformat_vnet_sw_interface,
158 : vnm, &sw_if_index))
159 : ;
160 0 : else if (unformat (line_input, "gso-enabled"))
161 0 : gso_enabled = 1;
162 0 : else if (unformat (line_input, "csum-offload-enabled"))
163 0 : checksum_offload_enabled = 1;
164 0 : else if (unformat (line_input, "offloads-disabled"))
165 0 : offloads_disabled = 1;
166 : else
167 0 : return clib_error_return (0, "unknown input `%U'",
168 : format_unformat_error, input);
169 : }
170 0 : unformat_free (line_input);
171 :
172 0 : if (sw_if_index == ~0)
173 0 : return clib_error_return (0,
174 : "please specify interface name or sw_if_index");
175 :
176 0 : hw = vnet_get_sup_hw_interface_api_visible_or_null (vnm, sw_if_index);
177 0 : if (hw == NULL || virtio_device_class.index != hw->dev_class_index)
178 0 : return clib_error_return (0, "not a virtio interface");
179 :
180 0 : vif = pool_elt_at_index (vim->interfaces, hw->dev_instance);
181 :
182 0 : if (virtio_pci_enable_disable_offloads
183 : (vm, vif, gso_enabled, checksum_offload_enabled, offloads_disabled) < 0)
184 0 : return clib_error_return (0, "not able to enable/disable offloads");
185 :
186 0 : return 0;
187 : }
188 :
189 : /* *INDENT-OFF* */
190 272887 : VLIB_CLI_COMMAND (virtio_pci_enable_command, static) = {
191 : .path = "set virtio pci",
192 : .short_help = "set virtio pci {<interface> | sw_if_index <sw_idx>}"
193 : " [gso-enabled | csum-offload-enabled | offloads-disabled]",
194 : .function = virtio_pci_enable_command_fn,
195 : };
196 : /* *INDENT-ON* */
197 :
198 : static clib_error_t *
199 0 : show_virtio_pci_fn (vlib_main_t * vm, unformat_input_t * input,
200 : vlib_cli_command_t * cmd)
201 : {
202 0 : virtio_main_t *vim = &virtio_main;
203 0 : vnet_main_t *vnm = &vnet_main;
204 : virtio_if_t *vif;
205 0 : clib_error_t *error = 0;
206 0 : u32 hw_if_index, *hw_if_indices = 0;
207 : vnet_hw_interface_t *hi;
208 0 : u8 show_descr = 0, show_device_config = 0;
209 :
210 0 : while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
211 : {
212 0 : if (unformat
213 : (input, "%U", unformat_vnet_hw_interface, vnm, &hw_if_index))
214 : {
215 0 : hi = vnet_get_hw_interface (vnm, hw_if_index);
216 0 : if (virtio_device_class.index != hi->dev_class_index)
217 : {
218 0 : error = clib_error_return (0, "unknown input `%U'",
219 : format_unformat_error, input);
220 0 : goto done;
221 : }
222 0 : vec_add1 (hw_if_indices, hw_if_index);
223 : }
224 0 : else if (unformat (input, "descriptors") || unformat (input, "desc"))
225 0 : show_descr = 1;
226 0 : else if (unformat (input, "debug-device"))
227 0 : show_device_config = 1;
228 : else
229 : {
230 0 : error = clib_error_return (0, "unknown input `%U'",
231 : format_unformat_error, input);
232 0 : goto done;
233 : }
234 : }
235 :
236 0 : if (vec_len (hw_if_indices) == 0)
237 : {
238 0 : pool_foreach (vif, vim->interfaces)
239 0 : vec_add1 (hw_if_indices, vif->hw_if_index);
240 : }
241 0 : else if (show_device_config)
242 : {
243 0 : vif = pool_elt_at_index (vim->interfaces, hi->dev_instance);
244 0 : if (vif->type == VIRTIO_IF_TYPE_PCI)
245 0 : vif->virtio_pci_func->device_debug_config_space (vm, vif);
246 : }
247 :
248 0 : virtio_show (vm, hw_if_indices, show_descr, VIRTIO_IF_TYPE_PCI);
249 :
250 0 : done:
251 0 : vec_free (hw_if_indices);
252 0 : return error;
253 : }
254 :
255 : /* *INDENT-OFF* */
256 272887 : VLIB_CLI_COMMAND (show_virtio_pci_command, static) = {
257 : .path = "show virtio pci",
258 : .short_help = "show virtio pci [<interface>] [descriptors | desc] [debug-device]",
259 : .function = show_virtio_pci_fn,
260 : };
261 : /* *INDENT-ON* */
262 :
263 : clib_error_t *
264 559 : virtio_pci_cli_init (vlib_main_t * vm)
265 : {
266 559 : return 0;
267 : }
268 :
269 73919 : VLIB_INIT_FUNCTION (virtio_pci_cli_init);
270 :
271 : /*
272 : * fd.io coding-style-patch-verification: ON
273 : *
274 : * Local Variables:
275 : * eval: (c-set-style "gnu")
276 : * End:
277 : */
|