summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authornp <np@FreeBSD.org>2013-02-26 00:27:27 +0000
committernp <np@FreeBSD.org>2013-02-26 00:27:27 +0000
commitb803c7de89432aa2b5990620a631d44776c10a45 (patch)
tree13f48187ef670ac30a91f7085111c96bf6fb5952 /sys
parentf9193e6daaff1856be00a9438fef1064b731599a (diff)
downloadFreeBSD-src-b803c7de89432aa2b5990620a631d44776c10a45.zip
FreeBSD-src-b803c7de89432aa2b5990620a631d44776c10a45.tar.gz
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
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/cxgbe/adapter.h2
-rw-r--r--sys/dev/cxgbe/common/t4_msg.h18
-rw-r--r--sys/dev/cxgbe/firmware/t4fw_interface.h2
-rw-r--r--sys/dev/cxgbe/t4_main.c40
-rw-r--r--sys/dev/cxgbe/t4_sge.c11
5 files changed, 67 insertions, 6 deletions
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, &param, &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, &param, &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]));
}
OpenPOWER on IntegriCloud