[4/4] firmware: tegra: use in-band messages for firmware version query

Message ID 1539758250-7380-5-git-send-email-talho@nvidia.com
State New
Headers show
Series
  • BPMP-FW version query ("tag") update
Related show

Commit Message

Timo Alho Oct. 17, 2018, 6:37 a.m.
Add support for a new MRQ, that uses in-band messaging instead of IOVA
buffer, to retrieve the firmware version 'tag' during boot. If an
older firmware is used, that does not support the new MRQ, fall back
to the earlier implementation.

Signed-off-by: Timo Alho <talho@nvidia.com>
---
 drivers/firmware/tegra/bpmp.c | 33 +++++++++++++++++++++++++++++++--
 1 file changed, 31 insertions(+), 2 deletions(-)

Comments

Jon Hunter Oct. 17, 2018, 9:23 a.m. | #1
On 17/10/2018 07:37, Timo Alho wrote:
> Add support for a new MRQ, that uses in-band messaging instead of IOVA
> buffer, to retrieve the firmware version 'tag' during boot. If an
> older firmware is used, that does not support the new MRQ, fall back
> to the earlier implementation.
> 
> Signed-off-by: Timo Alho <talho@nvidia.com>
> ---
>  drivers/firmware/tegra/bpmp.c | 33 +++++++++++++++++++++++++++++++--
>  1 file changed, 31 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/firmware/tegra/bpmp.c b/drivers/firmware/tegra/bpmp.c
> index 5bb46a5..46f8141 100644
> --- a/drivers/firmware/tegra/bpmp.c
> +++ b/drivers/firmware/tegra/bpmp.c
> @@ -549,8 +549,9 @@ static int tegra_bpmp_ping(struct tegra_bpmp *bpmp)
>  	return err;
>  }
>  
> -static int tegra_bpmp_get_firmware_tag(struct tegra_bpmp *bpmp, char *tag,
> -				       size_t size)
> +/* deprecated version of tag query */
> +static int tegra_bpmp_get_firmware_tag_old(struct tegra_bpmp *bpmp, char *tag,
> +					   size_t size)
>  {
>  	struct mrq_query_tag_request request;
>  	struct tegra_bpmp_message msg;
> @@ -584,6 +585,34 @@ static int tegra_bpmp_get_firmware_tag(struct tegra_bpmp *bpmp, char *tag,
>  	return err;
>  }
>  
> +static int tegra_bpmp_get_firmware_tag(struct tegra_bpmp *bpmp, char *tag,
> +				       size_t size)
> +{
> +	struct mrq_query_fw_tag_response resp;
> +	struct tegra_bpmp_message msg = {
> +		.mrq = MRQ_QUERY_FW_TAG,
> +		.rx = {
> +			.data = &resp,
> +			.size = sizeof(resp),
> +		},
> +	};
> +	int err;
> +
> +	if (!tegra_bpmp_mrq_is_supported(bpmp, MRQ_QUERY_FW_TAG))
> +		return tegra_bpmp_get_firmware_tag_old(bpmp, tag, size);
> +
> +	err = tegra_bpmp_transfer(bpmp, &msg);
> +
> +	if (err)
> +		return err;
> +	if (msg.rx.ret < 0)
> +		return -EINVAL;
> +
> +	strlcpy(tag, &resp.tag[0], size);
> +
> +	return 0;
> +}
> +
>  static void tegra_bpmp_channel_signal(struct tegra_bpmp_channel *channel)
>  {
>  	unsigned long flags = channel->ob->flags;
> 

Acked-by: Jon Hunter <jonathanh@nvidia.com>

Cheers,
Jon
Sivaram Nair Oct. 17, 2018, 6:22 p.m. | #2
On Wed, Oct 17, 2018 at 09:37:30AM +0300, Timo Alho wrote:
> Add support for a new MRQ, that uses in-band messaging instead of IOVA
> buffer, to retrieve the firmware version 'tag' during boot. If an
> older firmware is used, that does not support the new MRQ, fall back
> to the earlier implementation.
> 
> Signed-off-by: Timo Alho <talho@nvidia.com>
> ---
>  drivers/firmware/tegra/bpmp.c | 33 +++++++++++++++++++++++++++++++--
>  1 file changed, 31 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/firmware/tegra/bpmp.c b/drivers/firmware/tegra/bpmp.c
> index 5bb46a5..46f8141 100644
> --- a/drivers/firmware/tegra/bpmp.c
> +++ b/drivers/firmware/tegra/bpmp.c
> @@ -549,8 +549,9 @@ static int tegra_bpmp_ping(struct tegra_bpmp *bpmp)
>  	return err;
>  }
>  
> -static int tegra_bpmp_get_firmware_tag(struct tegra_bpmp *bpmp, char *tag,
> -				       size_t size)
> +/* deprecated version of tag query */
> +static int tegra_bpmp_get_firmware_tag_old(struct tegra_bpmp *bpmp, char *tag,
> +					   size_t size)
>  {
>  	struct mrq_query_tag_request request;
>  	struct tegra_bpmp_message msg;
> @@ -584,6 +585,34 @@ static int tegra_bpmp_get_firmware_tag(struct tegra_bpmp *bpmp, char *tag,
>  	return err;
>  }
>  
> +static int tegra_bpmp_get_firmware_tag(struct tegra_bpmp *bpmp, char *tag,
> +				       size_t size)
> +{
> +	struct mrq_query_fw_tag_response resp;
> +	struct tegra_bpmp_message msg = {
> +		.mrq = MRQ_QUERY_FW_TAG,
> +		.rx = {
> +			.data = &resp,
> +			.size = sizeof(resp),
> +		},
> +	};
> +	int err;
> +
> +	if (!tegra_bpmp_mrq_is_supported(bpmp, MRQ_QUERY_FW_TAG))
> +		return tegra_bpmp_get_firmware_tag_old(bpmp, tag, size);
> +
> +	err = tegra_bpmp_transfer(bpmp, &msg);
> +
> +	if (err)
> +		return err;
> +	if (msg.rx.ret < 0)
> +		return -EINVAL;
> +
> +	strlcpy(tag, &resp.tag[0], size);

I suspect that we are now printing only the first 30 bytes of the tag
string (against the actual 32). Fix that too (in a separate patch)?

> +
> +	return 0;
> +}
> +
>  static void tegra_bpmp_channel_signal(struct tegra_bpmp_channel *channel)
>  {
>  	unsigned long flags = channel->ob->flags;
> -- 
> 2.7.4
>
Timo Alho Oct. 18, 2018, 5:31 p.m. | #3
On 17.10.2018 21.22, Sivaram Nair wrote:
> On Wed, Oct 17, 2018 at 09:37:30AM +0300, Timo Alho wrote:
>> Add support for a new MRQ, that uses in-band messaging instead of IOVA
>> buffer, to retrieve the firmware version 'tag' during boot. If an
>> older firmware is used, that does not support the new MRQ, fall back
>> to the earlier implementation.
>>
>> Signed-off-by: Timo Alho <talho@nvidia.com>
>> ---
>>   drivers/firmware/tegra/bpmp.c | 33 +++++++++++++++++++++++++++++++--
>>   1 file changed, 31 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/firmware/tegra/bpmp.c b/drivers/firmware/tegra/bpmp.c
>> index 5bb46a5..46f8141 100644
>> --- a/drivers/firmware/tegra/bpmp.c
>> +++ b/drivers/firmware/tegra/bpmp.c
>> @@ -549,8 +549,9 @@ static int tegra_bpmp_ping(struct tegra_bpmp *bpmp)
>>   	return err;
>>   }
>>   
>> -static int tegra_bpmp_get_firmware_tag(struct tegra_bpmp *bpmp, char *tag,
>> -				       size_t size)
>> +/* deprecated version of tag query */
>> +static int tegra_bpmp_get_firmware_tag_old(struct tegra_bpmp *bpmp, char *tag,
>> +					   size_t size)
>>   {
>>   	struct mrq_query_tag_request request;
>>   	struct tegra_bpmp_message msg;
>> @@ -584,6 +585,34 @@ static int tegra_bpmp_get_firmware_tag(struct tegra_bpmp *bpmp, char *tag,
>>   	return err;
>>   }
>>   
>> +static int tegra_bpmp_get_firmware_tag(struct tegra_bpmp *bpmp, char *tag,
>> +				       size_t size)
>> +{
>> +	struct mrq_query_fw_tag_response resp;
>> +	struct tegra_bpmp_message msg = {
>> +		.mrq = MRQ_QUERY_FW_TAG,
>> +		.rx = {
>> +			.data = &resp,
>> +			.size = sizeof(resp),
>> +		},
>> +	};
>> +	int err;
>> +
>> +	if (!tegra_bpmp_mrq_is_supported(bpmp, MRQ_QUERY_FW_TAG))
>> +		return tegra_bpmp_get_firmware_tag_old(bpmp, tag, size);
>> +
>> +	err = tegra_bpmp_transfer(bpmp, &msg);
>> +
>> +	if (err)
>> +		return err;
>> +	if (msg.rx.ret < 0)
>> +		return -EINVAL;
>> +
>> +	strlcpy(tag, &resp.tag[0], size);
> 
> I suspect that we are now printing only the first 30 bytes of the tag
> string (against the actual 32). Fix that too (in a separate patch)?

Indeed seems to be the case. Will push a new series that fixes also this 
issue.

Patch

diff --git a/drivers/firmware/tegra/bpmp.c b/drivers/firmware/tegra/bpmp.c
index 5bb46a5..46f8141 100644
--- a/drivers/firmware/tegra/bpmp.c
+++ b/drivers/firmware/tegra/bpmp.c
@@ -549,8 +549,9 @@  static int tegra_bpmp_ping(struct tegra_bpmp *bpmp)
 	return err;
 }
 
-static int tegra_bpmp_get_firmware_tag(struct tegra_bpmp *bpmp, char *tag,
-				       size_t size)
+/* deprecated version of tag query */
+static int tegra_bpmp_get_firmware_tag_old(struct tegra_bpmp *bpmp, char *tag,
+					   size_t size)
 {
 	struct mrq_query_tag_request request;
 	struct tegra_bpmp_message msg;
@@ -584,6 +585,34 @@  static int tegra_bpmp_get_firmware_tag(struct tegra_bpmp *bpmp, char *tag,
 	return err;
 }
 
+static int tegra_bpmp_get_firmware_tag(struct tegra_bpmp *bpmp, char *tag,
+				       size_t size)
+{
+	struct mrq_query_fw_tag_response resp;
+	struct tegra_bpmp_message msg = {
+		.mrq = MRQ_QUERY_FW_TAG,
+		.rx = {
+			.data = &resp,
+			.size = sizeof(resp),
+		},
+	};
+	int err;
+
+	if (!tegra_bpmp_mrq_is_supported(bpmp, MRQ_QUERY_FW_TAG))
+		return tegra_bpmp_get_firmware_tag_old(bpmp, tag, size);
+
+	err = tegra_bpmp_transfer(bpmp, &msg);
+
+	if (err)
+		return err;
+	if (msg.rx.ret < 0)
+		return -EINVAL;
+
+	strlcpy(tag, &resp.tag[0], size);
+
+	return 0;
+}
+
 static void tegra_bpmp_channel_signal(struct tegra_bpmp_channel *channel)
 {
 	unsigned long flags = channel->ob->flags;