diff options
Diffstat (limited to 'drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c')
-rw-r--r-- | drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c | 755 |
1 files changed, 0 insertions, 755 deletions
diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c deleted file mode 100644 index 725540f9adde..000000000000 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c +++ /dev/null @@ -1,755 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="ar6k_gmbox.c" company="Atheros"> -// Copyright (c) 2007-2010 Atheros Corporation. 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 above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// Generic MBOX API implementation -// -// Author(s): ="Atheros" -//============================================================================== -#include "a_config.h" -#include "athdefs.h" -#include "a_osapi.h" -#include "../htc_debug.h" -#include "hif.h" -#include "htc_packet.h" -#include "ar6k.h" -#include "hw/mbox_host_reg.h" -#include "gmboxif.h" - -/* - * This file provides management functions and a toolbox for GMBOX protocol modules. - * Only one protocol module can be installed at a time. The determination of which protocol - * module is installed is determined at compile time. - * - */ -#ifdef ATH_AR6K_ENABLE_GMBOX - /* GMBOX definitions */ -#define GMBOX_INT_STATUS_ENABLE_REG 0x488 -#define GMBOX_INT_STATUS_RX_DATA (1 << 0) -#define GMBOX_INT_STATUS_TX_OVERFLOW (1 << 1) -#define GMBOX_INT_STATUS_RX_OVERFLOW (1 << 2) - -#define GMBOX_LOOKAHEAD_MUX_REG 0x498 -#define GMBOX_LA_MUX_OVERRIDE_2_3 (1 << 0) - -#define AR6K_GMBOX_CREDIT_DEC_ADDRESS (COUNT_DEC_ADDRESS + 4 * AR6K_GMBOX_CREDIT_COUNTER) -#define AR6K_GMBOX_CREDIT_SIZE_ADDRESS (COUNT_ADDRESS + AR6K_GMBOX_CREDIT_SIZE_COUNTER) - - - /* external APIs for allocating and freeing internal I/O packets to handle ASYNC I/O */ -extern void AR6KFreeIOPacket(struct ar6k_device *pDev, struct htc_packet *pPacket); -extern struct htc_packet *AR6KAllocIOPacket(struct ar6k_device *pDev); - - -/* callback when our fetch to enable/disable completes */ -static void DevGMboxIRQActionAsyncHandler(void *Context, struct htc_packet *pPacket) -{ - struct ar6k_device *pDev = (struct ar6k_device *)Context; - - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevGMboxIRQActionAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev)); - - if (pPacket->Status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("IRQAction Operation (%d) failed! status:%d \n", pPacket->PktInfo.AsRx.HTCRxFlags,pPacket->Status)); - } - /* free this IO packet */ - AR6KFreeIOPacket(pDev,pPacket); - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevGMboxIRQActionAsyncHandler \n")); -} - -static int DevGMboxCounterEnableDisable(struct ar6k_device *pDev, GMBOX_IRQ_ACTION_TYPE IrqAction, bool AsyncMode) -{ - int status = 0; - struct ar6k_irq_enable_registers regs; - struct htc_packet *pIOPacket = NULL; - - LOCK_AR6K(pDev); - - if (GMBOX_CREDIT_IRQ_ENABLE == IrqAction) { - pDev->GMboxInfo.CreditCountIRQEnabled = true; - pDev->IrqEnableRegisters.counter_int_status_enable |= - COUNTER_INT_STATUS_ENABLE_BIT_SET(1 << AR6K_GMBOX_CREDIT_COUNTER); - pDev->IrqEnableRegisters.int_status_enable |= INT_STATUS_ENABLE_COUNTER_SET(0x01); - } else { - pDev->GMboxInfo.CreditCountIRQEnabled = false; - pDev->IrqEnableRegisters.counter_int_status_enable &= - ~(COUNTER_INT_STATUS_ENABLE_BIT_SET(1 << AR6K_GMBOX_CREDIT_COUNTER)); - } - /* copy into our temp area */ - memcpy(®s,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE); - - UNLOCK_AR6K(pDev); - - do { - - if (AsyncMode) { - - pIOPacket = AR6KAllocIOPacket(pDev); - - if (NULL == pIOPacket) { - status = A_NO_MEMORY; - A_ASSERT(false); - break; - } - - /* copy values to write to our async I/O buffer */ - memcpy(pIOPacket->pBuffer,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE); - - /* stick in our completion routine when the I/O operation completes */ - pIOPacket->Completion = DevGMboxIRQActionAsyncHandler; - pIOPacket->pContext = pDev; - pIOPacket->PktInfo.AsRx.HTCRxFlags = IrqAction; - /* write it out asynchronously */ - HIFReadWrite(pDev->HIFDevice, - INT_STATUS_ENABLE_ADDRESS, - pIOPacket->pBuffer, - AR6K_IRQ_ENABLE_REGS_SIZE, - HIF_WR_ASYNC_BYTE_INC, - pIOPacket); - - pIOPacket = NULL; - break; - } - - /* if we get here we are doing it synchronously */ - status = HIFReadWrite(pDev->HIFDevice, - INT_STATUS_ENABLE_ADDRESS, - ®s.int_status_enable, - AR6K_IRQ_ENABLE_REGS_SIZE, - HIF_WR_SYNC_BYTE_INC, - NULL); - } while (false); - - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - (" IRQAction Operation (%d) failed! status:%d \n", IrqAction, status)); - } else { - if (!AsyncMode) { - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, - (" IRQAction Operation (%d) success \n", IrqAction)); - } - } - - if (pIOPacket != NULL) { - AR6KFreeIOPacket(pDev,pIOPacket); - } - - return status; -} - - -int DevGMboxIRQAction(struct ar6k_device *pDev, GMBOX_IRQ_ACTION_TYPE IrqAction, bool AsyncMode) -{ - int status = 0; - struct htc_packet *pIOPacket = NULL; - u8 GMboxIntControl[4]; - - if (GMBOX_CREDIT_IRQ_ENABLE == IrqAction) { - return DevGMboxCounterEnableDisable(pDev, GMBOX_CREDIT_IRQ_ENABLE, AsyncMode); - } else if(GMBOX_CREDIT_IRQ_DISABLE == IrqAction) { - return DevGMboxCounterEnableDisable(pDev, GMBOX_CREDIT_IRQ_DISABLE, AsyncMode); - } - - if (GMBOX_DISABLE_ALL == IrqAction) { - /* disable credit IRQ, those are on a different set of registers */ - DevGMboxCounterEnableDisable(pDev, GMBOX_CREDIT_IRQ_DISABLE, AsyncMode); - } - - /* take the lock to protect interrupt enable shadows */ - LOCK_AR6K(pDev); - - switch (IrqAction) { - - case GMBOX_DISABLE_ALL: - pDev->GMboxControlRegisters.int_status_enable = 0; - break; - case GMBOX_ERRORS_IRQ_ENABLE: - pDev->GMboxControlRegisters.int_status_enable |= GMBOX_INT_STATUS_TX_OVERFLOW | - GMBOX_INT_STATUS_RX_OVERFLOW; - break; - case GMBOX_RECV_IRQ_ENABLE: - pDev->GMboxControlRegisters.int_status_enable |= GMBOX_INT_STATUS_RX_DATA; - break; - case GMBOX_RECV_IRQ_DISABLE: - pDev->GMboxControlRegisters.int_status_enable &= ~GMBOX_INT_STATUS_RX_DATA; - break; - case GMBOX_ACTION_NONE: - default: - A_ASSERT(false); - break; - } - - GMboxIntControl[0] = pDev->GMboxControlRegisters.int_status_enable; - GMboxIntControl[1] = GMboxIntControl[0]; - GMboxIntControl[2] = GMboxIntControl[0]; - GMboxIntControl[3] = GMboxIntControl[0]; - - UNLOCK_AR6K(pDev); - - do { - - if (AsyncMode) { - - pIOPacket = AR6KAllocIOPacket(pDev); - - if (NULL == pIOPacket) { - status = A_NO_MEMORY; - A_ASSERT(false); - break; - } - - /* copy values to write to our async I/O buffer */ - memcpy(pIOPacket->pBuffer,GMboxIntControl,sizeof(GMboxIntControl)); - - /* stick in our completion routine when the I/O operation completes */ - pIOPacket->Completion = DevGMboxIRQActionAsyncHandler; - pIOPacket->pContext = pDev; - pIOPacket->PktInfo.AsRx.HTCRxFlags = IrqAction; - /* write it out asynchronously */ - HIFReadWrite(pDev->HIFDevice, - GMBOX_INT_STATUS_ENABLE_REG, - pIOPacket->pBuffer, - sizeof(GMboxIntControl), - HIF_WR_ASYNC_BYTE_FIX, - pIOPacket); - pIOPacket = NULL; - break; - } - - /* if we get here we are doing it synchronously */ - - status = HIFReadWrite(pDev->HIFDevice, - GMBOX_INT_STATUS_ENABLE_REG, - GMboxIntControl, - sizeof(GMboxIntControl), - HIF_WR_SYNC_BYTE_FIX, - NULL); - - } while (false); - - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - (" IRQAction Operation (%d) failed! status:%d \n", IrqAction, status)); - } else { - if (!AsyncMode) { - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, - (" IRQAction Operation (%d) success \n", IrqAction)); - } - } - - if (pIOPacket != NULL) { - AR6KFreeIOPacket(pDev,pIOPacket); - } - - return status; -} - -void DevCleanupGMbox(struct ar6k_device *pDev) -{ - if (pDev->GMboxEnabled) { - pDev->GMboxEnabled = false; - GMboxProtocolUninstall(pDev); - } -} - -int DevSetupGMbox(struct ar6k_device *pDev) -{ - int status = 0; - u8 muxControl[4]; - - do { - - if (0 == pDev->MailBoxInfo.GMboxAddress) { - break; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_ANY,(" GMBOX Advertised: Address:0x%X , size:%d \n", - pDev->MailBoxInfo.GMboxAddress, pDev->MailBoxInfo.GMboxSize)); - - status = DevGMboxIRQAction(pDev, GMBOX_DISABLE_ALL, PROC_IO_SYNC); - - if (status) { - break; - } - - /* write to mailbox look ahead mux control register, we want the - * GMBOX lookaheads to appear on lookaheads 2 and 3 - * the register is 1-byte wide so we need to hit it 4 times to align the operation - * to 4-bytes */ - muxControl[0] = GMBOX_LA_MUX_OVERRIDE_2_3; - muxControl[1] = GMBOX_LA_MUX_OVERRIDE_2_3; - muxControl[2] = GMBOX_LA_MUX_OVERRIDE_2_3; - muxControl[3] = GMBOX_LA_MUX_OVERRIDE_2_3; - - status = HIFReadWrite(pDev->HIFDevice, - GMBOX_LOOKAHEAD_MUX_REG, - muxControl, - sizeof(muxControl), - HIF_WR_SYNC_BYTE_FIX, /* hit this register 4 times */ - NULL); - - if (status) { - break; - } - - status = GMboxProtocolInstall(pDev); - - if (status) { - break; - } - - pDev->GMboxEnabled = true; - - } while (false); - - return status; -} - -int DevCheckGMboxInterrupts(struct ar6k_device *pDev) -{ - int status = 0; - u8 counter_int_status; - int credits; - u8 host_int_status2; - - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("+DevCheckGMboxInterrupts \n")); - - /* the caller guarantees that this is a context that allows for blocking I/O */ - - do { - - host_int_status2 = pDev->IrqProcRegisters.host_int_status2 & - pDev->GMboxControlRegisters.int_status_enable; - - if (host_int_status2 & GMBOX_INT_STATUS_TX_OVERFLOW) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("GMBOX : TX Overflow \n")); - status = A_ECOMM; - } - - if (host_int_status2 & GMBOX_INT_STATUS_RX_OVERFLOW) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("GMBOX : RX Overflow \n")); - status = A_ECOMM; - } - - if (status) { - if (pDev->GMboxInfo.pTargetFailureCallback != NULL) { - pDev->GMboxInfo.pTargetFailureCallback(pDev->GMboxInfo.pProtocolContext, status); - } - break; - } - - if (host_int_status2 & GMBOX_INT_STATUS_RX_DATA) { - if (pDev->IrqProcRegisters.gmbox_rx_avail > 0) { - A_ASSERT(pDev->GMboxInfo.pMessagePendingCallBack != NULL); - status = pDev->GMboxInfo.pMessagePendingCallBack( - pDev->GMboxInfo.pProtocolContext, - (u8 *)&pDev->IrqProcRegisters.rx_gmbox_lookahead_alias[0], - pDev->IrqProcRegisters.gmbox_rx_avail); - } - } - - if (status) { - break; - } - - counter_int_status = pDev->IrqProcRegisters.counter_int_status & - pDev->IrqEnableRegisters.counter_int_status_enable; - - /* check if credit interrupt is pending */ - if (counter_int_status & (COUNTER_INT_STATUS_ENABLE_BIT_SET(1 << AR6K_GMBOX_CREDIT_COUNTER))) { - - /* do synchronous read */ - status = DevGMboxReadCreditCounter(pDev, PROC_IO_SYNC, &credits); - - if (status) { - break; - } - - A_ASSERT(pDev->GMboxInfo.pCreditsPendingCallback != NULL); - status = pDev->GMboxInfo.pCreditsPendingCallback(pDev->GMboxInfo.pProtocolContext, - credits, - pDev->GMboxInfo.CreditCountIRQEnabled); - } - - } while (false); - - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("-DevCheckGMboxInterrupts (%d) \n",status)); - - return status; -} - - -int DevGMboxWrite(struct ar6k_device *pDev, struct htc_packet *pPacket, u32 WriteLength) -{ - u32 paddedLength; - bool sync = (pPacket->Completion == NULL) ? true : false; - int status; - u32 address; - - /* adjust the length to be a multiple of block size if appropriate */ - paddedLength = DEV_CALC_SEND_PADDED_LEN(pDev, WriteLength); - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND, - ("DevGMboxWrite, Padded Length: %d Mbox:0x%X (mode:%s)\n", - WriteLength, - pDev->MailBoxInfo.GMboxAddress, - sync ? "SYNC" : "ASYNC")); - - /* last byte of packet has to hit the EOM marker */ - address = pDev->MailBoxInfo.GMboxAddress + pDev->MailBoxInfo.GMboxSize - paddedLength; - - status = HIFReadWrite(pDev->HIFDevice, - address, - pPacket->pBuffer, - paddedLength, /* the padded length */ - sync ? HIF_WR_SYNC_BLOCK_INC : HIF_WR_ASYNC_BLOCK_INC, - sync ? NULL : pPacket); /* pass the packet as the context to the HIF request */ - - if (sync) { - pPacket->Status = status; - } else { - if (status == A_PENDING) { - status = 0; - } - } - - return status; -} - -int DevGMboxRead(struct ar6k_device *pDev, struct htc_packet *pPacket, u32 ReadLength) -{ - - u32 paddedLength; - int status; - bool sync = (pPacket->Completion == NULL) ? true : false; - - /* adjust the length to be a multiple of block size if appropriate */ - paddedLength = DEV_CALC_RECV_PADDED_LEN(pDev, ReadLength); - - if (paddedLength > pPacket->BufferLength) { - A_ASSERT(false); - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("DevGMboxRead, Not enough space for padlen:%d recvlen:%d bufferlen:%d \n", - paddedLength,ReadLength,pPacket->BufferLength)); - if (pPacket->Completion != NULL) { - COMPLETE_HTC_PACKET(pPacket,A_EINVAL); - return 0; - } - return A_EINVAL; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_RECV, - ("DevGMboxRead (0x%lX : hdr:0x%X) Padded Length: %d Mbox:0x%X (mode:%s)\n", - (unsigned long)pPacket, pPacket->PktInfo.AsRx.ExpectedHdr, - paddedLength, - pDev->MailBoxInfo.GMboxAddress, - sync ? "SYNC" : "ASYNC")); - - status = HIFReadWrite(pDev->HIFDevice, - pDev->MailBoxInfo.GMboxAddress, - pPacket->pBuffer, - paddedLength, - sync ? HIF_RD_SYNC_BLOCK_FIX : HIF_RD_ASYNC_BLOCK_FIX, - sync ? NULL : pPacket); /* pass the packet as the context to the HIF request */ - - if (sync) { - pPacket->Status = status; - } - - return status; -} - - -static int ProcessCreditCounterReadBuffer(u8 *pBuffer, int Length) -{ - int credits = 0; - - /* theory of how this works: - * We read the credit decrement register multiple times on a byte-wide basis. - * The number of times (32) aligns the I/O operation to be a multiple of 4 bytes and provides a - * reasonable chance to acquire "all" pending credits in a single I/O operation. - * - * Once we obtain the filled buffer, we can walk through it looking for credit decrement transitions. - * Each non-zero byte represents a single credit decrement (which is a credit given back to the host) - * For example if the target provides 3 credits and added 4 more during the 32-byte read operation the following - * pattern "could" appear: - * - * 0x3 0x2 0x1 0x0 0x0 0x0 0x0 0x0 0x1 0x0 0x1 0x0 0x1 0x0 0x1 0x0 ......rest zeros - * <---------> <-----------------------------> - * \_ credits aleady there \_ target adding 4 more credits - * - * The total available credits would be 7, since there are 7 non-zero bytes in the buffer. - * - * */ - - if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) { - DebugDumpBytes(pBuffer, Length, "GMBOX Credit read buffer"); - } - - while (Length) { - if (*pBuffer != 0) { - credits++; - } - Length--; - pBuffer++; - } - - return credits; -} - - -/* callback when our fetch to enable/disable completes */ -static void DevGMboxReadCreditsAsyncHandler(void *Context, struct htc_packet *pPacket) -{ - struct ar6k_device *pDev = (struct ar6k_device *)Context; - - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevGMboxReadCreditsAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev)); - - if (pPacket->Status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("Read Credit Operation failed! status:%d \n", pPacket->Status)); - } else { - int credits = 0; - credits = ProcessCreditCounterReadBuffer(pPacket->pBuffer, AR6K_REG_IO_BUFFER_SIZE); - pDev->GMboxInfo.pCreditsPendingCallback(pDev->GMboxInfo.pProtocolContext, - credits, - pDev->GMboxInfo.CreditCountIRQEnabled); - - - } - /* free this IO packet */ - AR6KFreeIOPacket(pDev,pPacket); - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevGMboxReadCreditsAsyncHandler \n")); -} - -int DevGMboxReadCreditCounter(struct ar6k_device *pDev, bool AsyncMode, int *pCredits) -{ - int status = 0; - struct htc_packet *pIOPacket = NULL; - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+DevGMboxReadCreditCounter (%s) \n", AsyncMode ? "ASYNC" : "SYNC")); - - do { - - pIOPacket = AR6KAllocIOPacket(pDev); - - if (NULL == pIOPacket) { - status = A_NO_MEMORY; - A_ASSERT(false); - break; - } - - A_MEMZERO(pIOPacket->pBuffer,AR6K_REG_IO_BUFFER_SIZE); - - if (AsyncMode) { - /* stick in our completion routine when the I/O operation completes */ - pIOPacket->Completion = DevGMboxReadCreditsAsyncHandler; - pIOPacket->pContext = pDev; - /* read registers asynchronously */ - HIFReadWrite(pDev->HIFDevice, - AR6K_GMBOX_CREDIT_DEC_ADDRESS, - pIOPacket->pBuffer, - AR6K_REG_IO_BUFFER_SIZE, /* hit the register multiple times */ - HIF_RD_ASYNC_BYTE_FIX, - pIOPacket); - pIOPacket = NULL; - break; - } - - pIOPacket->Completion = NULL; - /* if we get here we are doing it synchronously */ - status = HIFReadWrite(pDev->HIFDevice, - AR6K_GMBOX_CREDIT_DEC_ADDRESS, - pIOPacket->pBuffer, - AR6K_REG_IO_BUFFER_SIZE, - HIF_RD_SYNC_BYTE_FIX, - NULL); - } while (false); - - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - (" DevGMboxReadCreditCounter failed! status:%d \n", status)); - } - - if (pIOPacket != NULL) { - if (!status) { - /* sync mode processing */ - *pCredits = ProcessCreditCounterReadBuffer(pIOPacket->pBuffer, AR6K_REG_IO_BUFFER_SIZE); - } - AR6KFreeIOPacket(pDev,pIOPacket); - } - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-DevGMboxReadCreditCounter (%s) (%d) \n", - AsyncMode ? "ASYNC" : "SYNC", status)); - - return status; -} - -int DevGMboxReadCreditSize(struct ar6k_device *pDev, int *pCreditSize) -{ - int status; - u8 buffer[4]; - - status = HIFReadWrite(pDev->HIFDevice, - AR6K_GMBOX_CREDIT_SIZE_ADDRESS, - buffer, - sizeof(buffer), - HIF_RD_SYNC_BYTE_FIX, /* hit the register 4 times to align the I/O */ - NULL); - - if (!status) { - if (buffer[0] == 0) { - *pCreditSize = 256; - } else { - *pCreditSize = buffer[0]; - } - - } - - return status; -} - -void DevNotifyGMboxTargetFailure(struct ar6k_device *pDev) -{ - /* Target ASSERTED!!! */ - if (pDev->GMboxInfo.pTargetFailureCallback != NULL) { - pDev->GMboxInfo.pTargetFailureCallback(pDev->GMboxInfo.pProtocolContext, A_HARDWARE); - } -} - -int DevGMboxRecvLookAheadPeek(struct ar6k_device *pDev, u8 *pLookAheadBuffer, int *pLookAheadBytes) -{ - - int status = 0; - struct ar6k_irq_proc_registers procRegs; - int maxCopy; - - do { - /* on entry the caller provides the length of the lookahead buffer */ - if (*pLookAheadBytes > sizeof(procRegs.rx_gmbox_lookahead_alias)) { - A_ASSERT(false); - status = A_EINVAL; - break; - } - - maxCopy = *pLookAheadBytes; - *pLookAheadBytes = 0; - /* load the register table from the device */ - status = HIFReadWrite(pDev->HIFDevice, - HOST_INT_STATUS_ADDRESS, - (u8 *)&procRegs, - AR6K_IRQ_PROC_REGS_SIZE, - HIF_RD_SYNC_BYTE_INC, - NULL); - - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("DevGMboxRecvLookAheadPeek : Failed to read register table (%d) \n",status)); - break; - } - - if (procRegs.gmbox_rx_avail > 0) { - int bytes = procRegs.gmbox_rx_avail > maxCopy ? maxCopy : procRegs.gmbox_rx_avail; - memcpy(pLookAheadBuffer,&procRegs.rx_gmbox_lookahead_alias[0],bytes); - *pLookAheadBytes = bytes; - } - - } while (false); - - return status; -} - -int DevGMboxSetTargetInterrupt(struct ar6k_device *pDev, int Signal, int AckTimeoutMS) -{ - int status = 0; - int i; - u8 buffer[4]; - - A_MEMZERO(buffer, sizeof(buffer)); - - do { - - if (Signal >= MBOX_SIG_HCI_BRIDGE_MAX) { - status = A_EINVAL; - break; - } - - /* set the last buffer to do the actual signal trigger */ - buffer[3] = (1 << Signal); - - status = HIFReadWrite(pDev->HIFDevice, - INT_WLAN_ADDRESS, - buffer, - sizeof(buffer), - HIF_WR_SYNC_BYTE_FIX, /* hit the register 4 times to align the I/O */ - NULL); - - if (status) { - break; - } - - } while (false); - - - if (!status) { - /* now read back the register to see if the bit cleared */ - while (AckTimeoutMS) { - status = HIFReadWrite(pDev->HIFDevice, - INT_WLAN_ADDRESS, - buffer, - sizeof(buffer), - HIF_RD_SYNC_BYTE_FIX, - NULL); - - if (status) { - break; - } - - for (i = 0; i < sizeof(buffer); i++) { - if (buffer[i] & (1 << Signal)) { - /* bit is still set */ - break; - } - } - - if (i >= sizeof(buffer)) { - /* done */ - break; - } - - AckTimeoutMS--; - A_MDELAY(1); - } - - if (0 == AckTimeoutMS) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("DevGMboxSetTargetInterrupt : Ack Timed-out (sig:%d) \n",Signal)); - status = A_ERROR; - } - } - - return status; - -} - -#endif //ATH_AR6K_ENABLE_GMBOX - - - - |