Coverage Report

Created: 2026-07-25 06:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/nsmd/libnsm/pci-links.c
Line
Count
Source
1
#include "pci-links.h"
2
3
#include <endian.h>
4
#include <stdio.h>
5
#include <string.h>
6
7
int encode_query_scalar_group_telemetry_v1_req(uint8_t instance_id,
8
                 uint8_t device_id,
9
                 uint8_t group_index,
10
                 struct nsm_msg *msg)
11
0
{
12
0
  if (msg == NULL) {
13
0
    return NSM_SW_ERROR_NULL;
14
0
  }
15
16
0
  struct nsm_header_info header = {0};
17
0
  header.nsm_msg_type = NSM_REQUEST;
18
0
  header.instance_id = instance_id;
19
0
  header.nvidia_msg_type = NSM_TYPE_PCI_LINK;
20
21
0
  uint8_t rc = pack_nsm_header(&header, &(msg->hdr));
22
0
  if (rc != NSM_SW_SUCCESS) {
23
0
    return rc;
24
0
  }
25
26
0
  struct nsm_query_scalar_group_telemetry_v1_req *request =
27
0
      (struct nsm_query_scalar_group_telemetry_v1_req *)msg->payload;
28
29
0
  request->hdr.command = NSM_QUERY_SCALAR_GROUP_TELEMETRY_V1;
30
0
  request->hdr.data_size = 2;
31
0
  request->device_id = device_id;
32
0
  request->group_index = group_index;
33
34
0
  return NSM_SW_SUCCESS;
35
0
}
36
37
int decode_query_scalar_group_telemetry_v1_req(const struct nsm_msg *msg,
38
                 size_t msg_len,
39
                 uint8_t *device_id,
40
                 uint8_t *group_index)
41
0
{
42
0
  if (msg == NULL || device_id == NULL || group_index == NULL) {
43
0
    return NSM_SW_ERROR_NULL;
44
0
  }
45
46
0
  struct nsm_header_info header = {0};
47
0
  uint8_t rc = unpack_nsm_header(&msg->hdr, &header);
48
0
  if (rc != NSM_SW_SUCCESS) {
49
0
    return rc;
50
0
  }
51
52
0
  if (msg_len <
53
0
      sizeof(struct nsm_msg_hdr) +
54
0
    sizeof(struct nsm_query_scalar_group_telemetry_v1_req)) {
55
0
    return NSM_SW_ERROR_LENGTH;
56
0
  }
57
58
0
  struct nsm_query_scalar_group_telemetry_v1_req *request =
59
0
      (struct nsm_query_scalar_group_telemetry_v1_req *)msg->payload;
60
61
0
  if (request->hdr.data_size <
62
0
      sizeof(struct nsm_query_scalar_group_telemetry_v1_req) -
63
0
    NSM_REQUEST_CONVENTION_LEN) {
64
0
    return NSM_SW_ERROR_DATA;
65
0
  }
66
67
0
  *device_id = request->device_id;
68
0
  *group_index = request->group_index;
69
0
  return NSM_SW_SUCCESS;
70
0
}
71
72
int encode_query_scalar_group_telemetry_v1_resp(uint8_t instance_id, uint8_t cc,
73
            uint16_t reason_code,
74
            const uint16_t data_size,
75
            uint8_t *data,
76
            struct nsm_msg *msg)
77
0
{
78
0
  if (msg == NULL || data == NULL) {
79
0
    return NSM_SW_ERROR_NULL;
80
0
  }
81
82
0
  struct nsm_header_info header = {NSM_RESPONSE, instance_id,
83
0
           NSM_TYPE_PCI_LINK};
84
0
  uint8_t rc = pack_nsm_header(&header, &msg->hdr);
85
0
  if (rc != NSM_SW_SUCCESS) {
86
0
    return rc;
87
0
  }
88
89
0
  if (cc != NSM_SUCCESS) {
90
0
    return encode_reason_code(
91
0
        cc, reason_code, NSM_QUERY_SCALAR_GROUP_TELEMETRY_V1, msg);
92
0
  }
93
94
0
  struct nsm_query_scalar_group_telemetry_v1_resp *resp =
95
0
      (struct nsm_query_scalar_group_telemetry_v1_resp *)msg->payload;
96
97
0
  resp->hdr.command = NSM_QUERY_SCALAR_GROUP_TELEMETRY_V1;
98
0
  resp->hdr.completion_code = cc;
99
0
  resp->hdr.data_size = htole16(data_size);
100
0
  int cnt = data_size / sizeof(uint32_t);
101
0
  uint32_t val;
102
0
  for (int idx = 0; idx < cnt; idx++) {
103
0
    memcpy(&val, data + idx * sizeof(uint32_t), sizeof(uint32_t));
104
0
    val = htole32(val);
105
0
    memcpy(resp->data + idx * sizeof(uint32_t), &val,
106
0
           sizeof(uint32_t));
107
0
  }
108
0
  return NSM_SW_SUCCESS;
109
0
}
110
111
int decode_query_scalar_group_telemetry_v1_resp(const struct nsm_msg *msg,
112
            size_t msg_len, uint8_t *cc,
113
            uint16_t *data_size,
114
            uint16_t *reason_code,
115
            uint8_t *data)
116
0
{
117
0
  if (msg == NULL || cc == NULL || data_size == NULL ||
118
0
      reason_code == NULL || data == NULL) {
119
0
    return NSM_SW_ERROR_NULL;
120
0
  }
121
0
  int rc = decode_reason_code_and_cc(msg, msg_len, cc, reason_code);
122
0
  if (rc != NSM_SW_SUCCESS || *cc != NSM_SUCCESS) {
123
0
    return rc;
124
0
  }
125
126
0
  if (msg_len <
127
0
      sizeof(struct nsm_msg_hdr) +
128
0
    sizeof(struct nsm_query_scalar_group_telemetry_v1_resp)) {
129
0
    return NSM_SW_ERROR_LENGTH;
130
0
  }
131
132
0
  struct nsm_query_scalar_group_telemetry_v1_resp *resp =
133
0
      (struct nsm_query_scalar_group_telemetry_v1_resp *)msg->payload;
134
135
0
  *data_size = le16toh(resp->hdr.data_size);
136
0
  int cnt = *data_size / sizeof(uint32_t);
137
0
  uint32_t val;
138
0
  for (int idx = 0; idx < cnt; idx++) {
139
0
    memcpy(&val, resp->data + idx * sizeof(uint32_t),
140
0
           sizeof(uint32_t));
141
0
    val = le32toh(val);
142
0
    memcpy(data + idx * sizeof(uint32_t), &val, sizeof(uint32_t));
143
0
  }
144
0
  return NSM_SW_SUCCESS;
145
0
}
146
147
int encode_query_scalar_group_telemetry_v1_group0_resp(
148
    uint8_t instance_id, uint8_t cc, uint16_t reason_code,
149
    struct nsm_query_scalar_group_telemetry_group_0 *data, struct nsm_msg *msg)
150
0
{
151
0
  return encode_query_scalar_group_telemetry_v1_resp(
152
0
      instance_id, cc, reason_code,
153
0
      sizeof(struct nsm_query_scalar_group_telemetry_group_0),
154
0
      (uint8_t *)data, msg);
155
0
}
156
157
int decode_query_scalar_group_telemetry_v1_group0_resp(
158
    const struct nsm_msg *msg, size_t msg_len, uint8_t *cc, uint16_t *data_size,
159
    uint16_t *reason_code,
160
    struct nsm_query_scalar_group_telemetry_group_0 *data)
161
0
{
162
0
  int ret = decode_query_scalar_group_telemetry_v1_resp(
163
0
      msg, msg_len, cc, data_size, reason_code, (uint8_t *)data);
164
0
  if (ret != NSM_SW_SUCCESS || *cc != NSM_SUCCESS)
165
0
    return ret;
166
0
  if (*data_size <
167
0
      sizeof(struct nsm_query_scalar_group_telemetry_group_0))
168
0
    ret = NSM_SW_ERROR_LENGTH;
169
0
  return ret;
170
0
}
171
172
int encode_query_scalar_group_telemetry_v1_group1_resp(
173
    uint8_t instance_id, uint8_t cc, uint16_t reason_code,
174
    struct nsm_query_scalar_group_telemetry_group_1 *data, struct nsm_msg *msg)
175
0
{
176
0
  return encode_query_scalar_group_telemetry_v1_resp(
177
0
      instance_id, cc, reason_code,
178
0
      sizeof(struct nsm_query_scalar_group_telemetry_group_1),
179
0
      (uint8_t *)data, msg);
180
0
}
181
182
int decode_query_scalar_group_telemetry_v1_group1_resp(
183
    const struct nsm_msg *msg, size_t msg_len, uint8_t *cc, uint16_t *data_size,
184
    uint16_t *reason_code,
185
    struct nsm_query_scalar_group_telemetry_group_1 *data)
186
0
{
187
0
  int ret = decode_query_scalar_group_telemetry_v1_resp(
188
0
      msg, msg_len, cc, data_size, reason_code, (uint8_t *)data);
189
0
  if (ret != NSM_SW_SUCCESS || *cc != NSM_SUCCESS)
190
0
    return ret;
191
0
  if (*data_size <
192
0
      sizeof(struct nsm_query_scalar_group_telemetry_group_1))
193
0
    ret = NSM_SW_ERROR_LENGTH;
194
0
  return ret;
195
0
}
196
197
int encode_query_scalar_group_telemetry_v1_group2_resp(
198
    uint8_t instance_id, uint8_t cc, uint16_t reason_code,
199
    struct nsm_query_scalar_group_telemetry_group_2 *data, struct nsm_msg *msg)
200
0
{
201
0
  return encode_query_scalar_group_telemetry_v1_resp(
202
0
      instance_id, cc, reason_code,
203
0
      sizeof(struct nsm_query_scalar_group_telemetry_group_2),
204
0
      (uint8_t *)data, msg);
205
0
}
206
207
int decode_query_scalar_group_telemetry_v1_group2_resp(
208
    const struct nsm_msg *msg, size_t msg_len, uint8_t *cc, uint16_t *data_size,
209
    uint16_t *reason_code,
210
    struct nsm_query_scalar_group_telemetry_group_2 *data)
211
0
{
212
0
  int ret = decode_query_scalar_group_telemetry_v1_resp(
213
0
      msg, msg_len, cc, data_size, reason_code, (uint8_t *)data);
214
0
  if (ret != NSM_SW_SUCCESS || *cc != NSM_SUCCESS)
215
0
    return ret;
216
0
  if (*data_size <
217
0
      sizeof(struct nsm_query_scalar_group_telemetry_group_2))
218
0
    ret = NSM_SW_ERROR_LENGTH;
219
0
  return ret;
220
0
}
221
222
int encode_query_scalar_group_telemetry_v1_group3_resp(
223
    uint8_t instance_id, uint8_t cc, uint16_t reason_code,
224
    struct nsm_query_scalar_group_telemetry_group_3 *data, struct nsm_msg *msg)
225
0
{
226
0
  return encode_query_scalar_group_telemetry_v1_resp(
227
0
      instance_id, cc, reason_code,
228
0
      sizeof(struct nsm_query_scalar_group_telemetry_group_3),
229
0
      (uint8_t *)data, msg);
230
0
}
231
232
int decode_query_scalar_group_telemetry_v1_group3_resp(
233
    const struct nsm_msg *msg, size_t msg_len, uint8_t *cc, uint16_t *data_size,
234
    uint16_t *reason_code,
235
    struct nsm_query_scalar_group_telemetry_group_3 *data)
236
0
{
237
0
  int ret = decode_query_scalar_group_telemetry_v1_resp(
238
0
      msg, msg_len, cc, data_size, reason_code, (uint8_t *)data);
239
0
  if (ret != NSM_SW_SUCCESS || *cc != NSM_SUCCESS)
240
0
    return ret;
241
0
  if (*data_size <
242
0
      sizeof(struct nsm_query_scalar_group_telemetry_group_3))
243
0
    ret = NSM_SW_ERROR_LENGTH;
244
0
  return ret;
245
0
}
246
247
int encode_query_scalar_group_telemetry_v1_group4_resp(
248
    uint8_t instance_id, uint8_t cc, uint16_t reason_code,
249
    struct nsm_query_scalar_group_telemetry_group_4 *data, struct nsm_msg *msg)
250
0
{
251
0
  return encode_query_scalar_group_telemetry_v1_resp(
252
0
      instance_id, cc, reason_code,
253
0
      sizeof(struct nsm_query_scalar_group_telemetry_group_4),
254
0
      (uint8_t *)data, msg);
255
0
}
256
257
int decode_query_scalar_group_telemetry_v1_group4_resp(
258
    const struct nsm_msg *msg, size_t msg_len, uint8_t *cc, uint16_t *data_size,
259
    uint16_t *reason_code,
260
    struct nsm_query_scalar_group_telemetry_group_4 *data)
261
0
{
262
0
  int ret = decode_query_scalar_group_telemetry_v1_resp(
263
0
      msg, msg_len, cc, data_size, reason_code, (uint8_t *)data);
264
265
0
  if (ret != NSM_SW_SUCCESS || *cc != NSM_SUCCESS)
266
0
    return ret;
267
0
  if (*data_size <
268
0
      sizeof(struct nsm_query_scalar_group_telemetry_group_4))
269
0
    ret = NSM_SW_ERROR_LENGTH;
270
0
  return ret;
271
0
}
272
273
int encode_query_scalar_group_telemetry_v1_group5_resp(
274
    uint8_t instance_id, uint8_t cc, uint16_t reason_code,
275
    struct nsm_query_scalar_group_telemetry_group_5 *data, struct nsm_msg *msg)
276
0
{
277
0
  return encode_query_scalar_group_telemetry_v1_resp(
278
0
      instance_id, cc, reason_code,
279
0
      sizeof(struct nsm_query_scalar_group_telemetry_group_5),
280
0
      (uint8_t *)data, msg);
281
0
}
282
283
int decode_query_scalar_group_telemetry_v1_group5_resp(
284
    const struct nsm_msg *msg, size_t msg_len, uint8_t *cc, uint16_t *data_size,
285
    uint16_t *reason_code,
286
    struct nsm_query_scalar_group_telemetry_group_5 *data)
287
0
{
288
0
  int ret = decode_query_scalar_group_telemetry_v1_resp(
289
0
      msg, msg_len, cc, data_size, reason_code, (uint8_t *)data);
290
0
  if (ret != NSM_SW_SUCCESS || *cc != NSM_SUCCESS)
291
0
    return ret;
292
0
  if (*data_size <
293
0
      sizeof(struct nsm_query_scalar_group_telemetry_group_5))
294
0
    ret = NSM_SW_ERROR_LENGTH;
295
0
  return ret;
296
0
}
297
298
int encode_query_scalar_group_telemetry_v1_group6_resp(
299
    uint8_t instance_id, uint8_t cc, uint16_t reason_code,
300
    struct nsm_query_scalar_group_telemetry_group_6 *data, struct nsm_msg *msg)
301
0
{
302
0
  return encode_query_scalar_group_telemetry_v1_resp(
303
0
      instance_id, cc, reason_code,
304
0
      sizeof(struct nsm_query_scalar_group_telemetry_group_6),
305
0
      (uint8_t *)data, msg);
306
0
}
307
308
int decode_query_scalar_group_telemetry_v1_group6_resp(
309
    const struct nsm_msg *msg, size_t msg_len, uint8_t *cc, uint16_t *data_size,
310
    uint16_t *reason_code,
311
    struct nsm_query_scalar_group_telemetry_group_6 *data)
312
0
{
313
0
  int ret = decode_query_scalar_group_telemetry_v1_resp(
314
0
      msg, msg_len, cc, data_size, reason_code, (uint8_t *)data);
315
0
  if (ret != NSM_SW_SUCCESS || *cc != NSM_SUCCESS)
316
0
    return ret;
317
0
  if (*data_size <
318
0
      sizeof(struct nsm_query_scalar_group_telemetry_group_6))
319
0
    ret = NSM_SW_ERROR_LENGTH;
320
0
  return ret;
321
0
}
322
323
int encode_query_scalar_group_telemetry_v1_group8_resp(
324
    uint8_t instance_id, uint8_t cc, uint16_t reason_code,
325
    struct nsm_query_scalar_group_telemetry_group_8 *data, struct nsm_msg *msg)
326
0
{
327
0
  return encode_query_scalar_group_telemetry_v1_resp(
328
0
      instance_id, cc, reason_code,
329
0
      sizeof(struct nsm_query_scalar_group_telemetry_group_8),
330
0
      (uint8_t *)data, msg);
331
0
}
332
333
int decode_query_scalar_group_telemetry_v1_group8_resp(
334
    const struct nsm_msg *msg, size_t msg_len, uint8_t *cc, uint16_t *data_size,
335
    uint16_t *reason_code,
336
    struct nsm_query_scalar_group_telemetry_group_8 *data)
337
0
{
338
0
  int ret = decode_query_scalar_group_telemetry_v1_resp(
339
0
      msg, msg_len, cc, data_size, reason_code, (uint8_t *)data);
340
0
  if (ret != NSM_SW_SUCCESS || *cc != NSM_SUCCESS)
341
0
    return ret;
342
0
  if (*data_size !=
343
0
      sizeof(struct nsm_query_scalar_group_telemetry_group_8))
344
0
    ret = NSM_SW_ERROR_LENGTH;
345
0
  return ret;
346
0
}
347
348
int encode_query_scalar_group_telemetry_v1_group9_resp(
349
    uint8_t instance_id, uint8_t cc, uint16_t reason_code,
350
    struct nsm_query_scalar_group_telemetry_group_9 *data, struct nsm_msg *msg)
351
0
{
352
0
  return encode_query_scalar_group_telemetry_v1_resp(
353
0
      instance_id, cc, reason_code,
354
0
      sizeof(struct nsm_query_scalar_group_telemetry_group_9),
355
0
      (uint8_t *)data, msg);
356
0
}
357
358
int decode_query_scalar_group_telemetry_v1_group9_resp(
359
    const struct nsm_msg *msg, size_t msg_len, uint8_t *cc, uint16_t *data_size,
360
    uint16_t *reason_code,
361
    struct nsm_query_scalar_group_telemetry_group_9 *data)
362
0
{
363
0
  int ret = decode_query_scalar_group_telemetry_v1_resp(
364
0
      msg, msg_len, cc, data_size, reason_code, (uint8_t *)data);
365
0
  if (ret != NSM_SW_SUCCESS || *cc != NSM_SUCCESS)
366
0
    return ret;
367
0
  if (*data_size !=
368
0
      sizeof(struct nsm_query_scalar_group_telemetry_group_9))
369
0
    ret = NSM_SW_ERROR_LENGTH;
370
0
  return ret;
371
0
}
372
373
int encode_query_scalar_group_telemetry_v1_group10_resp(
374
    uint8_t instance_id, uint8_t cc, uint16_t reason_code,
375
    const struct nsm_query_scalar_group_telemetry_group_10 *data,
376
    struct nsm_msg *msg)
377
0
{
378
0
  return encode_query_scalar_group_telemetry_v1_resp(
379
0
      instance_id, cc, reason_code,
380
0
      sizeof(struct nsm_query_scalar_group_telemetry_group_10),
381
0
      (uint8_t *)data, msg);
382
0
}
383
384
int decode_query_scalar_group_telemetry_v1_group10_resp(
385
    const struct nsm_msg *msg, size_t msg_len, uint8_t *cc,
386
    uint16_t *reason_code,
387
    struct nsm_query_scalar_group_telemetry_group_10 *data)
388
0
{
389
0
  uint16_t data_size = 0;
390
0
  int ret = decode_query_scalar_group_telemetry_v1_resp(
391
0
      msg, msg_len, cc, &data_size, reason_code, (uint8_t *)data);
392
0
  if (ret != NSM_SW_SUCCESS || *cc != NSM_SUCCESS)
393
0
    return ret;
394
0
  if (msg_len <
395
0
      sizeof(struct nsm_msg_hdr) +
396
0
    sizeof(
397
0
        struct nsm_query_scalar_group_telemetry_v1_group_10_resp)) {
398
0
    return NSM_SW_ERROR_LENGTH;
399
0
  }
400
0
  if (data_size !=
401
0
      sizeof(struct nsm_query_scalar_group_telemetry_group_10))
402
0
    ret = NSM_SW_ERROR_LENGTH;
403
0
  return ret;
404
0
}
405
406
int encode_assert_pcie_fundamental_reset_req(uint8_t instance_id,
407
               uint8_t device_index,
408
               uint8_t action,
409
               struct nsm_msg *msg)
410
0
{
411
0
  if (msg == NULL) {
412
0
    return NSM_SW_ERROR_NULL;
413
0
  }
414
415
0
  struct nsm_header_info header = {0};
416
0
  header.nsm_msg_type = NSM_REQUEST;
417
0
  header.instance_id = instance_id;
418
0
  header.nvidia_msg_type = NSM_TYPE_PCI_LINK;
419
420
0
  uint8_t rc = pack_nsm_header(&header, &(msg->hdr));
421
0
  if (rc != NSM_SW_SUCCESS) {
422
0
    return rc;
423
0
  }
424
425
0
  struct nsm_assert_pcie_fundamental_reset_req *request =
426
0
      (struct nsm_assert_pcie_fundamental_reset_req *)msg->payload;
427
428
0
  request->hdr.command = NSM_ASSERT_PCIE_FUNDAMENTAL_RESET;
429
0
  request->hdr.data_size = 2 * sizeof(uint8_t);
430
0
  request->device_index = device_index;
431
0
  request->action = action;
432
0
  return NSM_SW_SUCCESS;
433
0
}
434
435
int decode_assert_pcie_fundamental_reset_req(const struct nsm_msg *msg,
436
               size_t msg_len,
437
               uint8_t *device_index,
438
               uint8_t *action)
439
0
{
440
0
  if (msg == NULL || device_index == NULL || action == NULL) {
441
0
    return NSM_SW_ERROR_NULL;
442
0
  }
443
444
0
  if (msg_len !=
445
0
      sizeof(struct nsm_msg_hdr) +
446
0
    sizeof(struct nsm_assert_pcie_fundamental_reset_req)) {
447
0
    return NSM_SW_ERROR_LENGTH;
448
0
  }
449
450
0
  struct nsm_assert_pcie_fundamental_reset_req *request =
451
0
      (struct nsm_assert_pcie_fundamental_reset_req *)msg->payload;
452
453
0
  if (request->hdr.data_size != 2 * sizeof(uint8_t)) {
454
0
    return NSM_SW_ERROR_DATA;
455
0
  }
456
457
0
  *device_index = request->device_index;
458
0
  *action = request->action;
459
0
  return NSM_SW_SUCCESS;
460
0
}
461
462
int encode_assert_pcie_fundamental_reset_resp(uint8_t instance_id, uint8_t cc,
463
                uint16_t reason_code,
464
                struct nsm_msg *msg)
465
0
{
466
0
  if (msg == NULL) {
467
0
    return NSM_SW_ERROR_NULL;
468
0
  }
469
470
0
  struct nsm_header_info header = {0};
471
0
  header.nsm_msg_type = NSM_RESPONSE;
472
0
  header.instance_id = instance_id & INSTANCEID_MASK;
473
0
  header.nvidia_msg_type = NSM_TYPE_PCI_LINK;
474
475
0
  uint8_t rc = pack_nsm_header(&header, &msg->hdr);
476
0
  if (rc != NSM_SUCCESS) {
477
0
    return rc;
478
0
  }
479
0
  if (cc != NSM_SUCCESS) {
480
0
    return encode_reason_code(
481
0
        cc, reason_code, NSM_ASSERT_PCIE_FUNDAMENTAL_RESET, msg);
482
0
  }
483
484
0
  struct nsm_common_resp *resp = (struct nsm_common_resp *)msg->payload;
485
0
  resp->command = NSM_ASSERT_PCIE_FUNDAMENTAL_RESET;
486
0
  resp->completion_code = cc;
487
0
  resp->data_size = 0;
488
489
0
  return NSM_SW_SUCCESS;
490
0
}
491
492
int decode_assert_pcie_fundamental_reset_resp(const struct nsm_msg *msg,
493
                size_t msg_len, uint8_t *cc,
494
                uint16_t *data_size,
495
                uint16_t *reason_code)
496
0
{
497
0
  return decode_common_resp(msg, msg_len, cc, data_size, reason_code);
498
0
}
499
500
int encode_query_available_clearable_scalar_data_sources_v1_req(
501
    uint8_t instance_id, uint8_t device_index, uint8_t group_id,
502
    struct nsm_msg *msg)
503
0
{
504
0
  if (msg == NULL) {
505
0
    return NSM_SW_ERROR_NULL;
506
0
  }
507
508
0
  struct nsm_header_info header = {0};
509
0
  header.nsm_msg_type = NSM_REQUEST;
510
0
  header.instance_id = instance_id;
511
0
  header.nvidia_msg_type = NSM_TYPE_PCI_LINK;
512
513
0
  uint8_t rc = pack_nsm_header(&header, &(msg->hdr));
514
0
  if (rc != NSM_SW_SUCCESS) {
515
0
    return rc;
516
0
  }
517
518
0
  struct nsm_query_scalar_group_telemetry_v1_req *request =
519
0
      (struct nsm_query_scalar_group_telemetry_v1_req *)msg->payload;
520
521
0
  request->hdr.command =
522
0
      NSM_QUERY_AVAILABLE_CLEARABLE_SCALAR_DATA_SOURCES;
523
0
  request->hdr.data_size =
524
0
      sizeof(struct
525
0
       nsm_query_available_clearable_scalar_data_sources_v1_req) -
526
0
      sizeof(struct nsm_common_req);
527
0
  request->device_id = device_index;
528
0
  request->group_index = group_id;
529
530
0
  return NSM_SW_SUCCESS;
531
0
}
532
533
int decode_query_available_clearable_scalar_data_sources_v1_req(
534
    const struct nsm_msg *msg, size_t msg_len, uint8_t *device_index,
535
    uint8_t *group_id)
536
0
{
537
0
  if (msg == NULL || device_index == NULL || group_id == NULL) {
538
0
    return NSM_SW_ERROR_NULL;
539
0
  }
540
541
0
  if (msg_len !=
542
0
      sizeof(struct nsm_msg_hdr) +
543
0
    sizeof(
544
0
        struct
545
0
        nsm_query_available_clearable_scalar_data_sources_v1_req)) {
546
0
    return NSM_SW_ERROR_LENGTH;
547
0
  }
548
549
0
  struct nsm_query_available_clearable_scalar_data_sources_v1_req
550
0
      *request =
551
0
    (struct nsm_query_available_clearable_scalar_data_sources_v1_req
552
0
         *)msg->payload;
553
554
0
  if (request->hdr.data_size !=
555
0
      sizeof(struct
556
0
       nsm_query_available_clearable_scalar_data_sources_v1_req) -
557
0
    sizeof(struct nsm_common_req)) {
558
0
    return NSM_SW_ERROR_DATA;
559
0
  }
560
561
0
  *device_index = request->device_index;
562
0
  *group_id = request->group_id;
563
0
  return NSM_SW_SUCCESS;
564
0
}
565
566
int encode_query_available_clearable_scalar_data_sources_v1_resp(
567
    uint8_t instance_id, uint8_t cc, uint16_t reason_code,
568
    const uint16_t data_size, uint8_t mask_length,
569
    uint8_t *available_data_source_mask, uint8_t *clearable_data_source_mask,
570
    struct nsm_msg *msg)
571
0
{
572
0
  if (msg == NULL || available_data_source_mask == NULL ||
573
0
      clearable_data_source_mask == NULL) {
574
0
    return NSM_SW_ERROR_NULL;
575
0
  }
576
577
0
  struct nsm_header_info header = {0};
578
0
  header.nsm_msg_type = NSM_RESPONSE;
579
0
  header.instance_id = instance_id & 0x1f;
580
0
  header.nvidia_msg_type = NSM_TYPE_PCI_LINK;
581
582
0
  uint8_t rc = pack_nsm_header(&header, &msg->hdr);
583
0
  if (rc != NSM_SW_SUCCESS) {
584
0
    return rc;
585
0
  }
586
587
0
  if (cc != NSM_SUCCESS) {
588
0
    return encode_reason_code(
589
0
        cc, reason_code,
590
0
        NSM_QUERY_AVAILABLE_CLEARABLE_SCALAR_DATA_SOURCES, msg);
591
0
  }
592
593
0
  struct nsm_query_available_clearable_scalar_data_sources_v1_resp *resp =
594
0
      (struct nsm_query_available_clearable_scalar_data_sources_v1_resp *)
595
0
    msg->payload;
596
597
0
  resp->hdr.command = NSM_QUERY_AVAILABLE_CLEARABLE_SCALAR_DATA_SOURCES;
598
0
  resp->hdr.completion_code = cc;
599
0
  resp->hdr.data_size = htole16(data_size);
600
0
  resp->mask_length = mask_length;
601
0
  uint8_t val;
602
0
  for (int idx = 0; idx < mask_length; idx++) {
603
0
    memcpy(&val, available_data_source_mask + idx * sizeof(uint8_t),
604
0
           sizeof(uint8_t));
605
0
    memcpy(resp->data + idx * sizeof(uint8_t), &val,
606
0
           sizeof(uint8_t));
607
0
  }
608
609
0
  for (int idx = 0; idx < mask_length; idx++) {
610
0
    memcpy(&val, clearable_data_source_mask + idx * sizeof(uint8_t),
611
0
           sizeof(uint8_t));
612
0
    memcpy(resp->data + (mask_length) * sizeof(uint8_t) +
613
0
         idx * sizeof(uint8_t),
614
0
           &val, sizeof(uint8_t));
615
0
  }
616
617
0
  return NSM_SW_SUCCESS;
618
0
}
619
620
int decode_query_available_clearable_scalar_data_sources_v1_resp(
621
    const struct nsm_msg *msg, size_t msg_len, uint8_t *cc, uint16_t *data_size,
622
    uint16_t *reason_code, uint8_t *mask_length,
623
    uint8_t *available_data_source_mask, uint8_t *clearable_data_source_mask)
624
0
{
625
0
  if (msg == NULL || cc == NULL || mask_length == NULL ||
626
0
      available_data_source_mask == NULL ||
627
0
      clearable_data_source_mask == NULL || reason_code == NULL ||
628
0
      data_size == NULL) {
629
0
    return NSM_SW_ERROR_NULL;
630
0
  }
631
0
  int rc = decode_reason_code_and_cc(msg, msg_len, cc, reason_code);
632
0
  if (rc != NSM_SW_SUCCESS || *cc != NSM_SUCCESS) {
633
0
    return rc;
634
0
  }
635
636
0
  if (msg_len <
637
0
      sizeof(struct nsm_msg_hdr) +
638
0
    sizeof(
639
0
        struct
640
0
        nsm_query_available_clearable_scalar_data_sources_v1_resp)) {
641
0
    return NSM_SW_ERROR_LENGTH;
642
0
  }
643
644
0
  struct nsm_query_available_clearable_scalar_data_sources_v1_resp *resp =
645
0
      (struct nsm_query_available_clearable_scalar_data_sources_v1_resp *)
646
0
    msg->payload;
647
648
0
  *data_size = le16toh(resp->hdr.data_size);
649
0
  *mask_length = resp->mask_length;
650
651
0
  if (*data_size !=
652
0
      sizeof(uint8_t) + 2 * (*mask_length) * sizeof(uint8_t)) {
653
0
    return NSM_SW_ERROR_DATA;
654
0
  }
655
656
0
  uint8_t val;
657
0
  for (int idx = 0; idx < *mask_length; idx++) {
658
0
    memcpy(&val, resp->data + idx * sizeof(uint8_t),
659
0
           sizeof(uint8_t));
660
0
    memcpy(available_data_source_mask + idx * sizeof(uint8_t), &val,
661
0
           sizeof(uint8_t));
662
0
  }
663
664
0
  for (int idx = 0; idx < *mask_length; idx++) {
665
0
    memcpy(&val,
666
0
           resp->data + (*mask_length) * sizeof(uint8_t) +
667
0
         idx * sizeof(uint8_t),
668
0
           sizeof(uint8_t));
669
0
    memcpy(clearable_data_source_mask + idx * sizeof(uint8_t), &val,
670
0
           sizeof(uint8_t));
671
0
  }
672
673
0
  return NSM_SW_SUCCESS;
674
0
}
675
676
int encode_clear_data_source_v1_req(uint8_t instance_id, uint8_t device_index,
677
            uint8_t groupId, uint8_t dsId,
678
            struct nsm_msg *msg)
679
0
{
680
0
  if (msg == NULL) {
681
0
    return NSM_SW_ERROR_NULL;
682
0
  }
683
684
0
  struct nsm_header_info header = {0};
685
0
  header.nsm_msg_type = NSM_REQUEST;
686
0
  header.instance_id = instance_id;
687
0
  header.nvidia_msg_type = NSM_TYPE_PCI_LINK;
688
689
0
  uint8_t rc = pack_nsm_header(&header, &(msg->hdr));
690
0
  if (rc != NSM_SW_SUCCESS) {
691
0
    return rc;
692
0
  }
693
694
0
  struct nsm_clear_data_source_v1_req *request =
695
0
      (struct nsm_clear_data_source_v1_req *)msg->payload;
696
697
0
  request->hdr.command = NSM_CLEAR_DATA_SOURCE_V1;
698
0
  request->hdr.data_size = sizeof(struct nsm_clear_data_source_v1_req) -
699
0
         sizeof(struct nsm_common_req);
700
0
  request->device_index = device_index;
701
0
  request->groupId = groupId;
702
0
  request->dsId = dsId;
703
0
  return NSM_SW_SUCCESS;
704
0
}
705
706
int decode_clear_data_source_v1_req(const struct nsm_msg *msg, size_t msg_len,
707
            uint8_t *device_index, uint8_t *groupId,
708
            uint8_t *dsId)
709
0
{
710
0
  if (msg == NULL || device_index == NULL || groupId == NULL ||
711
0
      dsId == NULL) {
712
0
    return NSM_SW_ERROR_NULL;
713
0
  }
714
715
0
  if (msg_len != sizeof(struct nsm_msg_hdr) +
716
0
         sizeof(struct nsm_clear_data_source_v1_req)) {
717
0
    return NSM_SW_ERROR_LENGTH;
718
0
  }
719
720
0
  struct nsm_clear_data_source_v1_req *request =
721
0
      (struct nsm_clear_data_source_v1_req *)msg->payload;
722
723
0
  if (request->hdr.data_size !=
724
0
      sizeof(struct nsm_clear_data_source_v1_req) -
725
0
    sizeof(struct nsm_common_req)) {
726
0
    return NSM_SW_ERROR_DATA;
727
0
  }
728
729
0
  *device_index = request->device_index;
730
0
  *groupId = request->groupId;
731
0
  *dsId = request->dsId;
732
0
  return NSM_SW_SUCCESS;
733
0
}
734
735
int encode_clear_data_source_v1_resp(uint8_t instance_id, uint8_t cc,
736
             uint16_t reason_code, struct nsm_msg *msg)
737
0
{
738
0
  if (msg == NULL) {
739
0
    return NSM_SW_ERROR_NULL;
740
0
  }
741
742
0
  struct nsm_header_info header = {0};
743
0
  header.nsm_msg_type = NSM_RESPONSE;
744
0
  header.instance_id = instance_id & INSTANCEID_MASK;
745
0
  header.nvidia_msg_type = NSM_TYPE_PCI_LINK;
746
747
0
  uint8_t rc = pack_nsm_header(&header, &msg->hdr);
748
0
  if (rc != NSM_SUCCESS) {
749
0
    return rc;
750
0
  }
751
0
  if (cc != NSM_SUCCESS) {
752
0
    return encode_reason_code(cc, reason_code,
753
0
            NSM_CLEAR_DATA_SOURCE_V1, msg);
754
0
  }
755
756
0
  struct nsm_common_resp *resp = (struct nsm_common_resp *)msg->payload;
757
0
  resp->command = NSM_CLEAR_DATA_SOURCE_V1;
758
0
  resp->completion_code = cc;
759
0
  resp->data_size = 0;
760
761
0
  return NSM_SW_SUCCESS;
762
0
}
763
764
int decode_clear_data_source_v1_resp(const struct nsm_msg *msg, size_t msg_len,
765
             uint8_t *cc, uint16_t *data_size,
766
             uint16_t *reason_code)
767
0
{
768
0
  return decode_common_resp(msg, msg_len, cc, data_size, reason_code);
769
0
}
770
771
int encode_list_available_pcie_ports_req(uint8_t instance_id,
772
           struct nsm_msg *msg)
773
0
{
774
0
  return encode_common_req(instance_id, NSM_TYPE_PCI_LINK,
775
0
         NSM_LIST_AVAILABLE_PCIE_PORTS, msg);
776
0
}
777
778
int decode_list_available_pcie_ports_req(const struct nsm_msg *msg,
779
           size_t msg_len)
780
0
{
781
0
  return decode_common_req(msg, msg_len);
782
0
}
783
784
int encode_list_available_pcie_ports_resp(
785
    uint8_t instance_id, uint8_t cc, uint16_t reason_code,
786
    const struct nsm_list_available_pcie_ports_info *info, struct nsm_msg *msg)
787
0
{
788
0
  if (msg == NULL || info == NULL) {
789
0
    return NSM_SW_ERROR_NULL;
790
0
  }
791
792
0
  struct nsm_header_info header = {NSM_RESPONSE, instance_id,
793
0
           NSM_TYPE_PCI_LINK};
794
795
0
  uint8_t rc = pack_nsm_header(&header, &msg->hdr);
796
0
  if (rc != NSM_SW_SUCCESS) {
797
0
    return rc;
798
0
  }
799
0
  if (cc != NSM_SUCCESS) {
800
0
    return encode_reason_code(cc, reason_code,
801
0
            NSM_LIST_AVAILABLE_PCIE_PORTS, msg);
802
0
  }
803
804
0
  struct nsm_list_available_pcie_ports_resp *resp =
805
0
      (struct nsm_list_available_pcie_ports_resp *)msg->payload;
806
807
0
  resp->hdr.command = NSM_LIST_AVAILABLE_PCIE_PORTS;
808
0
  resp->hdr.completion_code = cc;
809
0
  resp->hdr.data_size =
810
0
      sizeof(uint16_t) +
811
0
      info->ports_count * sizeof(struct nsm_pcie_upstream_port_info);
812
0
  resp->hdr.data_size = htole16(resp->hdr.data_size);
813
0
  resp->port_info.ports_count = htole16(info->ports_count);
814
0
  memcpy(resp->port_info.ports, info->ports,
815
0
         info->ports_count * sizeof(struct nsm_pcie_upstream_port_info));
816
0
  return rc;
817
0
}
818
819
int decode_list_available_pcie_ports_resp(
820
    const struct nsm_msg *msg, size_t msg_len, uint8_t *cc,
821
    uint16_t *reason_code, struct nsm_list_available_pcie_ports_info *info)
822
0
{
823
0
  if (msg == NULL || cc == NULL || reason_code == NULL || info == NULL) {
824
0
    return NSM_SW_ERROR_NULL;
825
0
  }
826
827
0
  int rc = decode_reason_code_and_cc(msg, msg_len, cc, reason_code);
828
0
  if (rc != NSM_SW_SUCCESS || *cc != NSM_SUCCESS) {
829
0
    return rc;
830
0
  }
831
832
0
  if (msg_len < NSM_LIST_AVAILABLE_PCIE_PORTS_RESPONSE_MIN_LEN) {
833
0
    return NSM_SW_ERROR_LENGTH;
834
0
  }
835
836
0
  struct nsm_list_available_pcie_ports_resp *resp =
837
0
      (struct nsm_list_available_pcie_ports_resp *)msg->payload;
838
839
0
  info->ports_count = le16toh(resp->port_info.ports_count);
840
841
0
  uint16_t data_size = le16toh(resp->hdr.data_size);
842
0
  uint16_t expected_data_size =
843
0
      (sizeof(uint16_t) +
844
0
       info->ports_count * sizeof(struct nsm_pcie_upstream_port_info));
845
0
  if (msg_len < (sizeof(struct nsm_msg_hdr) +
846
0
           sizeof(struct nsm_common_resp) + expected_data_size) ||
847
0
      data_size != expected_data_size) {
848
0
    return NSM_SW_ERROR_LENGTH;
849
0
  }
850
851
0
  memcpy(info->ports, resp->port_info.ports,
852
0
         info->ports_count * sizeof(struct nsm_pcie_upstream_port_info));
853
854
0
  for (int i = 0; i < info->ports_count; i++) {
855
0
    if (info->ports[i].type > NSM_PORT_TYPE_DOWNSTREAM) {
856
0
      return NSM_SW_ERROR_DATA;
857
0
    }
858
0
  }
859
860
0
  return NSM_SW_SUCCESS;
861
0
}
862
863
int encode_multiport_query_scalar_group_telemetry_v2_req(
864
    uint8_t instance_id,
865
    const struct nsm_multiport_query_scalar_group_telemetry_v2_req_data *data,
866
    struct nsm_msg *msg)
867
0
{
868
0
  if (msg == NULL || data == NULL) {
869
0
    return NSM_SW_ERROR_NULL;
870
0
  }
871
872
0
  struct nsm_header_info header = {NSM_REQUEST, instance_id,
873
0
           NSM_TYPE_PCI_LINK};
874
0
  uint8_t rc = pack_nsm_header(&header, &msg->hdr);
875
0
  if (rc != NSM_SW_SUCCESS) {
876
0
    return rc;
877
0
  }
878
879
0
  struct nsm_multiport_query_scalar_group_telemetry_v2_req *request =
880
0
      (struct nsm_multiport_query_scalar_group_telemetry_v2_req *)
881
0
    msg->payload;
882
883
0
  request->hdr.command = NSM_MULTIPORT_QUERY_SCALAR_GROUP_TELEMETRY_V2;
884
0
  request->hdr.data_size = sizeof(
885
0
      struct nsm_multiport_query_scalar_group_telemetry_v2_req_data);
886
0
  request->data = *data;
887
888
0
  return NSM_SW_SUCCESS;
889
0
}
890
891
int decode_multiport_query_scalar_group_telemetry_v1_req(
892
    const struct nsm_msg *msg, size_t msg_len,
893
    struct nsm_multiport_query_scalar_group_telemetry_v2_req_data *data)
894
0
{
895
0
  if (msg == NULL || data == NULL) {
896
0
    return NSM_SW_ERROR_NULL;
897
0
  }
898
899
0
  struct nsm_header_info header = {0};
900
0
  uint8_t rc = unpack_nsm_header(&msg->hdr, &header);
901
0
  if (rc != NSM_SW_SUCCESS) {
902
0
    return rc;
903
0
  }
904
905
0
  if (msg_len !=
906
0
      sizeof(struct nsm_msg_hdr) +
907
0
    sizeof(
908
0
        struct nsm_multiport_query_scalar_group_telemetry_v2_req)) {
909
0
    return NSM_SW_ERROR_LENGTH;
910
0
  }
911
912
0
  struct nsm_multiport_query_scalar_group_telemetry_v2_req *request =
913
0
      (struct nsm_multiport_query_scalar_group_telemetry_v2_req *)
914
0
    msg->payload;
915
916
0
  if (request->hdr.data_size !=
917
0
      sizeof(struct
918
0
       nsm_multiport_query_scalar_group_telemetry_v2_req_data)) {
919
0
    return NSM_SW_ERROR_LENGTH;
920
0
  }
921
922
0
  *data = request->data;
923
0
  return NSM_SW_SUCCESS;
924
0
}