A_STATUS BMIGetTargetInfo(A_VOID *pCxt, struct bmi_target_info *targ_info) { A_UINT32 cid; if (bmiDone) { return A_ERROR; } cid = A_CPU2LE32(BMI_GET_TARGET_INFO); if(A_OK != bmiBufferSend(pCxt, (A_UCHAR *)&cid, sizeof(cid))){ return A_ERROR; } if(A_OK != bmiBufferReceive(pCxt, (A_UCHAR *)&targ_info->target_ver, sizeof(targ_info->target_ver), TRUE)){ return A_ERROR; } targ_info->target_ver = A_LE2CPU32(targ_info->target_ver); if (targ_info->target_ver == TARGET_VERSION_SENTINAL) { /* Determine how many bytes are in the Target's targ_info */ if(A_OK != bmiBufferReceive(pCxt, (A_UCHAR *)&targ_info->target_info_byte_count, sizeof(targ_info->target_info_byte_count), TRUE)){ return A_ERROR; } targ_info->target_info_byte_count = A_LE2CPU32(targ_info->target_info_byte_count); /* * The Target's targ_info doesn't match the Host's targ_info. * We need to do some backwards compatibility work to make this OK. */ A_ASSERT(targ_info->target_info_byte_count == sizeof(*targ_info)); /* Read the remainder of the targ_info */ if(A_OK != bmiBufferReceive(pCxt, ((A_UCHAR *)targ_info)+sizeof(targ_info->target_info_byte_count), sizeof(*targ_info)-sizeof(targ_info->target_info_byte_count), TRUE)){ return A_ERROR; } targ_info->target_ver = A_LE2CPU32(targ_info->target_ver); targ_info->target_type = A_LE2CPU32(targ_info->target_type); } else { return A_ERROR; } return A_OK; }
static A_STATUS bmiBufferSend(A_VOID *pCxt, A_UCHAR *buffer, A_UINT32 length) { A_NETBUF_DECLARE req; A_VOID *pReq = (A_VOID*)&req; A_STATUS status; A_UINT32 timeout; A_UINT32 address; //A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); A_NETBUF_CONFIGURE(pReq, pBMICmdCredits, 0, sizeof(A_UINT32), sizeof(A_UINT32)); *pBMICmdCredits = 0; timeout = BMI_COMMUNICATION_TIMEOUT; while(timeout-- && !(*pBMICmdCredits)) { /* Read the counter register to get the command credits */ address = COUNT_DEC_ADDRESS + (HTC_MAILBOX_NUM_MAX + BMI_ENDPOINT) * 4; ATH_SET_PIO_EXTERNAL_READ_OPERATION(pReq, address, A_TRUE, sizeof(A_UINT32)); /* hit the credit counter with a 4-byte access, the first byte read will hit the counter and cause * a decrement, while the remaining 3 bytes has no effect. The rationale behind this is to * make all HIF accesses 4-byte aligned */ if(A_OK != (status = Hcd_DoPioExternalAccess(pCxt, pReq))){ break; } /* the counter is only 8=bits, ignore anything in the upper 3 bytes */ *pBMICmdCredits = A_LE2CPU32(*pBMICmdCredits); (*pBMICmdCredits) &= 0xFF; } if (*pBMICmdCredits) { A_NETBUF_CONFIGURE(pReq, buffer, 0, length, length); address = Hcd_GetMboxAddress(pCxt, BMI_ENDPOINT, length); address &= ATH_TRANS_ADDR_MASK; A_NETBUF_SET_ELEM(pReq, A_REQ_ADDRESS, address); A_NETBUF_SET_ELEM(pReq, A_REQ_TRANSFER_LEN, length); /* init the packet read params/cmd incremental vs fixed address etc. */ A_NETBUF_SET_ELEM(pReq, A_REQ_COMMAND, (ATH_TRANS_WRITE | ATH_TRANS_DMA)); status = Hcd_Request(pCxt, pReq); if (status != A_OK) { return A_ERROR; } } else { return A_ERROR; } return status; }
/* Strrcl_ChipUpFinish - Utility function to complete the chip_up process. * when WMI_READY is received from chip this function clears the chipDown * boolean and sends the wmi store recall command to the chip so that its * associated State can be refreshed. * void *pCxt - the driver context. *****************************************************************************/ static A_STATUS Strrcl_ChipUpFinish(void *pCxt) { A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); WMI_STORERECALL_RECALL_CMD *pDsetInfo; uint32_t dset_info_len; if (pDCxt->wmiReady == true) { switch (pDCxt->strrclState) { case STRRCL_ST_ACTIVE: /* clear the chipDown boolean to allow outside activity to resume */ pDCxt->chipDown = false; if (A_OK != STACK_INIT(pCxt)) { break; } pDCxt->strrclState = STRRCL_ST_ACTIVE_B; // INTENTIONAL FALL_THRU case STRRCL_ST_ACTIVE_B: /* send recall */ #if 0 pEv = (WMI_STORERECALL_STORE_EVENT*)pDCxt->strrclCxt; if(A_OK != wmi_storerecall_recall_cmd(pDCxt->pWmiCxt, A_LE2CPU32(pEv->length), &pEv->data[0])){ break; //try again later this is likely because a previous wmi cmd has not finished. } #elifndef ENABLE_LARGE_DSET setup_host_dset(pCxt); pDsetData = pDCxt->tempStorage; if(A_OK != wmi_storerecall_recall_cmd(pDCxt->pWmiCxt, A_LE2CPU32(pDCxt->strrclCxtLen), pDsetData)){ break; //try again later this is likely because a previous wmi cmd has not finished. } #else setup_host_dset(pCxt); pDsetInfo = (WMI_STORERECALL_RECALL_CMD *)pDCxt->tempStorage; if (pDsetInfo->length == 0) { dset_info_len = sizeof(WMI_STORERECALL_RECALL_CMD); } else { dset_info_len = sizeof(WMI_STORERECALL_RECALL_CMD) - sizeof(uint8_t); dset_info_len += sizeof(WMI_STORERECALL_RECALL_DSET) * pDsetInfo->length; } if (A_OK != wmi_storerecall_recall_cmd(pDCxt->pWmiCxt, dset_info_len, pDsetInfo)) { break; // try again later this is likely because a previous wmi cmd has not finished. } #endif pDCxt->strrclCxt = NULL; pDCxt->strrclCxtLen = 0; // pDCxt->strrclState = STRRCL_ST_AWAIT_FW; pDCxt->strrclState = STRRCL_ST_INIT; pDCxt->strrclBlock = false; /* Indicate completion to the custom layer */ API_STORE_RECALL_EVENT(pCxt); /* clear this function from the driver's temporary calls */ pDCxt->asynchRequest = NULL; /* Since we are setting MAX_PERF before going to store-recall we need to set the state after we wakes up */ restore_power_state(pDCxt, 1); /* POWER_STATE_MOVED_FOR_STRRCL */ break; // done!! default: A_ASSERT(0); // should never happen #if DRIVER_CONFIG_DISABLE_ASSERT break; #endif } } return A_OK; }
/* 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; }