Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2022 Intel Corporation
3 : : */
4 : :
5 : : #include <rte_atomic.h>
6 : : #include <rte_eal.h>
7 : : #include <rte_ether.h>
8 : : #include <rte_malloc.h>
9 : : #include <rte_memzone.h>
10 : : #include <rte_dev.h>
11 : : #include <errno.h>
12 : : #include <rte_alarm.h>
13 : :
14 : : #include "idpf_ethdev.h"
15 : : #include "idpf_rxtx.h"
16 : :
17 : : #define IDPF_TX_SINGLE_Q "tx_single"
18 : : #define IDPF_RX_SINGLE_Q "rx_single"
19 : : #define IDPF_VPORT "vport"
20 : :
21 : : rte_spinlock_t idpf_adapter_lock;
22 : : /* A list for all adapters, one adapter matches one PCI device */
23 : : struct idpf_adapter_list idpf_adapter_list;
24 : : bool idpf_adapter_list_init;
25 : :
26 : : static const char * const idpf_valid_args[] = {
27 : : IDPF_TX_SINGLE_Q,
28 : : IDPF_RX_SINGLE_Q,
29 : : IDPF_VPORT,
30 : : NULL
31 : : };
32 : :
33 : : uint32_t idpf_supported_speeds[] = {
34 : : RTE_ETH_SPEED_NUM_NONE,
35 : : RTE_ETH_SPEED_NUM_10M,
36 : : RTE_ETH_SPEED_NUM_100M,
37 : : RTE_ETH_SPEED_NUM_1G,
38 : : RTE_ETH_SPEED_NUM_2_5G,
39 : : RTE_ETH_SPEED_NUM_5G,
40 : : RTE_ETH_SPEED_NUM_10G,
41 : : RTE_ETH_SPEED_NUM_20G,
42 : : RTE_ETH_SPEED_NUM_25G,
43 : : RTE_ETH_SPEED_NUM_40G,
44 : : RTE_ETH_SPEED_NUM_50G,
45 : : RTE_ETH_SPEED_NUM_56G,
46 : : RTE_ETH_SPEED_NUM_100G,
47 : : RTE_ETH_SPEED_NUM_200G
48 : : };
49 : :
50 : : static const uint64_t idpf_map_hena_rss[] = {
51 : : [IDPF_HASH_NONF_UNICAST_IPV4_UDP] =
52 : : RTE_ETH_RSS_NONFRAG_IPV4_UDP,
53 : : [IDPF_HASH_NONF_MULTICAST_IPV4_UDP] =
54 : : RTE_ETH_RSS_NONFRAG_IPV4_UDP,
55 : : [IDPF_HASH_NONF_IPV4_UDP] =
56 : : RTE_ETH_RSS_NONFRAG_IPV4_UDP,
57 : : [IDPF_HASH_NONF_IPV4_TCP_SYN_NO_ACK] =
58 : : RTE_ETH_RSS_NONFRAG_IPV4_TCP,
59 : : [IDPF_HASH_NONF_IPV4_TCP] =
60 : : RTE_ETH_RSS_NONFRAG_IPV4_TCP,
61 : : [IDPF_HASH_NONF_IPV4_SCTP] =
62 : : RTE_ETH_RSS_NONFRAG_IPV4_SCTP,
63 : : [IDPF_HASH_NONF_IPV4_OTHER] =
64 : : RTE_ETH_RSS_NONFRAG_IPV4_OTHER,
65 : : [IDPF_HASH_FRAG_IPV4] = RTE_ETH_RSS_FRAG_IPV4,
66 : :
67 : : /* IPv6 */
68 : : [IDPF_HASH_NONF_UNICAST_IPV6_UDP] =
69 : : RTE_ETH_RSS_NONFRAG_IPV6_UDP,
70 : : [IDPF_HASH_NONF_MULTICAST_IPV6_UDP] =
71 : : RTE_ETH_RSS_NONFRAG_IPV6_UDP,
72 : : [IDPF_HASH_NONF_IPV6_UDP] =
73 : : RTE_ETH_RSS_NONFRAG_IPV6_UDP,
74 : : [IDPF_HASH_NONF_IPV6_TCP_SYN_NO_ACK] =
75 : : RTE_ETH_RSS_NONFRAG_IPV6_TCP,
76 : : [IDPF_HASH_NONF_IPV6_TCP] =
77 : : RTE_ETH_RSS_NONFRAG_IPV6_TCP,
78 : : [IDPF_HASH_NONF_IPV6_SCTP] =
79 : : RTE_ETH_RSS_NONFRAG_IPV6_SCTP,
80 : : [IDPF_HASH_NONF_IPV6_OTHER] =
81 : : RTE_ETH_RSS_NONFRAG_IPV6_OTHER,
82 : : [IDPF_HASH_FRAG_IPV6] = RTE_ETH_RSS_FRAG_IPV6,
83 : :
84 : : /* L2 Payload */
85 : : [IDPF_HASH_L2_PAYLOAD] = RTE_ETH_RSS_L2_PAYLOAD
86 : : };
87 : :
88 : : static const uint64_t idpf_ipv4_rss = RTE_ETH_RSS_NONFRAG_IPV4_UDP |
89 : : RTE_ETH_RSS_NONFRAG_IPV4_TCP |
90 : : RTE_ETH_RSS_NONFRAG_IPV4_SCTP |
91 : : RTE_ETH_RSS_NONFRAG_IPV4_OTHER |
92 : : RTE_ETH_RSS_FRAG_IPV4;
93 : :
94 : : static const uint64_t idpf_ipv6_rss = RTE_ETH_RSS_NONFRAG_IPV6_UDP |
95 : : RTE_ETH_RSS_NONFRAG_IPV6_TCP |
96 : : RTE_ETH_RSS_NONFRAG_IPV6_SCTP |
97 : : RTE_ETH_RSS_NONFRAG_IPV6_OTHER |
98 : : RTE_ETH_RSS_FRAG_IPV6;
99 : :
100 : : struct rte_idpf_xstats_name_off {
101 : : char name[RTE_ETH_XSTATS_NAME_SIZE];
102 : : unsigned int offset;
103 : : };
104 : :
105 : : static const struct rte_idpf_xstats_name_off rte_idpf_stats_strings[] = {
106 : : {"rx_bytes", offsetof(struct virtchnl2_vport_stats, rx_bytes)},
107 : : {"rx_unicast_packets", offsetof(struct virtchnl2_vport_stats, rx_unicast)},
108 : : {"rx_multicast_packets", offsetof(struct virtchnl2_vport_stats, rx_multicast)},
109 : : {"rx_broadcast_packets", offsetof(struct virtchnl2_vport_stats, rx_broadcast)},
110 : : {"rx_dropped_packets", offsetof(struct virtchnl2_vport_stats, rx_discards)},
111 : : {"rx_errors", offsetof(struct virtchnl2_vport_stats, rx_errors)},
112 : : {"rx_unknown_protocol_packets", offsetof(struct virtchnl2_vport_stats,
113 : : rx_unknown_protocol)},
114 : : {"tx_bytes", offsetof(struct virtchnl2_vport_stats, tx_bytes)},
115 : : {"tx_unicast_packets", offsetof(struct virtchnl2_vport_stats, tx_unicast)},
116 : : {"tx_multicast_packets", offsetof(struct virtchnl2_vport_stats, tx_multicast)},
117 : : {"tx_broadcast_packets", offsetof(struct virtchnl2_vport_stats, tx_broadcast)},
118 : : {"tx_dropped_packets", offsetof(struct virtchnl2_vport_stats, tx_discards)},
119 : : {"tx_error_packets", offsetof(struct virtchnl2_vport_stats, tx_errors)}};
120 : :
121 : : #define IDPF_NB_XSTATS (sizeof(rte_idpf_stats_strings) / \
122 : : sizeof(rte_idpf_stats_strings[0]))
123 : :
124 : : static int
125 : 0 : idpf_dev_link_update(struct rte_eth_dev *dev,
126 : : __rte_unused int wait_to_complete)
127 : : {
128 [ # # ]: 0 : struct idpf_vport *vport = dev->data->dev_private;
129 : : struct rte_eth_link new_link;
130 : : unsigned int i;
131 : :
132 : : memset(&new_link, 0, sizeof(new_link));
133 : :
134 : : /* initialize with default value */
135 [ # # ]: 0 : new_link.link_speed = vport->link_up ? RTE_ETH_SPEED_NUM_UNKNOWN : RTE_ETH_SPEED_NUM_NONE;
136 : :
137 : : /* update in case a match */
138 [ # # ]: 0 : for (i = 0; i < RTE_DIM(idpf_supported_speeds); i++) {
139 [ # # ]: 0 : if (vport->link_speed == idpf_supported_speeds[i]) {
140 : 0 : new_link.link_speed = vport->link_speed;
141 : 0 : break;
142 : : }
143 : : }
144 : :
145 : 0 : new_link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
146 : 0 : new_link.link_status = vport->link_up ? RTE_ETH_LINK_UP : RTE_ETH_LINK_DOWN;
147 : 0 : new_link.link_autoneg = (dev->data->dev_conf.link_speeds & RTE_ETH_LINK_SPEED_FIXED) ?
148 [ # # ]: 0 : RTE_ETH_LINK_FIXED : RTE_ETH_LINK_AUTONEG;
149 : :
150 : 0 : return rte_eth_linkstatus_set(dev, &new_link);
151 : : }
152 : :
153 : : static int
154 : 0 : idpf_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
155 : : {
156 : 0 : struct idpf_vport *vport = dev->data->dev_private;
157 : 0 : struct idpf_adapter *adapter = vport->adapter;
158 : :
159 : 0 : dev_info->max_rx_queues = adapter->caps.max_rx_q;
160 : 0 : dev_info->max_tx_queues = adapter->caps.max_tx_q;
161 : 0 : dev_info->min_rx_bufsize = IDPF_MIN_BUF_SIZE;
162 : 0 : dev_info->max_rx_pktlen = vport->max_mtu + IDPF_ETH_OVERHEAD;
163 : :
164 : 0 : dev_info->max_mtu = vport->max_mtu;
165 : 0 : dev_info->min_mtu = RTE_ETHER_MIN_MTU;
166 : :
167 : 0 : dev_info->hash_key_size = vport->rss_key_size;
168 : 0 : dev_info->reta_size = vport->rss_lut_size;
169 : :
170 : 0 : dev_info->flow_type_rss_offloads = IDPF_RSS_OFFLOAD_ALL;
171 : :
172 : 0 : dev_info->rx_offload_capa =
173 : : RTE_ETH_RX_OFFLOAD_IPV4_CKSUM |
174 : : RTE_ETH_RX_OFFLOAD_UDP_CKSUM |
175 : : RTE_ETH_RX_OFFLOAD_TCP_CKSUM |
176 : : RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM |
177 : : RTE_ETH_RX_OFFLOAD_TIMESTAMP |
178 : : RTE_ETH_RX_OFFLOAD_SCATTER;
179 : :
180 : 0 : dev_info->tx_offload_capa =
181 : : RTE_ETH_TX_OFFLOAD_IPV4_CKSUM |
182 : : RTE_ETH_TX_OFFLOAD_UDP_CKSUM |
183 : : RTE_ETH_TX_OFFLOAD_TCP_CKSUM |
184 : : RTE_ETH_TX_OFFLOAD_SCTP_CKSUM |
185 : : RTE_ETH_TX_OFFLOAD_TCP_TSO |
186 : : RTE_ETH_TX_OFFLOAD_MULTI_SEGS |
187 : : RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE;
188 : :
189 : 0 : dev_info->default_txconf = (struct rte_eth_txconf) {
190 : : .tx_free_thresh = IDPF_DEFAULT_TX_FREE_THRESH,
191 : : .tx_rs_thresh = IDPF_DEFAULT_TX_RS_THRESH,
192 : : };
193 : :
194 : 0 : dev_info->default_rxconf = (struct rte_eth_rxconf) {
195 : : .rx_free_thresh = IDPF_DEFAULT_RX_FREE_THRESH,
196 : : };
197 : :
198 : 0 : dev_info->tx_desc_lim = (struct rte_eth_desc_lim) {
199 : : .nb_max = IDPF_MAX_RING_DESC,
200 : : .nb_min = IDPF_MIN_RING_DESC,
201 : : .nb_align = IDPF_ALIGN_RING_DESC,
202 : : };
203 : :
204 : 0 : dev_info->rx_desc_lim = (struct rte_eth_desc_lim) {
205 : : .nb_max = IDPF_MAX_RING_DESC,
206 : : .nb_min = IDPF_MIN_RING_DESC,
207 : : .nb_align = IDPF_ALIGN_RING_DESC,
208 : : };
209 : :
210 : 0 : return 0;
211 : : }
212 : :
213 : : static int
214 : 0 : idpf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
215 : : {
216 : 0 : struct idpf_vport *vport = dev->data->dev_private;
217 : :
218 : : /* mtu setting is forbidden if port is start */
219 [ # # ]: 0 : if (dev->data->dev_started) {
220 : 0 : PMD_DRV_LOG(ERR, "port must be stopped before configuration");
221 : 0 : return -EBUSY;
222 : : }
223 : :
224 [ # # ]: 0 : if (mtu > vport->max_mtu) {
225 : 0 : PMD_DRV_LOG(ERR, "MTU should be less than %d", vport->max_mtu);
226 : 0 : return -EINVAL;
227 : : }
228 : :
229 : 0 : vport->max_pkt_len = mtu + IDPF_ETH_OVERHEAD;
230 : :
231 : 0 : return 0;
232 : : }
233 : :
234 : : static const uint32_t *
235 : 0 : idpf_dev_supported_ptypes_get(struct rte_eth_dev *dev __rte_unused,
236 : : size_t *no_of_elements)
237 : : {
238 : : static const uint32_t ptypes[] = {
239 : : RTE_PTYPE_L2_ETHER,
240 : : RTE_PTYPE_L3_IPV4_EXT_UNKNOWN,
241 : : RTE_PTYPE_L3_IPV6_EXT_UNKNOWN,
242 : : RTE_PTYPE_L4_FRAG,
243 : : RTE_PTYPE_L4_UDP,
244 : : RTE_PTYPE_L4_TCP,
245 : : RTE_PTYPE_L4_SCTP,
246 : : RTE_PTYPE_L4_ICMP,
247 : : };
248 : :
249 : 0 : *no_of_elements = RTE_DIM(ptypes);
250 : 0 : return ptypes;
251 : : }
252 : :
253 : : static uint64_t
254 : 0 : idpf_get_mbuf_alloc_failed_stats(struct rte_eth_dev *dev)
255 : : {
256 : : uint64_t mbuf_alloc_failed = 0;
257 : : struct idpf_rx_queue *rxq;
258 : : int i = 0;
259 : :
260 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++) {
261 : 0 : rxq = dev->data->rx_queues[i];
262 : 0 : mbuf_alloc_failed += rte_atomic_load_explicit(&rxq->rx_stats.mbuf_alloc_failed,
263 : : rte_memory_order_relaxed);
264 : : }
265 : :
266 : 0 : return mbuf_alloc_failed;
267 : : }
268 : :
269 : : static int
270 : 0 : idpf_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
271 : : {
272 : 0 : struct idpf_vport *vport =
273 : 0 : (struct idpf_vport *)dev->data->dev_private;
274 : 0 : struct virtchnl2_vport_stats *pstats = NULL;
275 : : int ret;
276 : :
277 : 0 : ret = idpf_vc_stats_query(vport, &pstats);
278 [ # # ]: 0 : if (ret == 0) {
279 [ # # ]: 0 : uint8_t crc_stats_len = (dev->data->dev_conf.rxmode.offloads &
280 : : RTE_ETH_RX_OFFLOAD_KEEP_CRC) ? 0 :
281 : : RTE_ETHER_CRC_LEN;
282 : :
283 : 0 : idpf_vport_stats_update(&vport->eth_stats_offset, pstats);
284 : 0 : stats->ipackets = pstats->rx_unicast + pstats->rx_multicast +
285 : 0 : pstats->rx_broadcast;
286 : 0 : stats->opackets = pstats->tx_broadcast + pstats->tx_multicast +
287 : 0 : pstats->tx_unicast;
288 : 0 : stats->ierrors = pstats->rx_errors;
289 : 0 : stats->imissed = pstats->rx_discards;
290 : 0 : stats->oerrors = pstats->tx_errors + pstats->tx_discards;
291 : 0 : stats->ibytes = pstats->rx_bytes;
292 : 0 : stats->ibytes -= stats->ipackets * crc_stats_len;
293 : 0 : stats->obytes = pstats->tx_bytes;
294 : :
295 : 0 : dev->data->rx_mbuf_alloc_failed = idpf_get_mbuf_alloc_failed_stats(dev);
296 : 0 : stats->rx_nombuf = dev->data->rx_mbuf_alloc_failed;
297 : : } else {
298 : 0 : PMD_DRV_LOG(ERR, "Get statistics failed");
299 : : }
300 : 0 : return ret;
301 : : }
302 : :
303 : : static void
304 : 0 : idpf_reset_mbuf_alloc_failed_stats(struct rte_eth_dev *dev)
305 : : {
306 : : struct idpf_rx_queue *rxq;
307 : : int i;
308 : :
309 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++) {
310 : 0 : rxq = dev->data->rx_queues[i];
311 : 0 : rte_atomic_store_explicit(&rxq->rx_stats.mbuf_alloc_failed, 0,
312 : : rte_memory_order_relaxed);
313 : : }
314 : 0 : }
315 : :
316 : : static int
317 : 0 : idpf_dev_stats_reset(struct rte_eth_dev *dev)
318 : : {
319 : 0 : struct idpf_vport *vport =
320 : 0 : (struct idpf_vport *)dev->data->dev_private;
321 : 0 : struct virtchnl2_vport_stats *pstats = NULL;
322 : : int ret;
323 : :
324 : 0 : ret = idpf_vc_stats_query(vport, &pstats);
325 [ # # ]: 0 : if (ret != 0)
326 : : return ret;
327 : :
328 : : /* set stats offset base on current values */
329 : 0 : vport->eth_stats_offset = *pstats;
330 : :
331 : 0 : idpf_reset_mbuf_alloc_failed_stats(dev);
332 : :
333 : 0 : return 0;
334 : : }
335 : :
336 : 0 : static int idpf_dev_xstats_reset(struct rte_eth_dev *dev)
337 : : {
338 : 0 : idpf_dev_stats_reset(dev);
339 : 0 : return 0;
340 : : }
341 : :
342 : 0 : static int idpf_dev_xstats_get(struct rte_eth_dev *dev,
343 : : struct rte_eth_xstat *xstats, unsigned int n)
344 : : {
345 : 0 : struct idpf_vport *vport =
346 : 0 : (struct idpf_vport *)dev->data->dev_private;
347 : 0 : struct virtchnl2_vport_stats *pstats = NULL;
348 : : unsigned int i;
349 : : int ret;
350 : :
351 [ # # ]: 0 : if (n < IDPF_NB_XSTATS)
352 : : return IDPF_NB_XSTATS;
353 : :
354 [ # # ]: 0 : if (!xstats)
355 : : return 0;
356 : :
357 : 0 : ret = idpf_vc_stats_query(vport, &pstats);
358 [ # # ]: 0 : if (ret) {
359 : 0 : PMD_DRV_LOG(ERR, "Get statistics failed");
360 : 0 : return 0;
361 : : }
362 : :
363 : 0 : idpf_vport_stats_update(&vport->eth_stats_offset, pstats);
364 : :
365 : : /* loop over xstats array and values from pstats */
366 [ # # ]: 0 : for (i = 0; i < IDPF_NB_XSTATS; i++) {
367 : 0 : xstats[i].id = i;
368 : 0 : xstats[i].value = *(uint64_t *)(((char *)pstats) +
369 : 0 : rte_idpf_stats_strings[i].offset);
370 : : }
371 : : return IDPF_NB_XSTATS;
372 : : }
373 : :
374 : 0 : static int idpf_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
375 : : struct rte_eth_xstat_name *xstats_names,
376 : : __rte_unused unsigned int limit)
377 : : {
378 : : unsigned int i;
379 : :
380 [ # # ]: 0 : if (xstats_names)
381 [ # # ]: 0 : for (i = 0; i < IDPF_NB_XSTATS; i++) {
382 : 0 : snprintf(xstats_names[i].name,
383 : : sizeof(xstats_names[i].name),
384 : 0 : "%s", rte_idpf_stats_strings[i].name);
385 : : }
386 : 0 : return IDPF_NB_XSTATS;
387 : : }
388 : :
389 : 0 : static int idpf_config_rss_hf(struct idpf_vport *vport, uint64_t rss_hf)
390 : : {
391 : : uint64_t hena = 0;
392 : : uint16_t i;
393 : :
394 : : /**
395 : : * RTE_ETH_RSS_IPV4 and RTE_ETH_RSS_IPV6 can be considered as 2
396 : : * generalizations of all other IPv4 and IPv6 RSS types.
397 : : */
398 [ # # ]: 0 : if (rss_hf & RTE_ETH_RSS_IPV4)
399 : 0 : rss_hf |= idpf_ipv4_rss;
400 : :
401 [ # # ]: 0 : if (rss_hf & RTE_ETH_RSS_IPV6)
402 : 0 : rss_hf |= idpf_ipv6_rss;
403 : :
404 [ # # ]: 0 : for (i = 0; i < RTE_DIM(idpf_map_hena_rss); i++) {
405 [ # # ]: 0 : if (idpf_map_hena_rss[i] & rss_hf)
406 : 0 : hena |= BIT_ULL(i);
407 : : }
408 : :
409 : : /**
410 : : * At present, cp doesn't process the virtual channel msg of rss_hf configuration,
411 : : * tips are given below.
412 : : */
413 [ # # ]: 0 : if (hena != vport->rss_hf)
414 : 0 : PMD_DRV_LOG(WARNING, "Updating RSS Hash Function is not supported at present.");
415 : :
416 : 0 : return 0;
417 : : }
418 : :
419 : : static int
420 : 0 : idpf_init_rss(struct idpf_vport *vport)
421 : : {
422 : : struct rte_eth_rss_conf *rss_conf;
423 : : struct rte_eth_dev_data *dev_data;
424 : : uint16_t i, nb_q;
425 : : int ret = 0;
426 : :
427 : 0 : dev_data = vport->dev_data;
428 : : rss_conf = &dev_data->dev_conf.rx_adv_conf.rss_conf;
429 : 0 : nb_q = dev_data->nb_rx_queues;
430 : :
431 [ # # ]: 0 : if (rss_conf->rss_key == NULL) {
432 [ # # ]: 0 : for (i = 0; i < vport->rss_key_size; i++)
433 : 0 : vport->rss_key[i] = (uint8_t)rte_rand();
434 [ # # ]: 0 : } else if (rss_conf->rss_key_len != vport->rss_key_size) {
435 : 0 : PMD_INIT_LOG(ERR, "Invalid RSS key length in RSS configuration, should be %d",
436 : : vport->rss_key_size);
437 : 0 : return -EINVAL;
438 : : } else {
439 [ # # ]: 0 : rte_memcpy(vport->rss_key, rss_conf->rss_key,
440 : : vport->rss_key_size);
441 : : }
442 : :
443 [ # # ]: 0 : for (i = 0; i < vport->rss_lut_size; i++)
444 : 0 : vport->rss_lut[i] = i % nb_q;
445 : :
446 : 0 : vport->rss_hf = IDPF_DEFAULT_RSS_HASH_EXPANDED;
447 : :
448 : 0 : ret = idpf_vport_rss_config(vport);
449 [ # # ]: 0 : if (ret != 0)
450 : 0 : PMD_INIT_LOG(ERR, "Failed to configure RSS");
451 : :
452 : : return ret;
453 : : }
454 : :
455 : : static int
456 : 0 : idpf_rss_reta_update(struct rte_eth_dev *dev,
457 : : struct rte_eth_rss_reta_entry64 *reta_conf,
458 : : uint16_t reta_size)
459 : : {
460 : 0 : struct idpf_vport *vport = dev->data->dev_private;
461 : 0 : struct idpf_adapter *adapter = vport->adapter;
462 : : uint16_t idx, shift;
463 : : int ret = 0;
464 : : uint16_t i;
465 : :
466 [ # # # # ]: 0 : if (adapter->caps.rss_caps == 0 || dev->data->nb_rx_queues == 0) {
467 : 0 : PMD_DRV_LOG(DEBUG, "RSS is not supported");
468 : 0 : return -ENOTSUP;
469 : : }
470 : :
471 [ # # ]: 0 : if (reta_size != vport->rss_lut_size) {
472 : 0 : PMD_DRV_LOG(ERR, "The size of hash lookup table configured "
473 : : "(%d) doesn't match the number of hardware can "
474 : : "support (%d)",
475 : : reta_size, vport->rss_lut_size);
476 : 0 : return -EINVAL;
477 : : }
478 : :
479 [ # # ]: 0 : for (i = 0; i < reta_size; i++) {
480 : 0 : idx = i / RTE_ETH_RETA_GROUP_SIZE;
481 : 0 : shift = i % RTE_ETH_RETA_GROUP_SIZE;
482 [ # # ]: 0 : if (reta_conf[idx].mask & (1ULL << shift))
483 : 0 : vport->rss_lut[i] = reta_conf[idx].reta[shift];
484 : : }
485 : :
486 : : /* send virtchnl ops to configure RSS */
487 : 0 : ret = idpf_vc_rss_lut_set(vport);
488 [ # # ]: 0 : if (ret)
489 : 0 : PMD_INIT_LOG(ERR, "Failed to configure RSS lut");
490 : :
491 : : return ret;
492 : : }
493 : :
494 : : static int
495 : 0 : idpf_rss_reta_query(struct rte_eth_dev *dev,
496 : : struct rte_eth_rss_reta_entry64 *reta_conf,
497 : : uint16_t reta_size)
498 : : {
499 : 0 : struct idpf_vport *vport = dev->data->dev_private;
500 : 0 : struct idpf_adapter *adapter = vport->adapter;
501 : : uint16_t idx, shift;
502 : : int ret = 0;
503 : : uint16_t i;
504 : :
505 [ # # # # ]: 0 : if (adapter->caps.rss_caps == 0 || dev->data->nb_rx_queues == 0) {
506 : 0 : PMD_DRV_LOG(DEBUG, "RSS is not supported");
507 : 0 : return -ENOTSUP;
508 : : }
509 : :
510 [ # # ]: 0 : if (reta_size != vport->rss_lut_size) {
511 : 0 : PMD_DRV_LOG(ERR, "The size of hash lookup table configured "
512 : : "(%d) doesn't match the number of hardware can "
513 : : "support (%d)", reta_size, vport->rss_lut_size);
514 : 0 : return -EINVAL;
515 : : }
516 : :
517 : 0 : ret = idpf_vc_rss_lut_get(vport);
518 [ # # ]: 0 : if (ret) {
519 : 0 : PMD_DRV_LOG(ERR, "Failed to get RSS LUT");
520 : 0 : return ret;
521 : : }
522 : :
523 [ # # ]: 0 : for (i = 0; i < reta_size; i++) {
524 : 0 : idx = i / RTE_ETH_RETA_GROUP_SIZE;
525 : 0 : shift = i % RTE_ETH_RETA_GROUP_SIZE;
526 [ # # ]: 0 : if (reta_conf[idx].mask & (1ULL << shift))
527 : 0 : reta_conf[idx].reta[shift] = vport->rss_lut[i];
528 : : }
529 : :
530 : : return 0;
531 : : }
532 : :
533 : : static int
534 : 0 : idpf_rss_hash_update(struct rte_eth_dev *dev,
535 : : struct rte_eth_rss_conf *rss_conf)
536 : : {
537 : 0 : struct idpf_vport *vport = dev->data->dev_private;
538 : 0 : struct idpf_adapter *adapter = vport->adapter;
539 : : int ret = 0;
540 : :
541 [ # # # # ]: 0 : if (adapter->caps.rss_caps == 0 || dev->data->nb_rx_queues == 0) {
542 : 0 : PMD_DRV_LOG(DEBUG, "RSS is not supported");
543 : 0 : return -ENOTSUP;
544 : : }
545 : :
546 [ # # # # ]: 0 : if (!rss_conf->rss_key || rss_conf->rss_key_len == 0) {
547 : 0 : PMD_DRV_LOG(DEBUG, "No key to be configured");
548 : 0 : goto skip_rss_key;
549 [ # # ]: 0 : } else if (rss_conf->rss_key_len != vport->rss_key_size) {
550 : 0 : PMD_DRV_LOG(ERR, "The size of hash key configured "
551 : : "(%d) doesn't match the size of hardware can "
552 : : "support (%d)",
553 : : rss_conf->rss_key_len,
554 : : vport->rss_key_size);
555 : 0 : return -EINVAL;
556 : : }
557 : :
558 [ # # ]: 0 : rte_memcpy(vport->rss_key, rss_conf->rss_key,
559 : : vport->rss_key_size);
560 : 0 : ret = idpf_vc_rss_key_set(vport);
561 [ # # ]: 0 : if (ret != 0) {
562 : 0 : PMD_INIT_LOG(ERR, "Failed to configure RSS key");
563 : 0 : return ret;
564 : : }
565 : :
566 : 0 : skip_rss_key:
567 : 0 : ret = idpf_config_rss_hf(vport, rss_conf->rss_hf);
568 [ # # ]: 0 : if (ret != 0) {
569 : 0 : PMD_INIT_LOG(ERR, "Failed to configure RSS hash");
570 : 0 : return ret;
571 : : }
572 : :
573 : : return 0;
574 : : }
575 : :
576 : : static uint64_t
577 : 0 : idpf_map_general_rss_hf(uint64_t config_rss_hf, uint64_t last_general_rss_hf)
578 : : {
579 : : uint64_t valid_rss_hf = 0;
580 : : uint16_t i;
581 : :
582 [ # # ]: 0 : for (i = 0; i < RTE_DIM(idpf_map_hena_rss); i++) {
583 : 0 : uint64_t bit = BIT_ULL(i);
584 : :
585 [ # # ]: 0 : if (bit & config_rss_hf)
586 : 0 : valid_rss_hf |= idpf_map_hena_rss[i];
587 : : }
588 : :
589 [ # # ]: 0 : if (valid_rss_hf & idpf_ipv4_rss)
590 : 0 : valid_rss_hf |= last_general_rss_hf & RTE_ETH_RSS_IPV4;
591 : :
592 [ # # ]: 0 : if (valid_rss_hf & idpf_ipv6_rss)
593 : 0 : valid_rss_hf |= last_general_rss_hf & RTE_ETH_RSS_IPV6;
594 : :
595 : 0 : return valid_rss_hf;
596 : : }
597 : :
598 : : static int
599 : 0 : idpf_rss_hash_conf_get(struct rte_eth_dev *dev,
600 : : struct rte_eth_rss_conf *rss_conf)
601 : : {
602 : 0 : struct idpf_vport *vport = dev->data->dev_private;
603 : 0 : struct idpf_adapter *adapter = vport->adapter;
604 : : int ret = 0;
605 : :
606 [ # # # # ]: 0 : if (adapter->caps.rss_caps == 0 || dev->data->nb_rx_queues == 0) {
607 : 0 : PMD_DRV_LOG(DEBUG, "RSS is not supported");
608 : 0 : return -ENOTSUP;
609 : : }
610 : :
611 : 0 : ret = idpf_vc_rss_hash_get(vport);
612 [ # # ]: 0 : if (ret) {
613 : 0 : PMD_DRV_LOG(ERR, "Failed to get RSS hf");
614 : 0 : return ret;
615 : : }
616 : :
617 : 0 : rss_conf->rss_hf = idpf_map_general_rss_hf(vport->rss_hf, vport->last_general_rss_hf);
618 : :
619 [ # # ]: 0 : if (!rss_conf->rss_key)
620 : : return 0;
621 : :
622 : 0 : ret = idpf_vc_rss_key_get(vport);
623 [ # # ]: 0 : if (ret) {
624 : 0 : PMD_DRV_LOG(ERR, "Failed to get RSS key");
625 : 0 : return ret;
626 : : }
627 : :
628 [ # # ]: 0 : if (rss_conf->rss_key_len > vport->rss_key_size)
629 : 0 : rss_conf->rss_key_len = vport->rss_key_size;
630 : :
631 [ # # ]: 0 : rte_memcpy(rss_conf->rss_key, vport->rss_key, rss_conf->rss_key_len);
632 : :
633 : : return 0;
634 : : }
635 : :
636 : : static int
637 : 0 : idpf_dev_configure(struct rte_eth_dev *dev)
638 : : {
639 : 0 : struct idpf_vport *vport = dev->data->dev_private;
640 : : struct rte_eth_conf *conf = &dev->data->dev_conf;
641 : 0 : struct idpf_adapter *adapter = vport->adapter;
642 : : int ret;
643 : :
644 [ # # ]: 0 : if (conf->link_speeds & RTE_ETH_LINK_SPEED_FIXED) {
645 : 0 : PMD_INIT_LOG(ERR, "Setting link speed is not supported");
646 : 0 : return -ENOTSUP;
647 : : }
648 : :
649 [ # # ]: 0 : if (conf->txmode.mq_mode != RTE_ETH_MQ_TX_NONE) {
650 : 0 : PMD_INIT_LOG(ERR, "Multi-queue TX mode %d is not supported",
651 : : conf->txmode.mq_mode);
652 : 0 : return -ENOTSUP;
653 : : }
654 : :
655 [ # # ]: 0 : if (conf->lpbk_mode != 0) {
656 : 0 : PMD_INIT_LOG(ERR, "Loopback operation mode %d is not supported",
657 : : conf->lpbk_mode);
658 : 0 : return -ENOTSUP;
659 : : }
660 : :
661 [ # # ]: 0 : if (conf->dcb_capability_en != 0) {
662 : 0 : PMD_INIT_LOG(ERR, "Priority Flow Control(PFC) if not supported");
663 : 0 : return -ENOTSUP;
664 : : }
665 : :
666 [ # # ]: 0 : if (conf->intr_conf.lsc != 0) {
667 : 0 : PMD_INIT_LOG(ERR, "LSC interrupt is not supported");
668 : 0 : return -ENOTSUP;
669 : : }
670 : :
671 [ # # ]: 0 : if (conf->intr_conf.rxq != 0) {
672 : 0 : PMD_INIT_LOG(ERR, "RXQ interrupt is not supported");
673 : 0 : return -ENOTSUP;
674 : : }
675 : :
676 [ # # ]: 0 : if (conf->intr_conf.rmv != 0) {
677 : 0 : PMD_INIT_LOG(ERR, "RMV interrupt is not supported");
678 : 0 : return -ENOTSUP;
679 : : }
680 : :
681 [ # # # # ]: 0 : if (adapter->caps.rss_caps != 0 && dev->data->nb_rx_queues != 0) {
682 : 0 : ret = idpf_init_rss(vport);
683 [ # # ]: 0 : if (ret != 0) {
684 : 0 : PMD_INIT_LOG(ERR, "Failed to init rss");
685 : 0 : return ret;
686 : : }
687 : : } else {
688 : 0 : PMD_INIT_LOG(ERR, "RSS is not supported.");
689 : 0 : return -1;
690 : : }
691 : :
692 : 0 : vport->max_pkt_len =
693 [ # # ]: 0 : (dev->data->mtu == 0) ? IDPF_DEFAULT_MTU : dev->data->mtu +
694 : : IDPF_ETH_OVERHEAD;
695 : :
696 : 0 : return 0;
697 : : }
698 : :
699 : : static int
700 : : idpf_config_rx_queues_irqs(struct rte_eth_dev *dev)
701 : : {
702 : 0 : struct idpf_vport *vport = dev->data->dev_private;
703 : 0 : uint16_t nb_rx_queues = dev->data->nb_rx_queues;
704 : :
705 : 0 : return idpf_vport_irq_map_config(vport, nb_rx_queues);
706 : : }
707 : :
708 : : static int
709 : 0 : idpf_start_queues(struct rte_eth_dev *dev)
710 : : {
711 : : struct idpf_rx_queue *rxq;
712 : : struct idpf_tx_queue *txq;
713 : : int err = 0;
714 : : int i;
715 : :
716 [ # # ]: 0 : for (i = 0; i < dev->data->nb_tx_queues; i++) {
717 : 0 : txq = dev->data->tx_queues[i];
718 [ # # # # ]: 0 : if (txq == NULL || txq->tx_deferred_start)
719 : 0 : continue;
720 : 0 : err = idpf_tx_queue_start(dev, i);
721 [ # # ]: 0 : if (err != 0) {
722 : 0 : PMD_DRV_LOG(ERR, "Fail to start Tx queue %u", i);
723 : 0 : return err;
724 : : }
725 : : }
726 : :
727 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++) {
728 : 0 : rxq = dev->data->rx_queues[i];
729 [ # # # # ]: 0 : if (rxq == NULL || rxq->rx_deferred_start)
730 : 0 : continue;
731 : 0 : err = idpf_rx_queue_start(dev, i);
732 [ # # ]: 0 : if (err != 0) {
733 : 0 : PMD_DRV_LOG(ERR, "Fail to start Rx queue %u", i);
734 : 0 : return err;
735 : : }
736 : : }
737 : :
738 : : return err;
739 : : }
740 : :
741 : : static int
742 : 0 : idpf_dev_start(struct rte_eth_dev *dev)
743 : : {
744 : 0 : struct idpf_vport *vport = dev->data->dev_private;
745 : 0 : struct idpf_adapter *base = vport->adapter;
746 : 0 : struct idpf_adapter_ext *adapter = IDPF_ADAPTER_TO_EXT(base);
747 : 0 : uint16_t num_allocated_vectors = base->caps.num_allocated_vectors;
748 : : uint16_t req_vecs_num;
749 : : int ret;
750 : :
751 : : req_vecs_num = IDPF_DFLT_Q_VEC_NUM;
752 [ # # ]: 0 : if (req_vecs_num + adapter->used_vecs_num > num_allocated_vectors) {
753 : 0 : PMD_DRV_LOG(ERR, "The accumulated request vectors' number should be less than %d",
754 : : num_allocated_vectors);
755 : : ret = -EINVAL;
756 : 0 : goto err_vec;
757 : : }
758 : :
759 : 0 : ret = idpf_vc_vectors_alloc(vport, req_vecs_num);
760 [ # # ]: 0 : if (ret != 0) {
761 : 0 : PMD_DRV_LOG(ERR, "Failed to allocate interrupt vectors");
762 : 0 : goto err_vec;
763 : : }
764 : 0 : adapter->used_vecs_num += req_vecs_num;
765 : :
766 : : ret = idpf_config_rx_queues_irqs(dev);
767 [ # # ]: 0 : if (ret != 0) {
768 : 0 : PMD_DRV_LOG(ERR, "Failed to configure irqs");
769 : 0 : goto err_irq;
770 : : }
771 : :
772 : 0 : ret = idpf_start_queues(dev);
773 [ # # ]: 0 : if (ret != 0) {
774 : 0 : PMD_DRV_LOG(ERR, "Failed to start queues");
775 : 0 : goto err_startq;
776 : : }
777 : :
778 : 0 : idpf_set_rx_function(dev);
779 : 0 : idpf_set_tx_function(dev);
780 : :
781 : 0 : ret = idpf_vc_vport_ena_dis(vport, true);
782 [ # # ]: 0 : if (ret != 0) {
783 : 0 : PMD_DRV_LOG(ERR, "Failed to enable vport");
784 : 0 : goto err_vport;
785 : : }
786 : :
787 [ # # ]: 0 : if (idpf_dev_stats_reset(dev))
788 : 0 : PMD_DRV_LOG(ERR, "Failed to reset stats");
789 : :
790 : : return 0;
791 : :
792 : : err_vport:
793 : 0 : idpf_stop_queues(dev);
794 : 0 : err_startq:
795 : 0 : idpf_vport_irq_unmap_config(vport, dev->data->nb_rx_queues);
796 : 0 : err_irq:
797 : 0 : idpf_vc_vectors_dealloc(vport);
798 : : err_vec:
799 : : return ret;
800 : : }
801 : :
802 : : static int
803 : 0 : idpf_dev_stop(struct rte_eth_dev *dev)
804 : : {
805 : 0 : struct idpf_vport *vport = dev->data->dev_private;
806 : :
807 [ # # ]: 0 : if (dev->data->dev_started == 0)
808 : : return 0;
809 : :
810 : 0 : idpf_vc_vport_ena_dis(vport, false);
811 : :
812 : 0 : idpf_stop_queues(dev);
813 : :
814 : 0 : idpf_vport_irq_unmap_config(vport, dev->data->nb_rx_queues);
815 : :
816 : 0 : idpf_vc_vectors_dealloc(vport);
817 : :
818 : 0 : return 0;
819 : : }
820 : :
821 : : static int
822 : 0 : idpf_dev_close(struct rte_eth_dev *dev)
823 : : {
824 : 0 : struct idpf_vport *vport = dev->data->dev_private;
825 : 0 : struct idpf_adapter_ext *adapter = IDPF_ADAPTER_TO_EXT(vport->adapter);
826 : :
827 : 0 : idpf_dev_stop(dev);
828 : :
829 : 0 : idpf_vport_deinit(vport);
830 : :
831 : 0 : adapter->cur_vports &= ~RTE_BIT32(vport->devarg_id);
832 : 0 : adapter->cur_vport_nb--;
833 : 0 : dev->data->dev_private = NULL;
834 : 0 : adapter->vports[vport->sw_idx] = NULL;
835 : 0 : rte_free(vport);
836 : :
837 : 0 : return 0;
838 : : }
839 : :
840 : : static const struct eth_dev_ops idpf_eth_dev_ops = {
841 : : .dev_configure = idpf_dev_configure,
842 : : .dev_close = idpf_dev_close,
843 : : .rx_queue_setup = idpf_rx_queue_setup,
844 : : .tx_queue_setup = idpf_tx_queue_setup,
845 : : .dev_infos_get = idpf_dev_info_get,
846 : : .dev_start = idpf_dev_start,
847 : : .dev_stop = idpf_dev_stop,
848 : : .link_update = idpf_dev_link_update,
849 : : .rx_queue_start = idpf_rx_queue_start,
850 : : .tx_queue_start = idpf_tx_queue_start,
851 : : .rx_queue_stop = idpf_rx_queue_stop,
852 : : .tx_queue_stop = idpf_tx_queue_stop,
853 : : .rx_queue_release = idpf_dev_rx_queue_release,
854 : : .tx_queue_release = idpf_dev_tx_queue_release,
855 : : .mtu_set = idpf_dev_mtu_set,
856 : : .dev_supported_ptypes_get = idpf_dev_supported_ptypes_get,
857 : : .stats_get = idpf_dev_stats_get,
858 : : .stats_reset = idpf_dev_stats_reset,
859 : : .reta_update = idpf_rss_reta_update,
860 : : .reta_query = idpf_rss_reta_query,
861 : : .rss_hash_update = idpf_rss_hash_update,
862 : : .rss_hash_conf_get = idpf_rss_hash_conf_get,
863 : : .xstats_get = idpf_dev_xstats_get,
864 : : .xstats_get_names = idpf_dev_xstats_get_names,
865 : : .xstats_reset = idpf_dev_xstats_reset,
866 : : };
867 : :
868 : : static int
869 : 0 : insert_value(struct idpf_devargs *devargs, uint16_t id)
870 : : {
871 : : uint16_t i;
872 : :
873 : : /* ignore duplicate */
874 [ # # ]: 0 : for (i = 0; i < devargs->req_vport_nb; i++) {
875 [ # # ]: 0 : if (devargs->req_vports[i] == id)
876 : : return 0;
877 : : }
878 : :
879 [ # # ]: 0 : if (devargs->req_vport_nb >= RTE_DIM(devargs->req_vports)) {
880 : 0 : PMD_INIT_LOG(ERR, "Total vport number can't be > %d",
881 : : IDPF_MAX_VPORT_NUM);
882 : 0 : return -EINVAL;
883 : : }
884 : :
885 : 0 : devargs->req_vports[devargs->req_vport_nb] = id;
886 : 0 : devargs->req_vport_nb++;
887 : :
888 : 0 : return 0;
889 : : }
890 : :
891 : : static const char *
892 : 0 : parse_range(const char *value, struct idpf_devargs *devargs)
893 : : {
894 : : uint16_t lo, hi, i;
895 : 0 : int n = 0;
896 : : int result;
897 : : const char *pos = value;
898 : :
899 : 0 : result = sscanf(value, "%hu%n-%hu%n", &lo, &n, &hi, &n);
900 [ # # ]: 0 : if (result == 1) {
901 [ # # ]: 0 : if (lo >= IDPF_MAX_VPORT_NUM)
902 : : return NULL;
903 [ # # ]: 0 : if (insert_value(devargs, lo) != 0)
904 : : return NULL;
905 [ # # ]: 0 : } else if (result == 2) {
906 [ # # # # ]: 0 : if (lo > hi || hi >= IDPF_MAX_VPORT_NUM)
907 : : return NULL;
908 [ # # ]: 0 : for (i = lo; i <= hi; i++) {
909 [ # # ]: 0 : if (insert_value(devargs, i) != 0)
910 : : return NULL;
911 : : }
912 : : } else {
913 : : return NULL;
914 : : }
915 : :
916 : 0 : return pos + n;
917 : : }
918 : :
919 : : static int
920 : 0 : parse_vport(const char *key, const char *value, void *args)
921 : : {
922 : : struct idpf_devargs *devargs = args;
923 : : const char *pos = value;
924 : :
925 : 0 : devargs->req_vport_nb = 0;
926 : :
927 [ # # ]: 0 : if (*pos == '[')
928 : 0 : pos++;
929 : :
930 : : while (1) {
931 : 0 : pos = parse_range(pos, devargs);
932 [ # # ]: 0 : if (pos == NULL) {
933 : 0 : PMD_INIT_LOG(ERR, "invalid value:\"%s\" for key:\"%s\", ",
934 : : value, key);
935 : 0 : return -EINVAL;
936 : : }
937 [ # # ]: 0 : if (*pos != ',')
938 : : break;
939 : 0 : pos++;
940 : : }
941 : :
942 [ # # # # ]: 0 : if (*value == '[' && *pos != ']') {
943 : 0 : PMD_INIT_LOG(ERR, "invalid value:\"%s\" for key:\"%s\", ",
944 : : value, key);
945 : 0 : return -EINVAL;
946 : : }
947 : :
948 : : return 0;
949 : : }
950 : :
951 : : static int
952 : 0 : parse_bool(const char *key, const char *value, void *args)
953 : : {
954 : : int *i = args;
955 : : char *end;
956 : : int num;
957 : :
958 : 0 : errno = 0;
959 : :
960 : 0 : num = strtoul(value, &end, 10);
961 : :
962 [ # # # # ]: 0 : if (errno == ERANGE || (num != 0 && num != 1)) {
963 : 0 : PMD_INIT_LOG(ERR, "invalid value:\"%s\" for key:\"%s\", value must be 0 or 1",
964 : : value, key);
965 : 0 : return -EINVAL;
966 : : }
967 : :
968 : 0 : *i = num;
969 : 0 : return 0;
970 : : }
971 : :
972 : : static int
973 : 0 : idpf_parse_devargs(struct rte_pci_device *pci_dev, struct idpf_adapter_ext *adapter,
974 : : struct idpf_devargs *idpf_args)
975 : : {
976 : 0 : struct rte_devargs *devargs = pci_dev->device.devargs;
977 : : struct rte_kvargs *kvlist;
978 : : int i, ret;
979 : :
980 : 0 : idpf_args->req_vport_nb = 0;
981 : :
982 [ # # ]: 0 : if (devargs == NULL)
983 : : return 0;
984 : :
985 : 0 : kvlist = rte_kvargs_parse(devargs->args, idpf_valid_args);
986 [ # # ]: 0 : if (kvlist == NULL) {
987 : 0 : PMD_INIT_LOG(ERR, "invalid kvargs key");
988 : 0 : return -EINVAL;
989 : : }
990 : :
991 : : /* check parsed devargs */
992 [ # # ]: 0 : if (adapter->cur_vport_nb + idpf_args->req_vport_nb >
993 : : IDPF_MAX_VPORT_NUM) {
994 : 0 : PMD_INIT_LOG(ERR, "Total vport number can't be > %d",
995 : : IDPF_MAX_VPORT_NUM);
996 : : ret = -EINVAL;
997 : 0 : goto bail;
998 : : }
999 : :
1000 [ # # ]: 0 : for (i = 0; i < idpf_args->req_vport_nb; i++) {
1001 [ # # ]: 0 : if (adapter->cur_vports & RTE_BIT32(idpf_args->req_vports[i])) {
1002 : 0 : PMD_INIT_LOG(ERR, "Vport %d has been created",
1003 : : idpf_args->req_vports[i]);
1004 : : ret = -EINVAL;
1005 : 0 : goto bail;
1006 : : }
1007 : : }
1008 : :
1009 : 0 : ret = rte_kvargs_process(kvlist, IDPF_VPORT, &parse_vport,
1010 : : idpf_args);
1011 [ # # ]: 0 : if (ret != 0)
1012 : 0 : goto bail;
1013 : :
1014 : 0 : ret = rte_kvargs_process(kvlist, IDPF_TX_SINGLE_Q, &parse_bool,
1015 : 0 : &adapter->base.is_tx_singleq);
1016 [ # # ]: 0 : if (ret != 0)
1017 : 0 : goto bail;
1018 : :
1019 : 0 : ret = rte_kvargs_process(kvlist, IDPF_RX_SINGLE_Q, &parse_bool,
1020 : 0 : &adapter->base.is_rx_singleq);
1021 [ # # ]: 0 : if (ret != 0)
1022 : 0 : goto bail;
1023 : :
1024 : 0 : bail:
1025 : 0 : rte_kvargs_free(kvlist);
1026 : 0 : return ret;
1027 : : }
1028 : :
1029 : : static struct idpf_vport *
1030 : : idpf_find_vport(struct idpf_adapter_ext *adapter, uint32_t vport_id)
1031 : : {
1032 : : struct idpf_vport *vport = NULL;
1033 : : int i;
1034 : :
1035 [ # # ]: 0 : for (i = 0; i < adapter->cur_vport_nb; i++) {
1036 : 0 : vport = adapter->vports[i];
1037 [ # # ]: 0 : if (vport->vport_id != vport_id)
1038 : : continue;
1039 : : else
1040 : : return vport;
1041 : : }
1042 : :
1043 : : return vport;
1044 : : }
1045 : :
1046 : : static void
1047 : 0 : idpf_handle_event_msg(struct idpf_vport *vport, uint8_t *msg, uint16_t msglen)
1048 : : {
1049 : : struct virtchnl2_event *vc_event = (struct virtchnl2_event *)msg;
1050 : 0 : struct rte_eth_dev_data *data = vport->dev_data;
1051 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[data->port_id];
1052 : :
1053 [ # # ]: 0 : if (msglen < sizeof(struct virtchnl2_event)) {
1054 : 0 : PMD_DRV_LOG(ERR, "Error event");
1055 : 0 : return;
1056 : : }
1057 : :
1058 [ # # ]: 0 : switch (vc_event->event) {
1059 : 0 : case VIRTCHNL2_EVENT_LINK_CHANGE:
1060 : 0 : PMD_DRV_LOG(DEBUG, "VIRTCHNL2_EVENT_LINK_CHANGE");
1061 : 0 : vport->link_up = !!(vc_event->link_status);
1062 : 0 : vport->link_speed = vc_event->link_speed;
1063 : 0 : idpf_dev_link_update(dev, 0);
1064 : 0 : break;
1065 : 0 : default:
1066 : 0 : PMD_DRV_LOG(ERR, " unknown event received %u", vc_event->event);
1067 : 0 : break;
1068 : : }
1069 : : }
1070 : :
1071 : : static void
1072 : 0 : idpf_handle_virtchnl_msg(struct idpf_adapter_ext *adapter_ex)
1073 : : {
1074 : : struct idpf_adapter *adapter = &adapter_ex->base;
1075 : 0 : struct idpf_dma_mem *dma_mem = NULL;
1076 : 0 : struct idpf_hw *hw = &adapter->hw;
1077 : : struct virtchnl2_event *vc_event;
1078 : : struct idpf_ctlq_msg ctlq_msg;
1079 : : enum idpf_mbx_opc mbx_op;
1080 : : struct idpf_vport *vport;
1081 : 0 : uint16_t pending = 1;
1082 : : uint32_t vc_op;
1083 : : int ret;
1084 : :
1085 [ # # ]: 0 : while (pending) {
1086 : 0 : ret = idpf_vc_ctlq_recv(hw->arq, &pending, &ctlq_msg);
1087 [ # # ]: 0 : if (ret) {
1088 : 0 : PMD_DRV_LOG(INFO, "Failed to read msg from virtual channel, ret: %d", ret);
1089 : 0 : return;
1090 : : }
1091 : :
1092 [ # # ]: 0 : rte_memcpy(adapter->mbx_resp, ctlq_msg.ctx.indirect.payload->va,
1093 : : IDPF_DFLT_MBX_BUF_SIZE);
1094 : :
1095 : 0 : mbx_op = rte_le_to_cpu_16(ctlq_msg.opcode);
1096 : 0 : vc_op = rte_le_to_cpu_32(ctlq_msg.cookie.mbx.chnl_opcode);
1097 : 0 : adapter->cmd_retval = rte_le_to_cpu_32(ctlq_msg.cookie.mbx.chnl_retval);
1098 : :
1099 [ # # ]: 0 : switch (mbx_op) {
1100 : 0 : case idpf_mbq_opc_send_msg_to_peer_pf:
1101 : : case idpf_mbq_opc_send_msg_to_peer_drv:
1102 [ # # ]: 0 : if (vc_op == VIRTCHNL2_OP_EVENT) {
1103 [ # # ]: 0 : if (ctlq_msg.data_len < sizeof(struct virtchnl2_event)) {
1104 : 0 : PMD_DRV_LOG(ERR, "Error event");
1105 : 0 : return;
1106 : : }
1107 : 0 : vc_event = (struct virtchnl2_event *)adapter->mbx_resp;
1108 : 0 : vport = idpf_find_vport(adapter_ex, vc_event->vport_id);
1109 [ # # ]: 0 : if (!vport) {
1110 : 0 : PMD_DRV_LOG(ERR, "Can't find vport.");
1111 : 0 : return;
1112 : : }
1113 : 0 : idpf_handle_event_msg(vport, adapter->mbx_resp,
1114 : : ctlq_msg.data_len);
1115 : : } else {
1116 [ # # ]: 0 : if (vc_op == adapter->pend_cmd)
1117 : : notify_cmd(adapter, adapter->cmd_retval);
1118 : : else
1119 : 0 : PMD_DRV_LOG(ERR, "command mismatch, expect %u, get %u",
1120 : : adapter->pend_cmd, vc_op);
1121 : :
1122 : 0 : PMD_DRV_LOG(DEBUG, " Virtual channel response is received,"
1123 : : "opcode = %d", vc_op);
1124 : : }
1125 : 0 : goto post_buf;
1126 : 0 : default:
1127 : 0 : PMD_DRV_LOG(DEBUG, "Request %u is not supported yet", mbx_op);
1128 : : }
1129 : : }
1130 : :
1131 : 0 : post_buf:
1132 [ # # ]: 0 : if (ctlq_msg.data_len)
1133 : 0 : dma_mem = ctlq_msg.ctx.indirect.payload;
1134 : : else
1135 : 0 : pending = 0;
1136 : :
1137 : 0 : ret = idpf_vc_ctlq_post_rx_buffs(hw, hw->arq, &pending, &dma_mem);
1138 [ # # # # ]: 0 : if (ret && dma_mem)
1139 : : idpf_free_dma_mem(hw, dma_mem);
1140 : : }
1141 : :
1142 : : static void
1143 : 0 : idpf_dev_alarm_handler(void *param)
1144 : : {
1145 : : struct idpf_adapter_ext *adapter = param;
1146 : :
1147 : 0 : idpf_handle_virtchnl_msg(adapter);
1148 : :
1149 : 0 : rte_eal_alarm_set(IDPF_ALARM_INTERVAL, idpf_dev_alarm_handler, adapter);
1150 : 0 : }
1151 : :
1152 : : static struct virtchnl2_get_capabilities req_caps = {
1153 : : .csum_caps =
1154 : : VIRTCHNL2_CAP_TX_CSUM_L3_IPV4 |
1155 : : VIRTCHNL2_CAP_TX_CSUM_L4_IPV4_TCP |
1156 : : VIRTCHNL2_CAP_TX_CSUM_L4_IPV4_UDP |
1157 : : VIRTCHNL2_CAP_TX_CSUM_L4_IPV4_SCTP |
1158 : : VIRTCHNL2_CAP_TX_CSUM_L4_IPV6_TCP |
1159 : : VIRTCHNL2_CAP_TX_CSUM_L4_IPV6_UDP |
1160 : : VIRTCHNL2_CAP_TX_CSUM_L4_IPV6_SCTP |
1161 : : VIRTCHNL2_CAP_TX_CSUM_GENERIC |
1162 : : VIRTCHNL2_CAP_RX_CSUM_L3_IPV4 |
1163 : : VIRTCHNL2_CAP_RX_CSUM_L4_IPV4_TCP |
1164 : : VIRTCHNL2_CAP_RX_CSUM_L4_IPV4_UDP |
1165 : : VIRTCHNL2_CAP_RX_CSUM_L4_IPV4_SCTP |
1166 : : VIRTCHNL2_CAP_RX_CSUM_L4_IPV6_TCP |
1167 : : VIRTCHNL2_CAP_RX_CSUM_L4_IPV6_UDP |
1168 : : VIRTCHNL2_CAP_RX_CSUM_L4_IPV6_SCTP |
1169 : : VIRTCHNL2_CAP_RX_CSUM_GENERIC,
1170 : :
1171 : : .rss_caps =
1172 : : VIRTCHNL2_CAP_RSS_IPV4_TCP |
1173 : : VIRTCHNL2_CAP_RSS_IPV4_UDP |
1174 : : VIRTCHNL2_CAP_RSS_IPV4_SCTP |
1175 : : VIRTCHNL2_CAP_RSS_IPV4_OTHER |
1176 : : VIRTCHNL2_CAP_RSS_IPV6_TCP |
1177 : : VIRTCHNL2_CAP_RSS_IPV6_UDP |
1178 : : VIRTCHNL2_CAP_RSS_IPV6_SCTP |
1179 : : VIRTCHNL2_CAP_RSS_IPV6_OTHER |
1180 : : VIRTCHNL2_CAP_RSS_IPV4_AH |
1181 : : VIRTCHNL2_CAP_RSS_IPV4_ESP |
1182 : : VIRTCHNL2_CAP_RSS_IPV4_AH_ESP |
1183 : : VIRTCHNL2_CAP_RSS_IPV6_AH |
1184 : : VIRTCHNL2_CAP_RSS_IPV6_ESP |
1185 : : VIRTCHNL2_CAP_RSS_IPV6_AH_ESP,
1186 : :
1187 : : .other_caps = VIRTCHNL2_CAP_WB_ON_ITR
1188 : : };
1189 : :
1190 : : static int
1191 : 0 : idpf_adapter_ext_init(struct rte_pci_device *pci_dev, struct idpf_adapter_ext *adapter)
1192 : : {
1193 : 0 : struct idpf_adapter *base = &adapter->base;
1194 : : struct idpf_hw *hw = &base->hw;
1195 : : int ret = 0;
1196 : :
1197 : 0 : hw->hw_addr = (void *)pci_dev->mem_resource[0].addr;
1198 : 0 : hw->hw_addr_len = pci_dev->mem_resource[0].len;
1199 : 0 : hw->back = base;
1200 : 0 : hw->vendor_id = pci_dev->id.vendor_id;
1201 : 0 : hw->device_id = pci_dev->id.device_id;
1202 : 0 : hw->subsystem_vendor_id = pci_dev->id.subsystem_vendor_id;
1203 : :
1204 [ # # ]: 0 : strncpy(adapter->name, pci_dev->device.name, PCI_PRI_STR_SIZE);
1205 : :
1206 [ # # ]: 0 : rte_memcpy(&base->caps, &req_caps, sizeof(struct virtchnl2_get_capabilities));
1207 : :
1208 : 0 : ret = idpf_adapter_init(base);
1209 [ # # ]: 0 : if (ret != 0) {
1210 : 0 : PMD_INIT_LOG(ERR, "Failed to init adapter");
1211 : 0 : goto err_adapter_init;
1212 : : }
1213 : :
1214 : 0 : rte_eal_alarm_set(IDPF_ALARM_INTERVAL, idpf_dev_alarm_handler, adapter);
1215 : :
1216 : 0 : adapter->max_vport_nb = adapter->base.caps.max_vports;
1217 : :
1218 : 0 : adapter->vports = rte_zmalloc("vports",
1219 : 0 : adapter->max_vport_nb *
1220 : : sizeof(*adapter->vports),
1221 : : 0);
1222 [ # # ]: 0 : if (adapter->vports == NULL) {
1223 : 0 : PMD_INIT_LOG(ERR, "Failed to allocate vports memory");
1224 : : ret = -ENOMEM;
1225 : 0 : goto err_vports_alloc;
1226 : : }
1227 : :
1228 : 0 : adapter->cur_vports = 0;
1229 : 0 : adapter->cur_vport_nb = 0;
1230 : :
1231 : 0 : adapter->used_vecs_num = 0;
1232 : :
1233 : 0 : return ret;
1234 : :
1235 : : err_vports_alloc:
1236 : 0 : rte_eal_alarm_cancel(idpf_dev_alarm_handler, adapter);
1237 : 0 : idpf_adapter_deinit(base);
1238 : : err_adapter_init:
1239 : : return ret;
1240 : : }
1241 : :
1242 : : static uint16_t
1243 : : idpf_vport_idx_alloc(struct idpf_adapter_ext *ad)
1244 : : {
1245 : : uint16_t vport_idx;
1246 : : uint16_t i;
1247 : :
1248 [ # # # # ]: 0 : for (i = 0; i < ad->max_vport_nb; i++) {
1249 [ # # # # ]: 0 : if (ad->vports[i] == NULL)
1250 : : break;
1251 : : }
1252 : :
1253 [ # # # # ]: 0 : if (i == ad->max_vport_nb)
1254 : : vport_idx = IDPF_INVALID_VPORT_IDX;
1255 : : else
1256 : : vport_idx = i;
1257 : :
1258 : : return vport_idx;
1259 : : }
1260 : :
1261 : : static int
1262 : 0 : idpf_dev_vport_init(struct rte_eth_dev *dev, void *init_params)
1263 : : {
1264 : 0 : struct idpf_vport *vport = dev->data->dev_private;
1265 : : struct idpf_vport_param *param = init_params;
1266 : 0 : struct idpf_adapter_ext *adapter = param->adapter;
1267 : : /* for sending create vport virtchnl msg prepare */
1268 : : struct virtchnl2_create_vport create_vport_info;
1269 : : int ret = 0;
1270 : :
1271 : 0 : dev->dev_ops = &idpf_eth_dev_ops;
1272 : 0 : vport->adapter = &adapter->base;
1273 : 0 : vport->sw_idx = param->idx;
1274 : 0 : vport->devarg_id = param->devarg_id;
1275 : :
1276 : : memset(&create_vport_info, 0, sizeof(create_vport_info));
1277 : 0 : ret = idpf_vport_info_init(vport, &create_vport_info);
1278 [ # # ]: 0 : if (ret != 0) {
1279 : 0 : PMD_INIT_LOG(ERR, "Failed to init vport req_info.");
1280 : 0 : goto err;
1281 : : }
1282 : :
1283 : 0 : ret = idpf_vport_init(vport, &create_vport_info, dev->data);
1284 [ # # ]: 0 : if (ret != 0) {
1285 : 0 : PMD_INIT_LOG(ERR, "Failed to init vports.");
1286 : 0 : goto err;
1287 : : }
1288 : :
1289 : 0 : dev->data->mac_addrs = rte_zmalloc(NULL, RTE_ETHER_ADDR_LEN, 0);
1290 [ # # ]: 0 : if (dev->data->mac_addrs == NULL) {
1291 : 0 : PMD_INIT_LOG(ERR, "Cannot allocate mac_addr memory.");
1292 : : ret = -ENOMEM;
1293 : 0 : goto err_mac_addrs;
1294 : : }
1295 : :
1296 : : rte_ether_addr_copy((struct rte_ether_addr *)vport->default_mac_addr,
1297 : : &dev->data->mac_addrs[0]);
1298 : :
1299 : 0 : adapter->vports[param->idx] = vport;
1300 : 0 : adapter->cur_vports |= RTE_BIT32(param->devarg_id);
1301 : 0 : adapter->cur_vport_nb++;
1302 : :
1303 : 0 : return 0;
1304 : :
1305 : : err_mac_addrs:
1306 : 0 : adapter->vports[param->idx] = NULL; /* reset */
1307 : 0 : idpf_vport_deinit(vport);
1308 : : err:
1309 : : return ret;
1310 : : }
1311 : :
1312 : : static const struct rte_pci_id pci_id_idpf_map[] = {
1313 : : { RTE_PCI_DEVICE(IDPF_INTEL_VENDOR_ID, IDPF_DEV_ID_PF) },
1314 : : { RTE_PCI_DEVICE(IDPF_INTEL_VENDOR_ID, IDPF_DEV_ID_SRIOV) },
1315 : : { .vendor_id = 0, /* sentinel */ },
1316 : : };
1317 : :
1318 : : static struct idpf_adapter_ext *
1319 : 0 : idpf_find_adapter_ext(struct rte_pci_device *pci_dev)
1320 : : {
1321 : : struct idpf_adapter_ext *adapter;
1322 : : int found = 0;
1323 : :
1324 [ # # ]: 0 : if (pci_dev == NULL)
1325 : : return NULL;
1326 : :
1327 : : rte_spinlock_lock(&idpf_adapter_lock);
1328 [ # # ]: 0 : TAILQ_FOREACH(adapter, &idpf_adapter_list, next) {
1329 [ # # ]: 0 : if (strncmp(adapter->name, pci_dev->device.name, PCI_PRI_STR_SIZE) == 0) {
1330 : : found = 1;
1331 : : break;
1332 : : }
1333 : : }
1334 : : rte_spinlock_unlock(&idpf_adapter_lock);
1335 : :
1336 [ # # ]: 0 : if (found == 0)
1337 : 0 : return NULL;
1338 : :
1339 : : return adapter;
1340 : : }
1341 : :
1342 : : static void
1343 : 0 : idpf_adapter_ext_deinit(struct idpf_adapter_ext *adapter)
1344 : : {
1345 : 0 : rte_eal_alarm_cancel(idpf_dev_alarm_handler, adapter);
1346 : 0 : idpf_adapter_deinit(&adapter->base);
1347 : :
1348 : 0 : rte_free(adapter->vports);
1349 : 0 : adapter->vports = NULL;
1350 : 0 : }
1351 : :
1352 : : static int
1353 : 0 : idpf_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
1354 : : struct rte_pci_device *pci_dev)
1355 : : {
1356 : : struct idpf_vport_param vport_param;
1357 : : struct idpf_adapter_ext *adapter;
1358 : : struct idpf_devargs devargs;
1359 : : char name[RTE_ETH_NAME_MAX_LEN];
1360 : : int i, retval;
1361 : : bool first_probe = false;
1362 : :
1363 [ # # ]: 0 : if (!idpf_adapter_list_init) {
1364 : : rte_spinlock_init(&idpf_adapter_lock);
1365 : 0 : TAILQ_INIT(&idpf_adapter_list);
1366 : 0 : idpf_adapter_list_init = true;
1367 : : }
1368 : :
1369 : 0 : adapter = idpf_find_adapter_ext(pci_dev);
1370 [ # # ]: 0 : if (adapter == NULL) {
1371 : : first_probe = true;
1372 : 0 : adapter = rte_zmalloc("idpf_adapter_ext",
1373 : : sizeof(struct idpf_adapter_ext), 0);
1374 [ # # ]: 0 : if (adapter == NULL) {
1375 : 0 : PMD_INIT_LOG(ERR, "Failed to allocate adapter.");
1376 : 0 : return -ENOMEM;
1377 : : }
1378 : :
1379 : 0 : retval = idpf_adapter_ext_init(pci_dev, adapter);
1380 [ # # ]: 0 : if (retval != 0) {
1381 : 0 : PMD_INIT_LOG(ERR, "Failed to init adapter.");
1382 : 0 : return retval;
1383 : : }
1384 : :
1385 : : rte_spinlock_lock(&idpf_adapter_lock);
1386 : 0 : TAILQ_INSERT_TAIL(&idpf_adapter_list, adapter, next);
1387 : : rte_spinlock_unlock(&idpf_adapter_lock);
1388 : : }
1389 : :
1390 : 0 : retval = idpf_parse_devargs(pci_dev, adapter, &devargs);
1391 [ # # ]: 0 : if (retval != 0) {
1392 : 0 : PMD_INIT_LOG(ERR, "Failed to parse private devargs");
1393 : 0 : goto err;
1394 : : }
1395 : :
1396 [ # # ]: 0 : if (devargs.req_vport_nb == 0) {
1397 : : /* If no vport devarg, create vport 0 by default. */
1398 : 0 : vport_param.adapter = adapter;
1399 : 0 : vport_param.devarg_id = 0;
1400 : 0 : vport_param.idx = idpf_vport_idx_alloc(adapter);
1401 [ # # ]: 0 : if (vport_param.idx == IDPF_INVALID_VPORT_IDX) {
1402 : 0 : PMD_INIT_LOG(ERR, "No space for vport %u", vport_param.devarg_id);
1403 : 0 : return 0;
1404 : : }
1405 : 0 : snprintf(name, sizeof(name), "idpf_%s_vport_0",
1406 : : pci_dev->device.name);
1407 : 0 : retval = rte_eth_dev_create(&pci_dev->device, name,
1408 : : sizeof(struct idpf_vport),
1409 : : NULL, NULL, idpf_dev_vport_init,
1410 : : &vport_param);
1411 [ # # ]: 0 : if (retval != 0)
1412 : 0 : PMD_DRV_LOG(ERR, "Failed to create default vport 0");
1413 : : } else {
1414 [ # # ]: 0 : for (i = 0; i < devargs.req_vport_nb; i++) {
1415 : 0 : vport_param.adapter = adapter;
1416 : 0 : vport_param.devarg_id = devargs.req_vports[i];
1417 : 0 : vport_param.idx = idpf_vport_idx_alloc(adapter);
1418 [ # # ]: 0 : if (vport_param.idx == IDPF_INVALID_VPORT_IDX) {
1419 : 0 : PMD_INIT_LOG(ERR, "No space for vport %u", vport_param.devarg_id);
1420 : 0 : break;
1421 : : }
1422 : 0 : snprintf(name, sizeof(name), "idpf_%s_vport_%d",
1423 : : pci_dev->device.name,
1424 : : devargs.req_vports[i]);
1425 : 0 : retval = rte_eth_dev_create(&pci_dev->device, name,
1426 : : sizeof(struct idpf_vport),
1427 : : NULL, NULL, idpf_dev_vport_init,
1428 : : &vport_param);
1429 [ # # ]: 0 : if (retval != 0)
1430 : 0 : PMD_DRV_LOG(ERR, "Failed to create vport %d",
1431 : : vport_param.devarg_id);
1432 : : }
1433 : : }
1434 : :
1435 : : return 0;
1436 : :
1437 : : err:
1438 [ # # ]: 0 : if (first_probe) {
1439 : : rte_spinlock_lock(&idpf_adapter_lock);
1440 [ # # ]: 0 : TAILQ_REMOVE(&idpf_adapter_list, adapter, next);
1441 : : rte_spinlock_unlock(&idpf_adapter_lock);
1442 : 0 : idpf_adapter_ext_deinit(adapter);
1443 : 0 : rte_free(adapter);
1444 : : }
1445 : : return retval;
1446 : : }
1447 : :
1448 : : static int
1449 : 0 : idpf_pci_remove(struct rte_pci_device *pci_dev)
1450 : : {
1451 : 0 : struct idpf_adapter_ext *adapter = idpf_find_adapter_ext(pci_dev);
1452 : : uint16_t port_id;
1453 : :
1454 : : /* Ethdev created can be found RTE_ETH_FOREACH_DEV_OF through rte_device */
1455 [ # # ]: 0 : RTE_ETH_FOREACH_DEV_OF(port_id, &pci_dev->device) {
1456 : 0 : rte_eth_dev_close(port_id);
1457 : : }
1458 : :
1459 : : rte_spinlock_lock(&idpf_adapter_lock);
1460 [ # # ]: 0 : TAILQ_REMOVE(&idpf_adapter_list, adapter, next);
1461 : : rte_spinlock_unlock(&idpf_adapter_lock);
1462 : 0 : idpf_adapter_ext_deinit(adapter);
1463 : 0 : rte_free(adapter);
1464 : :
1465 : 0 : return 0;
1466 : : }
1467 : :
1468 : : static struct rte_pci_driver rte_idpf_pmd = {
1469 : : .id_table = pci_id_idpf_map,
1470 : : .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
1471 : : .probe = idpf_pci_probe,
1472 : : .remove = idpf_pci_remove,
1473 : : };
1474 : :
1475 : : /**
1476 : : * Driver initialization routine.
1477 : : * Invoked once at EAL init time.
1478 : : * Register itself as the [Poll Mode] Driver of PCI devices.
1479 : : */
1480 : 251 : RTE_PMD_REGISTER_PCI(net_idpf, rte_idpf_pmd);
1481 : : RTE_PMD_REGISTER_PCI_TABLE(net_idpf, pci_id_idpf_map);
1482 : : RTE_PMD_REGISTER_KMOD_DEP(net_idpf, "* igb_uio | vfio-pci");
1483 : : RTE_PMD_REGISTER_PARAM_STRING(net_idpf,
1484 : : IDPF_TX_SINGLE_Q "=<0|1> "
1485 : : IDPF_RX_SINGLE_Q "=<0|1> "
1486 : : IDPF_VPORT "=[<begin>[-<end>][,<begin >[-<end>]][, ... ]]");
1487 : :
1488 [ - + ]: 251 : RTE_LOG_REGISTER_SUFFIX(idpf_logtype_init, init, NOTICE);
1489 [ - + ]: 251 : RTE_LOG_REGISTER_SUFFIX(idpf_logtype_driver, driver, NOTICE);
|