src/sys/dev/cxgbe/t4_sge.c
/*
 * If the SGL ends on an address that is not 16 byte aligned, this function will
 * add a 0 filled flit at the end.
 */
If the SGL ends on an address that is not 16 byte aligned, this function will
add a 0 filled flit at the end.
If the SGL ends on an address that is not 16 byte aligned this function will add a 0 filled flit at the end .
static void
write_gl_to_txd(struct sge_txq *txq, struct mbuf *m, caddr_t *to, int checkwrap)
{
	struct sge_eq *eq = &txq->eq;
	struct sglist *gl = txq->gl;
	struct sglist_seg *seg;
	__be64 *flitp, *wrap;
	struct ulptx_sgl *usgl;
	int i, nflits, nsegs;
	KASSERT(((uintptr_t)(*to) & 0xf) == 0,
	    ("%s: SGL must start at a 16 byte boundary: %p", __func__, *to));
	MPASS((uintptr_t)(*to) >= (uintptr_t)&eq->desc[0]);
	MPASS((uintptr_t)(*to) < (uintptr_t)&eq->desc[eq->sidx]);
	get_pkt_gl(m, gl);
	nsegs = gl->sg_nseg;
	MPASS(nsegs > 0);
	nflits = (3 * (nsegs - 1)) / 2 + ((nsegs - 1) & 1) + 2;
	flitp = (__be64 *)(*to);
	wrap = (__be64 *)(&eq->desc[eq->sidx]);
	seg = &gl->sg_segs[0];
	usgl = (void *)flitp;
	usgl->cmd_nsge = htobe32(V_ULPTX_CMD(ULP_TX_SC_DSGL) |
	    V_ULPTX_NSGE(nsegs));
	usgl->len0 = htobe32(seg->ss_len);
	usgl->addr0 = htobe64(seg->ss_paddr);
	seg++;
	if (checkwrap == 0 || (uintptr_t)(flitp + nflits) <= (uintptr_t)wrap) {
		for (i = 0; i < nsegs - 1; i++, seg++) {
			usgl->sge[i / 2].len[i & 1] = htobe32(seg->ss_len);
			usgl->sge[i / 2].addr[i & 1] = htobe64(seg->ss_paddr);
		}
		if (i & 1)
			usgl->sge[i / 2].len[1] = htobe32(0);
		flitp += nflits;
	} else {
		flitp = (void *)(usgl + 1);
		for (i = 0; i < nflits - 2; i++) {
			if (flitp == wrap)
				flitp = (void *)eq->desc;
			*flitp++ = get_flit(seg, nsegs - 1, i);
		}
	}
	if (nflits & 1) {
		MPASS(((uintptr_t)flitp) & 0xf);
		*flitp++ = 0;
	}
	MPASS((((uintptr_t)flitp) & 0xf) == 0);
	if (__predict_false(flitp == wrap))
		*to = (void *)eq->desc;
	else
		*to = (void *)flitp;
}
static void write_gl_to_txd ( struct sge_txq * txq , struct mbuf * m , caddr_t * to , int checkwrap ) { struct sge_eq * eq = & txq -> eq ; struct sglist * gl = txq -> gl ; struct sglist_seg * seg ; __be64 * flitp , * wrap ; struct ulptx_sgl * usgl ; int i , nflits , nsegs ; KASSERT ( ( ( uintptr_t ) ( * to ) & 0xf ) == 0 , ( " " , __func__ , * to ) ) ; MPASS ( ( uintptr_t ) ( * to ) >= ( uintptr_t ) & eq -> desc [ 0 ] ) ; MPASS ( ( uintptr_t ) ( * to ) < ( uintptr_t ) & eq -> desc [ eq -> sidx ] ) ; get_pkt_gl ( m , gl ) ; nsegs = gl -> sg_nseg ; MPASS ( nsegs > 0 ) ; nflits = ( 3 * ( nsegs - 1 ) ) / 2 + ( ( nsegs - 1 ) & 1 ) + 2 ; flitp = ( __be64 * ) ( * to ) ; wrap = ( __be64 * ) ( & eq -> desc [ eq -> sidx ] ) ; seg = & gl -> sg_segs [ 0 ] ; usgl = ( void * ) flitp ; usgl -> cmd_nsge = htobe32 ( V_ULPTX_CMD ( ULP_TX_SC_DSGL ) | V_ULPTX_NSGE ( nsegs ) ) ; usgl -> len0 = htobe32 ( seg -> ss_len ) ; usgl -> addr0 = htobe64 ( seg -> ss_paddr ) ; seg ++ ; if ( checkwrap == 0 || ( uintptr_t ) ( flitp + nflits ) <= ( uintptr_t ) wrap ) { for ( i = 0 ; i < nsegs - 1 ; i ++ , seg ++ ) { usgl -> sge [ i / 2 ] . len [ i & 1 ] = htobe32 ( seg -> ss_len ) ; usgl -> sge [ i / 2 ] . addr [ i & 1 ] = htobe64 ( seg -> ss_paddr ) ; } if ( i & 1 ) usgl -> sge [ i / 2 ] . len [ 1 ] = htobe32 ( 0 ) ; flitp += nflits ; } else { flitp = ( void * ) ( usgl + 1 ) ; for ( i = 0 ; i < nflits - 2 ; i ++ ) { if ( flitp == wrap ) flitp = ( void * ) eq -> desc ; * flitp ++ = get_flit ( seg , nsegs - 1 , i ) ; } } if ( nflits & 1 ) { MPASS ( ( ( uintptr_t ) flitp ) & 0xf ) ; * flitp ++ = 0 ; } MPASS ( ( ( ( uintptr_t ) flitp ) & 0xf ) == 0 ) ; if ( __predict_false ( flitp == wrap ) ) * to = ( void * ) eq -> desc ; else * to = ( void * ) flitp ; }
If the SGL ends on an address that is not 16 byte aligned, this function will
 add a 0 filled flit at the end.
If the SGL ends on an address that is not 16 byte aligned this function will add a 0 filled flit at the end .
/*
	 * We start at a 16 byte boundary somewhere inside the tx descriptor
	 * ring, so we're at least 16 bytes away from the status page.  There is
	 * no chance of a wrap around in the middle of usgl (which is 16 bytes).
	 */ /* Won't wrap around at all */ /* Will wrap somewhere in the rest of the SGL */ /* 2 flits already written, write the rest flit by flit */