aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/cxgbe/tom/t4_cpl_io.c
diff options
context:
space:
mode:
authorNavdeep Parhar <np@FreeBSD.org>2012-08-16 20:15:29 +0000
committerNavdeep Parhar <np@FreeBSD.org>2012-08-16 20:15:29 +0000
commit1f1b5a0f6ff250c497d907e8f113d400bed987a7 (patch)
tree8740418c5c70641ef3ae6db0a3dcdc2d7470741f /sys/dev/cxgbe/tom/t4_cpl_io.c
parentc6fd18e0275307b3905da6211fd5e905efe45e92 (diff)
downloadsrc-1f1b5a0f6ff250c497d907e8f113d400bed987a7.tar.gz
src-1f1b5a0f6ff250c497d907e8f113d400bed987a7.zip
Add a routine (t4_set_tcb_field) to update arbitrary parts of a hardware
TCB. Filters are programmed by modifying the TCB too (via a different routine) and the reply to any TCB update is delivered via a CPL_SET_TCB_RPL. Figure out whether the reply is for a filter-write or something else and route it appropriately. MFC after: 2 weeks
Notes
Notes: svn path=/head/; revision=239338
Diffstat (limited to 'sys/dev/cxgbe/tom/t4_cpl_io.c')
-rw-r--r--sys/dev/cxgbe/tom/t4_cpl_io.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/sys/dev/cxgbe/tom/t4_cpl_io.c b/sys/dev/cxgbe/tom/t4_cpl_io.c
index 2c1b75279301..384fc85aa034 100644
--- a/sys/dev/cxgbe/tom/t4_cpl_io.c
+++ b/sys/dev/cxgbe/tom/t4_cpl_io.c
@@ -1262,6 +1262,51 @@ do_fw4_ack(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m)
return (0);
}
+static int
+do_set_tcb_rpl(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m)
+{
+ struct adapter *sc = iq->adapter;
+ const struct cpl_set_tcb_rpl *cpl = (const void *)(rss + 1);
+ unsigned int tid = GET_TID(cpl);
+#ifdef INVARIANTS
+ unsigned int opcode = G_CPL_OPCODE(be32toh(OPCODE_TID(cpl)));
+#endif
+
+ KASSERT(opcode == CPL_SET_TCB_RPL,
+ ("%s: unexpected opcode 0x%x", __func__, opcode));
+ KASSERT(m == NULL, ("%s: wasn't expecting payload", __func__));
+
+ if (tid >= sc->tids.ftid_base &&
+ tid < sc->tids.ftid_base + sc->tids.nftids)
+ return (t4_filter_rpl(iq, rss, m)); /* TCB is a filter */
+
+ CXGBE_UNIMPLEMENTED(__func__);
+}
+
+void
+t4_set_tcb_field(struct adapter *sc, struct toepcb *toep, uint16_t word,
+ uint64_t mask, uint64_t val)
+{
+ struct wrqe *wr;
+ struct cpl_set_tcb_field *req;
+
+ wr = alloc_wrqe(sizeof(*req), toep->ctrlq);
+ if (wr == NULL) {
+ /* XXX */
+ panic("%s: allocation failure.", __func__);
+ }
+ req = wrtod(wr);
+
+ INIT_TP_WR_MIT_CPL(req, CPL_SET_TCB_FIELD, toep->tid);
+ req->reply_ctrl = htobe16(V_NO_REPLY(1) |
+ V_QUEUENO(toep->ofld_rxq->iq.abs_id));
+ req->word_cookie = htobe16(V_WORD(word) | V_COOKIE(0));
+ req->mask = htobe64(mask);
+ req->val = htobe64(val);
+
+ t4_wrq_tx(sc, wr);
+}
+
void
t4_init_cpl_io_handlers(struct adapter *sc)
{
@@ -1272,5 +1317,13 @@ t4_init_cpl_io_handlers(struct adapter *sc)
t4_register_cpl_handler(sc, CPL_ABORT_RPL_RSS, do_abort_rpl);
t4_register_cpl_handler(sc, CPL_RX_DATA, do_rx_data);
t4_register_cpl_handler(sc, CPL_FW4_ACK, do_fw4_ack);
+ t4_register_cpl_handler(sc, CPL_SET_TCB_RPL, do_set_tcb_rpl);
+}
+
+void
+t4_uninit_cpl_io_handlers(struct adapter *sc)
+{
+
+ t4_register_cpl_handler(sc, CPL_SET_TCB_RPL, t4_filter_rpl);
}
#endif