|
Packit |
857059 |
/* BEGIN_ICS_COPYRIGHT4 ****************************************
|
|
Packit |
857059 |
|
|
Packit |
857059 |
Copyright (c) 2015, Intel Corporation
|
|
Packit |
857059 |
|
|
Packit |
857059 |
Redistribution and use in source and binary forms, with or without
|
|
Packit |
857059 |
modification, are permitted provided that the following conditions are met:
|
|
Packit |
857059 |
|
|
Packit |
857059 |
* Redistributions of source code must retain the above copyright notice,
|
|
Packit |
857059 |
this list of conditions and the following disclaimer.
|
|
Packit |
857059 |
* Redistributions in binary form must reproduce the above copyright
|
|
Packit |
857059 |
notice, this list of conditions and the following disclaimer in the
|
|
Packit |
857059 |
documentation and/or other materials provided with the distribution.
|
|
Packit |
857059 |
* Neither the name of Intel Corporation nor the names of its contributors
|
|
Packit |
857059 |
may be used to endorse or promote products derived from this software
|
|
Packit |
857059 |
without specific prior written permission.
|
|
Packit |
857059 |
|
|
Packit |
857059 |
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
Packit |
857059 |
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
Packit |
857059 |
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
Packit |
857059 |
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
|
Packit |
857059 |
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
Packit |
857059 |
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
Packit |
857059 |
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
Packit |
857059 |
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
Packit |
857059 |
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
Packit |
857059 |
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
Packit |
857059 |
|
|
Packit |
857059 |
** END_ICS_COPYRIGHT4 ****************************************/
|
|
Packit |
857059 |
|
|
Packit |
857059 |
#include <datatypes.h>
|
|
Packit |
857059 |
#include <imemory.h>
|
|
Packit |
857059 |
#include <ilist.h>
|
|
Packit |
857059 |
#include <ievent.h>
|
|
Packit |
857059 |
#include <stl_sd.h>
|
|
Packit |
857059 |
#include <sdi.h>
|
|
Packit |
857059 |
#include <query.h>
|
|
Packit |
857059 |
#include <subscribe.h>
|
|
Packit |
857059 |
#include <multicast.h>
|
|
Packit |
857059 |
|
|
Packit |
857059 |
extern uint32 SADisable;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
ATOMIC_UINT Outstanding; // number of queries/operations in progress
|
|
Packit |
857059 |
|
|
Packit |
857059 |
uint32 NumLocalCAs = 0;
|
|
Packit |
857059 |
uint32 NumTotalPorts = 0;
|
|
Packit |
857059 |
EUI64 *pLocalCaGuidList = NULL;
|
|
Packit |
857059 |
IB_CA_ATTRIBUTES *pLocalCaInfo = NULL;
|
|
Packit |
857059 |
SPIN_LOCK *pLocalCaInfoLock = NULL;
|
|
Packit |
857059 |
IB_HANDLE CaNotifyHandle = NULL;
|
|
Packit |
857059 |
SPIN_LOCK *pCaPortListLock = NULL;
|
|
Packit |
857059 |
QUICK_LIST *pCaPortList = NULL;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
LIST_ITEM*
|
|
Packit |
857059 |
GetCaPortListItem(
|
|
Packit |
857059 |
EUI64 PortGuid
|
|
Packit |
857059 |
)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
LIST_ITEM *pCaPortListItem;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
_DBG_ENTER_LVL(_DBG_LVL_FUNC_TRACE, GetCaPortListItem);
|
|
Packit |
857059 |
|
|
Packit |
857059 |
_DBG_INFO(("Searching for Ca Port (GUID: %"PRIx64").\n", PortGuid));
|
|
Packit |
857059 |
|
|
Packit |
857059 |
for (pCaPortListItem = QListHead(pCaPortList);
|
|
Packit |
857059 |
pCaPortListItem != NULL;
|
|
Packit |
857059 |
pCaPortListItem = QListNext(pCaPortList, pCaPortListItem)
|
|
Packit |
857059 |
)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
CA_PORT *pCaPort = (CA_PORT *) QListObj(pCaPortListItem);
|
|
Packit |
857059 |
ASSERT(pCaPort != NULL);
|
|
Packit |
857059 |
|
|
Packit |
857059 |
if (pCaPort->PortGuid == PortGuid)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
_DBG_INFO(("Found Ca Port (GUID: %"PRIx64").\n", PortGuid));
|
|
Packit |
857059 |
_DBG_INFO(("SubnetAdm Ca Port (GUID: %"PRIx64").\n", pCaPort->SaPortGuid));
|
|
Packit |
857059 |
_DBG_LEAVE_LVL(_DBG_LVL_FUNC_TRACE);
|
|
Packit |
857059 |
return pCaPortListItem;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
_DBG_INFO(("Ca Port (GUID: %"PRIx64") not found.\n", PortGuid));
|
|
Packit |
857059 |
_DBG_LEAVE_LVL(_DBG_LVL_FUNC_TRACE);
|
|
Packit |
857059 |
return NULL;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
CA_PORT*
|
|
Packit |
857059 |
GetCaPort(
|
|
Packit |
857059 |
EUI64 PortGuid
|
|
Packit |
857059 |
)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
LIST_ITEM *pCaPortListItem = GetCaPortListItem(PortGuid);
|
|
Packit |
857059 |
CA_PORT *pCaPort = NULL;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
_DBG_ENTER_LVL(_DBG_LVL_FUNC_TRACE, GetCaPort);
|
|
Packit |
857059 |
|
|
Packit |
857059 |
if (pCaPortListItem != NULL)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
pCaPort = (CA_PORT *) QListObj(pCaPortListItem);
|
|
Packit |
857059 |
ASSERT(pCaPort != NULL);
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
_DBG_LEAVE_LVL(_DBG_LVL_FUNC_TRACE);
|
|
Packit |
857059 |
return pCaPort;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
void
|
|
Packit |
857059 |
AddCa(
|
|
Packit |
857059 |
EUI64 CaGuid
|
|
Packit |
857059 |
)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
IB_CA_ATTRIBUTES *pNewCaInfo = NULL;
|
|
Packit |
857059 |
uint32 ii;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
_DBG_ENTER_LVL(_DBG_LVL_FUNC_TRACE, AddCa);
|
|
Packit |
857059 |
|
|
Packit |
857059 |
_DBG_INFO(("Adding Ports for Channel Adapter (GUID: %"PRIx64").\n",
|
|
Packit |
857059 |
CaGuid));
|
|
Packit |
857059 |
|
|
Packit |
857059 |
if (pLocalCaInfo != NULL)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
SpinLockAcquire(pLocalCaInfoLock);
|
|
Packit |
857059 |
|
|
Packit |
857059 |
_DBG_INFO(("NumLocalCAs (%d).\n", NumLocalCAs));
|
|
Packit |
857059 |
|
|
Packit |
857059 |
for (ii = 0; ii < NumLocalCAs; ii++)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
if (pLocalCaInfo[ii].GUID == CaGuid)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
_DBG_INFO(
|
|
Packit |
857059 |
("Channel Adapter (GUID: %"PRIx64") Found @ Index (%d).\n",
|
|
Packit |
857059 |
pLocalCaInfo[ii].GUID, ii));
|
|
Packit |
857059 |
pNewCaInfo = &pLocalCaInfo[ii];
|
|
Packit |
857059 |
break;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
if (pNewCaInfo != NULL)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
IB_PORT_ATTRIBUTES *pPortAttr;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
_DBG_INFO(("Channel Adapter (GUID: %"PRIx64") Port Count (%d).\n",
|
|
Packit |
857059 |
pNewCaInfo->GUID, pNewCaInfo->Ports));
|
|
Packit |
857059 |
|
|
Packit |
857059 |
for (ii = 0, pPortAttr = pNewCaInfo->PortAttributesList;
|
|
Packit |
857059 |
ii < pNewCaInfo->Ports;
|
|
Packit |
857059 |
ii++, pPortAttr = pPortAttr->Next
|
|
Packit |
857059 |
)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
CA_PORT* pCaPort = (CA_PORT*)MemoryAllocateAndClear(sizeof(CA_PORT),
|
|
Packit |
857059 |
TRUE, SUBNET_DRIVER_TAG);
|
|
Packit |
857059 |
ASSERT(pCaPort != NULL);
|
|
Packit |
857059 |
|
|
Packit |
857059 |
pCaPort->CaGuid = CaGuid;
|
|
Packit |
857059 |
pCaPort->PortGuid = pPortAttr->GUID;
|
|
Packit |
857059 |
if (! LookupPKey(pPortAttr, DEFAULT_P_KEY, TRUE, &pCaPort->DefaultPkeyIndex))
|
|
Packit |
857059 |
pCaPort->DefaultPkeyIndex = 0;
|
|
Packit |
857059 |
QListSetObj(&pCaPort->CaPortListItem, pCaPort);
|
|
Packit |
857059 |
|
|
Packit |
857059 |
SpinLockAcquire(pCaPortListLock);
|
|
Packit |
857059 |
|
|
Packit |
857059 |
QListInsertTail(pCaPortList, &pCaPort->CaPortListItem);
|
|
Packit |
857059 |
|
|
Packit |
857059 |
_DBG_INFO(("Added Port (Number %d) (GUID: %"PRIx64
|
|
Packit |
857059 |
") (Channel Adapter GUID: %"PRIx64").\n",
|
|
Packit |
857059 |
ii,
|
|
Packit |
857059 |
pCaPort->PortGuid,
|
|
Packit |
857059 |
pCaPort->CaGuid));
|
|
Packit |
857059 |
|
|
Packit |
857059 |
SpinLockRelease(pCaPortListLock);
|
|
Packit |
857059 |
|
|
Packit |
857059 |
InitializeCaPortInfo(pPortAttr->GUID);
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
SpinLockRelease(pLocalCaInfoLock);
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
_DBG_LEAVE_LVL(_DBG_LVL_FUNC_TRACE);
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
void
|
|
Packit |
857059 |
RemoveCa(
|
|
Packit |
857059 |
EUI64 CaGuid
|
|
Packit |
857059 |
)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
LIST_ITEM *pCaPortListItem;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
_DBG_ENTER_LVL(_DBG_LVL_FUNC_TRACE, RemoveCa);
|
|
Packit |
857059 |
|
|
Packit |
857059 |
SpinLockAcquire(pCaPortListLock);
|
|
Packit |
857059 |
|
|
Packit |
857059 |
pCaPortListItem = QListHead(pCaPortList);
|
|
Packit |
857059 |
|
|
Packit |
857059 |
while (pCaPortListItem != NULL)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
CA_PORT *pCaPort = (CA_PORT *) QListObj(pCaPortListItem);
|
|
Packit |
857059 |
ASSERT(pCaPort != NULL);
|
|
Packit |
857059 |
|
|
Packit |
857059 |
pCaPortListItem = QListNext(pCaPortList, pCaPortListItem);
|
|
Packit |
857059 |
|
|
Packit |
857059 |
if (pCaPort->CaGuid == CaGuid)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
QListRemoveItem(pCaPortList, &pCaPort->CaPortListItem);
|
|
Packit |
857059 |
MemoryDeallocate(pCaPort);
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
SpinLockRelease(pCaPortListLock);
|
|
Packit |
857059 |
|
|
Packit |
857059 |
_DBG_LEAVE_LVL(_DBG_LVL_FUNC_TRACE);
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
uint32
|
|
Packit |
857059 |
GetNumTotalPorts(
|
|
Packit |
857059 |
IN void
|
|
Packit |
857059 |
)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
_DBG_ENTER_LVL(_DBG_LVL_FUNC_TRACE, GetNumTotalPorts);
|
|
Packit |
857059 |
_DBG_LEAVE_LVL(_DBG_LVL_FUNC_TRACE);
|
|
Packit |
857059 |
return (NumTotalPorts);
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
FSTATUS
|
|
Packit |
857059 |
iba_sd_get_local_port_guids_alloc(
|
|
Packit |
857059 |
IN OUT uint64 **ppLocalPortGuidsList,
|
|
Packit |
857059 |
IN OUT uint32 *LocalPortGuidsCount
|
|
Packit |
857059 |
)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
return iba_sd_get_local_port_guids_alloc2(ppLocalPortGuidsList, NULL,
|
|
Packit |
857059 |
LocalPortGuidsCount);
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
FSTATUS
|
|
Packit |
857059 |
iba_sd_get_local_port_guids_alloc2(
|
|
Packit |
857059 |
IN OUT uint64 **ppLocalPortGuidsList,
|
|
Packit |
857059 |
IN OUT uint64 **ppLocalPortSubnetPrefixList,
|
|
Packit |
857059 |
IN OUT uint32 *LocalPortGuidsCount
|
|
Packit |
857059 |
)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
FSTATUS Fstatus = FNOT_DONE;
|
|
Packit |
857059 |
LIST_ITEM *pCaPortListItem;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
_DBG_ENTER_LVL(_DBG_LVL_FUNC_TRACE, iba_sd_get_local_port_guids_alloc2);
|
|
Packit |
857059 |
|
|
Packit |
857059 |
if (ppLocalPortGuidsList) {
|
|
Packit |
857059 |
*ppLocalPortGuidsList = NULL;
|
|
Packit |
857059 |
} else {
|
|
Packit |
857059 |
Fstatus = FINVALID_PARAMETER;
|
|
Packit |
857059 |
goto done;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
if (ppLocalPortSubnetPrefixList)
|
|
Packit |
857059 |
*ppLocalPortSubnetPrefixList = NULL;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
if (LocalPortGuidsCount) {
|
|
Packit |
857059 |
*LocalPortGuidsCount = 0;
|
|
Packit |
857059 |
} else {
|
|
Packit |
857059 |
Fstatus = FINVALID_PARAMETER;
|
|
Packit |
857059 |
goto done;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
if (NumTotalPorts == 0)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
_DBG_INFO(("No LocalPortGuids allocated.\n"));
|
|
Packit |
857059 |
Fstatus = FSUCCESS;
|
|
Packit |
857059 |
goto done;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
*ppLocalPortGuidsList =
|
|
Packit |
857059 |
(EUI64*)MemoryAllocate2AndClear((sizeof(EUI64)*NumTotalPorts),
|
|
Packit |
857059 |
IBA_MEM_FLAG_SHORT_DURATION, SUBNET_DRIVER_TAG);
|
|
Packit |
857059 |
if (*ppLocalPortGuidsList == NULL)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
_DBG_ERROR(("Cannot allocate memory for LocalPortGuids\n"));
|
|
Packit |
857059 |
Fstatus = FINSUFFICIENT_MEMORY;
|
|
Packit |
857059 |
goto done;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
if (ppLocalPortSubnetPrefixList)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
*ppLocalPortSubnetPrefixList =
|
|
Packit |
857059 |
(EUI64*)MemoryAllocate2AndClear((sizeof(EUI64)*NumTotalPorts),
|
|
Packit |
857059 |
IBA_MEM_FLAG_SHORT_DURATION, SUBNET_DRIVER_TAG);
|
|
Packit |
857059 |
if (*ppLocalPortSubnetPrefixList == NULL)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
_DBG_ERROR(("Cannot allocate memory for LocalPortSubnetPrefix\n"));
|
|
Packit |
857059 |
Fstatus = FINSUFFICIENT_MEMORY;
|
|
Packit |
857059 |
goto fail;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
SpinLockAcquire(pCaPortListLock);
|
|
Packit |
857059 |
|
|
Packit |
857059 |
for (pCaPortListItem = QListHead(pCaPortList);
|
|
Packit |
857059 |
pCaPortListItem != NULL;
|
|
Packit |
857059 |
pCaPortListItem = QListNext(pCaPortList, pCaPortListItem)
|
|
Packit |
857059 |
)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
IB_PORT_ATTRIBUTES *pPortAttr;
|
|
Packit |
857059 |
FSTATUS status;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
CA_PORT *pCaPort = (CA_PORT *) QListObj(pCaPortListItem);
|
|
Packit |
857059 |
ASSERT(pCaPort != NULL);
|
|
Packit |
857059 |
|
|
Packit |
857059 |
status = iba_query_port_by_guid_alloc(pCaPort->PortGuid, &pPortAttr);
|
|
Packit |
857059 |
if (FSUCCESS != status)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
Fstatus = status;
|
|
Packit |
857059 |
break;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
_DBG_INFO(("The port state is %d\n",pPortAttr->PortState));
|
|
Packit |
857059 |
_DBG_INFO(("BaseLid <%d>\n",pPortAttr->Address.BaseLID));
|
|
Packit |
857059 |
if ((pPortAttr->Address.BaseLID != /*IB_INVALID_LID*/ 0) &&
|
|
Packit |
857059 |
(pPortAttr->PortState == PortStateActive))
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
//NOTENOTE: Return only active ports
|
|
Packit |
857059 |
(*ppLocalPortGuidsList)[*LocalPortGuidsCount] = pPortAttr->GUID;
|
|
Packit |
857059 |
if (ppLocalPortSubnetPrefixList)
|
|
Packit |
857059 |
(*ppLocalPortSubnetPrefixList)[*LocalPortGuidsCount] = pPortAttr->GIDTable[0].Type.Global.SubnetPrefix;
|
|
Packit |
857059 |
(*LocalPortGuidsCount)++;
|
|
Packit |
857059 |
Fstatus = FSUCCESS;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
MemoryDeallocate(pPortAttr);
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
SpinLockRelease(pCaPortListLock);
|
|
Packit |
857059 |
|
|
Packit |
857059 |
fail:
|
|
Packit |
857059 |
if (Fstatus != FSUCCESS) {
|
|
Packit |
857059 |
if (*ppLocalPortGuidsList != NULL) {
|
|
Packit |
857059 |
MemoryDeallocate(*ppLocalPortGuidsList);
|
|
Packit |
857059 |
*ppLocalPortGuidsList = 0;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
*LocalPortGuidsCount = 0;
|
|
Packit |
857059 |
if (ppLocalPortSubnetPrefixList && *ppLocalPortSubnetPrefixList)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
MemoryDeallocate(*ppLocalPortSubnetPrefixList);
|
|
Packit |
857059 |
*ppLocalPortSubnetPrefixList = 0;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
// enable this code in the future,
|
|
Packit |
857059 |
// for now for backward compatibility
|
|
Packit |
857059 |
// return an error code for no ports found (FNOT_DONE above)
|
|
Packit |
857059 |
//if (Fstatus == FNOT_DONE)
|
|
Packit |
857059 |
// Fstatus = FSUCCESS;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
done:
|
|
Packit |
857059 |
_DBG_LEAVE_EXT(_DBG_LVL_FUNC_TRACE);
|
|
Packit |
857059 |
return Fstatus;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
|
|
Packit |
857059 |
FSTATUS
|
|
Packit |
857059 |
GetLocalCaInfo(
|
|
Packit |
857059 |
void
|
|
Packit |
857059 |
)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
FSTATUS Fstatus;
|
|
Packit |
857059 |
uint32 ii;
|
|
Packit |
857059 |
uint32 OldNumLocalCAs = NumLocalCAs;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
_DBG_ENTER_LVL(_DBG_LVL_FUNC_TRACE, GetLocalCaInfo);
|
|
Packit |
857059 |
|
|
Packit |
857059 |
// This function has been called by holding a pLocalCaInfoLock spinlock
|
|
Packit |
857059 |
|
|
Packit |
857059 |
if (pLocalCaGuidList)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
MemoryDeallocate(pLocalCaGuidList);
|
|
Packit |
857059 |
pLocalCaGuidList = NULL;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
NumLocalCAs = 0;
|
|
Packit |
857059 |
Fstatus = iba_get_caguids_alloc(&NumLocalCAs, &pLocalCaGuidList);
|
|
Packit |
857059 |
if (Fstatus != FSUCCESS)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
_DBG_ERROR(("Fstatus <0x%x> getting local CA GUIDs\n", Fstatus));
|
|
Packit |
857059 |
pLocalCaGuidList = NULL;
|
|
Packit |
857059 |
NumLocalCAs = 0;
|
|
Packit |
857059 |
_DBG_LEAVE_EXT(_DBG_LVL_FUNC_TRACE);
|
|
Packit |
857059 |
return(Fstatus);
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
_DBG_INFO(("Number of Channel Adapters present <%d>\n", NumLocalCAs));
|
|
Packit |
857059 |
if (NumLocalCAs <= 0) {
|
|
Packit |
857059 |
_DBG_INFO(("No CA reported by GetCaGuids\n"));
|
|
Packit |
857059 |
return FSUCCESS;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
if (pLocalCaInfo)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
uint32 count;
|
|
Packit |
857059 |
for(count=0; count
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
if(pLocalCaInfo[count].PortAttributesList)
|
|
Packit |
857059 |
MemoryDeallocate(pLocalCaInfo[count].PortAttributesList);
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
MemoryDeallocate(pLocalCaInfo);
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
pLocalCaInfo = (IB_CA_ATTRIBUTES*)MemoryAllocateAndClear(
|
|
Packit |
857059 |
(sizeof(IB_CA_ATTRIBUTES) * NumLocalCAs), FALSE, SUBNET_DRIVER_TAG);
|
|
Packit |
857059 |
if (pLocalCaInfo == NULL)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
_DBG_ERROR(("Cannot allocate memory for local CA info\n"));
|
|
Packit |
857059 |
MemoryDeallocate(pLocalCaGuidList);
|
|
Packit |
857059 |
pLocalCaGuidList = NULL;
|
|
Packit |
857059 |
NumLocalCAs = 0;
|
|
Packit |
857059 |
_DBG_LEAVE_EXT(_DBG_LVL_FUNC_TRACE);
|
|
Packit |
857059 |
return(FINSUFFICIENT_MEMORY);
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
//Clear the number of Ports
|
|
Packit |
857059 |
NumTotalPorts = 0;
|
|
Packit |
857059 |
for (ii=0; ii
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
Fstatus = iba_query_ca_by_guid_alloc(pLocalCaGuidList[ii], &pLocalCaInfo[ii]);
|
|
Packit |
857059 |
if (Fstatus == FSUCCESS)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
NumTotalPorts += pLocalCaInfo[ii].Ports;
|
|
Packit |
857059 |
} else {
|
|
Packit |
857059 |
_DBG_ERROR(("Fstatus 0x%x Query CA by Guid failed.\n", Fstatus));
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
} //end for(; ; ;);
|
|
Packit |
857059 |
|
|
Packit |
857059 |
_DBG_LEAVE_EXT(_DBG_LVL_FUNC_TRACE);
|
|
Packit |
857059 |
return(FSUCCESS);
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
|
|
Packit |
857059 |
void
|
|
Packit |
857059 |
LocalCaChangeCallback(
|
|
Packit |
857059 |
IB_NOTIFY_RECORD NotifyRecord
|
|
Packit |
857059 |
)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
FSTATUS Status;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
_DBG_ENTER_LVL(_DBG_LVL_FUNC_TRACE, LocalCaChangeCallback);
|
|
Packit |
857059 |
|
|
Packit |
857059 |
if (SdUnloading)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
_DBG_LEAVE_LVL( _DBG_LVL_FUNC_TRACE );
|
|
Packit |
857059 |
return;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// re-collect the information only if there is a change that impacts us.
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
|
|
Packit |
857059 |
SpinLockAcquire(pLocalCaInfoLock);
|
|
Packit |
857059 |
Status = GetLocalCaInfo();
|
|
Packit |
857059 |
SpinLockRelease(pLocalCaInfoLock);
|
|
Packit |
857059 |
if (Status != FSUCCESS)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
_DBG_ERROR(
|
|
Packit |
857059 |
("GetLocalCaInfo failed during localcachange callback<%d>\n",
|
|
Packit |
857059 |
Status));
|
|
Packit |
857059 |
_DBG_LEAVE_LVL(_DBG_LVL_FUNC_TRACE);
|
|
Packit |
857059 |
return;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
switch (NotifyRecord.EventType)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
case IB_NOTIFY_CA_ADD:
|
|
Packit |
857059 |
_DBG_INFO(("IB_NOTIFY_CA_ADD (GUID: %"PRIx64").\n",
|
|
Packit |
857059 |
NotifyRecord.Guid));
|
|
Packit |
857059 |
AddCa(NotifyRecord.Guid);
|
|
Packit |
857059 |
break;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
case IB_NOTIFY_CA_REMOVE:
|
|
Packit |
857059 |
_DBG_INFO(("IB_NOTIFY_CA_REMOVE (GUID: %"PRIx64").\n",
|
|
Packit |
857059 |
NotifyRecord.Guid));
|
|
Packit |
857059 |
RemoveCa(NotifyRecord.Guid);
|
|
Packit |
857059 |
break;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
case IB_NOTIFY_LID_EVENT:
|
|
Packit |
857059 |
_DBG_INFO(("IB_NOTIFY_LID_EVENT (GUID: %"PRIx64").\n",
|
|
Packit |
857059 |
NotifyRecord.Guid));
|
|
Packit |
857059 |
InitializeCaPortInfo(NotifyRecord.Guid);
|
|
Packit |
857059 |
ReRegisterTrapSubscriptions(NotifyRecord.Guid);
|
|
Packit |
857059 |
break;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
case IB_NOTIFY_SM_EVENT:
|
|
Packit |
857059 |
_DBG_INFO(("IB_NOTIFY_SM_EVENT (GUID: %"PRIx64").\n",
|
|
Packit |
857059 |
NotifyRecord.Guid));
|
|
Packit |
857059 |
InitializeCaPortInfo(NotifyRecord.Guid);
|
|
Packit |
857059 |
ReRegisterTrapSubscriptions(NotifyRecord.Guid);
|
|
Packit |
857059 |
break;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
case IB_NOTIFY_PORT_DOWN:
|
|
Packit |
857059 |
_DBG_INFO(("IB_NOTIFY_PORT_DOWN (GUID: %"PRIx64").\n",
|
|
Packit |
857059 |
NotifyRecord.Guid));
|
|
Packit |
857059 |
InitializeCaPortInfo(NotifyRecord.Guid);
|
|
Packit |
857059 |
InvalidatePortTrapSubscriptions(NotifyRecord.Guid);
|
|
Packit |
857059 |
break;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
case IB_NOTIFY_PKEY_EVENT:
|
|
Packit |
857059 |
_DBG_INFO(("IB_NOTIFY_PKEY_EVENT (GUID: %"PRIx64").\n",
|
|
Packit |
857059 |
NotifyRecord.Guid));
|
|
Packit |
857059 |
InitializeCaPortInfo(NotifyRecord.Guid);
|
|
Packit |
857059 |
ReRegisterTrapSubscriptions(NotifyRecord.Guid);
|
|
Packit |
857059 |
break;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
default:
|
|
Packit |
857059 |
_DBG_INFO(("Someother Event (%lu) (GUID: %"PRIx64").\n",
|
|
Packit |
857059 |
NotifyRecord.EventType,
|
|
Packit |
857059 |
NotifyRecord.Guid));
|
|
Packit |
857059 |
break;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
#ifdef USE_SD_MULTICAST
|
|
Packit |
857059 |
McPortNotifyCallback(&NotifyRecord);
|
|
Packit |
857059 |
#endif
|
|
Packit |
857059 |
_DBG_LEAVE_LVL(_DBG_LVL_FUNC_TRACE);
|
|
Packit |
857059 |
|
|
Packit |
857059 |
return;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
FSTATUS
|
|
Packit |
857059 |
InitializeCaPortInfo(
|
|
Packit |
857059 |
EUI64 PortGuid
|
|
Packit |
857059 |
)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
FSTATUS Fstatus = FERROR;
|
|
Packit |
857059 |
CA_PORT *pCaPort;
|
|
Packit |
857059 |
IB_PORT_ATTRIBUTES *pPortAttr = NULL;
|
|
Packit |
857059 |
boolean bInitialized;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
_DBG_ENTER_LVL(_DBG_LVL_FUNC_TRACE, InitializeCaPortInfo);
|
|
Packit |
857059 |
|
|
Packit |
857059 |
if (SdUnloading)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
_DBG_LEAVE_LVL( _DBG_LVL_FUNC_TRACE );
|
|
Packit |
857059 |
return(FINVALID_STATE);
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
_DBG_INFO(("Number of Local CA are %d\n",NumLocalCAs));
|
|
Packit |
857059 |
|
|
Packit |
857059 |
SpinLockAcquire(pCaPortListLock);
|
|
Packit |
857059 |
|
|
Packit |
857059 |
pCaPort = GetCaPort(PortGuid);
|
|
Packit |
857059 |
if (pCaPort == NULL)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
SpinLockRelease(pCaPortListLock);
|
|
Packit |
857059 |
/* there is a rare possibility during shutdown that the port could go
|
|
Packit |
857059 |
* up/down after the Subnet Driver Remove Device has been called but
|
|
Packit |
857059 |
* before SMARemoveDevice is called. In which case IbtNotifyGroup is
|
|
Packit |
857059 |
* still enabled for the given CA and the SubnetDriver could get a port
|
|
Packit |
857059 |
* state change which will put is here. In this rare case we
|
|
Packit |
857059 |
* could fail to find the CaGuid and should ignore the callback
|
|
Packit |
857059 |
*/
|
|
Packit |
857059 |
_DBG_INFO(("GetCaPort returned NULL for Port (GUID: %"PRIx64").\n", PortGuid));
|
|
Packit |
857059 |
_DBG_LEAVE_LVL( _DBG_LVL_FUNC_TRACE );
|
|
Packit |
857059 |
return (Fstatus);
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// Note: The calling function should not fail driver load if this
|
|
Packit |
857059 |
// function returns error. It is possible that this function is called
|
|
Packit |
857059 |
// before the local CA has been initialized by a remote subnet manager
|
|
Packit |
857059 |
// In that case, this function will fail but will register for a local
|
|
Packit |
857059 |
// CA change callback. When the local CA does get initialized, this
|
|
Packit |
857059 |
// registered callback will be invoked and the callback will call this
|
|
Packit |
857059 |
// function again.
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// LID for the information provider is initially set to the LID of the
|
|
Packit |
857059 |
// subnet manager. This can be subsequently redirected. Get the SM LID
|
|
Packit |
857059 |
// using local IBT calls
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
|
|
Packit |
857059 |
Fstatus = iba_query_port_by_guid_alloc(PortGuid, &pPortAttr);
|
|
Packit |
857059 |
ASSERT(Fstatus == FSUCCESS);
|
|
Packit |
857059 |
|
|
Packit |
857059 |
_DBG_INFO(("The port state is %d\n",pPortAttr->PortState));
|
|
Packit |
857059 |
_DBG_INFO(("BaseLid <%d>\n",pPortAttr->Address.BaseLID));
|
|
Packit |
857059 |
|
|
Packit |
857059 |
if (! LookupPKey(pPortAttr, DEFAULT_P_KEY, TRUE, &pCaPort->DefaultPkeyIndex))
|
|
Packit |
857059 |
pCaPort->DefaultPkeyIndex = 0;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
pCaPort->Lid = pPortAttr->SMAddress.LID;
|
|
Packit |
857059 |
pCaPort->ServiceLevel = pPortAttr->SMAddress.ServiceLevel;
|
|
Packit |
857059 |
pCaPort->RemoteQp = GSI_QP;
|
|
Packit |
857059 |
pCaPort->RemoteQKey = GSI_QKEY;
|
|
Packit |
857059 |
// IB does not have Static rate in UD LRH
|
|
Packit |
857059 |
// so we can't be sure what rate of remote port is
|
|
Packit |
857059 |
// we use a constant value for GSI QPs
|
|
Packit |
857059 |
pCaPort->StaticRate = IB_STATIC_RATE_GSI;
|
|
Packit |
857059 |
pCaPort->PkeyIndex = pCaPort->DefaultPkeyIndex;
|
|
Packit |
857059 |
pCaPort->SaPortGuid = pPortAttr->GUID;
|
|
Packit |
857059 |
if(pPortAttr->NumGIDs > 0)
|
|
Packit |
857059 |
pCaPort->SubnetPrefix = pPortAttr->GIDTable[0].Type.Global.SubnetPrefix;
|
|
Packit |
857059 |
// default redirect to default location
|
|
Packit |
857059 |
pCaPort->RedirectedQP = pCaPort->RemoteQp;
|
|
Packit |
857059 |
pCaPort->RedirectedQKey = pCaPort->RemoteQKey;
|
|
Packit |
857059 |
pCaPort->RedirectedLid = pCaPort->Lid;
|
|
Packit |
857059 |
pCaPort->RedirectedSL = pCaPort->ServiceLevel;
|
|
Packit |
857059 |
pCaPort->RedirectedStaticRate = pCaPort->StaticRate;
|
|
Packit |
857059 |
pCaPort->RedirectedPkeyIndex = pCaPort->PkeyIndex;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
if ((pPortAttr->Address.BaseLID != /*IB_INVALID_LID*/ 0) &&
|
|
Packit |
857059 |
(pPortAttr->PortState == PortStateActive))
|
|
Packit |
857059 |
//NOTENOTE: Check for pPortAttr->SMAddress.LID != 0
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
pCaPort->SdSMAddressValid = TRUE;
|
|
Packit |
857059 |
Fstatus = FSUCCESS;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
// Free the port attributes buffer.
|
|
Packit |
857059 |
MemoryDeallocate( pPortAttr );
|
|
Packit |
857059 |
|
|
Packit |
857059 |
if (Fstatus != FSUCCESS)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// It is possible that local ports have not yet been initialized by
|
|
Packit |
857059 |
// a remote subnet manager. This is OK - we have registered for a
|
|
Packit |
857059 |
// callback when that happens and we will initialize the service
|
|
Packit |
857059 |
// provider at that time
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
|
|
Packit |
857059 |
pCaPort->bInitialized = FALSE;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
_DBG_INFO(("No local port currently available\n"));
|
|
Packit |
857059 |
pCaPort->SdSMAddressValid = FALSE;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
SpinLockRelease(pCaPortListLock);
|
|
Packit |
857059 |
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// We haven't collected enough information to send any message to the
|
|
Packit |
857059 |
// information provider, so simply return for now.
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
_DBG_LEAVE_LVL(_DBG_LVL_FUNC_TRACE);
|
|
Packit |
857059 |
return(Fstatus);
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
bInitialized = pCaPort->bInitialized;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
SpinLockRelease(pCaPortListLock);
|
|
Packit |
857059 |
|
|
Packit |
857059 |
if (! SADisable)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
if(bInitialized == FALSE)
|
|
Packit |
857059 |
SubnetAdmInit();
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
_DBG_LEAVE_LVL(_DBG_LVL_FUNC_TRACE);
|
|
Packit |
857059 |
return(FSUCCESS);
|
|
Packit |
857059 |
}
|