Commit 0a75709b authored by David S. Miller's avatar David S. Miller

Merge branch 'bnxt_en-error-recovery-follow-up-patches'

Michael Chan says:

====================
bnxt_en: error recovery follow-up patches.

A follow-up patchset for the recently added health and error recovery
feature.  The first fix is to prevent .ndo_set_rx_mode() from proceeding
when reset is in progress.  The 2nd fix is for the firmware coredump
command.  The 3rd and 4th patches update the error recovery process
slightly to add a state that polls and waits for the firmware to be down.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 8f7baad7 4037eb71
...@@ -6947,6 +6947,8 @@ static int __bnxt_hwrm_func_qcaps(struct bnxt *bp) ...@@ -6947,6 +6947,8 @@ static int __bnxt_hwrm_func_qcaps(struct bnxt *bp)
bp->fw_cap |= BNXT_FW_CAP_EXT_STATS_SUPPORTED; bp->fw_cap |= BNXT_FW_CAP_EXT_STATS_SUPPORTED;
if (flags & FUNC_QCAPS_RESP_FLAGS_ERROR_RECOVERY_CAPABLE) if (flags & FUNC_QCAPS_RESP_FLAGS_ERROR_RECOVERY_CAPABLE)
bp->fw_cap |= BNXT_FW_CAP_ERROR_RECOVERY; bp->fw_cap |= BNXT_FW_CAP_ERROR_RECOVERY;
if (flags & FUNC_QCAPS_RESP_FLAGS_ERR_RECOVER_RELOAD)
bp->fw_cap |= BNXT_FW_CAP_ERR_RECOVER_RELOAD;
bp->tx_push_thresh = 0; bp->tx_push_thresh = 0;
if (flags & FUNC_QCAPS_RESP_FLAGS_PUSH_MODE_SUPPORTED) if (flags & FUNC_QCAPS_RESP_FLAGS_PUSH_MODE_SUPPORTED)
...@@ -9557,14 +9559,16 @@ static bool bnxt_uc_list_updated(struct bnxt *bp) ...@@ -9557,14 +9559,16 @@ static bool bnxt_uc_list_updated(struct bnxt *bp)
static void bnxt_set_rx_mode(struct net_device *dev) static void bnxt_set_rx_mode(struct net_device *dev)
{ {
struct bnxt *bp = netdev_priv(dev); struct bnxt *bp = netdev_priv(dev);
struct bnxt_vnic_info *vnic = &bp->vnic_info[0]; struct bnxt_vnic_info *vnic;
u32 mask = vnic->rx_mask;
bool mc_update = false; bool mc_update = false;
bool uc_update; bool uc_update;
u32 mask;
if (!netif_running(dev)) if (!test_bit(BNXT_STATE_OPEN, &bp->state))
return; return;
vnic = &bp->vnic_info[0];
mask = vnic->rx_mask;
mask &= ~(CFA_L2_SET_RX_MASK_REQ_MASK_PROMISCUOUS | mask &= ~(CFA_L2_SET_RX_MASK_REQ_MASK_PROMISCUOUS |
CFA_L2_SET_RX_MASK_REQ_MASK_MCAST | CFA_L2_SET_RX_MASK_REQ_MASK_MCAST |
CFA_L2_SET_RX_MASK_REQ_MASK_ALL_MCAST | CFA_L2_SET_RX_MASK_REQ_MASK_ALL_MCAST |
...@@ -10095,6 +10099,8 @@ static void bnxt_force_fw_reset(struct bnxt *bp) ...@@ -10095,6 +10099,8 @@ static void bnxt_force_fw_reset(struct bnxt *bp)
wait_dsecs = fw_health->normal_func_wait_dsecs; wait_dsecs = fw_health->normal_func_wait_dsecs;
bp->fw_reset_state = BNXT_FW_RESET_STATE_ENABLE_DEV; bp->fw_reset_state = BNXT_FW_RESET_STATE_ENABLE_DEV;
} }
bp->fw_reset_min_dsecs = fw_health->post_reset_wait_dsecs;
bp->fw_reset_max_dsecs = fw_health->post_reset_max_wait_dsecs; bp->fw_reset_max_dsecs = fw_health->post_reset_max_wait_dsecs;
bnxt_queue_fw_reset_work(bp, wait_dsecs * HZ / 10); bnxt_queue_fw_reset_work(bp, wait_dsecs * HZ / 10);
} }
...@@ -10136,7 +10142,7 @@ void bnxt_fw_reset(struct bnxt *bp) ...@@ -10136,7 +10142,7 @@ void bnxt_fw_reset(struct bnxt *bp)
bnxt_rtnl_lock_sp(bp); bnxt_rtnl_lock_sp(bp);
if (test_bit(BNXT_STATE_OPEN, &bp->state) && if (test_bit(BNXT_STATE_OPEN, &bp->state) &&
!test_bit(BNXT_STATE_IN_FW_RESET, &bp->state)) { !test_bit(BNXT_STATE_IN_FW_RESET, &bp->state)) {
int n = 0; int n = 0, tmo;
set_bit(BNXT_STATE_IN_FW_RESET, &bp->state); set_bit(BNXT_STATE_IN_FW_RESET, &bp->state);
if (bp->pf.active_vfs && if (bp->pf.active_vfs &&
...@@ -10159,8 +10165,14 @@ void bnxt_fw_reset(struct bnxt *bp) ...@@ -10159,8 +10165,14 @@ void bnxt_fw_reset(struct bnxt *bp)
goto fw_reset_exit; goto fw_reset_exit;
} }
bnxt_fw_reset_close(bp); bnxt_fw_reset_close(bp);
bp->fw_reset_state = BNXT_FW_RESET_STATE_ENABLE_DEV; if (bp->fw_cap & BNXT_FW_CAP_ERR_RECOVER_RELOAD) {
bnxt_queue_fw_reset_work(bp, bp->fw_reset_min_dsecs * HZ / 10); bp->fw_reset_state = BNXT_FW_RESET_STATE_POLL_FW_DOWN;
tmo = HZ / 10;
} else {
bp->fw_reset_state = BNXT_FW_RESET_STATE_ENABLE_DEV;
tmo = bp->fw_reset_min_dsecs * HZ / 10;
}
bnxt_queue_fw_reset_work(bp, tmo);
} }
fw_reset_exit: fw_reset_exit:
bnxt_rtnl_unlock_sp(bp); bnxt_rtnl_unlock_sp(bp);
...@@ -10603,6 +10615,7 @@ static void bnxt_fw_reset_task(struct work_struct *work) ...@@ -10603,6 +10615,7 @@ static void bnxt_fw_reset_task(struct work_struct *work)
switch (bp->fw_reset_state) { switch (bp->fw_reset_state) {
case BNXT_FW_RESET_STATE_POLL_VF: { case BNXT_FW_RESET_STATE_POLL_VF: {
int n = bnxt_get_registered_vfs(bp); int n = bnxt_get_registered_vfs(bp);
int tmo;
if (n < 0) { if (n < 0) {
netdev_err(bp->dev, "Firmware reset aborted, subsequent func_qcfg cmd failed, rc = %d, %d msecs since reset timestamp\n", netdev_err(bp->dev, "Firmware reset aborted, subsequent func_qcfg cmd failed, rc = %d, %d msecs since reset timestamp\n",
...@@ -10624,11 +10637,38 @@ static void bnxt_fw_reset_task(struct work_struct *work) ...@@ -10624,11 +10637,38 @@ static void bnxt_fw_reset_task(struct work_struct *work)
bp->fw_reset_timestamp = jiffies; bp->fw_reset_timestamp = jiffies;
rtnl_lock(); rtnl_lock();
bnxt_fw_reset_close(bp); bnxt_fw_reset_close(bp);
bp->fw_reset_state = BNXT_FW_RESET_STATE_ENABLE_DEV; if (bp->fw_cap & BNXT_FW_CAP_ERR_RECOVER_RELOAD) {
bp->fw_reset_state = BNXT_FW_RESET_STATE_POLL_FW_DOWN;
tmo = HZ / 10;
} else {
bp->fw_reset_state = BNXT_FW_RESET_STATE_ENABLE_DEV;
tmo = bp->fw_reset_min_dsecs * HZ / 10;
}
rtnl_unlock(); rtnl_unlock();
bnxt_queue_fw_reset_work(bp, bp->fw_reset_min_dsecs * HZ / 10); bnxt_queue_fw_reset_work(bp, tmo);
return; return;
} }
case BNXT_FW_RESET_STATE_POLL_FW_DOWN: {
u32 val;
val = bnxt_fw_health_readl(bp, BNXT_FW_HEALTH_REG);
if (!(val & BNXT_FW_STATUS_SHUTDOWN) &&
!time_after(jiffies, bp->fw_reset_timestamp +
(bp->fw_reset_max_dsecs * HZ / 10))) {
bnxt_queue_fw_reset_work(bp, HZ / 5);
return;
}
if (!bp->fw_health->master) {
u32 wait_dsecs = bp->fw_health->normal_func_wait_dsecs;
bp->fw_reset_state = BNXT_FW_RESET_STATE_ENABLE_DEV;
bnxt_queue_fw_reset_work(bp, wait_dsecs * HZ / 10);
return;
}
bp->fw_reset_state = BNXT_FW_RESET_STATE_RESET_FW;
}
/* fall through */
case BNXT_FW_RESET_STATE_RESET_FW: { case BNXT_FW_RESET_STATE_RESET_FW: {
u32 wait_dsecs = bp->fw_health->post_reset_wait_dsecs; u32 wait_dsecs = bp->fw_health->post_reset_wait_dsecs;
......
...@@ -648,6 +648,7 @@ struct nqe_cn { ...@@ -648,6 +648,7 @@ struct nqe_cn {
#define SHORT_HWRM_CMD_TIMEOUT 20 #define SHORT_HWRM_CMD_TIMEOUT 20
#define HWRM_CMD_TIMEOUT (bp->hwrm_cmd_timeout) #define HWRM_CMD_TIMEOUT (bp->hwrm_cmd_timeout)
#define HWRM_RESET_TIMEOUT ((HWRM_CMD_TIMEOUT) * 4) #define HWRM_RESET_TIMEOUT ((HWRM_CMD_TIMEOUT) * 4)
#define HWRM_COREDUMP_TIMEOUT ((HWRM_CMD_TIMEOUT) * 12)
#define HWRM_RESP_ERR_CODE_MASK 0xffff #define HWRM_RESP_ERR_CODE_MASK 0xffff
#define HWRM_RESP_LEN_OFFSET 4 #define HWRM_RESP_LEN_OFFSET 4
#define HWRM_RESP_LEN_MASK 0xffff0000 #define HWRM_RESP_LEN_MASK 0xffff0000
...@@ -1397,6 +1398,7 @@ struct bnxt_fw_reporter_ctx { ...@@ -1397,6 +1398,7 @@ struct bnxt_fw_reporter_ctx {
#define BNXT_FW_HEALTH_WIN_MAP_OFF 8 #define BNXT_FW_HEALTH_WIN_MAP_OFF 8
#define BNXT_FW_STATUS_HEALTHY 0x8000 #define BNXT_FW_STATUS_HEALTHY 0x8000
#define BNXT_FW_STATUS_SHUTDOWN 0x100000
struct bnxt { struct bnxt {
void __iomem *bar0; void __iomem *bar0;
...@@ -1654,6 +1656,7 @@ struct bnxt { ...@@ -1654,6 +1656,7 @@ struct bnxt {
#define BNXT_FW_CAP_CFA_RFS_RING_TBL_IDX 0x00010000 #define BNXT_FW_CAP_CFA_RFS_RING_TBL_IDX 0x00010000
#define BNXT_FW_CAP_PCIE_STATS_SUPPORTED 0x00020000 #define BNXT_FW_CAP_PCIE_STATS_SUPPORTED 0x00020000
#define BNXT_FW_CAP_EXT_STATS_SUPPORTED 0x00040000 #define BNXT_FW_CAP_EXT_STATS_SUPPORTED 0x00040000
#define BNXT_FW_CAP_ERR_RECOVER_RELOAD 0x00100000
#define BNXT_NEW_RM(bp) ((bp)->fw_cap & BNXT_FW_CAP_NEW_RM) #define BNXT_NEW_RM(bp) ((bp)->fw_cap & BNXT_FW_CAP_NEW_RM)
u32 hwrm_spec_code; u32 hwrm_spec_code;
...@@ -1743,6 +1746,7 @@ struct bnxt { ...@@ -1743,6 +1746,7 @@ struct bnxt {
#define BNXT_FW_RESET_STATE_ENABLE_DEV 3 #define BNXT_FW_RESET_STATE_ENABLE_DEV 3
#define BNXT_FW_RESET_STATE_POLL_FW 4 #define BNXT_FW_RESET_STATE_POLL_FW 4
#define BNXT_FW_RESET_STATE_OPENING 5 #define BNXT_FW_RESET_STATE_OPENING 5
#define BNXT_FW_RESET_STATE_POLL_FW_DOWN 6
u16 fw_reset_min_dsecs; u16 fw_reset_min_dsecs;
#define BNXT_DFLT_FW_RST_MIN_DSECS 20 #define BNXT_DFLT_FW_RST_MIN_DSECS 20
......
...@@ -3112,7 +3112,7 @@ static int bnxt_hwrm_dbg_coredump_initiate(struct bnxt *bp, u16 component_id, ...@@ -3112,7 +3112,7 @@ static int bnxt_hwrm_dbg_coredump_initiate(struct bnxt *bp, u16 component_id,
req.component_id = cpu_to_le16(component_id); req.component_id = cpu_to_le16(component_id);
req.segment_id = cpu_to_le16(segment_id); req.segment_id = cpu_to_le16(segment_id);
return hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); return hwrm_send_message(bp, &req, sizeof(req), HWRM_COREDUMP_TIMEOUT);
} }
static int bnxt_hwrm_dbg_coredump_retrieve(struct bnxt *bp, u16 component_id, static int bnxt_hwrm_dbg_coredump_retrieve(struct bnxt *bp, u16 component_id,
......
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