qcacmn: SDIO HIF layer refactor

Redo the hif layer object for separating the transfer methods
1. Move swap_mailbox from hif_sdio_dev to hif_sdio_device
2. Move the mailbox registers to mailbox specific file
3. Send request flags to be populated per transfer method

Change-Id: Ia53ab2b8cd39875d1e7353a212057ff010e89db8
CRs-Fixed: 2252410
This commit is contained in:
Sriram Madhvapathi 2018-05-14 12:38:04 +05:30 • committed by nshrivas
commit 12bcba2d71
9 changed files with 110 additions and 95 deletions

View file

@ -40,7 +40,6 @@
#include "if_sdio.h"
#include "regtable_sdio.h"
/**
* hif_dev_alloc_rx_buffer() - allocate rx buffer.
* @pDev: sdio device context
@ -293,6 +292,40 @@ QDF_STATUS hif_dev_dsr_handler(void *context)
return status;
}
/** hif_dev_set_mailbox_swap() - Set the mailbox swap from firmware
* @pdev : The HIF layer object
*
* Return: none
*/
void hif_dev_set_mailbox_swap(struct hif_sdio_dev *pdev)
{
struct hif_sdio_device *hif_device = hif_dev_from_hif(pdev);
HIF_ENTER();
hif_device->swap_mailbox = true;
HIF_EXIT();
}
/** hif_dev_get_mailbox_swap() - Get the mailbox swap setting
* @pdev : The HIF layer object
*
* Return: none
*/
bool hif_dev_get_mailbox_swap(struct hif_sdio_dev *pdev)
{
struct hif_sdio_device *hif_device;
HIF_ENTER();
hif_device = hif_dev_from_hif(pdev);
HIF_EXIT();
return hif_device->swap_mailbox;
}
/**
* hif_dev_setup() - set up sdio device.
* @pDev: sdio device context

View file

@ -64,5 +64,9 @@ QDF_STATUS hif_dev_get_mbox_address(struct hif_sdio_dev *pdev,
uint32_t config_len);
void hif_dev_get_mbox_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_ */

View file

@ -25,6 +25,14 @@
#include "htc_api.h"
#include "hif_internal.h"
#if defined(CONFIG_SDIO_TRANSFER_MAILBOX)
#include <transfer/mailbox.h>
#elif defined(CONFIG_SDIO_TRANSFER_ADMA)
#error "Error - Not implemented yet"
#else
#error "Error - Invalid transfer method"
#endif
#define INVALID_MAILBOX_NUMBER 0xFF
#define HIF_SDIO_RX_BUFFER_SIZE 1792
@ -37,51 +45,6 @@
#define ATH_DEBUG_MAX_MASK 32
#define OTHER_INTS_ENABLED (INT_STATUS_ENABLE_ERROR_MASK | \
INT_STATUS_ENABLE_CPU_MASK | \
INT_STATUS_ENABLE_COUNTER_MASK)
/* HTC operational parameters */
#define HTC_TARGET_RESPONSE_TIMEOUT 2000 /* in ms */
#define HTC_TARGET_DEBUG_INTR_MASK 0x01
#define HTC_TARGET_CREDIT_INTR_MASK 0xF0
#define MAILBOX_COUNT 4
#define MAILBOX_FOR_BLOCK_SIZE 1
#define MAILBOX_USED_COUNT 2
#if defined(SDIO_3_0)
#define MAILBOX_LOOKAHEAD_SIZE_IN_WORD 2
#else
#define MAILBOX_LOOKAHEAD_SIZE_IN_WORD 1
#endif
#define AR6K_TARGET_DEBUG_INTR_MASK 0x01
PREPACK struct MBOX_IRQ_PROC_REGISTERS {
uint8_t host_int_status;
uint8_t cpu_int_status;
uint8_t error_int_status;
uint8_t counter_int_status;
uint8_t mbox_frame;
uint8_t rx_lookahead_valid;
uint8_t host_int_status2;
uint8_t gmbox_rx_avail;
uint32_t rx_lookahead[MAILBOX_LOOKAHEAD_SIZE_IN_WORD * MAILBOX_COUNT];
uint32_t int_status_enable;
} POSTPACK;
PREPACK struct MBOX_IRQ_ENABLE_REGISTERS {
uint8_t int_status_enable;
uint8_t cpu_int_status_enable;
uint8_t error_status_enable;
uint8_t counter_int_status_enable;
} POSTPACK;
#define TOTAL_CREDIT_COUNTER_CNT 4
PREPACK struct MBOX_COUNTER_REGISTERS {
uint32_t counter[TOTAL_CREDIT_COUNTER_CNT];
} POSTPACK;
#define SDIO_NUM_DATA_RX_BUFFERS 64
#define SDIO_DATA_RX_SIZE 1664
@ -90,9 +53,6 @@ struct hif_sdio_device {
qdf_spinlock_t Lock;
qdf_spinlock_t TxLock;
qdf_spinlock_t RxLock;
struct MBOX_IRQ_PROC_REGISTERS IrqProcRegisters;
struct MBOX_IRQ_ENABLE_REGISTERS IrqEnableRegisters;
struct MBOX_COUNTER_REGISTERS MailBoxCounterRegisters;
struct hif_msg_callbacks hif_callbacks;
struct hif_device_mbox_info MailBoxInfo;
uint32_t BlockSize;
@ -105,6 +65,8 @@ struct hif_sdio_device {
int RecheckIRQStatusCnt;
uint32_t RecvStateFlags;
void *pTarget;
bool swap_mailbox;
struct devRegisters devRegisters;
};
#define LOCK_HIF_DEV(device) qdf_spin_lock(&(device)->Lock)

View file

@ -43,12 +43,12 @@
#include "pld_sdio.h"
#include "targaddrs.h"
#include "sdio_api.h"
#include <hif_sdio_dev.h>
#ifndef REMOVE_PKT_LOG
#include "ol_txrx_types.h"
#include "pktlog_ac_api.h"
#include "pktlog_ac.h"
#endif
#ifndef ATH_BUS_PM
#ifdef CONFIG_PM
#define ATH_BUS_PM
@ -500,7 +500,7 @@ void hif_sdio_set_mailbox_swap(struct hif_softc *hif_sc)
struct hif_sdio_softc *scn = HIF_GET_SDIO_SOFTC(hif_sc);
struct hif_sdio_dev *hif_device = scn->hif_handle;
hif_device->swap_mailbox = true;
hif_dev_set_mailbox_swap(hif_device);
}
/**

View file

@ -218,7 +218,6 @@ struct hif_sdio_dev {
const struct sdio_device_id *id;
struct mmc_host *host;
void *htc_context;
bool swap_mailbox;
};
struct HIF_DEVICE_OS_DEVICE_INFO {

View file

@ -225,7 +225,7 @@ QDF_STATUS hif_dev_map_service_to_pipe(struct hif_sdio_dev *pdev, uint16_t svc,
switch (svc) {
case HTT_DATA_MSG_SVC:
if (pdev->swap_mailbox) {
if (hif_dev_get_mailbox_swap(pdev)) {
*ul_pipe = 1;
*dl_pipe = 0;
} else {
@ -249,7 +249,7 @@ QDF_STATUS hif_dev_map_service_to_pipe(struct hif_sdio_dev *pdev, uint16_t svc,
break;
case WMI_CONTROL_SVC:
if (pdev->swap_mailbox) {
if (hif_dev_get_mailbox_swap(pdev)) {
*ul_pipe = 3;
*dl_pipe = 2;
} else {
@ -279,16 +279,16 @@ void hif_dev_mask_interrupts(struct hif_sdio_device *pdev)
HIF_ENTER();
/* Disable all interrupts */
LOCK_HIF_DEV(pdev);
pdev->IrqEnableRegisters.int_status_enable = 0;
pdev->IrqEnableRegisters.cpu_int_status_enable = 0;
pdev->IrqEnableRegisters.error_status_enable = 0;
pdev->IrqEnableRegisters.counter_int_status_enable = 0;
mboxEnaRegs(pdev).int_status_enable = 0;
mboxEnaRegs(pdev).cpu_int_status_enable = 0;
mboxEnaRegs(pdev).error_status_enable = 0;
mboxEnaRegs(pdev).counter_int_status_enable = 0;
UNLOCK_HIF_DEV(pdev);
/* always synchronous */
status = hif_read_write(pdev->HIFDevice,
INT_STATUS_ENABLE_ADDRESS,
(char *)&pdev->IrqEnableRegisters,
(char *)&mboxEnaRegs(pdev),
sizeof(struct MBOX_IRQ_ENABLE_REGISTERS),
HIF_WR_SYNC_BYTE_INC, NULL);
@ -310,13 +310,13 @@ void hif_dev_unmask_interrupts(struct hif_sdio_device *pdev)
/* Enable all the interrupts except for the internal
* AR6000 CPU interrupt
*/
pdev->IrqEnableRegisters.int_status_enable =
mboxEnaRegs(pdev).int_status_enable =
INT_STATUS_ENABLE_ERROR_SET(0x01) |
INT_STATUS_ENABLE_CPU_SET(0x01)
| INT_STATUS_ENABLE_COUNTER_SET(0x01);
/* enable 2 mboxs INT */
pdev->IrqEnableRegisters.int_status_enable |=
mboxEnaRegs(pdev).int_status_enable |=
INT_STATUS_ENABLE_MBOX_DATA_SET(0x01) |
INT_STATUS_ENABLE_MBOX_DATA_SET(0x02);
@ -325,17 +325,17 @@ void hif_dev_unmask_interrupts(struct hif_sdio_device *pdev)
* #0 is used for report assertion from target
* #1 is used for inform host that credit arrived
*/
pdev->IrqEnableRegisters.cpu_int_status_enable = 0x03;
mboxEnaRegs(pdev).cpu_int_status_enable = 0x03;
/* Set up the Error Interrupt Status Register */
pdev->IrqEnableRegisters.error_status_enable =
mboxEnaRegs(pdev).error_status_enable =
(ERROR_STATUS_ENABLE_RX_UNDERFLOW_SET(0x01)
| ERROR_STATUS_ENABLE_TX_OVERFLOW_SET(0x01)) >> 16;
/* Set up the Counter Interrupt Status Register
* (only for debug interrupt to catch fatal errors)
*/
pdev->IrqEnableRegisters.counter_int_status_enable =
mboxEnaRegs(pdev).counter_int_status_enable =
(COUNTER_INT_STATUS_ENABLE_BIT_SET(AR6K_TARGET_DEBUG_INTR_MASK)) >> 24;
UNLOCK_HIF_DEV(pdev);
@ -343,7 +343,7 @@ void hif_dev_unmask_interrupts(struct hif_sdio_device *pdev)
/* always synchronous */
status = hif_read_write(pdev->HIFDevice,
INT_STATUS_ENABLE_ADDRESS,
(char *)&pdev->IrqEnableRegisters,
(char *)&mboxEnaRegs(pdev),
sizeof(struct MBOX_IRQ_ENABLE_REGISTERS),
HIF_WR_SYNC_BYTE_INC,
NULL);
@ -895,13 +895,13 @@ static QDF_STATUS hif_dev_service_cpu_interrupt(struct hif_sdio_device *pdev)
uint8_t reg_buffer[4];
uint8_t cpu_int_status;
cpu_int_status = pdev->IrqProcRegisters.cpu_int_status &
pdev->IrqEnableRegisters.cpu_int_status_enable;
cpu_int_status = mboxProcRegs(pdev).cpu_int_status &
mboxEnaRegs(pdev).cpu_int_status_enable;
HIF_ERROR("%s: 0x%x", __func__, (uint32_t)cpu_int_status);
/* Clear the interrupt */
pdev->IrqProcRegisters.cpu_int_status &= ~cpu_int_status;
mboxProcRegs(pdev).cpu_int_status &= ~cpu_int_status;
/*set up the register transfer buffer to hit the register
* 4 times , this is done to make the access 4-byte aligned
@ -954,7 +954,7 @@ static QDF_STATUS hif_dev_service_error_interrupt(struct hif_sdio_device *pdev)
uint8_t reg_buffer[4];
uint8_t error_int_status = 0;
error_int_status = pdev->IrqProcRegisters.error_int_status & 0x0F;
error_int_status = mboxProcRegs(pdev).error_int_status & 0x0F;
HIF_ERROR("%s: 0x%x", __func__, error_int_status);
if (ERROR_INT_STATUS_WAKEUP_GET(error_int_status))
@ -967,7 +967,7 @@ static QDF_STATUS hif_dev_service_error_interrupt(struct hif_sdio_device *pdev)
HIF_ERROR("%s: Error : Tx Overflow", __func__);
/* Clear the interrupt */
pdev->IrqProcRegisters.error_int_status &= ~error_int_status;
mboxProcRegs(pdev).error_int_status &= ~error_int_status;
/* set up the register transfer buffer to hit the register
* 4 times , this is done to make the access 4-byte
@ -1033,8 +1033,8 @@ QDF_STATUS hif_dev_service_counter_interrupt(struct hif_sdio_device *pdev)
AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("Counter Interrupt\n"));
counter_int_status = pdev->IrqProcRegisters.counter_int_status &
pdev->IrqEnableRegisters.counter_int_status_enable;
counter_int_status = mboxProcRegs(pdev).counter_int_status &
mboxEnaRegs(pdev).counter_int_status_enable;
AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
("Valid interrupt source in COUNTER_INT_STATUS: 0x%x\n",
@ -1051,6 +1051,8 @@ QDF_STATUS hif_dev_service_counter_interrupt(struct hif_sdio_device *pdev)
return QDF_STATUS_SUCCESS;
}
#define RX_LOOAHEAD_GET(pdev, i) \
mboxProcRegs(pdev).rx_lookahead[MAILBOX_LOOKAHEAD_SIZE_IN_WORD * i]
/**
* hif_dev_process_pending_irqs() - process pending interrupts
* @pDev: hif sdio device context
@ -1065,10 +1067,10 @@ QDF_STATUS hif_dev_process_pending_irqs(struct hif_sdio_device *pdev,
{
QDF_STATUS status = QDF_STATUS_SUCCESS;
uint8_t host_int_status = 0;
uint32_t look_ahead[MAILBOX_USED_COUNT];
uint32_t l_ahead[MAILBOX_USED_COUNT];
int i;
qdf_mem_zero(&look_ahead, sizeof(look_ahead));
qdf_mem_zero(&l_ahead, sizeof(l_ahead));
AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
("+ProcessPendingIRQs: (dev: 0x%lX)\n",
(unsigned long)pdev));
@ -1080,7 +1082,7 @@ QDF_STATUS hif_dev_process_pending_irqs(struct hif_sdio_device *pdev,
* This is a fully schedulable context.
*/
do {
if (pdev->IrqEnableRegisters.int_status_enable == 0) {
if (mboxEnaRegs(pdev).int_status_enable == 0) {
/* interrupt enables have been cleared, do not try
* to process any pending interrupts that
* may result in more bus transactions.
@ -1090,8 +1092,8 @@ QDF_STATUS hif_dev_process_pending_irqs(struct hif_sdio_device *pdev,
}
status = hif_read_write(pdev->HIFDevice,
HOST_INT_STATUS_ADDRESS,
(uint8_t *)&pdev->IrqProcRegisters,
sizeof(pdev->IrqProcRegisters),
(uint8_t *)&mboxProcRegs(pdev),
sizeof(mboxProcRegs(pdev)),
HIF_RD_SYNC_BYTE_INC, NULL);
if (QDF_IS_STATUS_ERROR(status))
@ -1099,37 +1101,33 @@ QDF_STATUS hif_dev_process_pending_irqs(struct hif_sdio_device *pdev,
if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_IRQ)) {
hif_dev_dump_registers(pdev,
&pdev->IrqProcRegisters,
&pdev->IrqEnableRegisters,
&pdev->MailBoxCounterRegisters);
&mboxProcRegs(pdev),
&mboxEnaRegs(pdev),
&mboxCountRegs(pdev));
}
/* Update only those registers that are enabled */
host_int_status = pdev->IrqProcRegisters.host_int_status
& pdev->IrqEnableRegisters.int_status_enable;
host_int_status = mboxProcRegs(pdev).host_int_status
& mboxEnaRegs(pdev).int_status_enable;
/* only look at mailbox status if the HIF layer did not
* provide this function, on some HIF interfaces reading
* the RX lookahead is not valid to do
*/
for (i = 0; i < MAILBOX_USED_COUNT; i++) {
look_ahead[i] = 0;
l_ahead[i] = 0;
if (host_int_status & (1 << i)) {
/* mask out pending mailbox value, we use
* "lookAhead" as the real flag for
* mailbox processing below
*/
host_int_status &= ~(1 << i);
if (pdev->IrqProcRegisters.
if (mboxProcRegs(pdev).
rx_lookahead_valid & (1 << i)) {
/* mailbox has a message and the
* look ahead is valid
*/
look_ahead[i] =
pdev->
IrqProcRegisters.rx_lookahead[
MAILBOX_LOOKAHEAD_SIZE_IN_WORD *
i];
l_ahead[i] = RX_LOOAHEAD_GET(pdev, i);
}
}
} /*end of for loop */
@ -1142,7 +1140,7 @@ QDF_STATUS hif_dev_process_pending_irqs(struct hif_sdio_device *pdev,
break;
for (i = 0; i < MAILBOX_USED_COUNT; i++) {
if (look_ahead[i] != 0) {
if (l_ahead[i] != 0) {
bLookAheadValid = true;
break;
}
@ -1160,11 +1158,11 @@ QDF_STATUS hif_dev_process_pending_irqs(struct hif_sdio_device *pdev,
for (i = 0; i < MAILBOX_USED_COUNT; i++) {
int fetched = 0;
if (look_ahead[i] == 0)
if (l_ahead[i] == 0)
continue;
AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
("mbox[%d],lookahead:0x%X\n",
i, look_ahead[i]));
i, l_ahead[i]));
/* Mailbox Interrupt, the HTC layer may issue
* async requests to empty the mailbox...
* When emptying the recv mailbox we use the
@ -1176,7 +1174,7 @@ QDF_STATUS hif_dev_process_pending_irqs(struct hif_sdio_device *pdev,
*/
status = hif_dev_recv_message_pending_handler(
pdev, i,
&look_ahead
&l_ahead
[i], 1,
async_processing,
&fetched);

View file

@ -88,5 +88,4 @@ struct devRegisters {
#define DEV_REGISTERS_SIZE (sizeof(struct MBOX_IRQ_PROC_REGISTERS) + \
sizeof(struct MBOX_IRQ_ENABLE_REGISTERS) + \
sizeof(struct MBOX_COUNTER_REGISTERS))
#endif /* _MAILBOX_H_ */

View file

@ -90,7 +90,7 @@ QDF_STATUS hif_dev_send_buffer(struct hif_sdio_device *pdev, uint32_t xfer_id,
QDF_STATUS status;
unsigned char *pData;
struct hif_sendContext *sctx;
uint32_t request = HIF_WR_ASYNC_BLOCK_INC;
uint32_t request = hif_get_send_buffer_flags(pdev);
uint32_t padded_length, addr = 0;
int frag_count = 0, i, count, head_len;

View file

@ -41,6 +41,12 @@
#include <a_debug.h>
#include "hif_sdio_internal.h"
#if defined(CONFIG_SDIO_TRANSFER_MAILBOX) && defined(CONFIG_SDIO_TRANSFER_ADMA)
#error "-----------------------------------------------"
#error "Error - Both transfer methods cannot be enabled"
#error "-----------------------------------------------"
#endif
#define NBUF_ALLOC_FAIL_WAIT_TIME 100
/* high nibble */
#define BUNDLE_COUNT_HIGH(f) (((f) & 0x0C) << 2)
@ -84,4 +90,18 @@ QDF_STATUS hif_dev_process_recv_header(struct hif_sdio_device *pdev,
HTC_PACKET *packet,
uint32_t *next_look_aheads,
int *num_look_aheads);
#ifdef CONFIG_SDIO_TRANSFER_MAILBOX
static inline uint32_t hif_get_send_buffer_flags(struct hif_sdio_device *pdev)
{
if (pdev)
return (uint32_t)HIF_WR_ASYNC_BLOCK_INC;
HIF_ERROR("%s: hif obj is null. Not populating xfer flags", __func__);
return 0;
}
#elif defined(CONFIG_SDIO_TRANSFER_ADMA)
#error "Error - Not implemented yet"
#endif
#endif /* __TRANSFER_H__ */