| 159 | } |
| 160 | |
| 161 | uint16_t |
| 162 | ionic_xmit_pkts_sg(void *tx_queue, struct rte_mbuf **tx_pkts, |
| 163 | uint16_t nb_pkts) |
| 164 | { |
| 165 | struct ionic_tx_qcq *txq = tx_queue; |
| 166 | struct ionic_queue *q = &txq->qcq.q; |
| 167 | struct ionic_tx_stats *stats = &txq->stats; |
| 168 | struct rte_mbuf *mbuf; |
| 169 | uint32_t bytes_tx = 0; |
| 170 | uint16_t nb_avail, nb_tx = 0; |
| 171 | uint64_t then, now, hz, delta; |
| 172 | int err; |
| 173 | |
| 174 | struct ionic_txq_desc *desc_base = q->base; |
| 175 | if (!(txq->flags & IONIC_QCQ_F_CMB)) |
| 176 | rte_prefetch0(&desc_base[q->head_idx]); |
| 177 | rte_prefetch0(IONIC_INFO_PTR(q, q->head_idx)); |
| 178 | |
| 179 | if (nb_pkts) { |
| 180 | rte_mbuf_prefetch_part1(tx_pkts[0]); |
| 181 | rte_mbuf_prefetch_part2(tx_pkts[0]); |
| 182 | } |
| 183 | |
| 184 | if (ionic_q_space_avail(q) < txq->free_thresh) { |
| 185 | /* Cleaning old buffers */ |
| 186 | ionic_tx_flush_sg(txq); |
| 187 | } |
| 188 | |
| 189 | nb_avail = ionic_q_space_avail(q); |
| 190 | if (nb_avail < nb_pkts) { |
| 191 | stats->stop += nb_pkts - nb_avail; |
| 192 | nb_pkts = nb_avail; |
| 193 | } |
| 194 | |
| 195 | while (nb_tx < nb_pkts) { |
| 196 | uint16_t next_idx = Q_NEXT_TO_POST(q, 1); |
| 197 | if (!(txq->flags & IONIC_QCQ_F_CMB)) |
| 198 | rte_prefetch0(&desc_base[next_idx]); |
| 199 | rte_prefetch0(IONIC_INFO_PTR(q, next_idx)); |
| 200 | |
| 201 | if (nb_tx + 1 < nb_pkts) { |
| 202 | rte_mbuf_prefetch_part1(tx_pkts[nb_tx + 1]); |
| 203 | rte_mbuf_prefetch_part2(tx_pkts[nb_tx + 1]); |
| 204 | } |
| 205 | |
| 206 | mbuf = tx_pkts[nb_tx]; |
| 207 | |
| 208 | if (mbuf->ol_flags & RTE_MBUF_F_TX_TCP_SEG) |
| 209 | err = ionic_tx_tso(txq, mbuf); |
| 210 | else |
| 211 | err = ionic_tx_sg(txq, mbuf); |
| 212 | if (err) { |
| 213 | stats->drop += nb_pkts - nb_tx; |
| 214 | break; |
| 215 | } |
| 216 | |
| 217 | bytes_tx += mbuf->pkt_len; |
| 218 | nb_tx++; |
nothing calls this directly
no test coverage detected