Vipin Mehta | 30295c8 | 2010-09-01 12:06:33 -0700 | [diff] [blame] | 1 | //------------------------------------------------------------------------------ |
| 2 | // <copyright file="ar6k.h" company="Atheros"> |
| 3 | // Copyright (c) 2007-2010 Atheros Corporation. All rights reserved. |
| 4 | // |
| 5 | // |
| 6 | // Permission to use, copy, modify, and/or distribute this software for any |
| 7 | // purpose with or without fee is hereby granted, provided that the above |
| 8 | // copyright notice and this permission notice appear in all copies. |
| 9 | // |
| 10 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
| 11 | // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
| 12 | // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
| 13 | // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
| 14 | // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
| 15 | // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
| 16 | // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
| 17 | // |
| 18 | // |
| 19 | //------------------------------------------------------------------------------ |
| 20 | //============================================================================== |
| 21 | // AR6K device layer that handles register level I/O |
| 22 | // |
| 23 | // Author(s): ="Atheros" |
| 24 | //============================================================================== |
| 25 | #ifndef AR6K_H_ |
| 26 | #define AR6K_H_ |
| 27 | |
| 28 | #include "hci_transport_api.h" |
| 29 | #include "../htc_debug.h" |
| 30 | |
| 31 | #define AR6K_MAILBOXES 4 |
| 32 | |
| 33 | /* HTC runs over mailbox 0 */ |
| 34 | #define HTC_MAILBOX 0 |
| 35 | |
| 36 | #define AR6K_TARGET_DEBUG_INTR_MASK 0x01 |
| 37 | |
| 38 | #define OTHER_INTS_ENABLED (INT_STATUS_ENABLE_ERROR_MASK | \ |
| 39 | INT_STATUS_ENABLE_CPU_MASK | \ |
| 40 | INT_STATUS_ENABLE_COUNTER_MASK) |
| 41 | |
| 42 | |
| 43 | //#define MBOXHW_UNIT_TEST 1 |
| 44 | |
| 45 | #include "athstartpack.h" |
| 46 | typedef PREPACK struct _AR6K_IRQ_PROC_REGISTERS { |
Joe Perches | ab3655d | 2011-02-02 14:05:49 -0800 | [diff] [blame] | 47 | u8 host_int_status; |
| 48 | u8 cpu_int_status; |
| 49 | u8 error_int_status; |
| 50 | u8 counter_int_status; |
| 51 | u8 mbox_frame; |
| 52 | u8 rx_lookahead_valid; |
| 53 | u8 host_int_status2; |
| 54 | u8 gmbox_rx_avail; |
Joe Perches | e1ce2a3 | 2011-02-02 14:05:51 -0800 | [diff] [blame] | 55 | u32 rx_lookahead[2]; |
| 56 | u32 rx_gmbox_lookahead_alias[2]; |
Vipin Mehta | 30295c8 | 2010-09-01 12:06:33 -0700 | [diff] [blame] | 57 | } POSTPACK AR6K_IRQ_PROC_REGISTERS; |
| 58 | |
| 59 | #define AR6K_IRQ_PROC_REGS_SIZE sizeof(AR6K_IRQ_PROC_REGISTERS) |
| 60 | |
| 61 | typedef PREPACK struct _AR6K_IRQ_ENABLE_REGISTERS { |
Joe Perches | ab3655d | 2011-02-02 14:05:49 -0800 | [diff] [blame] | 62 | u8 int_status_enable; |
| 63 | u8 cpu_int_status_enable; |
| 64 | u8 error_status_enable; |
| 65 | u8 counter_int_status_enable; |
Vipin Mehta | 30295c8 | 2010-09-01 12:06:33 -0700 | [diff] [blame] | 66 | } POSTPACK AR6K_IRQ_ENABLE_REGISTERS; |
| 67 | |
| 68 | typedef PREPACK struct _AR6K_GMBOX_CTRL_REGISTERS { |
Joe Perches | ab3655d | 2011-02-02 14:05:49 -0800 | [diff] [blame] | 69 | u8 int_status_enable; |
Vipin Mehta | 30295c8 | 2010-09-01 12:06:33 -0700 | [diff] [blame] | 70 | } POSTPACK AR6K_GMBOX_CTRL_REGISTERS; |
| 71 | |
| 72 | #include "athendpack.h" |
| 73 | |
| 74 | #define AR6K_IRQ_ENABLE_REGS_SIZE sizeof(AR6K_IRQ_ENABLE_REGISTERS) |
| 75 | |
| 76 | #define AR6K_REG_IO_BUFFER_SIZE 32 |
| 77 | #define AR6K_MAX_REG_IO_BUFFERS 8 |
Joe Perches | 1071a13 | 2011-02-02 14:05:47 -0800 | [diff] [blame] | 78 | #define FROM_DMA_BUFFER true |
| 79 | #define TO_DMA_BUFFER false |
Vipin Mehta | 30295c8 | 2010-09-01 12:06:33 -0700 | [diff] [blame] | 80 | #define AR6K_SCATTER_ENTRIES_PER_REQ 16 |
| 81 | #define AR6K_MAX_TRANSFER_SIZE_PER_SCATTER 16*1024 |
| 82 | #define AR6K_SCATTER_REQS 4 |
| 83 | #define AR6K_LEGACY_MAX_WRITE_LENGTH 2048 |
| 84 | |
| 85 | #ifndef A_CACHE_LINE_PAD |
| 86 | #define A_CACHE_LINE_PAD 128 |
| 87 | #endif |
| 88 | #define AR6K_MIN_SCATTER_ENTRIES_PER_REQ 2 |
| 89 | #define AR6K_MIN_TRANSFER_SIZE_PER_SCATTER 4*1024 |
| 90 | |
| 91 | /* buffers for ASYNC I/O */ |
| 92 | typedef struct AR6K_ASYNC_REG_IO_BUFFER { |
| 93 | HTC_PACKET HtcPacket; /* we use an HTC packet as a wrapper for our async register-based I/O */ |
Joe Perches | ab3655d | 2011-02-02 14:05:49 -0800 | [diff] [blame] | 94 | u8 _Pad1[A_CACHE_LINE_PAD]; |
| 95 | u8 Buffer[AR6K_REG_IO_BUFFER_SIZE]; /* cache-line safe with pads around */ |
| 96 | u8 _Pad2[A_CACHE_LINE_PAD]; |
Vipin Mehta | 30295c8 | 2010-09-01 12:06:33 -0700 | [diff] [blame] | 97 | } AR6K_ASYNC_REG_IO_BUFFER; |
| 98 | |
| 99 | typedef struct _AR6K_GMBOX_INFO { |
| 100 | void *pProtocolContext; |
Joe Perches | ab3655d | 2011-02-02 14:05:49 -0800 | [diff] [blame] | 101 | int (*pMessagePendingCallBack)(void *pContext, u8 LookAheadBytes[], int ValidBytes); |
Joe Perches | 1071a13 | 2011-02-02 14:05:47 -0800 | [diff] [blame] | 102 | int (*pCreditsPendingCallback)(void *pContext, int NumCredits, bool CreditIRQEnabled); |
Joe Perches | 1f4c34b | 2011-01-27 20:04:19 -0800 | [diff] [blame] | 103 | void (*pTargetFailureCallback)(void *pContext, int Status); |
Vipin Mehta | 30295c8 | 2010-09-01 12:06:33 -0700 | [diff] [blame] | 104 | void (*pStateDumpCallback)(void *pContext); |
Joe Perches | 1071a13 | 2011-02-02 14:05:47 -0800 | [diff] [blame] | 105 | bool CreditCountIRQEnabled; |
Vipin Mehta | 30295c8 | 2010-09-01 12:06:33 -0700 | [diff] [blame] | 106 | } AR6K_GMBOX_INFO; |
| 107 | |
| 108 | typedef struct _AR6K_DEVICE { |
| 109 | A_MUTEX_T Lock; |
Joe Perches | ab3655d | 2011-02-02 14:05:49 -0800 | [diff] [blame] | 110 | u8 _Pad1[A_CACHE_LINE_PAD]; |
Vipin Mehta | 30295c8 | 2010-09-01 12:06:33 -0700 | [diff] [blame] | 111 | AR6K_IRQ_PROC_REGISTERS IrqProcRegisters; /* cache-line safe with pads around */ |
Joe Perches | ab3655d | 2011-02-02 14:05:49 -0800 | [diff] [blame] | 112 | u8 _Pad2[A_CACHE_LINE_PAD]; |
Vipin Mehta | 30295c8 | 2010-09-01 12:06:33 -0700 | [diff] [blame] | 113 | AR6K_IRQ_ENABLE_REGISTERS IrqEnableRegisters; /* cache-line safe with pads around */ |
Joe Perches | ab3655d | 2011-02-02 14:05:49 -0800 | [diff] [blame] | 114 | u8 _Pad3[A_CACHE_LINE_PAD]; |
Vipin Mehta | 30295c8 | 2010-09-01 12:06:33 -0700 | [diff] [blame] | 115 | void *HIFDevice; |
Joe Perches | e1ce2a3 | 2011-02-02 14:05:51 -0800 | [diff] [blame] | 116 | u32 BlockSize; |
| 117 | u32 BlockMask; |
Vipin Mehta | 30295c8 | 2010-09-01 12:06:33 -0700 | [diff] [blame] | 118 | HIF_DEVICE_MBOX_INFO MailBoxInfo; |
| 119 | HIF_PENDING_EVENTS_FUNC GetPendingEventsFunc; |
| 120 | void *HTCContext; |
| 121 | HTC_PACKET_QUEUE RegisterIOList; |
| 122 | AR6K_ASYNC_REG_IO_BUFFER RegIOBuffers[AR6K_MAX_REG_IO_BUFFERS]; |
| 123 | void (*TargetFailureCallback)(void *Context); |
Joe Perches | 1f4c34b | 2011-01-27 20:04:19 -0800 | [diff] [blame] | 124 | int (*MessagePendingCallback)(void *Context, |
Joe Perches | e1ce2a3 | 2011-02-02 14:05:51 -0800 | [diff] [blame] | 125 | u32 LookAheads[], |
Vipin Mehta | 30295c8 | 2010-09-01 12:06:33 -0700 | [diff] [blame] | 126 | int NumLookAheads, |
Joe Perches | 1071a13 | 2011-02-02 14:05:47 -0800 | [diff] [blame] | 127 | bool *pAsyncProc, |
Vipin Mehta | 30295c8 | 2010-09-01 12:06:33 -0700 | [diff] [blame] | 128 | int *pNumPktsFetched); |
| 129 | HIF_DEVICE_IRQ_PROCESSING_MODE HifIRQProcessingMode; |
| 130 | HIF_MASK_UNMASK_RECV_EVENT HifMaskUmaskRecvEvent; |
Joe Perches | 1071a13 | 2011-02-02 14:05:47 -0800 | [diff] [blame] | 131 | bool HifAttached; |
Vipin Mehta | 30295c8 | 2010-09-01 12:06:33 -0700 | [diff] [blame] | 132 | HIF_DEVICE_IRQ_YIELD_PARAMS HifIRQYieldParams; |
Joe Perches | 1071a13 | 2011-02-02 14:05:47 -0800 | [diff] [blame] | 133 | bool DSRCanYield; |
Vipin Mehta | 30295c8 | 2010-09-01 12:06:33 -0700 | [diff] [blame] | 134 | int CurrentDSRRecvCount; |
| 135 | HIF_DEVICE_SCATTER_SUPPORT_INFO HifScatterInfo; |
| 136 | DL_LIST ScatterReqHead; |
Joe Perches | 1071a13 | 2011-02-02 14:05:47 -0800 | [diff] [blame] | 137 | bool ScatterIsVirtual; |
Vipin Mehta | 30295c8 | 2010-09-01 12:06:33 -0700 | [diff] [blame] | 138 | int MaxRecvBundleSize; |
| 139 | int MaxSendBundleSize; |
| 140 | AR6K_GMBOX_INFO GMboxInfo; |
Joe Perches | 1071a13 | 2011-02-02 14:05:47 -0800 | [diff] [blame] | 141 | bool GMboxEnabled; |
Vipin Mehta | 30295c8 | 2010-09-01 12:06:33 -0700 | [diff] [blame] | 142 | AR6K_GMBOX_CTRL_REGISTERS GMboxControlRegisters; |
| 143 | int RecheckIRQStatusCnt; |
| 144 | } AR6K_DEVICE; |
| 145 | |
| 146 | #define LOCK_AR6K(p) A_MUTEX_LOCK(&(p)->Lock); |
| 147 | #define UNLOCK_AR6K(p) A_MUTEX_UNLOCK(&(p)->Lock); |
| 148 | #define REF_IRQ_STATUS_RECHECK(p) (p)->RecheckIRQStatusCnt = 1 /* note: no need to lock this, it only gets set */ |
| 149 | |
Joe Perches | 1f4c34b | 2011-01-27 20:04:19 -0800 | [diff] [blame] | 150 | int DevSetup(AR6K_DEVICE *pDev); |
Vipin Mehta | 30295c8 | 2010-09-01 12:06:33 -0700 | [diff] [blame] | 151 | void DevCleanup(AR6K_DEVICE *pDev); |
Joe Perches | 1f4c34b | 2011-01-27 20:04:19 -0800 | [diff] [blame] | 152 | int DevUnmaskInterrupts(AR6K_DEVICE *pDev); |
| 153 | int DevMaskInterrupts(AR6K_DEVICE *pDev); |
| 154 | int DevPollMboxMsgRecv(AR6K_DEVICE *pDev, |
Joe Perches | e1ce2a3 | 2011-02-02 14:05:51 -0800 | [diff] [blame] | 155 | u32 *pLookAhead, |
Vipin Mehta | 30295c8 | 2010-09-01 12:06:33 -0700 | [diff] [blame] | 156 | int TimeoutMS); |
Joe Perches | 1f4c34b | 2011-01-27 20:04:19 -0800 | [diff] [blame] | 157 | int DevRWCompletionHandler(void *context, int status); |
| 158 | int DevDsrHandler(void *context); |
| 159 | int DevCheckPendingRecvMsgsAsync(void *context); |
Vipin Mehta | 30295c8 | 2010-09-01 12:06:33 -0700 | [diff] [blame] | 160 | void DevAsyncIrqProcessComplete(AR6K_DEVICE *pDev); |
| 161 | void DevDumpRegisters(AR6K_DEVICE *pDev, |
| 162 | AR6K_IRQ_PROC_REGISTERS *pIrqProcRegs, |
| 163 | AR6K_IRQ_ENABLE_REGISTERS *pIrqEnableRegs); |
| 164 | |
Joe Perches | 1071a13 | 2011-02-02 14:05:47 -0800 | [diff] [blame] | 165 | #define DEV_STOP_RECV_ASYNC true |
| 166 | #define DEV_STOP_RECV_SYNC false |
| 167 | #define DEV_ENABLE_RECV_ASYNC true |
| 168 | #define DEV_ENABLE_RECV_SYNC false |
| 169 | int DevStopRecv(AR6K_DEVICE *pDev, bool ASyncMode); |
| 170 | int DevEnableRecv(AR6K_DEVICE *pDev, bool ASyncMode); |
Joe Perches | 1f4c34b | 2011-01-27 20:04:19 -0800 | [diff] [blame] | 171 | int DevEnableInterrupts(AR6K_DEVICE *pDev); |
| 172 | int DevDisableInterrupts(AR6K_DEVICE *pDev); |
Joe Perches | e1ce2a3 | 2011-02-02 14:05:51 -0800 | [diff] [blame] | 173 | int DevWaitForPendingRecv(AR6K_DEVICE *pDev,u32 TimeoutInMs,bool *pbIsRecvPending); |
Vipin Mehta | 30295c8 | 2010-09-01 12:06:33 -0700 | [diff] [blame] | 174 | |
| 175 | #define DEV_CALC_RECV_PADDED_LEN(pDev, length) (((length) + (pDev)->BlockMask) & (~((pDev)->BlockMask))) |
| 176 | #define DEV_CALC_SEND_PADDED_LEN(pDev, length) DEV_CALC_RECV_PADDED_LEN(pDev,length) |
| 177 | #define DEV_IS_LEN_BLOCK_ALIGNED(pDev, length) (((length) % (pDev)->BlockSize) == 0) |
| 178 | |
Joe Perches | e1ce2a3 | 2011-02-02 14:05:51 -0800 | [diff] [blame] | 179 | static INLINE int DevSendPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, u32 SendLength) { |
| 180 | u32 paddedLength; |
Joe Perches | 1071a13 | 2011-02-02 14:05:47 -0800 | [diff] [blame] | 181 | bool sync = (pPacket->Completion == NULL) ? true : false; |
Joe Perches | 1f4c34b | 2011-01-27 20:04:19 -0800 | [diff] [blame] | 182 | int status; |
Vipin Mehta | 30295c8 | 2010-09-01 12:06:33 -0700 | [diff] [blame] | 183 | |
| 184 | /* adjust the length to be a multiple of block size if appropriate */ |
| 185 | paddedLength = DEV_CALC_SEND_PADDED_LEN(pDev, SendLength); |
| 186 | |
| 187 | #if 0 |
| 188 | if (paddedLength > pPacket->BufferLength) { |
Joe Perches | 1071a13 | 2011-02-02 14:05:47 -0800 | [diff] [blame] | 189 | A_ASSERT(false); |
Vipin Mehta | 30295c8 | 2010-09-01 12:06:33 -0700 | [diff] [blame] | 190 | if (pPacket->Completion != NULL) { |
| 191 | COMPLETE_HTC_PACKET(pPacket,A_EINVAL); |
Joe Perches | 4f69cef | 2011-02-02 14:05:57 -0800 | [diff] [blame] | 192 | return 0; |
Vipin Mehta | 30295c8 | 2010-09-01 12:06:33 -0700 | [diff] [blame] | 193 | } |
| 194 | return A_EINVAL; |
| 195 | } |
| 196 | #endif |
| 197 | |
| 198 | AR_DEBUG_PRINTF(ATH_DEBUG_SEND, |
| 199 | ("DevSendPacket, Padded Length: %d Mbox:0x%X (mode:%s)\n", |
| 200 | paddedLength, |
| 201 | pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX], |
| 202 | sync ? "SYNC" : "ASYNC")); |
| 203 | |
| 204 | status = HIFReadWrite(pDev->HIFDevice, |
| 205 | pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX], |
| 206 | pPacket->pBuffer, |
| 207 | paddedLength, /* the padded length */ |
| 208 | sync ? HIF_WR_SYNC_BLOCK_INC : HIF_WR_ASYNC_BLOCK_INC, |
| 209 | sync ? NULL : pPacket); /* pass the packet as the context to the HIF request */ |
| 210 | |
| 211 | if (sync) { |
| 212 | pPacket->Status = status; |
| 213 | } else { |
| 214 | if (status == A_PENDING) { |
Joe Perches | 4f69cef | 2011-02-02 14:05:57 -0800 | [diff] [blame] | 215 | status = 0; |
Vipin Mehta | 30295c8 | 2010-09-01 12:06:33 -0700 | [diff] [blame] | 216 | } |
| 217 | } |
| 218 | |
| 219 | return status; |
| 220 | } |
| 221 | |
Joe Perches | e1ce2a3 | 2011-02-02 14:05:51 -0800 | [diff] [blame] | 222 | static INLINE int DevRecvPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, u32 RecvLength) { |
| 223 | u32 paddedLength; |
Joe Perches | 1f4c34b | 2011-01-27 20:04:19 -0800 | [diff] [blame] | 224 | int status; |
Joe Perches | 1071a13 | 2011-02-02 14:05:47 -0800 | [diff] [blame] | 225 | bool sync = (pPacket->Completion == NULL) ? true : false; |
Vipin Mehta | 30295c8 | 2010-09-01 12:06:33 -0700 | [diff] [blame] | 226 | |
| 227 | /* adjust the length to be a multiple of block size if appropriate */ |
| 228 | paddedLength = DEV_CALC_RECV_PADDED_LEN(pDev, RecvLength); |
| 229 | |
| 230 | if (paddedLength > pPacket->BufferLength) { |
Joe Perches | 1071a13 | 2011-02-02 14:05:47 -0800 | [diff] [blame] | 231 | A_ASSERT(false); |
Vipin Mehta | 30295c8 | 2010-09-01 12:06:33 -0700 | [diff] [blame] | 232 | AR_DEBUG_PRINTF(ATH_DEBUG_ERR, |
| 233 | ("DevRecvPacket, Not enough space for padlen:%d recvlen:%d bufferlen:%d \n", |
| 234 | paddedLength,RecvLength,pPacket->BufferLength)); |
| 235 | if (pPacket->Completion != NULL) { |
| 236 | COMPLETE_HTC_PACKET(pPacket,A_EINVAL); |
Joe Perches | 4f69cef | 2011-02-02 14:05:57 -0800 | [diff] [blame] | 237 | return 0; |
Vipin Mehta | 30295c8 | 2010-09-01 12:06:33 -0700 | [diff] [blame] | 238 | } |
| 239 | return A_EINVAL; |
| 240 | } |
| 241 | |
| 242 | AR_DEBUG_PRINTF(ATH_DEBUG_RECV, |
| 243 | ("DevRecvPacket (0x%lX : hdr:0x%X) Padded Length: %d Mbox:0x%X (mode:%s)\n", |
| 244 | (unsigned long)pPacket, pPacket->PktInfo.AsRx.ExpectedHdr, |
| 245 | paddedLength, |
| 246 | pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX], |
| 247 | sync ? "SYNC" : "ASYNC")); |
| 248 | |
| 249 | status = HIFReadWrite(pDev->HIFDevice, |
| 250 | pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX], |
| 251 | pPacket->pBuffer, |
| 252 | paddedLength, |
| 253 | sync ? HIF_RD_SYNC_BLOCK_FIX : HIF_RD_ASYNC_BLOCK_FIX, |
| 254 | sync ? NULL : pPacket); /* pass the packet as the context to the HIF request */ |
| 255 | |
| 256 | if (sync) { |
| 257 | pPacket->Status = status; |
| 258 | } |
| 259 | |
| 260 | return status; |
| 261 | } |
| 262 | |
| 263 | #define DEV_CHECK_RECV_YIELD(pDev) \ |
| 264 | ((pDev)->CurrentDSRRecvCount >= (pDev)->HifIRQYieldParams.RecvPacketYieldCount) |
| 265 | |
| 266 | #define IS_DEV_IRQ_PROC_SYNC_MODE(pDev) (HIF_DEVICE_IRQ_SYNC_ONLY == (pDev)->HifIRQProcessingMode) |
| 267 | #define IS_DEV_IRQ_PROCESSING_ASYNC_ALLOWED(pDev) ((pDev)->HifIRQProcessingMode != HIF_DEVICE_IRQ_SYNC_ONLY) |
| 268 | |
| 269 | /**************************************************/ |
| 270 | /****** Scatter Function and Definitions |
| 271 | * |
| 272 | * |
| 273 | */ |
| 274 | |
Joe Perches | 1071a13 | 2011-02-02 14:05:47 -0800 | [diff] [blame] | 275 | int DevCopyScatterListToFromDMABuffer(HIF_SCATTER_REQ *pReq, bool FromDMA); |
Vipin Mehta | 30295c8 | 2010-09-01 12:06:33 -0700 | [diff] [blame] | 276 | |
| 277 | /* copy any READ data back into scatter list */ |
Joe Perches | 509c9d9 | 2011-01-27 20:04:20 -0800 | [diff] [blame] | 278 | #define DEV_FINISH_SCATTER_OPERATION(pR) \ |
| 279 | do { \ |
| 280 | if (!((pR)->CompletionStatus) && \ |
| 281 | !((pR)->Request & HIF_WRITE) && \ |
| 282 | ((pR)->ScatterMethod == HIF_SCATTER_DMA_BOUNCE)) { \ |
| 283 | (pR)->CompletionStatus = \ |
| 284 | DevCopyScatterListToFromDMABuffer((pR), \ |
| 285 | FROM_DMA_BUFFER); \ |
| 286 | } \ |
| 287 | } while (0) |
Vipin Mehta | 30295c8 | 2010-09-01 12:06:33 -0700 | [diff] [blame] | 288 | |
| 289 | /* copy any WRITE data to bounce buffer */ |
Joe Perches | 1f4c34b | 2011-01-27 20:04:19 -0800 | [diff] [blame] | 290 | static INLINE int DEV_PREPARE_SCATTER_OPERATION(HIF_SCATTER_REQ *pReq) { |
Vipin Mehta | 30295c8 | 2010-09-01 12:06:33 -0700 | [diff] [blame] | 291 | if ((pReq->Request & HIF_WRITE) && (pReq->ScatterMethod == HIF_SCATTER_DMA_BOUNCE)) { |
| 292 | return DevCopyScatterListToFromDMABuffer(pReq,TO_DMA_BUFFER); |
| 293 | } else { |
Joe Perches | 4f69cef | 2011-02-02 14:05:57 -0800 | [diff] [blame] | 294 | return 0; |
Vipin Mehta | 30295c8 | 2010-09-01 12:06:33 -0700 | [diff] [blame] | 295 | } |
| 296 | } |
| 297 | |
| 298 | |
Joe Perches | 1f4c34b | 2011-01-27 20:04:19 -0800 | [diff] [blame] | 299 | int DevSetupMsgBundling(AR6K_DEVICE *pDev, int MaxMsgsPerTransfer); |
Vipin Mehta | 774c1fe | 2011-02-18 13:13:09 -0800 | [diff] [blame^] | 300 | |
| 301 | int DevCleanupMsgBundling(AR6K_DEVICE *pDev); |
Vipin Mehta | 30295c8 | 2010-09-01 12:06:33 -0700 | [diff] [blame] | 302 | |
| 303 | #define DEV_GET_MAX_MSG_PER_BUNDLE(pDev) (pDev)->HifScatterInfo.MaxScatterEntries |
| 304 | #define DEV_GET_MAX_BUNDLE_LENGTH(pDev) (pDev)->HifScatterInfo.MaxTransferSizePerScatterReq |
| 305 | #define DEV_ALLOC_SCATTER_REQ(pDev) \ |
| 306 | (pDev)->HifScatterInfo.pAllocateReqFunc((pDev)->ScatterIsVirtual ? (pDev) : (pDev)->HIFDevice) |
| 307 | |
| 308 | #define DEV_FREE_SCATTER_REQ(pDev,pR) \ |
| 309 | (pDev)->HifScatterInfo.pFreeReqFunc((pDev)->ScatterIsVirtual ? (pDev) : (pDev)->HIFDevice,(pR)) |
| 310 | |
| 311 | #define DEV_GET_MAX_BUNDLE_RECV_LENGTH(pDev) (pDev)->MaxRecvBundleSize |
| 312 | #define DEV_GET_MAX_BUNDLE_SEND_LENGTH(pDev) (pDev)->MaxSendBundleSize |
| 313 | |
Joe Perches | 1071a13 | 2011-02-02 14:05:47 -0800 | [diff] [blame] | 314 | #define DEV_SCATTER_READ true |
| 315 | #define DEV_SCATTER_WRITE false |
| 316 | #define DEV_SCATTER_ASYNC true |
| 317 | #define DEV_SCATTER_SYNC false |
| 318 | int DevSubmitScatterRequest(AR6K_DEVICE *pDev, HIF_SCATTER_REQ *pScatterReq, bool Read, bool Async); |
Vipin Mehta | 30295c8 | 2010-09-01 12:06:33 -0700 | [diff] [blame] | 319 | |
| 320 | #ifdef MBOXHW_UNIT_TEST |
Joe Perches | 1f4c34b | 2011-01-27 20:04:19 -0800 | [diff] [blame] | 321 | int DoMboxHWTest(AR6K_DEVICE *pDev); |
Vipin Mehta | 30295c8 | 2010-09-01 12:06:33 -0700 | [diff] [blame] | 322 | #endif |
| 323 | |
| 324 | /* completely virtual */ |
| 325 | typedef struct _DEV_SCATTER_DMA_VIRTUAL_INFO { |
Joe Perches | ab3655d | 2011-02-02 14:05:49 -0800 | [diff] [blame] | 326 | u8 *pVirtDmaBuffer; /* dma-able buffer - CPU accessible address */ |
| 327 | u8 DataArea[1]; /* start of data area */ |
Vipin Mehta | 30295c8 | 2010-09-01 12:06:33 -0700 | [diff] [blame] | 328 | } DEV_SCATTER_DMA_VIRTUAL_INFO; |
| 329 | |
| 330 | |
| 331 | |
| 332 | void DumpAR6KDevState(AR6K_DEVICE *pDev); |
| 333 | |
| 334 | /**************************************************/ |
| 335 | /****** GMBOX functions and definitions |
| 336 | * |
| 337 | * |
| 338 | */ |
| 339 | |
| 340 | #ifdef ATH_AR6K_ENABLE_GMBOX |
| 341 | |
| 342 | void DevCleanupGMbox(AR6K_DEVICE *pDev); |
Joe Perches | 1f4c34b | 2011-01-27 20:04:19 -0800 | [diff] [blame] | 343 | int DevSetupGMbox(AR6K_DEVICE *pDev); |
| 344 | int DevCheckGMboxInterrupts(AR6K_DEVICE *pDev); |
Vipin Mehta | 30295c8 | 2010-09-01 12:06:33 -0700 | [diff] [blame] | 345 | void DevNotifyGMboxTargetFailure(AR6K_DEVICE *pDev); |
| 346 | |
| 347 | #else |
| 348 | |
| 349 | /* compiled out */ |
| 350 | #define DevCleanupGMbox(p) |
Joe Perches | 4f69cef | 2011-02-02 14:05:57 -0800 | [diff] [blame] | 351 | #define DevCheckGMboxInterrupts(p) 0 |
Vipin Mehta | 30295c8 | 2010-09-01 12:06:33 -0700 | [diff] [blame] | 352 | #define DevNotifyGMboxTargetFailure(p) |
| 353 | |
Joe Perches | 1f4c34b | 2011-01-27 20:04:19 -0800 | [diff] [blame] | 354 | static INLINE int DevSetupGMbox(AR6K_DEVICE *pDev) { |
Joe Perches | 1071a13 | 2011-02-02 14:05:47 -0800 | [diff] [blame] | 355 | pDev->GMboxEnabled = false; |
Joe Perches | 4f69cef | 2011-02-02 14:05:57 -0800 | [diff] [blame] | 356 | return 0; |
Vipin Mehta | 30295c8 | 2010-09-01 12:06:33 -0700 | [diff] [blame] | 357 | } |
| 358 | |
| 359 | #endif |
| 360 | |
| 361 | #ifdef ATH_AR6K_ENABLE_GMBOX |
| 362 | |
| 363 | /* GMBOX protocol modules must expose each of these internal APIs */ |
| 364 | HCI_TRANSPORT_HANDLE GMboxAttachProtocol(AR6K_DEVICE *pDev, HCI_TRANSPORT_CONFIG_INFO *pInfo); |
Joe Perches | 1f4c34b | 2011-01-27 20:04:19 -0800 | [diff] [blame] | 365 | int GMboxProtocolInstall(AR6K_DEVICE *pDev); |
Vipin Mehta | 30295c8 | 2010-09-01 12:06:33 -0700 | [diff] [blame] | 366 | void GMboxProtocolUninstall(AR6K_DEVICE *pDev); |
| 367 | |
| 368 | /* API used by GMBOX protocol modules */ |
| 369 | AR6K_DEVICE *HTCGetAR6KDevice(void *HTCHandle); |
| 370 | #define DEV_GMBOX_SET_PROTOCOL(pDev,recv_callback,credits_pending,failure,statedump,context) \ |
| 371 | { \ |
| 372 | (pDev)->GMboxInfo.pProtocolContext = (context); \ |
| 373 | (pDev)->GMboxInfo.pMessagePendingCallBack = (recv_callback); \ |
| 374 | (pDev)->GMboxInfo.pCreditsPendingCallback = (credits_pending); \ |
| 375 | (pDev)->GMboxInfo.pTargetFailureCallback = (failure); \ |
| 376 | (pDev)->GMboxInfo.pStateDumpCallback = (statedump); \ |
| 377 | } |
| 378 | |
| 379 | #define DEV_GMBOX_GET_PROTOCOL(pDev) (pDev)->GMboxInfo.pProtocolContext |
| 380 | |
Joe Perches | e1ce2a3 | 2011-02-02 14:05:51 -0800 | [diff] [blame] | 381 | int DevGMboxWrite(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, u32 WriteLength); |
| 382 | int DevGMboxRead(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, u32 ReadLength); |
Vipin Mehta | 30295c8 | 2010-09-01 12:06:33 -0700 | [diff] [blame] | 383 | |
Joe Perches | 1071a13 | 2011-02-02 14:05:47 -0800 | [diff] [blame] | 384 | #define PROC_IO_ASYNC true |
| 385 | #define PROC_IO_SYNC false |
Vipin Mehta | 30295c8 | 2010-09-01 12:06:33 -0700 | [diff] [blame] | 386 | typedef enum GMBOX_IRQ_ACTION_TYPE { |
| 387 | GMBOX_ACTION_NONE = 0, |
| 388 | GMBOX_DISABLE_ALL, |
| 389 | GMBOX_ERRORS_IRQ_ENABLE, |
| 390 | GMBOX_RECV_IRQ_ENABLE, |
| 391 | GMBOX_RECV_IRQ_DISABLE, |
| 392 | GMBOX_CREDIT_IRQ_ENABLE, |
| 393 | GMBOX_CREDIT_IRQ_DISABLE, |
| 394 | } GMBOX_IRQ_ACTION_TYPE; |
| 395 | |
Joe Perches | 1071a13 | 2011-02-02 14:05:47 -0800 | [diff] [blame] | 396 | int DevGMboxIRQAction(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION_TYPE, bool AsyncMode); |
| 397 | int DevGMboxReadCreditCounter(AR6K_DEVICE *pDev, bool AsyncMode, int *pCredits); |
Joe Perches | 1f4c34b | 2011-01-27 20:04:19 -0800 | [diff] [blame] | 398 | int DevGMboxReadCreditSize(AR6K_DEVICE *pDev, int *pCreditSize); |
Joe Perches | ab3655d | 2011-02-02 14:05:49 -0800 | [diff] [blame] | 399 | int DevGMboxRecvLookAheadPeek(AR6K_DEVICE *pDev, u8 *pLookAheadBuffer, int *pLookAheadBytes); |
Joe Perches | 1f4c34b | 2011-01-27 20:04:19 -0800 | [diff] [blame] | 400 | int DevGMboxSetTargetInterrupt(AR6K_DEVICE *pDev, int SignalNumber, int AckTimeoutMS); |
Vipin Mehta | 30295c8 | 2010-09-01 12:06:33 -0700 | [diff] [blame] | 401 | |
| 402 | #endif |
| 403 | |
| 404 | #endif /*AR6K_H_*/ |