From owner-p4-projects@FreeBSD.ORG Wed Jan 30 15:38:21 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 784D216A421; Wed, 30 Jan 2008 15:38:21 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 2488116A417 for ; Wed, 30 Jan 2008 15:38:21 +0000 (UTC) (envelope-from swise@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 1586B13C469 for ; Wed, 30 Jan 2008 15:38:21 +0000 (UTC) (envelope-from swise@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id m0UFcKfx057550 for ; Wed, 30 Jan 2008 15:38:20 GMT (envelope-from swise@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id m0UFcKmE057547 for perforce@freebsd.org; Wed, 30 Jan 2008 15:38:20 GMT (envelope-from swise@FreeBSD.org) Date: Wed, 30 Jan 2008 15:38:20 GMT Message-Id: <200801301538.m0UFcKmE057547@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to swise@FreeBSD.org using -f From: Steve Wise To: Perforce Change Reviews Cc: Subject: PERFORCE change 134477 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 30 Jan 2008 15:38:22 -0000 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 #include #include +#include #include #include #include @@ -55,11 +55,15 @@ #include #include - #include #include #include +#include #include +#include +#include +#include +#include #include #include @@ -67,6 +71,10 @@ #ifdef CONFIG_DEFINED #include +#include +#include +#include +#include #include #include #include @@ -74,6 +82,10 @@ #include #else #include +#include +#include +#include +#include #include #include #include @@ -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) <<<