Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2017 Intel Corporation
3 : : */
4 : :
5 : : #include <ctype.h>
6 : : #include <sys/queue.h>
7 : : #include <stdalign.h>
8 : : #include <stdio.h>
9 : : #include <errno.h>
10 : : #include <stdint.h>
11 : : #include <string.h>
12 : : #include <unistd.h>
13 : : #include <stdarg.h>
14 : : #include <inttypes.h>
15 : : #include <rte_byteorder.h>
16 : : #include <rte_common.h>
17 : : #include <rte_os_shim.h>
18 : :
19 : : #include <rte_interrupts.h>
20 : : #include <rte_debug.h>
21 : : #include <rte_pci.h>
22 : : #include <rte_alarm.h>
23 : : #include <rte_atomic.h>
24 : : #include <rte_eal.h>
25 : : #include <rte_ether.h>
26 : : #include <ethdev_driver.h>
27 : : #include <ethdev_pci.h>
28 : : #include <rte_malloc.h>
29 : : #include <rte_memzone.h>
30 : : #include <dev_driver.h>
31 : : #include <eal_export.h>
32 : :
33 : : #include "iavf.h"
34 : : #include "iavf_rxtx.h"
35 : : #include "iavf_generic_flow.h"
36 : : #include "rte_pmd_iavf.h"
37 : : #include "iavf_ipsec_crypto.h"
38 : :
39 : : /* devargs */
40 : : #define IAVF_PROTO_XTR_ARG "proto_xtr"
41 : : #define IAVF_QUANTA_SIZE_ARG "quanta_size"
42 : : #define IAVF_RESET_WATCHDOG_ARG "watchdog_period"
43 : : #define IAVF_ENABLE_AUTO_RESET_ARG "auto_reset"
44 : : #define IAVF_NO_POLL_ON_LINK_DOWN_ARG "no-poll-on-link-down"
45 : : #define IAVF_MBUF_CHECK_ARG "mbuf_check"
46 : : uint64_t iavf_timestamp_dynflag;
47 : : int iavf_timestamp_dynfield_offset = -1;
48 : : int rte_pmd_iavf_tx_lldp_dynfield_offset = -1;
49 : :
50 : : static const char * const iavf_valid_args[] = {
51 : : IAVF_PROTO_XTR_ARG,
52 : : IAVF_QUANTA_SIZE_ARG,
53 : : IAVF_RESET_WATCHDOG_ARG,
54 : : IAVF_ENABLE_AUTO_RESET_ARG,
55 : : IAVF_NO_POLL_ON_LINK_DOWN_ARG,
56 : : IAVF_MBUF_CHECK_ARG,
57 : : NULL
58 : : };
59 : :
60 : : static const struct rte_mbuf_dynfield iavf_proto_xtr_metadata_param = {
61 : : .name = "intel_pmd_dynfield_proto_xtr_metadata",
62 : : .size = sizeof(uint32_t),
63 : : .align = alignof(uint32_t),
64 : : .flags = 0,
65 : : };
66 : :
67 : : struct iavf_proto_xtr_ol {
68 : : const struct rte_mbuf_dynflag param;
69 : : uint64_t *ol_flag;
70 : : bool required;
71 : : };
72 : :
73 : : static struct iavf_proto_xtr_ol iavf_proto_xtr_params[] = {
74 : : [IAVF_PROTO_XTR_VLAN] = {
75 : : .param = { .name = "intel_pmd_dynflag_proto_xtr_vlan" },
76 : : .ol_flag = &rte_pmd_ifd_dynflag_proto_xtr_vlan_mask },
77 : : [IAVF_PROTO_XTR_IPV4] = {
78 : : .param = { .name = "intel_pmd_dynflag_proto_xtr_ipv4" },
79 : : .ol_flag = &rte_pmd_ifd_dynflag_proto_xtr_ipv4_mask },
80 : : [IAVF_PROTO_XTR_IPV6] = {
81 : : .param = { .name = "intel_pmd_dynflag_proto_xtr_ipv6" },
82 : : .ol_flag = &rte_pmd_ifd_dynflag_proto_xtr_ipv6_mask },
83 : : [IAVF_PROTO_XTR_IPV6_FLOW] = {
84 : : .param = { .name = "intel_pmd_dynflag_proto_xtr_ipv6_flow" },
85 : : .ol_flag = &rte_pmd_ifd_dynflag_proto_xtr_ipv6_flow_mask },
86 : : [IAVF_PROTO_XTR_TCP] = {
87 : : .param = { .name = "intel_pmd_dynflag_proto_xtr_tcp" },
88 : : .ol_flag = &rte_pmd_ifd_dynflag_proto_xtr_tcp_mask },
89 : : [IAVF_PROTO_XTR_IP_OFFSET] = {
90 : : .param = { .name = "intel_pmd_dynflag_proto_xtr_ip_offset" },
91 : : .ol_flag = &rte_pmd_ifd_dynflag_proto_xtr_ip_offset_mask },
92 : : [IAVF_PROTO_XTR_IPSEC_CRYPTO_SAID] = {
93 : : .param = {
94 : : .name = "intel_pmd_dynflag_proto_xtr_ipsec_crypto_said" },
95 : : .ol_flag =
96 : : &rte_pmd_ifd_dynflag_proto_xtr_ipsec_crypto_said_mask },
97 : : };
98 : :
99 : : static int iavf_dev_configure(struct rte_eth_dev *dev);
100 : : static int iavf_dev_start(struct rte_eth_dev *dev);
101 : : static int iavf_dev_stop(struct rte_eth_dev *dev);
102 : : static int iavf_dev_close(struct rte_eth_dev *dev);
103 : : static int iavf_dev_reset(struct rte_eth_dev *dev);
104 : : static int iavf_dev_info_get(struct rte_eth_dev *dev,
105 : : struct rte_eth_dev_info *dev_info);
106 : : static const uint32_t *iavf_dev_supported_ptypes_get(struct rte_eth_dev *dev,
107 : : size_t *no_of_elements);
108 : : static int iavf_dev_stats_get(struct rte_eth_dev *dev,
109 : : struct rte_eth_stats *stats, struct eth_queue_stats *qstats);
110 : : static int iavf_dev_stats_reset(struct rte_eth_dev *dev);
111 : : static int iavf_dev_xstats_reset(struct rte_eth_dev *dev);
112 : : static int iavf_dev_xstats_get(struct rte_eth_dev *dev,
113 : : struct rte_eth_xstat *xstats, unsigned int n);
114 : : static int iavf_dev_xstats_get_names(struct rte_eth_dev *dev,
115 : : struct rte_eth_xstat_name *xstats_names,
116 : : unsigned int limit);
117 : : static int iavf_dev_promiscuous_enable(struct rte_eth_dev *dev);
118 : : static int iavf_dev_promiscuous_disable(struct rte_eth_dev *dev);
119 : : static int iavf_dev_allmulticast_enable(struct rte_eth_dev *dev);
120 : : static int iavf_dev_allmulticast_disable(struct rte_eth_dev *dev);
121 : : static int iavf_dev_add_mac_addr(struct rte_eth_dev *dev,
122 : : struct rte_ether_addr *addr,
123 : : uint32_t index,
124 : : uint32_t pool);
125 : : static void iavf_dev_del_mac_addr(struct rte_eth_dev *dev, uint32_t index);
126 : : static int iavf_dev_vlan_filter_set(struct rte_eth_dev *dev,
127 : : uint16_t vlan_id, int on);
128 : : static int iavf_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask);
129 : : static int iavf_dev_rss_reta_update(struct rte_eth_dev *dev,
130 : : struct rte_eth_rss_reta_entry64 *reta_conf,
131 : : uint16_t reta_size);
132 : : static int iavf_dev_rss_reta_query(struct rte_eth_dev *dev,
133 : : struct rte_eth_rss_reta_entry64 *reta_conf,
134 : : uint16_t reta_size);
135 : : static int iavf_dev_rss_hash_update(struct rte_eth_dev *dev,
136 : : struct rte_eth_rss_conf *rss_conf);
137 : : static int iavf_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
138 : : struct rte_eth_rss_conf *rss_conf);
139 : : static int iavf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
140 : : static int iavf_dev_set_default_mac_addr(struct rte_eth_dev *dev,
141 : : struct rte_ether_addr *mac_addr);
142 : : static int iavf_dev_rx_queue_intr_enable(struct rte_eth_dev *dev,
143 : : uint16_t queue_id);
144 : : static int iavf_dev_rx_queue_intr_disable(struct rte_eth_dev *dev,
145 : : uint16_t queue_id);
146 : : static void iavf_dev_interrupt_handler(void *param);
147 : : static void iavf_disable_irq0(struct iavf_hw *hw);
148 : : static int iavf_dev_flow_ops_get(struct rte_eth_dev *dev,
149 : : const struct rte_flow_ops **ops);
150 : : static int iavf_set_mc_addr_list(struct rte_eth_dev *dev,
151 : : struct rte_ether_addr *mc_addrs,
152 : : uint32_t mc_addrs_num);
153 : : static int iavf_tm_ops_get(struct rte_eth_dev *dev __rte_unused, void *arg);
154 : :
155 : : static const struct rte_pci_id pci_id_iavf_map[] = {
156 : : { RTE_PCI_DEVICE(IAVF_INTEL_VENDOR_ID, IAVF_DEV_ID_ADAPTIVE_VF) },
157 : : { RTE_PCI_DEVICE(IAVF_INTEL_VENDOR_ID, IAVF_DEV_ID_VF) },
158 : : { RTE_PCI_DEVICE(IAVF_INTEL_VENDOR_ID, IAVF_DEV_ID_VF_HV) },
159 : : { RTE_PCI_DEVICE(IAVF_INTEL_VENDOR_ID, IAVF_DEV_ID_X722_VF) },
160 : : { RTE_PCI_DEVICE(IAVF_INTEL_VENDOR_ID, IAVF_DEV_ID_X722_A0_VF) },
161 : : { .vendor_id = 0, /* sentinel */ },
162 : : };
163 : :
164 : : struct rte_iavf_xstats_name_off {
165 : : char name[RTE_ETH_XSTATS_NAME_SIZE];
166 : : unsigned int offset;
167 : : };
168 : :
169 : : #define _OFF_OF(a) offsetof(struct iavf_eth_xstats, a)
170 : : static const struct rte_iavf_xstats_name_off rte_iavf_stats_strings[] = {
171 : : {"rx_bytes", _OFF_OF(eth_stats.rx_bytes)},
172 : : {"rx_unicast_packets", _OFF_OF(eth_stats.rx_unicast)},
173 : : {"rx_multicast_packets", _OFF_OF(eth_stats.rx_multicast)},
174 : : {"rx_broadcast_packets", _OFF_OF(eth_stats.rx_broadcast)},
175 : : {"rx_dropped_packets", _OFF_OF(eth_stats.rx_discards)},
176 : : {"rx_unknown_protocol_packets", offsetof(struct iavf_eth_stats,
177 : : rx_unknown_protocol)},
178 : : {"tx_bytes", _OFF_OF(eth_stats.tx_bytes)},
179 : : {"tx_unicast_packets", _OFF_OF(eth_stats.tx_unicast)},
180 : : {"tx_multicast_packets", _OFF_OF(eth_stats.tx_multicast)},
181 : : {"tx_broadcast_packets", _OFF_OF(eth_stats.tx_broadcast)},
182 : : {"tx_dropped_packets", _OFF_OF(eth_stats.tx_discards)},
183 : : {"tx_error_packets", _OFF_OF(eth_stats.tx_errors)},
184 : : {"tx_mbuf_error_packets", _OFF_OF(mbuf_stats.tx_pkt_errors)},
185 : :
186 : : {"inline_ipsec_crypto_ipackets", _OFF_OF(ips_stats.icount)},
187 : : {"inline_ipsec_crypto_ibytes", _OFF_OF(ips_stats.ibytes)},
188 : : {"inline_ipsec_crypto_ierrors", _OFF_OF(ips_stats.ierrors.count)},
189 : : {"inline_ipsec_crypto_ierrors_sad_lookup",
190 : : _OFF_OF(ips_stats.ierrors.sad_miss)},
191 : : {"inline_ipsec_crypto_ierrors_not_processed",
192 : : _OFF_OF(ips_stats.ierrors.not_processed)},
193 : : {"inline_ipsec_crypto_ierrors_icv_fail",
194 : : _OFF_OF(ips_stats.ierrors.icv_check)},
195 : : {"inline_ipsec_crypto_ierrors_length",
196 : : _OFF_OF(ips_stats.ierrors.ipsec_length)},
197 : : {"inline_ipsec_crypto_ierrors_misc",
198 : : _OFF_OF(ips_stats.ierrors.misc)},
199 : : };
200 : : #undef _OFF_OF
201 : :
202 : : #define IAVF_NB_XSTATS (sizeof(rte_iavf_stats_strings) / \
203 : : sizeof(rte_iavf_stats_strings[0]))
204 : :
205 : : static const struct eth_dev_ops iavf_eth_dev_ops = {
206 : : .dev_configure = iavf_dev_configure,
207 : : .dev_start = iavf_dev_start,
208 : : .dev_stop = iavf_dev_stop,
209 : : .dev_close = iavf_dev_close,
210 : : .dev_reset = iavf_dev_reset,
211 : : .dev_infos_get = iavf_dev_info_get,
212 : : .dev_supported_ptypes_get = iavf_dev_supported_ptypes_get,
213 : : .link_update = iavf_dev_link_update,
214 : : .stats_get = iavf_dev_stats_get,
215 : : .stats_reset = iavf_dev_stats_reset,
216 : : .xstats_get = iavf_dev_xstats_get,
217 : : .xstats_get_names = iavf_dev_xstats_get_names,
218 : : .xstats_reset = iavf_dev_xstats_reset,
219 : : .promiscuous_enable = iavf_dev_promiscuous_enable,
220 : : .promiscuous_disable = iavf_dev_promiscuous_disable,
221 : : .allmulticast_enable = iavf_dev_allmulticast_enable,
222 : : .allmulticast_disable = iavf_dev_allmulticast_disable,
223 : : .mac_addr_add = iavf_dev_add_mac_addr,
224 : : .mac_addr_remove = iavf_dev_del_mac_addr,
225 : : .set_mc_addr_list = iavf_set_mc_addr_list,
226 : : .vlan_filter_set = iavf_dev_vlan_filter_set,
227 : : .vlan_offload_set = iavf_dev_vlan_offload_set,
228 : : .rx_queue_start = iavf_dev_rx_queue_start,
229 : : .rx_queue_stop = iavf_dev_rx_queue_stop,
230 : : .tx_queue_start = iavf_dev_tx_queue_start,
231 : : .tx_queue_stop = iavf_dev_tx_queue_stop,
232 : : .rx_queue_setup = iavf_dev_rx_queue_setup,
233 : : .rx_queue_release = iavf_dev_rx_queue_release,
234 : : .tx_queue_setup = iavf_dev_tx_queue_setup,
235 : : .tx_queue_release = iavf_dev_tx_queue_release,
236 : : .mac_addr_set = iavf_dev_set_default_mac_addr,
237 : : .reta_update = iavf_dev_rss_reta_update,
238 : : .reta_query = iavf_dev_rss_reta_query,
239 : : .rss_hash_update = iavf_dev_rss_hash_update,
240 : : .rss_hash_conf_get = iavf_dev_rss_hash_conf_get,
241 : : .rxq_info_get = iavf_dev_rxq_info_get,
242 : : .txq_info_get = iavf_dev_txq_info_get,
243 : : .rx_burst_mode_get = iavf_rx_burst_mode_get,
244 : : .tx_burst_mode_get = iavf_tx_burst_mode_get,
245 : : .mtu_set = iavf_dev_mtu_set,
246 : : .rx_queue_intr_enable = iavf_dev_rx_queue_intr_enable,
247 : : .rx_queue_intr_disable = iavf_dev_rx_queue_intr_disable,
248 : : .flow_ops_get = iavf_dev_flow_ops_get,
249 : : .tx_done_cleanup = iavf_dev_tx_done_cleanup,
250 : : .get_monitor_addr = iavf_get_monitor_addr,
251 : : .tm_ops_get = iavf_tm_ops_get,
252 : : };
253 : :
254 : : static int
255 : 0 : iavf_tm_ops_get(struct rte_eth_dev *dev,
256 : : void *arg)
257 : : {
258 : 0 : struct iavf_adapter *adapter =
259 : 0 : IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
260 : :
261 [ # # ]: 0 : if (adapter->closed)
262 : : return -EIO;
263 : :
264 [ # # ]: 0 : if (!arg)
265 : : return -EINVAL;
266 : :
267 : 0 : *(const void **)arg = &iavf_tm_ops;
268 : :
269 : 0 : return 0;
270 : : }
271 : :
272 : : __rte_unused
273 : : static int
274 : 0 : iavf_vfr_inprogress(struct iavf_hw *hw)
275 : : {
276 : : int inprogress = 0;
277 : :
278 [ # # ]: 0 : if ((IAVF_READ_REG(hw, IAVF_VFGEN_RSTAT) &
279 : : IAVF_VFGEN_RSTAT_VFR_STATE_MASK) ==
280 : : VIRTCHNL_VFR_INPROGRESS)
281 : : inprogress = 1;
282 : :
283 : : if (inprogress)
284 : 0 : PMD_DRV_LOG(INFO, "Watchdog detected VFR in progress");
285 : :
286 : 0 : return inprogress;
287 : : }
288 : :
289 : : __rte_unused
290 : : static void
291 : 0 : iavf_dev_watchdog(void *cb_arg)
292 : : {
293 : : struct iavf_adapter *adapter = cb_arg;
294 : 0 : struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(adapter);
295 : : int vfr_inprogress = 0, rc = 0;
296 : :
297 : : /* check if watchdog has been disabled since last call */
298 [ # # ]: 0 : if (!adapter->vf.watchdog_enabled)
299 : : return;
300 : :
301 : : /* If in reset then poll vfr_inprogress register for completion */
302 [ # # ]: 0 : if (adapter->vf.vf_reset) {
303 : 0 : vfr_inprogress = iavf_vfr_inprogress(hw);
304 : :
305 [ # # ]: 0 : if (!vfr_inprogress) {
306 : 0 : PMD_DRV_LOG(INFO, "VF \"%s\" reset has completed",
307 : : adapter->vf.eth_dev->data->name);
308 : 0 : adapter->vf.vf_reset = false;
309 : 0 : iavf_set_no_poll(adapter, false);
310 : : }
311 : : /* If not in reset then poll vfr_inprogress register for VFLR event */
312 : : } else {
313 : 0 : vfr_inprogress = iavf_vfr_inprogress(hw);
314 : :
315 [ # # ]: 0 : if (vfr_inprogress) {
316 : 0 : PMD_DRV_LOG(INFO,
317 : : "VF \"%s\" reset event detected by watchdog",
318 : : adapter->vf.eth_dev->data->name);
319 : :
320 : : /* enter reset state with VFLR event */
321 : 0 : adapter->vf.vf_reset = true;
322 : 0 : iavf_set_no_poll(adapter, false);
323 : 0 : adapter->vf.link_up = false;
324 : :
325 : 0 : iavf_dev_event_post(adapter->vf.eth_dev, RTE_ETH_EVENT_INTR_RESET,
326 : : NULL, 0);
327 : : }
328 : : }
329 : :
330 [ # # ]: 0 : if (adapter->devargs.watchdog_period) {
331 : : /* re-alarm watchdog */
332 : 0 : rc = rte_eal_alarm_set(adapter->devargs.watchdog_period,
333 : : &iavf_dev_watchdog, cb_arg);
334 : :
335 [ # # ]: 0 : if (rc)
336 : 0 : PMD_DRV_LOG(ERR, "Failed \"%s\" to reset device watchdog alarm",
337 : : adapter->vf.eth_dev->data->name);
338 : : }
339 : : }
340 : :
341 : : void
342 : 0 : iavf_dev_watchdog_enable(struct iavf_adapter *adapter)
343 : : {
344 [ # # ]: 0 : if (!adapter->devargs.watchdog_period) {
345 : 0 : PMD_DRV_LOG(INFO, "Device watchdog is disabled");
346 : : } else {
347 [ # # ]: 0 : if (!adapter->vf.watchdog_enabled) {
348 : 0 : PMD_DRV_LOG(INFO, "Enabling device watchdog, period is %dμs",
349 : : adapter->devargs.watchdog_period);
350 : 0 : adapter->vf.watchdog_enabled = true;
351 [ # # ]: 0 : if (rte_eal_alarm_set(adapter->devargs.watchdog_period,
352 : : &iavf_dev_watchdog, (void *)adapter))
353 : 0 : PMD_DRV_LOG(ERR, "Failed to enable device watchdog");
354 : : }
355 : : }
356 : 0 : }
357 : :
358 : : void
359 : 0 : iavf_dev_watchdog_disable(struct iavf_adapter *adapter)
360 : : {
361 [ # # ]: 0 : if (!adapter->devargs.watchdog_period) {
362 : 0 : PMD_DRV_LOG(INFO, "Device watchdog is not enabled");
363 : : } else {
364 [ # # ]: 0 : if (adapter->vf.watchdog_enabled) {
365 : 0 : PMD_DRV_LOG(INFO, "Disabling device watchdog");
366 : 0 : adapter->vf.watchdog_enabled = false;
367 : 0 : rte_eal_alarm_cancel(&iavf_dev_watchdog, (void *)adapter);
368 : : }
369 : : }
370 : 0 : }
371 : :
372 : : static int
373 : 0 : iavf_set_mc_addr_list(struct rte_eth_dev *dev,
374 : : struct rte_ether_addr *mc_addrs,
375 : : uint32_t mc_addrs_num)
376 : : {
377 : 0 : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
378 : : struct iavf_adapter *adapter =
379 : : IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
380 : : int err, ret;
381 : :
382 [ # # ]: 0 : if (mc_addrs_num > IAVF_NUM_MACADDR_MAX) {
383 : 0 : PMD_DRV_LOG(ERR,
384 : : "can't add more than a limited number (%u) of addresses.",
385 : : (uint32_t)IAVF_NUM_MACADDR_MAX);
386 : 0 : return -EINVAL;
387 : : }
388 : :
389 [ # # ]: 0 : if (adapter->closed)
390 : : return -EIO;
391 : :
392 : : /* flush previous addresses */
393 : 0 : err = iavf_add_del_mc_addr_list(adapter, vf->mc_addrs, vf->mc_addrs_num,
394 : : false);
395 [ # # ]: 0 : if (err)
396 : : return err;
397 : :
398 : : /* add new ones */
399 : 0 : err = iavf_add_del_mc_addr_list(adapter, mc_addrs, mc_addrs_num, true);
400 : :
401 [ # # ]: 0 : if (err) {
402 : : /* if adding mac address list fails, should add the previous
403 : : * addresses back.
404 : : */
405 : 0 : ret = iavf_add_del_mc_addr_list(adapter, vf->mc_addrs,
406 : 0 : vf->mc_addrs_num, true);
407 [ # # ]: 0 : if (ret)
408 : 0 : return ret;
409 : : } else {
410 : 0 : vf->mc_addrs_num = mc_addrs_num;
411 : 0 : memcpy(vf->mc_addrs,
412 : : mc_addrs, mc_addrs_num * sizeof(*mc_addrs));
413 : : }
414 : :
415 : : return err;
416 : : }
417 : :
418 : : static void
419 : 0 : iavf_config_rss_hf(struct iavf_adapter *adapter, uint64_t rss_hf)
420 : : {
421 : : static const uint64_t map_hena_rss[] = {
422 : : /* IPv4 */
423 : : [IAVF_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP] =
424 : : RTE_ETH_RSS_NONFRAG_IPV4_UDP,
425 : : [IAVF_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP] =
426 : : RTE_ETH_RSS_NONFRAG_IPV4_UDP,
427 : : [IAVF_FILTER_PCTYPE_NONF_IPV4_UDP] =
428 : : RTE_ETH_RSS_NONFRAG_IPV4_UDP,
429 : : [IAVF_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK] =
430 : : RTE_ETH_RSS_NONFRAG_IPV4_TCP,
431 : : [IAVF_FILTER_PCTYPE_NONF_IPV4_TCP] =
432 : : RTE_ETH_RSS_NONFRAG_IPV4_TCP,
433 : : [IAVF_FILTER_PCTYPE_NONF_IPV4_SCTP] =
434 : : RTE_ETH_RSS_NONFRAG_IPV4_SCTP,
435 : : [IAVF_FILTER_PCTYPE_NONF_IPV4_OTHER] =
436 : : RTE_ETH_RSS_NONFRAG_IPV4_OTHER,
437 : : [IAVF_FILTER_PCTYPE_FRAG_IPV4] = RTE_ETH_RSS_FRAG_IPV4,
438 : :
439 : : /* IPv6 */
440 : : [IAVF_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP] =
441 : : RTE_ETH_RSS_NONFRAG_IPV6_UDP,
442 : : [IAVF_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP] =
443 : : RTE_ETH_RSS_NONFRAG_IPV6_UDP,
444 : : [IAVF_FILTER_PCTYPE_NONF_IPV6_UDP] =
445 : : RTE_ETH_RSS_NONFRAG_IPV6_UDP,
446 : : [IAVF_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK] =
447 : : RTE_ETH_RSS_NONFRAG_IPV6_TCP,
448 : : [IAVF_FILTER_PCTYPE_NONF_IPV6_TCP] =
449 : : RTE_ETH_RSS_NONFRAG_IPV6_TCP,
450 : : [IAVF_FILTER_PCTYPE_NONF_IPV6_SCTP] =
451 : : RTE_ETH_RSS_NONFRAG_IPV6_SCTP,
452 : : [IAVF_FILTER_PCTYPE_NONF_IPV6_OTHER] =
453 : : RTE_ETH_RSS_NONFRAG_IPV6_OTHER,
454 : : [IAVF_FILTER_PCTYPE_FRAG_IPV6] = RTE_ETH_RSS_FRAG_IPV6,
455 : :
456 : : /* L2 Payload */
457 : : [IAVF_FILTER_PCTYPE_L2_PAYLOAD] = RTE_ETH_RSS_L2_PAYLOAD
458 : : };
459 : :
460 : : const uint64_t ipv4_rss = RTE_ETH_RSS_NONFRAG_IPV4_UDP |
461 : : RTE_ETH_RSS_NONFRAG_IPV4_TCP |
462 : : RTE_ETH_RSS_NONFRAG_IPV4_SCTP |
463 : : RTE_ETH_RSS_NONFRAG_IPV4_OTHER |
464 : : RTE_ETH_RSS_FRAG_IPV4;
465 : :
466 : : const uint64_t ipv6_rss = RTE_ETH_RSS_NONFRAG_IPV6_UDP |
467 : : RTE_ETH_RSS_NONFRAG_IPV6_TCP |
468 : : RTE_ETH_RSS_NONFRAG_IPV6_SCTP |
469 : : RTE_ETH_RSS_NONFRAG_IPV6_OTHER |
470 : : RTE_ETH_RSS_FRAG_IPV6;
471 : :
472 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
473 : 0 : uint64_t caps = 0, hena = 0, valid_rss_hf = 0;
474 : : uint32_t i;
475 : : int ret;
476 : :
477 : 0 : ret = iavf_get_hena_caps(adapter, &caps);
478 [ # # ]: 0 : if (ret) {
479 : : /**
480 : : * RSS offload type configuration is not a necessary feature
481 : : * for VF, so here just print a warning and return.
482 : : */
483 : 0 : PMD_DRV_LOG(WARNING,
484 : : "fail to get RSS offload type caps, ret: %d", ret);
485 : 0 : return;
486 : : }
487 : :
488 : : /**
489 : : * RTE_ETH_RSS_IPV4 and RTE_ETH_RSS_IPV6 can be considered as 2
490 : : * generalizations of all other IPv4 and IPv6 RSS types.
491 : : */
492 [ # # ]: 0 : if (rss_hf & RTE_ETH_RSS_IPV4)
493 : 0 : rss_hf |= ipv4_rss;
494 : :
495 [ # # ]: 0 : if (rss_hf & RTE_ETH_RSS_IPV6)
496 : 0 : rss_hf |= ipv6_rss;
497 : :
498 : : RTE_BUILD_BUG_ON(RTE_DIM(map_hena_rss) > sizeof(uint64_t) * CHAR_BIT);
499 : :
500 [ # # ]: 0 : for (i = 0; i < RTE_DIM(map_hena_rss); i++) {
501 : 0 : uint64_t bit = BIT_ULL(i);
502 : :
503 [ # # # # ]: 0 : if ((caps & bit) && (map_hena_rss[i] & rss_hf)) {
504 : 0 : valid_rss_hf |= map_hena_rss[i];
505 : 0 : hena |= bit;
506 : : }
507 : : }
508 : :
509 : 0 : ret = iavf_set_hena(adapter, hena);
510 [ # # ]: 0 : if (ret) {
511 : : /**
512 : : * RSS offload type configuration is not a necessary feature
513 : : * for VF, so here just print a warning and return.
514 : : */
515 : 0 : PMD_DRV_LOG(WARNING,
516 : : "fail to set RSS offload types, ret: %d", ret);
517 : 0 : return;
518 : : }
519 : :
520 [ # # ]: 0 : if (valid_rss_hf & ipv4_rss)
521 : 0 : valid_rss_hf |= rss_hf & RTE_ETH_RSS_IPV4;
522 : :
523 [ # # ]: 0 : if (valid_rss_hf & ipv6_rss)
524 : 0 : valid_rss_hf |= rss_hf & RTE_ETH_RSS_IPV6;
525 : :
526 [ # # ]: 0 : if (rss_hf & ~valid_rss_hf)
527 : 0 : PMD_DRV_LOG(WARNING, "Unsupported rss_hf 0x%" PRIx64,
528 : : rss_hf & ~valid_rss_hf);
529 : :
530 : 0 : vf->rss_hf = valid_rss_hf;
531 : : }
532 : :
533 : : static int
534 : 0 : iavf_init_rss(struct iavf_adapter *adapter)
535 : : {
536 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
537 : : struct rte_eth_rss_conf *rss_conf;
538 : : uint16_t i, j, nb_q;
539 : : int ret;
540 : :
541 : 0 : rss_conf = &adapter->dev_data->dev_conf.rx_adv_conf.rss_conf;
542 : 0 : nb_q = RTE_MIN(adapter->dev_data->nb_rx_queues,
543 : : vf->max_rss_qregion);
544 : :
545 [ # # ]: 0 : if (!(vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_PF)) {
546 : 0 : PMD_DRV_LOG(DEBUG, "RSS is not supported");
547 : 0 : return -ENOTSUP;
548 : : }
549 : :
550 : : /* configure RSS key */
551 [ # # ]: 0 : if (!rss_conf->rss_key) {
552 : : /* Calculate the default hash key */
553 [ # # ]: 0 : for (i = 0; i < vf->vf_res->rss_key_size; i++)
554 : 0 : vf->rss_key[i] = (uint8_t)rte_rand();
555 : : } else
556 : 0 : rte_memcpy(vf->rss_key, rss_conf->rss_key,
557 [ # # ]: 0 : RTE_MIN(rss_conf->rss_key_len,
558 : : vf->vf_res->rss_key_size));
559 : :
560 : : /* init RSS LUT table */
561 [ # # ]: 0 : for (i = 0, j = 0; i < vf->vf_res->rss_lut_size; i++, j++) {
562 [ # # ]: 0 : if (j >= nb_q)
563 : : j = 0;
564 : 0 : vf->rss_lut[i] = j;
565 : : }
566 : : /* send virtchnl ops to configure RSS */
567 : 0 : ret = iavf_configure_rss_lut(adapter);
568 [ # # ]: 0 : if (ret)
569 : : return ret;
570 : 0 : ret = iavf_configure_rss_key(adapter);
571 [ # # ]: 0 : if (ret)
572 : : return ret;
573 : :
574 [ # # ]: 0 : if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF) {
575 : : /* Set RSS hash configuration based on rss_conf->rss_hf. */
576 : 0 : ret = iavf_rss_hash_set(adapter, rss_conf->rss_hf, true);
577 [ # # ]: 0 : if (ret) {
578 : 0 : PMD_DRV_LOG(ERR, "fail to set default RSS");
579 : 0 : return ret;
580 : : }
581 : : } else {
582 : 0 : iavf_config_rss_hf(adapter, rss_conf->rss_hf);
583 : : }
584 : :
585 : : return 0;
586 : : }
587 : :
588 : : static int
589 : 0 : iavf_queues_req_reset(struct rte_eth_dev *dev, uint16_t num)
590 : : {
591 : 0 : struct iavf_adapter *ad =
592 : 0 : IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
593 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(ad);
594 : : int ret;
595 : :
596 : 0 : ret = iavf_request_queues(dev, num);
597 [ # # ]: 0 : if (ret) {
598 : 0 : PMD_DRV_LOG(ERR, "request queues from PF failed");
599 : 0 : return ret;
600 : : }
601 : 0 : PMD_DRV_LOG(INFO, "change queue pairs from %u to %u",
602 : : vf->vsi_res->num_queue_pairs, num);
603 : :
604 : 0 : iavf_dev_watchdog_disable(ad);
605 : 0 : ret = iavf_dev_reset(dev);
606 [ # # ]: 0 : if (ret) {
607 : 0 : PMD_DRV_LOG(ERR, "vf reset failed");
608 : 0 : return ret;
609 : : }
610 : :
611 : : return 0;
612 : : }
613 : :
614 : : static int
615 : 0 : iavf_dev_vlan_insert_set(struct rte_eth_dev *dev)
616 : : {
617 : 0 : struct iavf_adapter *adapter =
618 : 0 : IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
619 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
620 : : bool enable;
621 : :
622 [ # # ]: 0 : if (!(vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN_V2))
623 : : return 0;
624 : :
625 : 0 : enable = !!(dev->data->dev_conf.txmode.offloads &
626 : : (RTE_ETH_TX_OFFLOAD_VLAN_INSERT | RTE_ETH_TX_OFFLOAD_QINQ_INSERT));
627 : 0 : iavf_config_vlan_insert_v2(adapter, enable);
628 : :
629 : 0 : return 0;
630 : : }
631 : :
632 : : static int
633 : 0 : iavf_dev_init_vlan(struct rte_eth_dev *dev)
634 : : {
635 : : int err;
636 : :
637 : 0 : err = iavf_dev_vlan_offload_set(dev,
638 : : RTE_ETH_VLAN_STRIP_MASK |
639 : : RTE_ETH_QINQ_STRIP_MASK |
640 : : RTE_ETH_VLAN_FILTER_MASK |
641 : : RTE_ETH_VLAN_EXTEND_MASK);
642 [ # # ]: 0 : if (err) {
643 : 0 : PMD_DRV_LOG(INFO,
644 : : "VLAN offloading is not supported, or offloading was refused by the PF");
645 : 0 : return err;
646 : : }
647 : :
648 : 0 : err = iavf_dev_vlan_insert_set(dev);
649 [ # # ]: 0 : if (err)
650 : 0 : PMD_DRV_LOG(ERR, "Failed to update vlan insertion");
651 : :
652 : : return err;
653 : : }
654 : :
655 : : static int
656 : 0 : iavf_dev_configure(struct rte_eth_dev *dev)
657 : : {
658 : 0 : struct iavf_adapter *ad =
659 : 0 : IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
660 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(ad);
661 : 0 : uint16_t num_queue_pairs = RTE_MAX(dev->data->nb_rx_queues,
662 : : dev->data->nb_tx_queues);
663 : : int ret;
664 : :
665 [ # # ]: 0 : if (ad->closed)
666 : : return -EIO;
667 : :
668 : 0 : ad->rx_bulk_alloc_allowed = true;
669 : :
670 : 0 : ad->tx_func_type = IAVF_TX_DEFAULT;
671 : :
672 [ # # ]: 0 : if (dev->data->dev_conf.rxmode.mq_mode & RTE_ETH_MQ_RX_RSS_FLAG)
673 : 0 : dev->data->dev_conf.rxmode.offloads |= RTE_ETH_RX_OFFLOAD_RSS_HASH;
674 : :
675 : : /* Large VF setting */
676 [ # # ]: 0 : if (num_queue_pairs > IAVF_MAX_NUM_QUEUES_DFLT) {
677 [ # # ]: 0 : if (!(vf->vf_res->vf_cap_flags &
678 : : VIRTCHNL_VF_LARGE_NUM_QPAIRS)) {
679 : 0 : PMD_DRV_LOG(ERR, "large VF is not supported");
680 : 0 : return -1;
681 : : }
682 : :
683 [ # # ]: 0 : if (num_queue_pairs > IAVF_MAX_NUM_QUEUES_LV) {
684 : 0 : PMD_DRV_LOG(ERR, "queue pairs number cannot be larger than %u",
685 : : IAVF_MAX_NUM_QUEUES_LV);
686 : 0 : return -1;
687 : : }
688 : :
689 : 0 : ret = iavf_queues_req_reset(dev, num_queue_pairs);
690 [ # # ]: 0 : if (ret)
691 : : return ret;
692 : :
693 : 0 : ret = iavf_get_max_rss_queue_region(ad);
694 [ # # ]: 0 : if (ret) {
695 : 0 : PMD_INIT_LOG(ERR, "get max rss queue region failed");
696 : 0 : return ret;
697 : : }
698 : :
699 : 0 : vf->lv_enabled = true;
700 : : } else {
701 : : /* Check if large VF is already enabled. If so, disable and
702 : : * release redundant queue resource.
703 : : * Or check if enough queue pairs. If not, request them from PF.
704 : : */
705 [ # # ]: 0 : if (vf->lv_enabled ||
706 [ # # ]: 0 : num_queue_pairs > vf->vsi_res->num_queue_pairs) {
707 : 0 : ret = iavf_queues_req_reset(dev, num_queue_pairs);
708 [ # # ]: 0 : if (ret)
709 : : return ret;
710 : :
711 : 0 : vf->lv_enabled = false;
712 : : }
713 : : /* if large VF is not required, use default rss queue region */
714 : 0 : vf->max_rss_qregion = IAVF_MAX_NUM_QUEUES_DFLT;
715 : : }
716 : :
717 : 0 : iavf_dev_init_vlan(dev);
718 : :
719 [ # # ]: 0 : if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_PF) {
720 [ # # ]: 0 : if (iavf_init_rss(ad) != 0) {
721 : 0 : PMD_DRV_LOG(ERR, "configure rss failed");
722 : 0 : return -1;
723 : : }
724 : : }
725 : : return 0;
726 : : }
727 : :
728 : : static int
729 : 0 : iavf_init_rxq(struct rte_eth_dev *dev, struct ci_rx_queue *rxq)
730 : : {
731 : 0 : struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(dev->data->dev_private);
732 : : struct rte_eth_dev_data *dev_data = dev->data;
733 : : uint16_t buf_size, max_pkt_len;
734 : 0 : uint32_t frame_size = dev->data->mtu + IAVF_ETH_OVERHEAD;
735 : : enum iavf_status err;
736 : :
737 [ # # ]: 0 : buf_size = rte_pktmbuf_data_room_size(rxq->mp) - RTE_PKTMBUF_HEADROOM;
738 : :
739 : : /* Calculate the maximum packet length allowed */
740 : 0 : max_pkt_len = RTE_MIN((uint32_t)
741 : : rxq->rx_buf_len * IAVF_MAX_CHAINED_RX_BUFFERS,
742 : : frame_size);
743 : :
744 : : /* Check if maximum packet length is set correctly. */
745 [ # # ]: 0 : if (max_pkt_len <= RTE_ETHER_MIN_LEN ||
746 : : max_pkt_len > IAVF_FRAME_SIZE_MAX) {
747 : 0 : PMD_DRV_LOG(ERR, "maximum packet length must be "
748 : : "larger than %u and smaller than %u",
749 : : (uint32_t)IAVF_ETH_MAX_LEN,
750 : : (uint32_t)IAVF_FRAME_SIZE_MAX);
751 : 0 : return -EINVAL;
752 : : }
753 : :
754 [ # # ]: 0 : if (rxq->offloads & RTE_ETH_RX_OFFLOAD_TIMESTAMP) {
755 : : /* Register mbuf field and flag for Rx timestamp */
756 : 0 : err = rte_mbuf_dyn_rx_timestamp_register(
757 : : &iavf_timestamp_dynfield_offset,
758 : : &iavf_timestamp_dynflag);
759 [ # # ]: 0 : if (err) {
760 : 0 : PMD_DRV_LOG(ERR,
761 : : "Cannot register mbuf field/flag for timestamp");
762 : 0 : return -EINVAL;
763 : : }
764 : : }
765 : :
766 : 0 : rxq->max_pkt_len = max_pkt_len;
767 [ # # # # ]: 0 : if ((dev_data->dev_conf.rxmode.offloads & RTE_ETH_RX_OFFLOAD_SCATTER) ||
768 : : rxq->max_pkt_len > buf_size) {
769 : 0 : dev_data->scattered_rx = 1;
770 : : }
771 : 0 : IAVF_PCI_REG_WRITE(rxq->qrx_tail, rxq->nb_rx_desc - 1);
772 : 0 : IAVF_WRITE_FLUSH(hw);
773 : :
774 : 0 : return 0;
775 : : }
776 : :
777 : : static int
778 : 0 : iavf_init_queues(struct rte_eth_dev *dev)
779 : : {
780 : 0 : struct ci_rx_queue **rxq = (struct ci_rx_queue **)dev->data->rx_queues;
781 : : int i, ret = IAVF_SUCCESS;
782 : :
783 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++) {
784 [ # # # # ]: 0 : if (!rxq[i] || !rxq[i]->q_set)
785 : 0 : continue;
786 : 0 : ret = iavf_init_rxq(dev, rxq[i]);
787 [ # # ]: 0 : if (ret != IAVF_SUCCESS)
788 : : break;
789 : : }
790 : : /* set rx/tx function to vector/scatter/single-segment
791 : : * according to parameters
792 : : */
793 : 0 : iavf_set_rx_function(dev);
794 : 0 : iavf_set_tx_function(dev);
795 : :
796 : 0 : return ret;
797 : : }
798 : :
799 : 0 : static int iavf_config_rx_queues_irqs(struct rte_eth_dev *dev,
800 : : struct rte_intr_handle *intr_handle)
801 : : {
802 : 0 : struct iavf_adapter *adapter =
803 : 0 : IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
804 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
805 : : struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(adapter);
806 : : struct iavf_qv_map *qv_map;
807 : : uint16_t interval, i;
808 : : int vec;
809 : :
810 [ # # ]: 0 : if (rte_intr_cap_multiple(intr_handle) &&
811 [ # # ]: 0 : dev->data->dev_conf.intr_conf.rxq) {
812 [ # # ]: 0 : if (rte_intr_efd_enable(intr_handle, dev->data->nb_rx_queues))
813 : : return -1;
814 : : }
815 : :
816 [ # # ]: 0 : if (rte_intr_dp_is_en(intr_handle)) {
817 [ # # ]: 0 : if (rte_intr_vec_list_alloc(intr_handle, "intr_vec",
818 : 0 : dev->data->nb_rx_queues)) {
819 : 0 : PMD_DRV_LOG(ERR, "Failed to allocate %d rx intr_vec",
820 : : dev->data->nb_rx_queues);
821 : 0 : return -1;
822 : : }
823 : : }
824 : :
825 : :
826 : 0 : qv_map = rte_zmalloc("qv_map",
827 : 0 : dev->data->nb_rx_queues * sizeof(struct iavf_qv_map), 0);
828 [ # # ]: 0 : if (!qv_map) {
829 : 0 : PMD_DRV_LOG(ERR, "Failed to allocate %d queue-vector map",
830 : : dev->data->nb_rx_queues);
831 : 0 : goto qv_map_alloc_err;
832 : : }
833 : :
834 [ # # # # ]: 0 : if (!dev->data->dev_conf.intr_conf.rxq ||
835 : 0 : !rte_intr_dp_is_en(intr_handle)) {
836 : : /* Rx interrupt disabled, Map interrupt only for writeback */
837 : 0 : vf->nb_msix = 1;
838 [ # # ]: 0 : if (vf->vf_res->vf_cap_flags &
839 : : VIRTCHNL_VF_OFFLOAD_WB_ON_ITR) {
840 : : /* If WB_ON_ITR supports, enable it */
841 : 0 : vf->msix_base = IAVF_RX_VEC_START;
842 : : /* Set the ITR for index zero, to 2us to make sure that
843 : : * we leave time for aggregation to occur, but don't
844 : : * increase latency dramatically.
845 : : */
846 : 0 : IAVF_WRITE_REG(hw,
847 : : IAVF_VFINT_DYN_CTLN1(vf->msix_base - 1),
848 : : (0 << IAVF_VFINT_DYN_CTLN1_ITR_INDX_SHIFT) |
849 : : IAVF_VFINT_DYN_CTLN1_WB_ON_ITR_MASK |
850 : : (2UL << IAVF_VFINT_DYN_CTLN1_INTERVAL_SHIFT));
851 : : /* debug - check for success! the return value
852 : : * should be 2, offset is 0x2800
853 : : */
854 : : /* IAVF_READ_REG(hw, IAVF_VFINT_ITRN1(0, 0)); */
855 : : } else {
856 : : /* If no WB_ON_ITR offload flags, need to set
857 : : * interrupt for descriptor write back.
858 : : */
859 : 0 : vf->msix_base = IAVF_MISC_VEC_ID;
860 : :
861 : : /* set ITR to default */
862 : : interval = iavf_calc_itr_interval(
863 : : IAVF_QUEUE_ITR_INTERVAL_DEFAULT);
864 : 0 : IAVF_WRITE_REG(hw, IAVF_VFINT_DYN_CTL01,
865 : : IAVF_VFINT_DYN_CTL01_INTENA_MASK |
866 : : (IAVF_ITR_INDEX_DEFAULT <<
867 : : IAVF_VFINT_DYN_CTL01_ITR_INDX_SHIFT) |
868 : : (interval <<
869 : : IAVF_VFINT_DYN_CTL01_INTERVAL_SHIFT));
870 : : }
871 : 0 : IAVF_WRITE_FLUSH(hw);
872 : : /* map all queues to the same interrupt */
873 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++) {
874 : 0 : qv_map[i].queue_id = i;
875 : 0 : qv_map[i].vector_id = vf->msix_base;
876 : : }
877 : 0 : vf->qv_map = qv_map;
878 : : } else {
879 [ # # ]: 0 : if (!rte_intr_allow_others(intr_handle)) {
880 : 0 : vf->nb_msix = 1;
881 : 0 : vf->msix_base = IAVF_MISC_VEC_ID;
882 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++) {
883 : 0 : qv_map[i].queue_id = i;
884 : 0 : qv_map[i].vector_id = vf->msix_base;
885 : 0 : rte_intr_vec_list_index_set(intr_handle,
886 : : i, IAVF_MISC_VEC_ID);
887 : : }
888 : 0 : vf->qv_map = qv_map;
889 : 0 : PMD_DRV_LOG(DEBUG,
890 : : "vector %u are mapping to all Rx queues",
891 : : vf->msix_base);
892 : : } else {
893 : : /* If Rx interrupt is required, and we can use
894 : : * multi interrupts, then the vec is from 1
895 : : */
896 : 0 : vf->nb_msix =
897 : 0 : RTE_MIN(rte_intr_nb_efd_get(intr_handle),
898 : : (uint16_t)(vf->vf_res->max_vectors - 1));
899 : 0 : vf->msix_base = IAVF_RX_VEC_START;
900 : : vec = IAVF_RX_VEC_START;
901 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++) {
902 : 0 : qv_map[i].queue_id = i;
903 : 0 : qv_map[i].vector_id = vec;
904 : 0 : rte_intr_vec_list_index_set(intr_handle,
905 : : i, vec++);
906 [ # # ]: 0 : if (vec >= vf->nb_msix + IAVF_RX_VEC_START)
907 : : vec = IAVF_RX_VEC_START;
908 : : }
909 : 0 : vf->qv_map = qv_map;
910 : 0 : PMD_DRV_LOG(DEBUG,
911 : : "%u vectors are mapping to %u Rx queues",
912 : : vf->nb_msix, dev->data->nb_rx_queues);
913 : : }
914 : : }
915 : :
916 [ # # ]: 0 : if (!vf->lv_enabled) {
917 [ # # ]: 0 : if (iavf_config_irq_map(adapter)) {
918 : 0 : PMD_DRV_LOG(ERR, "config interrupt mapping failed");
919 : 0 : goto config_irq_map_err;
920 : : }
921 : : } else {
922 [ # # ]: 0 : if (iavf_config_irq_map_lv(adapter, dev->data->nb_rx_queues)) {
923 : 0 : PMD_DRV_LOG(ERR, "config interrupt mapping for large VF failed");
924 : 0 : goto config_irq_map_err;
925 : : }
926 : : }
927 : : return 0;
928 : :
929 : 0 : config_irq_map_err:
930 : 0 : rte_free(vf->qv_map);
931 : 0 : vf->qv_map = NULL;
932 : :
933 : 0 : qv_map_alloc_err:
934 : 0 : rte_intr_vec_list_free(intr_handle);
935 : :
936 : 0 : return -1;
937 : : }
938 : :
939 : : static int
940 : 0 : iavf_start_queues(struct rte_eth_dev *dev)
941 : : {
942 : : struct ci_rx_queue *rxq;
943 : : struct ci_tx_queue *txq;
944 : : int i;
945 : : uint16_t nb_txq, nb_rxq;
946 : :
947 [ # # ]: 0 : for (nb_txq = 0; nb_txq < dev->data->nb_tx_queues; nb_txq++) {
948 : 0 : txq = dev->data->tx_queues[nb_txq];
949 [ # # ]: 0 : if (txq->tx_deferred_start)
950 : 0 : continue;
951 [ # # ]: 0 : if (iavf_dev_tx_queue_start(dev, nb_txq) != 0) {
952 : 0 : PMD_DRV_LOG(ERR, "Fail to start tx queue %u", nb_txq);
953 : 0 : goto tx_err;
954 : : }
955 : : }
956 : :
957 [ # # ]: 0 : for (nb_rxq = 0; nb_rxq < dev->data->nb_rx_queues; nb_rxq++) {
958 : 0 : rxq = dev->data->rx_queues[nb_rxq];
959 [ # # ]: 0 : if (rxq->rx_deferred_start)
960 : 0 : continue;
961 [ # # ]: 0 : if (iavf_dev_rx_queue_start(dev, nb_rxq) != 0) {
962 : 0 : PMD_DRV_LOG(ERR, "Fail to start rx queue %u", nb_rxq);
963 : 0 : goto rx_err;
964 : : }
965 : : }
966 : :
967 : : return 0;
968 : :
969 : : rx_err:
970 [ # # ]: 0 : for (i = 0; i < nb_rxq; i++)
971 : 0 : iavf_dev_rx_queue_stop(dev, i);
972 : 0 : tx_err:
973 [ # # ]: 0 : for (i = 0; i < nb_txq; i++)
974 : 0 : iavf_dev_tx_queue_stop(dev, i);
975 : :
976 : : return -1;
977 : : }
978 : :
979 : : static int
980 : 0 : iavf_dev_start(struct rte_eth_dev *dev)
981 : : {
982 : 0 : struct iavf_adapter *adapter =
983 : 0 : IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
984 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
985 : 0 : struct rte_intr_handle *intr_handle = dev->intr_handle;
986 : : uint16_t num_queue_pairs;
987 : : uint16_t index = 0;
988 : :
989 : 0 : PMD_INIT_FUNC_TRACE();
990 : :
991 [ # # ]: 0 : if (adapter->closed)
992 : : return -1;
993 : :
994 : 0 : adapter->stopped = 0;
995 : :
996 : 0 : vf->max_pkt_len = dev->data->mtu + IAVF_ETH_OVERHEAD;
997 : 0 : vf->num_queue_pairs = RTE_MAX(dev->data->nb_rx_queues,
998 : : dev->data->nb_tx_queues);
999 : : num_queue_pairs = vf->num_queue_pairs;
1000 : :
1001 [ # # ]: 0 : if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_QOS)
1002 [ # # ]: 0 : if (iavf_get_qos_cap(adapter)) {
1003 : 0 : PMD_INIT_LOG(ERR, "Failed to get qos capability");
1004 : 0 : return -1;
1005 : : }
1006 : :
1007 [ # # ]: 0 : if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_CAP_PTP) {
1008 [ # # ]: 0 : if (iavf_get_ptp_cap(adapter)) {
1009 : 0 : PMD_INIT_LOG(ERR, "Failed to get ptp capability");
1010 : 0 : return -1;
1011 : : }
1012 : : }
1013 : :
1014 : : /* Check Tx LLDP dynfield */
1015 : 0 : rte_pmd_iavf_tx_lldp_dynfield_offset =
1016 : 0 : rte_mbuf_dynfield_lookup(IAVF_TX_LLDP_DYNFIELD, NULL);
1017 : :
1018 [ # # ]: 0 : if (iavf_init_queues(dev) != 0) {
1019 : 0 : PMD_DRV_LOG(ERR, "failed to do Queue init");
1020 : 0 : return -1;
1021 : : }
1022 : :
1023 [ # # ]: 0 : if (iavf_set_vf_quanta_size(adapter, index, num_queue_pairs) != 0)
1024 : 0 : PMD_DRV_LOG(WARNING, "configure quanta size failed");
1025 : :
1026 [ # # ]: 0 : if (iavf_configure_queues(adapter, num_queue_pairs) != 0) {
1027 : 0 : PMD_DRV_LOG(ERR, "configure queues failed");
1028 : 0 : goto error;
1029 : : }
1030 : :
1031 [ # # ]: 0 : if (iavf_config_rx_queues_irqs(dev, intr_handle) != 0) {
1032 : 0 : PMD_DRV_LOG(ERR, "configure irq failed");
1033 : 0 : goto error;
1034 : : }
1035 : : /* re-enable intr again, because efd assign may change */
1036 [ # # ]: 0 : if (dev->data->dev_conf.intr_conf.rxq != 0) {
1037 [ # # ]: 0 : if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_WB_ON_ITR)
1038 : 0 : rte_intr_disable(intr_handle);
1039 : 0 : rte_intr_enable(intr_handle);
1040 : : }
1041 : :
1042 : : /* Set all mac addrs */
1043 : 0 : iavf_add_del_all_mac_addr(adapter, true);
1044 : :
1045 [ # # ]: 0 : if (!adapter->mac_primary_set)
1046 : 0 : adapter->mac_primary_set = true;
1047 : :
1048 : : /* Set all multicast addresses */
1049 : 0 : iavf_add_del_mc_addr_list(adapter, vf->mc_addrs, vf->mc_addrs_num,
1050 : : true);
1051 : :
1052 : : rte_spinlock_init(&vf->phc_time_aq_lock);
1053 : :
1054 [ # # ]: 0 : if (iavf_start_queues(dev) != 0) {
1055 : 0 : PMD_DRV_LOG(ERR, "enable queues failed");
1056 : 0 : goto error;
1057 : : }
1058 : :
1059 : : return 0;
1060 : :
1061 : : error:
1062 : : return -1;
1063 : : }
1064 : :
1065 : : static int
1066 : 0 : iavf_dev_stop(struct rte_eth_dev *dev)
1067 : : {
1068 : 0 : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
1069 : : struct iavf_adapter *adapter =
1070 : : IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
1071 : 0 : struct rte_intr_handle *intr_handle = dev->intr_handle;
1072 : :
1073 : 0 : PMD_INIT_FUNC_TRACE();
1074 : :
1075 [ # # ]: 0 : if (adapter->closed)
1076 : : return -1;
1077 : :
1078 [ # # ]: 0 : if (!(vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_WB_ON_ITR) &&
1079 [ # # ]: 0 : dev->data->dev_conf.intr_conf.rxq != 0)
1080 : 0 : rte_intr_disable(intr_handle);
1081 : :
1082 [ # # ]: 0 : if (adapter->stopped == 1)
1083 : : return 0;
1084 : :
1085 : : /* Disable the interrupt for Rx */
1086 : 0 : rte_intr_efd_disable(intr_handle);
1087 : : /* Rx interrupt vector mapping free */
1088 : 0 : rte_intr_vec_list_free(intr_handle);
1089 : :
1090 : 0 : iavf_stop_queues(dev);
1091 : :
1092 : 0 : adapter->stopped = 1;
1093 : 0 : dev->data->dev_started = 0;
1094 : :
1095 : 0 : return 0;
1096 : : }
1097 : :
1098 : : static int
1099 : 0 : iavf_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
1100 : : {
1101 : 0 : struct iavf_adapter *adapter =
1102 : 0 : IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
1103 : : struct iavf_info *vf = &adapter->vf;
1104 : : uint16_t max_queue_pairs;
1105 : :
1106 [ # # ]: 0 : if (adapter->closed)
1107 : : return -EIO;
1108 : :
1109 [ # # ]: 0 : if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_LARGE_NUM_QPAIRS)
1110 : : max_queue_pairs = IAVF_MAX_NUM_QUEUES_LV;
1111 : : else
1112 : : max_queue_pairs = IAVF_MAX_NUM_QUEUES_DFLT;
1113 : :
1114 : 0 : dev_info->max_rx_queues = max_queue_pairs;
1115 : 0 : dev_info->max_tx_queues = max_queue_pairs;
1116 : 0 : dev_info->min_rx_bufsize = IAVF_BUF_SIZE_MIN;
1117 : 0 : dev_info->max_rx_pktlen = IAVF_FRAME_SIZE_MAX;
1118 : 0 : dev_info->max_mtu = dev_info->max_rx_pktlen - IAVF_ETH_OVERHEAD;
1119 : 0 : dev_info->min_mtu = RTE_ETHER_MIN_MTU;
1120 : 0 : dev_info->hash_key_size = vf->vf_res->rss_key_size;
1121 : 0 : dev_info->reta_size = vf->vf_res->rss_lut_size;
1122 : 0 : dev_info->flow_type_rss_offloads = IAVF_RSS_OFFLOAD_ALL;
1123 : 0 : dev_info->max_mac_addrs = IAVF_NUM_MACADDR_MAX;
1124 : 0 : dev_info->dev_capa =
1125 : : RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP |
1126 : : RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP;
1127 : 0 : dev_info->rx_offload_capa =
1128 : : RTE_ETH_RX_OFFLOAD_VLAN_STRIP |
1129 : : RTE_ETH_RX_OFFLOAD_QINQ_STRIP |
1130 : : RTE_ETH_RX_OFFLOAD_IPV4_CKSUM |
1131 : : RTE_ETH_RX_OFFLOAD_UDP_CKSUM |
1132 : : RTE_ETH_RX_OFFLOAD_TCP_CKSUM |
1133 : : RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM |
1134 : : RTE_ETH_RX_OFFLOAD_SCATTER |
1135 : : RTE_ETH_RX_OFFLOAD_VLAN_FILTER |
1136 : : RTE_ETH_RX_OFFLOAD_VLAN_EXTEND |
1137 : : RTE_ETH_RX_OFFLOAD_RSS_HASH;
1138 : :
1139 : 0 : dev_info->tx_offload_capa =
1140 : : RTE_ETH_TX_OFFLOAD_VLAN_INSERT |
1141 : : RTE_ETH_TX_OFFLOAD_IPV4_CKSUM |
1142 : : RTE_ETH_TX_OFFLOAD_UDP_CKSUM |
1143 : : RTE_ETH_TX_OFFLOAD_TCP_CKSUM |
1144 : : RTE_ETH_TX_OFFLOAD_SCTP_CKSUM |
1145 : : RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM |
1146 : : RTE_ETH_TX_OFFLOAD_TCP_TSO |
1147 : : RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO |
1148 : : RTE_ETH_TX_OFFLOAD_GRE_TNL_TSO |
1149 : : RTE_ETH_TX_OFFLOAD_IPIP_TNL_TSO |
1150 : : RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO |
1151 : : RTE_ETH_TX_OFFLOAD_MULTI_SEGS |
1152 : : RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE;
1153 : :
1154 : : /* X710 does not support outer udp checksum */
1155 [ # # ]: 0 : if (adapter->hw.mac.type != IAVF_MAC_XL710)
1156 : 0 : dev_info->tx_offload_capa |= RTE_ETH_TX_OFFLOAD_OUTER_UDP_CKSUM;
1157 : :
1158 [ # # ]: 0 : if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_CRC)
1159 : 0 : dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_KEEP_CRC;
1160 : :
1161 [ # # ]: 0 : if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_CAP_PTP &&
1162 [ # # ]: 0 : vf->ptp_caps & VIRTCHNL_1588_PTP_CAP_RX_TSTAMP)
1163 : 0 : dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_TIMESTAMP;
1164 : :
1165 [ # # ]: 0 : if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN_V2 &&
1166 [ # # ]: 0 : vf->vlan_v2_caps.offloads.insertion_support.inner &&
1167 [ # # ]: 0 : vf->vlan_v2_caps.offloads.insertion_support.outer)
1168 : 0 : dev_info->tx_offload_capa |= RTE_ETH_TX_OFFLOAD_QINQ_INSERT;
1169 : :
1170 [ # # ]: 0 : if (iavf_ipsec_crypto_supported(adapter)) {
1171 : 0 : dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_SECURITY;
1172 : 0 : dev_info->tx_offload_capa |= RTE_ETH_TX_OFFLOAD_SECURITY;
1173 : : }
1174 : :
1175 : 0 : dev_info->default_rxconf = (struct rte_eth_rxconf) {
1176 : : .rx_free_thresh = IAVF_DEFAULT_RX_FREE_THRESH,
1177 : : .rx_drop_en = 0,
1178 : : .offloads = 0,
1179 : : };
1180 : :
1181 : 0 : dev_info->default_txconf = (struct rte_eth_txconf) {
1182 : : .tx_free_thresh = IAVF_DEFAULT_TX_FREE_THRESH,
1183 : : .tx_rs_thresh = IAVF_DEFAULT_TX_RS_THRESH,
1184 : : .offloads = 0,
1185 : : };
1186 : :
1187 : 0 : dev_info->rx_desc_lim = (struct rte_eth_desc_lim) {
1188 : : .nb_max = IAVF_MAX_RING_DESC,
1189 : : .nb_min = IAVF_MIN_RING_DESC,
1190 : : .nb_align = IAVF_ALIGN_RING_DESC,
1191 : : };
1192 : :
1193 : 0 : dev_info->tx_desc_lim = (struct rte_eth_desc_lim) {
1194 : : .nb_max = IAVF_MAX_RING_DESC,
1195 : : .nb_min = IAVF_MIN_RING_DESC,
1196 : : .nb_align = IAVF_ALIGN_RING_DESC,
1197 : : .nb_mtu_seg_max = IAVF_TX_MAX_MTU_SEG,
1198 : : .nb_seg_max = IAVF_MAX_RING_DESC,
1199 : : };
1200 : :
1201 : 0 : dev_info->err_handle_mode = RTE_ETH_ERROR_HANDLE_MODE_PASSIVE;
1202 : :
1203 : 0 : return 0;
1204 : : }
1205 : :
1206 : : static const uint32_t *
1207 : 0 : iavf_dev_supported_ptypes_get(struct rte_eth_dev *dev __rte_unused,
1208 : : size_t *no_of_elements)
1209 : : {
1210 : : static const uint32_t ptypes[] = {
1211 : : RTE_PTYPE_L2_ETHER,
1212 : : RTE_PTYPE_L3_IPV4_EXT_UNKNOWN,
1213 : : RTE_PTYPE_L4_FRAG,
1214 : : RTE_PTYPE_L4_ICMP,
1215 : : RTE_PTYPE_L4_NONFRAG,
1216 : : RTE_PTYPE_L4_SCTP,
1217 : : RTE_PTYPE_L4_TCP,
1218 : : RTE_PTYPE_L4_UDP,
1219 : : };
1220 : 0 : *no_of_elements = RTE_DIM(ptypes);
1221 : 0 : return ptypes;
1222 : : }
1223 : :
1224 : : int
1225 : 0 : iavf_dev_link_update(struct rte_eth_dev *dev,
1226 : : __rte_unused int wait_to_complete)
1227 : : {
1228 : : struct rte_eth_link new_link;
1229 [ # # # # : 0 : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
# # # # #
# ]
1230 : :
1231 : : memset(&new_link, 0, sizeof(new_link));
1232 : :
1233 : : /* Only read status info stored in VF, and the info is updated
1234 : : * when receive LINK_CHANGE evnet from PF by Virtchnnl.
1235 : : */
1236 [ # # # # : 0 : switch (vf->link_speed) {
# # # # #
# ]
1237 : 0 : case 10:
1238 : 0 : new_link.link_speed = RTE_ETH_SPEED_NUM_10M;
1239 : 0 : break;
1240 : 0 : case 100:
1241 : 0 : new_link.link_speed = RTE_ETH_SPEED_NUM_100M;
1242 : 0 : break;
1243 : 0 : case 1000:
1244 : 0 : new_link.link_speed = RTE_ETH_SPEED_NUM_1G;
1245 : 0 : break;
1246 : 0 : case 10000:
1247 : 0 : new_link.link_speed = RTE_ETH_SPEED_NUM_10G;
1248 : 0 : break;
1249 : 0 : case 20000:
1250 : 0 : new_link.link_speed = RTE_ETH_SPEED_NUM_20G;
1251 : 0 : break;
1252 : 0 : case 25000:
1253 : 0 : new_link.link_speed = RTE_ETH_SPEED_NUM_25G;
1254 : 0 : break;
1255 : 0 : case 40000:
1256 : 0 : new_link.link_speed = RTE_ETH_SPEED_NUM_40G;
1257 : 0 : break;
1258 : 0 : case 50000:
1259 : 0 : new_link.link_speed = RTE_ETH_SPEED_NUM_50G;
1260 : 0 : break;
1261 : 0 : case 100000:
1262 : 0 : new_link.link_speed = RTE_ETH_SPEED_NUM_100G;
1263 : 0 : break;
1264 : : default:
1265 : : new_link.link_speed = RTE_ETH_SPEED_NUM_NONE;
1266 : : break;
1267 : : }
1268 : :
1269 : 0 : new_link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
1270 : 0 : new_link.link_status = vf->link_up ? RTE_ETH_LINK_UP :
1271 : : RTE_ETH_LINK_DOWN;
1272 [ # # ]: 0 : new_link.link_autoneg = !(dev->data->dev_conf.link_speeds &
1273 : : RTE_ETH_LINK_SPEED_FIXED);
1274 : :
1275 : 0 : return rte_eth_linkstatus_set(dev, &new_link);
1276 : : }
1277 : :
1278 : : static int
1279 : 0 : iavf_dev_promiscuous_enable(struct rte_eth_dev *dev)
1280 : : {
1281 : 0 : struct iavf_adapter *adapter =
1282 : 0 : IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
1283 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1284 : :
1285 : 0 : return iavf_config_promisc(adapter,
1286 : 0 : true, vf->promisc_multicast_enabled);
1287 : : }
1288 : :
1289 : : static int
1290 : 0 : iavf_dev_promiscuous_disable(struct rte_eth_dev *dev)
1291 : : {
1292 : 0 : struct iavf_adapter *adapter =
1293 : 0 : IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
1294 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1295 : :
1296 : 0 : return iavf_config_promisc(adapter,
1297 : 0 : false, vf->promisc_multicast_enabled);
1298 : : }
1299 : :
1300 : : static int
1301 : 0 : iavf_dev_allmulticast_enable(struct rte_eth_dev *dev)
1302 : : {
1303 : 0 : struct iavf_adapter *adapter =
1304 : 0 : IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
1305 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1306 : :
1307 : 0 : return iavf_config_promisc(adapter,
1308 : 0 : vf->promisc_unicast_enabled, true);
1309 : : }
1310 : :
1311 : : static int
1312 : 0 : iavf_dev_allmulticast_disable(struct rte_eth_dev *dev)
1313 : : {
1314 : 0 : struct iavf_adapter *adapter =
1315 : 0 : IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
1316 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1317 : :
1318 : 0 : return iavf_config_promisc(adapter,
1319 : 0 : vf->promisc_unicast_enabled, false);
1320 : : }
1321 : :
1322 : : static int
1323 : 0 : iavf_dev_add_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *addr,
1324 : : __rte_unused uint32_t index,
1325 : : __rte_unused uint32_t pool)
1326 : : {
1327 : 0 : struct iavf_adapter *adapter =
1328 [ # # ]: 0 : IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
1329 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1330 : : int err;
1331 : :
1332 [ # # ]: 0 : if (rte_is_zero_ether_addr(addr)) {
1333 : 0 : PMD_DRV_LOG(ERR, "Invalid Ethernet Address");
1334 : 0 : return -EINVAL;
1335 : : }
1336 : :
1337 : 0 : err = iavf_add_del_eth_addr(adapter, addr, true, VIRTCHNL_ETHER_ADDR_EXTRA);
1338 [ # # ]: 0 : if (err) {
1339 : 0 : PMD_DRV_LOG(ERR, "fail to add MAC address");
1340 : 0 : return -EIO;
1341 : : }
1342 : :
1343 : 0 : vf->mac_num++;
1344 : :
1345 : 0 : return 0;
1346 : : }
1347 : :
1348 : : static void
1349 : 0 : iavf_dev_del_mac_addr(struct rte_eth_dev *dev, uint32_t index)
1350 : : {
1351 : 0 : struct iavf_adapter *adapter =
1352 : 0 : IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
1353 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1354 : : struct rte_ether_addr *addr;
1355 : : int err;
1356 : :
1357 : 0 : addr = &dev->data->mac_addrs[index];
1358 : :
1359 : 0 : err = iavf_add_del_eth_addr(adapter, addr, false, VIRTCHNL_ETHER_ADDR_EXTRA);
1360 [ # # ]: 0 : if (err)
1361 : 0 : PMD_DRV_LOG(ERR, "fail to delete MAC address");
1362 : :
1363 : 0 : vf->mac_num--;
1364 : 0 : }
1365 : :
1366 : : static int
1367 : 0 : iavf_disable_vlan_strip_ex(struct rte_eth_dev *dev, int on)
1368 : : {
1369 : : /* For i40e kernel drivers which supports both vlan(v1 & v2) VIRTCHNL OP,
1370 : : * it will set strip on when setting filter on but dpdk side will not
1371 : : * change strip flag. To be consistent with dpdk side, explicitly disable
1372 : : * strip again.
1373 : : *
1374 : : */
1375 : 0 : struct iavf_adapter *adapter =
1376 : 0 : IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
1377 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1378 : : struct rte_eth_conf *dev_conf = &dev->data->dev_conf;
1379 : : int err;
1380 : :
1381 : 0 : if (adapter->hw.mac.type == IAVF_MAC_XL710 ||
1382 [ # # ]: 0 : adapter->hw.mac.type == IAVF_MAC_VF ||
1383 : : adapter->hw.mac.type == IAVF_MAC_X722_VF) {
1384 [ # # # # ]: 0 : if (on && !(dev_conf->rxmode.offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP)) {
1385 [ # # ]: 0 : if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN_V2)
1386 : 0 : err = iavf_config_vlan_strip_v2(adapter, false);
1387 : : else
1388 : 0 : err = iavf_disable_vlan_strip(adapter);
1389 [ # # ]: 0 : if (err)
1390 : 0 : return -EIO;
1391 : : }
1392 : : }
1393 : : return 0;
1394 : : }
1395 : :
1396 : : static int
1397 : 0 : iavf_dev_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
1398 : : {
1399 : 0 : struct iavf_adapter *adapter =
1400 : 0 : IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
1401 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1402 : : int err;
1403 : :
1404 [ # # ]: 0 : if (adapter->closed)
1405 : : return -EIO;
1406 : :
1407 [ # # ]: 0 : if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN_V2) {
1408 : 0 : err = iavf_add_del_vlan_v2(adapter, vlan_id, on);
1409 [ # # ]: 0 : if (err)
1410 : : return -EIO;
1411 : :
1412 : 0 : return iavf_disable_vlan_strip_ex(dev, on);
1413 : : }
1414 : :
1415 [ # # ]: 0 : if (!(vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN))
1416 : : return -ENOTSUP;
1417 : :
1418 : 0 : err = iavf_add_del_vlan(adapter, vlan_id, on);
1419 [ # # ]: 0 : if (err)
1420 : : return -EIO;
1421 : :
1422 : 0 : return iavf_disable_vlan_strip_ex(dev, on);
1423 : : }
1424 : :
1425 : : static void
1426 : 0 : iavf_iterate_vlan_filters_v2(struct rte_eth_dev *dev, bool enable)
1427 : : {
1428 : 0 : struct rte_vlan_filter_conf *vfc = &dev->data->vlan_filter_conf;
1429 : 0 : struct iavf_adapter *adapter =
1430 : : IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
1431 : : uint32_t i, j;
1432 : : uint64_t ids;
1433 : :
1434 [ # # ]: 0 : for (i = 0; i < RTE_DIM(vfc->ids); i++) {
1435 [ # # ]: 0 : if (vfc->ids[i] == 0)
1436 : 0 : continue;
1437 : :
1438 : : ids = vfc->ids[i];
1439 [ # # ]: 0 : for (j = 0; ids != 0 && j < 64; j++, ids >>= 1) {
1440 [ # # ]: 0 : if (ids & 1)
1441 : 0 : iavf_add_del_vlan_v2(adapter,
1442 : 0 : 64 * i + j, enable);
1443 : : }
1444 : : }
1445 : 0 : }
1446 : :
1447 : : static int
1448 : 0 : iavf_dev_vlan_offload_set_v2(struct rte_eth_dev *dev, int mask)
1449 : : {
1450 : 0 : struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
1451 : 0 : struct iavf_adapter *adapter =
1452 : : IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
1453 : : bool enable;
1454 : : int err;
1455 : :
1456 [ # # ]: 0 : if (mask & RTE_ETH_VLAN_FILTER_MASK) {
1457 : 0 : enable = !!(rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_FILTER);
1458 : :
1459 : 0 : iavf_iterate_vlan_filters_v2(dev, enable);
1460 : : }
1461 : :
1462 [ # # ]: 0 : if (mask & RTE_ETH_VLAN_STRIP_MASK) {
1463 : 0 : enable = !!(rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP);
1464 : :
1465 : 0 : err = iavf_config_vlan_strip_v2(adapter, enable);
1466 : : /* If not support, the stripping is already disabled by PF */
1467 [ # # ]: 0 : if (err == -ENOTSUP && !enable)
1468 : : err = 0;
1469 [ # # ]: 0 : if (err)
1470 : 0 : return -EIO;
1471 : : }
1472 : :
1473 : : return 0;
1474 : : }
1475 : :
1476 : : static int
1477 : 0 : iavf_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask)
1478 : : {
1479 : 0 : struct iavf_adapter *adapter =
1480 : 0 : IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
1481 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1482 : : struct rte_eth_conf *dev_conf = &dev->data->dev_conf;
1483 : : int err;
1484 : :
1485 [ # # ]: 0 : if (adapter->closed)
1486 : : return -EIO;
1487 : :
1488 [ # # ]: 0 : if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN_V2)
1489 : 0 : return iavf_dev_vlan_offload_set_v2(dev, mask);
1490 : :
1491 [ # # ]: 0 : if (!(vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN))
1492 : : return -ENOTSUP;
1493 : :
1494 : : /* Vlan stripping setting */
1495 [ # # ]: 0 : if (mask & RTE_ETH_VLAN_STRIP_MASK) {
1496 : : /* Enable or disable VLAN stripping */
1497 [ # # ]: 0 : if (dev_conf->rxmode.offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP)
1498 : 0 : err = iavf_enable_vlan_strip(adapter);
1499 : : else
1500 : 0 : err = iavf_disable_vlan_strip(adapter);
1501 : :
1502 [ # # ]: 0 : if (err)
1503 : 0 : return -EIO;
1504 : : }
1505 : : return 0;
1506 : : }
1507 : :
1508 : : static int
1509 : 0 : iavf_dev_rss_reta_update(struct rte_eth_dev *dev,
1510 : : struct rte_eth_rss_reta_entry64 *reta_conf,
1511 : : uint16_t reta_size)
1512 : : {
1513 : 0 : struct iavf_adapter *adapter =
1514 : 0 : IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
1515 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1516 : : uint8_t *lut;
1517 : : uint16_t i, idx, shift;
1518 : : int ret;
1519 : :
1520 [ # # ]: 0 : if (adapter->closed)
1521 : : return -EIO;
1522 : :
1523 [ # # ]: 0 : if (!(vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_PF))
1524 : : return -ENOTSUP;
1525 : :
1526 [ # # ]: 0 : if (reta_size != vf->vf_res->rss_lut_size) {
1527 : 0 : PMD_DRV_LOG(ERR, "The size of hash lookup table configured "
1528 : : "(%d) doesn't match the number of hardware can "
1529 : : "support (%d)", reta_size, vf->vf_res->rss_lut_size);
1530 : 0 : return -EINVAL;
1531 : : }
1532 : :
1533 : 0 : lut = calloc(1, reta_size);
1534 [ # # ]: 0 : if (!lut) {
1535 : 0 : PMD_DRV_LOG(ERR, "No memory can be allocated");
1536 : 0 : return -ENOMEM;
1537 : : }
1538 : : /* store the old lut table temporarily */
1539 [ # # ]: 0 : rte_memcpy(lut, vf->rss_lut, reta_size);
1540 : :
1541 [ # # ]: 0 : for (i = 0; i < reta_size; i++) {
1542 : 0 : idx = i / RTE_ETH_RETA_GROUP_SIZE;
1543 : 0 : shift = i % RTE_ETH_RETA_GROUP_SIZE;
1544 [ # # ]: 0 : if (reta_conf[idx].mask & (1ULL << shift))
1545 : 0 : lut[i] = reta_conf[idx].reta[shift];
1546 : : }
1547 : :
1548 : : rte_memcpy(vf->rss_lut, lut, reta_size);
1549 : : /* send virtchnl ops to configure RSS */
1550 : 0 : ret = iavf_configure_rss_lut(adapter);
1551 [ # # ]: 0 : if (ret) /* revert back */
1552 [ # # ]: 0 : rte_memcpy(vf->rss_lut, lut, reta_size);
1553 : 0 : free(lut);
1554 : :
1555 : 0 : return ret;
1556 : : }
1557 : :
1558 : : static int
1559 : 0 : iavf_dev_rss_reta_query(struct rte_eth_dev *dev,
1560 : : struct rte_eth_rss_reta_entry64 *reta_conf,
1561 : : uint16_t reta_size)
1562 : : {
1563 : 0 : struct iavf_adapter *adapter =
1564 : 0 : IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
1565 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1566 : : uint16_t i, idx, shift;
1567 : :
1568 [ # # ]: 0 : if (adapter->closed)
1569 : : return -EIO;
1570 : :
1571 [ # # ]: 0 : if (!(vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_PF))
1572 : : return -ENOTSUP;
1573 : :
1574 [ # # ]: 0 : if (reta_size != vf->vf_res->rss_lut_size) {
1575 : 0 : PMD_DRV_LOG(ERR, "The size of hash lookup table configured "
1576 : : "(%d) doesn't match the number of hardware can "
1577 : : "support (%d)", reta_size, vf->vf_res->rss_lut_size);
1578 : 0 : return -EINVAL;
1579 : : }
1580 : :
1581 [ # # ]: 0 : for (i = 0; i < reta_size; i++) {
1582 : 0 : idx = i / RTE_ETH_RETA_GROUP_SIZE;
1583 : 0 : shift = i % RTE_ETH_RETA_GROUP_SIZE;
1584 [ # # ]: 0 : if (reta_conf[idx].mask & (1ULL << shift))
1585 : 0 : reta_conf[idx].reta[shift] = vf->rss_lut[i];
1586 : : }
1587 : :
1588 : : return 0;
1589 : : }
1590 : :
1591 : : static int
1592 : 0 : iavf_set_rss_key(struct iavf_adapter *adapter, uint8_t *key, uint8_t key_len)
1593 : : {
1594 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1595 : :
1596 : : /* HENA setting, it is enabled by default, no change */
1597 [ # # ]: 0 : if (!key || key_len == 0) {
1598 : 0 : PMD_DRV_LOG(DEBUG, "No key to be configured");
1599 : 0 : return 0;
1600 [ # # ]: 0 : } else if (key_len != vf->vf_res->rss_key_size) {
1601 : 0 : PMD_DRV_LOG(ERR, "The size of hash key configured "
1602 : : "(%d) doesn't match the size of hardware can "
1603 : : "support (%d)", key_len,
1604 : : vf->vf_res->rss_key_size);
1605 : 0 : return -EINVAL;
1606 : : }
1607 : :
1608 [ # # ]: 0 : rte_memcpy(vf->rss_key, key, key_len);
1609 : :
1610 : 0 : return iavf_configure_rss_key(adapter);
1611 : : }
1612 : :
1613 : : static int
1614 : 0 : iavf_dev_rss_hash_update(struct rte_eth_dev *dev,
1615 : : struct rte_eth_rss_conf *rss_conf)
1616 : : {
1617 : 0 : struct iavf_adapter *adapter =
1618 : 0 : IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
1619 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1620 : : int ret;
1621 : :
1622 : 0 : adapter->dev_data->dev_conf.rx_adv_conf.rss_conf = *rss_conf;
1623 : :
1624 [ # # ]: 0 : if (adapter->closed)
1625 : : return -EIO;
1626 : :
1627 [ # # ]: 0 : if (!(vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_PF))
1628 : : return -ENOTSUP;
1629 : :
1630 : : /* Set hash key. */
1631 : 0 : ret = iavf_set_rss_key(adapter, rss_conf->rss_key,
1632 : 0 : rss_conf->rss_key_len);
1633 [ # # ]: 0 : if (ret)
1634 : : return ret;
1635 : :
1636 [ # # ]: 0 : if (rss_conf->rss_hf == 0) {
1637 : 0 : vf->rss_hf = 0;
1638 : 0 : ret = iavf_set_hena(adapter, 0);
1639 : :
1640 : : /* It is a workaround, temporarily allow error to be returned
1641 : : * due to possible lack of PF handling for hena = 0.
1642 : : */
1643 [ # # ]: 0 : if (ret)
1644 : 0 : PMD_DRV_LOG(WARNING, "fail to clean existing RSS, lack PF support");
1645 : 0 : return 0;
1646 : : }
1647 : :
1648 [ # # ]: 0 : if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF) {
1649 : : /* Clear existing RSS. */
1650 : 0 : ret = iavf_set_hena(adapter, 0);
1651 : :
1652 : : /* It is a workaround, temporarily allow error to be returned
1653 : : * due to possible lack of PF handling for hena = 0.
1654 : : */
1655 [ # # ]: 0 : if (ret)
1656 : 0 : PMD_DRV_LOG(WARNING, "fail to clean existing RSS,"
1657 : : "lack PF support");
1658 : :
1659 : : /* Set new RSS configuration. */
1660 : 0 : ret = iavf_rss_hash_set(adapter, rss_conf->rss_hf, true);
1661 [ # # ]: 0 : if (ret) {
1662 : 0 : PMD_DRV_LOG(ERR, "fail to set new RSS");
1663 : 0 : return ret;
1664 : : }
1665 : : } else {
1666 : 0 : iavf_config_rss_hf(adapter, rss_conf->rss_hf);
1667 : : }
1668 : :
1669 : : return 0;
1670 : : }
1671 : :
1672 : : static int
1673 : 0 : iavf_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
1674 : : struct rte_eth_rss_conf *rss_conf)
1675 : : {
1676 : 0 : struct iavf_adapter *adapter =
1677 : 0 : IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
1678 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1679 : :
1680 [ # # ]: 0 : if (adapter->closed)
1681 : : return -EIO;
1682 : :
1683 [ # # ]: 0 : if (!(vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_PF))
1684 : : return -ENOTSUP;
1685 : :
1686 : 0 : rss_conf->rss_hf = vf->rss_hf;
1687 : :
1688 [ # # ]: 0 : if (!rss_conf->rss_key)
1689 : : return 0;
1690 : :
1691 : 0 : rss_conf->rss_key_len = vf->vf_res->rss_key_size;
1692 [ # # ]: 0 : rte_memcpy(rss_conf->rss_key, vf->rss_key, rss_conf->rss_key_len);
1693 : :
1694 : : return 0;
1695 : : }
1696 : :
1697 : : static int
1698 : 0 : iavf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu __rte_unused)
1699 : : {
1700 : : /* mtu setting is forbidden if port is start */
1701 [ # # ]: 0 : if (dev->data->dev_started) {
1702 : 0 : PMD_DRV_LOG(ERR, "port must be stopped before configuration");
1703 : 0 : return -EBUSY;
1704 : : }
1705 : :
1706 : : return 0;
1707 : : }
1708 : :
1709 : : static int
1710 : 0 : iavf_dev_set_default_mac_addr(struct rte_eth_dev *dev,
1711 : : struct rte_ether_addr *mac_addr)
1712 : : {
1713 : 0 : struct iavf_adapter *adapter =
1714 : 0 : IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
1715 : : struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(adapter);
1716 : : struct rte_ether_addr *old_addr;
1717 : : int ret;
1718 : :
1719 [ # # ]: 0 : old_addr = (struct rte_ether_addr *)hw->mac.addr;
1720 : :
1721 [ # # ]: 0 : if (rte_is_same_ether_addr(old_addr, mac_addr))
1722 : : return 0;
1723 : :
1724 [ # # ]: 0 : if (adapter->mac_primary_set) { /* delete old PRIMARY MAC only if set */
1725 : 0 : ret = iavf_add_del_eth_addr(adapter, old_addr, false, VIRTCHNL_ETHER_ADDR_PRIMARY);
1726 [ # # ]: 0 : if (ret)
1727 : 0 : PMD_DRV_LOG(ERR, "Fail to delete old MAC:"
1728 : : RTE_ETHER_ADDR_PRT_FMT,
1729 : : RTE_ETHER_ADDR_BYTES(old_addr));
1730 : : }
1731 : :
1732 : 0 : ret = iavf_add_del_eth_addr(adapter, mac_addr, true, VIRTCHNL_ETHER_ADDR_PRIMARY);
1733 [ # # ]: 0 : if (ret)
1734 : 0 : PMD_DRV_LOG(ERR, "Fail to add new MAC:"
1735 : : RTE_ETHER_ADDR_PRT_FMT,
1736 : : RTE_ETHER_ADDR_BYTES(mac_addr));
1737 : :
1738 [ # # ]: 0 : if (ret)
1739 : : return -EIO;
1740 : :
1741 [ # # ]: 0 : if (!adapter->mac_primary_set)
1742 : 0 : adapter->mac_primary_set = true;
1743 : :
1744 : : rte_ether_addr_copy(mac_addr, (struct rte_ether_addr *)hw->mac.addr);
1745 : 0 : return 0;
1746 : : }
1747 : :
1748 : : static void
1749 : : iavf_stat_update_48(uint64_t *offset, uint64_t *stat)
1750 : : {
1751 [ # # ]: 0 : if (*stat >= *offset)
1752 : 0 : *stat = *stat - *offset;
1753 : : else
1754 : 0 : *stat = (uint64_t)((*stat +
1755 : : ((uint64_t)1 << IAVF_48_BIT_WIDTH)) - *offset);
1756 : :
1757 [ # # # # : 0 : *stat &= IAVF_48_BIT_MASK;
# # # # #
# # # ]
1758 : : }
1759 : :
1760 : : static void
1761 : : iavf_stat_update_32(uint64_t *offset, uint64_t *stat)
1762 : : {
1763 [ # # # # : 0 : if (*stat >= *offset)
# # ]
1764 : 0 : *stat = (uint64_t)(*stat - *offset);
1765 : : else
1766 : 0 : *stat = (uint64_t)((*stat +
1767 : : ((uint64_t)1 << IAVF_32_BIT_WIDTH)) - *offset);
1768 : : }
1769 : :
1770 : : static void
1771 [ # # ]: 0 : iavf_update_stats(struct iavf_vsi *vsi, struct virtchnl_eth_stats *nes)
1772 : : {
1773 : : struct virtchnl_eth_stats *oes = &vsi->eth_stats_offset.eth_stats;
1774 : :
1775 : : iavf_stat_update_48(&oes->rx_bytes, &nes->rx_bytes);
1776 : : iavf_stat_update_48(&oes->rx_unicast, &nes->rx_unicast);
1777 : : iavf_stat_update_48(&oes->rx_multicast, &nes->rx_multicast);
1778 : : iavf_stat_update_48(&oes->rx_broadcast, &nes->rx_broadcast);
1779 : : iavf_stat_update_32(&oes->rx_discards, &nes->rx_discards);
1780 : : iavf_stat_update_48(&oes->tx_bytes, &nes->tx_bytes);
1781 : : iavf_stat_update_48(&oes->tx_unicast, &nes->tx_unicast);
1782 : : iavf_stat_update_48(&oes->tx_multicast, &nes->tx_multicast);
1783 : : iavf_stat_update_48(&oes->tx_broadcast, &nes->tx_broadcast);
1784 : : iavf_stat_update_32(&oes->tx_errors, &nes->tx_errors);
1785 : : iavf_stat_update_32(&oes->tx_discards, &nes->tx_discards);
1786 : 0 : }
1787 : :
1788 : : static int
1789 : 0 : iavf_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
1790 : : struct eth_queue_stats *qstats __rte_unused)
1791 : : {
1792 : 0 : struct iavf_adapter *adapter =
1793 : 0 : IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
1794 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
1795 : 0 : struct iavf_vsi *vsi = &vf->vsi;
1796 : 0 : struct virtchnl_eth_stats *pstats = NULL;
1797 : : int ret;
1798 : :
1799 : 0 : ret = iavf_query_stats(adapter, &pstats);
1800 [ # # ]: 0 : if (ret == 0) {
1801 [ # # ]: 0 : uint8_t crc_stats_len = (dev->data->dev_conf.rxmode.offloads &
1802 : : RTE_ETH_RX_OFFLOAD_KEEP_CRC) ? 0 :
1803 : : RTE_ETHER_CRC_LEN;
1804 : 0 : iavf_update_stats(vsi, pstats);
1805 : 0 : stats->ipackets = pstats->rx_unicast + pstats->rx_multicast +
1806 : 0 : pstats->rx_broadcast - pstats->rx_discards;
1807 : 0 : stats->opackets = pstats->tx_broadcast + pstats->tx_multicast +
1808 : 0 : pstats->tx_unicast;
1809 : 0 : stats->imissed = pstats->rx_discards;
1810 : 0 : stats->oerrors = pstats->tx_errors + pstats->tx_discards;
1811 : 0 : stats->ibytes = pstats->rx_bytes;
1812 : 0 : stats->ibytes -= stats->ipackets * crc_stats_len;
1813 : 0 : stats->obytes = pstats->tx_bytes;
1814 : : } else {
1815 : 0 : PMD_DRV_LOG(ERR, "Get statistics failed");
1816 : : }
1817 : 0 : return ret;
1818 : : }
1819 : :
1820 : : static int
1821 : 0 : iavf_dev_stats_reset(struct rte_eth_dev *dev)
1822 : : {
1823 : : int ret;
1824 : 0 : struct iavf_adapter *adapter =
1825 : 0 : IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
1826 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
1827 : : struct iavf_vsi *vsi = &vf->vsi;
1828 : 0 : struct virtchnl_eth_stats *pstats = NULL;
1829 : :
1830 : : /* read stat values to clear hardware registers */
1831 : 0 : ret = iavf_query_stats(adapter, &pstats);
1832 [ # # ]: 0 : if (ret != 0)
1833 : : return ret;
1834 : :
1835 : : /* set stats offset base on current values */
1836 : 0 : vsi->eth_stats_offset.eth_stats = *pstats;
1837 : :
1838 : 0 : return 0;
1839 : : }
1840 : :
1841 : : static int
1842 : 0 : iavf_dev_xstats_reset(struct rte_eth_dev *dev)
1843 : : {
1844 : 0 : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
1845 : 0 : iavf_dev_stats_reset(dev);
1846 : 0 : memset(&vf->vsi.eth_stats_offset.ips_stats, 0,
1847 : : sizeof(struct iavf_ipsec_crypto_stats));
1848 : 0 : memset(&vf->vsi.eth_stats_offset.mbuf_stats, 0,
1849 : : sizeof(struct iavf_mbuf_stats));
1850 : :
1851 : 0 : return 0;
1852 : : }
1853 : :
1854 : 0 : static int iavf_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
1855 : : struct rte_eth_xstat_name *xstats_names,
1856 : : __rte_unused unsigned int limit)
1857 : : {
1858 : : unsigned int i;
1859 : :
1860 [ # # ]: 0 : if (xstats_names != NULL)
1861 [ # # ]: 0 : for (i = 0; i < IAVF_NB_XSTATS; i++) {
1862 : 0 : snprintf(xstats_names[i].name,
1863 : : sizeof(xstats_names[i].name),
1864 : 0 : "%s", rte_iavf_stats_strings[i].name);
1865 : : }
1866 : 0 : return IAVF_NB_XSTATS;
1867 : : }
1868 : :
1869 : : static void
1870 : 0 : iavf_dev_update_ipsec_xstats(struct rte_eth_dev *ethdev,
1871 : : struct iavf_ipsec_crypto_stats *ips)
1872 : : {
1873 : : uint16_t idx;
1874 [ # # ]: 0 : for (idx = 0; idx < ethdev->data->nb_rx_queues; idx++) {
1875 : : struct ci_rx_queue *rxq;
1876 : : struct iavf_ipsec_crypto_stats *stats;
1877 : 0 : rxq = (struct ci_rx_queue *)ethdev->data->rx_queues[idx];
1878 : 0 : stats = &rxq->stats->ipsec_crypto;
1879 : 0 : ips->icount += stats->icount;
1880 : 0 : ips->ibytes += stats->ibytes;
1881 : 0 : ips->ierrors.count += stats->ierrors.count;
1882 : 0 : ips->ierrors.sad_miss += stats->ierrors.sad_miss;
1883 : 0 : ips->ierrors.not_processed += stats->ierrors.not_processed;
1884 : 0 : ips->ierrors.icv_check += stats->ierrors.icv_check;
1885 : 0 : ips->ierrors.ipsec_length += stats->ierrors.ipsec_length;
1886 : 0 : ips->ierrors.misc += stats->ierrors.misc;
1887 : : }
1888 : 0 : }
1889 : :
1890 : : static void
1891 : : iavf_dev_update_mbuf_stats(struct rte_eth_dev *ethdev,
1892 : : struct iavf_mbuf_stats *mbuf_stats)
1893 : : {
1894 : : uint16_t idx;
1895 : : struct ci_tx_queue *txq;
1896 : :
1897 [ # # ]: 0 : for (idx = 0; idx < ethdev->data->nb_tx_queues; idx++) {
1898 : 0 : txq = ethdev->data->tx_queues[idx];
1899 : 0 : mbuf_stats->tx_pkt_errors += txq->mbuf_errors;
1900 : : }
1901 : : }
1902 : :
1903 : 0 : static int iavf_dev_xstats_get(struct rte_eth_dev *dev,
1904 : : struct rte_eth_xstat *xstats, unsigned int n)
1905 : : {
1906 : : int ret;
1907 : : unsigned int i;
1908 : 0 : struct iavf_adapter *adapter =
1909 : 0 : IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
1910 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
1911 : 0 : struct iavf_vsi *vsi = &vf->vsi;
1912 : 0 : struct virtchnl_eth_stats *pstats = NULL;
1913 : 0 : struct iavf_eth_xstats iavf_xtats = {{0}};
1914 : :
1915 [ # # ]: 0 : if (n < IAVF_NB_XSTATS)
1916 : : return IAVF_NB_XSTATS;
1917 : :
1918 : 0 : ret = iavf_query_stats(adapter, &pstats);
1919 [ # # ]: 0 : if (ret != 0)
1920 : : return 0;
1921 : :
1922 [ # # ]: 0 : if (!xstats)
1923 : : return 0;
1924 : :
1925 : 0 : iavf_update_stats(vsi, pstats);
1926 : 0 : iavf_xtats.eth_stats = *pstats;
1927 : :
1928 [ # # ]: 0 : if (iavf_ipsec_crypto_supported(adapter))
1929 : 0 : iavf_dev_update_ipsec_xstats(dev, &iavf_xtats.ips_stats);
1930 : :
1931 [ # # ]: 0 : if (adapter->devargs.mbuf_check)
1932 : : iavf_dev_update_mbuf_stats(dev, &iavf_xtats.mbuf_stats);
1933 : :
1934 : : /* loop over xstats array and values from pstats */
1935 [ # # ]: 0 : for (i = 0; i < IAVF_NB_XSTATS; i++) {
1936 : 0 : xstats[i].id = i;
1937 : 0 : xstats[i].value = *(uint64_t *)(((char *)&iavf_xtats) +
1938 : 0 : rte_iavf_stats_strings[i].offset);
1939 : : }
1940 : :
1941 : : return IAVF_NB_XSTATS;
1942 : : }
1943 : :
1944 : :
1945 : : static int
1946 : 0 : iavf_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
1947 : : {
1948 : 0 : struct iavf_adapter *adapter =
1949 : 0 : IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
1950 : 0 : struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
1951 : : struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(adapter);
1952 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
1953 : : uint16_t msix_intr;
1954 : :
1955 [ # # ]: 0 : if (adapter->closed)
1956 : : return -EIO;
1957 : :
1958 : 0 : msix_intr = rte_intr_vec_list_index_get(pci_dev->intr_handle,
1959 : : queue_id);
1960 [ # # ]: 0 : if (msix_intr == IAVF_MISC_VEC_ID) {
1961 : 0 : PMD_DRV_LOG(INFO, "MISC is also enabled for control");
1962 : 0 : IAVF_WRITE_REG(hw, IAVF_VFINT_DYN_CTL01,
1963 : : IAVF_VFINT_DYN_CTL01_INTENA_MASK |
1964 : : IAVF_VFINT_DYN_CTL01_CLEARPBA_MASK |
1965 : : IAVF_VFINT_DYN_CTL01_ITR_INDX_MASK);
1966 : : } else {
1967 : 0 : IAVF_WRITE_REG(hw,
1968 : : IAVF_VFINT_DYN_CTLN1
1969 : : (msix_intr - IAVF_RX_VEC_START),
1970 : : IAVF_VFINT_DYN_CTLN1_INTENA_MASK |
1971 : : IAVF_VFINT_DYN_CTL01_CLEARPBA_MASK |
1972 : : IAVF_VFINT_DYN_CTLN1_ITR_INDX_MASK);
1973 : : }
1974 : :
1975 : 0 : IAVF_WRITE_FLUSH(hw);
1976 : :
1977 [ # # ]: 0 : if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_WB_ON_ITR)
1978 : 0 : rte_intr_ack(pci_dev->intr_handle);
1979 : :
1980 : : return 0;
1981 : : }
1982 : :
1983 : : static int
1984 : 0 : iavf_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id)
1985 : : {
1986 : 0 : struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
1987 : 0 : struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1988 : : uint16_t msix_intr;
1989 : :
1990 : 0 : msix_intr = rte_intr_vec_list_index_get(pci_dev->intr_handle,
1991 : : queue_id);
1992 [ # # ]: 0 : if (msix_intr == IAVF_MISC_VEC_ID) {
1993 : 0 : PMD_DRV_LOG(ERR, "MISC is used for control, cannot disable it");
1994 : 0 : return -EIO;
1995 : : }
1996 : :
1997 : 0 : IAVF_WRITE_REG(hw,
1998 : : IAVF_VFINT_DYN_CTLN1(msix_intr - IAVF_RX_VEC_START),
1999 : : IAVF_VFINT_DYN_CTLN1_WB_ON_ITR_MASK);
2000 : :
2001 : 0 : IAVF_WRITE_FLUSH(hw);
2002 : 0 : return 0;
2003 : : }
2004 : :
2005 : : static int
2006 : : iavf_check_vf_reset_done(struct iavf_hw *hw)
2007 : : {
2008 : : int i, reset;
2009 : :
2010 [ # # # # ]: 0 : for (i = 0; i < IAVF_RESET_WAIT_CNT; i++) {
2011 : 0 : reset = IAVF_READ_REG(hw, IAVF_VFGEN_RSTAT) &
2012 : : IAVF_VFGEN_RSTAT_VFR_STATE_MASK;
2013 : : reset = reset >> IAVF_VFGEN_RSTAT_VFR_STATE_SHIFT;
2014 [ # # # # ]: 0 : if (reset == VIRTCHNL_VFR_VFACTIVE ||
2015 : : reset == VIRTCHNL_VFR_COMPLETED)
2016 : : break;
2017 : : rte_delay_ms(20);
2018 : : }
2019 : :
2020 [ # # # # ]: 0 : if (i >= IAVF_RESET_WAIT_CNT)
2021 : : return -1;
2022 : :
2023 : : return 0;
2024 : : }
2025 : :
2026 : : static int
2027 : 0 : iavf_lookup_proto_xtr_type(const char *flex_name)
2028 : : {
2029 : : static struct {
2030 : : const char *name;
2031 : : enum iavf_proto_xtr_type type;
2032 : : } xtr_type_map[] = {
2033 : : { "vlan", IAVF_PROTO_XTR_VLAN },
2034 : : { "ipv4", IAVF_PROTO_XTR_IPV4 },
2035 : : { "ipv6", IAVF_PROTO_XTR_IPV6 },
2036 : : { "ipv6_flow", IAVF_PROTO_XTR_IPV6_FLOW },
2037 : : { "tcp", IAVF_PROTO_XTR_TCP },
2038 : : { "ip_offset", IAVF_PROTO_XTR_IP_OFFSET },
2039 : : { "ipsec_crypto_said", IAVF_PROTO_XTR_IPSEC_CRYPTO_SAID },
2040 : : };
2041 : : uint32_t i;
2042 : :
2043 [ # # ]: 0 : for (i = 0; i < RTE_DIM(xtr_type_map); i++) {
2044 [ # # ]: 0 : if (strcmp(flex_name, xtr_type_map[i].name) == 0)
2045 : 0 : return xtr_type_map[i].type;
2046 : : }
2047 : :
2048 : 0 : PMD_DRV_LOG(ERR, "wrong proto_xtr type, it should be: "
2049 : : "vlan|ipv4|ipv6|ipv6_flow|tcp|ip_offset|ipsec_crypto_said");
2050 : :
2051 : 0 : return -1;
2052 : : }
2053 : :
2054 : : /**
2055 : : * Parse elem, the elem could be single number/range or '(' ')' group
2056 : : * 1) A single number elem, it's just a simple digit. e.g. 9
2057 : : * 2) A single range elem, two digits with a '-' between. e.g. 2-6
2058 : : * 3) A group elem, combines multiple 1) or 2) with '( )'. e.g (0,2-4,6)
2059 : : * Within group elem, '-' used for a range separator;
2060 : : * ',' used for a single number.
2061 : : */
2062 : : static int
2063 : 0 : iavf_parse_queue_set(const char *input, int xtr_type,
2064 : : struct iavf_devargs *devargs)
2065 : : {
2066 : : const char *str = input;
2067 : 0 : char *end = NULL;
2068 : : uint32_t min, max;
2069 : : uint32_t idx;
2070 : :
2071 [ # # ]: 0 : while (isblank(*str))
2072 : 0 : str++;
2073 : :
2074 [ # # # # ]: 0 : if (!isdigit(*str) && *str != '(')
2075 : : return -1;
2076 : :
2077 : : /* process single number or single range of number */
2078 [ # # ]: 0 : if (*str != '(') {
2079 : 0 : errno = 0;
2080 : 0 : idx = strtoul(str, &end, 10);
2081 [ # # # # : 0 : if (errno || !end || idx >= IAVF_MAX_QUEUE_NUM)
# # ]
2082 : : return -1;
2083 : :
2084 [ # # ]: 0 : while (isblank(*end))
2085 : 0 : end++;
2086 : :
2087 : : min = idx;
2088 : : max = idx;
2089 : :
2090 : : /* process single <number>-<number> */
2091 [ # # ]: 0 : if (*end == '-') {
2092 : 0 : end++;
2093 [ # # ]: 0 : while (isblank(*end))
2094 : 0 : end++;
2095 [ # # ]: 0 : if (!isdigit(*end))
2096 : : return -1;
2097 : :
2098 : 0 : errno = 0;
2099 : 0 : idx = strtoul(end, &end, 10);
2100 [ # # # # : 0 : if (errno || !end || idx >= IAVF_MAX_QUEUE_NUM)
# # ]
2101 : : return -1;
2102 : :
2103 : : max = idx;
2104 [ # # ]: 0 : while (isblank(*end))
2105 : 0 : end++;
2106 : : }
2107 : :
2108 [ # # ]: 0 : if (*end != ':')
2109 : : return -1;
2110 : :
2111 : 0 : for (idx = RTE_MIN(min, max);
2112 [ # # ]: 0 : idx <= RTE_MAX(min, max); idx++)
2113 : 0 : devargs->proto_xtr[idx] = xtr_type;
2114 : :
2115 : : return 0;
2116 : : }
2117 : :
2118 : : /* process set within bracket */
2119 : 0 : str++;
2120 [ # # ]: 0 : while (isblank(*str))
2121 : 0 : str++;
2122 [ # # ]: 0 : if (*str == '\0')
2123 : : return -1;
2124 : :
2125 : : min = IAVF_MAX_QUEUE_NUM;
2126 : : do {
2127 : : /* go ahead to the first digit */
2128 [ # # ]: 0 : while (isblank(*str))
2129 : 0 : str++;
2130 [ # # ]: 0 : if (!isdigit(*str))
2131 : : return -1;
2132 : :
2133 : : /* get the digit value */
2134 : 0 : errno = 0;
2135 : 0 : idx = strtoul(str, &end, 10);
2136 [ # # # # : 0 : if (errno || !end || idx >= IAVF_MAX_QUEUE_NUM)
# # ]
2137 : : return -1;
2138 : :
2139 : : /* go ahead to separator '-',',' and ')' */
2140 [ # # ]: 0 : while (isblank(*end))
2141 : 0 : end++;
2142 [ # # ]: 0 : if (*end == '-') {
2143 [ # # ]: 0 : if (min == IAVF_MAX_QUEUE_NUM)
2144 : : min = idx;
2145 : : else /* avoid continuous '-' */
2146 : : return -1;
2147 [ # # ]: 0 : } else if (*end == ',' || *end == ')') {
2148 : : max = idx;
2149 [ # # ]: 0 : if (min == IAVF_MAX_QUEUE_NUM)
2150 : : min = idx;
2151 : :
2152 : 0 : for (idx = RTE_MIN(min, max);
2153 [ # # ]: 0 : idx <= RTE_MAX(min, max); idx++)
2154 : 0 : devargs->proto_xtr[idx] = xtr_type;
2155 : :
2156 : : min = IAVF_MAX_QUEUE_NUM;
2157 : : } else {
2158 : : return -1;
2159 : : }
2160 : :
2161 : 0 : str = end + 1;
2162 [ # # ]: 0 : } while (*end != ')' && *end != '\0');
2163 : :
2164 : : return 0;
2165 : : }
2166 : :
2167 : : static int
2168 : 0 : iavf_parse_queue_proto_xtr(const char *queues, struct iavf_devargs *devargs)
2169 : : {
2170 : : const char *queue_start;
2171 : : uint32_t idx;
2172 : : int xtr_type;
2173 : : char flex_name[32];
2174 : :
2175 [ # # ]: 0 : while (isblank(*queues))
2176 : 0 : queues++;
2177 : :
2178 [ # # ]: 0 : if (*queues != '[') {
2179 : 0 : xtr_type = iavf_lookup_proto_xtr_type(queues);
2180 [ # # ]: 0 : if (xtr_type < 0)
2181 : : return -1;
2182 : :
2183 : 0 : devargs->proto_xtr_dflt = xtr_type;
2184 : :
2185 : 0 : return 0;
2186 : : }
2187 : :
2188 : 0 : queues++;
2189 : : do {
2190 [ # # ]: 0 : while (isblank(*queues))
2191 : 0 : queues++;
2192 [ # # ]: 0 : if (*queues == '\0')
2193 : : return -1;
2194 : :
2195 : : queue_start = queues;
2196 : :
2197 : : /* go across a complete bracket */
2198 [ # # ]: 0 : if (*queue_start == '(') {
2199 : 0 : queues += strcspn(queues, ")");
2200 [ # # ]: 0 : if (*queues != ')')
2201 : : return -1;
2202 : : }
2203 : :
2204 : : /* scan the separator ':' */
2205 : 0 : queues += strcspn(queues, ":");
2206 [ # # ]: 0 : if (*queues++ != ':')
2207 : : return -1;
2208 [ # # ]: 0 : while (isblank(*queues))
2209 : 0 : queues++;
2210 : :
2211 : 0 : for (idx = 0; ; idx++) {
2212 [ # # # # ]: 0 : if (isblank(queues[idx]) ||
2213 [ # # ]: 0 : queues[idx] == ',' ||
2214 [ # # ]: 0 : queues[idx] == ']' ||
2215 : : queues[idx] == '\0')
2216 : : break;
2217 : :
2218 [ # # ]: 0 : if (idx > sizeof(flex_name) - 2)
2219 : : return -1;
2220 : :
2221 : 0 : flex_name[idx] = queues[idx];
2222 : : }
2223 : 0 : flex_name[idx] = '\0';
2224 : 0 : xtr_type = iavf_lookup_proto_xtr_type(flex_name);
2225 [ # # ]: 0 : if (xtr_type < 0)
2226 : : return -1;
2227 : :
2228 : : queues += idx;
2229 : :
2230 [ # # # # : 0 : while (isblank(*queues) || *queues == ',' || *queues == ']')
# # ]
2231 : 0 : queues++;
2232 : :
2233 [ # # ]: 0 : if (iavf_parse_queue_set(queue_start, xtr_type, devargs) < 0)
2234 : : return -1;
2235 [ # # ]: 0 : } while (*queues != '\0');
2236 : :
2237 : : return 0;
2238 : : }
2239 : :
2240 : : static int
2241 : 0 : iavf_handle_proto_xtr_arg(__rte_unused const char *key, const char *value,
2242 : : void *extra_args)
2243 : : {
2244 : : struct iavf_devargs *devargs = extra_args;
2245 : :
2246 [ # # ]: 0 : if (!value || !extra_args)
2247 : : return -EINVAL;
2248 : :
2249 [ # # ]: 0 : if (iavf_parse_queue_proto_xtr(value, devargs) < 0) {
2250 : 0 : PMD_DRV_LOG(ERR, "the proto_xtr's parameter is wrong : '%s'",
2251 : : value);
2252 : 0 : return -1;
2253 : : }
2254 : :
2255 : : return 0;
2256 : : }
2257 : :
2258 : : static int
2259 : 0 : parse_u16(__rte_unused const char *key, const char *value, void *args)
2260 : : {
2261 : : u16 *num = (u16 *)args;
2262 : : u16 tmp;
2263 : :
2264 : 0 : errno = 0;
2265 : 0 : tmp = strtoull(value, NULL, 10);
2266 [ # # # # ]: 0 : if (errno || !tmp) {
2267 : 0 : PMD_DRV_LOG(WARNING, "%s: \"%s\" is not a valid u16",
2268 : : key, value);
2269 : 0 : return -1;
2270 : : }
2271 : :
2272 : 0 : *num = tmp;
2273 : :
2274 : 0 : return 0;
2275 : : }
2276 : :
2277 : : static int
2278 : 0 : parse_bool(const char *key, const char *value, void *args)
2279 : : {
2280 : : int *i = (int *)args;
2281 : : char *end;
2282 : : int num;
2283 : :
2284 : 0 : num = strtoul(value, &end, 10);
2285 : :
2286 [ # # ]: 0 : if (num != 0 && num != 1) {
2287 : 0 : PMD_DRV_LOG(WARNING, "invalid value:\"%s\" for key:\"%s\", "
2288 : : "value must be 0 or 1",
2289 : : value, key);
2290 : 0 : return -1;
2291 : : }
2292 : :
2293 : 0 : *i = num;
2294 : 0 : return 0;
2295 : : }
2296 : :
2297 : : static int
2298 : 0 : iavf_parse_watchdog_period(__rte_unused const char *key, const char *value, void *args)
2299 : : {
2300 : : int *num = (int *)args;
2301 : : int tmp;
2302 : :
2303 : 0 : errno = 0;
2304 : : tmp = atoi(value);
2305 [ # # ]: 0 : if (tmp < 0) {
2306 : 0 : PMD_DRV_LOG(WARNING, "%s: \"%s\" is not greater than or equal to zero",
2307 : : key, value);
2308 : 0 : return -1;
2309 : : }
2310 : :
2311 : 0 : *num = tmp;
2312 : :
2313 : 0 : return 0;
2314 : : }
2315 : :
2316 : : static int
2317 : 0 : iavf_parse_mbuf_check(__rte_unused const char *key, const char *value, void *args)
2318 : : {
2319 : : char *cur;
2320 : : char *tmp;
2321 : : int str_len;
2322 : : int valid_len;
2323 : : int ret = 0;
2324 : : uint64_t *mc_flags = args;
2325 : 0 : char *str2 = strdup(value);
2326 : :
2327 [ # # ]: 0 : if (str2 == NULL)
2328 : : return -1;
2329 : :
2330 : 0 : str_len = strlen(str2);
2331 [ # # ]: 0 : if (str_len == 0) {
2332 : : ret = -1;
2333 : 0 : goto err_end;
2334 : : }
2335 : :
2336 : : /* Try stripping the outer square brackets of the parameter string. */
2337 [ # # # # ]: 0 : if (str2[0] == '[' && str2[str_len - 1] == ']') {
2338 [ # # ]: 0 : if (str_len < 3) {
2339 : : ret = -1;
2340 : 0 : goto err_end;
2341 : : }
2342 : 0 : valid_len = str_len - 2;
2343 : 0 : memmove(str2, str2 + 1, valid_len);
2344 : 0 : memset(str2 + valid_len, '\0', 2);
2345 : : }
2346 : :
2347 : 0 : cur = strtok_r(str2, ",", &tmp);
2348 [ # # ]: 0 : while (cur != NULL) {
2349 [ # # ]: 0 : if (!strcmp(cur, "mbuf"))
2350 : 0 : *mc_flags |= IAVF_MBUF_CHECK_F_TX_MBUF;
2351 [ # # ]: 0 : else if (!strcmp(cur, "size"))
2352 : 0 : *mc_flags |= IAVF_MBUF_CHECK_F_TX_SIZE;
2353 [ # # ]: 0 : else if (!strcmp(cur, "segment"))
2354 : 0 : *mc_flags |= IAVF_MBUF_CHECK_F_TX_SEGMENT;
2355 [ # # ]: 0 : else if (!strcmp(cur, "offload"))
2356 : 0 : *mc_flags |= IAVF_MBUF_CHECK_F_TX_OFFLOAD;
2357 : : else
2358 : 0 : PMD_DRV_LOG(ERR, "Unsupported diagnostic type: %s", cur);
2359 : 0 : cur = strtok_r(NULL, ",", &tmp);
2360 : : }
2361 : :
2362 : 0 : err_end:
2363 : 0 : free(str2);
2364 : 0 : return ret;
2365 : : }
2366 : :
2367 : 0 : static int iavf_parse_devargs(struct rte_eth_dev *dev)
2368 : : {
2369 : 0 : struct iavf_adapter *ad =
2370 : 0 : IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
2371 : 0 : struct rte_devargs *devargs = dev->device->devargs;
2372 : : struct rte_kvargs *kvlist;
2373 : : int ret;
2374 : 0 : int watchdog_period = -1;
2375 : :
2376 [ # # ]: 0 : if (!devargs)
2377 : : return 0;
2378 : :
2379 : 0 : kvlist = rte_kvargs_parse(devargs->args, iavf_valid_args);
2380 [ # # ]: 0 : if (!kvlist) {
2381 : 0 : PMD_INIT_LOG(ERR, "invalid kvargs key");
2382 : 0 : return -EINVAL;
2383 : : }
2384 : :
2385 : 0 : ad->devargs.proto_xtr_dflt = IAVF_PROTO_XTR_NONE;
2386 : 0 : memset(ad->devargs.proto_xtr, IAVF_PROTO_XTR_NONE,
2387 : : sizeof(ad->devargs.proto_xtr));
2388 : :
2389 : 0 : ret = rte_kvargs_process(kvlist, IAVF_PROTO_XTR_ARG,
2390 : 0 : &iavf_handle_proto_xtr_arg, &ad->devargs);
2391 [ # # ]: 0 : if (ret)
2392 : 0 : goto bail;
2393 : :
2394 : 0 : ret = rte_kvargs_process(kvlist, IAVF_QUANTA_SIZE_ARG,
2395 : 0 : &parse_u16, &ad->devargs.quanta_size);
2396 [ # # ]: 0 : if (ret)
2397 : 0 : goto bail;
2398 : :
2399 : 0 : ret = rte_kvargs_process(kvlist, IAVF_RESET_WATCHDOG_ARG,
2400 : : &iavf_parse_watchdog_period, &watchdog_period);
2401 [ # # ]: 0 : if (ret)
2402 : 0 : goto bail;
2403 [ # # ]: 0 : if (watchdog_period == -1)
2404 : 0 : ad->devargs.watchdog_period = IAVF_DEV_WATCHDOG_PERIOD;
2405 : : else
2406 : 0 : ad->devargs.watchdog_period = watchdog_period;
2407 : :
2408 : 0 : ret = rte_kvargs_process(kvlist, IAVF_NO_POLL_ON_LINK_DOWN_ARG,
2409 : 0 : &parse_bool, &ad->devargs.no_poll_on_link_down);
2410 [ # # ]: 0 : if (ret)
2411 : 0 : goto bail;
2412 : :
2413 [ # # ]: 0 : if (ad->devargs.quanta_size != 0 &&
2414 [ # # # # ]: 0 : (ad->devargs.quanta_size < 256 || ad->devargs.quanta_size > 4096 ||
2415 : : ad->devargs.quanta_size & 0x40)) {
2416 : 0 : PMD_INIT_LOG(ERR, "invalid quanta size");
2417 : : ret = -EINVAL;
2418 : 0 : goto bail;
2419 : : }
2420 : :
2421 : 0 : ret = rte_kvargs_process(kvlist, IAVF_MBUF_CHECK_ARG,
2422 : 0 : &iavf_parse_mbuf_check, &ad->devargs.mbuf_check);
2423 [ # # ]: 0 : if (ret)
2424 : 0 : goto bail;
2425 : :
2426 : 0 : ret = rte_kvargs_process(kvlist, IAVF_ENABLE_AUTO_RESET_ARG,
2427 : 0 : &parse_bool, &ad->devargs.auto_reset);
2428 [ # # ]: 0 : if (ret)
2429 : 0 : goto bail;
2430 : :
2431 [ # # ]: 0 : if (ad->devargs.auto_reset != 0)
2432 : 0 : ad->devargs.no_poll_on_link_down = 1;
2433 : :
2434 : 0 : bail:
2435 : 0 : rte_kvargs_free(kvlist);
2436 : 0 : return ret;
2437 : : }
2438 : :
2439 : : static void
2440 : 0 : iavf_init_proto_xtr(struct rte_eth_dev *dev)
2441 : : {
2442 : 0 : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
2443 : : struct iavf_adapter *ad =
2444 : : IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
2445 : : const struct iavf_proto_xtr_ol *xtr_ol;
2446 : : bool proto_xtr_enable = false;
2447 : : int offset;
2448 : : uint16_t i;
2449 : :
2450 : 0 : vf->proto_xtr = rte_zmalloc("vf proto xtr",
2451 : 0 : vf->vsi_res->num_queue_pairs, 0);
2452 [ # # ]: 0 : if (unlikely(!(vf->proto_xtr))) {
2453 : 0 : PMD_DRV_LOG(ERR, "no memory for setting up proto_xtr's table");
2454 : 0 : return;
2455 : : }
2456 : :
2457 [ # # ]: 0 : for (i = 0; i < vf->vsi_res->num_queue_pairs; i++) {
2458 [ # # ]: 0 : vf->proto_xtr[i] = ad->devargs.proto_xtr[i] !=
2459 : : IAVF_PROTO_XTR_NONE ?
2460 : : ad->devargs.proto_xtr[i] :
2461 : : ad->devargs.proto_xtr_dflt;
2462 : :
2463 [ # # ]: 0 : if (vf->proto_xtr[i] != IAVF_PROTO_XTR_NONE) {
2464 : : uint8_t type = vf->proto_xtr[i];
2465 : :
2466 : 0 : iavf_proto_xtr_params[type].required = true;
2467 : : proto_xtr_enable = true;
2468 : : }
2469 : : }
2470 : :
2471 [ # # ]: 0 : if (likely(!proto_xtr_enable))
2472 : : return;
2473 : :
2474 : 0 : offset = rte_mbuf_dynfield_register(&iavf_proto_xtr_metadata_param);
2475 [ # # ]: 0 : if (unlikely(offset == -1)) {
2476 : 0 : PMD_DRV_LOG(ERR,
2477 : : "failed to extract protocol metadata, error %d",
2478 : : -rte_errno);
2479 : 0 : return;
2480 : : }
2481 : :
2482 : 0 : PMD_DRV_LOG(DEBUG,
2483 : : "proto_xtr metadata offset in mbuf is : %d",
2484 : : offset);
2485 : 0 : rte_pmd_ifd_dynfield_proto_xtr_metadata_offs = offset;
2486 : :
2487 [ # # ]: 0 : for (i = 0; i < RTE_DIM(iavf_proto_xtr_params); i++) {
2488 : 0 : xtr_ol = &iavf_proto_xtr_params[i];
2489 : :
2490 : 0 : uint8_t rxdid = iavf_proto_xtr_type_to_rxdid((uint8_t)i);
2491 : :
2492 [ # # ]: 0 : if (!xtr_ol->required)
2493 : 0 : continue;
2494 : :
2495 [ # # ]: 0 : if (!(vf->supported_rxdid & RTE_BIT64(rxdid))) {
2496 : 0 : PMD_DRV_LOG(ERR,
2497 : : "rxdid[%u] is not supported in hardware",
2498 : : rxdid);
2499 : 0 : rte_pmd_ifd_dynfield_proto_xtr_metadata_offs = -1;
2500 : 0 : break;
2501 : : }
2502 : :
2503 : 0 : offset = rte_mbuf_dynflag_register(&xtr_ol->param);
2504 [ # # ]: 0 : if (unlikely(offset == -1)) {
2505 : 0 : PMD_DRV_LOG(ERR,
2506 : : "failed to register proto_xtr offload '%s', error %d",
2507 : : xtr_ol->param.name, -rte_errno);
2508 : :
2509 : 0 : rte_pmd_ifd_dynfield_proto_xtr_metadata_offs = -1;
2510 : 0 : break;
2511 : : }
2512 : :
2513 : 0 : PMD_DRV_LOG(DEBUG,
2514 : : "proto_xtr offload '%s' offset in mbuf is : %d",
2515 : : xtr_ol->param.name, offset);
2516 : 0 : *xtr_ol->ol_flag = 1ULL << offset;
2517 : : }
2518 : : }
2519 : :
2520 : : static int
2521 : 0 : iavf_init_vf(struct rte_eth_dev *dev)
2522 : : {
2523 : : int err, bufsz;
2524 : 0 : struct iavf_adapter *adapter =
2525 : 0 : IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
2526 : 0 : struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(dev->data->dev_private);
2527 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
2528 : :
2529 : 0 : vf->eth_dev = dev;
2530 : :
2531 : 0 : err = iavf_parse_devargs(dev);
2532 [ # # ]: 0 : if (err) {
2533 : 0 : PMD_INIT_LOG(ERR, "Failed to parse devargs");
2534 : 0 : goto err;
2535 : : }
2536 : :
2537 : 0 : err = iavf_set_mac_type(hw);
2538 [ # # ]: 0 : if (err) {
2539 : 0 : PMD_INIT_LOG(ERR, "set_mac_type failed: %d", err);
2540 : 0 : goto err;
2541 : : }
2542 : :
2543 : : err = iavf_check_vf_reset_done(hw);
2544 : : if (err) {
2545 : 0 : PMD_INIT_LOG(ERR, "VF is still resetting");
2546 : 0 : goto err;
2547 : : }
2548 : :
2549 : : iavf_init_adminq_parameter(hw);
2550 : 0 : err = iavf_init_adminq(hw);
2551 [ # # ]: 0 : if (err) {
2552 : 0 : PMD_INIT_LOG(ERR, "init_adminq failed: %d", err);
2553 : 0 : goto err;
2554 : : }
2555 : :
2556 : 0 : vf->aq_resp = rte_zmalloc("vf_aq_resp", IAVF_AQ_BUF_SZ, 0);
2557 [ # # ]: 0 : if (!vf->aq_resp) {
2558 : 0 : PMD_INIT_LOG(ERR, "unable to allocate vf_aq_resp memory");
2559 : 0 : goto err_aq;
2560 : : }
2561 [ # # ]: 0 : if (iavf_check_api_version(adapter) != 0) {
2562 : 0 : PMD_INIT_LOG(ERR, "check_api version failed");
2563 : 0 : goto err_api;
2564 : : }
2565 : :
2566 : : bufsz = sizeof(struct virtchnl_vf_resource) +
2567 : : (IAVF_MAX_VF_VSI * sizeof(struct virtchnl_vsi_resource));
2568 : 0 : vf->vf_res = rte_zmalloc("vf_res", bufsz, 0);
2569 [ # # ]: 0 : if (!vf->vf_res) {
2570 : 0 : PMD_INIT_LOG(ERR, "unable to allocate vf_res memory");
2571 : 0 : goto err_api;
2572 : : }
2573 : :
2574 [ # # ]: 0 : if (iavf_get_vf_resource(adapter) != 0) {
2575 : 0 : PMD_INIT_LOG(ERR, "iavf_get_vf_config failed");
2576 : 0 : goto err_alloc;
2577 : : }
2578 : : /* Allocate memort for RSS info */
2579 [ # # ]: 0 : if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_PF) {
2580 : 0 : vf->rss_key = rte_zmalloc("rss_key",
2581 : 0 : vf->vf_res->rss_key_size, 0);
2582 [ # # ]: 0 : if (!vf->rss_key) {
2583 : 0 : PMD_INIT_LOG(ERR, "unable to allocate rss_key memory");
2584 : 0 : goto err_rss;
2585 : : }
2586 : 0 : vf->rss_lut = rte_zmalloc("rss_lut",
2587 : 0 : vf->vf_res->rss_lut_size, 0);
2588 [ # # ]: 0 : if (!vf->rss_lut) {
2589 : 0 : PMD_INIT_LOG(ERR, "unable to allocate rss_lut memory");
2590 : 0 : goto err_rss;
2591 : : }
2592 : : }
2593 : :
2594 [ # # ]: 0 : if (vf->vsi_res->num_queue_pairs > IAVF_MAX_NUM_QUEUES_DFLT)
2595 : 0 : vf->lv_enabled = true;
2596 : :
2597 [ # # ]: 0 : if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RX_FLEX_DESC) {
2598 [ # # ]: 0 : if (iavf_get_supported_rxdid(adapter) != 0) {
2599 : 0 : PMD_INIT_LOG(ERR, "failed to do get supported rxdid");
2600 : 0 : goto err_rss;
2601 : : }
2602 : : }
2603 : :
2604 [ # # ]: 0 : if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN_V2) {
2605 [ # # ]: 0 : if (iavf_get_vlan_offload_caps_v2(adapter) != 0) {
2606 : 0 : PMD_INIT_LOG(ERR, "failed to do get VLAN offload v2 capabilities");
2607 : 0 : goto err_rss;
2608 : : }
2609 : : }
2610 : :
2611 [ # # ]: 0 : if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_QOS) {
2612 : : bufsz = sizeof(struct virtchnl_qos_cap_list) +
2613 : : IAVF_MAX_TRAFFIC_CLASS *
2614 : : sizeof(struct virtchnl_qos_cap_elem);
2615 : 0 : vf->qos_cap = rte_zmalloc("qos_cap", bufsz, 0);
2616 [ # # ]: 0 : if (!vf->qos_cap) {
2617 : 0 : PMD_INIT_LOG(ERR, "unable to allocate qos_cap memory");
2618 : 0 : goto err_rss;
2619 : : }
2620 : 0 : iavf_tm_conf_init(dev);
2621 : : }
2622 : :
2623 : 0 : iavf_init_proto_xtr(dev);
2624 : :
2625 : 0 : return 0;
2626 : 0 : err_rss:
2627 : 0 : rte_free(vf->rss_key);
2628 : 0 : rte_free(vf->rss_lut);
2629 : 0 : err_alloc:
2630 : 0 : rte_free(vf->qos_cap);
2631 : 0 : rte_free(vf->vf_res);
2632 : 0 : vf->vsi_res = NULL;
2633 : 0 : err_api:
2634 : 0 : rte_free(vf->aq_resp);
2635 : 0 : err_aq:
2636 : 0 : iavf_shutdown_adminq(hw);
2637 : : err:
2638 : : return -1;
2639 : : }
2640 : :
2641 : : static void
2642 : 0 : iavf_uninit_vf(struct rte_eth_dev *dev)
2643 : : {
2644 : 0 : struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(dev->data->dev_private);
2645 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
2646 : :
2647 : 0 : iavf_shutdown_adminq(hw);
2648 : :
2649 : 0 : rte_free(vf->vf_res);
2650 : 0 : vf->vsi_res = NULL;
2651 : 0 : vf->vf_res = NULL;
2652 : :
2653 : 0 : rte_free(vf->aq_resp);
2654 : 0 : vf->aq_resp = NULL;
2655 : :
2656 : 0 : rte_free(vf->qos_cap);
2657 : 0 : vf->qos_cap = NULL;
2658 : :
2659 : 0 : rte_free(vf->rss_lut);
2660 : 0 : vf->rss_lut = NULL;
2661 : 0 : rte_free(vf->rss_key);
2662 : 0 : vf->rss_key = NULL;
2663 : 0 : }
2664 : :
2665 : : /* Enable default admin queue interrupt setting */
2666 : : static inline void
2667 : : iavf_enable_irq0(struct iavf_hw *hw)
2668 : : {
2669 : : /* Enable admin queue interrupt trigger */
2670 : 0 : IAVF_WRITE_REG(hw, IAVF_VFINT_ICR0_ENA1,
2671 : : IAVF_VFINT_ICR0_ENA1_ADMINQ_MASK);
2672 : :
2673 : 0 : IAVF_WRITE_REG(hw, IAVF_VFINT_DYN_CTL01,
2674 : : IAVF_VFINT_DYN_CTL01_INTENA_MASK |
2675 : : IAVF_VFINT_DYN_CTL01_CLEARPBA_MASK |
2676 : : IAVF_VFINT_DYN_CTL01_ITR_INDX_MASK);
2677 : :
2678 : 0 : IAVF_WRITE_FLUSH(hw);
2679 : : }
2680 : :
2681 : : static inline void
2682 : : iavf_disable_irq0(struct iavf_hw *hw)
2683 : : {
2684 : : /* Disable all interrupt types */
2685 : 0 : IAVF_WRITE_REG(hw, IAVF_VFINT_ICR0_ENA1, 0);
2686 : 0 : IAVF_WRITE_REG(hw, IAVF_VFINT_DYN_CTL01,
2687 : : IAVF_VFINT_DYN_CTL01_ITR_INDX_MASK);
2688 : 0 : IAVF_WRITE_FLUSH(hw);
2689 : : }
2690 : :
2691 : : static void
2692 : 0 : iavf_dev_interrupt_handler(void *param)
2693 : : {
2694 : : struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
2695 : 0 : struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(dev->data->dev_private);
2696 : :
2697 : : iavf_disable_irq0(hw);
2698 : :
2699 : 0 : iavf_handle_virtchnl_msg(dev);
2700 : :
2701 : : iavf_enable_irq0(hw);
2702 : 0 : }
2703 : :
2704 : : void
2705 : 0 : iavf_dev_alarm_handler(void *param)
2706 : : {
2707 : : struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
2708 [ # # # # : 0 : if (dev == NULL || dev->data == NULL || dev->data->dev_private == NULL)
# # ]
2709 : : return;
2710 : :
2711 : : struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(dev->data->dev_private);
2712 : : uint32_t icr0;
2713 : :
2714 : : iavf_disable_irq0(hw);
2715 : :
2716 : : /* read out interrupt causes */
2717 : 0 : icr0 = IAVF_READ_REG(hw, IAVF_VFINT_ICR01);
2718 : :
2719 [ # # ]: 0 : if (icr0 & IAVF_VFINT_ICR01_ADMINQ_MASK) {
2720 : 0 : PMD_DRV_LOG(DEBUG, "ICR01_ADMINQ is reported");
2721 : 0 : iavf_handle_virtchnl_msg(dev);
2722 : : }
2723 : :
2724 : : iavf_enable_irq0(hw);
2725 : :
2726 : 0 : rte_eal_alarm_set(IAVF_ALARM_INTERVAL,
2727 : : iavf_dev_alarm_handler, dev);
2728 : : }
2729 : :
2730 : : static int
2731 : 0 : iavf_dev_flow_ops_get(struct rte_eth_dev *dev,
2732 : : const struct rte_flow_ops **ops)
2733 : : {
2734 : 0 : struct iavf_adapter *adapter =
2735 : 0 : IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
2736 : :
2737 [ # # ]: 0 : if (adapter->closed)
2738 : : return -EIO;
2739 : :
2740 : 0 : *ops = &iavf_flow_ops;
2741 : 0 : return 0;
2742 : : }
2743 : :
2744 : : static void
2745 : 0 : iavf_default_rss_disable(struct iavf_adapter *adapter)
2746 : : {
2747 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
2748 : : int ret = 0;
2749 : :
2750 [ # # ]: 0 : if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_PF) {
2751 : : /* Set hena = 0 to ask PF to cleanup all existing RSS. */
2752 : 0 : ret = iavf_set_hena(adapter, 0);
2753 [ # # ]: 0 : if (ret)
2754 : : /* It is a workaround, temporarily allow error to be
2755 : : * returned due to possible lack of PF handling for
2756 : : * hena = 0.
2757 : : */
2758 : 0 : PMD_INIT_LOG(WARNING, "fail to disable default RSS,"
2759 : : "lack PF support");
2760 : : }
2761 : 0 : }
2762 : :
2763 : : static int
2764 : 0 : iavf_dev_init(struct rte_eth_dev *eth_dev)
2765 : : {
2766 : 0 : struct iavf_adapter *adapter =
2767 : 0 : IAVF_DEV_PRIVATE_TO_ADAPTER(eth_dev->data->dev_private);
2768 : : struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(adapter);
2769 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
2770 : 0 : struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
2771 : : int ret = 0;
2772 : :
2773 : 0 : PMD_INIT_FUNC_TRACE();
2774 : :
2775 : : /* assign ops func pointer */
2776 : 0 : eth_dev->dev_ops = &iavf_eth_dev_ops;
2777 : 0 : eth_dev->rx_queue_count = iavf_dev_rxq_count;
2778 : 0 : eth_dev->rx_descriptor_status = iavf_dev_rx_desc_status;
2779 : 0 : eth_dev->tx_descriptor_status = iavf_dev_tx_desc_status;
2780 : 0 : eth_dev->rx_pkt_burst = &iavf_recv_pkts;
2781 : 0 : eth_dev->tx_pkt_burst = &iavf_xmit_pkts;
2782 : 0 : eth_dev->tx_pkt_prepare = &iavf_prep_pkts;
2783 : :
2784 : : /* For secondary processes, we don't initialise any further as primary
2785 : : * has already done this work.
2786 : : */
2787 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
2788 : 0 : iavf_set_rx_function(eth_dev);
2789 : : /* LLDP may have been enabled by the primary process. Store the offset before
2790 : : * setting the TX function because it may be used in the selection function.
2791 : : */
2792 : 0 : rte_pmd_iavf_tx_lldp_dynfield_offset =
2793 : 0 : rte_mbuf_dynfield_lookup(IAVF_TX_LLDP_DYNFIELD, NULL);
2794 : 0 : iavf_set_tx_function(eth_dev);
2795 : 0 : return 0;
2796 : : }
2797 : 0 : rte_eth_copy_pci_info(eth_dev, pci_dev);
2798 : :
2799 : 0 : hw->vendor_id = pci_dev->id.vendor_id;
2800 : 0 : hw->device_id = pci_dev->id.device_id;
2801 : 0 : hw->subsystem_vendor_id = pci_dev->id.subsystem_vendor_id;
2802 : 0 : hw->subsystem_device_id = pci_dev->id.subsystem_device_id;
2803 : 0 : hw->bus.bus_id = pci_dev->addr.bus;
2804 : 0 : hw->bus.device = pci_dev->addr.devid;
2805 : 0 : hw->bus.func = pci_dev->addr.function;
2806 : 0 : hw->hw_addr = (void *)pci_dev->mem_resource[0].addr;
2807 : 0 : hw->back = IAVF_DEV_PRIVATE_TO_ADAPTER(eth_dev->data->dev_private);
2808 : 0 : adapter->dev_data = eth_dev->data;
2809 : 0 : adapter->stopped = 1;
2810 : 0 : adapter->mac_primary_set = false;
2811 : :
2812 [ # # ]: 0 : if (iavf_dev_event_handler_init())
2813 : 0 : goto init_vf_err;
2814 : :
2815 [ # # ]: 0 : if (iavf_init_vf(eth_dev) != 0) {
2816 : 0 : PMD_INIT_LOG(ERR, "Init vf failed");
2817 : 0 : return -1;
2818 : : }
2819 : :
2820 : : /* set default ptype table */
2821 : 0 : iavf_set_default_ptype_table(eth_dev);
2822 : :
2823 : : /* copy mac addr */
2824 : 0 : eth_dev->data->mac_addrs = rte_zmalloc(
2825 : : "iavf_mac", RTE_ETHER_ADDR_LEN * IAVF_NUM_MACADDR_MAX, 0);
2826 [ # # ]: 0 : if (!eth_dev->data->mac_addrs) {
2827 : 0 : PMD_INIT_LOG(ERR, "Failed to allocate %d bytes needed to"
2828 : : " store MAC addresses",
2829 : : RTE_ETHER_ADDR_LEN * IAVF_NUM_MACADDR_MAX);
2830 : : ret = -ENOMEM;
2831 : 0 : goto init_vf_err;
2832 : : }
2833 : : /* If the MAC address is not configured by host,
2834 : : * generate a random one.
2835 : : */
2836 : : if (!rte_is_valid_assigned_ether_addr(
2837 : : (struct rte_ether_addr *)hw->mac.addr))
2838 : 0 : rte_eth_random_addr(hw->mac.addr);
2839 : 0 : rte_ether_addr_copy((struct rte_ether_addr *)hw->mac.addr,
2840 [ # # ]: 0 : ð_dev->data->mac_addrs[0]);
2841 : :
2842 : :
2843 [ # # # # ]: 0 : if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_WB_ON_ITR &&
2844 : : /* register callback func to eal lib */
2845 : 0 : rte_intr_callback_register(pci_dev->intr_handle,
2846 : : iavf_dev_interrupt_handler, (void *)eth_dev) == 0)
2847 : :
2848 : : /* enable uio intr after callback register */
2849 : 0 : rte_intr_enable(pci_dev->intr_handle);
2850 : : else
2851 : 0 : rte_eal_alarm_set(IAVF_ALARM_INTERVAL,
2852 : : iavf_dev_alarm_handler, eth_dev);
2853 : :
2854 : : /* configure and enable device interrupt */
2855 : : iavf_enable_irq0(hw);
2856 : :
2857 : 0 : ret = iavf_flow_init(adapter);
2858 [ # # ]: 0 : if (ret) {
2859 : 0 : PMD_INIT_LOG(ERR, "Failed to initialize flow");
2860 : 0 : goto flow_init_err;
2861 : : }
2862 : :
2863 : : /** Check if the IPsec Crypto offload is supported and create
2864 : : * security_ctx if it is.
2865 : : */
2866 [ # # ]: 0 : if (iavf_ipsec_crypto_supported(adapter)) {
2867 : : /* Initialize security_ctx only for primary process*/
2868 : 0 : ret = iavf_security_ctx_create(adapter);
2869 [ # # ]: 0 : if (ret) {
2870 : 0 : PMD_INIT_LOG(ERR, "failed to create ipsec crypto security instance");
2871 : 0 : goto flow_init_err;
2872 : : }
2873 : :
2874 : 0 : ret = iavf_security_init(adapter);
2875 [ # # ]: 0 : if (ret) {
2876 : 0 : PMD_INIT_LOG(ERR, "failed to initialized ipsec crypto resources");
2877 : 0 : goto security_init_err;
2878 : : }
2879 : : }
2880 : :
2881 : : /* Get PTP caps early to verify device capabilities */
2882 [ # # ]: 0 : if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_CAP_PTP) {
2883 [ # # ]: 0 : if (iavf_get_ptp_cap(adapter)) {
2884 : 0 : PMD_INIT_LOG(ERR, "Failed to get ptp capability");
2885 : 0 : goto security_init_err;
2886 : : }
2887 : : }
2888 : :
2889 : 0 : iavf_default_rss_disable(adapter);
2890 : :
2891 : 0 : iavf_dev_stats_reset(eth_dev);
2892 : :
2893 : : /* Start device watchdog */
2894 : 0 : iavf_dev_watchdog_enable(adapter);
2895 : 0 : adapter->closed = false;
2896 : :
2897 : 0 : return 0;
2898 : :
2899 : 0 : security_init_err:
2900 : 0 : iavf_security_ctx_destroy(adapter);
2901 : :
2902 : 0 : flow_init_err:
2903 : : iavf_disable_irq0(hw);
2904 : :
2905 [ # # ]: 0 : if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_WB_ON_ITR) {
2906 : : /* disable uio intr before callback unregiser */
2907 : 0 : rte_intr_disable(pci_dev->intr_handle);
2908 : :
2909 : : /* unregister callback func from eal lib */
2910 : 0 : rte_intr_callback_unregister(pci_dev->intr_handle,
2911 : : iavf_dev_interrupt_handler, eth_dev);
2912 : : } else {
2913 : 0 : rte_eal_alarm_cancel(iavf_dev_alarm_handler, eth_dev);
2914 : : }
2915 : :
2916 : 0 : rte_free(eth_dev->data->mac_addrs);
2917 : 0 : eth_dev->data->mac_addrs = NULL;
2918 : :
2919 : 0 : init_vf_err:
2920 : 0 : iavf_uninit_vf(eth_dev);
2921 : :
2922 : 0 : return ret;
2923 : : }
2924 : :
2925 : : static int
2926 : 0 : iavf_dev_close(struct rte_eth_dev *dev)
2927 : : {
2928 : 0 : struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(dev->data->dev_private);
2929 : 0 : struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
2930 : 0 : struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
2931 : : struct iavf_adapter *adapter =
2932 : : IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
2933 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
2934 : : int ret;
2935 : :
2936 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
2937 : : return 0;
2938 : :
2939 [ # # ]: 0 : if (adapter->closed) {
2940 : : ret = 0;
2941 : 0 : goto out;
2942 : : }
2943 : :
2944 : 0 : ret = iavf_dev_stop(dev);
2945 : :
2946 : : /*
2947 : : * Release redundant queue resource when close the dev
2948 : : * so that other vfs can re-use the queues.
2949 : : */
2950 [ # # ]: 0 : if (vf->lv_enabled) {
2951 : 0 : ret = iavf_request_queues(dev, IAVF_MAX_NUM_QUEUES_DFLT);
2952 [ # # ]: 0 : if (ret)
2953 : 0 : PMD_DRV_LOG(ERR, "Reset the num of queues failed");
2954 : :
2955 : 0 : vf->max_rss_qregion = IAVF_MAX_NUM_QUEUES_DFLT;
2956 : : }
2957 : :
2958 : 0 : adapter->closed = true;
2959 : :
2960 : : /* free iAVF security device context all related resources */
2961 : 0 : iavf_security_ctx_destroy(adapter);
2962 : :
2963 : : /* remove RSS configuration */
2964 : 0 : iavf_hash_uninit(adapter);
2965 : :
2966 : 0 : iavf_flow_flush(dev, NULL);
2967 : 0 : iavf_flow_uninit(adapter);
2968 : :
2969 : : /*
2970 : : * disable promiscuous mode before reset vf
2971 : : * it is a workaround solution when work with kernel driver
2972 : : * and it is not the normal way
2973 : : */
2974 [ # # ]: 0 : if (vf->promisc_unicast_enabled || vf->promisc_multicast_enabled)
2975 : 0 : iavf_config_promisc(adapter, false, false);
2976 : :
2977 : 0 : iavf_vf_reset(hw);
2978 : 0 : iavf_shutdown_adminq(hw);
2979 [ # # ]: 0 : if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_WB_ON_ITR) {
2980 : : /* disable uio intr before callback unregister */
2981 : 0 : rte_intr_disable(intr_handle);
2982 : :
2983 : : /* unregister callback func from eal lib */
2984 : 0 : rte_intr_callback_unregister(intr_handle,
2985 : : iavf_dev_interrupt_handler, dev);
2986 : : } else {
2987 : 0 : rte_eal_alarm_cancel(iavf_dev_alarm_handler, dev);
2988 : : }
2989 : : iavf_disable_irq0(hw);
2990 : :
2991 [ # # ]: 0 : if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_QOS)
2992 : 0 : iavf_tm_conf_uninit(dev);
2993 : :
2994 [ # # ]: 0 : if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_PF) {
2995 [ # # ]: 0 : if (vf->rss_lut) {
2996 : 0 : rte_free(vf->rss_lut);
2997 : 0 : vf->rss_lut = NULL;
2998 : : }
2999 [ # # ]: 0 : if (vf->rss_key) {
3000 : 0 : rte_free(vf->rss_key);
3001 : 0 : vf->rss_key = NULL;
3002 : : }
3003 : : }
3004 : :
3005 : 0 : rte_free(vf->vf_res);
3006 : 0 : vf->vsi_res = NULL;
3007 : 0 : vf->vf_res = NULL;
3008 : :
3009 : 0 : rte_free(vf->aq_resp);
3010 : 0 : vf->aq_resp = NULL;
3011 : :
3012 : : /*
3013 : : * If the VF is reset via VFLR, the device will be knocked out of bus
3014 : : * master mode, and the driver will fail to recover from the reset. Fix
3015 : : * this by enabling bus mastering after every reset. In a non-VFLR case,
3016 : : * the bus master bit will not be disabled, and this call will have no
3017 : : * effect.
3018 : : */
3019 : 0 : out:
3020 [ # # # # ]: 0 : if (vf->vf_reset && !rte_pci_set_bus_master(pci_dev, true)) {
3021 : 0 : vf->vf_reset = false;
3022 : 0 : iavf_set_no_poll(adapter, false);
3023 : : }
3024 : :
3025 : : /* disable watchdog */
3026 : 0 : iavf_dev_watchdog_disable(adapter);
3027 : :
3028 : 0 : return ret;
3029 : : }
3030 : :
3031 : : static int
3032 : 0 : iavf_dev_uninit(struct rte_eth_dev *dev)
3033 : : {
3034 : 0 : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
3035 : :
3036 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
3037 : : return -EPERM;
3038 : :
3039 : 0 : iavf_dev_close(dev);
3040 : :
3041 [ # # ]: 0 : if (!vf->in_reset_recovery)
3042 : 0 : iavf_dev_event_handler_fini();
3043 : :
3044 : : return 0;
3045 : : }
3046 : :
3047 : : /*
3048 : : * Reset VF device only to re-initialize resources in PMD layer
3049 : : */
3050 : : static int
3051 : 0 : iavf_dev_reset(struct rte_eth_dev *dev)
3052 : : {
3053 : : int ret;
3054 : 0 : struct iavf_adapter *adapter =
3055 : 0 : IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
3056 : : struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(dev->data->dev_private);
3057 : : /*
3058 : : * Check whether the VF reset has been done and inform application,
3059 : : * to avoid calling the virtual channel command, which may cause
3060 : : * the device to be abnormal.
3061 : : */
3062 : : ret = iavf_check_vf_reset_done(hw);
3063 : : if (ret) {
3064 : 0 : PMD_DRV_LOG(ERR, "Wait too long for reset done!");
3065 : 0 : return ret;
3066 : : }
3067 : 0 : iavf_set_no_poll(adapter, false);
3068 : :
3069 : 0 : PMD_DRV_LOG(DEBUG, "Start dev_reset ...");
3070 : 0 : ret = iavf_dev_uninit(dev);
3071 [ # # ]: 0 : if (ret)
3072 : : return ret;
3073 : :
3074 : 0 : return iavf_dev_init(dev);
3075 : : }
3076 : :
3077 : : static inline bool
3078 : : iavf_is_reset(struct iavf_hw *hw)
3079 : : {
3080 : 0 : return !(IAVF_READ_REG(hw, IAVF_VF_ARQLEN1) &
3081 : : IAVF_VF_ARQLEN1_ARQENABLE_MASK);
3082 : : }
3083 : :
3084 : : static bool
3085 : : iavf_is_reset_detected(struct iavf_adapter *adapter)
3086 : : {
3087 : : struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(adapter);
3088 : : int i;
3089 : :
3090 : : /* poll until we see the reset actually happen */
3091 [ # # ]: 0 : for (i = 0; i < IAVF_RESET_DETECTED_CNT; i++) {
3092 [ # # ]: 0 : if (iavf_is_reset(hw))
3093 : : return true;
3094 : : rte_delay_ms(20);
3095 : : }
3096 : :
3097 : : return false;
3098 : : }
3099 : :
3100 : : /*
3101 : : * Handle hardware reset
3102 : : */
3103 : : void
3104 : 0 : iavf_handle_hw_reset(struct rte_eth_dev *dev, bool vf_initiated_reset)
3105 : : {
3106 : 0 : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
3107 : : struct iavf_adapter *adapter = dev->data->dev_private;
3108 : : int ret;
3109 : : bool restart_device = false;
3110 : :
3111 [ # # ]: 0 : if (vf_initiated_reset) {
3112 : 0 : restart_device = dev->data->dev_started;
3113 : : } else {
3114 [ # # ]: 0 : if (!dev->data->dev_started)
3115 : : return;
3116 : :
3117 [ # # ]: 0 : if (!iavf_is_reset_detected(adapter)) {
3118 : 0 : PMD_DRV_LOG(DEBUG, "reset not start");
3119 : 0 : return;
3120 : : }
3121 : : }
3122 : :
3123 : 0 : vf->in_reset_recovery = true;
3124 : 0 : iavf_set_no_poll(adapter, false);
3125 : :
3126 : : /* Call the pre reset callback */
3127 [ # # ]: 0 : if (vf->pre_reset_cb != NULL)
3128 : 0 : vf->pre_reset_cb(dev->data->port_id, vf->pre_reset_cb_arg);
3129 : :
3130 : 0 : ret = iavf_dev_reset(dev);
3131 [ # # ]: 0 : if (ret)
3132 : 0 : goto error;
3133 : :
3134 : : /* VF states restore */
3135 : 0 : ret = iavf_dev_configure(dev);
3136 [ # # ]: 0 : if (ret)
3137 : 0 : goto error;
3138 : :
3139 : 0 : iavf_dev_xstats_reset(dev);
3140 : :
3141 [ # # ]: 0 : if (!vf_initiated_reset || restart_device) {
3142 : : /* start the device */
3143 : 0 : ret = iavf_dev_start(dev);
3144 [ # # ]: 0 : if (ret)
3145 : 0 : goto error;
3146 : :
3147 : 0 : dev->data->dev_started = 1;
3148 : : }
3149 : 0 : goto exit;
3150 : :
3151 : 0 : error:
3152 : 0 : PMD_DRV_LOG(DEBUG, "RESET recover with error code=%dn", ret);
3153 : 0 : exit:
3154 : : /* Call the post reset callback */
3155 [ # # ]: 0 : if (vf->post_reset_cb != NULL)
3156 : 0 : vf->post_reset_cb(dev->data->port_id, ret, vf->post_reset_cb_arg);
3157 : :
3158 : 0 : vf->in_reset_recovery = false;
3159 : 0 : iavf_set_no_poll(adapter, false);
3160 : :
3161 : 0 : return;
3162 : : }
3163 : :
3164 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_pmd_iavf_reinit, 25.11)
3165 : : int
3166 : 0 : rte_pmd_iavf_reinit(uint16_t port)
3167 : : {
3168 : : struct rte_eth_dev *dev;
3169 : : struct iavf_adapter *adapter;
3170 : :
3171 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
3172 : :
3173 : 0 : dev = &rte_eth_devices[port];
3174 : :
3175 [ # # ]: 0 : if (!is_iavf_supported(dev)) {
3176 : 0 : PMD_DRV_LOG(ERR, "Cannot reinit VF, port %u is not an IAVF device.", port);
3177 : 0 : return -ENOTSUP;
3178 : : }
3179 : :
3180 [ # # ]: 0 : if (!dev->data->dev_configured) {
3181 : 0 : PMD_DRV_LOG(ERR, "Cannot reinit unconfigured port %u.", port);
3182 : 0 : return -EINVAL;
3183 : : }
3184 : :
3185 : 0 : adapter = dev->data->dev_private;
3186 [ # # # # ]: 0 : if (dev->data->dev_started && !adapter->devargs.no_poll_on_link_down) {
3187 : 0 : PMD_DRV_LOG(ERR, "Cannot reinit started port %u. Either stop the port or enable "
3188 : : "no-poll-on-link-down in devargs.", port);
3189 : 0 : return -EINVAL;
3190 : : }
3191 : :
3192 : 0 : iavf_handle_hw_reset(dev, true);
3193 : :
3194 : 0 : return 0;
3195 : : }
3196 : :
3197 : : static int
3198 : 0 : iavf_validate_reset_cb(uint16_t port, void *cb, void *cb_arg)
3199 : : {
3200 : : struct rte_eth_dev *dev;
3201 : : struct iavf_info *vf;
3202 : :
3203 [ # # ]: 0 : RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
3204 : :
3205 [ # # ]: 0 : if (cb == NULL && cb_arg != NULL) {
3206 : 0 : PMD_DRV_LOG(ERR, "Cannot unregister reset cb on port %u, arg must be NULL.", port);
3207 : 0 : return -EINVAL;
3208 : : }
3209 : :
3210 : 0 : dev = &rte_eth_devices[port];
3211 [ # # ]: 0 : if (!is_iavf_supported(dev)) {
3212 : 0 : PMD_DRV_LOG(ERR, "Cannot modify reset cb, port %u not an IAVF device.", port);
3213 : 0 : return -ENOTSUP;
3214 : : }
3215 : :
3216 : 0 : vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
3217 [ # # ]: 0 : if (vf->in_reset_recovery) {
3218 : 0 : PMD_DRV_LOG(ERR, "Cannot modify reset cb on port %u, VF is resetting.", port);
3219 : 0 : return -EBUSY;
3220 : : }
3221 : :
3222 : : return 0;
3223 : : }
3224 : :
3225 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_pmd_iavf_register_pre_reset_cb, 26.03)
3226 : : int
3227 : 0 : rte_pmd_iavf_register_pre_reset_cb(uint16_t port,
3228 : : iavf_pre_reset_cb_t pre_reset_cb,
3229 : : void *pre_reset_cb_arg)
3230 : : {
3231 : : struct rte_eth_dev *dev;
3232 : : struct iavf_info *vf;
3233 : : int ret;
3234 : :
3235 : 0 : ret = iavf_validate_reset_cb(port, pre_reset_cb, pre_reset_cb_arg);
3236 [ # # ]: 0 : if (ret)
3237 : : return ret;
3238 : :
3239 : : dev = &rte_eth_devices[port];
3240 : 0 : vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
3241 : 0 : vf->pre_reset_cb = pre_reset_cb;
3242 : 0 : vf->pre_reset_cb_arg = pre_reset_cb_arg;
3243 : :
3244 : 0 : return 0;
3245 : : }
3246 : :
3247 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_pmd_iavf_register_post_reset_cb, 26.03)
3248 : : int
3249 : 0 : rte_pmd_iavf_register_post_reset_cb(uint16_t port,
3250 : : iavf_post_reset_cb_t post_reset_cb,
3251 : : void *post_reset_cb_arg)
3252 : : {
3253 : : struct rte_eth_dev *dev;
3254 : : struct iavf_info *vf;
3255 : : int ret;
3256 : :
3257 : 0 : ret = iavf_validate_reset_cb(port, post_reset_cb, post_reset_cb_arg);
3258 [ # # ]: 0 : if (ret)
3259 : : return ret;
3260 : :
3261 : : dev = &rte_eth_devices[port];
3262 : 0 : vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
3263 : 0 : vf->post_reset_cb = post_reset_cb;
3264 : 0 : vf->post_reset_cb_arg = post_reset_cb_arg;
3265 : :
3266 : 0 : return 0;
3267 : : }
3268 : :
3269 : : void
3270 : 0 : iavf_set_no_poll(struct iavf_adapter *adapter, bool link_change)
3271 : : {
3272 : : struct iavf_info *vf = &adapter->vf;
3273 : :
3274 : 0 : adapter->no_poll = (link_change & !vf->link_up) ||
3275 [ # # # # : 0 : vf->vf_reset || vf->in_reset_recovery;
# # ]
3276 : 0 : }
3277 : :
3278 : : static int
3279 : 0 : iavf_dcf_cap_check_handler(__rte_unused const char *key,
3280 : : const char *value, __rte_unused void *opaque)
3281 : : {
3282 [ # # ]: 0 : if (strcmp(value, "dcf"))
3283 : 0 : return -1;
3284 : :
3285 : : return 0;
3286 : : }
3287 : :
3288 : : static int
3289 : 0 : iavf_dcf_cap_selected(struct rte_devargs *devargs)
3290 : : {
3291 : : struct rte_kvargs *kvlist;
3292 : : const char *key = "cap";
3293 : : int ret = 0;
3294 : :
3295 [ # # ]: 0 : if (devargs == NULL)
3296 : : return 0;
3297 : :
3298 : 0 : kvlist = rte_kvargs_parse(devargs->args, NULL);
3299 [ # # ]: 0 : if (kvlist == NULL)
3300 : : return 0;
3301 : :
3302 [ # # ]: 0 : if (!rte_kvargs_count(kvlist, key))
3303 : 0 : goto exit;
3304 : :
3305 : : /* dcf capability selected when there's a key-value pair: cap=dcf */
3306 [ # # ]: 0 : if (rte_kvargs_process(kvlist, key,
3307 : : iavf_dcf_cap_check_handler, NULL) < 0)
3308 : 0 : goto exit;
3309 : :
3310 : : ret = 1;
3311 : :
3312 : 0 : exit:
3313 : 0 : rte_kvargs_free(kvlist);
3314 : 0 : return ret;
3315 : : }
3316 : :
3317 : 0 : static int eth_iavf_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
3318 : : struct rte_pci_device *pci_dev)
3319 : : {
3320 [ # # ]: 0 : if (iavf_dcf_cap_selected(pci_dev->device.devargs))
3321 : : return 1;
3322 : :
3323 : 0 : return rte_eth_dev_pci_generic_probe(pci_dev,
3324 : : sizeof(struct iavf_adapter), iavf_dev_init);
3325 : : }
3326 : :
3327 : 0 : static int eth_iavf_pci_remove(struct rte_pci_device *pci_dev)
3328 : : {
3329 : 0 : return rte_eth_dev_pci_generic_remove(pci_dev, iavf_dev_uninit);
3330 : : }
3331 : :
3332 : : /* Adaptive virtual function driver struct */
3333 : : static struct rte_pci_driver rte_iavf_pmd = {
3334 : : .id_table = pci_id_iavf_map,
3335 : : .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
3336 : : .probe = eth_iavf_pci_probe,
3337 : : .remove = eth_iavf_pci_remove,
3338 : : };
3339 : :
3340 : 0 : bool is_iavf_supported(struct rte_eth_dev *dev)
3341 : : {
3342 : 0 : return !strcmp(dev->device->driver->name, rte_iavf_pmd.driver.name);
3343 : : }
3344 : :
3345 : 276 : RTE_PMD_REGISTER_PCI(net_iavf, rte_iavf_pmd);
3346 : : RTE_PMD_REGISTER_PCI_TABLE(net_iavf, pci_id_iavf_map);
3347 : : RTE_PMD_REGISTER_KMOD_DEP(net_iavf, "* igb_uio | vfio-pci");
3348 : : RTE_PMD_REGISTER_PARAM_STRING(net_iavf, "cap=dcf");
3349 [ - + ]: 276 : RTE_LOG_REGISTER_SUFFIX(iavf_logtype_init, init, NOTICE);
3350 [ - + ]: 276 : RTE_LOG_REGISTER_SUFFIX(iavf_logtype_driver, driver, NOTICE);
3351 : : #ifdef RTE_ETHDEV_DEBUG_RX
3352 : : RTE_LOG_REGISTER_SUFFIX(iavf_logtype_rx, rx, DEBUG);
3353 : : #endif
3354 : : #ifdef RTE_ETHDEV_DEBUG_TX
3355 : : RTE_LOG_REGISTER_SUFFIX(iavf_logtype_tx, tx, DEBUG);
3356 : : #endif
|