|
@@ -330,11 +330,12 @@ int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, const void *cmd,
|
|
* mailbox access list but this is a start. We very rearely
|
|
* mailbox access list but this is a start. We very rearely
|
|
* contend on access to the mailbox ...
|
|
* contend on access to the mailbox ...
|
|
*/
|
|
*/
|
|
- if (i > FW_CMD_MAX_TIMEOUT) {
|
|
|
|
|
|
+ pcie_fw = t4_read_reg(adap, PCIE_FW_A);
|
|
|
|
+ if (i > FW_CMD_MAX_TIMEOUT || (pcie_fw & PCIE_FW_ERR_F)) {
|
|
spin_lock(&adap->mbox_lock);
|
|
spin_lock(&adap->mbox_lock);
|
|
list_del(&entry.list);
|
|
list_del(&entry.list);
|
|
spin_unlock(&adap->mbox_lock);
|
|
spin_unlock(&adap->mbox_lock);
|
|
- ret = -EBUSY;
|
|
|
|
|
|
+ ret = (pcie_fw & PCIE_FW_ERR_F) ? -ENXIO : -EBUSY;
|
|
t4_record_mbox(adap, cmd, size, access, ret);
|
|
t4_record_mbox(adap, cmd, size, access, ret);
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
@@ -432,6 +433,7 @@ int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, const void *cmd,
|
|
spin_lock(&adap->mbox_lock);
|
|
spin_lock(&adap->mbox_lock);
|
|
list_del(&entry.list);
|
|
list_del(&entry.list);
|
|
spin_unlock(&adap->mbox_lock);
|
|
spin_unlock(&adap->mbox_lock);
|
|
|
|
+ t4_fatal_err(adap);
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -7557,6 +7559,39 @@ int t4_prep_adapter(struct adapter *adapter)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * t4_shutdown_adapter - shut down adapter, host & wire
|
|
|
|
+ * @adapter: the adapter
|
|
|
|
+ *
|
|
|
|
+ * Perform an emergency shutdown of the adapter and stop it from
|
|
|
|
+ * continuing any further communication on the ports or DMA to the
|
|
|
|
+ * host. This is typically used when the adapter and/or firmware
|
|
|
|
+ * have crashed and we want to prevent any further accidental
|
|
|
|
+ * communication with the rest of the world. This will also force
|
|
|
|
+ * the port Link Status to go down -- if register writes work --
|
|
|
|
+ * which should help our peers figure out that we're down.
|
|
|
|
+ */
|
|
|
|
+int t4_shutdown_adapter(struct adapter *adapter)
|
|
|
|
+{
|
|
|
|
+ int port;
|
|
|
|
+
|
|
|
|
+ t4_intr_disable(adapter);
|
|
|
|
+ t4_write_reg(adapter, DBG_GPIO_EN_A, 0);
|
|
|
|
+ for_each_port(adapter, port) {
|
|
|
|
+ u32 a_port_cfg = PORT_REG(port,
|
|
|
|
+ is_t4(adapter->params.chip)
|
|
|
|
+ ? XGMAC_PORT_CFG_A
|
|
|
|
+ : MAC_PORT_CFG_A);
|
|
|
|
+
|
|
|
|
+ t4_write_reg(adapter, a_port_cfg,
|
|
|
|
+ t4_read_reg(adapter, a_port_cfg)
|
|
|
|
+ & ~SIGNAL_DET_V(1));
|
|
|
|
+ }
|
|
|
|
+ t4_set_reg_field(adapter, SGE_CONTROL_A, GLOBALENABLE_F, 0);
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* t4_bar2_sge_qregs - return BAR2 SGE Queue register information
|
|
* t4_bar2_sge_qregs - return BAR2 SGE Queue register information
|
|
* @adapter: the adapter
|
|
* @adapter: the adapter
|