static void ath6kl_hif_dump_fw_crash(struct ath6kl *ar) { __le32 regdump_val[REGISTER_DUMP_LEN_MAX]; u32 i, address, regdump_addr = 0; int ret; if (ar->target_type != TARGET_TYPE_AR6003) return; /* the reg dump pointer is copied to the host interest area */ address = ath6kl_get_hi_item_addr(ar, HI_ITEM(hi_failure_state)); address = TARG_VTOP(ar->target_type, address); /* read RAM location through diagnostic window */ ret = ath6kl_diag_read32(ar, address, ®dump_addr); if (ret || !regdump_addr) { ath6kl_warn("failed to get ptr to register dump area: %d\n", ret); return; } ath6kl_dbg(ATH6KL_DBG_IRQ, "register dump data address 0x%x\n", regdump_addr); regdump_addr = TARG_VTOP(ar->target_type, regdump_addr); /* fetch register dump data */ ret = ath6kl_diag_read(ar, regdump_addr, (u8 *)®dump_val[0], REG_DUMP_COUNT_AR6003 * (sizeof(u32))); if (ret) { ath6kl_warn("failed to get register dump: %d\n", ret); return; } ath6kl_info("crash dump:\n"); ath6kl_info("hw 0x%x fw %s\n", ar->wiphy->hw_version, ar->wiphy->fw_version); BUILD_BUG_ON(REG_DUMP_COUNT_AR6003 % 4); for (i = 0; i < REG_DUMP_COUNT_AR6003 / 4; i++) { ath6kl_info("%d: 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x\n", 4 * i, le32_to_cpu(regdump_val[i]), le32_to_cpu(regdump_val[i + 1]), le32_to_cpu(regdump_val[i + 2]), le32_to_cpu(regdump_val[i + 3])); } }
static void ath6kl_dump_target_assert_info(struct ath6kl *ar) { u32 address; u32 regdump_loc = 0; int status; u32 regdump_val[REGISTER_DUMP_LEN_MAX]; u32 i; if (ar->target_type != TARGET_TYPE_AR6003) return; /* the reg dump pointer is copied to the host interest area */ address = ath6kl_get_hi_item_addr(ar, HI_ITEM(hi_failure_state)); address = TARG_VTOP(address); /* read RAM location through diagnostic window */ status = ath6kl_read_reg_diag(ar, &address, ®dump_loc); if (status || !regdump_loc) { ath6kl_err("failed to get ptr to register dump area\n"); return; } ath6kl_dbg(ATH6KL_DBG_TRC, "location of register dump data: 0x%X\n", regdump_loc); regdump_loc = TARG_VTOP(regdump_loc); /* fetch register dump data */ status = ath6kl_access_datadiag(ar, regdump_loc, (u8 *)®dump_val[0], REG_DUMP_COUNT_AR6003 * (sizeof(u32)), true); if (status) { ath6kl_err("failed to get register dump\n"); return; } ath6kl_dbg(ATH6KL_DBG_TRC, "Register Dump:\n"); for (i = 0; i < REG_DUMP_COUNT_AR6003; i++) ath6kl_dbg(ATH6KL_DBG_TRC, " %d : 0x%8.8X\n", i, regdump_val[i]); }
static int ath6kl_set_host_app_area(struct ath6kl *ar) { u32 address, data; struct host_app_area host_app_area; /* Fetch the address of the host_app_area_s * instance in the host interest area */ address = ath6kl_get_hi_item_addr(ar, HI_ITEM(hi_app_host_interest)); address = TARG_VTOP(address); if (ath6kl_read_reg_diag(ar, &address, &data)) return -EIO; address = TARG_VTOP(data); host_app_area.wmi_protocol_ver = WMI_PROTOCOL_VERSION; if (ath6kl_access_datadiag(ar, address, (u8 *)&host_app_area, sizeof(struct host_app_area), false)) return -EIO; return 0; }
static void ath6kl_hif_dump(struct ath6kl *ar, u32 fw_dump_addr, u32 len) { __le32 regdump_val[MAX_DUMP_BYTE_NUM_ONE_ITERATION / 4]; u32 read_len = 0; u32 i = 0,count; int ret; u32 phy_addr = TARG_VTOP(ar->target_type, fw_dump_addr); len = (len + 3) & (~0x3); fw_dump_addr = (fw_dump_addr + 3) & (~0x3); while(len) { read_len = len; if(read_len > MAX_DUMP_BYTE_NUM_ONE_ITERATION) read_len = MAX_DUMP_BYTE_NUM_ONE_ITERATION; phy_addr = TARG_VTOP(ar->target_type, fw_dump_addr); ret = ath6kl_diag_read(ar, phy_addr, (u8 *) ®dump_val[0], read_len); if (ret) { ath6kl_warn("failed to get register dump: %d\n", ret); return; } count = read_len / 4; for (i = 0; i < count; i += 4) { ath6kl_info("0x%08x: 0x%08x 0x%08x 0x%08x 0x%08x\n", le32_to_cpu(fw_dump_addr + 4 * i), le32_to_cpu(regdump_val[i]), le32_to_cpu(regdump_val[i + 1]), le32_to_cpu(regdump_val[i + 2]), le32_to_cpu(regdump_val[i + 3])); } len -= read_len; fw_dump_addr += read_len; } }
static void ath6kl_hif_dump_fw_more(struct ath6kl *ar, u32 mask) { u32 fw_dump_addr, fw_dump_len; u32 address; int ret; if (ar->target_type != TARGET_TYPE_AR6003 ) { ath6kl_warn("not support dump stack for type: %x\n", ar->target_type); return; } if(mask & DUMP_MASK_FULL_STACK) { if(ar->wiphy->hw_version == AR6003_HW_2_1_1_VERSION) { fw_dump_addr = AR6003_HW211_KERNELSTACK_BASE - DUMP_STACK_OFFSET; fw_dump_len = AR6003_HW211_KERNELSTACK_SIZE + DUMP_STACK_OFFSET; ath6kl_warn("firmware stack:0x%x, len:0x%x\n", AR6003_HW211_KERNELSTACK_BASE, AR6003_HW211_KERNELSTACK_SIZE); ath6kl_hif_dump(ar, fw_dump_addr, fw_dump_len); } } if(mask & DUMP_MASK_DBGLOG) { if(ar->wiphy->hw_version == AR6003_HW_2_1_1_VERSION) { address = TARG_VTOP(ar->target_type, AR6003_HW211_DBGLOG_ADDR); ret = ath6kl_diag_read32(ar, address, &fw_dump_addr); if(!ret && fw_dump_addr) { fw_dump_len = AR6003_HW211_DBGLOG_SIZE; ath6kl_warn("fw dblog:0x%x, len:0x%x\n", fw_dump_addr, AR6003_HW211_DBGLOG_SIZE); ath6kl_hif_dump(ar, fw_dump_addr, fw_dump_len); } } } }
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);
int ath6kl_read_fwlogs(struct ath6kl *ar) { struct ath6kl_dbglog_hdr debug_hdr; struct ath6kl_dbglog_buf debug_buf; u32 address, length, dropped, firstbuf, debug_hdr_addr; int ret = 0, loop; u8 *buf; buf = kmalloc(ATH6KL_FWLOG_PAYLOAD_SIZE, GFP_KERNEL); if (!buf) return -ENOMEM; address = TARG_VTOP(ar->target_type, ath6kl_get_hi_item_addr(ar, HI_ITEM(hi_dbglog_hdr))); ret = ath6kl_diag_read32(ar, address, &debug_hdr_addr); if (ret) goto out; /* Get the contents of the ring buffer */ if (debug_hdr_addr == 0) { ath6kl_warn("Invalid address for debug_hdr_addr\n"); ret = -EINVAL; goto out; } address = TARG_VTOP(ar->target_type, debug_hdr_addr); ath6kl_diag_read(ar, address, &debug_hdr, sizeof(debug_hdr)); address = TARG_VTOP(ar->target_type, le32_to_cpu(debug_hdr.dbuf_addr)); firstbuf = address; dropped = le32_to_cpu(debug_hdr.dropped); ath6kl_diag_read(ar, address, &debug_buf, sizeof(debug_buf)); loop = 100; do { address = TARG_VTOP(ar->target_type, le32_to_cpu(debug_buf.buffer_addr)); length = le32_to_cpu(debug_buf.length); if (length != 0 && (le32_to_cpu(debug_buf.length) <= le32_to_cpu(debug_buf.bufsize))) { length = ALIGN(length, 4); ret = ath6kl_diag_read(ar, address, buf, length); if (ret) goto out; ath6kl_debug_fwlog_event(ar, buf, length); } address = TARG_VTOP(ar->target_type, le32_to_cpu(debug_buf.next)); ath6kl_diag_read(ar, address, &debug_buf, sizeof(debug_buf)); if (ret) goto out; loop--; if (WARN_ON(loop == 0)) { ret = -ETIMEDOUT; goto out; } } while (address != firstbuf); out: kfree(buf); return ret; }
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; }
/* 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); }