From 303c73c76d382dde5486e9d808e2b5d22d9bdfc9 Mon Sep 17 00:00:00 2001 From: Sriram Madhvapathi Date: Tue, 15 May 2018 15:34:05 +0530 Subject: [PATCH] qcacmn: SDIO HIF layer refactor 1. Move mailbox transfer dma definitions to mailbox.h 2. hif_configure_device changes to make it more generic 3. Add address fixup function Change-Id: I12bdf8b07350411093ba35071411525a8333cf93 CRs-Fixed: 2252417 --- hif/inc/hif.h | 4 +- hif/src/sdio/hif_bmi_reg_access.c | 8 +- hif/src/sdio/hif_sdio.c | 4 + hif/src/sdio/hif_sdio_common.h | 87 ------- hif/src/sdio/hif_sdio_dev.c | 20 +- hif/src/sdio/hif_sdio_dev.h | 8 +- .../sdio/native_sdio/include/hif_internal.h | 17 -- hif/src/sdio/native_sdio/src/dev_quirks.c | 1 + hif/src/sdio/native_sdio/src/hif.c | 212 +++++++----------- hif/src/sdio/native_sdio/src/hif_scatter.c | 7 +- hif/src/sdio/transfer/mailbox.c | 88 +++++++- hif/src/sdio/transfer/mailbox.h | 102 +++++++++ hif/src/sdio/transfer/transfer.h | 3 + 13 files changed, 286 insertions(+), 275 deletions(-) diff --git a/hif/inc/hif.h b/hif/inc/hif.h index 8c7bdb9411bb..3773b5d489c3 100644 --- a/hif/inc/hif.h +++ b/hif/inc/hif.h @@ -362,8 +362,8 @@ enum hif_disable_type { */ enum hif_device_config_opcode { HIF_DEVICE_POWER_STATE = 0, - HIF_DEVICE_GET_MBOX_BLOCK_SIZE, - HIF_DEVICE_GET_MBOX_ADDR, + HIF_DEVICE_GET_BLOCK_SIZE, + HIF_DEVICE_GET_FIFO_ADDR, HIF_DEVICE_GET_PENDING_EVENTS_FUNC, HIF_DEVICE_GET_IRQ_PROC_MODE, HIF_DEVICE_GET_RECV_EVENT_MASK_UNMASK_FUNC, diff --git a/hif/src/sdio/hif_bmi_reg_access.c b/hif/src/sdio/hif_bmi_reg_access.c index 5aa5a441da8a..bc6f8d0640ea 100644 --- a/hif/src/sdio/hif_bmi_reg_access.c +++ b/hif/src/sdio/hif_bmi_reg_access.c @@ -50,7 +50,7 @@ hif_bmi_buffer_send(struct hif_sdio_dev *device, char *buffer, uint32_t length) uint32_t address; uint32_t mbox_address[HTC_MAILBOX_NUM_MAX]; - hif_configure_device(device, HIF_DEVICE_GET_MBOX_ADDR, + hif_configure_device(device, HIF_DEVICE_GET_FIFO_ADDR, &mbox_address[0], sizeof(mbox_address)); *p_bmi_cmd_credits = 0; @@ -176,7 +176,7 @@ hif_bmi_buffer_receive(struct hif_sdio_dev *device, pending_events_func_check = true; } - hif_configure_device(device, HIF_DEVICE_GET_MBOX_ADDR, + hif_configure_device(device, HIF_DEVICE_GET_FIFO_ADDR, &mbox_address[0], sizeof(mbox_address)); /* @@ -298,7 +298,7 @@ hif_reg_based_get_target_info(struct hif_opaque_softc *hif_ctx, struct hif_sdio_softc *scn = HIF_GET_SDIO_SOFTC(hif_ctx); struct hif_sdio_dev *device = scn->hif_handle; - AR_DEBUG_PRINTF(ATH_DEBUG_BMI, + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI Get Target Info: Enter (device: 0x%pK)\n", device)); cid = BMI_GET_TARGET_INFO; @@ -367,7 +367,7 @@ hif_reg_based_get_target_info(struct hif_opaque_softc *hif_ctx, targ_info->target_type = TARGET_TYPE_AR6001; } - AR_DEBUG_PRINTF(ATH_DEBUG_BMI, + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI Get Target Info: Exit (ver: 0x%x type: 0x%x)\n", targ_info->target_ver, targ_info->target_type)); diff --git a/hif/src/sdio/hif_sdio.c b/hif/src/sdio/hif_sdio.c index e5743bde6253..8111fdb42638 100644 --- a/hif/src/sdio/hif_sdio.c +++ b/hif/src/sdio/hif_sdio.c @@ -172,11 +172,15 @@ void hif_post_init(struct hif_opaque_softc *hif_ctx, void *target, struct hif_sdio_dev *hif_device = scn->hif_handle; struct hif_sdio_device *htc_sdio_device = hif_dev_from_hif(hif_device); + HIF_ENTER(); + if (htc_sdio_device == NULL) htc_sdio_device = hif_dev_create(hif_device, callbacks, target); if (htc_sdio_device) hif_dev_setup(htc_sdio_device); + + HIF_EXIT(); } /** diff --git a/hif/src/sdio/hif_sdio_common.h b/hif/src/sdio/hif_sdio_common.h index 5e10ebf78a1e..dc0900da8988 100644 --- a/hif/src/sdio/hif_sdio_common.h +++ b/hif/src/sdio/hif_sdio_common.h @@ -32,92 +32,5 @@ #define FUNCTION_CLASS 0x0 #define MANUFACTURER_CODE 0x271 - /* Mailbox address in SDIO address space */ -#if defined(SDIO_3_0) -#define HIF_MBOX_BASE_ADDR 0x1000 -#define HIF_MBOX_DUMMY_WIDTH 0x800 -#else -#define HIF_MBOX_BASE_ADDR 0x800 -#define HIF_MBOX_DUMMY_WIDTH 0 -#endif - -#define HIF_MBOX_WIDTH 0x800 - -#define HIF_MBOX_START_ADDR(mbox) \ - (HIF_MBOX_BASE_ADDR + mbox * (HIF_MBOX_WIDTH + HIF_MBOX_DUMMY_WIDTH)) - -#define HIF_MBOX_END_ADDR(mbox) \ - (HIF_MBOX_START_ADDR(mbox) + HIF_MBOX_WIDTH - 1) - - /* extended MBOX address for larger MBOX writes to MBOX 0*/ -#if defined(SDIO_3_0) -#define HIF_MBOX0_EXTENDED_BASE_ADDR 0x5000 -#else -#define HIF_MBOX0_EXTENDED_BASE_ADDR 0x2800 -#endif -#define HIF_MBOX0_EXTENDED_WIDTH_AR6002 (6*1024) -#define HIF_MBOX0_EXTENDED_WIDTH_AR6003 (18*1024) - - /* version 1 of the chip has only a 12K extended mbox range */ -#define HIF_MBOX0_EXTENDED_BASE_ADDR_AR6003_V1 0x4000 -#define HIF_MBOX0_EXTENDED_WIDTH_AR6003_V1 (12*1024) - -#define HIF_MBOX0_EXTENDED_BASE_ADDR_AR6004 0x2800 -#define HIF_MBOX0_EXTENDED_WIDTH_AR6004 (18*1024) - - -#if defined(SDIO_3_0) -#define HIF_MBOX0_EXTENDED_BASE_ADDR_AR6320 0x5000 -#define HIF_MBOX0_EXTENDED_WIDTH_AR6320 (36*1024) -#define HIF_MBOX0_EXTENDED_WIDTH_AR6320_ROME_2_0 (56*1024) -#define HIF_MBOX1_EXTENDED_WIDTH_AR6320 (36*1024) -#define HIF_MBOX_DUMMY_SPACE_SIZE_AR6320 (2*1024) -#else -#define HIF_MBOX0_EXTENDED_BASE_ADDR_AR6320 0x2800 -#define HIF_MBOX0_EXTENDED_WIDTH_AR6320 (24*1024) -#define HIF_MBOX1_EXTENDED_WIDTH_AR6320 (24*1024) -#define HIF_MBOX_DUMMY_SPACE_SIZE_AR6320 0 -#endif - - - /* GMBOX addresses */ -#define HIF_GMBOX_BASE_ADDR 0x7000 -#define HIF_GMBOX_WIDTH 0x4000 - -/* for SDIO we recommend a 128-byte block size */ -#if defined(WITH_BACKPORTS) -#define HIF_DEFAULT_IO_BLOCK_SIZE 128 -#else -#define HIF_DEFAULT_IO_BLOCK_SIZE 256 -#endif - -#define FIFO_TIMEOUT_AND_CHIP_CONTROL 0x00000868 -#define FIFO_TIMEOUT_AND_CHIP_CONTROL_DISABLE_SLEEP_OFF 0xFFFEFFFF -#define FIFO_TIMEOUT_AND_CHIP_CONTROL_DISABLE_SLEEP_ON 0x10000 -/* In SDIO 2.0, asynchronous interrupt is not in SPEC - * requirement, but AR6003 support it, so the register - * is placed in vendor specific field 0xF0(bit0) - * In SDIO 3.0, the register is defined in SPEC, and its - * address is 0x16(bit1) - */ -/* interrupt mode register of AR6003 */ -#define CCCR_SDIO_IRQ_MODE_REG_AR6003 0xF0 -/* mode to enable special 4-bit interrupt assertion without clock */ -#define SDIO_IRQ_MODE_ASYNC_4BIT_IRQ_AR6003 (1 << 0) - /* interrupt mode register of AR6320 */ -#define CCCR_SDIO_IRQ_MODE_REG_AR6320 0x16 -/* mode to enable special 4-bit interrupt assertion without clock */ -#define SDIO_IRQ_MODE_ASYNC_4BIT_IRQ_AR6320 (1 << 1) - -#define CCCR_SDIO_ASYNC_INT_DELAY_ADDRESS 0xF0 -#define CCCR_SDIO_ASYNC_INT_DELAY_LSB 0x06 -#define CCCR_SDIO_ASYNC_INT_DELAY_MASK 0xC0 - -/* Vendor Specific Driver Strength Settings */ -#define CCCR_SDIO_DRIVER_STRENGTH_ENABLE_ADDR 0xf2 -#define CCCR_SDIO_DRIVER_STRENGTH_ENABLE_MASK 0x0e -#define CCCR_SDIO_DRIVER_STRENGTH_ENABLE_A 0x02 -#define CCCR_SDIO_DRIVER_STRENGTH_ENABLE_C 0x04 -#define CCCR_SDIO_DRIVER_STRENGTH_ENABLE_D 0x08 #endif /* _HIF_SDIO_COMMON_H_ */ diff --git a/hif/src/sdio/hif_sdio_dev.c b/hif/src/sdio/hif_sdio_dev.c index 9dd9d82c43df..fa2ca277114c 100644 --- a/hif/src/sdio/hif_sdio_dev.c +++ b/hif/src/sdio/hif_sdio_dev.c @@ -87,6 +87,7 @@ struct hif_sdio_device *hif_dev_create(struct hif_sdio_dev *hif_device, QDF_STATUS status; struct hif_sdio_device *pdev; + HIF_ENTER(); pdev = qdf_mem_malloc(sizeof(struct hif_sdio_device)); if (!pdev) { A_ASSERT(false); @@ -107,6 +108,7 @@ struct hif_sdio_device *hif_dev_create(struct hif_sdio_dev *hif_device, A_MEMCPY(&pdev->hif_callbacks, callbacks, sizeof(*callbacks)); + HIF_EXIT(); return pdev; } @@ -336,31 +338,19 @@ bool hif_dev_get_mailbox_swap(struct hif_sdio_dev *pdev) QDF_STATUS hif_dev_setup(struct hif_sdio_device *pdev) { QDF_STATUS status; - uint32_t blocksizes[MAILBOX_COUNT]; struct htc_callbacks htc_cbs; struct hif_sdio_dev *hif_device = pdev->HIFDevice; HIF_ENTER(); - status = hif_configure_device(hif_device, - HIF_DEVICE_GET_MBOX_ADDR, - &pdev->MailBoxInfo, - sizeof(pdev->MailBoxInfo)); + status = hif_dev_setup_device(pdev); - if (status != QDF_STATUS_SUCCESS) - HIF_ERROR("%s: HIF_DEVICE_GET_MBOX_ADDR failed", __func__); - status = hif_configure_device(hif_device, - HIF_DEVICE_GET_MBOX_BLOCK_SIZE, - blocksizes, sizeof(blocksizes)); if (status != QDF_STATUS_SUCCESS) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("(%s)HIF_DEVICE_GET_MBOX_BLOCK_SIZE failed!!!\n", - __func__)); - A_ASSERT(false); + HIF_ERROR("%s: device specific setup failed", __func__); + return QDF_STATUS_E_INVAL; } - pdev->BlockSize = blocksizes[MAILBOX_FOR_BLOCK_SIZE]; pdev->BlockMask = pdev->BlockSize - 1; A_ASSERT((pdev->BlockSize & pdev->BlockMask) == 0); diff --git a/hif/src/sdio/hif_sdio_dev.h b/hif/src/sdio/hif_sdio_dev.h index 077f50ed4af0..6558f1f4b846 100644 --- a/hif/src/sdio/hif_sdio_dev.h +++ b/hif/src/sdio/hif_sdio_dev.h @@ -58,15 +58,15 @@ QDF_STATUS hif_dev_map_service_to_pipe(struct hif_sdio_dev *pdev, void hif_dev_unmask_interrupts(struct hif_sdio_device *pdev); -#ifdef CONFIG_SDIO_TRANSFER_MAILBOX -QDF_STATUS hif_dev_get_mbox_address(struct hif_sdio_dev *pdev, +int hif_dev_setup_device(struct hif_sdio_device *pdev); + +QDF_STATUS hif_dev_get_fifo_address(struct hif_sdio_dev *pdev, struct hif_device_mbox_info *config, uint32_t config_len); -void hif_dev_get_mbox_block_size(void *config); +void hif_dev_get_block_size(void *config); void hif_dev_set_mailbox_swap(struct hif_sdio_dev *pdev); bool hif_dev_get_mailbox_swap(struct hif_sdio_dev *pdev); -#endif #endif /* HIF_SDIO_DEV_H_ */ diff --git a/hif/src/sdio/native_sdio/include/hif_internal.h b/hif/src/sdio/native_sdio/include/hif_internal.h index 315808979d09..90991417becf 100644 --- a/hif/src/sdio/native_sdio/include/hif_internal.h +++ b/hif/src/sdio/native_sdio/include/hif_internal.h @@ -50,12 +50,6 @@ #define FLAGS_CARD_ENAB 0x02 #define FLAGS_CARD_IRQ_UNMSK 0x04 -#define HIF_MBOX_BLOCK_SIZE HIF_DEFAULT_IO_BLOCK_SIZE -#define HIF_MBOX0_BLOCK_SIZE 1 -#define HIF_MBOX1_BLOCK_SIZE HIF_MBOX_BLOCK_SIZE -#define HIF_MBOX2_BLOCK_SIZE HIF_MBOX_BLOCK_SIZE -#define HIF_MBOX3_BLOCK_SIZE HIF_MBOX_BLOCK_SIZE - /* * direction - Direction of transfer (HIF_SDIO_READ/HIF_SDIO_WRITE). */ @@ -113,17 +107,6 @@ #define HIF_AMODE_MASK (HIF_FIXED_ADDRESS | \ HIF_INCREMENTAL_ADDRESS) -/* - * data written into the dummy space will not put into the final mbox FIFO - */ -#define HIF_DUMMY_SPACE_MASK 0xFFFF0000 - -/* - * data written into the dummy space will not put into the final mbox FIFO - */ -#define HIF_DUMMY_SPACE_MASK 0xFFFF0000 - - #define HIF_WR_ASYNC_BYTE_FIX \ (HIF_SDIO_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | \ HIF_BYTE_BASIS | HIF_FIXED_ADDRESS) diff --git a/hif/src/sdio/native_sdio/src/dev_quirks.c b/hif/src/sdio/native_sdio/src/dev_quirks.c index 76440211ad3c..65c2c75ddeca 100644 --- a/hif/src/sdio/native_sdio/src/dev_quirks.c +++ b/hif/src/sdio/native_sdio/src/dev_quirks.c @@ -39,6 +39,7 @@ #include "regtable_sdio.h" #include "wma_api.h" #include "hif_internal.h" +#include /* QUIRK PARAMETERS */ unsigned int writecccr1; diff --git a/hif/src/sdio/native_sdio/src/hif.c b/hif/src/sdio/native_sdio/src/hif.c index 5bba6ddd52d2..2da8bd3e8471 100644 --- a/hif/src/sdio/native_sdio/src/hif.c +++ b/hif/src/sdio/native_sdio/src/hif.c @@ -36,6 +36,7 @@ #include "regtable_sdio.h" #include "wma_api.h" #include "hif_internal.h" +#include /* by default setup a bounce buffer for the data packets, * if the underlying host controller driver @@ -261,8 +262,7 @@ QDF_STATUS hif_init(struct osdrv_callbacks *callbacks) */ static QDF_STATUS __hif_read_write(struct hif_sdio_dev *device, - uint32_t address, - char *buffer, + uint32_t address, char *buffer, uint32_t length, uint32_t request, void *context) { uint8_t opcode; @@ -271,22 +271,26 @@ __hif_read_write(struct hif_sdio_dev *device, uint8_t *tbuffer; bool bounced = false; - AR_DEBUG_ASSERT(device != NULL); - AR_DEBUG_ASSERT(device->func != NULL); - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, - ("__hif_read_write, addr:0X%06X, len:%08d, %s, %s\n", - address, length, - request & HIF_SDIO_READ ? "Read " : "Write", - request & HIF_ASYNCHRONOUS ? "Async" : "Sync ")); + if (device == NULL) { + HIF_ERROR("%s: device null!", __func__); + return QDF_STATUS_E_INVAL; + } + + if (device->func == NULL) { + HIF_ERROR("%s: func null!", __func__); + return QDF_STATUS_E_INVAL; + } + + HIF_INFO("%s: addr:0X%06X, len:%08d, %s, %s", __func__, address, length, + request & HIF_SDIO_READ ? "Read " : "Write", + request & HIF_ASYNCHRONOUS ? "Async" : "Sync "); do { if (request & HIF_EXTENDED_IO) { - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, - ("%s: Command type: CMD53\n", __func__)); + HIF_INFO_HI("%s: Command type: CMD53\n", __func__); } else { - AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, - ("%s: Invalid command type: 0x%08x\n", - __func__, request)); + HIF_ERROR("%s: Invalid command type: 0x%08x\n", + __func__, request); status = QDF_STATUS_E_INVAL; break; } @@ -294,89 +298,39 @@ __hif_read_write(struct hif_sdio_dev *device, if (request & HIF_BLOCK_BASIS) { /* round to whole block length size */ length = - (length / HIF_MBOX_BLOCK_SIZE) * - HIF_MBOX_BLOCK_SIZE; - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, - ("%s: Block mode (BlockLen: %d)\n", - __func__, length)); + (length / HIF_BLOCK_SIZE) * + HIF_BLOCK_SIZE; + HIF_INFO_HI("%s: Block mode (BlockLen: %d)\n", + __func__, length); } else if (request & HIF_BYTE_BASIS) { - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, - ("%s: Byte mode (BlockLen: %d)\n", - __func__, length)); + HIF_INFO_HI("%s: Byte mode (BlockLen: %d)\n", + __func__, length); } else { - AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, - ("%s: Invalid data mode: 0x%08x\n", - __func__, request)); + HIF_ERROR("%s: Invalid data mode: 0x%08x\n", + __func__, request); status = QDF_STATUS_E_INVAL; break; } if (request & HIF_SDIO_WRITE) { - struct hif_device_mbox_info MailBoxInfo; - unsigned int mboxLength = 0; + hif_fixup_write_param(device, request, + &length, &address); - hif_configure_device(device, - HIF_DEVICE_GET_MBOX_ADDR, - &MailBoxInfo, sizeof(MailBoxInfo)); - if (address >= 0x800 && address < 0xC00) { - /* Host control register and CIS Window */ - mboxLength = 0; - } else if (address == MailBoxInfo.mbox_addresses[0] - || address == MailBoxInfo.mbox_addresses[1] - || address == MailBoxInfo.mbox_addresses[2] - || address == - MailBoxInfo.mbox_addresses[3]) { - mboxLength = HIF_MBOX_WIDTH; - } else if (address == - MailBoxInfo.mbox_prop[0].extended_address) { - mboxLength = - MailBoxInfo.mbox_prop[0].extended_size; - } else if (address == - MailBoxInfo.mbox_prop[1].extended_address) { - mboxLength = - MailBoxInfo.mbox_prop[1].extended_size; - } else { - AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, - ("Invalid written address: 0x%08x\n", - address)); - break; - } - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, - ("address:%08X, Length:0x%08X, Dummy:0x%04X, Final:0x%08X\n", - address, length, - (request & HIF_DUMMY_SPACE_MASK) >> 16, - mboxLength == - 0 ? address : address + (mboxLength - - length))); - if (mboxLength != 0) { - if (length > mboxLength) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, - ("%s: written length(0x%08X) larger than mbox len(0x%08x)\n", - __func__, length, mboxLength)); - break; - } - address += (mboxLength - length); - /* - * plus dummy byte count - */ - address += ((request & - HIF_DUMMY_SPACE_MASK) >> 16); - } + HIF_INFO_HI("addr:%08X, len:0x%08X, dummy:0x%04X\n", + address, length, + (request & HIF_DUMMY_SPACE_MASK) >> 16); } if (request & HIF_FIXED_ADDRESS) { opcode = CMD53_FIXED_ADDRESS; - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, - ("%s: Address mode: Fixed 0x%X\n", - __func__, address)); + HIF_INFO_HI("%s: Addr mode: fixed 0x%X\n", + __func__, address); } else if (request & HIF_INCREMENTAL_ADDRESS) { opcode = CMD53_INCR_ADDRESS; - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, - ("%s: Address mode: Incremental 0x%X\n", - __func__, address)); + HIF_INFO_HI("%s: Address mode: Incremental 0x%X\n", + __func__, address); } else { - AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, - ("%s: Invalid address mode: 0x%08x\n", - __func__, request)); + HIF_ERROR("%s: Invalid address mode: 0x%08x\n", + __func__, request); status = QDF_STATUS_E_INVAL; break; } @@ -389,9 +343,8 @@ __hif_read_write(struct hif_sdio_dev *device, /* copy the write data to the dma buffer */ AR_DEBUG_ASSERT(length <= HIF_DMA_BUFFER_SIZE); if (length > HIF_DMA_BUFFER_SIZE) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, - ("%s: Invalid write length: %d\n", - __func__, length)); + HIF_ERROR("%s: Invalid write len: %d\n", + __func__, length); status = QDF_STATUS_E_INVAL; break; } @@ -404,22 +357,17 @@ __hif_read_write(struct hif_sdio_dev *device, tbuffer = buffer; #endif if (opcode == CMD53_FIXED_ADDRESS && tbuffer != NULL) { - ret = - sdio_writesb(device->func, address, - tbuffer, - length); - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, - ("%s: writesb ret=%d address: 0x%X, len: %d, 0x%X\n", - __func__, ret, address, length, - *(int *)tbuffer)); + ret = sdio_writesb(device->func, address, + tbuffer, length); + HIF_INFO_HI("%s:r=%d addr:0x%X, len:%d, 0x%X\n", + __func__, ret, address, length, + *(int *)tbuffer); } else if (tbuffer) { - ret = - sdio_memcpy_toio(device->func, address, - tbuffer, length); - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, - ("%s: writeio ret=%d address: 0x%X, len: %d, 0x%X\n", - __func__, ret, address, length, - *(int *)tbuffer)); + ret = sdio_memcpy_toio(device->func, address, + tbuffer, length); + HIF_INFO_HI("%s:r=%d addr:0x%X, len:%d, 0x%X\n", + __func__, ret, address, length, + *(int *)tbuffer); } } else if (request & HIF_SDIO_READ) { #if HIF_USE_DMA_BOUNCE_BUFFER @@ -442,46 +390,37 @@ __hif_read_write(struct hif_sdio_dev *device, tbuffer = buffer; #endif if (opcode == CMD53_FIXED_ADDRESS && tbuffer != NULL) { - ret = - sdio_readsb(device->func, tbuffer, - address, - length); - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, - ("%s: readsb ret=%d address: 0x%X, len: %d, 0x%X\n", - __func__, ret, address, length, - *(int *)tbuffer)); + ret = sdio_readsb(device->func, tbuffer, + address, length); + HIF_INFO_HI("%s:r=%d addr:0x%X, len:%d, 0x%X\n", + __func__, ret, address, length, + *(int *)tbuffer); } else if (tbuffer) { - ret = - sdio_memcpy_fromio(device->func, - tbuffer, - address, length); - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, - ("%s: readio ret=%d address: 0x%X, len: %d, 0x%X\n", - __func__, ret, address, length, - *(int *)tbuffer)); + ret = sdio_memcpy_fromio(device->func, + tbuffer, address, + length); + HIF_INFO_HI("%s:r=%d addr:0x%X, len:%d, 0x%X\n", + __func__, ret, address, length, + *(int *)tbuffer); } #if HIF_USE_DMA_BOUNCE_BUFFER if (bounced && tbuffer) memcpy(buffer, tbuffer, length); #endif } else { - AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, - ("%s: Invalid direction: 0x%08x\n", - __func__, request)); + HIF_ERROR("%s: Invalid dir: 0x%08x", __func__, request); status = QDF_STATUS_E_INVAL; return status; } if (ret) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, - ("%s: SDIO bus operation failed! MMC stack returned : %d\n", - __func__, ret)); - AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, - ("__hif_read_write, addr:0X%06X, len:%08d, %s, %s\n", - address, length, - request & HIF_SDIO_READ ? "Read " : "Write", - request & HIF_ASYNCHRONOUS ? "Async" : - "Sync ")); + HIF_ERROR("%s: SDIO bus operation failed!", __func__); + HIF_ERROR("%s: MMC stack returned : %d", __func__, ret); + HIF_ERROR("%s: addr:0X%06X, len:%08d, %s, %s", + __func__, address, length, + request & HIF_SDIO_READ ? "Read " : "Write", + request & HIF_ASYNCHRONOUS ? + "Async" : "Sync"); status = QDF_STATUS_E_FAILURE; } } while (false); @@ -1036,15 +975,14 @@ hif_configure_device(struct hif_sdio_dev *device, QDF_STATUS status = QDF_STATUS_SUCCESS; switch (opcode) { -#ifdef CONFIG_SDIO_TRANSFER_MAILBOX - case HIF_DEVICE_GET_MBOX_BLOCK_SIZE: - hif_dev_get_mbox_block_size(config); + case HIF_DEVICE_GET_BLOCK_SIZE: + hif_dev_get_block_size(config); break; - case HIF_DEVICE_GET_MBOX_ADDR: - hif_dev_get_mbox_address(device, config, config_len); + case HIF_DEVICE_GET_FIFO_ADDR: + hif_dev_get_fifo_address(device, config, config_len); break; -#endif + case HIF_DEVICE_GET_PENDING_EVENTS_FUNC: HIF_WARN("%s: opcode %d", __func__, opcode); status = QDF_STATUS_E_FAILURE; @@ -1729,10 +1667,10 @@ static QDF_STATUS hif_enable_func(struct hif_sdio_dev *device, return QDF_STATUS_E_FAILURE; } - ret = sdio_set_block_size(func, HIF_MBOX_BLOCK_SIZE); + ret = sdio_set_block_size(func, HIF_BLOCK_SIZE); if (ret) { HIF_ERROR("%s: Unable to set block size 0x%X : %d\n", - __func__, HIF_MBOX_BLOCK_SIZE, ret); + __func__, HIF_BLOCK_SIZE, ret); sdio_release_host(func); return QDF_STATUS_E_FAILURE; } diff --git a/hif/src/sdio/native_sdio/src/hif_scatter.c b/hif/src/sdio/native_sdio/src/hif_scatter.c index fb135b392887..c3c28aed4d9c 100644 --- a/hif/src/sdio/native_sdio/src/hif_scatter.c +++ b/hif/src/sdio/native_sdio/src/hif_scatter.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -27,6 +27,7 @@ #include "dl_list.h" #define ATH_MODULE_NAME hif #include "a_debug.h" +#include #ifdef HIF_LINUX_MMC_SCATTER_SUPPORT @@ -123,8 +124,8 @@ QDF_STATUS do_hif_read_write_scatter(struct hif_sdio_dev *device, memset(&cmd, 0, sizeof(struct mmc_command)); memset(&data, 0, sizeof(struct mmc_data)); - data.blksz = HIF_MBOX_BLOCK_SIZE; - data.blocks = req->total_length / HIF_MBOX_BLOCK_SIZE; + data.blksz = HIF_BLOCK_SIZE; + data.blocks = req->total_length / HIF_BLOCK_SIZE; AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, ("HIF-SCATTER: (%s) Address: 0x%X, (BlockLen: %d, BlockCount: %d), (tot:%d,sg:%d)\n", diff --git a/hif/src/sdio/transfer/mailbox.c b/hif/src/sdio/transfer/mailbox.c index 89ebdc10dd83..b2b930d813ef 100644 --- a/hif/src/sdio/transfer/mailbox.c +++ b/hif/src/sdio/transfer/mailbox.c @@ -171,13 +171,13 @@ static void set_extended_mbox_window_info(uint16_t manf_id, } /** - * hif_dev_get_mbox_address() - get the mbox addresses for dma + * hif_dev_get_fifo_address() - get the fifo addresses for dma * @pdev: SDIO HIF object * @config: mbox address config pointer * * Return : 0 for success, non-zero for error */ -QDF_STATUS hif_dev_get_mbox_address(struct hif_sdio_dev *pdev, +QDF_STATUS hif_dev_get_fifo_address(struct hif_sdio_dev *pdev, struct hif_device_mbox_info *config, uint32_t config_len) { @@ -196,12 +196,12 @@ QDF_STATUS hif_dev_get_mbox_address(struct hif_sdio_dev *pdev, } /** - * hif_dev_get_mbox_size() - get the mbox block size for dma + * hif_dev_get_block_size() - get the mbox block size for dma * @config : mbox size config pointer * * Return : NONE */ -void hif_dev_get_mbox_block_size(void *config) +void hif_dev_get_block_size(void *config) { ((uint32_t *)config)[0] = HIF_MBOX0_BLOCK_SIZE; ((uint32_t *)config)[1] = HIF_MBOX1_BLOCK_SIZE; @@ -267,6 +267,35 @@ QDF_STATUS hif_dev_map_service_to_pipe(struct hif_sdio_dev *pdev, uint16_t svc, return status; } +/** hif_dev_setup_device() - Setup device specific stuff here required for hif + * @pdev : HIF layer object + * + * return 0 on success, error otherwise + */ +int hif_dev_setup_device(struct hif_sdio_device *pdev) +{ + int status = 0; + uint32_t blocksizes[MAILBOX_COUNT]; + + status = hif_configure_device(pdev->HIFDevice, + HIF_DEVICE_GET_FIFO_ADDR, + &pdev->MailBoxInfo, + sizeof(pdev->MailBoxInfo)); + + if (status != QDF_STATUS_SUCCESS) + HIF_ERROR("%s: HIF_DEVICE_GET_MBOX_ADDR failed", __func__); + + status = hif_configure_device(pdev->HIFDevice, + HIF_DEVICE_GET_BLOCK_SIZE, + blocksizes, sizeof(blocksizes)); + if (status != QDF_STATUS_SUCCESS) + HIF_ERROR("%s: HIF_DEVICE_GET_MBOX_BLOCK_SIZE fail", __func__); + + pdev->BlockSize = blocksizes[MAILBOX_FOR_BLOCK_SIZE]; + + return status; +} + /** hif_dev_mask_interrupts() - Disable the interrupts in the device * @pdev SDIO HIF Object * @@ -476,6 +505,53 @@ int hif_get_send_address(struct hif_sdio_device *pdev, return 0; } +/** + * hif_fixup_write_param() - Tweak the address and length parameters + * @pdev: The pointer to the hif device object + * @length: The length pointer + * @addr: The addr pointer + * + * Return: None + */ +void hif_fixup_write_param(struct hif_sdio_dev *pdev, uint32_t req, + uint32_t *length, uint32_t *addr) +{ + struct hif_device_mbox_info mboxinfo; + uint32_t taddr = *addr, mboxlen = 0; + + hif_configure_device(pdev, HIF_DEVICE_GET_FIFO_ADDR, + &mboxinfo, sizeof(mboxinfo)); + + if (taddr >= 0x800 && taddr < 0xC00) { + /* Host control register and CIS Window */ + mboxlen = 0; + } else if (taddr == mboxinfo.mbox_addresses[0] || + taddr == mboxinfo.mbox_addresses[1] || + taddr == mboxinfo.mbox_addresses[2] || + taddr == mboxinfo.mbox_addresses[3]) { + mboxlen = HIF_MBOX_WIDTH; + } else if (taddr == mboxinfo.mbox_prop[0].extended_address) { + mboxlen = mboxinfo.mbox_prop[0].extended_size; + } else if (taddr == mboxinfo.mbox_prop[1].extended_address) { + mboxlen = mboxinfo.mbox_prop[1].extended_size; + } else { + HIF_ERROR("%s: Invalid write addr: 0x%08x\n", __func__, taddr); + return; + } + + if (mboxlen != 0) { + if (*length > mboxlen) { + HIF_ERROR("%s: Error (%u > %u)", + __func__, *length, mboxlen); + return; + } + + taddr = taddr + (mboxlen - *length); + taddr = taddr + ((req & HIF_DUMMY_SPACE_MASK) >> 16); + *addr = taddr; + } +} + /** * hif_dev_recv_packet() - Receieve HTC packet/packet information from device * @pdev : HIF device object @@ -589,7 +665,7 @@ static QDF_STATUS hif_dev_issue_recv_packet_bundle DEV_CALC_RECV_PADDED_LEN(pdev, packet->ActualLength); if (packet->PktInfo.AsRx.HTCRxFlags & HTC_RX_PKT_LAST_BUNDLED_PKT_HAS_ADDTIONAL_BLOCK) - padded_length += HIF_MBOX_BLOCK_SIZE; + padded_length += HIF_BLOCK_SIZE; if ((bundleSpaceRemaining - padded_length) < 0) { /* exceeds what we can transfer, put the packet back */ HTC_PACKET_ENQUEUE_TO_HEAD(recv_pkt_queue, packet); @@ -637,7 +713,7 @@ static QDF_STATUS hif_dev_issue_recv_packet_bundle if (packet->PktInfo.AsRx.HTCRxFlags & HTC_RX_PKT_LAST_BUNDLED_PKT_HAS_ADDTIONAL_BLOCK) padded_length += - HIF_MBOX_BLOCK_SIZE; + HIF_BLOCK_SIZE; A_MEMCPY(packet->pBuffer, buffer, padded_length); buffer += padded_length; diff --git a/hif/src/sdio/transfer/mailbox.h b/hif/src/sdio/transfer/mailbox.h index 0771ec1d6bfb..9123d872e76d 100644 --- a/hif/src/sdio/transfer/mailbox.h +++ b/hif/src/sdio/transfer/mailbox.h @@ -49,6 +49,108 @@ #endif #define AR6K_TARGET_DEBUG_INTR_MASK 0x01 +/* Mailbox address in SDIO address space */ +#if defined(SDIO_3_0) +#define HIF_MBOX_BASE_ADDR 0x1000 +#define HIF_MBOX_DUMMY_WIDTH 0x800 +#else +#define HIF_MBOX_BASE_ADDR 0x800 +#define HIF_MBOX_DUMMY_WIDTH 0 +#endif + +#define HIF_MBOX_WIDTH 0x800 + +#define HIF_MBOX_START_ADDR(mbox) \ + (HIF_MBOX_BASE_ADDR + mbox * (HIF_MBOX_WIDTH + HIF_MBOX_DUMMY_WIDTH)) + +#define HIF_MBOX_END_ADDR(mbox) \ + (HIF_MBOX_START_ADDR(mbox) + HIF_MBOX_WIDTH - 1) + +/* extended MBOX address for larger MBOX writes to MBOX 0*/ +#if defined(SDIO_3_0) +#define HIF_MBOX0_EXTENDED_BASE_ADDR 0x5000 +#else +#define HIF_MBOX0_EXTENDED_BASE_ADDR 0x2800 +#endif +#define HIF_MBOX0_EXTENDED_WIDTH_AR6002 (6 * 1024) +#define HIF_MBOX0_EXTENDED_WIDTH_AR6003 (18 * 1024) + +/* version 1 of the chip has only a 12K extended mbox range */ +#define HIF_MBOX0_EXTENDED_BASE_ADDR_AR6003_V1 0x4000 +#define HIF_MBOX0_EXTENDED_WIDTH_AR6003_V1 (12 * 1024) + +#define HIF_MBOX0_EXTENDED_BASE_ADDR_AR6004 0x2800 +#define HIF_MBOX0_EXTENDED_WIDTH_AR6004 (18 * 1024) + +#if defined(SDIO_3_0) +#define HIF_MBOX0_EXTENDED_BASE_ADDR_AR6320 0x5000 +#define HIF_MBOX0_EXTENDED_WIDTH_AR6320 (36 * 1024) +#define HIF_MBOX0_EXTENDED_WIDTH_AR6320_ROME_2_0 (56 * 1024) +#define HIF_MBOX1_EXTENDED_WIDTH_AR6320 (36 * 1024) +#define HIF_MBOX_DUMMY_SPACE_SIZE_AR6320 (2 * 1024) +#else +#define HIF_MBOX0_EXTENDED_BASE_ADDR_AR6320 0x2800 +#define HIF_MBOX0_EXTENDED_WIDTH_AR6320 (24 * 1024) +#define HIF_MBOX1_EXTENDED_WIDTH_AR6320 (24 * 1024) +#define HIF_MBOX_DUMMY_SPACE_SIZE_AR6320 0 +#endif + +/* GMBOX addresses */ +#define HIF_GMBOX_BASE_ADDR 0x7000 +#define HIF_GMBOX_WIDTH 0x4000 + +/* for SDIO we recommend a 128-byte block size */ +#if defined(WITH_BACKPORTS) +#define HIF_DEFAULT_IO_BLOCK_SIZE 128 +#else +#define HIF_DEFAULT_IO_BLOCK_SIZE 256 +#endif + +#define FIFO_TIMEOUT_AND_CHIP_CONTROL 0x00000868 +#define FIFO_TIMEOUT_AND_CHIP_CONTROL_DISABLE_SLEEP_OFF 0xFFFEFFFF +#define FIFO_TIMEOUT_AND_CHIP_CONTROL_DISABLE_SLEEP_ON 0x10000 +/* In SDIO 2.0, asynchronous interrupt is not in SPEC + * requirement, but AR6003 support it, so the register + * is placed in vendor specific field 0xF0(bit0) + * In SDIO 3.0, the register is defined in SPEC, and its + * address is 0x16(bit1) + */ +/* interrupt mode register of AR6003 */ +#define CCCR_SDIO_IRQ_MODE_REG_AR6003 0xF0 +/* mode to enable special 4-bit interrupt assertion without clock */ +#define SDIO_IRQ_MODE_ASYNC_4BIT_IRQ_AR6003 (1 << 0) +/* interrupt mode register of AR6320 */ +#define CCCR_SDIO_IRQ_MODE_REG_AR6320 0x16 +/* mode to enable special 4-bit interrupt assertion without clock */ +#define SDIO_IRQ_MODE_ASYNC_4BIT_IRQ_AR6320 (1 << 1) + +#define CCCR_SDIO_ASYNC_INT_DELAY_ADDRESS 0xF0 +#define CCCR_SDIO_ASYNC_INT_DELAY_LSB 0x06 +#define CCCR_SDIO_ASYNC_INT_DELAY_MASK 0xC0 + +/* Vendor Specific Driver Strength Settings */ +#define CCCR_SDIO_DRIVER_STRENGTH_ENABLE_ADDR 0xf2 +#define CCCR_SDIO_DRIVER_STRENGTH_ENABLE_MASK 0x0e +#define CCCR_SDIO_DRIVER_STRENGTH_ENABLE_A 0x02 +#define CCCR_SDIO_DRIVER_STRENGTH_ENABLE_C 0x04 +#define CCCR_SDIO_DRIVER_STRENGTH_ENABLE_D 0x08 + +#define HIF_BLOCK_SIZE HIF_DEFAULT_IO_BLOCK_SIZE +#define HIF_MBOX0_BLOCK_SIZE 1 +#define HIF_MBOX1_BLOCK_SIZE HIF_BLOCK_SIZE +#define HIF_MBOX2_BLOCK_SIZE HIF_BLOCK_SIZE +#define HIF_MBOX3_BLOCK_SIZE HIF_BLOCK_SIZE + +/* + * data written into the dummy space will not put into the final mbox FIFO + */ +#define HIF_DUMMY_SPACE_MASK 0xFFFF0000 + +/* + * data written into the dummy space will not put into the final mbox FIFO + */ +#define HIF_DUMMY_SPACE_MASK 0xFFFF0000 + PREPACK struct MBOX_IRQ_PROC_REGISTERS { uint8_t host_int_status; uint8_t cpu_int_status; diff --git a/hif/src/sdio/transfer/transfer.h b/hif/src/sdio/transfer/transfer.h index 6dc6bd4e2df0..4a728385134a 100644 --- a/hif/src/sdio/transfer/transfer.h +++ b/hif/src/sdio/transfer/transfer.h @@ -90,6 +90,9 @@ QDF_STATUS hif_dev_process_recv_header(struct hif_sdio_device *pdev, HTC_PACKET *packet, uint32_t *next_look_aheads, int *num_look_aheads); +void hif_fixup_write_param(struct hif_sdio_dev *pdev, uint32_t req, + uint32_t *length, uint32_t *addr); + #ifdef CONFIG_SDIO_TRANSFER_MAILBOX static inline uint32_t hif_get_send_buffer_flags(struct hif_sdio_device *pdev) {