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