FreeBSD/sys/dev/vnic/nicvf_queues.c
/* Returns MBUF for a received packet */
Returns MBUF for a received packet
Returns MBUF for a received packet
struct mbuf *
nicvf_get_rcv_mbuf(struct nicvf *nic, struct cqe_rx_t *cqe_rx)
{
	int frag;
	int payload_len = 0;
	struct mbuf *mbuf;
	struct mbuf *mbuf_frag;
	uint16_t *rb_lens = NULL;
	uint64_t *rb_ptrs = NULL;
	mbuf = NULL;
	rb_lens = (uint16_t *)((uint8_t *)cqe_rx + (3 * sizeof(uint64_t)));
	rb_ptrs = (uint64_t *)((uint8_t *)cqe_rx + (6 * sizeof(uint64_t)));
	dprintf(nic->dev, "%s rb_cnt %d rb0_ptr %lx rb0_sz %d\n",
	    __func__, cqe_rx->rb_cnt, cqe_rx->rb0_ptr, cqe_rx->rb0_sz);
	for (frag = 0; frag < cqe_rx->rb_cnt; frag++) {
		payload_len = rb_lens[frag_num(frag)];
		if (frag == 0) {
			mbuf = nicvf_rb_ptr_to_mbuf(nic,
			    (*rb_ptrs - cqe_rx->align_pad));
			mbuf->m_len = payload_len;
			mbuf->m_data += cqe_rx->align_pad;
			if_setrcvif(mbuf, nic->ifp);
		} else {
			mbuf_frag = nicvf_rb_ptr_to_mbuf(nic, *rb_ptrs);
			m_append(mbuf, payload_len, mbuf_frag->m_data);
			m_freem(mbuf_frag);
		}
		rb_ptrs++;
	}
	if (__predict_true(mbuf != NULL)) {
		m_fixhdr(mbuf);
		mbuf->m_pkthdr.flowid = cqe_rx->rq_idx;
		M_HASHTYPE_SET(mbuf, M_HASHTYPE_OPAQUE);
		if (__predict_true((if_getcapenable(nic->ifp) & IFCAP_RXCSUM) != 0)) {
			if (__predict_true(cqe_rx->l3_type == L3TYPE_IPV4)) {
				mbuf->m_pkthdr.csum_flags =
				    (CSUM_IP_CHECKED | CSUM_IP_VALID);
			}
			switch (cqe_rx->l4_type) {
			case L4TYPE_UDP:
			case L4TYPE_TCP: 
				mbuf->m_pkthdr.csum_flags |=
				    (CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
				mbuf->m_pkthdr.csum_data = 0xffff;
				break;
			case L4TYPE_SCTP:
				mbuf->m_pkthdr.csum_flags |= CSUM_SCTP_VALID;
				break;
			default:
				break;
			}
		}
	}
	return (mbuf);
}
struct mbuf * nicvf_get_rcv_mbuf ( struct nicvf * nic , struct cqe_rx_t * cqe_rx ) { int frag ; int payload_len = 0 ; struct mbuf * mbuf ; struct mbuf * mbuf_frag ; uint16_t * rb_lens = NULL ; uint64_t * rb_ptrs = NULL ; mbuf = NULL ; rb_lens = ( uint16_t * ) ( ( uint8_t * ) cqe_rx + ( 3 * sizeof ( uint64_t ) ) ) ; rb_ptrs = ( uint64_t * ) ( ( uint8_t * ) cqe_rx + ( 6 * sizeof ( uint64_t ) ) ) ; dprintf ( nic -> dev , " \n " , __func__ , cqe_rx -> rb_cnt , cqe_rx -> rb0_ptr , cqe_rx -> rb0_sz ) ; for ( frag = 0 ; frag < cqe_rx -> rb_cnt ; frag ++ ) { payload_len = rb_lens [ frag_num ( frag ) ] ; if ( frag == 0 ) { mbuf = nicvf_rb_ptr_to_mbuf ( nic , ( * rb_ptrs - cqe_rx -> align_pad ) ) ; mbuf -> m_len = payload_len ; mbuf -> m_data += cqe_rx -> align_pad ; if_setrcvif ( mbuf , nic -> ifp ) ; } else { mbuf_frag = nicvf_rb_ptr_to_mbuf ( nic , * rb_ptrs ) ; m_append ( mbuf , payload_len , mbuf_frag -> m_data ) ; m_freem ( mbuf_frag ) ; } rb_ptrs ++ ; } if ( __predict_true ( mbuf != NULL ) ) { m_fixhdr ( mbuf ) ; mbuf -> m_pkthdr . flowid = cqe_rx -> rq_idx ; M_HASHTYPE_SET ( mbuf , M_HASHTYPE_OPAQUE ) ; if ( __predict_true ( ( if_getcapenable ( nic -> ifp ) & IFCAP_RXCSUM ) != 0 ) ) { if ( __predict_true ( cqe_rx -> l3_type == L3TYPE_IPV4 ) ) { mbuf -> m_pkthdr . csum_flags = ( CSUM_IP_CHECKED | CSUM_IP_VALID ) ; } switch ( cqe_rx -> l4_type ) { case L4TYPE_UDP : case L4TYPE_TCP : mbuf -> m_pkthdr . csum_flags |= ( CSUM_DATA_VALID | CSUM_PSEUDO_HDR ) ; mbuf -> m_pkthdr . csum_data = 0xffff ; break ; case L4TYPE_SCTP : mbuf -> m_pkthdr . csum_flags |= CSUM_SCTP_VALID ; break ; default : break ; } } } return ( mbuf ) ; }
Returns MBUF for a received packet
Returns MBUF for a received packet
/* First fragment */ /* Add fragments */ /* Next buffer pointer */ /*
			 * HW by default verifies IP & TCP/UDP/SCTP checksums
			 */ /* fall through */