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