1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 2014-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 //
25 //     nvlink.h
26 //
27 
28 #ifndef _NVLINK_H_
29 #define _NVLINK_H_
30 
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34 
35 #include <nv-kernel-interface-api.h>
36 #include "nvlink_common.h"
37 #include "nvlink_lib_ctrl.h"
38 #include "nv_list.h"
39 #include "nvlink_errors.h"
40 #include "nvCpuUuid.h"
41 
42 // Debug Prints
43 #if defined(DEVELOP) || defined(DEBUG) || defined(NV_MODS)
44         #define NVLINK_PRINT_ENABLED    1
45         #define NVLINK_PRINT(format_and_stuff) nvlink_print format_and_stuff
46 
47         #define DBG_MODULE_NVLINK_CORE  __FILE__, __LINE__, __FUNCTION__
48         #define DBG_MODULE_IBMNPU       DBG_MODULE_NVLINK_CORE
49         #define DBG_MODULE_TEGRASHIM    DBG_MODULE_NVLINK_CORE
50         #define DBG_MODULE_EBRIDGE      DBG_MODULE_NVLINK_CORE
51         #define DBG_MODULE_NVSWITCH     DBG_MODULE_NVLINK_CORE
52 #else
53     #define NVLINK_PRINT(format_and_stuff)  ((void)(0))
54 #endif
55 
56 // Devices that support NVLINK
57 #define NVLINK_DEVICE_TYPE_EBRIDGE         0x0
58 #define NVLINK_DEVICE_TYPE_IBMNPU          0x1
59 #define NVLINK_DEVICE_TYPE_GPU             0x2
60 #define NVLINK_DEVICE_TYPE_NVSWITCH        0x3
61 #define NVLINK_DEVICE_TYPE_TEGRASHIM       0x4
62 
63 // NVLink versions
64 #define NVLINK_DEVICE_VERSION_10           0x00000001
65 #define NVLINK_DEVICE_VERSION_20           0x00000002
66 #define NVLINK_DEVICE_VERSION_22           0x00000004
67 #define NVLINK_DEVICE_VERSION_30           0x00000005
68 #define NVLINK_DEVICE_VERSION_31           0x00000006
69 #define NVLINK_DEVICE_VERSION_40           0x00000007
70 
71 // Link Transition Timeouts in miliseconds
72 #define NVLINK_TRANSITION_OFF_TIMEOUT        1
73 #define NVLINK_TRANSITION_SAFE_TIMEOUT       70
74 #define NVLINK_TRANSITION_HS_TIMEOUT         7000
75 #define NVLINK_TRANSITION_ACTIVE_PENDING     2000
76 #define NVLINK_TRANSITION_POST_HS_TIMEOUT    70
77 
78 // Link training seed values
79 #define NVLINK_MAX_SEED_NUM                6
80 #define NVLINK_MAX_SEED_BUFFER_SIZE        NVLINK_MAX_SEED_NUM + 1
81 
82 #define NVLINK_MAX_SYSTEM_LINK_NUM         624
83 
84 // Forwards
85 struct nvlink_device;
86 struct nvlink_device_handle;
87 struct nvlink_link;
88 struct nvlink_link_handlers;
89 
90 // nvlink device state
91 struct nvlink_device
92 {
93     NVListRec node;
94 
95     // List of links associated with this device
96     NVListRec link_list;
97 
98     // Uniquely identifies a device in the core
99     NvU64 deviceId;
100 
101     // Client supplied names and ids
102     char *driverName;
103     char *deviceName;
104     NvU8 *uuid;
105 
106     // PCI Information
107     struct nvlink_pci_info pciInfo;
108 
109     // Device type and status
110     NvU64  type;
111     NvBool initialized;
112 
113     // Training type: ALI or Non-ALI
114     NvBool enableALI;
115 
116     // fabric node id
117     NvU16  nodeId;
118 
119     // per Ioctrl data
120     NvU32 numIoctrls;
121     NvU32 numLinksPerIoctrl;
122     NvU32 numActiveLinksPerIoctrl;
123 
124     //
125     // boolean indicating if a given device
126     // is a reduced nvlink config
127     //
128     NvBool bReducedNvlinkConfig;
129 
130     // Client private information
131     void *pDevInfo;
132 };
133 
134 // nvlink link change type
135 enum nvlink_link_change_type
136 {
137     nvlink_retrain_from_off,
138     nvlink_retrain_from_safe,
139 
140 };
141 
142 // nvlink link_change parameters
143 struct nvlink_link_change
144 {
145     struct nvlink_link *master;
146     struct nvlink_link *slave;
147 
148     enum nvlink_link_change_type change_type;
149 };
150 
151 //
152 // Structure representing Nvlink Error Threshold
153 //
154 struct nvlink_link_error_threshold
155 {
156     NvU8 thresholdMan;
157     NvU8 thresholdExp;
158     NvU8 timescaleMan;
159     NvU8 timescaleExp;
160     NvBool bInterruptEn;
161     NvBool bUserConfig;
162     NvBool bInterruptTrigerred; // Error threshold interrupt generated
163 };
164 
165 // nvlink link state
166 struct nvlink_link
167 {
168     NVListRec node;
169 
170     // Device the link is associated with
171     struct nvlink_device *dev;
172 
173     // Lock for per link structure
174     void *linkLock;
175 
176     // Uniquely identifies a link in the core
177     NvU64 linkId;
178 
179     // If this link is the master of its connection
180     NvBool master;
181 
182     // Client supplied link name and number
183     char  *linkName;
184     NvU32 linkNumber;
185 
186     NvU64 token;
187 
188     // Link state
189     NvU32 state;
190     NvBool inSWCFG;
191 
192     // Sublink states
193     NvU32 tx_sublink_state;
194     NvU32 rx_sublink_state;
195 
196     // Has rceiver detect passed
197     NvBool bRxDetected;
198 
199     // Link failed when sending InitPll to minion
200     NvBool bTxCommonModeFail;
201 
202     // Link failed when transitioning to SWCFG
203     NvBool bSafeTransitionFail;
204 
205     // Link failed when sending INITPHASE5 to minion
206     NvBool bInitphase5Fails;
207 
208     // IP version
209     NvU32 version;
210 
211     // Has state been saved
212     NvBool bStateSaved;
213 
214     // Number of retries to put link to safe
215     NvU32 safe_retries;
216 
217     // Set if LINK is ac coupled
218     NvBool ac_coupled;
219 
220     // Number of retries to discover the other end of the link
221     NvU32 packet_injection_retries;
222 
223     // Local Sid of the link.
224     NvU64 localSid;
225 
226     // Remote Sid of the link.
227     NvU64 remoteSid;
228 
229     // Remote LinkId to which the current link is connected.
230     NvU32 remoteLinkId;
231 
232     NvU32 remoteDeviceType;
233 
234     // Has INITNEGOTIATE received CONFIG_GOOD (NVL3.0+)
235     NvBool bInitnegotiateConfigGood;
236 
237     NvBool bCciManaged;
238 
239     // Power state transition status
240     enum
241     {
242         nvlink_power_state_in_L0,
243         nvlink_power_state_entering_L2,
244         nvlink_power_state_in_L2,
245         nvlink_power_state_exiting_L2
246     } powerStateTransitionStatus;
247 
248     // Link handlers
249     const struct nvlink_link_handlers *link_handlers;
250 
251     // Client private information
252     void *link_info;
253 
254     // Outstanding link change request information
255     struct nvlink_link_change link_change;
256 
257     //seed data for given nvlink
258     NvU32 seedData[NVLINK_MAX_SEED_BUFFER_SIZE];
259 
260     struct nvlink_link_error_threshold errorThreshold;
261 };
262 
263 // nvlink link handler ops
264 struct nvlink_link_handlers
265 {
266     NV_API_CALL NvlStatus (*add)                        (struct nvlink_link *link);
267     NV_API_CALL NvlStatus (*remove)                     (struct nvlink_link *link);
268     NV_API_CALL NvlStatus (*lock)                       (struct nvlink_link *link);
269     NV_API_CALL void      (*unlock)                     (struct nvlink_link *link);
270     NV_API_CALL NvlStatus (*queue_link_change)          (struct nvlink_link_change *link_change);
271     NV_API_CALL NvlStatus (*set_dl_link_mode)           (struct nvlink_link *link, NvU64  mode, NvU32 flags);
272     NV_API_CALL NvlStatus (*get_dl_link_mode)           (struct nvlink_link *link, NvU64 *mode);
273     NV_API_CALL NvlStatus (*set_tl_link_mode)           (struct nvlink_link *link, NvU64  mode, NvU32 flags);
274     NV_API_CALL NvlStatus (*get_tl_link_mode)           (struct nvlink_link *link, NvU64 *mode);
275     NV_API_CALL NvlStatus (*set_tx_mode)                (struct nvlink_link *link, NvU64  mode, NvU32 flags);
276     NV_API_CALL NvlStatus (*get_tx_mode)                (struct nvlink_link *link, NvU64 *mode, NvU32 *subMode);
277     NV_API_CALL NvlStatus (*set_rx_mode)                (struct nvlink_link *link, NvU64  mode, NvU32 flags);
278     NV_API_CALL NvlStatus (*get_rx_mode)                (struct nvlink_link *link, NvU64 *mode, NvU32 *subMode);
279     NV_API_CALL NvlStatus (*set_rx_detect)              (struct nvlink_link *link, NvU32 flags);
280     NV_API_CALL NvlStatus (*get_rx_detect)              (struct nvlink_link *link);
281     NV_API_CALL NvlStatus (*write_discovery_token)      (struct nvlink_link *link, NvU64  token);
282     NV_API_CALL NvlStatus (*read_discovery_token)       (struct nvlink_link *link, NvU64 *token);
283     NV_API_CALL void      (*training_complete)          (struct nvlink_link *link);
284     NV_API_CALL void      (*get_uphy_load)              (struct nvlink_link *link, NvBool* bUnlocked);
285     NV_API_CALL NvlStatus (*get_cci_link_mode)          (struct nvlink_link *link, NvU64 *mode);
286     NV_API_CALL NvlStatus (*ali_training)               (struct nvlink_link *link);
287 };
288 
289 //
290 // Represents an intranode connections in single/multi-node system.
291 // Both endpoints of the connection is visible from same node.
292 //
293 struct nvlink_intranode_conn
294 {
295     NVListRec node;
296     struct nvlink_link *end0;
297     struct nvlink_link *end1;
298 };
299 
300 //
301 // Represents internode connections in a multi-node system.
302 // One of the endpoint of the connection must be a local link.
303 //
304 struct nvlink_internode_conn
305 {
306     NVListRec                    node;
307     struct nvlink_link          *local_end;
308     nvlink_remote_endpoint_info  remote_end;
309 };
310 
311 
312 // Typedefs
313 typedef struct nvlink_device           nvlink_device;
314 typedef struct nvlink_device_handle    nvlink_device_handle;
315 typedef struct nvlink_link             nvlink_link;
316 typedef struct nvlink_link_change      nvlink_link_change;
317 typedef struct nvlink_device_handlers  nvlink_device_handlers;
318 typedef struct nvlink_link_handlers    nvlink_link_handlers;
319 typedef struct nvlink_intranode_conn   nvlink_intranode_conn;
320 typedef struct nvlink_internode_conn   nvlink_internode_conn;
321 typedef enum   nvlink_link_change_type nvlink_link_change_type;
322 typedef struct nvlink_inband_data      nvlink_inband_data;
323 
324 
325 #define NVLINK_MAX_NUM_SAFE_RETRIES                 7
326 #define NVLINK_MAX_NUM_PACKET_INJECTION_RETRIES     4
327 
328 
329 // NVLINK LINK states
330 #define NVLINK_LINKSTATE_OFF                            0x00   // OFF
331 #define NVLINK_LINKSTATE_HS                             0x01   // High Speed
332 #define NVLINK_LINKSTATE_SAFE                           0x02   // Safe/Discovery State
333 #define NVLINK_LINKSTATE_FAULT                          0x03   // Faulty
334 #define NVLINK_LINKSTATE_RECOVERY                       0x04   // Recovery
335 #define NVLINK_LINKSTATE_FAIL                           0x05   // Unconnected/Fail
336 #define NVLINK_LINKSTATE_DETECT                         0x06   // Detect mode
337 #define NVLINK_LINKSTATE_RESET                          0x07   // Reset
338 #define NVLINK_LINKSTATE_ENABLE_PM                      0x08   // Enable Link Power Management
339 #define NVLINK_LINKSTATE_DISABLE_PM                     0x09   // Disable Link Power Management
340 #define NVLINK_LINKSTATE_SLEEP                          0x0A   // Sleep (L2)
341 #define NVLINK_LINKSTATE_SAVE_STATE                     0x0B   // Save state while entering L2
342 #define NVLINK_LINKSTATE_RESTORE_STATE                  0x0C   // Restore state while exiting L2
343 #define NVLINK_LINKSTATE_PRE_HS                         0x0E   // Settings before moving to High Speed
344 #define NVLINK_LINKSTATE_DISABLE_ERR_DETECT             0x0F   // Disable Error detection (interrupt)
345 #define NVLINK_LINKSTATE_LANE_DISABLE                   0x10   // Disable Lanes
346 #define NVLINK_LINKSTATE_LANE_SHUTDOWN                  0x11   // Shutdown Lanes in PHY
347 #define NVLINK_LINKSTATE_TRAFFIC_SETUP                  0x12   // Setup traffic flow after ACTIVE
348 #define NVLINK_LINKSTATE_INITPHASE1                     0x13   // INITPHASE1
349 #define NVLINK_LINKSTATE_INITNEGOTIATE                  0x14   // Initialize the negotiation (Ampere And Later)
350 #define NVLINK_LINKSTATE_POST_INITNEGOTIATE             0x15   // Sends DL stat
351 #define NVLINK_LINKSTATE_INITOPTIMIZE                   0x16   // INITOPTIMIZE
352 #define NVLINK_LINKSTATE_POST_INITOPTIMIZE              0x17   // POST INITOPTIMIZE DL stat check
353 #define NVLINK_LINKSTATE_DISABLE_HEARTBEAT              0x18   // Disables the heartbeat errors
354 #define NVLINK_LINKSTATE_CONTAIN                        0x19   // TL is in contain mode
355 #define NVLINK_LINKSTATE_INITTL                         0x1A   // INITTL
356 #define NVLINK_LINKSTATE_INITPHASE5                     0x1B   // INITPHASE5
357 #define NVLINK_LINKSTATE_ALI                            0x1C   // ALI
358 #define NVLINK_LINKSTATE_ACTIVE_PENDING                 0x1D   // Intermediate state for a link going to active
359 #define NVLINK_LINKSTATE_TRAINING_CCI                   0x1E   // Intermediate state for a link that is still training
360 #define NVLINK_LINKSTATE_INVALID                        0xFF   // Invalid state
361 
362 // NVLINK TX SUBLINK states
363 #define NVLINK_SUBLINK_STATE_TX_HS                      0x0   // TX High Speed
364 #define NVLINK_SUBLINK_STATE_TX_SINGLE_LANE             0x4   // TX Single Lane (1/8th or 1/4th) Mode (Deprecated)
365 #define NVLINK_SUBLINK_STATE_TX_LOW_POWER               0x4   // TX Single Lane Mode / L1
366 #define NVLINK_SUBLINK_STATE_TX_TRAIN                   0x5   // TX training
367 #define NVLINK_SUBLINK_STATE_TX_SAFE                    0x6   // TX Safe Mode
368 #define NVLINK_SUBLINK_STATE_TX_OFF                     0x7   // TX OFF
369 #define NVLINK_SUBLINK_STATE_TX_COMMON_MODE             0x8   // TX common mode enable
370 #define NVLINK_SUBLINK_STATE_TX_COMMON_MODE_DISABLE     0x9   // TX common mode disable
371 #define NVLINK_SUBLINK_STATE_TX_DATA_READY              0xA   // Do Data Ready and Data Enable
372 #define NVLINK_SUBLINK_STATE_TX_EQ                      0xB   // TX equalization
373 #define NVLINK_SUBLINK_STATE_TX_PRBS_EN                 0xC   // TX IOBIST PRBS generator enable
374 #define NVLINK_SUBLINK_STATE_TX_POST_HS                 0xD   // TX Post High Speed settings
375 
376 // NVLINK RX SUBLINK states
377 #define NVLINK_SUBLINK_STATE_RX_HS                      0x0   // RX High Speed
378 #define NVLINK_SUBLINK_STATE_RX_SINGLE_LANE             0x4   // RX Single Lane (1/8th or 1/4th) Mode (Deprecated)
379 #define NVLINK_SUBLINK_STATE_RX_LOW_POWER               0x4   // RX Single Lane Mode / L1
380 #define NVLINK_SUBLINK_STATE_RX_TRAIN                   0x5   // RX training
381 #define NVLINK_SUBLINK_STATE_RX_SAFE                    0x6   // RX Safe Mode
382 #define NVLINK_SUBLINK_STATE_RX_OFF                     0x7   // RX OFF
383 #define NVLINK_SUBLINK_STATE_RX_RXCAL                   0x8   // RX in calibration
384 #define NVLINK_SUBLINK_STATE_RX_INIT_TERM               0x9   // Enable RX termination
385 
386 // NVLINK TX SUBLINK sub-states
387 #define NVLINK_SUBLINK_SUBSTATE_TX_STABLE               0x0   // TX Stable
388 
389 // NVLINK RX SUBLINK sub-states
390 #define NVLINK_SUBLINK_SUBSTATE_RX_STABLE               0x0   // RX Stable
391 
392 // State change flags
393 #define NVLINK_STATE_CHANGE_ASYNC                       0x0   // Don't wait for the state change to complete
394 #define NVLINK_STATE_CHANGE_SYNC                        0x1   // Wait for the state change to complete
395 
396 
397 /************************************************************************************************/
398 /***************************** NVLink library management functions ******************************/
399 /************************************************************************************************/
400 
401 /*
402  * Check if the nvlink core library is initialized
403  */
404 NvBool nvlink_lib_is_initialized(void);
405 
406 /*
407  * Check if there are no devices registered
408  */
409 NvBool nvlink_lib_is_device_list_empty(void);
410 
411 /*
412  * Get if a device registerd to the nvlink corelib has a reduced nvlink config
413  */
414 NvBool nvlink_lib_is_registerd_device_with_reduced_config(void);
415 
416 /************************************************************************************************/
417 /************************** NVLink library driver-side interface ********************************/
418 /***************** Manages device and link registration and un-registration *********************/
419 /************************************************************************************************/
420 
421 /*
422  * Associates device in the NVLink Core
423  * During the call, the calling driver must support callbacks into the driver from Core
424  */
425 NvlStatus nvlink_lib_register_device(nvlink_device *dev);
426 
427 /*
428  * Unassociates device in the NVLink Core
429  * Includes removing any links related to the device if still registered
430  * During the call, the calling driver must support callbacks into the driver from Core
431  */
432 NvlStatus nvlink_lib_unregister_device(nvlink_device *dev);
433 
434 
435 /*
436  * Associates link with a device in the NVLink Core
437  * During the call, the calling driver must support callbacks into the driver from Core
438  */
439 NvlStatus nvlink_lib_register_link(nvlink_device *dev, nvlink_link *link);
440 
441 /*
442  * Unassociates link from a device in the NVLink Core
443  * During the call, the calling driver must support callbacks into the driver from Core
444  */
445 NvlStatus nvlink_lib_unregister_link(nvlink_link *link);
446 
447 /*
448 * Gets number of devices with type deviceType
449 */
450 NvlStatus nvlink_lib_return_device_count_by_type(NvU32 deviceType, NvU32 *numDevices);
451 
452 
453 /************************************************************************************************/
454 /***************************** NVLink device management functions ******************************/
455 /************************************************************************************************/
456 
457 /*
458  * Update UUID and deviceName in core library
459  */
460 NvlStatus nvlink_lib_update_uuid_and_device_name(nvlink_device_info *devInfo,
461                                                  NvU8 *uuid,
462                                                  char *deviceName);
463 
464 
465 /************************************************************************************************/
466 /******************************* NVLink link management functions *******************************/
467 /************************************************************************************************/
468 
469 /*
470  * Check if the device has no links registered
471  */
472 NvBool nvlink_lib_is_link_list_empty(nvlink_device *dev);
473 
474 /*
475  * Get the link associated with the given device's link number
476  */
477 NvlStatus nvlink_lib_get_link(nvlink_device  *device,
478                               NvU32           link_id,
479                               nvlink_link   **link);
480 
481 /*
482  * Set the link endpoint as the link master
483  */
484 NvlStatus nvlink_lib_set_link_master(nvlink_link *link);
485 
486 /*
487  * Get the link master associated with this endpoint
488  */
489 NvlStatus nvlink_lib_get_link_master(nvlink_link *link, nvlink_link **master);
490 
491 /*
492  * Set the training state for the given link as non-ALI or ALI
493  */
494 NvlStatus nvlink_lib_link_set_training_mode(nvlink_link *link, NvBool enableALI);
495 
496 /************************************************************************************************/
497 /*************************** NVLink topology discovery functions ********************************/
498 /************************************************************************************************/
499 
500 /*
501  * Get the connected remote endpoint information
502  *   For a given link, return the other endpoint details it is connected
503  *   to. If there is no connection associated with the given link, then
504  *   conn_info.connected member will be NV_FALSE.
505  *
506  *   Note: This routine will not initiate any link initialization or topology
507  *   discovery.
508  */
509 NvlStatus nvlink_lib_get_remote_conn_info(nvlink_link *link, nvlink_conn_info *conn_info);
510 
511 /*
512  * Get the connected remote endpoint information
513  *   For a given end of a link, returns the device and link information
514  *   for the remote end along with a boolean variable that specifies if
515  *   the topology detection was complete
516  */
517 NvlStatus nvlink_lib_discover_and_get_remote_conn_info(nvlink_link      *end,
518                                                        nvlink_conn_info *conn_info,
519                                                        NvU32             flags);
520 
521 
522 /************************************************************************************************/
523 /****************************** NVLink initialization functions *********************************/
524 /************************************************************************************************/
525 
526 /*
527  * Re-init a given link from OFF to SWCFG
528  */
529 NvlStatus nvlink_lib_reinit_link_from_off_to_swcfg(nvlink_link *link,
530                                                    NvU32        flags);
531 
532 /************************************************************************************************/
533 /********************************** NVLink training functions ***********************************/
534 /************************************************************************************************/
535 
536 /*
537  * Train a given set of links from SWCFG to ACTIVE state
538  *    a. For low training latency - caller passes all links as an array
539  *    b. For high training latency - caller passes link one by one
540  */
541 NvlStatus nvlink_lib_train_links_from_swcfg_to_active(nvlink_link **links,
542                                                       NvU32         linkCount,
543                                                       NvU32         flags);
544 
545 /*
546  * Train a given set of links of a device from L2 to ACTIVE state
547  */
548 NvlStatus nvlink_lib_train_links_from_L2_to_active(nvlink_device *dev,
549                                                    NvU32          linkMask,
550                                                    NvU32          flags);
551 
552 /*
553  * Retrain a given link from SWCFG to ACTIVE
554  */
555 NvlStatus nvlink_lib_retrain_link_from_swcfg_to_active(nvlink_link *link,
556                                                        NvU32        flags);
557 
558 /*
559  * Save the seed Data passed in from an endpoint driver
560 */
561 NvlStatus nvlink_lib_save_training_seeds(nvlink_link * link,
562                                          NvU32 *       seedData);
563 NvlStatus nvlink_lib_copy_training_seeds(nvlink_link * link,
564                                          NvU32 * seedDataCopy);
565 
566 /*
567  * Send the endpoint driver back the seeds we have stored
568 */
569 void nvlink_lib_restore_training_seeds(nvlink_link * link,
570                                        NvU32 *       seedData);
571 
572 /*
573  * Check that the requested links have trained to active
574 */
575 NvlStatus nvlink_lib_check_training_complete(nvlink_link **links,
576                                              NvU32 linkCount);
577 
578 
579 /************************************************************************************************/
580 /********************************** NVLink shutdown functions ***********************************/
581 /************************************************************************************************/
582 
583 /*
584  * [CLEAN SHUTDOWN]
585  * Shutdown given links of a device from active to L2 state
586  */
587 NvlStatus nvlink_lib_powerdown_links_from_active_to_L2(nvlink_device *dev,
588                                                        NvU32          linkMask,
589                                                        NvU32          flags);
590 
591 /*
592  * [PSEUDO-CLEAN SHUTDOWN]
593  * Shutdown the given array of links from ACTIVE to OFF state
594  */
595 NvlStatus nvlink_lib_powerdown_links_from_active_to_off(nvlink_link **links,
596                                                         NvU32         numLinks,
597                                                         NvU32         flags);
598 
599 /*
600  * Power down the given array of links from ACTIVE to SWCFG state
601  */
602 NvlStatus nvlink_lib_powerdown_links_from_active_to_swcfg(nvlink_link **links,
603                                                           NvU32         numLinks,
604                                                           NvU32         flags);
605 
606 /*
607  * Reset the given array of links
608  */
609 NvlStatus nvlink_lib_reset_links(nvlink_link **links,
610                                  NvU32         numLinks,
611                                  NvU32         flags);
612 
613 /*
614  * Floorsweep the necessary links and set buffer ready on the active links
615  */
616 NvlStatus nvlink_lib_powerdown_floorswept_links_to_off(nvlink_device *pDevice);
617 
618 
619 /*
620  * Nvlink core library structure iterators
621  */
622 
623 #define FOR_EACH_DEVICE_REGISTERED(dev, head, node)  \
624         nvListForEachEntry(dev, &head.node, node)
625 
626 #define FOR_EACH_LINK_REGISTERED(link, dev, node)    \
627         nvListForEachEntry(link, &dev->link_list, node)
628 
629 #define FOR_EACH_LINK_REGISTERED_SAFE(link, next, dev, node)       \
630         nvListForEachEntry_safe(link, next, &dev->link_list, node)
631 
632 #define FOR_EACH_CONNECTION(conn, head, node)        \
633         nvListForEachEntry(conn, &head.node, node)
634 
635 #ifdef __cplusplus
636 }
637 #endif
638 
639 #endif // _NVLINK_H_
640