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