1 /*
2 * SPDX-FileCopyrightText: Copyright (c) 2017-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3 * SPDX-License-Identifier: MIT
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24 #include "common_nvswitch.h"
25 #include "rom_nvswitch.h"
26 #include "error_nvswitch.h"
27 #include "regkey_nvswitch.h"
28 #include "bios_nvswitch.h"
29 #include "haldef_nvswitch.h"
30 #include "flcn/haldefs_flcnable_nvswitch.h"
31 #include "flcn/flcn_nvswitch.h"
32 #include "soe/soe_nvswitch.h"
33 #include "soe/soeififr.h"
34 #include "nvVer.h"
35 #include "nvlink_inband_msg.h"
36 #include "cci/cci_nvswitch.h"
37
38 static NvlStatus _nvswitch_ctrl_inband_flush_data(nvswitch_device *device, NVSWITCH_INBAND_FLUSH_DATA_PARAMS *p);
39
40 #define NVSWITCH_DEV_CMD_CHECK_ADMIN NVBIT64(0)
41 #define NVSWITCH_DEV_CMD_CHECK_FM NVBIT64(1)
42
43 #define NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(cmd, function, type, private, flags)\
44 case cmd: \
45 { \
46 if (sizeof(type) != size) \
47 { \
48 retval = -NVL_BAD_ARGS; \
49 break; \
50 } \
51 \
52 retval = _nvswitch_lib_validate_privileged_ctrl(private, flags); \
53 if (retval != NVL_SUCCESS) \
54 { \
55 break; \
56 } \
57 \
58 retval = function(device, params); \
59 break; \
60 } \
61
62 #define NVSWITCH_DEV_CMD_DISPATCH_RESERVED(cmd) \
63 case cmd: \
64 { \
65 retval = -NVL_ERR_NOT_SUPPORTED; \
66 break; \
67 } \
68
69 const static NvU32 nvswitch_lr10_device_ids[] =
70 {
71 0x1AE8, 0x1AF0, 0x1AF1, 0x1AF2, 0x1AF3, 0x1AF4, 0x1AF5, 0x1AF6, 0x1AF7,
72 0x1AF8, 0x1AF9, 0x1AFA, 0x1AFB, 0x1AFC, 0x1AFD, 0x1AFE, 0x1AFF
73 };
74
75 const static NvU32 nvswitch_ls10_device_ids[] =
76 {
77 // PCIE endpoint to manage the NVLink switch HW
78 0x22A0, 0x22A1, 0x22A2, 0x22A3, 0x22A4, 0x22A5, 0x22A6, 0x22A7,
79 // PCI-PCI Bridge, Laguna Switch Function 0
80 0x22A8, 0x22A9, 0x22AA, 0x22AB,
81 // Non-Transparent Bridge, Laguna Switch Function 1
82 0x22AC, 0x22AD, 0x22AE, 0x22AF
83 };
84
85 nvlink_link_handlers link_handlers;
86
87 static NvBool
_nvswitch_is_device_id_present(const NvU32 * array,NvU32 array_len,NvU32 device_id)88 _nvswitch_is_device_id_present
89 (
90 const NvU32 *array,
91 NvU32 array_len,
92 NvU32 device_id
93 )
94 {
95 NvU32 i = 0;
96
97 for(i = 0; i < array_len; i++)
98 {
99 if (array[i] == device_id)
100 {
101 return NV_TRUE;
102 }
103 }
104
105 return NV_FALSE;
106 }
107
108 NvBool
nvswitch_is_lr10_device_id(NvU32 device_id)109 nvswitch_is_lr10_device_id
110 (
111 NvU32 device_id
112 )
113 {
114 NvU32 count = (sizeof(nvswitch_lr10_device_ids) /
115 sizeof(nvswitch_lr10_device_ids[0]));
116
117 return _nvswitch_is_device_id_present(nvswitch_lr10_device_ids, count, device_id);
118 }
119
120 NvBool
nvswitch_is_ls10_device_id(NvU32 device_id)121 nvswitch_is_ls10_device_id
122 (
123 NvU32 device_id
124 )
125 {
126 NvU32 count = (sizeof(nvswitch_ls10_device_ids) /
127 sizeof(nvswitch_ls10_device_ids[0]));
128
129 return _nvswitch_is_device_id_present(nvswitch_ls10_device_ids, count, device_id);
130 }
131
132 /*
133 * NVLink corelib callbacks are used by the NVLink library separate from the
134 * NVSwitch driver, therefore they do not take a device lock and can not modify
135 * nvswitch_device state or use error logging.
136 *
137 * These NVSwitch functions modify link state outside of the corelib:
138 * _nvswitch_ctrl_inject_link_error - injects asynchronous link errors (MODS-only)
139 */
140
141 static NV_API_CALL NvlStatus
_nvswitch_corelib_add_link(nvlink_link * link)142 _nvswitch_corelib_add_link
143 (
144 nvlink_link *link
145 )
146 {
147 nvswitch_device *device = link->dev->pDevInfo;
148 return device->hal.nvswitch_corelib_add_link(link);
149 }
150
151 static NV_API_CALL NvlStatus
_nvswitch_corelib_remove_link(nvlink_link * link)152 _nvswitch_corelib_remove_link
153 (
154 nvlink_link *link
155 )
156 {
157 nvswitch_device *device = link->dev->pDevInfo;
158 return device->hal.nvswitch_corelib_remove_link(link);
159 }
160
161 static NV_API_CALL NvlStatus
_nvswitch_corelib_set_dl_link_mode(nvlink_link * link,NvU64 mode,NvU32 flags)162 _nvswitch_corelib_set_dl_link_mode
163 (
164 nvlink_link *link,
165 NvU64 mode,
166 NvU32 flags
167 )
168 {
169 nvswitch_device *device = link->dev->pDevInfo;
170 return device->hal.nvswitch_corelib_set_dl_link_mode(link, mode, flags);
171 }
172
173 static NV_API_CALL NvlStatus
_nvswitch_corelib_get_dl_link_mode(nvlink_link * link,NvU64 * mode)174 _nvswitch_corelib_get_dl_link_mode
175 (
176 nvlink_link *link,
177 NvU64 *mode
178 )
179 {
180 nvswitch_device *device = link->dev->pDevInfo;
181 return device->hal.nvswitch_corelib_get_dl_link_mode(link, mode);
182 }
183
184 static NV_API_CALL NvlStatus
_nvswitch_corelib_set_tl_link_mode(nvlink_link * link,NvU64 mode,NvU32 flags)185 _nvswitch_corelib_set_tl_link_mode
186 (
187 nvlink_link *link,
188 NvU64 mode,
189 NvU32 flags
190 )
191 {
192 nvswitch_device *device = link->dev->pDevInfo;
193 return device->hal.nvswitch_corelib_set_tl_link_mode(link, mode, flags);
194 }
195
196 static NV_API_CALL NvlStatus
_nvswitch_corelib_get_tl_link_mode(nvlink_link * link,NvU64 * mode)197 _nvswitch_corelib_get_tl_link_mode
198 (
199 nvlink_link *link,
200 NvU64 *mode
201 )
202 {
203 nvswitch_device *device = link->dev->pDevInfo;
204 return device->hal.nvswitch_corelib_get_tl_link_mode(link, mode);
205 }
206
207 static NV_API_CALL NvlStatus
_nvswitch_corelib_set_tx_mode(nvlink_link * link,NvU64 mode,NvU32 flags)208 _nvswitch_corelib_set_tx_mode
209 (
210 nvlink_link *link,
211 NvU64 mode,
212 NvU32 flags
213 )
214 {
215 nvswitch_device *device = link->dev->pDevInfo;
216 return device->hal.nvswitch_corelib_set_tx_mode(link, mode, flags);
217 }
218
219 static NV_API_CALL NvlStatus
_nvswitch_corelib_get_tx_mode(nvlink_link * link,NvU64 * mode,NvU32 * subMode)220 _nvswitch_corelib_get_tx_mode
221 (
222 nvlink_link *link,
223 NvU64 *mode,
224 NvU32 *subMode
225 )
226 {
227 nvswitch_device *device = link->dev->pDevInfo;
228 return device->hal.nvswitch_corelib_get_tx_mode(link, mode, subMode);
229 }
230
231 static NV_API_CALL NvlStatus
_nvswitch_corelib_set_rx_mode(nvlink_link * link,NvU64 mode,NvU32 flags)232 _nvswitch_corelib_set_rx_mode
233 (
234 nvlink_link *link,
235 NvU64 mode,
236 NvU32 flags
237 )
238 {
239 nvswitch_device *device = link->dev->pDevInfo;
240 return device->hal.nvswitch_corelib_set_rx_mode(link, mode, flags);
241 }
242
243 static NV_API_CALL NvlStatus
_nvswitch_corelib_get_rx_mode(nvlink_link * link,NvU64 * mode,NvU32 * subMode)244 _nvswitch_corelib_get_rx_mode
245 (
246 nvlink_link *link,
247 NvU64 *mode,
248 NvU32 *subMode
249 )
250 {
251 nvswitch_device *device = link->dev->pDevInfo;
252 return device->hal.nvswitch_corelib_get_rx_mode(link, mode, subMode);
253 }
254
255 static NV_API_CALL NvlStatus
_nvswitch_corelib_set_rx_detect(nvlink_link * link,NvU32 flags)256 _nvswitch_corelib_set_rx_detect
257 (
258 nvlink_link *link,
259 NvU32 flags
260 )
261 {
262 nvswitch_device *device = link->dev->pDevInfo;
263 return device->hal.nvswitch_corelib_set_rx_detect(link, flags);
264 }
265
266 static NV_API_CALL NvlStatus
_nvswitch_corelib_get_rx_detect(nvlink_link * link)267 _nvswitch_corelib_get_rx_detect
268 (
269 nvlink_link *link
270 )
271 {
272 nvswitch_device *device = link->dev->pDevInfo;
273 return device->hal.nvswitch_corelib_get_rx_detect(link);
274 }
275
276 static NV_API_CALL void
_nvswitch_corelib_training_complete(nvlink_link * link)277 _nvswitch_corelib_training_complete
278 (
279 nvlink_link *link
280 )
281 {
282 nvswitch_device *device = link->dev->pDevInfo;
283 device->hal.nvswitch_corelib_training_complete(link);
284 }
285
286 static NV_API_CALL void
_nvswitch_corelib_get_uphy_load(nvlink_link * link,NvBool * bUnlocked)287 _nvswitch_corelib_get_uphy_load
288 (
289 nvlink_link *link,
290 NvBool *bUnlocked
291 )
292 {
293 nvswitch_device *device = link->dev->pDevInfo;
294 device->hal.nvswitch_corelib_get_uphy_load(link, bUnlocked);
295 }
296
297
298 static NV_API_CALL NvlStatus
_nvswitch_corelib_write_discovery_token(nvlink_link * link,NvU64 token)299 _nvswitch_corelib_write_discovery_token
300 (
301 nvlink_link *link,
302 NvU64 token
303 )
304 {
305 nvswitch_device *device = link->dev->pDevInfo;
306
307 if (link->version >= NVLINK_DEVICE_VERSION_40)
308 {
309 nvswitch_store_topology_information(device, link);
310 return NVL_SUCCESS;
311 }
312
313 return NVL_SUCCESS;
314 }
315
316 static NV_API_CALL NvlStatus
_nvswitch_corelib_read_discovery_token(nvlink_link * link,NvU64 * token)317 _nvswitch_corelib_read_discovery_token
318 (
319 nvlink_link *link,
320 NvU64 *token
321 )
322 {
323 if (link->version >= NVLINK_DEVICE_VERSION_40)
324 {
325 return NVL_SUCCESS;
326 }
327 return NVL_SUCCESS;
328 }
329
330 static NV_API_CALL NvlStatus
_nvswitch_corelib_get_cci_link_mode(nvlink_link * link,NvU64 * mode)331 _nvswitch_corelib_get_cci_link_mode
332 (
333 nvlink_link *link,
334 NvU64 *mode
335 )
336 {
337 nvswitch_device *device = link->dev->pDevInfo;
338 return device->hal.nvswitch_cci_get_cci_link_mode(device, link->linkNumber, mode);
339 }
340
341 static NV_API_CALL NvlStatus
_nvswitch_corelib_ali_training(nvlink_link * link)342 _nvswitch_corelib_ali_training
343 (
344 nvlink_link *link
345 )
346 {
347 nvswitch_device *device = link->dev->pDevInfo;
348 return device->hal.nvswitch_launch_ALI_link_training(device, link, NV_FALSE);
349 }
350
351 void
nvswitch_get_link_handlers(nvlink_link_handlers * nvswitch_link_handlers)352 nvswitch_get_link_handlers
353 (
354 nvlink_link_handlers *nvswitch_link_handlers
355 )
356 {
357 if (!nvswitch_link_handlers)
358 {
359 NVSWITCH_ASSERT(0);
360 return;
361 }
362
363 nvswitch_link_handlers->add = _nvswitch_corelib_add_link;
364 nvswitch_link_handlers->remove = _nvswitch_corelib_remove_link;
365 nvswitch_link_handlers->set_dl_link_mode = _nvswitch_corelib_set_dl_link_mode;
366 nvswitch_link_handlers->get_dl_link_mode = _nvswitch_corelib_get_dl_link_mode;
367 nvswitch_link_handlers->set_tl_link_mode = _nvswitch_corelib_set_tl_link_mode;
368 nvswitch_link_handlers->get_tl_link_mode = _nvswitch_corelib_get_tl_link_mode;
369 nvswitch_link_handlers->set_tx_mode = _nvswitch_corelib_set_tx_mode;
370 nvswitch_link_handlers->get_tx_mode = _nvswitch_corelib_get_tx_mode;
371 nvswitch_link_handlers->set_rx_mode = _nvswitch_corelib_set_rx_mode;
372 nvswitch_link_handlers->get_rx_mode = _nvswitch_corelib_get_rx_mode;
373 nvswitch_link_handlers->set_rx_detect = _nvswitch_corelib_set_rx_detect;
374 nvswitch_link_handlers->get_rx_detect = _nvswitch_corelib_get_rx_detect;
375 nvswitch_link_handlers->training_complete = _nvswitch_corelib_training_complete;
376 nvswitch_link_handlers->get_uphy_load = _nvswitch_corelib_get_uphy_load;
377 nvswitch_link_handlers->write_discovery_token = _nvswitch_corelib_write_discovery_token;
378 nvswitch_link_handlers->read_discovery_token = _nvswitch_corelib_read_discovery_token;
379 nvswitch_link_handlers->ali_training = _nvswitch_corelib_ali_training;
380 nvswitch_link_handlers->get_cci_link_mode = _nvswitch_corelib_get_cci_link_mode;
381 }
382
383 #define NVSWITCH_INIT_REGKEY(_private, _regkey, _string, _default_val) \
384 do \
385 { \
386 NvU32 data; \
387 \
388 device->regkeys._regkey = _default_val; \
389 if (NV_SWITCH_REGKEY_PRIVATE_ALLOWED || !NV_SWITCH_REGKEY##_private) \
390 { \
391 if (NVL_SUCCESS == \
392 nvswitch_os_read_registry_dword(device->os_handle, _string, &data)) \
393 { \
394 NVSWITCH_PRINT(device, SETUP, \
395 "%s: Applying regkey %s=0x%x\n", \
396 __FUNCTION__, \
397 _string, data); \
398 device->regkeys._regkey = data; \
399 } \
400 } \
401 } while(0)
402
403 static void
_nvswitch_init_device_regkeys(nvswitch_device * device)404 _nvswitch_init_device_regkeys
405 (
406 nvswitch_device *device
407 )
408 {
409 //
410 // Public external use regkeys
411 //
412 NVSWITCH_INIT_REGKEY(_PUBLIC, ato_control,
413 NV_SWITCH_REGKEY_ATO_CONTROL,
414 NV_SWITCH_REGKEY_ATO_CONTROL_DEFAULT);
415
416 NVSWITCH_INIT_REGKEY(_PUBLIC, sto_control,
417 NV_SWITCH_REGKEY_STO_CONTROL,
418 NV_SWITCH_REGKEY_STO_CONTROL_DEFAULT);
419
420 NVSWITCH_INIT_REGKEY(_PUBLIC, crc_bit_error_rate_short,
421 NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_SHORT,
422 NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_SHORT_DEFAULT);
423
424 NVSWITCH_INIT_REGKEY(_PUBLIC, crc_bit_error_rate_long,
425 NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_LONG,
426 NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_LONG_DEFAULT);
427
428 NVSWITCH_INIT_REGKEY(_PUBLIC, surpress_link_errors_for_gpu_reset,
429 NV_SWITCH_REGKEY_SURPRESS_LINK_ERRORS_FOR_GPU_RESET,
430 NV_SWITCH_REGKEY_SURPRESS_LINK_ERRORS_FOR_GPU_RESET_DISABLE);
431
432 NVSWITCH_INIT_REGKEY(_PUBLIC, cci_control,
433 NV_SWITCH_REGKEY_CCI_CONTROL,
434 NV_SWITCH_REGKEY_CCI_CONTROL_DEFAULT);
435 NVSWITCH_INIT_REGKEY(_PRIVATE, cci_link_train_disable_mask,
436 NV_SWITCH_REGKEY_CCI_DISABLE_LINK_TRAIN_MASK,
437 NV_SWITCH_REGKEY_CCI_DISABLE_LINK_TRAIN_MASK_DEFAULT);
438 NVSWITCH_INIT_REGKEY(_PRIVATE, cci_link_train_disable_mask2,
439 NV_SWITCH_REGKEY_CCI_DISABLE_LINK_TRAIN_MASK2,
440 NV_SWITCH_REGKEY_CCI_DISABLE_LINK_TRAIN_MASK2_DEFAULT);
441 NVSWITCH_INIT_REGKEY(_PUBLIC, cci_max_onboard_attempts,
442 NV_SWITCH_REGKEY_CCI_MAX_ONBOARD_ATTEMPTS,
443 NV_SWITCH_REGKEY_CCI_MAX_ONBOARD_ATTEMPTS_DEFAULT);
444 NVSWITCH_INIT_REGKEY(_PUBLIC, cci_error_log_enable,
445 NV_SWITCH_REGKEY_CCI_ERROR_LOG_ENABLE,
446 NV_SWITCH_REGKEY_CCI_ERROR_LOG_ENABLE_DEFAULT);
447 //
448 // Debug use regkeys
449 // Not available on release build kernel drivers
450 //
451 NVSWITCH_INIT_REGKEY(_PRIVATE, external_fabric_mgmt,
452 NV_SWITCH_REGKEY_EXTERNAL_FABRIC_MGMT,
453 NV_SWITCH_REGKEY_EXTERNAL_FABRIC_MGMT_ENABLE);
454
455 NVSWITCH_INIT_REGKEY(_PRIVATE, txtrain_control,
456 NV_SWITCH_REGKEY_TXTRAIN_CONTROL,
457 NV_SWITCH_REGKEY_TXTRAIN_CONTROL_NOP);
458
459 NVSWITCH_INIT_REGKEY(_PRIVATE, crossbar_DBI,
460 NV_SWITCH_REGKEY_CROSSBAR_DBI,
461 NV_SWITCH_REGKEY_CROSSBAR_DBI_ENABLE);
462
463 NVSWITCH_INIT_REGKEY(_PRIVATE, link_DBI,
464 NV_SWITCH_REGKEY_LINK_DBI,
465 NV_SWITCH_REGKEY_LINK_DBI_ENABLE);
466
467 NVSWITCH_INIT_REGKEY(_PRIVATE, ac_coupled_mask,
468 NV_SWITCH_REGKEY_AC_COUPLED_MASK,
469 0);
470
471 NVSWITCH_INIT_REGKEY(_PRIVATE, ac_coupled_mask2,
472 NV_SWITCH_REGKEY_AC_COUPLED_MASK2,
473 0);
474
475 NVSWITCH_INIT_REGKEY(_PRIVATE, swap_clk,
476 NV_SWITCH_REGKEY_SWAP_CLK_OVERRIDE,
477 nvswitch_get_swap_clk_default(device));
478
479 NVSWITCH_INIT_REGKEY(_PRIVATE, link_enable_mask,
480 NV_SWITCH_REGKEY_ENABLE_LINK_MASK,
481 NV_U32_MAX);
482
483 NVSWITCH_INIT_REGKEY(_PRIVATE, link_enable_mask2,
484 NV_SWITCH_REGKEY_ENABLE_LINK_MASK2,
485 NV_U32_MAX);
486
487 NVSWITCH_INIT_REGKEY(_PRIVATE, bandwidth_shaper,
488 NV_SWITCH_REGKEY_BANDWIDTH_SHAPER,
489 NV_SWITCH_REGKEY_BANDWIDTH_SHAPER_PROD);
490
491 NVSWITCH_INIT_REGKEY(_PRIVATE, ssg_control,
492 NV_SWITCH_REGKEY_SSG_CONTROL,
493 0);
494
495 NVSWITCH_INIT_REGKEY(_PRIVATE, skip_buffer_ready,
496 NV_SWITCH_REGKEY_SKIP_BUFFER_READY,
497 0);
498
499 NVSWITCH_INIT_REGKEY(_PUBLIC, enable_pm,
500 NV_SWITCH_REGKEY_ENABLE_PM,
501 NV_SWITCH_REGKEY_ENABLE_PM_YES);
502
503 NVSWITCH_INIT_REGKEY(_PRIVATE, chiplib_forced_config_link_mask,
504 NV_SWITCH_REGKEY_CHIPLIB_FORCED_LINK_CONFIG_MASK,
505 0);
506
507 NVSWITCH_INIT_REGKEY(_PRIVATE, chiplib_forced_config_link_mask2,
508 NV_SWITCH_REGKEY_CHIPLIB_FORCED_LINK_CONFIG_MASK2,
509 0);
510
511 NVSWITCH_INIT_REGKEY(_PRIVATE, soe_dma_self_test,
512 NV_SWITCH_REGKEY_SOE_DMA_SELFTEST,
513 NV_SWITCH_REGKEY_SOE_DMA_SELFTEST_ENABLE);
514
515 NVSWITCH_INIT_REGKEY(_PRIVATE, soe_disable,
516 NV_SWITCH_REGKEY_SOE_DISABLE,
517 NV_SWITCH_REGKEY_SOE_DISABLE_NO);
518
519 NVSWITCH_INIT_REGKEY(_PRIVATE, latency_counter,
520 NV_SWITCH_REGKEY_LATENCY_COUNTER_LOGGING,
521 NV_SWITCH_REGKEY_LATENCY_COUNTER_LOGGING_ENABLE);
522
523 NVSWITCH_INIT_REGKEY(_PRIVATE, nvlink_speed_control,
524 NV_SWITCH_REGKEY_SPEED_CONTROL,
525 NV_SWITCH_REGKEY_SPEED_CONTROL_SPEED_DEFAULT);
526
527 NVSWITCH_INIT_REGKEY(_PRIVATE, inforom_bbx_periodic_flush,
528 NV_SWITCH_REGKEY_INFOROM_BBX_ENABLE_PERIODIC_FLUSHING,
529 NV_SWITCH_REGKEY_INFOROM_BBX_ENABLE_PERIODIC_FLUSHING_DISABLE);
530
531 NVSWITCH_INIT_REGKEY(_PRIVATE, inforom_bbx_write_periodicity,
532 NV_SWITCH_REGKEY_INFOROM_BBX_WRITE_PERIODICITY,
533 NV_SWITCH_REGKEY_INFOROM_BBX_WRITE_PERIODICITY_DEFAULT);
534
535 NVSWITCH_INIT_REGKEY(_PRIVATE, inforom_bbx_write_min_duration,
536 NV_SWITCH_REGKEY_INFOROM_BBX_WRITE_MIN_DURATION,
537 NV_SWITCH_REGKEY_INFOROM_BBX_WRITE_MIN_DURATION_DEFAULT);
538
539 NVSWITCH_INIT_REGKEY(_PRIVATE, minion_disable,
540 NV_SWITCH_REGKEY_MINION_DISABLE,
541 NV_SWITCH_REGKEY_MINION_DISABLE_NO);
542
543 NVSWITCH_INIT_REGKEY(_PRIVATE, set_ucode_target,
544 NV_SWITCH_REGKEY_MINION_SET_UCODE_TARGET,
545 NV_SWITCH_REGKEY_MINION_SET_UCODE_TARGET_DEFAULT);
546
547 NVSWITCH_INIT_REGKEY(_PRIVATE, set_simmode,
548 NV_SWITCH_REGKEY_MINION_SET_SIMMODE,
549 NV_SWITCH_REGKEY_MINION_SET_SIMMODE_DEFAULT);
550
551 NVSWITCH_INIT_REGKEY(_PRIVATE, set_smf_settings,
552 NV_SWITCH_REGKEY_MINION_SET_SMF_SETTINGS,
553 NV_SWITCH_REGKEY_MINION_SET_SMF_SETTINGS_DEFAULT);
554
555 NVSWITCH_INIT_REGKEY(_PRIVATE, select_uphy_tables,
556 NV_SWITCH_REGKEY_MINION_SELECT_UPHY_TABLES,
557 NV_SWITCH_REGKEY_MINION_SELECT_UPHY_TABLES_DEFAULT);
558
559 NVSWITCH_INIT_REGKEY(_PRIVATE, link_training_mode,
560 NV_SWITCH_REGKEY_LINK_TRAINING_SELECT,
561 NV_SWITCH_REGKEY_LINK_TRAINING_SELECT_DEFAULT);
562
563 NVSWITCH_INIT_REGKEY(_PRIVATE, i2c_access_control,
564 NV_SWITCH_REGKEY_I2C_ACCESS_CONTROL,
565 NV_SWITCH_REGKEY_I2C_ACCESS_CONTROL_DEFAULT);
566
567 NVSWITCH_INIT_REGKEY(_PRIVATE, force_kernel_i2c,
568 NV_SWITCH_REGKEY_FORCE_KERNEL_I2C,
569 NV_SWITCH_REGKEY_FORCE_KERNEL_I2C_DEFAULT);
570
571 NVSWITCH_INIT_REGKEY(_PRIVATE, link_recal_settings,
572 NV_SWITCH_REGKEY_LINK_RECAL_SETTINGS,
573 NV_SWITCH_REGKEY_LINK_RECAL_SETTINGS_NOP);
574
575 NVSWITCH_INIT_REGKEY(_PRIVATE, lp_threshold,
576 NV_SWITCH_REGKEY_SET_LP_THRESHOLD,
577 NV_SWITCH_REGKEY_SET_LP_THRESHOLD_DEFAULT);
578
579 NVSWITCH_INIT_REGKEY(_PUBLIC, minion_intr,
580 NV_SWITCH_REGKEY_MINION_INTERRUPTS,
581 NV_SWITCH_REGKEY_MINION_INTERRUPTS_DEFAULT);
582
583 NVSWITCH_INIT_REGKEY(_PRIVATE, block_code_mode,
584 NV_SWITCH_REGKEY_BLOCK_CODE_MODE,
585 NV_SWITCH_REGKEY_BLOCK_CODE_MODE_DEFAULT);
586
587 NVSWITCH_INIT_REGKEY(_PRIVATE, reference_clock_mode,
588 NV_SWITCH_REGKEY_REFERENCE_CLOCK_MODE,
589 NV_SWITCH_REGKEY_REFERENCE_CLOCK_MODE_DEFAULT);
590
591 NVSWITCH_INIT_REGKEY(_PRIVATE, debug_level,
592 NV_SWITCH_REGKEY_DBG_LEVEL,
593 NV_SWITCH_REGKEY_DBG_LEVEL_DEFAULT);
594 }
595
596 ct_assert(NVSWITCH_DBG_LEVEL_MMIO == NV_SWITCH_REGKEY_DBG_LEVEL_MMIO);
597 ct_assert(NVSWITCH_DBG_LEVEL_NOISY == NV_SWITCH_REGKEY_DBG_LEVEL_NOISY);
598 ct_assert(NVSWITCH_DBG_LEVEL_SETUP == NV_SWITCH_REGKEY_DBG_LEVEL_SETUP);
599 ct_assert(NVSWITCH_DBG_LEVEL_INFO == NV_SWITCH_REGKEY_DBG_LEVEL_INFO);
600 ct_assert(NVSWITCH_DBG_LEVEL_WARN == NV_SWITCH_REGKEY_DBG_LEVEL_WARN);
601 ct_assert(NVSWITCH_DBG_LEVEL_ERROR == NV_SWITCH_REGKEY_DBG_LEVEL_ERROR);
602
603 NvU64
nvswitch_lib_deferred_task_dispatcher(nvswitch_device * device)604 nvswitch_lib_deferred_task_dispatcher
605 (
606 nvswitch_device *device
607 )
608 {
609 NvU64 time_nsec;
610 NvU64 time_next_nsec = nvswitch_os_get_platform_time() + 100*NVSWITCH_INTERVAL_1MSEC_IN_NS;
611 NVSWITCH_TASK_TYPE *task;
612 NVSWITCH_TASK_TYPE *prev_task;
613
614 if (!NVSWITCH_IS_DEVICE_VALID(device))
615 {
616 return NV_U64_MAX;
617 }
618
619 prev_task = NULL;
620 task = device->tasks;
621
622 // Walk the task list, executing those whose next execution interval is at hand
623 while (task)
624 {
625 // Get current time (nsec) for scheduling
626 time_nsec = nvswitch_os_get_platform_time();
627
628 if (time_nsec >= task->last_run_nsec + task->period_nsec)
629 {
630 //
631 // The task has never been run or it is time to run
632 // Mark its last run time
633 //
634 task->last_run_nsec = time_nsec;
635 // Run the task
636 if (NVSWITCH_IS_DEVICE_INITIALIZED(device) ||
637 (task->flags & NVSWITCH_TASK_TYPE_FLAGS_RUN_EVEN_IF_DEVICE_NOT_INITIALIZED))
638 {
639 if(task->flags & NVSWITCH_TASK_TYPE_FLAGS_VOID_PTR_ARGS)
640 (*task->task_fn_vdptr)(device, task->task_args); // run task with provided args
641 else
642 (*task->task_fn_devptr)(device);
643 }
644 }
645
646 // Determine its next run time
647 time_next_nsec = NV_MIN(task->last_run_nsec + task->period_nsec, time_next_nsec);
648
649 // Advance pointer. If run once flag is set and task ran, remove task from list.
650 if((task->flags & NVSWITCH_TASK_TYPE_FLAGS_RUN_ONCE) &&
651 (task->last_run_nsec == time_nsec))
652 {
653 prev_task = task->prev;
654
655 // Removing from list head
656 if (prev_task == NULL)
657 {
658 device->tasks = task->next;
659 if (device->tasks != NULL)
660 {
661 device->tasks->prev = NULL;
662 }
663 nvswitch_os_free(task);
664 task = device->tasks;
665 }
666 else
667 {
668 prev_task->next = task->next;
669 if (prev_task->next != NULL)
670 {
671 prev_task->next->prev = prev_task;
672 }
673 nvswitch_os_free(task);
674 task = prev_task->next;
675 }
676 }
677 else
678 {
679 task = task->next;
680 }
681 }
682
683 time_nsec = nvswitch_os_get_platform_time();
684
685 // Return to the OS layer how long to wait before calling again
686 return(time_next_nsec >= time_nsec ? time_next_nsec - time_nsec : 0);
687 }
688
689 static NvlStatus
_nvswitch_setup_hal(nvswitch_device * device,NvU32 pci_device_id)690 _nvswitch_setup_hal
691 (
692 nvswitch_device *device,
693 NvU32 pci_device_id
694 )
695 {
696 if (nvswitch_is_lr10_device_id(pci_device_id))
697 {
698 nvswitch_setup_hal_lr10(device);
699 return NVL_SUCCESS;
700 }
701 if (nvswitch_is_ls10_device_id(pci_device_id))
702 {
703 nvswitch_setup_hal_ls10(device);
704 return NVL_SUCCESS;
705 }
706 NVSWITCH_PRINT(device, ERROR,
707 "NVSwitch HAL setup failed - Unrecognized PCI Device ID\n");
708 return -NVL_ERR_NOT_SUPPORTED;
709 }
710
711 NvlStatus
nvswitch_lib_check_api_version(const char * user_version,char * kernel_version,NvU32 length)712 nvswitch_lib_check_api_version
713 (
714 const char *user_version,
715 char *kernel_version,
716 NvU32 length
717 )
718 {
719 const NvLength VERSION_LENGTH = nvswitch_os_strlen(NV_VERSION_STRING);
720
721 if (kernel_version == NULL || user_version == NULL)
722 {
723 return -NVL_BAD_ARGS;
724 }
725
726 if (length < VERSION_LENGTH)
727 {
728 return -NVL_NO_MEM;
729 }
730
731 nvswitch_os_memset(kernel_version, 0x0, length);
732 nvswitch_os_strncpy(kernel_version, NV_VERSION_STRING, VERSION_LENGTH);
733
734 kernel_version[length - 1] = '\0';
735
736 if (nvswitch_os_strncmp(user_version, kernel_version, VERSION_LENGTH))
737 {
738 return -NVL_ERR_NOT_SUPPORTED;
739 }
740
741 return NVL_SUCCESS;
742 }
743
744 NvBool
nvswitch_is_inforom_supported(nvswitch_device * device)745 nvswitch_is_inforom_supported
746 (
747 nvswitch_device *device
748 )
749 {
750 return device->hal.nvswitch_is_inforom_supported(device);
751 }
752
753 NvBool
nvswitch_is_spi_supported(nvswitch_device * device)754 nvswitch_is_spi_supported
755 (
756 nvswitch_device *device
757 )
758 {
759 return device->hal.nvswitch_is_spi_supported(device);
760 }
761
762 NvBool
nvswitch_is_bios_supported(nvswitch_device * device)763 nvswitch_is_bios_supported
764 (
765 nvswitch_device *device
766 )
767 {
768 return device->hal.nvswitch_is_bios_supported(device);
769 }
770
771 NvBool
nvswitch_is_smbpbi_supported(nvswitch_device * device)772 nvswitch_is_smbpbi_supported
773 (
774 nvswitch_device *device
775 )
776 {
777 return device->hal.nvswitch_is_smbpbi_supported(device);
778 }
779
780 NvBool
nvswitch_is_soe_supported(nvswitch_device * device)781 nvswitch_is_soe_supported
782 (
783 nvswitch_device *device
784 )
785 {
786 return device->hal.nvswitch_is_soe_supported(device);
787 }
788
789
790 NvlStatus
nvswitch_init_soe(nvswitch_device * device)791 nvswitch_init_soe
792 (
793 nvswitch_device *device
794 )
795 {
796 return device->hal.nvswitch_init_soe(device);
797 }
798
799 void
nvswitch_soe_init_l2_state(nvswitch_device * device)800 nvswitch_soe_init_l2_state
801 (
802 nvswitch_device *device
803 )
804 {
805 device->hal.nvswitch_soe_init_l2_state(device);
806 }
807
808 NvlStatus
nvswitch_soe_issue_ingress_stop(nvswitch_device * device,NvU32 nport,NvBool bStop)809 nvswitch_soe_issue_ingress_stop
810 (
811 nvswitch_device *device,
812 NvU32 nport,
813 NvBool bStop
814 )
815 {
816 return device->hal.nvswitch_soe_issue_ingress_stop(device, nport, bStop);
817 }
818
819 void
nvswitch_fsp_update_cmdq_head_tail(nvswitch_device * device,NvU32 queueHead,NvU32 queueTail)820 nvswitch_fsp_update_cmdq_head_tail
821 (
822 nvswitch_device *device,
823 NvU32 queueHead,
824 NvU32 queueTail
825 )
826 {
827 device->hal.nvswitch_fsp_update_cmdq_head_tail(device, queueHead, queueTail);
828 }
829
830 void
nvswitch_fsp_get_cmdq_head_tail(nvswitch_device * device,NvU32 * pQueueHead,NvU32 * pQueueTail)831 nvswitch_fsp_get_cmdq_head_tail
832 (
833 nvswitch_device *device,
834 NvU32 *pQueueHead,
835 NvU32 *pQueueTail
836 )
837 {
838 device->hal.nvswitch_fsp_get_cmdq_head_tail(device, pQueueHead, pQueueTail);
839 }
840
841 void
nvswitch_fsp_update_msgq_head_tail(nvswitch_device * device,NvU32 msgqHead,NvU32 msgqTail)842 nvswitch_fsp_update_msgq_head_tail
843 (
844 nvswitch_device *device,
845 NvU32 msgqHead,
846 NvU32 msgqTail
847 )
848 {
849 device->hal.nvswitch_fsp_update_msgq_head_tail(device, msgqHead, msgqTail);
850 }
851
852 void
nvswitch_fsp_get_msgq_head_tail(nvswitch_device * device,NvU32 * pMsgqHead,NvU32 * pMsgqTail)853 nvswitch_fsp_get_msgq_head_tail
854 (
855 nvswitch_device *device,
856 NvU32 *pMsgqHead,
857 NvU32 *pMsgqTail
858 )
859 {
860 device->hal.nvswitch_fsp_get_msgq_head_tail(device, pMsgqHead, pMsgqTail);
861 }
862
863 NvU32
nvswitch_fsp_get_channel_size(nvswitch_device * device)864 nvswitch_fsp_get_channel_size
865 (
866 nvswitch_device *device
867 )
868 {
869 return device->hal.nvswitch_fsp_get_channel_size(device);
870 }
871
872 NvU8
nvswitch_fsp_nvdm_to_seid(nvswitch_device * device,NvU8 nvdmType)873 nvswitch_fsp_nvdm_to_seid
874 (
875 nvswitch_device *device,
876 NvU8 nvdmType
877 )
878 {
879 return device->hal.nvswitch_fsp_nvdm_to_seid(device, nvdmType);
880 }
881
882 NvU32
nvswitch_fsp_create_mctp_header(nvswitch_device * device,NvU8 som,NvU8 eom,NvU8 seid,NvU8 seq)883 nvswitch_fsp_create_mctp_header
884 (
885 nvswitch_device *device,
886 NvU8 som,
887 NvU8 eom,
888 NvU8 seid,
889 NvU8 seq
890 )
891 {
892 return device->hal.nvswitch_fsp_create_mctp_header(device, som, eom, seid, seq);
893 }
894
895 NvU32
nvswitch_fsp_create_nvdm_header(nvswitch_device * device,NvU32 nvdmType)896 nvswitch_fsp_create_nvdm_header
897 (
898 nvswitch_device *device,
899 NvU32 nvdmType
900 )
901 {
902 return device->hal.nvswitch_fsp_create_nvdm_header(device, nvdmType);
903 }
904
905 NvlStatus
nvswitch_fsp_get_packet_info(nvswitch_device * device,NvU8 * pBuffer,NvU32 size,NvU8 * pPacketState,NvU8 * pTag)906 nvswitch_fsp_get_packet_info
907 (
908 nvswitch_device *device,
909 NvU8 *pBuffer,
910 NvU32 size,
911 NvU8 *pPacketState,
912 NvU8 *pTag
913 )
914 {
915 return device->hal.nvswitch_fsp_get_packet_info(device, pBuffer, size, pPacketState, pTag);
916 }
917
918 NvlStatus
nvswitch_fsp_validate_mctp_payload_header(nvswitch_device * device,NvU8 * pBuffer,NvU32 size)919 nvswitch_fsp_validate_mctp_payload_header
920 (
921 nvswitch_device *device,
922 NvU8 *pBuffer,
923 NvU32 size
924 )
925 {
926 return device->hal.nvswitch_fsp_validate_mctp_payload_header(device, pBuffer, size);
927 }
928
929 NvlStatus
nvswitch_fsp_process_nvdm_msg(nvswitch_device * device,NvU8 * pBuffer,NvU32 size)930 nvswitch_fsp_process_nvdm_msg
931 (
932 nvswitch_device *device,
933 NvU8 *pBuffer,
934 NvU32 size
935 )
936 {
937 return device->hal.nvswitch_fsp_process_nvdm_msg(device, pBuffer, size);
938 }
939
940 NvlStatus
nvswitch_fsp_process_cmd_response(nvswitch_device * device,NvU8 * pBuffer,NvU32 size)941 nvswitch_fsp_process_cmd_response
942 (
943 nvswitch_device *device,
944 NvU8 *pBuffer,
945 NvU32 size
946 )
947 {
948 return device->hal.nvswitch_fsp_process_cmd_response(device, pBuffer, size);
949 }
950
951 NvlStatus
nvswitch_fsp_config_ememc(nvswitch_device * device,NvU32 offset,NvBool bAincw,NvBool bAincr)952 nvswitch_fsp_config_ememc
953 (
954 nvswitch_device *device,
955 NvU32 offset,
956 NvBool bAincw,
957 NvBool bAincr
958 )
959 {
960 return device->hal.nvswitch_fsp_config_ememc(device, offset, bAincw, bAincr);
961 }
962
963 NvlStatus
nvswitch_fsp_write_to_emem(nvswitch_device * device,NvU8 * pBuffer,NvU32 size)964 nvswitch_fsp_write_to_emem
965 (
966 nvswitch_device *device,
967 NvU8 *pBuffer,
968 NvU32 size
969 )
970 {
971 return device->hal.nvswitch_fsp_write_to_emem(device, pBuffer, size);
972 }
973
974 NvlStatus
nvswitch_fsp_read_from_emem(nvswitch_device * device,NvU8 * pBuffer,NvU32 size)975 nvswitch_fsp_read_from_emem
976 (
977 nvswitch_device *device,
978 NvU8 *pBuffer,
979 NvU32 size
980 )
981 {
982 return device->hal.nvswitch_fsp_read_from_emem(device, pBuffer, size);
983 }
984
985 NvlStatus
nvswitch_fsp_error_code_to_nvlstatus_map(nvswitch_device * device,NvU32 errorCode)986 nvswitch_fsp_error_code_to_nvlstatus_map
987 (
988 nvswitch_device *device,
989 NvU32 errorCode
990 )
991 {
992 return device->hal.nvswitch_fsp_error_code_to_nvlstatus_map(device, errorCode);
993 }
994
995 static NvlStatus
_nvswitch_ctrl_fsprpc_get_caps(nvswitch_device * device,NVSWITCH_FSPRPC_GET_CAPS_PARAMS * params)996 _nvswitch_ctrl_fsprpc_get_caps
997 (
998 nvswitch_device *device,
999 NVSWITCH_FSPRPC_GET_CAPS_PARAMS *params
1000 )
1001 {
1002 return device->hal.nvswitch_fsprpc_get_caps(device, params);
1003 }
1004
1005 static NvlStatus
_nvswitch_ctrl_get_attestation_certificate_chain(nvswitch_device * device,NVSWITCH_GET_ATTESTATION_CERTIFICATE_CHAIN_PARAMS * params)1006 _nvswitch_ctrl_get_attestation_certificate_chain
1007 (
1008 nvswitch_device *device,
1009 NVSWITCH_GET_ATTESTATION_CERTIFICATE_CHAIN_PARAMS *params
1010 )
1011 {
1012 return device->hal.nvswitch_tnvl_get_attestation_certificate_chain(device, params);
1013 }
1014
1015 static NvlStatus
_nvswitch_ctrl_get_attestation_report(nvswitch_device * device,NVSWITCH_GET_ATTESTATION_REPORT_PARAMS * params)1016 _nvswitch_ctrl_get_attestation_report
1017 (
1018 nvswitch_device *device,
1019 NVSWITCH_GET_ATTESTATION_REPORT_PARAMS *params
1020 )
1021 {
1022 return device->hal.nvswitch_tnvl_get_attestation_report(device, params);
1023 }
1024
1025 static NvlStatus
_nvswitch_ctrl_get_tnvl_status(nvswitch_device * device,NVSWITCH_GET_TNVL_STATUS_PARAMS * params)1026 _nvswitch_ctrl_get_tnvl_status
1027 (
1028 nvswitch_device *device,
1029 NVSWITCH_GET_TNVL_STATUS_PARAMS *params
1030 )
1031 {
1032 return device->hal.nvswitch_tnvl_get_status(device, params);
1033 }
1034
1035 static NvlStatus
_nvswitch_construct_soe(nvswitch_device * device)1036 _nvswitch_construct_soe
1037 (
1038 nvswitch_device *device
1039 )
1040 {
1041 FLCNABLE *pSoe = NULL;
1042 NvlStatus retval;
1043
1044 device->pSoe = pSoe = (PFLCNABLE)soeAllocNew();
1045 if (pSoe == NULL)
1046 {
1047 NVSWITCH_PRINT(device, ERROR, "SOE allocation failed.\n");
1048 return -NVL_NO_MEM;
1049 }
1050
1051 retval = soeInit(device, (PSOE)pSoe, device->nvlink_device->pciInfo.pciDeviceId);
1052 if (retval != NVL_SUCCESS)
1053 {
1054 NVSWITCH_PRINT(device, ERROR, "SOE init failed.\n");
1055 goto soe_init_failed;
1056 }
1057
1058 if (flcnableConstruct_HAL(device, pSoe) != NV_OK)
1059 {
1060 NVSWITCH_PRINT(device, ERROR, "FALCON construct failed.\n");
1061 retval = -NVL_ERR_INVALID_STATE;
1062 goto flcn_construct_failed;
1063 }
1064
1065 return NVL_SUCCESS;
1066
1067 flcn_construct_failed:
1068 soeDestroy(device, (PSOE)pSoe);
1069
1070 soe_init_failed:
1071 nvswitch_os_free(pSoe);
1072 device->pSoe = NULL;
1073
1074 return retval;
1075 }
1076
1077 static void
_nvswitch_destruct_soe(nvswitch_device * device)1078 _nvswitch_destruct_soe
1079 (
1080 nvswitch_device *device
1081 )
1082 {
1083 FLCNABLE *pSoe = device->pSoe;
1084
1085 if (pSoe == NULL)
1086 {
1087 return;
1088 }
1089
1090 flcnableDestruct_HAL(device, pSoe);
1091 soeDestroy(device, (PSOE)pSoe);
1092
1093 nvswitch_os_free(pSoe);
1094 device->pSoe = NULL;
1095 }
1096
1097 static NvlStatus
_nvswitch_construct_cci(nvswitch_device * device)1098 _nvswitch_construct_cci
1099 (
1100 nvswitch_device *device
1101 )
1102 {
1103 CCI *pCci = NULL;
1104 NvlStatus retval;
1105
1106 device->pCci = pCci = cciAllocNew();
1107 if (pCci == NULL)
1108 {
1109 NVSWITCH_PRINT(device, ERROR, "CCI allocation failed.\n");
1110 return -NVL_NO_MEM;
1111 }
1112
1113 retval = cciInit(device, pCci, device->nvlink_device->pciInfo.pciDeviceId);
1114 if (retval != NVL_SUCCESS)
1115 {
1116 NVSWITCH_PRINT(device, ERROR, "CCI init failed.\n");
1117 goto cci_init_failed;
1118 }
1119
1120 return NVL_SUCCESS;
1121
1122 cci_init_failed:
1123 nvswitch_os_free(pCci);
1124 device->pCci = NULL;
1125
1126 return retval;
1127 }
1128
1129 static void
_nvswitch_destruct_cci(nvswitch_device * device)1130 _nvswitch_destruct_cci
1131 (
1132 nvswitch_device *device
1133 )
1134 {
1135 CCI *pCci = device->pCci;
1136
1137 if (pCci == NULL)
1138 {
1139 return;
1140 }
1141
1142 cciDestroy(device, pCci);
1143
1144 nvswitch_os_free(pCci);
1145 device->pCci = NULL;
1146 }
1147
1148 static void
_nvswitch_update_link_state_led(nvswitch_device * device)1149 _nvswitch_update_link_state_led
1150 (
1151 nvswitch_device *device
1152 )
1153 {
1154 device->hal.nvswitch_update_link_state_led(device);
1155 }
1156
1157 static void
_nvswitch_led_shutdown(nvswitch_device * device)1158 _nvswitch_led_shutdown
1159 (
1160 nvswitch_device *device
1161 )
1162 {
1163 device->hal.nvswitch_led_shutdown(device);
1164 }
1165
1166 static NvlStatus
_nvswitch_initialize_device_state(nvswitch_device * device)1167 _nvswitch_initialize_device_state
1168 (
1169 nvswitch_device *device
1170 )
1171 {
1172 return device->hal.nvswitch_initialize_device_state(device);
1173 }
1174
1175 static NvlStatus
_nvswitch_post_init_device_setup(nvswitch_device * device)1176 _nvswitch_post_init_device_setup
1177 (
1178 nvswitch_device *device
1179 )
1180 {
1181 return device->hal.nvswitch_post_init_device_setup(device);
1182 }
1183
1184 static NvlStatus
_nvswitch_setup_system_registers(nvswitch_device * device)1185 _nvswitch_setup_system_registers
1186 (
1187 nvswitch_device *device
1188 )
1189 {
1190 return device->hal.nvswitch_setup_system_registers(device);
1191 }
1192
1193 static void
_nvswitch_post_init_blacklist_device_setup(nvswitch_device * device)1194 _nvswitch_post_init_blacklist_device_setup
1195 (
1196 nvswitch_device *device
1197 )
1198 {
1199 device->hal.nvswitch_post_init_blacklist_device_setup(device);
1200 }
1201
1202 static void
_nvswitch_set_dma_mask(nvswitch_device * device)1203 _nvswitch_set_dma_mask
1204 (
1205 nvswitch_device *device
1206 )
1207 {
1208 NvU32 hw_dma_width, retval;
1209
1210 hw_dma_width = device->hal.nvswitch_get_device_dma_width(device);
1211
1212 if (hw_dma_width == 0)
1213 {
1214 NVSWITCH_PRINT(device, INFO, "DMA is not supported on this device\n");
1215 return;
1216 }
1217
1218 retval = nvswitch_os_set_dma_mask(device->os_handle, hw_dma_width);
1219 if (retval == NVL_SUCCESS)
1220 {
1221 device->dma_addr_width = hw_dma_width;
1222 return;
1223 }
1224
1225 NVSWITCH_PRINT(device, SETUP,
1226 "%s: Failed to set DMA mask, trying 32-bit fallback : %d\n",
1227 __FUNCTION__, retval);
1228
1229 retval = nvswitch_os_set_dma_mask(device->os_handle, 32);
1230 if (retval == NVL_SUCCESS)
1231 {
1232 device->dma_addr_width = 32;
1233 return;
1234 }
1235
1236 // failure is not fatal, the driver will just restrict DMA functionality
1237 NVSWITCH_PRINT(device, ERROR, "Failed to set DMA mask : %d\n", retval);
1238 }
1239
1240 NvlStatus
nvswitch_deassert_link_reset(nvswitch_device * device,nvlink_link * link)1241 nvswitch_deassert_link_reset
1242 (
1243 nvswitch_device *device,
1244 nvlink_link *link
1245 )
1246 {
1247 return device->hal.nvswitch_deassert_link_reset(device, link);
1248 }
1249
1250 NvU32
nvswitch_get_sublink_width(nvswitch_device * device,NvU32 linkNumber)1251 nvswitch_get_sublink_width
1252 (
1253 nvswitch_device *device,
1254 NvU32 linkNumber
1255 )
1256 {
1257 return device->hal.nvswitch_get_sublink_width(device, linkNumber);
1258 }
1259
1260 static void
_nvswitch_unregister_links(nvswitch_device * device)1261 _nvswitch_unregister_links
1262 (
1263 nvswitch_device *device
1264 )
1265 {
1266 nvlink_link *link = NULL;
1267 NvU32 link_num;
1268 NvBool is_blacklisted;
1269
1270
1271 if (!NVSWITCH_IS_DEVICE_INITIALIZED(device))
1272 return;
1273
1274 device->nvlink_device->initialized = 0;
1275 is_blacklisted = (device->device_fabric_state == NVSWITCH_DEVICE_FABRIC_STATE_BLACKLISTED);
1276
1277 for (link_num = 0; link_num < nvswitch_get_num_links(device); link_num++)
1278 {
1279 if (nvlink_lib_get_link(device->nvlink_device, link_num, &link) == NVL_SUCCESS)
1280 {
1281 nvlink_lib_unregister_link(link);
1282 nvswitch_destroy_link(link);
1283 }
1284 }
1285
1286 if (!is_blacklisted)
1287 nvswitch_inforom_nvlink_flush(device);
1288 }
1289
1290 NvlStatus NV_API_CALL
nvswitch_lib_read_fabric_state(nvswitch_device * device,NVSWITCH_DEVICE_FABRIC_STATE * device_fabric_state,NVSWITCH_DEVICE_BLACKLIST_REASON * device_blacklist_reason,NVSWITCH_DRIVER_FABRIC_STATE * driver_fabric_state)1291 nvswitch_lib_read_fabric_state
1292 (
1293 nvswitch_device *device,
1294 NVSWITCH_DEVICE_FABRIC_STATE *device_fabric_state,
1295 NVSWITCH_DEVICE_BLACKLIST_REASON *device_blacklist_reason,
1296 NVSWITCH_DRIVER_FABRIC_STATE *driver_fabric_state
1297 )
1298 {
1299 if (!NVSWITCH_IS_DEVICE_ACCESSIBLE(device))
1300 return -NVL_BAD_ARGS;
1301
1302 if (device_fabric_state != NULL)
1303 *device_fabric_state = device->device_fabric_state;
1304
1305 if (device_blacklist_reason != NULL)
1306 *device_blacklist_reason = device->device_blacklist_reason;
1307
1308 if (driver_fabric_state != NULL)
1309 *driver_fabric_state = device->driver_fabric_state;
1310
1311 return NVL_SUCCESS;
1312 }
1313
1314 static NvlStatus
nvswitch_lib_blacklist_device(nvswitch_device * device,NVSWITCH_DEVICE_BLACKLIST_REASON device_blacklist_reason)1315 nvswitch_lib_blacklist_device
1316 (
1317 nvswitch_device *device,
1318 NVSWITCH_DEVICE_BLACKLIST_REASON device_blacklist_reason
1319 )
1320 {
1321 NvlStatus status;
1322
1323 if (!NVSWITCH_IS_DEVICE_ACCESSIBLE(device))
1324 {
1325 return -NVL_BAD_ARGS;
1326 }
1327
1328 if (device->device_fabric_state == NVSWITCH_DEVICE_FABRIC_STATE_BLACKLISTED)
1329 {
1330 NVSWITCH_PRINT(device, WARN, "Device is already blacklisted\n");
1331 return -NVL_ERR_NOT_SUPPORTED;
1332 }
1333
1334 device->device_fabric_state = NVSWITCH_DEVICE_FABRIC_STATE_BLACKLISTED;
1335 device->device_blacklist_reason = device_blacklist_reason;
1336
1337 status = device->hal.nvswitch_write_fabric_state(device);
1338 if (status != NVL_SUCCESS)
1339 NVSWITCH_PRINT(device, INFO, "Cannot send fabric state to SOE\n");
1340
1341 return NVL_SUCCESS;
1342 }
1343
1344 static NvlStatus
nvswitch_ctrl_blacklist_device(nvswitch_device * device,NVSWITCH_BLACKLIST_DEVICE_PARAMS * p)1345 nvswitch_ctrl_blacklist_device(
1346 nvswitch_device *device,
1347 NVSWITCH_BLACKLIST_DEVICE_PARAMS *p
1348 )
1349 {
1350 NvlStatus status;
1351
1352 status = nvswitch_lib_blacklist_device(device, p->deviceReason);
1353 if (status != NVL_SUCCESS)
1354 return status;
1355
1356 if (nvswitch_is_tnvl_mode_locked(device))
1357 {
1358 NVSWITCH_PRINT(device, ERROR,
1359 "%s(%d): Security locked\n", __FUNCTION__, __LINE__);
1360 }
1361 else
1362 {
1363 nvswitch_lib_disable_interrupts(device);
1364 }
1365
1366 // Unregister links from NVLinkCoreLib, so that link training is not
1367 // attempted
1368 _nvswitch_unregister_links(device);
1369
1370 // Keep device registered for HAL access and Fabric State updates
1371
1372 return NVL_SUCCESS;
1373 }
1374
1375 static NvlStatus
nvswitch_ctrl_set_fm_driver_state(nvswitch_device * device,NVSWITCH_SET_FM_DRIVER_STATE_PARAMS * p)1376 nvswitch_ctrl_set_fm_driver_state(
1377 nvswitch_device *device,
1378 NVSWITCH_SET_FM_DRIVER_STATE_PARAMS *p
1379 )
1380 {
1381 NvU32 prev_fm_status;
1382
1383 if (!NVSWITCH_IS_DEVICE_ACCESSIBLE(device))
1384 {
1385 return -NVL_BAD_ARGS;
1386 }
1387
1388 prev_fm_status = device->driver_fabric_state;
1389 device->driver_fabric_state = p->driverState;
1390 device->fabric_state_timestamp = nvswitch_os_get_platform_time();
1391
1392 if (prev_fm_status != p->driverState)
1393 {
1394 if (nvswitch_lib_notify_client_events(device,
1395 NVSWITCH_DEVICE_EVENT_FABRIC_STATE) != NVL_SUCCESS)
1396 {
1397 NVSWITCH_PRINT(device, ERROR, "%s: Failed to notify event\n",
1398 __FUNCTION__);
1399 }
1400 }
1401
1402 return NVL_SUCCESS;
1403 }
1404
1405 static NvlStatus
nvswitch_ctrl_set_device_fabric_state(nvswitch_device * device,NVSWITCH_SET_DEVICE_FABRIC_STATE_PARAMS * p)1406 nvswitch_ctrl_set_device_fabric_state(
1407 nvswitch_device *device,
1408 NVSWITCH_SET_DEVICE_FABRIC_STATE_PARAMS *p
1409 )
1410 {
1411 if (!NVSWITCH_IS_DEVICE_ACCESSIBLE(device))
1412 {
1413 return -NVL_BAD_ARGS;
1414 }
1415
1416 if (device->device_fabric_state == NVSWITCH_DEVICE_FABRIC_STATE_BLACKLISTED)
1417 return -NVL_ERR_NOT_SUPPORTED;
1418
1419 device->device_fabric_state = p->deviceState;
1420 device->fabric_state_timestamp = nvswitch_os_get_platform_time();
1421
1422 // If FM had exceeded timeout, reset the status to not timed-out
1423 if (device->driver_fabric_state == NVSWITCH_DRIVER_FABRIC_STATE_MANAGER_TIMEOUT)
1424 device->driver_fabric_state = NVSWITCH_DRIVER_FABRIC_STATE_CONFIGURED;
1425
1426 return NVL_SUCCESS;
1427 }
1428
1429 static NvlStatus
nvswitch_ctrl_set_fm_timeout(nvswitch_device * device,NVSWITCH_SET_FM_HEARTBEAT_TIMEOUT_PARAMS * p)1430 nvswitch_ctrl_set_fm_timeout(
1431 nvswitch_device *device,
1432 NVSWITCH_SET_FM_HEARTBEAT_TIMEOUT_PARAMS *p
1433 )
1434 {
1435 if (!NVSWITCH_IS_DEVICE_ACCESSIBLE(device))
1436 {
1437 return -NVL_BAD_ARGS;
1438 }
1439
1440 device->fm_timeout = p->fmTimeout;
1441
1442 return NVL_SUCCESS;
1443 }
1444
1445 static NvlStatus
_nvswitch_ctrl_register_events(nvswitch_device * device,NVSWITCH_REGISTER_EVENTS_PARAMS * p,void * osPrivate)1446 _nvswitch_ctrl_register_events(
1447 nvswitch_device *device,
1448 NVSWITCH_REGISTER_EVENTS_PARAMS *p,
1449 void *osPrivate
1450 )
1451 {
1452 NvlStatus status = NVL_SUCCESS;
1453 NvU32 i;
1454 NvBool many_events, os_descriptor;
1455 void *osDescriptor = osPrivate;
1456
1457 if (!NVSWITCH_IS_DEVICE_ACCESSIBLE(device))
1458 {
1459 return -NVL_BAD_ARGS;
1460 }
1461
1462 status = nvswitch_os_get_supported_register_events_params(&many_events,
1463 &os_descriptor);
1464 if (status != NVL_SUCCESS)
1465 {
1466 return status;
1467 }
1468
1469 if ((!many_events && (p->numEvents > 1)) ||
1470 (p->numEvents == 0))
1471 {
1472 return -NVL_BAD_ARGS;
1473 }
1474
1475 if (os_descriptor)
1476 {
1477 osDescriptor = (void *) p->osDescriptor;
1478 }
1479
1480 for (i = 0; i < p->numEvents; i++)
1481 {
1482 status = nvswitch_lib_add_client_event(device, osDescriptor, p->eventIds[i]);
1483 if (status != NVL_SUCCESS)
1484 {
1485 NVSWITCH_PRINT(device, ERROR, "%s: Failed to add client event.\n", __FUNCTION__);
1486 return status;
1487 }
1488 }
1489
1490 return NVL_SUCCESS;
1491 }
1492
1493 static NvlStatus
_nvswitch_ctrl_unregister_events(nvswitch_device * device,NVSWITCH_UNREGISTER_EVENTS_PARAMS * p,void * osPrivate)1494 _nvswitch_ctrl_unregister_events(
1495 nvswitch_device *device,
1496 NVSWITCH_UNREGISTER_EVENTS_PARAMS *p,
1497 void *osPrivate
1498 )
1499 {
1500 NvlStatus status = NVL_SUCCESS;
1501 NvBool many_events, os_descriptor;
1502 void *osDescriptor = osPrivate;
1503
1504 if (!NVSWITCH_IS_DEVICE_ACCESSIBLE(device))
1505 {
1506 return -NVL_BAD_ARGS;
1507 }
1508
1509 status = nvswitch_os_get_supported_register_events_params(&many_events,
1510 &os_descriptor);
1511 if (status != NVL_SUCCESS)
1512 {
1513 return status;
1514 }
1515
1516 if (os_descriptor)
1517 {
1518 osDescriptor = (void *) p->osDescriptor;
1519 }
1520
1521 status = nvswitch_lib_remove_client_events(device, osDescriptor);
1522 if (status != NVL_SUCCESS)
1523 {
1524 NVSWITCH_PRINT(device, ERROR, "%s: Failed to remove client event.\n", __FUNCTION__);
1525 return status;
1526 }
1527
1528 return NVL_SUCCESS;
1529 }
1530
1531 /*
1532 * @Brief : Sends NACK or drops given inband msg based on message type
1533 *
1534 * @Description :
1535 *
1536 * @param[in] device NvSwitch device to contain this link
1537 * @param[in] linkId Link ID
1538 * @param[in] msghdr Header to the message
1539 *
1540 */
1541 static void
nvswitch_send_nack_or_drop(nvswitch_device * device,NvU32 linkId,nvlink_inband_msg_header_t * msghdr)1542 nvswitch_send_nack_or_drop
1543 (
1544 nvswitch_device *device,
1545 NvU32 linkId,
1546 nvlink_inband_msg_header_t *msghdr
1547 )
1548 {
1549 switch(msghdr->type)
1550 {
1551 case NVLINK_INBAND_MSG_TYPE_MC_TEAM_SETUP_REQ:
1552 device->hal.nvswitch_send_inband_nack(device, (NvU32 *)msghdr, linkId);
1553 NVSWITCH_PRINT(device, ERROR,
1554 "Sending NACK for message (type 0x%x)\n", msghdr->type);
1555 return;
1556 default:
1557 // TODO: Add SXid in future if needed.
1558 NVSWITCH_PRINT(device, ERROR,
1559 "Dropping message (type 0x%x)\n", msghdr->type);
1560 return;
1561 }
1562 }
1563
1564 /*
1565 * @Brief : Deletes all the entries in persistent or non-persistent lists.
1566 * Send nacks if requested.
1567 *
1568 * @Description :
1569 *
1570 * @param[in] device NVSwitch device to contain this link
1571 * @param[in] linkId Link number
1572 * @param[in] bSendNack Send nacks if true
1573 * @param[in] bNonPersistentOnly Clear only non-persistent list
1574 */
1575 static void
_nvswitch_inband_clear_lists(nvswitch_device * device,NvU32 linkId,NvBool bSendNack,NvBool bNonPersistentOnly)1576 _nvswitch_inband_clear_lists
1577 (
1578 nvswitch_device *device,
1579 NvU32 linkId,
1580 NvBool bSendNack,
1581 NvBool bNonPersistentOnly
1582 )
1583 {
1584 nvswitch_inband_data_list *curr = NULL;
1585 nvswitch_inband_data_list *next = NULL;
1586 nvlink_inband_msg_header_t *msghdr = NULL;
1587
1588 nvListForEachEntry_safe(curr, next,
1589 &device->link[linkId].inbandData.nonpersistent_list, entry)
1590 {
1591 if (bSendNack)
1592 {
1593 msghdr = (nvlink_inband_msg_header_t *)curr->data;
1594 nvswitch_send_nack_or_drop(device, linkId, msghdr);
1595 }
1596
1597 nvListDel(&curr->entry);
1598 nvswitch_os_free(curr);
1599 }
1600
1601 if (bNonPersistentOnly)
1602 return;
1603
1604 nvListForEachEntry_safe(curr, next,
1605 &device->link[linkId].inbandData.persistent_list, entry)
1606 {
1607 if (bSendNack)
1608 {
1609 msghdr = (nvlink_inband_msg_header_t *)curr->data;
1610 nvswitch_send_nack_or_drop(device, linkId, msghdr);
1611 }
1612
1613 nvListDel(&curr->entry);
1614 nvswitch_os_free(curr);
1615 }
1616 }
1617
1618 static void
nvswitch_fabric_state_heartbeat(nvswitch_device * device)1619 nvswitch_fabric_state_heartbeat(
1620 nvswitch_device *device
1621 )
1622 {
1623 NvU64 age;
1624 NvU32 linkId;
1625
1626 if (!NVSWITCH_IS_DEVICE_VALID(device))
1627 return;
1628
1629 age = nvswitch_os_get_platform_time() - device->fabric_state_timestamp;
1630
1631 // Check to see if we have exceeded the FM timeout
1632 if (device->driver_fabric_state == NVSWITCH_DRIVER_FABRIC_STATE_CONFIGURED &&
1633 age > (NvU64)device->fm_timeout * 1000ULL * 1000ULL)
1634 device->driver_fabric_state = NVSWITCH_DRIVER_FABRIC_STATE_MANAGER_TIMEOUT;
1635
1636 //
1637 // If FM is not running, clear pending non-persistent messages. Persistent
1638 // messages can be processed by the FM when it restarts.
1639 //
1640 if (device->driver_fabric_state != NVSWITCH_DRIVER_FABRIC_STATE_CONFIGURED)
1641 {
1642 for (linkId = 0; linkId < nvswitch_get_num_links(device); linkId++)
1643 _nvswitch_inband_clear_lists(device, linkId,
1644 NV_TRUE /* Nack */,
1645 NV_TRUE /* Non-persistent only */);
1646 }
1647
1648 (void)device->hal.nvswitch_write_fabric_state(device);
1649 }
1650
1651 static NvlStatus
_nvswitch_ctrl_set_training_error_info(nvswitch_device * device,NVSWITCH_SET_TRAINING_ERROR_INFO_PARAMS * p)1652 _nvswitch_ctrl_set_training_error_info
1653 (
1654 nvswitch_device *device,
1655 NVSWITCH_SET_TRAINING_ERROR_INFO_PARAMS *p
1656 )
1657 {
1658 return device->hal.nvswitch_set_training_error_info(device, p);
1659 }
1660
1661 static NvlStatus
_nvswitch_ctrl_get_fatal_error_scope(nvswitch_device * device,NVSWITCH_GET_FATAL_ERROR_SCOPE_PARAMS * pParams)1662 _nvswitch_ctrl_get_fatal_error_scope
1663 (
1664 nvswitch_device *device,
1665 NVSWITCH_GET_FATAL_ERROR_SCOPE_PARAMS *pParams
1666 )
1667 {
1668 return device->hal.nvswitch_ctrl_get_fatal_error_scope(device, pParams);
1669 }
1670
1671 static NvlStatus
_nvswitch_ctrl_therm_get_temperature_limit(nvswitch_device * device,NVSWITCH_CTRL_GET_TEMPERATURE_LIMIT_PARAMS * pParams)1672 _nvswitch_ctrl_therm_get_temperature_limit
1673 (
1674 nvswitch_device *device,
1675 NVSWITCH_CTRL_GET_TEMPERATURE_LIMIT_PARAMS *pParams
1676 )
1677 {
1678 if (!NVSWITCH_IS_DEVICE_ACCESSIBLE(device))
1679 {
1680 return -NVL_BAD_ARGS;
1681 }
1682
1683 return device->hal.nvswitch_ctrl_therm_get_temperature_limit(device, pParams);
1684 }
1685
1686 //
1687 // Construct an port event log
1688 //
1689 // If port_event_log_size > 0 a circular buffer is created to record port events
1690 //
1691 NvlStatus
_nvswitch_construct_port_event_log(NVSWITCH_PORT_EVENT_LOG_TYPE * port_events,NvU32 port_event_log_size,NvBool overwritable)1692 _nvswitch_construct_port_event_log
1693 (
1694 NVSWITCH_PORT_EVENT_LOG_TYPE *port_events,
1695 NvU32 port_event_log_size,
1696 NvBool overwritable
1697 )
1698 {
1699 NvlStatus retval = NVL_SUCCESS;
1700
1701 NVSWITCH_ASSERT(port_events != NULL);
1702
1703 port_events->port_event_start = 0;
1704 port_events->port_event_count = 0;
1705 port_events->port_event_total = 0;
1706 port_events->port_event_log_size = 0;
1707 port_events->port_event_log = NULL;
1708 port_events->overwritable = overwritable;
1709 port_events->bOverflow = NV_FALSE;
1710
1711 if (port_event_log_size > 0)
1712 {
1713 port_events->port_event_log = nvswitch_os_malloc(port_event_log_size * sizeof(NVSWITCH_PORT_EVENT_TYPE));
1714 }
1715
1716 if (port_events->port_event_log != NULL)
1717 {
1718 port_events->port_event_log_size = port_event_log_size;
1719 nvswitch_os_memset(port_events->port_event_log, 0, port_events->port_event_log_size * sizeof(NVSWITCH_PORT_EVENT_TYPE));
1720 }
1721
1722 if (port_event_log_size != port_events->port_event_log_size)
1723 {
1724 retval = -NVL_NO_MEM;
1725 }
1726
1727 return retval;
1728 }
1729
1730 //
1731 // Destroy an error log
1732 //
1733 void
_nvswitch_destroy_port_event_log(nvswitch_device * device,NVSWITCH_PORT_EVENT_LOG_TYPE * port_events)1734 _nvswitch_destroy_port_event_log
1735 (
1736 nvswitch_device *device,
1737 NVSWITCH_PORT_EVENT_LOG_TYPE *port_events
1738 )
1739 {
1740 if (port_events == NULL)
1741 return;
1742
1743 port_events->port_event_start = 0;
1744 port_events->port_event_count = 0;
1745 port_events->port_event_log_size = 0;
1746 port_events->bOverflow = NV_FALSE;
1747
1748 if (port_events->port_event_log != NULL)
1749 {
1750 nvswitch_os_free(port_events->port_event_log);
1751 port_events->port_event_log = NULL;
1752 }
1753 }
1754
1755 NvlStatus
nvswitch_lib_initialize_device(nvswitch_device * device)1756 nvswitch_lib_initialize_device
1757 (
1758 nvswitch_device *device
1759 )
1760 {
1761 NvlStatus retval = NVL_SUCCESS;
1762 NvU8 link_num;
1763 nvlink_link *link = NULL;
1764 NvBool is_blacklisted_by_os = NV_FALSE;
1765
1766 if (!NVSWITCH_IS_DEVICE_ACCESSIBLE(device))
1767 {
1768 return -NVL_BAD_ARGS;
1769 }
1770
1771 if (NVSWITCH_IS_DEVICE_INITIALIZED(device))
1772 {
1773 NVSWITCH_PRINT(device, SETUP, "Device is already initialized!\n");
1774 return NVL_SUCCESS;
1775 }
1776
1777 NVSWITCH_PRINT(device, SETUP,
1778 "Initializing nvswitch at (%04x:%02x:%02x.%02x)\n",
1779 device->nvlink_device->pciInfo.domain,
1780 device->nvlink_device->pciInfo.bus,
1781 device->nvlink_device->pciInfo.device,
1782 device->nvlink_device->pciInfo.function);
1783
1784 nvListInit(&device->client_events_list);
1785
1786 for (link_num=0; link_num < nvswitch_get_num_links(device); link_num++)
1787 {
1788 nvListInit(&device->link[link_num].inbandData.persistent_list);
1789 nvListInit(&device->link[link_num].inbandData.nonpersistent_list);
1790 }
1791
1792 retval = nvswitch_lib_load_platform_info(device);
1793 if (retval != NVL_SUCCESS)
1794 {
1795 NVSWITCH_PRINT(device, ERROR, "Failed to load platform information\n");
1796 return retval;
1797 }
1798
1799 if (nvswitch_is_soe_supported(device))
1800 {
1801 retval = _nvswitch_construct_soe(device);
1802 if (retval != NVL_SUCCESS)
1803 {
1804 return retval;
1805 }
1806 }
1807 else
1808 {
1809 NVSWITCH_PRINT(device, INFO, "SOE is not supported, skipping construct\n");
1810 }
1811 if (nvswitch_is_cci_supported(device))
1812 {
1813 retval = _nvswitch_construct_cci(device);
1814 if (retval != NVL_SUCCESS)
1815 {
1816 NVSWITCH_PRINT(device, ERROR, "Failed to construct CCI: %d\n", retval);
1817 goto nvswitch_initialize_cci_fail;
1818 }
1819 }
1820 else
1821 {
1822 NVSWITCH_PRINT(device, INFO, "CCI is not supported, skipping construct\n");
1823 }
1824
1825 _nvswitch_set_dma_mask(device);
1826
1827 retval = _nvswitch_initialize_device_state(device);
1828 if (NVL_SUCCESS != retval)
1829 {
1830 NVSWITCH_PRINT(device, ERROR,
1831 "Failed to initialize device state: %d!\n",
1832 retval);
1833 goto nvswitch_initialize_device_state_fail;
1834 }
1835
1836 device->hal.nvswitch_load_uuid(device);
1837
1838 /*
1839 * Check module parameters for blacklisted device
1840 */
1841 if (nvswitch_os_is_uuid_in_blacklist(&device->uuid) == NV_TRUE)
1842 {
1843 NVSWITCH_PRINT(device, SETUP,
1844 "Blacklisted nvswitch at (%04x:%02x:%02x.%02x)\n",
1845 device->nvlink_device->pciInfo.domain,
1846 device->nvlink_device->pciInfo.bus,
1847 device->nvlink_device->pciInfo.device,
1848 device->nvlink_device->pciInfo.function);
1849 is_blacklisted_by_os = NV_TRUE;
1850 // initialization continues until we have updated InfoROM...
1851 }
1852
1853 if (nvswitch_is_inforom_supported(device))
1854 {
1855 retval = nvswitch_initialize_inforom(device);
1856 if (NVL_SUCCESS != retval)
1857 {
1858 NVSWITCH_PRINT(device, ERROR,
1859 "Failed to initialize InfoROM rc: %d\n",
1860 retval);
1861 goto nvswitch_initialize_device_state_fail;
1862 }
1863
1864 retval = nvswitch_initialize_inforom_objects(device);
1865 if (NVL_SUCCESS != retval)
1866 {
1867 NVSWITCH_PRINT(device, ERROR,
1868 "Failed to initialize InfoROM objects! rc:%d\n",
1869 retval);
1870 goto nvswitch_initialize_inforom_fail;
1871 }
1872 }
1873 else
1874 {
1875 NVSWITCH_PRINT(device, INFO,
1876 "InfoROM is not supported, skipping init\n");
1877 }
1878
1879 (void)device->hal.nvswitch_read_oob_blacklist_state(device);
1880 (void)device->hal.nvswitch_write_fabric_state(device);
1881
1882 nvswitch_task_create(device, &nvswitch_fabric_state_heartbeat,
1883 NVSWITCH_HEARTBEAT_INTERVAL_NS,
1884 NVSWITCH_TASK_TYPE_FLAGS_RUN_EVEN_IF_DEVICE_NOT_INITIALIZED);
1885
1886 //
1887 // Blacklisted devices return successfully in order to preserve the fabric state heartbeat
1888 // and ensure OOB utilities don't think the driver has died
1889 //
1890 if (device->device_blacklist_reason == NVSWITCH_DEVICE_BLACKLIST_REASON_MANUAL_OUT_OF_BAND)
1891 {
1892 NVSWITCH_PRINT(device, SETUP,
1893 "Blacklisted nvswitch at (%04x:%02x:%02x.%02x)\n",
1894 device->nvlink_device->pciInfo.domain,
1895 device->nvlink_device->pciInfo.bus,
1896 device->nvlink_device->pciInfo.device,
1897 device->nvlink_device->pciInfo.function);
1898 return NVL_SUCCESS;
1899 }
1900
1901 if (is_blacklisted_by_os)
1902 {
1903 (void)nvswitch_lib_blacklist_device(device, NVSWITCH_DEVICE_BLACKLIST_REASON_MANUAL_IN_BAND);
1904 return NVL_SUCCESS;
1905 }
1906
1907 for (link_num=0; link_num < nvswitch_get_num_links(device); link_num++)
1908 {
1909 if (!nvswitch_is_link_valid(device, link_num))
1910 {
1911 continue;
1912 }
1913
1914 retval = nvswitch_create_link(device, link_num, &link);
1915 if (NVL_SUCCESS != retval)
1916 {
1917 NVSWITCH_PRINT(device, ERROR,
1918 "Failed to create link %d : %d!\n",
1919 link_num,
1920 retval);
1921 goto nvswitch_link_fail;
1922 }
1923
1924 retval = nvlink_lib_register_link(device->nvlink_device, link);
1925 if (NVL_SUCCESS != retval)
1926 {
1927 NVSWITCH_PRINT(device, ERROR,
1928 "Failed to register link %d with the nvlink core : %d!\n",
1929 link_num,
1930 retval);
1931
1932 // Free the single dangling link.
1933 nvswitch_destroy_link(link);
1934
1935 goto nvswitch_link_fail;
1936 }
1937
1938 nvswitch_reset_persistent_link_hw_state(device, link_num);
1939
1940 //
1941 // During Nvswitch initialization, the default L1 thresholds are programmed by the
1942 // BIOS from the BIOS tables. Save these L1 Threshold Values in scratch registers
1943 // for use when resetting the thresholds to default.
1944 //
1945 nvswitch_program_l1_scratch_reg(device, link_num);
1946
1947 //
1948 // WAR : Initializing the L1 threshold registers at this point as a WAR for
1949 // Bug 3963639 where it was discussed that the L1 threshold register should have
1950 // the default value for all available links and not just for active links.
1951 //
1952 nvswitch_init_lpwr_regs(link);
1953 }
1954
1955 retval = nvswitch_set_training_mode(device);
1956
1957 if (retval != NVL_SUCCESS)
1958 {
1959 NVSWITCH_PRINT(device, ERROR, "Failed to determine link training mode! rc: %d\n", retval);
1960 goto nvswitch_link_fail;
1961 }
1962 // Initialize select scratch registers to 0x0
1963 device->hal.nvswitch_init_scratch(device);
1964
1965 retval = nvswitch_construct_error_log(&device->log_FATAL_ERRORS, 1024, NV_FALSE);
1966 if (retval != NVL_SUCCESS)
1967 {
1968 NVSWITCH_PRINT(device, ERROR, "Failed to construct log_FATAL_ERRORS! rc: %d\n", retval);
1969 goto nvswitch_construct_error_log_fail;
1970 }
1971
1972 retval = nvswitch_construct_error_log(&device->log_NONFATAL_ERRORS, 1024, NV_TRUE);
1973 if (retval != NVL_SUCCESS)
1974 {
1975 NVSWITCH_PRINT(device, ERROR, "Failed to construct log_NONFATAL_ERRORS! rc: %d\n", retval);
1976 goto nvswitch_construct_error_log_fail;
1977 }
1978
1979 retval = _nvswitch_construct_port_event_log(&device->log_PORT_EVENTS, NVSWITCH_PORT_EVENT_LOG_SIZE, NV_TRUE);
1980 if (retval != NVL_SUCCESS)
1981 {
1982 NVSWITCH_PRINT(device, ERROR, "Failed to construct log_PORT_EVENTS! rc: %d\n", retval);
1983 goto nvswitch_construct_port_event_log_fail;
1984 }
1985
1986 if (device->regkeys.latency_counter == NV_SWITCH_REGKEY_LATENCY_COUNTER_LOGGING_ENABLE)
1987 {
1988 nvswitch_task_create(device, &nvswitch_internal_latency_bin_log,
1989 nvswitch_get_latency_sample_interval_msec(device) * NVSWITCH_INTERVAL_1MSEC_IN_NS * 9/10, 0);
1990 }
1991
1992 nvswitch_task_create(device, &nvswitch_ecc_writeback_task,
1993 (60 * NVSWITCH_INTERVAL_1SEC_IN_NS), 0);
1994
1995 if (IS_RTLSIM(device) || IS_EMULATION(device) || IS_FMODEL(device))
1996 {
1997 NVSWITCH_PRINT(device, WARN,
1998 "%s: Skipping setup of NvSwitch thermal alert monitoring\n",
1999 __FUNCTION__);
2000 }
2001 else
2002 {
2003 nvswitch_task_create(device, &nvswitch_monitor_thermal_alert,
2004 100*NVSWITCH_INTERVAL_1MSEC_IN_NS, 0);
2005 }
2006
2007 device->nvlink_device->initialized = 1;
2008
2009 return NVL_SUCCESS;
2010
2011 nvswitch_construct_error_log_fail:
2012 //free allocated memory to avoid leaking
2013 nvswitch_destroy_error_log(device, &device->log_FATAL_ERRORS);
2014 nvswitch_destroy_error_log(device, &device->log_NONFATAL_ERRORS);
2015
2016 nvswitch_construct_port_event_log_fail:
2017 //free allocated memory to avoid leaking
2018 _nvswitch_destroy_port_event_log(device, &device->log_PORT_EVENTS);
2019
2020 nvswitch_link_fail:
2021 // Track down all links that successfully registered.
2022 for (link_num = 0; link_num < nvswitch_get_num_links(device); link_num++)
2023 {
2024 if (nvlink_lib_get_link(device->nvlink_device, link_num, &link) == NVL_SUCCESS)
2025 {
2026 nvlink_lib_unregister_link(link);
2027 nvswitch_destroy_link(link);
2028 }
2029 }
2030
2031 nvswitch_destroy_inforom_objects(device);
2032
2033 nvswitch_initialize_inforom_fail:
2034 nvswitch_destroy_inforom(device);
2035
2036 nvswitch_initialize_device_state_fail:
2037 _nvswitch_destruct_cci(device);
2038 nvswitch_initialize_cci_fail:
2039 _nvswitch_destruct_soe(device);
2040 nvswitch_tasks_destroy(device);
2041
2042 return retval;
2043 }
2044
2045 NvBool
nvswitch_lib_validate_device_id(NvU32 device_id)2046 nvswitch_lib_validate_device_id
2047 (
2048 NvU32 device_id
2049 )
2050 {
2051 if (nvswitch_is_lr10_device_id(device_id))
2052 {
2053 return NV_TRUE;
2054 }
2055 if (nvswitch_is_ls10_device_id(device_id))
2056 {
2057 return NV_TRUE;
2058 }
2059 return NV_FALSE;
2060 }
2061
2062 NvlStatus
nvswitch_lib_post_init_device(nvswitch_device * device)2063 nvswitch_lib_post_init_device
2064 (
2065 nvswitch_device *device
2066 )
2067 {
2068 NvlStatus retval;
2069 NvlStatus status;
2070 NvU32 link_num;
2071 NvU64 mode;
2072 nvlink_link *link;
2073 NvU64 enabledLinkMaskNonCci;
2074
2075 if (!NVSWITCH_IS_DEVICE_INITIALIZED(device))
2076 {
2077 return -NVL_ERR_INVALID_STATE;
2078 }
2079
2080 retval = _nvswitch_post_init_device_setup(device);
2081 if (retval != NVL_SUCCESS)
2082 {
2083 return retval;
2084 }
2085
2086 if (nvswitch_is_bios_supported(device))
2087 {
2088 retval = nvswitch_bios_get_image(device);
2089 if (retval != NVL_SUCCESS)
2090 {
2091 return retval;
2092 }
2093
2094 retval = nvswitch_parse_bios_image(device);
2095 if (retval != NVL_SUCCESS)
2096 {
2097 return retval;
2098 }
2099 }
2100 else
2101 {
2102 NVSWITCH_PRINT(device, ERROR,
2103 "%s: Skipping BIOS parsing since BIOS is unsupported.\n",
2104 __FUNCTION__);
2105 }
2106
2107 if (nvswitch_is_cci_supported(device))
2108 {
2109 retval = cciLoad(device);
2110 if (NVL_SUCCESS != retval)
2111 {
2112 NVSWITCH_PRINT(device, ERROR, "%s: Init CCI failed\n",
2113 __FUNCTION__);
2114 return retval;
2115 }
2116
2117 enabledLinkMaskNonCci = nvswitch_get_enabled_link_mask(device);
2118
2119 FOR_EACH_INDEX_IN_MASK(64, link_num, enabledLinkMaskNonCci)
2120 {
2121 if (cciIsLinkManaged(device, link_num))
2122 {
2123 enabledLinkMaskNonCci = enabledLinkMaskNonCci & ~NVBIT64(link_num);
2124 }
2125 }
2126 FOR_EACH_INDEX_IN_MASK_END;
2127
2128 if (enabledLinkMaskNonCci != 0)
2129 {
2130 nvswitch_task_create(device, &_nvswitch_update_link_state_led,
2131 NVSWITCH_INTERVAL_1SEC_IN_NS, 0);
2132 }
2133 }
2134 else
2135 {
2136 NVSWITCH_PRINT(device, INFO, "%s: Skipping CCI init.\n",
2137 __FUNCTION__);
2138 }
2139
2140 retval = _nvswitch_setup_system_registers(device);
2141 if (retval != NVL_SUCCESS)
2142 {
2143 return retval;
2144 }
2145
2146 nvswitch_smbpbi_post_init(device);
2147
2148 // ALI launched by VBIOS on silicon
2149 if (IS_RTLSIM(device) || IS_EMULATION(device) || IS_FMODEL(device))
2150 {
2151 (void)nvswitch_launch_ALI(device);
2152 }
2153
2154 //
2155 // There is an edge case where a hyperisor may not send same number
2156 // of reset to switch and GPUs, so try to re-train links in fault
2157 // if possible
2158 //
2159 for (link_num=0; link_num < nvswitch_get_num_links(device); link_num++)
2160 {
2161 // Sanity check
2162 if (!nvswitch_is_link_valid(device, link_num))
2163 {
2164 continue;
2165 }
2166
2167 // CCI links are trained and managed by SOE, skip any driver based training
2168 if (cciIsLinkManaged(device, link_num))
2169 {
2170 continue;
2171 }
2172 status = nvlink_lib_get_link(device->nvlink_device, link_num, &link);
2173 if (status != NVL_SUCCESS)
2174 {
2175 NVSWITCH_PRINT(device, ERROR, "%s: Failed to get link for LinkId %d\n",
2176 __FUNCTION__, link_num);
2177 continue;
2178 }
2179
2180 // If the link is in fault then re-train
2181 if(_nvswitch_corelib_get_dl_link_mode(link, &mode) != NVL_SUCCESS)
2182 {
2183 NVSWITCH_PRINT(device, ERROR, "%s: nvlipt_lnk_status: Failed to check link mode! LinkId %d\n",
2184 __FUNCTION__, link_num);
2185 }
2186 else if(mode == NVLINK_LINKSTATE_FAULT)
2187 {
2188 NVSWITCH_PRINT(device, INFO, "%s: retraining LinkId %d\n",
2189 __FUNCTION__, link_num);
2190 nvswitch_reset_and_train_link(device, link);
2191 }
2192 }
2193
2194 return NVL_SUCCESS;
2195 }
2196
2197 void
nvswitch_lib_post_init_blacklist_device(nvswitch_device * device)2198 nvswitch_lib_post_init_blacklist_device
2199 (
2200 nvswitch_device *device
2201 )
2202 {
2203 _nvswitch_post_init_blacklist_device_setup(device);
2204 }
2205
2206 void
_nvswitch_check_pending_data_and_notify(nvswitch_device * device,NVSWITCH_CLIENT_EVENT * event)2207 _nvswitch_check_pending_data_and_notify
2208 (
2209 nvswitch_device *device,
2210 NVSWITCH_CLIENT_EVENT *event
2211 )
2212 {
2213 switch (event->eventId)
2214 {
2215 case NVSWITCH_DEVICE_EVENT_INBAND_DATA:
2216 {
2217 NvU32 i;
2218
2219 for (i = 0; i < nvswitch_get_num_links(device); i++)
2220 {
2221 if (!nvListIsEmpty(&device->link[i].inbandData.persistent_list) ||
2222 !nvListIsEmpty(&device->link[i].inbandData.nonpersistent_list))
2223 {
2224 (void)nvswitch_os_notify_client_event(device->os_handle,
2225 event->private_driver_data,
2226 event->eventId);
2227 }
2228 }
2229 break;
2230 }
2231
2232 default:
2233 return;
2234 }
2235 }
2236
2237 /*!
2238 * @brief: Gets the client event associated with the file descriptor
2239 * if it already exists in the Device's client event list.
2240 *
2241 * If found, and if there is pending data for the event,
2242 * the event is triggered before returning to unblock the
2243 * client right away.
2244 */
2245 NvlStatus
nvswitch_lib_get_client_event(nvswitch_device * device,void * osPrivate,NVSWITCH_CLIENT_EVENT ** ppClientEvent)2246 nvswitch_lib_get_client_event
2247 (
2248 nvswitch_device *device,
2249 void *osPrivate,
2250 NVSWITCH_CLIENT_EVENT **ppClientEvent
2251 )
2252 {
2253 NVSWITCH_CLIENT_EVENT *curr = NULL;
2254
2255 *ppClientEvent = NULL;
2256
2257 if(!NVSWITCH_IS_DEVICE_VALID(device))
2258 {
2259 return -NVL_BAD_ARGS;
2260 }
2261
2262 nvListForEachEntry(curr, &device->client_events_list, entry)
2263 {
2264 if (curr->private_driver_data == osPrivate)
2265 {
2266 *ppClientEvent = curr;
2267 _nvswitch_check_pending_data_and_notify(device, curr);
2268 return NVL_SUCCESS;
2269 }
2270 }
2271
2272 return -NVL_NOT_FOUND;
2273 }
2274
2275 /*!
2276 * @brief: Adds an event to the front of the
2277 * Device's client event list.
2278 */
2279 NvlStatus
nvswitch_lib_add_client_event(nvswitch_device * device,void * osPrivate,NvU32 eventId)2280 nvswitch_lib_add_client_event
2281 (
2282 nvswitch_device *device,
2283 void *osPrivate,
2284 NvU32 eventId
2285 )
2286 {
2287 NVSWITCH_CLIENT_EVENT *newEvent;
2288 NvlStatus status = NVL_SUCCESS;
2289
2290 if (!NVSWITCH_IS_DEVICE_VALID(device))
2291 {
2292 return -NVL_BAD_ARGS;
2293 }
2294
2295 if (eventId >= NVSWITCH_DEVICE_EVENT_COUNT)
2296 {
2297 NVSWITCH_PRINT(device, ERROR, "%s: Invalid event Id.\n", __FUNCTION__);
2298 return -NVL_BAD_ARGS;
2299 }
2300
2301 // Invoke OS specific API to add event.
2302 status = nvswitch_os_add_client_event(device->os_handle,
2303 osPrivate,
2304 eventId);
2305 if (status != NVL_SUCCESS)
2306 {
2307 NVSWITCH_PRINT(device, ERROR, "%s: Failed to add client event.\n", __FUNCTION__);
2308 return status;
2309 }
2310
2311 newEvent = nvswitch_os_malloc(sizeof(*newEvent));
2312 if (newEvent == NULL)
2313 {
2314 return -NVL_NO_MEM;
2315 }
2316
2317 newEvent->eventId = eventId;
2318 newEvent->private_driver_data = osPrivate;
2319
2320 nvListAdd(&newEvent->entry, &device->client_events_list);
2321
2322 return NVL_SUCCESS;
2323 }
2324
2325 /*!
2326 * @brief: Removes all events corresponding to osPrivate,
2327 * from the Device's client event list.
2328 */
2329 NvlStatus
nvswitch_lib_remove_client_events(nvswitch_device * device,void * osPrivate)2330 nvswitch_lib_remove_client_events
2331 (
2332 nvswitch_device *device,
2333 void *osPrivate
2334 )
2335 {
2336 NVSWITCH_CLIENT_EVENT *curr = NULL;
2337 NVSWITCH_CLIENT_EVENT *next = NULL;
2338 NvlStatus status = NVL_SUCCESS;
2339
2340 //
2341 // Device shutdown may happen before this is called, so return
2342 // if device is gone
2343 //
2344 if (!NVSWITCH_IS_DEVICE_VALID(device))
2345 {
2346 return NVL_SUCCESS;
2347 }
2348
2349 nvListForEachEntry_safe(curr, next, &device->client_events_list, entry)
2350 {
2351 if (curr->private_driver_data == osPrivate)
2352 {
2353 nvListDel(&curr->entry);
2354 nvswitch_os_free(curr);
2355 }
2356 }
2357
2358 // Invoke OS specific API to remove event.
2359 status = nvswitch_os_remove_client_event(device->os_handle,
2360 osPrivate);
2361 if (status != NVL_SUCCESS)
2362 {
2363 NVSWITCH_PRINT(device, ERROR, "%s: Failed to remove client events.\n", __FUNCTION__);
2364 return status;
2365 }
2366
2367 return NVL_SUCCESS;
2368 }
2369
2370 /*!
2371 * @brief: Notifies all events with matching event id in the
2372 * Device's client event list.
2373 */
2374 NvlStatus
nvswitch_lib_notify_client_events(nvswitch_device * device,NvU32 eventId)2375 nvswitch_lib_notify_client_events
2376 (
2377 nvswitch_device *device,
2378 NvU32 eventId
2379 )
2380 {
2381 NvlStatus status;
2382 NVSWITCH_CLIENT_EVENT *curr = NULL;
2383
2384 if (!NVSWITCH_IS_DEVICE_VALID(device))
2385 {
2386 return -NVL_BAD_ARGS;
2387 }
2388
2389 if (eventId >= NVSWITCH_DEVICE_EVENT_COUNT)
2390 {
2391 NVSWITCH_PRINT(device, ERROR, "%s: Invalid event Id.\n", __FUNCTION__);
2392 return -NVL_BAD_ARGS;
2393 }
2394
2395 nvListForEachEntry(curr, &device->client_events_list, entry)
2396 {
2397 if (curr->eventId == eventId)
2398 {
2399 // OS specific event notification.
2400 status = nvswitch_os_notify_client_event(device->os_handle,
2401 curr->private_driver_data,
2402 eventId);
2403 if (status != NVL_SUCCESS)
2404 {
2405 return status;
2406 }
2407 }
2408 }
2409
2410 return NVL_SUCCESS;
2411 }
2412
2413 void
nvswitch_record_port_event(nvswitch_device * device,NVSWITCH_PORT_EVENT_LOG_TYPE * port_events,NvU32 link_id,NvU8 port_event_type)2414 nvswitch_record_port_event
2415 (
2416 nvswitch_device *device,
2417 NVSWITCH_PORT_EVENT_LOG_TYPE *port_events,
2418 NvU32 link_id,
2419 NvU8 port_event_type
2420 )
2421 {
2422 NvU32 idx;
2423
2424 NVSWITCH_ASSERT(port_events != NULL);
2425
2426 // If no port events log has been created, then don't log it.
2427 if ((port_events->port_event_log_size != 0) &&
2428 (port_events->port_event_log != NULL))
2429 {
2430 idx = (port_events->port_event_start + port_events->port_event_count)
2431 % port_events->port_event_log_size;
2432
2433 if (port_events->port_event_count == port_events->port_event_log_size)
2434 {
2435 // Error: ring buffer is already full/
2436 if (port_events->overwritable)
2437 {
2438 port_events->port_event_start = (port_events->port_event_start + 1)
2439 % port_events->port_event_log_size;
2440 port_events->bOverflow = NV_TRUE;
2441 }
2442 else
2443 {
2444 // No logging, ring buffer is full
2445 return;
2446 }
2447 }
2448 else
2449 {
2450 port_events->port_event_count++;
2451 }
2452 // Log port event info
2453 port_events->port_event_log[idx].link_id = link_id;
2454 port_events->port_event_log[idx].port_event_type = port_event_type;
2455
2456 // Log tracking info
2457 port_events->port_event_log[idx].time = nvswitch_os_get_platform_time();
2458 port_events->port_event_log[idx].local_port_event_num = port_events->port_event_total;
2459 }
2460 port_events->port_event_total++;
2461 }
2462
2463 /*
2464 * @Brief : Retrives a port event entry by index.
2465 *
2466 * @Description : Retrieves the port_event at index port_event_idx. If index is out
2467 * of range, returns an empty port event entry with port_event_type = 2
2468 *
2469 * @param[in] device NVSwitch device to contain this link
2470 * @param[in] port_events Log of all port events with metadata
2471 * @param[in] port_event_idx Index of entry to retrieve (0 = oldest port event)
2472 * @param[out] port_event_count Clear only non-persistent list
2473 */
2474 void
nvswitch_get_port_event(nvswitch_device * device,NVSWITCH_PORT_EVENT_LOG_TYPE * port_events,NVSWITCH_PORT_EVENT_TYPE * port_event_entry,NvU32 port_event_idx,NvU32 * port_event_count)2475 nvswitch_get_port_event
2476 (
2477 nvswitch_device *device,
2478 NVSWITCH_PORT_EVENT_LOG_TYPE *port_events,
2479 NVSWITCH_PORT_EVENT_TYPE *port_event_entry,
2480 NvU32 port_event_idx,
2481 NvU32 *port_event_count
2482 )
2483 {
2484 NvU32 idx;
2485 NVSWITCH_ASSERT(port_events != NULL);
2486
2487 if (port_event_entry != NULL)
2488 {
2489 // Index is out of range
2490 if (port_event_idx >= port_events->port_event_count)
2491 {
2492 nvswitch_os_memset(port_event_entry, 0, sizeof(*port_event_entry));
2493 port_event_entry->port_event_type = NVSWITCH_PORT_EVENT_TYPE_INVALID;
2494 port_event_entry->time = nvswitch_os_get_platform_time();
2495 }
2496 else
2497 {
2498 idx = (port_events->port_event_start + port_event_idx) % port_events->port_event_log_size;
2499 *port_event_entry = port_events->port_event_log[idx];
2500 }
2501 }
2502
2503 if (port_event_count)
2504 {
2505 *port_event_count = port_events->port_event_count;
2506 }
2507 }
2508
2509 NvlStatus
nvswitch_ctrl_get_port_events(nvswitch_device * device,NVSWITCH_GET_PORT_EVENTS_PARAMS * p)2510 nvswitch_ctrl_get_port_events
2511 (
2512 nvswitch_device *device,
2513 NVSWITCH_GET_PORT_EVENTS_PARAMS *p
2514 )
2515 {
2516 NvU32 index = 0;
2517 NvU32 count = 0;
2518 NVSWITCH_PORT_EVENT_LOG_TYPE *port_events = &device->log_PORT_EVENTS;
2519 NVSWITCH_PORT_EVENT_TYPE port_event;
2520
2521 nvswitch_os_memset(p->portEvent, 0, sizeof(NVSWITCH_PORT_EVENT)
2522 *NVSWITCH_PORT_EVENT_COUNT_SIZE);
2523 p->nextPortEventIndex = port_events->port_event_total;
2524 p->portEventCount = 0;
2525 p->bOverflow = port_events->bOverflow;
2526
2527 // Return if there are no more port events to get
2528 nvswitch_get_port_event(device, port_events, &port_event, index, &count);
2529 if (count == 0)
2530 {
2531 return NVL_SUCCESS;
2532 }
2533
2534 // If port event's local_port_Event_num is smaller than the portEventIndex
2535 // passed in by the client, fast-forward index by the difference.
2536 // This will skip over port events that were previously read by the client.
2537 if (port_event.local_port_event_num < p->portEventIndex)
2538 {
2539 index = (NvU32) (p->portEventIndex - port_event.local_port_event_num);
2540 }
2541
2542 // Return if there are no more events after fast-forwarding.
2543 if (index >= count)
2544 {
2545 return NVL_SUCCESS;
2546 }
2547
2548 while ((p->portEventCount < NVSWITCH_PORT_EVENT_COUNT_SIZE) && (index < count))
2549 {
2550 nvswitch_get_port_event(device, port_events, &port_event, index, NULL);
2551
2552 p->portEvent[p->portEventCount].port_event_type = port_event.port_event_type;
2553 p->portEvent[p->portEventCount].link_id = port_event.link_id;
2554 p->portEvent[p->portEventCount].time = port_event.time;
2555
2556 p->portEventCount++;
2557 index++;
2558 }
2559
2560 p->portEventIndex = port_event.local_port_event_num + 1;
2561
2562 return NVL_SUCCESS;
2563 }
2564
2565 /*!
2566 @brief: Release ROM image from memory.
2567 */
2568 void
_nvswitch_destroy_rom(nvswitch_device * device)2569 _nvswitch_destroy_rom(nvswitch_device *device)
2570 {
2571 if (device->biosImage.pImage != NULL)
2572 {
2573 nvswitch_os_free(device->biosImage.pImage);
2574 device->biosImage.pImage = NULL;
2575 }
2576 }
2577
2578 /*!
2579 * @brief: Free the device's client event list
2580 */
2581 static void
_nvswitch_destroy_event_list(nvswitch_device * device)2582 _nvswitch_destroy_event_list(nvswitch_device *device)
2583 {
2584 NVSWITCH_CLIENT_EVENT *curr = NULL;
2585 NVSWITCH_CLIENT_EVENT *next = NULL;
2586
2587 nvListForEachEntry_safe(curr, next, &device->client_events_list, entry)
2588 {
2589 nvListDel(&curr->entry);
2590 nvswitch_os_free(curr);
2591 }
2592 }
2593
2594 NvlStatus
nvswitch_lib_shutdown_device(nvswitch_device * device)2595 nvswitch_lib_shutdown_device
2596 (
2597 nvswitch_device *device
2598 )
2599 {
2600 NVSWITCH_INBAND_FLUSH_DATA_PARAMS p;
2601
2602 if (!NVSWITCH_IS_DEVICE_ACCESSIBLE(device))
2603 {
2604 return -NVL_BAD_ARGS;
2605 }
2606
2607 //
2608 // Set fabric state to offline
2609 //
2610 if (device->device_fabric_state != NVSWITCH_DEVICE_FABRIC_STATE_BLACKLISTED)
2611 device->device_fabric_state = NVSWITCH_DEVICE_FABRIC_STATE_OFFLINE;
2612 device->driver_fabric_state = NVSWITCH_DRIVER_FABRIC_STATE_OFFLINE;
2613 (void)device->hal.nvswitch_write_fabric_state(device);
2614
2615 nvswitch_hw_counter_shutdown(device);
2616
2617 // FLUSH any pending messages to avoid memory leaks
2618 p.linkMask = nvswitch_get_enabled_link_mask(device);
2619 _nvswitch_ctrl_inband_flush_data(device, &p);
2620
2621 _nvswitch_destruct_cci(device);
2622 _nvswitch_led_shutdown(device);
2623
2624 _nvswitch_unregister_links(device);
2625
2626 nvswitch_destroy_error_log(device, &device->log_FATAL_ERRORS);
2627 nvswitch_destroy_error_log(device, &device->log_NONFATAL_ERRORS);
2628
2629 _nvswitch_destroy_port_event_log(device, &device->log_PORT_EVENTS);
2630
2631 nvswitch_smbpbi_unload(device);
2632 _nvswitch_destroy_event_list(device);
2633
2634 nvswitch_destroy_inforom_objects(device);
2635 nvswitch_destroy_inforom(device);
2636
2637 nvswitch_smbpbi_destroy(device);
2638
2639 nvswitch_destroy_device_state(device);
2640
2641 _nvswitch_destroy_rom(device);
2642
2643 _nvswitch_destruct_soe(device);
2644
2645 nvswitch_tasks_destroy(device);
2646
2647 return NVL_SUCCESS;
2648 }
2649
2650 NvlStatus
nvswitch_lib_get_log_count(nvswitch_device * device,NvU32 * fatal,NvU32 * nonfatal,NvU32 * portEvent)2651 nvswitch_lib_get_log_count
2652 (
2653 nvswitch_device *device,
2654 NvU32 *fatal, NvU32 *nonfatal, NvU32 *portEvent
2655 )
2656 {
2657 if (!NVSWITCH_IS_DEVICE_INITIALIZED(device) ||
2658 fatal == NULL || nonfatal == NULL || portEvent == NULL)
2659 {
2660 return -NVL_BAD_ARGS;
2661 }
2662
2663 *fatal = device->log_FATAL_ERRORS.error_count;
2664 *nonfatal = device->log_NONFATAL_ERRORS.error_count;
2665 *portEvent = device->log_PORT_EVENTS.port_event_count;
2666 // No report of log_INFO currently
2667
2668 return NVL_SUCCESS;
2669 }
2670
2671 NvlStatus
nvswitch_lib_load_platform_info(nvswitch_device * device)2672 nvswitch_lib_load_platform_info
2673 (
2674 nvswitch_device *device
2675 )
2676 {
2677 if (!NVSWITCH_IS_DEVICE_ACCESSIBLE(device))
2678 {
2679 return -NVL_BAD_ARGS;
2680 }
2681
2682 device->hal.nvswitch_determine_platform(device);
2683
2684 return NVL_SUCCESS;
2685 }
2686
2687 void
nvswitch_lib_get_device_info(nvswitch_device * device,struct nvlink_pci_info ** pciInfo)2688 nvswitch_lib_get_device_info
2689 (
2690 nvswitch_device *device,
2691 struct nvlink_pci_info **pciInfo
2692 )
2693 {
2694 if (!NVSWITCH_IS_DEVICE_VALID(device) || pciInfo == NULL)
2695 {
2696 NVSWITCH_ASSERT(0);
2697 return;
2698 }
2699
2700 *pciInfo = &device->nvlink_device->pciInfo;
2701 }
2702
2703 NvlStatus
nvswitch_lib_get_bios_version(nvswitch_device * device,NvU64 * version)2704 nvswitch_lib_get_bios_version
2705 (
2706 nvswitch_device *device,
2707 NvU64 *version
2708 )
2709 {
2710 NVSWITCH_GET_BIOS_INFO_PARAMS p = { 0 };
2711 NvlStatus ret;
2712
2713 if (!device)
2714 return -NVL_BAD_ARGS;
2715
2716 ret = device->hal.nvswitch_ctrl_get_bios_info(device, &p);
2717
2718 if (version != NULL)
2719 {
2720 *version = p.version;
2721 }
2722
2723 return ret;
2724 }
2725
2726 NvlStatus
nvswitch_lib_use_pin_irq(nvswitch_device * device)2727 nvswitch_lib_use_pin_irq
2728 (
2729 nvswitch_device *device
2730 )
2731 {
2732 return IS_FMODEL(device);
2733 }
2734
2735
2736 NvlStatus
nvswitch_lib_register_device(NvU16 pci_domain,NvU8 pci_bus,NvU8 pci_device,NvU8 pci_func,NvU16 pci_device_id,void * os_handle,NvU32 os_instance,nvswitch_device ** return_device)2737 nvswitch_lib_register_device
2738 (
2739 NvU16 pci_domain,
2740 NvU8 pci_bus,
2741 NvU8 pci_device,
2742 NvU8 pci_func,
2743 NvU16 pci_device_id,
2744 void *os_handle,
2745 NvU32 os_instance,
2746 nvswitch_device **return_device
2747 )
2748 {
2749 nvswitch_device *device = NULL;
2750 nvlink_device *coreDev = NULL;
2751 NvlStatus retval = NVL_SUCCESS;
2752
2753 if (!nvlink_lib_is_initialized())
2754 {
2755 NVSWITCH_PRINT(device, ERROR,
2756 "NVLink core lib isn't initialized yet!\n");
2757 return -NVL_INITIALIZATION_TOTAL_FAILURE;
2758 }
2759
2760 if (return_device == NULL || os_handle == NULL)
2761 {
2762 return -NVL_BAD_ARGS;
2763 }
2764
2765 *return_device = NULL;
2766
2767 device = nvswitch_os_malloc(sizeof(*device));
2768 if (NULL == device)
2769 {
2770 NVSWITCH_PRINT(device, ERROR,
2771 "nvswitch_os_malloc during device creation failed!\n");
2772 return -NVL_NO_MEM;
2773 }
2774 nvswitch_os_memset(device, 0, sizeof(*device));
2775
2776 nvswitch_os_snprintf(device->name, sizeof(device->name),
2777 NVSWITCH_DEVICE_NAME "%d", os_instance);
2778
2779 coreDev = nvswitch_os_malloc(sizeof(*coreDev));
2780 if (NULL == coreDev)
2781 {
2782 NVSWITCH_PRINT(device, ERROR,
2783 "nvswitch_os_malloc during device creation failed!\n");
2784
2785 retval = -NVL_NO_MEM;
2786 goto nvlink_lib_register_device_fail;
2787 }
2788 nvswitch_os_memset(coreDev, 0, sizeof(*coreDev));
2789
2790 coreDev->driverName =
2791 nvswitch_os_malloc(sizeof(NVSWITCH_DRIVER_NAME));
2792 if (coreDev->driverName == NULL)
2793 {
2794 NVSWITCH_PRINT(device, ERROR,
2795 "nvswitch_os_malloc during device creation failed!\n");
2796
2797 retval = -NVL_NO_MEM;
2798 goto nvlink_lib_register_device_fail;
2799 }
2800 nvswitch_os_memcpy(coreDev->driverName, NVSWITCH_DRIVER_NAME,
2801 sizeof(NVSWITCH_DRIVER_NAME));
2802
2803 device->os_handle = os_handle;
2804 device->os_instance = os_instance;
2805
2806 device->nvlink_device = coreDev;
2807 device->nvlink_device->deviceName = device->name;
2808 device->nvlink_device->uuid = NULL; // No UUID support for switch
2809
2810 device->nvlink_device->pciInfo.domain = pci_domain;
2811 device->nvlink_device->pciInfo.bus = pci_bus;
2812 device->nvlink_device->pciInfo.device = pci_device;
2813 device->nvlink_device->pciInfo.function = pci_func;
2814 device->nvlink_device->pciInfo.pciDeviceId = pci_device_id;
2815
2816 // nvlink_device has a back pointer to nvswitch_device
2817 device->nvlink_device->pDevInfo = device;
2818 device->nvlink_device->type = NVLINK_DEVICE_TYPE_NVSWITCH;
2819
2820 //
2821 // Initialize the Fabric State
2822 //
2823 device->fm_timeout = NVSWITCH_DEFAULT_FM_HEARTBEAT_TIMEOUT_MSEC;
2824 device->fabric_state_sequence_number = 0;
2825 device->driver_fabric_state = NVSWITCH_DRIVER_FABRIC_STATE_STANDBY;
2826 device->device_fabric_state = NVSWITCH_DEVICE_FABRIC_STATE_STANDBY;
2827 device->device_blacklist_reason = NVSWITCH_DEVICE_BLACKLIST_REASON_NONE;
2828
2829 //
2830 // Initialize TNVL Mode
2831 //
2832 device->tnvl_mode = NVSWITCH_DEVICE_TNVL_MODE_DISABLED;
2833
2834 //
2835 // Initialize HAL connectivity as early as possible so that other lib
2836 // interfaces can work.
2837 //
2838 retval = _nvswitch_setup_hal(device, device->nvlink_device->pciInfo.pciDeviceId);
2839 if (retval != NVL_SUCCESS)
2840 {
2841 goto nvlink_lib_register_device_fail;
2842 }
2843
2844 //
2845 // Initialize regkeys as early as possible so that most routines can take
2846 // advantage of them.
2847 //
2848 _nvswitch_init_device_regkeys(device);
2849
2850 // After regkeys have been set then only set the enableALI field.
2851 device->nvlink_device->enableALI = (device->regkeys.link_training_mode ==
2852 NV_SWITCH_REGKEY_LINK_TRAINING_SELECT_ALI) ? NV_TRUE:NV_FALSE;
2853
2854 retval = nvlink_lib_register_device(device->nvlink_device);
2855 if (NVL_SUCCESS != retval)
2856 {
2857 NVSWITCH_PRINT(device, ERROR,
2858 "nvlinklib register device failed!\n");
2859 goto nvlink_lib_register_device_fail;
2860 }
2861
2862 *return_device = device;
2863
2864 NVSWITCH_PRINT(device, SETUP,
2865 "Successfully registered with nvlinkcore\n");
2866
2867 return retval;
2868
2869 nvlink_lib_register_device_fail:
2870
2871 if (NULL != coreDev)
2872 {
2873 nvswitch_os_free(coreDev->driverName);
2874 nvswitch_os_free(coreDev);
2875 }
2876
2877 if (NULL != device)
2878 nvswitch_os_free(device);
2879
2880 return retval;
2881 }
2882
2883 void
nvswitch_lib_unregister_device(nvswitch_device * device)2884 nvswitch_lib_unregister_device
2885 (
2886 nvswitch_device *device
2887 )
2888 {
2889 if (!NVSWITCH_IS_DEVICE_VALID(device))
2890 {
2891 NVSWITCH_ASSERT(0);
2892 return;
2893 }
2894
2895 nvlink_lib_unregister_device(device->nvlink_device);
2896
2897 nvswitch_os_free(device->nvlink_device->driverName);
2898 nvswitch_os_free(device->nvlink_device);
2899 nvswitch_os_free(device);
2900
2901 return;
2902 }
2903
2904 /*!
2905 * @brief: Gets the mask of valid I2C ports on the
2906 * Device.
2907 */
2908 NvlStatus
nvswitch_lib_get_valid_ports_mask(nvswitch_device * device,NvU32 * validPortsMask)2909 nvswitch_lib_get_valid_ports_mask
2910 (
2911 nvswitch_device *device,
2912 NvU32 *validPortsMask
2913 )
2914 {
2915 NvU32 port_info;
2916 NvU32 i;
2917 NvU32 ports_mask = 0;
2918 NvBool is_i2c_access_allowed;
2919 NvBool is_port_allowed;
2920
2921 if (!NVSWITCH_IS_DEVICE_VALID(device) ||
2922 (validPortsMask == NULL))
2923 {
2924 return -NVL_BAD_ARGS;
2925 }
2926
2927 is_i2c_access_allowed = (device->regkeys.i2c_access_control ==
2928 NV_SWITCH_REGKEY_I2C_ACCESS_CONTROL_ENABLE) ?
2929 NV_TRUE : NV_FALSE;
2930
2931 for (i = 0; i < NVSWITCH_MAX_I2C_PORTS; i++)
2932 {
2933 port_info = nvswitch_i2c_get_port_info(device, i);
2934
2935 is_port_allowed = is_i2c_access_allowed ? NV_TRUE :
2936 FLD_TEST_DRF(_I2C, _PORTINFO, _ACCESS_ALLOWED, _TRUE,
2937 port_info);
2938
2939 if (is_port_allowed &&
2940 FLD_TEST_DRF(_I2C, _PORTINFO, _DEFINED, _PRESENT, port_info))
2941 {
2942 ports_mask |= NVBIT(i);
2943 }
2944 }
2945
2946 *validPortsMask = ports_mask;
2947 return NVL_SUCCESS;
2948 }
2949
2950 /*!
2951 * @brief: Returns if the I2C transactions are supported.
2952 */
2953 NvBool
nvswitch_lib_is_i2c_supported(nvswitch_device * device)2954 nvswitch_lib_is_i2c_supported
2955 (
2956 nvswitch_device *device
2957 )
2958 {
2959 if (!NVSWITCH_IS_DEVICE_VALID(device))
2960 {
2961 NVSWITCH_ASSERT(0);
2962 return NV_FALSE;
2963 }
2964
2965 return nvswitch_is_i2c_supported(device);
2966 }
2967
2968 static NvlStatus
_nvswitch_perform_i2c_transfer(nvswitch_device * device,NvU32 client,NvU8 type,NvU16 addr,NvU8 port,NvU8 cmd,NvU32 msgLength,NvU8 * pData)2969 _nvswitch_perform_i2c_transfer
2970 (
2971 nvswitch_device *device,
2972 NvU32 client,
2973 NvU8 type,
2974 NvU16 addr,
2975 NvU8 port,
2976 NvU8 cmd,
2977 NvU32 msgLength,
2978 NvU8 *pData
2979 )
2980 {
2981 NvlStatus status;
2982 NvU16 deviceAddr;
2983 NvU32 speedMode;
2984 NvBool bIsRead = NV_FALSE;
2985 NvU32 flags = 0;
2986 NVSWITCH_CTRL_I2C_INDEXED_PARAMS i2c_params = {0};
2987 NvBool is_i2c_access_allowed;
2988
2989 if (!nvswitch_os_is_admin())
2990 {
2991 return -NVL_ERR_INSUFFICIENT_PERMISSIONS;
2992 }
2993
2994 is_i2c_access_allowed = (device->regkeys.i2c_access_control ==
2995 NV_SWITCH_REGKEY_I2C_ACCESS_CONTROL_ENABLE) ?
2996 NV_TRUE : NV_FALSE;
2997
2998 //
2999 // The address needs to be shifted by 1,
3000 // See NVSWITCH_CTRL_I2C_INDEXED_PARAMS
3001 //
3002 deviceAddr = addr << 1;
3003 speedMode = device->pI2c->Ports[port].defaultSpeedMode;
3004 flags = DRF_DEF(SWITCH_CTRL, _I2C_FLAGS, _START, _SEND) |
3005 DRF_DEF(SWITCH_CTRL, _I2C_FLAGS, _STOP, _SEND) |
3006 DRF_DEF(SWITCH_CTRL, _I2C_FLAGS, _ADDRESS_MODE, _7BIT) |
3007 DRF_DEF(SWITCH_CTRL, _I2C_FLAGS, _FLAVOR, _HW) |
3008 DRF_DEF(SWITCH_CTRL, _I2C_FLAGS, _BLOCK_PROTOCOL, _DISABLED) |
3009 DRF_DEF(SWITCH_CTRL, _I2C_FLAGS, _TRANSACTION_MODE, _NORMAL);
3010
3011 switch (speedMode)
3012 {
3013 case NVSWITCH_I2C_SPEED_MODE_1000KHZ:
3014 {
3015 flags = FLD_SET_DRF(SWITCH_CTRL, _I2C_FLAGS, _SPEED_MODE, _1000KHZ, flags);
3016 break;
3017 }
3018 case NVSWITCH_I2C_SPEED_MODE_400KHZ:
3019 {
3020 flags = FLD_SET_DRF(SWITCH_CTRL, _I2C_FLAGS, _SPEED_MODE, _400KHZ, flags);
3021 break;
3022 }
3023 case NVSWITCH_I2C_SPEED_MODE_300KHZ:
3024 {
3025 flags = FLD_SET_DRF(SWITCH_CTRL, _I2C_FLAGS, _SPEED_MODE, _300KHZ, flags);
3026 break;
3027 }
3028 case NVSWITCH_I2C_SPEED_MODE_200KHZ:
3029 {
3030 flags = FLD_SET_DRF(SWITCH_CTRL, _I2C_FLAGS, _SPEED_MODE, _200KHZ, flags);
3031 break;
3032 }
3033 case NVSWITCH_I2C_SPEED_MODE_100KHZ:
3034 {
3035 flags = FLD_SET_DRF(SWITCH_CTRL, _I2C_FLAGS, _SPEED_MODE, _100KHZ, flags);
3036 break;
3037 }
3038 default:
3039 {
3040 NVSWITCH_PRINT(device, ERROR, "Invalid I2C speed!\n");
3041 status = -NVL_BAD_ARGS;
3042 goto end;
3043 }
3044 }
3045
3046 switch (type)
3047 {
3048 case NVSWITCH_I2C_CMD_READ:
3049 bIsRead = NV_TRUE;
3050 // Fall through
3051 case NVSWITCH_I2C_CMD_WRITE:
3052 {
3053 flags = FLD_SET_DRF(SWITCH_CTRL, _I2C_FLAGS, _INDEX_LENGTH, _ZERO, flags);
3054 break;
3055 }
3056 case NVSWITCH_I2C_CMD_SMBUS_READ:
3057 {
3058 bIsRead = NV_TRUE;
3059 flags = FLD_SET_DRF(SWITCH_CTRL, _I2C_FLAGS, _RESTART, _SEND, flags);
3060 // Fall through
3061 }
3062 case NVSWITCH_I2C_CMD_SMBUS_WRITE:
3063 {
3064 flags = FLD_SET_DRF(SWITCH_CTRL, _I2C_FLAGS, _INDEX_LENGTH, _ONE, flags);
3065 break;
3066 }
3067 case NVSWITCH_I2C_CMD_SMBUS_QUICK_READ:
3068 bIsRead = NV_TRUE;
3069 // Fall through
3070 case NVSWITCH_I2C_CMD_SMBUS_QUICK_WRITE:
3071 {
3072 flags = FLD_SET_DRF(SWITCH_CTRL, _I2C_FLAGS, _INDEX_LENGTH, _ZERO, flags);
3073 msgLength = 0;
3074 break;
3075 }
3076 default:
3077 {
3078 NVSWITCH_PRINT(device, ERROR, "Invalid SMBUS protocol! Protocol not supported.\n");
3079 status = -NVL_BAD_ARGS;
3080 goto end;
3081 }
3082 }
3083
3084 if (!is_i2c_access_allowed &&
3085 !nvswitch_i2c_is_device_access_allowed(device, port, deviceAddr, bIsRead))
3086 {
3087 return -NVL_BAD_ARGS;
3088 }
3089
3090 if (msgLength > NVSWITCH_CTRL_I2C_MESSAGE_LENGTH_MAX)
3091 {
3092 NVSWITCH_PRINT(device, ERROR,
3093 "Length of buffer (0x%x bytes) provided larger than max (0x%x bytes)\n",
3094 msgLength, NVSWITCH_CTRL_I2C_MESSAGE_LENGTH_MAX);
3095 status = -NVL_BAD_ARGS;
3096 goto end;
3097 }
3098
3099 if (bIsRead)
3100 {
3101 i2c_params.bIsRead = NV_TRUE;
3102 }
3103 else
3104 {
3105 flags = FLD_SET_DRF(SWITCH_CTRL, _I2C_FLAGS, _RESTART, _NONE, flags);
3106 nvswitch_os_memcpy(i2c_params.message, pData, msgLength);
3107 }
3108
3109 if (FLD_TEST_DRF(SWITCH_CTRL, _I2C_FLAGS, _INDEX_LENGTH, _ONE, flags))
3110 {
3111 i2c_params.index[0] = cmd;
3112 }
3113
3114 i2c_params.port = port;
3115 i2c_params.address = deviceAddr;
3116 i2c_params.acquirer = client;
3117 i2c_params.flags = flags;
3118 i2c_params.messageLength = msgLength;
3119
3120 status = nvswitch_ctrl_i2c_indexed(device, &i2c_params);
3121 if (status != NVL_SUCCESS)
3122 {
3123 NVSWITCH_PRINT(device, ERROR, "I2C transfer Failed!\n");
3124 goto end;
3125 }
3126
3127 if (bIsRead)
3128 {
3129 nvswitch_os_memcpy(pData, i2c_params.message, msgLength);
3130 }
3131
3132 end:
3133 return status;
3134 }
3135
3136 /*!
3137 * @brief: Performs an I2C transaction.
3138 */
3139 NvlStatus
nvswitch_lib_i2c_transfer(nvswitch_device * device,NvU32 port,NvU8 type,NvU8 addr,NvU8 command,NvU32 len,NvU8 * pData)3140 nvswitch_lib_i2c_transfer
3141 (
3142 nvswitch_device *device,
3143 NvU32 port,
3144 NvU8 type,
3145 NvU8 addr,
3146 NvU8 command,
3147 NvU32 len,
3148 NvU8 *pData
3149 )
3150 {
3151 NvlStatus status;
3152 NvU32 port_info;
3153 NvBool is_i2c_access_allowed;
3154 NvBool is_port_allowed;
3155
3156 if (!NVSWITCH_IS_DEVICE_VALID(device))
3157 {
3158 NVSWITCH_ASSERT(0);
3159 return -NVL_ERR_INVALID_STATE;
3160 }
3161
3162 port_info = nvswitch_i2c_get_port_info(device, port);
3163
3164 is_i2c_access_allowed = (device->regkeys.i2c_access_control ==
3165 NV_SWITCH_REGKEY_I2C_ACCESS_CONTROL_ENABLE) ?
3166 NV_TRUE : NV_FALSE;
3167 is_port_allowed = is_i2c_access_allowed ? NV_TRUE :
3168 FLD_TEST_DRF(_I2C, _PORTINFO, _ACCESS_ALLOWED, _TRUE,
3169 port_info);
3170
3171 if (!is_port_allowed ||
3172 !FLD_TEST_DRF(_I2C, _PORTINFO, _DEFINED, _PRESENT, port_info))
3173 {
3174 NVSWITCH_PRINT(device, INFO,
3175 "%s: Invalid port access %d.\n",
3176 __FUNCTION__, port);
3177 return (-NVL_BAD_ARGS);
3178 }
3179
3180 status = _nvswitch_perform_i2c_transfer(device, NVSWITCH_I2C_ACQUIRER_EXTERNAL,
3181 type, (NvU16)addr, port, command, len, pData);
3182 if (status != NVL_SUCCESS)
3183 {
3184 NVSWITCH_PRINT(device, ERROR, "I2C transaction failed!\n");
3185 return status;
3186 }
3187
3188 return NVL_SUCCESS;
3189 }
3190
3191 void
nvswitch_timeout_create(NvU64 timeout_ns,NVSWITCH_TIMEOUT * time)3192 nvswitch_timeout_create
3193 (
3194 NvU64 timeout_ns,
3195 NVSWITCH_TIMEOUT *time
3196 )
3197 {
3198 NvU64 time_current;
3199
3200 time_current = nvswitch_os_get_platform_time();
3201 time->timeout_ns = time_current + timeout_ns;
3202 }
3203
3204 NvBool
nvswitch_timeout_check(NVSWITCH_TIMEOUT * time)3205 nvswitch_timeout_check
3206 (
3207 NVSWITCH_TIMEOUT *time
3208 )
3209 {
3210 NvU64 time_current;
3211
3212 time_current = nvswitch_os_get_platform_time();
3213 return (time->timeout_ns <= time_current);
3214 }
3215
3216 NvlStatus
nvswitch_task_create(nvswitch_device * device,void (* task_fn)(nvswitch_device * device),NvU64 period_nsec,NvU32 flags)3217 nvswitch_task_create
3218 (
3219 nvswitch_device *device,
3220 void (*task_fn)(nvswitch_device *device),
3221 NvU64 period_nsec,
3222 NvU32 flags
3223 )
3224 {
3225 NVSWITCH_TASK_TYPE *task;
3226 task = nvswitch_os_malloc(sizeof(NVSWITCH_TASK_TYPE));
3227
3228 if (task == NULL)
3229 {
3230 NVSWITCH_PRINT(device, ERROR,
3231 "%s: Unable to allocate task.\n",
3232 __FUNCTION__);
3233 return -NVL_NO_MEM;
3234 }
3235 else
3236 {
3237 task->task_fn_devptr = task_fn;
3238 task->task_args = NULL;
3239 task->period_nsec = period_nsec;
3240 task->last_run_nsec = nvswitch_os_get_platform_time(); // Prevent deferred tasks from being run immediately
3241 task->flags = flags;
3242 task->prev = NULL;
3243 task->next = device->tasks;
3244 if (device->tasks != NULL)
3245 {
3246 device->tasks->prev = task;
3247 }
3248 device->tasks = task;
3249 }
3250
3251 return NVL_SUCCESS;
3252 }
3253
3254 NvlStatus
nvswitch_task_create_args(nvswitch_device * device,void * fn_args,void (* task_fn)(nvswitch_device * device,void * fn_args),NvU64 period_nsec,NvU32 flags)3255 nvswitch_task_create_args
3256 (
3257 nvswitch_device *device,
3258 void *fn_args,
3259 void (*task_fn)(nvswitch_device* device, void *fn_args),
3260 NvU64 period_nsec,
3261 NvU32 flags
3262 )
3263 {
3264 NVSWITCH_TASK_TYPE *task;
3265 task = nvswitch_os_malloc(sizeof(NVSWITCH_TASK_TYPE));
3266
3267 flags = flags | NVSWITCH_TASK_TYPE_FLAGS_VOID_PTR_ARGS; // ensure dispatcher always executes tasks passed through this function with args
3268
3269 if (task == NULL)
3270 {
3271 NVSWITCH_PRINT(device, ERROR,
3272 "%s: Unable to allocate task.\n",
3273 __FUNCTION__);
3274 return -NVL_NO_MEM;
3275 }
3276 else
3277 {
3278 task->task_fn_vdptr = task_fn;
3279 task->task_args = fn_args;
3280 task->period_nsec = period_nsec;
3281 task->last_run_nsec = nvswitch_os_get_platform_time(); // Prevent deferred tasks from being run immediately
3282 task->flags = flags;
3283 task->prev = NULL;
3284 task->next = device->tasks;
3285 if (device->tasks != NULL)
3286 {
3287 device->tasks->prev = task;
3288 }
3289 device->tasks = task;
3290 }
3291
3292 return NVL_SUCCESS;
3293 }
3294
3295 void
nvswitch_tasks_destroy(nvswitch_device * device)3296 nvswitch_tasks_destroy
3297 (
3298 nvswitch_device *device
3299 )
3300 {
3301 NVSWITCH_TASK_TYPE *task = device->tasks;
3302 NVSWITCH_TASK_TYPE *next_task;
3303
3304 device->tasks = NULL;
3305
3306 while (task)
3307 {
3308 next_task = task->next;
3309 nvswitch_os_free(task);
3310 task = next_task;
3311 }
3312 }
3313
3314 void
nvswitch_destroy_device_state(nvswitch_device * device)3315 nvswitch_destroy_device_state
3316 (
3317 nvswitch_device *device
3318 )
3319 {
3320 device->hal.nvswitch_destroy_device_state(device);
3321 }
3322
3323 static NvlStatus
_nvswitch_ctrl_get_info(nvswitch_device * device,NVSWITCH_GET_INFO * p)3324 _nvswitch_ctrl_get_info
3325 (
3326 nvswitch_device *device,
3327 NVSWITCH_GET_INFO *p
3328 )
3329 {
3330 return device->hal.nvswitch_ctrl_get_info(device, p);
3331 }
3332
3333 static NvlStatus
_nvswitch_ctrl_get_nvlink_status(nvswitch_device * device,NVSWITCH_GET_NVLINK_STATUS_PARAMS * ret)3334 _nvswitch_ctrl_get_nvlink_status
3335 (
3336 nvswitch_device *device,
3337 NVSWITCH_GET_NVLINK_STATUS_PARAMS *ret
3338 )
3339 {
3340 return device->hal.nvswitch_ctrl_get_nvlink_status(device, ret);
3341 }
3342
3343 static NvlStatus
_nvswitch_ctrl_get_counters(nvswitch_device * device,NVSWITCH_NVLINK_GET_COUNTERS_PARAMS * ret)3344 _nvswitch_ctrl_get_counters
3345 (
3346 nvswitch_device *device,
3347 NVSWITCH_NVLINK_GET_COUNTERS_PARAMS *ret
3348 )
3349 {
3350 return device->hal.nvswitch_ctrl_get_counters(device, ret);
3351 }
3352
3353 NvlStatus
nvswitch_set_nport_port_config(nvswitch_device * device,NVSWITCH_SET_SWITCH_PORT_CONFIG * p)3354 nvswitch_set_nport_port_config
3355 (
3356 nvswitch_device *device,
3357 NVSWITCH_SET_SWITCH_PORT_CONFIG *p
3358 )
3359 {
3360 return device->hal.nvswitch_set_nport_port_config(device, p);
3361 }
3362
3363 static NvlStatus
_nvswitch_ctrl_set_switch_port_config(nvswitch_device * device,NVSWITCH_SET_SWITCH_PORT_CONFIG * p)3364 _nvswitch_ctrl_set_switch_port_config
3365 (
3366 nvswitch_device *device,
3367 NVSWITCH_SET_SWITCH_PORT_CONFIG *p
3368 )
3369 {
3370 return device->hal.nvswitch_ctrl_set_switch_port_config(device, p);
3371 }
3372
3373 static NvlStatus
_nvswitch_ctrl_get_ingress_request_table(nvswitch_device * device,NVSWITCH_GET_INGRESS_REQUEST_TABLE_PARAMS * params)3374 _nvswitch_ctrl_get_ingress_request_table
3375 (
3376 nvswitch_device *device,
3377 NVSWITCH_GET_INGRESS_REQUEST_TABLE_PARAMS *params
3378 )
3379 {
3380 return device->hal.nvswitch_ctrl_get_ingress_request_table(device, params);
3381 }
3382
3383 static NvlStatus
_nvswitch_ctrl_set_ingress_request_table(nvswitch_device * device,NVSWITCH_SET_INGRESS_REQUEST_TABLE * p)3384 _nvswitch_ctrl_set_ingress_request_table
3385 (
3386 nvswitch_device *device,
3387 NVSWITCH_SET_INGRESS_REQUEST_TABLE *p
3388 )
3389 {
3390 return device->hal.nvswitch_ctrl_set_ingress_request_table(device, p);
3391 }
3392
3393 static NvlStatus
_nvswitch_ctrl_set_ingress_request_valid(nvswitch_device * device,NVSWITCH_SET_INGRESS_REQUEST_VALID * p)3394 _nvswitch_ctrl_set_ingress_request_valid
3395 (
3396 nvswitch_device *device,
3397 NVSWITCH_SET_INGRESS_REQUEST_VALID *p
3398 )
3399 {
3400 return device->hal.nvswitch_ctrl_set_ingress_request_valid(device, p);
3401 }
3402
3403 static NvlStatus
_nvswitch_ctrl_get_ingress_response_table(nvswitch_device * device,NVSWITCH_GET_INGRESS_RESPONSE_TABLE_PARAMS * params)3404 _nvswitch_ctrl_get_ingress_response_table
3405 (
3406 nvswitch_device *device,
3407 NVSWITCH_GET_INGRESS_RESPONSE_TABLE_PARAMS *params
3408 )
3409 {
3410 return device->hal.nvswitch_ctrl_get_ingress_response_table(device, params);
3411 }
3412
3413 static NvlStatus
_nvswitch_ctrl_set_ingress_response_table(nvswitch_device * device,NVSWITCH_SET_INGRESS_RESPONSE_TABLE * p)3414 _nvswitch_ctrl_set_ingress_response_table
3415 (
3416 nvswitch_device *device,
3417 NVSWITCH_SET_INGRESS_RESPONSE_TABLE *p
3418 )
3419 {
3420 return device->hal.nvswitch_ctrl_set_ingress_response_table(device, p);
3421 }
3422
3423 static NvlStatus
_nvswitch_ctrl_set_ganged_link_table(nvswitch_device * device,NVSWITCH_SET_GANGED_LINK_TABLE * p)3424 _nvswitch_ctrl_set_ganged_link_table
3425 (
3426 nvswitch_device *device,
3427 NVSWITCH_SET_GANGED_LINK_TABLE *p
3428 )
3429 {
3430 return device->hal.nvswitch_ctrl_set_ganged_link_table(device, p);
3431 }
3432
3433 void
nvswitch_init_npg_multicast(nvswitch_device * device)3434 nvswitch_init_npg_multicast
3435 (
3436 nvswitch_device *device
3437 )
3438 {
3439 device->hal.nvswitch_init_npg_multicast(device);
3440 }
3441
3442 void
nvswitch_init_warm_reset(nvswitch_device * device)3443 nvswitch_init_warm_reset
3444 (
3445 nvswitch_device *device
3446 )
3447 {
3448 device->hal.nvswitch_init_warm_reset(device);
3449 }
3450
3451 static NvlStatus
_nvswitch_ctrl_set_remap_policy(nvswitch_device * device,NVSWITCH_SET_REMAP_POLICY * p)3452 _nvswitch_ctrl_set_remap_policy
3453 (
3454 nvswitch_device *device,
3455 NVSWITCH_SET_REMAP_POLICY *p
3456 )
3457 {
3458 return device->hal.nvswitch_ctrl_set_remap_policy(device, p);
3459 }
3460
3461 static NvlStatus
_nvswitch_ctrl_get_remap_policy(nvswitch_device * device,NVSWITCH_GET_REMAP_POLICY_PARAMS * params)3462 _nvswitch_ctrl_get_remap_policy
3463 (
3464 nvswitch_device *device,
3465 NVSWITCH_GET_REMAP_POLICY_PARAMS *params
3466 )
3467 {
3468 return device->hal.nvswitch_ctrl_get_remap_policy(device, params);
3469 }
3470
3471 static NvlStatus
_nvswitch_ctrl_set_remap_policy_valid(nvswitch_device * device,NVSWITCH_SET_REMAP_POLICY_VALID * p)3472 _nvswitch_ctrl_set_remap_policy_valid
3473 (
3474 nvswitch_device *device,
3475 NVSWITCH_SET_REMAP_POLICY_VALID *p
3476 )
3477 {
3478 return device->hal.nvswitch_ctrl_set_remap_policy_valid(device, p);
3479 }
3480
3481 static NvlStatus
_nvswitch_ctrl_set_routing_id(nvswitch_device * device,NVSWITCH_SET_ROUTING_ID * p)3482 _nvswitch_ctrl_set_routing_id
3483 (
3484 nvswitch_device *device,
3485 NVSWITCH_SET_ROUTING_ID *p
3486 )
3487 {
3488 return device->hal.nvswitch_ctrl_set_routing_id(device, p);
3489 }
3490
3491 static NvlStatus
_nvswitch_ctrl_get_routing_id(nvswitch_device * device,NVSWITCH_GET_ROUTING_ID_PARAMS * params)3492 _nvswitch_ctrl_get_routing_id
3493 (
3494 nvswitch_device *device,
3495 NVSWITCH_GET_ROUTING_ID_PARAMS *params
3496 )
3497 {
3498 return device->hal.nvswitch_ctrl_get_routing_id(device, params);
3499 }
3500
3501 static NvlStatus
_nvswitch_ctrl_set_routing_id_valid(nvswitch_device * device,NVSWITCH_SET_ROUTING_ID_VALID * p)3502 _nvswitch_ctrl_set_routing_id_valid
3503 (
3504 nvswitch_device *device,
3505 NVSWITCH_SET_ROUTING_ID_VALID *p
3506 )
3507 {
3508 return device->hal.nvswitch_ctrl_set_routing_id_valid(device, p);
3509 }
3510
3511 static NvlStatus
_nvswitch_ctrl_set_routing_lan(nvswitch_device * device,NVSWITCH_SET_ROUTING_LAN * p)3512 _nvswitch_ctrl_set_routing_lan
3513 (
3514 nvswitch_device *device,
3515 NVSWITCH_SET_ROUTING_LAN *p
3516 )
3517 {
3518 return device->hal.nvswitch_ctrl_set_routing_lan(device, p);
3519 }
3520
3521 static NvlStatus
_nvswitch_ctrl_get_routing_lan(nvswitch_device * device,NVSWITCH_GET_ROUTING_LAN_PARAMS * params)3522 _nvswitch_ctrl_get_routing_lan
3523 (
3524 nvswitch_device *device,
3525 NVSWITCH_GET_ROUTING_LAN_PARAMS *params
3526 )
3527 {
3528 return device->hal.nvswitch_ctrl_get_routing_lan(device, params);
3529 }
3530
3531 static NvlStatus
_nvswitch_ctrl_set_routing_lan_valid(nvswitch_device * device,NVSWITCH_SET_ROUTING_LAN_VALID * p)3532 _nvswitch_ctrl_set_routing_lan_valid
3533 (
3534 nvswitch_device *device,
3535 NVSWITCH_SET_ROUTING_LAN_VALID *p
3536 )
3537 {
3538 return device->hal.nvswitch_ctrl_set_routing_lan_valid(device, p);
3539 }
3540
3541 static NvlStatus
_nvswitch_ctrl_get_internal_latency(nvswitch_device * device,NVSWITCH_GET_INTERNAL_LATENCY * p)3542 _nvswitch_ctrl_get_internal_latency
3543 (
3544 nvswitch_device *device,
3545 NVSWITCH_GET_INTERNAL_LATENCY *p
3546 )
3547 {
3548 return device->hal.nvswitch_ctrl_get_internal_latency(device, p);
3549 }
3550
3551 static NvlStatus
_nvswitch_ctrl_get_nvlipt_counters(nvswitch_device * device,NVSWITCH_GET_NVLIPT_COUNTERS * p)3552 _nvswitch_ctrl_get_nvlipt_counters
3553 (
3554 nvswitch_device *device,
3555 NVSWITCH_GET_NVLIPT_COUNTERS *p
3556 )
3557 {
3558 //
3559 // This control call is now deprecated.
3560 // New control call to fetch throughput counters is:
3561 // nvswitch_ctrl_get_throughput_counters
3562 //
3563 return -NVL_ERR_NOT_SUPPORTED;
3564 }
3565
3566 static NvlStatus
_nvswitch_ctrl_set_nvlipt_counter_config(nvswitch_device * device,NVSWITCH_SET_NVLIPT_COUNTER_CONFIG * p)3567 _nvswitch_ctrl_set_nvlipt_counter_config
3568 (
3569 nvswitch_device *device,
3570 NVSWITCH_SET_NVLIPT_COUNTER_CONFIG *p
3571 )
3572 {
3573 //
3574 // This control call is now deprecated.
3575 // New control call to fetch throughput counters is:
3576 // nvswitch_ctrl_get_throughput_counters_lr10
3577 //
3578 // Setting counter config is not allowed on these
3579 // non-configurable counters. These counters are
3580 // expected to be used by monitoring clients.
3581 //
3582 return -NVL_ERR_NOT_SUPPORTED;
3583 }
3584
3585 static NvlStatus
_nvswitch_ctrl_get_nvlipt_counter_config(nvswitch_device * device,NVSWITCH_GET_NVLIPT_COUNTER_CONFIG * p)3586 _nvswitch_ctrl_get_nvlipt_counter_config
3587 (
3588 nvswitch_device *device,
3589 NVSWITCH_GET_NVLIPT_COUNTER_CONFIG *p
3590 )
3591 {
3592 //
3593 // This control call is now deprecated.
3594 // New control call to fetch throughput counters is:
3595 // nvswitch_ctrl_get_throughput_counters_lr10
3596 //
3597 // Getting counter config is useful if counters are
3598 // configurable. These counters are not configurable
3599 // and are expected to be used by monitoring clients.
3600 //
3601 return -NVL_ERR_NOT_SUPPORTED;
3602 }
3603
3604 static NvlStatus
_nvswitch_ctrl_register_read(nvswitch_device * device,NVSWITCH_REGISTER_READ * p)3605 _nvswitch_ctrl_register_read
3606 (
3607 nvswitch_device *device,
3608 NVSWITCH_REGISTER_READ *p
3609 )
3610 {
3611 return device->hal.nvswitch_ctrl_register_read(device, p);
3612 }
3613
3614 static NvlStatus
_nvswitch_ctrl_register_write(nvswitch_device * device,NVSWITCH_REGISTER_WRITE * p)3615 _nvswitch_ctrl_register_write
3616 (
3617 nvswitch_device *device,
3618 NVSWITCH_REGISTER_WRITE *p
3619 )
3620 {
3621 return device->hal.nvswitch_ctrl_register_write(device, p);
3622 }
3623
3624 NvU32
nvswitch_i2c_get_port_info(nvswitch_device * device,NvU32 port)3625 nvswitch_i2c_get_port_info
3626 (
3627 nvswitch_device *device,
3628 NvU32 port
3629 )
3630 {
3631 return device->hal.nvswitch_i2c_get_port_info(device, port);
3632 }
3633
3634 NvlStatus
nvswitch_ctrl_i2c_indexed(nvswitch_device * device,NVSWITCH_CTRL_I2C_INDEXED_PARAMS * pParams)3635 nvswitch_ctrl_i2c_indexed
3636 (
3637 nvswitch_device *device,
3638 NVSWITCH_CTRL_I2C_INDEXED_PARAMS *pParams
3639 )
3640 {
3641 return device->hal.nvswitch_ctrl_i2c_indexed(device, pParams);
3642 }
3643
3644 static NvlStatus
_nvswitch_ctrl_therm_read_temperature(nvswitch_device * device,NVSWITCH_CTRL_GET_TEMPERATURE_PARAMS * info)3645 _nvswitch_ctrl_therm_read_temperature
3646 (
3647 nvswitch_device *device,
3648 NVSWITCH_CTRL_GET_TEMPERATURE_PARAMS *info
3649 )
3650 {
3651 return device->hal.nvswitch_ctrl_therm_read_temperature(device, info);
3652 }
3653
3654 static NvlStatus
_nvswitch_ctrl_get_bios_info(nvswitch_device * device,NVSWITCH_GET_BIOS_INFO_PARAMS * p)3655 _nvswitch_ctrl_get_bios_info
3656 (
3657 nvswitch_device *device,
3658 NVSWITCH_GET_BIOS_INFO_PARAMS *p
3659 )
3660 {
3661 return device->hal.nvswitch_ctrl_get_bios_info(device, p);
3662 }
3663
3664 static NvlStatus
_nvswitch_ctrl_get_inforom_version(nvswitch_device * device,NVSWITCH_GET_INFOROM_VERSION_PARAMS * p)3665 _nvswitch_ctrl_get_inforom_version
3666 (
3667 nvswitch_device *device,
3668 NVSWITCH_GET_INFOROM_VERSION_PARAMS *p
3669 )
3670 {
3671 return device->hal.nvswitch_ctrl_get_inforom_version(device, p);
3672 }
3673
3674 NvlStatus
nvswitch_ctrl_set_latency_bins(nvswitch_device * device,NVSWITCH_SET_LATENCY_BINS * p)3675 nvswitch_ctrl_set_latency_bins
3676 (
3677 nvswitch_device *device,
3678 NVSWITCH_SET_LATENCY_BINS *p
3679 )
3680 {
3681 return device->hal.nvswitch_ctrl_set_latency_bins(device, p);
3682 }
3683
3684 static NvlStatus
_nvswitch_ctrl_get_ingress_reqlinkid(nvswitch_device * device,NVSWITCH_GET_INGRESS_REQLINKID_PARAMS * params)3685 _nvswitch_ctrl_get_ingress_reqlinkid
3686 (
3687 nvswitch_device *device,
3688 NVSWITCH_GET_INGRESS_REQLINKID_PARAMS *params
3689 )
3690 {
3691 return device->hal.nvswitch_ctrl_get_ingress_reqlinkid(device, params);
3692 }
3693
3694 NvlStatus
nvswitch_ctrl_get_throughput_counters(nvswitch_device * device,NVSWITCH_GET_THROUGHPUT_COUNTERS_PARAMS * p)3695 nvswitch_ctrl_get_throughput_counters
3696 (
3697 nvswitch_device *device,
3698 NVSWITCH_GET_THROUGHPUT_COUNTERS_PARAMS *p
3699 )
3700 {
3701 return device->hal.nvswitch_ctrl_get_throughput_counters(device, p);
3702 }
3703
3704 static NvlStatus
_nvswitch_ctrl_unregister_link(nvswitch_device * device,NVSWITCH_UNREGISTER_LINK_PARAMS * params)3705 _nvswitch_ctrl_unregister_link
3706 (
3707 nvswitch_device *device,
3708 NVSWITCH_UNREGISTER_LINK_PARAMS *params
3709 )
3710 {
3711 nvlink_link *link = nvswitch_get_link(device, (NvU8)params->portNum);
3712
3713 if (link == NULL)
3714 {
3715 return -NVL_BAD_ARGS;
3716 }
3717
3718 // With ALI in FW, links can be unregistered while Active
3719 if (!device->nvlink_device->enableALI)
3720 {
3721
3722 if (device->hal.nvswitch_is_link_in_use(device, params->portNum))
3723 {
3724 return -NVL_ERR_STATE_IN_USE;
3725 }
3726
3727 }
3728
3729 nvlink_lib_unregister_link(link);
3730 nvswitch_destroy_link(link);
3731
3732 return NVL_SUCCESS;
3733 }
3734
3735 static NvlStatus
_nvswitch_ctrl_acquire_capability(nvswitch_device * device,NVSWITCH_ACQUIRE_CAPABILITY_PARAMS * params,void * osPrivate)3736 _nvswitch_ctrl_acquire_capability
3737 (
3738 nvswitch_device *device,
3739 NVSWITCH_ACQUIRE_CAPABILITY_PARAMS *params,
3740 void *osPrivate
3741 )
3742 {
3743 return nvswitch_os_acquire_fabric_mgmt_cap(osPrivate,
3744 params->capDescriptor);
3745 }
3746
3747 static NvlStatus
_nvswitch_ctrl_reset_and_drain_links(nvswitch_device * device,NVSWITCH_RESET_AND_DRAIN_LINKS_PARAMS * params)3748 _nvswitch_ctrl_reset_and_drain_links
3749 (
3750 nvswitch_device *device,
3751 NVSWITCH_RESET_AND_DRAIN_LINKS_PARAMS *params
3752 )
3753 {
3754 return device->hal.nvswitch_reset_and_drain_links(device, params->linkMask, NV_FALSE);
3755 }
3756
3757 static NvlStatus
_nvswitch_ctrl_get_fom_values(nvswitch_device * device,NVSWITCH_GET_FOM_VALUES_PARAMS * ret)3758 _nvswitch_ctrl_get_fom_values
3759 (
3760 nvswitch_device *device,
3761 NVSWITCH_GET_FOM_VALUES_PARAMS *ret
3762 )
3763 {
3764 return device->hal.nvswitch_ctrl_get_fom_values(device, ret);
3765 }
3766
3767 static NvlStatus
_nvswitch_ctrl_get_nvlink_ecc_errors(nvswitch_device * device,NVSWITCH_GET_NVLINK_ECC_ERRORS_PARAMS * params)3768 _nvswitch_ctrl_get_nvlink_ecc_errors
3769 (
3770 nvswitch_device *device,
3771 NVSWITCH_GET_NVLINK_ECC_ERRORS_PARAMS *params
3772 )
3773 {
3774 return device->hal.nvswitch_get_nvlink_ecc_errors(device, params);
3775 }
3776
3777 static NvlStatus
_nvswitch_ctrl_set_mc_rid_table(nvswitch_device * device,NVSWITCH_SET_MC_RID_TABLE_PARAMS * p)3778 _nvswitch_ctrl_set_mc_rid_table
3779 (
3780 nvswitch_device *device,
3781 NVSWITCH_SET_MC_RID_TABLE_PARAMS *p
3782 )
3783 {
3784 return device->hal.nvswitch_ctrl_set_mc_rid_table(device, p);
3785 }
3786
3787 static NvlStatus
_nvswitch_ctrl_get_mc_rid_table(nvswitch_device * device,NVSWITCH_GET_MC_RID_TABLE_PARAMS * p)3788 _nvswitch_ctrl_get_mc_rid_table
3789 (
3790 nvswitch_device *device,
3791 NVSWITCH_GET_MC_RID_TABLE_PARAMS *p
3792 )
3793 {
3794 return device->hal.nvswitch_ctrl_get_mc_rid_table(device, p);
3795 }
3796
3797 static NvlStatus
_nvswitch_ctrl_set_residency_bins(nvswitch_device * device,NVSWITCH_SET_RESIDENCY_BINS * p)3798 _nvswitch_ctrl_set_residency_bins
3799 (
3800 nvswitch_device *device,
3801 NVSWITCH_SET_RESIDENCY_BINS *p
3802 )
3803 {
3804 return device->hal.nvswitch_ctrl_set_residency_bins(device, p);
3805 }
3806
3807 static NvlStatus
_nvswitch_ctrl_get_residency_bins(nvswitch_device * device,NVSWITCH_GET_RESIDENCY_BINS * p)3808 _nvswitch_ctrl_get_residency_bins
3809 (
3810 nvswitch_device *device,
3811 NVSWITCH_GET_RESIDENCY_BINS *p
3812 )
3813 {
3814 return device->hal.nvswitch_ctrl_get_residency_bins(device, p);
3815 }
3816
3817 static NvlStatus
_nvswitch_ctrl_get_rb_stall_busy(nvswitch_device * device,NVSWITCH_GET_RB_STALL_BUSY * p)3818 _nvswitch_ctrl_get_rb_stall_busy
3819 (
3820 nvswitch_device *device,
3821 NVSWITCH_GET_RB_STALL_BUSY *p
3822 )
3823 {
3824 return device->hal.nvswitch_ctrl_get_rb_stall_busy(device, p);
3825 }
3826
3827 NvlStatus
nvswitch_ctrl_get_multicast_id_error_vector(nvswitch_device * device,NVSWITCH_GET_MULTICAST_ID_ERROR_VECTOR * p)3828 nvswitch_ctrl_get_multicast_id_error_vector
3829 (
3830 nvswitch_device *device,
3831 NVSWITCH_GET_MULTICAST_ID_ERROR_VECTOR *p
3832 )
3833 {
3834 return device->hal.nvswitch_ctrl_get_multicast_id_error_vector(device, p);
3835 }
3836
3837 NvlStatus
nvswitch_ctrl_clear_multicast_id_error_vector(nvswitch_device * device,NVSWITCH_CLEAR_MULTICAST_ID_ERROR_VECTOR * p)3838 nvswitch_ctrl_clear_multicast_id_error_vector
3839 (
3840 nvswitch_device *device,
3841 NVSWITCH_CLEAR_MULTICAST_ID_ERROR_VECTOR *p
3842 )
3843 {
3844 return device->hal.nvswitch_ctrl_clear_multicast_id_error_vector(device, p);
3845 }
3846
3847 static NvlStatus
_nvswitch_ctrl_inband_send_data(nvswitch_device * device,NVSWITCH_INBAND_SEND_DATA_PARAMS * p)3848 _nvswitch_ctrl_inband_send_data
3849 (
3850 nvswitch_device *device,
3851 NVSWITCH_INBAND_SEND_DATA_PARAMS *p
3852 )
3853 {
3854 return device->hal.nvswitch_ctrl_inband_send_data(device, p);
3855 }
3856
3857 static NvlStatus
_nvswitch_ctrl_inband_read_data(nvswitch_device * device,NVSWITCH_INBAND_READ_DATA_PARAMS * p)3858 _nvswitch_ctrl_inband_read_data
3859 (
3860 nvswitch_device *device,
3861 NVSWITCH_INBAND_READ_DATA_PARAMS *p
3862 )
3863 {
3864 return device->hal.nvswitch_ctrl_inband_read_data(device, p);
3865 }
3866
3867 static NvlStatus
_nvswitch_ctrl_inband_flush_data(nvswitch_device * device,NVSWITCH_INBAND_FLUSH_DATA_PARAMS * p)3868 _nvswitch_ctrl_inband_flush_data
3869 (
3870 nvswitch_device *device,
3871 NVSWITCH_INBAND_FLUSH_DATA_PARAMS *p
3872 )
3873 {
3874 NvU32 i;
3875 NvU64 enabledLinkMask;
3876
3877 if (p->linkMask == 0)
3878 {
3879 NVSWITCH_PRINT(device, ERROR, "Nothing to clear\n");
3880 return NVL_SUCCESS;
3881 }
3882
3883 enabledLinkMask = nvswitch_get_enabled_link_mask(device);
3884
3885 FOR_EACH_INDEX_IN_MASK(64, i, p->linkMask)
3886 {
3887 if (nvswitch_is_link_valid(device, i) &&
3888 (enabledLinkMask & NVBIT64(i)))
3889 {
3890 //
3891 // Flush is expected to clear both persistent and non-persistent
3892 // list. FM does flush when it wants to drop (ignore) all pending
3893 // messages w/o any NACKs.
3894 //
3895 _nvswitch_inband_clear_lists(device, i,
3896 NV_FALSE /* Nack */,
3897 NV_FALSE /* Non-persistent only */);
3898 }
3899 }
3900 FOR_EACH_INDEX_IN_MASK_END;
3901
3902 return NVL_SUCCESS;
3903 }
3904
3905 static NvlStatus
_nvswitch_ctrl_inband_pending_data_stats(nvswitch_device * device,NVSWITCH_INBAND_PENDING_DATA_STATS_PARAMS * p)3906 _nvswitch_ctrl_inband_pending_data_stats
3907 (
3908 nvswitch_device *device,
3909 NVSWITCH_INBAND_PENDING_DATA_STATS_PARAMS *p
3910 )
3911 {
3912 NvU32 link_num;
3913 NvU64 enabledLinkMask, persistent_mask = 0, nonpersistent_mask = 0;
3914
3915 enabledLinkMask = nvswitch_get_enabled_link_mask(device);
3916
3917 for (link_num = 0; link_num < nvswitch_get_num_links(device); link_num++)
3918 {
3919 if (nvswitch_is_link_valid(device, link_num) &&
3920 (enabledLinkMask & NVBIT64(link_num)))
3921 {
3922 if (!nvListIsEmpty(&device->link[link_num].inbandData.persistent_list))
3923 {
3924 persistent_mask |= NVBIT64(link_num);
3925 }
3926
3927 if (!nvListIsEmpty(&device->link[link_num].inbandData.nonpersistent_list))
3928 {
3929 nonpersistent_mask |= NVBIT64(link_num);
3930 }
3931 }
3932 }
3933
3934 if (persistent_mask > 0)
3935 {
3936 p->linkMask = persistent_mask;
3937 }
3938 else
3939 {
3940 p->linkMask = nonpersistent_mask;
3941 }
3942
3943 return NVL_SUCCESS;
3944 }
3945
3946 static NvlStatus
_nvswitch_ctrl_get_board_part_number(nvswitch_device * device,NVSWITCH_GET_BOARD_PART_NUMBER_VECTOR * p)3947 _nvswitch_ctrl_get_board_part_number
3948 (
3949 nvswitch_device *device,
3950 NVSWITCH_GET_BOARD_PART_NUMBER_VECTOR *p
3951 )
3952 {
3953 if (IS_RTLSIM(device) || IS_EMULATION(device) || IS_FMODEL(device))
3954 {
3955 NVSWITCH_PRINT(device, INFO,
3956 "%s: Skipping retrieval of board part number on FSF\n",
3957 __FUNCTION__);
3958
3959 nvswitch_os_memset(p, 0, sizeof(NVSWITCH_GET_BOARD_PART_NUMBER_VECTOR));
3960
3961 return NVL_SUCCESS;
3962 }
3963 else
3964 {
3965 if (!nvswitch_is_inforom_supported(device))
3966 {
3967 NVSWITCH_PRINT(device, ERROR, "InfoROM is not supported\n");
3968 return -NVL_ERR_NOT_SUPPORTED;
3969 }
3970
3971 return device->hal.nvswitch_ctrl_get_board_part_number(device, p);
3972 }
3973 }
3974
3975 static NvlStatus
_nvswitch_ctrl_i2c_smbus_command(nvswitch_device * device,NVSWITCH_I2C_SMBUS_COMMAND_PARAMS * pParams)3976 _nvswitch_ctrl_i2c_smbus_command
3977 (
3978 nvswitch_device *device,
3979 NVSWITCH_I2C_SMBUS_COMMAND_PARAMS *pParams
3980 )
3981 {
3982 NvU32 port_info;
3983 NvU32 port = pParams->port;
3984 NvU8 msgLen;
3985 NvU8 cmd;
3986 NvU16 addr;
3987 NvU8 cmdType;
3988 NvU8 *pData;
3989 NvBool is_i2c_access_allowed;
3990 NvBool is_port_allowed;
3991
3992 port_info = nvswitch_i2c_get_port_info(device, port);
3993
3994 is_i2c_access_allowed = (device->regkeys.i2c_access_control ==
3995 NV_SWITCH_REGKEY_I2C_ACCESS_CONTROL_ENABLE) ?
3996 NV_TRUE : NV_FALSE;
3997 is_port_allowed = is_i2c_access_allowed ? NV_TRUE :
3998 FLD_TEST_DRF(_I2C, _PORTINFO, _ACCESS_ALLOWED, _TRUE,
3999 port_info);
4000
4001 if (!is_port_allowed ||
4002 !FLD_TEST_DRF(_I2C, _PORTINFO, _DEFINED, _PRESENT, port_info))
4003 {
4004 NVSWITCH_PRINT(device, ERROR, "Invalid port access %d.\n", port);
4005 return NVL_BAD_ARGS;
4006 }
4007
4008 addr = pParams->deviceAddr;
4009
4010 switch (pParams->cmdType)
4011 {
4012 case NVSWITCH_I2C_SMBUS_CMD_QUICK:
4013 {
4014 cmd = 0;
4015 msgLen = 0;
4016 cmdType = pParams->bRead ?
4017 NVSWITCH_I2C_CMD_SMBUS_QUICK_READ :
4018 NVSWITCH_I2C_CMD_SMBUS_QUICK_WRITE;
4019 pData = NULL;
4020 break;
4021 }
4022 case NVSWITCH_I2C_SMBUS_CMD_BYTE:
4023 {
4024 cmd = 0;
4025 msgLen = 1;
4026 cmdType = pParams->bRead ?
4027 NVSWITCH_I2C_CMD_READ :
4028 NVSWITCH_I2C_CMD_WRITE;
4029 pData = (NvU8 *)&pParams->transactionData.smbusByte.message;
4030 break;
4031 }
4032 case NVSWITCH_I2C_SMBUS_CMD_BYTE_DATA:
4033 {
4034 msgLen = 1;
4035 cmd = pParams->transactionData.smbusByteData.cmd;
4036 cmdType = pParams->bRead ?
4037 NVSWITCH_I2C_CMD_SMBUS_READ :
4038 NVSWITCH_I2C_CMD_SMBUS_WRITE;
4039 pData = (NvU8 *)&pParams->transactionData.smbusByteData.message;
4040 break;
4041 }
4042 case NVSWITCH_I2C_SMBUS_CMD_WORD_DATA:
4043 {
4044 msgLen = 2;
4045 cmd = pParams->transactionData.smbusWordData.cmd;
4046 cmdType = pParams->bRead ?
4047 NVSWITCH_I2C_CMD_SMBUS_READ :
4048 NVSWITCH_I2C_CMD_SMBUS_WRITE;
4049 pData = (NvU8 *)&pParams->transactionData.smbusWordData.message;
4050 break;
4051 }
4052 default:
4053 {
4054 NVSWITCH_PRINT(device, ERROR, "Invalid Smbus command: %d.\n", port);
4055 return NVL_BAD_ARGS;
4056 }
4057 }
4058
4059 return _nvswitch_perform_i2c_transfer(device, NVSWITCH_I2C_ACQUIRER_IOCTL,
4060 cmdType, addr, port, cmd, msgLen, pData);
4061 }
4062
4063 NvBool
nvswitch_does_link_need_termination_enabled(nvswitch_device * device,nvlink_link * link)4064 nvswitch_does_link_need_termination_enabled
4065 (
4066 nvswitch_device *device,
4067 nvlink_link *link
4068 )
4069 {
4070 return device->hal.nvswitch_does_link_need_termination_enabled(device, link);
4071 }
4072
4073 NvlStatus
nvswitch_link_termination_setup(nvswitch_device * device,nvlink_link * link)4074 nvswitch_link_termination_setup
4075 (
4076 nvswitch_device *device,
4077 nvlink_link* link
4078 )
4079 {
4080 return device->hal.nvswitch_link_termination_setup(device, link);
4081 }
4082
4083 static NvlStatus
_nvswitch_ctrl_cci_cmis_presence(nvswitch_device * device,NVSWITCH_CCI_CMIS_PRESENCE_PARAMS * pParams)4084 _nvswitch_ctrl_cci_cmis_presence
4085 (
4086 nvswitch_device *device,
4087 NVSWITCH_CCI_CMIS_PRESENCE_PARAMS *pParams
4088 )
4089 {
4090 nvswitch_os_memset(pParams, 0, sizeof(NVSWITCH_CCI_CMIS_PRESENCE_PARAMS));
4091 if (device->pCci != NULL)
4092 {
4093 (void)cciGetXcvrMask(device, &pParams->cagesMask, &pParams->modulesMask);
4094 }
4095
4096 // IOCTL will always succeed
4097 return NVL_SUCCESS;
4098 }
4099
4100 static NvlStatus
_nvswitch_ctrl_cci_nvlink_mappings(nvswitch_device * device,NVSWITCH_CCI_CMIS_NVLINK_MAPPING_PARAMS * pParams)4101 _nvswitch_ctrl_cci_nvlink_mappings
4102 (
4103 nvswitch_device *device,
4104 NVSWITCH_CCI_CMIS_NVLINK_MAPPING_PARAMS *pParams
4105 )
4106 {
4107 if (device->pCci == NULL)
4108 {
4109 NVSWITCH_PRINT(device, ERROR,
4110 "%s: CCI not supported\n",
4111 __FUNCTION__);
4112 return -NVL_ERR_NOT_SUPPORTED;
4113 }
4114
4115 return cciGetCageMapping(device, pParams->cageIndex, &pParams->linkMask, &pParams->encodedValue);
4116 }
4117
4118 static NvlStatus
_nvswitch_ctrl_cci_memory_access_read(nvswitch_device * device,NVSWITCH_CCI_CMIS_MEMORY_ACCESS_READ_PARAMS * pParams)4119 _nvswitch_ctrl_cci_memory_access_read
4120 (
4121 nvswitch_device *device,
4122 NVSWITCH_CCI_CMIS_MEMORY_ACCESS_READ_PARAMS *pParams
4123 )
4124 {
4125 NvlStatus retVal;
4126
4127 if (device->pCci == NULL)
4128 {
4129 NVSWITCH_PRINT(device, ERROR,
4130 "%s: CCI not supported\n",
4131 __FUNCTION__);
4132 return -NVL_ERR_NOT_SUPPORTED;
4133 }
4134
4135 if (!cciCmisAccessTryLock(device, pParams->cageIndex))
4136 {
4137 return -NVL_ERR_STATE_IN_USE;
4138 }
4139
4140 retVal = cciCmisRead(device, pParams->cageIndex, pParams->bank,
4141 pParams->page, pParams->address, pParams->count,
4142 pParams->data);
4143
4144 if (!pParams->bSequenceLock)
4145 {
4146 cciCmisAccessReleaseLock(device, pParams->cageIndex);
4147 }
4148
4149 return retVal;
4150 }
4151
4152 static NvlStatus
_nvswitch_ctrl_cci_memory_access_write(nvswitch_device * device,NVSWITCH_CCI_CMIS_MEMORY_ACCESS_WRITE_PARAMS * pParams)4153 _nvswitch_ctrl_cci_memory_access_write
4154 (
4155 nvswitch_device *device,
4156 NVSWITCH_CCI_CMIS_MEMORY_ACCESS_WRITE_PARAMS *pParams
4157 )
4158 {
4159 NvlStatus retVal;
4160
4161 if (device->pCci == NULL)
4162 {
4163 NVSWITCH_PRINT(device, ERROR,
4164 "%s: CCI not supported\n",
4165 __FUNCTION__);
4166 return -NVL_ERR_NOT_SUPPORTED;
4167 }
4168
4169 if (!cciCmisAccessTryLock(device, pParams->cageIndex))
4170 {
4171 return -NVL_ERR_STATE_IN_USE;
4172 }
4173
4174 retVal = cciCmisWrite(device, pParams->cageIndex, pParams->bank,
4175 pParams->page, pParams->address, pParams->count,
4176 pParams->data);
4177
4178 if (!pParams->bSequenceLock)
4179 {
4180 cciCmisAccessReleaseLock(device, pParams->cageIndex);
4181 }
4182
4183 return retVal;
4184 }
4185
4186 static NvlStatus
_nvswitch_ctrl_cci_cage_bezel_marking(nvswitch_device * device,NVSWITCH_CCI_CMIS_CAGE_BEZEL_MARKING_PARAMS * pParams)4187 _nvswitch_ctrl_cci_cage_bezel_marking
4188 (
4189 nvswitch_device *device,
4190 NVSWITCH_CCI_CMIS_CAGE_BEZEL_MARKING_PARAMS *pParams
4191 )
4192 {
4193 if (device->pCci == NULL)
4194 {
4195 NVSWITCH_PRINT(device, ERROR,
4196 "%s: CCI not supported\n",
4197 __FUNCTION__);
4198 return -NVL_ERR_NOT_SUPPORTED;
4199 }
4200
4201 return cciCmisCageBezelMarking(device, pParams->cageIndex, pParams->bezelMarking);
4202 }
4203
4204 static NvlStatus
_nvswitch_ctrl_get_soe_heartbeat(nvswitch_device * device,NVSWITCH_GET_SOE_HEARTBEAT_PARAMS * pParams)4205 _nvswitch_ctrl_get_soe_heartbeat
4206 (
4207 nvswitch_device *device,
4208 NVSWITCH_GET_SOE_HEARTBEAT_PARAMS *pParams
4209 )
4210 {
4211 return device->hal.nvswitch_ctrl_get_soe_heartbeat(device, pParams);
4212 }
4213
4214 static NvlStatus
_nvswitch_ctrl_set_continuous_ali(nvswitch_device * device,NVSWITCH_SET_CONTINUOUS_ALI_PARAMS * pParams)4215 _nvswitch_ctrl_set_continuous_ali
4216 (
4217 nvswitch_device *device,
4218 NVSWITCH_SET_CONTINUOUS_ALI_PARAMS *pParams
4219 )
4220 {
4221 device->bModeContinuousALI = pParams->bEnable;
4222 NVSWITCH_PRINT(device, INFO,
4223 "%s: Continuous ALI 0x%x\n",
4224 __FUNCTION__, device->bModeContinuousALI);
4225 return NVL_SUCCESS;
4226 }
4227
4228 static NvlStatus
_nvswitch_ctrl_request_ali(nvswitch_device * device,NVSWITCH_REQUEST_ALI_PARAMS * pParams)4229 _nvswitch_ctrl_request_ali
4230 (
4231 nvswitch_device *device,
4232 NVSWITCH_REQUEST_ALI_PARAMS *pParams
4233 )
4234 {
4235 nvlink_link *link;
4236 NvU64 linkStateTl;
4237 NvU64 enabledLinkMask;
4238 NvU8 linkId;
4239
4240 if (device->bModeContinuousALI)
4241 {
4242 return -NVL_ERR_INVALID_STATE;
4243 }
4244
4245 // Only process enabled links
4246 enabledLinkMask = nvswitch_get_enabled_link_mask(device);
4247 pParams->linkMaskTrain &= enabledLinkMask;
4248
4249 NVSWITCH_PRINT(device, INFO,
4250 "%s: ALI requested for links 0x%llx\n",
4251 __FUNCTION__, pParams->linkMaskTrain);
4252
4253 // Handle access links
4254 FOR_EACH_INDEX_IN_MASK(64, linkId, pParams->linkMaskTrain)
4255 {
4256 // Only directly launch ALI on non-CCI managed links
4257 if (cciIsLinkManaged(device, linkId))
4258 {
4259 continue;
4260 }
4261
4262 link = nvswitch_get_link(device, linkId);
4263 if ((link == NULL) ||
4264 !NVSWITCH_IS_LINK_ENG_VALID(device, linkId, NVLIPT_LNK) ||
4265 (linkId >= NVSWITCH_NVLINK_MAX_LINKS) ||
4266 (device->hal.nvswitch_corelib_get_tl_link_mode(link, &linkStateTl) != NVL_SUCCESS))
4267 {
4268 continue;
4269 }
4270
4271 if (linkStateTl == NVLINK_LINKSTATE_ACTIVE_PENDING)
4272 {
4273 continue;
4274 }
4275
4276 // Forcibly reset and re-train access links
4277 device->hal.nvswitch_reset_and_drain_links(device,
4278 NVBIT64(linkId), NV_TRUE);
4279 }
4280 FOR_EACH_INDEX_IN_MASK_END;
4281
4282 // Ask CCI to handle trunk links
4283 nvswitch_ctrl_cci_request_ali(device, pParams);
4284
4285 return NVL_SUCCESS;
4286 }
4287
4288 static NvlStatus
_nvswitch_ctrl_get_inforom_nvlink_max_correctable_error_rate(nvswitch_device * device,NVSWITCH_GET_NVLINK_MAX_CORRECTABLE_ERROR_RATES_PARAMS * params)4289 _nvswitch_ctrl_get_inforom_nvlink_max_correctable_error_rate
4290 (
4291 nvswitch_device *device,
4292 NVSWITCH_GET_NVLINK_MAX_CORRECTABLE_ERROR_RATES_PARAMS *params
4293 )
4294 {
4295 return nvswitch_inforom_nvlink_get_max_correctable_error_rate(device, params);
4296 }
4297
4298 static NvlStatus
_nvswitch_ctrl_get_inforom_nvlink_errors(nvswitch_device * device,NVSWITCH_GET_NVLINK_ERROR_COUNTS_PARAMS * params)4299 _nvswitch_ctrl_get_inforom_nvlink_errors
4300 (
4301 nvswitch_device *device,
4302 NVSWITCH_GET_NVLINK_ERROR_COUNTS_PARAMS *params
4303 )
4304 {
4305 return nvswitch_inforom_nvlink_get_errors(device, params);
4306 }
4307
4308 static NvlStatus
_nvswitch_ctrl_get_inforom_ecc_errors(nvswitch_device * device,NVSWITCH_GET_ECC_ERROR_COUNTS_PARAMS * params)4309 _nvswitch_ctrl_get_inforom_ecc_errors
4310 (
4311 nvswitch_device *device,
4312 NVSWITCH_GET_ECC_ERROR_COUNTS_PARAMS *params
4313 )
4314 {
4315 return nvswitch_inforom_ecc_get_errors(device, params);
4316 }
4317
4318 static NvlStatus
_nvswitch_ctrl_get_inforom_bbx_sxid(nvswitch_device * device,NVSWITCH_GET_SXIDS_PARAMS * params)4319 _nvswitch_ctrl_get_inforom_bbx_sxid
4320 (
4321 nvswitch_device *device,
4322 NVSWITCH_GET_SXIDS_PARAMS *params
4323 )
4324 {
4325 return nvswitch_inforom_bbx_get_sxid(device, params);
4326 }
4327
4328 static NvlStatus
_nvswitch_ctrl_get_inforom_bbx_sys_info(nvswitch_device * device,NVSWITCH_GET_SYS_INFO_PARAMS * params)4329 _nvswitch_ctrl_get_inforom_bbx_sys_info
4330 (
4331 nvswitch_device *device,
4332 NVSWITCH_GET_SYS_INFO_PARAMS *params
4333 )
4334 {
4335 return nvswitch_inforom_bbx_get_data(device, RM_SOE_IFR_BBX_GET_SYS_INFO, (void *)params);
4336 }
4337
4338 static NvlStatus
_nvswitch_ctrl_get_inforom_bbx_time_info(nvswitch_device * device,NVSWITCH_GET_TIME_INFO_PARAMS * params)4339 _nvswitch_ctrl_get_inforom_bbx_time_info
4340 (
4341 nvswitch_device *device,
4342 NVSWITCH_GET_TIME_INFO_PARAMS *params
4343 )
4344 {
4345 return nvswitch_inforom_bbx_get_data(device, RM_SOE_IFR_BBX_GET_TIME_INFO, (void *)params);
4346 }
4347
4348 static NvlStatus
_nvswitch_ctrl_get_inforom_bbx_temp_data(nvswitch_device * device,NVSWITCH_GET_TEMP_DATA_PARAMS * params)4349 _nvswitch_ctrl_get_inforom_bbx_temp_data
4350 (
4351 nvswitch_device *device,
4352 NVSWITCH_GET_TEMP_DATA_PARAMS *params
4353 )
4354 {
4355 return nvswitch_inforom_bbx_get_data(device, RM_SOE_IFR_BBX_GET_TEMP_DATA, (void *)params);
4356 }
4357
4358 static NvlStatus
_nvswitch_ctrl_get_inforom_bbx_temp_samples(nvswitch_device * device,NVSWITCH_GET_TEMP_SAMPLES_PARAMS * params)4359 _nvswitch_ctrl_get_inforom_bbx_temp_samples
4360 (
4361 nvswitch_device *device,
4362 NVSWITCH_GET_TEMP_SAMPLES_PARAMS *params
4363 )
4364 {
4365 return nvswitch_inforom_bbx_get_data(device, RM_SOE_IFR_BBX_GET_TEMP_SAMPLES, (void *)params);
4366 }
4367
4368 static NvlStatus
_nvswitch_ctrl_get_nvlink_lp_counters(nvswitch_device * device,NVSWITCH_GET_NVLINK_LP_COUNTERS_PARAMS * params)4369 _nvswitch_ctrl_get_nvlink_lp_counters
4370 (
4371 nvswitch_device *device,
4372 NVSWITCH_GET_NVLINK_LP_COUNTERS_PARAMS *params
4373 )
4374 {
4375 return device->hal.nvswitch_ctrl_get_nvlink_lp_counters(device, params);
4376 }
4377
4378 static NvlStatus
_nvswitch_ctrl_get_sw_info(nvswitch_device * device,NVSWITCH_GET_SW_INFO_PARAMS * params)4379 _nvswitch_ctrl_get_sw_info
4380 (
4381 nvswitch_device *device,
4382 NVSWITCH_GET_SW_INFO_PARAMS *params
4383 )
4384 {
4385 return device->hal.nvswitch_ctrl_get_sw_info(device, params);
4386 }
4387
4388 static NvlStatus
_nvswitch_lib_validate_privileged_ctrl(void * osPrivate,NvU64 flags)4389 _nvswitch_lib_validate_privileged_ctrl
4390 (
4391 void *osPrivate,
4392 NvU64 flags
4393 )
4394 {
4395 if (flags & NVSWITCH_DEV_CMD_CHECK_ADMIN)
4396 {
4397 if (nvswitch_os_is_admin())
4398 {
4399 return NVL_SUCCESS;
4400 }
4401 }
4402
4403 if (flags & NVSWITCH_DEV_CMD_CHECK_FM)
4404 {
4405 if (nvswitch_os_is_fabric_manager(osPrivate))
4406 {
4407 return NVL_SUCCESS;
4408 }
4409 }
4410
4411 return -NVL_ERR_INSUFFICIENT_PERMISSIONS;
4412 }
4413
4414 /*
4415 * @Brief : Copy the data from the persistant or nonpersistant list
4416 *
4417 * @Description :
4418 *
4419 * @param[in] device NvSwitch device to contain this link
4420 * @param[out] data Destination Data
4421 * @param[in] linkId link number of the link
4422 * @param[out] dataSize Size of data copied
4423 *
4424 * @returns NVL_SUCCESS if action succeeded,
4425 * -NVL_NOT_FOUND if link doesnt have data
4426 */
4427 NvlStatus
nvswitch_inband_read_data(nvswitch_device * device,NvU8 * dest,NvU32 linkId,NvU32 * dataSize)4428 nvswitch_inband_read_data
4429 (
4430 nvswitch_device *device,
4431 NvU8 *dest,
4432 NvU32 linkId,
4433 NvU32 *dataSize
4434 )
4435 {
4436 nvswitch_inband_data_list *curr = NULL;
4437 NVListRec *list;
4438
4439 if (nvListIsEmpty(&device->link[linkId].inbandData.persistent_list) &&
4440 nvListIsEmpty(&device->link[linkId].inbandData.nonpersistent_list))
4441 {
4442 NVSWITCH_PRINT(device, ERROR, "%s: LinkId %d doesnt have any data to send\n",
4443 __FUNCTION__, linkId);
4444 *dataSize = 0;
4445 return -NVL_NOT_FOUND;
4446 }
4447
4448 list = nvListIsEmpty(&device->link[linkId].inbandData.persistent_list) ?
4449 &device->link[linkId].inbandData.nonpersistent_list :
4450 &device->link[linkId].inbandData.persistent_list;
4451
4452 nvListForEachEntry(curr, list, entry)
4453 {
4454 *dataSize = curr->dataSize;
4455 nvswitch_os_memcpy(dest, curr->data, curr->dataSize);
4456 nvListDel(&curr->entry);
4457 nvswitch_os_free(curr);
4458 break;
4459 }
4460
4461 return NVL_SUCCESS;
4462 }
4463
4464 /*
4465 * @Brief : Returns NV_TRUE if the given inband msg
4466 * needs to go to persistant list
4467 *
4468 * @Description :
4469 *
4470 * @param[in] device NvSwitch device to contain this link
4471 * @param[in] msghdr Header to the message
4472 *
4473 */
4474
4475 static NvBool
nvswitch_is_message_persistent(nvswitch_device * device,nvlink_inband_msg_header_t * msghdr)4476 nvswitch_is_message_persistent
4477 (
4478 nvswitch_device *device,
4479 nvlink_inband_msg_header_t *msghdr
4480 )
4481 {
4482 // We expect only one message per received data
4483 switch(msghdr->type)
4484 {
4485 case NVLINK_INBAND_MSG_TYPE_MC_TEAM_RELEASE_REQ:
4486 return NV_TRUE;
4487 default:
4488 return NV_FALSE;
4489 }
4490 }
4491
4492 /*
4493 * @Brief : Moves the data into persistant or nonpersistant list
4494 *
4495 * @Description :
4496 *
4497 * @param[in] device NvSwitch device to contain this link
4498 * @param[in] linkId link number of the link
4499 *
4500 */
4501 void
nvswitch_filter_messages(nvswitch_device * device,NvU32 linkId)4502 nvswitch_filter_messages
4503 (
4504 nvswitch_device *device,
4505 NvU32 linkId
4506 )
4507 {
4508 NvlStatus status;
4509 nvlink_inband_msg_header_t *msghdr = NULL;
4510 nvswitch_inband_data_list *msg = device->link[linkId].inbandData.message;
4511 NvU8 *buffer = device->link[linkId].inbandData.message->data;
4512 NVSWITCH_DRIVER_FABRIC_STATE driver_fabric_state = 0;
4513 NvBool bSendNackOrDrop = NV_FALSE;
4514
4515 NVSWITCH_ASSERT(nvswitch_lib_read_fabric_state(device, NULL, NULL,
4516 &driver_fabric_state) == NVL_SUCCESS);
4517
4518 msghdr = (nvlink_inband_msg_header_t*)buffer;
4519
4520 if (nvswitch_is_message_persistent(device, msghdr))
4521 {
4522 if (nvListCount(&device->link[linkId].inbandData.persistent_list) <
4523 device->hal.nvswitch_get_max_persistent_message_count(device))
4524 {
4525 nvListAdd(&msg->entry, &device->link[linkId].inbandData.persistent_list);
4526 }
4527 else
4528 {
4529 bSendNackOrDrop = NV_TRUE;
4530 }
4531 }
4532 else
4533 {
4534 if (driver_fabric_state == NVSWITCH_DRIVER_FABRIC_STATE_CONFIGURED)
4535 {
4536 nvListAdd(&msg->entry,
4537 &device->link[linkId].inbandData.nonpersistent_list);
4538 }
4539 else
4540 {
4541 bSendNackOrDrop = NV_TRUE;
4542 }
4543 }
4544
4545 if (bSendNackOrDrop)
4546 {
4547 nvswitch_send_nack_or_drop(device, linkId, msghdr);
4548 nvswitch_os_free(msg);
4549 }
4550 else
4551 {
4552 status = nvswitch_lib_notify_client_events(device,
4553 NVSWITCH_DEVICE_EVENT_INBAND_DATA);
4554 if (status != NVL_SUCCESS)
4555 {
4556 NVSWITCH_PRINT(device, ERROR, "%s: Failed to notify INBAND_DATA event\n",
4557 __FUNCTION__);
4558 }
4559 }
4560
4561 device->link[linkId].inbandData.message = NULL;
4562 }
4563
4564 /*
4565 * @Brief : Constructs an NVS link struct with the given data
4566 *
4567 * @Description :
4568 *
4569 * @param[in] device NvSwitch device to contain this link
4570 * @param[in] link_num link number of the link
4571 * @param[out] link reference to store the created link into
4572 *
4573 * @returns NVL_SUCCESS if action succeeded,
4574 * -NVL_NO_MEM if memory allocation failed
4575 */
4576 NvlStatus
nvswitch_create_link(nvswitch_device * device,NvU32 link_number,nvlink_link ** link)4577 nvswitch_create_link
4578 (
4579 nvswitch_device *device,
4580 NvU32 link_number,
4581 nvlink_link **link
4582 )
4583 {
4584 NvlStatus retval = NVL_SUCCESS;
4585 nvlink_link *ret = NULL;
4586 LINK_INFO *link_info = NULL;
4587 NvU64 ac_coupled_mask;
4588
4589 NVSWITCH_ASSERT(nvswitch_get_num_links(device) <= NVSWITCH_MAX_NUM_LINKS);
4590
4591 ret = nvswitch_os_malloc(sizeof(*ret));
4592 if (NULL == ret)
4593 {
4594 NVSWITCH_PRINT(device, ERROR,
4595 "nvswitch_os_malloc during link creation failed!\n");
4596 retval = -NVL_NO_MEM;
4597 goto nvswitch_create_link_cleanup;
4598 }
4599 nvswitch_os_memset(ret, 0, sizeof(*ret));
4600
4601 link_info = nvswitch_os_malloc(sizeof(*link_info));
4602 if (NULL == link_info)
4603 {
4604 NVSWITCH_PRINT(device, ERROR,
4605 "nvswitch_os_malloc during link creation failed!\n");
4606 retval = -NVL_NO_MEM;
4607 goto nvswitch_create_link_cleanup;
4608 }
4609 nvswitch_os_memset(link_info, 0, sizeof(*link_info));
4610 nvswitch_os_snprintf(link_info->name, sizeof(link_info->name), NVSWITCH_LINK_NAME "%d", link_number);
4611
4612 ret->dev = device->nvlink_device;
4613 ret->linkName = link_info->name;
4614 ret->linkNumber = link_number;
4615 ret->state = NVLINK_LINKSTATE_OFF;
4616 ret->ac_coupled = NV_FALSE;
4617 ret->version = nvswitch_get_link_ip_version(device, link_number);
4618
4619 ac_coupled_mask = ((NvU64)device->regkeys.ac_coupled_mask2 << 32 |
4620 (NvU64)device->regkeys.ac_coupled_mask);
4621
4622 if (ac_coupled_mask)
4623 {
4624 if (ac_coupled_mask & NVBIT64(link_number))
4625 {
4626 ret->ac_coupled = NV_TRUE;
4627 }
4628 }
4629 else if (device->firmware.nvlink.link_config_found)
4630 {
4631 if (device->firmware.nvlink.link_ac_coupled_mask & NVBIT64(link_number))
4632 {
4633 ret->ac_coupled = NV_TRUE;
4634 }
4635 }
4636
4637 // Initialize NVLink corelib callbacks for switch
4638 nvswitch_get_link_handlers(&link_handlers);
4639
4640 ret->link_handlers = &link_handlers;
4641
4642 //
4643 // link_info is used to store private link information
4644 //
4645
4646 ret->link_info = link_info;
4647
4648 *link = ret;
4649
4650 return retval;
4651
4652 nvswitch_create_link_cleanup:
4653 if (NULL != ret)
4654 {
4655 nvswitch_os_free(ret);
4656 }
4657 if (NULL != link_info)
4658 {
4659 nvswitch_os_free(link_info);
4660 }
4661
4662 return retval;
4663 }
4664
4665 void
nvswitch_destroy_link(nvlink_link * link)4666 nvswitch_destroy_link
4667 (
4668 nvlink_link *link
4669 )
4670 {
4671 if (NULL != link->link_info)
4672 {
4673 nvswitch_os_free(link->link_info);
4674 }
4675
4676 nvswitch_os_free(link);
4677 }
4678
4679 NvU32
nvswitch_get_num_links(nvswitch_device * device)4680 nvswitch_get_num_links
4681 (
4682 nvswitch_device *device
4683 )
4684 {
4685 return device->hal.nvswitch_get_num_links(device);
4686 }
4687
4688 NvBool
nvswitch_is_link_valid(nvswitch_device * device,NvU32 link_id)4689 nvswitch_is_link_valid
4690 (
4691 nvswitch_device *device,
4692 NvU32 link_id
4693 )
4694 {
4695 return device->hal.nvswitch_is_link_valid(device, link_id);
4696 }
4697
4698 nvlink_link*
nvswitch_get_link(nvswitch_device * device,NvU8 link_id)4699 nvswitch_get_link(nvswitch_device *device, NvU8 link_id)
4700 {
4701 nvlink_link *link = NULL;
4702
4703 nvlink_lib_get_link(device->nvlink_device, link_id, &link);
4704
4705 return link;
4706 }
4707
4708 NvU64
nvswitch_get_enabled_link_mask(nvswitch_device * device)4709 nvswitch_get_enabled_link_mask
4710 (
4711 nvswitch_device *device
4712 )
4713 {
4714 NvU64 ret;
4715 nvlink_link *link;
4716 NvU32 link_num;
4717
4718 ret = 0x0;
4719
4720 for (link_num = 0; link_num < nvswitch_get_num_links(device); link_num++)
4721 {
4722 if (nvlink_lib_get_link(device->nvlink_device, link_num, &link) == NVL_SUCCESS)
4723 {
4724 ret |= NVBIT64(link_num);
4725 }
4726 }
4727
4728 return ret;
4729 }
4730
4731 void
nvswitch_set_fatal_error(nvswitch_device * device,NvBool device_fatal,NvU32 link_id)4732 nvswitch_set_fatal_error
4733 (
4734 nvswitch_device *device,
4735 NvBool device_fatal,
4736 NvU32 link_id
4737 )
4738 {
4739 device->hal.nvswitch_set_fatal_error(device, device_fatal, link_id);
4740 }
4741
4742 NvU32
nvswitch_get_swap_clk_default(nvswitch_device * device)4743 nvswitch_get_swap_clk_default
4744 (
4745 nvswitch_device *device
4746 )
4747 {
4748 return device->hal.nvswitch_get_swap_clk_default(device);
4749 }
4750
4751 NvU32
nvswitch_get_latency_sample_interval_msec(nvswitch_device * device)4752 nvswitch_get_latency_sample_interval_msec
4753 (
4754 nvswitch_device *device
4755 )
4756 {
4757 return device->hal.nvswitch_get_latency_sample_interval_msec(device);
4758 }
4759
4760 void
nvswitch_internal_latency_bin_log(nvswitch_device * device)4761 nvswitch_internal_latency_bin_log
4762 (
4763 nvswitch_device *device
4764 )
4765 {
4766 device->hal.nvswitch_internal_latency_bin_log(device);
4767 }
4768
4769 void
nvswitch_ecc_writeback_task(nvswitch_device * device)4770 nvswitch_ecc_writeback_task
4771 (
4772 nvswitch_device *device
4773 )
4774 {
4775 device->hal.nvswitch_ecc_writeback_task(device);
4776 }
4777
4778 void
nvswitch_monitor_thermal_alert(nvswitch_device * device)4779 nvswitch_monitor_thermal_alert
4780 (
4781 nvswitch_device *device
4782 )
4783 {
4784 device->hal.nvswitch_monitor_thermal_alert(device);
4785 }
4786
4787 void
nvswitch_hw_counter_shutdown(nvswitch_device * device)4788 nvswitch_hw_counter_shutdown
4789 (
4790 nvswitch_device *device
4791 )
4792 {
4793 device->hal.nvswitch_hw_counter_shutdown(device);
4794 }
4795
4796 NvlStatus
nvswitch_get_rom_info(nvswitch_device * device,NVSWITCH_EEPROM_TYPE * eeprom)4797 nvswitch_get_rom_info
4798 (
4799 nvswitch_device *device,
4800 NVSWITCH_EEPROM_TYPE *eeprom
4801 )
4802 {
4803 return device->hal.nvswitch_get_rom_info(device, eeprom);
4804 }
4805
4806 void
nvswitch_lib_enable_interrupts(nvswitch_device * device)4807 nvswitch_lib_enable_interrupts
4808 (
4809 nvswitch_device *device
4810 )
4811 {
4812 if (!NVSWITCH_IS_DEVICE_ACCESSIBLE(device))
4813 {
4814 NVSWITCH_ASSERT(0);
4815 return;
4816 }
4817
4818 device->hal.nvswitch_lib_enable_interrupts(device);
4819 }
4820
4821 void
nvswitch_lib_disable_interrupts(nvswitch_device * device)4822 nvswitch_lib_disable_interrupts
4823 (
4824 nvswitch_device *device
4825 )
4826 {
4827 if (!NVSWITCH_IS_DEVICE_ACCESSIBLE(device))
4828 {
4829 NVSWITCH_ASSERT(0);
4830 return;
4831 }
4832
4833 device->hal.nvswitch_lib_disable_interrupts(device);
4834 }
4835
4836 NvlStatus
nvswitch_lib_check_interrupts(nvswitch_device * device)4837 nvswitch_lib_check_interrupts
4838 (
4839 nvswitch_device *device
4840 )
4841 {
4842 if (!NVSWITCH_IS_DEVICE_INITIALIZED(device))
4843 {
4844 return -NVL_BAD_ARGS;
4845 }
4846
4847 return device->hal.nvswitch_lib_check_interrupts(device);
4848 }
4849
4850 NvlStatus
nvswitch_lib_service_interrupts(nvswitch_device * device)4851 nvswitch_lib_service_interrupts
4852 (
4853 nvswitch_device *device
4854 )
4855 {
4856 if (!NVSWITCH_IS_DEVICE_INITIALIZED(device))
4857 {
4858 return -NVL_BAD_ARGS;
4859 }
4860
4861 return device->hal.nvswitch_lib_service_interrupts(device);
4862 }
4863
4864 NvU64
nvswitch_hw_counter_read_counter(nvswitch_device * device)4865 nvswitch_hw_counter_read_counter
4866 (
4867 nvswitch_device *device
4868 )
4869 {
4870 return device->hal.nvswitch_hw_counter_read_counter(device);
4871 }
4872
4873 NvU32
nvswitch_get_link_ip_version(nvswitch_device * device,NvU32 link_id)4874 nvswitch_get_link_ip_version
4875 (
4876 nvswitch_device *device,
4877 NvU32 link_id
4878 )
4879 {
4880 return device->hal.nvswitch_get_link_ip_version(device, link_id);
4881 }
4882
4883 NvU32
nvswitch_reg_read_32(nvswitch_device * device,NvU32 offset)4884 nvswitch_reg_read_32
4885 (
4886 nvswitch_device *device,
4887 NvU32 offset
4888 )
4889 {
4890 NvU32 val;
4891
4892 if (device->nvlink_device->pciInfo.bars[0].pBar == NULL)
4893 {
4894 NVSWITCH_PRINT(device, ERROR,
4895 "register read failed at offset 0x%x\n", offset);
4896
4897 return 0xFFFFFFFF;
4898 }
4899
4900 val = nvswitch_os_mem_read32((NvU8 *)device->nvlink_device->pciInfo.bars[0].pBar + offset);
4901
4902 if ((val & 0xFFFF0000) == 0xBADF0000)
4903 {
4904 NvU32 boot_0;
4905 NVSWITCH_PRINT(device, WARN,
4906 "Potential IO failure reading 0x%x (0x%x)\n", offset, val);
4907 boot_0 = nvswitch_os_mem_read32((NvU8 *)device->nvlink_device->pciInfo.bars[0].pBar + 0x0);
4908
4909 if ((boot_0 & 0xFFFF0000) == 0xBADF0000)
4910 {
4911 NVSWITCH_PRINT_SXID(device, NVSWITCH_ERR_HW_HOST_IO_FAILURE,
4912 "IO failure\n");
4913 NVSWITCH_PRINT(device, ERROR,
4914 "IO failure reading 0x%x (0x%x)\n", offset, val);
4915 }
4916 }
4917
4918 #ifdef _VERBOSE_REG_ACCESS
4919 NVSWITCH_PRINT(device, SETUP,
4920 "NVSWITCH read 0x%6x+%6x = 0x%08x\n",
4921 device->nvlink_device->pciInfo.bars[0].baseAddr, offset, val);
4922 #endif
4923
4924 return val;
4925 }
4926
4927 void
nvswitch_reg_write_32(nvswitch_device * device,NvU32 offset,NvU32 data)4928 nvswitch_reg_write_32
4929 (
4930 nvswitch_device *device,
4931 NvU32 offset,
4932 NvU32 data
4933 )
4934 {
4935 if (device->nvlink_device->pciInfo.bars[0].pBar == NULL)
4936 {
4937 NVSWITCH_PRINT(device, ERROR,
4938 "register write failed at offset 0x%x\n", offset);
4939
4940 return;
4941 }
4942
4943 #ifdef _VERBOSE_REG_ACCESS
4944 NVSWITCH_PRINT(device, SETUP,
4945 "NVSWITCH write 0x%6x+%6x = 0x%08x\n",
4946 device->nvlink_device->pciInfo.bars[0].baseAddr, offset, data);
4947 #endif
4948
4949 // Write the register
4950 nvswitch_os_mem_write32((NvU8 *)device->nvlink_device->pciInfo.bars[0].pBar + offset, data);
4951
4952 return;
4953 }
4954
4955 NvU64
nvswitch_read_64bit_counter(nvswitch_device * device,NvU32 lo_offset,NvU32 hi_offset)4956 nvswitch_read_64bit_counter
4957 (
4958 nvswitch_device *device,
4959 NvU32 lo_offset,
4960 NvU32 hi_offset
4961 )
4962 {
4963 NvU32 hi0;
4964 NvU32 hi1;
4965 NvU32 lo;
4966
4967 hi0 = nvswitch_reg_read_32(device, hi_offset);
4968 do
4969 {
4970 hi1 = hi0;
4971 lo = nvswitch_reg_read_32(device, lo_offset);
4972 hi0 = nvswitch_reg_read_32(device, hi_offset);
4973 } while (hi0 != hi1);
4974
4975 return (lo | ((NvU64)hi0 << 32));
4976 }
4977
4978 NvlStatus
nvswitch_validate_pll_config(nvswitch_device * device,NVSWITCH_PLL_INFO * switch_pll,NVSWITCH_PLL_LIMITS default_pll_limits)4979 nvswitch_validate_pll_config
4980 (
4981 nvswitch_device *device,
4982 NVSWITCH_PLL_INFO *switch_pll,
4983 NVSWITCH_PLL_LIMITS default_pll_limits
4984 )
4985 {
4986 NvU32 update_rate_khz;
4987 NvU32 vco_freq_khz;
4988 NVSWITCH_PLL_LIMITS pll_limits;
4989
4990 NVSWITCH_PRINT(device, SETUP,
4991 "%s: Validating PLL: %dkHz * %d / (%d * %d * (1 << %d))\n",
4992 __FUNCTION__,
4993 switch_pll->src_freq_khz,
4994 switch_pll->N,
4995 switch_pll->M,
4996 switch_pll->PL,
4997 switch_pll->dist_mode);
4998
4999 //
5000 // These parameters could come from schmoo'ing API, settings file or a ROM.
5001 // For now, hard code with POR.
5002 //
5003 if (device->firmware.firmware_size > 0 &&
5004 device->firmware.clocks.clocks_found &&
5005 device->firmware.clocks.sys_pll.valid)
5006 {
5007 pll_limits = device->firmware.clocks.sys_pll;
5008 }
5009 else
5010 {
5011 pll_limits = default_pll_limits;
5012 }
5013
5014 NVSWITCH_ASSERT(switch_pll->M != 0);
5015 NVSWITCH_ASSERT(switch_pll->PL != 0);
5016
5017 if ((switch_pll->src_freq_khz < pll_limits.ref_min_mhz * 1000) ||
5018 (switch_pll->src_freq_khz > pll_limits.ref_max_mhz * 1000))
5019 {
5020 NVSWITCH_PRINT(device, ERROR,
5021 "%s: ERROR: Ref(%d) out-of-range\n",
5022 __FUNCTION__,
5023 switch_pll->src_freq_khz);
5024 return -NVL_ERR_INVALID_STATE;
5025 }
5026
5027 if ((switch_pll->M < pll_limits.m_min) ||
5028 (switch_pll->M > pll_limits.m_max))
5029 {
5030 NVSWITCH_PRINT(device, ERROR,
5031 "%s: ERROR: M(%d) out-of-range\n",
5032 __FUNCTION__,
5033 switch_pll->M);
5034 return -NVL_ERR_INVALID_STATE;
5035 }
5036
5037 if ((switch_pll->N < pll_limits.n_min) ||
5038 (switch_pll->N > pll_limits.n_max))
5039 {
5040 NVSWITCH_PRINT(device, ERROR,
5041 "%s: ERROR: N(%d) out-of-range\n",
5042 __FUNCTION__,
5043 switch_pll->N);
5044 return -NVL_ERR_INVALID_STATE;
5045 }
5046
5047 if ((switch_pll->PL < pll_limits.pl_min) ||
5048 (switch_pll->PL > pll_limits.pl_max))
5049 {
5050 NVSWITCH_PRINT(device, ERROR,
5051 "%s: ERROR: PL(%d) out-of-range\n",
5052 __FUNCTION__,
5053 switch_pll->PL);
5054 return -NVL_ERR_INVALID_STATE;
5055 }
5056
5057 vco_freq_khz = switch_pll->src_freq_khz * switch_pll->N
5058 / switch_pll->M;
5059 if ((vco_freq_khz < pll_limits.vco_min_mhz * 1000) ||
5060 (vco_freq_khz > pll_limits.vco_max_mhz * 1000))
5061 {
5062 NVSWITCH_PRINT(device, ERROR,
5063 "%s: ERROR: VCO(%d) freq out-of-range\n",
5064 __FUNCTION__,
5065 vco_freq_khz);
5066 return -NVL_ERR_INVALID_STATE;
5067 }
5068
5069 update_rate_khz = switch_pll->src_freq_khz / switch_pll->M;
5070 if ((update_rate_khz < pll_limits.update_min_mhz * 1000) ||
5071 (update_rate_khz > pll_limits.update_max_mhz * 1000))
5072 {
5073 NVSWITCH_PRINT(device, ERROR,
5074 "%s: ERROR: update rate(%d) out-of-range\n",
5075 __FUNCTION__,
5076 update_rate_khz);
5077 return -NVL_ERR_INVALID_STATE;
5078 }
5079
5080 switch_pll->vco_freq_khz = vco_freq_khz;
5081
5082 switch_pll->freq_khz =
5083 switch_pll->src_freq_khz * switch_pll->N /
5084 (switch_pll->M * switch_pll->PL * (1 << switch_pll->dist_mode));
5085
5086 NVSWITCH_PRINT(device, SETUP,
5087 "%s: Validated PLL: %dkHz * %d / (%d * %d * (1 << %d)) = %dkHz\n",
5088 __FUNCTION__,
5089 switch_pll->src_freq_khz,
5090 switch_pll->N,
5091 switch_pll->M,
5092 switch_pll->PL,
5093 switch_pll->dist_mode,
5094 switch_pll->freq_khz);
5095
5096 return NVL_SUCCESS;
5097 }
5098
5099 NvlStatus
nvswitch_init_pll_config(nvswitch_device * device)5100 nvswitch_init_pll_config
5101 (
5102 nvswitch_device *device
5103 )
5104 {
5105 return device->hal.nvswitch_init_pll_config(device);
5106 }
5107
5108 NvlStatus
nvswitch_init_pll(nvswitch_device * device)5109 nvswitch_init_pll
5110 (
5111 nvswitch_device *device
5112 )
5113 {
5114 return device->hal.nvswitch_init_pll(device);
5115 }
5116
5117 void
nvswitch_init_clock_gating(nvswitch_device * device)5118 nvswitch_init_clock_gating
5119 (
5120 nvswitch_device *device
5121 )
5122 {
5123 device->hal.nvswitch_init_clock_gating(device);
5124 }
5125
5126 void
nvswitch_lib_get_uuid(nvswitch_device * device,NvUuid * uuid)5127 nvswitch_lib_get_uuid
5128 (
5129 nvswitch_device *device,
5130 NvUuid *uuid
5131 )
5132 {
5133 if (!NVSWITCH_IS_DEVICE_INITIALIZED(device) || (uuid == NULL))
5134 {
5135 return;
5136 }
5137
5138 nvswitch_os_memcpy(uuid, &device->uuid, sizeof(device->uuid));
5139 }
5140
5141 NvlStatus
nvswitch_lib_get_physid(nvswitch_device * device,NvU32 * phys_id)5142 nvswitch_lib_get_physid
5143 (
5144 nvswitch_device *device,
5145 NvU32 *phys_id
5146 )
5147 {
5148 NVSWITCH_GET_INFO get_info;
5149 NvlStatus ret;
5150
5151 if (phys_id == NULL || !NVSWITCH_IS_DEVICE_ACCESSIBLE(device))
5152 {
5153 return -NVL_BAD_ARGS;
5154 }
5155
5156 get_info.count=1;
5157 get_info.index[0] = NVSWITCH_GET_INFO_INDEX_PHYSICAL_ID;
5158
5159 ret = _nvswitch_ctrl_get_info(device, &get_info);
5160 if (ret != NVL_SUCCESS)
5161 {
5162 NVSWITCH_PRINT(device, ERROR,
5163 "Failed to get physical ID\n");
5164 return ret;
5165 }
5166
5167 *phys_id = get_info.info[0];
5168
5169 return NVL_SUCCESS;
5170 }
5171
5172 void
nvswitch_i2c_set_hw_speed_mode(nvswitch_device * device,NvU32 port,NvU32 speedMode)5173 nvswitch_i2c_set_hw_speed_mode
5174 (
5175 nvswitch_device *device,
5176 NvU32 port,
5177 NvU32 speedMode
5178 )
5179 {
5180 device->hal.nvswitch_i2c_set_hw_speed_mode(device, port, speedMode);
5181 return;
5182 }
5183
5184 void
nvswitch_lib_smbpbi_log_sxid(nvswitch_device * device,NvU32 sxid,const char * pFormat,...)5185 nvswitch_lib_smbpbi_log_sxid
5186 (
5187 nvswitch_device *device,
5188 NvU32 sxid,
5189 const char *pFormat,
5190 ...
5191 )
5192 {
5193 va_list arglist;
5194 int msglen;
5195 char string[RM_SOE_SMBPBI_CMD_LOG_MESSAGE_MAX_STRING + 1];
5196
5197 nvswitch_os_memset(string, 0, (NvLength)sizeof(string));
5198
5199 va_start(arglist, pFormat);
5200 msglen = nvswitch_os_vsnprintf(string, sizeof(string), pFormat, arglist);
5201 va_end(arglist);
5202
5203 if (!(msglen < 0))
5204 {
5205 //
5206 // HALs will know that the string is being truncated by seeing that the
5207 // last byte in the buffer is not nul.
5208 //
5209 msglen = NV_MIN(msglen + 1, (int)RM_SOE_SMBPBI_CMD_LOG_MESSAGE_MAX_STRING);
5210 device->hal.nvswitch_smbpbi_log_message(device, sxid, msglen, (NvU8 *) string);
5211 }
5212 }
5213
5214 NvlStatus
nvswitch_set_minion_initialized(nvswitch_device * device,NvU32 idx_minion,NvBool initialized)5215 nvswitch_set_minion_initialized
5216 (
5217 nvswitch_device *device,
5218 NvU32 idx_minion,
5219 NvBool initialized
5220 )
5221 {
5222 return device->hal.nvswitch_set_minion_initialized(device, idx_minion, initialized);
5223 }
5224
5225 NvBool
nvswitch_is_minion_initialized(nvswitch_device * device,NvU32 idx_minion)5226 nvswitch_is_minion_initialized
5227 (
5228 nvswitch_device *device,
5229 NvU32 idx_minion
5230 )
5231 {
5232 return device->hal.nvswitch_is_minion_initialized(device, idx_minion);
5233 }
5234
5235 NvlStatus
nvswitch_device_discovery(nvswitch_device * device,NvU32 discovery_offset)5236 nvswitch_device_discovery
5237 (
5238 nvswitch_device *device,
5239 NvU32 discovery_offset
5240 )
5241 {
5242 return device->hal.nvswitch_device_discovery(device, discovery_offset);
5243 }
5244
5245 void
nvswitch_filter_discovery(nvswitch_device * device)5246 nvswitch_filter_discovery
5247 (
5248 nvswitch_device *device
5249 )
5250 {
5251 device->hal.nvswitch_filter_discovery(device);
5252 }
5253
5254 NvlStatus
nvswitch_process_discovery(nvswitch_device * device)5255 nvswitch_process_discovery
5256 (
5257 nvswitch_device *device
5258 )
5259 {
5260 return device->hal.nvswitch_process_discovery(device);
5261 }
5262
5263 NvlStatus
nvswitch_init_minion(nvswitch_device * device)5264 nvswitch_init_minion
5265 (
5266 nvswitch_device *device
5267 )
5268 {
5269 return device->hal.nvswitch_init_minion(device);
5270 }
5271
5272 NvU32
nvswitch_get_link_eng_inst(nvswitch_device * device,NvU32 link_id,NVSWITCH_ENGINE_ID eng_id)5273 nvswitch_get_link_eng_inst
5274 (
5275 nvswitch_device *device,
5276 NvU32 link_id,
5277 NVSWITCH_ENGINE_ID eng_id
5278 )
5279 {
5280 return device->hal.nvswitch_get_link_eng_inst(device, link_id, eng_id);
5281 }
5282
5283 void *
nvswitch_alloc_chipdevice(nvswitch_device * device)5284 nvswitch_alloc_chipdevice
5285 (
5286 nvswitch_device *device
5287 )
5288 {
5289 return(device->hal.nvswitch_alloc_chipdevice(device));
5290 }
5291
5292 void
nvswitch_free_chipdevice(nvswitch_device * device)5293 nvswitch_free_chipdevice
5294 (
5295 nvswitch_device *device
5296 )
5297 {
5298 if (device->chip_device)
5299 {
5300 nvswitch_os_free(device->chip_device);
5301 device->chip_device = NULL;
5302 }
5303 }
5304
5305 NvlStatus
nvswitch_init_thermal(nvswitch_device * device)5306 nvswitch_init_thermal
5307 (
5308 nvswitch_device *device
5309 )
5310 {
5311 return(device->hal.nvswitch_init_thermal(device));
5312 }
5313
5314 NvU32
nvswitch_read_physical_id(nvswitch_device * device)5315 nvswitch_read_physical_id
5316 (
5317 nvswitch_device *device
5318 )
5319 {
5320 return(device->hal.nvswitch_read_physical_id(device));
5321 }
5322
5323 NvU32
nvswitch_get_caps_nvlink_version(nvswitch_device * device)5324 nvswitch_get_caps_nvlink_version
5325 (
5326 nvswitch_device *device
5327 )
5328 {
5329 return(device->hal.nvswitch_get_caps_nvlink_version(device));
5330 }
5331
5332 void
nvswitch_initialize_interrupt_tree(nvswitch_device * device)5333 nvswitch_initialize_interrupt_tree
5334 (
5335 nvswitch_device *device
5336 )
5337 {
5338 device->hal.nvswitch_initialize_interrupt_tree(device);
5339 }
5340
5341 void
nvswitch_init_dlpl_interrupts(nvlink_link * link)5342 nvswitch_init_dlpl_interrupts
5343 (
5344 nvlink_link *link
5345 )
5346 {
5347 nvswitch_device *device = link->dev->pDevInfo;
5348
5349 device->hal.nvswitch_init_dlpl_interrupts(link);
5350 }
5351
5352 NvlStatus
nvswitch_initialize_pmgr(nvswitch_device * device)5353 nvswitch_initialize_pmgr
5354 (
5355 nvswitch_device *device
5356 )
5357 {
5358 return(device->hal.nvswitch_initialize_pmgr(device));
5359 }
5360
5361 NvlStatus
nvswitch_initialize_ip_wrappers(nvswitch_device * device)5362 nvswitch_initialize_ip_wrappers
5363 (
5364 nvswitch_device *device
5365 )
5366 {
5367 return(device->hal.nvswitch_initialize_ip_wrappers(device));
5368 }
5369
5370 NvlStatus
nvswitch_initialize_route(nvswitch_device * device)5371 nvswitch_initialize_route
5372 (
5373 nvswitch_device *device
5374 )
5375 {
5376 return(device->hal.nvswitch_initialize_route(device));
5377 }
5378
5379 void
nvswitch_soe_unregister_events(nvswitch_device * device)5380 nvswitch_soe_unregister_events
5381 (
5382 nvswitch_device *device
5383 )
5384 {
5385 device->hal.nvswitch_soe_unregister_events(device);
5386 }
5387
5388 NvlStatus
nvswitch_soe_register_event_callbacks(nvswitch_device * device)5389 nvswitch_soe_register_event_callbacks
5390 (
5391 nvswitch_device *device
5392 )
5393 {
5394 return device->hal.nvswitch_soe_register_event_callbacks(device);
5395 }
5396
5397 NVSWITCH_BIOS_NVLINK_CONFIG *
nvswitch_get_bios_nvlink_config(nvswitch_device * device)5398 nvswitch_get_bios_nvlink_config
5399 (
5400 nvswitch_device *device
5401 )
5402 {
5403 return(device->hal.nvswitch_get_bios_nvlink_config(device));
5404 }
5405
5406 NvlStatus
nvswitch_minion_send_command(nvswitch_device * device,NvU32 linkNumber,NvU32 command,NvU32 scratch0)5407 nvswitch_minion_send_command
5408 (
5409 nvswitch_device *device,
5410 NvU32 linkNumber,
5411 NvU32 command,
5412 NvU32 scratch0
5413 )
5414 {
5415 return(device->hal.nvswitch_minion_send_command(device, linkNumber,
5416 command, scratch0));
5417 }
5418
5419 NvlStatus
nvswitch_init_nport(nvswitch_device * device)5420 nvswitch_init_nport
5421 (
5422 nvswitch_device *device
5423 )
5424 {
5425 return device->hal.nvswitch_init_nport(device);
5426 }
5427
5428 NvlStatus
nvswitch_init_nxbar(nvswitch_device * device)5429 nvswitch_init_nxbar
5430 (
5431 nvswitch_device *device
5432 )
5433 {
5434 return device->hal.nvswitch_init_nxbar(device);
5435 }
5436
5437 NvlStatus
nvswitch_clear_nport_rams(nvswitch_device * device)5438 nvswitch_clear_nport_rams
5439 (
5440 nvswitch_device *device
5441 )
5442 {
5443 return device->hal.nvswitch_clear_nport_rams(device);
5444 }
5445
5446 NvlStatus
nvswitch_pri_ring_init(nvswitch_device * device)5447 nvswitch_pri_ring_init
5448 (
5449 nvswitch_device *device
5450 )
5451 {
5452 return(device->hal.nvswitch_pri_ring_init(device));
5453 }
5454
5455 NvlStatus
nvswitch_get_remap_table_selector(nvswitch_device * device,NVSWITCH_TABLE_SELECT_REMAP table_selector,NvU32 * remap_ram_sel)5456 nvswitch_get_remap_table_selector
5457 (
5458 nvswitch_device *device,
5459 NVSWITCH_TABLE_SELECT_REMAP table_selector,
5460 NvU32 *remap_ram_sel
5461 )
5462 {
5463 return device->hal.nvswitch_get_remap_table_selector(device, table_selector, remap_ram_sel);
5464 }
5465
5466 NvU32
nvswitch_get_ingress_ram_size(nvswitch_device * device,NvU32 ingress_ram_selector)5467 nvswitch_get_ingress_ram_size
5468 (
5469 nvswitch_device *device,
5470 NvU32 ingress_ram_selector // NV_INGRESS_REQRSPMAPADDR_RAM_ADDRESS_*
5471 )
5472 {
5473 return device->hal.nvswitch_get_ingress_ram_size(device, ingress_ram_selector);
5474 }
5475
5476 NvlStatus
nvswitch_minion_get_dl_status(nvswitch_device * device,NvU32 linkId,NvU32 statusIdx,NvU32 statusArgs,NvU32 * statusData)5477 nvswitch_minion_get_dl_status
5478 (
5479 nvswitch_device *device,
5480 NvU32 linkId,
5481 NvU32 statusIdx,
5482 NvU32 statusArgs,
5483 NvU32 *statusData
5484 )
5485 {
5486 return device->hal.nvswitch_minion_get_dl_status(device, linkId, statusIdx, statusArgs, statusData);
5487 }
5488
5489 NvBool
nvswitch_is_i2c_supported(nvswitch_device * device)5490 nvswitch_is_i2c_supported
5491 (
5492 nvswitch_device *device
5493 )
5494 {
5495 return device->hal.nvswitch_is_i2c_supported(device);
5496 }
5497
5498
5499 NvlStatus
nvswitch_poll_sublink_state(nvswitch_device * device,nvlink_link * link)5500 nvswitch_poll_sublink_state
5501 (
5502 nvswitch_device *device,
5503 nvlink_link *link
5504 )
5505 {
5506 return device->hal.nvswitch_poll_sublink_state(device, link);
5507 }
5508
5509 void
nvswitch_setup_link_loopback_mode(nvswitch_device * device,NvU32 linkNumber)5510 nvswitch_setup_link_loopback_mode
5511 (
5512 nvswitch_device *device,
5513 NvU32 linkNumber
5514 )
5515 {
5516 device->hal.nvswitch_setup_link_loopback_mode(device, linkNumber);
5517 }
5518
5519 void
nvswitch_reset_persistent_link_hw_state(nvswitch_device * device,NvU32 linkNumber)5520 nvswitch_reset_persistent_link_hw_state
5521 (
5522 nvswitch_device *device,
5523 NvU32 linkNumber
5524 )
5525 {
5526 device->hal.nvswitch_reset_persistent_link_hw_state(device, linkNumber);
5527 }
5528
5529 void
nvswitch_store_topology_information(nvswitch_device * device,nvlink_link * link)5530 nvswitch_store_topology_information
5531 (
5532 nvswitch_device *device,
5533 nvlink_link *link
5534 )
5535 {
5536 device->hal.nvswitch_store_topology_information(device, link);
5537 }
5538
5539 void
nvswitch_init_lpwr_regs(nvlink_link * link)5540 nvswitch_init_lpwr_regs
5541 (
5542 nvlink_link *link
5543 )
5544 {
5545 nvswitch_device *device = link->dev->pDevInfo;
5546 device->hal.nvswitch_init_lpwr_regs(link);
5547 }
5548
5549 void
nvswitch_program_l1_scratch_reg(nvswitch_device * device,NvU32 linkNumber)5550 nvswitch_program_l1_scratch_reg
5551 (
5552 nvswitch_device *device,
5553 NvU32 linkNumber
5554 )
5555 {
5556 device->hal.nvswitch_program_l1_scratch_reg(device, linkNumber);
5557 }
5558
5559 NvlStatus
nvswitch_check_io_sanity(nvswitch_device * device)5560 nvswitch_check_io_sanity
5561 (
5562 nvswitch_device *device
5563 )
5564 {
5565 return device->hal.nvswitch_check_io_sanity(device);
5566 }
5567
5568 NvlStatus
nvswitch_launch_ALI(nvswitch_device * device)5569 nvswitch_launch_ALI
5570 (
5571 nvswitch_device *device
5572 )
5573 {
5574 return device->hal.nvswitch_launch_ALI(device);
5575 }
5576
5577 NvlStatus
nvswitch_set_training_mode(nvswitch_device * device)5578 nvswitch_set_training_mode
5579 (
5580 nvswitch_device *device
5581 )
5582 {
5583 return device->hal.nvswitch_set_training_mode(device);
5584 }
5585
5586 NvBool
nvswitch_is_link_in_reset(nvswitch_device * device,nvlink_link * link)5587 nvswitch_is_link_in_reset
5588 (
5589 nvswitch_device *device,
5590 nvlink_link *link
5591 )
5592 {
5593 return device->hal.nvswitch_is_link_in_reset(device, link);
5594 }
5595
5596 NvBool
nvswitch_i2c_is_device_access_allowed(nvswitch_device * device,NvU32 port,NvU8 addr,NvBool bIsRead)5597 nvswitch_i2c_is_device_access_allowed
5598 (
5599 nvswitch_device *device,
5600 NvU32 port,
5601 NvU8 addr,
5602 NvBool bIsRead
5603 )
5604 {
5605 return device->hal.nvswitch_i2c_is_device_access_allowed(device, port, addr, bIsRead);
5606 }
5607
5608 NvlStatus
nvswitch_parse_bios_image(nvswitch_device * device)5609 nvswitch_parse_bios_image
5610 (
5611 nvswitch_device *device
5612 )
5613 {
5614 return device->hal.nvswitch_parse_bios_image(device);
5615 }
5616
5617 void
nvswitch_init_buffer_ready(nvswitch_device * device,nvlink_link * link,NvBool bNportBufferReady)5618 nvswitch_init_buffer_ready
5619 (
5620 nvswitch_device *device,
5621 nvlink_link *link,
5622 NvBool bNportBufferReady
5623 )
5624 {
5625 device->hal.nvswitch_init_buffer_ready(device, link, bNportBufferReady);
5626 }
5627
5628 void
nvswitch_apply_recal_settings(nvswitch_device * device,nvlink_link * link)5629 nvswitch_apply_recal_settings
5630 (
5631 nvswitch_device *device,
5632 nvlink_link *link
5633 )
5634 {
5635 device->hal.nvswitch_apply_recal_settings(device, link);
5636 }
5637
5638 NvlStatus
nvswitch_launch_ALI_link_training(nvswitch_device * device,nvlink_link * link,NvBool bSync)5639 nvswitch_launch_ALI_link_training
5640 (
5641 nvswitch_device *device,
5642 nvlink_link *link,
5643 NvBool bSync
5644 )
5645 {
5646 return device->hal.nvswitch_launch_ALI_link_training(device, link, bSync);
5647 }
5648
5649 NvlStatus
nvswitch_reset_and_train_link(nvswitch_device * device,nvlink_link * link)5650 nvswitch_reset_and_train_link
5651 (
5652 nvswitch_device *device,
5653 nvlink_link *link
5654 )
5655 {
5656 return device->hal.nvswitch_reset_and_train_link(device, link);
5657 }
5658
5659 static NvlStatus
_nvswitch_ctrl_get_err_info(nvswitch_device * device,NVSWITCH_NVLINK_GET_ERR_INFO_PARAMS * ret)5660 _nvswitch_ctrl_get_err_info
5661 (
5662 nvswitch_device *device,
5663 NVSWITCH_NVLINK_GET_ERR_INFO_PARAMS *ret
5664 )
5665 {
5666 return device->hal.nvswitch_ctrl_get_err_info(device, ret);
5667 }
5668
5669 static NvlStatus
_nvswitch_ctrl_clear_counters(nvswitch_device * device,NVSWITCH_NVLINK_CLEAR_COUNTERS_PARAMS * ret)5670 _nvswitch_ctrl_clear_counters
5671 (
5672 nvswitch_device *device,
5673 NVSWITCH_NVLINK_CLEAR_COUNTERS_PARAMS *ret
5674 )
5675 {
5676 return device->hal.nvswitch_ctrl_clear_counters(device, ret);
5677 }
5678
5679 void
nvswitch_setup_link_system_registers(nvswitch_device * device,nvlink_link * link)5680 nvswitch_setup_link_system_registers
5681 (
5682 nvswitch_device *device,
5683 nvlink_link *link
5684 )
5685 {
5686 device->hal.nvswitch_setup_link_system_registers(device, link);
5687 }
5688
5689 void
nvswitch_load_link_disable_settings(nvswitch_device * device,nvlink_link * link)5690 nvswitch_load_link_disable_settings
5691 (
5692 nvswitch_device *device,
5693 nvlink_link *link
5694 )
5695 {
5696 device->hal.nvswitch_load_link_disable_settings(device, link);
5697 }
5698
5699 static NvlStatus
_nvswitch_ctrl_set_nvlink_error_threshold(nvswitch_device * device,NVSWITCH_SET_NVLINK_ERROR_THRESHOLD_PARAMS * pParams)5700 _nvswitch_ctrl_set_nvlink_error_threshold
5701 (
5702 nvswitch_device *device,
5703 NVSWITCH_SET_NVLINK_ERROR_THRESHOLD_PARAMS *pParams
5704 )
5705 {
5706 return device->hal.nvswitch_ctrl_set_nvlink_error_threshold(device, pParams);
5707 }
5708
5709 static NvlStatus
_nvswitch_ctrl_get_nvlink_error_threshold(nvswitch_device * device,NVSWITCH_GET_NVLINK_ERROR_THRESHOLD_PARAMS * pParams)5710 _nvswitch_ctrl_get_nvlink_error_threshold
5711 (
5712 nvswitch_device *device,
5713 NVSWITCH_GET_NVLINK_ERROR_THRESHOLD_PARAMS *pParams
5714 )
5715 {
5716 return device->hal.nvswitch_ctrl_get_nvlink_error_threshold(device, pParams);
5717 }
5718
5719 static NvlStatus
_nvswitch_ctrl_therm_read_voltage(nvswitch_device * device,NVSWITCH_CTRL_GET_VOLTAGE_PARAMS * info)5720 _nvswitch_ctrl_therm_read_voltage
5721 (
5722 nvswitch_device *device,
5723 NVSWITCH_CTRL_GET_VOLTAGE_PARAMS *info
5724 )
5725 {
5726 return device->hal.nvswitch_ctrl_therm_read_voltage(device, info);
5727 }
5728
5729 static NvlStatus
_nvswitch_ctrl_therm_read_power(nvswitch_device * device,NVSWITCH_GET_POWER_PARAMS * info)5730 _nvswitch_ctrl_therm_read_power
5731 (
5732 nvswitch_device *device,
5733 NVSWITCH_GET_POWER_PARAMS *info
5734 )
5735 {
5736 return device->hal.nvswitch_ctrl_therm_read_power(device, info);
5737 }
5738
5739 NvlStatus
nvswitch_get_board_id(nvswitch_device * device,NvU16 * boardId)5740 nvswitch_get_board_id
5741 (
5742 nvswitch_device *device,
5743 NvU16 *boardId
5744 )
5745 {
5746 return device->hal.nvswitch_get_board_id(device, boardId);
5747 }
5748
5749 NvlStatus
_nvswitch_ctrl_get_link_l1_capability(nvswitch_device * device,NVSWITCH_GET_NVLINK_L1_CAPABILITY_PARAMS * p)5750 _nvswitch_ctrl_get_link_l1_capability
5751 (
5752 nvswitch_device *device,
5753 NVSWITCH_GET_NVLINK_L1_CAPABILITY_PARAMS *p
5754 )
5755 {
5756 NvlStatus status;
5757 nvlink_link *link;
5758 NvU8 i;
5759
5760 if (p->linkMask == 0)
5761 {
5762 NVSWITCH_PRINT(device, ERROR, "%s: No links in linkMask\n", __FUNCTION__);
5763 return -NVL_BAD_ARGS;
5764 }
5765
5766 FOR_EACH_INDEX_IN_MASK(64, i, p->linkMask)
5767 {
5768 NvU32 linkNum;
5769
5770 NVSWITCH_ASSERT(i < NVSWITCH_LINK_COUNT(device));
5771
5772 link = nvswitch_get_link(device, i);
5773 if ((link == NULL) ||
5774 (i >= NVSWITCH_NVLINK_MAX_LINKS))
5775 {
5776 NVSWITCH_PRINT(device, ERROR, "%s: Invalid input link %d set in linkMask\n",
5777 __FUNCTION__, i);
5778 return -NVL_BAD_ARGS;
5779 }
5780
5781 linkNum = link->linkNumber;
5782
5783 status = device->hal.nvswitch_ctrl_get_link_l1_capability(device, linkNum, &(p->l1Capable[linkNum]));
5784 if (status != NVL_SUCCESS)
5785 {
5786 NVSWITCH_PRINT(device, ERROR, "%s: Failed to get l1 capability for link %d\n",
5787 __FUNCTION__, linkNum);
5788 return status;
5789 }
5790 }
5791 FOR_EACH_INDEX_IN_MASK_END;
5792
5793 return NVL_SUCCESS;
5794 }
5795
5796 NvlStatus
_nvswitch_ctrl_get_link_l1_threshold(nvswitch_device * device,NVSWITCH_GET_NVLINK_L1_THRESHOLD_PARAMS * p)5797 _nvswitch_ctrl_get_link_l1_threshold
5798 (
5799 nvswitch_device *device,
5800 NVSWITCH_GET_NVLINK_L1_THRESHOLD_PARAMS *p
5801 )
5802 {
5803 NvlStatus status;
5804 nvlink_link *link;
5805 NvBool isL1Capable;
5806 NvU8 i;
5807
5808 if (device->regkeys.enable_pm == NV_SWITCH_REGKEY_ENABLE_PM_NO)
5809 {
5810 NVSWITCH_PRINT(device, INFO, "%s: L1 Threshold is disabled\n", __FUNCTION__);
5811 return -NVL_ERR_NOT_SUPPORTED;
5812 }
5813
5814 if (p->linkMask == 0)
5815 {
5816 NVSWITCH_PRINT(device, ERROR, "%s: No links in linkMask\n", __FUNCTION__);
5817 return -NVL_BAD_ARGS;
5818 }
5819
5820 FOR_EACH_INDEX_IN_MASK(64, i, p->linkMask)
5821 {
5822 NvU32 linkNum;
5823
5824 NVSWITCH_ASSERT(i < NVSWITCH_LINK_COUNT(device));
5825
5826 link = nvswitch_get_link(device, i);
5827 if ((link == NULL) ||
5828 (i >= NVSWITCH_NVLINK_MAX_LINKS))
5829 {
5830 NVSWITCH_PRINT(device, ERROR, "%s: Invalid input link %d set in linkMask\n",
5831 __FUNCTION__, i);
5832 return -NVL_BAD_ARGS;
5833 }
5834
5835 linkNum = link->linkNumber;
5836
5837 status = device->hal.nvswitch_ctrl_get_link_l1_capability(device, linkNum, &isL1Capable);
5838 if (status != NVL_SUCCESS)
5839 {
5840 NVSWITCH_PRINT(device, ERROR, "%s: Failed to get l1 capability for link %d\n",
5841 __FUNCTION__, linkNum);
5842 return status;
5843 }
5844
5845 if (!isL1Capable)
5846 {
5847 NVSWITCH_PRINT(device, ERROR, "%s: Input link %d does not support L1\n",
5848 __FUNCTION__, i);
5849 return -NVL_ERR_NOT_SUPPORTED;
5850 }
5851
5852 // Get HAL
5853 status = device->hal.nvswitch_ctrl_get_link_l1_threshold(device, linkNum, &(p->l1Threshold[linkNum]));
5854 if (status != NVL_SUCCESS)
5855 {
5856 NVSWITCH_PRINT(device, ERROR, "%s: Failed to get L1 Threshold for link %d\n",
5857 __FUNCTION__, linkNum);
5858 return status;
5859 }
5860 }
5861 FOR_EACH_INDEX_IN_MASK_END;
5862
5863 return NVL_SUCCESS;
5864 }
5865
5866 NvlStatus
_nvswitch_ctrl_set_link_l1_threshold(nvswitch_device * device,NVSWITCH_SET_NVLINK_L1_THRESHOLD_PARAMS * p)5867 _nvswitch_ctrl_set_link_l1_threshold
5868 (
5869 nvswitch_device *device,
5870 NVSWITCH_SET_NVLINK_L1_THRESHOLD_PARAMS *p
5871 )
5872 {
5873 NvlStatus status;
5874 nvlink_link *link;
5875 NvBool isL1Capable;
5876 NvU8 i;
5877
5878 if (device->regkeys.enable_pm == NV_SWITCH_REGKEY_ENABLE_PM_NO)
5879 {
5880 NVSWITCH_PRINT(device, INFO, "%s: L1 Threshold is disabled\n", __FUNCTION__);
5881 return -NVL_ERR_NOT_SUPPORTED;
5882 }
5883
5884 if (p->linkMask == 0)
5885 {
5886 NVSWITCH_PRINT(device, ERROR, "%s: No links in linkMask\n", __FUNCTION__);
5887 return -NVL_BAD_ARGS;
5888 }
5889
5890 FOR_EACH_INDEX_IN_MASK(64, i, p->linkMask)
5891 {
5892 NvU32 linkNum;
5893 NvU32 l1Threshold;
5894
5895 NVSWITCH_ASSERT(i < NVSWITCH_LINK_COUNT(device));
5896
5897 link = nvswitch_get_link(device, i);
5898 if ((link == NULL) ||
5899 (i >= NVSWITCH_NVLINK_MAX_LINKS))
5900 {
5901 NVSWITCH_PRINT(device, ERROR, "%s: Invalid input link %d set in linkMask\n",
5902 __FUNCTION__, i);
5903 return -NVL_BAD_ARGS;
5904 }
5905
5906 linkNum = link->linkNumber;
5907 l1Threshold = p->l1Threshold[linkNum];
5908
5909 status = device->hal.nvswitch_ctrl_get_link_l1_capability(device, linkNum, &isL1Capable);
5910 if (status != NVL_SUCCESS)
5911 {
5912 NVSWITCH_PRINT(device, ERROR, "%s: Failed to get l1 capability for link %d\n",
5913 __FUNCTION__, linkNum);
5914 return status;
5915 }
5916
5917 if (!isL1Capable)
5918 {
5919 NVSWITCH_PRINT(device, ERROR, "%s: Input link %d does not support L1\n",
5920 __FUNCTION__, i);
5921 return -NVL_ERR_NOT_SUPPORTED;
5922 }
5923
5924 if (((l1Threshold < NVSWITCH_SET_NVLINK_L1_THRESHOLD_MIN) ||
5925 (l1Threshold > NVSWITCH_SET_NVLINK_L1_THRESHOLD_MAX)) &&
5926 (l1Threshold != NVSWITCH_SET_NVLINK_L1_THRESHOLD_DEFAULT))
5927 {
5928 return -NVL_BAD_ARGS;
5929 }
5930
5931 status = device->hal.nvswitch_ctrl_set_link_l1_threshold(link,
5932 p->l1Threshold[linkNum]);
5933 if (status != NVL_SUCCESS)
5934 {
5935 NVSWITCH_PRINT(device, ERROR, "%s: Failed to set L1 Threshold for link %d\n",
5936 __FUNCTION__, linkNum);
5937 return status;
5938 }
5939 }
5940 FOR_EACH_INDEX_IN_MASK_END
5941
5942 return NVL_SUCCESS;
5943 }
5944
5945 NvlStatus
nvswitch_detect_tnvl_mode(nvswitch_device * device)5946 nvswitch_detect_tnvl_mode
5947 (
5948 nvswitch_device *device
5949 )
5950 {
5951 return device->hal.nvswitch_detect_tnvl_mode(device);
5952 }
5953
5954 NvBool
nvswitch_is_tnvl_mode_enabled(nvswitch_device * device)5955 nvswitch_is_tnvl_mode_enabled
5956 (
5957 nvswitch_device *device
5958 )
5959 {
5960 return device->hal.nvswitch_is_tnvl_mode_enabled(device);
5961 }
5962
5963 NvBool
nvswitch_is_tnvl_mode_locked(nvswitch_device * device)5964 nvswitch_is_tnvl_mode_locked
5965 (
5966 nvswitch_device *device
5967 )
5968 {
5969 return device->hal.nvswitch_is_tnvl_mode_locked(device);
5970 }
5971
5972 NvBool NV_API_CALL
nvswitch_lib_is_tnvl_enabled(nvswitch_device * device)5973 nvswitch_lib_is_tnvl_enabled
5974 (
5975 nvswitch_device *device
5976 )
5977 {
5978 return nvswitch_is_tnvl_mode_enabled(device);
5979 }
5980
5981 NvlStatus
nvswitch_tnvl_send_fsp_lock_config(nvswitch_device * device)5982 nvswitch_tnvl_send_fsp_lock_config
5983 (
5984 nvswitch_device *device
5985 )
5986 {
5987 return device->hal.nvswitch_tnvl_send_fsp_lock_config(device);
5988 }
5989
5990 static NvlStatus
_nvswitch_ctrl_set_device_tnvl_lock(nvswitch_device * device,NVSWITCH_SET_DEVICE_TNVL_LOCK_PARAMS * p)5991 _nvswitch_ctrl_set_device_tnvl_lock
5992 (
5993 nvswitch_device *device,
5994 NVSWITCH_SET_DEVICE_TNVL_LOCK_PARAMS *p
5995 )
5996 {
5997 NvlStatus status = NVL_SUCCESS;
5998
5999 if (!NVSWITCH_IS_DEVICE_ACCESSIBLE(device))
6000 {
6001 return -NVL_BAD_ARGS;
6002 }
6003
6004 if (!nvswitch_is_tnvl_mode_enabled(device))
6005 {
6006 NVSWITCH_PRINT(device, ERROR,
6007 "%s: TNVL is not enabled\n",
6008 __FUNCTION__);
6009 return -NVL_ERR_NOT_SUPPORTED;
6010 }
6011
6012 // Return failure if FM is not yet configured
6013 if (device->device_fabric_state != NVSWITCH_DEVICE_FABRIC_STATE_CONFIGURED)
6014 {
6015 NVSWITCH_PRINT(device, ERROR,
6016 "%s: FM is not configured yet\n",
6017 __FUNCTION__);
6018 return -NVL_ERR_INVALID_STATE;
6019 }
6020
6021 //
6022 // Disable non-fatal and legacy interrupts
6023 // Disable commands to SOE
6024 //
6025
6026 // Send lock-config command to FSP
6027 status = nvswitch_tnvl_send_fsp_lock_config(device);
6028 if (status == NVL_SUCCESS)
6029 {
6030 device->tnvl_mode = NVSWITCH_DEVICE_TNVL_MODE_LOCKED;
6031 }
6032 else
6033 {
6034 device->tnvl_mode = NVSWITCH_DEVICE_TNVL_MODE_FAILURE;
6035 }
6036
6037 return status;
6038 }
6039
6040 NvlStatus
nvswitch_lib_ctrl(nvswitch_device * device,NvU32 cmd,void * params,NvU64 size,void * osPrivate)6041 nvswitch_lib_ctrl
6042 (
6043 nvswitch_device *device,
6044 NvU32 cmd,
6045 void *params,
6046 NvU64 size,
6047 void *osPrivate
6048 )
6049 {
6050 NvlStatus retval;
6051 NvU64 flags = 0;
6052
6053 if (!NVSWITCH_IS_DEVICE_ACCESSIBLE(device) || params == NULL)
6054 {
6055 return -NVL_BAD_ARGS;
6056 }
6057
6058 flags = NVSWITCH_DEV_CMD_CHECK_ADMIN | NVSWITCH_DEV_CMD_CHECK_FM;
6059 switch (cmd)
6060 {
6061 NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_INFO,
6062 _nvswitch_ctrl_get_info,
6063 NVSWITCH_GET_INFO);
6064 NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_INTERNAL_LATENCY,
6065 _nvswitch_ctrl_get_internal_latency,
6066 NVSWITCH_GET_INTERNAL_LATENCY);
6067 NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_NVLIPT_COUNTERS,
6068 _nvswitch_ctrl_get_nvlipt_counters,
6069 NVSWITCH_GET_NVLIPT_COUNTERS);
6070 NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_ERRORS,
6071 nvswitch_ctrl_get_errors,
6072 NVSWITCH_GET_ERRORS_PARAMS);
6073 NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_PORT_EVENTS,
6074 nvswitch_ctrl_get_port_events,
6075 NVSWITCH_GET_PORT_EVENTS_PARAMS);
6076 NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_NVLINK_STATUS,
6077 _nvswitch_ctrl_get_nvlink_status,
6078 NVSWITCH_GET_NVLINK_STATUS_PARAMS);
6079 NVSWITCH_DEV_CMD_DISPATCH_WITH_PRIVATE_DATA(
6080 CTRL_NVSWITCH_ACQUIRE_CAPABILITY,
6081 _nvswitch_ctrl_acquire_capability,
6082 NVSWITCH_ACQUIRE_CAPABILITY_PARAMS,
6083 osPrivate);
6084 NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_TEMPERATURE,
6085 _nvswitch_ctrl_therm_read_temperature,
6086 NVSWITCH_CTRL_GET_TEMPERATURE_PARAMS);
6087 NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_THROUGHPUT_COUNTERS,
6088 nvswitch_ctrl_get_throughput_counters,
6089 NVSWITCH_GET_THROUGHPUT_COUNTERS_PARAMS);
6090 NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_FATAL_ERROR_SCOPE,
6091 _nvswitch_ctrl_get_fatal_error_scope,
6092 NVSWITCH_GET_FATAL_ERROR_SCOPE_PARAMS);
6093 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6094 CTRL_NVSWITCH_SET_SWITCH_PORT_CONFIG,
6095 _nvswitch_ctrl_set_switch_port_config,
6096 NVSWITCH_SET_SWITCH_PORT_CONFIG,
6097 osPrivate, flags);
6098 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6099 CTRL_NVSWITCH_GET_INGRESS_REQUEST_TABLE,
6100 _nvswitch_ctrl_get_ingress_request_table,
6101 NVSWITCH_GET_INGRESS_REQUEST_TABLE_PARAMS,
6102 osPrivate, flags);
6103 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6104 CTRL_NVSWITCH_SET_INGRESS_REQUEST_TABLE,
6105 _nvswitch_ctrl_set_ingress_request_table,
6106 NVSWITCH_SET_INGRESS_REQUEST_TABLE,
6107 osPrivate, flags);
6108 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6109 CTRL_NVSWITCH_SET_INGRESS_REQUEST_VALID,
6110 _nvswitch_ctrl_set_ingress_request_valid,
6111 NVSWITCH_SET_INGRESS_REQUEST_VALID,
6112 osPrivate, flags);
6113 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6114 CTRL_NVSWITCH_GET_INGRESS_RESPONSE_TABLE,
6115 _nvswitch_ctrl_get_ingress_response_table,
6116 NVSWITCH_GET_INGRESS_RESPONSE_TABLE_PARAMS,
6117 osPrivate, flags);
6118 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6119 CTRL_NVSWITCH_SET_INGRESS_RESPONSE_TABLE,
6120 _nvswitch_ctrl_set_ingress_response_table,
6121 NVSWITCH_SET_INGRESS_RESPONSE_TABLE,
6122 osPrivate, flags);
6123 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6124 CTRL_NVSWITCH_SET_GANGED_LINK_TABLE,
6125 _nvswitch_ctrl_set_ganged_link_table,
6126 NVSWITCH_SET_GANGED_LINK_TABLE,
6127 osPrivate, flags);
6128 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(CTRL_NVSWITCH_SET_LATENCY_BINS,
6129 nvswitch_ctrl_set_latency_bins,
6130 NVSWITCH_SET_LATENCY_BINS,
6131 osPrivate, flags);
6132 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6133 CTRL_NVSWITCH_SET_NVLIPT_COUNTER_CONFIG,
6134 _nvswitch_ctrl_set_nvlipt_counter_config,
6135 NVSWITCH_SET_NVLIPT_COUNTER_CONFIG,
6136 osPrivate, flags);
6137 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6138 CTRL_NVSWITCH_GET_NVLIPT_COUNTER_CONFIG,
6139 _nvswitch_ctrl_get_nvlipt_counter_config,
6140 NVSWITCH_GET_NVLIPT_COUNTER_CONFIG,
6141 osPrivate, flags);
6142 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(CTRL_NVSWITCH_SET_REMAP_POLICY,
6143 _nvswitch_ctrl_set_remap_policy,
6144 NVSWITCH_SET_REMAP_POLICY,
6145 osPrivate, flags);
6146 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(CTRL_NVSWITCH_GET_REMAP_POLICY,
6147 _nvswitch_ctrl_get_remap_policy,
6148 NVSWITCH_GET_REMAP_POLICY_PARAMS,
6149 osPrivate, flags);
6150 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6151 CTRL_NVSWITCH_SET_REMAP_POLICY_VALID,
6152 _nvswitch_ctrl_set_remap_policy_valid,
6153 NVSWITCH_SET_REMAP_POLICY_VALID,
6154 osPrivate, flags);
6155 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(CTRL_NVSWITCH_SET_ROUTING_ID,
6156 _nvswitch_ctrl_set_routing_id,
6157 NVSWITCH_SET_ROUTING_ID,
6158 osPrivate, flags);
6159 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(CTRL_NVSWITCH_GET_ROUTING_ID,
6160 _nvswitch_ctrl_get_routing_id,
6161 NVSWITCH_GET_ROUTING_ID_PARAMS,
6162 osPrivate, flags);
6163 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(CTRL_NVSWITCH_SET_ROUTING_ID_VALID,
6164 _nvswitch_ctrl_set_routing_id_valid,
6165 NVSWITCH_SET_ROUTING_LAN_VALID,
6166 osPrivate, flags);
6167 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(CTRL_NVSWITCH_SET_ROUTING_LAN,
6168 _nvswitch_ctrl_set_routing_lan,
6169 NVSWITCH_SET_ROUTING_LAN,
6170 osPrivate, flags);
6171 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(CTRL_NVSWITCH_GET_ROUTING_LAN,
6172 _nvswitch_ctrl_get_routing_lan,
6173 NVSWITCH_GET_ROUTING_LAN_PARAMS,
6174 osPrivate, flags);
6175 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6176 CTRL_NVSWITCH_SET_ROUTING_LAN_VALID,
6177 _nvswitch_ctrl_set_routing_lan_valid,
6178 NVSWITCH_SET_ROUTING_LAN_VALID,
6179 osPrivate, flags);
6180 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6181 CTRL_NVSWITCH_GET_INGRESS_REQLINKID,
6182 _nvswitch_ctrl_get_ingress_reqlinkid,
6183 NVSWITCH_GET_INGRESS_REQLINKID_PARAMS,
6184 osPrivate, flags);
6185 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(CTRL_NVSWITCH_UNREGISTER_LINK,
6186 _nvswitch_ctrl_unregister_link,
6187 NVSWITCH_UNREGISTER_LINK_PARAMS,
6188 osPrivate, flags);
6189 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6190 CTRL_NVSWITCH_RESET_AND_DRAIN_LINKS,
6191 _nvswitch_ctrl_reset_and_drain_links,
6192 NVSWITCH_RESET_AND_DRAIN_LINKS_PARAMS,
6193 osPrivate, flags);
6194 NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_BIOS_INFO,
6195 _nvswitch_ctrl_get_bios_info,
6196 NVSWITCH_GET_BIOS_INFO_PARAMS);
6197 NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_INFOROM_VERSION,
6198 _nvswitch_ctrl_get_inforom_version,
6199 NVSWITCH_GET_INFOROM_VERSION_PARAMS);
6200 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6201 CTRL_NVSWITCH_BLACKLIST_DEVICE,
6202 nvswitch_ctrl_blacklist_device,
6203 NVSWITCH_BLACKLIST_DEVICE_PARAMS,
6204 osPrivate, flags);
6205 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6206 CTRL_NVSWITCH_SET_FM_DRIVER_STATE,
6207 nvswitch_ctrl_set_fm_driver_state,
6208 NVSWITCH_SET_FM_DRIVER_STATE_PARAMS,
6209 osPrivate, flags);
6210 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6211 CTRL_NVSWITCH_SET_DEVICE_FABRIC_STATE,
6212 nvswitch_ctrl_set_device_fabric_state,
6213 NVSWITCH_SET_DEVICE_FABRIC_STATE_PARAMS,
6214 osPrivate, flags);
6215 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6216 CTRL_NVSWITCH_SET_FM_HEARTBEAT_TIMEOUT,
6217 nvswitch_ctrl_set_fm_timeout,
6218 NVSWITCH_SET_FM_HEARTBEAT_TIMEOUT_PARAMS,
6219 osPrivate, flags);
6220 NVSWITCH_DEV_CMD_DISPATCH_WITH_PRIVATE_DATA(
6221 CTRL_NVSWITCH_REGISTER_EVENTS,
6222 _nvswitch_ctrl_register_events,
6223 NVSWITCH_REGISTER_EVENTS_PARAMS,
6224 osPrivate);
6225 NVSWITCH_DEV_CMD_DISPATCH_WITH_PRIVATE_DATA(
6226 CTRL_NVSWITCH_UNREGISTER_EVENTS,
6227 _nvswitch_ctrl_unregister_events,
6228 NVSWITCH_UNREGISTER_EVENTS_PARAMS,
6229 osPrivate);
6230 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6231 CTRL_NVSWITCH_SET_TRAINING_ERROR_INFO,
6232 _nvswitch_ctrl_set_training_error_info,
6233 NVSWITCH_SET_TRAINING_ERROR_INFO_PARAMS,
6234 osPrivate, flags);
6235 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6236 CTRL_NVSWITCH_SET_MC_RID_TABLE,
6237 _nvswitch_ctrl_set_mc_rid_table,
6238 NVSWITCH_SET_MC_RID_TABLE_PARAMS,
6239 osPrivate, flags);
6240 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6241 CTRL_NVSWITCH_GET_MC_RID_TABLE,
6242 _nvswitch_ctrl_get_mc_rid_table,
6243 NVSWITCH_GET_MC_RID_TABLE_PARAMS,
6244 osPrivate, flags);
6245 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6246 CTRL_NVSWITCH_GET_COUNTERS,
6247 _nvswitch_ctrl_get_counters,
6248 NVSWITCH_NVLINK_GET_COUNTERS_PARAMS,
6249 osPrivate, flags);
6250 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6251 CTRL_NVSWITCH_GET_NVLINK_ECC_ERRORS,
6252 _nvswitch_ctrl_get_nvlink_ecc_errors,
6253 NVSWITCH_GET_NVLINK_ECC_ERRORS_PARAMS,
6254 osPrivate, flags);
6255 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6256 CTRL_NVSWITCH_I2C_SMBUS_COMMAND,
6257 _nvswitch_ctrl_i2c_smbus_command,
6258 NVSWITCH_I2C_SMBUS_COMMAND_PARAMS,
6259 osPrivate, NVSWITCH_DEV_CMD_CHECK_ADMIN);
6260 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6261 CTRL_NVSWITCH_CCI_CMIS_PRESENCE,
6262 _nvswitch_ctrl_cci_cmis_presence,
6263 NVSWITCH_CCI_CMIS_PRESENCE_PARAMS,
6264 osPrivate, flags);
6265 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6266 CTRL_NVSWITCH_CCI_CMIS_NVLINK_MAPPING,
6267 _nvswitch_ctrl_cci_nvlink_mappings,
6268 NVSWITCH_CCI_CMIS_NVLINK_MAPPING_PARAMS,
6269 osPrivate, flags);
6270 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6271 CTRL_NVSWITCH_CCI_CMIS_MEMORY_ACCESS_READ,
6272 _nvswitch_ctrl_cci_memory_access_read,
6273 NVSWITCH_CCI_CMIS_MEMORY_ACCESS_READ_PARAMS,
6274 osPrivate, flags);
6275 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6276 CTRL_NVSWITCH_CCI_CMIS_MEMORY_ACCESS_WRITE,
6277 _nvswitch_ctrl_cci_memory_access_write,
6278 NVSWITCH_CCI_CMIS_MEMORY_ACCESS_WRITE_PARAMS,
6279 osPrivate, flags);
6280 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6281 CTRL_NVSWITCH_CCI_CMIS_CAGE_BEZEL_MARKING,
6282 _nvswitch_ctrl_cci_cage_bezel_marking,
6283 NVSWITCH_CCI_CMIS_CAGE_BEZEL_MARKING_PARAMS,
6284 osPrivate, flags);
6285 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6286 CTRL_NVSWITCH_CCI_GET_GRADING_VALUES,
6287 nvswitch_ctrl_get_grading_values,
6288 NVSWITCH_CCI_GET_GRADING_VALUES_PARAMS,
6289 osPrivate, flags);
6290 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6291 CTRL_NVSWITCH_CCI_GET_PORTS_CPLD_INFO,
6292 nvswitch_ctrl_get_ports_cpld_info,
6293 NVSWITCH_CCI_GET_PORTS_CPLD_INFO_PARAMS,
6294 osPrivate, flags);
6295 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6296 CTRL_NVSWITCH_CCI_GET_FW_REVISIONS,
6297 nvswitch_ctrl_get_cci_fw_revisions,
6298 NVSWITCH_CCI_GET_FW_REVISION_PARAMS,
6299 osPrivate, flags);
6300 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6301 CTRL_NVSWITCH_CCI_SET_LOCATE_LED,
6302 nvswitch_ctrl_set_locate_led,
6303 NVSWITCH_CCI_SET_LOCATE_LED_PARAMS,
6304 osPrivate, flags);
6305 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6306 CTRL_NVSWITCH_GET_SOE_HEARTBEAT,
6307 _nvswitch_ctrl_get_soe_heartbeat,
6308 NVSWITCH_GET_SOE_HEARTBEAT_PARAMS,
6309 osPrivate, flags);
6310 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6311 CTRL_NVSWITCH_SET_CONTINUOUS_ALI,
6312 _nvswitch_ctrl_set_continuous_ali,
6313 NVSWITCH_SET_CONTINUOUS_ALI_PARAMS,
6314 osPrivate, flags);
6315 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6316 CTRL_NVSWITCH_REQUEST_ALI,
6317 _nvswitch_ctrl_request_ali,
6318 NVSWITCH_REQUEST_ALI_PARAMS,
6319 osPrivate, flags);
6320 NVSWITCH_DEV_CMD_DISPATCH(
6321 CTRL_NVSWITCH_GET_TEMPERATURE_LIMIT,
6322 _nvswitch_ctrl_therm_get_temperature_limit,
6323 NVSWITCH_CTRL_GET_TEMPERATURE_LIMIT_PARAMS);
6324 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6325 CTRL_NVSWITCH_GET_NVLINK_MAX_ERROR_RATES,
6326 _nvswitch_ctrl_get_inforom_nvlink_max_correctable_error_rate,
6327 NVSWITCH_GET_NVLINK_MAX_CORRECTABLE_ERROR_RATES_PARAMS,
6328 osPrivate, flags);
6329 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6330 CTRL_NVSWITCH_GET_NVLINK_ERROR_COUNTS,
6331 _nvswitch_ctrl_get_inforom_nvlink_errors,
6332 NVSWITCH_GET_NVLINK_ERROR_COUNTS_PARAMS,
6333 osPrivate, flags);
6334 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6335 CTRL_NVSWITCH_GET_ECC_ERROR_COUNTS,
6336 _nvswitch_ctrl_get_inforom_ecc_errors,
6337 NVSWITCH_GET_ECC_ERROR_COUNTS_PARAMS,
6338 osPrivate, flags);
6339 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6340 CTRL_NVSWITCH_GET_SXIDS,
6341 _nvswitch_ctrl_get_inforom_bbx_sxid,
6342 NVSWITCH_GET_SXIDS_PARAMS,
6343 osPrivate, flags);
6344 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6345 CTRL_NVSWITCH_GET_FOM_VALUES,
6346 _nvswitch_ctrl_get_fom_values,
6347 NVSWITCH_GET_FOM_VALUES_PARAMS,
6348 osPrivate, flags);
6349 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6350 CTRL_NVSWITCH_GET_NVLINK_LP_COUNTERS,
6351 _nvswitch_ctrl_get_nvlink_lp_counters,
6352 NVSWITCH_GET_NVLINK_LP_COUNTERS_PARAMS,
6353 osPrivate, flags);
6354 NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_RESIDENCY_BINS,
6355 _nvswitch_ctrl_get_residency_bins,
6356 NVSWITCH_GET_RESIDENCY_BINS);
6357 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(CTRL_NVSWITCH_SET_RESIDENCY_BINS,
6358 _nvswitch_ctrl_set_residency_bins,
6359 NVSWITCH_SET_RESIDENCY_BINS,
6360 osPrivate, flags);
6361 NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_RB_STALL_BUSY,
6362 _nvswitch_ctrl_get_rb_stall_busy,
6363 NVSWITCH_GET_RB_STALL_BUSY);
6364 NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_MULTICAST_ID_ERROR_VECTOR,
6365 nvswitch_ctrl_get_multicast_id_error_vector,
6366 NVSWITCH_GET_MULTICAST_ID_ERROR_VECTOR);
6367 NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_CLEAR_MULTICAST_ID_ERROR_VECTOR,
6368 nvswitch_ctrl_clear_multicast_id_error_vector,
6369 NVSWITCH_CLEAR_MULTICAST_ID_ERROR_VECTOR);
6370 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6371 CTRL_NVSWITCH_INBAND_SEND_DATA,
6372 _nvswitch_ctrl_inband_send_data,
6373 NVSWITCH_INBAND_SEND_DATA_PARAMS,
6374 osPrivate, flags);
6375 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6376 CTRL_NVSWITCH_INBAND_READ_DATA,
6377 _nvswitch_ctrl_inband_read_data,
6378 NVSWITCH_INBAND_READ_DATA_PARAMS,
6379 osPrivate, flags);
6380 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6381 CTRL_NVSWITCH_INBAND_FLUSH_DATA,
6382 _nvswitch_ctrl_inband_flush_data,
6383 NVSWITCH_INBAND_FLUSH_DATA_PARAMS,
6384 osPrivate, flags);
6385 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6386 CTRL_NVSWITCH_INBAND_PENDING_DATA_STATS,
6387 _nvswitch_ctrl_inband_pending_data_stats,
6388 NVSWITCH_INBAND_PENDING_DATA_STATS_PARAMS,
6389 osPrivate, flags);
6390 NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_BOARD_PART_NUMBER,
6391 _nvswitch_ctrl_get_board_part_number,
6392 NVSWITCH_GET_BOARD_PART_NUMBER_VECTOR);
6393 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6394 CTRL_NVSWITCH_GET_SW_INFO,
6395 _nvswitch_ctrl_get_sw_info,
6396 NVSWITCH_GET_SW_INFO_PARAMS,
6397 osPrivate, flags);
6398 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(CTRL_NVSWITCH_REGISTER_READ,
6399 _nvswitch_ctrl_register_read,
6400 NVSWITCH_REGISTER_READ,
6401 osPrivate, flags);
6402 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(CTRL_NVSWITCH_REGISTER_WRITE,
6403 _nvswitch_ctrl_register_write,
6404 NVSWITCH_REGISTER_WRITE,
6405 osPrivate, flags);
6406 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(CTRL_NVSWITCH_GET_ERR_INFO,
6407 _nvswitch_ctrl_get_err_info,
6408 NVSWITCH_NVLINK_GET_ERR_INFO_PARAMS,
6409 osPrivate, flags);
6410 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(CTRL_NVSWITCH_CLEAR_COUNTERS,
6411 _nvswitch_ctrl_clear_counters,
6412 NVSWITCH_NVLINK_CLEAR_COUNTERS_PARAMS,
6413 osPrivate, flags);
6414 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(CTRL_NVSWITCH_SET_NVLINK_ERROR_THRESHOLD,
6415 _nvswitch_ctrl_set_nvlink_error_threshold,
6416 NVSWITCH_SET_NVLINK_ERROR_THRESHOLD_PARAMS,
6417 osPrivate, flags);
6418 NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_NVLINK_ERROR_THRESHOLD,
6419 _nvswitch_ctrl_get_nvlink_error_threshold,
6420 NVSWITCH_GET_NVLINK_ERROR_THRESHOLD_PARAMS);
6421 NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_VOLTAGE,
6422 _nvswitch_ctrl_therm_read_voltage,
6423 NVSWITCH_CTRL_GET_VOLTAGE_PARAMS);
6424 NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_POWER,
6425 _nvswitch_ctrl_therm_read_power,
6426 NVSWITCH_GET_POWER_PARAMS);
6427 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6428 CTRL_NVSWITCH_GET_SYS_INFO,
6429 _nvswitch_ctrl_get_inforom_bbx_sys_info,
6430 NVSWITCH_GET_SYS_INFO_PARAMS,
6431 osPrivate, flags);
6432 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6433 CTRL_NVSWITCH_GET_TIME_INFO,
6434 _nvswitch_ctrl_get_inforom_bbx_time_info,
6435 NVSWITCH_GET_TIME_INFO_PARAMS,
6436 osPrivate, flags);
6437 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6438 CTRL_NVSWITCH_GET_TEMP_DATA,
6439 _nvswitch_ctrl_get_inforom_bbx_temp_data,
6440 NVSWITCH_GET_TEMP_DATA_PARAMS,
6441 osPrivate, flags);
6442 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6443 CTRL_NVSWITCH_GET_TEMP_SAMPLES,
6444 _nvswitch_ctrl_get_inforom_bbx_temp_samples,
6445 NVSWITCH_GET_TEMP_SAMPLES_PARAMS,
6446 osPrivate, flags);
6447 NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_NVLINK_L1_CAPABILITY,
6448 _nvswitch_ctrl_get_link_l1_capability,
6449 NVSWITCH_GET_NVLINK_L1_CAPABILITY_PARAMS);
6450 NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_NVLINK_L1_THRESHOLD,
6451 _nvswitch_ctrl_get_link_l1_threshold,
6452 NVSWITCH_GET_NVLINK_L1_THRESHOLD_PARAMS);
6453 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(CTRL_NVSWITCH_SET_NVLINK_L1_THRESHOLD,
6454 _nvswitch_ctrl_set_link_l1_threshold,
6455 NVSWITCH_SET_NVLINK_L1_THRESHOLD_PARAMS,
6456 osPrivate, flags);
6457 NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_FSPRPC_GET_CAPS,
6458 _nvswitch_ctrl_fsprpc_get_caps,
6459 NVSWITCH_FSPRPC_GET_CAPS_PARAMS);
6460 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6461 CTRL_NVSWITCH_SET_DEVICE_TNVL_LOCK,
6462 _nvswitch_ctrl_set_device_tnvl_lock,
6463 NVSWITCH_SET_DEVICE_TNVL_LOCK_PARAMS,
6464 osPrivate, flags);
6465 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6466 CTRL_NVSWITCH_GET_ATTESTATION_CERTIFICATE_CHAIN,
6467 _nvswitch_ctrl_get_attestation_certificate_chain,
6468 NVSWITCH_GET_ATTESTATION_CERTIFICATE_CHAIN_PARAMS,
6469 osPrivate, flags);
6470 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6471 CTRL_NVSWITCH_GET_ATTESTATION_REPORT,
6472 _nvswitch_ctrl_get_attestation_report,
6473 NVSWITCH_GET_ATTESTATION_REPORT_PARAMS,
6474 osPrivate, flags);
6475 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
6476 CTRL_NVSWITCH_GET_TNVL_STATUS,
6477 _nvswitch_ctrl_get_tnvl_status,
6478 NVSWITCH_GET_TNVL_STATUS_PARAMS,
6479 osPrivate, flags);
6480 default:
6481 nvswitch_os_print(NVSWITCH_DBG_LEVEL_INFO, "unknown ioctl %x\n", cmd);
6482 retval = -NVL_BAD_ARGS;
6483 break;
6484 }
6485
6486 return retval;
6487 }
6488
6489 #if defined(DEVELOP) || defined(DEBUG) || defined(NV_MODS)
nvswitch_assert_log(const char * function,const char * file,NvU32 line)6490 void nvswitch_assert_log
6491 (
6492 const char *function,
6493 const char *file,
6494 NvU32 line
6495 )
6496 {
6497 nvswitch_os_assert_log("NVSwitch: Assertion failed in %s() at %s:%d\n",
6498 function, file, line);
6499 }
6500 #else
nvswitch_assert_log(void)6501 void nvswitch_assert_log(void)
6502 {
6503 nvswitch_os_assert_log("NVSwitch: Assertion failed\n");
6504 }
6505 #endif
6506