diff mbox series

[V6,07/21] core/pldm: Encode GetPLDMCommands response

Message ID 20220913102705.65506-8-clombard@linux.vnet.ibm.com
State Superseded
Headers show
Series Implement MCTP and PLDM features | expand

Commit Message

Christophe Lombard Sept. 13, 2022, 10:26 a.m. UTC
The GetPLDMCommands command can be used to discover the PLDM command
capabilities supported by a PLDM terminus for a specific PLDM Type and
version as a responder.

Reviewed-by: Abhishek Singh Tomar <abhishek at linux.ibm.com>
Signed-off-by: Christophe Lombard <clombard@linux.vnet.ibm.com>
---
 core/pldm/pldm-responder.c | 90 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 90 insertions(+)

Comments

Abhishek Singh Tomar Sept. 29, 2022, 2:28 p.m. UTC | #1
On Tue, Sep 13, 2022 at 12:26:51PM +0200, Christophe Lombard wrote:
> The GetPLDMCommands command can be used to discover the PLDM command
> capabilities supported by a PLDM terminus for a specific PLDM Type and
> version as a responder.
> 
Reviewed-by: Abhishek Singh Tomar <abhishek@linux.ibm.com>
> Signed-off-by: Christophe Lombard <clombard@linux.vnet.ibm.com>
> ---
>  core/pldm/pldm-responder.c | 90 ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 90 insertions(+)
> 
> diff --git a/core/pldm/pldm-responder.c b/core/pldm/pldm-responder.c
> index 6058af51..88545685 100644
> --- a/core/pldm/pldm-responder.c
> +++ b/core/pldm/pldm-responder.c
> @@ -205,6 +205,95 @@ static struct pldm_cmd pldm_base_get_types = {
>  	.handler = base_get_types_handler,
>  };
> 
> +/*
> + * Extended error codes defined for the Base command set.
> + */
> +#define INVALID_PLDM_TYPE_IN_REQUEST_DATA      0x83
> +#define INVALID_PLDM_VERSION_IN_REQUEST_DATA   0x84
> +
> +/*
> + * GetPLDMCommands (0x05)
> + * The GetPLDMCommands command can be used to discover the PLDM command
> + * capabilities supported by aPLDM terminus for a specific PLDM Type and
> + * version as a responder.
> + */
> +static int base_get_commands_handler(const struct pldm_rx_data *req)
> +{
> +	char response_msg[PKT_SIZE(struct pldm_get_commands_resp)];
> +	bitmap_elem_t cmd_map[BITMAP_ELEMS(256)];
> +	const struct pldm_type *type;
> +	const struct pldm_cmd *iter;
> +	size_t payload_len;
> +	ver32_t version;
> +	uint8_t type_id;
> +	int rc;
> +
> +	payload_len = req->msg_len - sizeof(struct pldm_msg_hdr);
> +	rc = decode_get_commands_req(req->msg, payload_len,
> +				     &type_id, &version);
> +	if (rc) {
> +		prlog(PR_ERR, "Failed to decode GetPLDMCommands request, rc = %d", rc);
> +		cc_resp(req, req->hdrinf.pldm_type,
> +			req->hdrinf.command, PLDM_ERROR);
> +		return OPAL_INTERNAL_ERROR;
> +	}
> +
> +	type = find_type(type_id);
> +	if (!type) {
> +		cc_resp(req, req->hdrinf.pldm_type,
> +			req->hdrinf.command,
> +			INVALID_PLDM_TYPE_IN_REQUEST_DATA);
> +		return OPAL_PARAMETER;
> +	}
> +
> +	if (memcmp(&type->version, &version, sizeof(version))) {
> +		cc_resp(req, req->hdrinf.pldm_type,
> +			req->hdrinf.command,
> +			INVALID_PLDM_VERSION_IN_REQUEST_DATA);
> +		return OPAL_PARAMETER;
> +	}
> +
> +	/*
> +	* build the supported type list from the registered type
> +	* handlers
> +	*/
> +	memset(cmd_map, 0, sizeof(cmd_map));
> +	list_for_each(&type->commands, iter, link)
> +		bitmap_set_bit(cmd_map, iter->pldm_cmd_id);
> +	/* fix the endian */
> +	for (int i = 0; i < BITMAP_ELEMS(256); i++)
> +		cmd_map[i] = cpu_to_le64(cmd_map[i]);
> +
> +	memset(response_msg, 0, sizeof(response_msg));
> +
> +	/* create a PLDM response message for GetPLDMCommands */
> +	rc = encode_get_commands_resp(req->hdrinf.instance,
> +				      PLDM_SUCCESS,
> +				      (bitfield8_t *)cmd_map,
> +				      (struct pldm_msg *)response_msg);
> +	if (rc != PLDM_SUCCESS) {
> +		prlog(PR_ERR, "Encode GetPLDMCommands Error, rc: %d\n", rc);
> +		cc_resp(req, req->hdrinf.pldm_type,
> +			req->hdrinf.command, PLDM_ERROR);
> +		return OPAL_PARAMETER;
> +	}
> +
> +	/* send PLDM message over MCTP */
> +	rc = pldm_mctp_message_tx(req->source_eid, response_msg, sizeof(response_msg));
> +	if (rc) {
> +		prlog(PR_ERR, "Failed to send GetPLDMCommands response, rc = %d\n", rc);
> +		return OPAL_HARDWARE;
> +	}
> +
> +	return OPAL_SUCCESS;
> +}
> +
> +static struct pldm_cmd pldm_base_get_commands = {
> +	.name = "PLDM_GET_PLDM_COMMANDS",
> +	.pldm_cmd_id = PLDM_GET_PLDM_COMMANDS,
> +	.handler = base_get_commands_handler,
> +};
> +
>  int pldm_responder_handle_request(struct pldm_rx_data *rx)
>  {
>  	const struct pldm_type *type;
> @@ -242,6 +331,7 @@ int pldm_responder_init(void)
>  	add_type(&pldm_base_type);
>  	add_cmd(&pldm_base_type, &pldm_base_get_tid);
>  	add_cmd(&pldm_base_type, &pldm_base_get_types);
> +	add_cmd(&pldm_base_type, &pldm_base_get_commands);
> 
>  	return OPAL_SUCCESS;
>  }
> -- 
> 2.37.3
> 
> _______________________________________________
> Skiboot mailing list
> Skiboot@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/skiboot
Frederic Barrat April 12, 2023, 2:48 p.m. UTC | #2
On 13/09/2022 12:26, Christophe Lombard wrote:
> The GetPLDMCommands command can be used to discover the PLDM command
> capabilities supported by a PLDM terminus for a specific PLDM Type and
> version as a responder.
> 
> Reviewed-by: Abhishek Singh Tomar <abhishek at linux.ibm.com>
> Signed-off-by: Christophe Lombard <clombard@linux.vnet.ibm.com>
> ---
>   core/pldm/pldm-responder.c | 90 ++++++++++++++++++++++++++++++++++++++
>   1 file changed, 90 insertions(+)
> 
> diff --git a/core/pldm/pldm-responder.c b/core/pldm/pldm-responder.c
> index 6058af51..88545685 100644
> --- a/core/pldm/pldm-responder.c
> +++ b/core/pldm/pldm-responder.c
> @@ -205,6 +205,95 @@ static struct pldm_cmd pldm_base_get_types = {
>   	.handler = base_get_types_handler,
>   };
>   
> +/*
> + * Extended error codes defined for the Base command set.
> + */
> +#define INVALID_PLDM_TYPE_IN_REQUEST_DATA      0x83
> +#define INVALID_PLDM_VERSION_IN_REQUEST_DATA   0x84
> +
> +/*
> + * GetPLDMCommands (0x05)
> + * The GetPLDMCommands command can be used to discover the PLDM command
> + * capabilities supported by aPLDM terminus for a specific PLDM Type and
> + * version as a responder.
> + */
> +static int base_get_commands_handler(const struct pldm_rx_data *req)
> +{
> +	char response_msg[PKT_SIZE(struct pldm_get_commands_resp)];
> +	bitmap_elem_t cmd_map[BITMAP_ELEMS(256)];


Like in the previous patch, libpldm gives a macro:
#define PLDM_MAX_CMDS_PER_TYPE 256

   Fred


> +	const struct pldm_type *type;
> +	const struct pldm_cmd *iter;
> +	size_t payload_len;
> +	ver32_t version;
> +	uint8_t type_id;
> +	int rc;
> +
> +	payload_len = req->msg_len - sizeof(struct pldm_msg_hdr);
> +	rc = decode_get_commands_req(req->msg, payload_len,
> +				     &type_id, &version);
> +	if (rc) {
> +		prlog(PR_ERR, "Failed to decode GetPLDMCommands request, rc = %d", rc);
> +		cc_resp(req, req->hdrinf.pldm_type,
> +			req->hdrinf.command, PLDM_ERROR);
> +		return OPAL_INTERNAL_ERROR;
> +	}
> +
> +	type = find_type(type_id);
> +	if (!type) {
> +		cc_resp(req, req->hdrinf.pldm_type,
> +			req->hdrinf.command,
> +			INVALID_PLDM_TYPE_IN_REQUEST_DATA);
> +		return OPAL_PARAMETER;
> +	}
> +
> +	if (memcmp(&type->version, &version, sizeof(version))) {
> +		cc_resp(req, req->hdrinf.pldm_type,
> +			req->hdrinf.command,
> +			INVALID_PLDM_VERSION_IN_REQUEST_DATA);
> +		return OPAL_PARAMETER;
> +	}
> +
> +	/*
> +	* build the supported type list from the registered type
> +	* handlers
> +	*/
> +	memset(cmd_map, 0, sizeof(cmd_map));
> +	list_for_each(&type->commands, iter, link)
> +		bitmap_set_bit(cmd_map, iter->pldm_cmd_id);
> +	/* fix the endian */
> +	for (int i = 0; i < BITMAP_ELEMS(256); i++)
> +		cmd_map[i] = cpu_to_le64(cmd_map[i]);
> +
> +	memset(response_msg, 0, sizeof(response_msg));
> +
> +	/* create a PLDM response message for GetPLDMCommands */
> +	rc = encode_get_commands_resp(req->hdrinf.instance,
> +				      PLDM_SUCCESS,
> +				      (bitfield8_t *)cmd_map,
> +				      (struct pldm_msg *)response_msg);
> +	if (rc != PLDM_SUCCESS) {
> +		prlog(PR_ERR, "Encode GetPLDMCommands Error, rc: %d\n", rc);
> +		cc_resp(req, req->hdrinf.pldm_type,
> +			req->hdrinf.command, PLDM_ERROR);
> +		return OPAL_PARAMETER;
> +	}
> +
> +	/* send PLDM message over MCTP */
> +	rc = pldm_mctp_message_tx(req->source_eid, response_msg, sizeof(response_msg));
> +	if (rc) {
> +		prlog(PR_ERR, "Failed to send GetPLDMCommands response, rc = %d\n", rc);
> +		return OPAL_HARDWARE;
> +	}
> +
> +	return OPAL_SUCCESS;
> +}
> +
> +static struct pldm_cmd pldm_base_get_commands = {
> +	.name = "PLDM_GET_PLDM_COMMANDS",
> +	.pldm_cmd_id = PLDM_GET_PLDM_COMMANDS,
> +	.handler = base_get_commands_handler,
> +};
> +
>   int pldm_responder_handle_request(struct pldm_rx_data *rx)
>   {
>   	const struct pldm_type *type;
> @@ -242,6 +331,7 @@ int pldm_responder_init(void)
>   	add_type(&pldm_base_type);
>   	add_cmd(&pldm_base_type, &pldm_base_get_tid);
>   	add_cmd(&pldm_base_type, &pldm_base_get_types);
> +	add_cmd(&pldm_base_type, &pldm_base_get_commands);
>   
>   	return OPAL_SUCCESS;
>   }
Christophe Lombard April 13, 2023, 7:58 a.m. UTC | #3
Le 12/04/2023 à 16:48, Frederic Barrat a écrit :
>
>
> On 13/09/2022 12:26, Christophe Lombard wrote:
>> The GetPLDMCommands command can be used to discover the PLDM command
>> capabilities supported by a PLDM terminus for a specific PLDM Type and
>> version as a responder.
>>
>> Reviewed-by: Abhishek Singh Tomar <abhishek at linux.ibm.com>
>> Signed-off-by: Christophe Lombard <clombard@linux.vnet.ibm.com>
>> ---
>>   core/pldm/pldm-responder.c | 90 ++++++++++++++++++++++++++++++++++++++
>>   1 file changed, 90 insertions(+)
>>
>> diff --git a/core/pldm/pldm-responder.c b/core/pldm/pldm-responder.c
>> index 6058af51..88545685 100644
>> --- a/core/pldm/pldm-responder.c
>> +++ b/core/pldm/pldm-responder.c
>> @@ -205,6 +205,95 @@ static struct pldm_cmd pldm_base_get_types = {
>>       .handler = base_get_types_handler,
>>   };
>>   +/*
>> + * Extended error codes defined for the Base command set.
>> + */
>> +#define INVALID_PLDM_TYPE_IN_REQUEST_DATA      0x83
>> +#define INVALID_PLDM_VERSION_IN_REQUEST_DATA   0x84
>> +
>> +/*
>> + * GetPLDMCommands (0x05)
>> + * The GetPLDMCommands command can be used to discover the PLDM command
>> + * capabilities supported by aPLDM terminus for a specific PLDM Type 
>> and
>> + * version as a responder.
>> + */
>> +static int base_get_commands_handler(const struct pldm_rx_data *req)
>> +{
>> +    char response_msg[PKT_SIZE(struct pldm_get_commands_resp)];
>> +    bitmap_elem_t cmd_map[BITMAP_ELEMS(256)];
>
>
> Like in the previous patch, libpldm gives a macro:
> #define PLDM_MAX_CMDS_PER_TYPE 256
>
>   Fred
>

ok. Thanks

>
>> +    const struct pldm_type *type;
>> +    const struct pldm_cmd *iter;
>> +    size_t payload_len;
>> +    ver32_t version;
>> +    uint8_t type_id;
>> +    int rc;
>> +
>> +    payload_len = req->msg_len - sizeof(struct pldm_msg_hdr);
>> +    rc = decode_get_commands_req(req->msg, payload_len,
>> +                     &type_id, &version);
>> +    if (rc) {
>> +        prlog(PR_ERR, "Failed to decode GetPLDMCommands request, rc 
>> = %d", rc);
>> +        cc_resp(req, req->hdrinf.pldm_type,
>> +            req->hdrinf.command, PLDM_ERROR);
>> +        return OPAL_INTERNAL_ERROR;
>> +    }
>> +
>> +    type = find_type(type_id);
>> +    if (!type) {
>> +        cc_resp(req, req->hdrinf.pldm_type,
>> +            req->hdrinf.command,
>> +            INVALID_PLDM_TYPE_IN_REQUEST_DATA);
>> +        return OPAL_PARAMETER;
>> +    }
>> +
>> +    if (memcmp(&type->version, &version, sizeof(version))) {
>> +        cc_resp(req, req->hdrinf.pldm_type,
>> +            req->hdrinf.command,
>> +            INVALID_PLDM_VERSION_IN_REQUEST_DATA);
>> +        return OPAL_PARAMETER;
>> +    }
>> +
>> +    /*
>> +    * build the supported type list from the registered type
>> +    * handlers
>> +    */
>> +    memset(cmd_map, 0, sizeof(cmd_map));
>> +    list_for_each(&type->commands, iter, link)
>> +        bitmap_set_bit(cmd_map, iter->pldm_cmd_id);
>> +    /* fix the endian */
>> +    for (int i = 0; i < BITMAP_ELEMS(256); i++)
>> +        cmd_map[i] = cpu_to_le64(cmd_map[i]);
>> +
>> +    memset(response_msg, 0, sizeof(response_msg));
>> +
>> +    /* create a PLDM response message for GetPLDMCommands */
>> +    rc = encode_get_commands_resp(req->hdrinf.instance,
>> +                      PLDM_SUCCESS,
>> +                      (bitfield8_t *)cmd_map,
>> +                      (struct pldm_msg *)response_msg);
>> +    if (rc != PLDM_SUCCESS) {
>> +        prlog(PR_ERR, "Encode GetPLDMCommands Error, rc: %d\n", rc);
>> +        cc_resp(req, req->hdrinf.pldm_type,
>> +            req->hdrinf.command, PLDM_ERROR);
>> +        return OPAL_PARAMETER;
>> +    }
>> +
>> +    /* send PLDM message over MCTP */
>> +    rc = pldm_mctp_message_tx(req->source_eid, response_msg, 
>> sizeof(response_msg));
>> +    if (rc) {
>> +        prlog(PR_ERR, "Failed to send GetPLDMCommands response, rc = 
>> %d\n", rc);
>> +        return OPAL_HARDWARE;
>> +    }
>> +
>> +    return OPAL_SUCCESS;
>> +}
>> +
>> +static struct pldm_cmd pldm_base_get_commands = {
>> +    .name = "PLDM_GET_PLDM_COMMANDS",
>> +    .pldm_cmd_id = PLDM_GET_PLDM_COMMANDS,
>> +    .handler = base_get_commands_handler,
>> +};
>> +
>>   int pldm_responder_handle_request(struct pldm_rx_data *rx)
>>   {
>>       const struct pldm_type *type;
>> @@ -242,6 +331,7 @@ int pldm_responder_init(void)
>>       add_type(&pldm_base_type);
>>       add_cmd(&pldm_base_type, &pldm_base_get_tid);
>>       add_cmd(&pldm_base_type, &pldm_base_get_types);
>> +    add_cmd(&pldm_base_type, &pldm_base_get_commands);
>>         return OPAL_SUCCESS;
>>   }
diff mbox series

Patch

diff --git a/core/pldm/pldm-responder.c b/core/pldm/pldm-responder.c
index 6058af51..88545685 100644
--- a/core/pldm/pldm-responder.c
+++ b/core/pldm/pldm-responder.c
@@ -205,6 +205,95 @@  static struct pldm_cmd pldm_base_get_types = {
 	.handler = base_get_types_handler,
 };
 
+/*
+ * Extended error codes defined for the Base command set.
+ */
+#define INVALID_PLDM_TYPE_IN_REQUEST_DATA      0x83
+#define INVALID_PLDM_VERSION_IN_REQUEST_DATA   0x84
+
+/*
+ * GetPLDMCommands (0x05)
+ * The GetPLDMCommands command can be used to discover the PLDM command
+ * capabilities supported by aPLDM terminus for a specific PLDM Type and
+ * version as a responder.
+ */
+static int base_get_commands_handler(const struct pldm_rx_data *req)
+{
+	char response_msg[PKT_SIZE(struct pldm_get_commands_resp)];
+	bitmap_elem_t cmd_map[BITMAP_ELEMS(256)];
+	const struct pldm_type *type;
+	const struct pldm_cmd *iter;
+	size_t payload_len;
+	ver32_t version;
+	uint8_t type_id;
+	int rc;
+
+	payload_len = req->msg_len - sizeof(struct pldm_msg_hdr);
+	rc = decode_get_commands_req(req->msg, payload_len,
+				     &type_id, &version);
+	if (rc) {
+		prlog(PR_ERR, "Failed to decode GetPLDMCommands request, rc = %d", rc);
+		cc_resp(req, req->hdrinf.pldm_type,
+			req->hdrinf.command, PLDM_ERROR);
+		return OPAL_INTERNAL_ERROR;
+	}
+
+	type = find_type(type_id);
+	if (!type) {
+		cc_resp(req, req->hdrinf.pldm_type,
+			req->hdrinf.command,
+			INVALID_PLDM_TYPE_IN_REQUEST_DATA);
+		return OPAL_PARAMETER;
+	}
+
+	if (memcmp(&type->version, &version, sizeof(version))) {
+		cc_resp(req, req->hdrinf.pldm_type,
+			req->hdrinf.command,
+			INVALID_PLDM_VERSION_IN_REQUEST_DATA);
+		return OPAL_PARAMETER;
+	}
+
+	/*
+	* build the supported type list from the registered type
+	* handlers
+	*/
+	memset(cmd_map, 0, sizeof(cmd_map));
+	list_for_each(&type->commands, iter, link)
+		bitmap_set_bit(cmd_map, iter->pldm_cmd_id);
+	/* fix the endian */
+	for (int i = 0; i < BITMAP_ELEMS(256); i++)
+		cmd_map[i] = cpu_to_le64(cmd_map[i]);
+
+	memset(response_msg, 0, sizeof(response_msg));
+
+	/* create a PLDM response message for GetPLDMCommands */
+	rc = encode_get_commands_resp(req->hdrinf.instance,
+				      PLDM_SUCCESS,
+				      (bitfield8_t *)cmd_map,
+				      (struct pldm_msg *)response_msg);
+	if (rc != PLDM_SUCCESS) {
+		prlog(PR_ERR, "Encode GetPLDMCommands Error, rc: %d\n", rc);
+		cc_resp(req, req->hdrinf.pldm_type,
+			req->hdrinf.command, PLDM_ERROR);
+		return OPAL_PARAMETER;
+	}
+
+	/* send PLDM message over MCTP */
+	rc = pldm_mctp_message_tx(req->source_eid, response_msg, sizeof(response_msg));
+	if (rc) {
+		prlog(PR_ERR, "Failed to send GetPLDMCommands response, rc = %d\n", rc);
+		return OPAL_HARDWARE;
+	}
+
+	return OPAL_SUCCESS;
+}
+
+static struct pldm_cmd pldm_base_get_commands = {
+	.name = "PLDM_GET_PLDM_COMMANDS",
+	.pldm_cmd_id = PLDM_GET_PLDM_COMMANDS,
+	.handler = base_get_commands_handler,
+};
+
 int pldm_responder_handle_request(struct pldm_rx_data *rx)
 {
 	const struct pldm_type *type;
@@ -242,6 +331,7 @@  int pldm_responder_init(void)
 	add_type(&pldm_base_type);
 	add_cmd(&pldm_base_type, &pldm_base_get_tid);
 	add_cmd(&pldm_base_type, &pldm_base_get_types);
+	add_cmd(&pldm_base_type, &pldm_base_get_commands);
 
 	return OPAL_SUCCESS;
 }