Coverage Report

Created: 2026-08-13 06:26

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/nsmd/libnsm/diagnostics.c
Line
Count
Source
1
/*
2
 * SPDX-FileCopyrightText: Copyright (c) 2023-2024 NVIDIA CORPORATION &
3
 * AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0
4
 *
5
 * Licensed under the Apache License, Version 2.0 (the "License");
6
 * you may not use this file except in compliance with the License.
7
 * You may obtain a copy of the License at
8
 *
9
 * http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17
18
#include "diagnostics.h"
19
#include <endian.h>
20
#include <stdio.h>
21
#include <string.h>
22
23
int encode_get_device_diagnostics_req(uint8_t instance_id, uint8_t segment_id,
24
              struct nsm_msg *msg)
25
0
{
26
0
  if (msg == NULL) {
27
0
    return NSM_SW_ERROR_NULL;
28
0
  }
29
30
0
  struct nsm_header_info header = {0};
31
0
  header.nsm_msg_type = NSM_REQUEST;
32
0
  header.instance_id = instance_id;
33
0
  header.nvidia_msg_type = NSM_TYPE_DIAGNOSTIC;
34
35
0
  uint8_t rc = pack_nsm_header(&header, &(msg->hdr));
36
0
  if (rc != NSM_SW_SUCCESS) {
37
0
    return rc;
38
0
  }
39
40
0
  struct nsm_get_device_diagnostics_req *request =
41
0
      (struct nsm_get_device_diagnostics_req *)msg->payload;
42
43
0
  request->hdr.command = NSM_GET_DEVICE_DIAGNOSTICS;
44
0
  request->hdr.data_size = sizeof(struct nsm_get_device_diagnostics_req) -
45
0
         sizeof(struct nsm_common_req);
46
0
  request->segment_id = segment_id;
47
0
  return NSM_SW_SUCCESS;
48
0
}
49
50
int decode_get_device_diagnostics_req(const struct nsm_msg *msg, size_t msg_len,
51
              uint8_t *segment_id)
52
0
{
53
0
  if (msg == NULL || segment_id == NULL) {
54
0
    return NSM_SW_ERROR_NULL;
55
0
  }
56
57
0
  if (msg_len != sizeof(struct nsm_msg_hdr) +
58
0
         sizeof(struct nsm_get_device_diagnostics_req)) {
59
0
    return NSM_SW_ERROR_LENGTH;
60
0
  }
61
62
0
  struct nsm_get_device_diagnostics_req *request =
63
0
      (struct nsm_get_device_diagnostics_req *)msg->payload;
64
65
0
  if (request->hdr.data_size !=
66
0
      sizeof(struct nsm_get_device_diagnostics_req) -
67
0
    sizeof(struct nsm_common_req)) {
68
0
    return NSM_SW_ERROR_DATA;
69
0
  }
70
71
0
  *segment_id = request->segment_id;
72
73
0
  return NSM_SW_SUCCESS;
74
0
}
75
76
int encode_get_device_diagnostics_resp(uint8_t instance_id, uint8_t cc,
77
               uint16_t reason_code,
78
               const uint8_t *seg_data,
79
               const uint16_t seg_data_size,
80
               const uint8_t next_segment_id,
81
               struct nsm_msg *msg)
82
0
{
83
0
  if (msg == NULL) {
84
0
    return NSM_SW_ERROR_NULL;
85
0
  }
86
87
0
  struct nsm_header_info header = {0};
88
0
  header.nsm_msg_type = NSM_RESPONSE;
89
0
  header.instance_id = instance_id & INSTANCEID_MASK;
90
0
  header.nvidia_msg_type = NSM_TYPE_DIAGNOSTIC;
91
92
0
  uint8_t rc = pack_nsm_header(&header, &(msg->hdr));
93
0
  if (rc != NSM_SW_SUCCESS) {
94
0
    return rc;
95
0
  }
96
97
0
  if (cc != NSM_SUCCESS) {
98
0
    return encode_reason_code(cc, reason_code,
99
0
            NSM_GET_DEVICE_DIAGNOSTICS, msg);
100
0
  }
101
102
0
  struct nsm_get_device_diagnostics_resp *response =
103
0
      (struct nsm_get_device_diagnostics_resp *)msg->payload;
104
105
0
  response->hdr.command = NSM_GET_DEVICE_DIAGNOSTICS;
106
0
  response->hdr.completion_code = cc;
107
0
  response->hdr.data_size =
108
0
      htole16(seg_data_size + sizeof(next_segment_id));
109
0
  response->next_segment_id = next_segment_id;
110
0
  memcpy(response->segment_data, seg_data, seg_data_size);
111
0
  return NSM_SW_SUCCESS;
112
0
}
113
114
int decode_get_device_diagnostics_resp(const struct nsm_msg *msg,
115
               size_t msg_len, uint8_t *cc,
116
               uint16_t *reason_code, uint8_t *seg_data,
117
               uint16_t *seg_data_size,
118
               uint8_t *next_segment_id)
119
0
{
120
0
  if (seg_data == NULL || seg_data_size == NULL ||
121
0
      next_segment_id == NULL) {
122
0
    return NSM_SW_ERROR_NULL;
123
0
  }
124
125
0
  int rc = decode_reason_code_and_cc(msg, msg_len, cc, reason_code);
126
0
  if (rc != NSM_SW_SUCCESS || *cc != NSM_SUCCESS) {
127
0
    return rc;
128
0
  }
129
130
0
  if (msg_len < sizeof(struct nsm_msg_hdr) +
131
0
        sizeof(struct nsm_common_resp) +
132
0
        sizeof(*next_segment_id)) {
133
0
    return NSM_SW_ERROR_LENGTH;
134
0
  }
135
136
0
  struct nsm_get_device_diagnostics_resp *response =
137
0
      (struct nsm_get_device_diagnostics_resp *)msg->payload;
138
139
0
  if (response->hdr.data_size < sizeof(*next_segment_id)) {
140
0
    return NSM_SW_ERROR_DATA;
141
0
  }
142
143
0
  *seg_data_size =
144
0
      response->hdr.data_size - sizeof(response->next_segment_id);
145
0
  *next_segment_id = response->next_segment_id;
146
0
  memcpy(seg_data, response->segment_data, *seg_data_size);
147
0
  return NSM_SW_SUCCESS;
148
0
}
149
150
int encode_reset_enum_data(uint8_t resetType, uint8_t *data, size_t *data_len)
151
0
{
152
0
  if (data == NULL || data_len == NULL) {
153
0
    return NSM_SW_ERROR_NULL;
154
0
  }
155
156
0
  *data = resetType; // Enum is 1 byte
157
0
  *data_len = sizeof(uint8_t);
158
159
0
  return NSM_SW_SUCCESS;
160
0
}
161
162
int encode_reset_count_data(uint16_t count, uint8_t *data, size_t *data_len)
163
0
{
164
0
  if (data == NULL || data_len == NULL) {
165
0
    return NSM_SW_ERROR_NULL;
166
0
  }
167
168
0
  uint16_t le_count = htole16(count);
169
0
  memcpy(data, &le_count, sizeof(uint16_t));
170
0
  *data_len = sizeof(uint16_t);
171
172
0
  return NSM_SW_SUCCESS;
173
0
}
174
175
int encode_reset_count_256data(const uint64_t *counter, uint8_t *data,
176
             size_t *data_len)
177
0
{
178
0
  if (data == NULL || data_len == NULL) {
179
0
    return NSM_SW_ERROR_NULL;
180
0
  }
181
182
0
  for (size_t i = 0; i < 4; i++) {
183
0
    uint64_t le_count = htole64(counter[i]);
184
0
    memcpy(data + i * sizeof(uint64_t), &le_count,
185
0
           sizeof(uint64_t));
186
0
  }
187
0
  *data_len = sizeof(uint64_t) * 4;
188
189
0
  return NSM_SW_SUCCESS;
190
0
}
191
192
int decode_reset_enum_data(const uint8_t *data, size_t data_len,
193
         uint8_t *resetType)
194
0
{
195
0
  if (data == NULL || resetType == NULL) {
196
0
    return NSM_SW_ERROR_NULL;
197
0
  }
198
199
0
  if (data_len != sizeof(uint8_t)) {
200
0
    return NSM_SW_ERROR_LENGTH;
201
0
  }
202
203
0
  *resetType = *data; // Enum is 1 byte
204
0
  return NSM_SW_SUCCESS;
205
0
}
206
207
int decode_reset_count_data(const uint8_t *data, size_t data_len,
208
          uint16_t *count)
209
0
{
210
0
  if (data == NULL || count == NULL) {
211
0
    return NSM_SW_ERROR_NULL;
212
0
  }
213
214
0
  if (data_len != sizeof(uint16_t)) {
215
0
    return NSM_SW_ERROR_LENGTH;
216
0
  }
217
218
0
  uint16_t le_count;
219
0
  memcpy(&le_count, data, sizeof(uint16_t));
220
0
  *count = le16toh(le_count);
221
222
0
  return NSM_SW_SUCCESS;
223
0
}
224
225
int decode_reset_count_256data(const uint8_t *data, size_t data_len,
226
             uint64_t *counter, size_t counter_len)
227
0
{
228
0
  if (data == NULL || counter == NULL || counter_len != 4) {
229
0
    return NSM_SW_ERROR_NULL;
230
0
  }
231
232
0
  if (data_len != sizeof(uint64_t) * counter_len) {
233
0
    return NSM_SW_ERROR_LENGTH;
234
0
  }
235
236
0
  for (size_t i = 0; i < counter_len; i++) {
237
0
    uint64_t le_count;
238
0
    memcpy(&le_count, data + i * sizeof(uint64_t),
239
0
           sizeof(uint64_t));
240
0
    counter[i] = le64toh(le_count);
241
0
  }
242
243
0
  return NSM_SW_SUCCESS;
244
0
}
245
246
int encode_get_device_reset_statistics_req(uint8_t instance_id,
247
             struct nsm_msg *msg)
248
0
{
249
0
  if (msg == NULL) {
250
0
    return NSM_SW_ERROR_NULL;
251
0
  }
252
253
0
  struct nsm_header_info header = {0};
254
0
  header.nsm_msg_type = NSM_REQUEST;
255
0
  header.instance_id = instance_id;
256
0
  header.nvidia_msg_type = NSM_TYPE_DIAGNOSTIC;
257
258
0
  uint8_t rc = pack_nsm_header(&header, &(msg->hdr));
259
0
  if (rc != NSM_SW_SUCCESS) {
260
0
    return rc;
261
0
  }
262
263
0
  struct nsm_common_req *request = (struct nsm_common_req *)msg->payload;
264
0
  request->command = NSM_GET_DEVICE_RESET_STATISTICS;
265
0
  request->data_size = 0; // No additional payload for the request
266
267
0
  return NSM_SW_SUCCESS;
268
0
}
269
270
int decode_get_device_reset_statistics_req(const struct nsm_msg *msg,
271
             size_t msg_len)
272
0
{
273
0
  if (msg == NULL) {
274
0
    return NSM_SW_ERROR_NULL;
275
0
  }
276
277
  // Validate message length
278
0
  if (msg_len <
279
0
      sizeof(struct nsm_msg_hdr) + sizeof(struct nsm_common_req)) {
280
0
    return NSM_SW_ERROR_LENGTH;
281
0
  }
282
283
  // Cast the payload to nsm_common_req structure
284
0
  const struct nsm_common_req *request =
285
0
      (const struct nsm_common_req *)msg->payload;
286
287
  // Validate that the data_size field in the common request is 0
288
  // (indicating no extra data)
289
0
  if (request->data_size != 0) {
290
0
    return NSM_SW_ERROR_DATA;
291
0
  }
292
293
0
  return NSM_SW_SUCCESS;
294
0
}
295
296
int encode_reset_network_device_req(uint8_t instance_id, uint8_t mode,
297
            struct nsm_msg *msg)
298
0
{
299
0
  if (msg == NULL) {
300
0
    return NSM_SW_ERROR_NULL;
301
0
  }
302
303
0
  struct nsm_header_info header = {0};
304
0
  header.nsm_msg_type = NSM_REQUEST;
305
0
  header.instance_id = instance_id;
306
0
  header.nvidia_msg_type = NSM_TYPE_DIAGNOSTIC;
307
308
0
  uint8_t rc = pack_nsm_header(&header, &(msg->hdr));
309
0
  if (rc != NSM_SW_SUCCESS) {
310
0
    return rc;
311
0
  }
312
313
0
  struct nsm_reset_network_device_req *request =
314
0
      (struct nsm_reset_network_device_req *)msg->payload;
315
316
0
  request->hdr.command = NSM_RESET_NETWORK_DEVICE;
317
0
  request->hdr.data_size = sizeof(mode);
318
0
  request->mode = mode;
319
320
0
  return NSM_SW_SUCCESS;
321
0
}
322
323
int decode_reset_network_device_req(const struct nsm_msg *msg, size_t msg_len,
324
            uint8_t *mode)
325
0
{
326
0
  if (msg == NULL || mode == NULL) {
327
0
    return NSM_SW_ERROR_NULL;
328
0
  }
329
330
0
  if (msg_len < sizeof(struct nsm_msg_hdr) +
331
0
        sizeof(struct nsm_reset_network_device_req)) {
332
0
    return NSM_SW_ERROR_LENGTH;
333
0
  }
334
335
0
  struct nsm_reset_network_device_req *request =
336
0
      (struct nsm_reset_network_device_req *)msg->payload;
337
338
0
  if (request->hdr.data_size < sizeof(request->mode)) {
339
0
    return NSM_SW_ERROR_DATA;
340
0
  }
341
342
0
  *mode = request->mode;
343
344
0
  return NSM_SW_SUCCESS;
345
0
}
346
347
int encode_reset_network_device_resp(uint8_t instance_id, uint16_t reason_code,
348
             struct nsm_msg *msg)
349
0
{
350
0
  return encode_cc_only_resp(instance_id, NSM_TYPE_DIAGNOSTIC,
351
0
           NSM_RESET_NETWORK_DEVICE, NSM_SUCCESS,
352
0
           reason_code, msg);
353
0
}
354
355
int decode_reset_network_device_resp(const struct nsm_msg *msg, size_t msgLen,
356
             uint8_t *cc, uint16_t *reason_code)
357
0
{
358
0
  int rc = decode_reason_code_and_cc(msg, msgLen, cc, reason_code);
359
0
  if (rc != NSM_SW_SUCCESS || *cc != NSM_SUCCESS) {
360
0
    return rc;
361
0
  }
362
363
0
  if (msgLen < sizeof(struct nsm_msg_hdr) +
364
0
       sizeof(nsm_reset_network_device_resp)) {
365
0
    return NSM_SW_ERROR_LENGTH;
366
0
  }
367
368
0
  nsm_reset_network_device_resp *resp =
369
0
      (nsm_reset_network_device_resp *)msg->payload;
370
0
  if (resp->data_size != 0) {
371
0
    return NSM_SW_ERROR_DATA;
372
0
  }
373
374
0
  return NSM_SW_SUCCESS;
375
0
}
376
377
int encode_enable_disable_wp_req(
378
    uint8_t instance_id,
379
    enum diagnostics_enable_disable_wp_data_index data_index, uint8_t value,
380
    struct nsm_msg *msg)
381
0
{
382
0
  if (msg == NULL) {
383
0
    return NSM_SW_ERROR_NULL;
384
0
  }
385
386
0
  struct nsm_header_info header = {0};
387
0
  header.nsm_msg_type = NSM_REQUEST;
388
0
  header.instance_id = instance_id;
389
0
  header.nvidia_msg_type = NSM_TYPE_DIAGNOSTIC;
390
391
0
  uint8_t rc = pack_nsm_header(&header, &(msg->hdr));
392
0
  if (rc != NSM_SW_SUCCESS) {
393
0
    return rc;
394
0
  }
395
396
0
  struct nsm_enable_disable_wp_req *request =
397
0
      (struct nsm_enable_disable_wp_req *)msg->payload;
398
399
0
  request->hdr.command = NSM_ENABLE_DISABLE_WP;
400
0
  request->hdr.data_size = 2;
401
0
  request->data_index = data_index;
402
0
  request->value = value;
403
404
0
  return NSM_SW_SUCCESS;
405
0
}
406
407
int decode_enable_disable_wp_req(
408
    const struct nsm_msg *msg, size_t msg_len,
409
    enum diagnostics_enable_disable_wp_data_index *data_index, uint8_t *value)
410
0
{
411
0
  if (msg == NULL || data_index == NULL || value == NULL) {
412
0
    return NSM_SW_ERROR_NULL;
413
0
  }
414
415
0
  if (msg_len < sizeof(struct nsm_msg_hdr) +
416
0
        sizeof(struct nsm_enable_disable_wp_req)) {
417
0
    return NSM_SW_ERROR_LENGTH;
418
0
  }
419
420
0
  struct nsm_enable_disable_wp_req *request =
421
0
      (struct nsm_enable_disable_wp_req *)msg->payload;
422
423
0
  if (request->hdr.data_size < sizeof(struct nsm_enable_disable_wp_req) -
424
0
           NSM_REQUEST_CONVENTION_LEN) {
425
0
    return NSM_SW_ERROR_DATA;
426
0
  }
427
428
0
  *data_index = request->data_index;
429
0
  *value = request->value;
430
0
  return NSM_SW_SUCCESS;
431
0
}
432
433
int encode_enable_disable_wp_resp(uint8_t instance_id, uint8_t cc,
434
          uint16_t reason_code, struct nsm_msg *msg)
435
0
{
436
0
  return encode_common_resp(instance_id, cc, reason_code,
437
0
          NSM_TYPE_DIAGNOSTIC, NSM_ENABLE_DISABLE_WP,
438
0
          msg);
439
0
}
440
441
int decode_enable_disable_wp_resp(const struct nsm_msg *msg, size_t msg_len,
442
          uint8_t *cc, uint16_t *reason_code)
443
0
{
444
0
  uint16_t data_size = 0;
445
0
  int rc = decode_common_resp(msg, msg_len, cc, &data_size, reason_code);
446
0
  if (data_size != 0) {
447
0
    return NSM_SW_ERROR_LENGTH;
448
0
  }
449
0
  return rc;
450
0
}
451
452
int encode_get_network_device_debug_info_req(uint8_t instance_id,
453
               uint8_t debug_type,
454
               uint32_t handle,
455
               struct nsm_msg *msg)
456
0
{
457
0
  if (msg == NULL) {
458
0
    return NSM_SW_ERROR_NULL;
459
0
  }
460
461
0
  struct nsm_header_info header = {0};
462
0
  header.nsm_msg_type = NSM_REQUEST;
463
0
  header.instance_id = instance_id;
464
0
  header.nvidia_msg_type = NSM_TYPE_DIAGNOSTIC;
465
466
0
  uint8_t rc = pack_nsm_header(&header, &(msg->hdr));
467
0
  if (rc != NSM_SW_SUCCESS) {
468
0
    return rc;
469
0
  }
470
471
0
  struct nsm_get_network_device_debug_info_req *request =
472
0
      (struct nsm_get_network_device_debug_info_req *)msg->payload;
473
474
0
  request->hdr.command = NSM_GET_NETWORK_DEVICE_DEBUG_INFO;
475
0
  request->hdr.data_size =
476
0
      sizeof(struct nsm_get_network_device_debug_info_req) -
477
0
      sizeof(struct nsm_common_req);
478
0
  request->debug_info_type = debug_type;
479
0
  request->reserved = 0x00;
480
0
  request->record_handle = htole32(handle);
481
482
0
  return NSM_SW_SUCCESS;
483
0
}
484
485
int decode_get_network_device_debug_info_req(const struct nsm_msg *msg,
486
               size_t msg_len,
487
               uint8_t *debug_type,
488
               uint32_t *handle)
489
0
{
490
0
  if (msg == NULL || debug_type == NULL || handle == NULL) {
491
0
    return NSM_SW_ERROR_NULL;
492
0
  }
493
494
0
  if (msg_len <
495
0
      sizeof(struct nsm_msg_hdr) +
496
0
    sizeof(struct nsm_get_network_device_debug_info_req)) {
497
0
    return NSM_SW_ERROR_LENGTH;
498
0
  }
499
500
0
  struct nsm_get_network_device_debug_info_req *request =
501
0
      (struct nsm_get_network_device_debug_info_req *)msg->payload;
502
503
0
  if (request->hdr.data_size !=
504
0
      sizeof(struct nsm_get_network_device_debug_info_req) -
505
0
    sizeof(struct nsm_common_req)) {
506
0
    return NSM_SW_ERROR_DATA;
507
0
  }
508
509
0
  *debug_type = request->debug_info_type;
510
0
  *handle = le32toh(request->record_handle);
511
512
0
  return NSM_SW_SUCCESS;
513
0
}
514
515
int encode_get_network_device_debug_info_resp(uint8_t instance_id, uint8_t cc,
516
                uint16_t reason_code,
517
                const uint8_t *seg_data,
518
                const uint16_t seg_data_size,
519
                const uint32_t next_handle,
520
                struct nsm_msg *msg)
521
0
{
522
0
  if (msg == NULL) {
523
0
    return NSM_SW_ERROR_NULL;
524
0
  }
525
526
0
  struct nsm_header_info header = {0};
527
0
  header.nsm_msg_type = NSM_RESPONSE;
528
0
  header.instance_id = instance_id & INSTANCEID_MASK;
529
0
  header.nvidia_msg_type = NSM_TYPE_DIAGNOSTIC;
530
531
0
  uint8_t rc = pack_nsm_header(&header, &msg->hdr);
532
0
  if (rc != NSM_SW_SUCCESS) {
533
0
    return rc;
534
0
  }
535
536
0
  if (cc != NSM_SUCCESS) {
537
0
    return encode_reason_code(
538
0
        cc, reason_code, NSM_GET_NETWORK_DEVICE_DEBUG_INFO, msg);
539
0
  }
540
541
0
  struct nsm_get_network_device_debug_info_resp *resp =
542
0
      (struct nsm_get_network_device_debug_info_resp *)msg->payload;
543
544
0
  resp->hdr.command = NSM_GET_NETWORK_DEVICE_DEBUG_INFO;
545
0
  resp->hdr.completion_code = cc;
546
547
0
  uint16_t total_data_size = seg_data_size + sizeof(next_handle);
548
0
  resp->hdr.data_size = htole16(total_data_size);
549
0
  resp->next_record_handle = htole32(next_handle);
550
551
0
  if (cc == NSM_SUCCESS) {
552
0
    {
553
0
      if (seg_data == NULL) {
554
0
        return NSM_SW_ERROR_NULL;
555
0
      }
556
0
    }
557
0
    memcpy(resp->segment_data, seg_data, seg_data_size);
558
0
  }
559
560
0
  return NSM_SW_SUCCESS;
561
0
}
562
563
int decode_get_network_device_debug_info_resp(const struct nsm_msg *msg,
564
                size_t msg_len, uint8_t *cc,
565
                uint16_t *reason_code,
566
                uint16_t *seg_data_size,
567
                uint8_t *seg_data,
568
                uint32_t *next_handle)
569
0
{
570
0
  if (seg_data == NULL || seg_data_size == NULL || next_handle == NULL) {
571
0
    return NSM_SW_ERROR_NULL;
572
0
  }
573
574
0
  int rc = decode_reason_code_and_cc(msg, msg_len, cc, reason_code);
575
0
  if (rc != NSM_SW_SUCCESS || *cc != NSM_SUCCESS) {
576
0
    return rc;
577
0
  }
578
579
0
  if (msg_len <
580
0
      sizeof(struct nsm_msg_hdr) +
581
0
    sizeof(struct nsm_get_network_device_debug_info_resp) -
582
0
    sizeof(uint8_t)) {
583
0
    return NSM_SW_ERROR_LENGTH;
584
0
  }
585
586
0
  struct nsm_get_network_device_debug_info_resp *resp =
587
0
      (struct nsm_get_network_device_debug_info_resp *)msg->payload;
588
589
0
  uint16_t total_data_size = le16toh(resp->hdr.data_size);
590
0
  *next_handle = le32toh(resp->next_record_handle);
591
0
  *seg_data_size = total_data_size - sizeof(resp->next_record_handle);
592
593
0
  memcpy(seg_data, resp->segment_data, *seg_data_size);
594
595
0
  return NSM_SW_SUCCESS;
596
0
}
597
598
int encode_erase_trace_req(uint8_t instance_id, struct nsm_msg *msg)
599
0
{
600
0
  if (msg == NULL) {
601
0
    return NSM_SW_ERROR_NULL;
602
0
  }
603
604
0
  struct nsm_header_info header = {0};
605
0
  header.nsm_msg_type = NSM_REQUEST;
606
0
  header.instance_id = instance_id;
607
0
  header.nvidia_msg_type = NSM_TYPE_DIAGNOSTIC;
608
609
0
  uint8_t rc = pack_nsm_header(&header, &(msg->hdr));
610
0
  if (rc != NSM_SW_SUCCESS) {
611
0
    return rc;
612
0
  }
613
614
0
  struct nsm_erase_trace_req *request =
615
0
      (struct nsm_erase_trace_req *)msg->payload;
616
617
0
  request->hdr.command = NSM_ERASE_TRACE;
618
0
  request->hdr.data_size = 0x00;
619
620
0
  return NSM_SW_SUCCESS;
621
0
}
622
623
int decode_erase_trace_req(const struct nsm_msg *msg, size_t msg_len)
624
0
{
625
0
  if (msg == NULL) {
626
0
    return NSM_SW_ERROR_NULL;
627
0
  }
628
629
0
  if (msg_len <
630
0
      sizeof(struct nsm_msg_hdr) + sizeof(struct nsm_erase_trace_req)) {
631
0
    return NSM_SW_ERROR_LENGTH;
632
0
  }
633
634
0
  struct nsm_erase_trace_req *request =
635
0
      (struct nsm_erase_trace_req *)msg->payload;
636
637
0
  if (request->hdr.data_size != 0) {
638
0
    return NSM_SW_ERROR_DATA;
639
0
  }
640
641
0
  return NSM_SW_SUCCESS;
642
0
}
643
644
int encode_erase_trace_resp(uint8_t instance_id, uint8_t cc,
645
          uint16_t reason_code, uint8_t result_status,
646
          struct nsm_msg *msg)
647
0
{
648
0
  if (msg == NULL) {
649
0
    return NSM_SW_ERROR_NULL;
650
0
  }
651
652
0
  struct nsm_header_info header = {0};
653
0
  header.nsm_msg_type = NSM_RESPONSE;
654
0
  header.instance_id = instance_id & INSTANCEID_MASK;
655
0
  header.nvidia_msg_type = NSM_TYPE_DIAGNOSTIC;
656
657
0
  uint8_t rc = pack_nsm_header(&header, &msg->hdr);
658
0
  if (rc != NSM_SW_SUCCESS) {
659
0
    return rc;
660
0
  }
661
662
0
  if (cc != NSM_SUCCESS) {
663
0
    return encode_reason_code(cc, reason_code, NSM_ERASE_TRACE,
664
0
            msg);
665
0
  }
666
667
0
  struct nsm_erase_trace_resp *response =
668
0
      (struct nsm_erase_trace_resp *)msg->payload;
669
670
0
  response->hdr.command = NSM_ERASE_TRACE;
671
0
  response->hdr.completion_code = cc;
672
0
  response->hdr.data_size = htole16(sizeof(uint8_t));
673
0
  response->result_status = result_status;
674
675
0
  return NSM_SW_SUCCESS;
676
0
}
677
678
int decode_erase_trace_resp(const struct nsm_msg *msg, size_t msg_len,
679
          uint8_t *cc, uint16_t *reason_code,
680
          uint8_t *result_status)
681
0
{
682
0
  if (result_status == NULL) {
683
0
    return NSM_SW_ERROR_NULL;
684
0
  }
685
686
0
  int rc = decode_reason_code_and_cc(msg, msg_len, cc, reason_code);
687
0
  if (rc != NSM_SW_SUCCESS || *cc != NSM_SUCCESS) {
688
0
    return rc;
689
0
  }
690
691
0
  if (msg_len !=
692
0
      sizeof(struct nsm_msg_hdr) + sizeof(struct nsm_erase_trace_resp)) {
693
0
    return NSM_SW_ERROR_LENGTH;
694
0
  }
695
696
0
  struct nsm_erase_trace_resp *response =
697
0
      (struct nsm_erase_trace_resp *)msg->payload;
698
699
0
  uint16_t data_size = le16toh(response->hdr.data_size);
700
0
  if (data_size != sizeof(uint8_t)) {
701
0
    return NSM_SW_ERROR_DATA;
702
0
  }
703
704
0
  *result_status = response->result_status;
705
706
0
  return NSM_SW_SUCCESS;
707
0
}
708
709
int encode_get_network_device_log_info_req(uint8_t instance_id,
710
             uint32_t record_handle,
711
             struct nsm_msg *msg)
712
0
{
713
0
  if (msg == NULL) {
714
0
    return NSM_SW_ERROR_NULL;
715
0
  }
716
717
0
  struct nsm_header_info header = {0};
718
0
  header.nsm_msg_type = NSM_REQUEST;
719
0
  header.instance_id = instance_id;
720
0
  header.nvidia_msg_type = NSM_TYPE_DIAGNOSTIC;
721
722
0
  uint8_t rc = pack_nsm_header(&header, &(msg->hdr));
723
0
  if (rc != NSM_SW_SUCCESS) {
724
0
    return rc;
725
0
  }
726
727
0
  struct nsm_get_network_device_log_info_req *request =
728
0
      (struct nsm_get_network_device_log_info_req *)msg->payload;
729
730
0
  request->hdr.command = NSM_GET_NETWORK_DEVICE_LOG_INFO;
731
0
  request->hdr.data_size =
732
0
      sizeof(struct nsm_get_network_device_log_info_req) -
733
0
      sizeof(struct nsm_common_req);
734
0
  request->record_handle = htole32(record_handle);
735
736
0
  return NSM_SW_SUCCESS;
737
0
}
738
739
int decode_get_network_device_log_info_req(const struct nsm_msg *msg,
740
             size_t msg_len,
741
             uint32_t *record_handle)
742
0
{
743
0
  if (msg == NULL || record_handle == NULL) {
744
0
    return NSM_SW_ERROR_NULL;
745
0
  }
746
747
0
  if (msg_len < sizeof(struct nsm_msg_hdr) +
748
0
        sizeof(struct nsm_get_network_device_log_info_req)) {
749
0
    return NSM_SW_ERROR_LENGTH;
750
0
  }
751
752
0
  struct nsm_get_network_device_log_info_req *request =
753
0
      (struct nsm_get_network_device_log_info_req *)msg->payload;
754
755
0
  if (request->hdr.data_size !=
756
0
      sizeof(struct nsm_get_network_device_log_info_req) -
757
0
    sizeof(struct nsm_common_req)) {
758
0
    return NSM_SW_ERROR_DATA;
759
0
  }
760
761
0
  *record_handle = le32toh(request->record_handle);
762
763
0
  return NSM_SW_SUCCESS;
764
0
}
765
766
int encode_get_network_device_log_info_resp(
767
    uint8_t instance_id, uint8_t cc, uint16_t reason_code,
768
    const uint32_t next_handle,
769
    struct nsm_device_log_info_breakdown log_info_breakdown,
770
    const uint8_t *log_data, const uint16_t log_data_size, struct nsm_msg *msg)
771
0
{
772
0
  if (msg == NULL) {
773
0
    return NSM_SW_ERROR_NULL;
774
0
  }
775
776
0
  struct nsm_header_info header = {0};
777
0
  header.nsm_msg_type = NSM_RESPONSE;
778
0
  header.instance_id = instance_id & INSTANCEID_MASK;
779
0
  header.nvidia_msg_type = NSM_TYPE_DIAGNOSTIC;
780
781
0
  uint8_t rc = pack_nsm_header(&header, &msg->hdr);
782
0
  if (rc != NSM_SW_SUCCESS) {
783
0
    return rc;
784
0
  }
785
786
0
  if (cc != NSM_SUCCESS) {
787
0
    return encode_reason_code(cc, reason_code,
788
0
            NSM_GET_NETWORK_DEVICE_LOG_INFO, msg);
789
0
  }
790
791
0
  struct nsm_get_network_device_log_info_resp *resp =
792
0
      (struct nsm_get_network_device_log_info_resp *)msg->payload;
793
794
0
  resp->hdr.command = NSM_GET_NETWORK_DEVICE_LOG_INFO;
795
0
  resp->hdr.completion_code = cc;
796
797
0
  uint16_t total_data_size = log_data_size + sizeof(next_handle) +
798
0
           sizeof(struct nsm_device_log_info);
799
0
  resp->hdr.data_size = htole16(total_data_size);
800
0
  resp->next_record_handle = htole32(next_handle);
801
802
0
  struct nsm_device_log_info *log_info =
803
0
      (struct nsm_device_log_info *)(&log_info_breakdown);
804
0
  resp->log_info.lost_events_and_synced_time =
805
0
      log_info->lost_events_and_synced_time;
806
0
  resp->log_info.reserved1 = log_info->reserved1;
807
0
  resp->log_info.reserved2 = log_info->reserved2;
808
0
  resp->log_info.time_low = htole32(log_info->time_low);
809
0
  resp->log_info.time_high = htole32(log_info->time_high);
810
0
  resp->log_info.entry_prefix_and_length =
811
0
      htole32(log_info->entry_prefix_and_length);
812
0
  resp->log_info.entry_suffix = htole64(log_info->entry_suffix);
813
814
0
  if (cc == NSM_SUCCESS) {
815
0
    {
816
0
      if (log_data == NULL) {
817
0
        return NSM_SW_ERROR_NULL;
818
0
      }
819
0
    }
820
0
    memcpy(resp->log_data, log_data, log_data_size);
821
0
  }
822
823
0
  return NSM_SW_SUCCESS;
824
0
}
825
826
int decode_get_network_device_log_info_resp(
827
    const struct nsm_msg *msg, size_t msg_len, uint8_t *cc,
828
    uint16_t *reason_code, uint32_t *next_handle,
829
    struct nsm_device_log_info_breakdown *log_info, uint8_t *log_data,
830
    uint16_t *log_data_size)
831
0
{
832
0
  if (log_info == NULL || log_data == NULL || log_data_size == NULL ||
833
0
      next_handle == NULL) {
834
0
    return NSM_SW_ERROR_NULL;
835
0
  }
836
837
0
  int rc = decode_reason_code_and_cc(msg, msg_len, cc, reason_code);
838
0
  if (rc != NSM_SW_SUCCESS || *cc != NSM_SUCCESS) {
839
0
    return rc;
840
0
  }
841
842
0
  if (msg_len < sizeof(struct nsm_msg_hdr) +
843
0
        sizeof(struct nsm_get_network_device_log_info_resp) -
844
0
        sizeof(uint8_t)) {
845
0
    return NSM_SW_ERROR_LENGTH;
846
0
  }
847
848
0
  struct nsm_get_network_device_log_info_resp *resp =
849
0
      (struct nsm_get_network_device_log_info_resp *)msg->payload;
850
851
0
  uint16_t total_data_size = le16toh(resp->hdr.data_size);
852
0
  *next_handle = le32toh(resp->next_record_handle);
853
0
  *log_data_size = total_data_size - sizeof(resp->next_record_handle) -
854
0
       sizeof(struct nsm_device_log_info);
855
856
0
  struct nsm_device_log_info info = {0};
857
0
  info.lost_events_and_synced_time =
858
0
      resp->log_info.lost_events_and_synced_time;
859
0
  info.reserved1 = 0;
860
0
  info.reserved2 = 0;
861
0
  info.time_low = le32toh(resp->log_info.time_low);
862
0
  info.time_high = le32toh(resp->log_info.time_high);
863
0
  info.entry_prefix_and_length =
864
0
      le32toh(resp->log_info.entry_prefix_and_length);
865
0
  info.entry_suffix = le64toh(resp->log_info.entry_suffix);
866
0
  memcpy(log_info, &info, sizeof(struct nsm_device_log_info));
867
868
0
  memcpy(log_data, resp->log_data, *log_data_size);
869
870
0
  return NSM_SW_SUCCESS;
871
0
}
872
873
int encode_erase_debug_info_req(uint8_t instance_id, uint8_t info_type,
874
        struct nsm_msg *msg)
875
0
{
876
0
  if (msg == NULL) {
877
0
    return NSM_SW_ERROR_NULL;
878
0
  }
879
880
0
  struct nsm_header_info header = {0};
881
0
  header.nsm_msg_type = NSM_REQUEST;
882
0
  header.instance_id = instance_id;
883
0
  header.nvidia_msg_type = NSM_TYPE_DIAGNOSTIC;
884
885
0
  uint8_t rc = pack_nsm_header(&header, &(msg->hdr));
886
0
  if (rc != NSM_SW_SUCCESS) {
887
0
    return rc;
888
0
  }
889
890
0
  struct nsm_erase_debug_info_req *request =
891
0
      (struct nsm_erase_debug_info_req *)msg->payload;
892
893
0
  request->hdr.command = NSM_ERASE_DEBUG_INFO;
894
0
  request->hdr.data_size = sizeof(struct nsm_erase_debug_info_req) -
895
0
         sizeof(struct nsm_common_req);
896
0
  request->debug_info_type = info_type;
897
0
  request->reserved = 0;
898
899
0
  return NSM_SW_SUCCESS;
900
0
}
901
902
int decode_erase_debug_info_req(const struct nsm_msg *msg, size_t msg_len,
903
        uint8_t *info_type)
904
0
{
905
0
  if (msg == NULL || info_type == NULL) {
906
0
    return NSM_SW_ERROR_NULL;
907
0
  }
908
909
0
  if (msg_len < sizeof(struct nsm_msg_hdr) +
910
0
        sizeof(struct nsm_erase_debug_info_req)) {
911
0
    return NSM_SW_ERROR_LENGTH;
912
0
  }
913
914
0
  struct nsm_erase_debug_info_req *request =
915
0
      (struct nsm_erase_debug_info_req *)msg->payload;
916
917
0
  if (request->hdr.data_size != sizeof(struct nsm_erase_debug_info_req) -
918
0
            sizeof(struct nsm_common_req)) {
919
0
    return NSM_SW_ERROR_DATA;
920
0
  }
921
922
0
  *info_type = request->debug_info_type;
923
924
0
  return NSM_SW_SUCCESS;
925
0
}
926
927
int encode_erase_debug_info_resp(uint8_t instance_id, uint8_t cc,
928
         uint16_t reason_code, uint8_t result_status,
929
         struct nsm_msg *msg)
930
0
{
931
0
  if (msg == NULL) {
932
0
    return NSM_SW_ERROR_NULL;
933
0
  }
934
935
0
  struct nsm_header_info header = {0};
936
0
  header.nsm_msg_type = NSM_RESPONSE;
937
0
  header.instance_id = instance_id & INSTANCEID_MASK;
938
0
  header.nvidia_msg_type = NSM_TYPE_DIAGNOSTIC;
939
940
0
  uint8_t rc = pack_nsm_header(&header, &msg->hdr);
941
0
  if (rc != NSM_SW_SUCCESS) {
942
0
    return rc;
943
0
  }
944
945
0
  if (cc != NSM_SUCCESS) {
946
0
    return encode_reason_code(cc, reason_code, NSM_ERASE_TRACE,
947
0
            msg);
948
0
  }
949
950
0
  struct nsm_erase_debug_info_resp *response =
951
0
      (struct nsm_erase_debug_info_resp *)msg->payload;
952
953
0
  response->hdr.command = NSM_ERASE_DEBUG_INFO;
954
0
  response->hdr.completion_code = cc;
955
0
  response->hdr.data_size =
956
0
      htole16(sizeof(struct nsm_erase_debug_info_resp) -
957
0
        sizeof(struct nsm_common_resp));
958
0
  response->result_status = result_status;
959
0
  response->reserved = 0;
960
961
0
  return NSM_SW_SUCCESS;
962
0
}
963
964
int decode_erase_debug_info_resp(const struct nsm_msg *msg, size_t msg_len,
965
         uint8_t *cc, uint16_t *reason_code,
966
         uint8_t *result_status)
967
0
{
968
0
  if (result_status == NULL) {
969
0
    return NSM_SW_ERROR_NULL;
970
0
  }
971
972
0
  int rc = decode_reason_code_and_cc(msg, msg_len, cc, reason_code);
973
0
  if (rc != NSM_SW_SUCCESS || *cc != NSM_SUCCESS) {
974
0
    return rc;
975
0
  }
976
977
0
  if (msg_len != sizeof(struct nsm_msg_hdr) +
978
0
         sizeof(struct nsm_erase_debug_info_resp)) {
979
0
    return NSM_SW_ERROR_LENGTH;
980
0
  }
981
982
0
  struct nsm_erase_debug_info_resp *response =
983
0
      (struct nsm_erase_debug_info_resp *)msg->payload;
984
985
0
  uint16_t data_size = le16toh(response->hdr.data_size);
986
0
  if (data_size != sizeof(struct nsm_erase_debug_info_resp) -
987
0
           sizeof(struct nsm_common_resp)) {
988
0
    return NSM_SW_ERROR_DATA;
989
0
  }
990
991
0
  *result_status = response->result_status;
992
993
0
  return NSM_SW_SUCCESS;
994
0
}