/* 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 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; }
/* Driver_WriteRegDiag - Writes four bytes of data to the specified chip * device address. * void *pCxt - the driver context. * uint32_t address - the device chip address to start the write. * uint8_t *data - the start of data source buffer. *****************************************************************************/ A_STATUS Driver_WriteRegDiag(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)); ATH_SET_PIO_EXTERNAL_WRITE_OPERATION(pReq, WINDOW_DATA_ADDRESS, true, sizeof(uint32_t)); do { if (A_OK != (status = Hcd_DoPioExternalAccess(pCxt, pReq))) { break; } /* set window register, which starts the write cycle */ if (A_OK != (status = Driver_SetAddressWindowRegister(pCxt, WINDOW_WRITE_ADDR_ADDRESS, *address))) { break; } } while (0); return status; }
static A_STATUS bmiBufferReceive(A_VOID *pCxt, A_UCHAR *buffer, A_UINT32 length, A_BOOL want_timeout) { A_STATUS status; A_UINT32 address; A_UINT32 availableRecvBytes; A_NETBUF_DECLARE req; A_VOID *pReq = (A_VOID*)&req; //A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); if (length >= 4) { /* NB: Currently, always true */ /* * NB: word_available is declared static for esoteric reasons * having to do with protection on some OSes. */ static A_UINT32 word_available; A_UINT32 timeout; word_available = 0; timeout = BMI_COMMUNICATION_TIMEOUT; while((!want_timeout || timeout--) && !word_available) { status = Hcd_DoPioInternalAccess(pCxt, ATH_SPI_RDBUF_BYTE_AVA_REG, &availableRecvBytes, A_TRUE); if (status != A_OK) { break; } if (availableRecvBytes >= sizeof(A_UINT32)) { word_available = 1; } } if (!word_available) { return A_ERROR; } } 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_READ | ATH_TRANS_DMA)); status = Hcd_Request(pCxt, pReq); if (status != A_OK) { return A_ERROR; } 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; }