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

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
Loading
Loading
Loading
Loading
+48 −8
Original line number Diff line number Diff line
@@ -6947,6 +6947,8 @@ static int __bnxt_hwrm_func_qcaps(struct bnxt *bp)
		bp->fw_cap |= BNXT_FW_CAP_EXT_STATS_SUPPORTED;
	if (flags &  FUNC_QCAPS_RESP_FLAGS_ERROR_RECOVERY_CAPABLE)
		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;
	if (flags & FUNC_QCAPS_RESP_FLAGS_PUSH_MODE_SUPPORTED)
@@ -9557,14 +9559,16 @@ static bool bnxt_uc_list_updated(struct bnxt *bp)
static void bnxt_set_rx_mode(struct net_device *dev)
{
	struct bnxt *bp = netdev_priv(dev);
	struct bnxt_vnic_info *vnic = &bp->vnic_info[0];
	u32 mask = vnic->rx_mask;
	struct bnxt_vnic_info *vnic;
	bool mc_update = false;
	bool uc_update;
	u32 mask;

	if (!netif_running(dev))
	if (!test_bit(BNXT_STATE_OPEN, &bp->state))
		return;

	vnic = &bp->vnic_info[0];
	mask = vnic->rx_mask;
	mask &= ~(CFA_L2_SET_RX_MASK_REQ_MASK_PROMISCUOUS |
		  CFA_L2_SET_RX_MASK_REQ_MASK_MCAST |
		  CFA_L2_SET_RX_MASK_REQ_MASK_ALL_MCAST |
@@ -10095,6 +10099,8 @@ static void bnxt_force_fw_reset(struct bnxt *bp)
		wait_dsecs = fw_health->normal_func_wait_dsecs;
		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;
	bnxt_queue_fw_reset_work(bp, wait_dsecs * HZ / 10);
}
@@ -10136,7 +10142,7 @@ void bnxt_fw_reset(struct bnxt *bp)
	bnxt_rtnl_lock_sp(bp);
	if (test_bit(BNXT_STATE_OPEN, &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);
		if (bp->pf.active_vfs &&
@@ -10159,8 +10165,14 @@ void bnxt_fw_reset(struct bnxt *bp)
			goto fw_reset_exit;
		}
		bnxt_fw_reset_close(bp);
		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;
		bnxt_queue_fw_reset_work(bp, bp->fw_reset_min_dsecs * HZ / 10);
			tmo = bp->fw_reset_min_dsecs * HZ / 10;
		}
		bnxt_queue_fw_reset_work(bp, tmo);
	}
fw_reset_exit:
	bnxt_rtnl_unlock_sp(bp);
@@ -10603,6 +10615,7 @@ static void bnxt_fw_reset_task(struct work_struct *work)
	switch (bp->fw_reset_state) {
	case BNXT_FW_RESET_STATE_POLL_VF: {
		int n = bnxt_get_registered_vfs(bp);
		int tmo;

		if (n < 0) {
			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)
		bp->fw_reset_timestamp = jiffies;
		rtnl_lock();
		bnxt_fw_reset_close(bp);
		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();
		bnxt_queue_fw_reset_work(bp, bp->fw_reset_min_dsecs * HZ / 10);
		bnxt_queue_fw_reset_work(bp, tmo);
		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: {
		u32 wait_dsecs = bp->fw_health->post_reset_wait_dsecs;

+4 −0
Original line number Diff line number Diff line
@@ -648,6 +648,7 @@ struct nqe_cn {
#define SHORT_HWRM_CMD_TIMEOUT		20
#define HWRM_CMD_TIMEOUT		(bp->hwrm_cmd_timeout)
#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_LEN_OFFSET		4
#define HWRM_RESP_LEN_MASK		0xffff0000
@@ -1397,6 +1398,7 @@ struct bnxt_fw_reporter_ctx {
#define BNXT_FW_HEALTH_WIN_MAP_OFF	8

#define BNXT_FW_STATUS_HEALTHY		0x8000
#define BNXT_FW_STATUS_SHUTDOWN		0x100000

struct bnxt {
	void __iomem		*bar0;
@@ -1654,6 +1656,7 @@ struct bnxt {
	#define BNXT_FW_CAP_CFA_RFS_RING_TBL_IDX	0x00010000
	#define BNXT_FW_CAP_PCIE_STATS_SUPPORTED	0x00020000
	#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)
	u32			hwrm_spec_code;
@@ -1743,6 +1746,7 @@ struct bnxt {
#define BNXT_FW_RESET_STATE_ENABLE_DEV	3
#define BNXT_FW_RESET_STATE_POLL_FW	4
#define BNXT_FW_RESET_STATE_OPENING	5
#define BNXT_FW_RESET_STATE_POLL_FW_DOWN	6

	u16			fw_reset_min_dsecs;
#define BNXT_DFLT_FW_RST_MIN_DSECS	20
+1 −1
Original line number Diff line number Diff line
@@ -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.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,
+103 −43
Original line number Diff line number Diff line
@@ -44,11 +44,12 @@ struct hwrm_resp_hdr {
#define TLV_TYPE_ENGINE_CKV_IV                   0x8003UL
#define TLV_TYPE_ENGINE_CKV_AUTH_TAG             0x8004UL
#define TLV_TYPE_ENGINE_CKV_CIPHERTEXT           0x8005UL
#define TLV_TYPE_ENGINE_CKV_ALGORITHMS           0x8006UL
#define TLV_TYPE_ENGINE_CKV_HOST_ALGORITHMS      0x8006UL
#define TLV_TYPE_ENGINE_CKV_HOST_ECC_PUBLIC_KEY  0x8007UL
#define TLV_TYPE_ENGINE_CKV_ECDSA_SIGNATURE      0x8008UL
#define TLV_TYPE_ENGINE_CKV_SRT_ECC_PUBLIC_KEY   0x8009UL
#define TLV_TYPE_LAST                           TLV_TYPE_ENGINE_CKV_SRT_ECC_PUBLIC_KEY
#define TLV_TYPE_ENGINE_CKV_FW_ECC_PUBLIC_KEY    0x8009UL
#define TLV_TYPE_ENGINE_CKV_FW_ALGORITHMS        0x800aUL
#define TLV_TYPE_LAST                           TLV_TYPE_ENGINE_CKV_FW_ALGORITHMS


/* tlv (size:64b/8B) */
@@ -201,10 +202,16 @@ struct cmd_nums {
	#define HWRM_PORT_QSTATS_EXT                      0xb4UL
	#define HWRM_PORT_PHY_MDIO_WRITE                  0xb5UL
	#define HWRM_PORT_PHY_MDIO_READ                   0xb6UL
	#define HWRM_PORT_PHY_MDIO_BUS_ACQUIRE            0xb7UL
	#define HWRM_PORT_PHY_MDIO_BUS_RELEASE            0xb8UL
	#define HWRM_FW_RESET                             0xc0UL
	#define HWRM_FW_QSTATUS                           0xc1UL
	#define HWRM_FW_HEALTH_CHECK                      0xc2UL
	#define HWRM_FW_SYNC                              0xc3UL
	#define HWRM_FW_STATE_BUFFER_QCAPS                0xc4UL
	#define HWRM_FW_STATE_QUIESCE                     0xc5UL
	#define HWRM_FW_STATE_BACKUP                      0xc6UL
	#define HWRM_FW_STATE_RESTORE                     0xc7UL
	#define HWRM_FW_SET_TIME                          0xc8UL
	#define HWRM_FW_GET_TIME                          0xc9UL
	#define HWRM_FW_SET_STRUCTURED_DATA               0xcaUL
@@ -216,7 +223,10 @@ struct cmd_nums {
	#define HWRM_FWD_ASYNC_EVENT_CMPL                 0xd3UL
	#define HWRM_OEM_CMD                              0xd4UL
	#define HWRM_PORT_PRBS_TEST                       0xd5UL
	#define HWRM_PORT_SFP_SIDEBAND_CFG                0xd6UL
	#define HWRM_PORT_SFP_SIDEBAND_QCFG               0xd7UL
	#define HWRM_TEMP_MONITOR_QUERY                   0xe0UL
	#define HWRM_REG_POWER_QUERY                      0xe1UL
	#define HWRM_WOL_FILTER_ALLOC                     0xf0UL
	#define HWRM_WOL_FILTER_FREE                      0xf1UL
	#define HWRM_WOL_FILTER_QCFG                      0xf2UL
@@ -411,8 +421,8 @@ struct hwrm_err_output {
#define HWRM_VERSION_MAJOR 1
#define HWRM_VERSION_MINOR 10
#define HWRM_VERSION_UPDATE 0
#define HWRM_VERSION_RSVD 89
#define HWRM_VERSION_STR "1.10.0.89"
#define HWRM_VERSION_RSVD 100
#define HWRM_VERSION_STR "1.10.0.100"

/* hwrm_ver_get_input (size:192b/24B) */
struct hwrm_ver_get_input {
@@ -805,6 +815,37 @@ struct hwrm_async_event_cmpl_vf_cfg_change {
	#define ASYNC_EVENT_CMPL_VF_CFG_CHANGE_EVENT_DATA1_TRUSTED_VF_CFG_CHANGE     0x10UL
};

/* hwrm_async_event_cmpl_default_vnic_change (size:128b/16B) */
struct hwrm_async_event_cmpl_default_vnic_change {
	__le16	type;
	#define ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_TYPE_MASK            0x3fUL
	#define ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_TYPE_SFT             0
	#define ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_TYPE_HWRM_ASYNC_EVENT  0x2eUL
	#define ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_TYPE_LAST             ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_TYPE_HWRM_ASYNC_EVENT
	#define ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_UNUSED1_MASK         0xffc0UL
	#define ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_UNUSED1_SFT          6
	__le16	event_id;
	#define ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_EVENT_ID_ALLOC_FREE_NOTIFICATION 0x35UL
	#define ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_EVENT_ID_LAST                   ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_EVENT_ID_ALLOC_FREE_NOTIFICATION
	__le32	event_data2;
	u8	opaque_v;
	#define ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_V          0x1UL
	#define ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_OPAQUE_MASK 0xfeUL
	#define ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_OPAQUE_SFT 1
	u8	timestamp_lo;
	__le16	timestamp_hi;
	__le32	event_data1;
	#define ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_EVENT_DATA1_DEF_VNIC_STATE_MASK          0x3UL
	#define ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_EVENT_DATA1_DEF_VNIC_STATE_SFT           0
	#define ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_EVENT_DATA1_DEF_VNIC_STATE_DEF_VNIC_ALLOC  0x1UL
	#define ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_EVENT_DATA1_DEF_VNIC_STATE_DEF_VNIC_FREE   0x2UL
	#define ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_EVENT_DATA1_DEF_VNIC_STATE_LAST           ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_EVENT_DATA1_DEF_VNIC_STATE_DEF_VNIC_FREE
	#define ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_EVENT_DATA1_PF_ID_MASK                   0x3fcUL
	#define ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_EVENT_DATA1_PF_ID_SFT                    2
	#define ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_EVENT_DATA1_VF_ID_MASK                   0x3fffc00UL
	#define ASYNC_EVENT_CMPL_DEFAULT_VNIC_CHANGE_EVENT_DATA1_VF_ID_SFT                    10
};

/* hwrm_async_event_cmpl_hw_flow_aged (size:128b/16B) */
struct hwrm_async_event_cmpl_hw_flow_aged {
	__le16	type;
@@ -1072,6 +1113,8 @@ struct hwrm_func_qcaps_output {
	#define FUNC_QCAPS_RESP_FLAGS_HOT_RESET_CAPABLE                     0x400000UL
	#define FUNC_QCAPS_RESP_FLAGS_ERROR_RECOVERY_CAPABLE                0x800000UL
	#define FUNC_QCAPS_RESP_FLAGS_EXT_STATS_SUPPORTED                   0x1000000UL
	#define FUNC_QCAPS_RESP_FLAGS_ERR_RECOVER_RELOAD                    0x2000000UL
	#define FUNC_QCAPS_RESP_FLAGS_NOTIFY_VF_DEF_VNIC_CHNG_SUPPORTED     0x4000000UL
	u8	mac_address[6];
	__le16	max_rsscos_ctx;
	__le16	max_cmpl_rings;
@@ -1208,7 +1251,8 @@ struct hwrm_func_qcfg_output {
	__le16	alloc_stat_ctx;
	__le16	alloc_msix;
	__le16	registered_vfs;
	u8	unused_1[3];
	__le16	l2_doorbell_bar_size_kb;
	u8	unused_1;
	u8	always_1;
	__le32	reset_addr_poll;
	u8	unused_2[3];
@@ -1363,7 +1407,11 @@ struct hwrm_func_qstats_input {
	__le16	target_id;
	__le64	resp_addr;
	__le16	fid;
	u8	unused_0[6];
	u8	flags;
	#define FUNC_QSTATS_REQ_FLAGS_UNUSED    0x0UL
	#define FUNC_QSTATS_REQ_FLAGS_ROCE_ONLY 0x1UL
	#define FUNC_QSTATS_REQ_FLAGS_LAST     FUNC_QSTATS_REQ_FLAGS_ROCE_ONLY
	u8	unused_0[5];
};

/* hwrm_func_qstats_output (size:1408b/176B) */
@@ -4714,7 +4762,7 @@ struct hwrm_vnic_free_output {
	u8	valid;
};

/* hwrm_vnic_cfg_input (size:320b/40B) */
/* hwrm_vnic_cfg_input (size:384b/48B) */
struct hwrm_vnic_cfg_input {
	__le16	req_type;
	__le16	cmpl_ring;
@@ -4737,6 +4785,7 @@ struct hwrm_vnic_cfg_input {
	#define VNIC_CFG_REQ_ENABLES_MRU                      0x10UL
	#define VNIC_CFG_REQ_ENABLES_DEFAULT_RX_RING_ID       0x20UL
	#define VNIC_CFG_REQ_ENABLES_DEFAULT_CMPL_RING_ID     0x40UL
	#define VNIC_CFG_REQ_ENABLES_QUEUE_ID                 0x80UL
	__le16	vnic_id;
	__le16	dflt_ring_grp;
	__le16	rss_rule;
@@ -4745,6 +4794,8 @@ struct hwrm_vnic_cfg_input {
	__le16	mru;
	__le16	default_rx_ring_id;
	__le16	default_cmpl_ring_id;
	__le16	queue_id;
	u8	unused0[6];
};

/* hwrm_vnic_cfg_output (size:128b/16B) */
@@ -4785,6 +4836,7 @@ struct hwrm_vnic_qcaps_output {
	#define VNIC_QCAPS_RESP_FLAGS_RSS_DFLT_CR_CAP                     0x20UL
	#define VNIC_QCAPS_RESP_FLAGS_ROCE_MIRRORING_CAPABLE_VNIC_CAP     0x40UL
	#define VNIC_QCAPS_RESP_FLAGS_OUTERMOST_RSS_CAP                   0x80UL
	#define VNIC_QCAPS_RESP_FLAGS_COS_ASSIGNMENT_CAP                  0x100UL
	__le16	max_aggs_supported;
	u8	unused_1[5];
	u8	valid;
@@ -6802,7 +6854,8 @@ struct hwrm_fw_reset_input {
	#define FW_RESET_REQ_EMBEDDED_PROC_TYPE_AP                    0x5UL
	#define FW_RESET_REQ_EMBEDDED_PROC_TYPE_CHIP                  0x6UL
	#define FW_RESET_REQ_EMBEDDED_PROC_TYPE_HOST_RESOURCE_REINIT  0x7UL
	#define FW_RESET_REQ_EMBEDDED_PROC_TYPE_LAST                FW_RESET_REQ_EMBEDDED_PROC_TYPE_HOST_RESOURCE_REINIT
	#define FW_RESET_REQ_EMBEDDED_PROC_TYPE_IMPACTLESS_ACTIVATION 0x8UL
	#define FW_RESET_REQ_EMBEDDED_PROC_TYPE_LAST                 FW_RESET_REQ_EMBEDDED_PROC_TYPE_IMPACTLESS_ACTIVATION
	u8	selfrst_status;
	#define FW_RESET_REQ_SELFRST_STATUS_SELFRSTNONE      0x0UL
	#define FW_RESET_REQ_SELFRST_STATUS_SELFRSTASAP      0x1UL
@@ -7125,7 +7178,14 @@ struct hwrm_temp_monitor_query_output {
	__le16	seq_id;
	__le16	resp_len;
	u8	temp;
	u8	unused_0[6];
	u8	phy_temp;
	u8	om_temp;
	u8	flags;
	#define TEMP_MONITOR_QUERY_RESP_FLAGS_TEMP_NOT_AVAILABLE         0x1UL
	#define TEMP_MONITOR_QUERY_RESP_FLAGS_PHY_TEMP_NOT_AVAILABLE     0x2UL
	#define TEMP_MONITOR_QUERY_RESP_FLAGS_OM_NOT_PRESENT             0x4UL
	#define TEMP_MONITOR_QUERY_RESP_FLAGS_OM_TEMP_NOT_AVAILABLE      0x8UL
	u8	unused_0[3];
	u8	valid;
};