Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/cxgbe/tom/t4_cpl_io.c
Show First 20 Lines • Show All 102 Lines • ▼ Show 20 Lines | send_flowc_wr(struct toepcb *toep, struct tcpcb *tp) | ||||
if (toep->params.tc_idx != -1) { | if (toep->params.tc_idx != -1) { | ||||
MPASS(toep->params.tc_idx >= 0 && | MPASS(toep->params.tc_idx >= 0 && | ||||
toep->params.tc_idx < sc->chip_params->nsched_cls); | toep->params.tc_idx < sc->chip_params->nsched_cls); | ||||
nparams++; | nparams++; | ||||
} | } | ||||
flowclen = sizeof(*flowc) + nparams * sizeof(struct fw_flowc_mnemval); | flowclen = sizeof(*flowc) + nparams * sizeof(struct fw_flowc_mnemval); | ||||
wr = alloc_wrqe(roundup2(flowclen, 16), toep->ofld_txq); | wr = alloc_wrqe(roundup2(flowclen, 16), &toep->ofld_txq->wrq); | ||||
if (wr == NULL) { | if (wr == NULL) { | ||||
/* XXX */ | /* XXX */ | ||||
panic("%s: allocation failure.", __func__); | panic("%s: allocation failure.", __func__); | ||||
} | } | ||||
flowc = wrtod(wr); | flowc = wrtod(wr); | ||||
memset(flowc, 0, wr->wr_len); | memset(flowc, 0, wr->wr_len); | ||||
flowc->op_to_nparams = htobe32(V_FW_WR_OP(FW_FLOWC_WR) | | flowc->op_to_nparams = htobe32(V_FW_WR_OP(FW_FLOWC_WR) | | ||||
▲ Show 20 Lines • Show All 77 Lines • ▼ Show 20 Lines | if (toep->params.tc_idx != tc_idx) { | ||||
struct fw_flowc_wr *flowc; | struct fw_flowc_wr *flowc; | ||||
int nparams = 1, flowclen, flowclen16; | int nparams = 1, flowclen, flowclen16; | ||||
struct ofld_tx_sdesc *txsd = &toep->txsd[toep->txsd_pidx]; | struct ofld_tx_sdesc *txsd = &toep->txsd[toep->txsd_pidx]; | ||||
flowclen = sizeof(*flowc) + nparams * sizeof(struct | flowclen = sizeof(*flowc) + nparams * sizeof(struct | ||||
fw_flowc_mnemval); | fw_flowc_mnemval); | ||||
flowclen16 = howmany(flowclen, 16); | flowclen16 = howmany(flowclen, 16); | ||||
if (toep->tx_credits < flowclen16 || toep->txsd_avail == 0 || | if (toep->tx_credits < flowclen16 || toep->txsd_avail == 0 || | ||||
(wr = alloc_wrqe(roundup2(flowclen, 16), toep->ofld_txq)) == NULL) { | (wr = alloc_wrqe(roundup2(flowclen, 16), | ||||
&toep->ofld_txq->wrq)) == NULL) { | |||||
if (tc_idx >= 0) | if (tc_idx >= 0) | ||||
t4_release_cl_rl(sc, port_id, tc_idx); | t4_release_cl_rl(sc, port_id, tc_idx); | ||||
return (ENOMEM); | return (ENOMEM); | ||||
} | } | ||||
flowc = wrtod(wr); | flowc = wrtod(wr); | ||||
memset(flowc, 0, wr->wr_len); | memset(flowc, 0, wr->wr_len); | ||||
▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | send_reset(struct adapter *sc, struct toepcb *toep, uint32_t snd_nxt) | ||||
if (toep->flags & TPF_ABORT_SHUTDOWN) | if (toep->flags & TPF_ABORT_SHUTDOWN) | ||||
return; /* abort already in progress */ | return; /* abort already in progress */ | ||||
toep->flags |= TPF_ABORT_SHUTDOWN; | toep->flags |= TPF_ABORT_SHUTDOWN; | ||||
KASSERT(toep->flags & TPF_FLOWC_WR_SENT, | KASSERT(toep->flags & TPF_FLOWC_WR_SENT, | ||||
("%s: flowc_wr not sent for tid %d.", __func__, tid)); | ("%s: flowc_wr not sent for tid %d.", __func__, tid)); | ||||
wr = alloc_wrqe(sizeof(*req), toep->ofld_txq); | wr = alloc_wrqe(sizeof(*req), &toep->ofld_txq->wrq); | ||||
if (wr == NULL) { | if (wr == NULL) { | ||||
/* XXX */ | /* XXX */ | ||||
panic("%s: allocation failure.", __func__); | panic("%s: allocation failure.", __func__); | ||||
} | } | ||||
req = wrtod(wr); | req = wrtod(wr); | ||||
INIT_TP_WR_MIT_CPL(req, CPL_ABORT_REQ, tid); | INIT_TP_WR_MIT_CPL(req, CPL_ABORT_REQ, tid); | ||||
if (inp->inp_flags & INP_DROPPED) | if (inp->inp_flags & INP_DROPPED) | ||||
▲ Show 20 Lines • Show All 208 Lines • ▼ Show 20 Lines | CTR3(KTR_CXGBE, "%s: tid %u%s", __func__, toep->tid, | ||||
toep->flags & TPF_FIN_SENT ? ", IGNORED" : ""); | toep->flags & TPF_FIN_SENT ? ", IGNORED" : ""); | ||||
if (toep->flags & TPF_FIN_SENT) | if (toep->flags & TPF_FIN_SENT) | ||||
return (0); | return (0); | ||||
KASSERT(toep->flags & TPF_FLOWC_WR_SENT, | KASSERT(toep->flags & TPF_FLOWC_WR_SENT, | ||||
("%s: flowc_wr not sent for tid %u.", __func__, tid)); | ("%s: flowc_wr not sent for tid %u.", __func__, tid)); | ||||
wr = alloc_wrqe(sizeof(*req), toep->ofld_txq); | wr = alloc_wrqe(sizeof(*req), &toep->ofld_txq->wrq); | ||||
if (wr == NULL) { | if (wr == NULL) { | ||||
/* XXX */ | /* XXX */ | ||||
panic("%s: allocation failure.", __func__); | panic("%s: allocation failure.", __func__); | ||||
} | } | ||||
req = wrtod(wr); | req = wrtod(wr); | ||||
req->wr.wr_hi = htonl(V_FW_WR_OP(FW_TP_WR) | | req->wr.wr_hi = htonl(V_FW_WR_OP(FW_TP_WR) | | ||||
V_FW_WR_IMMDLEN(sizeof(*req) - sizeof(req->wr))); | V_FW_WR_IMMDLEN(sizeof(*req) - sizeof(req->wr))); | ||||
▲ Show 20 Lines • Show All 315 Lines • ▼ Show 20 Lines | if (__predict_false(toep->flags & TPF_FIN_SENT)) | ||||
panic("%s: excess tx.", __func__); | panic("%s: excess tx.", __func__); | ||||
shove = m == NULL && !(tp->t_flags & TF_MORETOCOME); | shove = m == NULL && !(tp->t_flags & TF_MORETOCOME); | ||||
if (plen <= max_imm && !nomap_mbuf_seen) { | if (plen <= max_imm && !nomap_mbuf_seen) { | ||||
/* Immediate data tx */ | /* Immediate data tx */ | ||||
wr = alloc_wrqe(roundup2(sizeof(*txwr) + plen, 16), | wr = alloc_wrqe(roundup2(sizeof(*txwr) + plen, 16), | ||||
toep->ofld_txq); | &toep->ofld_txq->wrq); | ||||
if (wr == NULL) { | if (wr == NULL) { | ||||
/* XXX: how will we recover from this? */ | /* XXX: how will we recover from this? */ | ||||
toep->flags |= TPF_TX_SUSPENDED; | toep->flags |= TPF_TX_SUSPENDED; | ||||
return; | return; | ||||
} | } | ||||
txwr = wrtod(wr); | txwr = wrtod(wr); | ||||
credits = howmany(wr->wr_len, 16); | credits = howmany(wr->wr_len, 16); | ||||
write_tx_wr(txwr, toep, plen, plen, credits, shove, 0); | write_tx_wr(txwr, toep, plen, plen, credits, shove, 0); | ||||
m_copydata(sndptr, 0, plen, (void *)(txwr + 1)); | m_copydata(sndptr, 0, plen, (void *)(txwr + 1)); | ||||
nsegs = 0; | nsegs = 0; | ||||
} else { | } else { | ||||
int wr_len; | int wr_len; | ||||
/* DSGL tx */ | /* DSGL tx */ | ||||
wr_len = sizeof(*txwr) + sizeof(struct ulptx_sgl) + | wr_len = sizeof(*txwr) + sizeof(struct ulptx_sgl) + | ||||
((3 * (nsegs - 1)) / 2 + ((nsegs - 1) & 1)) * 8; | ((3 * (nsegs - 1)) / 2 + ((nsegs - 1) & 1)) * 8; | ||||
wr = alloc_wrqe(roundup2(wr_len, 16), toep->ofld_txq); | wr = alloc_wrqe(roundup2(wr_len, 16), | ||||
&toep->ofld_txq->wrq); | |||||
if (wr == NULL) { | if (wr == NULL) { | ||||
/* XXX: how will we recover from this? */ | /* XXX: how will we recover from this? */ | ||||
toep->flags |= TPF_TX_SUSPENDED; | toep->flags |= TPF_TX_SUSPENDED; | ||||
return; | return; | ||||
} | } | ||||
txwr = wrtod(wr); | txwr = wrtod(wr); | ||||
credits = howmany(wr_len, 16); | credits = howmany(wr_len, 16); | ||||
write_tx_wr(txwr, toep, 0, plen, credits, shove, 0); | write_tx_wr(txwr, toep, 0, plen, credits, shove, 0); | ||||
▲ Show 20 Lines • Show All 160 Lines • ▼ Show 20 Lines | while ((sndptr = mbufq_first(pduq)) != NULL) { | ||||
* for. | * for. | ||||
*/ | */ | ||||
adjusted_plen = plen + ulp_extra_len[ulp_submode]; | adjusted_plen = plen + ulp_extra_len[ulp_submode]; | ||||
if (plen <= max_imm) { | if (plen <= max_imm) { | ||||
/* Immediate data tx */ | /* Immediate data tx */ | ||||
wr = alloc_wrqe(roundup2(sizeof(*txwr) + plen, 16), | wr = alloc_wrqe(roundup2(sizeof(*txwr) + plen, 16), | ||||
toep->ofld_txq); | &toep->ofld_txq->wrq); | ||||
if (wr == NULL) { | if (wr == NULL) { | ||||
/* XXX: how will we recover from this? */ | /* XXX: how will we recover from this? */ | ||||
toep->flags |= TPF_TX_SUSPENDED; | toep->flags |= TPF_TX_SUSPENDED; | ||||
return; | return; | ||||
} | } | ||||
txwr = wrtod(wr); | txwr = wrtod(wr); | ||||
credits = howmany(wr->wr_len, 16); | credits = howmany(wr->wr_len, 16); | ||||
write_tx_wr(txwr, toep, plen, adjusted_plen, credits, | write_tx_wr(txwr, toep, plen, adjusted_plen, credits, | ||||
shove, ulp_submode); | shove, ulp_submode); | ||||
m_copydata(sndptr, 0, plen, (void *)(txwr + 1)); | m_copydata(sndptr, 0, plen, (void *)(txwr + 1)); | ||||
nsegs = 0; | nsegs = 0; | ||||
} else { | } else { | ||||
int wr_len; | int wr_len; | ||||
/* DSGL tx */ | /* DSGL tx */ | ||||
wr_len = sizeof(*txwr) + sizeof(struct ulptx_sgl) + | wr_len = sizeof(*txwr) + sizeof(struct ulptx_sgl) + | ||||
((3 * (nsegs - 1)) / 2 + ((nsegs - 1) & 1)) * 8; | ((3 * (nsegs - 1)) / 2 + ((nsegs - 1) & 1)) * 8; | ||||
wr = alloc_wrqe(roundup2(wr_len, 16), toep->ofld_txq); | wr = alloc_wrqe(roundup2(wr_len, 16), | ||||
&toep->ofld_txq->wrq); | |||||
if (wr == NULL) { | if (wr == NULL) { | ||||
/* XXX: how will we recover from this? */ | /* XXX: how will we recover from this? */ | ||||
toep->flags |= TPF_TX_SUSPENDED; | toep->flags |= TPF_TX_SUSPENDED; | ||||
return; | return; | ||||
} | } | ||||
txwr = wrtod(wr); | txwr = wrtod(wr); | ||||
credits = howmany(wr_len, 16); | credits = howmany(wr_len, 16); | ||||
write_tx_wr(txwr, toep, 0, adjusted_plen, credits, | write_tx_wr(txwr, toep, 0, adjusted_plen, credits, | ||||
▲ Show 20 Lines • Show All 298 Lines • ▼ Show 20 Lines | |||||
done: | done: | ||||
INP_WUNLOCK(inp); | INP_WUNLOCK(inp); | ||||
NET_EPOCH_EXIT(et); | NET_EPOCH_EXIT(et); | ||||
CURVNET_RESTORE(); | CURVNET_RESTORE(); | ||||
return (0); | return (0); | ||||
} | } | ||||
void | void | ||||
send_abort_rpl(struct adapter *sc, struct sge_wrq *ofld_txq, int tid, | send_abort_rpl(struct adapter *sc, struct sge_ofld_txq *ofld_txq, int tid, | ||||
int rst_status) | int rst_status) | ||||
{ | { | ||||
struct wrqe *wr; | struct wrqe *wr; | ||||
struct cpl_abort_rpl *cpl; | struct cpl_abort_rpl *cpl; | ||||
wr = alloc_wrqe(sizeof(*cpl), ofld_txq); | wr = alloc_wrqe(sizeof(*cpl), &ofld_txq->wrq); | ||||
if (wr == NULL) { | if (wr == NULL) { | ||||
/* XXX */ | /* XXX */ | ||||
panic("%s: allocation failure.", __func__); | panic("%s: allocation failure.", __func__); | ||||
} | } | ||||
cpl = wrtod(wr); | cpl = wrtod(wr); | ||||
INIT_TP_WR_MIT_CPL(cpl, CPL_ABORT_RPL, tid); | INIT_TP_WR_MIT_CPL(cpl, CPL_ABORT_RPL, tid); | ||||
cpl->cmd = rst_status; | cpl->cmd = rst_status; | ||||
Show All 23 Lines | |||||
*/ | */ | ||||
static int | static int | ||||
do_abort_req(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m) | do_abort_req(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m) | ||||
{ | { | ||||
struct adapter *sc = iq->adapter; | struct adapter *sc = iq->adapter; | ||||
const struct cpl_abort_req_rss *cpl = (const void *)(rss + 1); | const struct cpl_abort_req_rss *cpl = (const void *)(rss + 1); | ||||
unsigned int tid = GET_TID(cpl); | unsigned int tid = GET_TID(cpl); | ||||
struct toepcb *toep = lookup_tid(sc, tid); | struct toepcb *toep = lookup_tid(sc, tid); | ||||
struct sge_wrq *ofld_txq = toep->ofld_txq; | struct sge_ofld_txq *ofld_txq = toep->ofld_txq; | ||||
struct inpcb *inp; | struct inpcb *inp; | ||||
struct tcpcb *tp; | struct tcpcb *tp; | ||||
struct epoch_tracker et; | struct epoch_tracker et; | ||||
#ifdef INVARIANTS | #ifdef INVARIANTS | ||||
unsigned int opcode = G_CPL_OPCODE(be32toh(OPCODE_TID(cpl))); | unsigned int opcode = G_CPL_OPCODE(be32toh(OPCODE_TID(cpl))); | ||||
#endif | #endif | ||||
KASSERT(opcode == CPL_ABORT_REQ_RSS, | KASSERT(opcode == CPL_ABORT_REQ_RSS, | ||||
▲ Show 20 Lines • Show All 901 Lines • Show Last 20 Lines |