Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(C) 2022-2023 Intel Corporation
3 : : * Copyright(C) 2023 Google LLC
4 : : */
5 : :
6 : : #include "gve_ethdev.h"
7 : : #include "base/gve_adminq.h"
8 : : #include "base/gve_register.h"
9 : : #include "base/gve_osdep.h"
10 : : #include "gve_version.h"
11 : : #include "rte_ether.h"
12 : : #include "gve_rss.h"
13 : : #include <ethdev_driver.h>
14 : :
15 : : static int gve_init_priv(struct gve_priv *priv, bool skip_describe_device);
16 : : static void gve_start_dev_status_polling(struct rte_eth_dev *dev);
17 : : static void gve_stop_dev_status_polling(struct rte_eth_dev *dev);
18 : :
19 : : static void
20 : : gve_write_version(uint8_t *driver_version_register)
21 : : {
22 : 0 : const char *c = gve_version_string();
23 [ # # ]: 0 : while (*c) {
24 : 0 : writeb(*c, driver_version_register);
25 : 0 : c++;
26 : : }
27 : : writeb('\n', driver_version_register);
28 : : }
29 : :
30 : : static const struct rte_memzone *
31 : 0 : gve_alloc_using_mz(const char *name, uint32_t num_pages)
32 : : {
33 : : const struct rte_memzone *mz;
34 : 0 : mz = rte_memzone_reserve_aligned(name, num_pages * PAGE_SIZE,
35 : 0 : rte_socket_id(),
36 : : RTE_MEMZONE_IOVA_CONTIG, PAGE_SIZE);
37 [ # # ]: 0 : if (mz == NULL)
38 : 0 : PMD_DRV_LOG(ERR, "Failed to alloc memzone %s.", name);
39 : 0 : return mz;
40 : : }
41 : :
42 : : static int
43 : 0 : gve_alloc_using_malloc(void **bufs, uint32_t num_entries)
44 : : {
45 : : uint32_t i;
46 : :
47 [ # # ]: 0 : for (i = 0; i < num_entries; i++) {
48 : 0 : bufs[i] = rte_malloc_socket(NULL, PAGE_SIZE, PAGE_SIZE, rte_socket_id());
49 [ # # ]: 0 : if (bufs[i] == NULL) {
50 : 0 : PMD_DRV_LOG(ERR, "Failed to malloc");
51 : 0 : goto free_bufs;
52 : : }
53 : : }
54 : : return 0;
55 : :
56 : : free_bufs:
57 [ # # ]: 0 : while (i > 0)
58 : 0 : rte_free(bufs[--i]);
59 : :
60 : : return -ENOMEM;
61 : : }
62 : :
63 : : static struct gve_queue_page_list *
64 : 0 : gve_alloc_queue_page_list(const char *name, uint32_t num_pages, bool is_rx)
65 : : {
66 : : struct gve_queue_page_list *qpl;
67 : : const struct rte_memzone *mz;
68 : : uint32_t i;
69 : :
70 : 0 : qpl = rte_zmalloc("qpl struct", sizeof(struct gve_queue_page_list), 0);
71 [ # # ]: 0 : if (!qpl)
72 : : return NULL;
73 : :
74 : 0 : qpl->page_buses = rte_zmalloc("qpl page buses",
75 : : num_pages * sizeof(dma_addr_t), 0);
76 [ # # ]: 0 : if (qpl->page_buses == NULL) {
77 : 0 : PMD_DRV_LOG(ERR, "Failed to alloc qpl page buses");
78 : 0 : goto free_qpl_struct;
79 : : }
80 : :
81 [ # # ]: 0 : if (is_rx) {
82 : : /* RX QPL need not be IOVA contiguous.
83 : : * Allocate 4K size buffers using malloc
84 : : */
85 : 0 : qpl->qpl_bufs = rte_zmalloc("qpl bufs",
86 : : num_pages * sizeof(void *), 0);
87 [ # # ]: 0 : if (qpl->qpl_bufs == NULL) {
88 : 0 : PMD_DRV_LOG(ERR, "Failed to alloc qpl bufs");
89 : 0 : goto free_qpl_page_buses;
90 : : }
91 : :
92 [ # # ]: 0 : if (gve_alloc_using_malloc(qpl->qpl_bufs, num_pages))
93 : 0 : goto free_qpl_page_bufs;
94 : :
95 : : /* Populate the IOVA addresses */
96 [ # # ]: 0 : for (i = 0; i < num_pages; i++)
97 : 0 : qpl->page_buses[i] =
98 : 0 : rte_malloc_virt2iova(qpl->qpl_bufs[i]);
99 : : } else {
100 : : /* TX QPL needs to be IOVA contiguous
101 : : * Allocate QPL using memzone
102 : : */
103 : 0 : mz = gve_alloc_using_mz(name, num_pages);
104 [ # # ]: 0 : if (!mz)
105 : 0 : goto free_qpl_page_buses;
106 : :
107 : 0 : qpl->mz = mz;
108 : :
109 : : /* Populate the IOVA addresses */
110 [ # # ]: 0 : for (i = 0; i < num_pages; i++)
111 : 0 : qpl->page_buses[i] = mz->iova + i * PAGE_SIZE;
112 : : }
113 : :
114 : 0 : qpl->num_entries = num_pages;
115 : 0 : return qpl;
116 : :
117 : : free_qpl_page_bufs:
118 : 0 : rte_free(qpl->qpl_bufs);
119 : 0 : free_qpl_page_buses:
120 : 0 : rte_free(qpl->page_buses);
121 : 0 : free_qpl_struct:
122 : 0 : rte_free(qpl);
123 : 0 : return NULL;
124 : : }
125 : :
126 : : static void
127 : 0 : gve_free_queue_page_list(struct gve_queue_page_list *qpl)
128 : : {
129 [ # # ]: 0 : if (qpl->mz) {
130 : 0 : rte_memzone_free(qpl->mz);
131 : 0 : qpl->mz = NULL;
132 : : } else if (qpl->qpl_bufs) {
133 : : uint32_t i;
134 : :
135 : : for (i = 0; i < qpl->num_entries; i++)
136 : : rte_free(qpl->qpl_bufs[i]);
137 : : }
138 : :
139 [ # # ]: 0 : if (qpl->qpl_bufs) {
140 : 0 : rte_free(qpl->qpl_bufs);
141 : 0 : qpl->qpl_bufs = NULL;
142 : : }
143 : :
144 [ # # ]: 0 : if (qpl->page_buses) {
145 : 0 : rte_free(qpl->page_buses);
146 : 0 : qpl->page_buses = NULL;
147 : : }
148 : 0 : rte_free(qpl);
149 : 0 : }
150 : :
151 : : struct gve_queue_page_list *
152 : 0 : gve_setup_queue_page_list(struct gve_priv *priv, uint16_t queue_id, bool is_rx,
153 : : uint32_t num_pages)
154 : : {
155 [ # # ]: 0 : const char *queue_type_string = is_rx ? "rx" : "tx";
156 : : char qpl_name[RTE_MEMZONE_NAMESIZE];
157 : : struct gve_queue_page_list *qpl;
158 : : int err;
159 : :
160 : : /* Allocate a new QPL. */
161 : 0 : snprintf(qpl_name, sizeof(qpl_name), "gve_%s_%s_qpl%d",
162 : 0 : priv->pci_dev->device.name, queue_type_string, queue_id);
163 : 0 : qpl = gve_alloc_queue_page_list(qpl_name, num_pages, is_rx);
164 [ # # ]: 0 : if (!qpl) {
165 : 0 : PMD_DRV_LOG(ERR,
166 : : "Failed to alloc %s qpl for queue %hu.",
167 : : queue_type_string, queue_id);
168 : 0 : return NULL;
169 : : }
170 : :
171 : : /* Assign the QPL an ID. */
172 : 0 : qpl->id = queue_id;
173 [ # # ]: 0 : if (is_rx)
174 : 0 : qpl->id += priv->max_nb_txq;
175 : :
176 : : /* Validate page registration limit and register QPLs. */
177 : 0 : if (priv->num_registered_pages + qpl->num_entries >
178 [ # # ]: 0 : priv->max_registered_pages) {
179 : 0 : PMD_DRV_LOG(ERR, "Pages %" PRIu64 " > max registered pages %" PRIu64,
180 : : priv->num_registered_pages + qpl->num_entries,
181 : : priv->max_registered_pages);
182 : 0 : goto cleanup_qpl;
183 : : }
184 : 0 : err = gve_adminq_register_page_list(priv, qpl);
185 [ # # ]: 0 : if (err) {
186 : 0 : PMD_DRV_LOG(ERR,
187 : : "Failed to register %s qpl for queue %hu.",
188 : : queue_type_string, queue_id);
189 : 0 : goto cleanup_qpl;
190 : : }
191 : 0 : priv->num_registered_pages += qpl->num_entries;
192 : 0 : return qpl;
193 : :
194 : 0 : cleanup_qpl:
195 : 0 : gve_free_queue_page_list(qpl);
196 : 0 : return NULL;
197 : : }
198 : :
199 : : int
200 : 0 : gve_teardown_queue_page_list(struct gve_priv *priv,
201 : : struct gve_queue_page_list *qpl)
202 : : {
203 : 0 : int err = gve_adminq_unregister_page_list(priv, qpl->id);
204 [ # # ]: 0 : if (err) {
205 : 0 : PMD_DRV_LOG(CRIT, "Unable to unregister qpl %d!", qpl->id);
206 : 0 : return err;
207 : : }
208 : 0 : priv->num_registered_pages -= qpl->num_entries;
209 : 0 : gve_free_queue_page_list(qpl);
210 : 0 : return 0;
211 : : }
212 : :
213 : : static int
214 : 0 : gve_dev_configure(struct rte_eth_dev *dev)
215 : : {
216 : 0 : struct gve_priv *priv = dev->data->dev_private;
217 : :
218 [ # # ]: 0 : if (dev->data->dev_conf.rxmode.mq_mode & RTE_ETH_MQ_RX_RSS_FLAG) {
219 : 0 : dev->data->dev_conf.rxmode.offloads |= RTE_ETH_RX_OFFLOAD_RSS_HASH;
220 : 0 : priv->rss_config.alg = GVE_RSS_HASH_TOEPLITZ;
221 : : }
222 : :
223 [ # # ]: 0 : if (dev->data->dev_conf.rxmode.offloads & RTE_ETH_RX_OFFLOAD_TCP_LRO)
224 : 0 : priv->enable_rsc = 1;
225 : :
226 : : /* Reset RSS RETA in case number of queues changed. */
227 [ # # ]: 0 : if (priv->rss_config.indir) {
228 : : struct gve_rss_config update_reta_config;
229 : 0 : gve_init_rss_config_from_priv(priv, &update_reta_config);
230 : 0 : gve_generate_rss_reta(dev, &update_reta_config);
231 : :
232 : 0 : int err = gve_adminq_configure_rss(priv, &update_reta_config);
233 [ # # ]: 0 : if (err)
234 : 0 : PMD_DRV_LOG(ERR,
235 : : "Could not reconfigure RSS redirection table.");
236 : : else
237 : 0 : gve_update_priv_rss_config(priv, &update_reta_config);
238 : :
239 : 0 : gve_free_rss_config(&update_reta_config);
240 : : return err;
241 : : }
242 : :
243 : : return 0;
244 : : }
245 : :
246 : : static int
247 : 0 : gve_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complete)
248 : : {
249 [ # # ]: 0 : struct gve_priv *priv = dev->data->dev_private;
250 : : struct rte_eth_link link;
251 : : int err;
252 : :
253 : : memset(&link, 0, sizeof(link));
254 : 0 : link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
255 : 0 : link.link_autoneg = RTE_ETH_LINK_AUTONEG;
256 : :
257 [ # # ]: 0 : if (!dev->data->dev_started) {
258 : : link.link_status = RTE_ETH_LINK_DOWN;
259 : : link.link_speed = RTE_ETH_SPEED_NUM_NONE;
260 : : } else {
261 : 0 : link.link_status = RTE_ETH_LINK_UP;
262 : 0 : PMD_DRV_LOG(DEBUG, "Get link status from hw");
263 : 0 : err = gve_adminq_report_link_speed(priv);
264 [ # # ]: 0 : if (err) {
265 : 0 : PMD_DRV_LOG(ERR, "Failed to get link speed.");
266 : 0 : priv->link_speed = RTE_ETH_SPEED_NUM_UNKNOWN;
267 : : }
268 : 0 : link.link_speed = priv->link_speed;
269 : : }
270 : :
271 : 0 : return rte_eth_linkstatus_set(dev, &link);
272 : : }
273 : :
274 : : static int
275 : 0 : gve_alloc_stats_report(struct gve_priv *priv,
276 : : uint16_t nb_tx_queues, uint16_t nb_rx_queues)
277 : : {
278 : : char z_name[RTE_MEMZONE_NAMESIZE];
279 : : int tx_stats_cnt;
280 : : int rx_stats_cnt;
281 : :
282 : 0 : tx_stats_cnt = (GVE_TX_STATS_REPORT_NUM + NIC_TX_STATS_REPORT_NUM) *
283 : : nb_tx_queues;
284 : 0 : rx_stats_cnt = (GVE_RX_STATS_REPORT_NUM + NIC_RX_STATS_REPORT_NUM) *
285 : : nb_rx_queues;
286 : 0 : priv->stats_report_len = sizeof(struct gve_stats_report) +
287 : 0 : sizeof(struct stats) * (tx_stats_cnt + rx_stats_cnt);
288 : :
289 : 0 : snprintf(z_name, sizeof(z_name), "gve_stats_report_%s",
290 : 0 : priv->pci_dev->device.name);
291 : 0 : priv->stats_report_mem = rte_memzone_reserve_aligned(z_name,
292 : 0 : priv->stats_report_len,
293 : 0 : rte_socket_id(),
294 : : RTE_MEMZONE_IOVA_CONTIG, PAGE_SIZE);
295 : :
296 [ # # ]: 0 : if (!priv->stats_report_mem)
297 : : return -ENOMEM;
298 : :
299 : : /* offset by skipping stats written by gve. */
300 : 0 : priv->stats_start_idx = (GVE_TX_STATS_REPORT_NUM * nb_tx_queues) +
301 : : (GVE_RX_STATS_REPORT_NUM * nb_rx_queues);
302 : 0 : priv->stats_end_idx = priv->stats_start_idx +
303 : 0 : (NIC_TX_STATS_REPORT_NUM * nb_tx_queues) +
304 : 0 : (NIC_RX_STATS_REPORT_NUM * nb_rx_queues) - 1;
305 : :
306 : 0 : return 0;
307 : : }
308 : :
309 : : static void
310 : : gve_free_stats_report(struct rte_eth_dev *dev)
311 : : {
312 : : struct gve_priv *priv = dev->data->dev_private;
313 : 0 : rte_memzone_free(priv->stats_report_mem);
314 : 0 : priv->stats_report_mem = NULL;
315 : 0 : }
316 : :
317 : : /* Read Rx NIC stats from shared region */
318 : : static void
319 : 0 : gve_get_imissed_from_nic(struct rte_eth_dev *dev)
320 : : {
321 : : struct gve_stats_report *stats_report;
322 : : struct gve_rx_queue *rxq;
323 : : struct gve_priv *priv;
324 : : struct stats stat;
325 : : int queue_id;
326 : : int stat_id;
327 : : int i;
328 : :
329 : 0 : priv = dev->data->dev_private;
330 [ # # ]: 0 : if (!priv->stats_report_mem)
331 : : return;
332 : 0 : stats_report = (struct gve_stats_report *)
333 : : priv->stats_report_mem->addr;
334 [ # # ]: 0 : for (i = priv->stats_start_idx; i <= priv->stats_end_idx; i++) {
335 : 0 : stat = stats_report->stats[i];
336 [ # # ]: 0 : queue_id = cpu_to_be32(stat.queue_id);
337 : 0 : rxq = dev->data->rx_queues[queue_id];
338 [ # # ]: 0 : if (rxq == NULL)
339 : 0 : continue;
340 [ # # ]: 0 : stat_id = cpu_to_be32(stat.stat_name);
341 : : /* Update imissed. */
342 [ # # ]: 0 : if (stat_id == RX_NO_BUFFERS_POSTED)
343 [ # # ]: 0 : rxq->stats.imissed = cpu_to_be64(stat.value);
344 : : }
345 : : }
346 : :
347 : : static int
348 : 0 : gve_start_queues(struct rte_eth_dev *dev)
349 : : {
350 : 0 : struct gve_priv *priv = dev->data->dev_private;
351 : : uint16_t num_queues;
352 : : uint16_t i;
353 : : int ret;
354 : :
355 : 0 : num_queues = dev->data->nb_tx_queues;
356 : 0 : priv->txqs = (struct gve_tx_queue **)dev->data->tx_queues;
357 : 0 : ret = gve_adminq_create_tx_queues(priv, num_queues);
358 [ # # ]: 0 : if (ret != 0) {
359 : 0 : PMD_DRV_LOG(ERR, "Failed to create %u tx queues.", num_queues);
360 : 0 : return ret;
361 : : }
362 [ # # ]: 0 : for (i = 0; i < num_queues; i++) {
363 [ # # ]: 0 : if (gve_is_gqi(priv))
364 : 0 : ret = gve_tx_queue_start(dev, i);
365 : : else
366 : 0 : ret = gve_tx_queue_start_dqo(dev, i);
367 [ # # ]: 0 : if (ret != 0) {
368 : 0 : PMD_DRV_LOG(ERR, "Fail to start Tx queue %d", i);
369 : 0 : goto err_tx;
370 : : }
371 : : }
372 : :
373 : 0 : num_queues = dev->data->nb_rx_queues;
374 : 0 : priv->rxqs = (struct gve_rx_queue **)dev->data->rx_queues;
375 : 0 : ret = gve_adminq_create_rx_queues(priv, num_queues);
376 [ # # ]: 0 : if (ret != 0) {
377 : 0 : PMD_DRV_LOG(ERR, "Failed to create %u rx queues.", num_queues);
378 : 0 : goto err_tx;
379 : : }
380 [ # # ]: 0 : for (i = 0; i < num_queues; i++) {
381 [ # # ]: 0 : if (gve_is_gqi(priv))
382 : 0 : ret = gve_rx_queue_start(dev, i);
383 : : else
384 : 0 : ret = gve_rx_queue_start_dqo(dev, i);
385 [ # # ]: 0 : if (ret != 0) {
386 : 0 : PMD_DRV_LOG(ERR, "Fail to start Rx queue %d", i);
387 [ # # ]: 0 : goto err_rx;
388 : : }
389 : : }
390 : :
391 : : gve_set_device_rings_ok(priv);
392 : :
393 : 0 : return 0;
394 : :
395 : : err_rx:
396 [ # # ]: 0 : if (gve_is_gqi(priv))
397 : 0 : gve_stop_rx_queues(dev);
398 : : else
399 : 0 : gve_stop_rx_queues_dqo(dev);
400 [ # # ]: 0 : err_tx:
401 [ # # ]: 0 : if (gve_is_gqi(priv))
402 : 0 : gve_stop_tx_queues(dev);
403 : : else
404 : 0 : gve_stop_tx_queues_dqo(dev);
405 : :
406 : : gve_clear_device_rings_ok(priv);
407 : 0 : return ret;
408 : : }
409 : :
410 : : static int
411 : 0 : gve_dev_start(struct rte_eth_dev *dev)
412 : : {
413 : : struct gve_priv *priv;
414 : : int ret;
415 : :
416 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
417 : 0 : PMD_DRV_LOG(WARNING, "Cannot start device in secondary.");
418 : 0 : return -EPERM;
419 : : }
420 : :
421 : 0 : ret = gve_start_queues(dev);
422 [ # # ]: 0 : if (ret != 0) {
423 : 0 : PMD_DRV_LOG(ERR, "Failed to start queues");
424 : 0 : return ret;
425 : : }
426 : :
427 : 0 : dev->data->dev_started = 1;
428 : 0 : gve_link_update(dev, 0);
429 : :
430 [ # # ]: 0 : priv = dev->data->dev_private;
431 : : /* No stats available yet for Dqo. */
432 [ # # ]: 0 : if (gve_is_gqi(priv)) {
433 : 0 : ret = gve_alloc_stats_report(priv,
434 : 0 : dev->data->nb_tx_queues,
435 : 0 : dev->data->nb_rx_queues);
436 [ # # ]: 0 : if (ret != 0) {
437 : 0 : PMD_DRV_LOG(ERR,
438 : : "Failed to allocate region for stats reporting.");
439 : 0 : return ret;
440 : : }
441 : 0 : ret = gve_adminq_report_stats(priv, priv->stats_report_len,
442 : 0 : priv->stats_report_mem->iova,
443 : : GVE_STATS_REPORT_TIMER_PERIOD);
444 [ # # ]: 0 : if (ret != 0) {
445 : 0 : PMD_DRV_LOG(ERR, "gve_adminq_report_stats command failed.");
446 : 0 : return ret;
447 : : }
448 : : }
449 : :
450 : 0 : gve_start_dev_status_polling(dev);
451 : :
452 : 0 : return 0;
453 : : }
454 : :
455 : : static int
456 : 0 : gve_dev_stop(struct rte_eth_dev *dev)
457 : : {
458 : 0 : struct gve_priv *priv = dev->data->dev_private;
459 : :
460 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
461 : 0 : PMD_DRV_LOG(WARNING, "Cannot stop device in secondary.");
462 : 0 : return -EPERM;
463 : : }
464 : :
465 : : /*
466 : : * Block until all polling callbacks have concluded before tearing down
467 : : * any device resources.
468 : : */
469 : : gve_stop_dev_status_polling(dev);
470 : :
471 : 0 : dev->data->dev_started = 0;
472 [ # # ]: 0 : dev->data->dev_link.link_status = RTE_ETH_LINK_DOWN;
473 : :
474 : : gve_clear_device_rings_ok(priv);
475 [ # # ]: 0 : if (gve_is_gqi(priv)) {
476 : 0 : gve_stop_tx_queues(dev);
477 : 0 : gve_stop_rx_queues(dev);
478 : : } else {
479 : 0 : gve_stop_tx_queues_dqo(dev);
480 : 0 : gve_stop_rx_queues_dqo(dev);
481 : : }
482 : :
483 [ # # ]: 0 : if (gve_is_gqi(dev->data->dev_private))
484 : : gve_free_stats_report(dev);
485 : :
486 : : return 0;
487 : : }
488 : :
489 : : static void
490 : 0 : gve_free_queues(struct rte_eth_dev *dev)
491 : : {
492 [ # # ]: 0 : struct gve_priv *priv = dev->data->dev_private;
493 : : uint16_t i;
494 : :
495 [ # # ]: 0 : if (gve_is_gqi(priv)) {
496 [ # # ]: 0 : for (i = 0; i < dev->data->nb_tx_queues; i++)
497 : 0 : gve_tx_queue_release(dev, i);
498 : :
499 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++)
500 : 0 : gve_rx_queue_release(dev, i);
501 : : } else {
502 [ # # ]: 0 : for (i = 0; i < dev->data->nb_tx_queues; i++)
503 : 0 : gve_tx_queue_release_dqo(dev, i);
504 : :
505 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++)
506 : 0 : gve_rx_queue_release_dqo(dev, i);
507 : : }
508 : 0 : }
509 : :
510 : : static void
511 : : gve_free_counter_array(struct gve_priv *priv)
512 : : {
513 : 0 : rte_memzone_free(priv->cnt_array_mz);
514 : 0 : priv->cnt_array = NULL;
515 : : }
516 : :
517 : : static void
518 : : gve_free_irq_db(struct gve_priv *priv)
519 : : {
520 : 0 : rte_memzone_free(priv->irq_dbs_mz);
521 : 0 : priv->irq_dbs = NULL;
522 : 0 : }
523 : :
524 : : static void
525 : : gve_free_ptype_lut_dqo(struct gve_priv *priv)
526 : : {
527 [ # # ]: 0 : if (!gve_is_gqi(priv)) {
528 : 0 : rte_free(priv->ptype_lut_dqo);
529 : 0 : priv->ptype_lut_dqo = NULL;
530 : : }
531 : : }
532 : :
533 : : static int
534 : 0 : gve_setup_flow_subsystem(struct gve_priv *priv)
535 : : {
536 : : int err;
537 : :
538 : 0 : priv->flow_rule_bmp_size =
539 : 0 : rte_bitmap_get_memory_footprint(priv->max_flow_rules);
540 : 0 : priv->avail_flow_rule_bmp_mem = rte_zmalloc("gve_flow_rule_bmp",
541 : : priv->flow_rule_bmp_size, 0);
542 [ # # ]: 0 : if (!priv->avail_flow_rule_bmp_mem) {
543 : 0 : PMD_DRV_LOG(ERR, "Failed to alloc bitmap for flow rules.");
544 : 0 : return -ENOMEM;
545 : : }
546 : :
547 : 0 : err = gve_flow_init_bmp(priv);
548 [ # # ]: 0 : if (err) {
549 : 0 : PMD_DRV_LOG(ERR, "Failed to initialize flow rule bitmap.");
550 : 0 : goto free_flow_rule_bmp;
551 : : }
552 : :
553 : 0 : TAILQ_INIT(&priv->active_flows);
554 : : gve_set_flow_subsystem_ok(priv);
555 : :
556 : 0 : return 0;
557 : :
558 : : free_flow_rule_bmp:
559 : 0 : gve_flow_free_bmp(priv);
560 : 0 : return err;
561 : : }
562 : :
563 : : static void
564 : 0 : gve_teardown_flow_subsystem(struct gve_priv *priv)
565 : : {
566 : 0 : pthread_mutex_lock(&priv->flow_rule_lock);
567 : :
568 : : gve_clear_flow_subsystem_ok(priv);
569 : 0 : gve_flow_free_bmp(priv);
570 : 0 : gve_free_flow_rules(priv);
571 : :
572 : 0 : pthread_mutex_unlock(&priv->flow_rule_lock);
573 : 0 : }
574 : :
575 : : static void
576 [ # # ]: 0 : gve_teardown_device_resources(struct gve_priv *priv)
577 : : {
578 : : int err;
579 : :
580 : : /* Tell device its resources are being freed */
581 [ # # ]: 0 : if (gve_get_device_resources_ok(priv)) {
582 : 0 : err = gve_adminq_deconfigure_device_resources(priv);
583 [ # # ]: 0 : if (err)
584 : 0 : PMD_DRV_LOG(ERR,
585 : : "Could not deconfigure device resources: err=%d",
586 : : err);
587 : : }
588 : :
589 : : gve_free_ptype_lut_dqo(priv);
590 : : gve_free_counter_array(priv);
591 : : gve_free_irq_db(priv);
592 : : gve_clear_device_resources_ok(priv);
593 : 0 : }
594 : :
595 : : static int
596 : 0 : gve_dev_close(struct rte_eth_dev *dev)
597 : : {
598 : 0 : struct gve_priv *priv = dev->data->dev_private;
599 : : int err = 0;
600 : :
601 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
602 : : return 0;
603 : :
604 [ # # ]: 0 : if (dev->data->dev_started) {
605 : 0 : err = gve_dev_stop(dev);
606 [ # # ]: 0 : if (err != 0)
607 : 0 : PMD_DRV_LOG(ERR, "Failed to stop dev.");
608 : : }
609 : :
610 [ # # ]: 0 : if (gve_get_flow_subsystem_ok(priv))
611 : 0 : gve_teardown_flow_subsystem(priv);
612 : :
613 : 0 : pthread_mutex_destroy(&priv->flow_rule_lock);
614 : :
615 : 0 : gve_free_queues(dev);
616 : 0 : gve_teardown_device_resources(priv);
617 : 0 : gve_adminq_free(priv);
618 : :
619 : 0 : dev->data->mac_addrs = NULL;
620 : :
621 : 0 : return err;
622 : : }
623 : :
624 : : static int
625 : 0 : gve_dev_reset(struct rte_eth_dev *dev)
626 : : {
627 : 0 : struct gve_priv *priv = dev->data->dev_private;
628 : : int err;
629 : :
630 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
631 : 0 : PMD_DRV_LOG(ERR,
632 : : "Device reset on port %u not supported in secondary processes.",
633 : : dev->data->port_id);
634 : 0 : return -EPERM;
635 : : }
636 : :
637 : : /* Tear down all device resources before re-initializing. */
638 [ # # ]: 0 : if (gve_get_flow_subsystem_ok(priv))
639 : 0 : gve_teardown_flow_subsystem(priv);
640 : :
641 : : /*
642 : : * Note that gve_teardown_flow_subsystem does not destroy the
643 : : * flow_rule_lock. The lock is preserved across device resets and only
644 : : * destroyed on dev_close.
645 : : */
646 : 0 : gve_free_queues(dev);
647 : 0 : gve_teardown_device_resources(priv);
648 : 0 : gve_adminq_free(priv);
649 : :
650 : 0 : err = gve_init_priv(priv, true);
651 [ # # ]: 0 : if (err != 0) {
652 : 0 : PMD_DRV_LOG(ERR,
653 : : "Failed to re-init device on port %u after reset.",
654 : : dev->data->port_id);
655 : 0 : return err;
656 : : }
657 : :
658 : : return 0;
659 : : }
660 : :
661 : : static int
662 : 0 : gve_verify_driver_compatibility(struct gve_priv *priv)
663 : : {
664 : : const struct rte_memzone *driver_info_mem;
665 : : struct gve_driver_info *driver_info;
666 : : int err;
667 : :
668 : 0 : driver_info_mem = rte_memzone_reserve_aligned("verify_driver_compatibility",
669 : : sizeof(struct gve_driver_info),
670 : 0 : rte_socket_id(),
671 : : RTE_MEMZONE_IOVA_CONTIG, PAGE_SIZE);
672 : :
673 [ # # ]: 0 : if (driver_info_mem == NULL) {
674 : 0 : PMD_DRV_LOG(ERR,
675 : : "Could not alloc memzone for driver compatibility");
676 : 0 : return -ENOMEM;
677 : : }
678 : 0 : driver_info = (struct gve_driver_info *)driver_info_mem->addr;
679 : :
680 : 0 : *driver_info = (struct gve_driver_info) {
681 : : .os_type = 5, /* DPDK */
682 : : .driver_major = GVE_VERSION_MAJOR,
683 : : .driver_minor = GVE_VERSION_MINOR,
684 : : .driver_sub = GVE_VERSION_SUB,
685 : : .os_version_major = cpu_to_be32(DPDK_VERSION_MAJOR),
686 : : .os_version_minor = cpu_to_be32(DPDK_VERSION_MINOR),
687 : : .os_version_sub = cpu_to_be32(DPDK_VERSION_SUB),
688 : : .driver_capability_flags = {
689 : : cpu_to_be64(GVE_DRIVER_CAPABILITY_FLAGS1),
690 : : cpu_to_be64(GVE_DRIVER_CAPABILITY_FLAGS2),
691 : : cpu_to_be64(GVE_DRIVER_CAPABILITY_FLAGS3),
692 : : cpu_to_be64(GVE_DRIVER_CAPABILITY_FLAGS4),
693 : : },
694 : : };
695 : :
696 : 0 : populate_driver_version_strings((char *)driver_info->os_version_str1,
697 : 0 : (char *)driver_info->os_version_str2);
698 : :
699 : 0 : err = gve_adminq_verify_driver_compatibility(priv,
700 : : sizeof(struct gve_driver_info),
701 : 0 : (dma_addr_t)driver_info_mem->iova);
702 : : /* It's ok if the device doesn't support this */
703 [ # # ]: 0 : if (err == -EOPNOTSUPP)
704 : : err = 0;
705 : :
706 : 0 : rte_memzone_free(driver_info_mem);
707 : 0 : return err;
708 : : }
709 : :
710 : : static int
711 : 0 : gve_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
712 : : {
713 : 0 : struct gve_priv *priv = dev->data->dev_private;
714 : :
715 : 0 : dev_info->device = dev->device;
716 : 0 : dev_info->max_mac_addrs = 1;
717 : 0 : dev_info->max_rx_queues = priv->max_nb_rxq;
718 [ # # ]: 0 : dev_info->max_tx_queues = priv->max_nb_txq;
719 [ # # ]: 0 : if (gve_is_gqi(priv)) {
720 : 0 : dev_info->min_rx_bufsize = GVE_RX_MIN_BUF_SIZE_GQI;
721 : 0 : dev_info->max_rx_bufsize = GVE_RX_MAX_BUF_SIZE_GQI;
722 : : } else {
723 : 0 : dev_info->min_rx_bufsize = GVE_RX_MIN_BUF_SIZE_DQO;
724 : 0 : dev_info->max_rx_bufsize = GVE_RX_MAX_BUF_SIZE_DQO;
725 : : }
726 : :
727 : 0 : dev_info->max_rx_pktlen = priv->max_mtu + RTE_ETHER_HDR_LEN;
728 : 0 : dev_info->max_mtu = priv->max_mtu;
729 : 0 : dev_info->min_mtu = RTE_ETHER_MIN_MTU;
730 : :
731 : 0 : dev_info->rx_offload_capa = RTE_ETH_RX_OFFLOAD_RSS_HASH;
732 : 0 : dev_info->tx_offload_capa =
733 : : RTE_ETH_TX_OFFLOAD_MULTI_SEGS |
734 : : RTE_ETH_TX_OFFLOAD_UDP_CKSUM |
735 : : RTE_ETH_TX_OFFLOAD_TCP_CKSUM |
736 : : RTE_ETH_TX_OFFLOAD_SCTP_CKSUM |
737 : : RTE_ETH_TX_OFFLOAD_TCP_TSO;
738 : :
739 [ # # ]: 0 : if (!gve_is_gqi(priv)) {
740 : 0 : dev_info->tx_offload_capa |= RTE_ETH_TX_OFFLOAD_IPV4_CKSUM;
741 : 0 : dev_info->rx_offload_capa |=
742 : : RTE_ETH_RX_OFFLOAD_IPV4_CKSUM |
743 : : RTE_ETH_RX_OFFLOAD_UDP_CKSUM |
744 : : RTE_ETH_RX_OFFLOAD_TCP_CKSUM |
745 : : RTE_ETH_RX_OFFLOAD_TCP_LRO;
746 : : }
747 : :
748 : 0 : dev_info->default_rxconf = (struct rte_eth_rxconf) {
749 : : .rx_free_thresh = GVE_DEFAULT_RX_FREE_THRESH,
750 : : .rx_drop_en = 0,
751 : : .offloads = 0,
752 : : };
753 : :
754 : 0 : dev_info->default_txconf = (struct rte_eth_txconf) {
755 : : .tx_free_thresh = GVE_DEFAULT_TX_FREE_THRESH,
756 : : .tx_rs_thresh = GVE_DEFAULT_TX_RS_THRESH,
757 : : .offloads = 0,
758 : : };
759 : :
760 : 0 : dev_info->default_rxportconf.ring_size = priv->default_rx_desc_cnt;
761 : 0 : dev_info->rx_desc_lim = (struct rte_eth_desc_lim) {
762 : 0 : .nb_max = priv->max_rx_desc_cnt,
763 : 0 : .nb_min = priv->min_rx_desc_cnt,
764 : : .nb_align = 1,
765 : : };
766 : :
767 : 0 : dev_info->default_txportconf.ring_size = priv->default_tx_desc_cnt;
768 : 0 : dev_info->tx_desc_lim = (struct rte_eth_desc_lim) {
769 : 0 : .nb_max = priv->max_tx_desc_cnt,
770 : 0 : .nb_min = priv->min_tx_desc_cnt,
771 : : .nb_align = 1,
772 : : .nb_mtu_seg_max = GVE_TX_MAX_DATA_DESCS - 1,
773 : : };
774 : :
775 : 0 : dev_info->flow_type_rss_offloads = GVE_RTE_RSS_OFFLOAD_ALL;
776 : 0 : dev_info->hash_key_size = GVE_RSS_HASH_KEY_SIZE;
777 : 0 : dev_info->reta_size = GVE_RSS_INDIR_SIZE;
778 : :
779 : 0 : return 0;
780 : : }
781 : :
782 : : static int
783 : 0 : gve_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
784 : : struct eth_queue_stats *qstats __rte_unused)
785 : : {
786 : : uint16_t i;
787 [ # # ]: 0 : if (gve_is_gqi(dev->data->dev_private))
788 : 0 : gve_get_imissed_from_nic(dev);
789 : :
790 [ # # ]: 0 : for (i = 0; i < dev->data->nb_tx_queues; i++) {
791 : 0 : struct gve_tx_queue *txq = dev->data->tx_queues[i];
792 [ # # ]: 0 : if (txq == NULL)
793 : 0 : continue;
794 : :
795 : 0 : stats->opackets += txq->stats.packets;
796 : 0 : stats->obytes += txq->stats.bytes;
797 : 0 : stats->oerrors += txq->stats.errors;
798 : : }
799 : :
800 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++) {
801 : 0 : struct gve_rx_queue *rxq = dev->data->rx_queues[i];
802 [ # # ]: 0 : if (rxq == NULL)
803 : 0 : continue;
804 : :
805 : 0 : stats->ipackets += rxq->stats.packets;
806 : 0 : stats->ibytes += rxq->stats.bytes;
807 : 0 : stats->ierrors += rxq->stats.errors;
808 : 0 : stats->rx_nombuf += rxq->stats.no_mbufs;
809 : 0 : stats->imissed += rxq->stats.imissed;
810 : : }
811 : :
812 : 0 : return 0;
813 : : }
814 : :
815 : : static int
816 : 0 : gve_dev_stats_reset(struct rte_eth_dev *dev)
817 : : {
818 : : uint16_t i;
819 : :
820 [ # # ]: 0 : for (i = 0; i < dev->data->nb_tx_queues; i++) {
821 : 0 : struct gve_tx_queue *txq = dev->data->tx_queues[i];
822 [ # # ]: 0 : if (txq == NULL)
823 : 0 : continue;
824 : :
825 : 0 : memset(&txq->stats, 0, sizeof(txq->stats));
826 : : }
827 : :
828 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++) {
829 : 0 : struct gve_rx_queue *rxq = dev->data->rx_queues[i];
830 [ # # ]: 0 : if (rxq == NULL)
831 : 0 : continue;
832 : :
833 : 0 : memset(&rxq->stats, 0, sizeof(rxq->stats));
834 : : }
835 : :
836 : 0 : return 0;
837 : : }
838 : :
839 : : static int
840 : 0 : gve_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
841 : : {
842 : 0 : struct gve_priv *priv = dev->data->dev_private;
843 : : int err;
844 : :
845 [ # # # # ]: 0 : if (mtu < RTE_ETHER_MIN_MTU || mtu > priv->max_mtu) {
846 : 0 : PMD_DRV_LOG(ERR, "MIN MTU is %u, MAX MTU is %u",
847 : : RTE_ETHER_MIN_MTU, priv->max_mtu);
848 : 0 : return -EINVAL;
849 : : }
850 : :
851 : : /* mtu setting is forbidden if port is start */
852 [ # # ]: 0 : if (dev->data->dev_started) {
853 : 0 : PMD_DRV_LOG(ERR, "Port must be stopped before configuration");
854 : 0 : return -EBUSY;
855 : : }
856 : :
857 : 0 : err = gve_adminq_set_mtu(priv, mtu);
858 [ # # ]: 0 : if (err) {
859 : 0 : PMD_DRV_LOG(ERR, "Failed to set mtu as %u err = %d", mtu, err);
860 : 0 : return err;
861 : : }
862 : :
863 : : return 0;
864 : : }
865 : :
866 : : #define TX_QUEUE_STATS_OFFSET(x) offsetof(struct gve_tx_stats, x)
867 : : #define RX_QUEUE_STATS_OFFSET(x) offsetof(struct gve_rx_stats, x)
868 : :
869 : : static const struct gve_xstats_name_offset tx_xstats_name_offset[] = {
870 : : { "packets", TX_QUEUE_STATS_OFFSET(packets) },
871 : : { "bytes", TX_QUEUE_STATS_OFFSET(bytes) },
872 : : { "errors", TX_QUEUE_STATS_OFFSET(errors) },
873 : : };
874 : :
875 : : static const struct gve_xstats_name_offset rx_xstats_name_offset[] = {
876 : : { "packets", RX_QUEUE_STATS_OFFSET(packets) },
877 : : { "bytes", RX_QUEUE_STATS_OFFSET(bytes) },
878 : : { "errors", RX_QUEUE_STATS_OFFSET(errors) },
879 : : { "mbuf_alloc_errors", RX_QUEUE_STATS_OFFSET(no_mbufs) },
880 : : { "mbuf_alloc_errors_bulk", RX_QUEUE_STATS_OFFSET(no_mbufs_bulk) },
881 : : { "imissed", RX_QUEUE_STATS_OFFSET(imissed) },
882 : : };
883 : :
884 : : static int
885 : 0 : gve_xstats_count(struct rte_eth_dev *dev)
886 : : {
887 : : uint16_t i, count = 0;
888 : :
889 [ # # ]: 0 : for (i = 0; i < dev->data->nb_tx_queues; i++) {
890 [ # # ]: 0 : if (dev->data->tx_queues[i])
891 : 0 : count += RTE_DIM(tx_xstats_name_offset);
892 : : }
893 : :
894 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++) {
895 [ # # ]: 0 : if (dev->data->rx_queues[i])
896 : 0 : count += RTE_DIM(rx_xstats_name_offset);
897 : : }
898 : :
899 : 0 : return count;
900 : : }
901 : :
902 : : static int
903 : 0 : gve_xstats_get(struct rte_eth_dev *dev,
904 : : struct rte_eth_xstat *xstats,
905 : : unsigned int size)
906 : : {
907 : 0 : uint16_t i, j, count = gve_xstats_count(dev);
908 : : const char *stats;
909 : :
910 [ # # ]: 0 : if (gve_is_gqi(dev->data->dev_private))
911 : 0 : gve_get_imissed_from_nic(dev);
912 : :
913 [ # # # # ]: 0 : if (xstats == NULL || size < count)
914 : 0 : return count;
915 : :
916 : : count = 0;
917 : :
918 [ # # ]: 0 : for (i = 0; i < dev->data->nb_tx_queues; i++) {
919 : 0 : const struct gve_tx_queue *txq = dev->data->tx_queues[i];
920 [ # # ]: 0 : if (txq == NULL)
921 : 0 : continue;
922 : :
923 : 0 : stats = (const char *)&txq->stats;
924 [ # # ]: 0 : for (j = 0; j < RTE_DIM(tx_xstats_name_offset); j++, count++) {
925 : 0 : xstats[count].id = count;
926 : 0 : xstats[count].value = *(const uint64_t *)
927 : 0 : (stats + tx_xstats_name_offset[j].offset);
928 : : }
929 : : }
930 : :
931 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++) {
932 : 0 : const struct gve_rx_queue *rxq = dev->data->rx_queues[i];
933 [ # # ]: 0 : if (rxq == NULL)
934 : 0 : continue;
935 : :
936 : 0 : stats = (const char *)&rxq->stats;
937 [ # # ]: 0 : for (j = 0; j < RTE_DIM(rx_xstats_name_offset); j++, count++) {
938 : 0 : xstats[count].id = count;
939 : 0 : xstats[count].value = *(const uint64_t *)
940 : 0 : (stats + rx_xstats_name_offset[j].offset);
941 : : }
942 : : }
943 : :
944 : 0 : return count;
945 : : }
946 : :
947 : : static int
948 : 0 : gve_xstats_get_names(struct rte_eth_dev *dev,
949 : : struct rte_eth_xstat_name *xstats_names,
950 : : unsigned int size)
951 : : {
952 : 0 : uint16_t i, j, count = gve_xstats_count(dev);
953 : :
954 [ # # # # ]: 0 : if (xstats_names == NULL || size < count)
955 : 0 : return count;
956 : :
957 : : count = 0;
958 : :
959 [ # # ]: 0 : for (i = 0; i < dev->data->nb_tx_queues; i++) {
960 [ # # ]: 0 : if (dev->data->tx_queues[i] == NULL)
961 : 0 : continue;
962 : :
963 [ # # ]: 0 : for (j = 0; j < RTE_DIM(tx_xstats_name_offset); j++)
964 : 0 : snprintf(xstats_names[count++].name,
965 : : RTE_ETH_XSTATS_NAME_SIZE,
966 : 0 : "tx_q%u_%s", i, tx_xstats_name_offset[j].name);
967 : : }
968 : :
969 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++) {
970 [ # # ]: 0 : if (dev->data->rx_queues[i] == NULL)
971 : 0 : continue;
972 : :
973 [ # # ]: 0 : for (j = 0; j < RTE_DIM(rx_xstats_name_offset); j++)
974 : 0 : snprintf(xstats_names[count++].name,
975 : : RTE_ETH_XSTATS_NAME_SIZE,
976 : 0 : "rx_q%u_%s", i, rx_xstats_name_offset[j].name);
977 : : }
978 : :
979 : 0 : return count;
980 : : }
981 : :
982 : :
983 : : static int
984 : 0 : gve_rss_hash_update(struct rte_eth_dev *dev,
985 : : struct rte_eth_rss_conf *rss_conf)
986 : : {
987 : 0 : struct gve_priv *priv = dev->data->dev_private;
988 : : struct gve_rss_config gve_rss_conf;
989 : : int rss_reta_size;
990 : : int err;
991 : :
992 [ # # ]: 0 : if (gve_validate_rss_hf(rss_conf->rss_hf)) {
993 : 0 : PMD_DRV_LOG(ERR, "Unsupported hash function.");
994 : 0 : return -EINVAL;
995 : : }
996 : :
997 [ # # ]: 0 : if (rss_conf->algorithm != RTE_ETH_HASH_FUNCTION_TOEPLITZ &&
998 : : rss_conf->algorithm != RTE_ETH_HASH_FUNCTION_DEFAULT) {
999 : 0 : PMD_DRV_LOG(ERR, "Device only supports Toeplitz algorithm.");
1000 : 0 : return -EINVAL;
1001 : : }
1002 : :
1003 [ # # ]: 0 : if (rss_conf->rss_key_len) {
1004 [ # # ]: 0 : if (rss_conf->rss_key_len != GVE_RSS_HASH_KEY_SIZE) {
1005 : 0 : PMD_DRV_LOG(ERR,
1006 : : "Invalid hash key size. Only RSS hash key size "
1007 : : "of %u supported", GVE_RSS_HASH_KEY_SIZE);
1008 : 0 : return -EINVAL;
1009 : : }
1010 : :
1011 [ # # ]: 0 : if (!rss_conf->rss_key) {
1012 : 0 : PMD_DRV_LOG(ERR, "RSS key must be non-null.");
1013 : 0 : return -EINVAL;
1014 : : }
1015 : : } else {
1016 [ # # ]: 0 : if (!priv->rss_config.key_size) {
1017 : 0 : PMD_DRV_LOG(ERR, "RSS key must be initialized before "
1018 : : "any other configuration.");
1019 : 0 : return -EINVAL;
1020 : : }
1021 : 0 : rss_conf->rss_key_len = priv->rss_config.key_size;
1022 : : }
1023 : :
1024 : 0 : rss_reta_size = priv->rss_config.indir ?
1025 [ # # ]: 0 : priv->rss_config.indir_size :
1026 : : GVE_RSS_INDIR_SIZE;
1027 : 0 : err = gve_init_rss_config(&gve_rss_conf, rss_conf->rss_key_len,
1028 : : rss_reta_size);
1029 [ # # ]: 0 : if (err)
1030 : : return err;
1031 : :
1032 : 0 : gve_rss_conf.alg = GVE_RSS_HASH_TOEPLITZ;
1033 : 0 : err = gve_update_rss_hash_types(priv, &gve_rss_conf, rss_conf);
1034 [ # # ]: 0 : if (err)
1035 : 0 : goto err;
1036 : 0 : err = gve_update_rss_key(priv, &gve_rss_conf, rss_conf);
1037 [ # # ]: 0 : if (err)
1038 : 0 : goto err;
1039 : :
1040 : : /* Set redirection table to default or preexisting. */
1041 [ # # ]: 0 : if (!priv->rss_config.indir)
1042 : 0 : gve_generate_rss_reta(dev, &gve_rss_conf);
1043 : : else
1044 : 0 : memcpy(gve_rss_conf.indir, priv->rss_config.indir,
1045 : 0 : gve_rss_conf.indir_size * sizeof(*priv->rss_config.indir));
1046 : :
1047 : 0 : err = gve_adminq_configure_rss(priv, &gve_rss_conf);
1048 [ # # ]: 0 : if (!err)
1049 : 0 : gve_update_priv_rss_config(priv, &gve_rss_conf);
1050 : :
1051 : 0 : err:
1052 : 0 : gve_free_rss_config(&gve_rss_conf);
1053 : 0 : return err;
1054 : : }
1055 : :
1056 : : static int
1057 : 0 : gve_rss_hash_conf_get(struct rte_eth_dev *dev,
1058 : : struct rte_eth_rss_conf *rss_conf)
1059 : : {
1060 : 0 : struct gve_priv *priv = dev->data->dev_private;
1061 : :
1062 [ # # ]: 0 : if (!(dev->data->dev_conf.rxmode.offloads &
1063 : : RTE_ETH_RX_OFFLOAD_RSS_HASH)) {
1064 : 0 : PMD_DRV_LOG(ERR, "RSS not configured.");
1065 : 0 : return -ENOTSUP;
1066 : : }
1067 : :
1068 : :
1069 : 0 : gve_to_rte_rss_hf(priv->rss_config.hash_types, rss_conf);
1070 : 0 : rss_conf->rss_key_len = priv->rss_config.key_size;
1071 [ # # ]: 0 : if (rss_conf->rss_key) {
1072 [ # # ]: 0 : if (!priv->rss_config.key) {
1073 : 0 : PMD_DRV_LOG(ERR, "Unable to retrieve default RSS hash key.");
1074 : 0 : return -ENOTSUP;
1075 : : }
1076 : 0 : memcpy(rss_conf->rss_key, priv->rss_config.key,
1077 : : rss_conf->rss_key_len * sizeof(*rss_conf->rss_key));
1078 : : }
1079 : :
1080 : : return 0;
1081 : : }
1082 : :
1083 : : static int
1084 : 0 : gve_rss_reta_update(struct rte_eth_dev *dev,
1085 : : struct rte_eth_rss_reta_entry64 *reta_conf, uint16_t reta_size)
1086 : : {
1087 : 0 : struct gve_priv *priv = dev->data->dev_private;
1088 : : struct gve_rss_config gve_rss_conf;
1089 : : int table_id;
1090 : : int err;
1091 : : int i;
1092 : :
1093 : : /* RSS key must be set before the redirection table can be set. */
1094 [ # # # # ]: 0 : if (!priv->rss_config.key || priv->rss_config.key_size == 0) {
1095 : 0 : PMD_DRV_LOG(ERR, "RSS hash key msut be set before the "
1096 : : "redirection table can be updated.");
1097 : 0 : return -ENOTSUP;
1098 : : }
1099 : :
1100 [ # # ]: 0 : if (reta_size != GVE_RSS_INDIR_SIZE) {
1101 : 0 : PMD_DRV_LOG(ERR, "Redirection table must have %hu elements",
1102 : : (uint16_t)GVE_RSS_INDIR_SIZE);
1103 : 0 : return -EINVAL;
1104 : : }
1105 : :
1106 : 0 : err = gve_init_rss_config_from_priv(priv, &gve_rss_conf);
1107 [ # # ]: 0 : if (err) {
1108 : 0 : PMD_DRV_LOG(ERR, "Error allocating new RSS config.");
1109 : 0 : return err;
1110 : : }
1111 : :
1112 : : table_id = 0;
1113 [ # # ]: 0 : for (i = 0; i < priv->rss_config.indir_size; i++) {
1114 : 0 : int table_entry = i % RTE_ETH_RETA_GROUP_SIZE;
1115 [ # # ]: 0 : if (reta_conf[table_id].mask & (1ULL << table_entry))
1116 : 0 : gve_rss_conf.indir[i] =
1117 : 0 : reta_conf[table_id].reta[table_entry];
1118 : :
1119 [ # # ]: 0 : if (table_entry == RTE_ETH_RETA_GROUP_SIZE - 1)
1120 : 0 : table_id++;
1121 : : }
1122 : :
1123 : 0 : err = gve_adminq_configure_rss(priv, &gve_rss_conf);
1124 [ # # ]: 0 : if (err)
1125 : 0 : PMD_DRV_LOG(ERR, "Problem configuring RSS with device.");
1126 : : else
1127 : 0 : gve_update_priv_rss_config(priv, &gve_rss_conf);
1128 : :
1129 : 0 : gve_free_rss_config(&gve_rss_conf);
1130 : 0 : return err;
1131 : : }
1132 : :
1133 : : static int
1134 : 0 : gve_rss_reta_query(struct rte_eth_dev *dev,
1135 : : struct rte_eth_rss_reta_entry64 *reta_conf, uint16_t reta_size)
1136 : : {
1137 : 0 : struct gve_priv *priv = dev->data->dev_private;
1138 : : int table_id;
1139 : : int i;
1140 : :
1141 [ # # ]: 0 : if (!(dev->data->dev_conf.rxmode.offloads &
1142 : : RTE_ETH_RX_OFFLOAD_RSS_HASH)) {
1143 : 0 : PMD_DRV_LOG(ERR, "RSS not configured.");
1144 : 0 : return -ENOTSUP;
1145 : : }
1146 : :
1147 : : /* RSS key must be set before the redirection table can be queried. */
1148 [ # # ]: 0 : if (!priv->rss_config.key) {
1149 : 0 : PMD_DRV_LOG(ERR, "RSS hash key must be set before the "
1150 : : "redirection table can be initialized.");
1151 : 0 : return -ENOTSUP;
1152 : : }
1153 : :
1154 [ # # ]: 0 : if (reta_size != priv->rss_config.indir_size) {
1155 : 0 : PMD_DRV_LOG(ERR, "RSS redirection table must have %d entries.",
1156 : : priv->rss_config.indir_size);
1157 : 0 : return -EINVAL;
1158 : : }
1159 : :
1160 : : table_id = 0;
1161 [ # # ]: 0 : for (i = 0; i < priv->rss_config.indir_size; i++) {
1162 : 0 : int table_entry = i % RTE_ETH_RETA_GROUP_SIZE;
1163 [ # # ]: 0 : if (reta_conf[table_id].mask & (1ULL << table_entry))
1164 : 0 : reta_conf[table_id].reta[table_entry] =
1165 : 0 : priv->rss_config.indir[i];
1166 : :
1167 [ # # ]: 0 : if (table_entry == RTE_ETH_RETA_GROUP_SIZE - 1)
1168 : 0 : table_id++;
1169 : : }
1170 : :
1171 : : return 0;
1172 : : }
1173 : :
1174 : : static int
1175 : 0 : gve_flow_ops_get(struct rte_eth_dev *dev, const struct rte_flow_ops **ops)
1176 : : {
1177 [ # # ]: 0 : struct gve_priv *priv = dev->data->dev_private;
1178 : :
1179 [ # # ]: 0 : if (!gve_get_flow_subsystem_ok(priv))
1180 : : return -ENOTSUP;
1181 : :
1182 : 0 : *ops = &gve_flow_ops;
1183 : 0 : return 0;
1184 : : }
1185 : :
1186 : : static const struct eth_dev_ops gve_eth_dev_ops = {
1187 : : .dev_configure = gve_dev_configure,
1188 : : .dev_start = gve_dev_start,
1189 : : .dev_stop = gve_dev_stop,
1190 : : .dev_close = gve_dev_close,
1191 : : .dev_reset = gve_dev_reset,
1192 : : .dev_infos_get = gve_dev_info_get,
1193 : : .rx_queue_setup = gve_rx_queue_setup,
1194 : : .tx_queue_setup = gve_tx_queue_setup,
1195 : : .rx_queue_release = gve_rx_queue_release,
1196 : : .tx_queue_release = gve_tx_queue_release,
1197 : : .rx_queue_start = gve_rx_queue_start,
1198 : : .tx_queue_start = gve_tx_queue_start,
1199 : : .rx_queue_stop = gve_rx_queue_stop,
1200 : : .tx_queue_stop = gve_tx_queue_stop,
1201 : : .flow_ops_get = gve_flow_ops_get,
1202 : : .link_update = gve_link_update,
1203 : : .stats_get = gve_dev_stats_get,
1204 : : .stats_reset = gve_dev_stats_reset,
1205 : : .mtu_set = gve_dev_mtu_set,
1206 : : .xstats_get = gve_xstats_get,
1207 : : .xstats_get_names = gve_xstats_get_names,
1208 : : .rss_hash_update = gve_rss_hash_update,
1209 : : .rss_hash_conf_get = gve_rss_hash_conf_get,
1210 : : .reta_update = gve_rss_reta_update,
1211 : : .reta_query = gve_rss_reta_query,
1212 : : };
1213 : :
1214 : : static const struct eth_dev_ops gve_eth_dev_ops_dqo = {
1215 : : .dev_configure = gve_dev_configure,
1216 : : .dev_start = gve_dev_start,
1217 : : .dev_stop = gve_dev_stop,
1218 : : .dev_close = gve_dev_close,
1219 : : .dev_reset = gve_dev_reset,
1220 : : .dev_infos_get = gve_dev_info_get,
1221 : : .rx_queue_setup = gve_rx_queue_setup_dqo,
1222 : : .tx_queue_setup = gve_tx_queue_setup_dqo,
1223 : : .rx_queue_release = gve_rx_queue_release_dqo,
1224 : : .tx_queue_release = gve_tx_queue_release_dqo,
1225 : : .rx_queue_start = gve_rx_queue_start_dqo,
1226 : : .tx_queue_start = gve_tx_queue_start_dqo,
1227 : : .rx_queue_stop = gve_rx_queue_stop_dqo,
1228 : : .tx_queue_stop = gve_tx_queue_stop_dqo,
1229 : : .flow_ops_get = gve_flow_ops_get,
1230 : : .link_update = gve_link_update,
1231 : : .stats_get = gve_dev_stats_get,
1232 : : .stats_reset = gve_dev_stats_reset,
1233 : : .mtu_set = gve_dev_mtu_set,
1234 : : .xstats_get = gve_xstats_get,
1235 : : .xstats_get_names = gve_xstats_get_names,
1236 : : .rss_hash_update = gve_rss_hash_update,
1237 : : .rss_hash_conf_get = gve_rss_hash_conf_get,
1238 : : .reta_update = gve_rss_reta_update,
1239 : : .reta_query = gve_rss_reta_query,
1240 : : };
1241 : :
1242 : : static int
1243 : 0 : pci_dev_msix_vec_count(struct rte_pci_device *pdev)
1244 : : {
1245 : 0 : off_t msix_pos = rte_pci_find_capability(pdev, RTE_PCI_CAP_ID_MSIX);
1246 : : uint16_t control;
1247 : :
1248 [ # # # # ]: 0 : if (msix_pos > 0 && rte_pci_read_config(pdev, &control, sizeof(control),
1249 : : msix_pos + RTE_PCI_MSIX_FLAGS) == sizeof(control))
1250 : 0 : return (control & RTE_PCI_MSIX_FLAGS_QSIZE) + 1;
1251 : :
1252 : : return 0;
1253 : : }
1254 : :
1255 : : static int
1256 : 0 : gve_setup_device_resources(struct gve_priv *priv)
1257 : : {
1258 : : char z_name[RTE_MEMZONE_NAMESIZE];
1259 : : const struct rte_memzone *mz;
1260 : : int err = 0;
1261 : :
1262 : 0 : snprintf(z_name, sizeof(z_name), "gve_%s_cnt_arr", priv->pci_dev->device.name);
1263 : 0 : mz = rte_memzone_reserve_aligned(z_name,
1264 : 0 : priv->num_event_counters * sizeof(*priv->cnt_array),
1265 : 0 : rte_socket_id(), RTE_MEMZONE_IOVA_CONTIG,
1266 : : PAGE_SIZE);
1267 [ # # ]: 0 : if (mz == NULL) {
1268 : 0 : PMD_DRV_LOG(ERR, "Could not alloc memzone for count array");
1269 : 0 : return -ENOMEM;
1270 : : }
1271 : 0 : priv->cnt_array = (rte_be32_t *)mz->addr;
1272 : 0 : priv->cnt_array_mz = mz;
1273 : :
1274 : 0 : snprintf(z_name, sizeof(z_name), "gve_%s_irqmz", priv->pci_dev->device.name);
1275 : 0 : mz = rte_memzone_reserve_aligned(z_name,
1276 : 0 : sizeof(*priv->irq_dbs) * (priv->num_ntfy_blks),
1277 : 0 : rte_socket_id(), RTE_MEMZONE_IOVA_CONTIG,
1278 : : PAGE_SIZE);
1279 [ # # ]: 0 : if (mz == NULL) {
1280 : 0 : PMD_DRV_LOG(ERR, "Could not alloc memzone for irq_dbs");
1281 : : err = -ENOMEM;
1282 : 0 : goto free_cnt_array;
1283 : : }
1284 : 0 : priv->irq_dbs = (struct gve_irq_db *)mz->addr;
1285 : 0 : priv->irq_dbs_mz = mz;
1286 : :
1287 : 0 : err = gve_adminq_configure_device_resources(priv,
1288 : 0 : priv->cnt_array_mz->iova,
1289 : 0 : priv->num_event_counters,
1290 : 0 : priv->irq_dbs_mz->iova,
1291 : : priv->num_ntfy_blks);
1292 [ # # ]: 0 : if (unlikely(err)) {
1293 : 0 : PMD_DRV_LOG(ERR, "Could not config device resources: err=%d", err);
1294 : 0 : goto free_irq_dbs;
1295 : : }
1296 [ # # ]: 0 : if (!gve_is_gqi(priv)) {
1297 : 0 : priv->ptype_lut_dqo = rte_zmalloc("gve_ptype_lut_dqo",
1298 : : sizeof(struct gve_ptype_lut), 0);
1299 [ # # ]: 0 : if (priv->ptype_lut_dqo == NULL) {
1300 : 0 : PMD_DRV_LOG(ERR, "Failed to alloc ptype lut.");
1301 : : err = -ENOMEM;
1302 : 0 : goto free_irq_dbs;
1303 : : }
1304 : 0 : err = gve_adminq_get_ptype_map_dqo(priv, priv->ptype_lut_dqo);
1305 [ # # ]: 0 : if (unlikely(err)) {
1306 : 0 : PMD_DRV_LOG(ERR, "Failed to get ptype map: err=%d", err);
1307 : 0 : goto free_ptype_lut;
1308 : : }
1309 : : }
1310 : :
1311 : : gve_set_device_resources_ok(priv);
1312 : :
1313 : 0 : return 0;
1314 : : free_ptype_lut:
1315 : 0 : rte_free(priv->ptype_lut_dqo);
1316 : 0 : priv->ptype_lut_dqo = NULL;
1317 : 0 : free_irq_dbs:
1318 : : gve_free_irq_db(priv);
1319 : 0 : free_cnt_array:
1320 : : gve_free_counter_array(priv);
1321 : :
1322 : 0 : return err;
1323 : : }
1324 : :
1325 : : static void
1326 : : gve_set_default_ring_size_bounds(struct gve_priv *priv)
1327 : : {
1328 : 0 : priv->max_tx_desc_cnt = GVE_DEFAULT_MAX_RING_SIZE;
1329 : 0 : priv->max_rx_desc_cnt = GVE_DEFAULT_MAX_RING_SIZE;
1330 : 0 : priv->min_tx_desc_cnt = GVE_DEFAULT_MIN_TX_RING_SIZE;
1331 : 0 : priv->min_rx_desc_cnt = GVE_DEFAULT_MIN_RX_RING_SIZE;
1332 : : }
1333 : :
1334 : : static void
1335 : 0 : gve_check_device_status(void *arg)
1336 : : {
1337 : : struct rte_eth_dev *dev = arg;
1338 : 0 : struct gve_priv *priv = dev->data->dev_private;
1339 : : uint32_t dev_status;
1340 : : int ret;
1341 : :
1342 : 0 : dev_status = ioread32be(&priv->reg_bar0->device_status);
1343 : :
1344 [ # # ]: 0 : if (dev_status & GVE_DEVICE_STATUS_RESET_MASK) {
1345 : 0 : PMD_DRV_LOG(INFO,
1346 : : "Device on port %u requests a reset. Stopping device status polling.",
1347 : : dev->data->port_id);
1348 : 0 : rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET,
1349 : : NULL);
1350 : : } else {
1351 : 0 : ret = rte_eal_alarm_set(GVE_DEV_POLL_INTERVAL_US,
1352 : : gve_check_device_status, dev);
1353 [ # # ]: 0 : if (ret != 0) {
1354 : 0 : PMD_DRV_LOG(ERR,
1355 : : "Port %u: Failed to re-arm alarm poller!",
1356 : : dev->data->port_id);
1357 : : }
1358 : : }
1359 : 0 : }
1360 : :
1361 : : static void
1362 : 0 : gve_start_dev_status_polling(struct rte_eth_dev *dev)
1363 : : {
1364 : : int ret;
1365 : :
1366 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
1367 : : return;
1368 : :
1369 : 0 : ret = rte_eal_alarm_set(GVE_DEV_POLL_INTERVAL_US,
1370 : : gve_check_device_status,
1371 : : dev);
1372 : :
1373 [ # # ]: 0 : if (ret != 0) {
1374 : 0 : PMD_DRV_LOG(ERR,
1375 : : "Port %u: Failed to arm device reset polling alarm! Err=%d",
1376 : : dev->data->port_id, ret);
1377 : : } else {
1378 : 0 : PMD_DRV_LOG(INFO,
1379 : : "Port %u: Armed device reset polling alarm.",
1380 : : dev->data->port_id);
1381 : : }
1382 : : }
1383 : :
1384 : : static void
1385 : : gve_stop_dev_status_polling(struct rte_eth_dev *dev)
1386 : : {
1387 : : /* Blocks until all in-progress callbacks have completed. */
1388 : 0 : rte_eal_alarm_cancel(gve_check_device_status, dev);
1389 : : }
1390 : :
1391 : : static int
1392 : 0 : gve_init_priv(struct gve_priv *priv, bool skip_describe_device)
1393 : : {
1394 : : int num_ntfy;
1395 : : int err;
1396 : :
1397 : : /* Set up the adminq */
1398 : 0 : err = gve_adminq_alloc(priv);
1399 [ # # ]: 0 : if (err) {
1400 : 0 : PMD_DRV_LOG(ERR, "Failed to alloc admin queue: err=%d", err);
1401 : 0 : return err;
1402 : : }
1403 : 0 : err = gve_verify_driver_compatibility(priv);
1404 [ # # ]: 0 : if (err) {
1405 : 0 : PMD_DRV_LOG(ERR, "Could not verify driver compatibility: err=%d", err);
1406 : 0 : goto free_adminq;
1407 : : }
1408 : :
1409 : : /* Set default descriptor counts */
1410 : : gve_set_default_ring_size_bounds(priv);
1411 : :
1412 [ # # ]: 0 : if (skip_describe_device)
1413 : 0 : goto setup_device;
1414 : :
1415 : : /* Get the initial information we need from the device */
1416 : 0 : err = gve_adminq_describe_device(priv);
1417 [ # # ]: 0 : if (err) {
1418 : 0 : PMD_DRV_LOG(ERR, "Could not get device information: err=%d", err);
1419 : 0 : goto free_adminq;
1420 : : }
1421 : :
1422 : 0 : num_ntfy = pci_dev_msix_vec_count(priv->pci_dev);
1423 [ # # ]: 0 : if (num_ntfy <= 0) {
1424 : 0 : PMD_DRV_LOG(ERR, "Could not count MSI-x vectors");
1425 : : err = -EIO;
1426 : 0 : goto free_adminq;
1427 [ # # ]: 0 : } else if (num_ntfy < GVE_MIN_MSIX) {
1428 : 0 : PMD_DRV_LOG(ERR, "GVE needs at least %d MSI-x vectors, but only has %d",
1429 : : GVE_MIN_MSIX, num_ntfy);
1430 : : err = -EINVAL;
1431 : 0 : goto free_adminq;
1432 : : }
1433 : :
1434 : 0 : priv->num_registered_pages = 0;
1435 : :
1436 : : /* gvnic has one Notification Block per MSI-x vector, except for the
1437 : : * management vector
1438 : : */
1439 : 0 : priv->num_ntfy_blks = (num_ntfy - 1) & ~0x1;
1440 : 0 : priv->mgmt_msix_idx = priv->num_ntfy_blks;
1441 : :
1442 : 0 : priv->max_nb_txq = RTE_MIN(priv->max_nb_txq, priv->num_ntfy_blks / 2);
1443 : 0 : priv->max_nb_rxq = RTE_MIN(priv->max_nb_rxq, priv->num_ntfy_blks / 2);
1444 : :
1445 [ # # ]: 0 : if (priv->default_num_queues > 0) {
1446 : 0 : priv->max_nb_txq = RTE_MIN(priv->default_num_queues, priv->max_nb_txq);
1447 : 0 : priv->max_nb_rxq = RTE_MIN(priv->default_num_queues, priv->max_nb_rxq);
1448 : : }
1449 : :
1450 : 0 : PMD_DRV_LOG(INFO, "Max TX queues %d, Max RX queues %d",
1451 : : priv->max_nb_txq, priv->max_nb_rxq);
1452 : :
1453 : 0 : setup_device:
1454 [ # # ]: 0 : if (priv->max_flow_rules) {
1455 : 0 : err = gve_setup_flow_subsystem(priv);
1456 [ # # ]: 0 : if (err)
1457 : 0 : PMD_DRV_LOG(WARNING,
1458 : : "Failed to set up flow subsystem: err=%d, flow steering will be disabled.",
1459 : : err);
1460 : : }
1461 : :
1462 : 0 : err = gve_setup_device_resources(priv);
1463 [ # # ]: 0 : if (!err)
1464 : : return 0;
1465 : 0 : free_adminq:
1466 : 0 : gve_adminq_free(priv);
1467 : 0 : return err;
1468 : : }
1469 : :
1470 : : static int
1471 : 0 : gve_dev_init(struct rte_eth_dev *eth_dev)
1472 : : {
1473 : 0 : struct gve_priv *priv = eth_dev->data->dev_private;
1474 : : int max_tx_queues, max_rx_queues;
1475 : : struct rte_pci_device *pci_dev;
1476 : : struct gve_registers *reg_bar;
1477 : : pthread_mutexattr_t mutexattr;
1478 : : rte_be32_t *db_bar;
1479 : : int err;
1480 : :
1481 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
1482 [ # # ]: 0 : if (gve_is_gqi(priv)) {
1483 : 0 : gve_set_rx_function(eth_dev);
1484 : 0 : gve_set_tx_function(eth_dev);
1485 : 0 : eth_dev->dev_ops = &gve_eth_dev_ops;
1486 : : } else {
1487 : 0 : gve_set_rx_function_dqo(eth_dev);
1488 : 0 : gve_set_tx_function_dqo(eth_dev);
1489 : 0 : eth_dev->dev_ops = &gve_eth_dev_ops_dqo;
1490 : : }
1491 : 0 : return 0;
1492 : : }
1493 : :
1494 : 0 : pci_dev = RTE_DEV_TO_PCI(eth_dev->device);
1495 : :
1496 : 0 : reg_bar = pci_dev->mem_resource[GVE_REG_BAR].addr;
1497 [ # # ]: 0 : if (!reg_bar) {
1498 : 0 : PMD_DRV_LOG(ERR, "Failed to map pci bar!");
1499 : 0 : return -ENOMEM;
1500 : : }
1501 : :
1502 : 0 : db_bar = pci_dev->mem_resource[GVE_DB_BAR].addr;
1503 [ # # ]: 0 : if (!db_bar) {
1504 : 0 : PMD_DRV_LOG(ERR, "Failed to map doorbell bar!");
1505 : 0 : return -ENOMEM;
1506 : : }
1507 : :
1508 : : gve_write_version(®_bar->driver_version);
1509 : : /* Get max queues to alloc etherdev */
1510 : : max_tx_queues = ioread32be(®_bar->max_tx_queues);
1511 : : max_rx_queues = ioread32be(®_bar->max_rx_queues);
1512 : :
1513 : 0 : priv->reg_bar0 = reg_bar;
1514 : 0 : priv->db_bar2 = db_bar;
1515 : 0 : priv->pci_dev = pci_dev;
1516 : 0 : priv->state_flags = 0x0;
1517 : :
1518 : 0 : priv->max_nb_txq = max_tx_queues;
1519 : 0 : priv->max_nb_rxq = max_rx_queues;
1520 : :
1521 : 0 : err = gve_init_priv(priv, false);
1522 [ # # ]: 0 : if (err)
1523 : : return err;
1524 : :
1525 [ # # ]: 0 : if (gve_is_gqi(priv)) {
1526 : 0 : eth_dev->dev_ops = &gve_eth_dev_ops;
1527 : 0 : gve_set_rx_function(eth_dev);
1528 : 0 : gve_set_tx_function(eth_dev);
1529 : : } else {
1530 : 0 : eth_dev->dev_ops = &gve_eth_dev_ops_dqo;
1531 : 0 : gve_set_rx_function_dqo(eth_dev);
1532 : 0 : gve_set_tx_function_dqo(eth_dev);
1533 : : }
1534 : :
1535 : 0 : eth_dev->data->mac_addrs = &priv->dev_addr;
1536 : :
1537 : 0 : pthread_mutexattr_init(&mutexattr);
1538 : 0 : pthread_mutexattr_setpshared(&mutexattr, PTHREAD_PROCESS_SHARED);
1539 : 0 : pthread_mutex_init(&priv->flow_rule_lock, &mutexattr);
1540 : 0 : pthread_mutexattr_destroy(&mutexattr);
1541 : :
1542 : 0 : return 0;
1543 : : }
1544 : :
1545 : : static int
1546 : 0 : gve_pci_probe(__rte_unused struct rte_pci_driver *pci_drv,
1547 : : struct rte_pci_device *pci_dev)
1548 : : {
1549 : 0 : return rte_eth_dev_pci_generic_probe(pci_dev, sizeof(struct gve_priv), gve_dev_init);
1550 : : }
1551 : :
1552 : : static int
1553 : 0 : gve_pci_remove(struct rte_pci_device *pci_dev)
1554 : : {
1555 : 0 : return rte_eth_dev_pci_generic_remove(pci_dev, gve_dev_close);
1556 : : }
1557 : :
1558 : : static const struct rte_pci_id pci_id_gve_map[] = {
1559 : : { RTE_PCI_DEVICE(GOOGLE_VENDOR_ID, GVE_DEV_ID) },
1560 : : { .device_id = 0 },
1561 : : };
1562 : :
1563 : : static struct rte_pci_driver rte_gve_pmd = {
1564 : : .id_table = pci_id_gve_map,
1565 : : .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
1566 : : .probe = gve_pci_probe,
1567 : : .remove = gve_pci_remove,
1568 : : };
1569 : :
1570 : 286 : RTE_PMD_REGISTER_PCI(net_gve, rte_gve_pmd);
1571 : : RTE_PMD_REGISTER_PCI_TABLE(net_gve, pci_id_gve_map);
1572 : : RTE_PMD_REGISTER_KMOD_DEP(net_gve, "* igb_uio | vfio-pci | nic_uio");
1573 [ - + ]: 286 : RTE_LOG_REGISTER_SUFFIX(gve_logtype_driver, driver, NOTICE);
|