A_STATUS BMIWriteSOCRegister(A_VOID *pCxt, A_UINT32 address, A_UINT32 param) { A_UINT32 cid; A_STATUS status; A_UINT32 offset, temp; A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address) + sizeof(param))); memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address) + sizeof(param)); if (bmiDone) { return A_ERROR; } cid = A_CPU2LE32(BMI_WRITE_SOC_REGISTER); offset = 0; A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); offset += sizeof(cid); temp = A_CPU2LE32(address); A_MEMCPY(&(pBMICmdBuf[offset]), &temp, sizeof(address)); offset += sizeof(address); A_MEMCPY(&(pBMICmdBuf[offset]), ¶m, sizeof(param)); offset += sizeof(param); status = bmiBufferSend(pCxt, pBMICmdBuf, offset); if (status != A_OK) { return A_ERROR; } return A_OK; }
A_STATUS BMIWriteMemory(A_VOID *pCxt, A_UINT32 address, A_UCHAR *buffer, A_UINT32 length) { A_UINT32 cid; A_UINT32 remaining, txlen, temp; const A_UINT32 header = sizeof(cid) + sizeof(address) + sizeof(length); //A_UCHAR alignedBuffer[BMI_DATASZ_MAX]; A_UCHAR *src; A_UINT8 *ptr; A_ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX + header)); memset (pBMICmdBuf, 0, BMI_DATASZ_MAX + header); if (bmiDone) { return A_ERROR; } cid = A_CPU2LE32(BMI_WRITE_MEMORY); remaining = length; while (remaining) { src = &buffer[length - remaining]; if (remaining < (BMI_DATASZ_MAX - header)) { if (remaining & 3) { /* align it with 4 bytes */ remaining = remaining + (4 - (remaining & 3)); //memcpy(alignedBuffer, src, remaining); //src = alignedBuffer; } txlen = remaining; } else { txlen = (BMI_DATASZ_MAX - header); } ptr = pBMICmdBuf; A_MEMCPY(ptr, &cid, sizeof(cid)); ptr += sizeof(cid); temp = A_CPU2LE32(address); A_MEMCPY(ptr, &temp, sizeof(address)); ptr += sizeof(address); temp = A_CPU2LE32(txlen); A_MEMCPY(ptr, &temp, sizeof(txlen)); ptr += sizeof(txlen); A_MEMCPY(ptr, src, txlen); ptr += txlen; if(A_OK != bmiBufferSend(pCxt, pBMICmdBuf, (A_UINT32)(ptr-pBMICmdBuf))){ return A_ERROR; } remaining -= txlen; address += txlen; } return A_OK; }
A_STATUS BMIReadMemory(A_VOID *pCxt, A_UINT32 address, A_UCHAR *buffer, A_UINT32 length) { A_UINT32 cid; A_STATUS status; A_UINT32 offset; A_UINT32 remaining, rxlen, temp; A_ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX + sizeof(cid) + sizeof(address) + sizeof(length))); memset (pBMICmdBuf, 0, BMI_DATASZ_MAX + sizeof(cid) + sizeof(address) + sizeof(length)); if (bmiDone) { return A_ERROR; } cid = A_CPU2LE32(BMI_READ_MEMORY); remaining = length; while (remaining) { //rxlen = (remaining < BMI_DATASZ_MAX) ? remaining : BMI_DATASZ_MAX; rxlen = (remaining < 4) ? remaining : 4; offset = 0; A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); offset += sizeof(cid); temp = A_CPU2LE32(address); A_MEMCPY(&(pBMICmdBuf[offset]), &temp, sizeof(address)); offset += sizeof(address); temp = A_CPU2LE32(rxlen); A_MEMCPY(&(pBMICmdBuf[offset]), &temp, sizeof(rxlen)); offset += sizeof(length); status = bmiBufferSend(pCxt, pBMICmdBuf, offset); if (status != A_OK) { return A_ERROR; } status = bmiBufferReceive(pCxt, pBMICmdBuf, rxlen, TRUE); if (status != A_OK) { return A_ERROR; } A_MEMCPY(&buffer[length - remaining], pBMICmdBuf, rxlen); remaining -= rxlen; address += rxlen; } return A_OK; }
A_STATUS BMIDone(A_VOID *pCxt) { A_STATUS status; A_UINT32 cid; if (bmiDone) { return A_OK; } bmiDone = TRUE; cid = A_CPU2LE32(BMI_DONE); status = bmiBufferSend(pCxt, (A_UCHAR *)&cid, sizeof(cid)); if (status != A_OK) { return A_ERROR; } if (pBMICmdCredits) { A_FREE(pBMICmdCredits, MALLOC_ID_TEMPORARY); pBMICmdCredits = NULL; } if (pBMICmdBuf) { A_FREE(pBMICmdBuf, MALLOC_ID_TEMPORARY); pBMICmdBuf = NULL; } return A_OK; }
/* Driver_SetAddressWindowRegister - Utility function to set the window * register. This is used for diagnostic reads and writes. * void *pCxt - the driver context. * uint32_t RegisterAddr - The window register address. * uint32_t Address - the target address. *****************************************************************************/ static A_STATUS Driver_SetAddressWindowRegister(void *pCxt, uint32_t RegisterAddr, uint32_t Address) { A_STATUS status; A_NETBUF_DECLARE req; void *pReq = (void *)&req; Address = A_CPU2LE32(Address); do { A_NETBUF_CONFIGURE(pReq, (((uint8_t *)(&Address)) + 1), (sizeof(uint32_t) - 1)); ATH_SET_PIO_EXTERNAL_WRITE_OPERATION(pReq, RegisterAddr + 1, true, (sizeof(uint32_t) - 1)); if (A_OK != (status = Hcd_DoPioExternalAccess(pCxt, pReq))) { break; } A_NETBUF_CONFIGURE(pReq, ((uint8_t *)(&Address)), sizeof(uint8_t)); ATH_SET_PIO_EXTERNAL_WRITE_OPERATION(pReq, RegisterAddr, true, sizeof(uint8_t)); if (A_OK != (status = Hcd_DoPioExternalAccess(pCxt, pReq))) { break; } } while (0); return status; }
static A_STATUS driver_thread_operation(A_VOID *pCxt) { A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); union{ A_UINT32 param; }stackU; #define PARAM (stackU.param) #define PTR_REG_MOD ((ATH_REGQUERY*)(pQuery)) switch(PTR_REG_MOD->operation) { case ATH_REG_OP_READ: // read Driver_ReadRegDiag(pCxt, &PTR_REG_MOD->address, &(PTR_REG_MOD->value)); PTR_REG_MOD->value = A_CPU2LE32((PTR_REG_MOD->value)); break; case ATH_REG_OP_WRITE: //write- PTR_REG_MOD->value = A_CPU2LE32((PTR_REG_MOD->value)); Driver_WriteRegDiag(pCxt, &PTR_REG_MOD->address, &(PTR_REG_MOD->value)); break; case ATH_REG_OP_RMW: //read-mod-write if(A_OK != Driver_ReadRegDiag(pCxt, &PTR_REG_MOD->address, &PARAM)){ break; } PARAM = A_CPU2LE32(PARAM); PARAM &= ~PTR_REG_MOD->mask; PARAM |= PTR_REG_MOD->value; PARAM = A_CPU2LE32(PARAM); Driver_WriteRegDiag(pCxt, &PTR_REG_MOD->address, &PARAM); break; } pDCxt->asynchRequest = NULL; reg_query_bool = A_TRUE; CUSTOM_DRIVER_WAKE_USER(pCxt); #undef PTR_REG_MOD #undef PARAM return A_OK; }
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; }
A_STATUS BMIExecute(A_VOID *pCxt, A_UINT32 address, A_UINT32 *param) { A_UINT32 cid; A_UINT32 temp; A_UINT8 *ptr; A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address) + sizeof(param))); memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address) + sizeof(param)); if (bmiDone) { return A_ERROR; } cid = A_CPU2LE32(BMI_EXECUTE); ptr = pBMICmdBuf; A_MEMCPY(ptr, &cid, sizeof(cid)); ptr += sizeof(cid); temp = A_CPU2LE32(address); A_MEMCPY(ptr, &temp, sizeof(address)); ptr += sizeof(address); A_MEMCPY(ptr, param, sizeof(*param)); ptr += sizeof(*param); if(A_OK != bmiBufferSend(pCxt, pBMICmdBuf, (A_UINT32)(ptr-pBMICmdBuf))){ return A_ERROR; } if(A_OK != bmiBufferReceive(pCxt, pBMICmdBuf, sizeof(*param), FALSE)){ return A_ERROR; } A_MEMCPY(param, pBMICmdBuf, sizeof(*param)); return A_OK; }
/* Driver_SetAddressWindowRegister - Utility function to set the window * register. This is used for diagnostic reads and writes. * void *pCxt - the driver context. * uint32_t RegisterAddr - The window register address. * uint32_t Address - the target address. *****************************************************************************/ static A_STATUS Driver_SetAddressWindowRegister(void *pCxt, uint32_t RegisterAddr, uint32_t Address) { A_STATUS status; uint8_t addrValue[4]; int32_t i; A_NETBUF_DECLARE req; void *pReq = (void *)&req; /* write bytes 1,2,3 of the register to set the upper address bytes, the LSB is written * last to initiate the access cycle */ Address = A_CPU2LE32(Address); for (i = 1; i <= 3; i++) { /* fill the buffer with the address byte value we want to hit 4 times*/ addrValue[0] = ((uint8_t *)&Address)[i]; addrValue[1] = addrValue[0]; addrValue[2] = addrValue[0]; addrValue[3] = addrValue[0]; A_NETBUF_CONFIGURE(pReq, (void *)addrValue, 0, 4, 4); ATH_SET_PIO_EXTERNAL_WRITE_OPERATION(pReq, RegisterAddr + i, false, 4); if (A_OK != (status = Hcd_DoPioExternalAccess(pCxt, pReq))) { break; } } if (status != A_OK) { return status; } A_NETBUF_CONFIGURE(pReq, (void *)&Address, 0, 4, 4); ATH_SET_PIO_EXTERNAL_WRITE_OPERATION(pReq, RegisterAddr, true, 4); status = Hcd_DoPioExternalAccess(pCxt, pReq); return status; }
0, A_CPU2LE16(1), //nonzero value requires endian correction IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN }; A_CONST WMI_SCAN_PARAMS_CMD default_scan_param = {0,0,0,0,0,WMI_SHORTSCANRATIO_DEFAULT, DEFAULT_SCAN_CTRL_FLAGS, 0, 0,0}; #if ENABLE_P2P_MODE A_CONST WMI_P2P_FW_SET_CONFIG_CMD default_p2p_config = { 0, "US", 81, 6, 81, 6, A_CPU2LE32(3000), 10 }; #endif A_VOID Api_BootProfile(A_VOID *pCxt, A_UINT8 val) { if(ath_custom_init.Boot_Profile != NULL){ ath_custom_init.Boot_Profile(val); } } /*****************************************************************************/ /* Api_InitStart - implements common code for initializing the driver. * This should be called before Api_InitFinish().