NVIDIA DOCA SDK Data Center on a Chip Framework Documentation
eth_txq_batch_lso_send_ethernet_frames_sample.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2024 NVIDIA CORPORATION AND AFFILIATES. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without modification, are permitted
5  * provided that the following conditions are met:
6  * * Redistributions of source code must retain the above copyright notice, this list of
7  * conditions and the following disclaimer.
8  * * Redistributions in binary form must reproduce the above copyright notice, this list of
9  * conditions and the following disclaimer in the documentation and/or other materials
10  * provided with the distribution.
11  * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
12  * to endorse or promote products derived from this software without specific prior written
13  * permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
17  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
19  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
20  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
21  * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
22  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  *
24  */
25 
26 #include <time.h>
27 #include <stdint.h>
28 #include <unistd.h>
29 
30 #include <doca_buf.h>
31 #include <doca_buf_inventory.h>
32 #include <doca_ctx.h>
33 #include <doca_eth_txq.h>
35 #include <doca_error.h>
36 #include <doca_log.h>
37 
38 #include "common.h"
39 #include "eth_common.h"
40 
41 DOCA_LOG_REGISTER(ETH_TXQ_BATCH_LSO_SEND_ETHERNET_FRAMES);
42 
43 #define SLEEP_IN_NANOS (10 * 1000) /* sample the task batch every 10 microseconds */
44 #define MAX_BURST_SIZE 256 /* Max burst size to set for eth_txq */
45 #define MAX_LSO_HEADER_SIZE 64 /* Max header size in LRO packet to set for eth_txq */
46 #define MAX_LIST_LENGTH 1 /* Max number of elements in a doca_buf */
47 #define MSS 1500 /* Max Segment Size in LSO tasks to set for eth_txq */
48 #define TASKS_IN_TASK_BATCH 32 /* Number of tasks associated with task batch */
49 #define BUFS_NUM TASKS_IN_TASK_BATCH /* Number of DOCA buffers */
50 #define GATHER_LISTS_NUM TASKS_IN_TASK_BATCH /* Number of DOCA gather_lists */
51 #define TASK_BATCHES_NUM 1 /* Task batches number */
52 #define LSO_PKT_SIZE 4000 /* Size of the packets in LSO send task batch */
53 #define LSO_SEND_TASK_USER_DATA 0x56789 /* User data for LSO send task batch */
54 #define ETHER_TYPE_IPV4 0x0800 /* IPV4 type */
55 
57  struct eth_core_resources core_resources; /* A struct to hold ETH core resources */
58  struct doca_eth_txq *eth_txq; /* DOCA ETH TXQ context */
59  struct doca_buf *lso_eth_payload_bufs[BUFS_NUM]; /* DOCA buffers array to contain LSO ethernet payloads */
60  struct doca_gather_list *lso_pkt_headers[GATHER_LISTS_NUM]; /* DOCA gather lists array to contain LSO packet
61  headers */
62  struct doca_task_batch *lso_send_task_batch; /* LSO send task batch */
63  uint8_t *lso_pkt_headers_buf; /* Buffer to create lso_pkt_headers with */
64  uint8_t src_mac_addr[DOCA_DEVINFO_MAC_ADDR_SIZE]; /* Device MAC address */
65  uint32_t inflight_task_batches; /* In flight task batches */
66 };
67 
68 /*
69  * ETH TXQ LSO send task batch common callback
70  *
71  * @task_batch [in]: Completed task batch
72  * @tasks_num [in]: Task number associated with task batch
73  * @ctx_user_data [in]: User provided data, used to store sample state
74  * @task_batch_user_data [in]: User provided data, used for identifying the task batch
75  * @task_user_data_array [in]: Array of user provided data, each used for identifying the task behind task batch
76  * @pkt_payload_array [in]: Array of packet payloads, each associated to one LSO send task that's part of the LSO send
77  * task batch
78  * @headers_array [in]: Array of headers, each associated to one LSO send task that's part of the LSO send task batch
79  * @status_array [in]: Array of status, each associated to one LSO send task that's part of the LSO send task batch (in
80  * successful CB, all are DOCA_SUCCESS)
81  */
82 static void task_batch_lso_send_common_cb(struct doca_task_batch *task_batch,
83  uint16_t tasks_num,
84  union doca_data ctx_user_data,
85  union doca_data task_batch_user_data,
86  union doca_data *task_user_data_array,
87  struct doca_buf **pkt_payload_array,
88  struct doca_gather_list **headers_array,
89  doca_error_t *status_array)
90 {
91  doca_error_t status;
92  size_t packet_payload_size;
93  uint32_t *inflight_task_batches;
94 
95  inflight_task_batches = (uint32_t *)ctx_user_data.ptr;
96  (*inflight_task_batches)--;
97  DOCA_LOG_INFO("LSO send task batch user data is 0x%lx", task_batch_user_data.u64);
98 
99  for (uint32_t i = 0; i < tasks_num; i++) {
100  if (status_array[i] != DOCA_SUCCESS) {
101  DOCA_LOG_ERR("Packet#%u associated with user data %lu: failed to send this packet, err: %s",
102  i,
103  task_user_data_array[i].u64,
104  doca_error_get_name(status_array[i]));
105  } else {
106  status = doca_buf_get_data_len(pkt_payload_array[i], &packet_payload_size);
107  if (status != DOCA_SUCCESS) {
108  DOCA_LOG_ERR(
109  "Packet#%u associated with user data %lu: failed to get successfully sent packet's payload size, err: %s",
110  i,
111  task_user_data_array[i].u64,
112  doca_error_get_name(status));
113  } else {
115  "Packet#%u associated with user data %lu: packet with payload size %lu was sent successfully",
116  i,
117  task_user_data_array[i].u64,
118  packet_payload_size);
119  }
120  }
121 
122  status = doca_buf_dec_refcount(pkt_payload_array[i], NULL);
123  if (status != DOCA_SUCCESS)
124  DOCA_LOG_ERR("Packet#%u: failed to free packet payload buf, err: %s",
125  i,
126  doca_error_get_name(status));
127 
128  free(headers_array[i]);
129  }
130 
131  doca_task_batch_free(task_batch);
132 }
133 
134 /*
135  * Destroy ETH TXQ context related resources
136  *
137  * @state [in]: eth_txq_batch_lso_send_sample_objects struct to destroy its ETH TXQ context
138  * @return: DOCA_SUCCESS on success, DOCA_ERROR otherwise
139  */
141 {
142  doca_error_t status;
143  enum doca_ctx_states ctx_state;
144  struct timespec ts = {
145  .tv_sec = 0,
146  .tv_nsec = SLEEP_IN_NANOS,
147  };
148 
149  status = doca_ctx_stop(state->core_resources.core_objs.ctx);
150  if (status == DOCA_ERROR_IN_PROGRESS) {
151  while (state->inflight_task_batches != 0) {
153  nanosleep(&ts, &ts);
154  }
155 
156  status = doca_ctx_get_state(state->core_resources.core_objs.ctx, &ctx_state);
157  if (status != DOCA_SUCCESS) {
158  DOCA_LOG_ERR("Failed get status of context, err: %s", doca_error_get_name(status));
159  return status;
160  }
161 
162  status = ctx_state == DOCA_CTX_STATE_IDLE ? DOCA_SUCCESS : DOCA_ERROR_BAD_STATE;
163  }
164 
165  if (status != DOCA_SUCCESS) {
166  DOCA_LOG_ERR("Failed to stop DOCA context, err: %s", doca_error_get_name(status));
167  return status;
168  }
169 
170  status = doca_eth_txq_destroy(state->eth_txq);
171  if (status != DOCA_SUCCESS) {
172  DOCA_LOG_ERR("Failed to destroy DOCA ETH TXQ context, err: %s", doca_error_get_name(status));
173  return status;
174  }
175 
176  return DOCA_SUCCESS;
177 }
178 
179 /*
180  * Destroy DOCA gather_lists for the packet headers
181  *
182  * @state [in]: eth_txq_batch_lso_send_sample_objects struct to destroy its packet headers DOCA gather_lists
183  * @return: DOCA_SUCCESS on success, DOCA_ERROR otherwise
184  */
186 {
187  for (uint32_t i = 0; i < GATHER_LISTS_NUM; i++)
188  free(state->lso_pkt_headers[i]);
189 
190  return DOCA_SUCCESS;
191 }
192 
193 /*
194  * Destroy DOCA buffers for the packet payloads
195  *
196  * @state [in]: eth_txq_batch_lso_send_sample_objects struct to destroy its packet payloads DOCA buffers
197  * @return: DOCA_SUCCESS on success, DOCA_ERROR otherwise
198  */
200 {
201  doca_error_t status;
202 
203  for (uint32_t i = 0; i < BUFS_NUM; i++) {
204  status = doca_buf_dec_refcount(state->lso_eth_payload_bufs[i], NULL);
205  if (status != DOCA_SUCCESS) {
206  DOCA_LOG_ERR("Failed to destroy lso_eth_payload_buf[%u] buffer, err: %s",
207  i,
208  doca_error_get_name(status));
209  return status;
210  }
211  }
212 
213  return DOCA_SUCCESS;
214 }
215 
216 /*
217  * Destroy ETH TXQ task batch
218  *
219  * @state [in]: eth_txq_batch_lso_send_sample_objects struct to destroy its task batch
220  */
222 {
224 }
225 
226 /*
227  * Retrieve ETH TXQ task batch
228  *
229  * @state [in]: eth_txq_batch_lso_send_sample_objects struct to retrieve its task batch
230  */
232 {
233  struct timespec ts = {
234  .tv_sec = 0,
235  .tv_nsec = SLEEP_IN_NANOS,
236  };
237 
238  while (state->inflight_task_batches != 0) {
240  nanosleep(&ts, &ts);
241  }
242 }
243 
244 /*
245  * Submit ETH TXQ task batch
246  *
247  * @state [in/out]: eth_txq_batch_lso_send_sample_objects struct to submit its task batch
248  * @return: DOCA_SUCCESS on success, DOCA_ERROR otherwise
249  */
251 {
252  doca_error_t status;
253 
255  if (status != DOCA_SUCCESS) {
256  DOCA_LOG_ERR("Failed to submit LSO send task batch, err: %s", doca_error_get_name(status));
257  return status;
258  }
259 
260  state->inflight_task_batches++;
261 
262  return DOCA_SUCCESS;
263 }
264 
265 /*
266  * Create ETH TXQ task batch
267  *
268  * @state [in/out]: eth_txq_batch_lso_send_sample_objects struct to create task batch with its ETH TXQ context
269  * @return: DOCA_SUCCESS on success, DOCA_ERROR otherwise
270  */
272 {
273  doca_error_t status;
274  union doca_data task_batch_user_data;
275  struct doca_buf **pkt_payload_array;
276  struct doca_gather_list **headers_array;
277  union doca_data *task_user_data_array;
278 
279  task_batch_user_data.u64 = LSO_SEND_TASK_USER_DATA;
282  task_batch_user_data,
283  &pkt_payload_array,
284  &headers_array,
285  &task_user_data_array,
286  &(state->lso_send_task_batch));
287  if (status != DOCA_SUCCESS) {
288  DOCA_LOG_ERR("Failed to allocate LSO send task batch, err: %s", doca_error_get_name(status));
289  return status;
290  }
291 
292  for (uint32_t i = 0; i < TASKS_IN_TASK_BATCH; i++) {
293  pkt_payload_array[i] = state->lso_eth_payload_bufs[i];
294  headers_array[i] = state->lso_pkt_headers[i];
295  task_user_data_array[i].u64 = i;
296  }
297 
298  return DOCA_SUCCESS;
299 }
300 
301 /*
302  * Create DOCA gather_lists for the packet headers
303  *
304  * @state [in/out]: eth_txq_batch_lso_send_sample_objects struct to create its packet headers DOCA gather_lists
305  * @return: DOCA_SUCCESS on success, DOCA_ERROR otherwise
306  */
308 {
309  doca_error_t status = DOCA_SUCCESS;
310  uint32_t i;
311 
312  for (i = 0; i < GATHER_LISTS_NUM; i++) {
313  state->lso_pkt_headers[i] = (struct doca_gather_list *)malloc(sizeof(struct doca_gather_list));
314  if (state->lso_pkt_headers[i] == NULL) {
315  status = DOCA_ERROR_NO_MEMORY;
316  DOCA_LOG_ERR("Failed to create lso_pkt_headers[%u] gather_list, err: %s",
317  i,
318  doca_error_get_name(status));
319  break;
320  }
321  }
322 
323  if (status != DOCA_SUCCESS) {
324  for (uint32_t j = 0; j < i; j++)
325  free(state->lso_pkt_headers[j]);
326 
327  return status;
328  }
329 
330  return DOCA_SUCCESS;
331 }
332 
333 /*
334  * Create DOCA buffers for the packets
335  *
336  * @dest_mac_addr [in]: Destination MAC address to set in ethernet header
337  * @state [in/out]: eth_txq_batch_lso_send_sample_objects struct to create its packet DOCA buffers
338  * @return: DOCA_SUCCESS on success, DOCA_ERROR otherwise
339  */
342 {
343  doca_error_t status, clean_status;
344  void *payload_addr;
345  struct ether_hdr *header_addr;
346  uint32_t i;
347 
348  for (i = 0; i < BUFS_NUM; i++) {
349  payload_addr = (void *)(((uint8_t *)state->core_resources.mmap_addr) + (i * LSO_PKT_SIZE));
352  payload_addr,
353  LSO_PKT_SIZE,
354  &(state->lso_eth_payload_bufs[i]));
355  if (status != DOCA_SUCCESS) {
356  DOCA_LOG_ERR("Failed to create DOCA buffer for LSO ethernet payload, err: %s",
357  doca_error_get_name(status));
358  break;
359  }
360 
361  header_addr = ((struct ether_hdr *)state->lso_pkt_headers_buf) + i;
362  state->lso_pkt_headers[i]->addr = (void *)header_addr;
363  state->lso_pkt_headers[i]->len = sizeof(struct ether_hdr);
364  state->lso_pkt_headers[i]->next = NULL;
365 
366  /* Create LSO packet header + payload */
367  memcpy(&(header_addr->src_addr), state->src_mac_addr, DOCA_DEVINFO_MAC_ADDR_SIZE);
368  memcpy(&(header_addr->dst_addr), dest_mac_addr, DOCA_DEVINFO_MAC_ADDR_SIZE);
369  header_addr->ether_type = htobe16(ETHER_TYPE_IPV4);
370  memset(payload_addr, i, LSO_PKT_SIZE - sizeof(struct ether_hdr));
371  }
372 
373  if (status != DOCA_SUCCESS) {
374  for (uint32_t j = 0; j < i; j++) {
375  clean_status = doca_buf_dec_refcount(state->lso_eth_payload_bufs[j], NULL);
376  if (clean_status != DOCA_SUCCESS)
377  return status;
378  }
379  }
380 
381  return DOCA_SUCCESS;
382 }
383 
384 /*
385  * Create ETH TXQ context related resources
386  *
387  * @state [in/out]: eth_txq_batch_lso_send_sample_objects struct to create its ETH TXQ context
388  * @return: DOCA_SUCCESS on success, DOCA_ERROR otherwise
389  */
391 {
392  doca_error_t status, clean_status;
393  union doca_data user_data;
394 
396  if (status != DOCA_SUCCESS) {
397  DOCA_LOG_ERR("Failed to create ETH TXQ context, err: %s", doca_error_get_name(status));
398  return status;
399  }
400 
401  status = doca_eth_txq_set_mss(state->eth_txq, MSS);
402  if (status != DOCA_SUCCESS) {
403  DOCA_LOG_ERR("Failed to set MSS, err: %s", doca_error_get_name(status));
404  goto destroy_eth_txq;
405  }
406 
408  if (status != DOCA_SUCCESS) {
409  DOCA_LOG_ERR("Failed to set max_lso_header_size, err: %s", doca_error_get_name(status));
410  goto destroy_eth_txq;
411  }
412 
414  if (status != DOCA_SUCCESS) {
415  DOCA_LOG_ERR("Failed to set type, err: %s", doca_error_get_name(status));
416  goto destroy_eth_txq;
417  }
418 
424  if (status != DOCA_SUCCESS) {
425  DOCA_LOG_ERR("Failed to configure LSO send task batch, err: %s", doca_error_get_name(status));
426  goto destroy_eth_txq;
427  }
428 
430  if (state->core_resources.core_objs.ctx == NULL) {
431  DOCA_LOG_ERR("Failed to retrieve DOCA ETH TXQ context as DOCA context, err: %s",
432  doca_error_get_name(status));
433  goto destroy_eth_txq;
434  }
435 
437  if (status != DOCA_SUCCESS) {
438  DOCA_LOG_ERR("Failed to connect PE, err: %s", doca_error_get_name(status));
439  goto destroy_eth_txq;
440  }
441 
442  user_data.ptr = &(state->inflight_task_batches);
443  status = doca_ctx_set_user_data(state->core_resources.core_objs.ctx, user_data);
444  if (status != DOCA_SUCCESS) {
445  DOCA_LOG_ERR("Failed to set user data for DOCA context, err: %s", doca_error_get_name(status));
446  goto destroy_eth_txq;
447  }
448 
449  status = doca_ctx_start(state->core_resources.core_objs.ctx);
450  if (status != DOCA_SUCCESS) {
451  DOCA_LOG_ERR("Failed to start DOCA context, err: %s", doca_error_get_name(status));
452  goto destroy_eth_txq;
453  }
454 
455  return DOCA_SUCCESS;
456 destroy_eth_txq:
457  clean_status = doca_eth_txq_destroy(state->eth_txq);
458  state->eth_txq = NULL;
459 
460  if (clean_status != DOCA_SUCCESS)
461  return clean_status;
462 
463  return status;
464 }
465 
466 /*
467  * Clean sample resources
468  *
469  * @state [in]: eth_txq_batch_lso_send_sample_objects struct to clean
470  */
472 {
473  doca_error_t status;
474 
475  if (state->lso_pkt_headers_buf != NULL)
476  free(state->lso_pkt_headers_buf);
477 
478  if (state->eth_txq != NULL) {
479  status = destroy_eth_txq_ctx(state);
480  if (status != DOCA_SUCCESS) {
481  DOCA_LOG_ERR("Failed to destroy eth_txq_ctx, err: %s", doca_error_get_name(status));
482  return;
483  }
484  }
485 
486  if (state->core_resources.core_objs.dev != NULL) {
487  status = destroy_eth_core_resources(&(state->core_resources));
488  if (status != DOCA_SUCCESS) {
489  DOCA_LOG_ERR("Failed to destroy core_resources, err: %s", doca_error_get_name(status));
490  return;
491  }
492  }
493 }
494 
495 /*
496  * Check if device supports needed capabilities
497  *
498  * @devinfo [in]: Device info for device to check
499  * @return: DOCA_SUCCESS in case the device supports needed capabilities and DOCA_ERROR otherwise
500  */
501 static doca_error_t check_device(struct doca_devinfo *devinfo)
502 {
503  doca_error_t status;
504  uint32_t max_supported_burst_size;
505  uint16_t max_supported_lso_header_size;
506 
507  status = doca_eth_txq_cap_get_max_burst_size(devinfo,
510  &max_supported_burst_size);
511  if (status != DOCA_SUCCESS) {
512  DOCA_LOG_ERR("Failed to get supported max burst size, err: %s", doca_error_get_name(status));
513  return status;
514  }
515 
516  if (max_supported_burst_size < MAX_BURST_SIZE)
518 
519  status = doca_eth_txq_cap_get_max_lso_header_size(devinfo, &max_supported_lso_header_size);
520  if (status != DOCA_SUCCESS) {
521  DOCA_LOG_ERR("Failed to get supported max lso header size, err: %s", doca_error_get_name(status));
522  return status;
523  }
524 
525  if (max_supported_lso_header_size < MAX_LSO_HEADER_SIZE)
527 
528  status =
530  if (status != DOCA_SUCCESS && status != DOCA_ERROR_NOT_SUPPORTED) {
531  DOCA_LOG_ERR("Failed to check supported type, err: %s", doca_error_get_name(status));
532  return status;
533  }
534 
535  return status;
536 }
537 
538 /*
539  * Run ETH TXQ batch LSO send ethernet frames
540  *
541  * @ib_dev_name [in]: IB device name of a doca device
542  * @dest_mac_addr [in]: destination MAC address to associate with the ethernet frames
543  * @return: DOCA_SUCCESS on success, DOCA_ERROR otherwise
544  */
545 doca_error_t eth_txq_batch_lso_send_ethernet_frames(const char *ib_dev_name, uint8_t *dest_mac_addr)
546 {
547  doca_error_t status, clean_status;
549  struct eth_core_config cfg = {.mmap_size = LSO_PKT_SIZE * BUFS_NUM,
550  .inventory_num_elements = BUFS_NUM,
551  .check_device = check_device,
552  .ibdev_name = ib_dev_name};
553 
554  memset(&state, 0, sizeof(struct eth_txq_batch_lso_send_sample_objects));
555  status = allocate_eth_core_resources(&cfg, &(state.core_resources));
556  if (status != DOCA_SUCCESS) {
557  DOCA_LOG_ERR("Failed allocate core resources, err: %s", doca_error_get_name(status));
558  return status;
559  }
560 
562  state.src_mac_addr,
564  if (status != DOCA_SUCCESS) {
565  DOCA_LOG_ERR("Failed to get device MAC address, err: %s", doca_error_get_name(status));
566  goto txq_lso_cleanup;
567  }
568 
569  status = create_eth_txq_ctx(&state);
570  if (status != DOCA_SUCCESS) {
571  DOCA_LOG_ERR("Failed to create/start ETH TXQ context, err: %s", doca_error_get_name(status));
572  goto txq_lso_cleanup;
573  }
574 
575  state.lso_pkt_headers_buf = (uint8_t *)malloc(sizeof(struct ether_hdr) * GATHER_LISTS_NUM);
576  if (state.lso_pkt_headers_buf == NULL) {
577  DOCA_LOG_ERR("Failed to allocate memory for LSO packet headers");
578  status = DOCA_ERROR_NO_MEMORY;
579  goto txq_lso_cleanup;
580  }
581 
583  if (status != DOCA_SUCCESS) {
584  DOCA_LOG_ERR("Failed to create packet headers gather_lists, err: %s", doca_error_get_name(status));
585  goto txq_lso_cleanup;
586  }
587 
588  status = create_eth_txq_lso_packet_payload_buffers(dest_mac_addr, &state);
589  if (status != DOCA_SUCCESS) {
590  DOCA_LOG_ERR("Failed to create packet payload buffers, err: %s", doca_error_get_name(status));
591  goto destroy_packet_headers_buffers;
592  }
593 
594  status = create_eth_txq_task_batch(&state);
595  if (status != DOCA_SUCCESS) {
596  DOCA_LOG_ERR("Failed to create task batch, err: %s", doca_error_get_name(status));
597  goto destroy_packet_payloads_buffers;
598  }
599 
600  status = submit_eth_txq_task_batch(&state);
601  if (status != DOCA_SUCCESS) {
602  DOCA_LOG_ERR("Failed to submit task batch, err: %s", doca_error_get_name(status));
603  goto destroy_txq_task_batch;
604  }
605 
607 
608  goto txq_lso_cleanup;
609 
610 destroy_txq_task_batch:
612 destroy_packet_payloads_buffers:
613  clean_status = destroy_eth_txq_packet_payload_buffers(&state);
614  if (clean_status != DOCA_SUCCESS)
615  return clean_status;
616 destroy_packet_headers_buffers:
617  clean_status = destroy_eth_txq_packet_headers_gather_lists(&state);
618  if (clean_status != DOCA_SUCCESS)
619  return clean_status;
620 txq_lso_cleanup:
621  eth_txq_lso_cleanup(&state);
622 
623  return status;
624 }
#define NULL
Definition: __stddef_null.h:26
doca_error_t destroy_eth_core_resources(struct eth_core_resources *resources)
Definition: eth_common.c:98
doca_error_t allocate_eth_core_resources(struct eth_core_config *cfg, struct eth_core_resources *resources)
Definition: eth_common.c:38
static doca_error_t create_eth_txq_packet_headers_gather_lists(struct eth_txq_batch_lso_send_sample_objects *state)
static doca_error_t create_eth_txq_task_batch(struct eth_txq_batch_lso_send_sample_objects *state)
static void task_batch_lso_send_common_cb(struct doca_task_batch *task_batch, uint16_t tasks_num, union doca_data ctx_user_data, union doca_data task_batch_user_data, union doca_data *task_user_data_array, struct doca_buf **pkt_payload_array, struct doca_gather_list **headers_array, doca_error_t *status_array)
static doca_error_t create_eth_txq_lso_packet_payload_buffers(uint8_t *dest_mac_addr, struct eth_txq_batch_lso_send_sample_objects *state)
static doca_error_t destroy_eth_txq_packet_payload_buffers(struct eth_txq_batch_lso_send_sample_objects *state)
static void eth_txq_lso_cleanup(struct eth_txq_batch_lso_send_sample_objects *state)
static doca_error_t create_eth_txq_ctx(struct eth_txq_batch_lso_send_sample_objects *state)
static void retrieve_eth_txq_task_batch(struct eth_txq_batch_lso_send_sample_objects *state)
static doca_error_t submit_eth_txq_task_batch(struct eth_txq_batch_lso_send_sample_objects *state)
doca_error_t eth_txq_batch_lso_send_ethernet_frames(const char *ib_dev_name, uint8_t *dest_mac_addr)
static doca_error_t destroy_eth_txq_packet_headers_gather_lists(struct eth_txq_batch_lso_send_sample_objects *state)
DOCA_LOG_REGISTER(ETH_TXQ_BATCH_LSO_SEND_ETHERNET_FRAMES)
static doca_error_t destroy_eth_txq_ctx(struct eth_txq_batch_lso_send_sample_objects *state)
static doca_error_t check_device(struct doca_devinfo *devinfo)
static void destroy_eth_txq_task_batch(struct eth_txq_batch_lso_send_sample_objects *state)
static doca_error_t doca_buf_inventory_buf_get_by_data(struct doca_buf_inventory *inventory, struct doca_mmap *mmap, void *data, size_t data_len, struct doca_buf **buf)
Allocate single element from buffer inventory and point it to the buffer defined by data & data_len a...
DOCA_STABLE doca_error_t doca_buf_dec_refcount(struct doca_buf *buf, uint16_t *refcount)
Decrease the object reference count by 1, if 0 reached, return the element back to the inventory.
DOCA_STABLE doca_error_t doca_buf_get_data_len(const struct doca_buf *buf, size_t *data_len)
Get buffer's data length.
DOCA_STABLE doca_error_t doca_ctx_start(struct doca_ctx *ctx)
Finalizes all configurations, and starts the DOCA CTX.
DOCA_STABLE doca_error_t doca_ctx_get_state(const struct doca_ctx *ctx, enum doca_ctx_states *state)
Get context state.
DOCA_STABLE doca_error_t doca_ctx_set_user_data(struct doca_ctx *ctx, union doca_data user_data)
set user data to context
DOCA_STABLE doca_error_t doca_ctx_stop(struct doca_ctx *ctx)
Stops the context allowing reconfiguration.
doca_ctx_states
This enum defines the states of a context.
Definition: doca_ctx.h:83
@ DOCA_CTX_STATE_IDLE
Definition: doca_ctx.h:88
#define DOCA_DEVINFO_MAC_ADDR_SIZE
Length of MAC address.
Definition: doca_dev.h:301
DOCA_STABLE doca_error_t doca_devinfo_get_mac_addr(const struct doca_devinfo *devinfo, uint8_t *mac_addr, uint32_t size)
Get the MAC address of a DOCA devinfo.
DOCA_STABLE struct doca_devinfo * doca_dev_as_devinfo(const struct doca_dev *dev)
Get local device info from device. This should be useful when wanting to query information about devi...
enum doca_error doca_error_t
DOCA API return codes.
DOCA_STABLE const char * doca_error_get_name(doca_error_t error)
Returns the string representation of an error code name.
@ DOCA_ERROR_BAD_STATE
Definition: doca_error.h:56
@ DOCA_ERROR_NOT_SUPPORTED
Definition: doca_error.h:42
@ DOCA_SUCCESS
Definition: doca_error.h:38
@ DOCA_ERROR_NO_MEMORY
Definition: doca_error.h:45
@ DOCA_ERROR_IN_PROGRESS
Definition: doca_error.h:64
DOCA_EXPERIMENTAL doca_error_t doca_eth_txq_task_batch_lso_send_allocate(struct doca_eth_txq *eth_txq, uint16_t tasks_num, union doca_data task_batch_user_data, struct doca_buf ***pkt_payload_array, struct doca_gather_list ***headers_array, union doca_data **task_user_data_array, struct doca_task_batch **task_batch)
This method allocates a doca_taskbtach of doca_eth_txq_task_lso_send tasks.
DOCA_EXPERIMENTAL doca_error_t doca_eth_txq_task_batch_lso_send_set_conf(struct doca_eth_txq *eth_txq, enum doca_task_batch_max_tasks_number max_tasks_number, uint16_t num_task_batches, doca_eth_txq_task_batch_lso_send_completion_cb_t success_completion_cb, doca_eth_txq_task_batch_lso_send_completion_cb_t error_completion_cb)
This method sets the task_batch of LSO send tasks configuration.
DOCA_EXPERIMENTAL struct doca_ctx * doca_eth_txq_as_doca_ctx(struct doca_eth_txq *eth_txq)
Convert doca_eth_txq instance into a generalized context for use with doca core objects.
DOCA_EXPERIMENTAL doca_error_t doca_eth_txq_cap_get_max_burst_size(const struct doca_devinfo *devinfo, uint32_t max_send_buf_list_len, uint16_t max_lso_header_size, uint32_t *max_burst_size)
Get the maximum burst size supported by the device.
DOCA_EXPERIMENTAL doca_error_t doca_eth_txq_create(struct doca_dev *dev, uint32_t max_burst_size, struct doca_eth_txq **eth_txq)
Create a DOCA ETH TXQ instance.
DOCA_EXPERIMENTAL doca_error_t doca_eth_txq_destroy(struct doca_eth_txq *eth_txq)
Destroy a DOCA ETH TXQ instance.
DOCA_EXPERIMENTAL doca_error_t doca_eth_txq_set_type(struct doca_eth_txq *eth_txq, enum doca_eth_txq_type type)
Set TX queue type property for doca_eth_txq. can only be called before calling doca_ctx_start().
DOCA_EXPERIMENTAL doca_error_t doca_eth_txq_cap_is_type_supported(const struct doca_devinfo *devinfo, enum doca_eth_txq_type type, enum doca_eth_txq_data_path_type data_path_type)
Check if TX queue type is supported.
DOCA_EXPERIMENTAL doca_error_t doca_eth_txq_set_mss(struct doca_eth_txq *eth_txq, uint16_t mss)
Set the Maximum Segment Size for doca_eth_txq. This value will be used per LSO send task / task_batch...
DOCA_EXPERIMENTAL doca_error_t doca_eth_txq_set_max_lso_header_size(struct doca_eth_txq *eth_txq, uint16_t max_lso_header_size)
Set the maximum LSO header size for doca_eth_txq. This value is the maximum header size of the LSO pa...
DOCA_EXPERIMENTAL doca_error_t doca_eth_txq_cap_get_max_lso_header_size(const struct doca_devinfo *devinfo, uint16_t *max_lso_header_size)
Get the maximum header size of an LSO packet supported by the device.
@ DOCA_ETH_TXQ_DATA_PATH_TYPE_CPU
Definition: doca_eth_txq.h:72
@ DOCA_ETH_TXQ_TYPE_REGULAR
Definition: doca_eth_txq.h:65
#define DOCA_LOG_ERR(format,...)
Generates an ERROR application log message.
Definition: doca_log.h:466
#define DOCA_LOG_INFO(format,...)
Generates an INFO application log message.
Definition: doca_log.h:486
DOCA_STABLE doca_error_t doca_pe_connect_ctx(struct doca_pe *pe, struct doca_ctx *ctx)
This method connects a context to a progress engine.
DOCA_EXPERIMENTAL void doca_task_batch_free(struct doca_task_batch *task_batch)
Free a task_batch back to where it was allocated from.
DOCA_STABLE uint8_t doca_pe_progress(struct doca_pe *pe)
Run the progress engine.
DOCA_EXPERIMENTAL doca_error_t doca_task_batch_submit(struct doca_task_batch *task_batch)
Submit a task_batch to a progress engine.
@ DOCA_TASK_BATCH_MAX_TASKS_NUMBER_64
Definition: doca_pe.h:51
uint64_t u64
const struct ip_frag_config * cfg
Definition: ip_frag_dp.c:0
#define htobe16
Definition: os_utils.hpp:39
Struct to represent a gather list.
Definition: doca_types.h:64
struct doca_gather_list * next
Definition: doca_types.h:67
uint64_t len
Definition: doca_types.h:66
struct program_core_objects core_objs
Definition: eth_common.h:40
struct doca_gather_list * lso_pkt_headers[GATHER_LISTS_NUM]
uint8_t dst_addr[DOCA_DEVINFO_MAC_ADDR_SIZE]
Definition: eth_common.h:54
uint16_t ether_type
Definition: packets.h:63
uint8_t src_addr[DOCA_DEVINFO_MAC_ADDR_SIZE]
Definition: eth_common.h:55
struct doca_pe * pe
Definition: common.h:51
struct doca_mmap * src_mmap
Definition: common.h:47
struct doca_buf_inventory * buf_inv
Definition: common.h:49
struct doca_dev * dev
Definition: common.h:46
struct doca_ctx * ctx
Definition: common.h:50
Convenience type for representing opaque data.
Definition: doca_types.h:56
uint64_t u64
Definition: doca_types.h:58
void * ptr
Definition: doca_types.h:57