|
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 |
|
|
Packit |
857059 |
#include "gsamain.h"
|
|
Packit |
857059 |
|
|
Packit |
857059 |
|
|
Packit |
857059 |
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// GsiPostSendDgrm
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// INPUTS:
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// ServiceHandle - Handle returned upon registration
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// DgrmList - List of datagram(s) to be posted for send
|
|
Packit |
857059 |
// each must have payload in network byte order
|
|
Packit |
857059 |
// however MAD and RMPP_HEADERs should be in host
|
|
Packit |
857059 |
// byte order. On success, GSI owns the buffer and
|
|
Packit |
857059 |
// will byte swap back the MAD header prior to send completion
|
|
Packit |
857059 |
// on failure the buffer will be restored to host byte order
|
|
Packit |
857059 |
// for the MAD and RMPP headers
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// OUTPUTS:
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// None
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// RETURNS:
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// FSUCCESS
|
|
Packit |
857059 |
// FINVALID_PARAMETER
|
|
Packit |
857059 |
// FINSUFFICIENT_RESOURCES
|
|
Packit |
857059 |
// FINVALID_STATE
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
FSTATUS
|
|
Packit |
857059 |
iba_gsi_post_send(
|
|
Packit |
857059 |
IN IB_HANDLE ServiceHandle,
|
|
Packit |
857059 |
IN IBT_DGRM_ELEMENT *DgrmList
|
|
Packit |
857059 |
)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
FSTATUS status=FCANCELED;
|
|
Packit |
857059 |
GSA_POST_SEND_LIST *pPostList;
|
|
Packit |
857059 |
GSA_SERVICE_CLASS_INFO *serviceClass;
|
|
Packit |
857059 |
IBT_DGRM_ELEMENT_PRIV *pDgrmPrivate;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
_DBG_ENTER_LVL (_DBG_LVL_SEND, iba_gsi_post_send);
|
|
Packit |
857059 |
|
|
Packit |
857059 |
serviceClass = (GSA_SERVICE_CLASS_INFO *)ServiceHandle;
|
|
Packit |
857059 |
pDgrmPrivate = (IBT_DGRM_ELEMENT_PRIV *)DgrmList;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
#if defined(DBG) || defined(IB_DEBUG)
|
|
Packit |
857059 |
if (GSA_CLASS_SIG != serviceClass->SigInfo )
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
_DBG_ERROR (("Bad Class Handle passed by client!!!\n"));
|
|
Packit |
857059 |
_DBG_BREAK;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
if ( pDgrmPrivate->MemPoolHandle->ServiceHandle != serviceClass )
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
_DBG_ERROR (("Dgrm List is not owned by given Class Handle!!!\n"));
|
|
Packit |
857059 |
_DBG_BREAK;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
#endif
|
|
Packit |
857059 |
|
|
Packit |
857059 |
// generate a PostSendList from the first datagram in post
|
|
Packit |
857059 |
pPostList = &pDgrmPrivate->PostSendList;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
// Fill in list details
|
|
Packit |
857059 |
pPostList->DgrmIn = 0;
|
|
Packit |
857059 |
AtomicWrite(&pPostList->DgrmOut, 0);
|
|
Packit |
857059 |
pPostList->DgrmList = DgrmList;
|
|
Packit |
857059 |
pPostList->SARRequest = FALSE;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
// Find out if client is a SAR client
|
|
Packit |
857059 |
if ( TRUE == serviceClass->bSARRequired )
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
_DBG_PRINT(_DBG_LVL_SEND,( "SAR Client request\n" ));
|
|
Packit |
857059 |
status = DoSARSend( serviceClass, pPostList );
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
// We get here if non SAR client or if SAR request was not segmented
|
|
Packit |
857059 |
if ( FCANCELED == status )
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
IBT_DGRM_ELEMENT *pDgrmPostList;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
// Get total send requests
|
|
Packit |
857059 |
pDgrmPostList = DgrmList;
|
|
Packit |
857059 |
while ( pDgrmPostList )
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
pPostList->DgrmIn++;
|
|
Packit |
857059 |
pDgrmPostList = \
|
|
Packit |
857059 |
(IBT_DGRM_ELEMENT *)pDgrmPostList->Element.pNextElement;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
status = GsiDoSendDgrm(serviceClass, pPostList);
|
|
Packit |
857059 |
} // SAR
|
|
Packit |
857059 |
|
|
Packit |
857059 |
_DBG_LEAVE_LVL(_DBG_LVL_SEND);
|
|
Packit |
857059 |
return status;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// GsiDoSendDgrm
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// INPUTS:
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// ServiceClass - ServiceClass from registration
|
|
Packit |
857059 |
// if NULL, assumed to be Dgrms from global RecvQ
|
|
Packit |
857059 |
// and 2nd buffer is a single MAD to be posted
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// pPostList - post list info.
|
|
Packit |
857059 |
// 1st pPostList->DgrmIn dgrms in this list will be posted.
|
|
Packit |
857059 |
// each must have payload in network byte order
|
|
Packit |
857059 |
// however MAD and RMPP_HEADERs should be in host
|
|
Packit |
857059 |
// byte order. On success, GSI owns the buffer and
|
|
Packit |
857059 |
// will byte swap back the MAD header prior to send completion
|
|
Packit |
857059 |
// on failure the buffer will be restored to host byte order
|
|
Packit |
857059 |
// for the MAD and RMPP headers
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// OUTPUTS:
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// None
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
// RETURNS:
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
//
|
|
Packit |
857059 |
FSTATUS
|
|
Packit |
857059 |
GsiDoSendDgrm(
|
|
Packit |
857059 |
GSA_SERVICE_CLASS_INFO *ServiceClass,
|
|
Packit |
857059 |
IN GSA_POST_SEND_LIST *pPostList
|
|
Packit |
857059 |
)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
FSTATUS status = FINVALID_PARAMETER; // list empty
|
|
Packit |
857059 |
IBT_DGRM_ELEMENT_PRIV *pDgrmPrivate, *pDgrmPrivateNext;
|
|
Packit |
857059 |
IB_HANDLE qp1Handle, cqHandle;
|
|
Packit |
857059 |
SPIN_LOCK *qpLock;
|
|
Packit |
857059 |
IB_L_KEY memLKey;
|
|
Packit |
857059 |
MAD *pMad;
|
|
Packit |
857059 |
uint32 dgrmCount, i, dgrmFailed;
|
|
Packit |
857059 |
IB_WORK_REQ workRequest;
|
|
Packit |
857059 |
IB_ADDRESS_VECTOR avInfo;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
_DBG_ENTER_LVL (_DBG_LVL_SEND, GsiDoSendDgrm);
|
|
Packit |
857059 |
|
|
Packit |
857059 |
pDgrmPrivate = (IBT_DGRM_ELEMENT_PRIV *)pPostList->DgrmList;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
dgrmCount = pPostList->DgrmIn;
|
|
Packit |
857059 |
dgrmFailed = 0; // set a count for bad requests
|
|
Packit |
857059 |
|
|
Packit |
857059 |
while ( dgrmCount-- )
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
pDgrmPrivateNext = (IBT_DGRM_ELEMENT_PRIV *)
|
|
Packit |
857059 |
pDgrmPrivate->DgrmElement.Element.pNextElement;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
pDgrmPrivate->Base = pPostList; // link for completion processing
|
|
Packit |
857059 |
|
|
Packit |
857059 |
ASSERT_VALID_WORKREQID((uintn)pDgrmPrivate);
|
|
Packit |
857059 |
workRequest.WorkReqId = BUILD_SQ_WORKREQID((uintn)pDgrmPrivate);
|
|
Packit |
857059 |
workRequest.Operation = WROpSend;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
workRequest.DSList = pDgrmPrivate->DsList;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
// zero out the options
|
|
Packit |
857059 |
workRequest.Req.SendUD.Options.AsUINT16 = 0;
|
|
Packit |
857059 |
workRequest.Req.SendUD.Options.s.SignaledCompletion = TRUE;
|
|
Packit |
857059 |
#if INCLUDE_16B
|
|
Packit |
857059 |
workRequest.Req.SendUD.Options.s.SendFMH = 0;
|
|
Packit |
857059 |
#endif
|
|
Packit |
857059 |
|
|
Packit |
857059 |
// Fill in user settings
|
|
Packit |
857059 |
workRequest.Req.SendUD.QPNumber = pDgrmPrivate->DgrmElement.RemoteQP;
|
|
Packit |
857059 |
// TBD check uses, may be safe to enable this line now
|
|
Packit |
857059 |
//workRequest.Req.SendUD.Qkey = pDgrmPrivate->DgrmElement.RemoteQKey;
|
|
Packit |
857059 |
workRequest.Req.SendUD.Qkey = QP1_WELL_KNOWN_Q_KEY;
|
|
Packit |
857059 |
workRequest.Req.SendUD.PkeyIndex= pDgrmPrivate->DgrmElement.PkeyIndex;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
#if defined(DBG) || defined(IB_DEBUG)
|
|
Packit |
857059 |
if (ServiceClass && !workRequest.Req.SendUD.QPNumber)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
AtomicIncrement( &ServiceClass->ErrorMsgs );
|
|
Packit |
857059 |
|
|
Packit |
857059 |
if (!(AtomicRead(&ServiceClass->ErrorMsgs) % 20))
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
_DBG_ERROR((
|
|
Packit |
857059 |
"Invalid QPNumber/Q_Key(substitution provided):\n"
|
|
Packit |
857059 |
"\tClass..........:x%x\n"
|
|
Packit |
857059 |
"\tSARClient......:%s\n"
|
|
Packit |
857059 |
"\tQPNumber.......:x%x\n"
|
|
Packit |
857059 |
"\tQ_Key..........:x%x\n",
|
|
Packit |
857059 |
ServiceClass->MgmtClass,
|
|
Packit |
857059 |
_DBG_PTR(ServiceClass->bSARRequired ? "TRUE":"FALSE"),
|
|
Packit |
857059 |
workRequest.Req.SendUD.QPNumber,
|
|
Packit |
857059 |
workRequest.Req.SendUD.Qkey
|
|
Packit |
857059 |
));
|
|
Packit |
857059 |
|
|
Packit |
857059 |
_DBG_ERROR((
|
|
Packit |
857059 |
"\tResponder......:%s\n"
|
|
Packit |
857059 |
"\tTrapProcessor..:%s\n"
|
|
Packit |
857059 |
"\tReportProcessor:%s\n",
|
|
Packit |
857059 |
_DBG_PTR(GSI_IS_RESPONDER(ServiceClass->RegistrationFlags)
|
|
Packit |
857059 |
? "TRUE":"FALSE"),
|
|
Packit |
857059 |
_DBG_PTR(GSI_IS_TRAP_PROCESSOR(ServiceClass->RegistrationFlags)
|
|
Packit |
857059 |
? "TRUE":"FALSE"),
|
|
Packit |
857059 |
_DBG_PTR(GSI_IS_REPORT_PROCESSOR(ServiceClass->RegistrationFlags)
|
|
Packit |
857059 |
? "TRUE":"FALSE")
|
|
Packit |
857059 |
));
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
workRequest.Req.SendUD.Qkey = QP1_WELL_KNOWN_Q_KEY;
|
|
Packit |
857059 |
workRequest.Req.SendUD.QPNumber = 1;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
ASSERT(workRequest.Req.SendUD.QPNumber);
|
|
Packit |
857059 |
|
|
Packit |
857059 |
if (workRequest.Req.SendUD.QPNumber != 1)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
_DBG_WARN((
|
|
Packit |
857059 |
"Send to RedirectedQP\n"
|
|
Packit |
857059 |
"\tQPNumber.....:x%x\n",
|
|
Packit |
857059 |
workRequest.Req.SendUD.QPNumber
|
|
Packit |
857059 |
));
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
#endif
|
|
Packit |
857059 |
// Fill in Address Vector Info
|
|
Packit |
857059 |
avInfo.PortGUID = pDgrmPrivate->DgrmElement.PortGuid;
|
|
Packit |
857059 |
avInfo.DestLID = pDgrmPrivate->DgrmElement.RemoteLID;
|
|
Packit |
857059 |
avInfo.PathBits = pDgrmPrivate->DgrmElement.PathBits;
|
|
Packit |
857059 |
avInfo.ServiceLevel = pDgrmPrivate->DgrmElement.ServiceLevel;
|
|
Packit |
857059 |
avInfo.StaticRate = pDgrmPrivate->DgrmElement.StaticRate;
|
|
Packit |
857059 |
avInfo.GlobalRoute = pDgrmPrivate->DgrmElement.GlobalRoute;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
if ( TRUE == avInfo.GlobalRoute )
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
/* structure copy */
|
|
Packit |
857059 |
avInfo.GlobalRouteInfo = pDgrmPrivate->DgrmElement.GRHInfo;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
status = GetCaContextFromAvInfo(
|
|
Packit |
857059 |
&avInfo,
|
|
Packit |
857059 |
pDgrmPrivate->MemPoolHandle->MemList->CaMemIndex,
|
|
Packit |
857059 |
&workRequest.Req.SendUD.AVHandle,
|
|
Packit |
857059 |
&qp1Handle,
|
|
Packit |
857059 |
&cqHandle,
|
|
Packit |
857059 |
&qpLock,
|
|
Packit |
857059 |
&memLKey );
|
|
Packit |
857059 |
|
|
Packit |
857059 |
if ( FSUCCESS == status )
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
pDgrmPrivate->AvHandle = workRequest.Req.SendUD.AVHandle;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
// fill in scatter/gather Ds list details
|
|
Packit |
857059 |
if (! ServiceClass)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
// Rmpp replies and GSI internal replies
|
|
Packit |
857059 |
IB_LOCAL_DATASEGMENT *pDsList = workRequest.DSList;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
ASSERT( pDgrmPrivate->MemPoolHandle->ReceivePool);
|
|
Packit |
857059 |
pMad = GsiDgrmGetRecvMad(&pDgrmPrivate->DgrmElement);
|
|
Packit |
857059 |
workRequest.DSListDepth = 1;
|
|
Packit |
857059 |
pDsList[0].Address = (uintn)pMad;
|
|
Packit |
857059 |
pDsList[0].Lkey = memLKey;
|
|
Packit |
857059 |
pDsList[0].Length =
|
|
Packit |
857059 |
GsiDgrmGetRecvMadByteCount(&pDgrmPrivate->DgrmElement);
|
|
Packit |
857059 |
workRequest.MessageLen =
|
|
Packit |
857059 |
GsiDgrmGetRecvMadByteCount(&pDgrmPrivate->DgrmElement);
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
else if ( TRUE != ServiceClass->bSARRequired )
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
// Direct sends from other callers
|
|
Packit |
857059 |
IBT_BUFFER *pBuffer;
|
|
Packit |
857059 |
IB_LOCAL_DATASEGMENT *pDsList = workRequest.DSList;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
pBuffer = pDgrmPrivate->DgrmElement.Element.pBufferList;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
workRequest.DSListDepth = \
|
|
Packit |
857059 |
pDgrmPrivate->MemPoolHandle->BuffersPerElement;
|
|
Packit |
857059 |
workRequest.MessageLen = 0;
|
|
Packit |
857059 |
for (i=0; i
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
pDsList[i].Address = (uintn)pBuffer->pData;
|
|
Packit |
857059 |
pDsList[i].Lkey = memLKey;
|
|
Packit |
857059 |
pDsList[i].Length = pBuffer->ByteCount;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
workRequest.MessageLen += pBuffer->ByteCount;
|
|
Packit |
857059 |
pBuffer = pBuffer->pNextBuffer;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
// Validate that buffers per element are sizeof MAD for non
|
|
Packit |
857059 |
// SAR clients
|
|
Packit |
857059 |
if ( workRequest.MessageLen > sizeof(MAD) )
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
_DBG_ERROR((
|
|
Packit |
857059 |
"Bad Non SAR Client posted buffer > sizeof(MAD)!\n"));
|
|
Packit |
857059 |
_DBG_BREAK;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
pMad = GsiDgrmGetSendMad(&pDgrmPrivate->DgrmElement);
|
|
Packit |
857059 |
} else {
|
|
Packit |
857059 |
// invoked for single packet GSI SAR send
|
|
Packit |
857059 |
// SAR will Always be 3: MAD_COMMON, SAR_HDR, DATA
|
|
Packit |
857059 |
IBT_BUFFER *pBuffer;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
pBuffer = pDgrmPrivate->DgrmElement.Element.pBufferList;
|
|
Packit |
857059 |
workRequest.DSListDepth = 3;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
// Fill in MAD Common info
|
|
Packit |
857059 |
workRequest.DSList[0].Address = (uintn)pBuffer->pData;
|
|
Packit |
857059 |
workRequest.DSList[0].Lkey = memLKey;
|
|
Packit |
857059 |
workRequest.DSList[0].Length = sizeof(MAD_COMMON);
|
|
Packit |
857059 |
|
|
Packit |
857059 |
// Fill in SAR Header info
|
|
Packit |
857059 |
workRequest.DSList[1].Address = \
|
|
Packit |
857059 |
(uintn)(pBuffer->pData) + sizeof(MAD_COMMON);
|
|
Packit |
857059 |
workRequest.DSList[1].Lkey = memLKey;
|
|
Packit |
857059 |
workRequest.DSList[1].Length = sizeof(RMPP_HEADER);
|
|
Packit |
857059 |
|
|
Packit |
857059 |
// Fill in Data info
|
|
Packit |
857059 |
workRequest.DSList[2].Address = \
|
|
Packit |
857059 |
(uintn)(pBuffer->pData) + \
|
|
Packit |
857059 |
sizeof(MAD_COMMON) +
|
|
Packit |
857059 |
sizeof(RMPP_HEADER);
|
|
Packit |
857059 |
workRequest.DSList[2].Lkey = memLKey;
|
|
Packit |
857059 |
workRequest.DSList[2].Length = pBuffer->ByteCount -
|
|
Packit |
857059 |
(sizeof(MAD_COMMON) + sizeof(RMPP_HEADER));
|
|
Packit |
857059 |
|
|
Packit |
857059 |
workRequest.MessageLen = pBuffer->ByteCount;
|
|
Packit |
857059 |
pMad = GsiDgrmGetSendMad(&pDgrmPrivate->DgrmElement);
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
// Set Transaction ID
|
|
Packit |
857059 |
|
|
Packit |
857059 |
// If this is a request, save the user's transaction id
|
|
Packit |
857059 |
// and use our own. We will restore the user's transaction id
|
|
Packit |
857059 |
// when the request completes. If this is not a request,
|
|
Packit |
857059 |
// we let the client control the transaction id which may have
|
|
Packit |
857059 |
// been remotely generated.
|
|
Packit |
857059 |
if( ServiceClass && MAD_IS_REQUEST(pMad))
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
// We need to save the TID in case we receive the
|
|
Packit |
857059 |
// response before being notified that the send completed.
|
|
Packit |
857059 |
pDgrmPrivate->SavedSendTid = pMad->common.TransactionID;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
pMad->common.TransactionID = (uint64)\
|
|
Packit |
857059 |
(pMad->common.TransactionID & 0xffffffffffffff00ll);
|
|
Packit |
857059 |
pMad->common.TransactionID = \
|
|
Packit |
857059 |
pMad->common.TransactionID | ServiceClass->ClientId;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
// Make headers Network Byte order
|
|
Packit |
857059 |
BSWAP_MAD_HEADER(pMad);
|
|
Packit |
857059 |
if( (ServiceClass && ServiceClass->bSARRequired) )
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
BSWAP_RMPP_HEADER (
|
|
Packit |
857059 |
(RMPP_HEADER *)((uintn)workRequest.DSList[1].Address) );
|
|
Packit |
857059 |
} else if( pPostList->SARRequest) {
|
|
Packit |
857059 |
// only applies to Rmpp Reply and Gsi reply
|
|
Packit |
857059 |
ASSERT(workRequest.DSListDepth == 1);
|
|
Packit |
857059 |
BSWAP_RMPP_HEADER (
|
|
Packit |
857059 |
(RMPP_HEADER *)&(((MAD_RMPP*)pMad)->RmppHdr));
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
#if defined(DBG) || defined(IB_DEBUG)
|
|
Packit |
857059 |
if (__DBG_LEVEL__ & _DBG_LVL_PKTDUMP)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
uint32 Length = workRequest.MessageLen;
|
|
Packit |
857059 |
IB_LOCAL_DATASEGMENT *Current = &workRequest.DSList[0];
|
|
Packit |
857059 |
for (i = 0; i < workRequest.DSListDepth; i++,Current++)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
_DBG_DUMP_MEMORY(_DBG_LVL_PKTDUMP, ("Send Packet"), (void *)(uintn)Current->Address,
|
|
Packit |
857059 |
MIN(Current->Length,Length));
|
|
Packit |
857059 |
Length -= MIN(Current->Length,Length);;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
#endif
|
|
Packit |
857059 |
|
|
Packit |
857059 |
// Submit to verbs
|
|
Packit |
857059 |
pDgrmPrivate->DgrmElement.OnSendQ = TRUE;
|
|
Packit |
857059 |
SpinLockAcquire( qpLock );
|
|
Packit |
857059 |
status = iba_post_send( qp1Handle, &workRequest );
|
|
Packit |
857059 |
SpinLockRelease( qpLock );
|
|
Packit |
857059 |
|
|
Packit |
857059 |
if ( FSUCCESS != status )
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
pDgrmPrivate->DgrmElement.OnSendQ = FALSE;
|
|
Packit |
857059 |
// restore headers to host Byte order
|
|
Packit |
857059 |
BSWAP_MAD_HEADER(pMad);
|
|
Packit |
857059 |
if( (ServiceClass && ServiceClass->bSARRequired) )
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
BSWAP_RMPP_HEADER (
|
|
Packit |
857059 |
(RMPP_HEADER *)((uintn)workRequest.DSList[1].Address) );
|
|
Packit |
857059 |
} else if( pPostList->SARRequest) {
|
|
Packit |
857059 |
// only applies to Rmpp Reply and Gsi reply
|
|
Packit |
857059 |
ASSERT(workRequest.DSListDepth == 1);
|
|
Packit |
857059 |
BSWAP_RMPP_HEADER (
|
|
Packit |
857059 |
(RMPP_HEADER *)&(((MAD_RMPP*)pMad)->RmppHdr));
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
// release AV
|
|
Packit |
857059 |
(void)PutAV(NULL,pDgrmPrivate->AvHandle);
|
|
Packit |
857059 |
pDgrmPrivate->DgrmElement.Element.Status = status;
|
|
Packit |
857059 |
AtomicIncrementVoid( &pPostList->DgrmOut );
|
|
Packit |
857059 |
dgrmFailed++;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
} else {
|
|
Packit |
857059 |
pDgrmPrivate->DgrmElement.Element.Status = status;
|
|
Packit |
857059 |
AtomicIncrementVoid( &pPostList->DgrmOut );
|
|
Packit |
857059 |
dgrmFailed++;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
pDgrmPrivate = pDgrmPrivateNext;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
// If all requests failed, fail the call and pass it back to user.
|
|
Packit |
857059 |
// There is no way of passing all failed entries through the callback
|
|
Packit |
857059 |
if ( pPostList->DgrmIn && dgrmFailed == pPostList->DgrmIn )
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
status = FINVALID_STATE;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
_DBG_LEAVE_LVL(_DBG_LVL_SEND);
|
|
Packit |
857059 |
return status;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
// uses pDgrm as a template for building an GET_RESP reply
|
|
Packit |
857059 |
// reporting a Invalid Class Version status
|
|
Packit |
857059 |
// MAD header and AV information is taken from pDgrm
|
|
Packit |
857059 |
// pDgrm is unaffected, assumes pDgrm is in Host byte order for
|
|
Packit |
857059 |
// MAD header and network byte order for rest of packet
|
|
Packit |
857059 |
void GsiSendInvalid(
|
|
Packit |
857059 |
IN IBT_DGRM_ELEMENT *pDgrm
|
|
Packit |
857059 |
)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
FSTATUS status = FSUCCESS;
|
|
Packit |
857059 |
uint32 i;
|
|
Packit |
857059 |
IBT_DGRM_ELEMENT *pDgrmList;
|
|
Packit |
857059 |
GSA_POST_SEND_LIST *pPostList;
|
|
Packit |
857059 |
MAD *pMad;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
_DBG_ENTER_LVL(_DBG_LVL_SEND, GsiSendInvalid);
|
|
Packit |
857059 |
|
|
Packit |
857059 |
i = 1;
|
|
Packit |
857059 |
status = DgrmPoolGet( g_GsaGlobalInfo->DgrmPoolRecvQ, &i, &pDgrmList );
|
|
Packit |
857059 |
if (FSUCCESS != status || i != 1)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
_DBG_ERROR(("GsiSendInvalid: No more elements in Pool!!!\n"));
|
|
Packit |
857059 |
goto done;
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
ASSERT(NULL != pDgrmList);
|
|
Packit |
857059 |
|
|
Packit |
857059 |
// we are using a Recv Pool Dgrm
|
|
Packit |
857059 |
pMad = GsiDgrmGetRecvMad(pDgrmList);
|
|
Packit |
857059 |
|
|
Packit |
857059 |
// Copy MAD Headers from template
|
|
Packit |
857059 |
MemoryCopy( pMad, GsiDgrmGetRecvMad(pDgrm), sizeof(MAD) );
|
|
Packit |
857059 |
|
|
Packit |
857059 |
pMad->common.mr.AsReg8 = MMTHD_GET_RESP;
|
|
Packit |
857059 |
pMad->common.u.NS.Status.AsReg16 = MAD_STATUS_UNSUPPORTED_CLASS_VER;
|
|
Packit |
857059 |
pMad->common.u.NS.Reserved1 = 0;
|
|
Packit |
857059 |
_DBG_INFO(("Invalid MAD: class %u\n", pMad->common.MgmtClass));
|
|
Packit |
857059 |
// GsiDoSendDgrm will BSWAP_MAD_HEADER
|
|
Packit |
857059 |
|
|
Packit |
857059 |
// Set remote info
|
|
Packit |
857059 |
GsiDgrmAddrCopy(pDgrmList, pDgrm);
|
|
Packit |
857059 |
|
|
Packit |
857059 |
// generate a PostSendList from the first datagram in post
|
|
Packit |
857059 |
pPostList = &(((IBT_DGRM_ELEMENT_PRIV *)pDgrmList)->PostSendList);
|
|
Packit |
857059 |
|
|
Packit |
857059 |
// Fill in list details
|
|
Packit |
857059 |
pPostList->DgrmIn = 1;
|
|
Packit |
857059 |
AtomicWrite(&pPostList->DgrmOut, 0);
|
|
Packit |
857059 |
pPostList->DgrmList = pDgrmList;
|
|
Packit |
857059 |
pPostList->SARRequest = FALSE;
|
|
Packit |
857059 |
|
|
Packit |
857059 |
status = GsiDoSendDgrm( NULL, pPostList);
|
|
Packit |
857059 |
if (status != FSUCCESS)
|
|
Packit |
857059 |
{
|
|
Packit |
857059 |
// release AV
|
|
Packit |
857059 |
DgrmPoolPut( pDgrmList );
|
|
Packit |
857059 |
}
|
|
Packit |
857059 |
|
|
Packit |
857059 |
done:
|
|
Packit |
857059 |
_DBG_LEAVE_LVL(_DBG_LVL_SEND);
|
|
Packit |
857059 |
}
|