Blame IbAccess/Common/Ibt/Bma/bmamain.c

Packit 857059
/* BEGIN_ICS_COPYRIGHT4 ****************************************
Packit 857059
Packit 857059
Copyright (c) 2015-2017, 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 "bmamain.h"
Packit 857059
#include "bmadebug.h"
Packit 857059
#include "bma_provider.h"
Packit 857059
#include "bspcommon/h/usrBootManager.h"
Packit 857059
#include "bspcommon/ibml/h/icsApi.h"
Packit 857059
Packit 857059
//
Packit 857059
// Debug params
Packit 857059
//
Packit 857059
#if ICS_LOGGING
Packit 857059
_IB_DBG_PARAM_BLOCK(_DBG_LVL_ALL, _DBG_BREAK_ENABLE, BMA_TAG, "Bma", MOD_BMA, Bma);
Packit 857059
#else
Packit 857059
_IB_DBG_PARAM_BLOCK((_DBG_LVL_FATAL | _DBG_LVL_ERROR), _DBG_BREAK_ENABLE, BMA_TAG, "Bma");
Packit 857059
#endif
Packit 857059
 
Packit 857059
//
Packit 857059
// Global Info
Packit 857059
//
Packit 857059
BMA_GLOBAL_INFO  *g_BmaGlobalInfo;
Packit 857059
Packit 857059
//
Packit 857059
// Stored settings
Packit 857059
//
Packit 857059
BMA_GLOBAL_CONFIG_PARAMETERS	g_BmaSettings = BMA_DEFAULT_SETTINGS;
Packit 857059
Packit 857059
Packit 857059
//
Packit 857059
// BmaLoad
Packit 857059
//
Packit 857059
// This routine is called by the VCA Init when the driver is first loaded. 
Packit 857059
// This routine is to create and initialize the BMA agent global data structures.
Packit 857059
//
Packit 857059
// INPUTS:
Packit 857059
//
Packit 857059
//	ComponentInfo - Address of IBT_COMPONENT_INFO that needs to be updated
Packit 857059
//	with this driver's specific handlers for add/remove of a channel adapter
Packit 857059
//	device as well as the overall driver unload handler.
Packit 857059
//
Packit 857059
// OUTPUTS:
Packit 857059
//
Packit 857059
//	None.
Packit 857059
//
Packit 857059
// RETURNS:
Packit 857059
//
Packit 857059
//	FSUCCESS - Indicates a successful load.
Packit 857059
//
Packit 857059
Packit 857059
FSTATUS
Packit 857059
BmaLoad(
Packit 857059
	IN IBT_COMPONENT_INFO		*ComponentInfo
Packit 857059
	)
Packit 857059
{
Packit 857059
	FSTATUS						status = FSUCCESS;
Packit 857059
	extern uint32 BmaDbg;
Packit 857059
#ifdef IB_TRACE
Packit 857059
	extern uint32 BmaTrace;
Packit 857059
#endif
Packit 857059
Packit 857059
Packit 857059
	_DBG_ENTER_LVL(_DBG_LVL_MAIN, BMALoad);
Packit 857059
	_DBG_INIT;
Packit 857059
Packit 857059
	__DBG_LEVEL__ = BmaDbg;
Packit 857059
#ifdef IB_TRACE
Packit 857059
	__DBG_TRACE_LEVEL__ = BmaTrace;
Packit 857059
#endif
Packit 857059
#if defined(IB_DEBUG) || defined(DBG)
Packit 857059
	MsgOut ("Bma:DebugFlags = 0x%8x\n", __DBG_LEVEL__);
Packit 857059
#endif
Packit 857059
Packit 857059
#if defined(VXWORKS)
Packit 857059
	_DBG_PRINT(_DBG_LVL_MAIN,  
Packit 857059
	(" InfiniBand Baseboard Management Class agent. Built %s %s\n",\
Packit 857059
	__DATE__, __TIME__ ));
Packit 857059
#else
Packit 857059
	_DBG_PRINT(_DBG_LVL_MAIN,  
Packit 857059
	(" InfiniBand Baseboard Management Class agent. Built %s %s\n",\
Packit 857059
	_DBG_PTR(__DATE__), _DBG_PTR(__TIME__) ));
Packit 857059
#endif
Packit 857059
Packit 857059
	_TRC_REGISTER();
Packit 857059
Packit 857059
	//
Packit 857059
    // Establish dispatch entry points for the functions supported.
Packit 857059
	//
Packit 857059
Packit 857059
	MemoryClear( ComponentInfo, sizeof(IBT_COMPONENT_INFO) );
Packit 857059
Packit 857059
	ComponentInfo->AddDevice = BmaAddDevice;
Packit 857059
	ComponentInfo->RemoveDevice = BmaRemoveDevice;
Packit 857059
	ComponentInfo->Unload = BmaUnload;
Packit 857059
Packit 857059
	
Packit 857059
	//
Packit 857059
    // Read any registry parameters for the driver which may be present.
Packit 857059
	//
Packit 857059
	//BmaReadRegistryParameters();
Packit 857059
Packit 857059
	//
Packit 857059
    // This function is called to initialize the GSA subsystem. This must be 
Packit 857059
	// called only once and if the function does not return success, the 
Packit 857059
	// caller must unload the component containing GSA or else not use the 
Packit 857059
	// GSA functionality since GSA will not be available.
Packit 857059
	//
Packit 857059
	// We are being asked to do a one-time initialization. Here we initialize 
Packit 857059
	// the list of channel adapters as well as initialize the list of service 
Packit 857059
	// classes as well as initialize the spin locks guarding these lists.
Packit 857059
	//
Packit 857059
Packit 857059
Packit 857059
	//
Packit 857059
	// Allocate space for Global data
Packit 857059
	//
Packit 857059
Packit 857059
	g_BmaGlobalInfo = (BMA_GLOBAL_INFO*)MemoryAllocateAndClear(
Packit 857059
									 sizeof(BMA_GLOBAL_INFO), FALSE, BMA_TAG );
Packit 857059
	if ( NULL != g_BmaGlobalInfo )
Packit 857059
	{
Packit 857059
	
Packit 857059
		//
Packit 857059
		// initialize global data
Packit 857059
		//
Packit 857059
Packit 857059
		g_BmaGlobalInfo->binitsuccess = FALSE; 
Packit 857059
Packit 857059
		SpinLockInitState( &g_BmaGlobalInfo->DevListLock );
Packit 857059
		if( !SpinLockInit( &g_BmaGlobalInfo->DevListLock ) )
Packit 857059
		{
Packit 857059
			_DBG_ERROR(( "Unable to initialize spin locks!\n" ));
Packit 857059
			status = FINSUFFICIENT_RESOURCES;
Packit 857059
			goto fail_lock;
Packit 857059
		}
Packit 857059
Packit 857059
		//
Packit 857059
		// Recv Queue and Thread
Packit 857059
		//
Packit 857059
		CmdThreadInitState(&g_BmaGlobalInfo->RecvThread);
Packit 857059
		if ( ! CmdThreadCreate(&g_BmaGlobalInfo->RecvThread,
Packit 857059
				THREAD_PRI_HIGH, "Bma", (CMD_THREAD_CALLBACK)BmaThreadCallback,
Packit 857059
				(CMD_THREAD_CALLBACK)BmaFreeCallback, (void*)g_BmaGlobalInfo))
Packit 857059
		{
Packit 857059
			_DBG_ERROR(("BmaMain: Unable to Create RecvThread\n"));
Packit 857059
			status = FINSUFFICIENT_RESOURCES;
Packit 857059
			goto fail_thread;
Packit 857059
		}
Packit 857059
		
Packit 857059
Packit 857059
		// initialize this general service class manager with GSI
Packit 857059
		status = iba_gsi_register_class(MCLASS_BM, 
Packit 857059
									IB_BM_CLASS_VERSION,
Packit 857059
									GSI_REGISTER_RESPONDER,	// Register as a Responder
Packit 857059
									FALSE,					// No SAR cap needed
Packit 857059
									g_BmaGlobalInfo,		// Context
Packit 857059
									BmaSendCallback,
Packit 857059
									BmaRecvCallback,
Packit 857059
									&g_BmaGlobalInfo->GsaHandle);
Packit 857059
							
Packit 857059
		if (status != FSUCCESS)
Packit 857059
		{
Packit 857059
			CmdThreadDestroy(&g_BmaGlobalInfo->RecvThread);
Packit 857059
fail_thread:
Packit 857059
			SpinLockDestroy( &g_BmaGlobalInfo->DevListLock );
Packit 857059
fail_lock:
Packit 857059
			MemoryDeallocate(g_BmaGlobalInfo);
Packit 857059
			g_BmaGlobalInfo = NULL;
Packit 857059
Packit 857059
			_DBG_ERROR(("BmaMain: Unable to register with GSA!!! <status %d>\n", status));
Packit 857059
Packit 857059
			_DBG_LEAVE_EXT(_DBG_LVL_FUNC_TRACE);
Packit 857059
Packit 857059
			return status;
Packit 857059
		}
Packit 857059
 
Packit 857059
	}
Packit 857059
	else
Packit 857059
	{
Packit 857059
		status = FINSUFFICIENT_RESOURCES;
Packit 857059
		_DBG_PRINT(_DBG_LVL_MAIN,("Not enough memory!\n"));
Packit 857059
	}
Packit 857059
Packit 857059
    
Packit 857059
	_DBG_LEAVE_LVL(_DBG_LVL_MAIN);
Packit 857059
    
Packit 857059
    return status;
Packit 857059
}
Packit 857059
Packit 857059
Packit 857059
//
Packit 857059
// BmaUnload
Packit 857059
//
Packit 857059
//	This routine should release resources allocated in the BmaLoad function.
Packit 857059
//	Also, since their is a single instance of the service for all channel
Packit 857059
//	adapters in the system, it will also release resources allocated in the
Packit 857059
//	BmaAddDevice function. 
Packit 857059
//
Packit 857059
// INPUTS:
Packit 857059
//
Packit 857059
//	None.
Packit 857059
//
Packit 857059
// OUTPUTS:
Packit 857059
//
Packit 857059
//	None.
Packit 857059
//
Packit 857059
// RETURNS:
Packit 857059
//
Packit 857059
//	None
Packit 857059
//
Packit 857059
//
Packit 857059
void
Packit 857059
BmaUnload(void)
Packit 857059
{
Packit 857059
Packit 857059
	_DBG_ENTER_LVL(_DBG_LVL_MAIN, BmaUnload);
Packit 857059
Packit 857059
	_TRC_UNREGISTER();
Packit 857059
Packit 857059
	if ( g_BmaGlobalInfo )
Packit 857059
	{
Packit 857059
Packit 857059
		// Destroy the datagram pool
Packit 857059
		if ( g_BmaGlobalInfo->DgrmPoolHandle )
Packit 857059
			iba_gsi_destroy_dgrm_pool( g_BmaGlobalInfo->DgrmPoolHandle );
Packit 857059
Packit 857059
		// Deregister this class agent with the GSA	
Packit 857059
		if ( g_BmaGlobalInfo->GsaHandle )
Packit 857059
			iba_gsi_deregister_class(g_BmaGlobalInfo->GsaHandle);
Packit 857059
Packit 857059
		//
Packit 857059
		// Recv Thread
Packit 857059
		//
Packit 857059
		CmdThreadDestroy(&g_BmaGlobalInfo->RecvThread);
Packit 857059
				
Packit 857059
		//
Packit 857059
		// Ca List Members
Packit 857059
		//
Packit 857059
		while ( g_BmaGlobalInfo->DevList )
Packit 857059
		{
Packit 857059
			BmaRemoveDevice( g_BmaGlobalInfo->DevList->CaGuid, NULL );
Packit 857059
		}
Packit 857059
Packit 857059
		//
Packit 857059
		// Ca List Lock
Packit 857059
		//
Packit 857059
		SpinLockDestroy( &g_BmaGlobalInfo->DevListLock );
Packit 857059
Packit 857059
Packit 857059
		//
Packit 857059
		// Free up global memory
Packit 857059
		//
Packit 857059
		MemoryDeallocate( g_BmaGlobalInfo );
Packit 857059
		g_BmaGlobalInfo = NULL;
Packit 857059
Packit 857059
	} // if g_BmaGlobalInfo
Packit 857059
Packit 857059
	_DBG_LEAVE_LVL(_DBG_LVL_MAIN);
Packit 857059
  
Packit 857059
Packit 857059
}
Packit 857059
Packit 857059
Packit 857059
//////////////////////////////////////////////////////////////////////////
Packit 857059
// BmaAddDevice()
Packit 857059
//
Packit 857059
// This routine is called once for every new device added.
Packit 857059
//
Packit 857059
// INPUTS:
Packit 857059
//		CaGuid - the channel adapters GUID
Packit 857059
//
Packit 857059
// OUTPUTS:
Packit 857059
//
Packit 857059
//	None.  Although function is defined to return context value, this
Packit 857059
//	value is not set since their is nothing specifically allocated for
Packit 857059
//	each new channel adapter, so nothing is done in the BmaRemoveDevice
Packit 857059
//	function that needs the context.
Packit 857059
//
Packit 857059
// RETURNS:
Packit 857059
//
Packit 857059
//	FSUCCESS - Indicates a successful initialization.
Packit 857059
//
Packit 857059
//
Packit 857059
FSTATUS
Packit 857059
BmaAddDevice(
Packit 857059
	IN	EUI64			CaGuid,
Packit 857059
	OUT void			**Context
Packit 857059
	)
Packit 857059
{
Packit 857059
	FSTATUS			status = FSUCCESS;
Packit 857059
	uint32			BufferSize;
Packit 857059
	BMA_DEV_INFO	*pDevInfo=NULL;
Packit 857059
Packit 857059
	_DBG_ENTER_LVL(_DBG_LVL_MAIN, BmaAddDevice);
Packit 857059
Packit 857059
	ASSERT(g_BmaGlobalInfo);
Packit 857059
Packit 857059
	if (!g_BmaGlobalInfo->binitsuccess)
Packit 857059
	{
Packit 857059
		// Create the datagram pool
Packit 857059
		BufferSize = sizeof(MAD);
Packit 857059
		status = iba_gsi_create_dgrm_pool(g_BmaGlobalInfo->GsaHandle,
Packit 857059
								g_BmaSettings.MaxNDgrm,
Packit 857059
								1,
Packit 857059
								&BufferSize,
Packit 857059
								0, //1,
Packit 857059
								&g_BmaGlobalInfo->DgrmPoolHandle
Packit 857059
								);
Packit 857059
		if (status != FSUCCESS)
Packit 857059
		{
Packit 857059
			// Cleanup
Packit 857059
			iba_gsi_deregister_class(g_BmaGlobalInfo->GsaHandle);
Packit 857059
Packit 857059
			MemoryDeallocate(g_BmaGlobalInfo);
Packit 857059
Packit 857059
			g_BmaGlobalInfo = NULL;
Packit 857059
Packit 857059
			_DBG_ERROR(("Unable to create BMA datagram pool!!! <status %d>\n", status));
Packit 857059
		}
Packit 857059
		else
Packit 857059
		{
Packit 857059
			g_BmaGlobalInfo->binitsuccess = TRUE;
Packit 857059
		}
Packit 857059
Packit 857059
	}
Packit 857059
Packit 857059
	if (g_BmaGlobalInfo->binitsuccess)
Packit 857059
	{
Packit 857059
		pDevInfo = (BMA_DEV_INFO*)MemoryAllocateAndClear(sizeof(BMA_DEV_INFO), FALSE, BMA_TAG );
Packit 857059
Packit 857059
		if (pDevInfo)
Packit 857059
		{
Packit 857059
			IB_CA_ATTRIBUTES CaAttributes;
Packit 857059
Packit 857059
			pDevInfo->CaGuid = CaGuid;
Packit 857059
			status = iba_query_ca_by_guid_alloc(CaGuid, &CaAttributes);
Packit 857059
			if ( status == FSUCCESS )
Packit 857059
			{
Packit 857059
				pDevInfo->NumPorts = CaAttributes.Ports;
Packit 857059
				pDevInfo->Port = (BMA_PORT_INFO*)
Packit 857059
					MemoryAllocateAndClear(sizeof(BMA_PORT_INFO)*pDevInfo->NumPorts, FALSE, BMA_TAG);
Packit 857059
				if (pDevInfo->Port)
Packit 857059
				{
Packit 857059
					IB_PORT_ATTRIBUTES *pPortAttr;
Packit 857059
					unsigned i;
Packit 857059
Packit 857059
					for ( i = 0, pPortAttr = CaAttributes.PortAttributesList;
Packit 857059
						  i < pDevInfo->NumPorts;
Packit 857059
						  i++, pPortAttr = pPortAttr->Next )
Packit 857059
					{
Packit 857059
						// Traps disabled by default, Trap settings are all zero
Packit 857059
						// BKey, BKeyProtect, BKeyViolations, and BKeyLease all init to zero
Packit 857059
						pDevInfo->Port[i].Guid = pPortAttr->GUID;
Packit 857059
					}
Packit 857059
Packit 857059
					MemoryDeallocate(CaAttributes.PortAttributesList);
Packit 857059
Packit 857059
					// Success, add this CA to the list
Packit 857059
					SpinLockAcquire( &g_BmaGlobalInfo->DevListLock );
Packit 857059
					pDevInfo->Next = g_BmaGlobalInfo->DevList;
Packit 857059
					g_BmaGlobalInfo->DevList = pDevInfo;
Packit 857059
					SpinLockRelease( &g_BmaGlobalInfo->DevListLock );
Packit 857059
				}
Packit 857059
				else
Packit 857059
				{
Packit 857059
					_DBG_ERROR(("MemAlloc failed for Port List!\n"));
Packit 857059
					status = FINSUFFICIENT_MEMORY;
Packit 857059
				}
Packit 857059
			}
Packit 857059
			else
Packit 857059
			{
Packit 857059
				_DBG_ERROR(("CA Query Failed!\n"));
Packit 857059
				MemoryDeallocate(pDevInfo);
Packit 857059
			}
Packit 857059
		}
Packit 857059
		else
Packit 857059
		{
Packit 857059
			_DBG_ERROR(("MemAlloc failed for pDevInfo!\n"));
Packit 857059
			status = FINSUFFICIENT_MEMORY;
Packit 857059
		}
Packit 857059
	}
Packit 857059
Packit 857059
	_DBG_LEAVE_LVL(_DBG_LVL_MAIN);
Packit 857059
Packit 857059
	return status;
Packit 857059
Packit 857059
} // BmaAddDevice()
Packit 857059
Packit 857059
Packit 857059
//////////////////////////////////////////////////////////////////////////
Packit 857059
// BmaRemoveDevice()
Packit 857059
//
Packit 857059
// This routine is called once for every CA device being removed.  Nothing
Packit 857059
//	is performed in this function.  All cleanup is performed in the BmaUnload
Packit 857059
//	function.
Packit 857059
//
Packit 857059
// INPUTS:
Packit 857059
//		CaGuid - the channel adapters GUID
Packit 857059
//		Context - driver defined unique context for this CA
Packit 857059
//
Packit 857059
// OUTPUTS:
Packit 857059
//
Packit 857059
//	None.
Packit 857059
//
Packit 857059
// RETURNS:
Packit 857059
//
Packit 857059
//	FSUCCESS - Indicates a successful initialization.
Packit 857059
//
Packit 857059
//
Packit 857059
FSTATUS
Packit 857059
BmaRemoveDevice(
Packit 857059
	IN	EUI64			CaGuid,
Packit 857059
	IN void				*Context
Packit 857059
	)
Packit 857059
{
Packit 857059
	FSTATUS			status = FSUCCESS;
Packit 857059
	BMA_DEV_INFO	*pDevInfo=NULL;
Packit 857059
Packit 857059
	_DBG_ENTER_LVL(_DBG_LVL_MAIN, BmaRemoveDevice);
Packit 857059
Packit 857059
	ASSERT(g_BmaGlobalInfo);
Packit 857059
Packit 857059
	SpinLockAcquire( &g_BmaGlobalInfo->DevListLock );
Packit 857059
	pDevInfo = g_BmaGlobalInfo->DevList;
Packit 857059
	if ( g_BmaGlobalInfo->DevList->CaGuid == CaGuid )
Packit 857059
	{
Packit 857059
		g_BmaGlobalInfo->DevList = pDevInfo->Next;
Packit 857059
	}
Packit 857059
	else
Packit 857059
	{
Packit 857059
		while ( pDevInfo->Next )
Packit 857059
		{
Packit 857059
			if ( pDevInfo->Next->CaGuid == CaGuid )
Packit 857059
			{
Packit 857059
				BMA_DEV_INFO *Found = pDevInfo->Next;
Packit 857059
				pDevInfo->Next = Found->Next;
Packit 857059
				pDevInfo = Found;
Packit 857059
				break;
Packit 857059
			}
Packit 857059
			pDevInfo = pDevInfo->Next;
Packit 857059
		}
Packit 857059
	}
Packit 857059
	SpinLockRelease( &g_BmaGlobalInfo->DevListLock );
Packit 857059
Packit 857059
	if (pDevInfo && pDevInfo->CaGuid == CaGuid)
Packit 857059
	{
Packit 857059
		MemoryDeallocate( pDevInfo->Port );
Packit 857059
		MemoryDeallocate( pDevInfo );
Packit 857059
	}
Packit 857059
	else
Packit 857059
	{
Packit 857059
		_DBG_ERROR(("Unable to find Ca with GUID 0x%"PRIx64"\n", CaGuid));
Packit 857059
		status = FERROR;
Packit 857059
	}
Packit 857059
Packit 857059
	_DBG_LEAVE_LVL(_DBG_LVL_MAIN);
Packit 857059
Packit 857059
	return status;
Packit 857059
Packit 857059
} // BmaRemoveDevice()