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

Merge branch 'bnxt_en-fixes'



Michael Chan says:

====================
bnxt_en: Bug fixes

This series contains bug fixes for FEC reporting, ethtool self test,
multicast setup, devlink health reporting and live patching, and
a firmware response timeout.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 8940e6b6 1278d17a
Loading
Loading
Loading
Loading
+35 −12
Original line number Diff line number Diff line
@@ -4747,8 +4747,10 @@ static int bnxt_hwrm_cfa_l2_set_rx_mask(struct bnxt *bp, u16 vnic_id)
		return rc;

	req->vnic_id = cpu_to_le32(vnic->fw_vnic_id);
	if (vnic->rx_mask & CFA_L2_SET_RX_MASK_REQ_MASK_MCAST) {
		req->num_mc_entries = cpu_to_le32(vnic->mc_list_count);
		req->mc_tbl_addr = cpu_to_le64(vnic->mc_list_mapping);
	}
	req->mask = cpu_to_le32(vnic->rx_mask);
	return hwrm_req_send_silent(bp, req);
}
@@ -7787,6 +7789,19 @@ static int bnxt_map_fw_health_regs(struct bnxt *bp)
	return 0;
}

static void bnxt_remap_fw_health_regs(struct bnxt *bp)
{
	if (!bp->fw_health)
		return;

	if (bp->fw_cap & BNXT_FW_CAP_ERROR_RECOVERY) {
		bp->fw_health->status_reliable = true;
		bp->fw_health->resets_reliable = true;
	} else {
		bnxt_try_map_fw_health_reg(bp);
	}
}

static int bnxt_hwrm_error_recovery_qcfg(struct bnxt *bp)
{
	struct bnxt_fw_health *fw_health = bp->fw_health;
@@ -8639,6 +8654,9 @@ static int bnxt_init_chip(struct bnxt *bp, bool irq_re_init)
	vnic->uc_filter_count = 1;

	vnic->rx_mask = 0;
	if (test_bit(BNXT_STATE_HALF_OPEN, &bp->state))
		goto skip_rx_mask;

	if (bp->dev->flags & IFF_BROADCAST)
		vnic->rx_mask |= CFA_L2_SET_RX_MASK_REQ_MASK_BCAST;

@@ -8648,7 +8666,7 @@ static int bnxt_init_chip(struct bnxt *bp, bool irq_re_init)
	if (bp->dev->flags & IFF_ALLMULTI) {
		vnic->rx_mask |= CFA_L2_SET_RX_MASK_REQ_MASK_ALL_MCAST;
		vnic->mc_list_count = 0;
	} else {
	} else if (bp->dev->flags & IFF_MULTICAST) {
		u32 mask = 0;

		bnxt_mc_list_updated(bp, &mask);
@@ -8659,6 +8677,7 @@ static int bnxt_init_chip(struct bnxt *bp, bool irq_re_init)
	if (rc)
		goto err_out;

skip_rx_mask:
	rc = bnxt_hwrm_set_coal(bp);
	if (rc)
		netdev_warn(bp->dev, "HWRM set coalescing failure rc: %x\n",
@@ -9850,8 +9869,8 @@ static int bnxt_hwrm_if_change(struct bnxt *bp, bool up)
		resc_reinit = true;
	if (flags & FUNC_DRV_IF_CHANGE_RESP_FLAGS_HOT_FW_RESET_DONE)
		fw_reset = true;
	else if (bp->fw_health && !bp->fw_health->status_reliable)
		bnxt_try_map_fw_health_reg(bp);
	else
		bnxt_remap_fw_health_regs(bp);

	if (test_bit(BNXT_STATE_IN_FW_RESET, &bp->state) && !fw_reset) {
		netdev_err(bp->dev, "RESET_DONE not set during FW reset.\n");
@@ -10330,13 +10349,15 @@ int bnxt_half_open_nic(struct bnxt *bp)
		goto half_open_err;
	}

	rc = bnxt_alloc_mem(bp, false);
	rc = bnxt_alloc_mem(bp, true);
	if (rc) {
		netdev_err(bp->dev, "bnxt_alloc_mem err: %x\n", rc);
		goto half_open_err;
	}
	rc = bnxt_init_nic(bp, false);
	set_bit(BNXT_STATE_HALF_OPEN, &bp->state);
	rc = bnxt_init_nic(bp, true);
	if (rc) {
		clear_bit(BNXT_STATE_HALF_OPEN, &bp->state);
		netdev_err(bp->dev, "bnxt_init_nic err: %x\n", rc);
		goto half_open_err;
	}
@@ -10344,7 +10365,7 @@ int bnxt_half_open_nic(struct bnxt *bp)

half_open_err:
	bnxt_free_skbs(bp);
	bnxt_free_mem(bp, false);
	bnxt_free_mem(bp, true);
	dev_close(bp->dev);
	return rc;
}
@@ -10354,9 +10375,10 @@ int bnxt_half_open_nic(struct bnxt *bp)
 */
void bnxt_half_close_nic(struct bnxt *bp)
{
	bnxt_hwrm_resource_free(bp, false, false);
	bnxt_hwrm_resource_free(bp, false, true);
	bnxt_free_skbs(bp);
	bnxt_free_mem(bp, false);
	bnxt_free_mem(bp, true);
	clear_bit(BNXT_STATE_HALF_OPEN, &bp->state);
}

void bnxt_reenable_sriov(struct bnxt *bp)
@@ -10772,7 +10794,7 @@ static void bnxt_set_rx_mode(struct net_device *dev)
	if (dev->flags & IFF_ALLMULTI) {
		mask |= CFA_L2_SET_RX_MASK_REQ_MASK_ALL_MCAST;
		vnic->mc_list_count = 0;
	} else {
	} else if (dev->flags & IFF_MULTICAST) {
		mc_update = bnxt_mc_list_updated(bp, &mask);
	}

@@ -10849,9 +10871,10 @@ static int bnxt_cfg_rx_mode(struct bnxt *bp)
	    !bnxt_promisc_ok(bp))
		vnic->rx_mask &= ~CFA_L2_SET_RX_MASK_REQ_MASK_PROMISCUOUS;
	rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, 0);
	if (rc && vnic->mc_list_count) {
	if (rc && (vnic->rx_mask & CFA_L2_SET_RX_MASK_REQ_MASK_MCAST)) {
		netdev_info(bp->dev, "Failed setting MC filters rc: %d, turning on ALL_MCAST mode\n",
			    rc);
		vnic->rx_mask &= ~CFA_L2_SET_RX_MASK_REQ_MASK_MCAST;
		vnic->rx_mask |= CFA_L2_SET_RX_MASK_REQ_MASK_ALL_MCAST;
		vnic->mc_list_count = 0;
		rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, 0);
+1 −0
Original line number Diff line number Diff line
@@ -1921,6 +1921,7 @@ struct bnxt {
#define BNXT_STATE_RECOVER		12
#define BNXT_STATE_FW_NON_FATAL_COND	13
#define BNXT_STATE_FW_ACTIVATE_RESET	14
#define BNXT_STATE_HALF_OPEN		15	/* For offline ethtool tests */

#define BNXT_NO_FW_ACCESS(bp)					\
	(test_bit(BNXT_STATE_FW_FATAL_COND, &(bp)->state) ||	\
+31 −8
Original line number Diff line number Diff line
@@ -367,6 +367,16 @@ bnxt_dl_livepatch_report_err(struct bnxt *bp, struct netlink_ext_ack *extack,
	}
}

/* Live patch status in NVM */
#define BNXT_LIVEPATCH_NOT_INSTALLED	0
#define BNXT_LIVEPATCH_INSTALLED	FW_LIVEPATCH_QUERY_RESP_STATUS_FLAGS_INSTALL
#define BNXT_LIVEPATCH_REMOVED		FW_LIVEPATCH_QUERY_RESP_STATUS_FLAGS_ACTIVE
#define BNXT_LIVEPATCH_MASK		(FW_LIVEPATCH_QUERY_RESP_STATUS_FLAGS_INSTALL | \
					 FW_LIVEPATCH_QUERY_RESP_STATUS_FLAGS_ACTIVE)
#define BNXT_LIVEPATCH_ACTIVATED	BNXT_LIVEPATCH_MASK

#define BNXT_LIVEPATCH_STATE(flags)	((flags) & BNXT_LIVEPATCH_MASK)

static int
bnxt_dl_livepatch_activate(struct bnxt *bp, struct netlink_ext_ack *extack)
{
@@ -374,8 +384,9 @@ bnxt_dl_livepatch_activate(struct bnxt *bp, struct netlink_ext_ack *extack)
	struct hwrm_fw_livepatch_query_input *query_req;
	struct hwrm_fw_livepatch_output *patch_resp;
	struct hwrm_fw_livepatch_input *patch_req;
	u16 flags, live_patch_state;
	bool activated = false;
	u32 installed = 0;
	u16 flags;
	u8 target;
	int rc;

@@ -394,7 +405,6 @@ bnxt_dl_livepatch_activate(struct bnxt *bp, struct netlink_ext_ack *extack)
		hwrm_req_drop(bp, query_req);
		return rc;
	}
	patch_req->opcode = FW_LIVEPATCH_REQ_OPCODE_ACTIVATE;
	patch_req->loadtype = FW_LIVEPATCH_REQ_LOADTYPE_NVM_INSTALL;
	patch_resp = hwrm_req_hold(bp, patch_req);

@@ -407,12 +417,20 @@ bnxt_dl_livepatch_activate(struct bnxt *bp, struct netlink_ext_ack *extack)
		}

		flags = le16_to_cpu(query_resp->status_flags);
		if (~flags & FW_LIVEPATCH_QUERY_RESP_STATUS_FLAGS_INSTALL)
		live_patch_state = BNXT_LIVEPATCH_STATE(flags);

		if (live_patch_state == BNXT_LIVEPATCH_NOT_INSTALLED)
			continue;
		if ((flags & FW_LIVEPATCH_QUERY_RESP_STATUS_FLAGS_ACTIVE) &&
		    !strncmp(query_resp->active_ver, query_resp->install_ver,
			     sizeof(query_resp->active_ver)))

		if (live_patch_state == BNXT_LIVEPATCH_ACTIVATED) {
			activated = true;
			continue;
		}

		if (live_patch_state == BNXT_LIVEPATCH_INSTALLED)
			patch_req->opcode = FW_LIVEPATCH_REQ_OPCODE_ACTIVATE;
		else if (live_patch_state == BNXT_LIVEPATCH_REMOVED)
			patch_req->opcode = FW_LIVEPATCH_REQ_OPCODE_DEACTIVATE;

		patch_req->fw_target = target;
		rc = hwrm_req_send(bp, patch_req);
@@ -424,9 +442,14 @@ bnxt_dl_livepatch_activate(struct bnxt *bp, struct netlink_ext_ack *extack)
	}

	if (!rc && !installed) {
		if (activated) {
			NL_SET_ERR_MSG_MOD(extack, "Live patch already activated");
			rc = -EEXIST;
		} else {
			NL_SET_ERR_MSG_MOD(extack, "No live patches found");
			rc = -ENOENT;
		}
	}
	hwrm_req_drop(bp, query_req);
	hwrm_req_drop(bp, patch_req);
	return rc;
+13 −4
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
#include "bnxt_hsi.h"
#include "bnxt.h"
#include "bnxt_hwrm.h"
#include "bnxt_ulp.h"
#include "bnxt_xdp.h"
#include "bnxt_ptp.h"
#include "bnxt_ethtool.h"
@@ -1969,6 +1970,9 @@ static int bnxt_get_fecparam(struct net_device *dev,
	case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_RS272_IEEE_ACTIVE:
		fec->active_fec |= ETHTOOL_FEC_LLRS;
		break;
	case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_NONE_ACTIVE:
		fec->active_fec |= ETHTOOL_FEC_OFF;
		break;
	}
	return 0;
}
@@ -3454,7 +3458,7 @@ static int bnxt_run_loopback(struct bnxt *bp)
	if (!skb)
		return -ENOMEM;
	data = skb_put(skb, pkt_size);
	eth_broadcast_addr(data);
	ether_addr_copy(&data[i], bp->dev->dev_addr);
	i += ETH_ALEN;
	ether_addr_copy(&data[i], bp->dev->dev_addr);
	i += ETH_ALEN;
@@ -3548,9 +3552,12 @@ static void bnxt_self_test(struct net_device *dev, struct ethtool_test *etest,
	if (!offline) {
		bnxt_run_fw_tests(bp, test_mask, &test_results);
	} else {
		rc = bnxt_close_nic(bp, false, false);
		if (rc)
		bnxt_ulp_stop(bp);
		rc = bnxt_close_nic(bp, true, false);
		if (rc) {
			bnxt_ulp_start(bp, rc);
			return;
		}
		bnxt_run_fw_tests(bp, test_mask, &test_results);

		buf[BNXT_MACLPBK_TEST_IDX] = 1;
@@ -3560,6 +3567,7 @@ static void bnxt_self_test(struct net_device *dev, struct ethtool_test *etest,
		if (rc) {
			bnxt_hwrm_mac_loopback(bp, false);
			etest->flags |= ETH_TEST_FL_FAILED;
			bnxt_ulp_start(bp, rc);
			return;
		}
		if (bnxt_run_loopback(bp))
@@ -3585,7 +3593,8 @@ static void bnxt_self_test(struct net_device *dev, struct ethtool_test *etest,
		}
		bnxt_hwrm_phy_loopback(bp, false, false);
		bnxt_half_close_nic(bp);
		rc = bnxt_open_nic(bp, false, true);
		rc = bnxt_open_nic(bp, true, true);
		bnxt_ulp_start(bp, rc);
	}
	if (rc || bnxt_test_irq(bp)) {
		buf[BNXT_IRQ_TEST_IDX] = 1;
+9 −3
Original line number Diff line number Diff line
@@ -644,17 +644,23 @@ static int __hwrm_send(struct bnxt *bp, struct bnxt_hwrm_ctx *ctx)

		/* Last byte of resp contains valid bit */
		valid = ((u8 *)ctx->resp) + len - 1;
		for (j = 0; j < HWRM_VALID_BIT_DELAY_USEC; j++) {
		for (j = 0; j < HWRM_VALID_BIT_DELAY_USEC; ) {
			/* make sure we read from updated DMA memory */
			dma_rmb();
			if (*valid)
				break;
			usleep_range(1, 5);
			if (j < 10) {
				udelay(1);
				j++;
			} else {
				usleep_range(20, 30);
				j += 20;
			}
		}

		if (j >= HWRM_VALID_BIT_DELAY_USEC) {
			hwrm_err(bp, ctx, "Error (timeout: %u) msg {0x%x 0x%x} len:%d v:%d\n",
				 hwrm_total_timeout(i), req_type,
				 hwrm_total_timeout(i) + j, req_type,
				 le16_to_cpu(ctx->req->seq_id), len, *valid);
			goto exit;
		}
Loading