* Tx burst function for single-segment packets with TSO. * Supports all types of Tx offloads, except multi-packets. * Uses MLX5_OPCODE_TSO to build WQEs, sends one packet per WQE. * Function stops sending if it encounters the multi-segment * packet or packet without TSO requested. * * The routine is responsible for storing processed mbuf into elts ring buffer * and update elts_head if inlin
| 2344 | * Local context variables updated. |
| 2345 | */ |
| 2346 | static __rte_always_inline enum mlx5_txcmp_code |
| 2347 | mlx5_tx_burst_tso(struct mlx5_txq_data *__rte_restrict txq, |
| 2348 | struct rte_mbuf **__rte_restrict pkts, |
| 2349 | unsigned int pkts_n, |
| 2350 | struct mlx5_txq_local *__rte_restrict loc, |
| 2351 | unsigned int olx) |
| 2352 | { |
| 2353 | MLX5_ASSERT(loc->elts_free && loc->wqe_free); |
| 2354 | MLX5_ASSERT(pkts_n > loc->pkts_sent); |
| 2355 | pkts += loc->pkts_sent + 1; |
| 2356 | pkts_n -= loc->pkts_sent; |
| 2357 | for (;;) { |
| 2358 | struct mlx5_wqe_dseg *__rte_restrict dseg; |
| 2359 | struct mlx5_wqe *__rte_restrict wqe; |
| 2360 | unsigned int ds, dlen, hlen, ntcp, vlan = 0; |
| 2361 | uint8_t *dptr; |
| 2362 | |
| 2363 | MLX5_ASSERT(NB_SEGS(loc->mbuf) == 1); |
| 2364 | if (MLX5_TXOFF_CONFIG(TXPP)) { |
| 2365 | enum mlx5_txcmp_code wret; |
| 2366 | |
| 2367 | /* Generate WAIT for scheduling if requested. */ |
| 2368 | wret = mlx5_tx_schedule_send(txq, loc, 1, olx); |
| 2369 | if (wret == MLX5_TXCMP_CODE_EXIT) |
| 2370 | return MLX5_TXCMP_CODE_EXIT; |
| 2371 | if (wret == MLX5_TXCMP_CODE_ERROR) |
| 2372 | return MLX5_TXCMP_CODE_ERROR; |
| 2373 | } |
| 2374 | dlen = rte_pktmbuf_data_len(loc->mbuf); |
| 2375 | if (MLX5_TXOFF_CONFIG(VLAN) && |
| 2376 | loc->mbuf->ol_flags & RTE_MBUF_F_TX_VLAN) { |
| 2377 | vlan = sizeof(struct rte_vlan_hdr); |
| 2378 | } |
| 2379 | /* |
| 2380 | * First calculate the WQE size to check |
| 2381 | * whether we have enough space in ring buffer. |
| 2382 | */ |
| 2383 | hlen = loc->mbuf->l2_len + vlan + |
| 2384 | loc->mbuf->l3_len + loc->mbuf->l4_len; |
| 2385 | if (unlikely((!hlen || !loc->mbuf->tso_segsz))) |
| 2386 | return MLX5_TXCMP_CODE_ERROR; |
| 2387 | if (loc->mbuf->ol_flags & RTE_MBUF_F_TX_TUNNEL_MASK) |
| 2388 | hlen += loc->mbuf->outer_l2_len + |
| 2389 | loc->mbuf->outer_l3_len; |
| 2390 | /* Segment must contain all TSO headers. */ |
| 2391 | if (unlikely(hlen > MLX5_MAX_TSO_HEADER || |
| 2392 | hlen <= MLX5_ESEG_MIN_INLINE_SIZE || |
| 2393 | hlen > (dlen + vlan))) |
| 2394 | return MLX5_TXCMP_CODE_ERROR; |
| 2395 | /* |
| 2396 | * Check whether there are enough free WQEBBs: |
| 2397 | * - Control Segment |
| 2398 | * - Ethernet Segment |
| 2399 | * - First Segment of inlined Ethernet data |
| 2400 | * - ... data continued ... |
| 2401 | * - Finishing Data Segment of pointer type |
| 2402 | */ |
| 2403 | ds = 4 + (hlen - MLX5_ESEG_MIN_INLINE_SIZE + |
no test coverage detected