+static_always_inline int
+avf_tx_fill_ctx_desc (vlib_main_t * vm, avf_txq_t * txq, avf_tx_desc_t * d,
+ vlib_buffer_t * b)
+{
+ vlib_buffer_t *ctx_ph = vlib_get_buffer (vm, txq->ctx_desc_placeholder_bi);
+ if (PREDICT_FALSE (ctx_ph->ref_count == 255))
+ {
+ /* We need a new placeholder buffer */
+ u32 new_bi;
+ u8 bpi = vlib_buffer_pool_get_default_for_numa (vm, vm->numa_node);
+ if (PREDICT_TRUE
+ (vlib_buffer_alloc_from_pool (vm, &new_bi, 1, bpi) == 1))
+ {
+ /* Remove our own reference on the current placeholder buffer */
+ ctx_ph->ref_count--;
+ /* Replace with the new placeholder buffer */
+ txq->ctx_desc_placeholder_bi = new_bi;
+ ctx_ph = vlib_get_buffer (vm, new_bi);
+ }
+ else
+ /* Impossible to enqueue a ctx descriptor, fail */
+ return 1;
+ }
+
+ /* Acquire a reference on the placeholder buffer */
+ ctx_ph->ref_count++;
+
+ u16 l234hdr_sz =
+ vnet_buffer (b)->l4_hdr_offset -
+ vnet_buffer (b)->l2_hdr_offset + vnet_buffer2 (b)->gso_l4_hdr_sz;
+ u16 tlen = vlib_buffer_length_in_chain (vm, b) - l234hdr_sz;
+ d[0].qword[0] = 0;
+ d[0].qword[1] = AVF_TXD_DTYP_CTX | AVF_TXD_CTX_CMD_TSO
+ | AVF_TXD_CTX_SEG_MSS (vnet_buffer2 (b)->gso_size) |
+ AVF_TXD_CTX_SEG_TLEN (tlen);
+ return 0;
+}
+
+