Blame IbAccess/Common/Ibt/Sma/smaca.c

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
Packit 857059
#include "smamain.h"
Packit 857059
#include "gsi_params.h"
Packit 857059
Packit 857059
extern uint32 CmMaxDgrms;
Packit 857059
Packit 857059
FSTATUS
Packit 857059
SmaDeviceReserve(
Packit 857059
	IN	SMA_CA_OBJ_PRIVATE		*CaObj
Packit 857059
	)
Packit 857059
{
Packit 857059
	FSTATUS						status				= FSUCCESS;
Packit 857059
	IB_CA_ATTRIBUTES			*pCaAttributes		= NULL;
Packit 857059
	IB_PORT_ATTRIBUTES			*pPortAttributesList= NULL;
Packit 857059
	SMA_PORT_TABLE_PRIV			*pPortTbl			= NULL;
Packit 857059
	uint32						qp0CqSize			= 0;
Packit 857059
	IB_PORT_ATTRIBUTES			*pTempPortAttributesList;
Packit 857059
	IB_QP_ATTRIBUTES_CREATE		qpCreateAttributes;
Packit 857059
	IB_QP_ATTRIBUTES_QUERY		qpAttributes;
Packit 857059
	uint32						i=0;
Packit 857059
	
Packit 857059
	_DBG_ENTER_LVL(_DBG_LVL_DEVICE, DeviceReserve);
Packit 857059
Packit 857059
	// query the device attributes from VCA
Packit 857059
	pCaAttributes = (IB_CA_ATTRIBUTES*)MemoryAllocateAndClear(sizeof(IB_CA_ATTRIBUTES), FALSE, SMA_MEM_TAG);
Packit 857059
	if ( !pCaAttributes )
Packit 857059
	{
Packit 857059
		status = FINSUFFICIENT_MEMORY;
Packit 857059
		_DBG_ERROR (("MemAlloc failed for CaAttributes!\n" ));
Packit 857059
		goto failcaalloc;
Packit 857059
	}			
Packit 857059
	
Packit 857059
	status = iba_query_ca(CaObj->CaHandle, pCaAttributes, NULL/*pContext*/);
Packit 857059
	if ( FSUCCESS != status )
Packit 857059
	{
Packit 857059
		_DBG_ERROR ((
Packit 857059
			"iba_query_ca() failed with NULL PortAttribs! :%s\n",
Packit 857059
			_DBG_PTR(FSTATUS_MSG (status)) ));
Packit 857059
		goto failquery;
Packit 857059
	}		
Packit 857059
Packit 857059
	pPortAttributesList = (IB_PORT_ATTRIBUTES*)MemoryAllocateAndClear(pCaAttributes->PortAttributesListSize, FALSE, SMA_MEM_TAG);
Packit 857059
	if ( !pPortAttributesList )
Packit 857059
	{
Packit 857059
		status = FINSUFFICIENT_MEMORY;
Packit 857059
		_DBG_ERROR ((
Packit 857059
			"MemAlloc failed for PortAttributesList!\n" ));
Packit 857059
		goto failportalloc;
Packit 857059
	}		
Packit 857059
Packit 857059
	_DBG_PRINT (_DBG_LVL_DEVICE,(
Packit 857059
		"Processing device CA      :GUID(x%"PRIx64")\n",
Packit 857059
		CaObj->CaPublic.CaGuid ));
Packit 857059
Packit 857059
	// build list and add Port info and tag other requirements
Packit 857059
	pCaAttributes->PortAttributesList	= pPortAttributesList;
Packit 857059
	pTempPortAttributesList				= pPortAttributesList; 
Packit 857059
Packit 857059
	status = iba_query_ca(CaObj->CaHandle, pCaAttributes, NULL/*pContext*/);
Packit 857059
	if ( FSUCCESS != status )
Packit 857059
	{
Packit 857059
		_DBG_ERROR ((
Packit 857059
				"iba_query_ca() failed for PortAttribs!:%s\n",
Packit 857059
				_DBG_PTR(FSTATUS_MSG (status)) ));
Packit 857059
		goto failquery2;
Packit 857059
	}		
Packit 857059
		
Packit 857059
	pPortTbl = (SMA_PORT_TABLE_PRIV*)MemoryAllocateAndClear(sizeof(SMA_PORT_BLOCK_PRIV) * pCaAttributes->Ports, FALSE, SMA_MEM_TAG);
Packit 857059
	if ( !pPortTbl )
Packit 857059
	{
Packit 857059
		status = FINSUFFICIENT_MEMORY;
Packit 857059
		_DBG_ERROR (("MemAlloc failed for PortList!\n" ));
Packit 857059
		goto failtblalloc;
Packit 857059
	}	
Packit 857059
		
Packit 857059
	// Reserve device resources
Packit 857059
Packit 857059
	// Fill in Ca details
Packit 857059
	CaObj->WorkReqId			 = 0;
Packit 857059
Packit 857059
	CaObj->Partitions			 = pCaAttributes->Partitions;
Packit 857059
	CaObj->AddressVectors		 = pCaAttributes->AddressVectors;
Packit 857059
	CaObj->CaPublic.Ports		 = pCaAttributes->Ports;
Packit 857059
	CaObj->CaPublic.Capabilities = pCaAttributes->Capabilities;
Packit 857059
Packit 857059
	// add port tables to list
Packit 857059
	CaObj->CaPublic.PortTbl 	 = (SMA_PORT_TABLE *)pPortTbl;
Packit 857059
Packit 857059
	// Allocate PD Resource
Packit 857059
	status = iba_alloc_sqp_pd( 
Packit 857059
						CaObj->CaHandle,
Packit 857059
// BUGBUG - does not account for send buffers allocated by registering Gsa/Smi managers
Packit 857059
// CM is likely to be the largest so we account for its Dgrms
Packit 857059
// however for SMI and GSI the Recv buffers will not use AVs, so this is
Packit 857059
// a reasonable guess
Packit 857059
#ifdef BUILD_CM
Packit 857059
						g_Settings.MaxSMPs +g_GsaSettings.MaxRecvBuffers
Packit 857059
						+ CmMaxDgrms,
Packit 857059
#else
Packit 857059
						g_Settings.MaxSMPs +g_GsaSettings.MaxRecvBuffers,
Packit 857059
#endif
Packit 857059
						&CaObj->PdHandle );
Packit 857059
	if ( FSUCCESS != status )
Packit 857059
	{
Packit 857059
		_DBG_ERROR (("AllocatePD() failed! :%s\n",
Packit 857059
				_DBG_PTR(FSTATUS_MSG (status)) ));
Packit 857059
		goto failpd;
Packit 857059
	}	
Packit 857059
Packit 857059
	// Create One CQ per CA for SMA
Packit 857059
	status = iba_create_cq(
Packit 857059
						CaObj->CaHandle,
Packit 857059
								// CqReqSize
Packit 857059
						MIN(pCaAttributes->WorkCompletions,
Packit 857059
								(CaObj->CaPublic.Ports	
Packit 857059
						 		* (g_Settings.SendQDepth
Packit 857059
									 + g_Settings.RecvQDepth))),
Packit 857059
						(void *)QPTypeSMI,					// Context
Packit 857059
						&CaObj->CqHandle,
Packit 857059
						&CaObj->CqSize );
Packit 857059
	if ( FSUCCESS != status )
Packit 857059
	{
Packit 857059
		_DBG_ERROR (( "iba_create_cq for SMA failed! :%s\n",
Packit 857059
								_DBG_PTR(FSTATUS_MSG (status)) ));
Packit 857059
		goto failcq;
Packit 857059
	}
Packit 857059
Packit 857059
	// Create One CQ per CA for GSA
Packit 857059
	status = iba_create_cq(
Packit 857059
						CaObj->CaHandle,
Packit 857059
								// CqReqSize
Packit 857059
						MIN(pCaAttributes->WorkCompletions,
Packit 857059
							(CaObj->CaPublic.Ports * (g_GsaSettings.SendQDepth+g_GsaSettings.RecvQDepth))),
Packit 857059
						(void *)QPTypeGSI,					// Context
Packit 857059
						&CaObj->Qp1CqHandle,
Packit 857059
						&CaObj->Qp1CqSize );
Packit 857059
	if ( FSUCCESS != status )
Packit 857059
	{
Packit 857059
		_DBG_ERROR (( "iba_create_cq for GSA failed! :%s\n",
Packit 857059
						_DBG_PTR(FSTATUS_MSG (status)) ));
Packit 857059
		goto failcq2;
Packit 857059
	}
Packit 857059
Packit 857059
	// Get a Special QP each for SMA and GSA on each port
Packit 857059
	for ( i=0; i< CaObj->CaPublic.Ports; i++ )
Packit 857059
	{
Packit 857059
		_DBG_PRINT(_DBG_LVL_DEVICE,(
Packit 857059
				"Processing device port(%d) :GUID(x%"PRIx64")\n",
Packit 857059
				i+1, 
Packit 857059
				pTempPortAttributesList->GUID ));
Packit 857059
Packit 857059
		// Fill in per Port details
Packit 857059
		pPortTbl->PortBlock[i].Public.PortNumber	= (uint8)i+1;
Packit 857059
		pPortTbl->PortBlock[i].Public.GUID			= \
Packit 857059
				pTempPortAttributesList->GUID;
Packit 857059
		pPortTbl->PortBlock[i].Public.NumGIDs		= \
Packit 857059
				pTempPortAttributesList->NumGIDs;
Packit 857059
		pPortTbl->PortBlock[i].Public.NumPKeys		= \
Packit 857059
				pTempPortAttributesList->NumPkeys;
Packit 857059
Packit 857059
		// fill in default Port state
Packit 857059
		pPortTbl->PortBlock[i].Public.State			= \
Packit 857059
				pTempPortAttributesList->PortState;
Packit 857059
Packit 857059
		// set QP attribs for SMA
Packit 857059
		qpCreateAttributes.Type				= QPTypeSMI;
Packit 857059
		qpCreateAttributes.PDHandle			= CaObj->PdHandle;
Packit 857059
		qpCreateAttributes.SendCQHandle		= CaObj->CqHandle;
Packit 857059
		qpCreateAttributes.RecvCQHandle		= CaObj->CqHandle;
Packit 857059
			
Packit 857059
		qpCreateAttributes.SendQDepth		= 
Packit 857059
						MIN(pCaAttributes->WorkReqs, g_Settings.SendQDepth);
Packit 857059
		qpCreateAttributes.RecvQDepth		= 
Packit 857059
						MIN(pCaAttributes->WorkReqs, g_Settings.RecvQDepth);
Packit 857059
Packit 857059
		qpCreateAttributes.SendDSListDepth	= 1;
Packit 857059
		qpCreateAttributes.RecvDSListDepth	= 2;
Packit 857059
				
Packit 857059
		qpCreateAttributes.CompletionFlags	= IB_COMPL_CNTL_SEND;
Packit 857059
			
Packit 857059
		status = iba_create_special_qp(
Packit 857059
						CaObj->CaHandle,
Packit 857059
						pPortTbl->PortBlock[i].Public.GUID,
Packit 857059
						&qpCreateAttributes,
Packit 857059
						&pPortTbl->PortBlock[i].QpHandle,	// Context
Packit 857059
						&pPortTbl->PortBlock[i].QpHandle,
Packit 857059
						&qpAttributes );
Packit 857059
		if ( FSUCCESS != status )
Packit 857059
		{
Packit 857059
			_DBG_ERROR ((
Packit 857059
					"CreateSpecialQP() failed on port(%d) for SMA :%s!\n",
Packit 857059
					i+1,
Packit 857059
					_DBG_PTR(FSTATUS_MSG (status)) ));
Packit 857059
			goto failsmi;
Packit 857059
		}
Packit 857059
Packit 857059
			
Packit 857059
		// set QP attribs for GSA
Packit 857059
		// Note: GSA QP created with fixed settings. Changes 
Packit 857059
		//	to QP and CQ size will be done in GSA module if applicable
Packit 857059
		qpCreateAttributes.Type				= QPTypeGSI;
Packit 857059
		qpCreateAttributes.PDHandle			= CaObj->PdHandle;
Packit 857059
		qpCreateAttributes.SendCQHandle		= CaObj->Qp1CqHandle;
Packit 857059
		qpCreateAttributes.RecvCQHandle		= CaObj->Qp1CqHandle;
Packit 857059
Packit 857059
		qpCreateAttributes.RecvDSListDepth	= 2; //pCaAttributes->DSListDepth;
Packit 857059
		qpCreateAttributes.SendDSListDepth	= 3; //pCaAttributes->DSListDepth;
Packit 857059
		qpCreateAttributes.RecvQDepth		= 
Packit 857059
						MIN(pCaAttributes->WorkReqs, g_GsaSettings.RecvQDepth);
Packit 857059
		qpCreateAttributes.SendQDepth		= 
Packit 857059
						MIN(pCaAttributes->WorkReqs, g_GsaSettings.SendQDepth);
Packit 857059
			
Packit 857059
		qpCreateAttributes.CompletionFlags = IB_COMPL_CNTL_SEND;
Packit 857059
						
Packit 857059
		status = iba_create_special_qp(
Packit 857059
						CaObj->CaHandle,
Packit 857059
						pPortTbl->PortBlock[i].Public.GUID,
Packit 857059
						&qpCreateAttributes,
Packit 857059
						&pPortTbl->PortBlock[i].Qp1Handle,	// Context
Packit 857059
						&pPortTbl->PortBlock[i].Qp1Handle,
Packit 857059
						&qpAttributes );
Packit 857059
		if ( FSUCCESS != status )
Packit 857059
		{
Packit 857059
			_DBG_ERROR ((
Packit 857059
					"CreateSpecialQP() failed on port(%d) for GSA :%s!\n",
Packit 857059
					i+1,
Packit 857059
					_DBG_PTR(FSTATUS_MSG (status)) ));
Packit 857059
			goto failgsi;
Packit 857059
		}
Packit 857059
Packit 857059
		// Spinlock for Qp0 & Qp1
Packit 857059
		SpinLockInitState( &pPortTbl->PortBlock[i].Qp0Lock );
Packit 857059
		SpinLockInitState( &pPortTbl->PortBlock[i].QpLock );
Packit 857059
Packit 857059
		if( !SpinLockInit( &pPortTbl->PortBlock[i].Qp0Lock ) )
Packit 857059
		{
Packit 857059
			_DBG_ERROR(( "Unable to initialize spinlocks for Port(%d)!\n", i+1 ));
Packit 857059
			goto faillock0;
Packit 857059
		}
Packit 857059
		if ( !SpinLockInit( &pPortTbl->PortBlock[i].QpLock ) )
Packit 857059
		{
Packit 857059
			_DBG_ERROR(( "Unable to initialize spinlocks for Port(%d)!\n", i+1 ));
Packit 857059
			goto faillock;
Packit 857059
		}
Packit 857059
Packit 857059
		// update info
Packit 857059
		pPortTbl->PortBlock[i].Qp0SendQDepth = \
Packit 857059
					qpAttributes.SendQDepth;
Packit 857059
		AtomicWrite(&pPortTbl->PortBlock[i].Qp0SendQTop,
Packit 857059
					qpAttributes.SendQDepth);
Packit 857059
		pPortTbl->PortBlock[i].Qp0RecvQDepth = \
Packit 857059
					qpAttributes.RecvQDepth;
Packit 857059
		AtomicWrite(&pPortTbl->PortBlock[i].Qp0RecvQTop,
Packit 857059
					qpAttributes.RecvQDepth);
Packit 857059
			
Packit 857059
		// keep count of All QP depths
Packit 857059
		qp0CqSize += pPortTbl->PortBlock[i].Qp0SendQDepth + \
Packit 857059
						pPortTbl->PortBlock[i].Qp0RecvQDepth;
Packit 857059
Packit 857059
		// loop
Packit 857059
		pTempPortAttributesList			= pTempPortAttributesList->Next;
Packit 857059
Packit 857059
	}	// i loop
Packit 857059
Packit 857059
	// add port tables to list
Packit 857059
	CaObj->CaPublic.PortTbl				= (SMA_PORT_TABLE *)pPortTbl;
Packit 857059
Packit 857059
	// SMA Only: GSA resize of QP and CQ handled in GSA module
Packit 857059
	// Resize CQ if necessary
Packit 857059
	// Validate CQ size depth with all Qp depths
Packit 857059
	_DBG_PRINT (_DBG_LVL_DEVICE, (
Packit 857059
				"CqSize: \n"
Packit 857059
				"\tStored.......:%d\n"
Packit 857059
				"\tCalculated...:%d\n"
Packit 857059
				"\tResize.......:%s\n",
Packit 857059
				MIN(pCaAttributes->WorkCompletions, g_Settings.MaxCqSize),
Packit 857059
				qp0CqSize,
Packit 857059
				_DBG_PTR(qp0CqSize < MIN(pCaAttributes->WorkCompletions, g_Settings.MaxCqSize) ? "TRUE":"FALSE") ));
Packit 857059
Packit 857059
	// Update Cqsize only if we have allocated more than 
Packit 857059
	// the h/w can achieve.
Packit 857059
	if ( qp0CqSize < MIN(pCaAttributes->WorkCompletions, g_Settings.MaxCqSize))
Packit 857059
	{
Packit 857059
		status = iba_resize_cq(
Packit 857059
					CaObj->CqHandle,
Packit 857059
					MIN(pCaAttributes->WorkCompletions, g_Settings.MaxCqSize),
Packit 857059
					&CaObj->CqSize );
Packit 857059
		if (FSUCCESS != status)
Packit 857059
		{
Packit 857059
			_DBG_ERROR ((
Packit 857059
						"iba_resize_cq() failed for SMA :%s!\n",
Packit 857059
						_DBG_PTR(FSTATUS_MSG (status)) ));
Packit 857059
			goto failresize;
Packit 857059
		}
Packit 857059
	}
Packit 857059
	MemoryDeallocate ( pPortAttributesList );
Packit 857059
	MemoryDeallocate ( pCaAttributes );
Packit 857059
Packit 857059
done:
Packit 857059
	_DBG_LEAVE_LVL(_DBG_LVL_DEVICE);
Packit 857059
    return status;
Packit 857059
Packit 857059
failresize:
Packit 857059
	--i;
Packit 857059
	SpinLockDestroy( &pPortTbl->PortBlock[i].QpLock );
Packit 857059
faillock:
Packit 857059
	SpinLockDestroy( &pPortTbl->PortBlock[i].Qp0Lock );
Packit 857059
faillock0:
Packit 857059
	iba_destroy_qp( pPortTbl->PortBlock[i].Qp1Handle );
Packit 857059
failgsi:
Packit 857059
	iba_destroy_qp( pPortTbl->PortBlock[i].QpHandle );
Packit 857059
failsmi:
Packit 857059
	while (i > 0)
Packit 857059
	{
Packit 857059
		--i;
Packit 857059
		SpinLockDestroy( &pPortTbl->PortBlock[i].QpLock );
Packit 857059
		SpinLockDestroy( &pPortTbl->PortBlock[i].Qp0Lock );
Packit 857059
		iba_destroy_qp( pPortTbl->PortBlock[i].Qp1Handle );
Packit 857059
		iba_destroy_qp( pPortTbl->PortBlock[i].QpHandle );
Packit 857059
	}
Packit 857059
	iba_destroy_cq( CaObj->Qp1CqHandle );
Packit 857059
	CaObj->Qp1CqHandle = NULL;
Packit 857059
failcq2:
Packit 857059
	iba_destroy_cq( CaObj->CqHandle );
Packit 857059
	CaObj->CqHandle = NULL;
Packit 857059
failcq:
Packit 857059
	iba_free_pd( CaObj->PdHandle );
Packit 857059
	CaObj->PdHandle = NULL;
Packit 857059
failpd:
Packit 857059
	MemoryDeallocate ( pPortTbl );
Packit 857059
	CaObj->CaPublic.PortTbl = NULL;
Packit 857059
failtblalloc:
Packit 857059
failquery2:
Packit 857059
	MemoryDeallocate ( pPortAttributesList );
Packit 857059
failportalloc:
Packit 857059
failquery:
Packit 857059
	MemoryDeallocate ( pCaAttributes );
Packit 857059
failcaalloc:
Packit 857059
	goto done;
Packit 857059
}
Packit 857059
Packit 857059
Packit 857059
Packit 857059
FSTATUS
Packit 857059
SmaConfigQp(
Packit 857059
	IN	IB_HANDLE				QpHandle,
Packit 857059
	IN	IB_QP_STATE				QpState,
Packit 857059
	IN	IB_QP_TYPE				QpType
Packit 857059
	)
Packit 857059
{
Packit 857059
	FSTATUS						status = FSUCCESS;
Packit 857059
	IB_QP_ATTRIBUTES_MODIFY		qpModAttributes;
Packit 857059
	
Packit 857059
	
Packit 857059
	_DBG_ENTER_LVL(_DBG_LVL_DEVICE, SmaConfigQp);
Packit 857059
Packit 857059
Packit 857059
	// set QP attribs based on transition and QpType
Packit 857059
	switch (QpState)
Packit 857059
	{
Packit 857059
	default:
Packit 857059
		_DBG_ERROR(("Invalid QP State requested!\n"));
Packit 857059
		status = FINVALID_SETTING;
Packit 857059
		goto done;
Packit 857059
		break;
Packit 857059
	
Packit 857059
	case QPStateInit:
Packit 857059
		{
Packit 857059
			qpModAttributes.RequestState	= QPStateInit;
Packit 857059
			qpModAttributes.Attrs = (IB_QP_ATTR_PKEYINDEX
Packit 857059
												| IB_QP_ATTR_QKEY);
Packit 857059
			qpModAttributes.PkeyIndex = 0;	// BUGBUG not applicable
Packit 857059
			if ( QPTypeSMI == QpType )
Packit 857059
				qpModAttributes.Qkey = 0;
Packit 857059
			else
Packit 857059
				qpModAttributes.Qkey = QP1_WELL_KNOWN_Q_KEY;
Packit 857059
		}
Packit 857059
		break;
Packit 857059
	
Packit 857059
	case QPStateReadyToRecv:
Packit 857059
		{
Packit 857059
			qpModAttributes.RequestState = QPStateReadyToRecv;
Packit 857059
			qpModAttributes.Attrs = 0;
Packit 857059
	
Packit 857059
		}
Packit 857059
		break;
Packit 857059
Packit 857059
	case QPStateReadyToSend:
Packit 857059
		{
Packit 857059
			qpModAttributes.RequestState = QPStateReadyToSend;
Packit 857059
			qpModAttributes.Attrs = IB_QP_ATTR_SENDPSN;
Packit 857059
			qpModAttributes.SendPSN = 0x00000001;
Packit 857059
		}
Packit 857059
		break;
Packit 857059
	}	// switch
Packit 857059
Packit 857059
	// transition QP states
Packit 857059
	status = iba_modify_qp( QpHandle, &qpModAttributes, NULL );
Packit 857059
	if ( FSUCCESS != status )
Packit 857059
	{
Packit 857059
		_DBG_ERROR(("Modify Qp failed!\n"));
Packit 857059
	}
Packit 857059
	
Packit 857059
done:
Packit 857059
	_DBG_LEAVE_LVL(_DBG_LVL_DEVICE);
Packit 857059
    return status;
Packit 857059
}
Packit 857059
Packit 857059
Packit 857059
Packit 857059
FSTATUS
Packit 857059
SmaDeviceConfig(
Packit 857059
	IN	SMA_CA_OBJ_PRIVATE		*CaObj,
Packit 857059
	IN	IB_QP_TYPE				QpType
Packit 857059
	)
Packit 857059
{
Packit 857059
	FSTATUS						status = FSUCCESS;
Packit 857059
	SMA_PORT_TABLE_PRIV			*pPortTbl;
Packit 857059
	uint32						i;
Packit 857059
			
Packit 857059
	_DBG_ENTER_LVL(_DBG_LVL_DEVICE, SmaDeviceConfig);
Packit 857059
Packit 857059
Packit 857059
	pPortTbl = (SMA_PORT_TABLE_PRIV *)CaObj->CaPublic.PortTbl;
Packit 857059
Packit 857059
	// Loop thru' all QP0's 
Packit 857059
	for ( i=0; i< CaObj->CaPublic.Ports; i++ )
Packit 857059
	{
Packit 857059
		// set QP to Init state
Packit 857059
		status = SmaConfigQp(
Packit 857059
			(( QPTypeSMI == QpType ) ? \
Packit 857059
			pPortTbl->PortBlock[i].QpHandle:pPortTbl->PortBlock[i].Qp1Handle),
Packit 857059
			QPStateInit,
Packit 857059
			QpType );
Packit 857059
		if ( FSUCCESS != status )
Packit 857059
		{
Packit 857059
			_DBG_ERROR((
Packit 857059
				"Could not transition QP%s to Init on port %d!\n", 
Packit 857059
				_DBG_PTR((( QPTypeSMI == QpType ) ? "0":"1")),
Packit 857059
				i+1));
Packit 857059
		} else {
Packit 857059
			// transition QP states
Packit 857059
Packit 857059
			// RecvQ to RTR
Packit 857059
			status = SmaConfigQp(
Packit 857059
						(( QPTypeSMI == QpType ) ? \
Packit 857059
						pPortTbl->PortBlock[i].QpHandle : \
Packit 857059
						pPortTbl->PortBlock[i].Qp1Handle),
Packit 857059
						QPStateReadyToRecv,
Packit 857059
						QpType );
Packit 857059
			if ( FSUCCESS == status )
Packit 857059
			{
Packit 857059
				// SendQ to RTS
Packit 857059
				status = SmaConfigQp(
Packit 857059
							(( QPTypeSMI == QpType ) ? \
Packit 857059
							pPortTbl->PortBlock[i].QpHandle : \
Packit 857059
							pPortTbl->PortBlock[i].Qp1Handle),
Packit 857059
							QPStateReadyToSend,
Packit 857059
							QpType );
Packit 857059
				if ( FSUCCESS != status )
Packit 857059
				{
Packit 857059
					// BUGBUG: return module error
Packit 857059
					_DBG_ERROR((
Packit 857059
						"Error transitioning QP%s on Port[%d] to RTS!\n", 
Packit 857059
						_DBG_PTR((( QPTypeSMI == QpType ) ? "0":"1")),
Packit 857059
						i+1));
Packit 857059
				}
Packit 857059
			} else {
Packit 857059
				// BUGBUG: return module error
Packit 857059
				_DBG_ERROR((
Packit 857059
					"Error transitioning QP%s on Port[%d] to RTR!\n", 
Packit 857059
					_DBG_PTR((( QPTypeSMI == QpType ) ? "0":"1")),
Packit 857059
					i+1));
Packit 857059
			}
Packit 857059
		}		// modify QP to hold CQ
Packit 857059
	}			// for Port loop
Packit 857059
Packit 857059
	_DBG_LEAVE_LVL(_DBG_LVL_DEVICE);
Packit 857059
    return status;
Packit 857059
}
Packit 857059
Packit 857059
Packit 857059
Packit 857059
FSTATUS
Packit 857059
GetAV(
Packit 857059
	IN	SMA_CA_OBJ_PRIVATE		*CaObj,
Packit 857059
	IN	IB_ADDRESS_VECTOR		*AvInfo,
Packit 857059
	OUT	IB_HANDLE				*AvHandle
Packit 857059
	)
Packit 857059
{
Packit 857059
	FSTATUS						status			= FSUCCESS;
Packit 857059
	SMA_PORT_TABLE_PRIV			*pPortTbl;
Packit 857059
			
Packit 857059
	_DBG_ENTER_LVL(_DBG_LVL_DEVICE, GetAV);
Packit 857059
Packit 857059
	pPortTbl = (SMA_PORT_TABLE_PRIV *)CaObj->CaPublic.PortTbl;
Packit 857059
Packit 857059
	// Create AV if one does not exist
Packit 857059
	_DBG_PRINT(_DBG_LVL_DEVICE,(
Packit 857059
		"AV Info:\n"
Packit 857059
		"Local:\n"
Packit 857059
		"\tPortGUID.....:x%"PRIx64"\n"
Packit 857059
		"\tPathBits.....:x%X\n"
Packit 857059
		"\tServiceLevel.:x%X\n"
Packit 857059
		"\tStaticRate...:x%X\n"
Packit 857059
		"Remote:\n"
Packit 857059
		"\tLID..........:x%X\n"
Packit 857059
		"\tGlobalRoute..:%s\n",
Packit 857059
		AvInfo->PortGUID,
Packit 857059
		AvInfo->PathBits,
Packit 857059
		AvInfo->ServiceLevel,
Packit 857059
		AvInfo->StaticRate,
Packit 857059
		AvInfo->DestLID,
Packit 857059
		_DBG_PTR(AvInfo->GlobalRoute == TRUE	? "TRUE":"FALSE" )));
Packit 857059
Packit 857059
	// Add Global Routing Info if present
Packit 857059
	if (AvInfo->GlobalRoute)
Packit 857059
	{
Packit 857059
		_DBG_PRINT(_DBG_LVL_DEVICE,(
Packit 857059
			"Global Route Info:\n"
Packit 857059
			"\tFlowLabel....:x%X\n"
Packit 857059
			"\tHopLimit.....:x%X\n"
Packit 857059
			"\tSrcGIDIndex..:x%X\n"
Packit 857059
			"\tTrafficClass.:x%X\n",
Packit 857059
			AvInfo->GlobalRouteInfo.FlowLabel,
Packit 857059
			AvInfo->GlobalRouteInfo.HopLimit,
Packit 857059
			AvInfo->GlobalRouteInfo.SrcGIDIndex,
Packit 857059
			AvInfo->GlobalRouteInfo.TrafficClass ));
Packit 857059
	}
Packit 857059
Packit 857059
	status = iba_create_av( CaObj->CaHandle, CaObj->PdHandle, AvInfo, AvHandle);
Packit 857059
Packit 857059
	_DBG_LEAVE_LVL(_DBG_LVL_DEVICE);
Packit 857059
    return status;
Packit 857059
}
Packit 857059
Packit 857059
Packit 857059
FSTATUS
Packit 857059
PutAV(
Packit 857059
	IN	SMA_CA_OBJ_PRIVATE		*CaObj,
Packit 857059
	IN	IB_HANDLE				AvHandle
Packit 857059
	)
Packit 857059
{
Packit 857059
	FSTATUS						status = FSUCCESS;
Packit 857059
			
Packit 857059
	_DBG_ENTER_LVL(_DBG_LVL_DEVICE, PutAV);
Packit 857059
Packit 857059
	// Destroy AV or cache it
Packit 857059
Packit 857059
	status = iba_destroy_av( AvHandle );
Packit 857059
Packit 857059
	_DBG_LEAVE_LVL (_DBG_LVL_DEVICE);
Packit 857059
    return status;
Packit 857059
}
Packit 857059
Packit 857059
Packit 857059
void
Packit 857059
NotifyIbtCallback (
Packit 857059
	IN	void				*Context
Packit 857059
	)
Packit 857059
{
Packit 857059
	SMA_CA_OBJ_PRIVATE		*pCaObj;
Packit 857059
	SMA_PORT_TABLE_PRIV		*pPortTbl;
Packit 857059
	SMA_PORT_BLOCK_PRIV		*pPortBlock;
Packit 857059
	uint32					j;
Packit 857059
Packit 857059
	_DBG_ENTER_LVL(_DBG_LVL_DEVICE, NotifyIbtCallback);
Packit 857059
Packit 857059
	// Scan through all CA's
Packit 857059
	SpinLockAcquire(&g_Sma->CaListLock);
Packit 857059
	for (pCaObj	= g_Sma->CaObj; pCaObj != NULL; pCaObj = pCaObj->Next)
Packit 857059
	{
Packit 857059
		boolean exists;
Packit 857059
Packit 857059
		pCaObj->UseCount++;
Packit 857059
		SpinLockRelease(&g_Sma->CaListLock);
Packit 857059
Packit 857059
		exists = IbtNotifyUserEvent( Context,
Packit 857059
								pCaObj->CaPublic.CaGuid, // Port/Node GUID
Packit 857059
								IB_NOTIFY_CA_ADD );
Packit 857059
		if (! exists)
Packit 857059
			goto release;
Packit 857059
Packit 857059
		// Now notify about port events too
Packit 857059
		pPortTbl = (SMA_PORT_TABLE_PRIV *)pCaObj->CaPublic.PortTbl;
Packit 857059
		for ( j = 0; j< pCaObj->CaPublic.Ports ; j++ )
Packit 857059
		{
Packit 857059
			pPortBlock = &pPortTbl->PortBlock[j];
Packit 857059
Packit 857059
			if ( IB_PORT_ACTIVE == pPortBlock->Public.State )
Packit 857059
			{
Packit 857059
				exists = IbtNotifyUserEvent( Context,
Packit 857059
								pPortBlock->Public.GUID,// Port/Node GUID
Packit 857059
								IB_NOTIFY_LID_EVENT );
Packit 857059
				if (! exists)
Packit 857059
					goto release;
Packit 857059
			}
Packit 857059
		}
Packit 857059
Packit 857059
		SpinLockAcquire(&g_Sma->CaListLock);
Packit 857059
		pCaObj->UseCount--;
Packit 857059
	}
Packit 857059
Packit 857059
done:
Packit 857059
	SpinLockRelease(&g_Sma->CaListLock);
Packit 857059
	_DBG_LEAVE_LVL (_DBG_LVL_DEVICE);
Packit 857059
	return;
Packit 857059
Packit 857059
release:
Packit 857059
	SpinLockAcquire(&g_Sma->CaListLock);
Packit 857059
	pCaObj->UseCount--;
Packit 857059
	goto done;
Packit 857059
}
Packit 857059
Packit 857059
void
Packit 857059
SetClassMask (
Packit 857059
	IN	uint8				Class,
Packit 857059
	IN	boolean				Enabled
Packit 857059
	)
Packit 857059
{
Packit 857059
	switch (Class)
Packit 857059
	{
Packit 857059
	case MCLASS_COMM_MGT:
Packit 857059
		if ( TRUE == Enabled )
Packit 857059
			g_Sma->IsConnectionManagementSupported = 1;
Packit 857059
		else
Packit 857059
			g_Sma->IsConnectionManagementSupported = 0;
Packit 857059
		break;
Packit 857059
Packit 857059
#if 0
Packit 857059
	case MCLASS_SNMP:
Packit 857059
		if ( TRUE == Enabled )
Packit 857059
			g_Sma->IsSNMPTunnelingSupported = 1;
Packit 857059
		else
Packit 857059
			g_Sma->IsSNMPTunnelingSupported = 0;
Packit 857059
		break;
Packit 857059
Packit 857059
	case MCLASS_DEV_MGT:
Packit 857059
		if ( TRUE == Enabled )
Packit 857059
			g_Sma->IsDeviceManagementSupported = 1;
Packit 857059
		else
Packit 857059
			g_Sma->IsDeviceManagementSupported = 0;
Packit 857059
		break;
Packit 857059
#endif
Packit 857059
Packit 857059
	//
Packit 857059
	// TBD:
Packit 857059
	// Must handle vendor Classes here
Packit 857059
	//case MCLASS_X:
Packit 857059
	//
Packit 857059
	
Packit 857059
	default:
Packit 857059
		_DBG_PRINT(_DBG_LVL_DEVICE,(
Packit 857059
			"No capabilities for this Class [x%X]\n", 
Packit 857059
			Class ));
Packit 857059
	}
Packit 857059
}
Packit 857059
Packit 857059
void
Packit 857059
SetPortCapabilities ( void )
Packit 857059
{
Packit 857059
	SMA_CA_OBJ_PRIVATE		*pCaObj;
Packit 857059
	FSTATUS					status;
Packit 857059
	SMA_PORT_TABLE_PRIV		*pPortTbl;
Packit 857059
	SMA_PORT_BLOCK_PRIV		*pPortBlock;
Packit 857059
	STL_SMP					*pSmp;
Packit 857059
	STL_PORT_INFO			*pPortInfo;
Packit 857059
	uint32					j;
Packit 857059
	uint8					portNo;
Packit 857059
	uint32					smps;
Packit 857059
	POOL_DATA_BLOCK			*pSmpBlock;
Packit 857059
Packit 857059
Packit 857059
	_DBG_ENTER_LVL (_DBG_LVL_DEVICE, SetPortCapabilities);
Packit 857059
Packit 857059
	for ( ;; )
Packit 857059
	{
Packit 857059
		smps		= 1;
Packit 857059
		pSmpBlock	= NULL;
Packit 857059
Packit 857059
		status = iba_smi_pool_get(
Packit 857059
					NULL,
Packit 857059
					&smps,			
Packit 857059
					(SMP_BLOCK **)&pSmpBlock );
Packit 857059
Packit 857059
		if ( (FSUCCESS != status) || (pSmpBlock == NULL) )
Packit 857059
		{
Packit 857059
			_DBG_ERROR ((
Packit 857059
					"Could not Grab from Pool!\n" ));
Packit 857059
			break;
Packit 857059
		}
Packit 857059
Packit 857059
		pSmp		= (STL_SMP*)pSmpBlock->Block.Smp;
Packit 857059
		pPortInfo	= (STL_PORT_INFO*)pSmp->SmpExt.DirectedRoute.SMPData;
Packit 857059
		
Packit 857059
		// Scan through all CA's
Packit 857059
		SpinLockAcquire(&g_Sma->CaListLock);
Packit 857059
		for (pCaObj	= g_Sma->CaObj; pCaObj != NULL; pCaObj = pCaObj->Next)
Packit 857059
		{
Packit 857059
			uint32	capMaskUpdate=0;
Packit 857059
			uint32	MadQueryLength;
Packit 857059
Packit 857059
			pCaObj->UseCount++;
Packit 857059
			SpinLockRelease(&g_Sma->CaListLock);
Packit 857059
Packit 857059
			// Set each port
Packit 857059
			pPortTbl = (SMA_PORT_TABLE_PRIV *)pCaObj->CaPublic.PortTbl;
Packit 857059
Packit 857059
			for ( j = 0; j< pCaObj->CaPublic.Ports ; j++ )
Packit 857059
			{
Packit 857059
				pPortBlock							= &pPortTbl->PortBlock[j];
Packit 857059
				portNo								= (uint8)j;	// switch port zero
Packit 857059
Packit 857059
				// Format MAD get PortInfo
Packit 857059
				pSmp->common.BaseVersion				= STL_BASE_VERSION;
Packit 857059
				pSmp->common.ClassVersion				= STL_SM_CLASS_VERSION;
Packit 857059
Packit 857059
				pSmp->common.mr.AsReg8				= 0;
Packit 857059
				pSmp->common.mr.s.Method				= MMTHD_GET;
Packit 857059
Packit 857059
				pSmp->SmpExt.DirectedRoute.DrDLID	= STL_LID_PERMISSIVE;
Packit 857059
				pSmp->SmpExt.DirectedRoute.DrSLID	= STL_LID_PERMISSIVE;
Packit 857059
Packit 857059
				pSmp->common.u.DR.s.Status		= 0;
Packit 857059
				pSmp->common.u.DR.s.D			= 0;
Packit 857059
				pSmp->common.u.DR.HopCount		= 0;
Packit 857059
				pSmp->common.u.DR.HopPointer	= 0;
Packit 857059
				//pSmp->common.TransactionID	= 0;
Packit 857059
				pSmp->common.MgmtClass			= MCLASS_SM_DIRECTED_ROUTE;
Packit 857059
Packit 857059
				pSmp->common.AttributeID		= STL_MCLASS_ATTRIB_ID_PORT_INFO;
Packit 857059
				pSmp->common.AttributeModifier	= 0x01000000 | portNo;
Packit 857059
Packit 857059
				STL_SMP_SET_LOCAL(pSmp);		// local request
Packit 857059
Packit 857059
				MadQueryLength = sizeof(*pSmp) - STL_MAX_PAYLOAD_SMP_DR;
Packit 857059
				status = iba_get_set_mad( pPortBlock->QpHandle, portNo,
Packit 857059
									0, // SLID ignored, local request
Packit 857059
									pSmp,
Packit 857059
									&MadQueryLength );
Packit 857059
				if ( FSUCCESS != status )
Packit 857059
				{
Packit 857059
					_DBG_ERROR ((
Packit 857059
						"Could not GET Port capabilities!\n" ));
Packit 857059
					break;
Packit 857059
				}
Packit 857059
Packit 857059
				// SWAP THE GETPORTINFO response
Packit 857059
				BSWAP_STL_PORT_INFO(pPortInfo);
Packit 857059
				ZERO_RSVD_STL_PORT_INFO(pPortInfo);
Packit 857059
Packit 857059
				// Set capability if necessary
Packit 857059
				if (g_Sma->IsConnectionManagementSupported && !pPortInfo->CapabilityMask.s.IsConnectionManagementSupported) {
Packit 857059
					pPortInfo->CapabilityMask.s.IsConnectionManagementSupported = \
Packit 857059
						g_Sma->IsConnectionManagementSupported;
Packit 857059
					capMaskUpdate = 1;
Packit 857059
				}
Packit 857059
				if (g_Sma->IsDeviceManagementSupported && !pPortInfo->CapabilityMask.s.IsDeviceManagementSupported) {
Packit 857059
					pPortInfo->CapabilityMask.s.IsDeviceManagementSupported = \
Packit 857059
						g_Sma->IsDeviceManagementSupported;
Packit 857059
					capMaskUpdate = 1;
Packit 857059
				}
Packit 857059
				if (!capMaskUpdate)
Packit 857059
					break;				// nothing to change
Packit 857059
				
Packit 857059
				// Do not change other fields
Packit 857059
				pPortInfo->LinkWidth.Enabled = STL_LINK_WIDTH_NOP;
Packit 857059
				pPortInfo->PortStates.s.PortState = IB_PORT_NOP;
Packit 857059
				pPortInfo->PortStates.s.PortPhysicalState = IB_PORT_PHYS_NOP;
Packit 857059
				pPortInfo->s4.OperationalVL = 0;
Packit 857059
				pPortInfo->LinkSpeed.Enabled = IB_LINK_SPEED_NOP;
Packit 857059
				
Packit 857059
				// SWAP THE SET PORT INFO payload
Packit 857059
				BSWAP_STL_PORT_INFO(pPortInfo);
Packit 857059
Packit 857059
				// Set base MAD info
Packit 857059
				pSmp->common.BaseVersion				= STL_BASE_VERSION;
Packit 857059
				pSmp->common.ClassVersion				= STL_SM_CLASS_VERSION;
Packit 857059
				
Packit 857059
				pSmp->common.mr.AsReg8				= 0;
Packit 857059
				pSmp->common.mr.s.Method			= MMTHD_SET;
Packit 857059
Packit 857059
				pSmp->SmpExt.DirectedRoute.DrDLID	= STL_LID_PERMISSIVE;
Packit 857059
				pSmp->SmpExt.DirectedRoute.DrSLID	= STL_LID_PERMISSIVE;
Packit 857059
				
Packit 857059
				pSmp->common.u.DR.s.Status		= 0;
Packit 857059
				pSmp->common.u.DR.s.D			= 0;
Packit 857059
				pSmp->common.u.DR.HopCount		= 0;
Packit 857059
				pSmp->common.u.DR.HopPointer	= 0;
Packit 857059
				//pSmp->common.TransactionID	= 0;
Packit 857059
				pSmp->common.MgmtClass			= MCLASS_SM_DIRECTED_ROUTE;
Packit 857059
Packit 857059
				pSmp->common.AttributeID		= STL_MCLASS_ATTRIB_ID_PORT_INFO;
Packit 857059
				pSmp->common.AttributeModifier	= 0x01000000 | portNo;
Packit 857059
Packit 857059
				STL_SMP_SET_LOCAL(pSmp);		// local request
Packit 857059
Packit 857059
				MadQueryLength = sizeof(*pSmp) - STL_MAX_PAYLOAD_SMP_DR + sizeof(*pPortInfo);
Packit 857059
				status = iba_get_set_mad( pPortBlock->QpHandle, portNo,
Packit 857059
										0, // SLID ignored, local request
Packit 857059
										pSmp,
Packit 857059
										&MadQueryLength );
Packit 857059
				if ( FSUCCESS != status )
Packit 857059
					break;
Packit 857059
Packit 857059
 			}	// loop j - ports
Packit 857059
Packit 857059
			SpinLockAcquire(&g_Sma->CaListLock);
Packit 857059
			pCaObj->UseCount--;
Packit 857059
			
Packit 857059
			if ( FSUCCESS != status )
Packit 857059
				break;
Packit 857059
Packit 857059
		}		// loop - CA's
Packit 857059
		SpinLockRelease(&g_Sma->CaListLock);
Packit 857059
Packit 857059
		status = iba_smi_pool_put( NULL, (SMP_BLOCK *)pSmpBlock );
Packit 857059
		break;
Packit 857059
	}
Packit 857059
Packit 857059
	_DBG_LEAVE_LVL (_DBG_LVL_DEVICE);
Packit 857059
}
Packit 857059
Packit 857059
void
Packit 857059
SetPortCapabilityMask (
Packit 857059
	IN	uint8				Class,
Packit 857059
	IN	boolean				Enabled
Packit 857059
	)
Packit 857059
{
Packit 857059
	_DBG_ENTER_LVL (_DBG_LVL_DEVICE, SetPortCapabilityMask );
Packit 857059
Packit 857059
	// Check init state of drivers
Packit 857059
	SetClassMask ( Class, Enabled );
Packit 857059
Packit 857059
	if ( g_Sma->NumCa )
Packit 857059
	{
Packit 857059
		SetPortCapabilities ();
Packit 857059
	} else {
Packit 857059
		_DBG_PRINT (_DBG_LVL_DEVICE, (
Packit 857059
			"No devices present. Caching capabilities for an Add Device\n" ));
Packit 857059
	}
Packit 857059
Packit 857059
	_DBG_LEAVE_LVL (_DBG_LVL_DEVICE);
Packit 857059
}