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

Merge branch 'bnxt_en-Updates'



Michael Chan says:

====================
bnxt_en: Updates.

This series has the firmware interface update that changes the aRFS/ntuple
interface on 57500 chips.  The 2nd patch adds a counter and improves
the hardware buffer error handling on the 57500 chips.  The rest of the
series is mainly enhancements on error recovery and firmware reset.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents c4154cff 642aebde
Loading
Loading
Loading
Loading
+34 −13
Original line number Diff line number Diff line
@@ -1767,9 +1767,13 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,

		rc = -EIO;
		if (rx_err & RX_CMPL_ERRORS_BUFFER_ERROR_MASK) {
			netdev_warn(bp->dev, "RX buffer error %x\n", rx_err);
			bnapi->cp_ring.rx_buf_errors++;
			if (!(bp->flags & BNXT_FLAG_CHIP_P5)) {
				netdev_warn(bp->dev, "RX buffer error %x\n",
					    rx_err);
				bnxt_sched_reset(bp, rxr);
			}
		}
		goto next_rx_no_len;
	}

@@ -4274,6 +4278,11 @@ static int bnxt_hwrm_do_send_msg(struct bnxt *bp, void *msg, u32 msg_len,
		/* Wait until hwrm response cmpl interrupt is processed */
		while (bp->hwrm_intr_seq_id != (u16)~seq_id &&
		       i++ < tmo_count) {
			/* Abort the wait for completion if the FW health
			 * check has failed.
			 */
			if (test_bit(BNXT_STATE_FW_FATAL_COND, &bp->state))
				return -EBUSY;
			/* on first few passes, just barely sleep */
			if (i < HWRM_SHORT_TIMEOUT_COUNTER)
				usleep_range(HWRM_SHORT_MIN_TIMEOUT,
@@ -4297,6 +4306,11 @@ static int bnxt_hwrm_do_send_msg(struct bnxt *bp, void *msg, u32 msg_len,

		/* Check if response len is updated */
		for (i = 0; i < tmo_count; i++) {
			/* Abort the wait for completion if the FW health
			 * check has failed.
			 */
			if (test_bit(BNXT_STATE_FW_FATAL_COND, &bp->state))
				return -EBUSY;
			len = (le32_to_cpu(*resp_len) & HWRM_RESP_LEN_MASK) >>
			      HWRM_RESP_LEN_SFT;
			if (len)
@@ -4437,7 +4451,8 @@ static int bnxt_hwrm_func_drv_rgtr(struct bnxt *bp)
	flags = FUNC_DRV_RGTR_REQ_FLAGS_16BIT_VER_MODE |
		FUNC_DRV_RGTR_REQ_FLAGS_HOT_RESET_SUPPORT;
	if (bp->fw_cap & BNXT_FW_CAP_ERROR_RECOVERY)
		flags |= FUNC_DRV_RGTR_REQ_FLAGS_ERROR_RECOVERY_SUPPORT;
		flags |= FUNC_DRV_RGTR_REQ_FLAGS_ERROR_RECOVERY_SUPPORT |
			 FUNC_DRV_RGTR_REQ_FLAGS_MASTER_SUPPORT;
	req.flags = cpu_to_le32(flags);
	req.ver_maj_8b = DRV_VER_MAJ;
	req.ver_min_8b = DRV_VER_MIN;
@@ -4601,21 +4616,21 @@ static int bnxt_hwrm_cfa_ntuple_filter_alloc(struct bnxt *bp,
	struct hwrm_cfa_ntuple_filter_alloc_output *resp;
	struct flow_keys *keys = &fltr->fkeys;
	struct bnxt_vnic_info *vnic;
	u32 dst_ena = 0;
	u32 flags = 0;
	int rc = 0;

	bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_CFA_NTUPLE_FILTER_ALLOC, -1, -1);
	req.l2_filter_id = bp->vnic_info[0].fw_l2_filter_id[fltr->l2_fltr_idx];

	if (bp->fw_cap & BNXT_FW_CAP_CFA_RFS_RING_TBL_IDX) {
		dst_ena = CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_RFS_RING_TBL_IDX;
		req.rfs_ring_tbl_idx = cpu_to_le16(fltr->rxq);
		vnic = &bp->vnic_info[0];
	if (bp->fw_cap & BNXT_FW_CAP_CFA_RFS_RING_TBL_IDX_V2) {
		flags = CFA_NTUPLE_FILTER_ALLOC_REQ_FLAGS_DEST_RFS_RING_IDX;
		req.dst_id = cpu_to_le16(fltr->rxq);
	} else {
		vnic = &bp->vnic_info[fltr->rxq + 1];
	}
		req.dst_id = cpu_to_le16(vnic->fw_vnic_id);
	req.enables = cpu_to_le32(BNXT_NTP_FLTR_FLAGS | dst_ena);
	}
	req.flags = cpu_to_le32(flags);
	req.enables = cpu_to_le32(BNXT_NTP_FLTR_FLAGS);

	req.ethertype = htons(ETH_P_IP);
	memcpy(req.src_macaddr, fltr->src_mac_addr, ETH_ALEN);
@@ -6943,6 +6958,8 @@ static int __bnxt_hwrm_func_qcaps(struct bnxt *bp)
		bp->flags |= BNXT_FLAG_ROCEV2_CAP;
	if (flags & FUNC_QCAPS_RESP_FLAGS_PCIE_STATS_SUPPORTED)
		bp->fw_cap |= BNXT_FW_CAP_PCIE_STATS_SUPPORTED;
	if (flags & FUNC_QCAPS_RESP_FLAGS_HOT_RESET_CAPABLE)
		bp->fw_cap |= BNXT_FW_CAP_HOT_RESET;
	if (flags & FUNC_QCAPS_RESP_FLAGS_EXT_STATS_SUPPORTED)
		bp->fw_cap |= BNXT_FW_CAP_EXT_STATS_SUPPORTED;
	if (flags &  FUNC_QCAPS_RESP_FLAGS_ERROR_RECOVERY_CAPABLE)
@@ -7042,8 +7059,8 @@ static int bnxt_hwrm_cfa_adv_flow_mgnt_qcaps(struct bnxt *bp)

	flags = le32_to_cpu(resp->flags);
	if (flags &
	    CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_RFS_RING_TBL_IDX_SUPPORTED)
		bp->fw_cap |= BNXT_FW_CAP_CFA_RFS_RING_TBL_IDX;
	    CFA_ADV_FLOW_MGNT_QCAPS_RESP_FLAGS_RFS_RING_TBL_IDX_V2_SUPPORTED)
		bp->fw_cap |= BNXT_FW_CAP_CFA_RFS_RING_TBL_IDX_V2;

hwrm_cfa_adv_qcaps_exit:
	mutex_unlock(&bp->hwrm_cmd_lock);
@@ -9693,7 +9710,7 @@ static bool bnxt_can_reserve_rings(struct bnxt *bp)
static bool bnxt_rfs_supported(struct bnxt *bp)
{
	if (bp->flags & BNXT_FLAG_CHIP_P5) {
		if (bp->fw_cap & BNXT_FW_CAP_CFA_RFS_RING_TBL_IDX)
		if (bp->fw_cap & BNXT_FW_CAP_CFA_RFS_RING_TBL_IDX_V2)
			return true;
		return false;
	}
@@ -10115,6 +10132,7 @@ static void bnxt_force_fw_reset(struct bnxt *bp)

void bnxt_fw_exception(struct bnxt *bp)
{
	netdev_warn(bp->dev, "Detected firmware fatal condition, initiating reset\n");
	set_bit(BNXT_STATE_FW_FATAL_COND, &bp->state);
	bnxt_rtnl_lock_sp(bp);
	bnxt_force_fw_reset(bp);
@@ -10743,6 +10761,7 @@ static void bnxt_fw_reset_task(struct work_struct *work)
		smp_mb__before_atomic();
		clear_bit(BNXT_STATE_IN_FW_RESET, &bp->state);
		bnxt_ulp_start(bp, rc);
		bnxt_dl_health_status_update(bp, true);
		rtnl_unlock();
		break;
	}
@@ -10750,6 +10769,8 @@ static void bnxt_fw_reset_task(struct work_struct *work)

fw_reset_abort:
	clear_bit(BNXT_STATE_IN_FW_RESET, &bp->state);
	if (bp->fw_reset_state != BNXT_FW_RESET_STATE_POLL_VF)
		bnxt_dl_health_status_update(bp, false);
	bp->fw_reset_state = 0;
	rtnl_lock();
	dev_close(bp->dev);
+6 −3
Original line number Diff line number Diff line
@@ -12,11 +12,11 @@
#define BNXT_H

#define DRV_MODULE_NAME		"bnxt_en"
#define DRV_MODULE_VERSION	"1.10.0"
#define DRV_MODULE_VERSION	"1.10.1"

#define DRV_VER_MAJ	1
#define DRV_VER_MIN	10
#define DRV_VER_UPD	0
#define DRV_VER_UPD	1

#include <linux/interrupt.h>
#include <linux/rhashtable.h>
@@ -932,6 +932,7 @@ struct bnxt_cp_ring_info {
	dma_addr_t		hw_stats_map;
	u32			hw_stats_ctx_id;
	u64			rx_l4_csum_errors;
	u64			rx_buf_errors;
	u64			missed_irqs;

	struct bnxt_ring_struct	cp_ring_struct;
@@ -1383,6 +1384,7 @@ struct bnxt_fw_health {
	u32 last_fw_reset_cnt;
	u8 enabled:1;
	u8 master:1;
	u8 fatal:1;
	u8 tmr_multiplier;
	u8 tmr_counter;
	u8 fw_reset_seq_cnt;
@@ -1666,10 +1668,11 @@ struct bnxt {
	#define BNXT_FW_CAP_ERROR_RECOVERY		0x00002000
	#define BNXT_FW_CAP_PKG_VER			0x00004000
	#define BNXT_FW_CAP_CFA_ADV_FLOW		0x00008000
	#define BNXT_FW_CAP_CFA_RFS_RING_TBL_IDX	0x00010000
	#define BNXT_FW_CAP_CFA_RFS_RING_TBL_IDX_V2	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_FW_CAP_HOT_RESET			0x00200000

#define BNXT_NEW_RM(bp)		((bp)->fw_cap & BNXT_FW_CAP_NEW_RM)
	u32			hwrm_spec_code;
+29 −1
Original line number Diff line number Diff line
@@ -91,6 +91,7 @@ static int bnxt_fw_fatal_recover(struct devlink_health_reporter *reporter,
	if (!priv_ctx)
		return -EOPNOTSUPP;

	bp->fw_health->fatal = true;
	event = fw_reporter_ctx->sp_event;
	if (event == BNXT_FW_RESET_NOTIFY_SP_EVENT)
		bnxt_fw_reset(bp);
@@ -199,6 +200,26 @@ void bnxt_devlink_health_report(struct bnxt *bp, unsigned long event)
	}
}

void bnxt_dl_health_status_update(struct bnxt *bp, bool healthy)
{
	struct bnxt_fw_health *health = bp->fw_health;
	u8 state;

	if (healthy)
		state = DEVLINK_HEALTH_REPORTER_STATE_HEALTHY;
	else
		state = DEVLINK_HEALTH_REPORTER_STATE_ERROR;

	if (health->fatal)
		devlink_health_reporter_state_update(health->fw_fatal_reporter,
						     state);
	else
		devlink_health_reporter_state_update(health->fw_reset_reporter,
						     state);

	health->fatal = false;
}

static const struct devlink_ops bnxt_dl_ops = {
#ifdef CONFIG_BNXT_SRIOV
	.eswitch_mode_set = bnxt_dl_eswitch_mode_set,
@@ -314,10 +335,17 @@ static int bnxt_hwrm_nvm_req(struct bnxt *bp, u32 param_id, void *msg,
	} else {
		rc = hwrm_send_message_silent(bp, msg, msg_len,
					      HWRM_CMD_TIMEOUT);
		if (!rc)
		if (!rc) {
			bnxt_copy_from_nvm_data(val, data,
						nvm_param.nvm_num_bits,
						nvm_param.dl_num_bytes);
		} else {
			struct hwrm_err_output *resp = bp->hwrm_cmd_resp_addr;

			if (resp->cmd_err ==
				NVM_GET_VARIABLE_CMD_ERR_CODE_VAR_NOT_EXIST)
				rc = -EOPNOTSUPP;
		}
	}
	dma_free_coherent(&bp->pdev->dev, sizeof(*data), data, data_dma_addr);
	if (rc == -EACCES)
+1 −0
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@ struct bnxt_dl_nvm_param {
};

void bnxt_devlink_health_report(struct bnxt *bp, unsigned long event);
void bnxt_dl_health_status_update(struct bnxt *bp, bool healthy);
int bnxt_dl_register(struct bnxt *bp);
void bnxt_dl_unregister(struct bnxt *bp);

+11 −3
Original line number Diff line number Diff line
@@ -173,6 +173,7 @@ static const char * const bnxt_ring_tpa2_stats_str[] = {

static const char * const bnxt_ring_sw_stats_str[] = {
	"rx_l4_csum_errors",
	"rx_buf_errors",
	"missed_irqs",
};

@@ -552,6 +553,7 @@ static void bnxt_get_ethtool_stats(struct net_device *dev,
		for (k = 0; k < stat_fields; j++, k++)
			buf[j] = le64_to_cpu(hw_stats[k]);
		buf[j++] = cpr->rx_l4_csum_errors;
		buf[j++] = cpr->rx_buf_errors;
		buf[j++] = cpr->missed_irqs;

		bnxt_sw_func_stats[RX_TOTAL_DISCARDS].counter +=
@@ -1785,6 +1787,8 @@ static int bnxt_firmware_reset(struct net_device *dev,
	case BNXT_FW_RESET_CHIP:
		req.embedded_proc_type = FW_RESET_REQ_EMBEDDED_PROC_TYPE_CHIP;
		req.selfrst_status = FW_RESET_REQ_SELFRST_STATUS_SELFRSTASAP;
		if (bp->fw_cap & BNXT_FW_CAP_HOT_RESET)
			req.flags = FW_RESET_REQ_FLAGS_RESET_GRACEFUL;
		break;
	case BNXT_FW_RESET_AP:
		req.embedded_proc_type = FW_RESET_REQ_EMBEDDED_PROC_TYPE_AP;
@@ -2981,7 +2985,8 @@ static int bnxt_reset(struct net_device *dev, u32 *flags)
		return -EOPNOTSUPP;
	}

	if (pci_vfs_assigned(bp->pdev)) {
	if (pci_vfs_assigned(bp->pdev) &&
	    !(bp->fw_cap & BNXT_FW_CAP_HOT_RESET)) {
		netdev_err(dev,
			   "Reset not allowed when VFs are assigned to VMs\n");
		return -EBUSY;
@@ -2994,7 +2999,9 @@ static int bnxt_reset(struct net_device *dev, u32 *flags)

		rc = bnxt_firmware_reset(dev, BNXT_FW_RESET_CHIP);
		if (!rc) {
			netdev_info(dev, "Reset request successful. Reload driver to complete reset\n");
			netdev_info(dev, "Reset request successful.\n");
			if (!(bp->fw_cap & BNXT_FW_CAP_HOT_RESET))
				netdev_info(dev, "Reload driver to complete reset\n");
			*flags = 0;
		}
	} else if (*flags == ETH_RESET_AP) {
@@ -3038,7 +3045,8 @@ static int bnxt_hwrm_dbg_dma_data(struct bnxt *bp, void *msg, int msg_len,
	mutex_lock(&bp->hwrm_cmd_lock);
	while (1) {
		*seq_ptr = cpu_to_le16(seq);
		rc = _hwrm_send_message(bp, msg, msg_len, HWRM_CMD_TIMEOUT);
		rc = _hwrm_send_message(bp, msg, msg_len,
					HWRM_COREDUMP_TIMEOUT);
		if (rc)
			break;

Loading