bss_t * wlan_node_alloc(struct ieee80211_node_table *nt, A_INT32 wh_size) { bss_t *ni; ni = A_MALLOC(sizeof(bss_t)); if (ni != NULL) { ni->ni_buf = A_MALLOC(wh_size); if (ni->ni_buf == NULL) { A_FREE(ni); ni = NULL; } } /* Make sure our lists are clean */ if (ni) { ni->ni_list_next = NULL; ni->ni_list_prev = NULL; ni->ni_hash_next = NULL; ni->ni_hash_prev = NULL; } return ni; }
/* APIs visible to the driver */ A_STATUS BMIInit(A_VOID *pCxt) { bmiDone = FALSE; /* * On some platforms, it's not possible to DMA to a static variable * in a device driver (e.g. Linux loadable driver module). * So we need to A_MALLOC space for "command credits" and for commands. * * Note: implicitly relies on A_MALLOC to provide a buffer that is * suitable for DMA (or PIO). This buffer will be passed down the * bus stack. */ if (!pBMICmdCredits) { pBMICmdCredits = (A_UINT32 *)A_MALLOC(4, MALLOC_ID_TEMPORARY); A_ASSERT(pBMICmdCredits); } if (!pBMICmdBuf) { pBMICmdBuf = (A_UCHAR *)A_MALLOC(MAX_BMI_CMDBUF_SZ, MALLOC_ID_TEMPORARY); A_ASSERT(pBMICmdBuf); } return A_OK; }
/* setup scatter DMA resources for each scatter request */ static A_STATUS SetupScatterResource(HIF_DEVICE *device, HIF_SCATTER_REQ *pReq) { A_STATUS status = A_OK; void *pDMAInfo = NULL; switch (device->ScatterMethod) { case HIF_SCATTER_DMA_REAL : /* just allocate memory for the scatter list */ pDMAInfo = A_MALLOC(sizeof(HIF_SCATTER_DMA_REAL_INFO)); if (NULL == pDMAInfo) { status = A_NO_MEMORY; break; } A_MEMZERO(pDMAInfo, sizeof(HIF_SCATTER_DMA_REAL_INFO)); pReq->ScatterMethod = HIF_SCATTER_DMA_REAL; break; case HIF_SCATTER_DMA_BOUNCE : { HIF_SCATTER_DMA_BOUNCE_INFO *pBounceInfo; /* allocate the management structure */ pBounceInfo = (HIF_SCATTER_DMA_BOUNCE_INFO *)A_MALLOC(sizeof(HIF_SCATTER_DMA_BOUNCE_INFO)); if (NULL == pBounceInfo) { status = A_NO_MEMORY; break; } A_MEMZERO(pBounceInfo, sizeof(HIF_SCATTER_DMA_BOUNCE_INFO)); /* allocate a bounce buffer for the request */ status = AllocateDMABounceBuffer(device, pBounceInfo); if (A_FAILED(status)) { A_FREE(pBounceInfo); break; } pDMAInfo = pBounceInfo; pReq->ScatterMethod = HIF_SCATTER_DMA_BOUNCE; pReq->pScatterBounceBuffer = pBounceInfo->pBounceBuffer + pBounceInfo->AlignmentOffset; } break; default: break; } if (pDMAInfo != NULL) { SET_DMA_INFO_SR(pReq,pDMAInfo); } return status; }
static HTC_PACKET *BuildHTCTxCtrlPacket(adf_os_device_t osdev) { HTC_PACKET *pPacket = NULL; adf_nbuf_t netbuf; do { pPacket = (HTC_PACKET *)A_MALLOC(sizeof(HTC_PACKET)); if (NULL == pPacket) { break; } A_MEMZERO(pPacket,sizeof(HTC_PACKET)); #ifdef ATH_USE_NCNB netbuf = adf_nbuf_alloc_ncnb(osdev, HTC_CONTROL_BUFFER_SIZE, 20, 4, TRUE); #else netbuf = adf_nbuf_alloc(osdev, HTC_CONTROL_BUFFER_SIZE, 20, 4, TRUE); #endif if (NULL == netbuf) { A_FREE(pPacket); pPacket = NULL; adf_os_print("%s: nbuf alloc failed\n",__func__); break; } AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("alloc ctrl netbuf :0x%p \n", netbuf)); SET_HTC_PACKET_NET_BUF_CONTEXT(pPacket, netbuf); } while (FALSE); return pPacket; }
static A_STATUS SendHCICommand(AR3K_CONFIG_INFO *pConfig, A_UINT8 *pBuffer, int Length) { HTC_PACKET *pPacket = NULL; A_STATUS status = A_OK; do { pPacket = (HTC_PACKET *)A_MALLOC(sizeof(HTC_PACKET)); if (NULL == pPacket) { status = A_NO_MEMORY; break; } A_MEMZERO(pPacket,sizeof(HTC_PACKET)); SET_HTC_PACKET_INFO_TX(pPacket, NULL, pBuffer, Length, HCI_COMMAND_TYPE, AR6K_CONTROL_PKT_TAG); /* issue synchronously */ status = HCI_TransportSendPkt(pConfig->pHCIDev,pPacket,TRUE); } while (FALSE); if (pPacket != NULL) { A_FREE(pPacket); } return status; }
/* function to set up virtual scatter support if HIF layer has not implemented the interface */ static A_STATUS DevSetupVirtualScatterSupport(AR6K_DEVICE *pDev) { A_STATUS status = A_OK; int bufferSize, sgreqSize; int i; DEV_SCATTER_DMA_VIRTUAL_INFO *pVirtualInfo; HIF_SCATTER_REQ *pReq; bufferSize = sizeof(DEV_SCATTER_DMA_VIRTUAL_INFO) + 2 * (A_GET_CACHE_LINE_BYTES()) + AR6K_MAX_TRANSFER_SIZE_PER_SCATTER; sgreqSize = sizeof(HIF_SCATTER_REQ) + (AR6K_SCATTER_ENTRIES_PER_REQ - 1) * (sizeof(HIF_SCATTER_ITEM)); for (i = 0; i < AR6K_SCATTER_REQS; i++) { /* allocate the scatter request, buffer info and the actual virtual buffer itself */ pReq = (HIF_SCATTER_REQ *)A_MALLOC(sgreqSize + bufferSize); if (NULL == pReq) { status = A_NO_MEMORY; break; } A_MEMZERO(pReq, sgreqSize); /* the virtual DMA starts after the scatter request struct */ pVirtualInfo = (DEV_SCATTER_DMA_VIRTUAL_INFO *)((A_UINT8 *)pReq + sgreqSize); A_MEMZERO(pVirtualInfo, sizeof(DEV_SCATTER_DMA_VIRTUAL_INFO)); pVirtualInfo->pVirtDmaBuffer = &pVirtualInfo->DataArea[0]; /* align buffer to cache line in case host controller can actually DMA this */ pVirtualInfo->pVirtDmaBuffer = A_ALIGN_TO_CACHE_LINE(pVirtualInfo->pVirtDmaBuffer); /* store the structure in the private area */ pReq->HIFPrivate[0] = pVirtualInfo; /* we emulate a DMA bounce interface */ pReq->ScatterMethod = HIF_SCATTER_DMA_BOUNCE; pReq->pScatterBounceBuffer = pVirtualInfo->pVirtDmaBuffer; /* free request to the list */ DevFreeScatterReq((HIF_DEVICE *)pDev,pReq); } if (A_FAILED(status)) { DevCleanupVirtualScatterSupport(pDev); } else { pDev->HifScatterInfo.pAllocateReqFunc = DevAllocScatterReq; pDev->HifScatterInfo.pFreeReqFunc = DevFreeScatterReq; pDev->HifScatterInfo.pReadWriteScatterFunc = DevReadWriteScatter; if (pDev->MailBoxInfo.MboxBusIFType == MBOX_BUS_IF_SPI) { AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("AR6K: SPI bus requires RX scatter limits\n")); pDev->HifScatterInfo.MaxScatterEntries = AR6K_MIN_SCATTER_ENTRIES_PER_REQ; pDev->HifScatterInfo.MaxTransferSizePerScatterReq = AR6K_MIN_TRANSFER_SIZE_PER_SCATTER; } else { pDev->HifScatterInfo.MaxScatterEntries = AR6K_SCATTER_ENTRIES_PER_REQ; pDev->HifScatterInfo.MaxTransferSizePerScatterReq = AR6K_MAX_TRANSFER_SIZE_PER_SCATTER; } pDev->ScatterIsVirtual = TRUE; } return status; }
/* APIs exported to other modules */ A_STATUS Abf_WlanStackNotificationInit(ATH_BT_FILTER_INSTANCE *pInstance, A_UINT32 flags) { A_STATUS status; ATHBT_FILTER_INFO *pInfo; ABF_WLAN_INFO *pAbfWlanInfo; pInfo = (ATHBT_FILTER_INFO *)pInstance->pContext; if (pInfo->pWlanInfo) { return A_OK; } pAbfWlanInfo = (ABF_WLAN_INFO *)A_MALLOC(sizeof(ABF_WLAN_INFO)); A_MEMZERO(pAbfWlanInfo,sizeof(ABF_WLAN_INFO)); A_MUTEX_INIT(&pAbfWlanInfo->hWaitEventLock); A_COND_INIT(&pAbfWlanInfo->hWaitEvent); A_MEMZERO(pAbfWlanInfo, sizeof(ABF_WLAN_INFO)); pAbfWlanInfo->pInfo = pInfo; pAbfWlanInfo->Loop = TRUE; pInfo->pWlanInfo = pAbfWlanInfo; /* Spawn a thread which will be used to process events from WLAN */ status = A_TASK_CREATE(&pInfo->hWlanThread, WlanEventThread, pAbfWlanInfo); if (A_FAILED(status)) { A_ERR("[%s] Failed to spawn a WLAN thread\n", __FUNCTION__); return A_ERROR; } A_INFO("WLAN Stack Notification init complete\n"); return A_OK; }
static int SendHCICommand(struct ar3k_config_info *pConfig, u8 *pBuffer, int Length) { struct htc_packet *pPacket = NULL; int status = 0; do { pPacket = (struct htc_packet *)A_MALLOC(sizeof(struct htc_packet)); if (NULL == pPacket) { status = A_NO_MEMORY; break; } A_MEMZERO(pPacket,sizeof(struct htc_packet)); SET_HTC_PACKET_INFO_TX(pPacket, NULL, pBuffer, Length, HCI_COMMAND_TYPE, AR6K_CONTROL_PKT_TAG); /* issue synchronously */ status = HCI_TransportSendPkt(pConfig->pHCIDev,pPacket,true); } while (false); if (pPacket != NULL) { kfree(pPacket); } return status; }
/* registered target arrival callback from the HIF layer */ HTC_HANDLE HTCCreate(void *hHIF, HTC_INIT_INFO *pInfo) { A_STATUS status = A_OK; HTC_TARGET *target = NULL; do { if ((target = (HTC_TARGET *)A_MALLOC(sizeof(HTC_TARGET))) == NULL) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HTC : Unable to allocate memory\n")); status = A_ERROR; break; } A_MEMCPY(&target->HTCInitInfo,pInfo,sizeof(HTC_INIT_INFO)); adf_os_mem_zero(target, sizeof(HTC_TARGET)); adf_os_spinlock_init(&target->HTCLock); adf_os_spinlock_init(&target->HTCRxLock); adf_os_spinlock_init(&target->HTCTxLock); /* setup HIF layer callbacks */ adf_os_mem_zero(&htcCallbacks, sizeof(completion_callbacks_t)); htcCallbacks.Context = target; htcCallbacks.rxCompletionHandler = HTCRxCompletionHandler; htcCallbacks.txCompletionHandler = HTCTxCompletionHandler; HIFPostInit(hHIF, target, &htcCallbacks); target->hif_dev = hHIF; adf_os_init_mutex(&target->htc_rdy_mutex); adf_os_mutex_acquire(&target->htc_rdy_mutex); /* Get HIF default pipe for HTC message exchange */ pEndpoint = &target->EndPoint[ENDPOINT0]; HIFGetDefaultPipe(hHIF, &pEndpoint->UL_PipeID, &pEndpoint->DL_PipeID); adf_os_print("[Default Pipe]UL: %x, DL: %x\n", pEndpoint->UL_PipeID, pEndpoint->DL_PipeID); /* TODO : other init */ } while (FALSE); target->host_handle = htcInfo.pContext; /* TODO INTEGRATION supply from host os handle for any os specific calls*/ target->os_handle = NULL; if (A_FAILED(status)) { HTCCleanup(target); target = NULL; } return (HTC_HANDLE)target; }
int android_request_firmware(const struct firmware **firmware_p, const char *name, struct device *device) { int ret = 0; struct firmware *firmware; char filename[256]; const char *raw_filename = name; *firmware_p = firmware = A_MALLOC(sizeof(*firmware)); if (!firmware) return -ENOMEM; A_MEMZERO(firmware, sizeof(*firmware)); sprintf(filename, "%s/%s", fwpath, raw_filename); #ifdef TARGET_EUROPA if (strcmp(raw_filename, "softmac")==0) { sprintf(filename, "/data/.nvmac.info"); } #endif /* TARGET_EUROPA */ do { size_t length, bufsize, bmisize; if ( (ret=android_readwrite_file(filename, NULL, NULL, 0)) < 0) { break; } else { length = ret; } bufsize = ALIGN(length, PAGE_SIZE); bmisize = A_ROUND_UP(length, 4); bufsize = max(bmisize, bufsize); firmware->data = vmalloc(bufsize); firmware->size = length; if (!firmware->data) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: Cannot allocate buffer for firmware\n", __FUNCTION__)); ret = -ENOMEM; break; } if ( (ret=android_readwrite_file(filename, (char*)firmware->data, NULL, length)) != length) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: file read error, ret %d request %d\n", __FUNCTION__, ret, length)); ret = -1; break; } } while (0); if (ret<0) { if (firmware) { if (firmware->data) vfree(firmware->data); A_FREE(firmware); } *firmware_p = NULL; } else { ret = 0; } return ret; }
A_STATUS FCore_ModifyControlActionString(BT_FILTER_CORE_INFO *pCore, ATHBT_STATE_INDICATION Indication, ATHBT_STATE State, A_CHAR *pAction, int StringLength, ATHBT_MODIFY_CONTROL_ACTION ModifyAction) { BT_CONTROL_ACTION_DESC *pNewDesc; BT_CONTROL_ACTION_DESC *pDescHead; A_CHAR *pString; /* get first entry at the head */ pDescHead = &pCore->ActionDescriptors[Indication].Action[State]; /* allocate and assemble an entry for this action */ pNewDesc = (BT_CONTROL_ACTION_DESC *)A_MALLOC(sizeof(BT_CONTROL_ACTION_DESC) + StringLength + 1); if (NULL == pNewDesc) { return A_NO_MEMORY; } A_MEMZERO(pNewDesc,sizeof(BT_CONTROL_ACTION_DESC)); /* setup and copy string */ pString = (A_CHAR *)((A_UINT8 *)pNewDesc + sizeof(BT_CONTROL_ACTION_DESC)); A_MEMCPY(pString,pAction,StringLength); pString[StringLength] = 0; pNewDesc->pActionString = pString; /* mark that it was allocated so we can clean it up later */ pNewDesc->Flags = BT_CA_DESC_FLAGS_ALLOCATED; switch (ModifyAction) { case ATHBT_MODIFY_CONTROL_ACTION_APPEND: /* append to the end of the list */ while (pDescHead->pNext != NULL) { pDescHead = pDescHead->pNext; } pDescHead->pNext = pNewDesc; break; case ATHBT_MODIFY_CONTROL_ACTION_REPLACE: /* remove any existing replacements or append operations */ CleanupModifiedControlActionDescChain(pDescHead); /* ignore the first entry's action string */ pDescHead->pActionString = NULL; /* add new replacement */ pDescHead->pNext = pNewDesc; break; default: A_FREE(pNewDesc); break; } return A_OK; }
static A_STATUS GetAdapterInfo(ABF_WLAN_INFO *pAbfWlanInfo) { A_STATUS status; struct ar6000_version *revinfo; revinfo = (struct ar6000_version *)A_MALLOC(sizeof(struct ar6000_version)); if (revinfo == NULL) { A_ERR("[%s] Failed to alloc WLAN revision info\n", __FUNCTION__); return A_ERROR; } /* Get the revision info */ status = Abf_WlanDispatchIO(pAbfWlanInfo->pInfo, AR6000_IOCTL_WMI_GETREV, (void *)revinfo, sizeof(struct ar6000_version)); if (A_FAILED(status)) { A_ERR("[%s] Failed to get WLAN revision\n", __FUNCTION__); return A_ERROR; } pAbfWlanInfo->HostVersion = revinfo->host_ver; pAbfWlanInfo->TargetVersion = revinfo->target_ver; A_INFO("Host Rev: 0x%x(%u.%u.%u.%u), Target Rev: 0x%x(%u.%u.%u.%u)\n", revinfo->host_ver, ((revinfo->host_ver)&0xf0000000)>>28, ((revinfo->host_ver)&0x0f000000)>>24, ((revinfo->host_ver)&0x00ff0000)>>16, ((revinfo->host_ver)&0x0000ffff), revinfo->target_ver, ((revinfo->target_ver)&0xf0000000)>>28, ((revinfo->target_ver)&0x0f000000)>>24, ((revinfo->target_ver)&0x00ff0000)>>16, ((revinfo->target_ver)&0x0000ffff)); A_FREE(revinfo); return A_OK; }
/* APIs visible to the driver */ void BMIInit(void) { bmiDone = FALSE; /* * On some platforms, it's not possible to DMA to a static variable * in a device driver (e.g. Linux loadable driver module). * So we need to A_MALLOC space for "command credits" and for commands. * * Note: implicitly relies on A_MALLOC to provide a buffer that is * suitable for DMA (or PIO). This buffer will be passed down the * bus stack. */ if (!pBMICmdBuf) { pBMICmdBuf = (A_UCHAR *)A_MALLOC(MAX_BMI_CMDBUF_SZ); A_ASSERT(pBMICmdBuf); } A_REGISTER_MODULE_DEBUG_INFO(bmi); }
static A_STATUS RecvHCIEvent(AR3K_CONFIG_INFO *pConfig, A_UINT8 *pBuffer, int *pLength) { A_STATUS status = A_OK; HTC_PACKET *pRecvPacket = NULL; do { pRecvPacket = (HTC_PACKET *)A_MALLOC(sizeof(HTC_PACKET)); if (NULL == pRecvPacket) { status = A_NO_MEMORY; AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to alloc HTC struct \n")); break; } A_MEMZERO(pRecvPacket,sizeof(HTC_PACKET)); SET_HTC_PACKET_INFO_RX_REFILL(pRecvPacket,NULL,pBuffer,*pLength,HCI_EVENT_TYPE); status = HCI_TransportRecvHCIEventSync(pConfig->pHCIDev, pRecvPacket, HCI_EVENT_RESP_TIMEOUTMS); if (A_FAILED(status)) { break; } *pLength = pRecvPacket->ActualLength; } while (FALSE); if (pRecvPacket != NULL) { A_FREE(pRecvPacket); } return status; }
static int RecvHCIEvent(struct ar3k_config_info *pConfig, u8 *pBuffer, int *pLength) { int status = 0; struct htc_packet *pRecvPacket = NULL; do { pRecvPacket = (struct htc_packet *)A_MALLOC(sizeof(struct htc_packet)); if (NULL == pRecvPacket) { status = A_NO_MEMORY; AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to alloc HTC struct \n")); break; } A_MEMZERO(pRecvPacket,sizeof(struct htc_packet)); SET_HTC_PACKET_INFO_RX_REFILL(pRecvPacket,NULL,pBuffer,*pLength,HCI_EVENT_TYPE); status = HCI_TransportRecvHCIEventSync(pConfig->pHCIDev, pRecvPacket, HCI_EVENT_RESP_TIMEOUTMS); if (status) { break; } *pLength = pRecvPacket->ActualLength; } while (false); if (pRecvPacket != NULL) { kfree(pRecvPacket); } return status; }
void * a_netbuf_alloc (A_UINT32 len) { void *buff = NULL; ndis_mini_buf_t *pb = NULL; pb = A_MALLOC (sizeof(ndis_mini_buf_t) + \ len + AR6000_DATA_OFFSET + \ DataBufferAlignmentBytes + DataBufferPadBytes); if (pb == NULL) { return NULL; } memset(pb, 0, sizeof(ndis_mini_buf_t)); buff = (void *) ((A_UINT8 *)pb + sizeof(ndis_mini_buf_t)); // // check buffer alignment // if ((DWORD)buff & DataBufferAlignmentMask) { // // not aligned, adjust buffer // (DWORD)buff += DataBufferAlignmentBytes; buff = (PUCHAR)((DWORD)buff & ~DataBufferAlignmentMask); } pb->buf = buff; pb->buf_len = len + AR6000_DATA_OFFSET; // Reserve headroom pb->buf_dat = pb->buf + AR6000_DATA_OFFSET; pb->buf_dat_len = 0; return pb; }
static void WirelessEvent(ATH_BT_FILTER_INSTANCE *pInstance, char *data, int len) { A_STATUS status = A_OK; struct iw_event iwe_buf, *iwe = &iwe_buf; char *pos, *end, *custom, *buf; pos = data; end = data + len; while ((pos + IW_EV_LCP_PK_LEN <= end) && (status == A_OK)) { /* Event data may be unaligned, so make a local, aligned copy * before processing. */ A_MEMCPY(&iwe_buf, pos, IW_EV_LCP_LEN); if (iwe->len <= IW_EV_LCP_LEN) { status = A_ERROR; break; } custom = pos + IW_EV_POINT_LEN; if (WIRELESS_EXT > 18 && (iwe->cmd == IWEVMICHAELMICFAILURE || iwe->cmd == IWEVCUSTOM || iwe->cmd == IWEVASSOCREQIE || iwe->cmd == IWEVASSOCRESPIE || iwe->cmd == IWEVPMKIDCAND || iwe->cmd == IWEVGENIE)) { /* WE-19 removed the pointer from struct iw_point */ char *dpos = (char *) &iwe_buf.u.data.length; int dlen = dpos - (char *) &iwe_buf; A_MEMCPY(dpos, pos + IW_EV_LCP_LEN, sizeof(struct iw_event) - dlen); } else { A_MEMCPY(&iwe_buf, pos, sizeof(struct iw_event)); custom += IW_EV_POINT_OFF; } switch (iwe->cmd) { case SIOCGIWAP: break; case IWEVCUSTOM: if (custom + iwe->u.data.length > end) { A_ERR("[%s:%d] Check Failed\n", __FUNCTION__, __LINE__); status = A_ERROR; break; } buf = A_MALLOC(iwe->u.data.length + 1); if (buf == NULL) { A_ERR("[%s:%d] Check Failed\n", __FUNCTION__, __LINE__); status = A_ERROR; break; } A_MEMCPY(buf, custom, iwe->u.data.length); status = WirelessCustomEvent(pInstance, buf, iwe->u.data.length); A_FREE(buf); break; case SIOCGIWSCAN: break; case SIOCSIWESSID: break; case IWEVGENIE: if (custom + iwe->u.data.length > end || (iwe->u.data.length < 2)) { A_ERR("event = IWEVGENIE with wrong length %d remain %d\n", iwe->u.data.length, (end-custom)); status = A_ERROR; break; } buf = A_MALLOC(iwe->u.data.length + 1); if (buf == NULL) { A_ERR("[%s:%d] Check Failed\n", __FUNCTION__, __LINE__); status = A_ERROR; break; } A_MEMCPY(buf, custom, iwe->u.data.length); status = WirelessCustomEvent(pInstance, buf, iwe->u.data.length); A_FREE(buf); break; default: break; } pos += iwe->len; } }
int PSSendOps(void *arg) { int i; int ps_index; int status = 0; PSCmdPacket *HciCmdList; /* List storing the commands */ const struct firmware* firmware; A_UINT32 numCmds; A_UINT8 *event; A_UINT8 *bufferToFree; struct hci_dev *device; A_UCHAR *buffer; A_UINT32 len; A_UINT32 DevType; A_UCHAR *PsFileName; A_UCHAR *patchFileName; A_UCHAR patch_loc[40]; A_UCHAR *path = NULL; A_UCHAR *config_path = NULL; A_UCHAR config_bdaddr[MAX_BDADDR_FORMAT_LENGTH]; AR3K_CONFIG_INFO *hdev = (AR3K_CONFIG_INFO*)arg; struct device *firmwareDev = NULL; A_UINT8 cFlags = 0; A_UINT8 bit7 = 0; status = 0; HciCmdList = NULL; #ifdef HCI_TRANSPORT_SDIO device = hdev->pBtStackHCIDev; firmwareDev = device->parent; #else device = hdev; firmwareDev = &device->dev; AthEnableSyncCommandOp(TRUE); #endif /* HCI_TRANSPORT_SDIO */ /* First verify if the controller is an FPGA or ASIC, so depending on the device type the PS file to be written will be different. */ path =(A_UCHAR *)A_MALLOC(MAX_FW_PATH_LEN); if(path == NULL) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Malloc failed to allocate %d bytes for path\n", MAX_FW_PATH_LEN)); goto complete; } config_path = (A_UCHAR *) A_MALLOC(MAX_FW_PATH_LEN); if(config_path == NULL) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Malloc failed to allocate %d bytes for config_path\n", MAX_FW_PATH_LEN)); goto complete; } if(A_ERROR == getDeviceType(hdev,&DevType)) { status = 1; goto complete; } if(A_ERROR == ReadVersionInfo(hdev)) { status = 1; goto complete; } patchFileName = PATCH_FILE; snprintf(path, MAX_FW_PATH_LEN, "%s/%xcoex/",CONFIG_PATH,Rom_Version); if(DevType){ if(DevType == 0xdeadc0de){ PsFileName = PS_ASIC_FILE; } else{ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" FPGA Test Image : %x %x \n",Rom_Version,Build_Version)); if((Rom_Version == 0x99999999) && (Build_Version == 1)){ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("FPGA Test Image : Skipping Patch File load\n")); patchFileName = NULL; } PsFileName = PS_FPGA_FILE; } } else{ PsFileName = PS_ASIC_FILE; } snprintf(config_path, MAX_FW_PATH_LEN, "%s%s",path,PsFileName); AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%x: FPGA/ASIC PS File Name %s\n", DevType,config_path)); /* Read the PS file to a dynamically allocated buffer */ if(A_REQUEST_FIRMWARE(&firmware,config_path,firmwareDev) < 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: firmware file open error\n", __FUNCTION__ )); status = 1; goto complete; } if(NULL == firmware || firmware->size == 0) { status = 1; goto complete; } buffer = (A_UCHAR *)A_MALLOC(firmware->size); if(buffer != NULL) { /* Copy the read file to a local Dynamic buffer */ memcpy(buffer,firmware->data,firmware->size); len = firmware->size; A_RELEASE_FIRMWARE(firmware); /* Parse the PS buffer to a global variable */ status = AthDoParsePS(buffer,len); A_FREE(buffer); } else { A_RELEASE_FIRMWARE(firmware); } /* Read the patch file to a dynamically allocated buffer */ if(patchFileName != NULL) snprintf(config_path, MAX_FW_PATH_LEN, "%s%s",path,patchFileName); else { status = 0; } AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Patch File Name %s\n", config_path)); if((patchFileName == NULL) || (A_REQUEST_FIRMWARE(&firmware,config_path,firmwareDev) < 0)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: firmware file open error\n", __FUNCTION__ )); /* * It is not necessary that Patch file be available, continue with PS Operations if. * failed. */ status = 0; } else { if(NULL == firmware || firmware->size == 0) { status = 0; } else { buffer = (A_UCHAR *)A_MALLOC(firmware->size); if(buffer != NULL) { /* Copy the read file to a local Dynamic buffer */ memcpy(buffer,firmware->data,firmware->size); len = firmware->size; A_RELEASE_FIRMWARE(firmware); /* parse and store the Patch file contents to a global variables */ patch_loc[0] = '\0'; status = AthDoParsePatch(buffer,len, patch_loc); A_FREE(buffer); } else { A_RELEASE_FIRMWARE(firmware); } } } /* Create an HCI command list from the parsed PS and patch information */ AthCreateCommandList(&HciCmdList,&numCmds); #define CONFIG_PLATFORM 0x21 #define CONFIG_TLPM 0x23 #define PLATFORM_CONFIG_BIT 0x01 #define TLPM_CONFIG_BIT 0x02 #define IDLE_TIMEOUT_OFFSET 12 #define WAKEUP_TIMEOUT_OFFSET 8 #define IDLE_TIMEOUT_DEFAULT_VAL 1000 #define WAKEUP_TIMEOUT_DEFAULT_VAL 10 hdev->IdleTimeout = IDLE_TIMEOUT_DEFAULT_VAL; hdev->WakeupTimeout = WAKEUP_TIMEOUT_DEFAULT_VAL; hdev->PwrMgmtEnabled = 0; ps_index = 2; /* CRC + PS Reset */ if (Patch_Count) ps_index += Patch_Count + 1; /* Patches + Enable patch Cmd */ for(i = ps_index; i <numCmds; i++) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Check PS ID %x\n", HciCmdList[i].Hcipacket[4])); /* search for Platform config and TLPM tags */ if((HciCmdList[i].Hcipacket[4] == CONFIG_PLATFORM) && (HciCmdList[i].Hcipacket[5] == 0)) { cFlags |= PLATFORM_CONFIG_BIT; bit7 = (HciCmdList[i].Hcipacket[7]) & (1<<7); if(bit7) { hdev->PwrMgmtEnabled = 1; AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("CONFIG PLATFORM present and Pwr Manage %x\n", hdev->PwrMgmtEnabled)); } } else if((HciCmdList[i].Hcipacket[4] == CONFIG_TLPM) && (HciCmdList[i].Hcipacket[5] == 0)) { cFlags |= TLPM_CONFIG_BIT; hdev->IdleTimeout = *((A_UINT32 *)&HciCmdList[i].Hcipacket[IDLE_TIMEOUT_OFFSET + 7]); hdev->WakeupTimeout = *((A_UINT16 *)&HciCmdList[i].Hcipacket[WAKEUP_TIMEOUT_OFFSET + 7]); AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("hdev->idletimeout %d hdev->WakeupTimeout %d",hdev->IdleTimeout, hdev->WakeupTimeout)); } } /* Form the parameter for PSSendOps() API */ /* * First Send the CRC packet, * We have to continue with the PS operations only if the CRC packet has been replied with * a Command complete event with status Error. */ if(SendHCICommandWaitCommandComplete (hdev, HciCmdList[0].Hcipacket, HciCmdList[0].packetLen, &event, &bufferToFree) == A_OK) { if(ReadPSEvent(event) == A_OK) { /* Exit if the status is success */ if(bufferToFree != NULL) { A_FREE(bufferToFree); } #ifndef HCI_TRANSPORT_SDIO if(bdaddr && bdaddr[0] !='\0') { write_bdaddr(hdev,bdaddr,BDADDR_TYPE_STRING); } #endif status = 1; goto complete; } if(bufferToFree != NULL) { A_FREE(bufferToFree); } } else { status = 0; goto complete; } /* Set Patch location */ if(patch_loc[0] != '\0') { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Setting Patch Location %s\n", patch_loc)); set_patch_ram(hdev,patch_loc,sizeof(patch_loc)); } for(i = 1; i <numCmds; i++) { Hci_log("PS/Patch Write -->",HciCmdList[i].Hcipacket,HciCmdList[i].packetLen); if(SendHCICommandWaitCommandComplete (hdev, HciCmdList[i].Hcipacket, HciCmdList[i].packetLen, &event, &bufferToFree) == A_OK) { if(ReadPSEvent(event) != A_OK) { /* Exit if the status is success */ if(bufferToFree != NULL) { A_FREE(bufferToFree); } status = 1; goto complete; } if(bufferToFree != NULL) { A_FREE(bufferToFree); } } else { status = 0; goto complete; } } #ifdef HCI_TRANSPORT_SDIO if(BDADDR == FALSE) if(hdev->bdaddr[0] !=0x00 || hdev->bdaddr[1] !=0x00 || hdev->bdaddr[2] !=0x00 || hdev->bdaddr[3] !=0x00 || hdev->bdaddr[4] !=0x00 || hdev->bdaddr[5] !=0x00) write_bdaddr(hdev,hdev->bdaddr,BDADDR_TYPE_HEX); /* if Platform config is present and TLPM is not available * write HCI command for TLPM with default timeout values */ if(bit7 && !(cFlags & TLPM_CONFIG_BIT)) { A_UCHAR TLPMHciCmd[] = {0x0b, 0xfc, 0x1c, 0x01, 0x23, 0x00, 0x18, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0xe8, 0x03, 0x00, 0x00, 0xe8, 0x03, 0x00, 0x00, 0xe8, 0x03, 0x00, 0x00 }; int CmdLen = sizeof(TLPMHciCmd); *((A_UINT32 *)&TLPMHciCmd[IDLE_TIMEOUT_OFFSET + 7]) = hdev->IdleTimeout; *((A_UINT16 *)&TLPMHciCmd[WAKEUP_TIMEOUT_OFFSET + 7]) = hdev->WakeupTimeout; if(SendHCICommandWaitCommandComplete (hdev, TLPMHciCmd, CmdLen, &event, &bufferToFree) == A_OK) { if(ReadPSEvent(event) != A_OK) { /* Exit if the status is success */ if(bufferToFree != NULL) { A_FREE(bufferToFree); } status = 1; goto complete; } if(bufferToFree != NULL) { A_FREE(bufferToFree); } } else { status = 0; goto complete; } } #ifndef HCI_TRANSPORT_SDIO if(bdaddr && bdaddr[0] != '\0') { write_bdaddr(hdev,bdaddr,BDADDR_TYPE_STRING); } else #endif /* HCI_TRANSPORT_SDIO */ /* Write BDADDR Read from OTP here */ #endif { /* Read Contents of BDADDR file if user has not provided any option */ snprintf(config_path,MAX_FW_PATH_LEN, "%s%s",path,BDADDR_FILE); AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BDADDR File Name %s\n", config_path)); if(A_REQUEST_FIRMWARE(&firmware,config_path,firmwareDev) < 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: firmware file open error\n", __FUNCTION__ )); goto complete; } if(NULL == firmware || firmware->size == 0) { goto complete; } len = (firmware->size > MAX_BDADDR_FORMAT_LENGTH)? MAX_BDADDR_FORMAT_LENGTH: firmware->size; memcpy(config_bdaddr, firmware->data,len); config_bdaddr[len] = '\0'; write_bdaddr(hdev,config_bdaddr,BDADDR_TYPE_STRING); A_RELEASE_FIRMWARE(firmware); } complete: #ifndef HCI_TRANSPORT_SDIO AthEnableSyncCommandOp(FALSE); PSTagMode = FALSE; wake_up_interruptible(&PsCompleteEvent); #endif /* HCI_TRANSPORT_SDIO */ if(NULL != HciCmdList) { AthFreeCommandList(&HciCmdList,numCmds); } if(path) { A_FREE(path); } if(config_path) { A_FREE(config_path); } return status; }
A_STATUS htcTargetInsertedHandler(HIF_DEVICE *device) { HTC_TARGET *target; HTC_ENDPOINT *endPoint; A_UINT8 count1, count2; HTC_EVENT_INFO eventInfo; HTC_REG_BUFFER *regBuffer; HTC_QUEUE_ELEMENT *element; HTC_MBOX_BUFFER *mboxBuffer; HTC_REG_REQUEST_LIST *regList; HTC_DATA_REQUEST_QUEUE *sendQueue, *recvQueue; HIF_REQUEST request; A_STATUS status; A_UINT32 address; HTC_DEBUG_PRINTF(ATH_LOG_TRC, "htcTargetInserted - Enter\n"); /* Initialize the locks */ A_MUTEX_INIT(&instanceCS); A_MUTEX_INIT(&creditCS); A_MUTEX_INIT(&counterCS); A_MUTEX_INIT(&txCS); /* Allocate target memory */ if ((target = (HTC_TARGET *)A_MALLOC(sizeof(HTC_TARGET))) == NULL) { HTC_DEBUG_PRINTF(ATH_LOG_ERR, "Unable to allocate memory\n"); return A_ERROR; } A_MEMZERO(target, sizeof(HTC_TARGET)); target->device = device; target->ready = FALSE; /* Initialize the endpoints, mbox queues, event table */ for (count1 = ENDPOINT1; count1 <= ENDPOINT4; count1 ++) { endPoint = &target->endPoint[count1]; HTC_DEBUG_PRINTF(ATH_LOG_INF, "endPoint[%d]: %p\n", count1, endPoint); A_MEMZERO(endPoint->txCreditsAvailable, HTC_TX_CREDITS_NUM_MAX); endPoint->txCreditsConsumed = 0; endPoint->txCreditsIntrEnable = FALSE; endPoint->rxLengthPending = 0; endPoint->target = target; endPoint->enabled = FALSE; for (count2 = 0; count2<HTC_DATA_REQUEST_RING_BUFFER_SIZE; count2 ++) { /* Send Queue */ sendQueue = &endPoint->sendQueue; sendQueue->head = sendQueue->size = 0; element = &sendQueue->element[count2]; A_MEMZERO(element, sizeof(HTC_DATA_REQUEST_ELEMENT)); element->buffer.free = TRUE; element->completionCB = htcTxCompletionCB; mboxBuffer = GET_MBOX_BUFFER(element); mboxBuffer->endPoint = endPoint; /* Receive Queue */ recvQueue = &endPoint->recvQueue; recvQueue->head = recvQueue->size = 0; element = &recvQueue->element[count2]; A_MEMZERO(element, sizeof(HTC_DATA_REQUEST_ELEMENT)); element->buffer.free = TRUE; element->completionCB = htcRxCompletionCB; mboxBuffer = GET_MBOX_BUFFER(element); mboxBuffer->endPoint = endPoint; } A_MEMZERO(&target->endPoint[count1].eventTable, sizeof(HTC_ENDPOINT_EVENT_TABLE)); } /* Populate the block size for each of the end points */ endPoint = &target->endPoint[ENDPOINT1]; endPoint->blockSize = HIF_MBOX0_BLOCK_SIZE; endPoint = &target->endPoint[ENDPOINT2]; endPoint->blockSize = HIF_MBOX1_BLOCK_SIZE; endPoint = &target->endPoint[ENDPOINT3]; endPoint->blockSize = HIF_MBOX2_BLOCK_SIZE; endPoint = &target->endPoint[ENDPOINT4]; endPoint->blockSize = HIF_MBOX3_BLOCK_SIZE; /* Initialize the shadow copy of the target register table */ A_MEMZERO(&target->table, sizeof(HTC_REGISTER_TABLE)); /* Initialize the register request list */ regList = &target->regList; for (count1 = 0; count1 < HTC_REG_REQUEST_LIST_SIZE; count1 ++) { element = ®List->element[count1]; A_MEMZERO(element, sizeof(HTC_REG_REQUEST_ELEMENT)); element->buffer.free = TRUE; element->completionCB = htcRegCompletionCB; regBuffer = GET_REG_BUFFER(element); regBuffer->target = target; } /* Add the target instance to the global list */ addTargetInstance(target); /* Disable all the dragon interrupts */ target->table.int_status_enable = 0; target->table.cpu_int_status_enable = 0; target->table.error_status_enable = 0; target->table.counter_int_status_enable = 0; HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO, HIF_SYNCHRONOUS, HIF_BYTE_BASIS, HIF_INCREMENTAL_ADDRESS); address = getRegAddr(INT_STATUS_ENABLE_REG, ENDPOINT_UNUSED); status = HIFReadWrite(target->device, address, &target->table.int_status_enable, 4, &request, NULL); AR_DEBUG_ASSERT(status == A_OK); /* * Frame a TARGET_AVAILABLE event and send it to the host. Return the * HIF_DEVICE handle as a parameter with the event. */ FRAME_EVENT(eventInfo, (A_UCHAR *)device, sizeof(HIF_DEVICE *), sizeof(HIF_DEVICE *), A_OK, NULL); dispatchEvent(target, ENDPOINT_UNUSED, HTC_TARGET_AVAILABLE, &eventInfo); HTC_DEBUG_PRINTF(ATH_LOG_TRC, "htcTargetInserted - Exit\n"); return A_OK; }
int PSSendOps(void *arg) { int i; int status = 0; PSCmdPacket *HciCmdList; /* List storing the commands */ const struct firmware* firmware; A_UINT32 numCmds; A_UINT8 *event; A_UINT8 *bufferToFree; struct hci_dev *device; A_UCHAR *buffer; A_UINT32 len; A_UINT32 DevType; A_UCHAR *PsFileName; A_UCHAR *patchFileName; AR3K_CONFIG_INFO *hdev = (AR3K_CONFIG_INFO*)arg; struct device *firmwareDev = NULL; status = 0; HciCmdList = NULL; #ifdef HCI_TRANSPORT_SDIO device = hdev->pBtStackHCIDev; firmwareDev = device->parent; #else device = hdev; firmwareDev = &device->dev; AthEnableSyncCommandOp(TRUE); #endif /* HCI_TRANSPORT_SDIO */ /* First verify if the controller is an FPGA or ASIC, so depending on the device type the PS file to be written will be different. */ if(A_ERROR == getDeviceType(hdev,&DevType)) { status = 1; goto complete; } if(A_ERROR == ReadVersionInfo(hdev)) { status = 1; goto complete; } patchFileName = PATCH_FILE; if(DevType){ if(DevType == 0xdeadc0de){ PsFileName = PS_ASIC_FILE; } else{ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" FPGA Test Image : %x %x \n",Rom_Version,Build_Version)); if((Rom_Version == 0x99999999) && (Build_Version == 1)){ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("FPGA Test Image : Skipping Patch File load\n")); patchFileName = NULL; } PsFileName = PS_FPGA_FILE; } } else{ PsFileName = PS_ASIC_FILE; } AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%x: FPGA/ASIC PS File Name %s\n", DevType,PsFileName)); /* Read the PS file to a dynamically allocated buffer */ if(request_firmware(&firmware,PsFileName,firmwareDev) < 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: firmware file open error\n", __FUNCTION__ )); status = 1; goto complete; } if(NULL == firmware || firmware->size == 0) { status = 1; goto complete; } buffer = (A_UCHAR *)A_MALLOC(firmware->size); if(buffer != NULL) { /* Copy the read file to a local Dynamic buffer */ memcpy(buffer,firmware->data,firmware->size); len = firmware->size; release_firmware(firmware); /* Parse the PS buffer to a global variable */ status = AthDoParsePS(buffer,len); A_FREE(buffer); } else { release_firmware(firmware); } /* Read the patch file to a dynamically allocated buffer */ if((patchFileName == NULL) || (request_firmware(&firmware,patchFileName,firmwareDev) < 0)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: firmware file open error\n", __FUNCTION__ )); /* * It is not necessary that Patch file be available, continue with PS Operations if. * failed. */ status = 0; } else { if(NULL == firmware || firmware->size == 0) { status = 0; } else { buffer = (A_UCHAR *)A_MALLOC(firmware->size); if(buffer != NULL) { /* Copy the read file to a local Dynamic buffer */ memcpy(buffer,firmware->data,firmware->size); len = firmware->size; release_firmware(firmware); /* parse and store the Patch file contents to a global variables */ status = AthDoParsePatch(buffer,len); A_FREE(buffer); } else { release_firmware(firmware); } } } /* Create an HCI command list from the parsed PS and patch information */ AthCreateCommandList(&HciCmdList,&numCmds); /* Form the parameter for PSSendOps() API */ /* * First Send the CRC packet, * We have to continue with the PS operations only if the CRC packet has been replied with * a Command complete event with status Error. */ if(SendHCICommandWaitCommandComplete (hdev, HciCmdList[0].Hcipacket, HciCmdList[0].packetLen, &event, &bufferToFree) == A_OK) { if(ReadPSEvent(event) == A_OK) { /* Exit if the status is success */ if(bufferToFree != NULL) { A_FREE(bufferToFree); } #ifndef HCI_TRANSPORT_SDIO if(bdaddr[0] !='\0') { write_bdaddr(hdev,bdaddr); } #endif status = 1; goto complete; } if(bufferToFree != NULL) { A_FREE(bufferToFree); } } else { status = 0; goto complete; } for(i = 1; i <numCmds; i++) { if(SendHCICommandWaitCommandComplete (hdev, HciCmdList[i].Hcipacket, HciCmdList[i].packetLen, &event, &bufferToFree) == A_OK) { if(ReadPSEvent(event) != A_OK) { /* Exit if the status is success */ if(bufferToFree != NULL) { A_FREE(bufferToFree); } status = 1; goto complete; } if(bufferToFree != NULL) { A_FREE(bufferToFree); } } else { status = 0; goto complete; } } #ifndef HCI_TRANSPORT_SDIO if(bdaddr[0] != '\0') { write_bdaddr(hdev,bdaddr); } else #endif /* HCI_TRANSPORT_SDIO */ { /* Read Contents of BDADDR file if user has not provided any option */ if(request_firmware(&firmware,BDADDR_FILE,firmwareDev) < 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: firmware file open error\n", __FUNCTION__ )); status = 1; goto complete; } if(NULL == firmware || firmware->size == 0) { status = 1; goto complete; } write_bdaddr(hdev,(A_UCHAR *)firmware->data); release_firmware(firmware); } complete: #ifndef HCI_TRANSPORT_SDIO AthEnableSyncCommandOp(FALSE); PSTagMode = FALSE; wake_up_interruptible(&PsCompleteEvent); #endif /* HCI_TRANSPORT_SDIO */ if(NULL != HciCmdList) { AthFreeCommandList(&HciCmdList,numCmds); } return status; }
A_STATUS SendHCICommandWaitCommandComplete(AR3K_CONFIG_INFO *pConfig, A_UINT8 *pHCICommand, int CmdLength, A_UINT8 **ppEventBuffer, A_UINT8 **ppBufferToFree) { A_STATUS status = A_OK; A_UINT8 *pBuffer = NULL; A_UINT8 *pTemp; int length; A_BOOL commandComplete = FALSE; A_UINT8 opCodeBytes[2]; do { length = max(HCI_MAX_EVT_RECV_LENGTH,CmdLength); length += pConfig->pHCIProps->HeadRoom + pConfig->pHCIProps->TailRoom; length += pConfig->pHCIProps->IOBlockPad; pBuffer = (A_UINT8 *)A_MALLOC(length); if (NULL == pBuffer) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: Failed to allocate bt buffer \n")); status = A_NO_MEMORY; break; } /* get the opcodes to check the command complete event */ opCodeBytes[0] = pHCICommand[HCI_CMD_OPCODE_BYTE_LOW_OFFSET]; opCodeBytes[1] = pHCICommand[HCI_CMD_OPCODE_BYTE_HI_OFFSET]; /* copy HCI command */ A_MEMCPY(pBuffer + pConfig->pHCIProps->HeadRoom,pHCICommand,CmdLength); /* send command */ status = SendHCICommand(pConfig, pBuffer + pConfig->pHCIProps->HeadRoom, CmdLength); if (A_FAILED(status)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: Failed to send HCI Command (%d) \n", status)); AR_DEBUG_PRINTBUF(pHCICommand,CmdLength,"HCI Bridge Failed HCI Command"); break; } /* reuse buffer to capture command complete event */ A_MEMZERO(pBuffer,length); status = RecvHCIEvent(pConfig,pBuffer,&length); if (A_FAILED(status)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: HCI event recv failed \n")); AR_DEBUG_PRINTBUF(pHCICommand,CmdLength,"HCI Bridge Failed HCI Command"); break; } pTemp = pBuffer + pConfig->pHCIProps->HeadRoom; if (pTemp[0] == HCI_CMD_COMPLETE_EVENT_CODE) { if ((pTemp[HCI_EVENT_OPCODE_BYTE_LOW] == opCodeBytes[0]) && (pTemp[HCI_EVENT_OPCODE_BYTE_HI] == opCodeBytes[1])) { commandComplete = TRUE; } } if (!commandComplete) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: Unexpected HCI event : %d \n",pTemp[0])); AR_DEBUG_PRINTBUF(pTemp,pTemp[1],"Unexpected HCI event"); status = A_ECOMM; break; } if (ppEventBuffer != NULL) { /* caller wants to look at the event */ *ppEventBuffer = pTemp; if (ppBufferToFree == NULL) { status = A_EINVAL; break; } /* caller must free the buffer */ *ppBufferToFree = pBuffer; pBuffer = NULL; } } while (FALSE); if (pBuffer != NULL) { A_FREE(pBuffer); } return status; }
A_STATUS download_binary (HIF_DEVICE *hifDevice, A_UINT32 address, wchar_t *fileName, wchar_t *fileRoot, A_BOOL bCompressed, AR6K_BIN_CACHE_INFO *pBinCache) { A_STATUS status = A_OK; A_UCHAR *buffer = NULL; A_UINT32 length = 0; A_UINT32 fileSize = 0; A_UINT32 next_address=0; A_INT32 file_left = 0; size_t nSize; wchar_t filePath[128]; HANDLE fd = NULL; BY_HANDLE_FILE_INFORMATION finfo; A_BOOL fillCache = FALSE; A_MEMZERO(&finfo, sizeof(finfo)); if ( wcslen(fileName) + wcslen(fileRoot) > 127 ) { ATHR_DISPLAY_MSG (L"CAR6K::WARNING!!!! :: File Name Very Long :: ====>"); return A_ERROR; } wcscpy(filePath,fileRoot); wcscat(filePath,fileName); ATHR_DISPLAY_MSG (L"file %s \n",filePath); do { if (pBinCache->Valid) { /* binary cache is valid */ if (bCompressed) { status = BMILZStreamStart (hifDevice, address); if (A_FAILED(status)) { break; } } if (bCompressed) { A_UINT32 lastWord = 0; A_UINT32 lastWordOffset = pBinCache->ActualLength & ~0x3; A_UINT32 unalignedBytes = pBinCache->ActualLength & 0x3; if (unalignedBytes) { /* copy the last word into a zero padded buffer */ A_MEMCPY(&lastWord, &pBinCache->pData[lastWordOffset], unalignedBytes); } status = BMILZData(hifDevice, pBinCache->pData, lastWordOffset); if (A_FAILED(status)) { break; } if (unalignedBytes) { status = BMILZData(hifDevice, (A_UINT8 *)&lastWord, 4); } } else { status = BMIWriteMemory(hifDevice, address, pBinCache->pData, A_ROUND_UP(pBinCache->ActualLength,4)); } if (bCompressed && A_SUCCESS(status)) { // // Close compressed stream and open a new (fake) one. This serves mainly to flush Target caches. // status = BMILZStreamStart (hifDevice, 0x00); if (A_FAILED(status)) { break; } } /* all done */ break; } //Determine the length of the file if ( (fd = CreateFile (filePath, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE) { status = A_ERROR; ATHR_DISPLAY_MSG (L"CAR6K::WARNING!!!! :: File Not Found :: ====> %s", filePath); break; } if (!GetFileInformationByHandle(fd, &finfo)) { ATHR_DISPLAY_MSG (L"CAR6K::WARNING!!!! :: File Size Error :: ====> %s", filePath); status = A_ERROR; break; } fileSize = finfo.nFileSizeLow; file_left = fileSize; if ((pBinCache->pData != NULL) && (!pBinCache->Static)) { /* binary caching is supported */ A_ASSERT(!pBinCache->Valid); if (fileSize <= pBinCache->MaxLength) { /* size if good, flag to cache this binary when read from the filesystem */ fillCache = TRUE; pBinCache->ActualLength = 0; /* reset */ } else { /* cache is not big enough to hold data */ A_ASSERT(FALSE); ATHR_DISPLAY_MSG (L"AR6K::WARNING!!!! :: File :%s (%d bytes) too big for cache (max=%d)", filePath, fileSize, pBinCache->MaxLength); } } // // zero data buffer and init length // buffer = (A_UCHAR *)A_MALLOC(MAX_BUF); if (NULL == buffer) { status = A_ERROR; break; } if (bCompressed) { status = BMILZStreamStart (hifDevice, address); if (status != A_OK) { break; } } while (file_left) { length = (file_left < (MAX_BUF)) ? file_left : MAX_BUF; if (bCompressed) { // // 0 pad last word of data to avoid messy uncompression // ((A_UINT32 *)buffer)[((length-1)/4)] = 0; } if (!ReadFile( fd, buffer, length, &nSize, NULL) || nSize != length) { ATHR_DISPLAY_MSG (L"CAR6K::WARNING!!!! :: ReadFile Error :: ====>"); status = A_ERROR; break; } next_address = address + fileSize - file_left; // // We round up the requested length because some SDIO Host controllers can't handle other lengths. // This generally isn't a problem for users, but it's something to be aware of. // length = A_ROUND_UP(length, 4); if (bCompressed) { status = BMILZData(hifDevice, buffer, length); } else { status = BMIWriteMemory(hifDevice, next_address, buffer, length); } if (status != A_OK) { break; } if (fillCache) { CopyChunkToBinCache(pBinCache, buffer, length); } if (file_left >= MAX_BUF) { file_left = file_left - MAX_BUF; } else { file_left = 0; } }; if (status != A_OK) { break; } if (fillCache) { /* cache was filled, mark it valid */ pBinCache->Valid = TRUE; } if (bCompressed) { // // Close compressed stream and open a new (fake) one. This serves mainly to flush Target caches. // status = BMILZStreamStart (hifDevice, 0x00); if (status != A_OK) { break; } } } while (FALSE); if (buffer) { free (buffer); buffer = NULL; } if (fd) { CloseHandle (fd); } return status; }
A_STATUS apply_patch (HIF_DEVICE *hifDevice, A_UINT32 TargetVersion, wchar_t *patchFile, wchar_t *fileRoot, AR6K_BIN_CACHE_INFO *pRomCache) { A_STATUS status = A_OK; HANDLE fd = INVALID_HANDLE_VALUE; wchar_t filePath[128]; A_UINT32 ret = 0; A_UINT32 id = 0; A_UINT32 tpid = 0; A_UINT32 chkSum = 0; A_UINT32 count = 0; A_UINT32 max = 0; A_UINT32 cmd = 0; A_UINT32 romAddr = 0; A_UINT32 ramAddr = 0; A_UINT32 reMapSz = 0; A_UCHAR *buffer = NULL; A_UINT32 length = 0; A_UINT32 i = 0; BY_HANDLE_FILE_INFORMATION finfo; A_UINT32 fileSize = 0; do { if (pRomCache->Valid) { buffer = pRomCache->pData; fileSize = pRomCache->ActualLength; } else { if ( wcslen(patchFile) + wcslen(fileRoot) > 127 ) { ATHR_DISPLAY_MSG (L"CAR6K::WARNING!!!! :: File Name Very Long :: ====>"); return A_ERROR; } wcscpy(filePath,fileRoot); wcscat(filePath,patchFile); ATHR_DISPLAY_MSG (L"file %s \n",filePath); //Read the patch distribution file if ( (fd = CreateFile (filePath, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE) { ATHR_DISPLAY_MSG (L"CAR6K:: No Patch File :: ====> %s", filePath); break; } if (!GetFileInformationByHandle(fd, &finfo)) { ATHR_DISPLAY_MSG (L"CAR6K::WARNING!!!! :: File Size Error :: ====> %s", filePath); status = A_ERROR; break; } fileSize = finfo.nFileSizeLow; if ((buffer=A_MALLOC(fileSize)) == NULL) { ATHR_DISPLAY_MSG (L"CAR6K::WARNING!!!! :: Unable allocated memory :: ====> %d",fileSize); status = A_ERROR; break; } if ( !ReadFile(fd, buffer, fileSize, &ret, NULL) || (ret != fileSize)) { ATHR_DISPLAY_MSG (L"CAR6K::WARNING!!!! :: Unable to read rpdf ID from :: ====> %s",filePath); status = A_ERROR; break; } if (pRomCache->Static) { pRomCache->Valid = TRUE; pRomCache->pData = buffer; pRomCache->ActualLength = fileSize; pRomCache->MaxLength = fileSize; } } id = *((A_UINT32 *)buffer); buffer += sizeof(id); chkSum = *((A_UINT32 *)buffer); buffer += sizeof(chkSum); count = *((A_UINT32 *)buffer); buffer += sizeof(count); if ( TargetVersion == AR6002_VERSION_REV2 ) { max = AR6002_REV2_MAX_PATCHES; } if (count > max) { ATHR_DISPLAY_MSG (L"CAR6K::WARNING!!!! :: Maximum patches supported :: %d ====> %d",max,count); status = A_ERROR; break; } for (; count; count--) { cmd = 0; romAddr = 0; ramAddr = 0; reMapSz = 0; length = 0; tpid = 0; cmd = *((A_UINT32 *)buffer); buffer += sizeof(cmd); if ( cmd != RPDF_CMD_INSTALL && cmd != RPDF_CMD_INST_ACT ) { ATHR_DISPLAY_MSG (L"CAR6K::WARNING!!!! :: Unknown command in patch specification :: ====> %d",cmd); status = A_ERROR; break; } reMapSz= *((A_UINT32 *)buffer); buffer += sizeof(reMapSz); if ( reMapSz == 0 || reMapSz & (reMapSz-1) ) { ATHR_DISPLAY_MSG (L"CAR6K::WARNING!!!! :: Invalid remap size :: ====> 0x%x",reMapSz); status = A_ERROR; break; } romAddr= *((A_UINT32 *)buffer); buffer += sizeof(romAddr); ramAddr= *((A_UINT32 *)buffer); buffer += sizeof(ramAddr); length= *((A_UINT32 *)buffer); buffer += sizeof(length); if (length > 0) { status = BMIWriteMemory(hifDevice, ramAddr, buffer, length); if (status != A_OK) { ATHR_DISPLAY_MSG (L"CAR6K::WARNING!!!! :: Unable write patch to target :: ====> "); break; } buffer += length; } if (cmd == RPDF_CMD_INST_ACT || cmd == RPDF_CMD_INSTALL) { status = BMIrompatchInstall(hifDevice, romAddr, ramAddr, reMapSz, 0, &tpid); if (status != A_OK) { ATHR_DISPLAY_MSG (L"CAR6K::WARNING!!!! :: Unable write patch registers in target :: ====> "); break; } InstalledPatches[NumPatches++] = tpid; } if (cmd == RPDF_CMD_INST_ACT && NumPatches) { status = BMIrompatchActivate(hifDevice, NumPatches, InstalledPatches); if (status != A_OK) { ATHR_DISPLAY_MSG (L"CAR6K::WARNING!!!! :: Unable activate patch in target :: ====> "); break; } } } } while (FALSE); if ((!pRomCache->Valid) && (buffer)) { A_FREE(buffer); } if (fd) { CloseHandle (fd); } NumPatches = 0; return status; }
int ar6000_htc_raw_open(AR_SOFTC_T *ar) { A_STATUS status; int streamID, endPt, count2; raw_htc_buffer *buffer; HTC_SERVICE_ID servicepriority; AR_RAW_HTC_T *arRaw = ar->arRawHtc; if (!arRaw) { arRaw = ar->arRawHtc = A_MALLOC(sizeof(AR_RAW_HTC_T)); if (arRaw) { A_MEMZERO(arRaw, sizeof(AR_RAW_HTC_T)); } } A_ASSERT(ar->arHtcTarget != NULL); if (!arRaw) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Faile to allocate memory for HTC RAW interface\n")); return -ENOMEM; } /* wait for target */ status = HTCWaitTarget(ar->arHtcTarget); if (A_FAILED(status)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HTCWaitTarget failed (%d)\n", status)); return -ENODEV; } for (endPt = 0; endPt < ENDPOINT_MAX; endPt++) { arRaw->arEp2RawMapping[endPt] = HTC_RAW_STREAM_NOT_MAPPED; } for (streamID = HTC_RAW_STREAM_0; streamID < HTC_RAW_STREAM_NUM_MAX; streamID++) { /* Initialize the data structures */ init_MUTEX(&arRaw->raw_htc_read_sem[streamID]); init_MUTEX(&arRaw->raw_htc_write_sem[streamID]); init_waitqueue_head(&arRaw->raw_htc_read_queue[streamID]); init_waitqueue_head(&arRaw->raw_htc_write_queue[streamID]); /* try to connect to the raw service */ status = ar6000_connect_raw_service(ar,streamID); if (A_FAILED(status)) { break; } if (arRawStream2EndpointID(ar,streamID) == 0) { break; } for (count2 = 0; count2 < RAW_HTC_READ_BUFFERS_NUM; count2 ++) { /* Initialize the receive buffers */ buffer = &arRaw->raw_htc_write_buffer[streamID][count2]; memset(buffer, 0, sizeof(raw_htc_buffer)); buffer = &arRaw->raw_htc_read_buffer[streamID][count2]; memset(buffer, 0, sizeof(raw_htc_buffer)); SET_HTC_PACKET_INFO_RX_REFILL(&buffer->HTCPacket, buffer, buffer->data, HTC_RAW_BUFFER_SIZE, arRawStream2EndpointID(ar,streamID)); /* Queue buffers to HTC for receive */ if ((status = HTCAddReceivePkt(ar->arHtcTarget, &buffer->HTCPacket)) != A_OK) { BMIInit(); return -EIO; } } for (count2 = 0; count2 < RAW_HTC_WRITE_BUFFERS_NUM; count2 ++) { /* Initialize the receive buffers */ buffer = &arRaw->raw_htc_write_buffer[streamID][count2]; memset(buffer, 0, sizeof(raw_htc_buffer)); } arRaw->read_buffer_available[streamID] = FALSE; arRaw->write_buffer_available[streamID] = TRUE; } if (A_FAILED(status)) { return -EIO; } AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("HTC RAW, number of streams the target supports: %d \n", streamID)); servicepriority = HTC_RAW_STREAMS_SVC; /* only 1 */ /* set callbacks and priority list */ HTCSetCreditDistribution(ar->arHtcTarget, ar, NULL, /* use default */ NULL, /* use default */ &servicepriority, 1); /* Start the HTC component */ if ((status = HTCStart(ar->arHtcTarget)) != A_OK) { BMIInit(); return -EIO; } (ar)->arRawIfInit = TRUE; return 0; }
int PSSendOps(void *arg) { int i; int status = 0; struct ps_cmd_packet *HciCmdList; /* List storing the commands */ const struct firmware* firmware; u32 numCmds; u8 *event; u8 *bufferToFree; struct hci_dev *device; u8 *buffer; u32 len; u32 DevType; u8 *PsFileName; u8 *patchFileName; u8 *path = NULL; u8 *config_path = NULL; u8 config_bdaddr[MAX_BDADDR_FORMAT_LENGTH]; struct ar3k_config_info *hdev = (struct ar3k_config_info*)arg; struct device *firmwareDev = NULL; status = 0; HciCmdList = NULL; #ifdef HCI_TRANSPORT_SDIO device = hdev->pBtStackHCIDev; firmwareDev = device->parent; #else device = hdev; firmwareDev = &device->dev; AthEnableSyncCommandOp(true); #endif /* HCI_TRANSPORT_SDIO */ /* First verify if the controller is an FPGA or ASIC, so depending on the device type the PS file to be written will be different. */ path =(u8 *)A_MALLOC(MAX_FW_PATH_LEN); if(path == NULL) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Malloc failed to allocate %d bytes for path\n", MAX_FW_PATH_LEN)); goto complete; } config_path = (u8 *) A_MALLOC(MAX_FW_PATH_LEN); if(config_path == NULL) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Malloc failed to allocate %d bytes for config_path\n", MAX_FW_PATH_LEN)); goto complete; } if(A_ERROR == getDeviceType(hdev,&DevType)) { status = 1; goto complete; } if(A_ERROR == ReadVersionInfo(hdev)) { status = 1; goto complete; } patchFileName = PATCH_FILE; snprintf(path, MAX_FW_PATH_LEN, "%s/%xcoex/",CONFIG_PATH,Rom_Version); if(DevType){ if(DevType == 0xdeadc0de){ PsFileName = PS_ASIC_FILE; } else{ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" FPGA Test Image : %x %x \n",Rom_Version,Build_Version)); if((Rom_Version == 0x99999999) && (Build_Version == 1)){ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("FPGA Test Image : Skipping Patch File load\n")); patchFileName = NULL; } PsFileName = PS_FPGA_FILE; } } else{ PsFileName = PS_ASIC_FILE; } snprintf(config_path, MAX_FW_PATH_LEN, "%s%s",path,PsFileName); AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%x: FPGA/ASIC PS File Name %s\n", DevType,config_path)); /* Read the PS file to a dynamically allocated buffer */ if(A_REQUEST_FIRMWARE(&firmware,config_path,firmwareDev) < 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: firmware file open error\n", __FUNCTION__ )); status = 1; goto complete; } if(NULL == firmware || firmware->size == 0) { status = 1; goto complete; } buffer = (u8 *)A_MALLOC(firmware->size); if(buffer != NULL) { /* Copy the read file to a local Dynamic buffer */ memcpy(buffer,firmware->data,firmware->size); len = firmware->size; A_RELEASE_FIRMWARE(firmware); /* Parse the PS buffer to a global variable */ status = AthDoParsePS(buffer,len); kfree(buffer); } else { A_RELEASE_FIRMWARE(firmware); } /* Read the patch file to a dynamically allocated buffer */ if(patchFileName != NULL) snprintf(config_path, MAX_FW_PATH_LEN, "%s%s",path,patchFileName); else { status = 0; } AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Patch File Name %s\n", config_path)); if((patchFileName == NULL) || (A_REQUEST_FIRMWARE(&firmware,config_path,firmwareDev) < 0)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: firmware file open error\n", __FUNCTION__ )); /* * It is not necessary that Patch file be available, continue with PS Operations if. * failed. */ status = 0; } else { if(NULL == firmware || firmware->size == 0) { status = 0; } else { buffer = (u8 *)A_MALLOC(firmware->size); if(buffer != NULL) { /* Copy the read file to a local Dynamic buffer */ memcpy(buffer,firmware->data,firmware->size); len = firmware->size; A_RELEASE_FIRMWARE(firmware); /* parse and store the Patch file contents to a global variables */ status = AthDoParsePatch(buffer,len); kfree(buffer); } else { A_RELEASE_FIRMWARE(firmware); } } } /* Create an HCI command list from the parsed PS and patch information */ AthCreateCommandList(&HciCmdList,&numCmds); /* Form the parameter for PSSendOps() API */ /* * First Send the CRC packet, * We have to continue with the PS operations only if the CRC packet has been replied with * a Command complete event with status Error. */ if(SendHCICommandWaitCommandComplete (hdev, HciCmdList[0].Hcipacket, HciCmdList[0].packetLen, &event, &bufferToFree) == 0) { if(ReadPSEvent(event) == 0) { /* Exit if the status is success */ if(bufferToFree != NULL) { kfree(bufferToFree); } #ifndef HCI_TRANSPORT_SDIO if(bdaddr && bdaddr[0] !='\0') { write_bdaddr(hdev,bdaddr,BDADDR_TYPE_STRING); } #endif status = 1; goto complete; } if(bufferToFree != NULL) { kfree(bufferToFree); } } else { status = 0; goto complete; } for(i = 1; i <numCmds; i++) { if(SendHCICommandWaitCommandComplete (hdev, HciCmdList[i].Hcipacket, HciCmdList[i].packetLen, &event, &bufferToFree) == 0) { if(ReadPSEvent(event) != 0) { /* Exit if the status is success */ if(bufferToFree != NULL) { kfree(bufferToFree); } status = 1; goto complete; } if(bufferToFree != NULL) { kfree(bufferToFree); } } else { status = 0; goto complete; } } #ifdef HCI_TRANSPORT_SDIO if(BDADDR == false) if(hdev->bdaddr[0] !=0x00 || hdev->bdaddr[1] !=0x00 || hdev->bdaddr[2] !=0x00 || hdev->bdaddr[3] !=0x00 || hdev->bdaddr[4] !=0x00 || hdev->bdaddr[5] !=0x00) write_bdaddr(hdev,hdev->bdaddr,BDADDR_TYPE_HEX); #ifndef HCI_TRANSPORT_SDIO if(bdaddr && bdaddr[0] != '\0') { write_bdaddr(hdev,bdaddr,BDADDR_TYPE_STRING); } else #endif /* HCI_TRANSPORT_SDIO */ /* Write BDADDR Read from OTP here */ #endif { /* Read Contents of BDADDR file if user has not provided any option */ snprintf(config_path,MAX_FW_PATH_LEN, "%s%s",path,BDADDR_FILE); AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Patch File Name %s\n", config_path)); if(A_REQUEST_FIRMWARE(&firmware,config_path,firmwareDev) < 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: firmware file open error\n", __FUNCTION__ )); status = 1; goto complete; } if(NULL == firmware || firmware->size == 0) { status = 1; goto complete; } len = min_t(size_t, firmware->size, MAX_BDADDR_FORMAT_LENGTH - 1); memcpy(config_bdaddr, firmware->data, len); config_bdaddr[len] = '\0'; write_bdaddr(hdev,config_bdaddr,BDADDR_TYPE_STRING); A_RELEASE_FIRMWARE(firmware); } complete: #ifndef HCI_TRANSPORT_SDIO AthEnableSyncCommandOp(false); PSTagMode = false; wake_up_interruptible(&PsCompleteEvent); #endif /* HCI_TRANSPORT_SDIO */ if(NULL != HciCmdList) { AthFreeCommandList(&HciCmdList,numCmds); } if(path) { kfree(path); } if(config_path) { kfree(config_path); } return status; }
NDIS_STATUS busDriverInit (NDIS_HANDLE miniportHandle, NDIS_HANDLE wrapperConfigurationContext, A_UINT32 sysIntr, BUS_DRIVER_HANDLE *busDriverHandle) { PNDIS_RESOURCE_LIST pNdisResourceList; PCM_PARTIAL_RESOURCE_DESCRIPTOR pResourceDesc; NDIS_PHYSICAL_ADDRESS physicalAddress; A_UINT32 bufferSize; A_UINT32 dwResourceCount; NDIS_STATUS status=NDIS_STATUS_FAILURE; A_UINT32 addressSpace; *busDriverHandle = NULL; HIF_DEBUG_PRINTF(ATH_LOG_TRC, "ar6000CFBusInit: Enter \n"); cfDevice = A_MALLOC(sizeof(CF_DEVICE)); if (cfDevice == NULL) { HIF_DEBUG_PRINTF(ATH_LOG_ERR, "ar6000CFBusInit: Allocate Memory for CF_DEVICE failed\n"); return status; } A_MEMZERO(cfDevice,sizeof(CF_DEVICE)); cfDevice->miniportHandle = miniportHandle; cfDevice->wrapperConfigurationContext=wrapperConfigurationContext; pNdisResourceList = NULL; bufferSize = 0; // First call is just to determine buffer size NdisMQueryAdapterResources( &status, wrapperConfigurationContext, pNdisResourceList, &bufferSize); pNdisResourceList = A_MALLOC(bufferSize); if (pNdisResourceList == NULL) { HIF_DEBUG_PRINTF(ATH_LOG_ERR, "ar6000CFBusInit: AllocateMemory for NDIS_RESOURCE_LIST failed\n"); A_FREE(cfDevice); return NDIS_STATUS_FAILURE; } NdisMQueryAdapterResources( &status, wrapperConfigurationContext, pNdisResourceList, &bufferSize); if (status != NDIS_STATUS_SUCCESS) { HIF_DEBUG_PRINTF(ATH_LOG_ERR, "ar6000CFBusInit: NdisMQueryAdapterResources failed \n"); A_FREE(pNdisResourceList); A_FREE(cfDevice); return status; } /* Search for I/O address and IRQ in assigned resources. */ dwResourceCount = pNdisResourceList->Count; pResourceDesc = &(pNdisResourceList->PartialDescriptors[0]); while (dwResourceCount--) { switch(pResourceDesc->Type) { case CmResourceTypeInterrupt: cfDevice->interruptNumber = pResourceDesc->u.Interrupt.Vector; HIF_DEBUG_PRINTF(ATH_LOG_INF, "ar6000CFBusInit: Interrupt Number = %u\n", cfDevice->interruptNumber); break; case CmResourceTypeMemory: cfDevice->memLen = pResourceDesc->u.Memory.Length; cfDevice->deviceMemBase = pResourceDesc->u.Memory.Start.LowPart; HIF_DEBUG_PRINTF(ATH_LOG_INF, "ar6000CFBusInit: Physical Address = %x Length = %x\n", cfDevice->deviceMemBase,cfDevice->memLen); break; default: HIF_DEBUG_PRINTF(ATH_LOG_ERR, "ar6000CFBusInit: Unexpected assigned resource type %u\n", pResourceDesc->Type); break; } pResourceDesc++; } A_FREE(pNdisResourceList); cfDevice->sysIntr = sysIntr; HIF_DEBUG_PRINTF(ATH_LOG_INF, "ar6000CFBusInit: sysIntr = %u\n", cfDevice->sysIntr); NdisSetPhysicalAddressLow(physicalAddress, cfDevice->deviceMemBase); NdisSetPhysicalAddressHigh(physicalAddress, 0); cfDevice->ndisMapped = 1; status = NdisMMapIoSpace((PVOID *)&cfDevice->mappedMemBase, cfDevice->miniportHandle, physicalAddress, cfDevice->memLen); if (status != NDIS_STATUS_SUCCESS) { HIF_DEBUG_PRINTF(ATH_LOG_ERR, "ar6000CFBusInit: NdisMmapIoSpace failed.. Trying MmMapIoSpace \n"); /* NdisMmapIoSpace fails sometimes in WINCE, type MmMapIoSpace */ cfDevice->mappedMemBase = (A_UINT32) MmMapIoSpace(physicalAddress, cfDevice->memLen, FALSE); if (!cfDevice->mappedMemBase) { HIF_DEBUG_PRINTF(ATH_LOG_ERR, "ar6000CFBusInit: MmMapIoSpace failed \n"); A_FREE(cfDevice); return NDIS_STATUS_FAILURE; } cfDevice->ndisMapped = 0; } addressSpace = 0; #ifdef SHARED_INTERRUPTS #if (UNDER_CE==600) giisrMappedAddress = (PVOID)cfDevice->mappedMemBase; #else if (!TransBusAddrToStatic(PCIBus, 0, physicalAddress, cfDevice->memLen, &addressSpace, &giisrMappedAddress)) { HIF_DEBUG_PRINTF(ATH_LOG_ERR, "ar6000CFBusInit : TransBusAddrToStatic failed \n"); A_FREE(cfDevice); return NDIS_STATUS_FAILURE; } #endif //UNDER_CE #endif //SHARED_INTERRUPTS *busDriverHandle = (BUS_DRIVER_HANDLE)cfDevice; HIF_DEBUG_PRINTF(ATH_LOG_TRC, "ar6000CFBusInit: Exit \n"); return NDIS_STATUS_SUCCESS; }
/* registered target arrival callback from the HIF layer */ HTC_HANDLE HTCCreate(void *hif_handle, HTC_INIT_INFO *pInfo) { HTC_TARGET *target = NULL; A_STATUS status = A_OK; int i; A_UINT32 ctrl_bufsz; A_UINT32 blocksizes[HTC_MAILBOX_NUM_MAX]; AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCCreate - Enter\n")); printk("HTCCreate !!\n"); do { /* allocate target memory */ if ((target = (HTC_TARGET *)A_MALLOC(sizeof(HTC_TARGET))) == NULL) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to allocate memory\n")); status = A_ERROR; break; } A_MEMZERO(target, sizeof(HTC_TARGET)); A_MUTEX_INIT(&target->HTCLock); A_MUTEX_INIT(&target->HTCRxLock); A_MUTEX_INIT(&target->HTCTxLock); INIT_HTC_PACKET_QUEUE(&target->ControlBufferTXFreeList); INIT_HTC_PACKET_QUEUE(&target->ControlBufferRXFreeList); /* give device layer the hif device handle */ target->Device.HIFDevice = hif_handle; /* give the device layer our context (for event processing) * the device layer will register it's own context with HIF * so we need to set this so we can fetch it in the target remove handler */ target->Device.HTCContext = target; /* set device layer target failure callback */ target->Device.TargetFailureCallback = HTCReportFailure; /* set device layer recv message pending callback */ target->Device.MessagePendingCallback = HTCRecvMessagePendingHandler; target->EpWaitingForBuffers = ENDPOINT_MAX; A_MEMCPY(&target->HTCInitInfo,pInfo,sizeof(HTC_INIT_INFO)); /* setup device layer */ status = DevSetup(&target->Device); if (A_FAILED(status)) { break; } /* get the block sizes */ status = HIFConfigureDevice(hif_handle, HIF_DEVICE_GET_MBOX_BLOCK_SIZE, blocksizes, sizeof(blocksizes)); if (A_FAILED(status)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to get block size info from HIF layer...\n")); break; } /* Set the control buffer size based on the block size */ if (blocksizes[1] > HTC_MAX_CONTROL_MESSAGE_LENGTH) { ctrl_bufsz = blocksizes[1] + HTC_HDR_LENGTH; } else { ctrl_bufsz = HTC_MAX_CONTROL_MESSAGE_LENGTH + HTC_HDR_LENGTH; } for (i = 0;i < NUM_CONTROL_BUFFERS;i++) { target->HTCControlBuffers[i].Buffer = A_MALLOC(ctrl_bufsz); if (target->HTCControlBuffers[i].Buffer == NULL) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to allocate memory\n")); status = A_ERROR; break; } } if (A_FAILED(status)) { break; } /* carve up buffers/packets for control messages */ for (i = 0; i < NUM_CONTROL_RX_BUFFERS; i++) { HTC_PACKET *pControlPacket; pControlPacket = &target->HTCControlBuffers[i].HtcPacket; SET_HTC_PACKET_INFO_RX_REFILL(pControlPacket, target, target->HTCControlBuffers[i].Buffer, ctrl_bufsz, ENDPOINT_0); HTC_FREE_CONTROL_RX(target,pControlPacket); } for (;i < NUM_CONTROL_BUFFERS;i++) { HTC_PACKET *pControlPacket; pControlPacket = &target->HTCControlBuffers[i].HtcPacket; INIT_HTC_PACKET_INFO(pControlPacket, target->HTCControlBuffers[i].Buffer, ctrl_bufsz); HTC_FREE_CONTROL_TX(target,pControlPacket); } } while (FALSE); if (A_FAILED(status)) { if (target != NULL) { HTCCleanup(target); target = NULL; } } AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCCreate - Exit\n")); return target; }
/* setup of HIF scatter resources */ A_STATUS SetupHIFScatterSupport(HIF_DEVICE *device, HIF_DEVICE_SCATTER_SUPPORT_INFO *pInfo) { A_STATUS status = A_ERROR; int i; HIF_SCATTER_REQ_PRIV *pReqPriv; BUS_REQUEST *busrequest; do { /* check if host supports scatter requests and it meets our requirements */ if (device->func->card->host->max_segs < MAX_SCATTER_ENTRIES_PER_REQ) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HIF-SCATTER : host only supports scatter of : %d entries, need: %d \n", device->func->card->host->max_segs, MAX_SCATTER_ENTRIES_PER_REQ)); status = A_ENOTSUP; break; } AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("HIF-SCATTER Enabled: max scatter req : %d entries: %d \n", MAX_SCATTER_REQUESTS, MAX_SCATTER_ENTRIES_PER_REQ)); for (i = 0; i < MAX_SCATTER_REQUESTS; i++) { /* allocate the private request blob */ pReqPriv = (HIF_SCATTER_REQ_PRIV *)A_MALLOC(sizeof(HIF_SCATTER_REQ_PRIV)); if (NULL == pReqPriv) { break; } A_MEMZERO(pReqPriv, sizeof(HIF_SCATTER_REQ_PRIV)); /* save the device instance*/ pReqPriv->device = device; /* allocate the scatter request */ pReqPriv->pHifScatterReq = (HIF_SCATTER_REQ *)A_MALLOC(sizeof(HIF_SCATTER_REQ) + (MAX_SCATTER_ENTRIES_PER_REQ - 1) * (sizeof(HIF_SCATTER_ITEM))); if (NULL == pReqPriv->pHifScatterReq) { A_FREE(pReqPriv); break; } /* just zero the main part of the scatter request */ A_MEMZERO(pReqPriv->pHifScatterReq, sizeof(HIF_SCATTER_REQ)); /* back pointer to the private struct */ pReqPriv->pHifScatterReq->HIFPrivate[0] = pReqPriv; /* allocate a bus request for this scatter request */ busrequest = hifAllocateBusRequest(device); if (NULL == busrequest) { A_FREE(pReqPriv->pHifScatterReq); A_FREE(pReqPriv); break; } /* assign the scatter request to this bus request */ busrequest->pScatterReq = pReqPriv; /* point back to the request */ pReqPriv->busrequest = busrequest; /* add it to the scatter pool */ FreeScatterReq(device,pReqPriv->pHifScatterReq); } if (i != MAX_SCATTER_REQUESTS) { status = A_NO_MEMORY; AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HIF-SCATTER : failed to alloc scatter resources !\n")); break; } /* set scatter function pointers */ pInfo->pAllocateReqFunc = AllocScatterReq; pInfo->pFreeReqFunc = FreeScatterReq; pInfo->pReadWriteScatterFunc = HifReadWriteScatter; pInfo->MaxScatterEntries = MAX_SCATTER_ENTRIES_PER_REQ; pInfo->MaxTransferSizePerScatterReq = MAX_SCATTER_REQ_TRANSFER_SIZE; status = A_OK; } while (FALSE); if (A_FAILED(status)) { CleanupHIFScatterResources(device); } return status; }
/* 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; }
A_STATUS ar6000_setup_hci(AR_SOFTC_T *ar) #endif { HCI_TRANSPORT_CONFIG_INFO config; A_STATUS status = A_OK; int i; HTC_PACKET *pPacket; AR6K_HCI_BRIDGE_INFO *pHcidevInfo; do { pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)A_MALLOC(sizeof(AR6K_HCI_BRIDGE_INFO)); if (NULL == pHcidevInfo) { status = A_NO_MEMORY; break; } A_MEMZERO(pHcidevInfo, sizeof(AR6K_HCI_BRIDGE_INFO)); #ifdef EXPORT_HCI_BRIDGE_INTERFACE g_pHcidevInfo = pHcidevInfo; pHcidevInfo->HCITransHdl = *(HCI_TRANSPORT_MISC_HANDLES *)ar; #else ar->hcidev_info = pHcidevInfo; pHcidevInfo->ar = ar; #endif spin_lock_init(&pHcidevInfo->BridgeLock); INIT_HTC_PACKET_QUEUE(&pHcidevInfo->HTCPacketStructHead); ar->exitCallback = AR3KConfigureExit; status = bt_setup_hci(pHcidevInfo); if (A_FAILED(status)) { break; } if (pHcidevInfo->HciNormalMode) { AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: running in normal mode... \n")); } else { AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: running in test mode... \n")); } pHcidevInfo->pHTCStructAlloc = (A_UINT8 *)A_MALLOC((sizeof(HTC_PACKET)) * NUM_HTC_PACKET_STRUCTS); if (NULL == pHcidevInfo->pHTCStructAlloc) { status = A_NO_MEMORY; break; } pPacket = (HTC_PACKET *)pHcidevInfo->pHTCStructAlloc; for (i = 0; i < NUM_HTC_PACKET_STRUCTS; i++,pPacket++) { FreeHTCStruct(pHcidevInfo,pPacket); } A_MEMZERO(&config,sizeof(HCI_TRANSPORT_CONFIG_INFO)); config.ACLRecvBufferWaterMark = MAX_ACL_RECV_BUFS / 2; config.EventRecvBufferWaterMark = MAX_EVT_RECV_BUFS / 2; config.MaxSendQueueDepth = MAX_HCI_WRITE_QUEUE_DEPTH; config.pContext = pHcidevInfo; config.TransportFailure = ar6000_hci_transport_failure; config.TransportReady = ar6000_hci_transport_ready; config.TransportRemoved = ar6000_hci_transport_removed; config.pHCISendComplete = ar6000_hci_send_complete; config.pHCIPktRecv = ar6000_hci_pkt_recv; config.pHCIPktRecvRefill = ar6000_hci_pkt_refill; config.pHCISendFull = ar6000_hci_pkt_send_full; #ifdef EXPORT_HCI_BRIDGE_INTERFACE pHcidevInfo->pHCIDev = HCI_TransportAttach(pHcidevInfo->HCITransHdl.htcHandle, &config); #else pHcidevInfo->pHCIDev = HCI_TransportAttach(ar->arHtcTarget, &config); #endif if (NULL == pHcidevInfo->pHCIDev) { status = A_ERROR; } } while (FALSE); if (A_FAILED(status)) { if (pHcidevInfo != NULL) { if (NULL == pHcidevInfo->pHCIDev) { /* GMBOX may not be present in older chips */ /* just return success */ status = A_OK; } } ar6000_cleanup_hci(ar); } return status; }