Allow for a different handler for each type of firmware message.
MFC after: 2 weeks
This commit is contained in:
parent
f39f73f47c
commit
1b4cc91fcc
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user