1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2023 Advanced Micro Devices, Inc */
5 #include <linux/pds/pds_auxbus.h>
8 pdsc_viftype
*pdsc_dl_find_viftype_by_id(struct pdsc
*pdsc
,
9 enum devlink_param_type dl_id
)
13 if (!pdsc
->viftype_status
)
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
];
24 int pdsc_dl_enable_get(struct devlink
*dl
, u32 id
,
25 struct devlink_param_gset_ctx
*ctx
)
27 struct pdsc
*pdsc
= devlink_priv(dl
);
28 struct pdsc_viftype
*vt_entry
;
30 vt_entry
= pdsc_dl_find_viftype_by_id(pdsc
, id
);
34 ctx
->val
.vbool
= vt_entry
->enabled
;
39 int pdsc_dl_enable_set(struct devlink
*dl
, u32 id
,
40 struct devlink_param_gset_ctx
*ctx
,
41 struct netlink_ext_ack
*extack
)
43 struct pdsc
*pdsc
= devlink_priv(dl
);
44 struct pdsc_viftype
*vt_entry
;
48 vt_entry
= pdsc_dl_find_viftype_by_id(pdsc
, id
);
49 if (!vt_entry
|| !vt_entry
->supported
)
52 if (vt_entry
->enabled
== ctx
->val
.vbool
)
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
;
59 err
= ctx
->val
.vbool
? pdsc_auxbus_dev_add(vf
, pdsc
) :
60 pdsc_auxbus_dev_del(vf
, pdsc
);
66 int pdsc_dl_enable_validate(struct devlink
*dl
, u32 id
,
67 union devlink_param_value val
,
68 struct netlink_ext_ack
*extack
)
70 struct pdsc
*pdsc
= devlink_priv(dl
);
71 struct pdsc_viftype
*vt_entry
;
73 vt_entry
= pdsc_dl_find_viftype_by_id(pdsc
, id
);
74 if (!vt_entry
|| !vt_entry
->supported
)
77 if (!pdsc
->viftype_status
[vt_entry
->vif_id
].supported
)
83 int pdsc_dl_flash_update(struct devlink
*dl
,
84 struct devlink_flash_update_params
*params
,
85 struct netlink_ext_ack
*extack
)
87 struct pdsc
*pdsc
= devlink_priv(dl
);
89 return pdsc_firmware_update(pdsc
, params
->fw
, extack
);
92 static char *fw_slotnames
[] = {
98 int pdsc_dl_info_get(struct devlink
*dl
, struct devlink_info_req
*req
,
99 struct netlink_ext_ack
*extack
)
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
,
105 struct pds_core_fw_list_info fw_list
;
106 struct pdsc
*pdsc
= devlink_priv(dl
);
107 union pds_core_dev_comp comp
;
113 mutex_lock(&pdsc
->devcmd_lock
);
114 err
= pdsc_devcmd_locked(pdsc
, &cmd
, &comp
, pdsc
->devcmd_timeout
* 2);
116 memcpy_fromio(&fw_list
, pdsc
->cmd_regs
->data
, sizeof(fw_list
));
117 mutex_unlock(&pdsc
->devcmd_lock
);
118 if (err
&& err
!= -EIO
)
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
));
126 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
);
133 err
= devlink_info_version_running_put(req
,
134 DEVLINK_INFO_VERSION_GENERIC_FW
,
135 pdsc
->dev_info
.fw_version
);
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
,
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
,
153 return devlink_info_serial_number_put(req
, pdsc
->dev_info
.serial_num
);
156 int pdsc_fw_reporter_diagnose(struct devlink_health_reporter
*reporter
,
157 struct devlink_fmsg
*fmsg
,
158 struct netlink_ext_ack
*extack
)
160 struct pdsc
*pdsc
= devlink_health_reporter_priv(reporter
);
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");
168 devlink_fmsg_string_pair_put(fmsg
, "Status", "healthy");
169 mutex_unlock(&pdsc
->config_lock
);
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
);