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 "nvVer.h" 34 #include "nvlink_inband_msg.h" 35 36 static NvlStatus _nvswitch_ctrl_inband_flush_data(nvswitch_device *device, NVSWITCH_INBAND_FLUSH_DATA_PARAMS *p); 37 38 #define NVSWITCH_DEV_CMD_CHECK_ADMIN NVBIT64(0) 39 #define NVSWITCH_DEV_CMD_CHECK_FM NVBIT64(1) 40 41 #define NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(cmd, function, type, private, flags)\ 42 case cmd: \ 43 { \ 44 if (sizeof(type) != size) \ 45 { \ 46 retval = -NVL_BAD_ARGS; \ 47 break; \ 48 } \ 49 \ 50 retval = _nvswitch_lib_validate_privileged_ctrl(private, flags); \ 51 if (retval != NVL_SUCCESS) \ 52 { \ 53 break; \ 54 } \ 55 \ 56 retval = function(device, params); \ 57 break; \ 58 } \ 59 60 #define NVSWITCH_DEV_CMD_DISPATCH_RESERVED(cmd) \ 61 case cmd: \ 62 { \ 63 retval = -NVL_ERR_NOT_IMPLEMENTED; \ 64 break; \ 65 } \ 66 67 const static NvU32 nvswitch_lr10_device_ids[] = 68 { 69 0x1AE8, 0x1AF0, 0x1AF1, 0x1AF2, 0x1AF3, 0x1AF4, 0x1AF5, 0x1AF6, 0x1AF7, 70 0x1AF8, 0x1AF9, 0x1AFA, 0x1AFB, 0x1AFC, 0x1AFD, 0x1AFE, 0x1AFF 71 }; 72 73 const static NvU32 nvswitch_ls10_device_ids[] = 74 { 75 // PCIE endpoint to manage the NVLink switch HW 76 0x22A0, 0x22A1, 0x22A2, 0x22A3, 0x22A4, 0x22A5, 0x22A6, 0x22A7, 77 // PCI-PCI Bridge, Laguna Switch Function 0 78 0x22A8, 0x22A9, 0x22AA, 0x22AB, 79 // Non-Transparent Bridge, Laguna Switch Function 1 80 0x22AC, 0x22AD, 0x22AE, 0x22AF 81 }; 82 83 nvlink_link_handlers link_handlers; 84 85 static NvBool 86 _nvswitch_is_device_id_present 87 ( 88 const NvU32 *array, 89 NvU32 array_len, 90 NvU32 device_id 91 ) 92 { 93 NvU32 i = 0; 94 95 for(i = 0; i < array_len; i++) 96 { 97 if (array[i] == device_id) 98 { 99 return NV_TRUE; 100 } 101 } 102 103 return NV_FALSE; 104 } 105 106 NvBool 107 nvswitch_is_lr10_device_id 108 ( 109 NvU32 device_id 110 ) 111 { 112 NvU32 count = (sizeof(nvswitch_lr10_device_ids) / 113 sizeof(nvswitch_lr10_device_ids[0])); 114 115 return _nvswitch_is_device_id_present(nvswitch_lr10_device_ids, count, device_id); 116 } 117 118 NvBool 119 nvswitch_is_ls10_device_id 120 ( 121 NvU32 device_id 122 ) 123 { 124 NvU32 count = (sizeof(nvswitch_ls10_device_ids) / 125 sizeof(nvswitch_ls10_device_ids[0])); 126 127 return _nvswitch_is_device_id_present(nvswitch_ls10_device_ids, count, device_id); 128 } 129 130 /* 131 * NVLink corelib callbacks are used by the NVLink library separate from the 132 * NVSwitch driver, therefore they do not take a device lock and can not modify 133 * nvswitch_device state or use error logging. 134 * 135 * These NVSwitch functions modify link state outside of the corelib: 136 * _nvswitch_ctrl_inject_link_error - injects asynchronous link errors (MODS-only) 137 */ 138 139 static NV_API_CALL NvlStatus 140 _nvswitch_corelib_add_link 141 ( 142 nvlink_link *link 143 ) 144 { 145 nvswitch_device *device = link->dev->pDevInfo; 146 return device->hal.nvswitch_corelib_add_link(link); 147 } 148 149 static NV_API_CALL NvlStatus 150 _nvswitch_corelib_remove_link 151 ( 152 nvlink_link *link 153 ) 154 { 155 nvswitch_device *device = link->dev->pDevInfo; 156 return device->hal.nvswitch_corelib_remove_link(link); 157 } 158 159 static NV_API_CALL NvlStatus 160 _nvswitch_corelib_set_dl_link_mode 161 ( 162 nvlink_link *link, 163 NvU64 mode, 164 NvU32 flags 165 ) 166 { 167 nvswitch_device *device = link->dev->pDevInfo; 168 return device->hal.nvswitch_corelib_set_dl_link_mode(link, mode, flags); 169 } 170 171 static NV_API_CALL NvlStatus 172 _nvswitch_corelib_get_dl_link_mode 173 ( 174 nvlink_link *link, 175 NvU64 *mode 176 ) 177 { 178 nvswitch_device *device = link->dev->pDevInfo; 179 return device->hal.nvswitch_corelib_get_dl_link_mode(link, mode); 180 } 181 182 static NV_API_CALL NvlStatus 183 _nvswitch_corelib_set_tl_link_mode 184 ( 185 nvlink_link *link, 186 NvU64 mode, 187 NvU32 flags 188 ) 189 { 190 nvswitch_device *device = link->dev->pDevInfo; 191 return device->hal.nvswitch_corelib_set_tl_link_mode(link, mode, flags); 192 } 193 194 static NV_API_CALL NvlStatus 195 _nvswitch_corelib_get_tl_link_mode 196 ( 197 nvlink_link *link, 198 NvU64 *mode 199 ) 200 { 201 nvswitch_device *device = link->dev->pDevInfo; 202 return device->hal.nvswitch_corelib_get_tl_link_mode(link, mode); 203 } 204 205 static NV_API_CALL NvlStatus 206 _nvswitch_corelib_set_tx_mode 207 ( 208 nvlink_link *link, 209 NvU64 mode, 210 NvU32 flags 211 ) 212 { 213 nvswitch_device *device = link->dev->pDevInfo; 214 return device->hal.nvswitch_corelib_set_tx_mode(link, mode, flags); 215 } 216 217 static NV_API_CALL NvlStatus 218 _nvswitch_corelib_get_tx_mode 219 ( 220 nvlink_link *link, 221 NvU64 *mode, 222 NvU32 *subMode 223 ) 224 { 225 nvswitch_device *device = link->dev->pDevInfo; 226 return device->hal.nvswitch_corelib_get_tx_mode(link, mode, subMode); 227 } 228 229 static NV_API_CALL NvlStatus 230 _nvswitch_corelib_set_rx_mode 231 ( 232 nvlink_link *link, 233 NvU64 mode, 234 NvU32 flags 235 ) 236 { 237 nvswitch_device *device = link->dev->pDevInfo; 238 return device->hal.nvswitch_corelib_set_rx_mode(link, mode, flags); 239 } 240 241 static NV_API_CALL NvlStatus 242 _nvswitch_corelib_get_rx_mode 243 ( 244 nvlink_link *link, 245 NvU64 *mode, 246 NvU32 *subMode 247 ) 248 { 249 nvswitch_device *device = link->dev->pDevInfo; 250 return device->hal.nvswitch_corelib_get_rx_mode(link, mode, subMode); 251 } 252 253 static NV_API_CALL NvlStatus 254 _nvswitch_corelib_set_rx_detect 255 ( 256 nvlink_link *link, 257 NvU32 flags 258 ) 259 { 260 nvswitch_device *device = link->dev->pDevInfo; 261 return device->hal.nvswitch_corelib_set_rx_detect(link, flags); 262 } 263 264 static NV_API_CALL NvlStatus 265 _nvswitch_corelib_get_rx_detect 266 ( 267 nvlink_link *link 268 ) 269 { 270 nvswitch_device *device = link->dev->pDevInfo; 271 return device->hal.nvswitch_corelib_get_rx_detect(link); 272 } 273 274 static NV_API_CALL void 275 _nvswitch_corelib_training_complete 276 ( 277 nvlink_link *link 278 ) 279 { 280 nvswitch_device *device = link->dev->pDevInfo; 281 device->hal.nvswitch_corelib_training_complete(link); 282 } 283 284 static NV_API_CALL void 285 _nvswitch_corelib_get_uphy_load 286 ( 287 nvlink_link *link, 288 NvBool *bUnlocked 289 ) 290 { 291 nvswitch_device *device = link->dev->pDevInfo; 292 return device->hal.nvswitch_corelib_get_uphy_load(link, bUnlocked); 293 } 294 295 296 static NV_API_CALL NvlStatus 297 _nvswitch_corelib_write_discovery_token 298 ( 299 nvlink_link *link, 300 NvU64 token 301 ) 302 { 303 nvswitch_device *device = link->dev->pDevInfo; 304 305 if (link->version >= NVLINK_DEVICE_VERSION_40) 306 { 307 nvswitch_store_topology_information(device, link); 308 return NVL_SUCCESS; 309 } 310 311 return NVL_SUCCESS; 312 } 313 314 static NV_API_CALL NvlStatus 315 _nvswitch_corelib_ali_training 316 ( 317 nvlink_link *link 318 ) 319 { 320 nvswitch_device *device = link->dev->pDevInfo; 321 return device->hal.nvswitch_launch_ALI_link_training(device, link, NV_FALSE); 322 } 323 324 void 325 nvswitch_get_link_handlers 326 ( 327 nvlink_link_handlers *nvswitch_link_handlers 328 ) 329 { 330 if (!nvswitch_link_handlers) 331 { 332 NVSWITCH_ASSERT(0); 333 return; 334 } 335 336 nvswitch_link_handlers->add = _nvswitch_corelib_add_link; 337 nvswitch_link_handlers->remove = _nvswitch_corelib_remove_link; 338 nvswitch_link_handlers->set_dl_link_mode = _nvswitch_corelib_set_dl_link_mode; 339 nvswitch_link_handlers->get_dl_link_mode = _nvswitch_corelib_get_dl_link_mode; 340 nvswitch_link_handlers->set_tl_link_mode = _nvswitch_corelib_set_tl_link_mode; 341 nvswitch_link_handlers->get_tl_link_mode = _nvswitch_corelib_get_tl_link_mode; 342 nvswitch_link_handlers->set_tx_mode = _nvswitch_corelib_set_tx_mode; 343 nvswitch_link_handlers->get_tx_mode = _nvswitch_corelib_get_tx_mode; 344 nvswitch_link_handlers->set_rx_mode = _nvswitch_corelib_set_rx_mode; 345 nvswitch_link_handlers->get_rx_mode = _nvswitch_corelib_get_rx_mode; 346 nvswitch_link_handlers->set_rx_detect = _nvswitch_corelib_set_rx_detect; 347 nvswitch_link_handlers->get_rx_detect = _nvswitch_corelib_get_rx_detect; 348 nvswitch_link_handlers->training_complete = _nvswitch_corelib_training_complete; 349 nvswitch_link_handlers->get_uphy_load = _nvswitch_corelib_get_uphy_load; 350 nvswitch_link_handlers->write_discovery_token = _nvswitch_corelib_write_discovery_token; 351 nvswitch_link_handlers->ali_training = _nvswitch_corelib_ali_training; 352 } 353 354 #define NVSWITCH_INIT_REGKEY(_private, _regkey, _string, _default_val) \ 355 do \ 356 { \ 357 NvU32 data; \ 358 \ 359 device->regkeys._regkey = _default_val; \ 360 if (NV_SWITCH_REGKEY_PRIVATE_ALLOWED || !NV_SWITCH_REGKEY##_private) \ 361 { \ 362 if (NVL_SUCCESS == \ 363 nvswitch_os_read_registry_dword(device->os_handle, _string, &data)) \ 364 { \ 365 NVSWITCH_PRINT(device, SETUP, \ 366 "%s: Applying regkey %s=0x%x\n", \ 367 __FUNCTION__, \ 368 _string, data); \ 369 device->regkeys._regkey = data; \ 370 } \ 371 } \ 372 } while(0) 373 374 static void 375 _nvswitch_init_device_regkeys 376 ( 377 nvswitch_device *device 378 ) 379 { 380 // 381 // Public external use regkeys 382 // 383 NVSWITCH_INIT_REGKEY(_PUBLIC, ato_control, 384 NV_SWITCH_REGKEY_ATO_CONTROL, 385 NV_SWITCH_REGKEY_ATO_CONTROL_DEFAULT); 386 387 NVSWITCH_INIT_REGKEY(_PUBLIC, sto_control, 388 NV_SWITCH_REGKEY_STO_CONTROL, 389 NV_SWITCH_REGKEY_STO_CONTROL_DEFAULT); 390 391 NVSWITCH_INIT_REGKEY(_PUBLIC, crc_bit_error_rate_short, 392 NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_SHORT, 393 NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_SHORT_DEFAULT); 394 395 NVSWITCH_INIT_REGKEY(_PUBLIC, crc_bit_error_rate_long, 396 NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_LONG, 397 NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_LONG_DEFAULT); 398 399 NVSWITCH_INIT_REGKEY(_PUBLIC, surpress_link_errors_for_gpu_reset, 400 NV_SWITCH_REGKEY_SURPRESS_LINK_ERRORS_FOR_GPU_RESET, 401 NV_SWITCH_REGKEY_SURPRESS_LINK_ERRORS_FOR_GPU_RESET_DISABLE); 402 403 // 404 // Debug use regkeys 405 // Not available on release build kernel drivers 406 // 407 NVSWITCH_INIT_REGKEY(_PRIVATE, external_fabric_mgmt, 408 NV_SWITCH_REGKEY_EXTERNAL_FABRIC_MGMT, 409 NV_SWITCH_REGKEY_EXTERNAL_FABRIC_MGMT_ENABLE); 410 411 NVSWITCH_INIT_REGKEY(_PRIVATE, txtrain_control, 412 NV_SWITCH_REGKEY_TXTRAIN_CONTROL, 413 NV_SWITCH_REGKEY_TXTRAIN_CONTROL_NOP); 414 415 NVSWITCH_INIT_REGKEY(_PRIVATE, crossbar_DBI, 416 NV_SWITCH_REGKEY_CROSSBAR_DBI, 417 NV_SWITCH_REGKEY_CROSSBAR_DBI_ENABLE); 418 419 NVSWITCH_INIT_REGKEY(_PRIVATE, link_DBI, 420 NV_SWITCH_REGKEY_LINK_DBI, 421 NV_SWITCH_REGKEY_LINK_DBI_ENABLE); 422 423 NVSWITCH_INIT_REGKEY(_PRIVATE, ac_coupled_mask, 424 NV_SWITCH_REGKEY_AC_COUPLED_MASK, 425 0); 426 427 NVSWITCH_INIT_REGKEY(_PRIVATE, ac_coupled_mask2, 428 NV_SWITCH_REGKEY_AC_COUPLED_MASK2, 429 0); 430 431 NVSWITCH_INIT_REGKEY(_PRIVATE, swap_clk, 432 NV_SWITCH_REGKEY_SWAP_CLK_OVERRIDE, 433 nvswitch_get_swap_clk_default(device)); 434 435 NVSWITCH_INIT_REGKEY(_PRIVATE, link_enable_mask, 436 NV_SWITCH_REGKEY_ENABLE_LINK_MASK, 437 NV_U32_MAX); 438 439 NVSWITCH_INIT_REGKEY(_PRIVATE, link_enable_mask2, 440 NV_SWITCH_REGKEY_ENABLE_LINK_MASK2, 441 NV_U32_MAX); 442 443 NVSWITCH_INIT_REGKEY(_PRIVATE, bandwidth_shaper, 444 NV_SWITCH_REGKEY_BANDWIDTH_SHAPER, 445 NV_SWITCH_REGKEY_BANDWIDTH_SHAPER_PROD); 446 447 NVSWITCH_INIT_REGKEY(_PRIVATE, ssg_control, 448 NV_SWITCH_REGKEY_SSG_CONTROL, 449 0); 450 451 NVSWITCH_INIT_REGKEY(_PRIVATE, skip_buffer_ready, 452 NV_SWITCH_REGKEY_SKIP_BUFFER_READY, 453 0); 454 455 NVSWITCH_INIT_REGKEY(_PRIVATE, enable_pm, 456 NV_SWITCH_REGKEY_ENABLE_PM, 457 NV_SWITCH_REGKEY_ENABLE_PM_YES); 458 459 NVSWITCH_INIT_REGKEY(_PRIVATE, chiplib_forced_config_link_mask, 460 NV_SWITCH_REGKEY_CHIPLIB_FORCED_LINK_CONFIG_MASK, 461 0); 462 463 NVSWITCH_INIT_REGKEY(_PRIVATE, chiplib_forced_config_link_mask2, 464 NV_SWITCH_REGKEY_CHIPLIB_FORCED_LINK_CONFIG_MASK2, 465 0); 466 467 NVSWITCH_INIT_REGKEY(_PRIVATE, soe_dma_self_test, 468 NV_SWITCH_REGKEY_SOE_DMA_SELFTEST, 469 NV_SWITCH_REGKEY_SOE_DMA_SELFTEST_ENABLE); 470 471 NVSWITCH_INIT_REGKEY(_PRIVATE, soe_disable, 472 NV_SWITCH_REGKEY_SOE_DISABLE, 473 NV_SWITCH_REGKEY_SOE_DISABLE_NO); 474 475 NVSWITCH_INIT_REGKEY(_PRIVATE, latency_counter, 476 NV_SWITCH_REGKEY_LATENCY_COUNTER_LOGGING, 477 NV_SWITCH_REGKEY_LATENCY_COUNTER_LOGGING_ENABLE); 478 479 NVSWITCH_INIT_REGKEY(_PRIVATE, nvlink_speed_control, 480 NV_SWITCH_REGKEY_SPEED_CONTROL, 481 NV_SWITCH_REGKEY_SPEED_CONTROL_SPEED_DEFAULT); 482 483 NVSWITCH_INIT_REGKEY(_PRIVATE, inforom_bbx_periodic_flush, 484 NV_SWITCH_REGKEY_INFOROM_BBX_ENABLE_PERIODIC_FLUSHING, 485 NV_SWITCH_REGKEY_INFOROM_BBX_ENABLE_PERIODIC_FLUSHING_DISABLE); 486 487 NVSWITCH_INIT_REGKEY(_PRIVATE, inforom_bbx_write_periodicity, 488 NV_SWITCH_REGKEY_INFOROM_BBX_WRITE_PERIODICITY, 489 NV_SWITCH_REGKEY_INFOROM_BBX_WRITE_PERIODICITY_DEFAULT); 490 491 NVSWITCH_INIT_REGKEY(_PRIVATE, inforom_bbx_write_min_duration, 492 NV_SWITCH_REGKEY_INFOROM_BBX_WRITE_MIN_DURATION, 493 NV_SWITCH_REGKEY_INFOROM_BBX_WRITE_MIN_DURATION_DEFAULT); 494 495 NVSWITCH_INIT_REGKEY(_PRIVATE, minion_disable, 496 NV_SWITCH_REGKEY_MINION_DISABLE, 497 NV_SWITCH_REGKEY_MINION_DISABLE_NO); 498 499 NVSWITCH_INIT_REGKEY(_PRIVATE, set_ucode_target, 500 NV_SWITCH_REGKEY_MINION_SET_UCODE_TARGET, 501 NV_SWITCH_REGKEY_MINION_SET_UCODE_TARGET_DEFAULT); 502 503 NVSWITCH_INIT_REGKEY(_PRIVATE, set_simmode, 504 NV_SWITCH_REGKEY_MINION_SET_SIMMODE, 505 NV_SWITCH_REGKEY_MINION_SET_SIMMODE_DEFAULT); 506 507 NVSWITCH_INIT_REGKEY(_PRIVATE, set_smf_settings, 508 NV_SWITCH_REGKEY_MINION_SET_SMF_SETTINGS, 509 NV_SWITCH_REGKEY_MINION_SET_SMF_SETTINGS_DEFAULT); 510 511 NVSWITCH_INIT_REGKEY(_PRIVATE, select_uphy_tables, 512 NV_SWITCH_REGKEY_MINION_SELECT_UPHY_TABLES, 513 NV_SWITCH_REGKEY_MINION_SELECT_UPHY_TABLES_DEFAULT); 514 515 NVSWITCH_INIT_REGKEY(_PRIVATE, link_training_mode, 516 NV_SWITCH_REGKEY_LINK_TRAINING_SELECT, 517 NV_SWITCH_REGKEY_LINK_TRAINING_SELECT_DEFAULT); 518 519 NVSWITCH_INIT_REGKEY(_PRIVATE, i2c_access_control, 520 NV_SWITCH_REGKEY_I2C_ACCESS_CONTROL, 521 NV_SWITCH_REGKEY_I2C_ACCESS_CONTROL_DEFAULT); 522 523 NVSWITCH_INIT_REGKEY(_PRIVATE, force_kernel_i2c, 524 NV_SWITCH_REGKEY_FORCE_KERNEL_I2C, 525 NV_SWITCH_REGKEY_FORCE_KERNEL_I2C_DEFAULT); 526 527 NVSWITCH_INIT_REGKEY(_PRIVATE, link_recal_settings, 528 NV_SWITCH_REGKEY_LINK_RECAL_SETTINGS, 529 NV_SWITCH_REGKEY_LINK_RECAL_SETTINGS_NOP); 530 531 NVSWITCH_INIT_REGKEY(_PRIVATE, lp_threshold, 532 NV_SWITCH_REGKEY_SET_LP_THRESHOLD, 533 NV_SWITCH_REGKEY_SET_LP_THRESHOLD_DEFAULT); 534 535 NVSWITCH_INIT_REGKEY(_PUBLIC, minion_intr, 536 NV_SWITCH_REGKEY_MINION_INTERRUPTS, 537 NV_SWITCH_REGKEY_MINION_INTERRUPTS_DEFAULT); 538 539 NVSWITCH_INIT_REGKEY(_PRIVATE, block_code_mode, 540 NV_SWITCH_REGKEY_BLOCK_CODE_MODE, 541 NV_SWITCH_REGKEY_BLOCK_CODE_MODE_DEFAULT); 542 543 NVSWITCH_INIT_REGKEY(_PRIVATE, reference_clock_mode, 544 NV_SWITCH_REGKEY_REFERENCE_CLOCK_MODE, 545 NV_SWITCH_REGKEY_REFERENCE_CLOCK_MODE_DEFAULT); 546 } 547 NvU64 548 nvswitch_lib_deferred_task_dispatcher 549 ( 550 nvswitch_device *device 551 ) 552 { 553 NvU64 time_nsec; 554 NvU64 time_next_nsec = nvswitch_os_get_platform_time() + 100*NVSWITCH_INTERVAL_1MSEC_IN_NS; 555 NVSWITCH_TASK_TYPE *task; 556 NVSWITCH_TASK_TYPE *prev_task; 557 558 if (!NVSWITCH_IS_DEVICE_VALID(device)) 559 { 560 return NV_U64_MAX; 561 } 562 563 prev_task = NULL; 564 task = device->tasks; 565 566 // Walk the task list, executing those whose next execution interval is at hand 567 while (task) 568 { 569 // Get current time (nsec) for scheduling 570 time_nsec = nvswitch_os_get_platform_time(); 571 572 if (time_nsec >= task->last_run_nsec + task->period_nsec) 573 { 574 // 575 // The task has never been run or it is time to run 576 // Mark its last run time 577 // 578 task->last_run_nsec = time_nsec; 579 // Run the task 580 if (NVSWITCH_IS_DEVICE_INITIALIZED(device) || 581 (task->flags & NVSWITCH_TASK_TYPE_FLAGS_RUN_EVEN_IF_DEVICE_NOT_INITIALIZED)) 582 { 583 if(task->flags & NVSWITCH_TASK_TYPE_FLAGS_VOID_PTR_ARGS) 584 (*task->task_fn_vdptr)(device, task->task_args); // run task with provided args 585 else 586 (*task->task_fn_devptr)(device); 587 } 588 } 589 590 // Determine its next run time 591 time_next_nsec = NV_MIN(task->last_run_nsec + task->period_nsec, time_next_nsec); 592 593 // Advance pointer. If run once flag is set and task ran, remove task from list. 594 if((task->flags & NVSWITCH_TASK_TYPE_FLAGS_RUN_ONCE) && 595 (task->last_run_nsec == time_nsec)) 596 { 597 prev_task = task->prev; 598 599 // Removing from list head 600 if (prev_task == NULL) 601 { 602 device->tasks = task->next; 603 if (device->tasks != NULL) 604 { 605 device->tasks->prev = NULL; 606 } 607 nvswitch_os_free(task); 608 task = device->tasks; 609 } 610 else 611 { 612 prev_task->next = task->next; 613 if (prev_task->next != NULL) 614 { 615 prev_task->next->prev = prev_task; 616 } 617 nvswitch_os_free(task); 618 task = prev_task->next; 619 } 620 } 621 else 622 { 623 task = task->next; 624 } 625 } 626 627 time_nsec = nvswitch_os_get_platform_time(); 628 629 // Return to the OS layer how long to wait before calling again 630 return(time_next_nsec >= time_nsec ? time_next_nsec - time_nsec : 0); 631 } 632 633 static NvlStatus 634 _nvswitch_setup_hal 635 ( 636 nvswitch_device *device, 637 NvU32 pci_device_id 638 ) 639 { 640 if (nvswitch_is_lr10_device_id(pci_device_id)) 641 { 642 nvswitch_setup_hal_lr10(device); 643 return NVL_SUCCESS; 644 } 645 if (nvswitch_is_ls10_device_id(pci_device_id)) 646 { 647 nvswitch_setup_hal_ls10(device); 648 return NVL_SUCCESS; 649 } 650 NVSWITCH_PRINT(device, ERROR, 651 "NVSwitch HAL setup failed - Unrecognized PCI Device ID\n"); 652 return -NVL_ERR_NOT_SUPPORTED; 653 } 654 655 NvlStatus 656 nvswitch_lib_check_api_version 657 ( 658 const char *user_version, 659 char *kernel_version, 660 NvU32 length 661 ) 662 { 663 const NvLength VERSION_LENGTH = nvswitch_os_strlen(NV_VERSION_STRING); 664 665 if (kernel_version == NULL || user_version == NULL) 666 { 667 return -NVL_BAD_ARGS; 668 } 669 670 if (length < VERSION_LENGTH) 671 { 672 return -NVL_NO_MEM; 673 } 674 675 nvswitch_os_memset(kernel_version, 0x0, length); 676 nvswitch_os_strncpy(kernel_version, NV_VERSION_STRING, VERSION_LENGTH); 677 678 kernel_version[length - 1] = '\0'; 679 680 if (nvswitch_os_strncmp(user_version, kernel_version, VERSION_LENGTH)) 681 { 682 return -NVL_ERR_NOT_SUPPORTED; 683 } 684 685 return NVL_SUCCESS; 686 } 687 688 NvBool 689 nvswitch_is_inforom_supported 690 ( 691 nvswitch_device *device 692 ) 693 { 694 return device->hal.nvswitch_is_inforom_supported(device); 695 } 696 697 NvBool 698 nvswitch_is_spi_supported 699 ( 700 nvswitch_device *device 701 ) 702 { 703 return device->hal.nvswitch_is_spi_supported(device); 704 } 705 706 NvBool 707 nvswitch_is_bios_supported 708 ( 709 nvswitch_device *device 710 ) 711 { 712 return device->hal.nvswitch_is_bios_supported(device); 713 } 714 715 NvBool 716 nvswitch_is_smbpbi_supported 717 ( 718 nvswitch_device *device 719 ) 720 { 721 return device->hal.nvswitch_is_smbpbi_supported(device); 722 } 723 724 NvBool 725 nvswitch_is_soe_supported 726 ( 727 nvswitch_device *device 728 ) 729 { 730 if (device->regkeys.soe_disable == NV_SWITCH_REGKEY_SOE_DISABLE_YES) 731 { 732 NVSWITCH_PRINT(device, INFO, "SOE is disabled via regkey.\n"); 733 return NV_FALSE; 734 } 735 736 return device->hal.nvswitch_is_soe_supported(device); 737 } 738 739 740 NvlStatus 741 nvswitch_init_soe 742 ( 743 nvswitch_device *device 744 ) 745 { 746 if (device->regkeys.soe_disable == NV_SWITCH_REGKEY_SOE_DISABLE_YES) 747 { 748 NVSWITCH_PRINT(device, INFO, "SOE is disabled via regkey.\n"); 749 return NV_FALSE; 750 } 751 752 return device->hal.nvswitch_init_soe(device); 753 } 754 755 void 756 nvswitch_soe_init_l2_state 757 ( 758 nvswitch_device *device 759 ) 760 { 761 device->hal.nvswitch_soe_init_l2_state(device); 762 } 763 764 static NvlStatus 765 _nvswitch_construct_soe 766 ( 767 nvswitch_device *device 768 ) 769 { 770 FLCNABLE *pSoe = NULL; 771 NvlStatus retval; 772 773 device->pSoe = pSoe = (PFLCNABLE)soeAllocNew(); 774 if (pSoe == NULL) 775 { 776 NVSWITCH_PRINT(device, ERROR, "SOE allocation failed.\n"); 777 return -NVL_NO_MEM; 778 } 779 780 retval = soeInit(device, (PSOE)pSoe, device->nvlink_device->pciInfo.pciDeviceId); 781 if (retval != NVL_SUCCESS) 782 { 783 NVSWITCH_PRINT(device, ERROR, "SOE init failed.\n"); 784 goto soe_init_failed; 785 } 786 787 if (flcnableConstruct_HAL(device, pSoe) != NV_OK) 788 { 789 NVSWITCH_PRINT(device, ERROR, "FALCON construct failed.\n"); 790 retval = -NVL_ERR_INVALID_STATE; 791 goto flcn_construct_failed; 792 } 793 794 return NVL_SUCCESS; 795 796 flcn_construct_failed: 797 soeDestroy(device, (PSOE)pSoe); 798 799 soe_init_failed: 800 nvswitch_os_free(pSoe); 801 device->pSoe = NULL; 802 803 return retval; 804 } 805 806 static void 807 _nvswitch_destruct_soe 808 ( 809 nvswitch_device *device 810 ) 811 { 812 FLCNABLE *pSoe = device->pSoe; 813 814 if (pSoe == NULL) 815 { 816 return; 817 } 818 819 flcnableDestruct_HAL(device, pSoe); 820 soeDestroy(device, (PSOE)pSoe); 821 822 nvswitch_os_free(pSoe); 823 device->pSoe = NULL; 824 } 825 826 static NvlStatus 827 _nvswitch_initialize_device_state 828 ( 829 nvswitch_device *device 830 ) 831 { 832 return device->hal.nvswitch_initialize_device_state(device); 833 } 834 835 static NvlStatus 836 _nvswitch_post_init_device_setup 837 ( 838 nvswitch_device *device 839 ) 840 { 841 return device->hal.nvswitch_post_init_device_setup(device); 842 } 843 844 static NvlStatus 845 _nvswitch_setup_system_registers 846 ( 847 nvswitch_device *device 848 ) 849 { 850 return device->hal.nvswitch_setup_system_registers(device); 851 } 852 853 static void 854 _nvswitch_post_init_blacklist_device_setup 855 ( 856 nvswitch_device *device 857 ) 858 { 859 device->hal.nvswitch_post_init_blacklist_device_setup(device); 860 } 861 862 static void 863 _nvswitch_set_dma_mask 864 ( 865 nvswitch_device *device 866 ) 867 { 868 NvU32 hw_dma_width, retval; 869 870 hw_dma_width = device->hal.nvswitch_get_device_dma_width(device); 871 872 if (hw_dma_width == 0) 873 { 874 NVSWITCH_PRINT(device, INFO, "DMA is not supported on this device\n"); 875 return; 876 } 877 878 retval = nvswitch_os_set_dma_mask(device->os_handle, hw_dma_width); 879 if (retval == NVL_SUCCESS) 880 { 881 device->dma_addr_width = hw_dma_width; 882 return; 883 } 884 885 NVSWITCH_PRINT(device, SETUP, 886 "%s: Failed to set DMA mask, trying 32-bit fallback : %d\n", 887 __FUNCTION__, retval); 888 889 retval = nvswitch_os_set_dma_mask(device->os_handle, 32); 890 if (retval == NVL_SUCCESS) 891 { 892 device->dma_addr_width = 32; 893 return; 894 } 895 896 // failure is not fatal, the driver will just restrict DMA functionality 897 NVSWITCH_PRINT(device, ERROR, "Failed to set DMA mask : %d\n", retval); 898 } 899 900 NvlStatus 901 nvswitch_deassert_link_reset 902 ( 903 nvswitch_device *device, 904 nvlink_link *link 905 ) 906 { 907 return device->hal.nvswitch_deassert_link_reset(device, link); 908 } 909 910 NvU32 911 nvswitch_get_sublink_width 912 ( 913 nvswitch_device *device, 914 NvU32 linkNumber 915 ) 916 { 917 return device->hal.nvswitch_get_sublink_width(device, linkNumber); 918 } 919 920 static void 921 _nvswitch_unregister_links 922 ( 923 nvswitch_device *device 924 ) 925 { 926 nvlink_link *link = NULL; 927 NvU32 link_num; 928 NvBool is_blacklisted; 929 930 931 if (!NVSWITCH_IS_DEVICE_INITIALIZED(device)) 932 return; 933 934 device->nvlink_device->initialized = 0; 935 is_blacklisted = (device->device_fabric_state == NVSWITCH_DEVICE_FABRIC_STATE_BLACKLISTED); 936 937 for (link_num = 0; link_num < nvswitch_get_num_links(device); link_num++) 938 { 939 if (nvlink_lib_get_link(device->nvlink_device, link_num, &link) == NVL_SUCCESS) 940 { 941 nvlink_lib_unregister_link(link); 942 nvswitch_destroy_link(link); 943 } 944 } 945 946 if (!is_blacklisted) 947 nvswitch_inforom_nvlink_flush(device); 948 } 949 950 NvlStatus NV_API_CALL 951 nvswitch_lib_read_fabric_state 952 ( 953 nvswitch_device *device, 954 NVSWITCH_DEVICE_FABRIC_STATE *device_fabric_state, 955 NVSWITCH_DEVICE_BLACKLIST_REASON *device_blacklist_reason, 956 NVSWITCH_DRIVER_FABRIC_STATE *driver_fabric_state 957 ) 958 { 959 if (!NVSWITCH_IS_DEVICE_ACCESSIBLE(device)) 960 return -NVL_BAD_ARGS; 961 962 if (device_fabric_state != NULL) 963 *device_fabric_state = device->device_fabric_state; 964 965 if (device_blacklist_reason != NULL) 966 *device_blacklist_reason = device->device_blacklist_reason; 967 968 if (driver_fabric_state != NULL) 969 *driver_fabric_state = device->driver_fabric_state; 970 971 return NVL_SUCCESS; 972 } 973 974 static NvlStatus 975 nvswitch_lib_blacklist_device 976 ( 977 nvswitch_device *device, 978 NVSWITCH_DEVICE_BLACKLIST_REASON device_blacklist_reason 979 ) 980 { 981 NvlStatus status; 982 983 if (!NVSWITCH_IS_DEVICE_ACCESSIBLE(device)) 984 { 985 return -NVL_BAD_ARGS; 986 } 987 988 if (device->device_fabric_state == NVSWITCH_DEVICE_FABRIC_STATE_BLACKLISTED) 989 { 990 NVSWITCH_PRINT(device, WARN, "Device is already blacklisted\n"); 991 return -NVL_ERR_NOT_SUPPORTED; 992 } 993 994 device->device_fabric_state = NVSWITCH_DEVICE_FABRIC_STATE_BLACKLISTED; 995 device->device_blacklist_reason = device_blacklist_reason; 996 997 status = device->hal.nvswitch_write_fabric_state(device); 998 if (status != NVL_SUCCESS) 999 NVSWITCH_PRINT(device, INFO, "Cannot send fabric state to SOE\n"); 1000 1001 return NVL_SUCCESS; 1002 } 1003 1004 static NvlStatus 1005 nvswitch_ctrl_blacklist_device( 1006 nvswitch_device *device, 1007 NVSWITCH_BLACKLIST_DEVICE_PARAMS *p 1008 ) 1009 { 1010 NvlStatus status; 1011 1012 status = nvswitch_lib_blacklist_device(device, p->deviceReason); 1013 if (status != NVL_SUCCESS) 1014 return status; 1015 1016 nvswitch_lib_disable_interrupts(device); 1017 1018 // Unregister links from NVLinkCoreLib, so that link training is not 1019 // attempted 1020 _nvswitch_unregister_links(device); 1021 1022 // Keep device registered for HAL access and Fabric State updates 1023 1024 return NVL_SUCCESS; 1025 } 1026 1027 static NvlStatus 1028 nvswitch_ctrl_set_fm_driver_state( 1029 nvswitch_device *device, 1030 NVSWITCH_SET_FM_DRIVER_STATE_PARAMS *p 1031 ) 1032 { 1033 NvU32 prev_fm_status; 1034 1035 if (!NVSWITCH_IS_DEVICE_ACCESSIBLE(device)) 1036 { 1037 return -NVL_BAD_ARGS; 1038 } 1039 1040 prev_fm_status = device->driver_fabric_state; 1041 device->driver_fabric_state = p->driverState; 1042 device->fabric_state_timestamp = nvswitch_os_get_platform_time(); 1043 1044 if (prev_fm_status != p->driverState) 1045 { 1046 if (nvswitch_lib_notify_client_events(device, 1047 NVSWITCH_DEVICE_EVENT_FABRIC_STATE) != NVL_SUCCESS) 1048 { 1049 NVSWITCH_PRINT(device, ERROR, "%s: Failed to notify event\n", 1050 __FUNCTION__); 1051 } 1052 } 1053 1054 return NVL_SUCCESS; 1055 } 1056 1057 static NvlStatus 1058 nvswitch_ctrl_set_device_fabric_state( 1059 nvswitch_device *device, 1060 NVSWITCH_SET_DEVICE_FABRIC_STATE_PARAMS *p 1061 ) 1062 { 1063 if (!NVSWITCH_IS_DEVICE_ACCESSIBLE(device)) 1064 { 1065 return -NVL_BAD_ARGS; 1066 } 1067 1068 if (device->device_fabric_state == NVSWITCH_DEVICE_FABRIC_STATE_BLACKLISTED) 1069 return -NVL_ERR_NOT_SUPPORTED; 1070 1071 device->device_fabric_state = p->deviceState; 1072 device->fabric_state_timestamp = nvswitch_os_get_platform_time(); 1073 1074 // If FM had exceeded timeout, reset the status to not timed-out 1075 if (device->driver_fabric_state == NVSWITCH_DRIVER_FABRIC_STATE_MANAGER_TIMEOUT) 1076 device->driver_fabric_state = NVSWITCH_DRIVER_FABRIC_STATE_CONFIGURED; 1077 1078 return NVL_SUCCESS; 1079 } 1080 1081 static NvlStatus 1082 nvswitch_ctrl_set_fm_timeout( 1083 nvswitch_device *device, 1084 NVSWITCH_SET_FM_HEARTBEAT_TIMEOUT_PARAMS *p 1085 ) 1086 { 1087 if (!NVSWITCH_IS_DEVICE_ACCESSIBLE(device)) 1088 { 1089 return -NVL_BAD_ARGS; 1090 } 1091 1092 device->fm_timeout = p->fmTimeout; 1093 1094 return NVL_SUCCESS; 1095 } 1096 1097 static NvlStatus 1098 _nvswitch_ctrl_register_events( 1099 nvswitch_device *device, 1100 NVSWITCH_REGISTER_EVENTS_PARAMS *p, 1101 void *osPrivate 1102 ) 1103 { 1104 NvlStatus status = NVL_SUCCESS; 1105 NvU32 i; 1106 NvBool many_events, os_descriptor; 1107 void *osDescriptor = osPrivate; 1108 1109 if (!NVSWITCH_IS_DEVICE_ACCESSIBLE(device)) 1110 { 1111 return -NVL_BAD_ARGS; 1112 } 1113 1114 status = nvswitch_os_get_supported_register_events_params(&many_events, 1115 &os_descriptor); 1116 if (status != NVL_SUCCESS) 1117 { 1118 return status; 1119 } 1120 1121 if ((!many_events && (p->numEvents > 1)) || 1122 (p->numEvents == 0)) 1123 { 1124 return -NVL_BAD_ARGS; 1125 } 1126 1127 if (os_descriptor) 1128 { 1129 osDescriptor = (void *) p->osDescriptor; 1130 } 1131 1132 for (i = 0; i < p->numEvents; i++) 1133 { 1134 status = nvswitch_lib_add_client_event(device, osDescriptor, p->eventIds[i]); 1135 if (status != NVL_SUCCESS) 1136 { 1137 NVSWITCH_PRINT(device, ERROR, "%s: Failed to add client event.\n", __FUNCTION__); 1138 return status; 1139 } 1140 } 1141 1142 return NVL_SUCCESS; 1143 } 1144 1145 static NvlStatus 1146 _nvswitch_ctrl_unregister_events( 1147 nvswitch_device *device, 1148 NVSWITCH_UNREGISTER_EVENTS_PARAMS *p, 1149 void *osPrivate 1150 ) 1151 { 1152 NvlStatus status = NVL_SUCCESS; 1153 NvBool many_events, os_descriptor; 1154 void *osDescriptor = osPrivate; 1155 1156 if (!NVSWITCH_IS_DEVICE_ACCESSIBLE(device)) 1157 { 1158 return -NVL_BAD_ARGS; 1159 } 1160 1161 status = nvswitch_os_get_supported_register_events_params(&many_events, 1162 &os_descriptor); 1163 if (status != NVL_SUCCESS) 1164 { 1165 return status; 1166 } 1167 1168 if (os_descriptor) 1169 { 1170 osDescriptor = (void *) p->osDescriptor; 1171 } 1172 1173 status = nvswitch_lib_remove_client_events(device, osDescriptor); 1174 if (status != NVL_SUCCESS) 1175 { 1176 NVSWITCH_PRINT(device, ERROR, "%s: Failed to remove client event.\n", __FUNCTION__); 1177 return status; 1178 } 1179 1180 return NVL_SUCCESS; 1181 } 1182 1183 /* 1184 * @Brief : Sends NACK or drops given inband msg based on message type 1185 * 1186 * @Description : 1187 * 1188 * @param[in] device NvSwitch device to contain this link 1189 * @param[in] linkId Link ID 1190 * @param[in] msghdr Header to the message 1191 * 1192 */ 1193 static void 1194 nvswitch_send_nack_or_drop 1195 ( 1196 nvswitch_device *device, 1197 NvU32 linkId, 1198 nvlink_inband_msg_header_t *msghdr 1199 ) 1200 { 1201 switch(msghdr->type) 1202 { 1203 case NVLINK_INBAND_MSG_TYPE_MC_TEAM_SETUP_REQ: 1204 device->hal.nvswitch_send_inband_nack(device, (NvU32 *)msghdr, linkId); 1205 NVSWITCH_PRINT(device, ERROR, 1206 "Sending NACK for message (type 0x%x)\n", msghdr->type); 1207 return; 1208 default: 1209 // TODO: Add SXid in future if needed. 1210 NVSWITCH_PRINT(device, ERROR, 1211 "Dropping message (type 0x%x)\n", msghdr->type); 1212 return; 1213 } 1214 } 1215 1216 /* 1217 * @Brief : Deletes all the entries in persistent or non-persistent lists. 1218 * Send nacks if requested. 1219 * 1220 * @Description : 1221 * 1222 * @param[in] device NVSwitch device to contain this link 1223 * @param[in] linkId Link number 1224 * @param[in] bSendNack Send nacks if true 1225 * @param[in] bNonPersistentOnly Clear only non-persistent list 1226 */ 1227 static void 1228 _nvswitch_inband_clear_lists 1229 ( 1230 nvswitch_device *device, 1231 NvU32 linkId, 1232 NvBool bSendNack, 1233 NvBool bNonPersistentOnly 1234 ) 1235 { 1236 nvswitch_inband_data_list *curr = NULL; 1237 nvswitch_inband_data_list *next = NULL; 1238 nvlink_inband_msg_header_t *msghdr = NULL; 1239 1240 nvListForEachEntry_safe(curr, next, 1241 &device->link[linkId].inbandData.nonpersistent_list, entry) 1242 { 1243 if (bSendNack) 1244 { 1245 msghdr = (nvlink_inband_msg_header_t *)curr->data; 1246 nvswitch_send_nack_or_drop(device, linkId, msghdr); 1247 } 1248 1249 nvListDel(&curr->entry); 1250 nvswitch_os_free(curr); 1251 } 1252 1253 if (bNonPersistentOnly) 1254 return; 1255 1256 nvListForEachEntry_safe(curr, next, 1257 &device->link[linkId].inbandData.persistent_list, entry) 1258 { 1259 if (bSendNack) 1260 { 1261 msghdr = (nvlink_inband_msg_header_t *)curr->data; 1262 nvswitch_send_nack_or_drop(device, linkId, msghdr); 1263 } 1264 1265 nvListDel(&curr->entry); 1266 nvswitch_os_free(curr); 1267 } 1268 } 1269 1270 static void 1271 nvswitch_fabric_state_heartbeat( 1272 nvswitch_device *device 1273 ) 1274 { 1275 NvU64 age; 1276 NvU32 linkId; 1277 1278 if (!NVSWITCH_IS_DEVICE_VALID(device)) 1279 return; 1280 1281 age = nvswitch_os_get_platform_time() - device->fabric_state_timestamp; 1282 1283 // Check to see if we have exceeded the FM timeout 1284 if (device->driver_fabric_state == NVSWITCH_DRIVER_FABRIC_STATE_CONFIGURED && 1285 age > (NvU64)device->fm_timeout * 1000ULL * 1000ULL) 1286 device->driver_fabric_state = NVSWITCH_DRIVER_FABRIC_STATE_MANAGER_TIMEOUT; 1287 1288 // 1289 // If FM is not running, clear pending non-persistent messages. Persistent 1290 // messages can be processed by the FM when it restarts. 1291 // 1292 if (device->driver_fabric_state != NVSWITCH_DRIVER_FABRIC_STATE_CONFIGURED) 1293 { 1294 for (linkId = 0; linkId < nvswitch_get_num_links(device); linkId++) 1295 _nvswitch_inband_clear_lists(device, linkId, 1296 NV_TRUE /* Nack */, 1297 NV_TRUE /* Non-persistent only */); 1298 } 1299 1300 (void)device->hal.nvswitch_write_fabric_state(device); 1301 } 1302 1303 static NvlStatus 1304 _nvswitch_ctrl_set_training_error_info 1305 ( 1306 nvswitch_device *device, 1307 NVSWITCH_SET_TRAINING_ERROR_INFO_PARAMS *p 1308 ) 1309 { 1310 return device->hal.nvswitch_set_training_error_info(device, p); 1311 } 1312 1313 static NvlStatus 1314 _nvswitch_ctrl_get_fatal_error_scope 1315 ( 1316 nvswitch_device *device, 1317 NVSWITCH_GET_FATAL_ERROR_SCOPE_PARAMS *pParams 1318 ) 1319 { 1320 return device->hal.nvswitch_ctrl_get_fatal_error_scope(device, pParams); 1321 } 1322 1323 static NvlStatus 1324 _nvswitch_ctrl_therm_get_temperature_limit 1325 ( 1326 nvswitch_device *device, 1327 NVSWITCH_CTRL_GET_TEMPERATURE_LIMIT_PARAMS *pParams 1328 ) 1329 { 1330 if (!NVSWITCH_IS_DEVICE_ACCESSIBLE(device)) 1331 { 1332 return -NVL_BAD_ARGS; 1333 } 1334 1335 return device->hal.nvswitch_ctrl_therm_get_temperature_limit(device, pParams); 1336 } 1337 1338 NvlStatus 1339 nvswitch_lib_initialize_device 1340 ( 1341 nvswitch_device *device 1342 ) 1343 { 1344 NvlStatus retval = NVL_SUCCESS; 1345 NvU8 link_num; 1346 nvlink_link *link = NULL; 1347 NvBool is_blacklisted_by_os = NV_FALSE; 1348 NvU64 mode; 1349 1350 if (!NVSWITCH_IS_DEVICE_ACCESSIBLE(device)) 1351 { 1352 return -NVL_BAD_ARGS; 1353 } 1354 1355 if (NVSWITCH_IS_DEVICE_INITIALIZED(device)) 1356 { 1357 NVSWITCH_PRINT(device, SETUP, "Device is already initialized!\n"); 1358 return NVL_SUCCESS; 1359 } 1360 1361 NVSWITCH_PRINT(device, SETUP, 1362 "Initializing nvswitch at (%04x:%02x:%02x.%02x)\n", 1363 device->nvlink_device->pciInfo.domain, 1364 device->nvlink_device->pciInfo.bus, 1365 device->nvlink_device->pciInfo.device, 1366 device->nvlink_device->pciInfo.function); 1367 1368 nvListInit(&device->client_events_list); 1369 1370 for (link_num=0; link_num < nvswitch_get_num_links(device); link_num++) 1371 { 1372 nvListInit(&device->link[link_num].inbandData.persistent_list); 1373 nvListInit(&device->link[link_num].inbandData.nonpersistent_list); 1374 } 1375 1376 retval = nvswitch_lib_load_platform_info(device); 1377 if (retval != NVL_SUCCESS) 1378 { 1379 NVSWITCH_PRINT(device, ERROR, "Failed to load platform information\n"); 1380 return retval; 1381 } 1382 1383 if (nvswitch_is_soe_supported(device)) 1384 { 1385 retval = _nvswitch_construct_soe(device); 1386 if (retval != NVL_SUCCESS) 1387 { 1388 return retval; 1389 } 1390 } 1391 else 1392 { 1393 NVSWITCH_PRINT(device, INFO, "SOE is not supported, skipping construct\n"); 1394 } 1395 1396 _nvswitch_set_dma_mask(device); 1397 1398 retval = _nvswitch_initialize_device_state(device); 1399 if (NVL_SUCCESS != retval) 1400 { 1401 NVSWITCH_PRINT(device, ERROR, 1402 "Failed to initialize device state: %d!\n", 1403 retval); 1404 goto nvswitch_initialize_device_state_fail; 1405 } 1406 1407 device->hal.nvswitch_load_uuid(device); 1408 1409 /* 1410 * Check module parameters for blacklisted device 1411 */ 1412 if (nvswitch_os_is_uuid_in_blacklist(&device->uuid) == NV_TRUE) 1413 { 1414 NVSWITCH_PRINT(device, SETUP, 1415 "Blacklisted nvswitch at (%04x:%02x:%02x.%02x)\n", 1416 device->nvlink_device->pciInfo.domain, 1417 device->nvlink_device->pciInfo.bus, 1418 device->nvlink_device->pciInfo.device, 1419 device->nvlink_device->pciInfo.function); 1420 is_blacklisted_by_os = NV_TRUE; 1421 // initialization continues until we have updated InfoROM... 1422 } 1423 1424 if (nvswitch_is_inforom_supported(device)) 1425 { 1426 retval = nvswitch_initialize_inforom(device); 1427 if (NVL_SUCCESS != retval) 1428 { 1429 NVSWITCH_PRINT(device, ERROR, 1430 "Failed to initialize InfoROM rc: %d\n", 1431 retval); 1432 goto nvswitch_initialize_device_state_fail; 1433 } 1434 1435 retval = nvswitch_initialize_inforom_objects(device); 1436 if (NVL_SUCCESS != retval) 1437 { 1438 NVSWITCH_PRINT(device, ERROR, 1439 "Failed to initialize InfoROM objects! rc:%d\n", 1440 retval); 1441 goto nvswitch_initialize_inforom_fail; 1442 } 1443 } 1444 else 1445 { 1446 NVSWITCH_PRINT(device, INFO, 1447 "InfoROM is not supported, skipping init\n"); 1448 } 1449 1450 (void)device->hal.nvswitch_read_oob_blacklist_state(device); 1451 (void)device->hal.nvswitch_write_fabric_state(device); 1452 1453 nvswitch_task_create(device, &nvswitch_fabric_state_heartbeat, 1454 NVSWITCH_HEARTBEAT_INTERVAL_NS, 1455 NVSWITCH_TASK_TYPE_FLAGS_RUN_EVEN_IF_DEVICE_NOT_INITIALIZED); 1456 1457 // 1458 // Blacklisted devices return successfully in order to preserve the fabric state heartbeat 1459 // and ensure OOB utilities don't think the driver has died 1460 // 1461 if (device->device_blacklist_reason == NVSWITCH_DEVICE_BLACKLIST_REASON_MANUAL_OUT_OF_BAND) 1462 { 1463 NVSWITCH_PRINT(device, SETUP, 1464 "Blacklisted nvswitch at (%04x:%02x:%02x.%02x)\n", 1465 device->nvlink_device->pciInfo.domain, 1466 device->nvlink_device->pciInfo.bus, 1467 device->nvlink_device->pciInfo.device, 1468 device->nvlink_device->pciInfo.function); 1469 return NVL_SUCCESS; 1470 } 1471 1472 if (is_blacklisted_by_os) 1473 { 1474 (void)nvswitch_lib_blacklist_device(device, NVSWITCH_DEVICE_BLACKLIST_REASON_MANUAL_IN_BAND); 1475 return NVL_SUCCESS; 1476 } 1477 1478 for (link_num=0; link_num < nvswitch_get_num_links(device); link_num++) 1479 { 1480 if (!nvswitch_is_link_valid(device, link_num)) 1481 { 1482 continue; 1483 } 1484 1485 retval = nvswitch_create_link(device, link_num, &link); 1486 if (NVL_SUCCESS != retval) 1487 { 1488 NVSWITCH_PRINT(device, ERROR, 1489 "Failed to create link %d : %d!\n", 1490 link_num, 1491 retval); 1492 goto nvswitch_link_fail; 1493 } 1494 1495 retval = nvlink_lib_register_link(device->nvlink_device, link); 1496 if (NVL_SUCCESS != retval) 1497 { 1498 NVSWITCH_PRINT(device, ERROR, 1499 "Failed to register link %d with the nvlink core : %d!\n", 1500 link_num, 1501 retval); 1502 1503 // Free the single dangling link. 1504 nvswitch_destroy_link(link); 1505 1506 goto nvswitch_link_fail; 1507 } 1508 1509 nvswitch_reset_persistent_link_hw_state(device, link_num); 1510 1511 if(_nvswitch_corelib_get_dl_link_mode(link, &mode) != NVL_SUCCESS) 1512 { 1513 NVSWITCH_PRINT(device, ERROR, "%s: nvlipt_lnk_status: Failed to check link mode! LinkId %d\n", 1514 __FUNCTION__, link_num); 1515 } 1516 else if(mode == NVLINK_LINKSTATE_FAULT) 1517 { 1518 NVSWITCH_PRINT(device, INFO, "%s: retraining LinkId %d\n", 1519 __FUNCTION__, link_num); 1520 nvswitch_reset_and_train_link(device, link); 1521 } 1522 1523 } 1524 1525 retval = nvswitch_set_training_mode(device); 1526 1527 if (retval != NVL_SUCCESS) 1528 { 1529 NVSWITCH_PRINT(device, ERROR, "Failed to determine link training mode! rc: %d\n", retval); 1530 goto nvswitch_link_fail; 1531 } 1532 // Initialize select scratch registers to 0x0 1533 device->hal.nvswitch_init_scratch(device); 1534 1535 retval = nvswitch_construct_error_log(&device->log_FATAL_ERRORS, 1024, NV_FALSE); 1536 if (retval != NVL_SUCCESS) 1537 { 1538 NVSWITCH_PRINT(device, ERROR, "Failed to construct log_FATAL_ERRORS! rc: %d\n", retval); 1539 goto nvswitch_construct_error_log_fail; 1540 } 1541 1542 retval = nvswitch_construct_error_log(&device->log_NONFATAL_ERRORS, 1024, NV_TRUE); 1543 if (retval != NVL_SUCCESS) 1544 { 1545 NVSWITCH_PRINT(device, ERROR, "Failed to construct log_NONFATAL_ERRORS! rc: %d\n", retval); 1546 goto nvswitch_construct_error_log_fail; 1547 } 1548 1549 if (device->regkeys.latency_counter == NV_SWITCH_REGKEY_LATENCY_COUNTER_LOGGING_ENABLE) 1550 { 1551 nvswitch_task_create(device, &nvswitch_internal_latency_bin_log, 1552 nvswitch_get_latency_sample_interval_msec(device) * NVSWITCH_INTERVAL_1MSEC_IN_NS * 9/10, 0); 1553 } 1554 1555 nvswitch_task_create(device, &nvswitch_ecc_writeback_task, 1556 (60 * NVSWITCH_INTERVAL_1SEC_IN_NS), 0); 1557 1558 if (IS_RTLSIM(device) || IS_EMULATION(device) || IS_FMODEL(device)) 1559 { 1560 NVSWITCH_PRINT(device, WARN, 1561 "%s: Skipping setup of NvSwitch thermal alert monitoring\n", 1562 __FUNCTION__); 1563 } 1564 else 1565 { 1566 nvswitch_task_create(device, &nvswitch_monitor_thermal_alert, 1567 100*NVSWITCH_INTERVAL_1MSEC_IN_NS, 0); 1568 } 1569 1570 device->nvlink_device->initialized = 1; 1571 1572 return NVL_SUCCESS; 1573 1574 nvswitch_construct_error_log_fail: 1575 //free allocated memory to avoid leaking 1576 nvswitch_destroy_error_log(device, &device->log_FATAL_ERRORS); 1577 nvswitch_destroy_error_log(device, &device->log_NONFATAL_ERRORS); 1578 1579 nvswitch_link_fail: 1580 // Track down all links that successfully registered. 1581 for (link_num = 0; link_num < nvswitch_get_num_links(device); link_num++) 1582 { 1583 if (nvlink_lib_get_link(device->nvlink_device, link_num, &link) == NVL_SUCCESS) 1584 { 1585 nvlink_lib_unregister_link(link); 1586 nvswitch_destroy_link(link); 1587 } 1588 } 1589 1590 nvswitch_destroy_inforom_objects(device); 1591 1592 nvswitch_initialize_inforom_fail: 1593 nvswitch_destroy_inforom(device); 1594 1595 nvswitch_initialize_device_state_fail: 1596 _nvswitch_destruct_soe(device); 1597 nvswitch_tasks_destroy(device); 1598 1599 return retval; 1600 } 1601 1602 NvBool 1603 nvswitch_lib_validate_device_id 1604 ( 1605 NvU32 device_id 1606 ) 1607 { 1608 if (nvswitch_is_lr10_device_id(device_id)) 1609 { 1610 return NV_TRUE; 1611 } 1612 if (nvswitch_is_ls10_device_id(device_id)) 1613 { 1614 return NV_TRUE; 1615 } 1616 return NV_FALSE; 1617 } 1618 1619 NvlStatus 1620 nvswitch_lib_post_init_device 1621 ( 1622 nvswitch_device *device 1623 ) 1624 { 1625 NvlStatus retval; 1626 1627 if (!NVSWITCH_IS_DEVICE_INITIALIZED(device)) 1628 { 1629 return -NVL_ERR_INVALID_STATE; 1630 } 1631 1632 retval = _nvswitch_post_init_device_setup(device); 1633 if (retval != NVL_SUCCESS) 1634 { 1635 return retval; 1636 } 1637 1638 if (nvswitch_is_bios_supported(device)) 1639 { 1640 retval = nvswitch_bios_get_image(device); 1641 if (retval != NVL_SUCCESS) 1642 { 1643 return retval; 1644 } 1645 1646 retval = nvswitch_parse_bios_image(device); 1647 if (retval != NVL_SUCCESS) 1648 { 1649 return retval; 1650 } 1651 } 1652 else 1653 { 1654 NVSWITCH_PRINT(device, ERROR, 1655 "%s: Skipping BIOS parsing since BIOS is unsupported.\n", 1656 __FUNCTION__); 1657 } 1658 1659 retval = _nvswitch_setup_system_registers(device); 1660 if (retval != NVL_SUCCESS) 1661 { 1662 return retval; 1663 } 1664 1665 nvswitch_smbpbi_post_init(device); 1666 1667 (void)nvswitch_launch_ALI(device); 1668 1669 return NVL_SUCCESS; 1670 } 1671 1672 void 1673 nvswitch_lib_post_init_blacklist_device 1674 ( 1675 nvswitch_device *device 1676 ) 1677 { 1678 _nvswitch_post_init_blacklist_device_setup(device); 1679 } 1680 1681 void 1682 _nvswitch_check_pending_data_and_notify 1683 ( 1684 nvswitch_device *device, 1685 NVSWITCH_CLIENT_EVENT *event 1686 ) 1687 { 1688 switch (event->eventId) 1689 { 1690 case NVSWITCH_DEVICE_EVENT_INBAND_DATA: 1691 { 1692 NvU32 i; 1693 1694 for (i = 0; i < nvswitch_get_num_links(device); i++) 1695 { 1696 if (!nvListIsEmpty(&device->link[i].inbandData.persistent_list) || 1697 !nvListIsEmpty(&device->link[i].inbandData.nonpersistent_list)) 1698 { 1699 (void)nvswitch_os_notify_client_event(device->os_handle, 1700 event->private_driver_data, 1701 event->eventId); 1702 } 1703 } 1704 break; 1705 } 1706 1707 default: 1708 return; 1709 } 1710 } 1711 1712 /*! 1713 * @brief: Gets the client event associated with the file descriptor 1714 * if it already exists in the Device's client event list. 1715 * 1716 * If found, and if there is pending data for the event, 1717 * the event is triggered before returning to unblock the 1718 * client right away. 1719 */ 1720 NvlStatus 1721 nvswitch_lib_get_client_event 1722 ( 1723 nvswitch_device *device, 1724 void *osPrivate, 1725 NVSWITCH_CLIENT_EVENT **ppClientEvent 1726 ) 1727 { 1728 NVSWITCH_CLIENT_EVENT *curr = NULL; 1729 1730 *ppClientEvent = NULL; 1731 1732 if(!NVSWITCH_IS_DEVICE_VALID(device)) 1733 { 1734 return -NVL_BAD_ARGS; 1735 } 1736 1737 nvListForEachEntry(curr, &device->client_events_list, entry) 1738 { 1739 if (curr->private_driver_data == osPrivate) 1740 { 1741 *ppClientEvent = curr; 1742 _nvswitch_check_pending_data_and_notify(device, curr); 1743 return NVL_SUCCESS; 1744 } 1745 } 1746 1747 return -NVL_NOT_FOUND; 1748 } 1749 1750 /*! 1751 * @brief: Adds an event to the front of the 1752 * Device's client event list. 1753 */ 1754 NvlStatus 1755 nvswitch_lib_add_client_event 1756 ( 1757 nvswitch_device *device, 1758 void *osPrivate, 1759 NvU32 eventId 1760 ) 1761 { 1762 NVSWITCH_CLIENT_EVENT *newEvent; 1763 NvlStatus status = NVL_SUCCESS; 1764 1765 if (!NVSWITCH_IS_DEVICE_VALID(device)) 1766 { 1767 return -NVL_BAD_ARGS; 1768 } 1769 1770 if (eventId >= NVSWITCH_DEVICE_EVENT_COUNT) 1771 { 1772 NVSWITCH_PRINT(device, ERROR, "%s: Invalid event Id.\n", __FUNCTION__); 1773 return -NVL_BAD_ARGS; 1774 } 1775 1776 // Invoke OS specific API to add event. 1777 status = nvswitch_os_add_client_event(device->os_handle, 1778 osPrivate, 1779 eventId); 1780 if (status != NVL_SUCCESS) 1781 { 1782 NVSWITCH_PRINT(device, ERROR, "%s: Failed to add client event.\n", __FUNCTION__); 1783 return status; 1784 } 1785 1786 newEvent = nvswitch_os_malloc(sizeof(*newEvent)); 1787 if (newEvent == NULL) 1788 { 1789 return -NVL_NO_MEM; 1790 } 1791 1792 newEvent->eventId = eventId; 1793 newEvent->private_driver_data = osPrivate; 1794 1795 nvListAdd(&newEvent->entry, &device->client_events_list); 1796 1797 return NVL_SUCCESS; 1798 } 1799 1800 /*! 1801 * @brief: Removes all events corresponding to osPrivate, 1802 * from the Device's client event list. 1803 */ 1804 NvlStatus 1805 nvswitch_lib_remove_client_events 1806 ( 1807 nvswitch_device *device, 1808 void *osPrivate 1809 ) 1810 { 1811 NVSWITCH_CLIENT_EVENT *curr = NULL; 1812 NVSWITCH_CLIENT_EVENT *next = NULL; 1813 NvlStatus status = NVL_SUCCESS; 1814 1815 // 1816 // Device shutdown may happen before this is called, so return 1817 // if device is gone 1818 // 1819 if (!NVSWITCH_IS_DEVICE_VALID(device)) 1820 { 1821 return NVL_SUCCESS; 1822 } 1823 1824 nvListForEachEntry_safe(curr, next, &device->client_events_list, entry) 1825 { 1826 if (curr->private_driver_data == osPrivate) 1827 { 1828 nvListDel(&curr->entry); 1829 nvswitch_os_free(curr); 1830 } 1831 } 1832 1833 // Invoke OS specific API to remove event. 1834 status = nvswitch_os_remove_client_event(device->os_handle, 1835 osPrivate); 1836 if (status != NVL_SUCCESS) 1837 { 1838 NVSWITCH_PRINT(device, ERROR, "%s: Failed to remove client events.\n", __FUNCTION__); 1839 return status; 1840 } 1841 1842 return NVL_SUCCESS; 1843 } 1844 1845 /*! 1846 * @brief: Notifies all events with matching event id in the 1847 * Device's client event list. 1848 */ 1849 NvlStatus 1850 nvswitch_lib_notify_client_events 1851 ( 1852 nvswitch_device *device, 1853 NvU32 eventId 1854 ) 1855 { 1856 NvlStatus status; 1857 NVSWITCH_CLIENT_EVENT *curr = NULL; 1858 1859 if (!NVSWITCH_IS_DEVICE_VALID(device)) 1860 { 1861 return -NVL_BAD_ARGS; 1862 } 1863 1864 if (eventId >= NVSWITCH_DEVICE_EVENT_COUNT) 1865 { 1866 NVSWITCH_PRINT(device, ERROR, "%s: Invalid event Id.\n", __FUNCTION__); 1867 return -NVL_BAD_ARGS; 1868 } 1869 1870 nvListForEachEntry(curr, &device->client_events_list, entry) 1871 { 1872 if (curr->eventId == eventId) 1873 { 1874 // OS specific event notification. 1875 status = nvswitch_os_notify_client_event(device->os_handle, 1876 curr->private_driver_data, 1877 eventId); 1878 if (status != NVL_SUCCESS) 1879 { 1880 return status; 1881 } 1882 } 1883 } 1884 1885 return NVL_SUCCESS; 1886 } 1887 1888 /*! 1889 @brief: Release ROM image from memory. 1890 */ 1891 void 1892 _nvswitch_destroy_rom(nvswitch_device *device) 1893 { 1894 if (device->biosImage.pImage != NULL) 1895 { 1896 nvswitch_os_free(device->biosImage.pImage); 1897 device->biosImage.pImage = NULL; 1898 } 1899 } 1900 1901 /*! 1902 * @brief: Free the device's client event list 1903 */ 1904 static void 1905 _nvswitch_destroy_event_list(nvswitch_device *device) 1906 { 1907 NVSWITCH_CLIENT_EVENT *curr = NULL; 1908 NVSWITCH_CLIENT_EVENT *next = NULL; 1909 1910 nvListForEachEntry_safe(curr, next, &device->client_events_list, entry) 1911 { 1912 nvListDel(&curr->entry); 1913 nvswitch_os_free(curr); 1914 } 1915 } 1916 1917 NvlStatus 1918 nvswitch_lib_shutdown_device 1919 ( 1920 nvswitch_device *device 1921 ) 1922 { 1923 NVSWITCH_INBAND_FLUSH_DATA_PARAMS p; 1924 1925 if (!NVSWITCH_IS_DEVICE_ACCESSIBLE(device)) 1926 { 1927 return -NVL_BAD_ARGS; 1928 } 1929 1930 // 1931 // Set fabric state to offline 1932 // 1933 if (device->device_fabric_state != NVSWITCH_DEVICE_FABRIC_STATE_BLACKLISTED) 1934 device->device_fabric_state = NVSWITCH_DEVICE_FABRIC_STATE_OFFLINE; 1935 device->driver_fabric_state = NVSWITCH_DRIVER_FABRIC_STATE_OFFLINE; 1936 (void)device->hal.nvswitch_write_fabric_state(device); 1937 1938 nvswitch_hw_counter_shutdown(device); 1939 1940 // FLUSH any pending messages to avoid memory leaks 1941 p.linkMask = nvswitch_get_enabled_link_mask(device); 1942 _nvswitch_ctrl_inband_flush_data(device, &p); 1943 1944 _nvswitch_unregister_links(device); 1945 1946 nvswitch_destroy_error_log(device, &device->log_FATAL_ERRORS); 1947 nvswitch_destroy_error_log(device, &device->log_NONFATAL_ERRORS); 1948 1949 nvswitch_smbpbi_unload(device); 1950 _nvswitch_destroy_event_list(device); 1951 1952 nvswitch_destroy_inforom_objects(device); 1953 nvswitch_destroy_inforom(device); 1954 1955 nvswitch_smbpbi_destroy(device); 1956 1957 nvswitch_destroy_device_state(device); 1958 1959 _nvswitch_destroy_rom(device); 1960 1961 _nvswitch_destruct_soe(device); 1962 1963 nvswitch_tasks_destroy(device); 1964 1965 return NVL_SUCCESS; 1966 } 1967 1968 NvlStatus 1969 nvswitch_lib_get_log_count 1970 ( 1971 nvswitch_device *device, 1972 NvU32 *fatal, NvU32 *nonfatal 1973 ) 1974 { 1975 if (!NVSWITCH_IS_DEVICE_INITIALIZED(device) || 1976 fatal == NULL || nonfatal == NULL) 1977 { 1978 return -NVL_BAD_ARGS; 1979 } 1980 1981 *fatal = device->log_FATAL_ERRORS.error_count; 1982 *nonfatal = device->log_NONFATAL_ERRORS.error_count; 1983 // No report of log_INFO currently 1984 1985 return NVL_SUCCESS; 1986 } 1987 1988 NvlStatus 1989 nvswitch_lib_load_platform_info 1990 ( 1991 nvswitch_device *device 1992 ) 1993 { 1994 if (!NVSWITCH_IS_DEVICE_ACCESSIBLE(device)) 1995 { 1996 return -NVL_BAD_ARGS; 1997 } 1998 1999 device->hal.nvswitch_determine_platform(device); 2000 2001 return NVL_SUCCESS; 2002 } 2003 2004 void 2005 nvswitch_lib_get_device_info 2006 ( 2007 nvswitch_device *device, 2008 struct nvlink_pci_info **pciInfo 2009 ) 2010 { 2011 if (!NVSWITCH_IS_DEVICE_VALID(device) || pciInfo == NULL) 2012 { 2013 NVSWITCH_ASSERT(0); 2014 return; 2015 } 2016 2017 *pciInfo = &device->nvlink_device->pciInfo; 2018 } 2019 2020 NvlStatus 2021 nvswitch_lib_get_bios_version 2022 ( 2023 nvswitch_device *device, 2024 NvU64 *version 2025 ) 2026 { 2027 NVSWITCH_GET_BIOS_INFO_PARAMS p = { 0 }; 2028 NvlStatus ret; 2029 2030 if (!device) 2031 return -NVL_BAD_ARGS; 2032 2033 ret = device->hal.nvswitch_ctrl_get_bios_info(device, &p); 2034 2035 if (version != NULL) 2036 { 2037 *version = p.version; 2038 } 2039 2040 return ret; 2041 } 2042 2043 NvlStatus 2044 nvswitch_lib_use_pin_irq 2045 ( 2046 nvswitch_device *device 2047 ) 2048 { 2049 return IS_FMODEL(device); 2050 } 2051 2052 2053 NvlStatus 2054 nvswitch_lib_register_device 2055 ( 2056 NvU16 pci_domain, 2057 NvU8 pci_bus, 2058 NvU8 pci_device, 2059 NvU8 pci_func, 2060 NvU16 pci_device_id, 2061 void *os_handle, 2062 NvU32 os_instance, 2063 nvswitch_device **return_device 2064 ) 2065 { 2066 nvswitch_device *device = NULL; 2067 nvlink_device *coreDev = NULL; 2068 NvlStatus retval = NVL_SUCCESS; 2069 2070 if (!nvlink_lib_is_initialized()) 2071 { 2072 NVSWITCH_PRINT(device, ERROR, 2073 "NVLink core lib isn't initialized yet!\n"); 2074 return -NVL_INITIALIZATION_TOTAL_FAILURE; 2075 } 2076 2077 if (return_device == NULL || os_handle == NULL) 2078 { 2079 return -NVL_BAD_ARGS; 2080 } 2081 2082 *return_device = NULL; 2083 2084 device = nvswitch_os_malloc(sizeof(*device)); 2085 if (NULL == device) 2086 { 2087 NVSWITCH_PRINT(device, ERROR, 2088 "nvswitch_os_malloc during device creation failed!\n"); 2089 return -NVL_NO_MEM; 2090 } 2091 nvswitch_os_memset(device, 0, sizeof(*device)); 2092 2093 nvswitch_os_snprintf(device->name, sizeof(device->name), 2094 NVSWITCH_DEVICE_NAME "%d", os_instance); 2095 2096 coreDev = nvswitch_os_malloc(sizeof(*coreDev)); 2097 if (NULL == coreDev) 2098 { 2099 NVSWITCH_PRINT(device, ERROR, 2100 "nvswitch_os_malloc during device creation failed!\n"); 2101 2102 retval = -NVL_NO_MEM; 2103 goto nvlink_lib_register_device_fail; 2104 } 2105 nvswitch_os_memset(coreDev, 0, sizeof(*coreDev)); 2106 2107 coreDev->driverName = 2108 nvswitch_os_malloc(sizeof(NVSWITCH_DRIVER_NAME)); 2109 if (coreDev->driverName == NULL) 2110 { 2111 NVSWITCH_PRINT(device, ERROR, 2112 "nvswitch_os_malloc during device creation failed!\n"); 2113 2114 retval = -NVL_NO_MEM; 2115 goto nvlink_lib_register_device_fail; 2116 } 2117 nvswitch_os_memcpy(coreDev->driverName, NVSWITCH_DRIVER_NAME, 2118 sizeof(NVSWITCH_DRIVER_NAME)); 2119 2120 device->os_handle = os_handle; 2121 device->os_instance = os_instance; 2122 2123 device->nvlink_device = coreDev; 2124 device->nvlink_device->deviceName = device->name; 2125 device->nvlink_device->uuid = NULL; // No UUID support for switch 2126 2127 device->nvlink_device->pciInfo.domain = pci_domain; 2128 device->nvlink_device->pciInfo.bus = pci_bus; 2129 device->nvlink_device->pciInfo.device = pci_device; 2130 device->nvlink_device->pciInfo.function = pci_func; 2131 device->nvlink_device->pciInfo.pciDeviceId = pci_device_id; 2132 2133 // nvlink_device has a back pointer to nvswitch_device 2134 device->nvlink_device->pDevInfo = device; 2135 device->nvlink_device->type = NVLINK_DEVICE_TYPE_NVSWITCH; 2136 2137 // 2138 // Initialize the Fabric State 2139 // 2140 device->fm_timeout = NVSWITCH_DEFAULT_FM_HEARTBEAT_TIMEOUT_MSEC; 2141 device->fabric_state_sequence_number = 0; 2142 device->driver_fabric_state = NVSWITCH_DRIVER_FABRIC_STATE_STANDBY; 2143 device->device_fabric_state = NVSWITCH_DEVICE_FABRIC_STATE_STANDBY; 2144 device->device_blacklist_reason = NVSWITCH_DEVICE_BLACKLIST_REASON_NONE; 2145 2146 // 2147 // Initialize HAL connectivity as early as possible so that other lib 2148 // interfaces can work. 2149 // 2150 retval = _nvswitch_setup_hal(device, device->nvlink_device->pciInfo.pciDeviceId); 2151 if (retval != NVL_SUCCESS) 2152 { 2153 goto nvlink_lib_register_device_fail; 2154 } 2155 2156 // 2157 // Initialize regkeys as early as possible so that most routines can take 2158 // advantage of them. 2159 // 2160 _nvswitch_init_device_regkeys(device); 2161 2162 // After regkeys have been set then only set the enableALI field. 2163 device->nvlink_device->enableALI = (device->regkeys.link_training_mode == 2164 NV_SWITCH_REGKEY_LINK_TRAINING_SELECT_ALI) ? NV_TRUE:NV_FALSE; 2165 2166 retval = nvlink_lib_register_device(device->nvlink_device); 2167 if (NVL_SUCCESS != retval) 2168 { 2169 NVSWITCH_PRINT(device, ERROR, 2170 "nvlinklib register device failed!\n"); 2171 goto nvlink_lib_register_device_fail; 2172 } 2173 2174 *return_device = device; 2175 2176 NVSWITCH_PRINT(device, SETUP, 2177 "Successfully registered with nvlinkcore\n"); 2178 2179 return retval; 2180 2181 nvlink_lib_register_device_fail: 2182 2183 if (NULL != coreDev) 2184 { 2185 nvswitch_os_free(coreDev->driverName); 2186 nvswitch_os_free(coreDev); 2187 } 2188 2189 if (NULL != device) 2190 nvswitch_os_free(device); 2191 2192 return retval; 2193 } 2194 2195 void 2196 nvswitch_lib_unregister_device 2197 ( 2198 nvswitch_device *device 2199 ) 2200 { 2201 if (!NVSWITCH_IS_DEVICE_VALID(device)) 2202 { 2203 NVSWITCH_ASSERT(0); 2204 return; 2205 } 2206 2207 nvlink_lib_unregister_device(device->nvlink_device); 2208 2209 nvswitch_os_free(device->nvlink_device->driverName); 2210 nvswitch_os_free(device->nvlink_device); 2211 nvswitch_os_free(device); 2212 2213 return; 2214 } 2215 2216 /*! 2217 * @brief: Gets the mask of valid I2C ports on the 2218 * Device. 2219 */ 2220 NvlStatus 2221 nvswitch_lib_get_valid_ports_mask 2222 ( 2223 nvswitch_device *device, 2224 NvU32 *validPortsMask 2225 ) 2226 { 2227 NvU32 port_info; 2228 NvU32 i; 2229 NvU32 ports_mask = 0; 2230 NvBool is_i2c_access_allowed; 2231 NvBool is_port_allowed; 2232 2233 if (!NVSWITCH_IS_DEVICE_VALID(device) || 2234 (validPortsMask == NULL)) 2235 { 2236 return -NVL_BAD_ARGS; 2237 } 2238 2239 is_i2c_access_allowed = (device->regkeys.i2c_access_control == 2240 NV_SWITCH_REGKEY_I2C_ACCESS_CONTROL_ENABLE) ? 2241 NV_TRUE : NV_FALSE; 2242 2243 for (i = 0; i < NVSWITCH_MAX_I2C_PORTS; i++) 2244 { 2245 port_info = nvswitch_i2c_get_port_info(device, i); 2246 2247 is_port_allowed = is_i2c_access_allowed ? NV_TRUE : 2248 FLD_TEST_DRF(_I2C, _PORTINFO, _ACCESS_ALLOWED, _TRUE, 2249 port_info); 2250 2251 if (is_port_allowed && 2252 FLD_TEST_DRF(_I2C, _PORTINFO, _DEFINED, _PRESENT, port_info)) 2253 { 2254 ports_mask |= NVBIT(i); 2255 } 2256 } 2257 2258 *validPortsMask = ports_mask; 2259 return NVL_SUCCESS; 2260 } 2261 2262 /*! 2263 * @brief: Returns if the I2C transactions are supported. 2264 */ 2265 NvBool 2266 nvswitch_lib_is_i2c_supported 2267 ( 2268 nvswitch_device *device 2269 ) 2270 { 2271 if (!NVSWITCH_IS_DEVICE_VALID(device)) 2272 { 2273 NVSWITCH_ASSERT(0); 2274 return NV_FALSE; 2275 } 2276 2277 return nvswitch_is_i2c_supported(device); 2278 } 2279 2280 static NvlStatus 2281 _nvswitch_perform_i2c_transfer 2282 ( 2283 nvswitch_device *device, 2284 NvU32 client, 2285 NvU8 type, 2286 NvU16 addr, 2287 NvU8 port, 2288 NvU8 cmd, 2289 NvU32 msgLength, 2290 NvU8 *pData 2291 ) 2292 { 2293 NvlStatus status; 2294 NvU16 deviceAddr; 2295 NvU32 speedMode; 2296 NvBool bIsRead = NV_FALSE; 2297 NvU32 flags = 0; 2298 NVSWITCH_CTRL_I2C_INDEXED_PARAMS i2c_params = {0}; 2299 NvBool is_i2c_access_allowed; 2300 2301 if (!nvswitch_os_is_admin()) 2302 { 2303 return -NVL_ERR_INSUFFICIENT_PERMISSIONS; 2304 } 2305 2306 is_i2c_access_allowed = (device->regkeys.i2c_access_control == 2307 NV_SWITCH_REGKEY_I2C_ACCESS_CONTROL_ENABLE) ? 2308 NV_TRUE : NV_FALSE; 2309 2310 // 2311 // The address needs to be shifted by 1, 2312 // See NVSWITCH_CTRL_I2C_INDEXED_PARAMS 2313 // 2314 deviceAddr = addr << 1; 2315 speedMode = device->pI2c->Ports[port].defaultSpeedMode; 2316 flags = DRF_DEF(SWITCH_CTRL, _I2C_FLAGS, _START, _SEND) | 2317 DRF_DEF(SWITCH_CTRL, _I2C_FLAGS, _STOP, _SEND) | 2318 DRF_DEF(SWITCH_CTRL, _I2C_FLAGS, _ADDRESS_MODE, _7BIT) | 2319 DRF_DEF(SWITCH_CTRL, _I2C_FLAGS, _FLAVOR, _HW) | 2320 DRF_DEF(SWITCH_CTRL, _I2C_FLAGS, _BLOCK_PROTOCOL, _DISABLED) | 2321 DRF_DEF(SWITCH_CTRL, _I2C_FLAGS, _TRANSACTION_MODE, _NORMAL); 2322 2323 switch (speedMode) 2324 { 2325 case NVSWITCH_I2C_SPEED_MODE_1000KHZ: 2326 { 2327 flags = FLD_SET_DRF(SWITCH_CTRL, _I2C_FLAGS, _SPEED_MODE, _1000KHZ, flags); 2328 break; 2329 } 2330 case NVSWITCH_I2C_SPEED_MODE_400KHZ: 2331 { 2332 flags = FLD_SET_DRF(SWITCH_CTRL, _I2C_FLAGS, _SPEED_MODE, _400KHZ, flags); 2333 break; 2334 } 2335 case NVSWITCH_I2C_SPEED_MODE_300KHZ: 2336 { 2337 flags = FLD_SET_DRF(SWITCH_CTRL, _I2C_FLAGS, _SPEED_MODE, _300KHZ, flags); 2338 break; 2339 } 2340 case NVSWITCH_I2C_SPEED_MODE_200KHZ: 2341 { 2342 flags = FLD_SET_DRF(SWITCH_CTRL, _I2C_FLAGS, _SPEED_MODE, _200KHZ, flags); 2343 break; 2344 } 2345 case NVSWITCH_I2C_SPEED_MODE_100KHZ: 2346 { 2347 flags = FLD_SET_DRF(SWITCH_CTRL, _I2C_FLAGS, _SPEED_MODE, _100KHZ, flags); 2348 break; 2349 } 2350 default: 2351 { 2352 NVSWITCH_PRINT(device, ERROR, "Invalid I2C speed!\n"); 2353 status = -NVL_BAD_ARGS; 2354 goto end; 2355 } 2356 } 2357 2358 switch (type) 2359 { 2360 case NVSWITCH_I2C_CMD_READ: 2361 bIsRead = NV_TRUE; 2362 // Fall through 2363 case NVSWITCH_I2C_CMD_WRITE: 2364 { 2365 flags = FLD_SET_DRF(SWITCH_CTRL, _I2C_FLAGS, _INDEX_LENGTH, _ZERO, flags); 2366 break; 2367 } 2368 case NVSWITCH_I2C_CMD_SMBUS_READ: 2369 { 2370 bIsRead = NV_TRUE; 2371 flags = FLD_SET_DRF(SWITCH_CTRL, _I2C_FLAGS, _RESTART, _SEND, flags); 2372 // Fall through 2373 } 2374 case NVSWITCH_I2C_CMD_SMBUS_WRITE: 2375 { 2376 flags = FLD_SET_DRF(SWITCH_CTRL, _I2C_FLAGS, _INDEX_LENGTH, _ONE, flags); 2377 break; 2378 } 2379 case NVSWITCH_I2C_CMD_SMBUS_QUICK_READ: 2380 bIsRead = NV_TRUE; 2381 // Fall through 2382 case NVSWITCH_I2C_CMD_SMBUS_QUICK_WRITE: 2383 { 2384 flags = FLD_SET_DRF(SWITCH_CTRL, _I2C_FLAGS, _INDEX_LENGTH, _ZERO, flags); 2385 msgLength = 0; 2386 break; 2387 } 2388 default: 2389 { 2390 NVSWITCH_PRINT(device, ERROR, "Invalid SMBUS protocol! Protocol not supported.\n"); 2391 status = -NVL_BAD_ARGS; 2392 goto end; 2393 } 2394 } 2395 2396 if (!is_i2c_access_allowed && 2397 !nvswitch_i2c_is_device_access_allowed(device, port, deviceAddr, bIsRead)) 2398 { 2399 return -NVL_BAD_ARGS; 2400 } 2401 2402 if (msgLength > NVSWITCH_CTRL_I2C_MESSAGE_LENGTH_MAX) 2403 { 2404 NVSWITCH_PRINT(device, ERROR, 2405 "Length of buffer (0x%x bytes) provided larger than max (0x%x bytes)\n", 2406 msgLength, NVSWITCH_CTRL_I2C_MESSAGE_LENGTH_MAX); 2407 status = -NVL_BAD_ARGS; 2408 goto end; 2409 } 2410 2411 if (bIsRead) 2412 { 2413 i2c_params.bIsRead = NV_TRUE; 2414 } 2415 else 2416 { 2417 flags = FLD_SET_DRF(SWITCH_CTRL, _I2C_FLAGS, _RESTART, _NONE, flags); 2418 nvswitch_os_memcpy(i2c_params.message, pData, msgLength); 2419 } 2420 2421 if (FLD_TEST_DRF(SWITCH_CTRL, _I2C_FLAGS, _INDEX_LENGTH, _ONE, flags)) 2422 { 2423 i2c_params.index[0] = cmd; 2424 } 2425 2426 i2c_params.port = port; 2427 i2c_params.address = deviceAddr; 2428 i2c_params.acquirer = client; 2429 i2c_params.flags = flags; 2430 i2c_params.messageLength = msgLength; 2431 2432 status = nvswitch_ctrl_i2c_indexed(device, &i2c_params); 2433 if (status != NVL_SUCCESS) 2434 { 2435 NVSWITCH_PRINT(device, ERROR, "I2C transfer Failed!\n"); 2436 goto end; 2437 } 2438 2439 if (bIsRead) 2440 { 2441 nvswitch_os_memcpy(pData, i2c_params.message, msgLength); 2442 } 2443 2444 end: 2445 return status; 2446 } 2447 2448 /*! 2449 * @brief: Performs an I2C transaction. 2450 */ 2451 NvlStatus 2452 nvswitch_lib_i2c_transfer 2453 ( 2454 nvswitch_device *device, 2455 NvU32 port, 2456 NvU8 type, 2457 NvU8 addr, 2458 NvU8 command, 2459 NvU32 len, 2460 NvU8 *pData 2461 ) 2462 { 2463 NvlStatus status; 2464 NvU32 port_info; 2465 NvBool is_i2c_access_allowed; 2466 NvBool is_port_allowed; 2467 2468 if (!NVSWITCH_IS_DEVICE_VALID(device)) 2469 { 2470 NVSWITCH_ASSERT(0); 2471 return -NVL_ERR_INVALID_STATE; 2472 } 2473 2474 port_info = nvswitch_i2c_get_port_info(device, port); 2475 2476 is_i2c_access_allowed = (device->regkeys.i2c_access_control == 2477 NV_SWITCH_REGKEY_I2C_ACCESS_CONTROL_ENABLE) ? 2478 NV_TRUE : NV_FALSE; 2479 is_port_allowed = is_i2c_access_allowed ? NV_TRUE : 2480 FLD_TEST_DRF(_I2C, _PORTINFO, _ACCESS_ALLOWED, _TRUE, 2481 port_info); 2482 2483 if (!is_port_allowed || 2484 !FLD_TEST_DRF(_I2C, _PORTINFO, _DEFINED, _PRESENT, port_info)) 2485 { 2486 NVSWITCH_PRINT(device, INFO, 2487 "%s: Invalid port access %d.\n", 2488 __FUNCTION__, port); 2489 return (-NVL_BAD_ARGS); 2490 } 2491 2492 status = _nvswitch_perform_i2c_transfer(device, NVSWITCH_I2C_ACQUIRER_EXTERNAL, 2493 type, (NvU16)addr, port, command, len, pData); 2494 if (status != NVL_SUCCESS) 2495 { 2496 NVSWITCH_PRINT(device, ERROR, "I2C transaction failed!\n"); 2497 return status; 2498 } 2499 2500 return NVL_SUCCESS; 2501 } 2502 2503 void 2504 nvswitch_timeout_create 2505 ( 2506 NvU64 timeout_ns, 2507 NVSWITCH_TIMEOUT *time 2508 ) 2509 { 2510 NvU64 time_current; 2511 2512 time_current = nvswitch_os_get_platform_time(); 2513 time->timeout_ns = time_current + timeout_ns; 2514 } 2515 2516 NvBool 2517 nvswitch_timeout_check 2518 ( 2519 NVSWITCH_TIMEOUT *time 2520 ) 2521 { 2522 NvU64 time_current; 2523 2524 time_current = nvswitch_os_get_platform_time(); 2525 return (time->timeout_ns <= time_current); 2526 } 2527 2528 NvlStatus 2529 nvswitch_task_create 2530 ( 2531 nvswitch_device *device, 2532 void (*task_fn)(nvswitch_device *device), 2533 NvU64 period_nsec, 2534 NvU32 flags 2535 ) 2536 { 2537 NVSWITCH_TASK_TYPE *task; 2538 task = nvswitch_os_malloc(sizeof(NVSWITCH_TASK_TYPE)); 2539 2540 if (task == NULL) 2541 { 2542 NVSWITCH_PRINT(device, ERROR, 2543 "%s: Unable to allocate task.\n", 2544 __FUNCTION__); 2545 return -NVL_NO_MEM; 2546 } 2547 else 2548 { 2549 task->task_fn_devptr = task_fn; 2550 task->task_args = NULL; 2551 task->period_nsec = period_nsec; 2552 task->last_run_nsec = nvswitch_os_get_platform_time(); // Prevent deferred tasks from being run immediately 2553 task->flags = flags; 2554 task->prev = NULL; 2555 task->next = device->tasks; 2556 if (device->tasks != NULL) 2557 { 2558 device->tasks->prev = task; 2559 } 2560 device->tasks = task; 2561 } 2562 2563 return NVL_SUCCESS; 2564 } 2565 2566 NvlStatus 2567 nvswitch_task_create_args 2568 ( 2569 nvswitch_device *device, 2570 void *fn_args, 2571 void (*task_fn)(nvswitch_device* device, void *fn_args), 2572 NvU64 period_nsec, 2573 NvU32 flags 2574 ) 2575 { 2576 NVSWITCH_TASK_TYPE *task; 2577 task = nvswitch_os_malloc(sizeof(NVSWITCH_TASK_TYPE)); 2578 2579 flags = flags | NVSWITCH_TASK_TYPE_FLAGS_VOID_PTR_ARGS; // ensure dispatcher always executes tasks passed through this function with args 2580 2581 if (task == NULL) 2582 { 2583 NVSWITCH_PRINT(device, ERROR, 2584 "%s: Unable to allocate task.\n", 2585 __FUNCTION__); 2586 return -NVL_NO_MEM; 2587 } 2588 else 2589 { 2590 task->task_fn_vdptr = task_fn; 2591 task->task_args = fn_args; 2592 task->period_nsec = period_nsec; 2593 task->last_run_nsec = nvswitch_os_get_platform_time(); // Prevent deferred tasks from being run immediately 2594 task->flags = flags; 2595 task->prev = NULL; 2596 task->next = device->tasks; 2597 if (device->tasks != NULL) 2598 { 2599 device->tasks->prev = task; 2600 } 2601 device->tasks = task; 2602 } 2603 2604 return NVL_SUCCESS; 2605 } 2606 2607 void 2608 nvswitch_tasks_destroy 2609 ( 2610 nvswitch_device *device 2611 ) 2612 { 2613 NVSWITCH_TASK_TYPE *task = device->tasks; 2614 NVSWITCH_TASK_TYPE *next_task; 2615 2616 device->tasks = NULL; 2617 2618 while (task) 2619 { 2620 next_task = task->next; 2621 nvswitch_os_free(task); 2622 task = next_task; 2623 } 2624 } 2625 2626 void 2627 nvswitch_destroy_device_state 2628 ( 2629 nvswitch_device *device 2630 ) 2631 { 2632 device->hal.nvswitch_destroy_device_state(device); 2633 } 2634 2635 static NvlStatus 2636 _nvswitch_ctrl_get_info 2637 ( 2638 nvswitch_device *device, 2639 NVSWITCH_GET_INFO *p 2640 ) 2641 { 2642 return device->hal.nvswitch_ctrl_get_info(device, p); 2643 } 2644 2645 static NvlStatus 2646 _nvswitch_ctrl_get_nvlink_status 2647 ( 2648 nvswitch_device *device, 2649 NVSWITCH_GET_NVLINK_STATUS_PARAMS *ret 2650 ) 2651 { 2652 return device->hal.nvswitch_ctrl_get_nvlink_status(device, ret); 2653 } 2654 2655 static NvlStatus 2656 _nvswitch_ctrl_get_counters 2657 ( 2658 nvswitch_device *device, 2659 NVSWITCH_NVLINK_GET_COUNTERS_PARAMS *ret 2660 ) 2661 { 2662 return device->hal.nvswitch_ctrl_get_counters(device, ret); 2663 } 2664 2665 NvlStatus 2666 nvswitch_set_nport_port_config 2667 ( 2668 nvswitch_device *device, 2669 NVSWITCH_SET_SWITCH_PORT_CONFIG *p 2670 ) 2671 { 2672 return device->hal.nvswitch_set_nport_port_config(device, p); 2673 } 2674 2675 static NvlStatus 2676 _nvswitch_ctrl_set_switch_port_config 2677 ( 2678 nvswitch_device *device, 2679 NVSWITCH_SET_SWITCH_PORT_CONFIG *p 2680 ) 2681 { 2682 return device->hal.nvswitch_ctrl_set_switch_port_config(device, p); 2683 } 2684 2685 static NvlStatus 2686 _nvswitch_ctrl_get_ingress_request_table 2687 ( 2688 nvswitch_device *device, 2689 NVSWITCH_GET_INGRESS_REQUEST_TABLE_PARAMS *params 2690 ) 2691 { 2692 return device->hal.nvswitch_ctrl_get_ingress_request_table(device, params); 2693 } 2694 2695 static NvlStatus 2696 _nvswitch_ctrl_set_ingress_request_table 2697 ( 2698 nvswitch_device *device, 2699 NVSWITCH_SET_INGRESS_REQUEST_TABLE *p 2700 ) 2701 { 2702 return device->hal.nvswitch_ctrl_set_ingress_request_table(device, p); 2703 } 2704 2705 static NvlStatus 2706 _nvswitch_ctrl_set_ingress_request_valid 2707 ( 2708 nvswitch_device *device, 2709 NVSWITCH_SET_INGRESS_REQUEST_VALID *p 2710 ) 2711 { 2712 return device->hal.nvswitch_ctrl_set_ingress_request_valid(device, p); 2713 } 2714 2715 static NvlStatus 2716 _nvswitch_ctrl_get_ingress_response_table 2717 ( 2718 nvswitch_device *device, 2719 NVSWITCH_GET_INGRESS_RESPONSE_TABLE_PARAMS *params 2720 ) 2721 { 2722 return device->hal.nvswitch_ctrl_get_ingress_response_table(device, params); 2723 } 2724 2725 static NvlStatus 2726 _nvswitch_ctrl_set_ingress_response_table 2727 ( 2728 nvswitch_device *device, 2729 NVSWITCH_SET_INGRESS_RESPONSE_TABLE *p 2730 ) 2731 { 2732 return device->hal.nvswitch_ctrl_set_ingress_response_table(device, p); 2733 } 2734 2735 static NvlStatus 2736 _nvswitch_ctrl_set_ganged_link_table 2737 ( 2738 nvswitch_device *device, 2739 NVSWITCH_SET_GANGED_LINK_TABLE *p 2740 ) 2741 { 2742 return device->hal.nvswitch_ctrl_set_ganged_link_table(device, p); 2743 } 2744 2745 void 2746 nvswitch_init_npg_multicast 2747 ( 2748 nvswitch_device *device 2749 ) 2750 { 2751 return device->hal.nvswitch_init_npg_multicast(device); 2752 } 2753 2754 void 2755 nvswitch_init_warm_reset 2756 ( 2757 nvswitch_device *device 2758 ) 2759 { 2760 return device->hal.nvswitch_init_warm_reset(device); 2761 } 2762 2763 static NvlStatus 2764 _nvswitch_ctrl_set_remap_policy 2765 ( 2766 nvswitch_device *device, 2767 NVSWITCH_SET_REMAP_POLICY *p 2768 ) 2769 { 2770 return device->hal.nvswitch_ctrl_set_remap_policy(device, p); 2771 } 2772 2773 static NvlStatus 2774 _nvswitch_ctrl_get_remap_policy 2775 ( 2776 nvswitch_device *device, 2777 NVSWITCH_GET_REMAP_POLICY_PARAMS *params 2778 ) 2779 { 2780 return device->hal.nvswitch_ctrl_get_remap_policy(device, params); 2781 } 2782 2783 static NvlStatus 2784 _nvswitch_ctrl_set_remap_policy_valid 2785 ( 2786 nvswitch_device *device, 2787 NVSWITCH_SET_REMAP_POLICY_VALID *p 2788 ) 2789 { 2790 return device->hal.nvswitch_ctrl_set_remap_policy_valid(device, p); 2791 } 2792 2793 static NvlStatus 2794 _nvswitch_ctrl_set_routing_id 2795 ( 2796 nvswitch_device *device, 2797 NVSWITCH_SET_ROUTING_ID *p 2798 ) 2799 { 2800 return device->hal.nvswitch_ctrl_set_routing_id(device, p); 2801 } 2802 2803 static NvlStatus 2804 _nvswitch_ctrl_get_routing_id 2805 ( 2806 nvswitch_device *device, 2807 NVSWITCH_GET_ROUTING_ID_PARAMS *params 2808 ) 2809 { 2810 return device->hal.nvswitch_ctrl_get_routing_id(device, params); 2811 } 2812 2813 static NvlStatus 2814 _nvswitch_ctrl_set_routing_id_valid 2815 ( 2816 nvswitch_device *device, 2817 NVSWITCH_SET_ROUTING_ID_VALID *p 2818 ) 2819 { 2820 return device->hal.nvswitch_ctrl_set_routing_id_valid(device, p); 2821 } 2822 2823 static NvlStatus 2824 _nvswitch_ctrl_set_routing_lan 2825 ( 2826 nvswitch_device *device, 2827 NVSWITCH_SET_ROUTING_LAN *p 2828 ) 2829 { 2830 return device->hal.nvswitch_ctrl_set_routing_lan(device, p); 2831 } 2832 2833 static NvlStatus 2834 _nvswitch_ctrl_get_routing_lan 2835 ( 2836 nvswitch_device *device, 2837 NVSWITCH_GET_ROUTING_LAN_PARAMS *params 2838 ) 2839 { 2840 return device->hal.nvswitch_ctrl_get_routing_lan(device, params); 2841 } 2842 2843 static NvlStatus 2844 _nvswitch_ctrl_set_routing_lan_valid 2845 ( 2846 nvswitch_device *device, 2847 NVSWITCH_SET_ROUTING_LAN_VALID *p 2848 ) 2849 { 2850 return device->hal.nvswitch_ctrl_set_routing_lan_valid(device, p); 2851 } 2852 2853 static NvlStatus 2854 _nvswitch_ctrl_get_internal_latency 2855 ( 2856 nvswitch_device *device, 2857 NVSWITCH_GET_INTERNAL_LATENCY *p 2858 ) 2859 { 2860 return device->hal.nvswitch_ctrl_get_internal_latency(device, p); 2861 } 2862 2863 static NvlStatus 2864 _nvswitch_ctrl_get_nvlipt_counters 2865 ( 2866 nvswitch_device *device, 2867 NVSWITCH_GET_NVLIPT_COUNTERS *p 2868 ) 2869 { 2870 // 2871 // This control call is now deprecated. 2872 // New control call to fetch throughput counters is: 2873 // nvswitch_ctrl_get_throughput_counters 2874 // 2875 return -NVL_ERR_NOT_SUPPORTED; 2876 } 2877 2878 static NvlStatus 2879 _nvswitch_ctrl_set_nvlipt_counter_config 2880 ( 2881 nvswitch_device *device, 2882 NVSWITCH_SET_NVLIPT_COUNTER_CONFIG *p 2883 ) 2884 { 2885 // 2886 // This control call is now deprecated. 2887 // New control call to fetch throughput counters is: 2888 // nvswitch_ctrl_get_throughput_counters_lr10 2889 // 2890 // Setting counter config is not allowed on these 2891 // non-configurable counters. These counters are 2892 // expected to be used by monitoring clients. 2893 // 2894 return -NVL_ERR_NOT_SUPPORTED; 2895 } 2896 2897 static NvlStatus 2898 _nvswitch_ctrl_get_nvlipt_counter_config 2899 ( 2900 nvswitch_device *device, 2901 NVSWITCH_GET_NVLIPT_COUNTER_CONFIG *p 2902 ) 2903 { 2904 // 2905 // This control call is now deprecated. 2906 // New control call to fetch throughput counters is: 2907 // nvswitch_ctrl_get_throughput_counters_lr10 2908 // 2909 // Getting counter config is useful if counters are 2910 // configurable. These counters are not configurable 2911 // and are expected to be used by monitoring clients. 2912 // 2913 return -NVL_ERR_NOT_SUPPORTED; 2914 } 2915 2916 static NvlStatus 2917 _nvswitch_ctrl_register_read 2918 ( 2919 nvswitch_device *device, 2920 NVSWITCH_REGISTER_READ *p 2921 ) 2922 { 2923 return device->hal.nvswitch_ctrl_register_read(device, p); 2924 } 2925 2926 static NvlStatus 2927 _nvswitch_ctrl_register_write 2928 ( 2929 nvswitch_device *device, 2930 NVSWITCH_REGISTER_WRITE *p 2931 ) 2932 { 2933 return device->hal.nvswitch_ctrl_register_write(device, p); 2934 } 2935 2936 NvU32 2937 nvswitch_i2c_get_port_info 2938 ( 2939 nvswitch_device *device, 2940 NvU32 port 2941 ) 2942 { 2943 return device->hal.nvswitch_i2c_get_port_info(device, port); 2944 } 2945 2946 NvlStatus 2947 nvswitch_ctrl_i2c_indexed 2948 ( 2949 nvswitch_device *device, 2950 NVSWITCH_CTRL_I2C_INDEXED_PARAMS *pParams 2951 ) 2952 { 2953 return device->hal.nvswitch_ctrl_i2c_indexed(device, pParams); 2954 } 2955 2956 static NvlStatus 2957 _nvswitch_ctrl_therm_read_temperature 2958 ( 2959 nvswitch_device *device, 2960 NVSWITCH_CTRL_GET_TEMPERATURE_PARAMS *info 2961 ) 2962 { 2963 return device->hal.nvswitch_ctrl_therm_read_temperature(device, info); 2964 } 2965 2966 static NvlStatus 2967 _nvswitch_ctrl_get_bios_info 2968 ( 2969 nvswitch_device *device, 2970 NVSWITCH_GET_BIOS_INFO_PARAMS *p 2971 ) 2972 { 2973 return device->hal.nvswitch_ctrl_get_bios_info(device, p); 2974 } 2975 2976 static NvlStatus 2977 _nvswitch_ctrl_get_inforom_version 2978 ( 2979 nvswitch_device *device, 2980 NVSWITCH_GET_INFOROM_VERSION_PARAMS *p 2981 ) 2982 { 2983 return device->hal.nvswitch_ctrl_get_inforom_version(device, p); 2984 } 2985 2986 NvlStatus 2987 nvswitch_ctrl_set_latency_bins 2988 ( 2989 nvswitch_device *device, 2990 NVSWITCH_SET_LATENCY_BINS *p 2991 ) 2992 { 2993 return device->hal.nvswitch_ctrl_set_latency_bins(device, p); 2994 } 2995 2996 static NvlStatus 2997 _nvswitch_ctrl_get_ingress_reqlinkid 2998 ( 2999 nvswitch_device *device, 3000 NVSWITCH_GET_INGRESS_REQLINKID_PARAMS *params 3001 ) 3002 { 3003 return device->hal.nvswitch_ctrl_get_ingress_reqlinkid(device, params); 3004 } 3005 3006 NvlStatus 3007 nvswitch_ctrl_get_throughput_counters 3008 ( 3009 nvswitch_device *device, 3010 NVSWITCH_GET_THROUGHPUT_COUNTERS_PARAMS *p 3011 ) 3012 { 3013 return device->hal.nvswitch_ctrl_get_throughput_counters(device, p); 3014 } 3015 3016 static NvlStatus 3017 _nvswitch_ctrl_unregister_link 3018 ( 3019 nvswitch_device *device, 3020 NVSWITCH_UNREGISTER_LINK_PARAMS *params 3021 ) 3022 { 3023 nvlink_link *link = nvswitch_get_link(device, (NvU8)params->portNum); 3024 3025 if (link == NULL) 3026 { 3027 return -NVL_BAD_ARGS; 3028 } 3029 3030 // With ALI in FW, links can be unregistered while Active 3031 if (!device->nvlink_device->enableALI) 3032 { 3033 3034 if (device->hal.nvswitch_is_link_in_use(device, params->portNum)) 3035 { 3036 return -NVL_ERR_STATE_IN_USE; 3037 } 3038 3039 } 3040 3041 nvlink_lib_unregister_link(link); 3042 nvswitch_destroy_link(link); 3043 3044 return NVL_SUCCESS; 3045 } 3046 3047 static NvlStatus 3048 _nvswitch_ctrl_acquire_capability 3049 ( 3050 nvswitch_device *device, 3051 NVSWITCH_ACQUIRE_CAPABILITY_PARAMS *params, 3052 void *osPrivate 3053 ) 3054 { 3055 return nvswitch_os_acquire_fabric_mgmt_cap(osPrivate, 3056 params->capDescriptor); 3057 } 3058 3059 static NvlStatus 3060 _nvswitch_ctrl_reset_and_drain_links 3061 ( 3062 nvswitch_device *device, 3063 NVSWITCH_RESET_AND_DRAIN_LINKS_PARAMS *params 3064 ) 3065 { 3066 return device->hal.nvswitch_reset_and_drain_links(device, params->linkMask); 3067 } 3068 3069 static NvlStatus 3070 _nvswitch_ctrl_get_fom_values 3071 ( 3072 nvswitch_device *device, 3073 NVSWITCH_GET_FOM_VALUES_PARAMS *ret 3074 ) 3075 { 3076 return device->hal.nvswitch_ctrl_get_fom_values(device, ret); 3077 } 3078 3079 static NvlStatus 3080 _nvswitch_ctrl_get_nvlink_ecc_errors 3081 ( 3082 nvswitch_device *device, 3083 NVSWITCH_GET_NVLINK_ECC_ERRORS_PARAMS *params 3084 ) 3085 { 3086 return device->hal.nvswitch_get_nvlink_ecc_errors(device, params); 3087 } 3088 3089 static NvlStatus 3090 _nvswitch_ctrl_set_mc_rid_table 3091 ( 3092 nvswitch_device *device, 3093 NVSWITCH_SET_MC_RID_TABLE_PARAMS *p 3094 ) 3095 { 3096 return device->hal.nvswitch_ctrl_set_mc_rid_table(device, p); 3097 } 3098 3099 static NvlStatus 3100 _nvswitch_ctrl_get_mc_rid_table 3101 ( 3102 nvswitch_device *device, 3103 NVSWITCH_GET_MC_RID_TABLE_PARAMS *p 3104 ) 3105 { 3106 return device->hal.nvswitch_ctrl_get_mc_rid_table(device, p); 3107 } 3108 3109 static NvlStatus 3110 _nvswitch_ctrl_set_residency_bins 3111 ( 3112 nvswitch_device *device, 3113 NVSWITCH_SET_RESIDENCY_BINS *p 3114 ) 3115 { 3116 return device->hal.nvswitch_ctrl_set_residency_bins(device, p); 3117 } 3118 3119 static NvlStatus 3120 _nvswitch_ctrl_get_residency_bins 3121 ( 3122 nvswitch_device *device, 3123 NVSWITCH_GET_RESIDENCY_BINS *p 3124 ) 3125 { 3126 return device->hal.nvswitch_ctrl_get_residency_bins(device, p); 3127 } 3128 3129 static NvlStatus 3130 _nvswitch_ctrl_get_rb_stall_busy 3131 ( 3132 nvswitch_device *device, 3133 NVSWITCH_GET_RB_STALL_BUSY *p 3134 ) 3135 { 3136 return device->hal.nvswitch_ctrl_get_rb_stall_busy(device, p); 3137 } 3138 3139 NvlStatus 3140 nvswitch_ctrl_get_multicast_id_error_vector 3141 ( 3142 nvswitch_device *device, 3143 NVSWITCH_GET_MULTICAST_ID_ERROR_VECTOR *p 3144 ) 3145 { 3146 return device->hal.nvswitch_ctrl_get_multicast_id_error_vector(device, p); 3147 } 3148 3149 NvlStatus 3150 nvswitch_ctrl_clear_multicast_id_error_vector 3151 ( 3152 nvswitch_device *device, 3153 NVSWITCH_CLEAR_MULTICAST_ID_ERROR_VECTOR *p 3154 ) 3155 { 3156 return device->hal.nvswitch_ctrl_clear_multicast_id_error_vector(device, p); 3157 } 3158 3159 static NvlStatus 3160 _nvswitch_ctrl_inband_send_data 3161 ( 3162 nvswitch_device *device, 3163 NVSWITCH_INBAND_SEND_DATA_PARAMS *p 3164 ) 3165 { 3166 return device->hal.nvswitch_ctrl_inband_send_data(device, p); 3167 } 3168 3169 static NvlStatus 3170 _nvswitch_ctrl_inband_read_data 3171 ( 3172 nvswitch_device *device, 3173 NVSWITCH_INBAND_READ_DATA_PARAMS *p 3174 ) 3175 { 3176 return device->hal.nvswitch_ctrl_inband_read_data(device, p); 3177 } 3178 3179 static NvlStatus 3180 _nvswitch_ctrl_inband_flush_data 3181 ( 3182 nvswitch_device *device, 3183 NVSWITCH_INBAND_FLUSH_DATA_PARAMS *p 3184 ) 3185 { 3186 NvU32 i; 3187 NvU64 enabledLinkMask; 3188 3189 if (p->linkMask == 0) 3190 { 3191 NVSWITCH_PRINT(device, ERROR, "Nothing to clear\n"); 3192 return NVL_SUCCESS; 3193 } 3194 3195 enabledLinkMask = nvswitch_get_enabled_link_mask(device); 3196 3197 FOR_EACH_INDEX_IN_MASK(64, i, p->linkMask) 3198 { 3199 if (nvswitch_is_link_valid(device, i) && 3200 (enabledLinkMask & NVBIT64(i))) 3201 { 3202 // 3203 // Flush is expected to clear both persistent and non-persistent 3204 // list. FM does flush when it wants to drop (ignore) all pending 3205 // messages w/o any NACKs. 3206 // 3207 _nvswitch_inband_clear_lists(device, i, 3208 NV_FALSE /* Nack */, 3209 NV_FALSE /* Non-persistent only */); 3210 } 3211 } 3212 FOR_EACH_INDEX_IN_MASK_END; 3213 3214 return NVL_SUCCESS; 3215 } 3216 3217 static NvlStatus 3218 _nvswitch_ctrl_inband_pending_data_stats 3219 ( 3220 nvswitch_device *device, 3221 NVSWITCH_INBAND_PENDING_DATA_STATS_PARAMS *p 3222 ) 3223 { 3224 NvU32 link_num; 3225 NvU64 enabledLinkMask, persistent_mask = 0, nonpersistent_mask = 0; 3226 3227 enabledLinkMask = nvswitch_get_enabled_link_mask(device); 3228 3229 for (link_num = 0; link_num < nvswitch_get_num_links(device); link_num++) 3230 { 3231 if (nvswitch_is_link_valid(device, link_num) && 3232 (enabledLinkMask & NVBIT64(link_num))) 3233 { 3234 if (!nvListIsEmpty(&device->link[link_num].inbandData.persistent_list)) 3235 { 3236 persistent_mask |= NVBIT64(link_num); 3237 } 3238 3239 if (!nvListIsEmpty(&device->link[link_num].inbandData.nonpersistent_list)) 3240 { 3241 nonpersistent_mask |= NVBIT64(link_num); 3242 } 3243 } 3244 } 3245 3246 if (persistent_mask > 0) 3247 { 3248 p->linkMask = persistent_mask; 3249 } 3250 else 3251 { 3252 p->linkMask = nonpersistent_mask; 3253 } 3254 3255 return NVL_SUCCESS; 3256 } 3257 3258 static NvlStatus 3259 _nvswitch_ctrl_get_board_part_number 3260 ( 3261 nvswitch_device *device, 3262 NVSWITCH_GET_BOARD_PART_NUMBER_VECTOR *p 3263 ) 3264 { 3265 if (IS_RTLSIM(device) || IS_EMULATION(device) || IS_FMODEL(device)) 3266 { 3267 NVSWITCH_PRINT(device, INFO, 3268 "%s: Skipping retrieval of board part number on FSF\n", 3269 __FUNCTION__); 3270 3271 nvswitch_os_memset(p, 0, sizeof(NVSWITCH_GET_BOARD_PART_NUMBER_VECTOR)); 3272 3273 return NVL_SUCCESS; 3274 } 3275 else 3276 { 3277 if (!nvswitch_is_inforom_supported(device)) 3278 { 3279 NVSWITCH_PRINT(device, ERROR, "InfoROM is not supported\n"); 3280 return -NVL_ERR_NOT_SUPPORTED; 3281 } 3282 3283 return device->hal.nvswitch_ctrl_get_board_part_number(device, p); 3284 } 3285 } 3286 3287 static NvlStatus 3288 _nvswitch_ctrl_i2c_smbus_command 3289 ( 3290 nvswitch_device *device, 3291 NVSWITCH_I2C_SMBUS_COMMAND_PARAMS *pParams 3292 ) 3293 { 3294 NvU32 port_info; 3295 NvU32 port = pParams->port; 3296 NvU8 msgLen; 3297 NvU8 cmd; 3298 NvU16 addr; 3299 NvU8 cmdType; 3300 NvU8 *pData; 3301 NvBool is_i2c_access_allowed; 3302 NvBool is_port_allowed; 3303 3304 port_info = nvswitch_i2c_get_port_info(device, port); 3305 3306 is_i2c_access_allowed = (device->regkeys.i2c_access_control == 3307 NV_SWITCH_REGKEY_I2C_ACCESS_CONTROL_ENABLE) ? 3308 NV_TRUE : NV_FALSE; 3309 is_port_allowed = is_i2c_access_allowed ? NV_TRUE : 3310 FLD_TEST_DRF(_I2C, _PORTINFO, _ACCESS_ALLOWED, _TRUE, 3311 port_info); 3312 3313 if (!is_port_allowed || 3314 !FLD_TEST_DRF(_I2C, _PORTINFO, _DEFINED, _PRESENT, port_info)) 3315 { 3316 NVSWITCH_PRINT(device, ERROR, "Invalid port access %d.\n", port); 3317 return NVL_BAD_ARGS; 3318 } 3319 3320 addr = pParams->deviceAddr; 3321 3322 switch (pParams->cmdType) 3323 { 3324 case NVSWITCH_I2C_SMBUS_CMD_QUICK: 3325 { 3326 cmd = 0; 3327 msgLen = 0; 3328 cmdType = pParams->bRead ? 3329 NVSWITCH_I2C_CMD_SMBUS_QUICK_READ : 3330 NVSWITCH_I2C_CMD_SMBUS_QUICK_WRITE; 3331 pData = NULL; 3332 break; 3333 } 3334 case NVSWITCH_I2C_SMBUS_CMD_BYTE: 3335 { 3336 cmd = 0; 3337 msgLen = 1; 3338 cmdType = pParams->bRead ? 3339 NVSWITCH_I2C_CMD_READ : 3340 NVSWITCH_I2C_CMD_WRITE; 3341 pData = (NvU8 *)&pParams->transactionData.smbusByte.message; 3342 break; 3343 } 3344 case NVSWITCH_I2C_SMBUS_CMD_BYTE_DATA: 3345 { 3346 msgLen = 1; 3347 cmd = pParams->transactionData.smbusByteData.cmd; 3348 cmdType = pParams->bRead ? 3349 NVSWITCH_I2C_CMD_SMBUS_READ : 3350 NVSWITCH_I2C_CMD_SMBUS_WRITE; 3351 pData = (NvU8 *)&pParams->transactionData.smbusByteData.message; 3352 break; 3353 } 3354 case NVSWITCH_I2C_SMBUS_CMD_WORD_DATA: 3355 { 3356 msgLen = 2; 3357 cmd = pParams->transactionData.smbusWordData.cmd; 3358 cmdType = pParams->bRead ? 3359 NVSWITCH_I2C_CMD_SMBUS_READ : 3360 NVSWITCH_I2C_CMD_SMBUS_WRITE; 3361 pData = (NvU8 *)&pParams->transactionData.smbusWordData.message; 3362 break; 3363 } 3364 default: 3365 { 3366 NVSWITCH_PRINT(device, ERROR, "Invalid Smbus command: %d.\n", port); 3367 return NVL_BAD_ARGS; 3368 } 3369 } 3370 3371 return _nvswitch_perform_i2c_transfer(device, NVSWITCH_I2C_ACQUIRER_IOCTL, 3372 cmdType, addr, port, cmd, msgLen, pData); 3373 } 3374 3375 NvBool 3376 nvswitch_does_link_need_termination_enabled 3377 ( 3378 nvswitch_device *device, 3379 nvlink_link *link 3380 ) 3381 { 3382 return device->hal.nvswitch_does_link_need_termination_enabled(device, link); 3383 } 3384 3385 NvlStatus 3386 nvswitch_link_termination_setup 3387 ( 3388 nvswitch_device *device, 3389 nvlink_link* link 3390 ) 3391 { 3392 return device->hal.nvswitch_link_termination_setup(device, link); 3393 } 3394 3395 static NvlStatus 3396 _nvswitch_ctrl_get_inforom_nvlink_max_correctable_error_rate 3397 ( 3398 nvswitch_device *device, 3399 NVSWITCH_GET_NVLINK_MAX_CORRECTABLE_ERROR_RATES_PARAMS *params 3400 ) 3401 { 3402 return nvswitch_inforom_nvlink_get_max_correctable_error_rate(device, params); 3403 } 3404 3405 static NvlStatus 3406 _nvswitch_ctrl_get_inforom_nvlink_errors 3407 ( 3408 nvswitch_device *device, 3409 NVSWITCH_GET_NVLINK_ERROR_COUNTS_PARAMS *params 3410 ) 3411 { 3412 return nvswitch_inforom_nvlink_get_errors(device, params); 3413 } 3414 3415 static NvlStatus 3416 _nvswitch_ctrl_get_inforom_ecc_errors 3417 ( 3418 nvswitch_device *device, 3419 NVSWITCH_GET_ECC_ERROR_COUNTS_PARAMS *params 3420 ) 3421 { 3422 return nvswitch_inforom_ecc_get_errors(device, params); 3423 } 3424 3425 static NvlStatus 3426 _nvswitch_ctrl_get_inforom_bbx_sxid 3427 ( 3428 nvswitch_device *device, 3429 NVSWITCH_GET_SXIDS_PARAMS *params 3430 ) 3431 { 3432 return nvswitch_inforom_bbx_get_sxid(device, params); 3433 } 3434 3435 static NvlStatus 3436 _nvswitch_ctrl_get_nvlink_lp_counters 3437 ( 3438 nvswitch_device *device, 3439 NVSWITCH_GET_NVLINK_LP_COUNTERS_PARAMS *params 3440 ) 3441 { 3442 return device->hal.nvswitch_ctrl_get_nvlink_lp_counters(device, params); 3443 } 3444 3445 static NvlStatus 3446 _nvswitch_ctrl_get_sw_info 3447 ( 3448 nvswitch_device *device, 3449 NVSWITCH_GET_SW_INFO_PARAMS *params 3450 ) 3451 { 3452 return device->hal.nvswitch_ctrl_get_sw_info(device, params); 3453 } 3454 3455 static NvlStatus 3456 _nvswitch_lib_validate_privileged_ctrl 3457 ( 3458 void *osPrivate, 3459 NvU64 flags 3460 ) 3461 { 3462 if (flags & NVSWITCH_DEV_CMD_CHECK_ADMIN) 3463 { 3464 if (nvswitch_os_is_admin()) 3465 { 3466 return NVL_SUCCESS; 3467 } 3468 } 3469 3470 if (flags & NVSWITCH_DEV_CMD_CHECK_FM) 3471 { 3472 if (nvswitch_os_is_fabric_manager(osPrivate)) 3473 { 3474 return NVL_SUCCESS; 3475 } 3476 } 3477 3478 return -NVL_ERR_INSUFFICIENT_PERMISSIONS; 3479 } 3480 3481 /* 3482 * @Brief : Copy the data from the persistant or nonpersistant list 3483 * 3484 * @Description : 3485 * 3486 * @param[in] device NvSwitch device to contain this link 3487 * @param[out] data Destination Data 3488 * @param[in] linkId link number of the link 3489 * @param[out] dataSize Size of data copied 3490 * 3491 * @returns NVL_SUCCESS if action succeeded, 3492 * -NVL_NOT_FOUND if link doesnt have data 3493 */ 3494 NvlStatus 3495 nvswitch_inband_read_data 3496 ( 3497 nvswitch_device *device, 3498 NvU8 *dest, 3499 NvU32 linkId, 3500 NvU32 *dataSize 3501 ) 3502 { 3503 nvswitch_inband_data_list *curr = NULL; 3504 NVListRec *list; 3505 3506 if (nvListIsEmpty(&device->link[linkId].inbandData.persistent_list) && 3507 nvListIsEmpty(&device->link[linkId].inbandData.nonpersistent_list)) 3508 { 3509 NVSWITCH_PRINT(device, ERROR, "%s: LinkId %d doesnt have any data to send\n", 3510 __FUNCTION__, linkId); 3511 *dataSize = 0; 3512 return -NVL_NOT_FOUND; 3513 } 3514 3515 list = nvListIsEmpty(&device->link[linkId].inbandData.persistent_list) ? 3516 &device->link[linkId].inbandData.nonpersistent_list : 3517 &device->link[linkId].inbandData.persistent_list; 3518 3519 nvListForEachEntry(curr, list, entry) 3520 { 3521 *dataSize = curr->dataSize; 3522 nvswitch_os_memcpy(dest, curr->data, curr->dataSize); 3523 nvListDel(&curr->entry); 3524 nvswitch_os_free(curr); 3525 break; 3526 } 3527 3528 return NVL_SUCCESS; 3529 } 3530 3531 /* 3532 * @Brief : Returns NV_TRUE if the given inband msg 3533 * needs to go to persistant list 3534 * 3535 * @Description : 3536 * 3537 * @param[in] device NvSwitch device to contain this link 3538 * @param[in] msghdr Header to the message 3539 * 3540 */ 3541 3542 static NvBool 3543 nvswitch_is_message_persistent 3544 ( 3545 nvswitch_device *device, 3546 nvlink_inband_msg_header_t *msghdr 3547 ) 3548 { 3549 // We expect only one message per received data 3550 switch(msghdr->type) 3551 { 3552 case NVLINK_INBAND_MSG_TYPE_MC_TEAM_RELEASE_REQ: 3553 return NV_TRUE; 3554 default: 3555 return NV_FALSE; 3556 } 3557 } 3558 3559 /* 3560 * @Brief : Moves the data into persistant or nonpersistant list 3561 * 3562 * @Description : 3563 * 3564 * @param[in] device NvSwitch device to contain this link 3565 * @param[in] linkId link number of the link 3566 * 3567 */ 3568 void 3569 nvswitch_filter_messages 3570 ( 3571 nvswitch_device *device, 3572 NvU32 linkId 3573 ) 3574 { 3575 NvlStatus status; 3576 nvlink_inband_msg_header_t *msghdr = NULL; 3577 nvswitch_inband_data_list *msg = device->link[linkId].inbandData.message; 3578 NvU8 *buffer = device->link[linkId].inbandData.message->data; 3579 NVSWITCH_DRIVER_FABRIC_STATE driver_fabric_state = 0; 3580 NvBool bSendNackOrDrop = NV_FALSE; 3581 3582 NVSWITCH_ASSERT(nvswitch_lib_read_fabric_state(device, NULL, NULL, 3583 &driver_fabric_state) == NVL_SUCCESS); 3584 3585 msghdr = (nvlink_inband_msg_header_t*)buffer; 3586 3587 if (nvswitch_is_message_persistent(device, msghdr)) 3588 { 3589 if (nvListCount(&device->link[linkId].inbandData.persistent_list) < 3590 device->hal.nvswitch_get_max_persistent_message_count(device)) 3591 { 3592 nvListAdd(&msg->entry, &device->link[linkId].inbandData.persistent_list); 3593 } 3594 else 3595 { 3596 bSendNackOrDrop = NV_TRUE; 3597 } 3598 } 3599 else 3600 { 3601 if (driver_fabric_state == NVSWITCH_DRIVER_FABRIC_STATE_CONFIGURED) 3602 { 3603 nvListAdd(&msg->entry, 3604 &device->link[linkId].inbandData.nonpersistent_list); 3605 } 3606 else 3607 { 3608 bSendNackOrDrop = NV_TRUE; 3609 } 3610 } 3611 3612 if (bSendNackOrDrop) 3613 { 3614 nvswitch_send_nack_or_drop(device, linkId, msghdr); 3615 nvswitch_os_free(msg); 3616 } 3617 else 3618 { 3619 status = nvswitch_lib_notify_client_events(device, 3620 NVSWITCH_DEVICE_EVENT_INBAND_DATA); 3621 if (status != NVL_SUCCESS) 3622 { 3623 NVSWITCH_PRINT(device, ERROR, "%s: Failed to notify INBAND_DATA event\n", 3624 __FUNCTION__); 3625 } 3626 } 3627 3628 device->link[linkId].inbandData.message = NULL; 3629 } 3630 3631 /* 3632 * @Brief : Constructs an NVS link struct with the given data 3633 * 3634 * @Description : 3635 * 3636 * @param[in] device NvSwitch device to contain this link 3637 * @param[in] link_num link number of the link 3638 * @param[out] link reference to store the created link into 3639 * 3640 * @returns NVL_SUCCESS if action succeeded, 3641 * -NVL_NO_MEM if memory allocation failed 3642 */ 3643 NvlStatus 3644 nvswitch_create_link 3645 ( 3646 nvswitch_device *device, 3647 NvU32 link_number, 3648 nvlink_link **link 3649 ) 3650 { 3651 NvlStatus retval = NVL_SUCCESS; 3652 nvlink_link *ret = NULL; 3653 LINK_INFO *link_info = NULL; 3654 NvU64 ac_coupled_mask; 3655 3656 NVSWITCH_ASSERT(nvswitch_get_num_links(device) <= NVSWITCH_MAX_NUM_LINKS); 3657 3658 ret = nvswitch_os_malloc(sizeof(*ret)); 3659 if (NULL == ret) 3660 { 3661 NVSWITCH_PRINT(device, ERROR, 3662 "nvswitch_os_malloc during link creation failed!\n"); 3663 retval = -NVL_NO_MEM; 3664 goto nvswitch_create_link_cleanup; 3665 } 3666 nvswitch_os_memset(ret, 0, sizeof(*ret)); 3667 3668 link_info = nvswitch_os_malloc(sizeof(*link_info)); 3669 if (NULL == link_info) 3670 { 3671 NVSWITCH_PRINT(device, ERROR, 3672 "nvswitch_os_malloc during link creation failed!\n"); 3673 retval = -NVL_NO_MEM; 3674 goto nvswitch_create_link_cleanup; 3675 } 3676 nvswitch_os_memset(link_info, 0, sizeof(*link_info)); 3677 nvswitch_os_snprintf(link_info->name, sizeof(link_info->name), NVSWITCH_LINK_NAME "%d", link_number); 3678 3679 ret->dev = device->nvlink_device; 3680 ret->linkName = link_info->name; 3681 ret->linkNumber = link_number; 3682 ret->state = NVLINK_LINKSTATE_OFF; 3683 ret->ac_coupled = NV_FALSE; 3684 ret->version = nvswitch_get_link_ip_version(device, link_number); 3685 3686 ac_coupled_mask = ((NvU64)device->regkeys.ac_coupled_mask2 << 32 | 3687 (NvU64)device->regkeys.ac_coupled_mask); 3688 3689 if (ac_coupled_mask) 3690 { 3691 if (ac_coupled_mask & NVBIT64(link_number)) 3692 { 3693 ret->ac_coupled = NV_TRUE; 3694 } 3695 } 3696 else if (device->firmware.nvlink.link_config_found) 3697 { 3698 if (device->firmware.nvlink.link_ac_coupled_mask & NVBIT64(link_number)) 3699 { 3700 ret->ac_coupled = NV_TRUE; 3701 } 3702 } 3703 3704 // Initialize NVLink corelib callbacks for switch 3705 nvswitch_get_link_handlers(&link_handlers); 3706 3707 ret->link_handlers = &link_handlers; 3708 3709 // 3710 // link_info is used to store private link information 3711 // 3712 3713 ret->link_info = link_info; 3714 3715 *link = ret; 3716 3717 return retval; 3718 3719 nvswitch_create_link_cleanup: 3720 if (NULL != ret) 3721 { 3722 nvswitch_os_free(ret); 3723 } 3724 if (NULL != link_info) 3725 { 3726 nvswitch_os_free(link_info); 3727 } 3728 3729 return retval; 3730 } 3731 3732 void 3733 nvswitch_destroy_link 3734 ( 3735 nvlink_link *link 3736 ) 3737 { 3738 if (NULL != link->link_info) 3739 { 3740 nvswitch_os_free(link->link_info); 3741 } 3742 3743 nvswitch_os_free(link); 3744 } 3745 3746 NvU32 3747 nvswitch_get_num_links 3748 ( 3749 nvswitch_device *device 3750 ) 3751 { 3752 return device->hal.nvswitch_get_num_links(device); 3753 } 3754 3755 NvBool 3756 nvswitch_is_link_valid 3757 ( 3758 nvswitch_device *device, 3759 NvU32 link_id 3760 ) 3761 { 3762 return device->hal.nvswitch_is_link_valid(device, link_id); 3763 } 3764 3765 nvlink_link* 3766 nvswitch_get_link(nvswitch_device *device, NvU8 link_id) 3767 { 3768 nvlink_link *link = NULL; 3769 3770 nvlink_lib_get_link(device->nvlink_device, link_id, &link); 3771 3772 return link; 3773 } 3774 3775 NvU64 3776 nvswitch_get_enabled_link_mask 3777 ( 3778 nvswitch_device *device 3779 ) 3780 { 3781 NvU64 ret; 3782 nvlink_link *link; 3783 NvU32 link_num; 3784 3785 ret = 0x0; 3786 3787 for (link_num = 0; link_num < nvswitch_get_num_links(device); link_num++) 3788 { 3789 if (nvlink_lib_get_link(device->nvlink_device, link_num, &link) == NVL_SUCCESS) 3790 { 3791 ret |= NVBIT64(link_num); 3792 } 3793 } 3794 3795 return ret; 3796 } 3797 3798 void 3799 nvswitch_set_fatal_error 3800 ( 3801 nvswitch_device *device, 3802 NvBool device_fatal, 3803 NvU32 link_id 3804 ) 3805 { 3806 device->hal.nvswitch_set_fatal_error(device, device_fatal, link_id); 3807 } 3808 3809 NvU32 3810 nvswitch_get_swap_clk_default 3811 ( 3812 nvswitch_device *device 3813 ) 3814 { 3815 return device->hal.nvswitch_get_swap_clk_default(device); 3816 } 3817 3818 NvU32 3819 nvswitch_get_latency_sample_interval_msec 3820 ( 3821 nvswitch_device *device 3822 ) 3823 { 3824 return device->hal.nvswitch_get_latency_sample_interval_msec(device); 3825 } 3826 3827 void 3828 nvswitch_internal_latency_bin_log 3829 ( 3830 nvswitch_device *device 3831 ) 3832 { 3833 device->hal.nvswitch_internal_latency_bin_log(device); 3834 } 3835 3836 void 3837 nvswitch_ecc_writeback_task 3838 ( 3839 nvswitch_device *device 3840 ) 3841 { 3842 device->hal.nvswitch_ecc_writeback_task(device); 3843 } 3844 3845 void 3846 nvswitch_monitor_thermal_alert 3847 ( 3848 nvswitch_device *device 3849 ) 3850 { 3851 device->hal.nvswitch_monitor_thermal_alert(device); 3852 } 3853 3854 void 3855 nvswitch_hw_counter_shutdown 3856 ( 3857 nvswitch_device *device 3858 ) 3859 { 3860 device->hal.nvswitch_hw_counter_shutdown(device); 3861 } 3862 3863 NvlStatus 3864 nvswitch_get_rom_info 3865 ( 3866 nvswitch_device *device, 3867 NVSWITCH_EEPROM_TYPE *eeprom 3868 ) 3869 { 3870 return device->hal.nvswitch_get_rom_info(device, eeprom); 3871 } 3872 3873 void 3874 nvswitch_lib_enable_interrupts 3875 ( 3876 nvswitch_device *device 3877 ) 3878 { 3879 if (!NVSWITCH_IS_DEVICE_ACCESSIBLE(device)) 3880 { 3881 NVSWITCH_ASSERT(0); 3882 return; 3883 } 3884 3885 device->hal.nvswitch_lib_enable_interrupts(device); 3886 } 3887 3888 void 3889 nvswitch_lib_disable_interrupts 3890 ( 3891 nvswitch_device *device 3892 ) 3893 { 3894 if (!NVSWITCH_IS_DEVICE_ACCESSIBLE(device)) 3895 { 3896 NVSWITCH_ASSERT(0); 3897 return; 3898 } 3899 3900 device->hal.nvswitch_lib_disable_interrupts(device); 3901 } 3902 3903 NvlStatus 3904 nvswitch_lib_check_interrupts 3905 ( 3906 nvswitch_device *device 3907 ) 3908 { 3909 if (!NVSWITCH_IS_DEVICE_INITIALIZED(device)) 3910 { 3911 return -NVL_BAD_ARGS; 3912 } 3913 3914 return device->hal.nvswitch_lib_check_interrupts(device); 3915 } 3916 3917 NvlStatus 3918 nvswitch_lib_service_interrupts 3919 ( 3920 nvswitch_device *device 3921 ) 3922 { 3923 if (!NVSWITCH_IS_DEVICE_INITIALIZED(device)) 3924 { 3925 return -NVL_BAD_ARGS; 3926 } 3927 3928 return device->hal.nvswitch_lib_service_interrupts(device); 3929 } 3930 3931 NvU64 3932 nvswitch_hw_counter_read_counter 3933 ( 3934 nvswitch_device *device 3935 ) 3936 { 3937 return device->hal.nvswitch_hw_counter_read_counter(device); 3938 } 3939 3940 NvU32 3941 nvswitch_get_link_ip_version 3942 ( 3943 nvswitch_device *device, 3944 NvU32 link_id 3945 ) 3946 { 3947 return device->hal.nvswitch_get_link_ip_version(device, link_id); 3948 } 3949 3950 NvU32 3951 nvswitch_reg_read_32 3952 ( 3953 nvswitch_device *device, 3954 NvU32 offset 3955 ) 3956 { 3957 NvU32 val; 3958 3959 if (device->nvlink_device->pciInfo.bars[0].pBar == NULL) 3960 { 3961 NVSWITCH_PRINT(device, ERROR, 3962 "register read failed at offset 0x%x\n", offset); 3963 3964 return 0xFFFFFFFF; 3965 } 3966 3967 val = nvswitch_os_mem_read32((NvU8 *)device->nvlink_device->pciInfo.bars[0].pBar + offset); 3968 3969 if ((val & 0xFFFF0000) == 0xBADF0000) 3970 { 3971 NvU32 boot_0; 3972 NVSWITCH_PRINT(device, WARN, 3973 "Potential IO failure reading 0x%x (0x%x)\n", offset, val); 3974 boot_0 = nvswitch_os_mem_read32((NvU8 *)device->nvlink_device->pciInfo.bars[0].pBar + 0x0); 3975 3976 if ((boot_0 & 0xFFFF0000) == 0xBADF0000) 3977 { 3978 NVSWITCH_PRINT_SXID(device, NVSWITCH_ERR_HW_HOST_IO_FAILURE, 3979 "IO failure\n"); 3980 NVSWITCH_PRINT(device, ERROR, 3981 "IO failure reading 0x%x (0x%x)\n", offset, val); 3982 } 3983 } 3984 3985 #ifdef _VERBOSE_REG_ACCESS 3986 NVSWITCH_PRINT(device, SETUP, 3987 "NVSWITCH read 0x%6x+%6x = 0x%08x\n", 3988 device->nvlink_device->pciInfo.bars[0].baseAddr, offset, val); 3989 #endif 3990 3991 return val; 3992 } 3993 3994 void 3995 nvswitch_reg_write_32 3996 ( 3997 nvswitch_device *device, 3998 NvU32 offset, 3999 NvU32 data 4000 ) 4001 { 4002 if (device->nvlink_device->pciInfo.bars[0].pBar == NULL) 4003 { 4004 NVSWITCH_PRINT(device, ERROR, 4005 "register write failed at offset 0x%x\n", offset); 4006 4007 return; 4008 } 4009 4010 #ifdef _VERBOSE_REG_ACCESS 4011 NVSWITCH_PRINT(device, SETUP, 4012 "NVSWITCH write 0x%6x+%6x = 0x%08x\n", 4013 device->nvlink_device->pciInfo.bars[0].baseAddr, offset, data); 4014 #endif 4015 4016 // Write the register 4017 nvswitch_os_mem_write32((NvU8 *)device->nvlink_device->pciInfo.bars[0].pBar + offset, data); 4018 4019 return; 4020 } 4021 4022 NvU64 4023 nvswitch_read_64bit_counter 4024 ( 4025 nvswitch_device *device, 4026 NvU32 lo_offset, 4027 NvU32 hi_offset 4028 ) 4029 { 4030 NvU32 hi0; 4031 NvU32 hi1; 4032 NvU32 lo; 4033 4034 hi0 = nvswitch_reg_read_32(device, hi_offset); 4035 do 4036 { 4037 hi1 = hi0; 4038 lo = nvswitch_reg_read_32(device, lo_offset); 4039 hi0 = nvswitch_reg_read_32(device, hi_offset); 4040 } while (hi0 != hi1); 4041 4042 return (lo | ((NvU64)hi0 << 32)); 4043 } 4044 4045 NvlStatus 4046 nvswitch_validate_pll_config 4047 ( 4048 nvswitch_device *device, 4049 NVSWITCH_PLL_INFO *switch_pll, 4050 NVSWITCH_PLL_LIMITS default_pll_limits 4051 ) 4052 { 4053 NvU32 update_rate_khz; 4054 NvU32 vco_freq_khz; 4055 NVSWITCH_PLL_LIMITS pll_limits; 4056 4057 NVSWITCH_PRINT(device, SETUP, 4058 "%s: Validating PLL: %dkHz * %d / (%d * %d * (1 << %d))\n", 4059 __FUNCTION__, 4060 switch_pll->src_freq_khz, 4061 switch_pll->N, 4062 switch_pll->M, 4063 switch_pll->PL, 4064 switch_pll->dist_mode); 4065 4066 // 4067 // These parameters could come from schmoo'ing API, settings file or a ROM. 4068 // For now, hard code with POR. 4069 // 4070 if (device->firmware.firmware_size > 0 && 4071 device->firmware.clocks.clocks_found && 4072 device->firmware.clocks.sys_pll.valid) 4073 { 4074 pll_limits = device->firmware.clocks.sys_pll; 4075 } 4076 else 4077 { 4078 pll_limits = default_pll_limits; 4079 } 4080 4081 NVSWITCH_ASSERT(switch_pll->M != 0); 4082 NVSWITCH_ASSERT(switch_pll->PL != 0); 4083 4084 if ((switch_pll->src_freq_khz < pll_limits.ref_min_mhz * 1000) || 4085 (switch_pll->src_freq_khz > pll_limits.ref_max_mhz * 1000)) 4086 { 4087 NVSWITCH_PRINT(device, ERROR, 4088 "%s: ERROR: Ref(%d) out-of-range\n", 4089 __FUNCTION__, 4090 switch_pll->src_freq_khz); 4091 return -NVL_ERR_INVALID_STATE; 4092 } 4093 4094 if ((switch_pll->M < pll_limits.m_min) || 4095 (switch_pll->M > pll_limits.m_max)) 4096 { 4097 NVSWITCH_PRINT(device, ERROR, 4098 "%s: ERROR: M(%d) out-of-range\n", 4099 __FUNCTION__, 4100 switch_pll->M); 4101 return -NVL_ERR_INVALID_STATE; 4102 } 4103 4104 if ((switch_pll->N < pll_limits.n_min) || 4105 (switch_pll->N > pll_limits.n_max)) 4106 { 4107 NVSWITCH_PRINT(device, ERROR, 4108 "%s: ERROR: N(%d) out-of-range\n", 4109 __FUNCTION__, 4110 switch_pll->N); 4111 return -NVL_ERR_INVALID_STATE; 4112 } 4113 4114 if ((switch_pll->PL < pll_limits.pl_min) || 4115 (switch_pll->PL > pll_limits.pl_max)) 4116 { 4117 NVSWITCH_PRINT(device, ERROR, 4118 "%s: ERROR: PL(%d) out-of-range\n", 4119 __FUNCTION__, 4120 switch_pll->PL); 4121 return -NVL_ERR_INVALID_STATE; 4122 } 4123 4124 vco_freq_khz = switch_pll->src_freq_khz * switch_pll->N 4125 / switch_pll->M; 4126 if ((vco_freq_khz < pll_limits.vco_min_mhz * 1000) || 4127 (vco_freq_khz > pll_limits.vco_max_mhz * 1000)) 4128 { 4129 NVSWITCH_PRINT(device, ERROR, 4130 "%s: ERROR: VCO(%d) freq out-of-range\n", 4131 __FUNCTION__, 4132 vco_freq_khz); 4133 return -NVL_ERR_INVALID_STATE; 4134 } 4135 4136 update_rate_khz = switch_pll->src_freq_khz / switch_pll->M; 4137 if ((update_rate_khz < pll_limits.update_min_mhz * 1000) || 4138 (update_rate_khz > pll_limits.update_max_mhz * 1000)) 4139 { 4140 NVSWITCH_PRINT(device, ERROR, 4141 "%s: ERROR: update rate(%d) out-of-range\n", 4142 __FUNCTION__, 4143 update_rate_khz); 4144 return -NVL_ERR_INVALID_STATE; 4145 } 4146 4147 switch_pll->vco_freq_khz = vco_freq_khz; 4148 4149 switch_pll->freq_khz = 4150 switch_pll->src_freq_khz * switch_pll->N / 4151 (switch_pll->M * switch_pll->PL * (1 << switch_pll->dist_mode)); 4152 4153 NVSWITCH_PRINT(device, SETUP, 4154 "%s: Validated PLL: %dkHz * %d / (%d * %d * (1 << %d)) = %dkHz\n", 4155 __FUNCTION__, 4156 switch_pll->src_freq_khz, 4157 switch_pll->N, 4158 switch_pll->M, 4159 switch_pll->PL, 4160 switch_pll->dist_mode, 4161 switch_pll->freq_khz); 4162 4163 return NVL_SUCCESS; 4164 } 4165 4166 NvlStatus 4167 nvswitch_init_pll_config 4168 ( 4169 nvswitch_device *device 4170 ) 4171 { 4172 return device->hal.nvswitch_init_pll_config(device); 4173 } 4174 4175 NvlStatus 4176 nvswitch_init_pll 4177 ( 4178 nvswitch_device *device 4179 ) 4180 { 4181 return device->hal.nvswitch_init_pll(device); 4182 } 4183 4184 void 4185 nvswitch_init_clock_gating 4186 ( 4187 nvswitch_device *device 4188 ) 4189 { 4190 return device->hal.nvswitch_init_clock_gating(device); 4191 } 4192 4193 void 4194 nvswitch_lib_get_uuid 4195 ( 4196 nvswitch_device *device, 4197 NvUuid *uuid 4198 ) 4199 { 4200 if (!NVSWITCH_IS_DEVICE_INITIALIZED(device) || (uuid == NULL)) 4201 { 4202 return; 4203 } 4204 4205 nvswitch_os_memcpy(uuid, &device->uuid, sizeof(device->uuid)); 4206 } 4207 4208 NvlStatus 4209 nvswitch_lib_get_physid 4210 ( 4211 nvswitch_device *device, 4212 NvU32 *phys_id 4213 ) 4214 { 4215 NVSWITCH_GET_INFO get_info; 4216 NvlStatus ret; 4217 4218 if (phys_id == NULL || !NVSWITCH_IS_DEVICE_ACCESSIBLE(device)) 4219 { 4220 return -NVL_BAD_ARGS; 4221 } 4222 4223 get_info.count=1; 4224 get_info.index[0] = NVSWITCH_GET_INFO_INDEX_PHYSICAL_ID; 4225 4226 ret = _nvswitch_ctrl_get_info(device, &get_info); 4227 if (ret != NVL_SUCCESS) 4228 { 4229 NVSWITCH_PRINT(device, ERROR, 4230 "Failed to get physical ID\n"); 4231 return ret; 4232 } 4233 4234 *phys_id = get_info.info[0]; 4235 4236 return NVL_SUCCESS; 4237 } 4238 4239 void 4240 nvswitch_i2c_set_hw_speed_mode 4241 ( 4242 nvswitch_device *device, 4243 NvU32 port, 4244 NvU32 speedMode 4245 ) 4246 { 4247 device->hal.nvswitch_i2c_set_hw_speed_mode(device, port, speedMode); 4248 return; 4249 } 4250 4251 void 4252 nvswitch_lib_smbpbi_log_sxid 4253 ( 4254 nvswitch_device *device, 4255 NvU32 sxid, 4256 const char *pFormat, 4257 ... 4258 ) 4259 { 4260 va_list arglist; 4261 int msglen; 4262 char string[RM_SOE_SMBPBI_CMD_LOG_MESSAGE_MAX_STRING + 1]; 4263 4264 nvswitch_os_memset(string, 0, (NvLength)sizeof(string)); 4265 4266 va_start(arglist, pFormat); 4267 msglen = nvswitch_os_vsnprintf(string, sizeof(string), pFormat, arglist); 4268 va_end(arglist); 4269 4270 if (!(msglen < 0)) 4271 { 4272 // 4273 // HALs will know that the string is being truncated by seeing that the 4274 // last byte in the buffer is not nul. 4275 // 4276 msglen = NV_MIN(msglen + 1, (int)RM_SOE_SMBPBI_CMD_LOG_MESSAGE_MAX_STRING); 4277 device->hal.nvswitch_smbpbi_log_message(device, sxid, msglen, (NvU8 *) string); 4278 } 4279 } 4280 4281 NvlStatus 4282 nvswitch_set_minion_initialized 4283 ( 4284 nvswitch_device *device, 4285 NvU32 idx_minion, 4286 NvBool initialized 4287 ) 4288 { 4289 return device->hal.nvswitch_set_minion_initialized(device, idx_minion, initialized); 4290 } 4291 4292 NvBool 4293 nvswitch_is_minion_initialized 4294 ( 4295 nvswitch_device *device, 4296 NvU32 idx_minion 4297 ) 4298 { 4299 return device->hal.nvswitch_is_minion_initialized(device, idx_minion); 4300 } 4301 4302 NvlStatus 4303 nvswitch_device_discovery 4304 ( 4305 nvswitch_device *device, 4306 NvU32 discovery_offset 4307 ) 4308 { 4309 return device->hal.nvswitch_device_discovery(device, discovery_offset); 4310 } 4311 4312 void 4313 nvswitch_filter_discovery 4314 ( 4315 nvswitch_device *device 4316 ) 4317 { 4318 device->hal.nvswitch_filter_discovery(device); 4319 } 4320 4321 NvlStatus 4322 nvswitch_process_discovery 4323 ( 4324 nvswitch_device *device 4325 ) 4326 { 4327 return device->hal.nvswitch_process_discovery(device); 4328 } 4329 4330 NvlStatus 4331 nvswitch_init_minion 4332 ( 4333 nvswitch_device *device 4334 ) 4335 { 4336 return device->hal.nvswitch_init_minion(device); 4337 } 4338 4339 NvU32 4340 nvswitch_get_link_eng_inst 4341 ( 4342 nvswitch_device *device, 4343 NvU32 link_id, 4344 NVSWITCH_ENGINE_ID eng_id 4345 ) 4346 { 4347 return device->hal.nvswitch_get_link_eng_inst(device, link_id, eng_id); 4348 } 4349 4350 void * 4351 nvswitch_alloc_chipdevice 4352 ( 4353 nvswitch_device *device 4354 ) 4355 { 4356 return(device->hal.nvswitch_alloc_chipdevice(device)); 4357 } 4358 4359 void 4360 nvswitch_free_chipdevice 4361 ( 4362 nvswitch_device *device 4363 ) 4364 { 4365 if (device->chip_device) 4366 { 4367 nvswitch_os_free(device->chip_device); 4368 device->chip_device = NULL; 4369 } 4370 } 4371 4372 NvlStatus 4373 nvswitch_init_thermal 4374 ( 4375 nvswitch_device *device 4376 ) 4377 { 4378 return(device->hal.nvswitch_init_thermal(device)); 4379 } 4380 4381 NvU32 4382 nvswitch_read_physical_id 4383 ( 4384 nvswitch_device *device 4385 ) 4386 { 4387 return(device->hal.nvswitch_read_physical_id(device)); 4388 } 4389 4390 NvU32 4391 nvswitch_get_caps_nvlink_version 4392 ( 4393 nvswitch_device *device 4394 ) 4395 { 4396 return(device->hal.nvswitch_get_caps_nvlink_version(device)); 4397 } 4398 4399 void 4400 nvswitch_initialize_interrupt_tree 4401 ( 4402 nvswitch_device *device 4403 ) 4404 { 4405 device->hal.nvswitch_initialize_interrupt_tree(device); 4406 } 4407 4408 void 4409 nvswitch_init_dlpl_interrupts 4410 ( 4411 nvlink_link *link 4412 ) 4413 { 4414 nvswitch_device *device = link->dev->pDevInfo; 4415 4416 device->hal.nvswitch_init_dlpl_interrupts(link); 4417 } 4418 4419 NvlStatus 4420 nvswitch_initialize_pmgr 4421 ( 4422 nvswitch_device *device 4423 ) 4424 { 4425 return(device->hal.nvswitch_initialize_pmgr(device)); 4426 } 4427 4428 NvlStatus 4429 nvswitch_initialize_ip_wrappers 4430 ( 4431 nvswitch_device *device 4432 ) 4433 { 4434 return(device->hal.nvswitch_initialize_ip_wrappers(device)); 4435 } 4436 4437 NvlStatus 4438 nvswitch_initialize_route 4439 ( 4440 nvswitch_device *device 4441 ) 4442 { 4443 return(device->hal.nvswitch_initialize_route(device)); 4444 } 4445 4446 void 4447 nvswitch_soe_unregister_events 4448 ( 4449 nvswitch_device *device 4450 ) 4451 { 4452 device->hal.nvswitch_soe_unregister_events(device); 4453 } 4454 4455 NvlStatus 4456 nvswitch_soe_register_event_callbacks 4457 ( 4458 nvswitch_device *device 4459 ) 4460 { 4461 return device->hal.nvswitch_soe_register_event_callbacks(device); 4462 } 4463 4464 NVSWITCH_BIOS_NVLINK_CONFIG * 4465 nvswitch_get_bios_nvlink_config 4466 ( 4467 nvswitch_device *device 4468 ) 4469 { 4470 return(device->hal.nvswitch_get_bios_nvlink_config(device)); 4471 } 4472 4473 NvlStatus 4474 nvswitch_minion_send_command 4475 ( 4476 nvswitch_device *device, 4477 NvU32 linkNumber, 4478 NvU32 command, 4479 NvU32 scratch0 4480 ) 4481 { 4482 return(device->hal.nvswitch_minion_send_command(device, linkNumber, 4483 command, scratch0)); 4484 } 4485 4486 NvlStatus 4487 nvswitch_init_nport 4488 ( 4489 nvswitch_device *device 4490 ) 4491 { 4492 return device->hal.nvswitch_init_nport(device); 4493 } 4494 4495 NvlStatus 4496 nvswitch_init_nxbar 4497 ( 4498 nvswitch_device *device 4499 ) 4500 { 4501 return device->hal.nvswitch_init_nxbar(device); 4502 } 4503 4504 NvlStatus 4505 nvswitch_clear_nport_rams 4506 ( 4507 nvswitch_device *device 4508 ) 4509 { 4510 return device->hal.nvswitch_clear_nport_rams(device); 4511 } 4512 4513 NvlStatus 4514 nvswitch_pri_ring_init 4515 ( 4516 nvswitch_device *device 4517 ) 4518 { 4519 return(device->hal.nvswitch_pri_ring_init(device)); 4520 } 4521 4522 NvlStatus 4523 nvswitch_get_remap_table_selector 4524 ( 4525 nvswitch_device *device, 4526 NVSWITCH_TABLE_SELECT_REMAP table_selector, 4527 NvU32 *remap_ram_sel 4528 ) 4529 { 4530 return device->hal.nvswitch_get_remap_table_selector(device, table_selector, remap_ram_sel); 4531 } 4532 4533 NvU32 4534 nvswitch_get_ingress_ram_size 4535 ( 4536 nvswitch_device *device, 4537 NvU32 ingress_ram_selector // NV_INGRESS_REQRSPMAPADDR_RAM_ADDRESS_* 4538 ) 4539 { 4540 return device->hal.nvswitch_get_ingress_ram_size(device, ingress_ram_selector); 4541 } 4542 4543 NvlStatus 4544 nvswitch_minion_get_dl_status 4545 ( 4546 nvswitch_device *device, 4547 NvU32 linkId, 4548 NvU32 statusIdx, 4549 NvU32 statusArgs, 4550 NvU32 *statusData 4551 ) 4552 { 4553 return device->hal.nvswitch_minion_get_dl_status(device, linkId, statusIdx, statusArgs, statusData); 4554 } 4555 4556 NvBool 4557 nvswitch_is_i2c_supported 4558 ( 4559 nvswitch_device *device 4560 ) 4561 { 4562 return device->hal.nvswitch_is_i2c_supported(device); 4563 } 4564 4565 4566 NvlStatus 4567 nvswitch_poll_sublink_state 4568 ( 4569 nvswitch_device *device, 4570 nvlink_link *link 4571 ) 4572 { 4573 return device->hal.nvswitch_poll_sublink_state(device, link); 4574 } 4575 4576 void 4577 nvswitch_setup_link_loopback_mode 4578 ( 4579 nvswitch_device *device, 4580 NvU32 linkNumber 4581 ) 4582 { 4583 return device->hal.nvswitch_setup_link_loopback_mode(device, linkNumber); 4584 } 4585 4586 void 4587 nvswitch_reset_persistent_link_hw_state 4588 ( 4589 nvswitch_device *device, 4590 NvU32 linkNumber 4591 ) 4592 { 4593 return device->hal.nvswitch_reset_persistent_link_hw_state(device, linkNumber); 4594 } 4595 4596 void 4597 nvswitch_store_topology_information 4598 ( 4599 nvswitch_device *device, 4600 nvlink_link *link 4601 ) 4602 { 4603 return device->hal.nvswitch_store_topology_information(device, link); 4604 } 4605 4606 void 4607 nvswitch_init_lpwr_regs 4608 ( 4609 nvlink_link *link 4610 ) 4611 { 4612 nvswitch_device *device = link->dev->pDevInfo; 4613 device->hal.nvswitch_init_lpwr_regs(link); 4614 } 4615 4616 NvlStatus 4617 nvswitch_launch_ALI 4618 ( 4619 nvswitch_device *device 4620 ) 4621 { 4622 return device->hal.nvswitch_launch_ALI(device); 4623 } 4624 4625 NvlStatus 4626 nvswitch_set_training_mode 4627 ( 4628 nvswitch_device *device 4629 ) 4630 { 4631 return device->hal.nvswitch_set_training_mode(device); 4632 } 4633 4634 NvBool 4635 nvswitch_is_link_in_reset 4636 ( 4637 nvswitch_device *device, 4638 nvlink_link *link 4639 ) 4640 { 4641 return device->hal.nvswitch_is_link_in_reset(device, link); 4642 } 4643 4644 NvBool 4645 nvswitch_i2c_is_device_access_allowed 4646 ( 4647 nvswitch_device *device, 4648 NvU32 port, 4649 NvU8 addr, 4650 NvBool bIsRead 4651 ) 4652 { 4653 return device->hal.nvswitch_i2c_is_device_access_allowed(device, port, addr, bIsRead); 4654 } 4655 4656 NvlStatus 4657 nvswitch_parse_bios_image 4658 ( 4659 nvswitch_device *device 4660 ) 4661 { 4662 return device->hal.nvswitch_parse_bios_image(device); 4663 } 4664 4665 void 4666 nvswitch_init_buffer_ready 4667 ( 4668 nvswitch_device *device, 4669 nvlink_link *link, 4670 NvBool bNportBufferReady 4671 ) 4672 { 4673 return device->hal.nvswitch_init_buffer_ready(device, link, bNportBufferReady); 4674 } 4675 4676 void 4677 nvswitch_apply_recal_settings 4678 ( 4679 nvswitch_device *device, 4680 nvlink_link *link 4681 ) 4682 { 4683 return device->hal.nvswitch_apply_recal_settings(device, link); 4684 } 4685 4686 NvlStatus 4687 nvswitch_launch_ALI_link_training 4688 ( 4689 nvswitch_device *device, 4690 nvlink_link *link, 4691 NvBool bSync 4692 ) 4693 { 4694 return device->hal.nvswitch_launch_ALI_link_training(device, link, bSync); 4695 } 4696 4697 NvlStatus 4698 nvswitch_reset_and_train_link 4699 ( 4700 nvswitch_device *device, 4701 nvlink_link *link 4702 ) 4703 { 4704 return device->hal.nvswitch_reset_and_train_link(device, link); 4705 } 4706 4707 static NvlStatus 4708 _nvswitch_ctrl_get_err_info 4709 ( 4710 nvswitch_device *device, 4711 NVSWITCH_NVLINK_GET_ERR_INFO_PARAMS *ret 4712 ) 4713 { 4714 return device->hal.nvswitch_ctrl_get_err_info(device, ret); 4715 } 4716 4717 static NvlStatus 4718 _nvswitch_ctrl_clear_counters 4719 ( 4720 nvswitch_device *device, 4721 NVSWITCH_NVLINK_CLEAR_COUNTERS_PARAMS *ret 4722 ) 4723 { 4724 return device->hal.nvswitch_ctrl_clear_counters(device, ret); 4725 } 4726 4727 void 4728 nvswitch_setup_link_system_registers 4729 ( 4730 nvswitch_device *device, 4731 nvlink_link *link 4732 ) 4733 { 4734 device->hal.nvswitch_setup_link_system_registers(device, link); 4735 } 4736 4737 void 4738 nvswitch_load_link_disable_settings 4739 ( 4740 nvswitch_device *device, 4741 nvlink_link *link 4742 ) 4743 { 4744 device->hal.nvswitch_load_link_disable_settings(device, link); 4745 } 4746 4747 static NvlStatus 4748 _nvswitch_ctrl_set_nvlink_error_threshold 4749 ( 4750 nvswitch_device *device, 4751 NVSWITCH_SET_NVLINK_ERROR_THRESHOLD_PARAMS *pParams 4752 ) 4753 { 4754 return device->hal.nvswitch_ctrl_set_nvlink_error_threshold(device, pParams); 4755 } 4756 4757 static NvlStatus 4758 _nvswitch_ctrl_get_nvlink_error_threshold 4759 ( 4760 nvswitch_device *device, 4761 NVSWITCH_GET_NVLINK_ERROR_THRESHOLD_PARAMS *pParams 4762 ) 4763 { 4764 return device->hal.nvswitch_ctrl_get_nvlink_error_threshold(device, pParams); 4765 } 4766 4767 static NvlStatus 4768 _nvswitch_ctrl_therm_read_voltage 4769 ( 4770 nvswitch_device *device, 4771 NVSWITCH_CTRL_GET_VOLTAGE_PARAMS *info 4772 ) 4773 { 4774 return device->hal.nvswitch_ctrl_therm_read_voltage(device, info); 4775 } 4776 4777 static NvlStatus 4778 _nvswitch_ctrl_therm_read_power 4779 ( 4780 nvswitch_device *device, 4781 NVSWITCH_GET_POWER_PARAMS *info 4782 ) 4783 { 4784 return device->hal.nvswitch_ctrl_therm_read_power(device, info); 4785 } 4786 4787 NvlStatus 4788 nvswitch_lib_ctrl 4789 ( 4790 nvswitch_device *device, 4791 NvU32 cmd, 4792 void *params, 4793 NvU64 size, 4794 void *osPrivate 4795 ) 4796 { 4797 NvlStatus retval; 4798 NvU64 flags = 0; 4799 4800 if (!NVSWITCH_IS_DEVICE_ACCESSIBLE(device) || params == NULL) 4801 { 4802 return -NVL_BAD_ARGS; 4803 } 4804 4805 flags = NVSWITCH_DEV_CMD_CHECK_ADMIN | NVSWITCH_DEV_CMD_CHECK_FM; 4806 switch (cmd) 4807 { 4808 NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_INFO, 4809 _nvswitch_ctrl_get_info, 4810 NVSWITCH_GET_INFO); 4811 NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_INTERNAL_LATENCY, 4812 _nvswitch_ctrl_get_internal_latency, 4813 NVSWITCH_GET_INTERNAL_LATENCY); 4814 NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_NVLIPT_COUNTERS, 4815 _nvswitch_ctrl_get_nvlipt_counters, 4816 NVSWITCH_GET_NVLIPT_COUNTERS); 4817 NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_ERRORS, 4818 nvswitch_ctrl_get_errors, 4819 NVSWITCH_GET_ERRORS_PARAMS); 4820 NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_NVLINK_STATUS, 4821 _nvswitch_ctrl_get_nvlink_status, 4822 NVSWITCH_GET_NVLINK_STATUS_PARAMS); 4823 NVSWITCH_DEV_CMD_DISPATCH_WITH_PRIVATE_DATA( 4824 CTRL_NVSWITCH_ACQUIRE_CAPABILITY, 4825 _nvswitch_ctrl_acquire_capability, 4826 NVSWITCH_ACQUIRE_CAPABILITY_PARAMS, 4827 osPrivate); 4828 NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_TEMPERATURE, 4829 _nvswitch_ctrl_therm_read_temperature, 4830 NVSWITCH_CTRL_GET_TEMPERATURE_PARAMS); 4831 NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_THROUGHPUT_COUNTERS, 4832 nvswitch_ctrl_get_throughput_counters, 4833 NVSWITCH_GET_THROUGHPUT_COUNTERS_PARAMS); 4834 NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_FATAL_ERROR_SCOPE, 4835 _nvswitch_ctrl_get_fatal_error_scope, 4836 NVSWITCH_GET_FATAL_ERROR_SCOPE_PARAMS); 4837 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED( 4838 CTRL_NVSWITCH_SET_SWITCH_PORT_CONFIG, 4839 _nvswitch_ctrl_set_switch_port_config, 4840 NVSWITCH_SET_SWITCH_PORT_CONFIG, 4841 osPrivate, flags); 4842 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED( 4843 CTRL_NVSWITCH_GET_INGRESS_REQUEST_TABLE, 4844 _nvswitch_ctrl_get_ingress_request_table, 4845 NVSWITCH_GET_INGRESS_REQUEST_TABLE_PARAMS, 4846 osPrivate, flags); 4847 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED( 4848 CTRL_NVSWITCH_SET_INGRESS_REQUEST_TABLE, 4849 _nvswitch_ctrl_set_ingress_request_table, 4850 NVSWITCH_SET_INGRESS_REQUEST_TABLE, 4851 osPrivate, flags); 4852 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED( 4853 CTRL_NVSWITCH_SET_INGRESS_REQUEST_VALID, 4854 _nvswitch_ctrl_set_ingress_request_valid, 4855 NVSWITCH_SET_INGRESS_REQUEST_VALID, 4856 osPrivate, flags); 4857 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED( 4858 CTRL_NVSWITCH_GET_INGRESS_RESPONSE_TABLE, 4859 _nvswitch_ctrl_get_ingress_response_table, 4860 NVSWITCH_GET_INGRESS_RESPONSE_TABLE_PARAMS, 4861 osPrivate, flags); 4862 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED( 4863 CTRL_NVSWITCH_SET_INGRESS_RESPONSE_TABLE, 4864 _nvswitch_ctrl_set_ingress_response_table, 4865 NVSWITCH_SET_INGRESS_RESPONSE_TABLE, 4866 osPrivate, flags); 4867 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED( 4868 CTRL_NVSWITCH_SET_GANGED_LINK_TABLE, 4869 _nvswitch_ctrl_set_ganged_link_table, 4870 NVSWITCH_SET_GANGED_LINK_TABLE, 4871 osPrivate, flags); 4872 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(CTRL_NVSWITCH_SET_LATENCY_BINS, 4873 nvswitch_ctrl_set_latency_bins, 4874 NVSWITCH_SET_LATENCY_BINS, 4875 osPrivate, flags); 4876 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED( 4877 CTRL_NVSWITCH_SET_NVLIPT_COUNTER_CONFIG, 4878 _nvswitch_ctrl_set_nvlipt_counter_config, 4879 NVSWITCH_SET_NVLIPT_COUNTER_CONFIG, 4880 osPrivate, flags); 4881 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED( 4882 CTRL_NVSWITCH_GET_NVLIPT_COUNTER_CONFIG, 4883 _nvswitch_ctrl_get_nvlipt_counter_config, 4884 NVSWITCH_GET_NVLIPT_COUNTER_CONFIG, 4885 osPrivate, flags); 4886 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(CTRL_NVSWITCH_SET_REMAP_POLICY, 4887 _nvswitch_ctrl_set_remap_policy, 4888 NVSWITCH_SET_REMAP_POLICY, 4889 osPrivate, flags); 4890 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(CTRL_NVSWITCH_GET_REMAP_POLICY, 4891 _nvswitch_ctrl_get_remap_policy, 4892 NVSWITCH_GET_REMAP_POLICY_PARAMS, 4893 osPrivate, flags); 4894 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED( 4895 CTRL_NVSWITCH_SET_REMAP_POLICY_VALID, 4896 _nvswitch_ctrl_set_remap_policy_valid, 4897 NVSWITCH_SET_REMAP_POLICY_VALID, 4898 osPrivate, flags); 4899 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(CTRL_NVSWITCH_SET_ROUTING_ID, 4900 _nvswitch_ctrl_set_routing_id, 4901 NVSWITCH_SET_ROUTING_ID, 4902 osPrivate, flags); 4903 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(CTRL_NVSWITCH_GET_ROUTING_ID, 4904 _nvswitch_ctrl_get_routing_id, 4905 NVSWITCH_GET_ROUTING_ID_PARAMS, 4906 osPrivate, flags); 4907 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(CTRL_NVSWITCH_SET_ROUTING_ID_VALID, 4908 _nvswitch_ctrl_set_routing_id_valid, 4909 NVSWITCH_SET_ROUTING_LAN_VALID, 4910 osPrivate, flags); 4911 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(CTRL_NVSWITCH_SET_ROUTING_LAN, 4912 _nvswitch_ctrl_set_routing_lan, 4913 NVSWITCH_SET_ROUTING_LAN, 4914 osPrivate, flags); 4915 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(CTRL_NVSWITCH_GET_ROUTING_LAN, 4916 _nvswitch_ctrl_get_routing_lan, 4917 NVSWITCH_GET_ROUTING_LAN_PARAMS, 4918 osPrivate, flags); 4919 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED( 4920 CTRL_NVSWITCH_SET_ROUTING_LAN_VALID, 4921 _nvswitch_ctrl_set_routing_lan_valid, 4922 NVSWITCH_SET_ROUTING_LAN_VALID, 4923 osPrivate, flags); 4924 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED( 4925 CTRL_NVSWITCH_GET_INGRESS_REQLINKID, 4926 _nvswitch_ctrl_get_ingress_reqlinkid, 4927 NVSWITCH_GET_INGRESS_REQLINKID_PARAMS, 4928 osPrivate, flags); 4929 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(CTRL_NVSWITCH_UNREGISTER_LINK, 4930 _nvswitch_ctrl_unregister_link, 4931 NVSWITCH_UNREGISTER_LINK_PARAMS, 4932 osPrivate, flags); 4933 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED( 4934 CTRL_NVSWITCH_RESET_AND_DRAIN_LINKS, 4935 _nvswitch_ctrl_reset_and_drain_links, 4936 NVSWITCH_RESET_AND_DRAIN_LINKS_PARAMS, 4937 osPrivate, flags); 4938 NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_BIOS_INFO, 4939 _nvswitch_ctrl_get_bios_info, 4940 NVSWITCH_GET_BIOS_INFO_PARAMS); 4941 NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_INFOROM_VERSION, 4942 _nvswitch_ctrl_get_inforom_version, 4943 NVSWITCH_GET_INFOROM_VERSION_PARAMS); 4944 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED( 4945 CTRL_NVSWITCH_BLACKLIST_DEVICE, 4946 nvswitch_ctrl_blacklist_device, 4947 NVSWITCH_BLACKLIST_DEVICE_PARAMS, 4948 osPrivate, flags); 4949 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED( 4950 CTRL_NVSWITCH_SET_FM_DRIVER_STATE, 4951 nvswitch_ctrl_set_fm_driver_state, 4952 NVSWITCH_SET_FM_DRIVER_STATE_PARAMS, 4953 osPrivate, flags); 4954 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED( 4955 CTRL_NVSWITCH_SET_DEVICE_FABRIC_STATE, 4956 nvswitch_ctrl_set_device_fabric_state, 4957 NVSWITCH_SET_DEVICE_FABRIC_STATE_PARAMS, 4958 osPrivate, flags); 4959 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED( 4960 CTRL_NVSWITCH_SET_FM_HEARTBEAT_TIMEOUT, 4961 nvswitch_ctrl_set_fm_timeout, 4962 NVSWITCH_SET_FM_HEARTBEAT_TIMEOUT_PARAMS, 4963 osPrivate, flags); 4964 NVSWITCH_DEV_CMD_DISPATCH_WITH_PRIVATE_DATA( 4965 CTRL_NVSWITCH_REGISTER_EVENTS, 4966 _nvswitch_ctrl_register_events, 4967 NVSWITCH_REGISTER_EVENTS_PARAMS, 4968 osPrivate); 4969 NVSWITCH_DEV_CMD_DISPATCH_WITH_PRIVATE_DATA( 4970 CTRL_NVSWITCH_UNREGISTER_EVENTS, 4971 _nvswitch_ctrl_unregister_events, 4972 NVSWITCH_UNREGISTER_EVENTS_PARAMS, 4973 osPrivate); 4974 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED( 4975 CTRL_NVSWITCH_SET_TRAINING_ERROR_INFO, 4976 _nvswitch_ctrl_set_training_error_info, 4977 NVSWITCH_SET_TRAINING_ERROR_INFO_PARAMS, 4978 osPrivate, flags); 4979 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED( 4980 CTRL_NVSWITCH_SET_MC_RID_TABLE, 4981 _nvswitch_ctrl_set_mc_rid_table, 4982 NVSWITCH_SET_MC_RID_TABLE_PARAMS, 4983 osPrivate, flags); 4984 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED( 4985 CTRL_NVSWITCH_GET_MC_RID_TABLE, 4986 _nvswitch_ctrl_get_mc_rid_table, 4987 NVSWITCH_GET_MC_RID_TABLE_PARAMS, 4988 osPrivate, flags); 4989 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED( 4990 CTRL_NVSWITCH_GET_COUNTERS, 4991 _nvswitch_ctrl_get_counters, 4992 NVSWITCH_NVLINK_GET_COUNTERS_PARAMS, 4993 osPrivate, flags); 4994 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED( 4995 CTRL_NVSWITCH_GET_NVLINK_ECC_ERRORS, 4996 _nvswitch_ctrl_get_nvlink_ecc_errors, 4997 NVSWITCH_GET_NVLINK_ECC_ERRORS_PARAMS, 4998 osPrivate, flags); 4999 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED( 5000 CTRL_NVSWITCH_I2C_SMBUS_COMMAND, 5001 _nvswitch_ctrl_i2c_smbus_command, 5002 NVSWITCH_I2C_SMBUS_COMMAND_PARAMS, 5003 osPrivate, NVSWITCH_DEV_CMD_CHECK_ADMIN); 5004 NVSWITCH_DEV_CMD_DISPATCH_RESERVED( 5005 CTRL_NVSWITCH_RESERVED_0); 5006 NVSWITCH_DEV_CMD_DISPATCH_RESERVED( 5007 CTRL_NVSWITCH_RESERVED_1); 5008 NVSWITCH_DEV_CMD_DISPATCH_RESERVED( 5009 CTRL_NVSWITCH_RESERVED_2); 5010 NVSWITCH_DEV_CMD_DISPATCH_RESERVED( 5011 CTRL_NVSWITCH_RESERVED_3); 5012 NVSWITCH_DEV_CMD_DISPATCH_RESERVED( 5013 CTRL_NVSWITCH_RESERVED_4); 5014 NVSWITCH_DEV_CMD_DISPATCH_RESERVED( 5015 CTRL_NVSWITCH_RESERVED_5); 5016 NVSWITCH_DEV_CMD_DISPATCH_RESERVED( 5017 CTRL_NVSWITCH_RESERVED_8); 5018 NVSWITCH_DEV_CMD_DISPATCH_RESERVED( 5019 CTRL_NVSWITCH_RESERVED_9); 5020 NVSWITCH_DEV_CMD_DISPATCH_RESERVED( 5021 CTRL_NVSWITCH_RESERVED_10); 5022 NVSWITCH_DEV_CMD_DISPATCH_RESERVED( 5023 CTRL_NVSWITCH_RESERVED_11); 5024 NVSWITCH_DEV_CMD_DISPATCH( 5025 CTRL_NVSWITCH_GET_TEMPERATURE_LIMIT, 5026 _nvswitch_ctrl_therm_get_temperature_limit, 5027 NVSWITCH_CTRL_GET_TEMPERATURE_LIMIT_PARAMS); 5028 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED( 5029 CTRL_NVSWITCH_GET_NVLINK_MAX_ERROR_RATES, 5030 _nvswitch_ctrl_get_inforom_nvlink_max_correctable_error_rate, 5031 NVSWITCH_GET_NVLINK_MAX_CORRECTABLE_ERROR_RATES_PARAMS, 5032 osPrivate, flags); 5033 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED( 5034 CTRL_NVSWITCH_GET_NVLINK_ERROR_COUNTS, 5035 _nvswitch_ctrl_get_inforom_nvlink_errors, 5036 NVSWITCH_GET_NVLINK_ERROR_COUNTS_PARAMS, 5037 osPrivate, flags); 5038 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED( 5039 CTRL_NVSWITCH_GET_ECC_ERROR_COUNTS, 5040 _nvswitch_ctrl_get_inforom_ecc_errors, 5041 NVSWITCH_GET_ECC_ERROR_COUNTS_PARAMS, 5042 osPrivate, flags); 5043 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED( 5044 CTRL_NVSWITCH_GET_SXIDS, 5045 _nvswitch_ctrl_get_inforom_bbx_sxid, 5046 NVSWITCH_GET_SXIDS_PARAMS, 5047 osPrivate, flags); 5048 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED( 5049 CTRL_NVSWITCH_GET_FOM_VALUES, 5050 _nvswitch_ctrl_get_fom_values, 5051 NVSWITCH_GET_FOM_VALUES_PARAMS, 5052 osPrivate, flags); 5053 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED( 5054 CTRL_NVSWITCH_GET_NVLINK_LP_COUNTERS, 5055 _nvswitch_ctrl_get_nvlink_lp_counters, 5056 NVSWITCH_GET_NVLINK_LP_COUNTERS_PARAMS, 5057 osPrivate, flags); 5058 NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_RESIDENCY_BINS, 5059 _nvswitch_ctrl_get_residency_bins, 5060 NVSWITCH_GET_RESIDENCY_BINS); 5061 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(CTRL_NVSWITCH_SET_RESIDENCY_BINS, 5062 _nvswitch_ctrl_set_residency_bins, 5063 NVSWITCH_SET_RESIDENCY_BINS, 5064 osPrivate, flags); 5065 NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_RB_STALL_BUSY, 5066 _nvswitch_ctrl_get_rb_stall_busy, 5067 NVSWITCH_GET_RB_STALL_BUSY); 5068 NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_MULTICAST_ID_ERROR_VECTOR, 5069 nvswitch_ctrl_get_multicast_id_error_vector, 5070 NVSWITCH_GET_MULTICAST_ID_ERROR_VECTOR); 5071 NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_CLEAR_MULTICAST_ID_ERROR_VECTOR, 5072 nvswitch_ctrl_clear_multicast_id_error_vector, 5073 NVSWITCH_CLEAR_MULTICAST_ID_ERROR_VECTOR); 5074 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED( 5075 CTRL_NVSWITCH_INBAND_SEND_DATA, 5076 _nvswitch_ctrl_inband_send_data, 5077 NVSWITCH_INBAND_SEND_DATA_PARAMS, 5078 osPrivate, flags); 5079 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED( 5080 CTRL_NVSWITCH_INBAND_READ_DATA, 5081 _nvswitch_ctrl_inband_read_data, 5082 NVSWITCH_INBAND_READ_DATA_PARAMS, 5083 osPrivate, flags); 5084 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED( 5085 CTRL_NVSWITCH_INBAND_FLUSH_DATA, 5086 _nvswitch_ctrl_inband_flush_data, 5087 NVSWITCH_INBAND_FLUSH_DATA_PARAMS, 5088 osPrivate, flags); 5089 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED( 5090 CTRL_NVSWITCH_INBAND_PENDING_DATA_STATS, 5091 _nvswitch_ctrl_inband_pending_data_stats, 5092 NVSWITCH_INBAND_PENDING_DATA_STATS_PARAMS, 5093 osPrivate, flags); 5094 NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_BOARD_PART_NUMBER, 5095 _nvswitch_ctrl_get_board_part_number, 5096 NVSWITCH_GET_BOARD_PART_NUMBER_VECTOR); 5097 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED( 5098 CTRL_NVSWITCH_GET_SW_INFO, 5099 _nvswitch_ctrl_get_sw_info, 5100 NVSWITCH_GET_SW_INFO_PARAMS, 5101 osPrivate, flags); 5102 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(CTRL_NVSWITCH_REGISTER_READ, 5103 _nvswitch_ctrl_register_read, 5104 NVSWITCH_REGISTER_READ, 5105 osPrivate, flags); 5106 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(CTRL_NVSWITCH_REGISTER_WRITE, 5107 _nvswitch_ctrl_register_write, 5108 NVSWITCH_REGISTER_WRITE, 5109 osPrivate, flags); 5110 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(CTRL_NVSWITCH_GET_ERR_INFO, 5111 _nvswitch_ctrl_get_err_info, 5112 NVSWITCH_NVLINK_GET_ERR_INFO_PARAMS, 5113 osPrivate, flags); 5114 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(CTRL_NVSWITCH_CLEAR_COUNTERS, 5115 _nvswitch_ctrl_clear_counters, 5116 NVSWITCH_NVLINK_CLEAR_COUNTERS_PARAMS, 5117 osPrivate, flags); 5118 NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(CTRL_NVSWITCH_SET_NVLINK_ERROR_THRESHOLD, 5119 _nvswitch_ctrl_set_nvlink_error_threshold, 5120 NVSWITCH_SET_NVLINK_ERROR_THRESHOLD_PARAMS, 5121 osPrivate, flags); 5122 NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_NVLINK_ERROR_THRESHOLD, 5123 _nvswitch_ctrl_get_nvlink_error_threshold, 5124 NVSWITCH_GET_NVLINK_ERROR_THRESHOLD_PARAMS); 5125 NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_VOLTAGE, 5126 _nvswitch_ctrl_therm_read_voltage, 5127 NVSWITCH_CTRL_GET_VOLTAGE_PARAMS); 5128 NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_POWER, 5129 _nvswitch_ctrl_therm_read_power, 5130 NVSWITCH_GET_POWER_PARAMS); 5131 5132 default: 5133 nvswitch_os_print(NVSWITCH_DBG_LEVEL_INFO, "unknown ioctl %x\n", cmd); 5134 retval = -NVL_BAD_ARGS; 5135 break; 5136 } 5137 5138 return retval; 5139 } 5140 5141 #if defined(DEVELOP) || defined(DEBUG) || defined(NV_MODS) 5142 void nvswitch_assert_log 5143 ( 5144 const char *function, 5145 const char *file, 5146 NvU32 line 5147 ) 5148 { 5149 nvswitch_os_assert_log("NVSwitch: Assertion failed in %s() at %s:%d\n", 5150 function, file, line); 5151 } 5152 #else 5153 void nvswitch_assert_log(void) 5154 { 5155 nvswitch_os_assert_log("NVSwitch: Assertion failed\n"); 5156 } 5157 #endif 5158