diff options
Diffstat (limited to 'drivers/net/ethernet/sfc/mcdi.c')
| -rw-r--r-- | drivers/net/ethernet/sfc/mcdi.c | 72 | 
1 files changed, 72 insertions, 0 deletions
diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c index af338208eae9..a7f2c31071e8 100644 --- a/drivers/net/ethernet/sfc/mcdi.c +++ b/drivers/net/ethernet/sfc/mcdi.c @@ -2175,6 +2175,78 @@ int efx_mcdi_get_privilege_mask(struct efx_nic *efx, u32 *mask)  	return 0;  } +int efx_mcdi_nvram_metadata(struct efx_nic *efx, unsigned int type, +			    u32 *subtype, u16 version[4], char *desc, +			    size_t descsize) +{ +	MCDI_DECLARE_BUF(inbuf, MC_CMD_NVRAM_METADATA_IN_LEN); +	efx_dword_t *outbuf; +	size_t outlen; +	u32 flags; +	int rc; + +	outbuf = kzalloc(MC_CMD_NVRAM_METADATA_OUT_LENMAX_MCDI2, GFP_KERNEL); +	if (!outbuf) +		return -ENOMEM; + +	MCDI_SET_DWORD(inbuf, NVRAM_METADATA_IN_TYPE, type); + +	rc = efx_mcdi_rpc_quiet(efx, MC_CMD_NVRAM_METADATA, inbuf, +				sizeof(inbuf), outbuf, +				MC_CMD_NVRAM_METADATA_OUT_LENMAX_MCDI2, +				&outlen); +	if (rc) +		goto out_free; +	if (outlen < MC_CMD_NVRAM_METADATA_OUT_LENMIN) { +		rc = -EIO; +		goto out_free; +	} + +	flags = MCDI_DWORD(outbuf, NVRAM_METADATA_OUT_FLAGS); + +	if (desc && descsize > 0) { +		if (flags & BIT(MC_CMD_NVRAM_METADATA_OUT_DESCRIPTION_VALID_LBN)) { +			if (descsize <= +			    MC_CMD_NVRAM_METADATA_OUT_DESCRIPTION_NUM(outlen)) { +				rc = -E2BIG; +				goto out_free; +			} + +			strncpy(desc, +				MCDI_PTR(outbuf, NVRAM_METADATA_OUT_DESCRIPTION), +				MC_CMD_NVRAM_METADATA_OUT_DESCRIPTION_NUM(outlen)); +			desc[MC_CMD_NVRAM_METADATA_OUT_DESCRIPTION_NUM(outlen)] = '\0'; +		} else { +			desc[0] = '\0'; +		} +	} + +	if (subtype) { +		if (flags & BIT(MC_CMD_NVRAM_METADATA_OUT_SUBTYPE_VALID_LBN)) +			*subtype = MCDI_DWORD(outbuf, NVRAM_METADATA_OUT_SUBTYPE); +		else +			*subtype = 0; +	} + +	if (version) { +		if (flags & BIT(MC_CMD_NVRAM_METADATA_OUT_VERSION_VALID_LBN)) { +			version[0] = MCDI_WORD(outbuf, NVRAM_METADATA_OUT_VERSION_W); +			version[1] = MCDI_WORD(outbuf, NVRAM_METADATA_OUT_VERSION_X); +			version[2] = MCDI_WORD(outbuf, NVRAM_METADATA_OUT_VERSION_Y); +			version[3] = MCDI_WORD(outbuf, NVRAM_METADATA_OUT_VERSION_Z); +		} else { +			version[0] = 0; +			version[1] = 0; +			version[2] = 0; +			version[3] = 0; +		} +	} + +out_free: +	kfree(outbuf); +	return rc; +} +  #ifdef CONFIG_SFC_MTD  #define EFX_MCDI_NVRAM_LEN_MAX 128  |