From b803c7de89432aa2b5990620a631d44776c10a45 Mon Sep 17 00:00:00 2001 From: np Date: Tue, 26 Feb 2013 00:27:27 +0000 Subject: cxgbe(4): Ask the card's firmware to pad up tiny CPLs by encapsulating them in a firmware message if it is able to do so. This works out better for one of the FIFOs in the chip. MFC after: 5 days --- sys/dev/cxgbe/adapter.h | 2 +- sys/dev/cxgbe/common/t4_msg.h | 18 +++++++++++---- sys/dev/cxgbe/firmware/t4fw_interface.h | 2 +- sys/dev/cxgbe/t4_main.c | 40 +++++++++++++++++++++++++++++++++ sys/dev/cxgbe/t4_sge.c | 11 +++++++++ 5 files changed, 67 insertions(+), 6 deletions(-) (limited to 'sys/dev') diff --git a/sys/dev/cxgbe/adapter.h b/sys/dev/cxgbe/adapter.h index 55cfa52..eee9e1a 100644 --- a/sys/dev/cxgbe/adapter.h +++ b/sys/dev/cxgbe/adapter.h @@ -600,7 +600,7 @@ struct adapter { struct callout sfl_callout; an_handler_t an_handler __aligned(CACHE_LINE_SIZE); - fw_msg_handler_t fw_msg_handler[4]; /* NUM_FW6_TYPES */ + fw_msg_handler_t fw_msg_handler[5]; /* NUM_FW6_TYPES */ cpl_handler_t cpl_handler[0xef]; /* NUM_CPL_CMDS */ #ifdef INVARIANTS diff --git a/sys/dev/cxgbe/common/t4_msg.h b/sys/dev/cxgbe/common/t4_msg.h index 92f760b..2111d30 100644 --- a/sys/dev/cxgbe/common/t4_msg.h +++ b/sys/dev/cxgbe/common/t4_msg.h @@ -2224,6 +2224,15 @@ struct cpl_sge_egr_update { #define V_EGR_QID(x) ((x) << S_EGR_QID) #define G_EGR_QID(x) (((x) >> S_EGR_QID) & M_EGR_QID) +/* cpl_fw*.type values */ +enum { + FW_TYPE_CMD_RPL = 0, + FW_TYPE_WR_RPL = 1, + FW_TYPE_CQE = 2, + FW_TYPE_OFLD_CONNECTION_WR_RPL = 3, + FW_TYPE_RSSCPL = 4, +}; + struct cpl_fw2_pld { RSS_HDR u8 opcode; @@ -2292,10 +2301,11 @@ struct cpl_fw6_msg { /* cpl_fw6_msg.type values */ enum { - FW6_TYPE_CMD_RPL = 0, - FW6_TYPE_WR_RPL = 1, - FW6_TYPE_CQE = 2, - FW6_TYPE_OFLD_CONNECTION_WR_RPL = 3, + FW6_TYPE_CMD_RPL = FW_TYPE_CMD_RPL, + FW6_TYPE_WR_RPL = FW_TYPE_WR_RPL, + FW6_TYPE_CQE = FW_TYPE_CQE, + FW6_TYPE_OFLD_CONNECTION_WR_RPL = FW_TYPE_OFLD_CONNECTION_WR_RPL, + FW6_TYPE_RSSCPL = FW_TYPE_RSSCPL, NUM_FW6_TYPES }; diff --git a/sys/dev/cxgbe/firmware/t4fw_interface.h b/sys/dev/cxgbe/firmware/t4fw_interface.h index cd03816..4b1fbff 100644 --- a/sys/dev/cxgbe/firmware/t4fw_interface.h +++ b/sys/dev/cxgbe/firmware/t4fw_interface.h @@ -3534,7 +3534,7 @@ enum fw_params_param_pfvf { FW_PARAMS_PARAM_PFVF_ACTIVE_FILTER_END = 0x2E, FW_PARAMS_PARAM_PFVF_ETHOFLD_START = 0x2F, FW_PARAMS_PARAM_PFVF_ETHOFLD_END = 0x30, - FW_PARAMS_PARAM_PFVF_CPLFW4MSG_CPLSGEEGRUPDATE = 0x31 + FW_PARAMS_PARAM_PFVF_CPLFW4MSG_ENCAP = 0x31 }; /* diff --git a/sys/dev/cxgbe/t4_main.c b/sys/dev/cxgbe/t4_main.c index 0e24c7c..da3accd 100644 --- a/sys/dev/cxgbe/t4_main.c +++ b/sys/dev/cxgbe/t4_main.c @@ -281,6 +281,7 @@ static int upload_config_file(struct adapter *, const struct firmware *, static int partition_resources(struct adapter *, const struct firmware *); static int get_params__pre_init(struct adapter *); static int get_params__post_init(struct adapter *); +static int set_params__post_init(struct adapter *); static void t4_set_desc(struct adapter *); static void build_medialist(struct port_info *); static int update_mac_settings(struct port_info *, int); @@ -519,6 +520,10 @@ t4_attach(device_t dev) if (rc != 0) goto done; /* error message displayed already */ + rc = set_params__post_init(sc); + if (rc != 0) + goto done; /* error message displayed already */ + if (sc->flags & MASTER_PF) { uint16_t indsz = min(RX_COPY_THRESHOLD - 1, M_INDICATESIZE); @@ -1991,6 +1996,33 @@ get_params__post_init(struct adapter *sc) return (rc); } +static int +set_params__post_init(struct adapter *sc) +{ + uint32_t param, val; + int rc; + + param = FW_PARAM_PFVF(CPLFW4MSG_ENCAP); + rc = -t4_query_params(sc, sc->mbox, sc->pf, 0, 1, ¶m, &val); + if (rc == 0) { + /* ask for encapsulated CPLs */ + param = FW_PARAM_PFVF(CPLFW4MSG_ENCAP); + val = 1; + rc = -t4_set_params(sc, sc->mbox, sc->pf, 0, 1, ¶m, &val); + if (rc != 0) { + device_printf(sc->dev, + "failed to set parameter (post_init): %d.\n", rc); + return (rc); + } + } else if (rc != FW_EINVAL) { + device_printf(sc->dev, + "failed to check for encapsulated CPLs: %d.\n", rc); + } else + rc = 0; /* the firmware doesn't support the param, no worries */ + + return (rc); +} + #undef FW_PARAM_PFVF #undef FW_PARAM_DEV @@ -3077,6 +3109,14 @@ t4_register_fw_msg_handler(struct adapter *sc, int type, fw_msg_handler_t h) if (type >= nitems(sc->fw_msg_handler)) return (EINVAL); + /* + * These are dispatched by the handler for FW{4|6}_CPL_MSG using the CPL + * handler dispatch table. Reject any attempt to install a handler for + * this subtype. + */ + if (type == FW_TYPE_RSSCPL || type == FW6_TYPE_RSSCPL) + return (EINVAL); + new = h ? (uintptr_t)h : (uintptr_t)fw_msg_not_handled; loc = (uintptr_t *) &sc->fw_msg_handler[type]; atomic_store_rel_ptr(loc, new); diff --git a/sys/dev/cxgbe/t4_sge.c b/sys/dev/cxgbe/t4_sge.c index 94dca53..578f06f 100644 --- a/sys/dev/cxgbe/t4_sge.c +++ b/sys/dev/cxgbe/t4_sge.c @@ -3509,6 +3509,10 @@ handle_sge_egr_update(struct sge_iq *iq, const struct rss_header *rss, return (0); } +/* handle_fw_msg works for both fw4_msg and fw6_msg because this is valid */ +CTASSERT(offsetof(struct cpl_fw4_msg, data) == \ + offsetof(struct cpl_fw6_msg, data)); + static int handle_fw_msg(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m) { @@ -3518,6 +3522,13 @@ handle_fw_msg(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m) KASSERT(m == NULL, ("%s: payload with opcode %02x", __func__, rss->opcode)); + if (cpl->type == FW_TYPE_RSSCPL || cpl->type == FW6_TYPE_RSSCPL) { + const struct rss_header *rss2; + + rss2 = (const struct rss_header *)&cpl->data[0]; + return (sc->cpl_handler[rss2->opcode](iq, rss2, m)); + } + return (sc->fw_msg_handler[cpl->type](sc, &cpl->data[0])); } -- cgit v1.1