drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
Extension
.c
Size
36760 bytes
Lines
1332
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (!h->severity) {
			h->severity = SEVERITY_FATAL;
			h->remedy = REMEDY_POWER_CYCLE_DEVICE;
			h->diagnoses++;
			devlink_health_report(h->fw_reporter,
					      "FW error diagnosed", h);
		}
		devlink_fmsg_string_pair_put(fmsg, "Status", "error");
		devlink_fmsg_u32_pair_put(fmsg, "Syndrome", fw_status);
	} else {
		devlink_fmsg_string_pair_put(fmsg, "Status", "healthy");
	}

	devlink_fmsg_string_pair_put(fmsg, "Severity",
				     bnxt_health_severity_str(h->severity));

	if (h->severity) {
		devlink_fmsg_string_pair_put(fmsg, "Remedy",
					     bnxt_health_remedy_str(h->remedy));
		if (h->remedy == REMEDY_DEVLINK_RECOVER)
			devlink_fmsg_string_pair_put(fmsg, "Impact",
						     "traffic+ntuple_cfg");
	}

	mutex_unlock(&h->lock);
	if (!h->resets_reliable)
		return 0;

	fw_resets = bnxt_fw_health_readl(bp, BNXT_FW_RESET_CNT_REG);
	devlink_fmsg_u32_pair_put(fmsg, "Resets", fw_resets);
	devlink_fmsg_u32_pair_put(fmsg, "Arrests", h->arrests);
	devlink_fmsg_u32_pair_put(fmsg, "Survivals", h->survivals);
	devlink_fmsg_u32_pair_put(fmsg, "Discoveries", h->discoveries);
	devlink_fmsg_u32_pair_put(fmsg, "Fatalities", h->fatalities);
	devlink_fmsg_u32_pair_put(fmsg, "Diagnoses", h->diagnoses);
	return 0;
}

static int bnxt_fw_dump(struct devlink_health_reporter *reporter,
			struct devlink_fmsg *fmsg, void *priv_ctx,
			struct netlink_ext_ack *extack)
{
	struct bnxt *bp = devlink_health_reporter_priv(reporter);
	u32 dump_len;
	void *data;
	int rc;

	/* TODO: no firmware dump support in devlink_health_report() context */
	if (priv_ctx)
		return -EOPNOTSUPP;

	dump_len = bnxt_get_coredump_length(bp, BNXT_DUMP_LIVE);
	if (!dump_len)
		return -EIO;

	data = vmalloc(dump_len);
	if (!data)
		return -ENOMEM;

	rc = bnxt_get_coredump(bp, BNXT_DUMP_LIVE, data, &dump_len);
	if (!rc) {
		devlink_fmsg_pair_nest_start(fmsg, "core");
		devlink_fmsg_binary_pair_put(fmsg, "data", data, dump_len);
		devlink_fmsg_u32_pair_put(fmsg, "size", dump_len);
		devlink_fmsg_pair_nest_end(fmsg);
	}

	vfree(data);
	return rc;
}

static int bnxt_fw_recover(struct devlink_health_reporter *reporter,
			   void *priv_ctx,
			   struct netlink_ext_ack *extack)
{
	struct bnxt *bp = devlink_health_reporter_priv(reporter);

	if (bp->fw_health->severity == SEVERITY_FATAL)
		return -ENODEV;

	set_bit(BNXT_STATE_RECOVER, &bp->state);
	__bnxt_fw_recover(bp);

	return -EINPROGRESS;
}

static const struct devlink_health_reporter_ops bnxt_dl_fw_reporter_ops = {
	.name = "fw",
	.diagnose = bnxt_fw_diagnose,
	.dump = bnxt_fw_dump,

Annotation

Implementation Notes