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