TX function modified to handle chained mbufs. Signed-off-by: Matej Vido <matejvido at gmail.com> Reviewed-by: Jan Viktorin <viktorin at rehivetech.com> --- drivers/net/szedata2/rte_eth_szedata2.c | 108 +++++++++++++++++++++++++++----- 1 file changed, 91 insertions(+), 17 deletions(-)
diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c index ddb45e4..e2d6501 100644 --- a/drivers/net/szedata2/rte_eth_szedata2.c +++ b/drivers/net/szedata2/rte_eth_szedata2.c @@ -737,7 +737,7 @@ eth_szedata2_tx(void *queue, next_packet: mbuf = bufs[nb_pkts - pkt_left]; - pkt_len = mbuf->data_len; + pkt_len = mbuf->pkt_len; mbuf_segs = mbuf->nb_segs; hwpkt_len = RTE_SZE2_PACKET_HEADER_SIZE_ALIGNED + @@ -764,9 +764,28 @@ next_packet: /* copy packet from mbuf */ tmp_dst = ((uint8_t *)(dst)) + RTE_SZE2_PACKET_HEADER_SIZE_ALIGNED; - rte_memcpy(tmp_dst, - rte_pktmbuf_mtod(mbuf, const void *), - pkt_len); + if (likely(mbuf_segs == 1)) { + /* + * non-scattered packet, + * transmit from one mbuf + */ + rte_memcpy(tmp_dst, + rte_pktmbuf_mtod(mbuf, const void *), + pkt_len); + } else { + /* scattered packet, transmit from more mbufs */ + struct rte_mbuf * m = mbuf; + while (m) { + rte_memcpy(tmp_dst, + rte_pktmbuf_mtod(m, + const void *), + m->data_len); + tmp_dst = ((uint8_t *)(tmp_dst)) + + m->data_len; + m = m->next; + } + } + dst = ((uint8_t *)dst) + hwpkt_len; unlock_size += hwpkt_len; @@ -805,19 +824,74 @@ next_packet: tmp_dst = ((uint8_t *)(dst)) + RTE_SZE2_PACKET_HEADER_SIZE_ALIGNED; - /* copy part of packet to first area */ - rte_memcpy(tmp_dst, - rte_pktmbuf_mtod(mbuf, const void *), - write_len); - - if (lck->next) - dst = lck->next->start; - - /* copy part of packet to second area */ - rte_memcpy(dst, - (const void *) (rte_pktmbuf_mtod(mbuf, - const uint8_t *) + - write_len), pkt_len - write_len); + if (likely(mbuf_segs == 1)) { + /* + * non-scattered packet, + * transmit from one mbuf + */ + /* copy part of packet to first area */ + rte_memcpy(tmp_dst, + rte_pktmbuf_mtod(mbuf, const void *), + write_len); + + if (lck->next) + dst = lck->next->start; + + /* copy part of packet to second area */ + rte_memcpy(dst, + (const void *) (rte_pktmbuf_mtod(mbuf, + const uint8_t *) + + write_len), pkt_len - write_len); + } else { + /* scattered packet, transmit from more mbufs */ + struct rte_mbuf * m = mbuf; + uint16_t written = 0; + uint16_t to_write = 0; + bool new_mbuf = true; + uint16_t write_off = 0; + + /* copy part of packet to first area */ + while (m && written < write_len) { + to_write = RTE_MIN(m->data_len, + write_len - written); + rte_memcpy(tmp_dst, + rte_pktmbuf_mtod(m, + const void *), + to_write); + + tmp_dst = ((uint8_t *)(tmp_dst)) + + to_write; + if (m->data_len <= write_len - + written) { + m = m->next; + new_mbuf = true; + } else { + new_mbuf = false; + } + written += to_write; + } + + if (lck->next) + dst = lck->next->start; + + tmp_dst = dst; + written = 0; + write_off = new_mbuf ? 0 : to_write; + + /* copy part of packet to second area */ + while (m && written < pkt_len - write_len) { + rte_memcpy(tmp_dst, (const void *) + (rte_pktmbuf_mtod(m, + uint8_t *) + write_off), + m->data_len - write_off); + + tmp_dst = ((uint8_t *)(tmp_dst)) + + (m->data_len - write_off); + written += m->data_len - write_off; + m = m->next; + write_off = 0; + } + } dst = ((uint8_t *)dst) + rem_len; unlock_size += hwpkt_len; -- 1.9.1