/* * Active open failed. */ static int do_act_open_rpl(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m) { struct adapter *sc = iq->adapter; const struct cpl_act_open_rpl *cpl = (const void *)(rss + 1); u_int atid = G_TID_TID(G_AOPEN_ATID(be32toh(cpl->atid_status))); u_int status = G_AOPEN_STATUS(be32toh(cpl->atid_status)); struct toepcb *toep = lookup_atid(sc, atid); int rc; KASSERT(m == NULL, ("%s: wasn't expecting payload", __func__)); KASSERT(toep->tid == atid, ("%s: toep tid/atid mismatch", __func__)); CTR3(KTR_CXGBE, "%s: atid %u, status %u ", __func__, atid, status); /* Ignore negative advice */ if (negative_advice(status)) return (0); if (status && act_open_has_tid(status)) release_tid(sc, GET_TID(cpl), toep->ctrlq); rc = act_open_rpl_status_to_errno(status); act_open_failure_cleanup(sc, atid, rc); return (0); }
/* * Active open failed. */ static int do_act_establish(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m) { struct adapter *sc = iq->adapter; const struct cpl_act_establish *cpl = (const void *)(rss + 1); unsigned int tid = GET_TID(cpl); unsigned int atid = G_TID_TID(ntohl(cpl->tos_atid)); struct toepcb *toep = lookup_atid(sc, atid); struct inpcb *inp = toep->inp; KASSERT(m == NULL, ("%s: wasn't expecting payload", __func__)); KASSERT(toep->tid == atid, ("%s: toep tid/atid mismatch", __func__)); CTR3(KTR_CXGBE, "%s: atid %u, tid %u", __func__, atid, tid); free_atid(sc, atid); INP_WLOCK(inp); toep->tid = tid; insert_tid(sc, tid, toep); if (inp->inp_flags & INP_DROPPED) { /* socket closed by the kernel before hw told us it connected */ send_flowc_wr(toep, NULL); send_reset(sc, toep, be32toh(cpl->snd_isn)); goto done; } make_established(toep, cpl->snd_isn, cpl->rcv_isn, cpl->tcp_opt); done: INP_WUNLOCK(inp); return (0); }
void act_open_failure_cleanup(struct adapter *sc, u_int atid, u_int status) { struct toepcb *toep = lookup_atid(sc, atid); struct inpcb *inp = toep->inp; struct toedev *tod = &toep->td->tod; free_atid(sc, atid); toep->tid = -1; if (status != EAGAIN) INP_INFO_RLOCK(&V_tcbinfo); INP_WLOCK(inp); toe_connect_failed(tod, inp, status); final_cpl_received(toep); /* unlocks inp */ if (status != EAGAIN) INP_INFO_RUNLOCK(&V_tcbinfo); }
static int do_act_open_rpl(struct t3cdev *dev, struct mbuf *m) { struct cpl_act_open_rpl *rpl = cplhdr(m); unsigned int atid = G_TID(ntohl(rpl->atid)); struct toe_tid_entry *toe_tid; toe_tid = lookup_atid(&(T3C_DATA (dev))->tid_maps, atid); if (toe_tid->ctx && toe_tid->client && toe_tid->client->handlers && toe_tid->client->handlers[CPL_ACT_OPEN_RPL]) { return toe_tid->client->handlers[CPL_ACT_OPEN_RPL] (dev, m, toe_tid->ctx); } else { log(LOG_ERR, "%s: received clientless CPL command 0x%x\n", dev->name, CPL_ACT_OPEN_RPL); return CPL_RET_BUF_DONE | CPL_RET_BAD_MSG; } }
void act_open_failure_cleanup(struct adapter *sc, u_int atid, u_int status) { struct toepcb *toep = lookup_atid(sc, atid); struct inpcb *inp = toep->inp; struct toedev *tod = &toep->td->tod; struct epoch_tracker et; free_atid(sc, atid); toep->tid = -1; CURVNET_SET(toep->vnet); if (status != EAGAIN) INP_INFO_RLOCK_ET(&V_tcbinfo, et); INP_WLOCK(inp); toe_connect_failed(tod, inp, status); final_cpl_received(toep); /* unlocks inp */ if (status != EAGAIN) INP_INFO_RUNLOCK_ET(&V_tcbinfo, et); CURVNET_RESTORE(); }
static int do_act_open_rpl(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m) { struct adapter *sc = iq->adapter; const struct cpl_act_open_rpl *cpl = (const void *)(rss + 1); unsigned int atid = G_TID_TID(G_AOPEN_ATID(be32toh(cpl->atid_status))); unsigned int status = G_AOPEN_STATUS(be32toh(cpl->atid_status)); struct toepcb *toep = lookup_atid(sc, atid); struct inpcb *inp = toep->inp; struct toedev *tod = &toep->td->tod; int rc; KASSERT(m == NULL, ("%s: wasn't expecting payload", __func__)); KASSERT(toep->tid == atid, ("%s: toep tid/atid mismatch", __func__)); CTR3(KTR_CXGBE, "%s: atid %u, status %u ", __func__, atid, status); /* Ignore negative advice */ if (negative_advice(status)) return (0); free_atid(sc, atid); toep->tid = -1; if (status && act_open_has_tid(status)) release_tid(sc, GET_TID(cpl), toep->ctrlq); rc = act_open_rpl_status_to_errno(status); if (rc != EAGAIN) INP_INFO_WLOCK(&V_tcbinfo); INP_WLOCK(inp); toe_connect_failed(tod, inp, rc); final_cpl_received(toep); /* unlocks inp */ if (rc != EAGAIN) INP_INFO_WUNLOCK(&V_tcbinfo); return (0); }
static int do_act_establish(struct t3cdev *dev, struct mbuf *m) { struct cpl_act_establish *req; unsigned int atid; struct toe_tid_entry *toe_tid; req = cplhdr(m); atid = G_PASS_OPEN_TID(ntohl(req->tos_tid)); toe_tid = lookup_atid(&(T3C_DATA (dev))->tid_maps, atid); if (toe_tid && toe_tid->ctx && toe_tid->client->handlers && toe_tid->client->handlers[CPL_ACT_ESTABLISH]) { return toe_tid->client->handlers[CPL_ACT_ESTABLISH] (dev, m, toe_tid->ctx); } else { log(LOG_ERR, "%s: received clientless CPL command 0x%x\n", dev->name, CPL_ACT_ESTABLISH); return CPL_RET_BUF_DONE | CPL_RET_BAD_MSG; } }
void hash_filter_rpl(struct adapter *adap, const struct cpl_act_open_rpl *rpl) { unsigned int ftid = TID_TID_G(AOPEN_ATID_G(ntohl(rpl->atid_status))); unsigned int status = AOPEN_STATUS_G(ntohl(rpl->atid_status)); struct tid_info *t = &adap->tids; unsigned int tid = GET_TID(rpl); struct filter_ctx *ctx = NULL; struct filter_entry *f; dev_dbg(adap->pdev_dev, "%s: tid = %u; atid = %u; status = %u\n", __func__, tid, ftid, status); f = lookup_atid(t, ftid); if (!f) { dev_err(adap->pdev_dev, "%s:could not find filter entry", __func__); return; } ctx = f->ctx; f->ctx = NULL; switch (status) { case CPL_ERR_NONE: f->tid = tid; f->pending = 0; f->valid = 1; cxgb4_insert_tid(t, f, f->tid, 0); cxgb4_free_atid(t, ftid); if (ctx) { ctx->tid = f->tid; ctx->result = 0; } if (configure_filter_tcb(adap, tid, f)) { clear_filter(adap, f); cxgb4_remove_tid(t, 0, tid, 0); kfree(f); if (ctx) { ctx->result = -EINVAL; complete(&ctx->completion); } return; } break; default: dev_err(adap->pdev_dev, "%s: filter creation PROBLEM; status = %u\n", __func__, status); if (ctx) { if (status == CPL_ERR_TCAM_FULL) ctx->result = -EAGAIN; else ctx->result = -EINVAL; } clear_filter(adap, f); cxgb4_free_atid(t, ftid); kfree(f); } if (ctx) complete(&ctx->completion); }