Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 2 Nov 2007 05:03:42 GMT
From:      Kip Macy <kmacy@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 128501 for review
Message-ID:  <200711020503.lA253gVi078239@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=128501

Change 128501 by kmacy@kmacy:storage:toestack on 2007/11/02 05:03:39

	add core functionality for transmit - but don't yet 
	hook in to cxgb_toe_send

Affected files ...

.. //depot/projects/toestack/sys/dev/cxgb/ulp/tom/cxgb_cpl_io.c#10 edit
.. //depot/projects/toestack/sys/dev/cxgb/ulp/tom/cxgb_defs.h#2 edit
.. //depot/projects/toestack/sys/dev/cxgb/ulp/tom/cxgb_tom.h#2 edit

Differences ...

==== //depot/projects/toestack/sys/dev/cxgb/ulp/tom/cxgb_cpl_io.c#10 (text+ko) ====

@@ -108,7 +108,7 @@
  * in the skb and whether it has any payload in its main body.  This maps the
  * length of the gather list represented by an skb into the # of necessary WRs.
  */
-static unsigned int skb_wrs[MAX_PAGE_IOV + 2] __read_mostly;
+static unsigned int mbuf_wrs[TX_MAX_SEGS] __read_mostly;
 
 /*
  * Max receive window supported by HW in bytes.  Only a small part of it can
@@ -122,6 +122,133 @@
  */
 #define MIN_RCV_WND (24 * 1024U)
 
+
+extern int tcp_do_autorcvbuf;
+extern int tcp_do_autosndbuf;
+extern int tcp_autorcvbuf_max;
+extern int tcp_autosndbuf_max;
+
+static inline unsigned int
+mkprio(unsigned int cntrl, const struct socket *so)
+{
+        return cntrl;
+}
+
+
+static inline void
+make_tx_data_wr(struct socket *so, struct mbuf *m, int len, struct mbuf *tail)
+{
+	struct tcpcb *tp = sototcpcb(so);
+	struct toepcb *toep = tp->t_toe;
+	struct tx_data_wr *req;
+
+	req = mtod(m, struct tx_data_wr *);
+	m->m_len = sizeof(*req);
+	req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA));
+	req->wr_lo = htonl(V_WR_TID(toep->tp_tid));
+	req->sndseq = htonl(tp->snd_nxt);
+	/* len includes the length of any HW ULP additions */
+	req->len = htonl(len);
+	req->param = htonl(V_TX_PORT(toep->tp_l2t->smt_idx));
+	/* V_TX_ULP_SUBMODE sets both the mode and submode */
+	req->flags = htonl(V_TX_ULP_SUBMODE(/*skb_ulp_mode(skb)*/ 0) |
+	                   V_TX_URG(/* skb_urgent(skb) */ 0 ) |
+	                   V_TX_SHOVE((!(tp->t_flags & TF_MORETOCOME) &&
+				   (tail ? 0 : 1))));
+
+	if (__predict_false((toep->tp_flags & TP_DATASENT) == 0)) {
+		req->flags |= htonl(V_TX_ACK_PAGES(2) | F_TX_INIT | 
+				    V_TX_CPU_IDX(toep->tp_qset_idx));
+ 
+		/* Sendbuffer is in units of 32KB.
+		 */
+		if (tcp_do_autosndbuf && so->so_snd.sb_flags & SB_AUTOSIZE) 
+			req->param |= htonl(V_TX_SNDBUF(tcp_autosndbuf_max >> 15));
+		else
+			req->param |= htonl(V_TX_SNDBUF(so->so_snd.sb_hiwat >> 15));
+		toep->tp_flags |= TP_DATASENT;
+	}
+	
+	
+	
+}
+
+int
+t3_push_frames(struct socket *so, int req_completion)
+{
+	struct tcpcb *tp = sototcpcb(so);
+	struct toepcb *toep = tp->t_toe;
+	
+	struct mbuf *tail, *m0;
+	struct t3cdev *cdev;
+	struct tom_data *d;
+	int bytes, count, total_bytes;
+	bus_dma_segment_t segs[TX_MAX_SEGS], *segp;
+	segp = segs;
+
+	if (tp->t_state == TCPS_SYN_SENT || tp->t_state == TCPS_CLOSED)
+		return (0);
+
+	if (so->so_state & (SS_ISDISCONNECTING|SS_ISDISCONNECTED))
+		return (0);
+
+	d = TOM_DATA(TOE_DEV(so));
+	cdev = d->cdev;
+	tail = so->so_snd.sb_sndptr ? so->so_snd.sb_sndptr : so->so_snd.sb_mb;
+	total_bytes = 0;
+	
+	while (toep->tp_wr_avail && (tail != NULL)) {
+
+		count = bytes = 0;
+		if ((m0 = m_gethdr(M_NOWAIT, MT_DATA)) == NULL)
+			return (0);
+
+		while ((mbuf_wrs[count + 1] <= toep->tp_wr_avail) && (tail != NULL) && (count < TX_MAX_SEGS)) {
+			bytes += tail->m_len;
+			count++;
+
+			/*
+			 * technically an abuse to be using this for a VA
+			 * but less gross than defining my own structure
+			 * or calling pmap_kextract from here :-|
+			 */
+			segp->ds_addr = (bus_addr_t)tail->m_data;
+			segp->ds_len = tail->m_len;
+			segp++;
+			tail = tail->m_next;
+		}
+
+		so->so_snd.sb_sndptr = tail;
+		so->so_snd.sb_sndptroff += bytes;
+		total_bytes += bytes;
+
+		
+		/*
+		 * XXX can drop socket buffer lock here
+		 */
+	
+		toep->tp_wr_avail -= mbuf_wrs[count];
+		toep->tp_wr_unacked += mbuf_wrs[count];
+	
+		make_tx_data_wr(so, m0, bytes, tail);
+		m_set_priority(m0, mkprio(CPL_PRIORITY_DATA, so));
+		m_set_sgl(m0, segs);
+		m_set_sgllen(m0, count);
+		m0->m_pkthdr.len = bytes;
+		if ((req_completion && toep->tp_wr_unacked == mbuf_wrs[count]) ||
+		    toep->tp_wr_unacked >= toep->tp_wr_max / 2) {
+			struct work_request_hdr *wr = cplhdr(m0);
+
+			wr->wr_hi |= htonl(F_WR_COMPL);
+			toep->tp_wr_unacked = 0;	
+		}
+
+		l2t_send(cdev, m0, toep->tp_l2t);
+	}
+
+	return (total_bytes);
+}
+
 static int
 cxgb_toe_disconnect(struct tcpcb *tp)
 {
@@ -188,12 +315,6 @@
 	cxgb_insert_tid(d->cdev, d->client, so, tid);
 }
 
-static inline unsigned int
-mkprio(unsigned int cntrl, const struct socket *so)
-{
-        return cntrl;
-}
-
 /**
  *	find_best_mtu - find the entry in the MTU table closest to an MTU
  *	@d: TOM state
@@ -247,9 +368,6 @@
 	tp->t_tu = &cxgb_toe_usrreqs;
 }
 
-extern int tcp_do_autorcvbuf;
-extern int tcp_autorcvbuf_max;
-
 /*
  * Determine the receive window scaling factor given a target max
  * receive window.
@@ -684,14 +802,14 @@
 {
 	int i;
 
-	if (skb_wrs[1])     /* already initialized */
+	if (mbuf_wrs[1])     /* already initialized */
 		return;
 
-	for (i = 1; i < ARRAY_SIZE(skb_wrs); i++) {
+	for (i = 1; i < ARRAY_SIZE(mbuf_wrs); i++) {
 		int sgl_len = (3 * i) / 2 + (i & 1);
 
 		sgl_len += 3;
-		skb_wrs[i] = sgl_len <= wr_len ?
+		mbuf_wrs[i] = sgl_len <= wr_len ?
 		       	1 : 1 + (sgl_len - 2) / (wr_len - 1);
 	}
 

==== //depot/projects/toestack/sys/dev/cxgb/ulp/tom/cxgb_defs.h#2 (text+ko) ====

@@ -13,6 +13,8 @@
 void t3tom_register_cpl_handler(unsigned int opcode, cxgb_cpl_handler_func h);
 void t3_init_offload_ops(void);
 void t3_init_wr_tab(unsigned int wr_len);
+int t3_push_frames(struct socket *so, int req_completion);
+
 void toepcb_hold(struct toepcb *);
 void toepcb_release(struct toepcb *);
 void toepcb_init(struct toepcb *);

==== //depot/projects/toestack/sys/dev/cxgb/ulp/tom/cxgb_tom.h#2 (text+ko) ====

@@ -78,6 +78,8 @@
 #define T3C_DEV(sk) ((TOM_DATA(TOE_DEV(sk)))->cdev)
 #define TOM_TUNABLE(dev, param) (TOM_DATA(dev)->conf.param)
 
+#define TP_DATASENT (1 << 0)
+
 struct toepcb {
 	struct toedev *tp_toedev;
 	int tp_tid;
@@ -91,6 +93,8 @@
 	int tp_qset_idx;
 	int tp_mss_clamp;
 	int tp_qset;
+	int tp_flags;
+	
 	volatile int tp_refcount;
 	
 	struct tcpcb *tp_tp;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200711020503.lA253gVi078239>