static A_STATUS HTCProcessTrailer(HTC_TARGET *target, A_UINT8 *pBuffer, int Length, HTC_ENDPOINT_ID FromEndpoint) { HTC_RECORD_HDR *pRecord; A_UINT8 htc_rec_id; A_UINT8 htc_rec_len; A_UINT8 *pRecordBuf; A_UINT8 *pOrigBuffer; int origLength; A_STATUS status; AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("+HTCProcessTrailer (length:%d) \n", Length)); if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) { AR_DEBUG_PRINTBUF(pBuffer,Length,"Recv Trailer"); } pOrigBuffer = pBuffer; origLength = Length; status = A_OK; while (Length > 0) { if (Length < sizeof(HTC_RECORD_HDR)) { status = A_EPROTO; break; } /* these are byte aligned structs */ pRecord = (HTC_RECORD_HDR *)pBuffer; Length -= sizeof(HTC_RECORD_HDR); pBuffer += sizeof(HTC_RECORD_HDR); htc_rec_len = HTC_GET_FIELD(pRecord, HTC_RECORD_HDR, LENGTH); htc_rec_id = HTC_GET_FIELD(pRecord, HTC_RECORD_HDR, RECORDID); if (htc_rec_len > Length) { /* no room left in buffer for record */ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, (" invalid record length: %d (id:%d) buffer has: %d bytes left \n", htc_rec_len, htc_rec_id, Length)); status = A_EPROTO; break; } /* start of record follows the header */ pRecordBuf = pBuffer; switch (htc_rec_id) { case HTC_RECORD_CREDITS: AR_DEBUG_ASSERT(htc_rec_len >= sizeof(HTC_CREDIT_REPORT)); HTCProcessCreditRpt(target, (HTC_CREDIT_REPORT *)pRecordBuf, htc_rec_len / (sizeof(HTC_CREDIT_REPORT)), FromEndpoint); break; default: AR_DEBUG_PRINTF(ATH_DEBUG_ERR, (" unhandled record: id:%d length:%d \n", htc_rec_id, htc_rec_len)); break; } if (A_FAILED(status)) { break; } /* advance buffer past this record for next time around */ pBuffer += htc_rec_len; Length -= htc_rec_len; } if (A_FAILED(status)) { DebugDumpBytes(pOrigBuffer,origLength,"BAD Recv Trailer"); } AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("-HTCProcessTrailer \n")); return status; }
A_STATUS HTCRxCompletionHandler( void *Context, adf_nbuf_t netbuf, a_uint8_t pipeID) { A_STATUS status = A_OK; HTC_FRAME_HDR *HtcHdr; HTC_TARGET *target = (HTC_TARGET *)Context; a_uint8_t *netdata; a_uint32_t netlen; HTC_ENDPOINT *pEndpoint; HTC_PACKET *pPacket; A_UINT16 payloadLen; a_uint32_t trailerlen = 0; A_UINT8 htc_ep_id; #ifdef RX_SG_SUPPORT LOCK_HTC_RX(target); if (target->IsRxSgInprogress) { target->CurRxSgTotalLen += adf_nbuf_len(netbuf); adf_nbuf_queue_add(&target->RxSgQueue, netbuf); if (target->CurRxSgTotalLen == target->ExpRxSgTotalLen) { netbuf = RxSgToSingleNetbuf(target); if (netbuf == NULL) { UNLOCK_HTC_RX(target); goto _out; } } else { netbuf = NULL; UNLOCK_HTC_RX(target); goto _out; } } UNLOCK_HTC_RX(target); #endif netdata = adf_nbuf_data(netbuf); netlen = adf_nbuf_len(netbuf); HtcHdr = (HTC_FRAME_HDR *)netdata; do { htc_ep_id = HTC_GET_FIELD(HtcHdr, HTC_FRAME_HDR, ENDPOINTID); pEndpoint = &target->EndPoint[htc_ep_id]; if (htc_ep_id >= ENDPOINT_MAX) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HTC Rx: invalid EndpointID=%d\n",htc_ep_id)); DebugDumpBytes((A_UINT8 *)HtcHdr,sizeof(HTC_FRAME_HDR),"BAD HTC Header"); status = A_ERROR; break; } /* * If this endpoint that received a message from the target has * a to-target HIF pipe whose send completions are polled rather * than interrupt-driven, this is a good point to ask HIF to check * whether it has any completed sends to handle. */ if (pEndpoint->ul_is_polled) { HTCSendCompleteCheck(pEndpoint, 1); } payloadLen = HTC_GET_FIELD(HtcHdr, HTC_FRAME_HDR, PAYLOADLEN); if (netlen < (payloadLen + HTC_HDR_LENGTH)) { #ifdef RX_SG_SUPPORT LOCK_HTC_RX(target); target->IsRxSgInprogress = TRUE; adf_nbuf_queue_init(&target->RxSgQueue); adf_nbuf_queue_add(&target->RxSgQueue, netbuf); target->ExpRxSgTotalLen = (payloadLen + HTC_HDR_LENGTH); target->CurRxSgTotalLen += netlen; UNLOCK_HTC_RX(target); netbuf = NULL; break; #else AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HTC Rx: insufficient length, got:%d expected =%d\n", netlen, payloadLen + HTC_HDR_LENGTH)); DebugDumpBytes((A_UINT8 *)HtcHdr,sizeof(HTC_FRAME_HDR),"BAD RX packet length"); status = A_ERROR; break; #endif } #ifdef HTC_EP_STAT_PROFILING LOCK_HTC_RX(target); INC_HTC_EP_STAT(pEndpoint,RxReceived,1); UNLOCK_HTC_RX(target); #endif //if (IS_TX_CREDIT_FLOW_ENABLED(pEndpoint)) { { A_UINT8 temp; /* get flags to check for trailer */ temp = HTC_GET_FIELD(HtcHdr, HTC_FRAME_HDR, FLAGS); if (temp & HTC_FLAGS_RECV_TRAILER) { /* extract the trailer length */ temp = HTC_GET_FIELD(HtcHdr, HTC_FRAME_HDR, CONTROLBYTES0); if ((temp < sizeof(HTC_RECORD_HDR)) || (temp > payloadLen)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HTCProcessRecvHeader, invalid header (payloadlength should be :%d, CB[0] is:%d) \n", payloadLen, temp)); status = A_EPROTO; break; } trailerlen = temp; /* process trailer data that follows HDR + application payload */ status = HTCProcessTrailer(target, ((A_UINT8 *)HtcHdr + HTC_HDR_LENGTH + payloadLen - temp), temp, htc_ep_id); if (A_FAILED(status)) { break; } } } if (((int)payloadLen - (int)trailerlen) <= 0) { /* zero length packet with trailer data, just drop these */ break; } if (htc_ep_id == ENDPOINT_0) { A_UINT16 message_id; HTC_UNKNOWN_MSG *htc_msg; /* remove HTC header */ adf_nbuf_pull_head(netbuf, HTC_HDR_LENGTH); netdata = adf_nbuf_data(netbuf); netlen = adf_nbuf_len(netbuf); htc_msg = (HTC_UNKNOWN_MSG*)netdata; message_id = HTC_GET_FIELD(htc_msg, HTC_UNKNOWN_MSG, MESSAGEID); switch (message_id) { default: /* handle HTC control message */ if (target->CtrlResponseProcessing) { /* this is a fatal error, target should not be sending unsolicited messages * on the endpoint 0 */ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HTC Rx Ctrl still processing\n")); status = A_ERROR; break; } LOCK_HTC_RX(target); target->CtrlResponseLength = min((int)netlen,HTC_MAX_CONTROL_MESSAGE_LENGTH); A_MEMCPY(target->CtrlResponseBuffer,netdata,target->CtrlResponseLength); UNLOCK_HTC_RX(target); adf_os_mutex_release(target->osdev, &target->CtrlResponseValid); break; case HTC_MSG_SEND_SUSPEND_COMPLETE: target->HTCInitInfo.TargetSendSuspendComplete(target->HTCInitInfo.pContext); break; } adf_nbuf_free(netbuf); netbuf = NULL; break; } /* the current message based HIF architecture allocates net bufs for recv packets * since this layer bridges that HIF to upper layers , which expects HTC packets, * we form the packets here * TODO_FIXME */ pPacket = AllocateHTCPacketContainer(target); if (NULL == pPacket) { status = A_NO_RESOURCE; break; } pPacket->Status = A_OK; pPacket->Endpoint = htc_ep_id; pPacket->pPktContext = netbuf; pPacket->pBuffer = adf_nbuf_data(netbuf) + HTC_HDR_LENGTH; pPacket->ActualLength = netlen - HTC_HEADER_LEN - trailerlen; /* TODO : this is a hack because the driver layer will set the actual length * of the skb again which will just double the length */ //A_NETBUF_TRIM(netbuf,netlen); adf_nbuf_trim_tail(netbuf, netlen); RecvPacketCompletion(target,pEndpoint,pPacket); /* recover the packet container */ FreeHTCPacketContainer(target,pPacket); netbuf = NULL; } while(FALSE); #ifdef RX_SG_SUPPORT _out: #endif if (netbuf != NULL) { adf_nbuf_free(netbuf); } return status; }
A_STATUS htc_wait_target(HTC_HANDLE HTCHandle) { A_STATUS status = A_OK; HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); HTC_READY_EX_MSG *pReadyMsg; HTC_SERVICE_CONNECT_REQ connect; HTC_SERVICE_CONNECT_RESP resp; HTC_READY_MSG *rdy_msg; A_UINT16 htc_rdy_msg_id; AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("htc_wait_target - Enter (target:0x%p) \n", HTCHandle)); AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("+HWT\n")); do { status = hif_start(target->hif_dev); if (A_FAILED(status)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("hif_start failed\n")); break; } status = htc_wait_recv_ctrl_message(target); if (A_FAILED(status)) { break; } if (target->CtrlResponseLength < (sizeof(HTC_READY_EX_MSG))) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Invalid HTC Ready Msg Len:%d! \n", target->CtrlResponseLength)); status = A_ECOMM; break; } pReadyMsg = (HTC_READY_EX_MSG *) target->CtrlResponseBuffer; rdy_msg = &pReadyMsg->Version2_0_Info; htc_rdy_msg_id = HTC_GET_FIELD(rdy_msg, HTC_READY_MSG, MESSAGEID); if (htc_rdy_msg_id != HTC_MSG_READY_ID) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Invalid HTC Ready Msg : 0x%X ! \n", htc_rdy_msg_id)); status = A_ECOMM; break; } target->TotalTransmitCredits = HTC_GET_FIELD(rdy_msg, HTC_READY_MSG, CREDITCOUNT); target->TargetCreditSize = (int)HTC_GET_FIELD(rdy_msg, HTC_READY_MSG, CREDITSIZE); target->MaxMsgsPerHTCBundle = (A_UINT8) pReadyMsg->MaxMsgsPerHTCBundle; /* for old fw this value is set to 0. But the minimum value should be 1, * i.e., no bundling */ if (target->MaxMsgsPerHTCBundle < 1) target->MaxMsgsPerHTCBundle = 1; AR_DEBUG_PRINTF(ATH_DEBUG_INIT, ("Target Ready! : transmit resources : %d size:%d, MaxMsgsPerHTCBundle = %d\n", target->TotalTransmitCredits, target->TargetCreditSize, target->MaxMsgsPerHTCBundle)); if ((0 == target->TotalTransmitCredits) || (0 == target->TargetCreditSize)) { status = A_ECOMM; break; } /* done processing */ target->CtrlResponseProcessing = false; htc_setup_target_buffer_assignments(target); /* setup our pseudo HTC control endpoint connection */ A_MEMZERO(&connect, sizeof(connect)); A_MEMZERO(&resp, sizeof(resp)); connect.EpCallbacks.pContext = target; connect.EpCallbacks.EpTxComplete = htc_control_tx_complete; connect.EpCallbacks.EpRecv = htc_control_rx_complete; connect.MaxSendQueueDepth = NUM_CONTROL_TX_BUFFERS; connect.ServiceID = HTC_CTRL_RSVD_SVC; /* connect fake service */ status = htc_connect_service((HTC_HANDLE) target, &connect, &resp); } while (false); AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("htc_wait_target - Exit (%d)\n", status)); AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("-HWT\n")); return status; }
A_STATUS HTCWaitTarget(HTC_HANDLE HTCHandle) { A_STATUS status = A_OK; HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); HTC_READY_EX_MSG *pReadyMsg; HTC_SERVICE_CONNECT_REQ connect; HTC_SERVICE_CONNECT_RESP resp; HTC_READY_MSG *rdy_msg; A_UINT16 htc_rdy_msg_id; AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCWaitTarget - Enter (target:0x%p) \n", HTCHandle)); AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("+HWT\n")); do { status = HIFStart(target->hif_dev); if (A_FAILED(status)) { break; } status = HTCWaitRecvCtrlMessage(target); if (A_FAILED(status)) { break; } if (target->CtrlResponseLength < (sizeof(HTC_READY_EX_MSG))) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Invalid HTC Ready Msg Len:%d! \n",target->CtrlResponseLength)); status = A_ECOMM; break; } pReadyMsg = (HTC_READY_EX_MSG *)target->CtrlResponseBuffer; rdy_msg = &pReadyMsg->Version2_0_Info; htc_rdy_msg_id = HTC_GET_FIELD(rdy_msg, HTC_READY_MSG, MESSAGEID); if (htc_rdy_msg_id != HTC_MSG_READY_ID) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Invalid HTC Ready Msg : 0x%X ! \n",htc_rdy_msg_id)); status = A_ECOMM; break; } target->TotalTransmitCredits = HTC_GET_FIELD(rdy_msg, HTC_READY_MSG, CREDITCOUNT); target->TargetCreditSize = (int)HTC_GET_FIELD(rdy_msg, HTC_READY_MSG, CREDITSIZE); AR_DEBUG_PRINTF(ATH_DEBUG_INIT, ("Target Ready! : transmit resources : %d size:%d\n", target->TotalTransmitCredits, target->TargetCreditSize)); if ((0 == target->TotalTransmitCredits) || (0 == target->TargetCreditSize)) { status = A_ECOMM; break; } /* done processing */ target->CtrlResponseProcessing = FALSE; HTCSetupTargetBufferAssignments(target); /* setup our pseudo HTC control endpoint connection */ A_MEMZERO(&connect,sizeof(connect)); A_MEMZERO(&resp,sizeof(resp)); connect.EpCallbacks.pContext = target; connect.EpCallbacks.EpTxComplete = HTCControlTxComplete; connect.EpCallbacks.EpRecv = HTCControlRxComplete; connect.MaxSendQueueDepth = NUM_CONTROL_TX_BUFFERS; connect.ServiceID = HTC_CTRL_RSVD_SVC; /* connect fake service */ status = HTCConnectService((HTC_HANDLE)target, &connect, &resp); } while (FALSE); AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCWaitTarget - Exit (%d)\n",status)); AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("-HWT\n")); return status; }
A_STATUS HTCConnectService(HTC_HANDLE HTCHandle, HTC_SERVICE_CONNECT_REQ *pConnectReq, HTC_SERVICE_CONNECT_RESP *pConnectResp) { HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); A_STATUS status = A_OK; HTC_PACKET *pSendPacket = NULL; HTC_CONNECT_SERVICE_RESPONSE_MSG *pResponseMsg; HTC_CONNECT_SERVICE_MSG *pConnectMsg; HTC_ENDPOINT_ID assignedEndpoint = ENDPOINT_MAX; HTC_ENDPOINT *pEndpoint; unsigned int maxMsgSize = 0; adf_nbuf_t netbuf; A_UINT8 txAlloc; int length; A_BOOL disableCreditFlowCtrl = FALSE; A_UINT16 conn_flags; A_UINT16 rsp_msg_id, rsp_msg_serv_id, rsp_msg_max_msg_size; A_UINT8 rsp_msg_status, rsp_msg_end_id, rsp_msg_serv_meta_len; AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+HTCConnectService, target:%p SvcID:0x%X \n", target, pConnectReq->ServiceID)); do { AR_DEBUG_ASSERT(pConnectReq->ServiceID != 0); if (HTC_CTRL_RSVD_SVC == pConnectReq->ServiceID) { /* special case for pseudo control service */ assignedEndpoint = ENDPOINT_0; maxMsgSize = HTC_MAX_CONTROL_MESSAGE_LENGTH; txAlloc = 0; } else { txAlloc = HTCGetCreditAllocation(target,pConnectReq->ServiceID); if (!txAlloc) { AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("Service %d does not allocate target credits!\n", pConnectReq->ServiceID)); } /* allocate a packet to send to the target */ pSendPacket = HTCAllocControlTxPacket(target); if (NULL == pSendPacket) { AR_DEBUG_ASSERT(FALSE); status = A_NO_MEMORY; break; } netbuf = (adf_nbuf_t)GET_HTC_PACKET_NET_BUF_CONTEXT(pSendPacket); length = sizeof(HTC_CONNECT_SERVICE_MSG) + pConnectReq->MetaDataLength; /* assemble connect service message */ adf_nbuf_put_tail(netbuf, length); pConnectMsg = (HTC_CONNECT_SERVICE_MSG *)adf_nbuf_data(netbuf); AR_DEBUG_ASSERT(pConnectMsg != NULL); A_MEMZERO(pConnectMsg,sizeof(HTC_CONNECT_SERVICE_MSG)); conn_flags = (pConnectReq->ConnectionFlags & ~HTC_SET_RECV_ALLOC_MASK) | HTC_CONNECT_FLAGS_SET_RECV_ALLOCATION(txAlloc); HTC_SET_FIELD(pConnectMsg, HTC_CONNECT_SERVICE_MSG, MESSAGEID, HTC_MSG_CONNECT_SERVICE_ID); HTC_SET_FIELD(pConnectMsg, HTC_CONNECT_SERVICE_MSG, SERVICE_ID, pConnectReq->ServiceID); HTC_SET_FIELD(pConnectMsg, HTC_CONNECT_SERVICE_MSG, CONNECTIONFLAGS, conn_flags); if (pConnectReq->ConnectionFlags & HTC_CONNECT_FLAGS_DISABLE_CREDIT_FLOW_CTRL) { disableCreditFlowCtrl = TRUE; } /* * EV #134248 BUG Fix : Credit miss happens resulting in failure to create * VAP. Disable Credit for WMI endpoint too. */ if (!htc_credit_flow ) { disableCreditFlowCtrl = TRUE; } /* check caller if it wants to transfer meta data */ if ((pConnectReq->pMetaData != NULL) && (pConnectReq->MetaDataLength <= HTC_SERVICE_META_DATA_MAX_LENGTH)) { /* copy meta data into message buffer (after header ) */ A_MEMCPY((A_UINT8 *)pConnectMsg + sizeof(HTC_CONNECT_SERVICE_MSG), pConnectReq->pMetaData, pConnectReq->MetaDataLength); HTC_SET_FIELD(pConnectMsg, HTC_CONNECT_SERVICE_MSG, SERVICEMETALENGTH, pConnectReq->MetaDataLength); } SET_HTC_PACKET_INFO_TX(pSendPacket, NULL, (A_UINT8 *)pConnectMsg, length, ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG); status = HTCSendPkt((HTC_HANDLE)target,pSendPacket); /* we don't own it anymore */ pSendPacket = NULL; if (A_FAILED(status)) { break; } /* wait for response */ status = HTCWaitRecvCtrlMessage(target); if (A_FAILED(status)) { break; } /* we controlled the buffer creation so it has to be properly aligned */ pResponseMsg = (HTC_CONNECT_SERVICE_RESPONSE_MSG *)target->CtrlResponseBuffer; rsp_msg_id = HTC_GET_FIELD(pResponseMsg, HTC_CONNECT_SERVICE_RESPONSE_MSG, MESSAGEID); rsp_msg_serv_id = HTC_GET_FIELD(pResponseMsg, HTC_CONNECT_SERVICE_RESPONSE_MSG, SERVICEID); rsp_msg_status = HTC_GET_FIELD(pResponseMsg, HTC_CONNECT_SERVICE_RESPONSE_MSG, STATUS); rsp_msg_end_id = HTC_GET_FIELD(pResponseMsg, HTC_CONNECT_SERVICE_RESPONSE_MSG, ENDPOINTID); rsp_msg_max_msg_size = HTC_GET_FIELD(pResponseMsg, HTC_CONNECT_SERVICE_RESPONSE_MSG, MAXMSGSIZE); rsp_msg_serv_meta_len = HTC_GET_FIELD(pResponseMsg, HTC_CONNECT_SERVICE_RESPONSE_MSG, SERVICEMETALENGTH); if ((rsp_msg_id != HTC_MSG_CONNECT_SERVICE_RESPONSE_ID) || (target->CtrlResponseLength < sizeof(HTC_CONNECT_SERVICE_RESPONSE_MSG))) { /* this message is not valid */ AR_DEBUG_ASSERT(FALSE); status = A_EPROTO; break; } AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCConnectService, service 0x%X connect response from target status:%d, assigned ep: %d\n", rsp_msg_serv_id, rsp_msg_status, rsp_msg_end_id)); pConnectResp->ConnectRespCode = rsp_msg_status; /* check response status */ if (rsp_msg_status != HTC_SERVICE_SUCCESS) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, (" Target failed service 0x%X connect request (status:%d)\n", rsp_msg_serv_id, rsp_msg_status)); status = A_EPROTO; break; } assignedEndpoint = (HTC_ENDPOINT_ID)rsp_msg_end_id; maxMsgSize = rsp_msg_max_msg_size; if ((pConnectResp->pMetaData != NULL) && (rsp_msg_serv_meta_len > 0) && (rsp_msg_serv_meta_len <= HTC_SERVICE_META_DATA_MAX_LENGTH)) { /* caller supplied a buffer and the target responded with data */ int copyLength = min((int)pConnectResp->BufferLength, (int)rsp_msg_serv_meta_len); /* copy the meta data */ A_MEMCPY(pConnectResp->pMetaData, ((A_UINT8 *)pResponseMsg) + sizeof(HTC_CONNECT_SERVICE_RESPONSE_MSG), copyLength); pConnectResp->ActualLength = copyLength; } /* done processing response buffer */ target->CtrlResponseProcessing = FALSE; } /* the rest of these are parameter checks so set the error status */ status = A_EPROTO; if (assignedEndpoint >= ENDPOINT_MAX) { AR_DEBUG_ASSERT(FALSE); break; } if (0 == maxMsgSize) { AR_DEBUG_ASSERT(FALSE); break; } pEndpoint = &target->EndPoint[assignedEndpoint]; pEndpoint->Id = assignedEndpoint; if (pEndpoint->ServiceID != 0) { /* endpoint already in use! */ AR_DEBUG_ASSERT(FALSE); break; } /* return assigned endpoint to caller */ pConnectResp->Endpoint = assignedEndpoint; pConnectResp->MaxMsgLength = maxMsgSize; /* setup the endpoint */ pEndpoint->ServiceID = pConnectReq->ServiceID; /* this marks the endpoint in use */ pEndpoint->MaxTxQueueDepth = pConnectReq->MaxSendQueueDepth; pEndpoint->MaxMsgLength = maxMsgSize; pEndpoint->TxCredits = txAlloc; pEndpoint->TxCreditSize = target->TargetCreditSize; pEndpoint->TxCreditsPerMaxMsg = maxMsgSize / target->TargetCreditSize; if (maxMsgSize % target->TargetCreditSize) { pEndpoint->TxCreditsPerMaxMsg++; } /* copy all the callbacks */ pEndpoint->EpCallBacks = pConnectReq->EpCallbacks; status = HIFMapServiceToPipe(target->hif_dev, pEndpoint->ServiceID, &pEndpoint->UL_PipeID, &pEndpoint->DL_PipeID, &pEndpoint->ul_is_polled, &pEndpoint->dl_is_polled); if (A_FAILED(status)) { break; } adf_os_assert(!pEndpoint->dl_is_polled); /* not currently supported */ if (pEndpoint->ul_is_polled) { adf_os_timer_init( target->osdev, &pEndpoint->ul_poll_timer, HTCSendCompleteCheckCleanup, pEndpoint); } AR_DEBUG_PRINTF(ATH_DEBUG_SETUP, ("HTC Service:0x%4.4X, ULpipe:%d DLpipe:%d id:%d Ready\n", pEndpoint->ServiceID,pEndpoint->UL_PipeID,pEndpoint->DL_PipeID,pEndpoint->Id)); if (disableCreditFlowCtrl && pEndpoint->TxCreditFlowEnabled) { pEndpoint->TxCreditFlowEnabled = FALSE; AR_DEBUG_PRINTF(ATH_DEBUG_WARN,("HTC Service:0x%4.4X ep:%d TX flow control disabled\n", pEndpoint->ServiceID, assignedEndpoint)); } } while (FALSE); AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-HTCConnectService \n")); return status; }