brintos

brintos / linux-shallow public Read only

0
0
Text · 4.4 KiB · 2681889 Raw
178 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Copyright(c) 2023 Advanced Micro Devices, Inc */3 4#include "core.h"5#include <linux/pds/pds_auxbus.h>6 7static struct8pdsc_viftype *pdsc_dl_find_viftype_by_id(struct pdsc *pdsc,9					 enum devlink_param_type dl_id)10{11	int vt;12 13	if (!pdsc->viftype_status)14		return NULL;15 16	for (vt = 0; vt < PDS_DEV_TYPE_MAX; vt++) {17		if (pdsc->viftype_status[vt].dl_id == dl_id)18			return &pdsc->viftype_status[vt];19	}20 21	return NULL;22}23 24int pdsc_dl_enable_get(struct devlink *dl, u32 id,25		       struct devlink_param_gset_ctx *ctx)26{27	struct pdsc *pdsc = devlink_priv(dl);28	struct pdsc_viftype *vt_entry;29 30	vt_entry = pdsc_dl_find_viftype_by_id(pdsc, id);31	if (!vt_entry)32		return -ENOENT;33 34	ctx->val.vbool = vt_entry->enabled;35 36	return 0;37}38 39int pdsc_dl_enable_set(struct devlink *dl, u32 id,40		       struct devlink_param_gset_ctx *ctx,41		       struct netlink_ext_ack *extack)42{43	struct pdsc *pdsc = devlink_priv(dl);44	struct pdsc_viftype *vt_entry;45	int err = 0;46	int vf_id;47 48	vt_entry = pdsc_dl_find_viftype_by_id(pdsc, id);49	if (!vt_entry || !vt_entry->supported)50		return -EOPNOTSUPP;51 52	if (vt_entry->enabled == ctx->val.vbool)53		return 0;54 55	vt_entry->enabled = ctx->val.vbool;56	for (vf_id = 0; vf_id < pdsc->num_vfs; vf_id++) {57		struct pdsc *vf = pdsc->vfs[vf_id].vf;58 59		err = ctx->val.vbool ? pdsc_auxbus_dev_add(vf, pdsc) :60				       pdsc_auxbus_dev_del(vf, pdsc);61	}62 63	return err;64}65 66int pdsc_dl_enable_validate(struct devlink *dl, u32 id,67			    union devlink_param_value val,68			    struct netlink_ext_ack *extack)69{70	struct pdsc *pdsc = devlink_priv(dl);71	struct pdsc_viftype *vt_entry;72 73	vt_entry = pdsc_dl_find_viftype_by_id(pdsc, id);74	if (!vt_entry || !vt_entry->supported)75		return -EOPNOTSUPP;76 77	if (!pdsc->viftype_status[vt_entry->vif_id].supported)78		return -ENODEV;79 80	return 0;81}82 83int pdsc_dl_flash_update(struct devlink *dl,84			 struct devlink_flash_update_params *params,85			 struct netlink_ext_ack *extack)86{87	struct pdsc *pdsc = devlink_priv(dl);88 89	return pdsc_firmware_update(pdsc, params->fw, extack);90}91 92static char *fw_slotnames[] = {93	"fw.goldfw",94	"fw.mainfwa",95	"fw.mainfwb",96};97 98int pdsc_dl_info_get(struct devlink *dl, struct devlink_info_req *req,99		     struct netlink_ext_ack *extack)100{101	union pds_core_dev_cmd cmd = {102		.fw_control.opcode = PDS_CORE_CMD_FW_CONTROL,103		.fw_control.oper = PDS_CORE_FW_GET_LIST,104	};105	struct pds_core_fw_list_info fw_list;106	struct pdsc *pdsc = devlink_priv(dl);107	union pds_core_dev_comp comp;108	char buf[32];109	int listlen;110	int err;111	int i;112 113	mutex_lock(&pdsc->devcmd_lock);114	err = pdsc_devcmd_locked(pdsc, &cmd, &comp, pdsc->devcmd_timeout * 2);115	if (!err)116		memcpy_fromio(&fw_list, pdsc->cmd_regs->data, sizeof(fw_list));117	mutex_unlock(&pdsc->devcmd_lock);118	if (err && err != -EIO)119		return err;120 121	listlen = fw_list.num_fw_slots;122	for (i = 0; i < listlen; i++) {123		if (i < ARRAY_SIZE(fw_slotnames))124			strscpy(buf, fw_slotnames[i], sizeof(buf));125		else126			snprintf(buf, sizeof(buf), "fw.slot_%d", i);127		err = devlink_info_version_stored_put(req, buf,128						      fw_list.fw_names[i].fw_version);129		if (err)130			return err;131	}132 133	err = devlink_info_version_running_put(req,134					       DEVLINK_INFO_VERSION_GENERIC_FW,135					       pdsc->dev_info.fw_version);136	if (err)137		return err;138 139	snprintf(buf, sizeof(buf), "0x%x", pdsc->dev_info.asic_type);140	err = devlink_info_version_fixed_put(req,141					     DEVLINK_INFO_VERSION_GENERIC_ASIC_ID,142					     buf);143	if (err)144		return err;145 146	snprintf(buf, sizeof(buf), "0x%x", pdsc->dev_info.asic_rev);147	err = devlink_info_version_fixed_put(req,148					     DEVLINK_INFO_VERSION_GENERIC_ASIC_REV,149					     buf);150	if (err)151		return err;152 153	return devlink_info_serial_number_put(req, pdsc->dev_info.serial_num);154}155 156int pdsc_fw_reporter_diagnose(struct devlink_health_reporter *reporter,157			      struct devlink_fmsg *fmsg,158			      struct netlink_ext_ack *extack)159{160	struct pdsc *pdsc = devlink_health_reporter_priv(reporter);161 162	mutex_lock(&pdsc->config_lock);163	if (test_bit(PDSC_S_FW_DEAD, &pdsc->state))164		devlink_fmsg_string_pair_put(fmsg, "Status", "dead");165	else if (!pdsc_is_fw_good(pdsc))166		devlink_fmsg_string_pair_put(fmsg, "Status", "unhealthy");167	else168		devlink_fmsg_string_pair_put(fmsg, "Status", "healthy");169	mutex_unlock(&pdsc->config_lock);170 171	devlink_fmsg_u32_pair_put(fmsg, "State",172				  pdsc->fw_status & ~PDS_CORE_FW_STS_F_GENERATION);173	devlink_fmsg_u32_pair_put(fmsg, "Generation", pdsc->fw_generation >> 4);174	devlink_fmsg_u32_pair_put(fmsg, "Recoveries", pdsc->fw_recoveries);175 176	return 0;177}178