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