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