/* set HTC/Mbox operational parameters, this can only be called when the target is in the * BMI phase */ A_STATUS ar6000_set_htc_params(HIF_DEVICE *hifDevice, A_UINT32 TargetType, A_UINT32 MboxIsrYieldValue, A_UINT8 HtcControlBuffers) { A_STATUS status; A_UINT32 blocksizes[HTC_MAILBOX_NUM_MAX]; do { /* get the block sizes */ status = HIFConfigureDevice(hifDevice, HIF_DEVICE_GET_MBOX_BLOCK_SIZE, blocksizes, sizeof(blocksizes)); if (A_FAILED(status)) { AR_DEBUG_PRINTF(ATH_LOG_ERR,("Failed to get block size info from HIF layer...\n")); break; } /* note: we actually get the block size for mailbox 1, for SDIO the block * size on mailbox 0 is artificially set to 1 */ /* must be a power of 2 */ A_ASSERT((blocksizes[1] & (blocksizes[1] - 1)) == 0); if (HtcControlBuffers != 0) { /* set override for number of control buffers to use */ blocksizes[1] |= ((A_UINT32)HtcControlBuffers) << 16; } /* set the host interest area for the block size */ status = BMIWriteMemory(hifDevice, HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_mbox_io_block_sz), (A_UCHAR *)&blocksizes[1], 4); if (A_FAILED(status)) { AR_DEBUG_PRINTF(ATH_LOG_ERR,("BMIWriteMemory for IO block size failed \n")); break; } AR_DEBUG_PRINTF(ATH_LOG_INF,("Block Size Set: %d (target address:0x%X)\n", blocksizes[1], HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_mbox_io_block_sz))); if (MboxIsrYieldValue != 0) { /* set the host interest area for the mbox ISR yield limit */ status = BMIWriteMemory(hifDevice, HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_mbox_isr_yield_limit), (A_UCHAR *)&MboxIsrYieldValue, 4); if (A_FAILED(status)) { AR_DEBUG_PRINTF(ATH_LOG_ERR,("BMIWriteMemory for yield limit failed \n")); break; } } } while (FALSE); return status; }
/* can only be called during bmi init stage */ A_STATUS ar6000_set_hci_bridge_flags(HIF_DEVICE *hifDevice, A_UINT32 TargetType, A_UINT32 Flags) { A_STATUS status = A_OK; do { if (TargetType != TARGET_TYPE_AR6003) { AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("Target Type:%d, does not support HCI bridging! \n", TargetType)); break; } /* set hci bridge flags */ status = BMIWriteMemory(hifDevice, HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_hci_bridge_flags), (A_UCHAR *)&Flags, 4); } while (FALSE); return status; }
/* This should be called in BMI phase after firmware is downloaded */ void ar6000_copy_cust_data_from_target(HIF_DEVICE *hifDevice, A_UINT32 TargetType) { A_UINT32 eepHeaderAddr; A_UINT8 AR6003CustDataShadow[AR6003_CUST_DATA_SIZE+4]; A_UINT8 MCKINLEYCustDataShadow[MCKINLEY_CUST_DATA_SIZE+4]; A_INT32 i; if (BMIReadMemory(hifDevice, HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_board_data), (A_UCHAR *)&eepHeaderAddr, 4)!= A_OK) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMIReadMemory for reading board data address failed \n")); return; } if (TargetType == TARGET_TYPE_MCKINLEY) { eepHeaderAddr += 36; /* MCKINLEY customer data section offset is 37 */ for (i=0; i<MCKINLEY_CUST_DATA_SIZE+4; i+=4){ if (BMIReadSOCRegister(hifDevice, eepHeaderAddr, (A_UINT32 *)&MCKINLEYCustDataShadow[i])!= A_OK) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMIReadSOCRegister () failed \n")); return ; } eepHeaderAddr +=4; } memcpy(custDataMCKINLEY, MCKINLEYCustDataShadow+1, MCKINLEY_CUST_DATA_SIZE); } if (TargetType == TARGET_TYPE_AR6003) { eepHeaderAddr += 36; /* AR6003 customer data section offset is 37 */ for (i=0; i<AR6003_CUST_DATA_SIZE+4; i+=4){ if (BMIReadSOCRegister(hifDevice, eepHeaderAddr, (A_UINT32 *)&AR6003CustDataShadow[i])!= A_OK) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMIReadSOCRegister () failed \n")); return ; } eepHeaderAddr +=4; } memcpy(custDataAR6003, AR6003CustDataShadow+1, AR6003_CUST_DATA_SIZE); } if (TargetType == TARGET_TYPE_AR6002) { eepHeaderAddr += 64; /* AR6002 customer data sectioin offset is 64 */ for (i=0; i<AR6002_CUST_DATA_SIZE; i+=4){ if (BMIReadSOCRegister(hifDevice, eepHeaderAddr, (A_UINT32 *)&custDataAR6002[i])!= A_OK) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMIReadSOCRegister () failed \n")); return ; } eepHeaderAddr +=4; } } return; }
static A_STATUS prepare_MCKINLEY(HIF_DEVICE *hifDevice, A_UINT32 TargetVersion) { A_STATUS status = A_OK; A_UINT32 value = 0; /* force the setting to disable sleep for Bringup FIXME_MK */ value |= WLAN_SYSTEM_SLEEP_DISABLE_MASK; status = BMIWriteMemory(hifDevice, HOST_INTEREST_ITEM_ADDRESS(TARGET_TYPE_AR6002, hi_system_sleep_setting), (A_UCHAR *)&value, 4); return status; }
A_UINT32 dbglog_get_debug_hdr_ptr(A_UINT32 tgtType, HIF_DEVICE *device) { A_UINT32 param = 0; A_UINT32 address = 0; A_STATUS status = A_OK; address = HOST_INTEREST_ITEM_ADDRESS(tgtType, hi_dbglog_hdr); if ((status = ar6000_ReadDataDiag(device, address, (A_UCHAR *)¶m, 4)) != A_OK) { param = 0; } return param; }
void ar6000_dump_target_assert_info(HIF_DEVICE *hifDevice, A_UINT32 TargetType) { A_UINT32 address; A_UINT32 regDumpArea = 0; A_STATUS status; A_UINT32 regDumpValues[REGISTER_DUMP_LEN_MAX]; A_UINT32 regDumpCount = 0; A_UINT32 i; do { /* the reg dump pointer is copied to the host interest area */ address = HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_failure_state); if (TargetType == TARGET_TYPE_AR6001) { /* for AR6001, this is a fixed location because the ptr is actually stuck in cache, * this may be fixed in later firmware versions */ address = 0x18a0; regDumpCount = REG_DUMP_COUNT_AR6001; } else if (TargetType == TARGET_TYPE_AR6002) { regDumpCount = REG_DUMP_COUNT_AR6002; } else { A_ASSERT(0); } /* read RAM location through diagnostic window */ status = ar6000_ReadRegDiag(hifDevice, &address, ®DumpArea); if (A_FAILED(status)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Failed to get ptr to register dump area \n")); break; } AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Location of register dump data: 0x%X \n",regDumpArea)); if (regDumpArea == 0) { /* no reg dump */ break; } if (TargetType == TARGET_TYPE_AR6001) { regDumpArea &= 0x0FFFFFFF; /* convert to physical address in target memory */ } /* fetch register dump data */ status = ar6000_ReadDataDiag(hifDevice, regDumpArea, (A_UCHAR *)®DumpValues[0], regDumpCount * (sizeof(A_UINT32))); if (A_FAILED(status)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Failed to get register dump \n")); break; } AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Register Dump: \n")); for (i = 0; i < regDumpCount; i++) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" %d : 0x%8.8X \n",i, regDumpValues[i])); } } while (FALSE); }
void ar6000_dump_target_assert_info(HIF_DEVICE *hifDevice, A_UINT32 TargetType) { A_UINT32 address; A_UINT32 regDumpArea = 0; A_STATUS status; A_UINT32 regDumpValues[REGISTER_DUMP_LEN_MAX]; A_UINT32 regDumpCount = 0; A_UINT32 i; do { /* the reg dump pointer is copied to the host interest area */ address = HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_failure_state); address = TARG_VTOP(TargetType, address); if (TargetType == TARGET_TYPE_AR6001) { /* for AR6001, this is a fixed location because the ptr is actually stuck in cache, * this may be fixed in later firmware versions */ address = 0x18a0; regDumpCount = REG_DUMP_COUNT_AR6001; } else if (TargetType == TARGET_TYPE_AR6002) { regDumpCount = REG_DUMP_COUNT_AR6002; } else if (TargetType == TARGET_TYPE_AR6003) { regDumpCount = REG_DUMP_COUNT_AR6003; } else { A_ASSERT(0); } /* read RAM location through diagnostic window */ status = ar6000_ReadRegDiag(hifDevice, &address, ®DumpArea); if (A_FAILED(status)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Failed to get ptr to register dump area \n")); break; } AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Location of register dump data: 0x%X \n",regDumpArea)); if (regDumpArea == 0) { /* no reg dump */ break; } regDumpArea = TARG_VTOP(TargetType, regDumpArea); /* fetch register dump data */ status = ar6000_ReadDataDiag(hifDevice, regDumpArea, (A_UCHAR *)®DumpValues[0], regDumpCount * (sizeof(A_UINT32))); if (A_FAILED(status)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Failed to get register dump \n")); break; } AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Register Dump: \n")); for (i = 0; i < regDumpCount; i++) { //ATHR_DISPLAY_MSG (_T(" %d : 0x%8.8X \n"), i, regDumpValues[i]); AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" %d : 0x%8.8X \n",i, regDumpValues[i])); #ifdef UNDER_CE /* * For Every logPrintf() Open the File so that in case of Crashes * We will have until the Last Message Flushed on to the File * So use logPrintf Sparingly..!! */ tgtassertPrintf (ATH_DEBUG_TRC," %d: 0x%8.8X \n",i, regDumpValues[i]); #endif } } while (FALSE); }
static uint_32 ath_ioctl_handler_ext(A_VOID* enet_ptr, ATH_IOCTL_PARAM_STRUCT_PTR param_ptr) { A_VOID* pCxt; A_DRIVER_CONTEXT *pDCxt; A_STATUS status = A_OK; uint_32 error = ENET_OK; ATH_REGQUERY regQuery; uint_32 *ptr,i; if((pCxt = ((ENET_CONTEXT_STRUCT_PTR)enet_ptr)->MAC_CONTEXT_PTR) == NULL) { return ENET_ERROR; } pDCxt = GET_DRIVER_COMMON(pCxt); switch(param_ptr->cmd_id) { case ATH_REG_QUERY: /* set the operation to be executed by the driver thread */ pQuery = param_ptr->data; reg_query_bool = A_FALSE; if(pDCxt->asynchRequest != NULL){ break; } pDCxt->asynchRequest = driver_thread_operation; /* wake up driver thread */ CUSTOM_DRIVER_WAKE_DRIVER(pCxt); /* wait for driver thread completion */ Custom_Driver_WaitForCondition(pCxt, &(reg_query_bool), A_TRUE, 5000); break; case ATH_MEM_QUERY: // read the memory location for stat storage regQuery.address = TARG_VTOP(HOST_INTEREST_ITEM_ADDRESS(hi_flash_is_present)); regQuery.operation = ATH_REG_OP_READ; pQuery = ®Query; reg_query_bool = A_FALSE; if(pDCxt->asynchRequest != NULL){ break; } pDCxt->asynchRequest = driver_thread_operation; CUSTOM_DRIVER_WAKE_DRIVER(pCxt); Custom_Driver_WaitForCondition(pCxt, &(reg_query_bool), A_TRUE, 5000); if(reg_query_bool == A_FALSE){ break; } //capture the value in regQuery.address regQuery.address = TARG_VTOP(regQuery.value); ptr = (uint_32*)param_ptr->data; for(i=0 ; i<5 ; i++){ reg_query_bool = A_FALSE; if(pDCxt->asynchRequest != NULL){ break; } pDCxt->asynchRequest = driver_thread_operation; CUSTOM_DRIVER_WAKE_DRIVER(pCxt); Custom_Driver_WaitForCondition(pCxt, &(reg_query_bool), A_TRUE, 5000); if(reg_query_bool == A_FALSE){ break; } /* CAUTION: this next line assumes that the stats are stored in * the same order that they appear in the ATH_MEMQUERY structure. */ ptr[i] = regQuery.value; regQuery.address+=4; } /* for allocram remaining we query address allocram_remaining_bytes.*/ regQuery.address = TARG_VTOP(0x541f2c); reg_query_bool = A_FALSE; if(pDCxt->asynchRequest != NULL){ break; } pDCxt->asynchRequest = driver_thread_operation; CUSTOM_DRIVER_WAKE_DRIVER(pCxt); Custom_Driver_WaitForCondition(pCxt, &(reg_query_bool), A_TRUE, 5000); if(reg_query_bool == A_FALSE){ break; } /* CAUTION: this next line assumes that the stats are stored in * the same order that they appear in the ATH_MEMQUERY structure. */ ptr[5] = regQuery.value; break; default: error = ENET_ERROR; break; } return error; }
static int ar6000_hci_transport_ready(HCI_TRANSPORT_HANDLE HCIHandle, struct hci_transport_properties *pProps, void *pContext) { struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext; int status; u32 address, hci_uart_pwr_mgmt_params; // struct ar3k_config_info ar3kconfig; pHcidevInfo->pHCIDev = HCIHandle; memcpy(&pHcidevInfo->HCIProps,pProps,sizeof(*pProps)); AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE,("HCI ready (hci:0x%lX, headroom:%d, tailroom:%d blockpad:%d) \n", (unsigned long)HCIHandle, pHcidevInfo->HCIProps.HeadRoom, pHcidevInfo->HCIProps.TailRoom, pHcidevInfo->HCIProps.IOBlockPad)); #ifdef EXPORT_HCI_BRIDGE_INTERFACE A_ASSERT((pProps->HeadRoom + pProps->TailRoom) <= (struct net_device *)(pHcidevInfo->HCITransHdl.netDevice)->hard_header_len); #else A_ASSERT((pProps->HeadRoom + pProps->TailRoom) <= pHcidevInfo->ar->arNetDev->hard_header_len); #endif /* provide buffers */ RefillRecvBuffers(pHcidevInfo, HCI_ACL_TYPE, MAX_ACL_RECV_BUFS); RefillRecvBuffers(pHcidevInfo, HCI_EVENT_TYPE, MAX_EVT_RECV_BUFS); do { /* start transport */ status = HCI_TransportStart(pHcidevInfo->pHCIDev); if (status) { break; } if (!pHcidevInfo->HciNormalMode) { /* in test mode, no need to go any further */ break; } // The delay is required when AR6K is driving the BT reset line // where time is needed after the BT chip is out of reset (HCI_TransportStart) // and before the first HCI command is issued (AR3KConfigure) // FIXME // The delay should be configurable and be only applied when AR6K driving the BT // reset line. This could be done by some module parameter or based on some HW config // info. For now apply 100ms delay blindly A_MDELAY(100); A_MEMZERO(&ar3kconfig,sizeof(ar3kconfig)); ar3kconfig.pHCIDev = pHcidevInfo->pHCIDev; ar3kconfig.pHCIProps = &pHcidevInfo->HCIProps; #ifdef EXPORT_HCI_BRIDGE_INTERFACE ar3kconfig.pHIFDevice = (struct hif_device *)(pHcidevInfo->HCITransHdl.hifDevice); #else ar3kconfig.pHIFDevice = pHcidevInfo->ar->arHifDevice; #endif ar3kconfig.pBtStackHCIDev = pHcidevInfo->pBtStackHCIDev; if (ar3khcibaud != 0) { /* user wants ar3k baud rate change */ ar3kconfig.Flags |= AR3K_CONFIG_FLAG_SET_AR3K_BAUD; ar3kconfig.Flags |= AR3K_CONFIG_FLAG_AR3K_BAUD_CHANGE_DELAY; ar3kconfig.AR3KBaudRate = ar3khcibaud; } if ((hciuartscale != 0) || (hciuartstep != 0)) { /* user wants to tune HCI bridge UART scale/step values */ ar3kconfig.AR6KScale = (u16)hciuartscale; ar3kconfig.AR6KStep = (u16)hciuartstep; ar3kconfig.Flags |= AR3K_CONFIG_FLAG_SET_AR6K_SCALE_STEP; } /* Fetch the address of the hi_hci_uart_pwr_mgmt_params instance in the host interest area */ address = TARG_VTOP(pHcidevInfo->ar->arTargetType, HOST_INTEREST_ITEM_ADDRESS(pHcidevInfo->ar, hi_hci_uart_pwr_mgmt_params)); status = ar6000_ReadRegDiag(pHcidevInfo->ar->arHifDevice, &address, &hci_uart_pwr_mgmt_params); if (0 == status) { ar3kconfig.PwrMgmtEnabled = (hci_uart_pwr_mgmt_params & 0x1); ar3kconfig.IdleTimeout = (hci_uart_pwr_mgmt_params & 0xFFFF0000) >> 16; ar3kconfig.WakeupTimeout = (hci_uart_pwr_mgmt_params & 0xFF00) >> 8; } else { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: failed to read hci_uart_pwr_mgmt_params! \n")); } /* configure the AR3K device */ memcpy(ar3kconfig.bdaddr,pHcidevInfo->ar->bdaddr,6); status = AR3KConfigure(&ar3kconfig); if (status) { break; } /* Make sure both AR6K and AR3K have power management enabled */ if (ar3kconfig.PwrMgmtEnabled) { status = HCI_TransportEnablePowerMgmt(pHcidevInfo->pHCIDev, true); if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: failed to enable TLPM for AR6K! \n")); } } status = bt_register_hci(pHcidevInfo); } while (false);
static A_STATUS ar6000_hci_transport_ready(HCI_TRANSPORT_HANDLE HCIHandle, HCI_TRANSPORT_PROPERTIES *pProps, void *pContext) { AR6K_HCI_BRIDGE_INFO *pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)pContext; A_STATUS status; AR_SOFTC_DEV_T *arDev = pHcidevInfo->ar->arDev[0]; pHcidevInfo->pHCIDev = HCIHandle; A_MEMCPY(&pHcidevInfo->HCIProps,pProps,sizeof(*pProps)); AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE,("HCI ready (hci:0x%lX, headroom:%d, tailroom:%d blockpad:%d) \n", (unsigned long)HCIHandle, pHcidevInfo->HCIProps.HeadRoom, pHcidevInfo->HCIProps.TailRoom, pHcidevInfo->HCIProps.IOBlockPad)); #ifdef EXPORT_HCI_BRIDGE_INTERFACE A_ASSERT((pProps->HeadRoom + pProps->TailRoom) <= (struct net_device *)(pHcidevInfo->HCITransHdl.netDevice)->hard_header_len); #else A_ASSERT((pProps->HeadRoom + pProps->TailRoom) <= arDev->arNetDev->hard_header_len); #endif /* provide buffers */ RefillRecvBuffers(pHcidevInfo, HCI_ACL_TYPE, MAX_ACL_RECV_BUFS); RefillRecvBuffers(pHcidevInfo, HCI_EVENT_TYPE, MAX_EVT_RECV_BUFS); do { /* start transport */ status = HCI_TransportStart(pHcidevInfo->pHCIDev); if (A_FAILED(status)) { break; } if (!pHcidevInfo->HciNormalMode) { /* in test mode, no need to go any further */ break; } /* The delay is required when AR6K is driving the BT reset line */ /* where time is needed after the BT chip is out of reset (HCI_TransportStart) */ /* and before the first HCI command is issued (AR3KConfigure) */ /* FIXME */ /* The delay should be configurable and be only applied when AR6K driving the BT */ /* reset line. This could be done by some module parameter or based on some HW config */ /* info. For now apply 100ms delay blindly */ A_MDELAY(100); A_MEMZERO(&ar3kconfig,sizeof(ar3kconfig)); ar3kconfig.pHCIDev = pHcidevInfo->pHCIDev; ar3kconfig.pHCIProps = &pHcidevInfo->HCIProps; #ifdef EXPORT_HCI_BRIDGE_INTERFACE ar3kconfig.pHIFDevice = (HIF_DEVICE *)(pHcidevInfo->HCITransHdl.hifDevice); #else ar3kconfig.pHIFDevice = pHcidevInfo->ar->arHifDevice; #endif ar3kconfig.pBtStackHCIDev = pHcidevInfo->pBtStackHCIDev; if (ar3khcibaud != 0) { /* user wants ar3k baud rate change */ ar3kconfig.Flags |= AR3K_CONFIG_FLAG_SET_AR3K_BAUD; ar3kconfig.Flags |= AR3K_CONFIG_FLAG_AR3K_BAUD_CHANGE_DELAY; ar3kconfig.AR3KBaudRate = ar3khcibaud; } if ((hciuartscale != 0) || (hciuartstep != 0)) { /* user wants to tune HCI bridge UART scale/step values */ ar3kconfig.AR6KScale = (A_UINT16)hciuartscale; ar3kconfig.AR6KStep = (A_UINT16)hciuartstep; ar3kconfig.Flags |= AR3K_CONFIG_FLAG_SET_AR6K_SCALE_STEP; } /* configure the AR3K device */ memcpy(ar3kconfig.bdaddr,arDev->bdaddr,6); status = AR3KConfigure(&ar3kconfig); if (A_FAILED(status)) { extern unsigned int setuphci; AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: Fail to configure AR3K. No device? Cleanup HCI\n")); pHcidevInfo->ar->exitCallback = NULL; ar6000_cleanup_hci(pHcidevInfo->ar); setuphci = 0; pHcidevInfo->ar->arBTSharing = 0; break; } /* Make sure both AR6K and AR3K have power management enabled */ if (ar3kconfig.PwrMgmtEnabled) { A_UINT32 address, hci_uart_pwr_mgmt_params; /* Fetch the address of the hi_hci_uart_pwr_mgmt_params instance in the host interest area */ address = TARG_VTOP(pHcidevInfo->ar->arTargetType, HOST_INTEREST_ITEM_ADDRESS(pHcidevInfo->ar->arTargetType, hi_hci_uart_pwr_mgmt_params)); status = ar6000_ReadRegDiag(pHcidevInfo->ar->arHifDevice, &address, &hci_uart_pwr_mgmt_params); hci_uart_pwr_mgmt_params &= 0xFFFF; /* wakeup timeout is [31:16] */ hci_uart_pwr_mgmt_params |= (ar3kconfig.WakeupTimeout << 16); status |= ar6000_WriteRegDiag(pHcidevInfo->ar->arHifDevice, &address, &hci_uart_pwr_mgmt_params); if (A_OK != status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: failed to write hci_uart_pwr_mgmt_params!\n")); } /* Fetch the address of the hi_hci_uart_pwr_mgmt_params_ext instance in the host interest area */ address = TARG_VTOP(pHcidevInfo->ar->arTargetType, HOST_INTEREST_ITEM_ADDRESS(pHcidevInfo->ar->arTargetType, hi_hci_uart_pwr_mgmt_params_ext)); status = ar6000_WriteRegDiag(pHcidevInfo->ar->arHifDevice, &address, &ar3kconfig.IdleTimeout); if (A_OK != status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: failed to write hci_uart_pwr_mgmt_params_ext!\n")); } status = HCI_TransportEnablePowerMgmt(pHcidevInfo->pHCIDev, TRUE); if (A_FAILED(status)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: failed to enable TLPM for AR6K! \n")); } } status = bt_register_hci(pHcidevInfo); } while (FALSE); return status; }
/* Modules for firmware download */ A_STATUS configure_ar6000(HIF_DEVICE *hifDevice, A_UINT32 TargetType, A_UINT32 TargetVersion, A_BOOL enableUART, A_BOOL timerWAR, A_UINT32 clkFreq, wchar_t *fileName, wchar_t *fileRoot, A_BOOL bCompressed, A_BOOL isColdBoot, wchar_t *eepromFile) { A_STATUS status = A_OK; A_UINT32 value = 0; A_UINT32 oldSleep = 0; /* do any target-specific preparation that can be done through BMI */ do { if (enableUART) { A_UINT32 uartparam; uartparam = 1; status = BMIWriteMemory(hifDevice, HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_serial_enable), (A_UCHAR *)&uartparam, 4); if (status != A_OK) { break; } } value = HTC_PROTOCOL_VERSION; status = BMIWriteMemory (hifDevice, HOST_INTEREST_ITEM_ADDRESS (TargetType, hi_app_host_interest), (A_UCHAR *)&value, 4); if (status != A_OK) { break; } /* Selectively enable/disable the WAR for Timer Hang Symptom in the * firmware by setting a bit in the AR6K Scratch register. The firmware will * read this during init and appropriately enable/disable the WAR. * This setting will be retained in the firmware till target reset. */ if (timerWAR) { A_UINT32 timerparam; status = BMIReadMemory(hifDevice, HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_option_flag), (A_UCHAR *)&timerparam, 4); if (status != A_OK) { break; } timerparam |= HI_OPTION_TIMER_WAR; status = BMIWriteMemory(hifDevice, HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_option_flag), (A_UCHAR *)&timerparam, 4); if (status != A_OK) { break; } } if (TargetType == TARGET_TYPE_AR6001) { #ifdef FLASH_18V // Change the flash access time for 1.8V flash to 150ns status = BMIWriteSOCRegister (hifDevice, 0xac004004, 0x920100d1); if (status != A_OK) { break; } #endif } /* set the firmware mode to AP */ { A_UINT32 param; A_UINT32 fwmode = HI_OPTION_FW_MODE_BSS_STA; if (BMIReadMemory(hifDevice, HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_option_flag), (A_UCHAR *)¶m,4)!= A_OK) { return -1; } param |= (fwmode << HI_OPTION_FW_MODE_SHIFT); if (BMIWriteMemory(hifDevice, HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_option_flag), (A_UCHAR *)¶m,4) != A_OK) { return -1; } } if (TargetType == TARGET_TYPE_AR6002) { // Store the value of sleep oldSleep = 0x0; status = BMIReadSOCRegister (hifDevice, 0x40C4, &oldSleep); if (status != A_OK) { break; } // disable sleep status = BMIWriteSOCRegister (hifDevice, 0x40C4, oldSleep | 0x1); if (status != A_OK) { break; } status = ar6002_download_image(hifDevice, TargetVersion, fileName, fileRoot, bCompressed,isColdBoot); if (status != A_OK) { break; } // Restore the value of sleep status = BMIWriteSOCRegister (hifDevice, 0x40C4, oldSleep); if (status != A_OK) { break; } if ((TargetVersion == AR6002_VERSION_REV2) && (AR6002_REV2_APP_START_OVERRIDE != 0)) { /* override default app start address known to ROM */ status = BMISetAppStart(hifDevice, AR6002_REV2_APP_START_OVERRIDE); if (status != A_OK) { break; } } } status = ar6000_configure_clock (hifDevice, TargetType, TargetVersion, clkFreq); if (status != A_OK) { break; } status = eeprom_ar6000_transfer (hifDevice, TargetType, fileRoot, eepromFile); if (status != A_OK) { break; } } while (FALSE); return status; }
static A_STATUS ar6000_configure_clock (HIF_DEVICE *hifDevice, A_UINT32 TargetType, A_UINT32 TargetVersion, A_UINT32 clkFreq) { A_UINT32 ext_clk_detected = 0; A_STATUS status = A_OK; do { if (TargetType == TARGET_TYPE_AR6001) { status = BMIWriteSOCRegister(hifDevice, 0xAC000020, 0x203); if (status != A_OK) { break; } status = BMIWriteSOCRegister (hifDevice, 0xAC000024, 0x203); if (status != A_OK) { break; } } if (TargetType == TARGET_TYPE_AR6002) { if (TargetVersion == AR6002_VERSION_REV2) { status = BMIReadMemory(hifDevice, HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_ext_clk_detected), (A_UCHAR *)&ext_clk_detected, 4); if (status != A_OK) { break; } #ifdef FORCE_INTERNAL_CLOCK status = BMIWriteSOCRegister (hifDevice, 0x40E0, 0x10000); if (status != A_OK) { break; } status = BMIWriteSOCRegister (hifDevice, 0x4028, 0x0); if (status != A_OK) { break; } #else // LPO_CAL.Enable for internal clock if (ext_clk_detected == 0x0) { status = BMIWriteSOCRegister (hifDevice, 0x40E0, 0x10000); if (status != A_OK) { break; } } #endif // Run at 40/44 MHz clock status = BMIWriteSOCRegister (hifDevice, 0x4020, 0x0); if (status != A_OK) { break; } } // Write refclk status = BMIWriteMemory(hifDevice, HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_refclk_hz), (A_UCHAR *)&clkFreq, 4); if (status != A_OK) { break; } } } while (FALSE); return status; }
/* Driver_DumpAssertInfo - Collects assert information from chip and writes * it to stdout. * void *pCxt - the driver context. * uint32_t *pData - buffer to store UINT32 results * uint16_t *pLength - IN/OUT param to store length of buffer for IN and * length of contents for OUT. *****************************************************************************/ A_STATUS Driver_DumpAssertInfo(void *pCxt, uint32_t *pData, uint16_t *pLength) { A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); uint32_t address; uint32_t regDumpArea = 0; A_STATUS status = A_ERROR; uint32_t regDumpCount = 0; do { if (*pLength < REGISTER_DUMP_LEN_MAX) { break; } /* clear it */ *pLength = 0; /* the reg dump pointer is copied to the host interest area */ address = HOST_INTEREST_ITEM_ADDRESS(hi_failure_state); address = TARG_VTOP(address); if (pDCxt->targetType == TARGET_TYPE_AR4100 || pDCxt->targetType == TARGET_TYPE_AR400X) { regDumpCount = REG_DUMP_COUNT_AR4100; } else { A_ASSERT(0); /* should never happen */ #if DRIVER_CONFIG_DISABLE_ASSERT break; #endif } /* read RAM location through diagnostic window */ if (A_OK != (status = Driver_ReadRegDiag(pCxt, &address, ®DumpArea))) { A_ASSERT(0); /* should never happen */ #if DRIVER_CONFIG_DISABLE_ASSERT break; #endif } regDumpArea = A_LE2CPU32(regDumpArea); if (regDumpArea == 0) { /* no reg dump */ break; } regDumpArea = TARG_VTOP(regDumpArea); /* fetch register dump data */ if (A_OK != (status = Driver_ReadDataDiag(pCxt, regDumpArea, (uint8_t *)&pData[0], regDumpCount * (sizeof(uint32_t))))) { A_ASSERT(0); /* should never happen */ #if DRIVER_CONFIG_DISABLE_ASSERT break; #endif } *pLength = regDumpCount; } while (0); return status; }
void ar6000_dump_target_assert_info(HIF_DEVICE *hifDevice, A_UINT32 TargetType) { A_UINT32 address; A_UINT32 regDumpArea = 0; A_STATUS status; A_UINT32 regDumpValues[REGISTER_DUMP_LEN_MAX]; A_UINT32 regDumpCount = 0; A_UINT32 i; do { address = HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_failure_state); address = TARG_VTOP(TargetType, address); if (TargetType == TARGET_TYPE_AR6001) { address = 0x18a0; regDumpCount = REG_DUMP_COUNT_AR6001; } else if (TargetType == TARGET_TYPE_AR6002) { regDumpCount = REG_DUMP_COUNT_AR6002; } else if (TargetType == TARGET_TYPE_AR6003) { regDumpCount = REG_DUMP_COUNT_AR6003; } else { A_ASSERT(0); } status = ar6000_ReadRegDiag(hifDevice, &address, ®DumpArea); if (A_FAILED(status)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Failed to get ptr to register dump area \n")); break; } AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Location of register dump data: 0x%X \n",regDumpArea)); if (regDumpArea == 0) { /* no reg dump */ break; } regDumpArea = TARG_VTOP(TargetType, regDumpArea); /* fetch register dump data */ status = ar6000_ReadDataDiag(hifDevice, regDumpArea, (A_UCHAR *)®DumpValues[0], regDumpCount * (sizeof(A_UINT32))); if (A_FAILED(status)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Failed to get register dump \n")); break; } AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Register Dump: \n")); for (i = 0; i < regDumpCount; i++) { ATHR_DISPLAY_MSG (_T(" %d : 0x%8.8X \n"), i, regDumpValues[i]); AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" %d : 0x%8.8X \n",i, regDumpValues[i])); #ifdef UNDER_CE logPrintf(ATH_DEBUG_ERR," %d: 0x%8.8X \n",i, regDumpValues[i]); #endif } } while (FALSE); }