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