Allow for a different handler for each type of firmware message.

MFC after:	2 weeks
This commit is contained in:
Navdeep Parhar 2012-08-16 18:31:50 +00:00
parent f39f73f47c
commit 1b4cc91fcc
4 changed files with 52 additions and 11 deletions

View File

@ -510,6 +510,7 @@ struct rss_header;
typedef int (*cpl_handler_t)(struct sge_iq *, const struct rss_header *,
struct mbuf *);
typedef int (*an_handler_t)(struct sge_iq *, const struct rsp_ctrl *);
typedef int (*fw_msg_handler_t)(struct adapter *, const __be64 *);
struct adapter {
SLIST_ENTRY(adapter) link;
@ -582,7 +583,8 @@ struct adapter {
struct callout sfl_callout;
an_handler_t an_handler __aligned(CACHE_LINE_SIZE);
cpl_handler_t cpl_handler[256];
fw_msg_handler_t fw_msg_handler[4]; /* NUM_FW6_TYPES */
cpl_handler_t cpl_handler[0xef]; /* NUM_CPL_CMDS */
};
#define ADAPTER_LOCK(sc) mtx_lock(&(sc)->sc_lock)
@ -741,6 +743,7 @@ void t4_os_link_changed(struct adapter *, int, int);
void t4_iterate(void (*)(struct adapter *, void *), void *);
int t4_register_cpl_handler(struct adapter *, int, cpl_handler_t);
int t4_register_an_handler(struct adapter *, an_handler_t);
int t4_register_fw_msg_handler(struct adapter *, int, fw_msg_handler_t);
/* t4_sge.c */
void t4_sge_modload(void);

View File

@ -2281,6 +2281,8 @@ enum {
FW6_TYPE_WR_RPL = 1,
FW6_TYPE_CQE = 2,
FW6_TYPE_OFLD_CONNECTION_WR_RPL = 3,
NUM_FW6_TYPES
};
struct cpl_fw6_msg_ofld_connection_wr_rpl {

View File

@ -306,6 +306,7 @@ static void cxgbe_vlan_config(void *, struct ifnet *, uint16_t);
static int cpl_not_handled(struct sge_iq *, const struct rss_header *,
struct mbuf *);
static int an_not_handled(struct sge_iq *, const struct rsp_ctrl *);
static int fw_msg_not_handled(struct adapter *, const __be64 *);
static int t4_sysctls(struct adapter *);
static int cxgbe_sysctls(struct port_info *);
static int sysctl_int_array(SYSCTL_HANDLER_ARGS);
@ -381,6 +382,10 @@ CTASSERT(offsetof(struct sge_ofld_rxq, iq) == offsetof(struct sge_rxq, iq));
CTASSERT(offsetof(struct sge_ofld_rxq, fl) == offsetof(struct sge_rxq, fl));
#endif
/* No easy way to include t4_msg.h before adapter.h so we check this way */
CTASSERT(ARRAY_SIZE(((struct adapter *)0)->cpl_handler) == NUM_CPL_CMDS);
CTASSERT(ARRAY_SIZE(((struct adapter *)0)->fw_msg_handler) == NUM_FW6_TYPES);
static int
t4_probe(device_t dev)
{
@ -458,6 +463,8 @@ t4_attach(device_t dev)
sc->an_handler = an_not_handled;
for (i = 0; i < ARRAY_SIZE(sc->cpl_handler); i++)
sc->cpl_handler[i] = cpl_not_handled;
for (i = 0; i < ARRAY_SIZE(sc->fw_msg_handler); i++)
sc->fw_msg_handler[i] = fw_msg_not_handled;
t4_register_cpl_handler(sc, CPL_SET_TCB_RPL, filter_rpl);
/* Prepare the adapter for operation */
@ -2980,7 +2987,7 @@ cpl_not_handled(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m)
panic("%s: opcode 0x%02x on iq %p with payload %p",
__func__, rss->opcode, iq, m);
#else
log(LOG_ERR, "%s: opcode 0x%02x on iq %p with payload %p",
log(LOG_ERR, "%s: opcode 0x%02x on iq %p with payload %p\n",
__func__, rss->opcode, iq, m);
m_freem(m);
#endif
@ -3009,7 +3016,7 @@ an_not_handled(struct sge_iq *iq, const struct rsp_ctrl *ctrl)
#ifdef INVARIANTS
panic("%s: async notification on iq %p (ctrl %p)", __func__, iq, ctrl);
#else
log(LOG_ERR, "%s: async notification on iq %p (ctrl %p)",
log(LOG_ERR, "%s: async notification on iq %p (ctrl %p)\n",
__func__, iq, ctrl);
#endif
return (EDOOFUS);
@ -3027,6 +3034,35 @@ t4_register_an_handler(struct adapter *sc, an_handler_t h)
return (0);
}
static int
fw_msg_not_handled(struct adapter *sc, const __be64 *rpl)
{
__be64 *r = __DECONST(__be64 *, rpl);
struct cpl_fw6_msg *cpl = member2struct(cpl_fw6_msg, data, r);
#ifdef INVARIANTS
panic("%s: fw_msg type %d", __func__, cpl->type);
#else
log(LOG_ERR, "%s: fw_msg type %d\n", __func__, cpl->type);
#endif
return (EDOOFUS);
}
int
t4_register_fw_msg_handler(struct adapter *sc, int type, fw_msg_handler_t h)
{
uintptr_t *loc, new;
if (type >= ARRAY_SIZE(sc->fw_msg_handler))
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);
return (0);
}
static int
t4_sysctls(struct adapter *sc)
{

View File

@ -185,7 +185,7 @@ static void write_eqflush_wr(struct sge_eq *);
static __be64 get_flit(bus_dma_segment_t *, int, int);
static int handle_sge_egr_update(struct sge_iq *, const struct rss_header *,
struct mbuf *);
static int handle_fw_rpl(struct sge_iq *, const struct rss_header *,
static int handle_fw_msg(struct sge_iq *, const struct rss_header *,
struct mbuf *);
static int sysctl_uint16(SYSCTL_HANDLER_ARGS);
@ -361,11 +361,13 @@ t4_sge_init(struct adapter *sc)
sc->sge.timer_val[4] = G_TIMERVALUE4(v) / core_ticks_per_usec(sc);
sc->sge.timer_val[5] = G_TIMERVALUE5(v) / core_ticks_per_usec(sc);
t4_register_cpl_handler(sc, CPL_FW4_MSG, handle_fw_rpl);
t4_register_cpl_handler(sc, CPL_FW6_MSG, handle_fw_rpl);
t4_register_cpl_handler(sc, CPL_FW4_MSG, handle_fw_msg);
t4_register_cpl_handler(sc, CPL_FW6_MSG, handle_fw_msg);
t4_register_cpl_handler(sc, CPL_SGE_EGR_UPDATE, handle_sge_egr_update);
t4_register_cpl_handler(sc, CPL_RX_PKT, t4_eth_rx);
t4_register_fw_msg_handler(sc, FW6_TYPE_CMD_RPL, t4_handle_fw_rpl);
return (rc);
}
@ -3520,17 +3522,15 @@ handle_sge_egr_update(struct sge_iq *iq, const struct rss_header *rss,
}
static int
handle_fw_rpl(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m)
handle_fw_msg(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m)
{
struct adapter *sc = iq->adapter;
const struct cpl_fw6_msg *cpl = (const void *)(rss + 1);
KASSERT(m == NULL, ("%s: payload with opcode %02x", __func__,
rss->opcode));
if (cpl->type == FW6_TYPE_CMD_RPL)
t4_handle_fw_rpl(iq->adapter, cpl->data);
return (0);
return (sc->fw_msg_handler[cpl->type](sc, &cpl->data[0]));
}
static int