PERFORCE change 118707 for review

Kip Macy kmacy at FreeBSD.org
Tue Apr 24 06:30:38 UTC 2007


http://perforce.freebsd.org/chv.cgi?CH=118707

Change 118707 by kmacy at kmacy_vt-x:opentoe_init on 2007/04/24 06:30:12

	factor out write work request for sgl header 
	implement write_ofld_wr
	call rx_offload when receiving offloaded packets

Affected files ...

.. //depot/projects/opentoe/sys/dev/cxgb/cxgb_sge.c#14 edit

Differences ...

==== //depot/projects/opentoe/sys/dev/cxgb/cxgb_sge.c#14 (text+ko) ====

@@ -998,6 +998,95 @@
 #endif
 }
 
+
+
+/**
+ *	write_wr_hdr_sgl - write a WR header and, optionally, SGL
+ *	@ndesc: number of Tx descriptors spanned by the SGL
+ *	@txd: first Tx descriptor to be written
+ *	@txqs: txq state (generation and producer index)
+ *	@txq: the SGE Tx queue
+ *	@sgl: the SGL
+ *	@flits: number of flits to the start of the SGL in the first descriptor
+ *	@sgl_flits: the SGL size in flits
+ *	@wr_hi: top 32 bits of WR header based on WR type (big endian)
+ *	@wr_lo: low 32 bits of WR header based on WR type (big endian)
+ *
+ *	Write a work request header and an associated SGL.  If the SGL is
+ *	small enough to fit into one Tx descriptor it has already been written
+ *	and we just need to write the WR header.  Otherwise we distribute the
+ *	SGL across the number of descriptors it spans.
+ */
+
+static void
+write_wr_hdr_sgl(unsigned int ndesc, struct tx_desc *txd, struct txq_state *txqs,
+    const struct sge_txq *txq, const struct sg_ent *sgl, unsigned int flits,
+    unsigned int sgl_flits, unsigned int wr_hi, unsigned int wr_lo)
+{
+
+	struct work_request_hdr *wrp = (struct work_request_hdr *)txd;
+	struct tx_sw_desc *txsd = &txq->sdesc[txqs->pidx];
+	
+	if (__predict_true(ndesc == 1)) {
+		wrp->wr_hi = htonl(F_WR_SOP | F_WR_EOP | V_WR_DATATYPE(1) |
+		    V_WR_SGLSFLT(flits)) | wr_hi;
+		wmb();
+		wrp->wr_lo = htonl(V_WR_LEN(flits + sgl_flits) |
+		    V_WR_GEN(txqs->gen)) | wr_lo;
+		/* XXX gen? */
+		wr_gen2(txd, txqs->gen);
+	} else {
+		unsigned int ogen = txqs->gen;
+		const uint64_t *fp = (const uint64_t *)sgl;
+		struct work_request_hdr *wp = wrp;
+		
+		wrp->wr_hi = htonl(F_WR_SOP | V_WR_DATATYPE(1) |
+		    V_WR_SGLSFLT(flits)) | wr_hi;
+		
+		while (sgl_flits) {
+			unsigned int avail = WR_FLITS - flits;
+
+			if (avail > sgl_flits)
+				avail = sgl_flits;
+			memcpy(&txd->flit[flits], fp, avail * sizeof(*fp));
+			sgl_flits -= avail;
+			ndesc--;
+			if (!sgl_flits)
+				break;
+			
+			fp += avail;
+			txd++;
+			txsd++;
+			if (++txqs->pidx == txq->size) {
+				txqs->pidx = 0;
+				txqs->gen ^= 1;
+				txd = txq->desc;
+				txsd = txq->sdesc;
+			}
+			
+			/*
+			 * when the head of the mbuf chain
+			 * is freed all clusters will be freed
+			 * with it
+			 */
+			txsd->m = NULL;
+			wrp = (struct work_request_hdr *)txd;
+			wrp->wr_hi = htonl(V_WR_DATATYPE(1) |
+			    V_WR_SGLSFLT(1)) | wr_hi;
+			wrp->wr_lo = htonl(V_WR_LEN(min(WR_FLITS,
+				    sgl_flits + 1)) |
+			    V_WR_GEN(txqs->gen)) | wr_lo;
+			wr_gen2(txd, txqs->gen);
+			flits = 1;
+		}
+		wrp->wr_hi |= htonl(F_WR_EOP);
+		wmb();
+		wp->wr_lo = htonl(V_WR_LEN(WR_FLITS) | V_WR_GEN(ogen)) | wr_lo;
+		wr_gen2((struct tx_desc *)wp, ogen);
+	}
+}
+
+	
 /* sizeof(*eh) + sizeof(*vhdr) + sizeof(*ip) + sizeof(*tcp) */
 #define TCPPKTHDRSIZE (ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN + 20 + 20)
 
@@ -1120,7 +1209,7 @@
 	m0 = *m;
 	ndesc = calc_tx_descs(m0, nsegs);
 	
-	sgp = (ndesc == 1) ? (struct sg_ent *)&txd->flit[flits] : &sgl[0];
+	sgp = (ndesc == 1) ? (struct sg_ent *)&txd->flit[flits] : sgl;
 	make_sgl(sgp, segs, nsegs);
 
 	sgl_flits = sgl_len(nsegs);
@@ -1132,65 +1221,8 @@
 	wr_lo = htonl(V_WR_TID(txq->token));
 	txsd->m = m0;
 	m0->m_priority = txqs.pidx; 
-	
-	if (__predict_true(ndesc == 1)) {
-		wrp->wr_hi = htonl(F_WR_SOP | F_WR_EOP | V_WR_DATATYPE(1) |
-		    V_WR_SGLSFLT(flits)) | wr_hi;
-		wmb();
-		wrp->wr_lo = htonl(V_WR_LEN(flits + sgl_flits) |
-		    V_WR_GEN(txqs.gen)) | wr_lo;
-		/* XXX gen? */
-		wr_gen2(txd, txqs.gen);
-	} else {
-		unsigned int ogen = txqs.gen;
-		const uint64_t *fp = (const uint64_t *)sgl;
-		struct work_request_hdr *wp = wrp;
-		
-		/* XXX - CHECK ME */
-		wrp->wr_hi = htonl(F_WR_SOP | V_WR_DATATYPE(1) |
-		    V_WR_SGLSFLT(flits)) | wr_hi;
-		
-		while (sgl_flits) {
-			unsigned int avail = WR_FLITS - flits;
 
-			if (avail > sgl_flits)
-				avail = sgl_flits;
-			memcpy(&txd->flit[flits], fp, avail * sizeof(*fp));
-			sgl_flits -= avail;
-			ndesc--;
-			if (!sgl_flits)
-				break;
-			
-			fp += avail;
-			txd++;
-			txsd++;
-			if (++txqs.pidx == txq->size) {
-				txqs.pidx = 0;
-				txqs.gen ^= 1;
-				txd = txq->desc;
-				txsd = txq->sdesc;
-			}
-			
-			/*
-			 * when the head of the mbuf chain
-			 * is freed all clusters will be freed
-			 * with it
-			 */
-			txsd->m = NULL;
-			wrp = (struct work_request_hdr *)txd;
-			wrp->wr_hi = htonl(V_WR_DATATYPE(1) |
-			    V_WR_SGLSFLT(1)) | wr_hi;
-			wrp->wr_lo = htonl(V_WR_LEN(min(WR_FLITS,
-				    sgl_flits + 1)) |
-			    V_WR_GEN(txqs.gen)) | wr_lo;
-			wr_gen2(txd, txqs.gen);
-			flits = 1;
-		}
-		wrp->wr_hi |= htonl(F_WR_EOP);
-		wmb();
-		wp->wr_lo = htonl(V_WR_LEN(WR_FLITS) | V_WR_GEN(ogen)) | wr_lo;
-		wr_gen2((struct tx_desc *)wp, ogen);
-	}
+	write_wr_hdr_sgl(ndesc, txd, &txqs, txq, sgl, flits, sgl_flits, wr_hi, wr_lo);
 	check_ring_tx_db(p->adapter, txq);
 
 	return (0);
@@ -1788,15 +1820,16 @@
  */
 static void
 write_ofld_wr(adapter_t *adap, struct mbuf *m,
-	  struct sge_txq *q, unsigned int pidx,
-	  unsigned int gen, unsigned int ndesc)
+    struct sge_txq *q, unsigned int pidx,
+    unsigned int gen, unsigned int ndesc,
+    bus_dma_segment_t *segs, unsigned int nsegs)
 {
-#ifdef notyet
 	unsigned int sgl_flits, flits;
 	struct work_request_hdr *from;
 	struct sg_ent *sgp, sgl[TX_MAX_SEGS / 2 + 1];
 	struct tx_desc *d = &q->desc[pidx];
-
+	struct txq_state txqs;
+	
 	if (immediate(m)) {
 		q->sdesc[pidx].m = NULL;
 		write_imm(d, m, m->m_len, gen);
@@ -1806,20 +1839,20 @@
 	/* Only TX_DATA builds SGLs */
 
 	from = mtod(m, struct work_request_hdr *);
-	memcpy(&d->flit[1], &from[1], skb->h.raw - skb->data - sizeof(*from));
+	memcpy(&d->flit[1], &from[1],
+	    (uint8_t *)m->m_pkthdr.header - mtod(m, uint8_t *) - sizeof(*from));
+
+	flits = ((uint8_t *)m->m_pkthdr.header - mtod(m, uint8_t *)) / 8;
+	sgp = (ndesc == 1) ? (struct sg_ent *)&d->flit[flits] : sgl;
+
+	make_sgl(sgp, segs, nsegs);
+	sgl_flits = sgl_len(nsegs);
 
-	flits = (skb->h.raw - skb->data) / 8;
-	sgp = ndesc == 1 ? (struct sg_ent *)&d->flit[flits] : sgl;
-	sgl_flits = make_sgl(skb, sgp, skb->h.raw, skb->tail - skb->h.raw,
-		       	     adap->pdev);
-	if (need_skb_unmap()) {
-		setup_deferred_unmapping(skb, adap->pdev, sgp, sgl_flits);
-		skb->destructor = deferred_unmap_destructor;
-		((struct unmap_info *)skb->cb)->len = skb->tail - skb->h.raw;
-	}
-	write_wr_hdr_sgl(ndesc, skb, d, pidx, q, sgl, flits, sgl_flits,
-			 gen, from->wr_hi, from->wr_lo);
-#endif
+	txqs.gen = q->gen;
+	txqs.pidx = q->pidx;
+	txqs.compl = (q->unacked & 8) << (S_WR_COMPL - 3);
+	write_wr_hdr_sgl(ndesc, d, &txqs, q, sgl, flits, sgl_flits,
+	    from->wr_hi, from->wr_lo);
 }
 
 /**
@@ -1830,7 +1863,7 @@
  * 	packet.  These packets are already fully constructed.
  */
 static __inline unsigned int
-calc_tx_descs_ofld(const struct mbuf *mbuf)
+calc_tx_descs_ofld(const struct mbuf *m, unsigned int nsegs)
 {
 #ifdef notyet	
 	unsigned int flits, cnt = skb_shinfo(skb)->nr_frags;
@@ -1860,12 +1893,19 @@
 ofld_xmit(adapter_t *adap, struct sge_txq *q, struct mbuf *m)
 {
 	int ret;
-	unsigned int pidx, gen;
-	unsigned int ndesc = calc_tx_descs_ofld(m);
+	unsigned int pidx, gen, nsegs;
+	unsigned int ndesc;
 	struct mbuf *m_vec[TX_CLEAN_MAX_DESC];
+	bus_dma_segment_t segs[TX_MAX_SEGS];
 	int i, cleaned;
-	
+	struct tx_sw_desc *stx = &q->sdesc[q->pidx];
+
 	mtx_lock(&q->lock);
+	if ((ret = busdma_map_mbufs(&m, q, stx, segs, &nsegs)) != 0) {
+		mtx_unlock(&q->lock);
+		return (ret);
+	}
+	ndesc = calc_tx_descs_ofld(m, nsegs);
 again:	cleaned = reclaim_completed_tx(adap, q, TX_CLEAN_MAX_DESC, m_vec);
 
 	ret = check_desc_avail(adap, q, m, ndesc, TXQ_OFLD);
@@ -1894,7 +1934,7 @@
 #endif
 	mtx_unlock(&q->lock);
 
-	write_ofld_wr(adap, m, q, pidx, gen, ndesc);
+	write_ofld_wr(adap, m, q, pidx, gen, ndesc, segs, nsegs);
 	check_ring_tx_db(adap, q);
 	
 	for (i = 0; i < cleaned; i++) {
@@ -1952,7 +1992,7 @@
 		__skb_unlink(skb, &q->sendq);
 #endif		
 		mtx_unlock(&q->lock);
-		write_ofld_wr(adap, skb, q, pidx, gen, ndesc);
+		write_ofld_wr(adap, skb, q, pidx, gen, ndesc, segs, nsegs);
 		mtx_lock(&q->lock);
 	}
 #endif	
@@ -2360,16 +2400,14 @@
 
 				rspq->m = NULL;
 			} else {
-#ifdef notyet
-				m->pkthdr.csum_data = rss_csum;
+				rspq->m->m_pkthdr.csum_data = rss_csum;
 				/*
 				 * XXX size mismatch
 				 */
-				m->m_priority = rss_hash;
+				rspq->m->m_priority = rss_hash;
 				
-				ngathered = rx_offload(&adap->tdev, rspq, m,
+				ngathered = rx_offload(&adap->tdev, rspq, rspq->m,
 				    offload_mbufs, ngathered);
-#endif
 			}
 #ifdef notyet			
 			taskqueue_enqueue(adap->tq, &adap->timer_reclaim_task);


More information about the p4-projects mailing list