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