]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/cxgbe/tom/t4_listen.c
Export tcp_always_keepalive for use by the Chelsio TOM module.
[FreeBSD/FreeBSD.git] / sys / dev / cxgbe / tom / t4_listen.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2012 Chelsio Communications, Inc.
5  * All rights reserved.
6  * Written by: Navdeep Parhar <np@FreeBSD.org>
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32
33 #include "opt_inet.h"
34 #include "opt_inet6.h"
35
36 #ifdef TCP_OFFLOAD
37 #include <sys/param.h>
38 #include <sys/types.h>
39 #include <sys/kernel.h>
40 #include <sys/ktr.h>
41 #include <sys/module.h>
42 #include <sys/protosw.h>
43 #include <sys/refcount.h>
44 #include <sys/domain.h>
45 #include <sys/fnv_hash.h>
46 #include <sys/socket.h>
47 #include <sys/socketvar.h>
48 #include <net/ethernet.h>
49 #include <net/if.h>
50 #include <net/if_types.h>
51 #include <net/if_vlan_var.h>
52 #include <net/route.h>
53 #include <netinet/in.h>
54 #include <netinet/in_fib.h>
55 #include <netinet/in_pcb.h>
56 #include <netinet/ip.h>
57 #include <netinet/ip6.h>
58 #include <netinet6/in6_fib.h>
59 #include <netinet6/scope6_var.h>
60 #include <netinet/tcp_timer.h>
61 #define TCPSTATES
62 #include <netinet/tcp_fsm.h>
63 #include <netinet/tcp_var.h>
64 #include <netinet/toecore.h>
65
66 #include "common/common.h"
67 #include "common/t4_msg.h"
68 #include "common/t4_regs.h"
69 #include "tom/t4_tom_l2t.h"
70 #include "tom/t4_tom.h"
71
72 /* stid services */
73 static int alloc_stid(struct adapter *, struct listen_ctx *, int);
74 static struct listen_ctx *lookup_stid(struct adapter *, int);
75 static void free_stid(struct adapter *, struct listen_ctx *);
76
77 /* lctx services */
78 static struct listen_ctx *alloc_lctx(struct adapter *, struct inpcb *,
79     struct vi_info *);
80 static int free_lctx(struct adapter *, struct listen_ctx *);
81 static void hold_lctx(struct listen_ctx *);
82 static void listen_hash_add(struct adapter *, struct listen_ctx *);
83 static struct listen_ctx *listen_hash_find(struct adapter *, struct inpcb *);
84 static struct listen_ctx *listen_hash_del(struct adapter *, struct inpcb *);
85 static struct inpcb *release_lctx(struct adapter *, struct listen_ctx *);
86
87 static inline void save_qids_in_mbuf(struct mbuf *, struct vi_info *);
88 static inline void get_qids_from_mbuf(struct mbuf *m, int *, int *);
89 static void send_reset_synqe(struct toedev *, struct synq_entry *);
90
91 static int
92 alloc_stid(struct adapter *sc, struct listen_ctx *lctx, int isipv6)
93 {
94         struct tid_info *t = &sc->tids;
95         u_int stid, n, f, mask;
96         struct stid_region *sr = &lctx->stid_region;
97
98         /*
99          * An IPv6 server needs 2 naturally aligned stids (1 stid = 4 cells) in
100          * the TCAM.  The start of the stid region is properly aligned (the chip
101          * requires each region to be 128-cell aligned).
102          */
103         n = isipv6 ? 2 : 1;
104         mask = n - 1;
105         KASSERT((t->stid_base & mask) == 0 && (t->nstids & mask) == 0,
106             ("%s: stid region (%u, %u) not properly aligned.  n = %u",
107             __func__, t->stid_base, t->nstids, n));
108
109         mtx_lock(&t->stid_lock);
110         if (n > t->nstids - t->stids_in_use) {
111                 mtx_unlock(&t->stid_lock);
112                 return (-1);
113         }
114
115         if (t->nstids_free_head >= n) {
116                 /*
117                  * This allocation will definitely succeed because the region
118                  * starts at a good alignment and we just checked we have enough
119                  * stids free.
120                  */
121                 f = t->nstids_free_head & mask;
122                 t->nstids_free_head -= n + f;
123                 stid = t->nstids_free_head;
124                 TAILQ_INSERT_HEAD(&t->stids, sr, link);
125         } else {
126                 struct stid_region *s;
127
128                 stid = t->nstids_free_head;
129                 TAILQ_FOREACH(s, &t->stids, link) {
130                         stid += s->used + s->free;
131                         f = stid & mask;
132                         if (s->free >= n + f) {
133                                 stid -= n + f;
134                                 s->free -= n + f;
135                                 TAILQ_INSERT_AFTER(&t->stids, s, sr, link);
136                                 goto allocated;
137                         }
138                 }
139
140                 if (__predict_false(stid != t->nstids)) {
141                         panic("%s: stids TAILQ (%p) corrupt."
142                             "  At %d instead of %d at the end of the queue.",
143                             __func__, &t->stids, stid, t->nstids);
144                 }
145
146                 mtx_unlock(&t->stid_lock);
147                 return (-1);
148         }
149
150 allocated:
151         sr->used = n;
152         sr->free = f;
153         t->stids_in_use += n;
154         t->stid_tab[stid] = lctx;
155         mtx_unlock(&t->stid_lock);
156
157         KASSERT(((stid + t->stid_base) & mask) == 0,
158             ("%s: EDOOFUS.", __func__));
159         return (stid + t->stid_base);
160 }
161
162 static struct listen_ctx *
163 lookup_stid(struct adapter *sc, int stid)
164 {
165         struct tid_info *t = &sc->tids;
166
167         return (t->stid_tab[stid - t->stid_base]);
168 }
169
170 static void
171 free_stid(struct adapter *sc, struct listen_ctx *lctx)
172 {
173         struct tid_info *t = &sc->tids;
174         struct stid_region *sr = &lctx->stid_region;
175         struct stid_region *s;
176
177         KASSERT(sr->used > 0, ("%s: nonsense free (%d)", __func__, sr->used));
178
179         mtx_lock(&t->stid_lock);
180         s = TAILQ_PREV(sr, stid_head, link);
181         if (s != NULL)
182                 s->free += sr->used + sr->free;
183         else
184                 t->nstids_free_head += sr->used + sr->free;
185         KASSERT(t->stids_in_use >= sr->used,
186             ("%s: stids_in_use (%u) < stids being freed (%u)", __func__,
187             t->stids_in_use, sr->used));
188         t->stids_in_use -= sr->used;
189         TAILQ_REMOVE(&t->stids, sr, link);
190         mtx_unlock(&t->stid_lock);
191 }
192
193 static struct listen_ctx *
194 alloc_lctx(struct adapter *sc, struct inpcb *inp, struct vi_info *vi)
195 {
196         struct listen_ctx *lctx;
197
198         INP_WLOCK_ASSERT(inp);
199
200         lctx = malloc(sizeof(struct listen_ctx), M_CXGBE, M_NOWAIT | M_ZERO);
201         if (lctx == NULL)
202                 return (NULL);
203
204         lctx->stid = alloc_stid(sc, lctx, inp->inp_vflag & INP_IPV6);
205         if (lctx->stid < 0) {
206                 free(lctx, M_CXGBE);
207                 return (NULL);
208         }
209
210         if (inp->inp_vflag & INP_IPV6 &&
211             !IN6_ARE_ADDR_EQUAL(&in6addr_any, &inp->in6p_laddr)) {
212                 struct tom_data *td = sc->tom_softc;
213
214                 lctx->ce = hold_lip(td, &inp->in6p_laddr, NULL);
215                 if (lctx->ce == NULL) {
216                         free(lctx, M_CXGBE);
217                         return (NULL);
218                 }
219         }
220
221         lctx->ctrlq = &sc->sge.ctrlq[vi->pi->port_id];
222         lctx->ofld_rxq = &sc->sge.ofld_rxq[vi->first_ofld_rxq];
223         refcount_init(&lctx->refcount, 1);
224         TAILQ_INIT(&lctx->synq);
225
226         lctx->inp = inp;
227         lctx->vnet = inp->inp_socket->so_vnet;
228         in_pcbref(inp);
229
230         return (lctx);
231 }
232
233 /* Don't call this directly, use release_lctx instead */
234 static int
235 free_lctx(struct adapter *sc, struct listen_ctx *lctx)
236 {
237         struct inpcb *inp = lctx->inp;
238         struct tom_data *td = sc->tom_softc;
239
240         INP_WLOCK_ASSERT(inp);
241         KASSERT(lctx->refcount == 0,
242             ("%s: refcount %d", __func__, lctx->refcount));
243         KASSERT(TAILQ_EMPTY(&lctx->synq),
244             ("%s: synq not empty.", __func__));
245         KASSERT(lctx->stid >= 0, ("%s: bad stid %d.", __func__, lctx->stid));
246
247         CTR4(KTR_CXGBE, "%s: stid %u, lctx %p, inp %p",
248             __func__, lctx->stid, lctx, lctx->inp);
249
250         if (lctx->ce)
251                 release_lip(td, lctx->ce);
252         free_stid(sc, lctx);
253         free(lctx, M_CXGBE);
254
255         return (in_pcbrele_wlocked(inp));
256 }
257
258 static void
259 hold_lctx(struct listen_ctx *lctx)
260 {
261
262         refcount_acquire(&lctx->refcount);
263 }
264
265 static inline uint32_t
266 listen_hashfn(void *key, u_long mask)
267 {
268
269         return (fnv_32_buf(&key, sizeof(key), FNV1_32_INIT) & mask);
270 }
271
272 /*
273  * Add a listen_ctx entry to the listen hash table.
274  */
275 static void
276 listen_hash_add(struct adapter *sc, struct listen_ctx *lctx)
277 {
278         struct tom_data *td = sc->tom_softc;
279         int bucket = listen_hashfn(lctx->inp, td->listen_mask);
280
281         mtx_lock(&td->lctx_hash_lock);
282         LIST_INSERT_HEAD(&td->listen_hash[bucket], lctx, link);
283         td->lctx_count++;
284         mtx_unlock(&td->lctx_hash_lock);
285 }
286
287 /*
288  * Look for the listening socket's context entry in the hash and return it.
289  */
290 static struct listen_ctx *
291 listen_hash_find(struct adapter *sc, struct inpcb *inp)
292 {
293         struct tom_data *td = sc->tom_softc;
294         int bucket = listen_hashfn(inp, td->listen_mask);
295         struct listen_ctx *lctx;
296
297         mtx_lock(&td->lctx_hash_lock);
298         LIST_FOREACH(lctx, &td->listen_hash[bucket], link) {
299                 if (lctx->inp == inp)
300                         break;
301         }
302         mtx_unlock(&td->lctx_hash_lock);
303
304         return (lctx);
305 }
306
307 /*
308  * Removes the listen_ctx structure for inp from the hash and returns it.
309  */
310 static struct listen_ctx *
311 listen_hash_del(struct adapter *sc, struct inpcb *inp)
312 {
313         struct tom_data *td = sc->tom_softc;
314         int bucket = listen_hashfn(inp, td->listen_mask);
315         struct listen_ctx *lctx, *l;
316
317         mtx_lock(&td->lctx_hash_lock);
318         LIST_FOREACH_SAFE(lctx, &td->listen_hash[bucket], link, l) {
319                 if (lctx->inp == inp) {
320                         LIST_REMOVE(lctx, link);
321                         td->lctx_count--;
322                         break;
323                 }
324         }
325         mtx_unlock(&td->lctx_hash_lock);
326
327         return (lctx);
328 }
329
330 /*
331  * Releases a hold on the lctx.  Must be called with the listening socket's inp
332  * locked.  The inp may be freed by this function and it returns NULL to
333  * indicate this.
334  */
335 static struct inpcb *
336 release_lctx(struct adapter *sc, struct listen_ctx *lctx)
337 {
338         struct inpcb *inp = lctx->inp;
339         int inp_freed = 0;
340
341         INP_WLOCK_ASSERT(inp);
342         if (refcount_release(&lctx->refcount))
343                 inp_freed = free_lctx(sc, lctx);
344
345         return (inp_freed ? NULL : inp);
346 }
347
348 static void
349 send_reset_synqe(struct toedev *tod, struct synq_entry *synqe)
350 {
351         struct adapter *sc = tod->tod_softc;
352         struct mbuf *m = synqe->syn;
353         struct ifnet *ifp = m->m_pkthdr.rcvif;
354         struct vi_info *vi = ifp->if_softc;
355         struct port_info *pi = vi->pi;
356         struct l2t_entry *e = &sc->l2t->l2tab[synqe->l2e_idx];
357         struct wrqe *wr;
358         struct fw_flowc_wr *flowc;
359         struct cpl_abort_req *req;
360         int txqid, rxqid, flowclen;
361         struct sge_wrq *ofld_txq;
362         struct sge_ofld_rxq *ofld_rxq;
363         const int nparams = 6;
364         unsigned int pfvf = G_FW_VIID_PFN(vi->viid) << S_FW_VIID_PFN;
365
366         INP_WLOCK_ASSERT(synqe->lctx->inp);
367
368         CTR5(KTR_CXGBE, "%s: synqe %p (0x%x), tid %d%s",
369             __func__, synqe, synqe->flags, synqe->tid,
370             synqe->flags & TPF_ABORT_SHUTDOWN ?
371             " (abort already in progress)" : "");
372         if (synqe->flags & TPF_ABORT_SHUTDOWN)
373                 return; /* abort already in progress */
374         synqe->flags |= TPF_ABORT_SHUTDOWN;
375
376         get_qids_from_mbuf(m, &txqid, &rxqid);
377         ofld_txq = &sc->sge.ofld_txq[txqid];
378         ofld_rxq = &sc->sge.ofld_rxq[rxqid];
379
380         /* The wrqe will have two WRs - a flowc followed by an abort_req */
381         flowclen = sizeof(*flowc) + nparams * sizeof(struct fw_flowc_mnemval);
382
383         wr = alloc_wrqe(roundup2(flowclen, EQ_ESIZE) + sizeof(*req), ofld_txq);
384         if (wr == NULL) {
385                 /* XXX */
386                 panic("%s: allocation failure.", __func__);
387         }
388         flowc = wrtod(wr);
389         req = (void *)((caddr_t)flowc + roundup2(flowclen, EQ_ESIZE));
390
391         /* First the flowc ... */
392         memset(flowc, 0, wr->wr_len);
393         flowc->op_to_nparams = htobe32(V_FW_WR_OP(FW_FLOWC_WR) |
394             V_FW_FLOWC_WR_NPARAMS(nparams));
395         flowc->flowid_len16 = htonl(V_FW_WR_LEN16(howmany(flowclen, 16)) |
396             V_FW_WR_FLOWID(synqe->tid));
397         flowc->mnemval[0].mnemonic = FW_FLOWC_MNEM_PFNVFN;
398         flowc->mnemval[0].val = htobe32(pfvf);
399         flowc->mnemval[1].mnemonic = FW_FLOWC_MNEM_CH;
400         flowc->mnemval[1].val = htobe32(pi->tx_chan);
401         flowc->mnemval[2].mnemonic = FW_FLOWC_MNEM_PORT;
402         flowc->mnemval[2].val = htobe32(pi->tx_chan);
403         flowc->mnemval[3].mnemonic = FW_FLOWC_MNEM_IQID;
404         flowc->mnemval[3].val = htobe32(ofld_rxq->iq.abs_id);
405         flowc->mnemval[4].mnemonic = FW_FLOWC_MNEM_SNDBUF;
406         flowc->mnemval[4].val = htobe32(512);
407         flowc->mnemval[5].mnemonic = FW_FLOWC_MNEM_MSS;
408         flowc->mnemval[5].val = htobe32(512);
409         synqe->flags |= TPF_FLOWC_WR_SENT;
410
411         /* ... then ABORT request */
412         INIT_TP_WR_MIT_CPL(req, CPL_ABORT_REQ, synqe->tid);
413         req->rsvd0 = 0; /* don't have a snd_nxt */
414         req->rsvd1 = 1; /* no data sent yet */
415         req->cmd = CPL_ABORT_SEND_RST;
416
417         t4_l2t_send(sc, wr, e);
418 }
419
420 static int
421 create_server(struct adapter *sc, struct listen_ctx *lctx)
422 {
423         struct wrqe *wr;
424         struct cpl_pass_open_req *req;
425         struct inpcb *inp = lctx->inp;
426
427         wr = alloc_wrqe(sizeof(*req), lctx->ctrlq);
428         if (wr == NULL) {
429                 log(LOG_ERR, "%s: allocation failure", __func__);
430                 return (ENOMEM);
431         }
432         req = wrtod(wr);
433
434         INIT_TP_WR(req, 0);
435         OPCODE_TID(req) = htobe32(MK_OPCODE_TID(CPL_PASS_OPEN_REQ, lctx->stid));
436         req->local_port = inp->inp_lport;
437         req->peer_port = 0;
438         req->local_ip = inp->inp_laddr.s_addr;
439         req->peer_ip = 0;
440         req->opt0 = htobe64(V_TX_CHAN(lctx->ctrlq->eq.tx_chan));
441         req->opt1 = htobe64(V_CONN_POLICY(CPL_CONN_POLICY_ASK) |
442             F_SYN_RSS_ENABLE | V_SYN_RSS_QUEUE(lctx->ofld_rxq->iq.abs_id));
443
444         t4_wrq_tx(sc, wr);
445         return (0);
446 }
447
448 static int
449 create_server6(struct adapter *sc, struct listen_ctx *lctx)
450 {
451         struct wrqe *wr;
452         struct cpl_pass_open_req6 *req;
453         struct inpcb *inp = lctx->inp;
454
455         wr = alloc_wrqe(sizeof(*req), lctx->ctrlq);
456         if (wr == NULL) {
457                 log(LOG_ERR, "%s: allocation failure", __func__);
458                 return (ENOMEM);
459         }
460         req = wrtod(wr);
461
462         INIT_TP_WR(req, 0);
463         OPCODE_TID(req) = htobe32(MK_OPCODE_TID(CPL_PASS_OPEN_REQ6, lctx->stid));
464         req->local_port = inp->inp_lport;
465         req->peer_port = 0;
466         req->local_ip_hi = *(uint64_t *)&inp->in6p_laddr.s6_addr[0];
467         req->local_ip_lo = *(uint64_t *)&inp->in6p_laddr.s6_addr[8];
468         req->peer_ip_hi = 0;
469         req->peer_ip_lo = 0;
470         req->opt0 = htobe64(V_TX_CHAN(lctx->ctrlq->eq.tx_chan));
471         req->opt1 = htobe64(V_CONN_POLICY(CPL_CONN_POLICY_ASK) |
472             F_SYN_RSS_ENABLE | V_SYN_RSS_QUEUE(lctx->ofld_rxq->iq.abs_id));
473
474         t4_wrq_tx(sc, wr);
475         return (0);
476 }
477
478 static int
479 destroy_server(struct adapter *sc, struct listen_ctx *lctx)
480 {
481         struct wrqe *wr;
482         struct cpl_close_listsvr_req *req;
483
484         wr = alloc_wrqe(sizeof(*req), lctx->ctrlq);
485         if (wr == NULL) {
486                 /* XXX */
487                 panic("%s: allocation failure.", __func__);
488         }
489         req = wrtod(wr);
490
491         INIT_TP_WR(req, 0);
492         OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_CLOSE_LISTSRV_REQ,
493             lctx->stid));
494         req->reply_ctrl = htobe16(lctx->ofld_rxq->iq.abs_id);
495         req->rsvd = htobe16(0);
496
497         t4_wrq_tx(sc, wr);
498         return (0);
499 }
500
501 /*
502  * Start a listening server by sending a passive open request to HW.
503  *
504  * Can't take adapter lock here and access to sc->flags,
505  * sc->offload_map, if_capenable are all race prone.
506  */
507 int
508 t4_listen_start(struct toedev *tod, struct tcpcb *tp)
509 {
510         struct adapter *sc = tod->tod_softc;
511         struct vi_info *vi;
512         struct port_info *pi;
513         struct inpcb *inp = tp->t_inpcb;
514         struct listen_ctx *lctx;
515         int i, rc, v;
516
517         INP_WLOCK_ASSERT(inp);
518
519         /* Don't start a hardware listener for any loopback address. */
520         if (inp->inp_vflag & INP_IPV6 && IN6_IS_ADDR_LOOPBACK(&inp->in6p_laddr))
521                 return (0);
522         if (!(inp->inp_vflag & INP_IPV6) &&
523             IN_LOOPBACK(ntohl(inp->inp_laddr.s_addr)))
524                 return (0);
525 #if 0
526         ADAPTER_LOCK(sc);
527         if (IS_BUSY(sc)) {
528                 log(LOG_ERR, "%s: listen request ignored, %s is busy",
529                     __func__, device_get_nameunit(sc->dev));
530                 goto done;
531         }
532
533         KASSERT(uld_active(sc, ULD_TOM),
534             ("%s: TOM not initialized", __func__));
535 #endif
536
537         /*
538          * Find an initialized VI with IFCAP_TOE (4 or 6).  We'll use the first
539          * such VI's queues to send the passive open and receive the reply to
540          * it.
541          *
542          * XXX: need a way to mark a port in use by offload.  if_cxgbe should
543          * then reject any attempt to bring down such a port (and maybe reject
544          * attempts to disable IFCAP_TOE on that port too?).
545          */
546         for_each_port(sc, i) {
547                 pi = sc->port[i];
548                 for_each_vi(pi, v, vi) {
549                         if (vi->flags & VI_INIT_DONE &&
550                             vi->ifp->if_capenable & IFCAP_TOE)
551                                 goto found;
552                 }
553         }
554         goto done;      /* no port that's UP with IFCAP_TOE enabled */
555 found:
556
557         if (listen_hash_find(sc, inp) != NULL)
558                 goto done;      /* already setup */
559
560         lctx = alloc_lctx(sc, inp, vi);
561         if (lctx == NULL) {
562                 log(LOG_ERR,
563                     "%s: listen request ignored, %s couldn't allocate lctx\n",
564                     __func__, device_get_nameunit(sc->dev));
565                 goto done;
566         }
567         listen_hash_add(sc, lctx);
568
569         CTR6(KTR_CXGBE, "%s: stid %u (%s), lctx %p, inp %p vflag 0x%x",
570             __func__, lctx->stid, tcpstates[tp->t_state], lctx, inp,
571             inp->inp_vflag);
572
573         if (inp->inp_vflag & INP_IPV6)
574                 rc = create_server6(sc, lctx);
575         else
576                 rc = create_server(sc, lctx);
577         if (rc != 0) {
578                 log(LOG_ERR, "%s: %s failed to create hw listener: %d.\n",
579                     __func__, device_get_nameunit(sc->dev), rc);
580                 (void) listen_hash_del(sc, inp);
581                 inp = release_lctx(sc, lctx);
582                 /* can't be freed, host stack has a reference */
583                 KASSERT(inp != NULL, ("%s: inp freed", __func__));
584                 goto done;
585         }
586         lctx->flags |= LCTX_RPL_PENDING;
587 done:
588 #if 0
589         ADAPTER_UNLOCK(sc);
590 #endif
591         return (0);
592 }
593
594 int
595 t4_listen_stop(struct toedev *tod, struct tcpcb *tp)
596 {
597         struct listen_ctx *lctx;
598         struct adapter *sc = tod->tod_softc;
599         struct inpcb *inp = tp->t_inpcb;
600         struct synq_entry *synqe;
601
602         INP_WLOCK_ASSERT(inp);
603
604         lctx = listen_hash_del(sc, inp);
605         if (lctx == NULL)
606                 return (ENOENT);        /* no hardware listener for this inp */
607
608         CTR4(KTR_CXGBE, "%s: stid %u, lctx %p, flags %x", __func__, lctx->stid,
609             lctx, lctx->flags);
610
611         /*
612          * If the reply to the PASS_OPEN is still pending we'll wait for it to
613          * arrive and clean up when it does.
614          */
615         if (lctx->flags & LCTX_RPL_PENDING) {
616                 KASSERT(TAILQ_EMPTY(&lctx->synq),
617                     ("%s: synq not empty.", __func__));
618                 return (EINPROGRESS);
619         }
620
621         /*
622          * The host stack will abort all the connections on the listening
623          * socket's so_comp.  It doesn't know about the connections on the synq
624          * so we need to take care of those.
625          */
626         TAILQ_FOREACH(synqe, &lctx->synq, link) {
627                 if (synqe->flags & TPF_SYNQE_HAS_L2TE)
628                         send_reset_synqe(tod, synqe);
629         }
630
631         destroy_server(sc, lctx);
632         return (0);
633 }
634
635 static inline void
636 hold_synqe(struct synq_entry *synqe)
637 {
638
639         refcount_acquire(&synqe->refcnt);
640 }
641
642 static inline void
643 release_synqe(struct synq_entry *synqe)
644 {
645
646         if (refcount_release(&synqe->refcnt)) {
647                 int needfree = synqe->flags & TPF_SYNQE_NEEDFREE;
648
649                 m_freem(synqe->syn);
650                 if (needfree)
651                         free(synqe, M_CXGBE);
652         }
653 }
654
655 void
656 t4_syncache_added(struct toedev *tod __unused, void *arg)
657 {
658         struct synq_entry *synqe = arg;
659
660         hold_synqe(synqe);
661 }
662
663 void
664 t4_syncache_removed(struct toedev *tod __unused, void *arg)
665 {
666         struct synq_entry *synqe = arg;
667
668         release_synqe(synqe);
669 }
670
671 int
672 t4_syncache_respond(struct toedev *tod, void *arg, struct mbuf *m)
673 {
674         struct adapter *sc = tod->tod_softc;
675         struct synq_entry *synqe = arg;
676         struct wrqe *wr;
677         struct l2t_entry *e;
678         struct tcpopt to;
679         struct ip *ip = mtod(m, struct ip *);
680         struct tcphdr *th;
681
682         wr = (struct wrqe *)atomic_readandclear_ptr(&synqe->wr);
683         if (wr == NULL) {
684                 m_freem(m);
685                 return (EALREADY);
686         }
687
688         if (ip->ip_v == IPVERSION)
689                 th = (void *)(ip + 1);
690         else
691                 th = (void *)((struct ip6_hdr *)ip + 1);
692         bzero(&to, sizeof(to));
693         tcp_dooptions(&to, (void *)(th + 1), (th->th_off << 2) - sizeof(*th),
694             TO_SYN);
695
696         /* save these for later */
697         synqe->iss = be32toh(th->th_seq);
698         synqe->ts = to.to_tsval;
699
700         if (chip_id(sc) >= CHELSIO_T5) {
701                 struct cpl_t5_pass_accept_rpl *rpl5 = wrtod(wr);
702
703                 rpl5->iss = th->th_seq;
704         }
705
706         e = &sc->l2t->l2tab[synqe->l2e_idx];
707         t4_l2t_send(sc, wr, e);
708
709         m_freem(m);     /* don't need this any more */
710         return (0);
711 }
712
713 static int
714 do_pass_open_rpl(struct sge_iq *iq, const struct rss_header *rss,
715     struct mbuf *m)
716 {
717         struct adapter *sc = iq->adapter;
718         const struct cpl_pass_open_rpl *cpl = (const void *)(rss + 1);
719         int stid = GET_TID(cpl);
720         unsigned int status = cpl->status;
721         struct listen_ctx *lctx = lookup_stid(sc, stid);
722         struct inpcb *inp = lctx->inp;
723 #ifdef INVARIANTS
724         unsigned int opcode = G_CPL_OPCODE(be32toh(OPCODE_TID(cpl)));
725 #endif
726
727         KASSERT(opcode == CPL_PASS_OPEN_RPL,
728             ("%s: unexpected opcode 0x%x", __func__, opcode));
729         KASSERT(m == NULL, ("%s: wasn't expecting payload", __func__));
730         KASSERT(lctx->stid == stid, ("%s: lctx stid mismatch", __func__));
731
732         INP_WLOCK(inp);
733
734         CTR4(KTR_CXGBE, "%s: stid %d, status %u, flags 0x%x",
735             __func__, stid, status, lctx->flags);
736
737         lctx->flags &= ~LCTX_RPL_PENDING;
738
739         if (status != CPL_ERR_NONE)
740                 log(LOG_ERR, "listener (stid %u) failed: %d\n", stid, status);
741
742 #ifdef INVARIANTS
743         /*
744          * If the inp has been dropped (listening socket closed) then
745          * listen_stop must have run and taken the inp out of the hash.
746          */
747         if (inp->inp_flags & INP_DROPPED) {
748                 KASSERT(listen_hash_del(sc, inp) == NULL,
749                     ("%s: inp %p still in listen hash", __func__, inp));
750         }
751 #endif
752
753         if (inp->inp_flags & INP_DROPPED && status != CPL_ERR_NONE) {
754                 if (release_lctx(sc, lctx) != NULL)
755                         INP_WUNLOCK(inp);
756                 return (status);
757         }
758
759         /*
760          * Listening socket stopped listening earlier and now the chip tells us
761          * it has started the hardware listener.  Stop it; the lctx will be
762          * released in do_close_server_rpl.
763          */
764         if (inp->inp_flags & INP_DROPPED) {
765                 destroy_server(sc, lctx);
766                 INP_WUNLOCK(inp);
767                 return (status);
768         }
769
770         /*
771          * Failed to start hardware listener.  Take inp out of the hash and
772          * release our reference on it.  An error message has been logged
773          * already.
774          */
775         if (status != CPL_ERR_NONE) {
776                 listen_hash_del(sc, inp);
777                 if (release_lctx(sc, lctx) != NULL)
778                         INP_WUNLOCK(inp);
779                 return (status);
780         }
781
782         /* hardware listener open for business */
783
784         INP_WUNLOCK(inp);
785         return (status);
786 }
787
788 static int
789 do_close_server_rpl(struct sge_iq *iq, const struct rss_header *rss,
790     struct mbuf *m)
791 {
792         struct adapter *sc = iq->adapter;
793         const struct cpl_close_listsvr_rpl *cpl = (const void *)(rss + 1);
794         int stid = GET_TID(cpl);
795         unsigned int status = cpl->status;
796         struct listen_ctx *lctx = lookup_stid(sc, stid);
797         struct inpcb *inp = lctx->inp;
798 #ifdef INVARIANTS
799         unsigned int opcode = G_CPL_OPCODE(be32toh(OPCODE_TID(cpl)));
800 #endif
801
802         KASSERT(opcode == CPL_CLOSE_LISTSRV_RPL,
803             ("%s: unexpected opcode 0x%x", __func__, opcode));
804         KASSERT(m == NULL, ("%s: wasn't expecting payload", __func__));
805         KASSERT(lctx->stid == stid, ("%s: lctx stid mismatch", __func__));
806
807         CTR3(KTR_CXGBE, "%s: stid %u, status %u", __func__, stid, status);
808
809         if (status != CPL_ERR_NONE) {
810                 log(LOG_ERR, "%s: failed (%u) to close listener for stid %u\n",
811                     __func__, status, stid);
812                 return (status);
813         }
814
815         INP_WLOCK(inp);
816         inp = release_lctx(sc, lctx);
817         if (inp != NULL)
818                 INP_WUNLOCK(inp);
819
820         return (status);
821 }
822
823 static void
824 done_with_synqe(struct adapter *sc, struct synq_entry *synqe)
825 {
826         struct listen_ctx *lctx = synqe->lctx;
827         struct inpcb *inp = lctx->inp;
828         struct vi_info *vi = synqe->syn->m_pkthdr.rcvif->if_softc;
829         struct l2t_entry *e = &sc->l2t->l2tab[synqe->l2e_idx];
830         int ntids;
831
832         INP_WLOCK_ASSERT(inp);
833         ntids = inp->inp_vflag & INP_IPV6 ? 2 : 1;
834
835         TAILQ_REMOVE(&lctx->synq, synqe, link);
836         inp = release_lctx(sc, lctx);
837         if (inp)
838                 INP_WUNLOCK(inp);
839         remove_tid(sc, synqe->tid, ntids);
840         release_tid(sc, synqe->tid, &sc->sge.ctrlq[vi->pi->port_id]);
841         t4_l2t_release(e);
842         release_synqe(synqe);   /* removed from synq list */
843 }
844
845 int
846 do_abort_req_synqe(struct sge_iq *iq, const struct rss_header *rss,
847     struct mbuf *m)
848 {
849         struct adapter *sc = iq->adapter;
850         const struct cpl_abort_req_rss *cpl = (const void *)(rss + 1);
851         unsigned int tid = GET_TID(cpl);
852         struct synq_entry *synqe = lookup_tid(sc, tid);
853         struct listen_ctx *lctx = synqe->lctx;
854         struct inpcb *inp = lctx->inp;
855         int txqid;
856         struct sge_wrq *ofld_txq;
857 #ifdef INVARIANTS
858         unsigned int opcode = G_CPL_OPCODE(be32toh(OPCODE_TID(cpl)));
859 #endif
860
861         KASSERT(opcode == CPL_ABORT_REQ_RSS,
862             ("%s: unexpected opcode 0x%x", __func__, opcode));
863         KASSERT(m == NULL, ("%s: wasn't expecting payload", __func__));
864         KASSERT(synqe->tid == tid, ("%s: toep tid mismatch", __func__));
865
866         CTR6(KTR_CXGBE, "%s: tid %u, synqe %p (0x%x), lctx %p, status %d",
867             __func__, tid, synqe, synqe->flags, synqe->lctx, cpl->status);
868
869         if (negative_advice(cpl->status))
870                 return (0);     /* Ignore negative advice */
871
872         INP_WLOCK(inp);
873
874         get_qids_from_mbuf(synqe->syn, &txqid, NULL);
875         ofld_txq = &sc->sge.ofld_txq[txqid];
876
877         /*
878          * If we'd initiated an abort earlier the reply to it is responsible for
879          * cleaning up resources.  Otherwise we tear everything down right here
880          * right now.  We owe the T4 a CPL_ABORT_RPL no matter what.
881          */
882         if (synqe->flags & TPF_ABORT_SHUTDOWN) {
883                 INP_WUNLOCK(inp);
884                 goto done;
885         }
886
887         done_with_synqe(sc, synqe);
888         /* inp lock released by done_with_synqe */
889 done:
890         send_abort_rpl(sc, ofld_txq, tid, CPL_ABORT_NO_RST);
891         return (0);
892 }
893
894 int
895 do_abort_rpl_synqe(struct sge_iq *iq, const struct rss_header *rss,
896     struct mbuf *m)
897 {
898         struct adapter *sc = iq->adapter;
899         const struct cpl_abort_rpl_rss *cpl = (const void *)(rss + 1);
900         unsigned int tid = GET_TID(cpl);
901         struct synq_entry *synqe = lookup_tid(sc, tid);
902         struct listen_ctx *lctx = synqe->lctx;
903         struct inpcb *inp = lctx->inp;
904 #ifdef INVARIANTS
905         unsigned int opcode = G_CPL_OPCODE(be32toh(OPCODE_TID(cpl)));
906 #endif
907
908         KASSERT(opcode == CPL_ABORT_RPL_RSS,
909             ("%s: unexpected opcode 0x%x", __func__, opcode));
910         KASSERT(m == NULL, ("%s: wasn't expecting payload", __func__));
911         KASSERT(synqe->tid == tid, ("%s: toep tid mismatch", __func__));
912
913         CTR6(KTR_CXGBE, "%s: tid %u, synqe %p (0x%x), lctx %p, status %d",
914             __func__, tid, synqe, synqe->flags, synqe->lctx, cpl->status);
915
916         INP_WLOCK(inp);
917         KASSERT(synqe->flags & TPF_ABORT_SHUTDOWN,
918             ("%s: wasn't expecting abort reply for synqe %p (0x%x)",
919             __func__, synqe, synqe->flags));
920
921         done_with_synqe(sc, synqe);
922         /* inp lock released by done_with_synqe */
923
924         return (0);
925 }
926
927 void
928 t4_offload_socket(struct toedev *tod, void *arg, struct socket *so)
929 {
930         struct adapter *sc = tod->tod_softc;
931         struct synq_entry *synqe = arg;
932 #ifdef INVARIANTS
933         struct inpcb *inp = sotoinpcb(so);
934 #endif
935         struct cpl_pass_establish *cpl = mtod(synqe->syn, void *);
936         struct toepcb *toep = *(struct toepcb **)(cpl + 1);
937
938         INP_INFO_RLOCK_ASSERT(&V_tcbinfo); /* prevents bad race with accept() */
939         INP_WLOCK_ASSERT(inp);
940         KASSERT(synqe->flags & TPF_SYNQE,
941             ("%s: %p not a synq_entry?", __func__, arg));
942
943         offload_socket(so, toep);
944         make_established(toep, cpl->snd_isn, cpl->rcv_isn, cpl->tcp_opt);
945         toep->flags |= TPF_CPL_PENDING;
946         update_tid(sc, synqe->tid, toep);
947         synqe->flags |= TPF_SYNQE_EXPANDED;
948 }
949
950 static inline void
951 save_qids_in_mbuf(struct mbuf *m, struct vi_info *vi)
952 {
953         uint32_t txqid, rxqid;
954
955         txqid = (arc4random() % vi->nofldtxq) + vi->first_ofld_txq;
956         rxqid = (arc4random() % vi->nofldrxq) + vi->first_ofld_rxq;
957
958         m->m_pkthdr.flowid = (txqid << 16) | (rxqid & 0xffff);
959 }
960
961 static inline void
962 get_qids_from_mbuf(struct mbuf *m, int *txqid, int *rxqid)
963 {
964
965         if (txqid)
966                 *txqid = m->m_pkthdr.flowid >> 16;
967         if (rxqid)
968                 *rxqid = m->m_pkthdr.flowid & 0xffff;
969 }
970
971 /*
972  * Use the trailing space in the mbuf in which the PASS_ACCEPT_REQ arrived to
973  * store some state temporarily.
974  */
975 static struct synq_entry *
976 mbuf_to_synqe(struct mbuf *m)
977 {
978         int len = roundup2(sizeof (struct synq_entry), 8);
979         int tspace = M_TRAILINGSPACE(m);
980         struct synq_entry *synqe = NULL;
981
982         if (tspace < len) {
983                 synqe = malloc(sizeof(*synqe), M_CXGBE, M_NOWAIT);
984                 if (synqe == NULL)
985                         return (NULL);
986                 synqe->flags = TPF_SYNQE | TPF_SYNQE_NEEDFREE;
987         } else {
988                 synqe = (void *)(m->m_data + m->m_len + tspace - len);
989                 synqe->flags = TPF_SYNQE;
990         }
991
992         return (synqe);
993 }
994
995 static void
996 t4opt_to_tcpopt(const struct tcp_options *t4opt, struct tcpopt *to)
997 {
998         bzero(to, sizeof(*to));
999
1000         if (t4opt->mss) {
1001                 to->to_flags |= TOF_MSS;
1002                 to->to_mss = be16toh(t4opt->mss);
1003         }
1004
1005         if (t4opt->wsf) {
1006                 to->to_flags |= TOF_SCALE;
1007                 to->to_wscale = t4opt->wsf;
1008         }
1009
1010         if (t4opt->tstamp)
1011                 to->to_flags |= TOF_TS;
1012
1013         if (t4opt->sack)
1014                 to->to_flags |= TOF_SACKPERM;
1015 }
1016
1017 /*
1018  * Options2 for passive open.
1019  */
1020 static uint32_t
1021 calc_opt2p(struct adapter *sc, struct port_info *pi, int rxqid,
1022     const struct tcp_options *tcpopt, struct tcphdr *th, int ulp_mode)
1023 {
1024         struct sge_ofld_rxq *ofld_rxq = &sc->sge.ofld_rxq[rxqid];
1025         uint32_t opt2;
1026
1027         opt2 = V_TX_QUEUE(sc->params.tp.tx_modq[pi->tx_chan]) |
1028             F_RSS_QUEUE_VALID | V_RSS_QUEUE(ofld_rxq->iq.abs_id);
1029
1030         if (V_tcp_do_rfc1323) {
1031                 if (tcpopt->tstamp)
1032                         opt2 |= F_TSTAMPS_EN;
1033                 if (tcpopt->sack)
1034                         opt2 |= F_SACK_EN;
1035                 if (tcpopt->wsf <= 14)
1036                         opt2 |= F_WND_SCALE_EN;
1037         }
1038
1039         if (V_tcp_do_ecn && th->th_flags & (TH_ECE | TH_CWR))
1040                 opt2 |= F_CCTRL_ECN;
1041
1042         /* RX_COALESCE is always a valid value (0 or M_RX_COALESCE). */
1043         if (is_t4(sc))
1044                 opt2 |= F_RX_COALESCE_VALID;
1045         else {
1046                 opt2 |= F_T5_OPT_2_VALID;
1047                 opt2 |= F_T5_ISS;
1048         }
1049         if (sc->tt.rx_coalesce)
1050                 opt2 |= V_RX_COALESCE(M_RX_COALESCE);
1051
1052         if (sc->tt.cong_algorithm != -1)
1053                 opt2 |= V_CONG_CNTRL(sc->tt.cong_algorithm & M_CONG_CNTRL);
1054
1055 #ifdef USE_DDP_RX_FLOW_CONTROL
1056         if (ulp_mode == ULP_MODE_TCPDDP)
1057                 opt2 |= F_RX_FC_VALID | F_RX_FC_DDP;
1058 #endif
1059
1060         return htobe32(opt2);
1061 }
1062
1063 static void
1064 pass_accept_req_to_protohdrs(struct adapter *sc, const struct mbuf *m,
1065     struct in_conninfo *inc, struct tcphdr *th)
1066 {
1067         const struct cpl_pass_accept_req *cpl = mtod(m, const void *);
1068         const struct ether_header *eh;
1069         unsigned int hlen = be32toh(cpl->hdr_len);
1070         uintptr_t l3hdr;
1071         const struct tcphdr *tcp;
1072
1073         eh = (const void *)(cpl + 1);
1074         if (chip_id(sc) >= CHELSIO_T6) {
1075                 l3hdr = ((uintptr_t)eh + G_T6_ETH_HDR_LEN(hlen));
1076                 tcp = (const void *)(l3hdr + G_T6_IP_HDR_LEN(hlen));
1077         } else {
1078                 l3hdr = ((uintptr_t)eh + G_ETH_HDR_LEN(hlen));
1079                 tcp = (const void *)(l3hdr + G_IP_HDR_LEN(hlen));
1080         }
1081
1082         if (inc) {
1083                 bzero(inc, sizeof(*inc));
1084                 inc->inc_fport = tcp->th_sport;
1085                 inc->inc_lport = tcp->th_dport;
1086                 if (((struct ip *)l3hdr)->ip_v == IPVERSION) {
1087                         const struct ip *ip = (const void *)l3hdr;
1088
1089                         inc->inc_faddr = ip->ip_src;
1090                         inc->inc_laddr = ip->ip_dst;
1091                 } else {
1092                         const struct ip6_hdr *ip6 = (const void *)l3hdr;
1093
1094                         inc->inc_flags |= INC_ISIPV6;
1095                         inc->inc6_faddr = ip6->ip6_src;
1096                         inc->inc6_laddr = ip6->ip6_dst;
1097                 }
1098         }
1099
1100         if (th) {
1101                 bcopy(tcp, th, sizeof(*th));
1102                 tcp_fields_to_host(th);         /* just like tcp_input */
1103         }
1104 }
1105
1106 static struct l2t_entry *
1107 get_l2te_for_nexthop(struct port_info *pi, struct ifnet *ifp,
1108     struct in_conninfo *inc)
1109 {
1110         struct l2t_entry *e;
1111         struct sockaddr_in6 sin6;
1112         struct sockaddr *dst = (void *)&sin6;
1113  
1114         if (inc->inc_flags & INC_ISIPV6) {
1115                 struct nhop6_basic nh6;
1116
1117                 bzero(dst, sizeof(struct sockaddr_in6));
1118                 dst->sa_len = sizeof(struct sockaddr_in6);
1119                 dst->sa_family = AF_INET6;
1120
1121                 if (IN6_IS_ADDR_LINKLOCAL(&inc->inc6_laddr)) {
1122                         /* no need for route lookup */
1123                         e = t4_l2t_get(pi, ifp, dst);
1124                         return (e);
1125                 }
1126
1127                 if (fib6_lookup_nh_basic(RT_DEFAULT_FIB, &inc->inc6_faddr,
1128                     0, 0, 0, &nh6) != 0)
1129                         return (NULL);
1130                 if (nh6.nh_ifp != ifp)
1131                         return (NULL);
1132                 ((struct sockaddr_in6 *)dst)->sin6_addr = nh6.nh_addr;
1133         } else {
1134                 struct nhop4_basic nh4;
1135
1136                 dst->sa_len = sizeof(struct sockaddr_in);
1137                 dst->sa_family = AF_INET;
1138
1139                 if (fib4_lookup_nh_basic(RT_DEFAULT_FIB, inc->inc_faddr, 0, 0,
1140                     &nh4) != 0)
1141                         return (NULL);
1142                 if (nh4.nh_ifp != ifp)
1143                         return (NULL);
1144                 ((struct sockaddr_in *)dst)->sin_addr = nh4.nh_addr;
1145         }
1146
1147         e = t4_l2t_get(pi, ifp, dst);
1148         return (e);
1149 }
1150
1151 #define REJECT_PASS_ACCEPT()    do { \
1152         reject_reason = __LINE__; \
1153         goto reject; \
1154 } while (0)
1155
1156 /*
1157  * The context associated with a tid entry via insert_tid could be a synq_entry
1158  * or a toepcb.  The only way CPL handlers can tell is via a bit in these flags.
1159  */
1160 CTASSERT(offsetof(struct toepcb, flags) == offsetof(struct synq_entry, flags));
1161
1162 /*
1163  * Incoming SYN on a listening socket.
1164  *
1165  * XXX: Every use of ifp in this routine has a bad race with up/down, toe/-toe,
1166  * etc.
1167  */
1168 static int
1169 do_pass_accept_req(struct sge_iq *iq, const struct rss_header *rss,
1170     struct mbuf *m)
1171 {
1172         struct adapter *sc = iq->adapter;
1173         struct toedev *tod;
1174         const struct cpl_pass_accept_req *cpl = mtod(m, const void *);
1175         struct cpl_pass_accept_rpl *rpl;
1176         struct wrqe *wr;
1177         unsigned int stid = G_PASS_OPEN_TID(be32toh(cpl->tos_stid));
1178         unsigned int tid = GET_TID(cpl);
1179         struct listen_ctx *lctx = lookup_stid(sc, stid);
1180         struct inpcb *inp;
1181         struct socket *so;
1182         struct in_conninfo inc;
1183         struct tcphdr th;
1184         struct tcpopt to;
1185         struct port_info *pi;
1186         struct vi_info *vi;
1187         struct ifnet *hw_ifp, *ifp;
1188         struct l2t_entry *e = NULL;
1189         int rscale, mtu_idx, rx_credits, rxqid, ulp_mode;
1190         struct synq_entry *synqe = NULL;
1191         int reject_reason, v, ntids;
1192         uint16_t vid;
1193         u_int wnd;
1194 #ifdef INVARIANTS
1195         unsigned int opcode = G_CPL_OPCODE(be32toh(OPCODE_TID(cpl)));
1196 #endif
1197
1198         KASSERT(opcode == CPL_PASS_ACCEPT_REQ,
1199             ("%s: unexpected opcode 0x%x", __func__, opcode));
1200         KASSERT(lctx->stid == stid, ("%s: lctx stid mismatch", __func__));
1201
1202         CTR4(KTR_CXGBE, "%s: stid %u, tid %u, lctx %p", __func__, stid, tid,
1203             lctx);
1204
1205         pass_accept_req_to_protohdrs(sc, m, &inc, &th);
1206         t4opt_to_tcpopt(&cpl->tcpopt, &to);
1207
1208         pi = sc->port[G_SYN_INTF(be16toh(cpl->l2info))];
1209
1210         CURVNET_SET(lctx->vnet);
1211
1212         /*
1213          * Use the MAC index to lookup the associated VI.  If this SYN
1214          * didn't match a perfect MAC filter, punt.
1215          */
1216         if (!(be16toh(cpl->l2info) & F_SYN_XACT_MATCH)) {
1217                 m_freem(m);
1218                 m = NULL;
1219                 REJECT_PASS_ACCEPT();
1220         }
1221         for_each_vi(pi, v, vi) {
1222                 if (vi->xact_addr_filt == G_SYN_MAC_IDX(be16toh(cpl->l2info)))
1223                         goto found;
1224         }
1225         m_freem(m);
1226         m = NULL;
1227         REJECT_PASS_ACCEPT();
1228
1229 found:
1230         hw_ifp = vi->ifp;       /* the (v)cxgbeX ifnet */
1231         m->m_pkthdr.rcvif = hw_ifp;
1232         tod = TOEDEV(hw_ifp);
1233
1234         /*
1235          * Figure out if there is a pseudo interface (vlan, lagg, etc.)
1236          * involved.  Don't offload if the SYN had a VLAN tag and the vid
1237          * doesn't match anything on this interface.
1238          *
1239          * XXX: lagg support, lagg + vlan support.
1240          */
1241         vid = EVL_VLANOFTAG(be16toh(cpl->vlan));
1242         if (vid != 0xfff) {
1243                 ifp = VLAN_DEVAT(hw_ifp, vid);
1244                 if (ifp == NULL)
1245                         REJECT_PASS_ACCEPT();
1246         } else
1247                 ifp = hw_ifp;
1248
1249         /*
1250          * Don't offload if the peer requested a TCP option that's not known to
1251          * the silicon.
1252          */
1253         if (cpl->tcpopt.unknown)
1254                 REJECT_PASS_ACCEPT();
1255
1256         if (inc.inc_flags & INC_ISIPV6) {
1257
1258                 /* Don't offload if the ifcap isn't enabled */
1259                 if ((ifp->if_capenable & IFCAP_TOE6) == 0)
1260                         REJECT_PASS_ACCEPT();
1261
1262                 /*
1263                  * SYN must be directed to an IP6 address on this ifnet.  This
1264                  * is more restrictive than in6_localip.
1265                  */
1266                 if (!in6_ifhasaddr(ifp, &inc.inc6_laddr))
1267                         REJECT_PASS_ACCEPT();
1268
1269                 ntids = 2;
1270         } else {
1271
1272                 /* Don't offload if the ifcap isn't enabled */
1273                 if ((ifp->if_capenable & IFCAP_TOE4) == 0)
1274                         REJECT_PASS_ACCEPT();
1275
1276                 /*
1277                  * SYN must be directed to an IP address on this ifnet.  This
1278                  * is more restrictive than in_localip.
1279                  */
1280                 if (!in_ifhasaddr(ifp, inc.inc_laddr))
1281                         REJECT_PASS_ACCEPT();
1282
1283                 ntids = 1;
1284         }
1285
1286         /*
1287          * Don't offload if the ifnet that the SYN came in on is not in the same
1288          * vnet as the listening socket.
1289          */
1290         if (lctx->vnet != ifp->if_vnet)
1291                 REJECT_PASS_ACCEPT();
1292
1293         e = get_l2te_for_nexthop(pi, ifp, &inc);
1294         if (e == NULL)
1295                 REJECT_PASS_ACCEPT();
1296
1297         synqe = mbuf_to_synqe(m);
1298         if (synqe == NULL)
1299                 REJECT_PASS_ACCEPT();
1300
1301         wr = alloc_wrqe(is_t4(sc) ? sizeof(struct cpl_pass_accept_rpl) :
1302             sizeof(struct cpl_t5_pass_accept_rpl), &sc->sge.ctrlq[pi->port_id]);
1303         if (wr == NULL)
1304                 REJECT_PASS_ACCEPT();
1305         rpl = wrtod(wr);
1306
1307         INP_INFO_RLOCK(&V_tcbinfo);     /* for 4-tuple check */
1308
1309         /* Don't offload if the 4-tuple is already in use */
1310         if (toe_4tuple_check(&inc, &th, ifp) != 0) {
1311                 INP_INFO_RUNLOCK(&V_tcbinfo);
1312                 free(wr, M_CXGBE);
1313                 REJECT_PASS_ACCEPT();
1314         }
1315         INP_INFO_RUNLOCK(&V_tcbinfo);
1316
1317         inp = lctx->inp;                /* listening socket, not owned by TOE */
1318         INP_WLOCK(inp);
1319
1320         /* Don't offload if the listening socket has closed */
1321         if (__predict_false(inp->inp_flags & INP_DROPPED)) {
1322                 /*
1323                  * The listening socket has closed.  The reply from the TOE to
1324                  * our CPL_CLOSE_LISTSRV_REQ will ultimately release all
1325                  * resources tied to this listen context.
1326                  */
1327                 INP_WUNLOCK(inp);
1328                 free(wr, M_CXGBE);
1329                 REJECT_PASS_ACCEPT();
1330         }
1331         so = inp->inp_socket;
1332
1333         mtu_idx = find_best_mtu_idx(sc, &inc, be16toh(cpl->tcpopt.mss));
1334         rscale = cpl->tcpopt.wsf && V_tcp_do_rfc1323 ? select_rcv_wscale() : 0;
1335         /* opt0 rcv_bufsiz initially, assumes its normal meaning later */
1336         wnd = max(so->sol_sbrcv_hiwat, MIN_RCV_WND);
1337         wnd = min(wnd, MAX_RCV_WND);
1338         rx_credits = min(wnd >> 10, M_RCV_BUFSIZ);
1339
1340         save_qids_in_mbuf(m, vi);
1341         get_qids_from_mbuf(m, NULL, &rxqid);
1342
1343         if (is_t4(sc))
1344                 INIT_TP_WR_MIT_CPL(rpl, CPL_PASS_ACCEPT_RPL, tid);
1345         else {
1346                 struct cpl_t5_pass_accept_rpl *rpl5 = (void *)rpl;
1347
1348                 INIT_TP_WR_MIT_CPL(rpl5, CPL_PASS_ACCEPT_RPL, tid);
1349         }
1350         if (sc->tt.ddp && (so->so_options & SO_NO_DDP) == 0) {
1351                 ulp_mode = ULP_MODE_TCPDDP;
1352                 synqe->flags |= TPF_SYNQE_TCPDDP;
1353         } else
1354                 ulp_mode = ULP_MODE_NONE;
1355         rpl->opt0 = calc_opt0(so, vi, e, mtu_idx, rscale, rx_credits, ulp_mode);
1356         rpl->opt2 = calc_opt2p(sc, pi, rxqid, &cpl->tcpopt, &th, ulp_mode);
1357
1358         synqe->tid = tid;
1359         synqe->lctx = lctx;
1360         synqe->syn = m;
1361         m = NULL;
1362         refcount_init(&synqe->refcnt, 1);       /* 1 means extra hold */
1363         synqe->l2e_idx = e->idx;
1364         synqe->rcv_bufsize = rx_credits;
1365         atomic_store_rel_ptr(&synqe->wr, (uintptr_t)wr);
1366
1367         insert_tid(sc, tid, synqe, ntids);
1368         TAILQ_INSERT_TAIL(&lctx->synq, synqe, link);
1369         hold_synqe(synqe);      /* hold for the duration it's in the synq */
1370         hold_lctx(lctx);        /* A synqe on the list has a ref on its lctx */
1371
1372         /*
1373          * If all goes well t4_syncache_respond will get called during
1374          * syncache_add.  Note that syncache_add releases the pcb lock.
1375          */
1376         toe_syncache_add(&inc, &to, &th, inp, tod, synqe);
1377         INP_UNLOCK_ASSERT(inp); /* ok to assert, we have a ref on the inp */
1378
1379         /*
1380          * If we replied during syncache_add (synqe->wr has been consumed),
1381          * good.  Otherwise, set it to 0 so that further syncache_respond
1382          * attempts by the kernel will be ignored.
1383          */
1384         if (atomic_cmpset_ptr(&synqe->wr, (uintptr_t)wr, 0)) {
1385
1386                 /*
1387                  * syncache may or may not have a hold on the synqe, which may
1388                  * or may not be stashed in the original SYN mbuf passed to us.
1389                  * Just copy it over instead of dealing with all possibilities.
1390                  */
1391                 m = m_dup(synqe->syn, M_NOWAIT);
1392                 if (m)
1393                         m->m_pkthdr.rcvif = hw_ifp;
1394
1395                 remove_tid(sc, synqe->tid, ntids);
1396                 free(wr, M_CXGBE);
1397
1398                 /* Yank the synqe out of the lctx synq. */
1399                 INP_WLOCK(inp);
1400                 TAILQ_REMOVE(&lctx->synq, synqe, link);
1401                 release_synqe(synqe);   /* removed from synq list */
1402                 inp = release_lctx(sc, lctx);
1403                 if (inp)
1404                         INP_WUNLOCK(inp);
1405
1406                 release_synqe(synqe);   /* extra hold */
1407                 REJECT_PASS_ACCEPT();
1408         }
1409
1410         CTR5(KTR_CXGBE, "%s: stid %u, tid %u, lctx %p, synqe %p, SYNACK",
1411             __func__, stid, tid, lctx, synqe);
1412
1413         INP_WLOCK(inp);
1414         synqe->flags |= TPF_SYNQE_HAS_L2TE;
1415         if (__predict_false(inp->inp_flags & INP_DROPPED)) {
1416                 /*
1417                  * Listening socket closed but tod_listen_stop did not abort
1418                  * this tid because there was no L2T entry for the tid at that
1419                  * time.  Abort it now.  The reply to the abort will clean up.
1420                  */
1421                 CTR6(KTR_CXGBE,
1422                     "%s: stid %u, tid %u, lctx %p, synqe %p (0x%x), ABORT",
1423                     __func__, stid, tid, lctx, synqe, synqe->flags);
1424                 if (!(synqe->flags & TPF_SYNQE_EXPANDED))
1425                         send_reset_synqe(tod, synqe);
1426                 INP_WUNLOCK(inp);
1427                 CURVNET_RESTORE();
1428
1429                 release_synqe(synqe);   /* extra hold */
1430                 return (__LINE__);
1431         }
1432         INP_WUNLOCK(inp);
1433         CURVNET_RESTORE();
1434
1435         release_synqe(synqe);   /* extra hold */
1436         return (0);
1437 reject:
1438         CURVNET_RESTORE();
1439         CTR4(KTR_CXGBE, "%s: stid %u, tid %u, REJECT (%d)", __func__, stid, tid,
1440             reject_reason);
1441
1442         if (e)
1443                 t4_l2t_release(e);
1444         release_tid(sc, tid, lctx->ctrlq);
1445
1446         if (__predict_true(m != NULL)) {
1447                 m_adj(m, sizeof(*cpl));
1448                 m->m_pkthdr.csum_flags |= (CSUM_IP_CHECKED | CSUM_IP_VALID |
1449                     CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
1450                 m->m_pkthdr.csum_data = 0xffff;
1451                 hw_ifp->if_input(hw_ifp, m);
1452         }
1453
1454         return (reject_reason);
1455 }
1456
1457 static void
1458 synqe_to_protohdrs(struct adapter *sc, struct synq_entry *synqe,
1459     const struct cpl_pass_establish *cpl, struct in_conninfo *inc,
1460     struct tcphdr *th, struct tcpopt *to)
1461 {
1462         uint16_t tcp_opt = be16toh(cpl->tcp_opt);
1463
1464         /* start off with the original SYN */
1465         pass_accept_req_to_protohdrs(sc, synqe->syn, inc, th);
1466
1467         /* modify parts to make it look like the ACK to our SYN|ACK */
1468         th->th_flags = TH_ACK;
1469         th->th_ack = synqe->iss + 1;
1470         th->th_seq = be32toh(cpl->rcv_isn);
1471         bzero(to, sizeof(*to));
1472         if (G_TCPOPT_TSTAMP(tcp_opt)) {
1473                 to->to_flags |= TOF_TS;
1474                 to->to_tsecr = synqe->ts;
1475         }
1476 }
1477
1478 static int
1479 do_pass_establish(struct sge_iq *iq, const struct rss_header *rss,
1480     struct mbuf *m)
1481 {
1482         struct adapter *sc = iq->adapter;
1483         struct vi_info *vi;
1484         struct ifnet *ifp;
1485         const struct cpl_pass_establish *cpl = (const void *)(rss + 1);
1486 #if defined(KTR) || defined(INVARIANTS)
1487         unsigned int stid = G_PASS_OPEN_TID(be32toh(cpl->tos_stid));
1488 #endif
1489         unsigned int tid = GET_TID(cpl);
1490         struct synq_entry *synqe = lookup_tid(sc, tid);
1491         struct listen_ctx *lctx = synqe->lctx;
1492         struct inpcb *inp = lctx->inp, *new_inp;
1493         struct socket *so;
1494         struct tcphdr th;
1495         struct tcpopt to;
1496         struct in_conninfo inc;
1497         struct toepcb *toep;
1498         u_int txqid, rxqid;
1499 #ifdef INVARIANTS
1500         unsigned int opcode = G_CPL_OPCODE(be32toh(OPCODE_TID(cpl)));
1501 #endif
1502
1503         KASSERT(opcode == CPL_PASS_ESTABLISH,
1504             ("%s: unexpected opcode 0x%x", __func__, opcode));
1505         KASSERT(m == NULL, ("%s: wasn't expecting payload", __func__));
1506         KASSERT(lctx->stid == stid, ("%s: lctx stid mismatch", __func__));
1507         KASSERT(synqe->flags & TPF_SYNQE,
1508             ("%s: tid %u (ctx %p) not a synqe", __func__, tid, synqe));
1509
1510         CURVNET_SET(lctx->vnet);
1511         INP_INFO_RLOCK(&V_tcbinfo);     /* for syncache_expand */
1512         INP_WLOCK(inp);
1513
1514         CTR6(KTR_CXGBE,
1515             "%s: stid %u, tid %u, synqe %p (0x%x), inp_flags 0x%x",
1516             __func__, stid, tid, synqe, synqe->flags, inp->inp_flags);
1517
1518         if (__predict_false(inp->inp_flags & INP_DROPPED)) {
1519
1520                 if (synqe->flags & TPF_SYNQE_HAS_L2TE) {
1521                         KASSERT(synqe->flags & TPF_ABORT_SHUTDOWN,
1522                             ("%s: listen socket closed but tid %u not aborted.",
1523                             __func__, tid));
1524                 }
1525
1526                 INP_WUNLOCK(inp);
1527                 INP_INFO_RUNLOCK(&V_tcbinfo);
1528                 CURVNET_RESTORE();
1529                 return (0);
1530         }
1531
1532         ifp = synqe->syn->m_pkthdr.rcvif;
1533         vi = ifp->if_softc;
1534         KASSERT(vi->pi->adapter == sc,
1535             ("%s: vi %p, sc %p mismatch", __func__, vi, sc));
1536
1537         get_qids_from_mbuf(synqe->syn, &txqid, &rxqid);
1538         KASSERT(rxqid == iq_to_ofld_rxq(iq) - &sc->sge.ofld_rxq[0],
1539             ("%s: CPL arrived on unexpected rxq.  %d %d", __func__, rxqid,
1540             (int)(iq_to_ofld_rxq(iq) - &sc->sge.ofld_rxq[0])));
1541
1542         toep = alloc_toepcb(vi, txqid, rxqid, M_NOWAIT);
1543         if (toep == NULL) {
1544 reset:
1545                 /*
1546                  * The reply to this abort will perform final cleanup.  There is
1547                  * no need to check for HAS_L2TE here.  We can be here only if
1548                  * we responded to the PASS_ACCEPT_REQ, and our response had the
1549                  * L2T idx.
1550                  */
1551                 send_reset_synqe(TOEDEV(ifp), synqe);
1552                 INP_WUNLOCK(inp);
1553                 INP_INFO_RUNLOCK(&V_tcbinfo);
1554                 CURVNET_RESTORE();
1555                 return (0);
1556         }
1557         toep->tid = tid;
1558         toep->l2te = &sc->l2t->l2tab[synqe->l2e_idx];
1559         if (synqe->flags & TPF_SYNQE_TCPDDP)
1560                 set_tcpddp_ulp_mode(toep);
1561         else
1562                 toep->ulp_mode = ULP_MODE_NONE;
1563         /* opt0 rcv_bufsiz initially, assumes its normal meaning later */
1564         toep->rx_credits = synqe->rcv_bufsize;
1565
1566         so = inp->inp_socket;
1567         KASSERT(so != NULL, ("%s: socket is NULL", __func__));
1568
1569         /* Come up with something that syncache_expand should be ok with. */
1570         synqe_to_protohdrs(sc, synqe, cpl, &inc, &th, &to);
1571
1572         /*
1573          * No more need for anything in the mbuf that carried the
1574          * CPL_PASS_ACCEPT_REQ.  Drop the CPL_PASS_ESTABLISH and toep pointer
1575          * there.  XXX: bad form but I don't want to increase the size of synqe.
1576          */
1577         m = synqe->syn;
1578         KASSERT(sizeof(*cpl) + sizeof(toep) <= m->m_len,
1579             ("%s: no room in mbuf %p (m_len %d)", __func__, m, m->m_len));
1580         bcopy(cpl, mtod(m, void *), sizeof(*cpl));
1581         *(struct toepcb **)(mtod(m, struct cpl_pass_establish *) + 1) = toep;
1582
1583         if (!toe_syncache_expand(&inc, &to, &th, &so) || so == NULL) {
1584                 free_toepcb(toep);
1585                 goto reset;
1586         }
1587
1588         /* New connection inpcb is already locked by syncache_expand(). */
1589         new_inp = sotoinpcb(so);
1590         INP_WLOCK_ASSERT(new_inp);
1591         MPASS(so->so_vnet == lctx->vnet);
1592         toep->vnet = lctx->vnet;
1593         if (inc.inc_flags & INC_ISIPV6)
1594                 toep->ce = hold_lip(sc->tom_softc, &inc.inc6_laddr, lctx->ce);
1595
1596         /*
1597          * This is for the unlikely case where the syncache entry that we added
1598          * has been evicted from the syncache, but the syncache_expand above
1599          * works because of syncookies.
1600          *
1601          * XXX: we've held the tcbinfo lock throughout so there's no risk of
1602          * anyone accept'ing a connection before we've installed our hooks, but
1603          * this somewhat defeats the purpose of having a tod_offload_socket :-(
1604          */
1605         if (__predict_false(!(synqe->flags & TPF_SYNQE_EXPANDED))) {
1606                 tcp_timer_activate(intotcpcb(new_inp), TT_KEEP, 0);
1607                 t4_offload_socket(TOEDEV(ifp), synqe, so);
1608         }
1609
1610         INP_WUNLOCK(new_inp);
1611
1612         /* Done with the synqe */
1613         TAILQ_REMOVE(&lctx->synq, synqe, link);
1614         inp = release_lctx(sc, lctx);
1615         if (inp != NULL)
1616                 INP_WUNLOCK(inp);
1617         INP_INFO_RUNLOCK(&V_tcbinfo);
1618         CURVNET_RESTORE();
1619         release_synqe(synqe);
1620
1621         return (0);
1622 }
1623
1624 void
1625 t4_init_listen_cpl_handlers(void)
1626 {
1627
1628         t4_register_cpl_handler(CPL_PASS_OPEN_RPL, do_pass_open_rpl);
1629         t4_register_cpl_handler(CPL_CLOSE_LISTSRV_RPL, do_close_server_rpl);
1630         t4_register_cpl_handler(CPL_PASS_ACCEPT_REQ, do_pass_accept_req);
1631         t4_register_cpl_handler(CPL_PASS_ESTABLISH, do_pass_establish);
1632 }
1633
1634 void
1635 t4_uninit_listen_cpl_handlers(void)
1636 {
1637
1638         t4_register_cpl_handler(CPL_PASS_OPEN_RPL, NULL);
1639         t4_register_cpl_handler(CPL_CLOSE_LISTSRV_RPL, NULL);
1640         t4_register_cpl_handler(CPL_PASS_ACCEPT_REQ, NULL);
1641         t4_register_cpl_handler(CPL_PASS_ESTABLISH, NULL);
1642 }
1643 #endif