1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 2017-2022 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 "core/core.h"
25 #include "gpu/gpu.h"
26 #include "gpu/bus/kern_bus.h"
27 #include "kernel/gpu/nvlink/kernel_nvlink.h"
28 
29 /*!
30  * @brief Returns the first available peer Id excluding the nvlink peerIds
31  *
32  * @param[in] pGpu
33  * @param[in] pKernelBus
34  *
35  * @returns NvU32 first free peer Id
36  */
37 NvU32
38 kbusGetUnusedPciePeerId_TU102
39 (
40     OBJGPU    *pGpu,
41     KernelBus *pKernelBus
42 )
43 {
44     KernelNvlink *pKernelNvlink = GPU_GET_KERNEL_NVLINK(pGpu);
45     NvU32         nvlinkIdMask  = 0;
46     NvU32         peerId;
47 
48     if ((pKernelNvlink != NULL) &&
49         (pKernelNvlink->getProperty(pKernelNvlink,
50                         PDB_PROP_KNVLINK_WAR_BUG_3471679_PEERID_FILTERING)))
51     {
52         //
53         // Get the mask of NvLink peerIds, to exclude them from the
54         // peerIds PCIE P2P is using.
55         // Pre-Ampere GPUs use a static peerId assignment reserved in
56         // busGetNvlinkP2PPeerId_GP100() and we need to make sure the
57         // PCIE and nvLink P2P assignments do not collide.
58         // Make this Windows + Turing only until bug 3471679 is fixed.
59         //
60         nvlinkIdMask = knvlinkGetUniquePeerIdMask_HAL(pGpu, pKernelNvlink);
61     }
62 
63     for (peerId = 0; peerId < pKernelBus->numPeers; peerId++)
64     {
65         if ((pKernelBus->p2pPcie.busPeer[peerId].refCount == 0) &&
66             (!pKernelBus->p2pPcie.busPeer[peerId].bReserved) &&
67             ((BIT(peerId) & nvlinkIdMask) == 0))
68         {
69             return peerId;
70         }
71     }
72     return BUS_INVALID_PEER;
73 }
74