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