Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6
[pandora-kernel.git] / drivers / staging / ath6kl / htc2 / AR6000 / ar6k.h
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 {
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
61 typedef 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
68 typedef 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 /* 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 */
94     A_UINT8       _Pad1[A_CACHE_LINE_PAD];
95     A_UINT8       Buffer[AR6K_REG_IO_BUFFER_SIZE];  /* cache-line safe with pads around */
96     A_UINT8       _Pad2[A_CACHE_LINE_PAD];
97 } AR6K_ASYNC_REG_IO_BUFFER;
98
99 typedef 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
108 typedef struct _AR6K_DEVICE {
109     A_MUTEX_T                   Lock;
110     A_UINT8       _Pad1[A_CACHE_LINE_PAD];
111     AR6K_IRQ_PROC_REGISTERS     IrqProcRegisters;   /* cache-line safe with pads around */
112     A_UINT8       _Pad2[A_CACHE_LINE_PAD];
113     AR6K_IRQ_ENABLE_REGISTERS   IrqEnableRegisters; /* cache-line safe with pads around */
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  /* note: no need to lock this, it only gets set */
149
150 A_STATUS DevSetup(AR6K_DEVICE *pDev);
151 void     DevCleanup(AR6K_DEVICE *pDev);
152 A_STATUS DevUnmaskInterrupts(AR6K_DEVICE *pDev);
153 A_STATUS DevMaskInterrupts(AR6K_DEVICE *pDev);
154 A_STATUS DevPollMboxMsgRecv(AR6K_DEVICE *pDev,
155                             A_UINT32    *pLookAhead,
156                             int          TimeoutMS);
157 A_STATUS DevRWCompletionHandler(void *context, A_STATUS status);
158 A_STATUS DevDsrHandler(void *context);
159 A_STATUS DevCheckPendingRecvMsgsAsync(void *context);
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
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 A_STATUS DevStopRecv(AR6K_DEVICE *pDev, A_BOOL ASyncMode);
170 A_STATUS DevEnableRecv(AR6K_DEVICE *pDev, A_BOOL ASyncMode);
171 A_STATUS DevEnableInterrupts(AR6K_DEVICE *pDev);
172 A_STATUS DevDisableInterrupts(AR6K_DEVICE *pDev);
173 A_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
179 static 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        /* 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) {
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,     /* 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) {
215             status = A_OK;    
216         }    
217     }
218
219     return status;
220 }
221                     
222 static 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         /* 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) {
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);  /* 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   
275 A_STATUS DevCopyScatterListToFromDMABuffer(HIF_SCATTER_REQ *pReq, A_BOOL FromDMA);
276     
277     /* copy any READ data back into scatter list */        
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     /* copy any WRITE data to bounce buffer */
286 static 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     
295 A_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
312 A_STATUS DevSubmitScatterRequest(AR6K_DEVICE *pDev, HIF_SCATTER_REQ *pScatterReq, A_BOOL Read, A_BOOL Async);
313
314 #ifdef MBOXHW_UNIT_TEST
315 A_STATUS DoMboxHWTest(AR6K_DEVICE *pDev);
316 #endif
317
318     /* completely virtual */
319 typedef struct _DEV_SCATTER_DMA_VIRTUAL_INFO {
320     A_UINT8            *pVirtDmaBuffer;      /* dma-able buffer - CPU accessible address */
321     A_UINT8            DataArea[1];      /* start of data area */
322 } DEV_SCATTER_DMA_VIRTUAL_INFO;
323
324
325
326 void     DumpAR6KDevState(AR6K_DEVICE *pDev);
327
328 /**************************************************/
329 /****** GMBOX functions and definitions
330  * 
331  *  
332  */
333
334 #ifdef ATH_AR6K_ENABLE_GMBOX
335
336 void     DevCleanupGMbox(AR6K_DEVICE *pDev);
337 A_STATUS DevSetupGMbox(AR6K_DEVICE *pDev);
338 A_STATUS DevCheckGMboxInterrupts(AR6K_DEVICE *pDev);
339 void     DevNotifyGMboxTargetFailure(AR6K_DEVICE *pDev);
340
341 #else
342
343     /* compiled out */
344 #define DevCleanupGMbox(p)
345 #define DevCheckGMboxInterrupts(p) A_OK
346 #define DevNotifyGMboxTargetFailure(p)
347
348 static 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     /* GMBOX protocol modules must expose each of these internal APIs */
358 HCI_TRANSPORT_HANDLE GMboxAttachProtocol(AR6K_DEVICE *pDev, HCI_TRANSPORT_CONFIG_INFO *pInfo);
359 A_STATUS             GMboxProtocolInstall(AR6K_DEVICE *pDev);
360 void                 GMboxProtocolUninstall(AR6K_DEVICE *pDev);
361
362     /* API used by GMBOX protocol modules */
363 AR6K_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
375 A_STATUS DevGMboxWrite(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 WriteLength);
376 A_STATUS DevGMboxRead(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 ReadLength);
377
378 #define PROC_IO_ASYNC TRUE
379 #define PROC_IO_SYNC  FALSE
380 typedef 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
390 A_STATUS DevGMboxIRQAction(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION_TYPE, A_BOOL AsyncMode);
391 A_STATUS DevGMboxReadCreditCounter(AR6K_DEVICE *pDev, A_BOOL AsyncMode, int *pCredits);
392 A_STATUS DevGMboxReadCreditSize(AR6K_DEVICE *pDev, int *pCreditSize);
393 A_STATUS DevGMboxRecvLookAheadPeek(AR6K_DEVICE *pDev, A_UINT8 *pLookAheadBuffer, int *pLookAheadBytes);
394 A_STATUS DevGMboxSetTargetInterrupt(AR6K_DEVICE *pDev, int SignalNumber, int AckTimeoutMS);
395
396 #endif
397
398 #endif /*AR6K_H_*/