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

Merge branch 'bnxt_en-devlink'



Michael Chan says:

====================
bnxt_en: devlink enhancements

This patch series implements some devlink enhancements for bnxt_en.
They include:

1. devlink reload to reinitialize driver or to activate new firmware.
2. Support enable_remote_dev_reset to enable/disable other functions
resetting the device.
3. Consolidate and improve the health reporters.
4. Support live firmware patch.
5. Provide devlink dev info "fw" version on older firmware.

v2:
In patch 3, don't use devlink_reload_disable() and devlink_reload_enable()
which are no longer available in the latest kernel.  Instead, check that
the netdev is not in unregistered state before proceeding with reload.

In patch 14, use min_t() instead of min() to fix the mismatched type
warning.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents a812a046 eff441f3
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@ Parameters
     - Permanent
   * - ``msix_vec_per_pf_min``
     - Permanent
   * - ``enable_remote_dev_reset``
     - Runtime

The ``bnxt`` driver also implements the following driver-specific
parameters.
+1 −1
Original line number Diff line number Diff line
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_BNXT) += bnxt_en.o

bnxt_en-y := bnxt.o bnxt_hwrm.o bnxt_sriov.o bnxt_ethtool.o bnxt_dcb.o bnxt_ulp.o bnxt_xdp.o bnxt_ptp.o bnxt_vfr.o bnxt_devlink.o bnxt_dim.o
bnxt_en-y := bnxt.o bnxt_hwrm.o bnxt_sriov.o bnxt_ethtool.o bnxt_dcb.o bnxt_ulp.o bnxt_xdp.o bnxt_ptp.o bnxt_vfr.o bnxt_devlink.o bnxt_dim.o bnxt_coredump.o
bnxt_en-$(CONFIG_BNXT_FLOWER_OFFLOAD) += bnxt_tc.o
bnxt_en-$(CONFIG_DEBUG_FS) += bnxt_debugfs.o
+163 −105
Original line number Diff line number Diff line
@@ -49,8 +49,6 @@
#include <linux/log2.h>
#include <linux/aer.h>
#include <linux/bitmap.h>
#include <linux/ptp_clock_kernel.h>
#include <linux/timecounter.h>
#include <linux/cpu_rmap.h>
#include <linux/cpumask.h>
#include <net/pkt_cls.h>
@@ -85,55 +83,7 @@ MODULE_DESCRIPTION("Broadcom BCM573xx network driver");

#define BNXT_TX_PUSH_THRESH 164

enum board_idx {
	BCM57301,
	BCM57302,
	BCM57304,
	BCM57417_NPAR,
	BCM58700,
	BCM57311,
	BCM57312,
	BCM57402,
	BCM57404,
	BCM57406,
	BCM57402_NPAR,
	BCM57407,
	BCM57412,
	BCM57414,
	BCM57416,
	BCM57417,
	BCM57412_NPAR,
	BCM57314,
	BCM57417_SFP,
	BCM57416_SFP,
	BCM57404_NPAR,
	BCM57406_NPAR,
	BCM57407_SFP,
	BCM57407_NPAR,
	BCM57414_NPAR,
	BCM57416_NPAR,
	BCM57452,
	BCM57454,
	BCM5745x_NPAR,
	BCM57508,
	BCM57504,
	BCM57502,
	BCM57508_NPAR,
	BCM57504_NPAR,
	BCM57502_NPAR,
	BCM58802,
	BCM58804,
	BCM58808,
	NETXTREME_E_VF,
	NETXTREME_C_VF,
	NETXTREME_S_VF,
	NETXTREME_C_VF_HV,
	NETXTREME_E_VF_HV,
	NETXTREME_E_P5_VF,
	NETXTREME_E_P5_VF_HV,
};

/* indexed by enum above */
/* indexed by enum board_idx */
static const struct {
	char *name;
} board_info[] = {
@@ -2172,7 +2122,7 @@ static int bnxt_async_event_process(struct bnxt *bp,
		set_bit(BNXT_RESET_TASK_SILENT_SP_EVENT, &bp->sp_event);
		break;
	case ASYNC_EVENT_CMPL_EVENT_ID_RESET_NOTIFY: {
		char *fatal_str = "non-fatal";
		char *type_str = "Solicited";

		if (!bp->fw_health)
			goto async_event_process_exit;
@@ -2184,13 +2134,21 @@ static int bnxt_async_event_process(struct bnxt *bp,
		bp->fw_reset_max_dsecs = le16_to_cpu(cmpl->timestamp_hi);
		if (!bp->fw_reset_max_dsecs)
			bp->fw_reset_max_dsecs = BNXT_DFLT_FW_RST_MAX_DSECS;
		if (EVENT_DATA1_RESET_NOTIFY_FATAL(data1)) {
			fatal_str = "fatal";
		if (EVENT_DATA1_RESET_NOTIFY_FW_ACTIVATION(data1)) {
			set_bit(BNXT_STATE_FW_ACTIVATE_RESET, &bp->state);
		} else if (EVENT_DATA1_RESET_NOTIFY_FATAL(data1)) {
			type_str = "Fatal";
			bp->fw_health->fatalities++;
			set_bit(BNXT_STATE_FW_FATAL_COND, &bp->state);
		} else if (data2 && BNXT_FW_STATUS_HEALTHY !=
			   EVENT_DATA2_RESET_NOTIFY_FW_STATUS_CODE(data2)) {
			type_str = "Non-fatal";
			bp->fw_health->survivals++;
			set_bit(BNXT_STATE_FW_NON_FATAL_COND, &bp->state);
		}
		netif_warn(bp, hw, bp->dev,
			   "Firmware %s reset event, data1: 0x%x, data2: 0x%x, min wait %u ms, max wait %u ms\n",
			   fatal_str, data1, data2,
			   "%s firmware reset event, data1: 0x%x, data2: 0x%x, min wait %u ms, max wait %u ms\n",
			   type_str, data1, data2,
			   bp->fw_reset_min_dsecs * 100,
			   bp->fw_reset_max_dsecs * 100);
		set_bit(BNXT_FW_RESET_NOTIFY_SP_EVENT, &bp->sp_event);
@@ -2198,17 +2156,18 @@ static int bnxt_async_event_process(struct bnxt *bp,
	}
	case ASYNC_EVENT_CMPL_EVENT_ID_ERROR_RECOVERY: {
		struct bnxt_fw_health *fw_health = bp->fw_health;
		char *status_desc = "healthy";
		u32 status;

		if (!fw_health)
			goto async_event_process_exit;

		if (!EVENT_DATA1_RECOVERY_ENABLED(data1)) {
			fw_health->enabled = false;
			netif_info(bp, drv, bp->dev,
				   "Error recovery info: error recovery[0]\n");
			netif_info(bp, drv, bp->dev, "Driver recovery watchdog is disabled\n");
			break;
		}
		fw_health->master = EVENT_DATA1_RECOVERY_MASTER_FUNC(data1);
		fw_health->primary = EVENT_DATA1_RECOVERY_MASTER_FUNC(data1);
		fw_health->tmr_multiplier =
			DIV_ROUND_UP(fw_health->polling_dsecs * HZ,
				     bp->current_interval * 10);
@@ -2218,10 +2177,13 @@ static int bnxt_async_event_process(struct bnxt *bp,
				bnxt_fw_health_readl(bp, BNXT_FW_HEARTBEAT_REG);
		fw_health->last_fw_reset_cnt =
			bnxt_fw_health_readl(bp, BNXT_FW_RESET_CNT_REG);
		status = bnxt_fw_health_readl(bp, BNXT_FW_HEALTH_REG);
		if (status != BNXT_FW_STATUS_HEALTHY)
			status_desc = "unhealthy";
		netif_info(bp, drv, bp->dev,
			   "Error recovery info: error recovery[1], master[%d], reset count[%u], health status: 0x%x\n",
			   fw_health->master, fw_health->last_fw_reset_cnt,
			   bnxt_fw_health_readl(bp, BNXT_FW_HEALTH_REG));
			   "Driver recovery watchdog, role: %s, firmware status: 0x%x (%s), resets: %u\n",
			   fw_health->primary ? "primary" : "backup", status,
			   status_desc, fw_health->last_fw_reset_cnt);
		if (!fw_health->enabled) {
			/* Make sure tmr_counter is set and visible to
			 * bnxt_health_check() before setting enabled to true.
@@ -4651,7 +4613,7 @@ int bnxt_hwrm_func_drv_rgtr(struct bnxt *bp, unsigned long *bmap, int bmap_size,
	return rc;
}

static int bnxt_hwrm_func_drv_unrgtr(struct bnxt *bp)
int bnxt_hwrm_func_drv_unrgtr(struct bnxt *bp)
{
	struct hwrm_func_drv_unrgtr_input *req;
	int rc;
@@ -7192,7 +7154,7 @@ static void bnxt_free_ctx_pg_tbls(struct bnxt *bp,
	ctx_pg->nr_pages = 0;
}

static void bnxt_free_ctx_mem(struct bnxt *bp)
void bnxt_free_ctx_mem(struct bnxt *bp)
{
	struct bnxt_ctx_mem_info *ctx = bp->ctx;
	int i;
@@ -7518,12 +7480,18 @@ static int __bnxt_hwrm_func_qcaps(struct bnxt *bp)
		bp->fw_cap |= BNXT_FW_CAP_ERR_RECOVER_RELOAD;
	if (!(flags & FUNC_QCAPS_RESP_FLAGS_VLAN_ACCELERATION_TX_DISABLED))
		bp->fw_cap |= BNXT_FW_CAP_VLAN_TX_INSERT;
	if (flags & FUNC_QCAPS_RESP_FLAGS_DBG_QCAPS_CMD_SUPPORTED)
		bp->fw_cap |= BNXT_FW_CAP_DBG_QCAPS;

	flags_ext = le32_to_cpu(resp->flags_ext);
	if (flags_ext & FUNC_QCAPS_RESP_FLAGS_EXT_EXT_HW_STATS_SUPPORTED)
		bp->fw_cap |= BNXT_FW_CAP_EXT_HW_STATS_SUPPORTED;
	if (BNXT_PF(bp) && (flags_ext & FUNC_QCAPS_RESP_FLAGS_EXT_PTP_PPS_SUPPORTED))
		bp->fw_cap |= BNXT_FW_CAP_PTP_PPS;
	if (BNXT_PF(bp) && (flags_ext & FUNC_QCAPS_RESP_FLAGS_EXT_HOT_RESET_IF_SUPPORT))
		bp->fw_cap |= BNXT_FW_CAP_HOT_RESET_IF;
	if (BNXT_PF(bp) && (flags_ext & FUNC_QCAPS_RESP_FLAGS_EXT_FW_LIVEPATCH_SUPPORTED))
		bp->fw_cap |= BNXT_FW_CAP_LIVEPATCH;

	bp->tx_push_thresh = 0;
	if ((flags & FUNC_QCAPS_RESP_FLAGS_PUSH_MODE_SUPPORTED) &&
@@ -7579,6 +7547,32 @@ static int __bnxt_hwrm_func_qcaps(struct bnxt *bp)
	return rc;
}

static void bnxt_hwrm_dbg_qcaps(struct bnxt *bp)
{
	struct hwrm_dbg_qcaps_output *resp;
	struct hwrm_dbg_qcaps_input *req;
	int rc;

	bp->fw_dbg_cap = 0;
	if (!(bp->fw_cap & BNXT_FW_CAP_DBG_QCAPS))
		return;

	rc = hwrm_req_init(bp, req, HWRM_DBG_QCAPS);
	if (rc)
		return;

	req->fid = cpu_to_le16(0xffff);
	resp = hwrm_req_hold(bp, req);
	rc = hwrm_req_send(bp, req);
	if (rc)
		goto hwrm_dbg_qcaps_exit;

	bp->fw_dbg_cap = le32_to_cpu(resp->flags);

hwrm_dbg_qcaps_exit:
	hwrm_req_drop(bp, req);
}

static int bnxt_hwrm_queue_qportcfg(struct bnxt *bp);

static int bnxt_hwrm_func_qcaps(struct bnxt *bp)
@@ -7588,6 +7582,9 @@ static int bnxt_hwrm_func_qcaps(struct bnxt *bp)
	rc = __bnxt_hwrm_func_qcaps(bp);
	if (rc)
		return rc;

	bnxt_hwrm_dbg_qcaps(bp);

	rc = bnxt_hwrm_queue_qportcfg(bp);
	if (rc) {
		netdev_err(bp->dev, "hwrm query qportcfg failure rc: %d\n", rc);
@@ -7642,6 +7639,7 @@ static int __bnxt_alloc_fw_health(struct bnxt *bp)
	if (!bp->fw_health)
		return -ENOMEM;

	mutex_init(&bp->fw_health->lock);
	return 0;
}

@@ -7688,12 +7686,16 @@ static void bnxt_inv_fw_health_reg(struct bnxt *bp)
	struct bnxt_fw_health *fw_health = bp->fw_health;
	u32 reg_type;

	if (!fw_health || !fw_health->status_reliable)
	if (!fw_health)
		return;

	reg_type = BNXT_FW_HEALTH_REG_TYPE(fw_health->regs[BNXT_FW_HEALTH_REG]);
	if (reg_type == BNXT_FW_HEALTH_REG_TYPE_GRC)
		fw_health->status_reliable = false;

	reg_type = BNXT_FW_HEALTH_REG_TYPE(fw_health->regs[BNXT_FW_RESET_CNT_REG]);
	if (reg_type == BNXT_FW_HEALTH_REG_TYPE_GRC)
		fw_health->resets_reliable = false;
}

static void bnxt_try_map_fw_health_reg(struct bnxt *bp)
@@ -7750,6 +7752,7 @@ static int bnxt_map_fw_health_regs(struct bnxt *bp)
	int i;

	bp->fw_health->status_reliable = false;
	bp->fw_health->resets_reliable = false;
	/* Only pre-map the monitoring GRC registers using window 3 */
	for (i = 0; i < 4; i++) {
		u32 reg = fw_health->regs[i];
@@ -7763,6 +7766,7 @@ static int bnxt_map_fw_health_regs(struct bnxt *bp)
		fw_health->mapped_regs[i] = BNXT_FW_HEALTH_WIN_OFF(reg);
	}
	bp->fw_health->status_reliable = true;
	bp->fw_health->resets_reliable = true;
	if (reg_base == 0xffffffff)
		return 0;

@@ -8208,6 +8212,10 @@ static int bnxt_hwrm_port_qstats_ext(struct bnxt *bp, u8 flags)
	if (!rc) {
		bp->fw_rx_stats_ext_size =
			le16_to_cpu(resp_qs->rx_stat_size) / 8;
		if (BNXT_FW_MAJ(bp) < 220 &&
		    bp->fw_rx_stats_ext_size > BNXT_RX_STATS_EXT_NUM_LEGACY)
			bp->fw_rx_stats_ext_size = BNXT_RX_STATS_EXT_NUM_LEGACY;

		bp->fw_tx_stats_ext_size = tx_stat_size ?
			le16_to_cpu(resp_qs->tx_stat_size) / 8 : 0;
	} else {
@@ -9246,7 +9254,7 @@ static char *bnxt_report_fec(struct bnxt_link_info *link_info)
	}
}

static void bnxt_report_link(struct bnxt *bp)
void bnxt_report_link(struct bnxt *bp)
{
	if (bp->link_info.link_up) {
		const char *signal = "";
@@ -9691,8 +9699,6 @@ static int bnxt_hwrm_shutdown_link(struct bnxt *bp)
	return hwrm_req_send(bp, req);
}

static int bnxt_fw_init_one(struct bnxt *bp);

static int bnxt_fw_reset_via_optee(struct bnxt *bp)
{
#ifdef CONFIG_TEE_BNXT_FW
@@ -9739,6 +9745,33 @@ static int bnxt_try_recover_fw(struct bnxt *bp)
	return -ENODEV;
}

int bnxt_cancel_reservations(struct bnxt *bp, bool fw_reset)
{
	struct bnxt_hw_resc *hw_resc = &bp->hw_resc;
	int rc;

	if (!BNXT_NEW_RM(bp))
		return 0; /* no resource reservations required */

	rc = bnxt_hwrm_func_resc_qcaps(bp, true);
	if (rc)
		netdev_err(bp->dev, "resc_qcaps failed\n");

	hw_resc->resv_cp_rings = 0;
	hw_resc->resv_stat_ctxs = 0;
	hw_resc->resv_irqs = 0;
	hw_resc->resv_tx_rings = 0;
	hw_resc->resv_rx_rings = 0;
	hw_resc->resv_hw_ring_grps = 0;
	hw_resc->resv_vnics = 0;
	if (!fw_reset) {
		bp->tx_nr_rings = 0;
		bp->rx_nr_rings = 0;
	}

	return rc;
}

static int bnxt_hwrm_if_change(struct bnxt *bp, bool up)
{
	struct hwrm_func_drv_if_change_output *resp;
@@ -9822,25 +9855,7 @@ static int bnxt_hwrm_if_change(struct bnxt *bp, bool up)
				return rc;
			}
		}
		if (BNXT_NEW_RM(bp)) {
			struct bnxt_hw_resc *hw_resc = &bp->hw_resc;

			rc = bnxt_hwrm_func_resc_qcaps(bp, true);
			if (rc)
				netdev_err(bp->dev, "resc_qcaps failed\n");

			hw_resc->resv_cp_rings = 0;
			hw_resc->resv_stat_ctxs = 0;
			hw_resc->resv_irqs = 0;
			hw_resc->resv_tx_rings = 0;
			hw_resc->resv_rx_rings = 0;
			hw_resc->resv_hw_ring_grps = 0;
			hw_resc->resv_vnics = 0;
			if (!fw_reset) {
				bp->tx_nr_rings = 0;
				bp->rx_nr_rings = 0;
			}
		}
		rc = bnxt_cancel_reservations(bp, fw_reset);
	}
	return rc;
}
@@ -10318,7 +10333,7 @@ void bnxt_half_close_nic(struct bnxt *bp)
	bnxt_free_mem(bp, false);
}

static void bnxt_reenable_sriov(struct bnxt *bp)
void bnxt_reenable_sriov(struct bnxt *bp)
{
	if (BNXT_PF(bp)) {
		struct bnxt_pf_info *pf = &bp->pf;
@@ -11295,14 +11310,18 @@ static void bnxt_fw_health_check(struct bnxt *bp)
	}

	val = bnxt_fw_health_readl(bp, BNXT_FW_HEARTBEAT_REG);
	if (val == fw_health->last_fw_heartbeat)
	if (val == fw_health->last_fw_heartbeat) {
		fw_health->arrests++;
		goto fw_reset;
	}

	fw_health->last_fw_heartbeat = val;

	val = bnxt_fw_health_readl(bp, BNXT_FW_RESET_CNT_REG);
	if (val != fw_health->last_fw_reset_cnt)
	if (val != fw_health->last_fw_reset_cnt) {
		fw_health->discoveries++;
		goto fw_reset;
	}

	fw_health->tmr_counter = fw_health->tmr_multiplier;
	return;
@@ -11508,7 +11527,7 @@ static void bnxt_force_fw_reset(struct bnxt *bp)
	}
	bnxt_fw_reset_close(bp);
	wait_dsecs = fw_health->master_func_wait_dsecs;
	if (fw_health->master) {
	if (fw_health->primary) {
		if (fw_health->flags & ERROR_RECOVERY_QCFG_RESP_FLAGS_CO_CPU)
			wait_dsecs = 0;
		bp->fw_reset_state = BNXT_FW_RESET_STATE_RESET_FW;
@@ -11772,13 +11791,17 @@ static void bnxt_sp_task(struct work_struct *work)
	if (test_and_clear_bit(BNXT_RST_RING_SP_EVENT, &bp->sp_event))
		bnxt_rx_ring_reset(bp);

	if (test_and_clear_bit(BNXT_FW_RESET_NOTIFY_SP_EVENT, &bp->sp_event))
		bnxt_devlink_health_report(bp, BNXT_FW_RESET_NOTIFY_SP_EVENT);
	if (test_and_clear_bit(BNXT_FW_RESET_NOTIFY_SP_EVENT, &bp->sp_event)) {
		if (test_bit(BNXT_STATE_FW_FATAL_COND, &bp->state) ||
		    test_bit(BNXT_STATE_FW_NON_FATAL_COND, &bp->state))
			bnxt_devlink_health_fw_report(bp);
		else
			bnxt_fw_reset(bp);
	}

	if (test_and_clear_bit(BNXT_FW_EXCEPTION_SP_EVENT, &bp->sp_event)) {
		if (!is_bnxt_fw_ok(bp))
			bnxt_devlink_health_report(bp,
						   BNXT_FW_EXCEPTION_SP_EVENT);
			bnxt_devlink_health_fw_report(bp);
	}

	smp_mb__before_atomic();
@@ -11989,7 +12012,7 @@ static void bnxt_fw_init_one_p3(struct bnxt *bp)

static int bnxt_probe_phy(struct bnxt *bp, bool fw_dflt);

static int bnxt_fw_init_one(struct bnxt *bp)
int bnxt_fw_init_one(struct bnxt *bp)
{
	int rc;

@@ -12051,6 +12074,27 @@ static void bnxt_fw_reset_writel(struct bnxt *bp, int reg_idx)
	}
}

bool bnxt_hwrm_reset_permitted(struct bnxt *bp)
{
	struct hwrm_func_qcfg_output *resp;
	struct hwrm_func_qcfg_input *req;
	bool result = true; /* firmware will enforce if unknown */

	if (~bp->fw_cap & BNXT_FW_CAP_HOT_RESET_IF)
		return result;

	if (hwrm_req_init(bp, req, HWRM_FUNC_QCFG))
		return result;

	req->fid = cpu_to_le16(0xffff);
	resp = hwrm_req_hold(bp, req);
	if (!hwrm_req_send(bp, req))
		result = !!(le16_to_cpu(resp->flags) &
			    FUNC_QCFG_RESP_FLAGS_HOT_RESET_ALLOWED);
	hwrm_req_drop(bp, req);
	return result;
}

static void bnxt_reset_all(struct bnxt *bp)
{
	struct bnxt_fw_health *fw_health = bp->fw_health;
@@ -12093,7 +12137,7 @@ static void bnxt_fw_reset_abort(struct bnxt *bp, int rc)
	clear_bit(BNXT_STATE_IN_FW_RESET, &bp->state);
	if (bp->fw_reset_state != BNXT_FW_RESET_STATE_POLL_VF) {
		bnxt_ulp_start(bp, rc);
		bnxt_dl_health_status_update(bp, false);
		bnxt_dl_health_fw_status_update(bp, false);
	}
	bp->fw_reset_state = 0;
	dev_close(bp->dev);
@@ -12159,7 +12203,7 @@ static void bnxt_fw_reset_task(struct work_struct *work)
			return;
		}

		if (!bp->fw_health->master) {
		if (!bp->fw_health->primary) {
			u32 wait_dsecs = bp->fw_health->normal_func_wait_dsecs;

			bp->fw_reset_state = BNXT_FW_RESET_STATE_ENABLE_DEV;
@@ -12192,6 +12236,10 @@ static void bnxt_fw_reset_task(struct work_struct *work)
			}
		}
		clear_bit(BNXT_STATE_FW_FATAL_COND, &bp->state);
		clear_bit(BNXT_STATE_FW_NON_FATAL_COND, &bp->state);
		if (test_and_clear_bit(BNXT_STATE_FW_ACTIVATE_RESET, &bp->state) &&
		    !test_bit(BNXT_STATE_FW_ACTIVATE, &bp->state))
			bnxt_dl_remote_reload(bp);
		if (pci_enable_device(bp->pdev)) {
			netdev_err(bp->dev, "Cannot re-enable PCI device\n");
			rc = -ENODEV;
@@ -12241,8 +12289,11 @@ static void bnxt_fw_reset_task(struct work_struct *work)
		bnxt_vf_reps_alloc(bp);
		bnxt_vf_reps_open(bp);
		bnxt_ptp_reapply_pps(bp);
		bnxt_dl_health_recovery_done(bp);
		bnxt_dl_health_status_update(bp, true);
		clear_bit(BNXT_STATE_FW_ACTIVATE, &bp->state);
		if (test_and_clear_bit(BNXT_STATE_RECOVER, &bp->state)) {
			bnxt_dl_health_fw_recovery_done(bp);
			bnxt_dl_health_fw_status_update(bp, true);
		}
		rtnl_unlock();
		break;
	}
@@ -13186,6 +13237,15 @@ static int bnxt_map_db_bar(struct bnxt *bp)
	return 0;
}

void bnxt_print_device_info(struct bnxt *bp)
{
	netdev_info(bp->dev, "%s found at mem %lx, node addr %pM\n",
		    board_info[bp->board_idx].name,
		    (long)pci_resource_start(bp->pdev, 0), bp->dev->dev_addr);

	pcie_print_link_status(bp->pdev);
}

static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
	struct net_device *dev;
@@ -13209,10 +13269,11 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
		return -ENOMEM;

	bp = netdev_priv(dev);
	bp->board_idx = ent->driver_data;
	bp->msg_enable = BNXT_DEF_MSG_ENABLE;
	bnxt_set_max_func_irqs(bp, max_irqs);

	if (bnxt_vf_pciid(ent->driver_data))
	if (bnxt_vf_pciid(bp->board_idx))
		bp->flags |= BNXT_FLAG_VF;

	if (pdev->msix_cap)
@@ -13382,10 +13443,7 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
		devlink_port_type_eth_set(&bp->dl_port, bp->dev);
	bnxt_dl_fw_reporters_create(bp);

	netdev_info(dev, "%s found at mem %lx, node addr %pM\n",
		    board_info[ent->driver_data].name,
		    (long)pci_resource_start(pdev, 0), dev->dev_addr);
	pcie_print_link_status(pdev);
	bnxt_print_device_info(bp);

	pci_save_state(pdev);
	return 0;
+104 −9
Original line number Diff line number Diff line
@@ -489,6 +489,15 @@ struct rx_tpa_end_cmp_ext {
	  ASYNC_EVENT_CMPL_RESET_NOTIFY_EVENT_DATA1_REASON_CODE_MASK) ==\
	 ASYNC_EVENT_CMPL_RESET_NOTIFY_EVENT_DATA1_REASON_CODE_FW_EXCEPTION_FATAL)

#define EVENT_DATA1_RESET_NOTIFY_FW_ACTIVATION(data1)			\
	(((data1) &							\
	  ASYNC_EVENT_CMPL_RESET_NOTIFY_EVENT_DATA1_REASON_CODE_MASK) ==\
	ASYNC_EVENT_CMPL_RESET_NOTIFY_EVENT_DATA1_REASON_CODE_FW_ACTIVATION)

#define EVENT_DATA2_RESET_NOTIFY_FW_STATUS_CODE(data2)			\
	((data2) &							\
	ASYNC_EVENT_CMPL_RESET_NOTIFY_EVENT_DATA2_FW_STATUS_CODE_MASK)

#define EVENT_DATA1_RECOVERY_MASTER_FUNC(data1)				\
	!!((data1) &							\
	   ASYNC_EVENT_CMPL_ERROR_RECOVERY_EVENT_DATA1_FLAGS_MASTER_FUNC)
@@ -1514,6 +1523,21 @@ struct bnxt_ctx_mem_info {
	struct bnxt_mem_init	mem_init[BNXT_CTX_MEM_INIT_MAX];
};

enum bnxt_health_severity {
	SEVERITY_NORMAL = 0,
	SEVERITY_WARNING,
	SEVERITY_RECOVERABLE,
	SEVERITY_FATAL,
};

enum bnxt_health_remedy {
	REMEDY_DEVLINK_RECOVER,
	REMEDY_POWER_CYCLE_DEVICE,
	REMEDY_POWER_CYCLE_HOST,
	REMEDY_FW_UPDATE,
	REMEDY_HW_REPLACE,
};

struct bnxt_fw_health {
	u32 flags;
	u32 polling_dsecs;
@@ -1531,9 +1555,9 @@ struct bnxt_fw_health {
	u32 last_fw_heartbeat;
	u32 last_fw_reset_cnt;
	u8 enabled:1;
	u8 master:1;
	u8 fatal:1;
	u8 primary:1;
	u8 status_reliable:1;
	u8 resets_reliable:1;
	u8 tmr_multiplier;
	u8 tmr_counter;
	u8 fw_reset_seq_cnt;
@@ -1543,12 +1567,15 @@ struct bnxt_fw_health {
	u32 echo_req_data1;
	u32 echo_req_data2;
	struct devlink_health_reporter	*fw_reporter;
	struct devlink_health_reporter *fw_reset_reporter;
	struct devlink_health_reporter *fw_fatal_reporter;
};

struct bnxt_fw_reporter_ctx {
	unsigned long sp_event;
	/* Protects severity and remedy */
	struct mutex lock;
	enum bnxt_health_severity severity;
	enum bnxt_health_remedy remedy;
	u32 arrests;
	u32 discoveries;
	u32 survivals;
	u32 fatalities;
	u32 diagnoses;
};

#define BNXT_FW_HEALTH_REG_TYPE_MASK	3
@@ -1586,6 +1613,54 @@ struct bnxt_fw_reporter_ctx {
#define BNXT_FW_RETRY			5
#define BNXT_FW_IF_RETRY		10

enum board_idx {
	BCM57301,
	BCM57302,
	BCM57304,
	BCM57417_NPAR,
	BCM58700,
	BCM57311,
	BCM57312,
	BCM57402,
	BCM57404,
	BCM57406,
	BCM57402_NPAR,
	BCM57407,
	BCM57412,
	BCM57414,
	BCM57416,
	BCM57417,
	BCM57412_NPAR,
	BCM57314,
	BCM57417_SFP,
	BCM57416_SFP,
	BCM57404_NPAR,
	BCM57406_NPAR,
	BCM57407_SFP,
	BCM57407_NPAR,
	BCM57414_NPAR,
	BCM57416_NPAR,
	BCM57452,
	BCM57454,
	BCM5745x_NPAR,
	BCM57508,
	BCM57504,
	BCM57502,
	BCM57508_NPAR,
	BCM57504_NPAR,
	BCM57502_NPAR,
	BCM58802,
	BCM58804,
	BCM58808,
	NETXTREME_E_VF,
	NETXTREME_C_VF,
	NETXTREME_S_VF,
	NETXTREME_C_VF_HV,
	NETXTREME_E_VF_HV,
	NETXTREME_E_P5_VF,
	NETXTREME_E_P5_VF_HV,
};

struct bnxt {
	void __iomem		*bar0;
	void __iomem		*bar1;
@@ -1840,6 +1915,10 @@ struct bnxt {
#define BNXT_STATE_DRV_REGISTERED	7
#define BNXT_STATE_PCI_CHANNEL_IO_FROZEN	8
#define BNXT_STATE_NAPI_DISABLED	9
#define BNXT_STATE_FW_ACTIVATE		11
#define BNXT_STATE_RECOVER		12
#define BNXT_STATE_FW_NON_FATAL_COND	13
#define BNXT_STATE_FW_ACTIVATE_RESET	14

#define BNXT_NO_FW_ACCESS(bp)					\
	(test_bit(BNXT_STATE_FW_FATAL_COND, &(bp)->state) ||	\
@@ -1879,8 +1958,13 @@ struct bnxt {
	#define BNXT_FW_CAP_VLAN_RX_STRIP		0x01000000
	#define BNXT_FW_CAP_VLAN_TX_INSERT		0x02000000
	#define BNXT_FW_CAP_EXT_HW_STATS_SUPPORTED	0x04000000
	#define BNXT_FW_CAP_LIVEPATCH			0x08000000
	#define BNXT_FW_CAP_PTP_PPS			0x10000000
	#define BNXT_FW_CAP_HOT_RESET_IF		0x20000000
	#define BNXT_FW_CAP_RING_MONITOR		0x40000000
	#define BNXT_FW_CAP_DBG_QCAPS			0x80000000

	u32			fw_dbg_cap;

#define BNXT_NEW_RM(bp)		((bp)->fw_cap & BNXT_FW_CAP_NEW_RM)
	u32			hwrm_spec_code;
@@ -2049,6 +2133,7 @@ struct bnxt {
	struct list_head	tc_indr_block_list;
	struct dentry		*debugfs_pdev;
	struct device		*hwmon_dev;
	enum board_idx		board_idx;
};

#define BNXT_NUM_RX_RING_STATS			8
@@ -2090,6 +2175,9 @@ struct bnxt {
#define BNXT_RX_STATS_EXT_OFFSET(counter)		\
	(offsetof(struct rx_port_stats_ext, counter) / 8)

#define BNXT_RX_STATS_EXT_NUM_LEGACY                   \
	BNXT_RX_STATS_EXT_OFFSET(rx_fec_corrected_blocks)

#define BNXT_TX_STATS_EXT_OFFSET(counter)		\
	(offsetof(struct tx_port_stats_ext, counter) / 8)

@@ -2181,11 +2269,13 @@ void bnxt_set_ring_params(struct bnxt *);
int bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode);
int bnxt_hwrm_func_drv_rgtr(struct bnxt *bp, unsigned long *bmap,
			    int bmap_size, bool async_only);
int bnxt_hwrm_func_drv_unrgtr(struct bnxt *bp);
int bnxt_get_nr_rss_ctxs(struct bnxt *bp, int rx_rings);
int bnxt_hwrm_vnic_cfg(struct bnxt *bp, u16 vnic_id);
int __bnxt_hwrm_get_tx_rings(struct bnxt *bp, u16 fid, int *tx_rings);
int bnxt_nq_rings_in_use(struct bnxt *bp);
int bnxt_hwrm_set_coal(struct bnxt *);
void bnxt_free_ctx_mem(struct bnxt *bp);
unsigned int bnxt_get_max_func_stat_ctxs(struct bnxt *bp);
unsigned int bnxt_get_avail_stat_ctxs_for_en(struct bnxt *bp);
unsigned int bnxt_get_max_func_cp_rings(struct bnxt *bp);
@@ -2194,9 +2284,11 @@ int bnxt_get_avail_msix(struct bnxt *bp, int num);
int bnxt_reserve_rings(struct bnxt *bp, bool irq_re_init);
void bnxt_tx_disable(struct bnxt *bp);
void bnxt_tx_enable(struct bnxt *bp);
void bnxt_report_link(struct bnxt *bp);
int bnxt_update_link(struct bnxt *bp, bool chng_link_state);
int bnxt_hwrm_set_pause(struct bnxt *);
int bnxt_hwrm_set_link_setting(struct bnxt *, bool, bool);
int bnxt_cancel_reservations(struct bnxt *bp, bool fw_reset);
int bnxt_hwrm_alloc_wol_fltr(struct bnxt *bp);
int bnxt_hwrm_free_wol_fltr(struct bnxt *bp);
int bnxt_hwrm_func_resc_qcaps(struct bnxt *bp, bool all);
@@ -2205,6 +2297,7 @@ int bnxt_hwrm_fw_set_time(struct bnxt *);
int bnxt_open_nic(struct bnxt *, bool, bool);
int bnxt_half_open_nic(struct bnxt *bp);
void bnxt_half_close_nic(struct bnxt *bp);
void bnxt_reenable_sriov(struct bnxt *bp);
int bnxt_close_nic(struct bnxt *, bool, bool);
int bnxt_dbg_hwrm_rd_reg(struct bnxt *bp, u32 reg_off, u16 num_words,
			 u32 *reg_buf);
@@ -2212,6 +2305,8 @@ void bnxt_fw_exception(struct bnxt *bp);
void bnxt_fw_reset(struct bnxt *bp);
int bnxt_check_rings(struct bnxt *bp, int tx, int rx, bool sh, int tcs,
		     int tx_xdp);
int bnxt_fw_init_one(struct bnxt *bp);
bool bnxt_hwrm_reset_permitted(struct bnxt *bp);
int bnxt_setup_mq_tc(struct net_device *dev, u8 tc);
int bnxt_get_max_rings(struct bnxt *, int *, int *, bool);
int bnxt_restore_pf_fw_resources(struct bnxt *bp);
@@ -2219,5 +2314,5 @@ int bnxt_get_port_parent_id(struct net_device *dev,
			    struct netdev_phys_item_id *ppid);
void bnxt_dim_work(struct work_struct *work);
int bnxt_hwrm_set_ring_coal(struct bnxt *bp, struct bnxt_napi *bnapi);

void bnxt_print_device_info(struct bnxt *bp);
#endif
+444 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading