cxgbe(4): Expanded interrupt handling for T7
- Catch up with the new cause/perr registers. The high level approach is the same but the T7 has an extra top level INT_CAUSE concentrator and a PERR_CAUSE concentrator with a changed layout. - Add various flags to control the interrupt handlers' behavior. - Implement a t4_intr_clear that internally use the slow handler as an iterator over known cause/perr registers. This lets the driver clear all of the interrupt sources that it knows about. The firmware sets up the interrupt enables and clears the causes normally so this call should be redundant. MFC after: 1 week Sponsored by: Chelsio Communications
This commit is contained in:
+11
-1
@@ -184,7 +184,16 @@ enum {
|
||||
DF_LOAD_FW_ANYTIME = (1 << 1), /* Allow LOAD_FW after init */
|
||||
DF_DISABLE_TCB_CACHE = (1 << 2), /* Disable TCB cache (T6+) */
|
||||
DF_DISABLE_CFG_RETRY = (1 << 3), /* Disable fallback config */
|
||||
DF_VERBOSE_SLOWINTR = (1 << 4), /* Chatty slow intr handler */
|
||||
|
||||
/* adapter intr handler flags */
|
||||
IHF_INTR_CLEAR_ON_INIT = (1 << 0), /* Driver calls t4_intr_clear */
|
||||
IHF_NO_SHOW = (1 << 1), /* Do not display intr info */
|
||||
IHF_VERBOSE = (1 << 2), /* Display extra intr info */
|
||||
IHF_FATAL_IFF_ENABLED = (1 << 3), /* Fatal only if enabled */
|
||||
IHF_IGNORE_IF_DISABLED = (1 << 4), /* Ignore if disabled */
|
||||
IHF_CLR_ALL_SET = (1 << 5), /* Clear all set bits */
|
||||
IHF_CLR_ALL_UNIGNORED = (1 << 6), /* Clear all unignored bits */
|
||||
IHF_RUN_ALL_ACTIONS = (1 << 7), /* As if all cause are set */
|
||||
};
|
||||
|
||||
#define IS_DETACHING(vi) ((vi)->flags & VI_DETACHING)
|
||||
@@ -1027,6 +1036,7 @@ struct adapter {
|
||||
int flags;
|
||||
int debug_flags;
|
||||
int error_flags; /* Used by error handler and live reset. */
|
||||
int intr_flags; /* Used by interrupt setup/handlers. */
|
||||
|
||||
char ifp_lockname[16];
|
||||
struct mtx ifp_lock;
|
||||
|
||||
@@ -684,9 +684,10 @@ u32 t4_hw_pci_read_cfg4(adapter_t *adapter, int reg);
|
||||
|
||||
struct fw_filter_wr;
|
||||
|
||||
void t4_intr_clear(struct adapter *adapter);
|
||||
void t4_intr_enable(struct adapter *adapter);
|
||||
void t4_intr_disable(struct adapter *adapter);
|
||||
bool t4_slow_intr_handler(struct adapter *adapter, bool verbose);
|
||||
bool t4_slow_intr_handler(struct adapter *adapter, int flags);
|
||||
|
||||
int t4_hash_mac_addr(const u8 *addr);
|
||||
int t4_link_l1cfg(struct adapter *adap, unsigned int mbox, unsigned int port,
|
||||
|
||||
+1194
-292
File diff suppressed because it is too large
Load Diff
@@ -1327,6 +1327,8 @@ t4_attach(device_t dev)
|
||||
sc->dev = dev;
|
||||
sysctl_ctx_init(&sc->ctx);
|
||||
TUNABLE_INT_FETCH("hw.cxgbe.dflags", &sc->debug_flags);
|
||||
if (TUNABLE_INT_FETCH("hw.cxgbe.iflags", &sc->intr_flags) == 0)
|
||||
sc->intr_flags = IHF_INTR_CLEAR_ON_INIT | IHF_CLR_ALL_UNIGNORED;
|
||||
|
||||
if ((pci_get_device(dev) & 0xff00) == 0x5400)
|
||||
t5_attribute_workaround(dev);
|
||||
@@ -3943,8 +3945,6 @@ fatal_error_task(void *arg, int pending)
|
||||
void
|
||||
t4_fatal_err(struct adapter *sc, bool fw_error)
|
||||
{
|
||||
const bool verbose = (sc->debug_flags & DF_VERBOSE_SLOWINTR) != 0;
|
||||
|
||||
stop_adapter(sc);
|
||||
if (atomic_testandset_int(&sc->error_flags, ilog2(ADAP_FATAL_ERR)))
|
||||
return;
|
||||
@@ -3957,7 +3957,7 @@ t4_fatal_err(struct adapter *sc, bool fw_error)
|
||||
* main INT_CAUSE registers here to make sure we haven't missed
|
||||
* anything interesting.
|
||||
*/
|
||||
t4_slow_intr_handler(sc, verbose);
|
||||
t4_slow_intr_handler(sc, sc->intr_flags);
|
||||
atomic_set_int(&sc->error_flags, ADAP_CIM_ERR);
|
||||
}
|
||||
t4_report_fw_error(sc);
|
||||
@@ -7908,6 +7908,9 @@ t4_sysctls(struct adapter *sc)
|
||||
SYSCTL_ADD_INT(ctx, children, OID_AUTO, "dflags", CTLFLAG_RW,
|
||||
&sc->debug_flags, 0, "flags to enable runtime debugging");
|
||||
|
||||
SYSCTL_ADD_INT(ctx, children, OID_AUTO, "iflags", CTLFLAG_RW,
|
||||
&sc->intr_flags, 0, "flags for the slow interrupt handler");
|
||||
|
||||
SYSCTL_ADD_STRING(ctx, children, OID_AUTO, "tp_version",
|
||||
CTLFLAG_RD, sc->tp_version, 0, "TP microcode version");
|
||||
|
||||
|
||||
@@ -1340,7 +1340,6 @@ t4_intr_err(void *arg)
|
||||
{
|
||||
struct adapter *sc = arg;
|
||||
uint32_t v;
|
||||
const bool verbose = (sc->debug_flags & DF_VERBOSE_SLOWINTR) != 0;
|
||||
|
||||
if (atomic_load_int(&sc->error_flags) & ADAP_FATAL_ERR)
|
||||
return;
|
||||
@@ -1351,7 +1350,7 @@ t4_intr_err(void *arg)
|
||||
t4_write_reg(sc, MYPF_REG(A_PL_PF_INT_CAUSE), v);
|
||||
}
|
||||
|
||||
if (t4_slow_intr_handler(sc, verbose))
|
||||
if (t4_slow_intr_handler(sc, sc->intr_flags))
|
||||
t4_fatal_err(sc, false);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user