提交 31d55c2d 编写于 作者: H Hariprasad Shenai 提交者: David S. Miller

cxgb4: Detect and display firmware reported errors

The adapter firmware can indicate error conditions to the host.
If the firmware has indicated an error, print out the reason for
the firmware error.

Based on original work by Casey Leedom <leedom@chelsio.com>
Signed-off-by: NHariprasad Shenai <hariprasad@chelsio.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 9bb59b96
...@@ -167,6 +167,34 @@ void t4_hw_pci_read_cfg4(struct adapter *adap, int reg, u32 *val) ...@@ -167,6 +167,34 @@ void t4_hw_pci_read_cfg4(struct adapter *adap, int reg, u32 *val)
t4_write_reg(adap, PCIE_CFG_SPACE_REQ, 0); t4_write_reg(adap, PCIE_CFG_SPACE_REQ, 0);
} }
/*
* t4_report_fw_error - report firmware error
* @adap: the adapter
*
* The adapter firmware can indicate error conditions to the host.
* If the firmware has indicated an error, print out the reason for
* the firmware error.
*/
static void t4_report_fw_error(struct adapter *adap)
{
static const char *const reason[] = {
"Crash", /* PCIE_FW_EVAL_CRASH */
"During Device Preparation", /* PCIE_FW_EVAL_PREP */
"During Device Configuration", /* PCIE_FW_EVAL_CONF */
"During Device Initialization", /* PCIE_FW_EVAL_INIT */
"Unexpected Event", /* PCIE_FW_EVAL_UNEXPECTEDEVENT */
"Insufficient Airflow", /* PCIE_FW_EVAL_OVERHEAT */
"Device Shutdown", /* PCIE_FW_EVAL_DEVICESHUTDOWN */
"Reserved", /* reserved */
};
u32 pcie_fw;
pcie_fw = t4_read_reg(adap, MA_PCIE_FW);
if (pcie_fw & FW_PCIE_FW_ERR)
dev_err(adap->pdev_dev, "Firmware reports adapter error: %s\n",
reason[FW_PCIE_FW_EVAL_GET(pcie_fw)]);
}
/* /*
* Get the reply to a mailbox command and store it in @rpl in big-endian order. * Get the reply to a mailbox command and store it in @rpl in big-endian order.
*/ */
...@@ -300,6 +328,7 @@ int t4_wr_mbox_meat(struct adapter *adap, int mbox, const void *cmd, int size, ...@@ -300,6 +328,7 @@ int t4_wr_mbox_meat(struct adapter *adap, int mbox, const void *cmd, int size,
dump_mbox(adap, mbox, data_reg); dump_mbox(adap, mbox, data_reg);
dev_err(adap->pdev_dev, "command %#x in mailbox %d timed out\n", dev_err(adap->pdev_dev, "command %#x in mailbox %d timed out\n",
*(const u8 *)cmd, mbox); *(const u8 *)cmd, mbox);
t4_report_fw_error(adap);
return -ETIMEDOUT; return -ETIMEDOUT;
} }
...@@ -1533,6 +1562,9 @@ static void cim_intr_handler(struct adapter *adapter) ...@@ -1533,6 +1562,9 @@ static void cim_intr_handler(struct adapter *adapter)
int fat; int fat;
if (t4_read_reg(adapter, MA_PCIE_FW) & FW_PCIE_FW_ERR)
t4_report_fw_error(adapter);
fat = t4_handle_intr_status(adapter, CIM_HOST_INT_CAUSE, fat = t4_handle_intr_status(adapter, CIM_HOST_INT_CAUSE,
cim_intr_info) + cim_intr_info) +
t4_handle_intr_status(adapter, CIM_HOST_UPACC_INT_CAUSE, t4_handle_intr_status(adapter, CIM_HOST_UPACC_INT_CAUSE,
...@@ -2751,12 +2783,16 @@ int t4_fw_hello(struct adapter *adap, unsigned int mbox, unsigned int evt_mbox, ...@@ -2751,12 +2783,16 @@ int t4_fw_hello(struct adapter *adap, unsigned int mbox, unsigned int evt_mbox,
/* /*
* Issue the HELLO command to the firmware. If it's not successful * Issue the HELLO command to the firmware. If it's not successful
* but indicates that we got a "busy" or "timeout" condition, retry * but indicates that we got a "busy" or "timeout" condition, retry
* the HELLO until we exhaust our retry limit. * the HELLO until we exhaust our retry limit. If we do exceed our
* retry limit, check to see if the firmware left us any error
* information and report that if so.
*/ */
ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c); ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c);
if (ret < 0) { if (ret < 0) {
if ((ret == -EBUSY || ret == -ETIMEDOUT) && retries-- > 0) if ((ret == -EBUSY || ret == -ETIMEDOUT) && retries-- > 0)
goto retry; goto retry;
if (t4_read_reg(adap, MA_PCIE_FW) & FW_PCIE_FW_ERR)
t4_report_fw_error(adap);
return ret; return ret;
} }
......
...@@ -2228,6 +2228,10 @@ struct fw_debug_cmd { ...@@ -2228,6 +2228,10 @@ struct fw_debug_cmd {
#define FW_PCIE_FW_MASTER(x) ((x) << FW_PCIE_FW_MASTER_SHIFT) #define FW_PCIE_FW_MASTER(x) ((x) << FW_PCIE_FW_MASTER_SHIFT)
#define FW_PCIE_FW_MASTER_GET(x) (((x) >> FW_PCIE_FW_MASTER_SHIFT) & \ #define FW_PCIE_FW_MASTER_GET(x) (((x) >> FW_PCIE_FW_MASTER_SHIFT) & \
FW_PCIE_FW_MASTER_MASK) FW_PCIE_FW_MASTER_MASK)
#define FW_PCIE_FW_EVAL_MASK 0x7
#define FW_PCIE_FW_EVAL_SHIFT 24
#define FW_PCIE_FW_EVAL_GET(x) (((x) >> FW_PCIE_FW_EVAL_SHIFT) & \
FW_PCIE_FW_EVAL_MASK)
struct fw_hdr { struct fw_hdr {
u8 ver; u8 ver;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册