A_STATUS ar6002_REV1_reset_force_host (HIF_DEVICE *hifDevice) { A_INT32 i; struct forceROM_s { A_UINT32 addr; A_UINT32 data; }; struct forceROM_s *ForceROM; A_INT32 szForceROM; A_STATUS status = A_OK; A_UINT32 address; A_UINT32 data; static struct forceROM_s ForceROM_NEW[] = { {0x52df80, 0x20f31c07}, {0x52df84, 0x92374420}, {0x52df88, 0x1d120c03}, {0x52df8c, 0xff8216f0}, {0x52df90, 0xf01d120c}, {0x52df94, 0x81004136}, {0x52df98, 0xbc9100bd}, {0x52df9c, 0x00bba100}, {0x00008000|MC_TCAM_TARGET_ADDRESS, 0x0012dfe0}, /* Use remap entry 0 */ {0x00008000|MC_TCAM_COMPARE_ADDRESS, 0x000e2380}, {0x00008000|MC_TCAM_MASK_ADDRESS, 0x00000000}, {0x00008000|MC_TCAM_VALID_ADDRESS, 0x00000001}, {0x00018000|(LOCAL_COUNT_ADDRESS+0x10), 0}, /* clear BMI credit counter */ {0x00004000|AR6002_RESET_CONTROL_ADDRESS, RESET_CONTROL_WARM_RST_MASK}, }; address = 0x004ed4b0; /* REV1 target software ID is stored here */ status = ar6000_ReadRegDiag(hifDevice, &address, &data); if (A_FAILED(status) || (data != AR6002_VERSION_REV1)) { return A_ERROR; /* Not AR6002 REV1 */ } ForceROM = ForceROM_NEW; szForceROM = sizeof(ForceROM_NEW)/sizeof(*ForceROM); ATH_DEBUG_PRINTF (DBG_MISC_DRV, ATH_DEBUG_TRC, ("Force Target to recognize Host....\n")); for (i = 0; i < szForceROM; i++) { if (ar6000_WriteRegDiag(hifDevice, &ForceROM[i].addr, &ForceROM[i].data) != A_OK) { ATH_DEBUG_PRINTF (DBG_MISC_DRV, ATH_DEBUG_TRC, ("Cannot force Target to recognize Host!\n")); return A_ERROR; } } A_MDELAY(1000); return A_OK; }
A_STATUS ar6000_get_core_clock_config(HIF_DEVICE *hifDevice, A_UINT32 *data) { A_UINT32 regAddress; A_STATUS status; regAddress = WLAN_RTC_BASE_ADDRESS | WLAN_CPU_CLOCK_ADDRESS; /* read CPU clock settings*/ status = ar6000_ReadRegDiag(hifDevice, ®Address, data); return status; }
int ar6000_get_core_clock_config(struct hif_device *hifDevice, u32 *data) { u32 regAddress; int status; regAddress = WLAN_RTC_BASE_ADDRESS | WLAN_CPU_CLOCK_ADDRESS; /* read CPU clock settings*/ status = ar6000_ReadRegDiag(hifDevice, ®Address, data); return status; }
A_STATUS ar6000_ReadDataDiag(HIF_DEVICE *hifDevice, A_UINT32 address, A_UCHAR *data, A_UINT32 length) { A_UINT32 count; A_STATUS status = A_OK; for (count = 0; count < length; count += 4, address += 4) { if ((status = ar6000_ReadRegDiag(hifDevice, &address, (A_UINT32 *)&data[count])) != A_OK) { break; } } return status; }
static A_STATUS _delay_until_target_alive(HIF_DEVICE *hifDevice, A_INT32 wait_msecs, A_UINT32 TargetType) { A_INT32 actual_wait; A_INT32 i; A_UINT32 address; actual_wait = 0; /* Hardcode the address of LOCAL_COUNT_ADDRESS based on the target type */ if (TargetType == TARGET_TYPE_AR6001) { address = AR6001_LOCAL_COUNT_ADDRESS; } else if (TargetType == TARGET_TYPE_AR6002) { address = AR6002_LOCAL_COUNT_ADDRESS; } else if (TargetType == TARGET_TYPE_AR6003) { address = AR6003_LOCAL_COUNT_ADDRESS; } else { A_ASSERT(0); } address += 0x10; for (i=0; actual_wait < wait_msecs; i++) { A_UINT32 data; A_MDELAY(100); actual_wait += 100; data = 0; if (ar6000_ReadRegDiag(hifDevice, &address, &data) != A_OK) { return A_ERROR; } if (data != 0) { /* No need to wait longer -- we have a BMI credit */ return A_OK; } } return A_ERROR; /* timed out */ }
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); }
/* reset device */ A_STATUS ar6000_reset_device(HIF_DEVICE *hifDevice, A_UINT32 TargetType) { #if !defined(DWSIM) A_STATUS status = A_OK; A_UINT32 address; A_UINT32 data; do { // address = RESET_CONTROL_ADDRESS; data = RESET_CONTROL_COLD_RST_MASK; /* Hardcode the address of RESET_CONTROL_ADDRESS based on the target type */ if (TargetType == TARGET_TYPE_AR6001) { address = 0x0C000000; } else { if (TargetType == TARGET_TYPE_AR6002) { address = 0x00004000; } else { A_ASSERT(0); } } status = ar6000_WriteRegDiag(hifDevice, &address, &data); if (A_FAILED(status)) { break; } /* * Read back the RESET CAUSE register to ensure that the cold reset * went through. */ msleep(2000); /* 2 second delay to allow things to settle down */ // address = RESET_CAUSE_ADDRESS; /* Hardcode the address of RESET_CAUSE_ADDRESS based on the target type */ if (TargetType == TARGET_TYPE_AR6001) { address = 0x0C0000CC; } else { if (TargetType == TARGET_TYPE_AR6002) { address = 0x000040C0; } else { A_ASSERT(0); } } data = 0; status = ar6000_ReadRegDiag(hifDevice, &address, &data); if (A_FAILED(status)) { break; } AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Reset Cause readback: 0x%X \n",data)); data &= RESET_CAUSE_LAST_MASK; if (data != 2) { AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Unable to cold reset the target \n")); } } while (FALSE); if (A_FAILED(status)) { AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Failed to reset target \n")); } #endif return A_OK; }
/* * Call this function just before the call to BMIInit * in order to force* AR6002 rev 1.x firmware to detect a Host. * THIS IS FOR USE ONLY WITH AR6002 REV 1.x. * TBDXXX: Remove this function when REV 1.x is desupported. */ A_STATUS ar6002_REV1_reset_force_host (HIF_DEVICE *hifDevice) { A_INT32 i; struct forceROM_s { A_UINT32 addr; A_UINT32 data; }; struct forceROM_s *ForceROM; A_INT32 szForceROM; A_STATUS status = A_OK; A_UINT32 address; A_UINT32 data; /* Force AR6002 REV1.x to recognize Host presence. * * Note: Use RAM at 0x52df80..0x52dfa0 with ROM Remap entry 0 * so that this workaround functions with AR6002.war1.sh. We * could fold that entire workaround into this one, but it's not * worth the effort at this point. This workaround cannot be * merged into the other workaround because this must be done * before BMI. */ static struct forceROM_s ForceROM_NEW[] = { {0x52df80, 0x20f31c07}, {0x52df84, 0x92374420}, {0x52df88, 0x1d120c03}, {0x52df8c, 0xff8216f0}, {0x52df90, 0xf01d120c}, {0x52df94, 0x81004136}, {0x52df98, 0xbc9100bd}, {0x52df9c, 0x00bba100}, {0x00008000|MC_TCAM_TARGET_ADDRESS, 0x0012dfe0}, /* Use remap entry 0 */ {0x00008000|MC_TCAM_COMPARE_ADDRESS, 0x000e2380}, {0x00008000|MC_TCAM_MASK_ADDRESS, 0x00000000}, {0x00008000|MC_TCAM_VALID_ADDRESS, 0x00000001}, {0x00018000|(LOCAL_COUNT_ADDRESS+0x10), 0}, /* clear BMI credit counter */ {0x00004000|AR6002_RESET_CONTROL_ADDRESS, RESET_CONTROL_WARM_RST_MASK}, }; address = 0x004ed4b0; /* REV1 target software ID is stored here */ status = ar6000_ReadRegDiag(hifDevice, &address, &data); if (A_FAILED(status) || (data != AR6002_VERSION_REV1)) { return A_ERROR; /* Not AR6002 REV1 */ } ForceROM = ForceROM_NEW; szForceROM = sizeof(ForceROM_NEW)/sizeof(*ForceROM); ATH_DEBUG_PRINTF (DBG_MISC_DRV, ATH_DEBUG_TRC, ("Force Target to recognize Host....\n")); for (i = 0; i < szForceROM; i++) { if (ar6000_WriteRegDiag(hifDevice, &ForceROM[i].addr, &ForceROM[i].data) != A_OK) { ATH_DEBUG_PRINTF (DBG_MISC_DRV, ATH_DEBUG_TRC, ("Cannot force Target to recognize Host!\n")); return A_ERROR; } } A_MDELAY(1000); return A_OK; }
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); }
/* reset device */ A_STATUS ar6000_reset_device(HIF_DEVICE *hifDevice, A_UINT32 TargetType, A_BOOL waitForCompletion, A_BOOL coldReset) { A_STATUS status = A_OK; A_UINT32 address; A_UINT32 data; do { // Workaround BEGIN // address = RESET_CONTROL_ADDRESS; if (coldReset) { data = RESET_CONTROL_COLD_RST_MASK; } else { data = RESET_CONTROL_MBOX_RST_MASK; } /* Hardcode the address of RESET_CONTROL_ADDRESS based on the target type */ if (TargetType == TARGET_TYPE_AR6001) { address = AR6001_RESET_CONTROL_ADDRESS; } else if (TargetType == TARGET_TYPE_AR6002) { address = AR6002_RESET_CONTROL_ADDRESS; } else if (TargetType == TARGET_TYPE_AR6003) { address = AR6003_RESET_CONTROL_ADDRESS; } else { A_ASSERT(0); } status = ar6000_WriteRegDiag(hifDevice, &address, &data); if (A_FAILED(status)) { break; } if (!waitForCompletion) { break; } #if 0 /* Up to 2 second delay to allow things to settle down */ (void)_delay_until_target_alive(hifDevice, 2000, TargetType); /* * Read back the RESET CAUSE register to ensure that the cold reset * went through. */ // address = RESET_CAUSE_ADDRESS; /* Hardcode the address of RESET_CAUSE_ADDRESS based on the target type */ if (TargetType == TARGET_TYPE_AR6001) { address = 0x0C0000CC; } else if (TargetType == TARGET_TYPE_AR6002) { address = 0x000040C0; } else if (TargetType == TARGET_TYPE_AR6003) { address = 0x000040C0; } else { A_ASSERT(0); } data = 0; status = ar6000_ReadRegDiag(hifDevice, &address, &data); if (A_FAILED(status)) { break; } AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Reset Cause readback: 0x%X \n",data)); data &= RESET_CAUSE_LAST_MASK; if (data != 2) { AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Unable to cold reset the target \n")); } #endif // Workaroud END } while (FALSE); if (A_FAILED(status)) { AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Failed to reset target \n")); } return A_OK; }
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; }
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); }
/* reset device */ A_STATUS ar6000_reset_device(HIF_DEVICE *hifDevice, A_UINT32 TargetType, A_BOOL waitForCompletion) { A_STATUS status = A_OK; A_UINT32 address; A_UINT32 data; do { data = RESET_CONTROL_COLD_RST_MASK; if (TargetType == TARGET_TYPE_AR6001) { address = AR6001_RESET_CONTROL_ADDRESS; } else if (TargetType == TARGET_TYPE_AR6002) { address = AR6002_RESET_CONTROL_ADDRESS; } else if (TargetType == TARGET_TYPE_AR6003) { address = AR6003_RESET_CONTROL_ADDRESS; } else { A_ASSERT(0); } status = ar6000_WriteRegDiag(hifDevice, &address, &data); if (A_FAILED(status)) { break; } if (!waitForCompletion) { break; } (void)_delay_until_target_alive(hifDevice, 1800, TargetType); if (TargetType == TARGET_TYPE_AR6001) { address = 0x0C0000CC; } else if (TargetType == TARGET_TYPE_AR6002) { address = 0x000040C0; } else if (TargetType == TARGET_TYPE_AR6003) { address = 0x000040C0; } else { A_ASSERT(0); } data = 0; status = ar6000_ReadRegDiag(hifDevice, &address, &data); if (A_FAILED(status)) { break; } AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Reset Cause readback: 0x%X \n",data)); data &= RESET_CAUSE_LAST_MASK; if (data != 2) { AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Unable to cold reset the target \n")); } } while (FALSE); if (A_FAILED(status)) { AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Failed to reset target \n")); } return A_OK; }