Skip to content

Commit

Permalink
cxgb4: Detect and display firmware reported errors
Browse files Browse the repository at this point in the history
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: Hariprasad Shenai <hariprasad@chelsio.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Hariprasad Shenai authored and David S. Miller committed Sep 2, 2014
1 parent 9bb59b9 commit 31d55c2
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 1 deletion.
38 changes: 37 additions & 1 deletion drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
Original file line number Diff line number Diff line change
Expand Up @@ -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_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.
*/
Expand Down Expand Up @@ -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);
dev_err(adap->pdev_dev, "command %#x in mailbox %d timed out\n",
*(const u8 *)cmd, mbox);
t4_report_fw_error(adap);
return -ETIMEDOUT;
}

Expand Down Expand Up @@ -1533,6 +1562,9 @@ static void cim_intr_handler(struct adapter *adapter)

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,
cim_intr_info) +
t4_handle_intr_status(adapter, CIM_HOST_UPACC_INT_CAUSE,
Expand Down Expand Up @@ -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
* 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);
if (ret < 0) {
if ((ret == -EBUSY || ret == -ETIMEDOUT) && retries-- > 0)
goto retry;
if (t4_read_reg(adap, MA_PCIE_FW) & FW_PCIE_FW_ERR)
t4_report_fw_error(adap);
return ret;
}

Expand Down
4 changes: 4 additions & 0 deletions drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_GET(x) (((x) >> FW_PCIE_FW_MASTER_SHIFT) & \
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 {
u8 ver;
Expand Down

0 comments on commit 31d55c2

Please sign in to comment.