int wmi_unified_connect_htc_service(struct wmi_unified * wmi_handle, void *htc_handle) { int status; HTC_SERVICE_CONNECT_RESP response; HTC_SERVICE_CONNECT_REQ connect; OS_MEMZERO(&connect, sizeof(connect)); OS_MEMZERO(&response, sizeof(response)); /* meta data is unused for now */ connect.pMetaData = NULL; connect.MetaDataLength = 0; /* these fields are the same for all service endpoints */ connect.EpCallbacks.pContext = wmi_handle; connect.EpCallbacks.EpTxCompleteMultiple = NULL /* Control path completion ar6000_tx_complete */; connect.EpCallbacks.EpRecv = wmi_control_rx /* Control path rx */; connect.EpCallbacks.EpRecvRefill = NULL /* ar6000_rx_refill */; connect.EpCallbacks.EpSendFull = NULL /* ar6000_tx_queue_full */; connect.EpCallbacks.EpTxComplete = wmi_htc_tx_complete /* ar6000_tx_queue_full */; /* connect to control service */ connect.ServiceID = WMI_CONTROL_SVC; if ((status = HTCConnectService(htc_handle, &connect, &response)) != EOK) { printk(" Failed to connect to WMI CONTROL service status:%d \n", status); return -1;; } wmi_handle->wmi_endpoint_id = response.Endpoint; wmi_handle->htc_handle = htc_handle; return EOK; }
int htt_htc_attach(struct htt_pdev_t *pdev) { HTC_SERVICE_CONNECT_REQ connect; HTC_SERVICE_CONNECT_RESP response; A_STATUS status; adf_os_mem_set(&connect, 0, sizeof(connect)); adf_os_mem_set(&response, 0, sizeof(response)); connect.pMetaData = NULL; connect.MetaDataLength = 0; connect.EpCallbacks.pContext = pdev; connect.EpCallbacks.EpTxComplete = htt_h2t_send_complete; connect.EpCallbacks.EpTxCompleteMultiple = NULL; connect.EpCallbacks.EpRecv = htt_t2h_msg_handler; /* rx buffers currently are provided by HIF, not by EpRecvRefill */ connect.EpCallbacks.EpRecvRefill = NULL; connect.EpCallbacks.RecvRefillWaterMark = 1; /* N/A, fill is done by HIF */ connect.EpCallbacks.EpSendFull = htt_h2t_full; /* * Specify how deep to let a queue get before HTCSendPkt will * call the EpSendFull function due to excessive send queue depth. */ connect.MaxSendQueueDepth = HTT_MAX_SEND_QUEUE_DEPTH; /* disable flow control for HTT data message service */ connect.ConnectionFlags |= HTC_CONNECT_FLAGS_DISABLE_CREDIT_FLOW_CTRL; /* connect to control service */ connect.ServiceID = HTT_DATA_MSG_SVC; status = HTCConnectService(pdev->htc_pdev, &connect, &response); if (status != A_OK) { return 1; /* failure */ } pdev->htc_endpoint = response.Endpoint; return 0; /* success */ }
static void ar6000_htc_raw_read_cb(void *Context, HTC_PACKET *pPacket) { AR_SOFTC_T *ar = (AR_SOFTC_T *)Context; raw_htc_buffer *busy; HTC_RAW_STREAM_ID streamID; AR_RAW_HTC_T *arRaw = ar->arRawHtc; busy = (raw_htc_buffer *)pPacket->pPktContext; A_ASSERT(busy != NULL); if (pPacket->Status == A_ECANCELED) { /* * HTC provides A_ECANCELED status when it doesn't want to be refilled * (probably due to a shutdown) */ return; } streamID = arEndpoint2RawStreamID(ar,pPacket->Endpoint); A_ASSERT(streamID != HTC_RAW_STREAM_NOT_MAPPED); if(streamID == HTC_RAW_STREAM_NOT_MAPPED) { return; /* in case panic_on_assert==0 */ } #ifdef CF if (down_trylock(&arRaw->raw_htc_read_sem[streamID])) { #else if (down_interruptible(&arRaw->raw_htc_read_sem[streamID])) { #endif /* CF */ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to down the semaphore\n")); } A_ASSERT((pPacket->Status != A_OK) || (pPacket->pBuffer == (busy->data + HTC_HEADER_LEN))); busy->length = pPacket->ActualLength + HTC_HEADER_LEN; busy->currPtr = HTC_HEADER_LEN; arRaw->read_buffer_available[streamID] = TRUE; //AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("raw read cb: 0x%X 0x%X \n", busy->currPtr,busy->length); up(&arRaw->raw_htc_read_sem[streamID]); /* Signal the waiting process */ AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("Waking up the StreamID(%d) read process\n", streamID)); wake_up_interruptible(&arRaw->raw_htc_read_queue[streamID]); } static void ar6000_htc_raw_write_cb(void *Context, HTC_PACKET *pPacket) { AR_SOFTC_T *ar = (AR_SOFTC_T *)Context; raw_htc_buffer *free; HTC_RAW_STREAM_ID streamID; AR_RAW_HTC_T *arRaw = ar->arRawHtc; free = (raw_htc_buffer *)pPacket->pPktContext; A_ASSERT(free != NULL); if (pPacket->Status == A_ECANCELED) { /* * HTC provides A_ECANCELED status when it doesn't want to be refilled * (probably due to a shutdown) */ return; } streamID = arEndpoint2RawStreamID(ar,pPacket->Endpoint); A_ASSERT(streamID != HTC_RAW_STREAM_NOT_MAPPED); if(streamID == HTC_RAW_STREAM_NOT_MAPPED) { return; /* in case panic_on_assert==0 */ } #ifdef CF if (down_trylock(&arRaw->raw_htc_write_sem[streamID])) { #else if (down_interruptible(&arRaw->raw_htc_write_sem[streamID])) { #endif AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to down the semaphore\n")); } A_ASSERT(pPacket->pBuffer == (free->data + HTC_HEADER_LEN)); free->length = 0; arRaw->write_buffer_available[streamID] = TRUE; up(&arRaw->raw_htc_write_sem[streamID]); /* Signal the waiting process */ AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("Waking up the StreamID(%d) write process\n", streamID)); wake_up_interruptible(&arRaw->raw_htc_write_queue[streamID]); } /* connect to a service */ static A_STATUS ar6000_connect_raw_service(AR_SOFTC_T *ar, HTC_RAW_STREAM_ID StreamID) { A_STATUS status; HTC_SERVICE_CONNECT_RESP response; A_UINT8 streamNo; HTC_SERVICE_CONNECT_REQ connect; do { A_MEMZERO(&connect,sizeof(connect)); /* pass the stream ID as meta data to the RAW streams service */ streamNo = (A_UINT8)StreamID; connect.pMetaData = &streamNo; connect.MetaDataLength = sizeof(A_UINT8); /* these fields are the same for all endpoints */ connect.EpCallbacks.pContext = ar; connect.EpCallbacks.EpTxComplete = ar6000_htc_raw_write_cb; connect.EpCallbacks.EpRecv = ar6000_htc_raw_read_cb; /* simple interface, we don't need these optional callbacks */ connect.EpCallbacks.EpRecvRefill = NULL; connect.EpCallbacks.EpSendFull = NULL; connect.MaxSendQueueDepth = RAW_HTC_WRITE_BUFFERS_NUM; /* connect to the raw streams service, we may be able to get 1 or more * connections, depending on WHAT is running on the target */ connect.ServiceID = HTC_RAW_STREAMS_SVC; A_MEMZERO(&response,sizeof(response)); /* try to connect to the raw stream, it is okay if this fails with * status HTC_SERVICE_NO_MORE_EP */ status = HTCConnectService(ar->arHtcTarget, &connect, &response); if (A_FAILED(status)) { if (response.ConnectRespCode == HTC_SERVICE_NO_MORE_EP) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HTC RAW , No more streams allowed \n")); status = A_OK; } break; } /* set endpoint mapping for the RAW HTC streams */ arSetRawStream2EndpointIDMap(ar,StreamID,response.Endpoint); AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("HTC RAW : stream ID: %d, endpoint: %d\n", StreamID, arRawStream2EndpointID(ar,StreamID))); } while (FALSE); 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; }
/* wait for the target to arrive (sends HTC Ready message) * this operation is fully synchronous and the message is polled for */ A_STATUS HTCWaitTarget(HTC_HANDLE HTCHandle) { HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); A_STATUS status; HTC_PACKET *pPacket = NULL; HTC_READY_MSG *pRdyMsg; HTC_SERVICE_CONNECT_REQ connect; HTC_SERVICE_CONNECT_RESP resp; AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCWaitTarget - Enter (target:0x%X) \n", (A_UINT32)target)); do { #ifdef MBOXHW_UNIT_TEST status = DoMboxHWTest(&target->Device); if (status != A_OK) { break; } #endif /* we should be getting 1 control message that the target is ready */ status = HTCWaitforControlMessage(target, &pPacket); if (A_FAILED(status)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, (" Target Not Available!!\n")); break; } /* we controlled the buffer creation so it has to be properly aligned */ pRdyMsg = (HTC_READY_MSG *)pPacket->pBuffer; if ((pRdyMsg->MessageID != HTC_MSG_READY_ID) || (pPacket->ActualLength < sizeof(HTC_READY_MSG))) { /* this message is not valid */ AR_DEBUG_ASSERT(FALSE); status = A_EPROTO; break; } if (pRdyMsg->CreditCount == 0 || pRdyMsg->CreditSize == 0) { /* this message is not valid */ AR_DEBUG_ASSERT(FALSE); status = A_EPROTO; break; } target->TargetCredits = pRdyMsg->CreditCount; target->TargetCreditSize = pRdyMsg->CreditSize; AR_DEBUG_PRINTF(ATH_DEBUG_TRC, (" Target Ready: credits: %d credit size: %d\n", target->TargetCredits, target->TargetCreditSize)); printk(" Target Ready: credits: %d credit size: %d\n",target->TargetCredits, target->TargetCreditSize); /* 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 = HTCControlRecv; connect.EpCallbacks.EpRecvRefill = NULL; /* not needed */ connect.EpCallbacks.EpSendFull = NULL; /* not nedded */ connect.MaxSendQueueDepth = NUM_CONTROL_BUFFERS; connect.ServiceID = HTC_CTRL_RSVD_SVC; /* connect fake service */ status = HTCConnectService((HTC_HANDLE)target, &connect, &resp); if (!A_FAILED(status)) { break; } } while (FALSE); if (pPacket != NULL) { HTC_FREE_CONTROL_RX(target,pPacket); } AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCWaitTarget - Exit\n")); return status; }
A_BOOL RunAR6kTest(A_UINT32 Channel, A_CHAR *pSSID, MTE_WIFI_TEST_STATUS *pTestStatus) { AR6K_FIRMWARE_INFO firmware; A_STATUS status = A_OK; A_MEMZERO(&firmware,sizeof(firmware)); InitializeMTE(); if (!GetFirmwareInfo(&firmware)) { DBG_LOG_PRINT(DBG_ZONE_ERR, ("Target Firmware missing!! Aborting.. \r\n")); return FALSE; } g_WifiMTE.SSIDLength = strlen(pSSID); A_ASSERT(g_WifiMTE.SSIDLength <= 32); A_MEMCPY(g_WifiMTE.SSID,pSSID,g_WifiMTE.SSIDLength); A_ASSERT(Channel <= MAX_WIFI_CHANNELS); A_ASSERT(Channel > 0); /* look up the channel hint (in Mhz) */ g_WifiMTE.WiFiChannel = g_ChannelLookUp[Channel]; DBG_LOG_PRINT(DBG_ZONE_INIT, ("Ar6k WiFi MTE Test Start..(SSID: %s , channel:%d) \r\n", g_WifiMTE.SSID, g_WifiMTE.WiFiChannel)); do { /* init test status */ g_WifiMTE.MteStatus = MTE_WIFI_STATUS_SDIO_INIT_FAILED; if (A_FAILED(HIFInit())) { DBG_LOG_PRINT(DBG_ZONE_ERR, ("** HIFInit Failed!!! \r\n")); break; } BMIInit(); /* all failures are setup failures this point forward */ g_WifiMTE.MteStatus = MTE_WIFI_STATUS_SETUP_FAILED; g_WifiMTE.HifDevice = HIFGetDevice(); DBG_LOG_PRINT(DBG_ZONE_ERR, ("Getting Target ID... \r\n")); status = BMIGetTargetInfo(g_WifiMTE.HifDevice, &g_WifiMTE.TargetInfo); if (A_FAILED(status)) { DBG_LOG_PRINT(DBG_ZONE_ERR, ("** Failed to Get Target Information \r\n")); break; } DBG_LOG_PRINT(DBG_ZONE_INIT, ("TARGET_TYPE:0x%X TARGET_VER : 0x%X \r\n", g_WifiMTE.TargetInfo.target_type, g_WifiMTE.TargetInfo.target_ver)); status = ar6000_prepare_target(g_WifiMTE.HifDevice, g_WifiMTE.TargetInfo.target_type, g_WifiMTE.TargetInfo.target_ver); if (A_FAILED(status)) { DBG_LOG_PRINT(DBG_ZONE_ERR, ("** Failed to prepare target \r\n")); break; } status = ar6000_configure_clock (g_WifiMTE.HifDevice, g_WifiMTE.TargetInfo.target_type, g_WifiMTE.TargetInfo.target_ver, BOARD_XTAL_FREQ); if (A_FAILED(status)) { DBG_LOG_PRINT(DBG_ZONE_ERR, ("** Failed to configure target XTAL \r\n")); break; } DBG_LOG_PRINT(DBG_ZONE_INIT, ("Download Firmware ... (firmware length: %d, %s) (datapatch len: %d) \r\n", firmware.AthwlanLength, firmware.AthwlanCompressed ? "COMPRESSED" : "UNCOMPRESSED", firmware.DataPatchLength)); status = DownloadFirmware(g_WifiMTE.HifDevice, g_WifiMTE.TargetInfo.target_type, g_WifiMTE.TargetInfo.target_ver, firmware.pAthwlan, firmware.AthwlanLength, firmware.AthwlanCompressed, firmware.pDataPatch, firmware.DataPatchLength); if (A_FAILED(status)) { DBG_LOG_PRINT(DBG_ZONE_ERR, ("** Failed to download firmware \r\n")); break; } DBG_LOG_PRINT(DBG_ZONE_INIT, ("Firmware Download Complete.. \r\n")); ar6000_enable_target_console(g_WifiMTE.HifDevice,g_WifiMTE.TargetInfo.target_type); status = ar6000_set_htc_params(g_WifiMTE.HifDevice, g_WifiMTE.TargetInfo.target_type, 0, 0); if (A_FAILED(status)) { DBG_LOG_PRINT(DBG_ZONE_ERR, ("** Failed to set HTC Params \r\n")); break; } DBG_LOG_PRINT(DBG_ZONE_INIT, ("Transferring EEPROM settings .. \r\n")); status = eeprom_ar6000_transfer(g_WifiMTE.HifDevice, g_WifiMTE.TargetInfo.target_type); if (A_FAILED(status)) { DBG_LOG_PRINT(DBG_ZONE_ERR, ("** Failed to transfer EEPROM settings \r\n")); break; } DBG_LOG_PRINT(DBG_ZONE_INIT, ("Starting Target .. \r\n")); status = BMIDone(g_WifiMTE.HifDevice); if (A_FAILED(status)) { DBG_LOG_PRINT(DBG_ZONE_ERR, ("** Target failed to start \r\n")); break; } /* from here on out, all mte failures are boot failures */ g_WifiMTE.MteStatus = MTE_WIFI_STATUS_BOOT_FAILED; DBG_LOG_PRINT(DBG_ZONE_INIT, ("Connecting HTC .. \r\n")); /* connect HTC layer */ g_WifiMTE.htcHandle = HTCConnect(g_WifiMTE.HifDevice); if (g_WifiMTE.htcHandle == NULL) { DBG_LOG_PRINT(DBG_ZONE_ERR, ("** HTC connection failed \r\n")); break; } status = HTCConnectService(g_WifiMTE.htcHandle, WMI_CONTROL_SVC, &g_WifiMTE.ControlEp); if (A_FAILED(status)) { DBG_LOG_PRINT(DBG_ZONE_ERR, ("** Failed to connect to WMI control service \r\n")); break; } status = HTCConnectService(g_WifiMTE.htcHandle, WMI_DATA_BE_SVC, &g_WifiMTE.DataEp); if (A_FAILED(status)) { DBG_LOG_PRINT(DBG_ZONE_ERR, ("** Failed to connect to WMI best effort data service \r\n")); break; } DBG_LOG_PRINT(DBG_ZONE_INIT, ("HTC is connected (wmi_ctrl:%d, data:%d) ... \r\n", g_WifiMTE.ControlEp, g_WifiMTE.DataEp)); status = HTCStart(g_WifiMTE.htcHandle); if (A_FAILED(status)) { DBG_LOG_PRINT(DBG_ZONE_ERR, ("** failed to start HTC \r\n")); break; } status = WMIInit(g_WifiMTE.htcHandle,g_WifiMTE.ControlEp,g_WifiMTE.DataEp); if (A_FAILED(status)) { DBG_LOG_PRINT(DBG_ZONE_ERR, ("** failed to init WMI \r\n")); break; } status = RunConnectionTest(); } while (FALSE); pTestStatus->StatusCode = g_WifiMTE.MteStatus; pTestStatus->RSSI = g_WifiMTE.RSSI; return (A_SUCCESS(status)); }