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