| /* |
| * SPDX-FileCopyrightText: Copyright (c) 2023-2024 NVIDIA CORPORATION & |
| * AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "debug-token.h" |
| |
| #include <endian.h> |
| #include <string.h> |
| |
| int decode_nsm_query_token_parameters_req( |
| const struct nsm_msg *msg, size_t msg_len, |
| enum nsm_debug_token_opcode *token_opcode) |
| { |
| if (msg == NULL || token_opcode == NULL) { |
| return NSM_SW_ERROR_NULL; |
| } |
| if (msg_len < sizeof(struct nsm_msg_hdr) + |
| sizeof(struct nsm_query_token_parameters_req)) { |
| return NSM_SW_ERROR_LENGTH; |
| } |
| |
| struct nsm_query_token_parameters_req *request = |
| (struct nsm_query_token_parameters_req *)msg->payload; |
| if (request->hdr.data_size < sizeof(request->token_opcode)) { |
| return NSM_SW_ERROR_DATA; |
| } |
| *token_opcode = request->token_opcode; |
| |
| return NSM_SW_SUCCESS; |
| } |
| |
| int encode_nsm_query_token_parameters_req( |
| uint8_t instance_id, enum nsm_debug_token_opcode token_opcode, |
| struct nsm_msg *msg) |
| { |
| if (msg == NULL) { |
| return NSM_SW_ERROR_NULL; |
| } |
| if (token_opcode != NSM_DEBUG_TOKEN_OPCODE_RMCS && |
| token_opcode != NSM_DEBUG_TOKEN_OPCODE_RMDT && |
| token_opcode != NSM_DEBUG_TOKEN_OPCODE_CRCS && |
| token_opcode != NSM_DEBUG_TOKEN_OPCODE_CRDT && |
| token_opcode != NSM_DEBUG_TOKEN_OPCODE_LINKX_FRC) { |
| return NSM_SW_ERROR_DATA; |
| } |
| |
| struct nsm_header_info header = {0}; |
| header.nsm_msg_type = NSM_REQUEST; |
| header.instance_id = instance_id; |
| header.nvidia_msg_type = NSM_TYPE_DIAGNOSTIC; |
| |
| uint8_t rc = pack_nsm_header(&header, &msg->hdr); |
| if (rc != NSM_SW_SUCCESS) { |
| return rc; |
| } |
| |
| struct nsm_query_token_parameters_req *request = |
| (struct nsm_query_token_parameters_req *)msg->payload; |
| request->hdr.command = NSM_QUERY_TOKEN_PARAMETERS; |
| request->hdr.data_size = 1; |
| request->token_opcode = token_opcode; |
| |
| return NSM_SW_SUCCESS; |
| } |
| |
| int decode_nsm_query_token_parameters_resp( |
| const struct nsm_msg *msg, size_t msg_len, uint8_t *cc, |
| uint16_t *reason_code, struct nsm_debug_token_request *token_request) |
| { |
| if (msg == NULL || token_request == NULL) { |
| return NSM_SW_ERROR_NULL; |
| } |
| |
| int rc = decode_reason_code_and_cc(msg, msg_len, cc, reason_code); |
| if (rc != NSM_SW_SUCCESS || *cc != NSM_SUCCESS) { |
| return rc; |
| } |
| |
| if (msg_len < sizeof(struct nsm_msg_hdr) + |
| sizeof(struct nsm_query_token_parameters_resp)) { |
| return NSM_SW_ERROR_LENGTH; |
| } |
| |
| struct nsm_query_token_parameters_resp *resp = |
| (struct nsm_query_token_parameters_resp *)msg->payload; |
| if (resp->token_request.token_request_size != |
| sizeof(struct nsm_debug_token_request)) { |
| return NSM_SW_ERROR_DATA; |
| } |
| *token_request = resp->token_request; |
| |
| return NSM_SW_SUCCESS; |
| } |
| |
| int encode_nsm_query_token_parameters_resp( |
| uint8_t instance_id, uint8_t cc, uint16_t reason_code, |
| struct nsm_debug_token_request *token_request, struct nsm_msg *msg) |
| { |
| if (msg == NULL) { |
| return NSM_SW_ERROR_NULL; |
| } |
| |
| struct nsm_header_info header = {0}; |
| header.nsm_msg_type = NSM_RESPONSE; |
| header.instance_id = instance_id; |
| header.nvidia_msg_type = NSM_TYPE_DIAGNOSTIC; |
| |
| uint8_t rc = pack_nsm_header(&header, &msg->hdr); |
| if (rc != NSM_SW_SUCCESS) { |
| return rc; |
| } |
| |
| if (cc != NSM_SUCCESS) { |
| return encode_reason_code(cc, reason_code, |
| NSM_QUERY_TOKEN_PARAMETERS, msg); |
| } |
| |
| struct nsm_query_token_parameters_resp *response = |
| (struct nsm_query_token_parameters_resp *)msg->payload; |
| response->hdr.command = NSM_QUERY_TOKEN_PARAMETERS; |
| response->hdr.completion_code = cc; |
| response->hdr.data_size = |
| htole16(sizeof(struct nsm_debug_token_request)); |
| response->token_request = *token_request; |
| |
| return NSM_SW_SUCCESS; |
| } |
| |
| int decode_nsm_provide_token_req(const struct nsm_msg *msg, size_t msg_len, |
| uint8_t *token_data, uint8_t *token_data_len) |
| { |
| if (msg == NULL || token_data == NULL || token_data_len == NULL) { |
| return NSM_SW_ERROR_NULL; |
| } |
| if (msg_len < |
| sizeof(struct nsm_msg_hdr) + sizeof(struct nsm_provide_token_req)) { |
| return NSM_SW_ERROR_LENGTH; |
| } |
| |
| struct nsm_provide_token_req *request = |
| (struct nsm_provide_token_req *)msg->payload; |
| if (request->hdr.data_size == 0) { |
| return NSM_SW_ERROR_DATA; |
| } |
| memcpy(token_data, request->token_data, request->hdr.data_size); |
| *token_data_len = request->hdr.data_size; |
| |
| return NSM_SW_SUCCESS; |
| } |
| |
| int encode_nsm_provide_token_req(uint8_t instance_id, const uint8_t *token_data, |
| const uint16_t token_data_len, |
| struct nsm_msg *msg) |
| { |
| if (msg == NULL || token_data == NULL) { |
| return NSM_SW_ERROR_NULL; |
| } |
| if (token_data_len == 0) { |
| return NSM_SW_ERROR_DATA; |
| } |
| |
| struct nsm_header_info header = {0}; |
| header.nsm_msg_type = NSM_REQUEST; |
| header.instance_id = instance_id; |
| header.nvidia_msg_type = NSM_TYPE_DIAGNOSTIC; |
| |
| uint8_t rc = pack_nsm_header_v2(&header, &msg->hdr); |
| if (rc != NSM_SW_SUCCESS) { |
| return rc; |
| } |
| |
| struct nsm_provide_token_req *request = |
| (struct nsm_provide_token_req *)msg->payload; |
| request->hdr.command = NSM_PROVIDE_TOKEN; |
| request->hdr.data_size = htole16(token_data_len); |
| memcpy(request->token_data, token_data, token_data_len); |
| |
| return NSM_SW_SUCCESS; |
| } |
| |
| int decode_nsm_provide_token_resp(const struct nsm_msg *msg, size_t msg_len, |
| uint8_t *cc, uint16_t *reason_code) |
| { |
| if (msg == NULL || cc == NULL || reason_code == NULL) { |
| return NSM_SW_ERROR_NULL; |
| } |
| |
| int rc = decode_reason_code_and_cc(msg, msg_len, cc, reason_code); |
| if (rc != NSM_SW_SUCCESS || *cc != NSM_SUCCESS) { |
| return rc; |
| } |
| |
| if (msg_len < |
| sizeof(struct nsm_msg_hdr) + sizeof(nsm_provide_token_resp)) { |
| return NSM_SW_ERROR_LENGTH; |
| } |
| |
| return NSM_SW_SUCCESS; |
| } |
| |
| int encode_nsm_provide_token_resp(uint8_t instance_id, uint8_t cc, |
| uint16_t reason_code, struct nsm_msg *msg) |
| { |
| if (msg == NULL) { |
| return NSM_SW_ERROR_NULL; |
| } |
| |
| struct nsm_header_info header = {0}; |
| header.nsm_msg_type = NSM_RESPONSE; |
| header.instance_id = instance_id; |
| header.nvidia_msg_type = NSM_TYPE_DIAGNOSTIC; |
| |
| uint8_t rc = pack_nsm_header(&header, &msg->hdr); |
| if (rc != NSM_SW_SUCCESS) { |
| return rc; |
| } |
| |
| if (cc != NSM_SUCCESS) { |
| return encode_reason_code(cc, reason_code, NSM_PROVIDE_TOKEN, |
| msg); |
| } |
| |
| struct nsm_query_token_parameters_resp *response = |
| (struct nsm_query_token_parameters_resp *)msg->payload; |
| response->hdr.command = NSM_PROVIDE_TOKEN; |
| response->hdr.completion_code = cc; |
| response->hdr.data_size = 0; |
| |
| return NSM_SW_SUCCESS; |
| } |
| |
| int decode_nsm_disable_tokens_req(const struct nsm_msg *msg, size_t msg_len) |
| { |
| if (msg == NULL) { |
| return NSM_SW_ERROR_NULL; |
| } |
| if (msg_len < |
| sizeof(struct nsm_msg_hdr) + sizeof(nsm_disable_tokens_req)) { |
| return NSM_SW_ERROR_LENGTH; |
| } |
| |
| return NSM_SW_SUCCESS; |
| } |
| |
| int encode_nsm_disable_tokens_req(uint8_t instance_id, struct nsm_msg *msg) |
| { |
| if (msg == NULL) { |
| return NSM_SW_ERROR_NULL; |
| } |
| |
| struct nsm_header_info header = {0}; |
| header.nsm_msg_type = NSM_REQUEST; |
| header.instance_id = instance_id; |
| header.nvidia_msg_type = NSM_TYPE_DIAGNOSTIC; |
| |
| uint8_t rc = pack_nsm_header(&header, &msg->hdr); |
| if (rc != NSM_SW_SUCCESS) { |
| return rc; |
| } |
| |
| nsm_disable_tokens_req *request = |
| (nsm_disable_tokens_req *)msg->payload; |
| request->command = NSM_DISABLE_TOKENS; |
| request->data_size = 0; |
| |
| return NSM_SW_SUCCESS; |
| } |
| |
| int decode_nsm_disable_tokens_resp(const struct nsm_msg *msg, size_t msg_len, |
| uint8_t *cc, uint16_t *reason_code) |
| { |
| if (msg == NULL || cc == NULL || reason_code == NULL) { |
| return NSM_SW_ERROR_NULL; |
| } |
| |
| int rc = decode_reason_code_and_cc(msg, msg_len, cc, reason_code); |
| if (rc != NSM_SW_SUCCESS || *cc != NSM_SUCCESS) { |
| return rc; |
| } |
| |
| if (msg_len < |
| sizeof(struct nsm_msg_hdr) + sizeof(nsm_disable_tokens_resp)) { |
| return NSM_SW_ERROR_LENGTH; |
| } |
| |
| return NSM_SW_SUCCESS; |
| } |
| |
| int encode_nsm_disable_tokens_resp(uint8_t instance_id, uint8_t cc, |
| uint16_t reason_code, struct nsm_msg *msg) |
| { |
| if (msg == NULL) { |
| return NSM_SW_ERROR_NULL; |
| } |
| |
| struct nsm_header_info header = {0}; |
| header.nsm_msg_type = NSM_RESPONSE; |
| header.instance_id = instance_id; |
| header.nvidia_msg_type = NSM_TYPE_DIAGNOSTIC; |
| |
| uint8_t rc = pack_nsm_header(&header, &msg->hdr); |
| if (rc != NSM_SW_SUCCESS) { |
| return rc; |
| } |
| |
| if (cc != NSM_SUCCESS) { |
| return encode_reason_code(cc, reason_code, NSM_DISABLE_TOKENS, |
| msg); |
| } |
| |
| struct nsm_query_token_parameters_resp *response = |
| (struct nsm_query_token_parameters_resp *)msg->payload; |
| response->hdr.command = NSM_DISABLE_TOKENS; |
| response->hdr.completion_code = cc; |
| response->hdr.data_size = 0; |
| |
| return NSM_SW_SUCCESS; |
| } |
| |
| int decode_nsm_query_token_status_req(const struct nsm_msg *msg, size_t msg_len, |
| enum nsm_debug_token_type *token_type) |
| { |
| if (msg == NULL || token_type == NULL) { |
| return NSM_SW_ERROR_NULL; |
| } |
| if (msg_len < sizeof(struct nsm_msg_hdr) + |
| sizeof(struct nsm_query_token_status_req)) { |
| return NSM_SW_ERROR_LENGTH; |
| } |
| |
| struct nsm_query_token_status_req *request = |
| (struct nsm_query_token_status_req *)msg->payload; |
| if (request->hdr.data_size < sizeof(request->token_type)) { |
| return NSM_SW_ERROR_DATA; |
| } |
| *token_type = request->token_type; |
| |
| return NSM_SW_SUCCESS; |
| } |
| |
| int encode_nsm_query_token_status_req(uint8_t instance_id, |
| enum nsm_debug_token_type token_type, |
| struct nsm_msg *msg) |
| { |
| if (msg == NULL) { |
| return NSM_SW_ERROR_NULL; |
| } |
| if (token_type != NSM_DEBUG_TOKEN_TYPE_FRC && |
| token_type != NSM_DEBUG_TOKEN_TYPE_CRCS && |
| token_type != NSM_DEBUG_TOKEN_TYPE_CRDT && |
| token_type != NSM_DEBUG_TOKEN_TYPE_DEBUG_FIRMWARE) { |
| return NSM_SW_ERROR_DATA; |
| } |
| |
| struct nsm_header_info header = {0}; |
| header.nsm_msg_type = NSM_REQUEST; |
| header.instance_id = instance_id; |
| header.nvidia_msg_type = NSM_TYPE_DIAGNOSTIC; |
| |
| uint8_t rc = pack_nsm_header(&header, &msg->hdr); |
| if (rc != NSM_SW_SUCCESS) { |
| return rc; |
| } |
| |
| struct nsm_query_token_status_req *request = |
| (struct nsm_query_token_status_req *)msg->payload; |
| request->hdr.command = NSM_QUERY_TOKEN_STATUS; |
| request->hdr.data_size = 1; |
| request->token_type = token_type; |
| |
| return NSM_SW_SUCCESS; |
| } |
| |
| int decode_nsm_query_token_status_resp( |
| const struct nsm_msg *msg, size_t msg_len, uint8_t *cc, |
| uint16_t *reason_code, enum nsm_debug_token_status *status, |
| enum nsm_debug_token_status_additional_info *additional_info, |
| enum nsm_debug_token_type *token_type, uint32_t *time_left) |
| { |
| if (msg == NULL || status == NULL || additional_info == NULL || |
| token_type == NULL || time_left == NULL) { |
| return NSM_SW_ERROR_NULL; |
| } |
| |
| int rc = decode_reason_code_and_cc(msg, msg_len, cc, reason_code); |
| if (rc != NSM_SW_SUCCESS || *cc != NSM_SUCCESS) { |
| return rc; |
| } |
| |
| if (msg_len < sizeof(struct nsm_msg_hdr) + |
| sizeof(struct nsm_query_token_status_resp)) { |
| return NSM_SW_ERROR_LENGTH; |
| } |
| |
| struct nsm_query_token_status_resp *resp = |
| (struct nsm_query_token_status_resp *)msg->payload; |
| *status = resp->status; |
| *additional_info = resp->additional_info; |
| *token_type = resp->token_type; |
| *time_left = resp->time_left; |
| |
| return NSM_SW_SUCCESS; |
| } |
| |
| int encode_nsm_query_token_status_resp( |
| uint8_t instance_id, uint8_t cc, uint16_t reason_code, |
| enum nsm_debug_token_status status, |
| enum nsm_debug_token_status_additional_info additional_info, |
| enum nsm_debug_token_type token_type, uint32_t time_left, |
| struct nsm_msg *msg) |
| { |
| if (msg == NULL) { |
| return NSM_SW_ERROR_NULL; |
| } |
| |
| struct nsm_header_info header = {0}; |
| header.nsm_msg_type = NSM_RESPONSE; |
| header.instance_id = instance_id; |
| header.nvidia_msg_type = NSM_TYPE_DIAGNOSTIC; |
| |
| uint8_t rc = pack_nsm_header(&header, &msg->hdr); |
| if (rc != NSM_SW_SUCCESS) { |
| return rc; |
| } |
| |
| if (cc != NSM_SUCCESS) { |
| return encode_reason_code(cc, reason_code, |
| NSM_QUERY_TOKEN_STATUS, msg); |
| } |
| |
| struct nsm_query_token_status_resp *response = |
| (struct nsm_query_token_status_resp *)msg->payload; |
| response->hdr.command = NSM_QUERY_TOKEN_STATUS; |
| response->hdr.completion_code = cc; |
| response->hdr.data_size = |
| htole16(sizeof(status) + sizeof(additional_info) + |
| sizeof(token_type) + sizeof(time_left)); |
| response->status = status; |
| response->additional_info = additional_info; |
| response->token_type = token_type; |
| response->time_left = time_left; |
| |
| return NSM_SW_SUCCESS; |
| } |
| |
| int decode_nsm_query_device_ids_req(const struct nsm_msg *msg, size_t msg_len) |
| { |
| if (msg == NULL) { |
| return NSM_SW_ERROR_NULL; |
| } |
| if (msg_len < |
| sizeof(struct nsm_msg_hdr) + sizeof(nsm_query_device_ids_req)) { |
| return NSM_SW_ERROR_LENGTH; |
| } |
| |
| return NSM_SW_SUCCESS; |
| } |
| |
| int encode_nsm_query_device_ids_req(uint8_t instance_id, struct nsm_msg *msg) |
| { |
| if (msg == NULL) { |
| return NSM_SW_ERROR_DATA; |
| } |
| |
| struct nsm_header_info header = {0}; |
| header.nsm_msg_type = NSM_REQUEST; |
| header.instance_id = instance_id; |
| header.nvidia_msg_type = NSM_TYPE_DIAGNOSTIC; |
| |
| uint8_t rc = pack_nsm_header(&header, &msg->hdr); |
| if (rc != NSM_SW_SUCCESS) { |
| return rc; |
| } |
| |
| nsm_query_device_ids_req *request = |
| (nsm_query_device_ids_req *)msg->payload; |
| request->command = NSM_QUERY_DEVICE_IDS; |
| request->data_size = 0; |
| |
| return NSM_SW_SUCCESS; |
| } |
| |
| int decode_nsm_query_device_ids_resp(const struct nsm_msg *msg, size_t msg_len, |
| uint8_t *cc, uint16_t *reason_code, |
| uint8_t *device_id, size_t *device_id_len) |
| { |
| if (msg == NULL || cc == NULL || reason_code == NULL || |
| device_id_len == NULL) { |
| return NSM_SW_ERROR_NULL; |
| } |
| |
| int rc = decode_reason_code_and_cc(msg, msg_len, cc, reason_code); |
| if (rc != NSM_SW_SUCCESS || *cc != NSM_SUCCESS) { |
| return rc; |
| } |
| |
| if (msg_len < sizeof(struct nsm_msg_hdr) + |
| sizeof(struct nsm_query_device_ids_resp)) { |
| return NSM_SW_ERROR_LENGTH; |
| } |
| |
| struct nsm_query_device_ids_resp *resp = |
| (struct nsm_query_device_ids_resp *)msg->payload; |
| *device_id_len = le16toh(resp->hdr.data_size); |
| if (device_id != NULL) { |
| memcpy(device_id, resp->data, *device_id_len); |
| } |
| |
| return NSM_SW_SUCCESS; |
| } |
| |
| int encode_nsm_query_device_ids_resp(uint8_t instance_id, uint8_t cc, |
| uint16_t reason_code, |
| const uint8_t *device_id, |
| size_t device_id_len, struct nsm_msg *msg) |
| { |
| if (msg == NULL || device_id == NULL) { |
| return NSM_SW_ERROR_NULL; |
| } |
| if (device_id_len == 0) { |
| return NSM_SW_ERROR_LENGTH; |
| } |
| |
| struct nsm_header_info header = {0}; |
| header.nsm_msg_type = NSM_RESPONSE; |
| header.instance_id = instance_id; |
| header.nvidia_msg_type = NSM_TYPE_DIAGNOSTIC; |
| |
| uint8_t rc = pack_nsm_header(&header, &msg->hdr); |
| if (rc != NSM_SW_SUCCESS) { |
| return rc; |
| } |
| |
| if (cc != NSM_SUCCESS) { |
| return encode_reason_code(cc, reason_code, NSM_QUERY_DEVICE_IDS, |
| msg); |
| } |
| |
| struct nsm_query_device_ids_resp *response = |
| (struct nsm_query_device_ids_resp *)msg->payload; |
| response->hdr.command = NSM_QUERY_DEVICE_IDS; |
| response->hdr.completion_code = cc; |
| response->hdr.data_size = htole16(device_id_len); |
| memcpy(response->data, device_id, device_id_len); |
| |
| return NSM_SW_SUCCESS; |
| } |
| |
| int decode_nsm_install_token_req(const struct nsm_msg *msg, size_t msg_len, |
| uint32_t *chunk_offset, uint32_t *chunk_length, |
| uint32_t *length_remaining, uint8_t *data) |
| { |
| if (msg == NULL || chunk_offset == NULL || chunk_length == NULL || |
| length_remaining == NULL) { |
| return NSM_SW_ERROR_NULL; |
| } |
| if (msg_len < |
| sizeof(struct nsm_msg_hdr) + sizeof(struct nsm_install_token_req)) { |
| return NSM_SW_ERROR_LENGTH; |
| } |
| |
| struct nsm_install_token_req *request = |
| (struct nsm_install_token_req *)msg->payload; |
| if (request->hdr.data_size < |
| sizeof(request->chunk_offset) + sizeof(request->chunk_length) + |
| sizeof(request->length_remaining) + sizeof(request->data)) { |
| return NSM_SW_ERROR_LENGTH; |
| } |
| *chunk_offset = le32toh(request->chunk_offset); |
| *chunk_length = le32toh(request->chunk_length); |
| *length_remaining = le32toh(request->length_remaining); |
| uint16_t expected_size = |
| sizeof(request->chunk_offset) + sizeof(request->chunk_length) + |
| sizeof(request->length_remaining) + *chunk_length; |
| if (request->hdr.data_size != expected_size) { |
| return NSM_SW_ERROR_LENGTH; |
| } |
| if (data != NULL) { |
| memcpy(data, request->data, *chunk_length); |
| } |
| |
| return NSM_SW_SUCCESS; |
| } |
| |
| int encode_nsm_install_token_req(uint8_t instance_id, uint32_t chunk_offset, |
| uint32_t chunk_length, |
| uint32_t length_remaining, const uint8_t *data, |
| struct nsm_msg *msg) |
| { |
| if (msg == NULL || data == NULL) { |
| return NSM_SW_ERROR_NULL; |
| } |
| |
| struct nsm_header_info header = {0}; |
| header.nsm_msg_type = NSM_REQUEST; |
| header.instance_id = instance_id; |
| header.nvidia_msg_type = NSM_TYPE_DIAGNOSTIC; |
| |
| uint8_t rc = pack_nsm_header_v2(&header, &msg->hdr); |
| if (rc != NSM_SW_SUCCESS) { |
| return rc; |
| } |
| |
| struct nsm_install_token_req *request = |
| (struct nsm_install_token_req *)msg->payload; |
| request->hdr.command = NSM_INSTALL_TOKEN; |
| request->hdr.data_size = |
| htole16(sizeof(chunk_offset) + sizeof(chunk_length) + |
| sizeof(length_remaining) + chunk_length); |
| request->chunk_offset = htole32(chunk_offset); |
| request->chunk_length = htole32(chunk_length); |
| request->length_remaining = htole32(length_remaining); |
| memcpy(request->data, data, chunk_length); |
| |
| return NSM_SW_SUCCESS; |
| } |
| |
| int decode_nsm_install_token_resp(const struct nsm_msg *msg, size_t msg_len, |
| uint8_t *cc, uint16_t *reason_code) |
| { |
| if (msg == NULL || cc == NULL || reason_code == NULL) { |
| return NSM_SW_ERROR_NULL; |
| } |
| |
| int rc = decode_reason_code_and_cc(msg, msg_len, cc, reason_code); |
| if (rc != NSM_SW_SUCCESS || *cc != NSM_SUCCESS) { |
| return rc; |
| } |
| |
| return NSM_SW_SUCCESS; |
| } |
| |
| int encode_nsm_install_token_resp(uint8_t instance_id, uint8_t cc, |
| uint16_t reason_code, struct nsm_msg *msg) |
| { |
| if (msg == NULL) { |
| return NSM_SW_ERROR_NULL; |
| } |
| |
| struct nsm_header_info header = {0}; |
| header.nsm_msg_type = NSM_RESPONSE; |
| header.instance_id = instance_id; |
| header.nvidia_msg_type = NSM_TYPE_DIAGNOSTIC; |
| |
| uint8_t rc = pack_nsm_header(&header, &msg->hdr); |
| if (rc != NSM_SW_SUCCESS) { |
| return rc; |
| } |
| |
| if (cc != NSM_SUCCESS) { |
| return encode_reason_code(cc, reason_code, NSM_INSTALL_TOKEN, |
| msg); |
| } |
| |
| nsm_install_token_resp *response = |
| (nsm_install_token_resp *)msg->payload; |
| response->command = NSM_INSTALL_TOKEN; |
| response->completion_code = cc; |
| response->data_size = 0; |
| |
| return NSM_SW_SUCCESS; |
| } |
| |
| int decode_nsm_erase_token_req(const struct nsm_msg *msg, size_t msg_len, |
| uint32_t *token_type) |
| { |
| if (msg == NULL || token_type == NULL) { |
| return NSM_SW_ERROR_NULL; |
| } |
| if (msg_len < |
| sizeof(struct nsm_msg_hdr) + sizeof(struct nsm_erase_token_req)) { |
| return NSM_SW_ERROR_LENGTH; |
| } |
| |
| struct nsm_erase_token_req *request = |
| (struct nsm_erase_token_req *)msg->payload; |
| if (request->hdr.data_size != sizeof(request->token_type)) { |
| return NSM_SW_ERROR_DATA; |
| } |
| *token_type = le32toh(request->token_type); |
| |
| return NSM_SW_SUCCESS; |
| } |
| |
| int encode_nsm_erase_token_req(uint8_t instance_id, uint32_t token_type, |
| struct nsm_msg *msg) |
| { |
| if (msg == NULL) { |
| return NSM_SW_ERROR_NULL; |
| } |
| |
| struct nsm_header_info header = {0}; |
| header.nsm_msg_type = NSM_REQUEST; |
| header.instance_id = instance_id; |
| header.nvidia_msg_type = NSM_TYPE_DIAGNOSTIC; |
| |
| uint8_t rc = pack_nsm_header(&header, &msg->hdr); |
| if (rc != NSM_SW_SUCCESS) { |
| return rc; |
| } |
| |
| struct nsm_erase_token_req *request = |
| (struct nsm_erase_token_req *)msg->payload; |
| request->hdr.command = NSM_ERASE_TOKEN; |
| request->hdr.data_size = htole16(sizeof(token_type)); |
| request->token_type = htole32(token_type); |
| |
| return NSM_SW_SUCCESS; |
| } |
| |
| int decode_nsm_erase_token_resp(const struct nsm_msg *msg, size_t msg_len, |
| uint8_t *cc, uint16_t *reason_code) |
| { |
| if (msg == NULL || cc == NULL || reason_code == NULL) { |
| return NSM_SW_ERROR_NULL; |
| } |
| |
| int rc = decode_reason_code_and_cc(msg, msg_len, cc, reason_code); |
| if (rc != NSM_SW_SUCCESS || *cc != NSM_SUCCESS) { |
| return rc; |
| } |
| |
| return NSM_SW_SUCCESS; |
| } |
| |
| int encode_nsm_erase_token_resp(uint8_t instance_id, uint8_t cc, |
| uint16_t reason_code, struct nsm_msg *msg) |
| { |
| if (msg == NULL) { |
| return NSM_SW_ERROR_NULL; |
| } |
| |
| struct nsm_header_info header = {0}; |
| header.nsm_msg_type = NSM_RESPONSE; |
| header.instance_id = instance_id; |
| header.nvidia_msg_type = NSM_TYPE_DIAGNOSTIC; |
| |
| uint8_t rc = pack_nsm_header(&header, &msg->hdr); |
| if (rc != NSM_SW_SUCCESS) { |
| return rc; |
| } |
| |
| if (cc != NSM_SUCCESS) { |
| return encode_reason_code(cc, reason_code, NSM_ERASE_TOKEN, |
| msg); |
| } |
| |
| nsm_erase_token_resp *response = (nsm_erase_token_resp *)msg->payload; |
| response->command = NSM_ERASE_TOKEN; |
| response->completion_code = cc; |
| response->data_size = 0; |
| |
| return NSM_SW_SUCCESS; |
| } |
| |
| int decode_nsm_query_token_req(const struct nsm_msg *msg, size_t msg_len) |
| { |
| if (msg == NULL) { |
| return NSM_SW_ERROR_NULL; |
| } |
| if (msg_len < |
| sizeof(struct nsm_msg_hdr) + sizeof(nsm_query_token_req)) { |
| return NSM_SW_ERROR_LENGTH; |
| } |
| |
| nsm_query_token_req *request = (nsm_query_token_req *)msg->payload; |
| if (request->data_size != 0) { |
| return NSM_SW_ERROR_DATA; |
| } |
| |
| return NSM_SW_SUCCESS; |
| } |
| |
| int encode_nsm_query_token_req(uint8_t instance_id, struct nsm_msg *msg) |
| { |
| if (msg == NULL) { |
| return NSM_SW_ERROR_NULL; |
| } |
| |
| struct nsm_header_info header = {0}; |
| header.nsm_msg_type = NSM_REQUEST; |
| header.instance_id = instance_id; |
| header.nvidia_msg_type = NSM_TYPE_DIAGNOSTIC; |
| |
| uint8_t rc = pack_nsm_header(&header, &msg->hdr); |
| if (rc != NSM_SW_SUCCESS) { |
| return rc; |
| } |
| |
| nsm_query_token_req *request = (nsm_query_token_req *)msg->payload; |
| request->command = NSM_QUERY_TOKEN; |
| request->data_size = 0; |
| |
| return NSM_SW_SUCCESS; |
| } |
| |
| int decode_nsm_query_token_resp(const struct nsm_msg *msg, size_t msg_len, |
| uint8_t *cc, uint16_t *reason_code, |
| uint8_t *tlv_payload, size_t *tlv_payload_len) |
| { |
| if (msg == NULL || cc == NULL || reason_code == NULL || |
| tlv_payload_len == NULL) { |
| return NSM_SW_ERROR_NULL; |
| } |
| |
| int rc = decode_reason_code_and_cc(msg, msg_len, cc, reason_code); |
| if (rc != NSM_SW_SUCCESS || *cc != NSM_SUCCESS) { |
| return rc; |
| } |
| |
| if (msg_len < |
| sizeof(struct nsm_msg_hdr) + sizeof(struct nsm_query_token_resp)) { |
| return NSM_SW_ERROR_LENGTH; |
| } |
| |
| struct nsm_query_token_resp *resp = |
| (struct nsm_query_token_resp *)msg->payload; |
| if (resp->hdr.data_size == 0) { |
| return NSM_SW_ERROR_DATA; |
| } |
| *tlv_payload_len = resp->hdr.data_size; |
| if (tlv_payload != NULL) { |
| memcpy(tlv_payload, resp->tlv_payload, *tlv_payload_len); |
| } |
| |
| return NSM_SW_SUCCESS; |
| } |
| |
| int encode_nsm_query_token_resp(uint8_t instance_id, uint8_t cc, |
| uint16_t reason_code, |
| const uint8_t *tlv_payload, |
| size_t tlv_payload_len, struct nsm_msg *msg) |
| { |
| if (msg == NULL) { |
| return NSM_SW_ERROR_NULL; |
| } |
| |
| struct nsm_header_info header = {0}; |
| header.nsm_msg_type = NSM_RESPONSE; |
| header.instance_id = instance_id; |
| header.nvidia_msg_type = NSM_TYPE_DIAGNOSTIC; |
| |
| uint8_t rc = pack_nsm_header(&header, &msg->hdr); |
| if (rc != NSM_SW_SUCCESS) { |
| return rc; |
| } |
| |
| if (cc != NSM_SUCCESS) { |
| return encode_reason_code(cc, reason_code, NSM_QUERY_TOKEN, |
| msg); |
| } |
| |
| struct nsm_query_token_resp *response = |
| (struct nsm_query_token_resp *)msg->payload; |
| response->hdr.command = NSM_QUERY_TOKEN; |
| response->hdr.completion_code = cc; |
| response->hdr.data_size = htole16(tlv_payload_len); |
| memcpy(response->tlv_payload, tlv_payload, tlv_payload_len); |
| |
| return NSM_SW_SUCCESS; |
| } |