src/dpdk/drivers/net/octeontx_ep/otx_ep_rxtx.c
uint16_t
otx_ep_xmit_pkts(void *tx_queue, struct rte_mbuf **pkts, uint16_t nb_pkts)
{
	struct otx_ep_instr_64B iqcmd;
	struct otx_ep_instr_queue *iq;
	struct otx_ep_device *otx_ep;
	struct rte_mbuf *m;

	uint32_t iqreq_type, sgbuf_sz;
	int dbell, index, count = 0;
	unsigned int pkt_len, i;
	int gather, gsz;
	void *iqreq_buf;
	uint64_t dptr;

	iq = (struct otx_ep_instr_queue *)tx_queue;
	otx_ep = iq->otx_ep_dev;

	iqcmd.ih.u64 = 0;
	iqcmd.pki_ih3.u64 = 0;
	iqcmd.irh.u64 = 0;

	/* ih invars */
	iqcmd.ih.s.fsz = OTX_EP_FSZ;
	iqcmd.ih.s.pkind = otx_ep->pkind; /* The SDK decided PKIND value */

	/* pki ih3 invars */
	iqcmd.pki_ih3.s.w = 1;
	iqcmd.pki_ih3.s.utt = 1;
	iqcmd.pki_ih3.s.tagtype = ORDERED_TAG;
	/* sl will be sizeof(pki_ih3) */
	iqcmd.pki_ih3.s.sl = OTX_EP_FSZ + OTX_CUST_DATA_LEN;

	/* irh invars */
	iqcmd.irh.s.opcode = OTX_EP_NW_PKT_OP;

	for (i = 0; i < nb_pkts; i++) {
		m = pkts[i];
		if (m->nb_segs == 1) {
			/* dptr */
			dptr = rte_mbuf_data_iova(m);
			pkt_len = rte_pktmbuf_data_len(m);
			iqreq_buf = m;
			iqreq_type = OTX_EP_REQTYPE_NORESP_NET;
			gather = 0;
			gsz = 0;
		} else {
			struct otx_ep_buf_free_info *finfo;
			int j, frags, num_sg;

			if (!(otx_ep->tx_offloads & DEV_TX_OFFLOAD_MULTI_SEGS))
				goto xmit_fail;

			finfo = (struct otx_ep_buf_free_info *)rte_malloc(NULL,
							sizeof(*finfo), 0);
			if (finfo == NULL) {
				otx_ep_err("free buffer alloc failed\n");
				goto xmit_fail;
			}
			num_sg = (m->nb_segs + 3) / 4;
			sgbuf_sz = sizeof(struct otx_ep_sg_entry) * num_sg;
			finfo->g.sg =
				rte_zmalloc(NULL, sgbuf_sz, OTX_EP_SG_ALIGN);
			if (finfo->g.sg == NULL) {
				rte_free(finfo);
				otx_ep_err("sg entry alloc failed\n");
				goto xmit_fail;
			}
			gather = 1;
			gsz = m->nb_segs;
			finfo->g.num_sg = num_sg;
			finfo->g.sg[0].ptr[0] = rte_mbuf_data_iova(m);
			set_sg_size(&finfo->g.sg[0], m->data_len, 0);
			pkt_len = m->data_len;
			finfo->mbuf = m;

			frags = m->nb_segs - 1;
			j = 1;
			m = m->next;
			while (frags--) {
				finfo->g.sg[(j >> 2)].ptr[(j & 3)] =
						rte_mbuf_data_iova(m);
				set_sg_size(&finfo->g.sg[(j >> 2)],
						m->data_len, (j & 3));
				pkt_len += m->data_len;
				j++;
				m = m->next;
			}
			dptr = rte_mem_virt2iova(finfo->g.sg);
			iqreq_buf = finfo;
			iqreq_type = OTX_EP_REQTYPE_NORESP_GATHER;
			if (pkt_len > OTX_EP_MAX_PKT_SZ) {
				rte_free(finfo->g.sg);
				rte_free(finfo);
				otx_ep_err("failed\n");
				goto xmit_fail;
			}
		}
		/* ih vars */
		iqcmd.ih.s.tlen = pkt_len + iqcmd.ih.s.fsz;
		iqcmd.ih.s.gather = gather;
		iqcmd.ih.s.gsz = gsz;

		iqcmd.dptr = dptr;
		otx_ep_swap_8B_data(&iqcmd.irh.u64, 1);

#ifdef OTX_EP_IO_DEBUG
		otx_ep_dbg("After swapping\n");
		otx_ep_dbg("Word0 [dptr]: 0x%016lx\n",
			   (unsigned long)iqcmd.dptr);
		otx_ep_dbg("Word1 [ihtx]: 0x%016lx\n", (unsigned long)iqcmd.ih);
		otx_ep_dbg("Word2 [pki_ih3]: 0x%016lx\n",
			   (unsigned long)iqcmd.pki_ih3);
		otx_ep_dbg("Word3 [rptr]: 0x%016lx\n",
			   (unsigned long)iqcmd.rptr);
		otx_ep_dbg("Word4 [irh]: 0x%016lx\n", (unsigned long)iqcmd.irh);
		otx_ep_dbg("Word5 [exhdr[0]]: 0x%016lx\n",
				(unsigned long)iqcmd.exhdr[0]);
		rte_pktmbuf_dump(stdout, m, rte_pktmbuf_pkt_len(m));
#endif
		dbell = (i == (unsigned int)(nb_pkts - 1)) ? 1 : 0;
		index = iq->host_write_index;
		if (otx_ep_send_data(otx_ep, iq, &iqcmd, dbell))
			goto xmit_fail;
		otx_ep_iqreq_add(iq, iqreq_buf, iqreq_type, index);
		iq->stats.tx_pkts++;
		iq->stats.tx_bytes += pkt_len;
		count++;
	}

xmit_fail:
	if (iq->instr_pending >= OTX_EP_MAX_INSTR)
		otx_ep_flush_iq(iq);

	/* Return no# of instructions posted successfully. */
	return count;
}
/* Enqueue requests/packets to OTX_EP IQ queue.
 * returns number of requests enqueued successfully
 */
Enqueue requests/packets to OTX_EP IQ queue.
returns number of requests enqueued successfully
Enqueue requests / packets to OTX_EP IQ queue . returns number of requests enqueued successfully
uint16_t
otx_ep_xmit_pkts(void *tx_queue, struct rte_mbuf **pkts, uint16_t nb_pkts)
{
	struct otx_ep_instr_64B iqcmd;
	struct otx_ep_instr_queue *iq;
	struct otx_ep_device *otx_ep;
	struct rte_mbuf *m;
	uint32_t iqreq_type, sgbuf_sz;
	int dbell, index, count = 0;
	unsigned int pkt_len, i;
	int gather, gsz;
	void *iqreq_buf;
	uint64_t dptr;
	iq = (struct otx_ep_instr_queue *)tx_queue;
	otx_ep = iq->otx_ep_dev;
	iqcmd.ih.u64 = 0;
	iqcmd.pki_ih3.u64 = 0;
	iqcmd.irh.u64 = 0;
	iqcmd.ih.s.fsz = OTX_EP_FSZ;
	iqcmd.ih.s.pkind = otx_ep->pkind; 
	iqcmd.pki_ih3.s.w = 1;
	iqcmd.pki_ih3.s.utt = 1;
	iqcmd.pki_ih3.s.tagtype = ORDERED_TAG;
	iqcmd.pki_ih3.s.sl = OTX_EP_FSZ + OTX_CUST_DATA_LEN;
	iqcmd.irh.s.opcode = OTX_EP_NW_PKT_OP;
	for (i = 0; i < nb_pkts; i++) {
		m = pkts[i];
		if (m->nb_segs == 1) {
			dptr = rte_mbuf_data_iova(m);
			pkt_len = rte_pktmbuf_data_len(m);
			iqreq_buf = m;
			iqreq_type = OTX_EP_REQTYPE_NORESP_NET;
			gather = 0;
			gsz = 0;
		} else {
			struct otx_ep_buf_free_info *finfo;
			int j, frags, num_sg;
			if (!(otx_ep->tx_offloads & DEV_TX_OFFLOAD_MULTI_SEGS))
				goto xmit_fail;
			finfo = (struct otx_ep_buf_free_info *)rte_malloc(NULL,
							sizeof(*finfo), 0);
			if (finfo == NULL) {
				otx_ep_err("free buffer alloc failed\n");
				goto xmit_fail;
			}
			num_sg = (m->nb_segs + 3) / 4;
			sgbuf_sz = sizeof(struct otx_ep_sg_entry) * num_sg;
			finfo->g.sg =
				rte_zmalloc(NULL, sgbuf_sz, OTX_EP_SG_ALIGN);
			if (finfo->g.sg == NULL) {
				rte_free(finfo);
				otx_ep_err("sg entry alloc failed\n");
				goto xmit_fail;
			}
			gather = 1;
			gsz = m->nb_segs;
			finfo->g.num_sg = num_sg;
			finfo->g.sg[0].ptr[0] = rte_mbuf_data_iova(m);
			set_sg_size(&finfo->g.sg[0], m->data_len, 0);
			pkt_len = m->data_len;
			finfo->mbuf = m;
			frags = m->nb_segs - 1;
			j = 1;
			m = m->next;
			while (frags--) {
				finfo->g.sg[(j >> 2)].ptr[(j & 3)] =
						rte_mbuf_data_iova(m);
				set_sg_size(&finfo->g.sg[(j >> 2)],
						m->data_len, (j & 3));
				pkt_len += m->data_len;
				j++;
				m = m->next;
			}
			dptr = rte_mem_virt2iova(finfo->g.sg);
			iqreq_buf = finfo;
			iqreq_type = OTX_EP_REQTYPE_NORESP_GATHER;
			if (pkt_len > OTX_EP_MAX_PKT_SZ) {
				rte_free(finfo->g.sg);
				rte_free(finfo);
				otx_ep_err("failed\n");
				goto xmit_fail;
			}
		}
		iqcmd.ih.s.tlen = pkt_len + iqcmd.ih.s.fsz;
		iqcmd.ih.s.gather = gather;
		iqcmd.ih.s.gsz = gsz;
		iqcmd.dptr = dptr;
		otx_ep_swap_8B_data(&iqcmd.irh.u64, 1);
#ifdef OTX_EP_IO_DEBUG
		otx_ep_dbg("After swapping\n");
		otx_ep_dbg("Word0 [dptr]: 0x%016lx\n",
			   (unsigned long)iqcmd.dptr);
		otx_ep_dbg("Word1 [ihtx]: 0x%016lx\n", (unsigned long)iqcmd.ih);
		otx_ep_dbg("Word2 [pki_ih3]: 0x%016lx\n",
			   (unsigned long)iqcmd.pki_ih3);
		otx_ep_dbg("Word3 [rptr]: 0x%016lx\n",
			   (unsigned long)iqcmd.rptr);
		otx_ep_dbg("Word4 [irh]: 0x%016lx\n", (unsigned long)iqcmd.irh);
		otx_ep_dbg("Word5 [exhdr[0]]: 0x%016lx\n",
				(unsigned long)iqcmd.exhdr[0]);
		rte_pktmbuf_dump(stdout, m, rte_pktmbuf_pkt_len(m));
#endif
		dbell = (i == (unsigned int)(nb_pkts - 1)) ? 1 : 0;
		index = iq->host_write_index;
		if (otx_ep_send_data(otx_ep, iq, &iqcmd, dbell))
			goto xmit_fail;
		otx_ep_iqreq_add(iq, iqreq_buf, iqreq_type, index);
		iq->stats.tx_pkts++;
		iq->stats.tx_bytes += pkt_len;
		count++;
	}
xmit_fail:
	if (iq->instr_pending >= OTX_EP_MAX_INSTR)
		otx_ep_flush_iq(iq);
	return count;
}
uint16_t otx_ep_xmit_pkts ( void * tx_queue , struct rte_mbuf * * pkts , uint16_t nb_pkts ) { struct otx_ep_instr_64B iqcmd ; struct otx_ep_instr_queue * iq ; struct otx_ep_device * otx_ep ; struct rte_mbuf * m ; uint32_t iqreq_type , sgbuf_sz ; int dbell , index , count = 0 ; unsigned int pkt_len , i ; int gather , gsz ; void * iqreq_buf ; uint64_t dptr ; iq = ( struct otx_ep_instr_queue * ) tx_queue ; otx_ep = iq -> otx_ep_dev ; iqcmd . ih . u64 = 0 ; iqcmd . pki_ih3 . u64 = 0 ; iqcmd . irh . u64 = 0 ; iqcmd . ih . s . fsz = OTX_EP_FSZ ; iqcmd . ih . s . pkind = otx_ep -> pkind ; iqcmd . pki_ih3 . s . w = 1 ; iqcmd . pki_ih3 . s . utt = 1 ; iqcmd . pki_ih3 . s . tagtype = ORDERED_TAG ; iqcmd . pki_ih3 . s . sl = OTX_EP_FSZ + OTX_CUST_DATA_LEN ; iqcmd . irh . s . opcode = OTX_EP_NW_PKT_OP ; for ( i = 0 ; i < nb_pkts ; i ++ ) { m = pkts [ i ] ; if ( m -> nb_segs == 1 ) { dptr = rte_mbuf_data_iova ( m ) ; pkt_len = rte_pktmbuf_data_len ( m ) ; iqreq_buf = m ; iqreq_type = OTX_EP_REQTYPE_NORESP_NET ; gather = 0 ; gsz = 0 ; } else { struct otx_ep_buf_free_info * finfo ; int j , frags , num_sg ; if ( ! ( otx_ep -> tx_offloads & DEV_TX_OFFLOAD_MULTI_SEGS ) ) goto xmit_fail ; finfo = ( struct otx_ep_buf_free_info * ) rte_malloc ( NULL , sizeof ( * finfo ) , 0 ) ; if ( finfo == NULL ) { otx_ep_err ( " \n " ) ; goto xmit_fail ; } num_sg = ( m -> nb_segs + 3 ) / 4 ; sgbuf_sz = sizeof ( struct otx_ep_sg_entry ) * num_sg ; finfo -> g . sg = rte_zmalloc ( NULL , sgbuf_sz , OTX_EP_SG_ALIGN ) ; if ( finfo -> g . sg == NULL ) { rte_free ( finfo ) ; otx_ep_err ( " \n " ) ; goto xmit_fail ; } gather = 1 ; gsz = m -> nb_segs ; finfo -> g . num_sg = num_sg ; finfo -> g . sg [ 0 ] . ptr [ 0 ] = rte_mbuf_data_iova ( m ) ; set_sg_size ( & finfo -> g . sg [ 0 ] , m -> data_len , 0 ) ; pkt_len = m -> data_len ; finfo -> mbuf = m ; frags = m -> nb_segs - 1 ; j = 1 ; m = m -> next ; while ( frags -- ) { finfo -> g . sg [ ( j >> 2 ) ] . ptr [ ( j & 3 ) ] = rte_mbuf_data_iova ( m ) ; set_sg_size ( & finfo -> g . sg [ ( j >> 2 ) ] , m -> data_len , ( j & 3 ) ) ; pkt_len += m -> data_len ; j ++ ; m = m -> next ; } dptr = rte_mem_virt2iova ( finfo -> g . sg ) ; iqreq_buf = finfo ; iqreq_type = OTX_EP_REQTYPE_NORESP_GATHER ; if ( pkt_len > OTX_EP_MAX_PKT_SZ ) { rte_free ( finfo -> g . sg ) ; rte_free ( finfo ) ; otx_ep_err ( " \n " ) ; goto xmit_fail ; } } iqcmd . ih . s . tlen = pkt_len + iqcmd . ih . s . fsz ; iqcmd . ih . s . gather = gather ; iqcmd . ih . s . gsz = gsz ; iqcmd . dptr = dptr ; otx_ep_swap_8B_data ( & iqcmd . irh . u64 , 1 ) ; #ifdef OTX_EP_IO_DEBUG otx_ep_dbg ( " \n " ) ; otx_ep_dbg ( " \n " , ( unsigned long ) iqcmd . dptr ) ; otx_ep_dbg ( " \n " , ( unsigned long ) iqcmd . ih ) ; otx_ep_dbg ( " \n " , ( unsigned long ) iqcmd . pki_ih3 ) ; otx_ep_dbg ( " \n " , ( unsigned long ) iqcmd . rptr ) ; otx_ep_dbg ( " \n " , ( unsigned long ) iqcmd . irh ) ; otx_ep_dbg ( " \n " , ( unsigned long ) iqcmd . exhdr [ 0 ] ) ; rte_pktmbuf_dump ( stdout , m , rte_pktmbuf_pkt_len ( m ) ) ; #endif dbell = ( i == ( unsigned int ) ( nb_pkts - 1 ) ) ? 1 : 0 ; index = iq -> host_write_index ; if ( otx_ep_send_data ( otx_ep , iq , & iqcmd , dbell ) ) goto xmit_fail ; otx_ep_iqreq_add ( iq , iqreq_buf , iqreq_type , index ) ; iq -> stats . tx_pkts ++ ; iq -> stats . tx_bytes += pkt_len ; count ++ ; } xmit_fail : if ( iq -> instr_pending >= OTX_EP_MAX_INSTR ) otx_ep_flush_iq ( iq ) ; return count ; }
Enqueue requests/packets to OTX_EP IQ queue.
Enqueue requests / packets to OTX_EP IQ queue .
/* ih invars */ /* The SDK decided PKIND value */ /* pki ih3 invars */ /* sl will be sizeof(pki_ih3) */ /* irh invars */ /* dptr */ /* ih vars */ /* Return no# of instructions posted successfully. */