pds_core: add support for identity version 2

Add a new capabilities field in struct pds_core_dev_identity,
which requires bumping the identity version to 2, i.e.
PDS_CORE_IDENTITY_VERSION_2. If version 2 negotiation fails,
then quietly fall back to version 1. If version 1 negotiation
fails, then driver load will fail.

Another patch in the series will make use of the capabilities
field.

Signed-off-by: Brett Creeley <brett.creeley@amd.com>
Link: https://patch.msgid.link/20260730-upstream_v8-v12-2-136cd174ee85@amd.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Brett Creeley 2026-07-30 04:25:19 +00:00 committed by Jakub Kicinski
parent 4b5137bfc0
commit e7960459d9
2 changed files with 39 additions and 9 deletions

View File

@ -250,15 +250,17 @@ int pdsc_devcmd_reset(struct pdsc *pdsc)
return pdsc_devcmd(pdsc, &cmd, &comp, pdsc->devcmd_timeout);
}
static int pdsc_devcmd_identify_locked(struct pdsc *pdsc)
static int pdsc_devcmd_identify_locked(struct pdsc *pdsc, u8 drv_ident_ver,
bool do_msg)
{
union pds_core_dev_comp comp = {};
union pds_core_dev_cmd cmd = {
.identify.opcode = PDS_CORE_CMD_IDENTIFY,
.identify.ver = PDS_CORE_IDENTITY_VERSION_1,
.identify.ver = drv_ident_ver,
};
return pdsc_devcmd_locked(pdsc, &cmd, &comp, pdsc->devcmd_timeout);
return __pdsc_devcmd_locked(pdsc, &cmd, &comp, pdsc->devcmd_timeout,
do_msg);
}
static void pdsc_init_devinfo(struct pdsc *pdsc)
@ -281,8 +283,9 @@ static void pdsc_init_devinfo(struct pdsc *pdsc)
dev_dbg(pdsc->dev, "fw_version %s\n", pdsc->dev_info.fw_version);
}
static int pdsc_identify(struct pdsc *pdsc)
static int pdsc_identify_ver(struct pdsc *pdsc, u8 drv_ident_ver)
{
bool do_msg = drv_ident_ver == PDS_CORE_IDENTITY_VERSION_1;
struct pds_core_drv_identity drv = {};
size_t sz;
int err;
@ -305,19 +308,22 @@ static int pdsc_identify(struct pdsc *pdsc)
sz = min_t(size_t, sizeof(drv), sizeof(pdsc->cmd_regs->data));
memcpy_toio(&pdsc->cmd_regs->data, &drv, sz);
err = pdsc_devcmd_identify_locked(pdsc);
err = pdsc_devcmd_identify_locked(pdsc, drv_ident_ver, do_msg);
if (!err) {
sz = min_t(size_t, sizeof(pdsc->dev_ident),
sizeof(pdsc->cmd_regs->data));
memcpy_fromio(&pdsc->dev_ident, &pdsc->cmd_regs->data, sz);
/* V1 firmware doesn't set capabilities, so the field may
* contain garbage from the outgoing driver identity.
*/
if (pdsc->dev_ident.version < PDS_CORE_IDENTITY_VERSION_2)
pdsc->dev_ident.capabilities = 0;
}
mutex_unlock(&pdsc->devcmd_lock);
if (err) {
dev_err(pdsc->dev, "Cannot identify device: %pe\n",
ERR_PTR(err));
if (err)
return err;
}
if (isprint(pdsc->dev_info.fw_version[0]) &&
isascii(pdsc->dev_info.fw_version[0]))
@ -334,6 +340,26 @@ static int pdsc_identify(struct pdsc *pdsc)
return 0;
}
static int pdsc_identify(struct pdsc *pdsc)
{
int err;
/* Older firmware rejects anything but PDS_CORE_IDENTITY_VERSION_1
* with PDS_RC_EVERSION (-EINVAL), so retry with V1 on version
* rejection. Don't retry on other errors like -ENXIO/-ETIMEDOUT
* which indicate firmware is not running or hung.
*/
err = pdsc_identify_ver(pdsc, PDS_CORE_IDENTITY_VERSION_2);
if (err == -EINVAL)
err = pdsc_identify_ver(pdsc, PDS_CORE_IDENTITY_VERSION_1);
if (err)
dev_err(pdsc->dev, "Cannot identify device: %pe\n",
ERR_PTR(err));
return err;
}
void pdsc_dev_uninit(struct pdsc *pdsc)
{
if (pdsc->intr_info) {

View File

@ -119,6 +119,8 @@ struct pds_core_drv_identity {
* value in usecs to device units using:
* device units = usecs * mult / div
* @vif_types: How many of each VIF device type is supported
* @capabilities: Device capabilities
* only supported on version >= PDS_CORE_IDENTITY_VERSION_2
*/
struct pds_core_dev_identity {
u8 version;
@ -131,9 +133,11 @@ struct pds_core_dev_identity {
__le32 intr_coal_mult;
__le32 intr_coal_div;
__le16 vif_types[PDS_DEV_TYPE_MAX];
__le64 capabilities;
};
#define PDS_CORE_IDENTITY_VERSION_1 1
#define PDS_CORE_IDENTITY_VERSION_2 2
/**
* struct pds_core_dev_identify_cmd - Driver/device identify command