Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 30 Jan 2008 15:38:20 GMT
From:      Steve Wise <swise@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 134477 for review
Message-ID:  <200801301538.m0UFcKmE057547@repoman.freebsd.org>

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

Change 134477 by swise@swise:vic10:iwarp on 2008/01/30 15:38:04

	First swipe at using a ksocket for streaming mode connection setup.

Affected files ...

.. //depot/projects/iwarp/sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb_iwch.c#5 edit
.. //depot/projects/iwarp/sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb_iwch_cm.c#12 edit
.. //depot/projects/iwarp/sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb_iwch_cm.h#4 edit
.. //depot/projects/iwarp/sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb_iwch_qp.c#5 edit
.. //depot/projects/iwarp/sys/netinet/tcp.h#5 edit
.. //depot/projects/iwarp/sys/netinet/tcp_usrreq.c#6 edit

Differences ...

==== //depot/projects/iwarp/sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb_iwch.c#5 (text+ko) ====

@@ -93,7 +93,9 @@
 	.add = open_rnic_dev,
 	.remove = close_rnic_dev,
 	.handlers = t3c_handlers,
+#if 0
 	.redirect = iwch_ep_redirect
+#endif
 };
 
 static TAILQ_HEAD( ,iwch_dev) dev_list;
@@ -265,3 +267,4 @@
 DECLARE_MODULE(iw_cxgb, mod_data, SI_SUB_EXEC, SI_ORDER_ANY);
 MODULE_DEPEND(iw_cxgb, rdma_core, 1, 1, 1);
 MODULE_DEPEND(iw_cxgb, if_cxgb, 1, 1, 1);
+MODULE_DEPEND(iw_cxgb, t3_tom, 1, 1, 1);

==== //depot/projects/iwarp/sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb_iwch_cm.c#12 (text+ko) ====

@@ -1,4 +1,3 @@
-
 /**************************************************************************
 
 Copyright (c) 2007, Chelsio Inc.
@@ -47,6 +46,7 @@
 #include <sys/linker.h>
 #include <sys/firmware.h>
 #include <sys/socket.h>
+#include <sys/socketvar.h>
 #include <sys/sockio.h>
 #include <sys/smp.h>
 #include <sys/sysctl.h>
@@ -55,11 +55,15 @@
 #include <sys/taskqueue.h>
 #include <sys/proc.h>
 
-
 #include <net/route.h>
 #include <netinet/in_systm.h>
 #include <netinet/in.h>
+#include <netinet/in_pcb.h>
 #include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcpip.h>
 
 #include <sys/linux_compat.h>
 #include <contrib/rdma/ib_verbs.h>
@@ -67,6 +71,10 @@
 
 #ifdef CONFIG_DEFINED
 #include <cxgb_include.h>
+#include <ulp/tom/cxgb_tom.h>
+#include <ulp/tom/cxgb_t3_ddp.h>
+#include <ulp/tom/cxgb_defs.h>
+#include <ulp/tom/cxgb_toepcb.h>
 #include <ulp/iw_cxgb/iw_cxgb_cxio_wr.h>
 #include <ulp/iw_cxgb/iw_cxgb_cxio_hal.h>
 #include <ulp/iw_cxgb/iw_cxgb_iwch_provider.h>
@@ -74,6 +82,10 @@
 #include <ulp/iw_cxgb/iw_cxgb_iwch.h>
 #else
 #include <dev/cxgb/cxgb_include.h>
+#include <dev/cxgb/ulp/tom/cxgb_tom.h>
+#include <dev/ulp/tom/cxgb_t3_ddp.h>
+#include <dev/cxgb/ulp/tom/cxgb_defs.h>
+#include <dev/cxgb/ulp/tom/cxgb_toepcb.h>
 #include <dev/cxgb/ulp/iw_cxgb/iw_cxgb_cxio_wr.h>
 #include <dev/cxgb/ulp/iw_cxgb/iw_cxgb_cxio_hal.h>
 #include <dev/cxgb/ulp/iw_cxgb/iw_cxgb_iwch_provider.h>
@@ -124,7 +136,7 @@
 static int rcv_win = 256 * 1024;
 TUNABLE_INT("hw.iw_cxgb.rcv_win", &rcv_win);
 SYSCTL_UINT(_hw_cxgb, OID_AUTO, rcv_win, CTLFLAG_RDTUN, &rcv_win, 0,
-    "TCP receive window in bytes (default=256)");
+    "TCP receive window in bytes (default=256KB)");
 
 static int snd_win = 32 * 1024;
 TUNABLE_INT("hw.iw_cxgb.snd_win", &snd_win);
@@ -141,16 +153,9 @@
 SYSCTL_UINT(_hw_cxgb, OID_AUTO, cong_flavor, CTLFLAG_RDTUN, &cong_flavor, 0,
     "TCP Congestion control flavor (default=1)");
 
-static void process_task(void *ctx, int pending);
-static struct task mbuf_task;
-static struct taskqueue *mbuf_taskq;
-
-static struct mbuf_head rxq;
-static cxgb_cpl_handler_func work_handlers[NUM_CPL_CMDS];
-
 static void ep_timeout(void *arg);
 static void connect_reply_upcall(struct iwch_ep *ep, int status);
-static struct mbuf *get_mbuf(struct mbuf *m, int len, int flags);
+static void iwch_so_upcall(struct socket *so, void *arg, int waitflag);
 
 static void
 start_ep_timer(struct iwch_ep *ep)
@@ -178,78 +183,35 @@
 	put_ep(&ep->com);
 }
 
-static void
-release_tid(struct t3cdev *tdev, u32 hwtid, struct mbuf *m)
+static int set_tcpinfo(struct iwch_ep *ep)
 {
-	struct cpl_tid_release *req;
+	struct tcp_info ti;
+	struct sockopt sopt;
+	int err;
 
-	m = get_mbuf(m, sizeof *req, M_NOWAIT);
-	if (m == NULL)
-		return;
-	req = (struct cpl_tid_release *) mbuf_put(m, sizeof(*req));
-	req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
-	OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_TID_RELEASE, hwtid));
-	m_set_priority(m, CPL_PRIORITY_SETUP); 
-	cxgb_ofld_send(tdev, m);
-	return;
-}
+	sopt.sopt_dir = SOPT_GET;
+	sopt.sopt_level = IPPROTO_TCP;
+	sopt.sopt_name = TCP_INFO;
+	sopt.sopt_val = (caddr_t)&ti;
+	sopt.sopt_valsize = sizeof ti;
+	
+	err = sogetopt(ep->com.so, &sopt);
+	if (err)
+		return -err;
+	if (!(ti.tcpi_options & TCPI_OPT_TOE)) {
+		printf("%s connection NOT OFFLOADED!\n", __FUNCTION__);
+		return -EINVAL;
+	}
 
-int
-iwch_quiesce_tid(struct iwch_ep *ep)
-{
-	struct cpl_set_tcb_field *req;
-	struct mbuf *m = get_mbuf(NULL, sizeof(*req), M_NOWAIT);
-
-	if (m == NULL)
-		return (-ENOMEM);
-	req = (struct cpl_set_tcb_field *) mbuf_put(m, sizeof(*req));
-	req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
-	req->wr.wr_lo = htonl(V_WR_TID(ep->hwtid));
-	OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SET_TCB_FIELD, ep->hwtid));
-	req->reply = 0;
-	req->cpu_idx = 0;
-	req->word = htons(W_TCB_RX_QUIESCE);
-	req->mask = cpu_to_be64(1ULL << S_TCB_RX_QUIESCE);
-	req->val = cpu_to_be64(1 << S_TCB_RX_QUIESCE);
-
-	m_set_priority(m, CPL_PRIORITY_DATA); 
-	cxgb_ofld_send(ep->com.tdev, m);
-	return 0;
-}
-
-int
-iwch_resume_tid(struct iwch_ep *ep)
-{
-	struct cpl_set_tcb_field *req;
-	struct mbuf *m = get_mbuf(NULL, sizeof(*req), M_NOWAIT);
-
-	if (m == NULL)
-		return (-ENOMEM);
-	req = (struct cpl_set_tcb_field *) mbuf_put(m, sizeof(*req));
-	req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
-	req->wr.wr_lo = htonl(V_WR_TID(ep->hwtid));
-	OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SET_TCB_FIELD, ep->hwtid));
-	req->reply = 0;
-	req->cpu_idx = 0;
-	req->word = htons(W_TCB_RX_QUIESCE);
-	req->mask = cpu_to_be64(1ULL << S_TCB_RX_QUIESCE);
-	req->val = 0;
-
-	m_set_priority(m, CPL_PRIORITY_DATA);
-	cxgb_ofld_send(ep->com.tdev, m);
-	return 0;
-}
-
-static void
-set_emss(struct iwch_ep *ep, u16 opt)
-{
-	PDBG("%s ep %p opt %u\n", __FUNCTION__, ep, opt);
-	ep->emss = T3C_DATA(ep->com.tdev)->mtus[G_TCPOPT_MSS(opt)] - 40;
-	if (G_TCPOPT_TSTAMP(opt))
+	ep->snd_seq = ti.tcpi_snd_nxt;
+	ep->rcv_seq = ti.tcpi_rcv_nxt;
+	ep->emss = ti.__tcpi_snd_mss - sizeof(struct tcpiphdr);
+	ep->hwtid = TOEPCB(ep->com.so)->tp_tid; /* XXX */
+	if (ti.tcpi_options & TCPI_OPT_TIMESTAMPS)
 		ep->emss -= 12;
 	if (ep->emss < 128)
 		ep->emss = 128;
-	PDBG("emss=%d\n", ep->emss);
+	return 0;
 }
 
 static enum iwch_ep_state
@@ -299,91 +261,62 @@
 void __free_ep(struct iwch_ep_common *epc)
 {
 	PDBG("%s ep %p state %s\n", __FUNCTION__, epc, states[state_read(epc)]);
+	BUG_ON(epc->so);
 	free(epc, M_DEVBUF);
 }
 
-static void
-release_ep_resources(struct iwch_ep *ep)
+int
+iwch_quiesce_tid(struct iwch_ep *ep)
 {
-	PDBG("%s ep %p tid %d\n", __FUNCTION__, ep, ep->hwtid);
-	cxgb_remove_tid(ep->com.tdev, (void *)ep, ep->hwtid);
-	RTFREE(ep->dst);
-	l2t_release(L2DATA(ep->com.tdev), ep->l2t);
-	put_ep(&ep->com);
-}
+#ifdef notyet
+	struct cpl_set_tcb_field *req;
+	struct mbuf *m = get_mbuf(NULL, sizeof(*req), M_NOWAIT);
 
-static void
-process_task(void *ctx, int pending)
-{
-	struct mbuf *m = NULL;
-	void *ep;
-	struct t3cdev *tdev;
-	int ret;
+	if (m == NULL)
+		return (-ENOMEM);
+	req = (struct cpl_set_tcb_field *) mbuf_put(m, sizeof(*req));
+	req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
+	req->wr.wr_lo = htonl(V_WR_TID(ep->hwtid));
+	OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SET_TCB_FIELD, ep->hwtid));
+	req->reply = 0;
+	req->cpu_idx = 0;
+	req->word = htons(W_TCB_RX_QUIESCE);
+	req->mask = cpu_to_be64(1ULL << S_TCB_RX_QUIESCE);
+	req->val = cpu_to_be64(1 << S_TCB_RX_QUIESCE);
 
-	while ((m = mbufq_dequeue(&rxq))) {
-		ep = m->m_pkthdr.rcvif;
-		tdev = (struct t3cdev *)m->m_pkthdr.header;
-		PDBG("%s dequeued mbuf %p ep %p tdev %p opcode %u\n", __FUNCTION__, m, ep, tdev, G_OPCODE(ntohl(m->m_pkthdr.csum_data)));
-		ret = work_handlers[G_OPCODE(ntohl(m->m_pkthdr.csum_data))](tdev, m, ep);
-		if (ret & CPL_RET_BUF_DONE)
-			m_free(m);
-
-		/*
-		 * ep was referenced in sched(), and is freed here.
-		 */
-		put_ep((struct iwch_ep_common *)ep);
-	}
+	m_set_priority(m, CPL_PRIORITY_DATA); 
+	cxgb_ofld_send(ep->com.tdev, m);
+#endif
+	return 0;
 }
 
-static int
-status2errno(int status)
+int
+iwch_resume_tid(struct iwch_ep *ep)
 {
-	switch (status) {
-	case CPL_ERR_NONE:
-		return 0;
-	case CPL_ERR_CONN_RESET:
-		return (-ECONNRESET);
-	case CPL_ERR_ARP_MISS:
-		return (-EHOSTUNREACH);
-	case CPL_ERR_CONN_TIMEDOUT:
-		return (-ETIMEDOUT);
-	case CPL_ERR_TCAM_FULL:
+#ifdef notyet
+	struct cpl_set_tcb_field *req;
+	struct mbuf *m = get_mbuf(NULL, sizeof(*req), M_NOWAIT);
+
+	if (m == NULL)
 		return (-ENOMEM);
-	case CPL_ERR_CONN_EXIST:
-		return (-EADDRINUSE);
-	default:
-		return (-EIO);
-	}
-}
+	req = (struct cpl_set_tcb_field *) mbuf_put(m, sizeof(*req));
+	req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
+	req->wr.wr_lo = htonl(V_WR_TID(ep->hwtid));
+	OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SET_TCB_FIELD, ep->hwtid));
+	req->reply = 0;
+	req->cpu_idx = 0;
+	req->word = htons(W_TCB_RX_QUIESCE);
+	req->mask = cpu_to_be64(1ULL << S_TCB_RX_QUIESCE);
+	req->val = 0;
 
-static void
-reset_mbuf(struct mbuf *m)
-{
-	m_set_sgl(m, NULL);
-	m_set_sgllen(m, 0);
-	m->m_len = 0;
-	m->m_pkthdr.len = 0;
+	m_set_priority(m, CPL_PRIORITY_DATA);
+	cxgb_ofld_send(ep->com.tdev, m);
+#endif
+	return 0;
 }
 
-/*
- * Try and reuse mbufs already allocated...
- */
-static struct mbuf *
-get_mbuf(struct mbuf *m, int len, int flags)
-{
-	if (!m || (m->m_flags & M_EXT)) {
-		/*
-		 * Assume len is less than MINCLBYTES :-/
-		 */
-		m = m_gethdr(MT_DATA, M_DONTWAIT);
-	}
-	reset_mbuf(m);
-	return (m);
-}
-
 static struct rtentry *
-find_route(struct t3cdev *dev, __be32 local_ip,
-    __be32 peer_ip, __be16 local_port,
+find_route(__be32 local_ip, __be32 peer_ip, __be16 local_port,
     __be16 peer_port, u8 tos)
 {
         struct route iproute;
@@ -398,191 +331,67 @@
 	return iproute.ro_rt;
 }
 
-static unsigned int
-find_best_mtu(const struct t3c_data *d, unsigned short mtu)
-{
-	int i = 0;
-
-	while (i < d->nmtus - 1 && d->mtus[i + 1] <= mtu)
-		++i;
-	return i;
-}
-
 static void
-arp_failure_discard(struct t3cdev *dev, struct mbuf *m)
+close_socket(struct iwch_ep_common *epc)
 {
-	PDBG("%s t3cdev %p\n", __FUNCTION__, dev);
-	m_free(m);
+	soclose(epc->so);
+	epc->so = NULL;
 }
 
-/*
- * Handle an ARP failure for an active open.
- */
 static void
-act_open_req_arp_failure(struct t3cdev *dev, struct mbuf *m)
+abort_socket(struct iwch_ep *ep)
 {
-	printf("ARP failure duing connect\n");
-	m_free(m);
-}
+	struct sockopt sopt;
+	int err;
+	int linger_time=0;
 
-/*
- * Handle an ARP failure for a CPL_ABORT_REQ.  Change it into a no RST variant
- * and send it along.
- */
-static void
-abort_arp_failure(struct t3cdev *dev, struct mbuf *m)
-{
-	struct cpl_abort_req *req = cplhdr(m);
-
-	PDBG("%s t3cdev %p\n", __FUNCTION__, dev);
-	req->cmd = CPL_ABORT_NO_RST;
-	cxgb_ofld_send(dev, m);
-}
-
-static int
-send_halfclose(struct iwch_ep *ep, int flags)
-{
-	struct cpl_close_con_req *req;
-	struct mbuf *m;
-
-	PDBG("%s ep %p\n", __FUNCTION__, ep);
-	m = get_mbuf(NULL, sizeof(*req), flags);
-	if (m == NULL) {
-		printf("%s - failed to alloc mbuf\n", __FUNCTION__);
-		return (-ENOMEM);
-	}
-	m_set_priority(m, CPL_PRIORITY_DATA);
-	set_arp_failure_handler(m, arp_failure_discard);
-	req = (struct cpl_close_con_req *) mbuf_put(m, sizeof(*req));
-	req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_CLOSE_CON));
-	req->wr.wr_lo = htonl(V_WR_TID(ep->hwtid));
-	OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_CLOSE_CON_REQ, ep->hwtid));
-	l2t_send(ep->com.tdev, m, ep->l2t);
-	return 0;
-}
-
-static int
-send_abort(struct iwch_ep *ep, struct mbuf *m, int flags)
-{
-	struct cpl_abort_req *req;
-
-	PDBG("%s ep %p\n", __FUNCTION__, ep);
-	m = get_mbuf(m, sizeof(*req), flags);
-	if (m == NULL) {
-		printf("%s - failed to alloc mbuf.\n",
-		       __FUNCTION__);
-		return (-ENOMEM);
-	}
-	m_set_priority(m, CPL_PRIORITY_DATA);
-	set_arp_failure_handler(m, abort_arp_failure);
-	req = (struct cpl_abort_req *) mbuf_put(m, sizeof(*req));
-	req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_HOST_ABORT_CON_REQ));
-	req->wr.wr_lo = htonl(V_WR_TID(ep->hwtid));
-	OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_ABORT_REQ, ep->hwtid));
-	req->cmd = CPL_ABORT_SEND_RST;
-	l2t_send(ep->com.tdev, m, ep->l2t);
-	return 0;
-}
-
-static int
-send_connect(struct iwch_ep *ep)
-{
-	struct cpl_act_open_req *req;
-	struct mbuf *m;
-	u32 opt0h, opt0l, opt2;
-	unsigned int mtu_idx;
-	int wscale;
-
-	PDBG("%s ep %p\n", __FUNCTION__, ep);
-
-	m = get_mbuf(NULL, sizeof(*req), M_NOWAIT);
-	if (m == NULL) {
-		printf("%s - failed to alloc mbuf.\n",
-		       __FUNCTION__);
-		return (-ENOMEM);
-	}
-	mtu_idx = find_best_mtu(T3C_DATA(ep->com.tdev), dst_mtu(ep->dst));
-	wscale = compute_wscale(rcv_win);
-	opt0h = V_NAGLE(0) |
-	    V_NO_CONG(nocong) |
-	    V_KEEP_ALIVE(1) |
-	    F_TCAM_BYPASS |
-	    V_WND_SCALE(wscale) |
-	    V_MSS_IDX(mtu_idx) |
-	    V_L2T_IDX(ep->l2t->idx) | V_TX_CHANNEL(ep->l2t->smt_idx);
-	opt0l = V_TOS((ep->tos >> 2) & M_TOS) | V_RCV_BUFSIZ(rcv_win>>10);
-	opt2 = V_FLAVORS_VALID(1) | V_CONG_CONTROL_FLAVOR(cong_flavor);
-	m_set_priority(m, CPL_PRIORITY_SETUP);
-	set_arp_failure_handler(m, act_open_req_arp_failure);
-
-	req = (struct cpl_act_open_req *) mbuf_put(m, sizeof(*req));
-	req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
-	OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_ACT_OPEN_REQ, ep->atid));
-	req->local_port = ep->com.local_addr.sin_port;
-	req->peer_port = ep->com.remote_addr.sin_port;
-	req->local_ip = ep->com.local_addr.sin_addr.s_addr;
-	req->peer_ip = ep->com.remote_addr.sin_addr.s_addr;
-	req->opt0h = htonl(opt0h);
-	req->opt0l = htonl(opt0l);
-	req->params = 0;
-	req->opt2 = htonl(opt2);
-	l2t_send(ep->com.tdev, m, ep->l2t);
-	return 0;
+	/* linger_time of 0 forces RST to be sent */
+	sopt.sopt_dir = SOPT_SET;
+	sopt.sopt_level = SOL_SOCKET;
+	sopt.sopt_name = SO_LINGER;
+	sopt.sopt_val = (caddr_t)&linger_time;
+	sopt.sopt_valsize = sizeof linger_time;
+	err = sosetopt(ep->com.so, &sopt);
+	if (err) 
+		printf("%s can't set linger to 0, no RST!\n", __FUNCTION__);
+	close_socket(&ep->com);
 }
 
 static void
-send_mpa_req(struct iwch_ep *ep, struct mbuf *m)
+send_mpa_req(struct iwch_ep *ep)
 {
 	int mpalen;
-	struct tx_data_wr *req;
 	struct mpa_message *mpa;
+	struct mbuf *m;
+	int err;
 
 	PDBG("%s ep %p pd_len %d\n", __FUNCTION__, ep, ep->plen);
 
 	mpalen = sizeof(*mpa) + ep->plen;
-	if (mpalen + sizeof(*req) > MHLEN) {
-		/*
-		 * XXX 
-		 */
-			
-		m_free(m);
-		m = m_gethdr(mpalen + sizeof(*req), M_NOWAIT);
-		if (m == NULL) {
-			connect_reply_upcall(ep, ENOMEM);
-			return;
-		}
+	m = m_gethdr(mpalen, M_NOWAIT);
+	if (m == NULL) {
+		connect_reply_upcall(ep, -ENOMEM);
+		return;
 	}
-	reset_mbuf(m);
-	m_set_priority(m, CPL_PRIORITY_DATA);
-	req = (struct tx_data_wr *)mbuf_put(m, sizeof(*req));
-	mpa = (struct mpa_message *)mbuf_put(m, mpalen);
+	mpa = mtod(m, struct mpa_message *);
+	m->m_len = mpalen;
+	m->m_pkthdr.len = mpalen;
 	memset(mpa, 0, sizeof(*mpa));
 	memcpy(mpa->key, MPA_KEY_REQ, sizeof(mpa->key));
 	mpa->flags = (crc_enabled ? MPA_CRC : 0) |
 		     (markers_enabled ? MPA_MARKERS : 0);
 	mpa->private_data_size = htons(ep->plen);
 	mpa->revision = mpa_rev;
-
 	if (ep->plen)
 		memcpy(mpa->private_data, ep->mpa_pkt + sizeof(*mpa), ep->plen);
 
-	/*
-	 * Reference the mpa mbuf.  This ensures the data area
-	 * will remain in memory until the hw acks the tx.
-	 * Function tx_ack() will deref it.
-	 */
-	m->m_type = MT_DONTFREE; /* XXX */
-	set_arp_failure_handler(m, arp_failure_discard);
-	req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA));
-	req->wr_lo = htonl(V_WR_TID(ep->hwtid));
-	req->len = htonl(mpalen);
-	req->param = htonl(V_TX_PORT(ep->l2t->smt_idx) |
-			   V_TX_SNDBUF(snd_win>>15));
-	req->flags = htonl(F_TX_INIT);
-	req->sndseq = htonl(ep->snd_seq);
-	BUG_ON(ep->mpa_mbuf);
-	ep->mpa_mbuf = m;
-	l2t_send(ep->com.tdev, m, ep->l2t);
+	err = sosend(ep->com.so, NULL, NULL, m, NULL, MSG_DONTWAIT, ep->com.thread);
+	if (err) {
+		m_freem(m);
+		connect_reply_upcall(ep, -ENOMEM);
+		return;
+	}
+		
 	start_ep_timer(ep);
 	state_set(&ep->com, MPA_REQ_SENT);
 	return;
@@ -592,21 +401,22 @@
 send_mpa_reject(struct iwch_ep *ep, const void *pdata, u8 plen)
 {
 	int mpalen;
-	struct tx_data_wr *req;
 	struct mpa_message *mpa;
 	struct mbuf *m;
+	int err;
 
 	PDBG("%s ep %p plen %d\n", __FUNCTION__, ep, plen);
 
 	mpalen = sizeof(*mpa) + plen;
 
-	m = get_mbuf(NULL, mpalen + sizeof(*req), M_NOWAIT);
+	m = m_gethdr(mpalen, M_NOWAIT);
 	if (m == NULL) {
 		printf("%s - cannot alloc mbuf!\n", __FUNCTION__);
 		return (-ENOMEM);
 	}
-	req = (struct tx_data_wr *)mbuf_put(m, sizeof(*req));
-	mpa = (struct mpa_message *) mbuf_put(m, mpalen);
+	mpa = mtod(m, struct mpa_message *);
+	m->m_len = mpalen;
+	m->m_pkthdr.len = mpalen;
 	memset(mpa, 0, sizeof(*mpa));
 	memcpy(mpa->key, MPA_KEY_REP, sizeof(mpa->key));
 	mpa->flags = MPA_REJECT;
@@ -614,20 +424,8 @@
 	mpa->private_data_size = htons(plen);
 	if (plen)
 		memcpy(mpa->private_data, pdata, plen);
-
-	m_set_priority(m, CPL_PRIORITY_DATA);
-	m->m_type = MT_DONTFREE; /* XXX */
-	set_arp_failure_handler(m, arp_failure_discard);
-	req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA));
-	req->wr_lo = htonl(V_WR_TID(ep->hwtid));
-	req->len = htonl(mpalen);
-	req->param = htonl(V_TX_PORT(ep->l2t->smt_idx) |
-			   V_TX_SNDBUF(snd_win>>15));
-	req->flags = htonl(F_TX_INIT);
-	req->sndseq = htonl(ep->snd_seq);
-	BUG_ON(ep->mpa_mbuf);
-	ep->mpa_mbuf = m;
-	l2t_send(ep->com.tdev, m, ep->l2t);
+	err = sosend(ep->com.so, NULL, NULL, m, NULL, MSG_DONTWAIT, ep->com.thread);
+	BUG_ON(err);
 	return 0;
 }
 
@@ -635,24 +433,21 @@
 send_mpa_reply(struct iwch_ep *ep, const void *pdata, u8 plen)
 {
 	int mpalen;
-	struct tx_data_wr *req;
 	struct mpa_message *mpa;
-	int len;
 	struct mbuf *m;
 
 	PDBG("%s ep %p plen %d\n", __FUNCTION__, ep, plen);
 
 	mpalen = sizeof(*mpa) + plen;
 
-	m = get_mbuf(NULL, mpalen + sizeof(*req), M_NOWAIT);
+	m = m_gethdr(mpalen, M_NOWAIT);
 	if (m == NULL) {
 		printf("%s - cannot alloc mbuf!\n", __FUNCTION__);
 		return (-ENOMEM);
 	}
-	m_set_priority(m, CPL_PRIORITY_DATA);
-	m->m_type = MT_DONTFREE; /* XXX */
-	req = (struct tx_data_wr *)mbuf_put(m, sizeof(*req));
-	mpa = (struct mpa_message *)mbuf_put(m, mpalen);
+	mpa = mtod(m, struct mpa_message *);
+	m->m_len = mpalen;
+	m->m_pkthdr.len = mpalen;
 	memset(mpa, 0, sizeof(*mpa));
 	memcpy(mpa->key, MPA_KEY_REP, sizeof(mpa->key));
 	mpa->flags = (ep->mpa_attr.crc_enabled ? MPA_CRC : 0) |
@@ -662,54 +457,17 @@
 	if (plen)
 		memcpy(mpa->private_data, pdata, plen);
 
-	set_arp_failure_handler(m, arp_failure_discard);
-	len = mpalen;
-	req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA));
-	req->wr_lo = htonl(V_WR_TID(ep->hwtid));
-	req->len = htonl(len);
-	req->param = htonl(V_TX_PORT(ep->l2t->smt_idx) |
-			   V_TX_SNDBUF(snd_win>>15));
-	req->flags = htonl(F_TX_INIT);
-	req->sndseq = htonl(ep->snd_seq);
-	ep->mpa_mbuf = m;
 	state_set(&ep->com, MPA_REP_SENT);
-	l2t_send(ep->com.tdev, m, ep->l2t);
-	return 0;
+	return sosend(ep->com.so, NULL, NULL, m, NULL, MSG_DONTWAIT, 
+		ep->com.thread);
 }
 
-static int
-act_establish(struct t3cdev *tdev, struct mbuf *m, void *ctx)
-{
-	struct iwch_ep *ep = ctx;
-	struct cpl_act_establish *req = cplhdr(m);
-	unsigned int tid = GET_TID(req);
-
-	PDBG("%s ep %p tid %d\n", __FUNCTION__, ep, tid);
-
-	/* setup the hwtid for this connection */
-	ep->hwtid = tid;
-	cxgb_insert_tid(ep->com.tdev, &t3c_client, ep, tid);
-
-	ep->snd_seq = ntohl(req->snd_isn);
-	ep->rcv_seq = ntohl(req->rcv_isn);
-
-	set_emss(ep, ntohs(req->tcp_opt));
-
-	/* dealloc the atid */
-	cxgb_free_atid(ep->com.tdev, ep->atid);
-
-	/* start MPA negotiation */
-	send_mpa_req(ep, m);
-
-	return 0;
-}
-
 static void
-abort_connection(struct iwch_ep *ep, struct mbuf *m, int flags)
+abort_connection(struct iwch_ep *ep)
 {
 	PDBG("%s ep %p\n", __FILE__, ep);
 	state_set(&ep->com, ABORTING);
-	send_abort(ep, m, flags);
+	abort_socket(ep);
 }
 
 static void
@@ -827,36 +585,16 @@
 	}
 }
 
-static int
-update_rx_credits(struct iwch_ep *ep, u32 credits)
-{
-	struct cpl_rx_data_ack *req;
-	struct mbuf *m;
-
-	PDBG("%s ep %p credits %u\n", __FUNCTION__, ep, credits);
-	m = get_mbuf(NULL, sizeof(*req), M_NOWAIT);
-	if (m == NULL) {
-		printf("update_rx_credits - cannot alloc mbuf!\n");
-		return 0;
-	}
-
-	req = (struct cpl_rx_data_ack *) mbuf_put(m, sizeof(*req));
-	req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
-	OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_RX_DATA_ACK, ep->hwtid));
-	req->credit_dack = htonl(V_RX_CREDITS(credits) | V_RX_FORCE_ACK(1));
-	m_set_priority(m, CPL_PRIORITY_ACK);
-	cxgb_ofld_send(ep->com.tdev, m);
-	return credits;
-}
-
 static void
-process_mpa_reply(struct iwch_ep *ep, struct mbuf *m)
+process_mpa_reply(struct iwch_ep *ep)
 {
 	struct mpa_message *mpa;
 	u16 plen;
 	struct iwch_qp_attributes attrs;
 	enum iwch_qp_attr_mask mask;
 	int err;
+	struct mbuf *top, *m;
+	int flags = MSG_DONTWAIT;
 
 	PDBG("%s ep %p\n", __FUNCTION__, ep);
 
@@ -869,27 +607,43 @@
 	if (state_read(&ep->com) != MPA_REQ_SENT)
 		return;
 
-	/*
-	 * If we get more than the supported amount of private data
-	 * then we must fail this connection.
-	 */
-	if (ep->mpa_pkt_len + m->m_len > sizeof(ep->mpa_pkt)) {
-		err = (-EINVAL);
+	err = soreceive(ep->com.so, NULL, NULL, &top, NULL, &flags);
+
+	if (err) {
+		err = -err;
 		goto err;
 	}
 
-	/*
-	 * copy the new data into our accumulation buffer.
-	 */
-	m_copydata(m, 0, m->m_len, &(ep->mpa_pkt[ep->mpa_pkt_len]));
-	ep->mpa_pkt_len += m->m_len;
+	m = top;
+	do {
+		/*
+		 * If we get more than the supported amount of private data
+		 * then we must fail this connection.
+		 */
+		if (ep->mpa_pkt_len + m->m_len > sizeof(ep->mpa_pkt)) {
+			err = (-EINVAL);
+			goto err;
+		}
+
+		/*
+		 * copy the new data into our accumulation buffer.
+		 */
+		m_copydata(m, 0, m->m_len, &(ep->mpa_pkt[ep->mpa_pkt_len]));
+		ep->mpa_pkt_len += m->m_len;
+		if (!m->m_next)
+			m = m->m_nextpkt;
+		else
+			m = m->m_next;
+	} while (m);
+
+	m_freem(top);
 
 	/*
 	 * if we don't even have the mpa message, then bail.
 	 */
 	if (ep->mpa_pkt_len < sizeof(*mpa))
 		return;
-	mpa = (struct mpa_message *) ep->mpa_pkt;
+	mpa = (struct mpa_message *)ep->mpa_pkt;
 
 	/* Validate MPA header. */
 	if (mpa->revision != mpa_rev) {
@@ -948,6 +702,10 @@
 	ep->mpa_attr.recv_marker_enabled = markers_enabled;
 	ep->mpa_attr.xmit_marker_enabled = mpa->flags & MPA_MARKERS ? 1 : 0;
 	ep->mpa_attr.version = mpa_rev;
+	if (set_tcpinfo(ep)) {
+		printf("%s set_tcpinfo error\n", __FUNCTION__);
+		goto err;
+	}
 	PDBG("%s - crc_enabled=%d, recv_marker_enabled=%d, "
 	     "xmit_marker_enabled=%d, version=%d\n", __FUNCTION__,
 	     ep->mpa_attr.crc_enabled, ep->mpa_attr.recv_marker_enabled,
@@ -969,17 +727,20 @@
 	if (!err)
 		goto out;
 err:
-	abort_connection(ep, m, M_NOWAIT);
+	abort_connection(ep);
 out:
 	connect_reply_upcall(ep, err);
 	return;
 }
 
 static void
-process_mpa_request(struct iwch_ep *ep, struct mbuf *m)
+process_mpa_request(struct iwch_ep *ep)
 {
 	struct mpa_message *mpa;
 	u16 plen;
+	int flags = MSG_DONTWAIT;
+	struct mbuf *top, *m;
+	int err;
 
 	PDBG("%s ep %p\n", __FUNCTION__, ep);
 
@@ -992,29 +753,52 @@
 	if (state_read(&ep->com) != MPA_REQ_WAIT)
 		return;
 
-	/*
-	 * If we get more than the supported amount of private data
-	 * then we must fail this connection.
-	 */
-	if (ep->mpa_pkt_len + m->m_len > sizeof(ep->mpa_pkt)) {
-		PDBG("%s mpa message too big %d\n", __FUNCTION__, ep->mpa_pkt_len + m->m_len);
-		abort_connection(ep, m, M_NOWAIT);
-		return;
+	err = soreceive(ep->com.so, NULL, NULL, &top, NULL, &flags);
+
+	if (err) {
+		if (err == EWOULDBLOCK) {
+			start_ep_timer(ep);
+			return;
+		}
+		goto err;
 	}
 
+	m = top;
+	do {
+
+		/*
+		 * If we get more than the supported amount of private data
+		 * then we must fail this connection.
+		 */
+		if (ep->mpa_pkt_len + m->m_len > sizeof(ep->mpa_pkt)) {
+			PDBG("%s mpa message too big %d\n", __FUNCTION__, 
+				ep->mpa_pkt_len + m->m_len);
+			goto err;
+		}
+
+
+		/*
+		 * Copy the new data into our accumulation buffer.
+		 */
+		m_copydata(m, 0, m->m_len, &(ep->mpa_pkt[ep->mpa_pkt_len]));
+		ep->mpa_pkt_len += m->m_len;
+
+		if (!m->m_next)
+			m = m->m_nextpkt;
+		else
+			m = m->m_next;
+	} while (m);
 
-	/*
-	 * Copy the new data into our accumulation buffer.
-	 */
-	m_copydata(m, 0, m->m_len, &(ep->mpa_pkt[ep->mpa_pkt_len]));
-	ep->mpa_pkt_len += m->m_len;
+	m_freem(top);
 
 	/*
 	 * If we don't even have the mpa message, then bail.
 	 * We'll continue process when more data arrives.
 	 */
 	if (ep->mpa_pkt_len < sizeof(*mpa)) {
-		PDBG("%s not enough header %d...waiting...\n", __FUNCTION__, ep->mpa_pkt_len);
+		start_ep_timer(ep);
+		PDBG("%s not enough header %d...waiting...\n", __FUNCTION__, 
+			ep->mpa_pkt_len);
 		return;
 	}
 	mpa = (struct mpa_message *) ep->mpa_pkt;
@@ -1024,14 +808,12 @@
 	 */
 	if (mpa->revision != mpa_rev) {
 		PDBG("%s bad mpa rev %d\n", __FUNCTION__, mpa->revision);
-		abort_connection(ep, m, M_NOWAIT);
-		return;
+		goto err;
 	}
 
 	if (memcmp(mpa->key, MPA_KEY_REQ, sizeof(mpa->key))) {
 		PDBG("%s bad mpa key |%16s|\n", __FUNCTION__, mpa->key);
-		abort_connection(ep, m, M_NOWAIT);
-		return;
+		goto err;
 	}
 
 	plen = ntohs(mpa->private_data_size);
@@ -1041,17 +823,16 @@
 	 */
 	if (plen > MPA_MAX_PRIVATE_DATA) {
 		PDBG("%s plen too big %d\n", __FUNCTION__, plen);
-		abort_connection(ep, m, M_NOWAIT);
-		return;
+		goto err;
 	}
 
 	/*
 	 * If plen does not account for pkt size
 	 */
 	if (ep->mpa_pkt_len > (sizeof(*mpa) + plen)) {
-		PDBG("%s more data after private data %d\n", __FUNCTION__, ep->mpa_pkt_len);
-		abort_connection(ep, m, M_NOWAIT);
-		return;
+		PDBG("%s more data after private data %d\n", __FUNCTION__, 
+			ep->mpa_pkt_len);
+		goto err;
 	}
 	ep->plen = (u8) plen;
 
@@ -1059,7 +840,9 @@
 	 * If we don't have all the pdata yet, then bail.
 	 */
 	if (ep->mpa_pkt_len < (sizeof(*mpa) + plen)) {
-		PDBG("%s more mpa msg to come %d\n", __FUNCTION__, ep->mpa_pkt_len);
+		start_ep_timer(ep);
+		PDBG("%s more mpa msg to come %d\n", __FUNCTION__, 
+			ep->mpa_pkt_len);
 		return;
 	}
 
@@ -1071,6 +854,10 @@
 	ep->mpa_attr.recv_marker_enabled = markers_enabled;
 	ep->mpa_attr.xmit_marker_enabled = mpa->flags & MPA_MARKERS ? 1 : 0;
 	ep->mpa_attr.version = mpa_rev;
+	if (set_tcpinfo(ep)) {
+		printf("%s set_tcpinfo error\n", __FUNCTION__);
+		goto err;
+	}
 	PDBG("%s - crc_enabled=%d, recv_marker_enabled=%d, "
 	     "xmit_marker_enabled=%d, version=%d\n", __FUNCTION__,
 	     ep->mpa_attr.crc_enabled, ep->mpa_attr.recv_marker_enabled,
@@ -1081,386 +868,14 @@
 	/* drive upcall */
 	connect_request_upcall(ep);
 	return;
-}
-
-static int
-rx_data(struct t3cdev *tdev, struct mbuf *m, void *ctx)
-{
-	struct iwch_ep *ep = ctx;
-	struct cpl_rx_data *hdr = cplhdr(m);
-	unsigned int dlen = ntohs(hdr->len);
-
-	PDBG("%s ep %p dlen %u\n", __FUNCTION__, ep, dlen);
-
-	m_adj(m, sizeof(*hdr));
-
-	/*
-	 * XXX assume pkthdr
-	 */
-	m->m_pkthdr.len = m->m_len = dlen;
-
-	ep->rcv_seq += dlen;
-	BUG_ON(ep->rcv_seq != (ntohl(hdr->seq) + dlen));
-
-	switch (state_read(&ep->com)) {
-	case MPA_REQ_SENT:
-		process_mpa_reply(ep, m);

>>> TRUNCATED FOR MAIL (1000 lines) <<<



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