Commit df97b34d authored by Michael Chan's avatar Michael Chan Committed by David S. Miller

bnxt_en: Reply to firmware's echo request async message.

This is a new async message that the firmware can send to check if it
can communicate with the driver.  This is an added error detection
scheme that firmware can use if it suspects errors in the PCIe
interface.  When the driver receives this async message, it will reply
back echoing some data in the async message.  If the firmware is not
getting the reply with the proper data after some retries, error
recovery will kick in.
Reviewed-by: default avatarAndy Gospodarek <gospo@broadcom.com>
Reviewed-by: default avatarEdwin Peer <edwin.peer@broadcom.com>
Reviewed-by: default avatarVasundhara Volam <vasundhara-v.volam@broadcom.com>
Signed-off-by: default avatarMichael Chan <michael.chan@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 41435c39
...@@ -257,6 +257,7 @@ static const u16 bnxt_async_events_arr[] = { ...@@ -257,6 +257,7 @@ static const u16 bnxt_async_events_arr[] = {
ASYNC_EVENT_CMPL_EVENT_ID_ERROR_RECOVERY, ASYNC_EVENT_CMPL_EVENT_ID_ERROR_RECOVERY,
ASYNC_EVENT_CMPL_EVENT_ID_DEBUG_NOTIFICATION, ASYNC_EVENT_CMPL_EVENT_ID_DEBUG_NOTIFICATION,
ASYNC_EVENT_CMPL_EVENT_ID_RING_MONITOR_MSG, ASYNC_EVENT_CMPL_EVENT_ID_RING_MONITOR_MSG,
ASYNC_EVENT_CMPL_EVENT_ID_ECHO_REQUEST,
}; };
static struct workqueue_struct *bnxt_pf_wq; static struct workqueue_struct *bnxt_pf_wq;
...@@ -2099,6 +2100,20 @@ static int bnxt_async_event_process(struct bnxt *bp, ...@@ -2099,6 +2100,20 @@ static int bnxt_async_event_process(struct bnxt *bp,
bnxt_sched_reset(bp, rxr); bnxt_sched_reset(bp, rxr);
goto async_event_process_exit; goto async_event_process_exit;
} }
case ASYNC_EVENT_CMPL_EVENT_ID_ECHO_REQUEST: {
struct bnxt_fw_health *fw_health = bp->fw_health;
netif_notice(bp, hw, bp->dev,
"Received firmware echo request, data1: 0x%x, data2: 0x%x\n",
data1, data2);
if (fw_health) {
fw_health->echo_req_data1 = data1;
fw_health->echo_req_data2 = data2;
set_bit(BNXT_FW_ECHO_REQUEST_SP_EVENT, &bp->sp_event);
break;
}
goto async_event_process_exit;
}
default: default:
goto async_event_process_exit; goto async_event_process_exit;
} }
...@@ -11208,6 +11223,17 @@ static void bnxt_init_ethtool_link_settings(struct bnxt *bp) ...@@ -11208,6 +11223,17 @@ static void bnxt_init_ethtool_link_settings(struct bnxt *bp)
link_info->req_flow_ctrl = link_info->force_pause_setting; link_info->req_flow_ctrl = link_info->force_pause_setting;
} }
static void bnxt_fw_echo_reply(struct bnxt *bp)
{
struct bnxt_fw_health *fw_health = bp->fw_health;
struct hwrm_func_echo_response_input req = {0};
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_ECHO_RESPONSE, -1, -1);
req.event_data1 = cpu_to_le32(fw_health->echo_req_data1);
req.event_data2 = cpu_to_le32(fw_health->echo_req_data2);
hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
}
static void bnxt_sp_task(struct work_struct *work) static void bnxt_sp_task(struct work_struct *work)
{ {
struct bnxt *bp = container_of(work, struct bnxt, sp_task); struct bnxt *bp = container_of(work, struct bnxt, sp_task);
...@@ -11275,6 +11301,9 @@ static void bnxt_sp_task(struct work_struct *work) ...@@ -11275,6 +11301,9 @@ static void bnxt_sp_task(struct work_struct *work)
if (test_and_clear_bit(BNXT_RING_COAL_NOW_SP_EVENT, &bp->sp_event)) if (test_and_clear_bit(BNXT_RING_COAL_NOW_SP_EVENT, &bp->sp_event))
bnxt_chk_missed_irq(bp); bnxt_chk_missed_irq(bp);
if (test_and_clear_bit(BNXT_FW_ECHO_REQUEST_SP_EVENT, &bp->sp_event))
bnxt_fw_echo_reply(bp);
/* These functions below will clear BNXT_STATE_IN_SP_TASK. They /* These functions below will clear BNXT_STATE_IN_SP_TASK. They
* must be the last functions to be called before exiting. * must be the last functions to be called before exiting.
*/ */
......
...@@ -1531,6 +1531,8 @@ struct bnxt_fw_health { ...@@ -1531,6 +1531,8 @@ struct bnxt_fw_health {
u32 fw_reset_seq_regs[16]; u32 fw_reset_seq_regs[16];
u32 fw_reset_seq_vals[16]; u32 fw_reset_seq_vals[16];
u32 fw_reset_seq_delay_msec[16]; u32 fw_reset_seq_delay_msec[16];
u32 echo_req_data1;
u32 echo_req_data2;
struct devlink_health_reporter *fw_reporter; struct devlink_health_reporter *fw_reporter;
struct devlink_health_reporter *fw_reset_reporter; struct devlink_health_reporter *fw_reset_reporter;
struct devlink_health_reporter *fw_fatal_reporter; struct devlink_health_reporter *fw_fatal_reporter;
...@@ -1940,6 +1942,7 @@ struct bnxt { ...@@ -1940,6 +1942,7 @@ struct bnxt {
#define BNXT_FW_RESET_NOTIFY_SP_EVENT 18 #define BNXT_FW_RESET_NOTIFY_SP_EVENT 18
#define BNXT_FW_EXCEPTION_SP_EVENT 19 #define BNXT_FW_EXCEPTION_SP_EVENT 19
#define BNXT_LINK_CFG_CHANGE_SP_EVENT 21 #define BNXT_LINK_CFG_CHANGE_SP_EVENT 21
#define BNXT_FW_ECHO_REQUEST_SP_EVENT 23
struct delayed_work fw_reset_task; struct delayed_work fw_reset_task;
int fw_reset_state; int fw_reset_state;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment