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