/** * tso_fill_packet_with_fragment - form descriptors for the current fragment * @tx_queue: Efx TX queue * @skb: Socket buffer * @st: TSO state * * Form descriptors for the current fragment, until we reach the end * of fragment or end-of-packet. Return 0 on success, 1 if not enough * space in @tx_queue. */ static inline int tso_fill_packet_with_fragment(struct efx_tx_queue *tx_queue, const struct sk_buff *skb, struct tso_state *st) { int n, end_of_packet, rc; if (st->ifc.len == 0) return 0; if (st->packet_space == 0) return 0; EFX_BUG_ON_PARANOID(st->ifc.len <= 0); EFX_BUG_ON_PARANOID(st->packet_space <= 0); n = min(st->ifc.len, st->packet_space); st->packet_space -= n; st->remaining_len -= n; st->ifc.len -= n; st->ifc.page_off += n; end_of_packet = st->remaining_len == 0 || st->packet_space == 0; rc = efx_tx_queue_insert(tx_queue, st->ifc.dma_addr, n, st->remaining_len ? NULL : skb, end_of_packet, st->ifc.unmap_addr, st->ifc.len ? 0 : st->ifc.unmap_len); st->ifc.dma_addr += n; return rc; }
/** * tso_fill_packet_with_fragment - form descriptors for the current fragment * @tx_queue: Efx TX queue * @skb: Socket buffer * @st: TSO state * * Form descriptors for the current fragment, until we reach the end * of fragment or end-of-packet. Return 0 on success, 1 if not enough * space in @tx_queue. */ static int tso_fill_packet_with_fragment(struct efx_tx_queue *tx_queue, const struct sk_buff *skb, struct tso_state *st) { struct efx_tx_buffer *buffer; int n, end_of_packet, rc; if (st->in_len == 0) return 0; if (st->packet_space == 0) return 0; EFX_BUG_ON_PARANOID(st->in_len <= 0); EFX_BUG_ON_PARANOID(st->packet_space <= 0); n = min(st->in_len, st->packet_space); st->packet_space -= n; st->out_len -= n; st->in_len -= n; rc = efx_tx_queue_insert(tx_queue, st->dma_addr, n, &buffer); if (likely(rc == 0)) { if (st->out_len == 0) /* Transfer ownership of the skb */ buffer->skb = skb; end_of_packet = st->out_len == 0 || st->packet_space == 0; buffer->continuation = !end_of_packet; if (st->in_len == 0) { /* Transfer ownership of the pci mapping */ buffer->unmap_len = st->unmap_len; buffer->unmap_single = st->unmap_single; st->unmap_len = 0; } } st->dma_addr += n; return rc; }
/** * tso_fill_packet_with_fragment - form descriptors for the current fragment * @tx_queue: Efx TX queue * @skb: Socket buffer * @st: TSO state * * Form descriptors for the current fragment, until we reach the end * of fragment or end-of-packet. */ static void tso_fill_packet_with_fragment(struct efx_tx_queue *tx_queue, const struct sk_buff *skb, struct tso_state *st) { struct efx_tx_buffer *buffer; int n; if (st->in_len == 0) return; if (st->packet_space == 0) return; EFX_WARN_ON_ONCE_PARANOID(st->in_len <= 0); EFX_WARN_ON_ONCE_PARANOID(st->packet_space <= 0); n = min(st->in_len, st->packet_space); st->packet_space -= n; st->out_len -= n; st->in_len -= n; efx_tx_queue_insert(tx_queue, st->dma_addr, n, &buffer); if (st->out_len == 0) { /* Transfer ownership of the skb */ buffer->skb = skb; buffer->flags = EFX_TX_BUF_SKB; } else if (st->packet_space != 0) { buffer->flags = EFX_TX_BUF_CONT; } if (st->in_len == 0) { /* Transfer ownership of the DMA mapping */ buffer->unmap_len = st->unmap_len; buffer->dma_offset = buffer->unmap_len - buffer->len; buffer->flags |= st->dma_flags; st->unmap_len = 0; } st->dma_addr += n; }