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
This commit is contained in:
Sriram Madhvapathi
2018-05-15 15:34:05 +05:30
committed by nshrivas
parent 12bcba2d71
commit 303c73c76d
13 changed files with 286 additions and 275 deletions

View File

@@ -362,8 +362,8 @@ enum hif_disable_type {
*/ */
enum hif_device_config_opcode { enum hif_device_config_opcode {
HIF_DEVICE_POWER_STATE = 0, HIF_DEVICE_POWER_STATE = 0,
HIF_DEVICE_GET_MBOX_BLOCK_SIZE, HIF_DEVICE_GET_BLOCK_SIZE,
HIF_DEVICE_GET_MBOX_ADDR, HIF_DEVICE_GET_FIFO_ADDR,
HIF_DEVICE_GET_PENDING_EVENTS_FUNC, HIF_DEVICE_GET_PENDING_EVENTS_FUNC,
HIF_DEVICE_GET_IRQ_PROC_MODE, HIF_DEVICE_GET_IRQ_PROC_MODE,
HIF_DEVICE_GET_RECV_EVENT_MASK_UNMASK_FUNC, HIF_DEVICE_GET_RECV_EVENT_MASK_UNMASK_FUNC,

View File

@@ -50,7 +50,7 @@ hif_bmi_buffer_send(struct hif_sdio_dev *device, char *buffer, uint32_t length)
uint32_t address; uint32_t address;
uint32_t mbox_address[HTC_MAILBOX_NUM_MAX]; 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)); &mbox_address[0], sizeof(mbox_address));
*p_bmi_cmd_credits = 0; *p_bmi_cmd_credits = 0;
@@ -176,7 +176,7 @@ hif_bmi_buffer_receive(struct hif_sdio_dev *device,
pending_events_func_check = true; 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)); &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_softc *scn = HIF_GET_SDIO_SOFTC(hif_ctx);
struct hif_sdio_dev *device = scn->hif_handle; 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", ("BMI Get Target Info: Enter (device: 0x%pK)\n",
device)); device));
cid = BMI_GET_TARGET_INFO; 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; 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", ("BMI Get Target Info: Exit (ver: 0x%x type: 0x%x)\n",
targ_info->target_ver, targ_info->target_ver,
targ_info->target_type)); targ_info->target_type));

View File

@@ -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_dev *hif_device = scn->hif_handle;
struct hif_sdio_device *htc_sdio_device = hif_dev_from_hif(hif_device); struct hif_sdio_device *htc_sdio_device = hif_dev_from_hif(hif_device);
HIF_ENTER();
if (htc_sdio_device == NULL) if (htc_sdio_device == NULL)
htc_sdio_device = hif_dev_create(hif_device, callbacks, target); htc_sdio_device = hif_dev_create(hif_device, callbacks, target);
if (htc_sdio_device) if (htc_sdio_device)
hif_dev_setup(htc_sdio_device); hif_dev_setup(htc_sdio_device);
HIF_EXIT();
} }
/** /**

View File

@@ -32,92 +32,5 @@
#define FUNCTION_CLASS 0x0 #define FUNCTION_CLASS 0x0
#define MANUFACTURER_CODE 0x271 #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_ */ #endif /* _HIF_SDIO_COMMON_H_ */

View File

@@ -87,6 +87,7 @@ struct hif_sdio_device *hif_dev_create(struct hif_sdio_dev *hif_device,
QDF_STATUS status; QDF_STATUS status;
struct hif_sdio_device *pdev; struct hif_sdio_device *pdev;
HIF_ENTER();
pdev = qdf_mem_malloc(sizeof(struct hif_sdio_device)); pdev = qdf_mem_malloc(sizeof(struct hif_sdio_device));
if (!pdev) { if (!pdev) {
A_ASSERT(false); 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)); A_MEMCPY(&pdev->hif_callbacks, callbacks, sizeof(*callbacks));
HIF_EXIT();
return pdev; 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 hif_dev_setup(struct hif_sdio_device *pdev)
{ {
QDF_STATUS status; QDF_STATUS status;
uint32_t blocksizes[MAILBOX_COUNT];
struct htc_callbacks htc_cbs; struct htc_callbacks htc_cbs;
struct hif_sdio_dev *hif_device = pdev->HIFDevice; struct hif_sdio_dev *hif_device = pdev->HIFDevice;
HIF_ENTER(); HIF_ENTER();
status = hif_configure_device(hif_device, status = hif_dev_setup_device(pdev);
HIF_DEVICE_GET_MBOX_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(hif_device,
HIF_DEVICE_GET_MBOX_BLOCK_SIZE,
blocksizes, sizeof(blocksizes));
if (status != QDF_STATUS_SUCCESS) { if (status != QDF_STATUS_SUCCESS) {
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, HIF_ERROR("%s: device specific setup failed", __func__);
("(%s)HIF_DEVICE_GET_MBOX_BLOCK_SIZE failed!!!\n", return QDF_STATUS_E_INVAL;
__func__));
A_ASSERT(false);
} }
pdev->BlockSize = blocksizes[MAILBOX_FOR_BLOCK_SIZE];
pdev->BlockMask = pdev->BlockSize - 1; pdev->BlockMask = pdev->BlockSize - 1;
A_ASSERT((pdev->BlockSize & pdev->BlockMask) == 0); A_ASSERT((pdev->BlockSize & pdev->BlockMask) == 0);

View File

@@ -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); void hif_dev_unmask_interrupts(struct hif_sdio_device *pdev);
#ifdef CONFIG_SDIO_TRANSFER_MAILBOX int hif_dev_setup_device(struct hif_sdio_device *pdev);
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, struct hif_device_mbox_info *config,
uint32_t config_len); 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); void hif_dev_set_mailbox_swap(struct hif_sdio_dev *pdev);
bool hif_dev_get_mailbox_swap(struct hif_sdio_dev *pdev); bool hif_dev_get_mailbox_swap(struct hif_sdio_dev *pdev);
#endif
#endif /* HIF_SDIO_DEV_H_ */ #endif /* HIF_SDIO_DEV_H_ */

View File

@@ -50,12 +50,6 @@
#define FLAGS_CARD_ENAB 0x02 #define FLAGS_CARD_ENAB 0x02
#define FLAGS_CARD_IRQ_UNMSK 0x04 #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). * direction - Direction of transfer (HIF_SDIO_READ/HIF_SDIO_WRITE).
*/ */
@@ -113,17 +107,6 @@
#define HIF_AMODE_MASK (HIF_FIXED_ADDRESS | \ #define HIF_AMODE_MASK (HIF_FIXED_ADDRESS | \
HIF_INCREMENTAL_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 \ #define HIF_WR_ASYNC_BYTE_FIX \
(HIF_SDIO_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | \ (HIF_SDIO_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | \
HIF_BYTE_BASIS | HIF_FIXED_ADDRESS) HIF_BYTE_BASIS | HIF_FIXED_ADDRESS)

View File

@@ -39,6 +39,7 @@
#include "regtable_sdio.h" #include "regtable_sdio.h"
#include "wma_api.h" #include "wma_api.h"
#include "hif_internal.h" #include "hif_internal.h"
#include <transfer/transfer.h>
/* QUIRK PARAMETERS */ /* QUIRK PARAMETERS */
unsigned int writecccr1; unsigned int writecccr1;

View File

@@ -36,6 +36,7 @@
#include "regtable_sdio.h" #include "regtable_sdio.h"
#include "wma_api.h" #include "wma_api.h"
#include "hif_internal.h" #include "hif_internal.h"
#include <transfer/transfer.h>
/* by default setup a bounce buffer for the data packets, /* by default setup a bounce buffer for the data packets,
* if the underlying host controller driver * if the underlying host controller driver
@@ -261,8 +262,7 @@ QDF_STATUS hif_init(struct osdrv_callbacks *callbacks)
*/ */
static QDF_STATUS static QDF_STATUS
__hif_read_write(struct hif_sdio_dev *device, __hif_read_write(struct hif_sdio_dev *device,
uint32_t address, uint32_t address, char *buffer,
char *buffer,
uint32_t length, uint32_t request, void *context) uint32_t length, uint32_t request, void *context)
{ {
uint8_t opcode; uint8_t opcode;
@@ -271,22 +271,26 @@ __hif_read_write(struct hif_sdio_dev *device,
uint8_t *tbuffer; uint8_t *tbuffer;
bool bounced = false; bool bounced = false;
AR_DEBUG_ASSERT(device != NULL); if (device == NULL) {
AR_DEBUG_ASSERT(device->func != NULL); HIF_ERROR("%s: device null!", __func__);
AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, return QDF_STATUS_E_INVAL;
("__hif_read_write, addr:0X%06X, len:%08d, %s, %s\n", }
address, length,
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_SDIO_READ ? "Read " : "Write",
request & HIF_ASYNCHRONOUS ? "Async" : "Sync ")); request & HIF_ASYNCHRONOUS ? "Async" : "Sync ");
do { do {
if (request & HIF_EXTENDED_IO) { if (request & HIF_EXTENDED_IO) {
AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, HIF_INFO_HI("%s: Command type: CMD53\n", __func__);
("%s: Command type: CMD53\n", __func__));
} else { } else {
AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, HIF_ERROR("%s: Invalid command type: 0x%08x\n",
("%s: Invalid command type: 0x%08x\n", __func__, request);
__func__, request));
status = QDF_STATUS_E_INVAL; status = QDF_STATUS_E_INVAL;
break; break;
} }
@@ -294,89 +298,39 @@ __hif_read_write(struct hif_sdio_dev *device,
if (request & HIF_BLOCK_BASIS) { if (request & HIF_BLOCK_BASIS) {
/* round to whole block length size */ /* round to whole block length size */
length = length =
(length / HIF_MBOX_BLOCK_SIZE) * (length / HIF_BLOCK_SIZE) *
HIF_MBOX_BLOCK_SIZE; HIF_BLOCK_SIZE;
AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, HIF_INFO_HI("%s: Block mode (BlockLen: %d)\n",
("%s: Block mode (BlockLen: %d)\n", __func__, length);
__func__, length));
} else if (request & HIF_BYTE_BASIS) { } else if (request & HIF_BYTE_BASIS) {
AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, HIF_INFO_HI("%s: Byte mode (BlockLen: %d)\n",
("%s: Byte mode (BlockLen: %d)\n", __func__, length);
__func__, length));
} else { } else {
AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, HIF_ERROR("%s: Invalid data mode: 0x%08x\n",
("%s: Invalid data mode: 0x%08x\n", __func__, request);
__func__, request));
status = QDF_STATUS_E_INVAL; status = QDF_STATUS_E_INVAL;
break; break;
} }
if (request & HIF_SDIO_WRITE) { if (request & HIF_SDIO_WRITE) {
struct hif_device_mbox_info MailBoxInfo; hif_fixup_write_param(device, request,
unsigned int mboxLength = 0; &length, &address);
hif_configure_device(device, HIF_INFO_HI("addr:%08X, len:0x%08X, dummy:0x%04X\n",
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, address, length,
(request & HIF_DUMMY_SPACE_MASK) >> 16, (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);
}
} }
if (request & HIF_FIXED_ADDRESS) { if (request & HIF_FIXED_ADDRESS) {
opcode = CMD53_FIXED_ADDRESS; opcode = CMD53_FIXED_ADDRESS;
AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, HIF_INFO_HI("%s: Addr mode: fixed 0x%X\n",
("%s: Address mode: Fixed 0x%X\n", __func__, address);
__func__, address));
} else if (request & HIF_INCREMENTAL_ADDRESS) { } else if (request & HIF_INCREMENTAL_ADDRESS) {
opcode = CMD53_INCR_ADDRESS; opcode = CMD53_INCR_ADDRESS;
AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, HIF_INFO_HI("%s: Address mode: Incremental 0x%X\n",
("%s: Address mode: Incremental 0x%X\n", __func__, address);
__func__, address));
} else { } else {
AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, HIF_ERROR("%s: Invalid address mode: 0x%08x\n",
("%s: Invalid address mode: 0x%08x\n", __func__, request);
__func__, request));
status = QDF_STATUS_E_INVAL; status = QDF_STATUS_E_INVAL;
break; break;
} }
@@ -389,9 +343,8 @@ __hif_read_write(struct hif_sdio_dev *device,
/* copy the write data to the dma buffer */ /* copy the write data to the dma buffer */
AR_DEBUG_ASSERT(length <= HIF_DMA_BUFFER_SIZE); AR_DEBUG_ASSERT(length <= HIF_DMA_BUFFER_SIZE);
if (length > HIF_DMA_BUFFER_SIZE) { if (length > HIF_DMA_BUFFER_SIZE) {
AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, HIF_ERROR("%s: Invalid write len: %d\n",
("%s: Invalid write length: %d\n", __func__, length);
__func__, length));
status = QDF_STATUS_E_INVAL; status = QDF_STATUS_E_INVAL;
break; break;
} }
@@ -404,22 +357,17 @@ __hif_read_write(struct hif_sdio_dev *device,
tbuffer = buffer; tbuffer = buffer;
#endif #endif
if (opcode == CMD53_FIXED_ADDRESS && tbuffer != NULL) { if (opcode == CMD53_FIXED_ADDRESS && tbuffer != NULL) {
ret = ret = sdio_writesb(device->func, address,
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));
} else if (tbuffer) {
ret =
sdio_memcpy_toio(device->func, address,
tbuffer, length); tbuffer, length);
AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, HIF_INFO_HI("%s:r=%d addr:0x%X, len:%d, 0x%X\n",
("%s: writeio ret=%d address: 0x%X, len: %d, 0x%X\n",
__func__, ret, address, length, __func__, ret, address, length,
*(int *)tbuffer)); *(int *)tbuffer);
} else if (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) { } else if (request & HIF_SDIO_READ) {
#if HIF_USE_DMA_BOUNCE_BUFFER #if HIF_USE_DMA_BOUNCE_BUFFER
@@ -442,46 +390,37 @@ __hif_read_write(struct hif_sdio_dev *device,
tbuffer = buffer; tbuffer = buffer;
#endif #endif
if (opcode == CMD53_FIXED_ADDRESS && tbuffer != NULL) { if (opcode == CMD53_FIXED_ADDRESS && tbuffer != NULL) {
ret = ret = sdio_readsb(device->func, tbuffer,
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));
} else if (tbuffer) {
ret =
sdio_memcpy_fromio(device->func,
tbuffer,
address, length); address, length);
AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, HIF_INFO_HI("%s:r=%d addr:0x%X, len:%d, 0x%X\n",
("%s: readio ret=%d address: 0x%X, len: %d, 0x%X\n",
__func__, ret, address, length, __func__, ret, address, length,
*(int *)tbuffer)); *(int *)tbuffer);
} else if (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 HIF_USE_DMA_BOUNCE_BUFFER
if (bounced && tbuffer) if (bounced && tbuffer)
memcpy(buffer, tbuffer, length); memcpy(buffer, tbuffer, length);
#endif #endif
} else { } else {
AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, HIF_ERROR("%s: Invalid dir: 0x%08x", __func__, request);
("%s: Invalid direction: 0x%08x\n",
__func__, request));
status = QDF_STATUS_E_INVAL; status = QDF_STATUS_E_INVAL;
return status; return status;
} }
if (ret) { if (ret) {
AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, HIF_ERROR("%s: SDIO bus operation failed!", __func__);
("%s: SDIO bus operation failed! MMC stack returned : %d\n", HIF_ERROR("%s: MMC stack returned : %d", __func__, ret);
__func__, ret)); HIF_ERROR("%s: addr:0X%06X, len:%08d, %s, %s",
AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, __func__, address, length,
("__hif_read_write, addr:0X%06X, len:%08d, %s, %s\n",
address, length,
request & HIF_SDIO_READ ? "Read " : "Write", request & HIF_SDIO_READ ? "Read " : "Write",
request & HIF_ASYNCHRONOUS ? "Async" : request & HIF_ASYNCHRONOUS ?
"Sync ")); "Async" : "Sync");
status = QDF_STATUS_E_FAILURE; status = QDF_STATUS_E_FAILURE;
} }
} while (false); } while (false);
@@ -1036,15 +975,14 @@ hif_configure_device(struct hif_sdio_dev *device,
QDF_STATUS status = QDF_STATUS_SUCCESS; QDF_STATUS status = QDF_STATUS_SUCCESS;
switch (opcode) { switch (opcode) {
#ifdef CONFIG_SDIO_TRANSFER_MAILBOX case HIF_DEVICE_GET_BLOCK_SIZE:
case HIF_DEVICE_GET_MBOX_BLOCK_SIZE: hif_dev_get_block_size(config);
hif_dev_get_mbox_block_size(config);
break; break;
case HIF_DEVICE_GET_MBOX_ADDR: case HIF_DEVICE_GET_FIFO_ADDR:
hif_dev_get_mbox_address(device, config, config_len); hif_dev_get_fifo_address(device, config, config_len);
break; break;
#endif
case HIF_DEVICE_GET_PENDING_EVENTS_FUNC: case HIF_DEVICE_GET_PENDING_EVENTS_FUNC:
HIF_WARN("%s: opcode %d", __func__, opcode); HIF_WARN("%s: opcode %d", __func__, opcode);
status = QDF_STATUS_E_FAILURE; 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; 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) { if (ret) {
HIF_ERROR("%s: Unable to set block size 0x%X : %d\n", 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); sdio_release_host(func);
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;
} }

View File

@@ -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 * Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the * any purpose with or without fee is hereby granted, provided that the
@@ -27,6 +27,7 @@
#include "dl_list.h" #include "dl_list.h"
#define ATH_MODULE_NAME hif #define ATH_MODULE_NAME hif
#include "a_debug.h" #include "a_debug.h"
#include <transfer/transfer.h>
#ifdef HIF_LINUX_MMC_SCATTER_SUPPORT #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(&cmd, 0, sizeof(struct mmc_command));
memset(&data, 0, sizeof(struct mmc_data)); memset(&data, 0, sizeof(struct mmc_data));
data.blksz = HIF_MBOX_BLOCK_SIZE; data.blksz = HIF_BLOCK_SIZE;
data.blocks = req->total_length / HIF_MBOX_BLOCK_SIZE; data.blocks = req->total_length / HIF_BLOCK_SIZE;
AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER,
("HIF-SCATTER: (%s) Address: 0x%X, (BlockLen: %d, BlockCount: %d), (tot:%d,sg:%d)\n", ("HIF-SCATTER: (%s) Address: 0x%X, (BlockLen: %d, BlockCount: %d), (tot:%d,sg:%d)\n",

View File

@@ -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 * @pdev: SDIO HIF object
* @config: mbox address config pointer * @config: mbox address config pointer
* *
* Return : 0 for success, non-zero for error * 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, struct hif_device_mbox_info *config,
uint32_t config_len) 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 * @config : mbox size config pointer
* *
* Return : NONE * 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)[0] = HIF_MBOX0_BLOCK_SIZE;
((uint32_t *)config)[1] = HIF_MBOX1_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; 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 /** hif_dev_mask_interrupts() - Disable the interrupts in the device
* @pdev SDIO HIF Object * @pdev SDIO HIF Object
* *
@@ -476,6 +505,53 @@ int hif_get_send_address(struct hif_sdio_device *pdev,
return 0; 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 * hif_dev_recv_packet() - Receieve HTC packet/packet information from device
* @pdev : HIF device object * @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); DEV_CALC_RECV_PADDED_LEN(pdev, packet->ActualLength);
if (packet->PktInfo.AsRx.HTCRxFlags & if (packet->PktInfo.AsRx.HTCRxFlags &
HTC_RX_PKT_LAST_BUNDLED_PKT_HAS_ADDTIONAL_BLOCK) 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) { if ((bundleSpaceRemaining - padded_length) < 0) {
/* exceeds what we can transfer, put the packet back */ /* exceeds what we can transfer, put the packet back */
HTC_PACKET_ENQUEUE_TO_HEAD(recv_pkt_queue, packet); 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 & if (packet->PktInfo.AsRx.HTCRxFlags &
HTC_RX_PKT_LAST_BUNDLED_PKT_HAS_ADDTIONAL_BLOCK) HTC_RX_PKT_LAST_BUNDLED_PKT_HAS_ADDTIONAL_BLOCK)
padded_length += padded_length +=
HIF_MBOX_BLOCK_SIZE; HIF_BLOCK_SIZE;
A_MEMCPY(packet->pBuffer, A_MEMCPY(packet->pBuffer,
buffer, padded_length); buffer, padded_length);
buffer += padded_length; buffer += padded_length;

View File

@@ -49,6 +49,108 @@
#endif #endif
#define AR6K_TARGET_DEBUG_INTR_MASK 0x01 #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 { PREPACK struct MBOX_IRQ_PROC_REGISTERS {
uint8_t host_int_status; uint8_t host_int_status;
uint8_t cpu_int_status; uint8_t cpu_int_status;

View File

@@ -90,6 +90,9 @@ QDF_STATUS hif_dev_process_recv_header(struct hif_sdio_device *pdev,
HTC_PACKET *packet, HTC_PACKET *packet,
uint32_t *next_look_aheads, uint32_t *next_look_aheads,
int *num_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 #ifdef CONFIG_SDIO_TRANSFER_MAILBOX
static inline uint32_t hif_get_send_buffer_flags(struct hif_sdio_device *pdev) static inline uint32_t hif_get_send_buffer_flags(struct hif_sdio_device *pdev)
{ {