/* stop HTC communications, i.e. stop interrupt reception, and flush all queued buffers */ void HTCStop(HTC_HANDLE HTCHandle) { HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); int i; HTC_ENDPOINT *pEndpoint; #ifdef RX_SG_SUPPORT adf_nbuf_t netbuf; adf_nbuf_queue_t *rx_sg_queue = &target->RxSgQueue; #endif AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+HTCStop \n")); /* cleanup endpoints */ for (i = 0; i < ENDPOINT_MAX; i++) { pEndpoint = &target->EndPoint[i]; HTCFlushRxHoldQueue(target,pEndpoint); HTCFlushEndpointTX(target,pEndpoint,HTC_TX_PACKET_TAG_ALL); } /* Note: HTCFlushEndpointTX for all endpoints should be called before * HIFStop - otherwise HTCTxCompletionHandler called from * hif_send_buffer_cleanup_on_pipe for residual tx frames in HIF layer, * might queue the packet again to HIF Layer - which could cause tx * buffer leak */ HIFStop(target->hif_dev); #ifdef RX_SG_SUPPORT LOCK_HTC_RX(target); while ((netbuf = adf_nbuf_queue_remove(rx_sg_queue)) != NULL) { adf_nbuf_free(netbuf); } RESET_RX_SG_CONFIG(target); UNLOCK_HTC_RX(target); #endif ResetEndpointStates(target); AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-HTCStop \n")); }
/* stop HTC communications, i.e. stop interrupt reception, and flush all queued buffers */ void HTCStop(HTC_HANDLE HTCHandle) { HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+HTCStop \n")); /* mark that we are shutting down .. */ target->HTCStateFlags |= HTC_STATE_STOPPING; /* Masking interrupts is a synchronous operation, when this function returns * all pending HIF I/O has completed, we can safely flush the queues */ DevMaskInterrupts(&target->Device); /* flush all send packets */ HTCFlushSendPkts(target); /* flush all recv buffers */ HTCFlushRecvBuffers(target); ResetEndpointStates(target); AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-HTCStop \n")); }
/* registered target arrival callback from the HIF layer */ HTC_HANDLE HTCCreate(void *hHIF, HTC_INIT_INFO *pInfo, adf_os_device_t osdev) { MSG_BASED_HIF_CALLBACKS htcCallbacks; HTC_ENDPOINT *pEndpoint=NULL; HTC_TARGET *target = NULL; int i; AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("+HTCCreate .. HIF :%p \n",hHIF)); A_REGISTER_MODULE_DEBUG_INFO(htc); if ((target = (HTC_TARGET *)A_MALLOC(sizeof(HTC_TARGET))) == NULL) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HTC : Unable to allocate memory\n")); return NULL; } A_MEMZERO(target, sizeof(HTC_TARGET)); adf_os_spinlock_init(&target->HTCLock); adf_os_spinlock_init(&target->HTCRxLock); adf_os_spinlock_init(&target->HTCTxLock); do { A_MEMCPY(&target->HTCInitInfo,pInfo,sizeof(HTC_INIT_INFO)); target->host_handle = pInfo->pContext; target->osdev = osdev; ResetEndpointStates(target); INIT_HTC_PACKET_QUEUE(&target->ControlBufferTXFreeList); for (i = 0; i < HTC_PACKET_CONTAINER_ALLOCATION; i++) { HTC_PACKET *pPacket = (HTC_PACKET *)A_MALLOC(sizeof(HTC_PACKET)); if (pPacket != NULL) { A_MEMZERO(pPacket,sizeof(HTC_PACKET)); FreeHTCPacketContainer(target,pPacket); } } #ifdef TODO_FIXME for (i = 0; i < NUM_CONTROL_TX_BUFFERS; i++) { pPacket = BuildHTCTxCtrlPacket(); if (NULL == pPacket) { break; } HTCFreeControlTxPacket(target,pPacket); } #endif /* setup HIF layer callbacks */ A_MEMZERO(&htcCallbacks, sizeof(MSG_BASED_HIF_CALLBACKS)); htcCallbacks.Context = target; htcCallbacks.rxCompletionHandler = HTCRxCompletionHandler; htcCallbacks.txCompletionHandler = HTCTxCompletionHandler; htcCallbacks.txResourceAvailHandler = HTCTxResourceAvailHandler; htcCallbacks.fwEventHandler = HTCFwEventHandler; target->hif_dev = hHIF; /* Get HIF default pipe for HTC message exchange */ pEndpoint = &target->EndPoint[ENDPOINT_0]; HIFPostInit(hHIF, target, &htcCallbacks); HIFGetDefaultPipe(hHIF, &pEndpoint->UL_PipeID, &pEndpoint->DL_PipeID); } while (FALSE); HTCRecvInit(target); AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("-HTCCreate (0x%p) \n", target)); return (HTC_HANDLE)target; }