1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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
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
44
45#include "athstartpack.h"
46typedef PREPACK struct _AR6K_IRQ_PROC_REGISTERS {
47 A_UINT8 host_int_status;
48 A_UINT8 cpu_int_status;
49 A_UINT8 error_int_status;
50 A_UINT8 counter_int_status;
51 A_UINT8 mbox_frame;
52 A_UINT8 rx_lookahead_valid;
53 A_UINT8 host_int_status2;
54 A_UINT8 gmbox_rx_avail;
55 A_UINT32 rx_lookahead[2];
56 A_UINT32 rx_gmbox_lookahead_alias[2];
57} POSTPACK AR6K_IRQ_PROC_REGISTERS;
58
59#define AR6K_IRQ_PROC_REGS_SIZE sizeof(AR6K_IRQ_PROC_REGISTERS)
60
61typedef PREPACK struct _AR6K_IRQ_ENABLE_REGISTERS {
62 A_UINT8 int_status_enable;
63 A_UINT8 cpu_int_status_enable;
64 A_UINT8 error_status_enable;
65 A_UINT8 counter_int_status_enable;
66} POSTPACK AR6K_IRQ_ENABLE_REGISTERS;
67
68typedef PREPACK struct _AR6K_GMBOX_CTRL_REGISTERS {
69 A_UINT8 int_status_enable;
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
78#define FROM_DMA_BUFFER TRUE
79#define TO_DMA_BUFFER FALSE
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
92typedef struct AR6K_ASYNC_REG_IO_BUFFER {
93 HTC_PACKET HtcPacket;
94 A_UINT8 _Pad1[A_CACHE_LINE_PAD];
95 A_UINT8 Buffer[AR6K_REG_IO_BUFFER_SIZE];
96 A_UINT8 _Pad2[A_CACHE_LINE_PAD];
97} AR6K_ASYNC_REG_IO_BUFFER;
98
99typedef struct _AR6K_GMBOX_INFO {
100 void *pProtocolContext;
101 A_STATUS (*pMessagePendingCallBack)(void *pContext, A_UINT8 LookAheadBytes[], int ValidBytes);
102 A_STATUS (*pCreditsPendingCallback)(void *pContext, int NumCredits, A_BOOL CreditIRQEnabled);
103 void (*pTargetFailureCallback)(void *pContext, A_STATUS Status);
104 void (*pStateDumpCallback)(void *pContext);
105 A_BOOL CreditCountIRQEnabled;
106} AR6K_GMBOX_INFO;
107
108typedef struct _AR6K_DEVICE {
109 A_MUTEX_T Lock;
110 A_UINT8 _Pad1[A_CACHE_LINE_PAD];
111 AR6K_IRQ_PROC_REGISTERS IrqProcRegisters;
112 A_UINT8 _Pad2[A_CACHE_LINE_PAD];
113 AR6K_IRQ_ENABLE_REGISTERS IrqEnableRegisters;
114 A_UINT8 _Pad3[A_CACHE_LINE_PAD];
115 void *HIFDevice;
116 A_UINT32 BlockSize;
117 A_UINT32 BlockMask;
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);
124 A_STATUS (*MessagePendingCallback)(void *Context,
125 A_UINT32 LookAheads[],
126 int NumLookAheads,
127 A_BOOL *pAsyncProc,
128 int *pNumPktsFetched);
129 HIF_DEVICE_IRQ_PROCESSING_MODE HifIRQProcessingMode;
130 HIF_MASK_UNMASK_RECV_EVENT HifMaskUmaskRecvEvent;
131 A_BOOL HifAttached;
132 HIF_DEVICE_IRQ_YIELD_PARAMS HifIRQYieldParams;
133 A_BOOL DSRCanYield;
134 int CurrentDSRRecvCount;
135 HIF_DEVICE_SCATTER_SUPPORT_INFO HifScatterInfo;
136 DL_LIST ScatterReqHead;
137 A_BOOL ScatterIsVirtual;
138 int MaxRecvBundleSize;
139 int MaxSendBundleSize;
140 AR6K_GMBOX_INFO GMboxInfo;
141 A_BOOL GMboxEnabled;
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
149
150A_STATUS DevSetup(AR6K_DEVICE *pDev);
151void DevCleanup(AR6K_DEVICE *pDev);
152A_STATUS DevUnmaskInterrupts(AR6K_DEVICE *pDev);
153A_STATUS DevMaskInterrupts(AR6K_DEVICE *pDev);
154A_STATUS DevPollMboxMsgRecv(AR6K_DEVICE *pDev,
155 A_UINT32 *pLookAhead,
156 int TimeoutMS);
157A_STATUS DevRWCompletionHandler(void *context, A_STATUS status);
158A_STATUS DevDsrHandler(void *context);
159A_STATUS DevCheckPendingRecvMsgsAsync(void *context);
160void DevAsyncIrqProcessComplete(AR6K_DEVICE *pDev);
161void DevDumpRegisters(AR6K_DEVICE *pDev,
162 AR6K_IRQ_PROC_REGISTERS *pIrqProcRegs,
163 AR6K_IRQ_ENABLE_REGISTERS *pIrqEnableRegs);
164
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
169A_STATUS DevStopRecv(AR6K_DEVICE *pDev, A_BOOL ASyncMode);
170A_STATUS DevEnableRecv(AR6K_DEVICE *pDev, A_BOOL ASyncMode);
171A_STATUS DevEnableInterrupts(AR6K_DEVICE *pDev);
172A_STATUS DevDisableInterrupts(AR6K_DEVICE *pDev);
173A_STATUS DevWaitForPendingRecv(AR6K_DEVICE *pDev,A_UINT32 TimeoutInMs,A_BOOL *pbIsRecvPending);
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
179static INLINE A_STATUS DevSendPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 SendLength) {
180 A_UINT32 paddedLength;
181 A_BOOL sync = (pPacket->Completion == NULL) ? TRUE : FALSE;
182 A_STATUS status;
183
184
185 paddedLength = DEV_CALC_SEND_PADDED_LEN(pDev, SendLength);
186
187#if 0
188 if (paddedLength > pPacket->BufferLength) {
189 A_ASSERT(FALSE);
190 if (pPacket->Completion != NULL) {
191 COMPLETE_HTC_PACKET(pPacket,A_EINVAL);
192 return A_OK;
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,
208 sync ? HIF_WR_SYNC_BLOCK_INC : HIF_WR_ASYNC_BLOCK_INC,
209 sync ? NULL : pPacket);
210
211 if (sync) {
212 pPacket->Status = status;
213 } else {
214 if (status == A_PENDING) {
215 status = A_OK;
216 }
217 }
218
219 return status;
220}
221
222static INLINE A_STATUS DevRecvPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 RecvLength) {
223 A_UINT32 paddedLength;
224 A_STATUS status;
225 A_BOOL sync = (pPacket->Completion == NULL) ? TRUE : FALSE;
226
227
228 paddedLength = DEV_CALC_RECV_PADDED_LEN(pDev, RecvLength);
229
230 if (paddedLength > pPacket->BufferLength) {
231 A_ASSERT(FALSE);
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);
237 return A_OK;
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);
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
271
272
273
274
275A_STATUS DevCopyScatterListToFromDMABuffer(HIF_SCATTER_REQ *pReq, A_BOOL FromDMA);
276
277
278#define DEV_FINISH_SCATTER_OPERATION(pR) \
279 if (A_SUCCESS((pR)->CompletionStatus) && \
280 !((pR)->Request & HIF_WRITE) && \
281 ((pR)->ScatterMethod == HIF_SCATTER_DMA_BOUNCE)) { \
282 (pR)->CompletionStatus = DevCopyScatterListToFromDMABuffer((pR),FROM_DMA_BUFFER); \
283 }
284
285
286static INLINE A_STATUS DEV_PREPARE_SCATTER_OPERATION(HIF_SCATTER_REQ *pReq) {
287 if ((pReq->Request & HIF_WRITE) && (pReq->ScatterMethod == HIF_SCATTER_DMA_BOUNCE)) {
288 return DevCopyScatterListToFromDMABuffer(pReq,TO_DMA_BUFFER);
289 } else {
290 return A_OK;
291 }
292}
293
294
295A_STATUS DevSetupMsgBundling(AR6K_DEVICE *pDev, int MaxMsgsPerTransfer);
296
297#define DEV_GET_MAX_MSG_PER_BUNDLE(pDev) (pDev)->HifScatterInfo.MaxScatterEntries
298#define DEV_GET_MAX_BUNDLE_LENGTH(pDev) (pDev)->HifScatterInfo.MaxTransferSizePerScatterReq
299#define DEV_ALLOC_SCATTER_REQ(pDev) \
300 (pDev)->HifScatterInfo.pAllocateReqFunc((pDev)->ScatterIsVirtual ? (pDev) : (pDev)->HIFDevice)
301
302#define DEV_FREE_SCATTER_REQ(pDev,pR) \
303 (pDev)->HifScatterInfo.pFreeReqFunc((pDev)->ScatterIsVirtual ? (pDev) : (pDev)->HIFDevice,(pR))
304
305#define DEV_GET_MAX_BUNDLE_RECV_LENGTH(pDev) (pDev)->MaxRecvBundleSize
306#define DEV_GET_MAX_BUNDLE_SEND_LENGTH(pDev) (pDev)->MaxSendBundleSize
307
308#define DEV_SCATTER_READ TRUE
309#define DEV_SCATTER_WRITE FALSE
310#define DEV_SCATTER_ASYNC TRUE
311#define DEV_SCATTER_SYNC FALSE
312A_STATUS DevSubmitScatterRequest(AR6K_DEVICE *pDev, HIF_SCATTER_REQ *pScatterReq, A_BOOL Read, A_BOOL Async);
313
314#ifdef MBOXHW_UNIT_TEST
315A_STATUS DoMboxHWTest(AR6K_DEVICE *pDev);
316#endif
317
318
319typedef struct _DEV_SCATTER_DMA_VIRTUAL_INFO {
320 A_UINT8 *pVirtDmaBuffer;
321 A_UINT8 DataArea[1];
322} DEV_SCATTER_DMA_VIRTUAL_INFO;
323
324
325
326void DumpAR6KDevState(AR6K_DEVICE *pDev);
327
328
329
330
331
332
333
334#ifdef ATH_AR6K_ENABLE_GMBOX
335
336void DevCleanupGMbox(AR6K_DEVICE *pDev);
337A_STATUS DevSetupGMbox(AR6K_DEVICE *pDev);
338A_STATUS DevCheckGMboxInterrupts(AR6K_DEVICE *pDev);
339void DevNotifyGMboxTargetFailure(AR6K_DEVICE *pDev);
340
341#else
342
343
344#define DevCleanupGMbox(p)
345#define DevCheckGMboxInterrupts(p) A_OK
346#define DevNotifyGMboxTargetFailure(p)
347
348static INLINE A_STATUS DevSetupGMbox(AR6K_DEVICE *pDev) {
349 pDev->GMboxEnabled = FALSE;
350 return A_OK;
351}
352
353#endif
354
355#ifdef ATH_AR6K_ENABLE_GMBOX
356
357
358HCI_TRANSPORT_HANDLE GMboxAttachProtocol(AR6K_DEVICE *pDev, HCI_TRANSPORT_CONFIG_INFO *pInfo);
359A_STATUS GMboxProtocolInstall(AR6K_DEVICE *pDev);
360void GMboxProtocolUninstall(AR6K_DEVICE *pDev);
361
362
363AR6K_DEVICE *HTCGetAR6KDevice(void *HTCHandle);
364#define DEV_GMBOX_SET_PROTOCOL(pDev,recv_callback,credits_pending,failure,statedump,context) \
365{ \
366 (pDev)->GMboxInfo.pProtocolContext = (context); \
367 (pDev)->GMboxInfo.pMessagePendingCallBack = (recv_callback); \
368 (pDev)->GMboxInfo.pCreditsPendingCallback = (credits_pending); \
369 (pDev)->GMboxInfo.pTargetFailureCallback = (failure); \
370 (pDev)->GMboxInfo.pStateDumpCallback = (statedump); \
371}
372
373#define DEV_GMBOX_GET_PROTOCOL(pDev) (pDev)->GMboxInfo.pProtocolContext
374
375A_STATUS DevGMboxWrite(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 WriteLength);
376A_STATUS DevGMboxRead(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 ReadLength);
377
378#define PROC_IO_ASYNC TRUE
379#define PROC_IO_SYNC FALSE
380typedef enum GMBOX_IRQ_ACTION_TYPE {
381 GMBOX_ACTION_NONE = 0,
382 GMBOX_DISABLE_ALL,
383 GMBOX_ERRORS_IRQ_ENABLE,
384 GMBOX_RECV_IRQ_ENABLE,
385 GMBOX_RECV_IRQ_DISABLE,
386 GMBOX_CREDIT_IRQ_ENABLE,
387 GMBOX_CREDIT_IRQ_DISABLE,
388} GMBOX_IRQ_ACTION_TYPE;
389
390A_STATUS DevGMboxIRQAction(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION_TYPE, A_BOOL AsyncMode);
391A_STATUS DevGMboxReadCreditCounter(AR6K_DEVICE *pDev, A_BOOL AsyncMode, int *pCredits);
392A_STATUS DevGMboxReadCreditSize(AR6K_DEVICE *pDev, int *pCreditSize);
393A_STATUS DevGMboxRecvLookAheadPeek(AR6K_DEVICE *pDev, A_UINT8 *pLookAheadBuffer, int *pLookAheadBytes);
394A_STATUS DevGMboxSetTargetInterrupt(AR6K_DEVICE *pDev, int SignalNumber, int AckTimeoutMS);
395
396#endif
397
398#endif
399