/* Driver_ReadRegDiag - Reads four bytes of data from the specified chip * device address. * void *pCxt - the driver context. * uint32_t address - the device chip address to start the read. * uint8_t *data - the start of data destination buffer. *****************************************************************************/ A_STATUS Driver_ReadRegDiag(void *pCxt, uint32_t *address, uint32_t *data) { A_STATUS status; A_NETBUF_DECLARE req; void *pReq = (void *)&req; A_NETBUF_CONFIGURE(pReq, data, 0, sizeof(uint32_t), sizeof(uint32_t)); do { /* set window register to start read cycle */ if (A_OK != (status = Driver_SetAddressWindowRegister(pCxt, WINDOW_READ_ADDR_ADDRESS, *address))) { break; } ATH_SET_PIO_EXTERNAL_READ_OPERATION(pReq, WINDOW_DATA_ADDRESS, true, sizeof(uint32_t)); if (A_OK != (status = Hcd_DoPioExternalAccess(pCxt, pReq))) { break; } } while (0); return status; }
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; }
A_STATUS HIFReadWrite(HIF_DEVICE *device, A_UINT32 address, A_UCHAR *buffer, A_UINT32 length, A_UINT32 request, void *context) { SDIO_STATUS status; SDREQUEST *sdrequest; BUS_REQUEST *busrequest = NULL; A_STATUS a_status = A_OK; /* Return any new requests if the shutdown is already in progress */ if (device->shutdownInProgress) { if (request & HIF_ASYNCHRONOUS) { device->htcCallbacks.rwCompletionHandler(context, A_ERROR); return A_PENDING; } return A_ERROR; } AR_DEBUG_ASSERT(device != NULL); AR_DEBUG_ASSERT(device->handle != NULL); AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("Device: %p\n", device)); if (length > device->curBlockSize) { AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("Invalid data length: %d\n", length)); return A_ERROR; } /* * We do not differentiate between the extended and the basic I/O so * we do not process the request type. */ /* * We do not differentiate between the byte and block data mode so * we do not process the request dmode. */ do { /* Addressing mode */ if (request & HIF_FIXED_ADDRESS) { AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("Address mode: Fixed\n")); } else if (request & HIF_INCREMENTAL_ADDRESS) { AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("Address mode: Incremental\n")); } else { AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("Invalid address mode: 0x%08x\n", request)); a_status = A_ERROR; break; } /* * Mailbox write. Adjust the address so that the last byte * falls on the EOM address. */ if (request & HIF_WRITE) { if ((address >= HIF_MBOX_START_ADDR(0)) && (address <= HIF_MBOX_END_ADDR(3))) { DBG_ASSERT(length <= HIF_MBOX_WIDTH); address += (HIF_MBOX_WIDTH - length); } } /* Allocate a new bus request */ busrequest = hifAllocateBusRequest(device); if (busrequest == NULL) { AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("Unable to allocate bus request\n")); a_status = A_ERROR; break; } sdrequest = busrequest->request; sdrequest->pDataBuffer = buffer; if (request & HIF_SYNCHRONOUS) { AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("Execution mode: Synchronous\n")); sdrequest->Flags = SDREQ_FLAGS_RAW; sdrequest->pCompleteContext = NULL; sdrequest->pCompletion = NULL; } else if (request & HIF_ASYNCHRONOUS) { /* Populate the bus request to be passed in as context */ AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("Execution mode: Asynchronous\n")); /* setup async context */ busrequest->device = device; busrequest->context = context; sdrequest->pCompleteContext = busrequest; sdrequest->Flags = SDREQ_FLAGS_RAW | SDREQ_FLAGS_TRANS_ASYNC; sdrequest->pCompletion = hifRWCompletionHandler; } /* Indicate to the bus driver if its a read or a write */ if (request & HIF_WRITE) { AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("Direction: Write\n")); if (((address >= HIF_MBOX_START_ADDR(0)) && (address <= HIF_MBOX_END_ADDR(3)))) { /* trapping HTC WRITE to mailbox, these will use the special DMA operation */ AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("--- MAILBOX WRITE ACCESS!!!!\n")); ATH_SET_DMA_OPERATION(sdrequest,ATH_TRANS_WRITE,address,length); } else { ATH_SET_PIO_EXTERNAL_WRITE_OPERATION(sdrequest, address, (request & HIF_INCREMENTAL_ADDRESS) ? TRUE : FALSE, length); } } else if (request & HIF_READ) { AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("Direction: Read\n")); if (((address >= HIF_MBOX_START_ADDR(0)) && (address <= HIF_MBOX_END_ADDR(3)))) { AR_DEBUG_PRINTF(ATH_DEBUG_TRC, (" --- MAILBOX READ ACCESS!!!!\n")); /* trapping on HTC READ mailbox , these will use the special DMA operation */ ATH_SET_DMA_OPERATION(sdrequest,ATH_TRANS_READ,address,length); } else { ATH_SET_PIO_EXTERNAL_READ_OPERATION(sdrequest, address, request & HIF_INCREMENTAL_ADDRESS ? TRUE : FALSE, length); } } else { AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("Invalid direction: 0x%08x\n", request)); a_status = A_ERROR; break; } /* issue the request */ status = SDDEVICE_CALL_REQUEST_FUNC(device->handle, sdrequest); if (!SDIO_SUCCESS(status)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("HIF Read/Write failure: %d\n", status)); a_status = A_ERROR; } } while (FALSE); if ((busrequest != NULL) && (request & HIF_SYNCHRONOUS)) { hifFreeBusRequest(device,busrequest); } return a_status; }