v_VOID_t vos_mem_free( v_VOID_t *ptr ) { unsigned long IrqFlags; if (ptr != NULL) { VOS_STATUS vosStatus; struct s_vos_mem_struct* memStruct = ((struct s_vos_mem_struct*)ptr) - 1; #ifdef CONFIG_WCNSS_MEM_PRE_ALLOC if (wcnss_prealloc_put(ptr)) return; #endif spin_lock_irqsave(&vosMemList.lock, IrqFlags); vosStatus = hdd_list_remove_node(&vosMemList, &memStruct->pNode); free_trace_usage(memStruct->fileName, memStruct->lineNum, memStruct->size); spin_unlock_irqrestore(&vosMemList.lock, IrqFlags); if(VOS_STATUS_SUCCESS == vosStatus) { if(0 == vos_mem_compare(memStruct->header, &WLAN_MEM_HEADER[0], sizeof(WLAN_MEM_HEADER)) ) { VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, "Memory Header is corrupted. MemInfo: Filename %s, LineNum %d", memStruct->fileName, (int)memStruct->lineNum); VOS_BUG(0); } if(0 == vos_mem_compare( (v_U8_t*)ptr + memStruct->size, &WLAN_MEM_TAIL[0], sizeof(WLAN_MEM_TAIL ) ) ) { VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, "Memory Trailer is corrupted. MemInfo: Filename %s, LineNum %d", memStruct->fileName, (int)memStruct->lineNum); VOS_BUG(0); } kfree((v_VOID_t*)memStruct); } else { VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, "%s: Unallocated memory (double free?)", __func__); VOS_BUG(0); } } }
/* polling routine to wait for a control packet to be received */ A_STATUS HTCWaitRecvCtrlMessage(HTC_TARGET *target) { // int count = HTC_TARGET_MAX_RESPONSE_POLL; AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("+HTCWaitCtrlMessageRecv\n")); adf_os_re_init_completion(target->CtrlResponseValid); /* Wait for BMI request/response transaction to complete */ if(!adf_os_wait_for_completion_timeout(&target->CtrlResponseValid, adf_os_msecs_to_ticks(HTC_CONTROL_RX_TIMEOUT))) { /* Reset the target by invoking power off and power on sequence to * the card to bring back into active state. */ if(hif_reset_target(target->hif_dev)) VOS_BUG(0); return A_ERROR; } AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("-HTCWaitCtrlMessageRecv success\n")); return A_OK; }
VOS_STATUS vos_start( v_CONTEXT_t vosContext ) { VOS_STATUS vStatus = VOS_STATUS_SUCCESS; tSirRetStatus sirStatus = eSIR_SUCCESS; pVosContextType pVosContext = (pVosContextType)vosContext; tHalMacStartParameters halStartParams; VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, "%s: Starting Libra SW", __func__); if (gpVosContext != pVosContext) { VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: mismatch in context", __func__); return VOS_STATUS_E_FAILURE; } if (( pVosContext->pWDAContext == NULL) || ( pVosContext->pMACContext == NULL) || ( pVosContext->pTLContext == NULL)) { if (pVosContext->pWDAContext == NULL) VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: WDA NULL context", __func__); else if (pVosContext->pMACContext == NULL) VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: MAC NULL context", __func__); else VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: TL NULL context", __func__); return VOS_STATUS_E_FAILURE; } vos_event_reset( &(gpVosContext->wdaCompleteEvent) ); vStatus = WDA_NVDownload_Start(pVosContext); if ( vStatus != VOS_STATUS_SUCCESS ) { VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: Failed to start NV Download", __func__); return VOS_STATUS_E_FAILURE; } vStatus = vos_wait_single_event( &(gpVosContext->wdaCompleteEvent), VOS_WDA_TIMEOUT ); if ( vStatus != VOS_STATUS_SUCCESS ) { if ( vStatus == VOS_STATUS_E_TIMEOUT ) { VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: Timeout occurred before WDA_NVDownload_start complete", __func__); } else { VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: WDA_NVDownload_start reporting other error", __func__); } VOS_ASSERT(0); vos_event_reset( &(gpVosContext->wdaCompleteEvent) ); if (vos_is_logp_in_progress(VOS_MODULE_ID_VOSS, NULL)) { VOS_BUG(0); } WDA_setNeedShutdown(vosContext); return VOS_STATUS_E_FAILURE; } VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, "%s: WDA_NVDownload_start correctly started", __func__); vStatus = WDA_start(pVosContext); if ( vStatus != VOS_STATUS_SUCCESS ) { VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: Failed to start WDA", __func__); return VOS_STATUS_E_FAILURE; } VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, "%s: WDA correctly started", __func__); vos_mem_zero((v_PVOID_t)&halStartParams, sizeof(tHalMacStartParameters)); sirStatus = macStart(pVosContext->pMACContext,(v_PVOID_t)&halStartParams); if (eSIR_SUCCESS != sirStatus) { VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, "%s: Failed to start MAC", __func__); goto err_wda_stop; } VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, "%s: MAC correctly started", __func__); vStatus = sme_Start(pVosContext->pMACContext); if (!VOS_IS_STATUS_SUCCESS(vStatus)) { VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, "%s: Failed to start SME", __func__); goto err_mac_stop; } VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, "%s: SME correctly started", __func__); vStatus = WLANTL_Start(pVosContext); if (!VOS_IS_STATUS_SUCCESS(vStatus)) { VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, "%s: Failed to start TL", __func__); goto err_sme_stop; } VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, "TL correctly started"); VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, "%s: VOSS Start is successful!!", __func__); return VOS_STATUS_SUCCESS; err_sme_stop: sme_Stop(pVosContext->pMACContext, HAL_STOP_TYPE_SYS_RESET); err_mac_stop: macStop( pVosContext->pMACContext, HAL_STOP_TYPE_SYS_RESET ); err_wda_stop: vos_event_reset( &(gpVosContext->wdaCompleteEvent) ); vStatus = WDA_stop( pVosContext, HAL_STOP_TYPE_RF_KILL); if (!VOS_IS_STATUS_SUCCESS(vStatus)) { VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: Failed to stop WDA", __func__); VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vStatus ) ); WDA_setNeedShutdown(vosContext); } else { vStatus = vos_wait_single_event( &(gpVosContext->wdaCompleteEvent), VOS_WDA_TIMEOUT ); if( vStatus != VOS_STATUS_SUCCESS ) { if( vStatus == VOS_STATUS_E_TIMEOUT ) { VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, "%s: Timeout occurred before WDA_stop complete", __func__); } else { VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, "%s: WDA_stop reporting other error", __func__); } VOS_ASSERT( 0 ); WDA_setNeedShutdown(vosContext); } } return VOS_STATUS_E_FAILURE; }
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); 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; VOS_BUG(0); break; } pEndpoint = &target->EndPoint[htc_ep_id]; /* * 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 =%zu\n", netlen, payloadLen + HTC_HDR_LENGTH)); DebugDumpBytes((A_UINT8 *)HtcHdr,sizeof(HTC_FRAME_HDR),"BAD RX packet length"); status = A_ERROR; VOS_BUG(0); 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, ("HTCRxCompletionHandler, 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; int wow_nack = 0; /* 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; VOS_BUG(FALSE); break; } LOCK_HTC_RX(target); target->CtrlResponseLength = min((int)netlen,HTC_MAX_CONTROL_MESSAGE_LENGTH); A_MEMCPY(target->CtrlResponseBuffer,netdata,target->CtrlResponseLength); /* Requester will clear this flag */ target->CtrlResponseProcessing = TRUE; UNLOCK_HTC_RX(target); adf_os_complete(&target->CtrlResponseValid); break; case HTC_MSG_SEND_SUSPEND_COMPLETE: wow_nack = 0; LOCK_HTC_CREDIT(target); htc_credit_record(HTC_SUSPEND_ACK, pEndpoint->TxCredits, HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue)); UNLOCK_HTC_CREDIT(target); target->HTCInitInfo.TargetSendSuspendComplete((void *)&wow_nack); HTCsuspendwow(target); break; case HTC_MSG_NACK_SUSPEND: wow_nack = 1; LOCK_HTC_CREDIT(target); htc_credit_record(HTC_SUSPEND_NACK, pEndpoint->TxCredits, HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue)); UNLOCK_HTC_CREDIT(target); target->HTCInitInfo.TargetSendSuspendComplete((void *)&wow_nack); 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; adf_nbuf_pull_head(netbuf, HTC_HEADER_LEN); adf_nbuf_set_pktlen(netbuf, pPacket->ActualLength); 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; }