Merge branch 'sh-latest' of git://git.kernel.org/pub/scm/linux/kernel/git/lethal...
[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 PREPACK struct ar6k_irq_proc_registers {
46     u8 host_int_status;
47     u8 cpu_int_status;
48     u8 error_int_status;
49     u8 counter_int_status;
50     u8 mbox_frame;
51     u8 rx_lookahead_valid;
52     u8 host_int_status2;
53     u8 gmbox_rx_avail;
54     u32 rx_lookahead[2];
55     u32 rx_gmbox_lookahead_alias[2];
56 } POSTPACK;
57
58 #define AR6K_IRQ_PROC_REGS_SIZE sizeof(struct ar6k_irq_proc_registers)
59
60 PREPACK struct ar6k_irq_enable_registers {
61     u8 int_status_enable;
62     u8 cpu_int_status_enable;
63     u8 error_status_enable;
64     u8 counter_int_status_enable;
65 } POSTPACK;
66
67 PREPACK struct ar6k_gmbox_ctrl_registers {
68     u8 int_status_enable;
69 } POSTPACK;
70
71 #define AR6K_IRQ_ENABLE_REGS_SIZE sizeof(struct ar6k_irq_enable_registers)
72
73 #define AR6K_REG_IO_BUFFER_SIZE     32
74 #define AR6K_MAX_REG_IO_BUFFERS     8
75 #define FROM_DMA_BUFFER true
76 #define TO_DMA_BUFFER   false
77 #define AR6K_SCATTER_ENTRIES_PER_REQ            16
78 #define AR6K_MAX_TRANSFER_SIZE_PER_SCATTER      16*1024
79 #define AR6K_SCATTER_REQS                       4
80 #define AR6K_LEGACY_MAX_WRITE_LENGTH            2048
81
82 #ifndef A_CACHE_LINE_PAD
83 #define A_CACHE_LINE_PAD                        128
84 #endif
85 #define AR6K_MIN_SCATTER_ENTRIES_PER_REQ        2
86 #define AR6K_MIN_TRANSFER_SIZE_PER_SCATTER      4*1024
87
88 /* buffers for ASYNC I/O */
89 struct ar6k_async_reg_io_buffer {
90     struct htc_packet    HtcPacket;   /* we use an HTC packet as a wrapper for our async register-based I/O */
91     u8 _Pad1[A_CACHE_LINE_PAD];
92     u8 Buffer[AR6K_REG_IO_BUFFER_SIZE];  /* cache-line safe with pads around */
93     u8 _Pad2[A_CACHE_LINE_PAD];
94 };
95
96 struct ar6k_gmbox_info { 
97     void        *pProtocolContext;
98     int    (*pMessagePendingCallBack)(void *pContext, u8 LookAheadBytes[], int ValidBytes);
99     int    (*pCreditsPendingCallback)(void *pContext, int NumCredits,  bool CreditIRQEnabled);
100     void        (*pTargetFailureCallback)(void *pContext, int Status);
101     void        (*pStateDumpCallback)(void *pContext);
102     bool      CreditCountIRQEnabled;
103 }; 
104
105 struct ar6k_device {
106     A_MUTEX_T                   Lock;
107     u8 _Pad1[A_CACHE_LINE_PAD];
108     struct ar6k_irq_proc_registers     IrqProcRegisters;   /* cache-line safe with pads around */
109     u8 _Pad2[A_CACHE_LINE_PAD];
110     struct ar6k_irq_enable_registers   IrqEnableRegisters; /* cache-line safe with pads around */
111     u8 _Pad3[A_CACHE_LINE_PAD];
112     void                        *HIFDevice;
113     u32 BlockSize;
114     u32 BlockMask;
115     struct hif_device_mbox_info        MailBoxInfo;
116     HIF_PENDING_EVENTS_FUNC     GetPendingEventsFunc;
117     void                        *HTCContext;
118     struct htc_packet_queue            RegisterIOList;
119     struct ar6k_async_reg_io_buffer    RegIOBuffers[AR6K_MAX_REG_IO_BUFFERS];
120     void                        (*TargetFailureCallback)(void *Context);
121     int                    (*MessagePendingCallback)(void *Context,
122                                                           u32 LookAheads[],
123                                                           int NumLookAheads, 
124                                                           bool *pAsyncProc,
125                                                           int *pNumPktsFetched);
126     HIF_DEVICE_IRQ_PROCESSING_MODE  HifIRQProcessingMode;
127     HIF_MASK_UNMASK_RECV_EVENT      HifMaskUmaskRecvEvent;
128     bool                          HifAttached;
129     struct hif_device_irq_yield_params     HifIRQYieldParams;
130     bool                          DSRCanYield;
131     int                             CurrentDSRRecvCount;
132     struct hif_device_scatter_support_info HifScatterInfo;
133     struct dl_list                         ScatterReqHead; 
134     bool                          ScatterIsVirtual;
135     int                             MaxRecvBundleSize;
136     int                             MaxSendBundleSize;
137     struct ar6k_gmbox_info                 GMboxInfo;
138     bool                          GMboxEnabled;
139     struct ar6k_gmbox_ctrl_registers       GMboxControlRegisters;
140     int                             RecheckIRQStatusCnt;
141 };
142
143 #define LOCK_AR6K(p)      A_MUTEX_LOCK(&(p)->Lock);
144 #define UNLOCK_AR6K(p)    A_MUTEX_UNLOCK(&(p)->Lock);
145 #define REF_IRQ_STATUS_RECHECK(p) (p)->RecheckIRQStatusCnt = 1  /* note: no need to lock this, it only gets set */
146
147 int DevSetup(struct ar6k_device *pDev);
148 void     DevCleanup(struct ar6k_device *pDev);
149 int DevUnmaskInterrupts(struct ar6k_device *pDev);
150 int DevMaskInterrupts(struct ar6k_device *pDev);
151 int DevPollMboxMsgRecv(struct ar6k_device *pDev,
152                             u32 *pLookAhead,
153                             int          TimeoutMS);
154 int DevRWCompletionHandler(void *context, int status);
155 int DevDsrHandler(void *context);
156 int DevCheckPendingRecvMsgsAsync(void *context);
157 void     DevAsyncIrqProcessComplete(struct ar6k_device *pDev);
158 void     DevDumpRegisters(struct ar6k_device               *pDev,
159                           struct ar6k_irq_proc_registers   *pIrqProcRegs,
160                           struct ar6k_irq_enable_registers *pIrqEnableRegs);
161
162 #define DEV_STOP_RECV_ASYNC true
163 #define DEV_STOP_RECV_SYNC  false
164 #define DEV_ENABLE_RECV_ASYNC true
165 #define DEV_ENABLE_RECV_SYNC  false
166 int DevStopRecv(struct ar6k_device *pDev, bool ASyncMode);
167 int DevEnableRecv(struct ar6k_device *pDev, bool ASyncMode);
168 int DevEnableInterrupts(struct ar6k_device *pDev);
169 int DevDisableInterrupts(struct ar6k_device *pDev);
170 int DevWaitForPendingRecv(struct ar6k_device *pDev,u32 TimeoutInMs,bool *pbIsRecvPending);
171
172 #define DEV_CALC_RECV_PADDED_LEN(pDev, length) (((length) + (pDev)->BlockMask) & (~((pDev)->BlockMask)))
173 #define DEV_CALC_SEND_PADDED_LEN(pDev, length) DEV_CALC_RECV_PADDED_LEN(pDev,length)
174 #define DEV_IS_LEN_BLOCK_ALIGNED(pDev, length) (((length) % (pDev)->BlockSize) == 0)
175
176 static INLINE int DevSendPacket(struct ar6k_device *pDev, struct htc_packet *pPacket, u32 SendLength) {
177     u32 paddedLength;
178     bool   sync = (pPacket->Completion == NULL) ? true : false;
179     int status;
180
181        /* adjust the length to be a multiple of block size if appropriate */
182     paddedLength = DEV_CALC_SEND_PADDED_LEN(pDev, SendLength);
183
184 #if 0                    
185     if (paddedLength > pPacket->BufferLength) {
186         A_ASSERT(false);
187         if (pPacket->Completion != NULL) {
188             COMPLETE_HTC_PACKET(pPacket,A_EINVAL);
189             return 0;
190         }
191         return A_EINVAL;
192     }
193 #endif
194     
195     AR_DEBUG_PRINTF(ATH_DEBUG_SEND,
196                 ("DevSendPacket, Padded Length: %d Mbox:0x%X (mode:%s)\n",
197                 paddedLength,
198                 pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX],
199                 sync ? "SYNC" : "ASYNC"));
200
201     status = HIFReadWrite(pDev->HIFDevice,
202                           pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX],
203                           pPacket->pBuffer,
204                           paddedLength,     /* the padded length */
205                           sync ? HIF_WR_SYNC_BLOCK_INC : HIF_WR_ASYNC_BLOCK_INC,
206                           sync ? NULL : pPacket);  /* pass the packet as the context to the HIF request */
207
208     if (sync) {
209         pPacket->Status = status;
210     } else {
211         if (status == A_PENDING) {
212             status = 0;
213         }    
214     }
215
216     return status;
217 }
218                     
219 static INLINE int DevRecvPacket(struct ar6k_device *pDev, struct htc_packet *pPacket, u32 RecvLength) {
220     u32 paddedLength;
221     int status;
222     bool   sync = (pPacket->Completion == NULL) ? true : false;
223
224         /* adjust the length to be a multiple of block size if appropriate */
225     paddedLength = DEV_CALC_RECV_PADDED_LEN(pDev, RecvLength);
226                     
227     if (paddedLength > pPacket->BufferLength) {
228         A_ASSERT(false);
229         AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
230                 ("DevRecvPacket, Not enough space for padlen:%d recvlen:%d bufferlen:%d \n",
231                     paddedLength,RecvLength,pPacket->BufferLength));
232         if (pPacket->Completion != NULL) {
233             COMPLETE_HTC_PACKET(pPacket,A_EINVAL);
234             return 0;
235         }
236         return A_EINVAL;
237     }
238
239     AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
240                 ("DevRecvPacket (0x%lX : hdr:0x%X) Padded Length: %d Mbox:0x%X (mode:%s)\n",
241                 (unsigned long)pPacket, pPacket->PktInfo.AsRx.ExpectedHdr,
242                 paddedLength,
243                 pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX],
244                 sync ? "SYNC" : "ASYNC"));
245
246     status = HIFReadWrite(pDev->HIFDevice,
247                           pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX],
248                           pPacket->pBuffer,
249                           paddedLength,
250                           sync ? HIF_RD_SYNC_BLOCK_FIX : HIF_RD_ASYNC_BLOCK_FIX,
251                           sync ? NULL : pPacket);  /* pass the packet as the context to the HIF request */
252
253     if (sync) {
254         pPacket->Status = status;
255     }
256
257     return status;
258 }
259
260 #define DEV_CHECK_RECV_YIELD(pDev) \
261             ((pDev)->CurrentDSRRecvCount >= (pDev)->HifIRQYieldParams.RecvPacketYieldCount)
262             
263 #define IS_DEV_IRQ_PROC_SYNC_MODE(pDev) (HIF_DEVICE_IRQ_SYNC_ONLY == (pDev)->HifIRQProcessingMode)
264 #define IS_DEV_IRQ_PROCESSING_ASYNC_ALLOWED(pDev) ((pDev)->HifIRQProcessingMode != HIF_DEVICE_IRQ_SYNC_ONLY)
265
266 /**************************************************/
267 /****** Scatter Function and Definitions
268  * 
269  *  
270  */
271   
272 int DevCopyScatterListToFromDMABuffer(struct hif_scatter_req *pReq, bool FromDMA);
273     
274     /* copy any READ data back into scatter list */        
275 #define DEV_FINISH_SCATTER_OPERATION(pR)                                \
276 do {                                                                    \
277         if (!((pR)->CompletionStatus) &&                                \
278             !((pR)->Request & HIF_WRITE) &&                             \
279             ((pR)->ScatterMethod == HIF_SCATTER_DMA_BOUNCE)) {          \
280                 (pR)->CompletionStatus =                                \
281                         DevCopyScatterListToFromDMABuffer((pR),         \
282                                                           FROM_DMA_BUFFER); \
283         }                                                               \
284 } while (0)
285     
286     /* copy any WRITE data to bounce buffer */
287 static INLINE int DEV_PREPARE_SCATTER_OPERATION(struct hif_scatter_req *pReq)  {
288     if ((pReq->Request & HIF_WRITE) && (pReq->ScatterMethod == HIF_SCATTER_DMA_BOUNCE)) {
289         return DevCopyScatterListToFromDMABuffer(pReq,TO_DMA_BUFFER);    
290     } else {
291         return 0;
292     }
293 }
294         
295     
296 int DevSetupMsgBundling(struct ar6k_device *pDev, int MaxMsgsPerTransfer);
297
298 int DevCleanupMsgBundling(struct ar6k_device *pDev);
299                                   
300 #define DEV_GET_MAX_MSG_PER_BUNDLE(pDev)        (pDev)->HifScatterInfo.MaxScatterEntries
301 #define DEV_GET_MAX_BUNDLE_LENGTH(pDev)         (pDev)->HifScatterInfo.MaxTransferSizePerScatterReq
302 #define DEV_ALLOC_SCATTER_REQ(pDev)             \
303     (pDev)->HifScatterInfo.pAllocateReqFunc((pDev)->ScatterIsVirtual ? (pDev) : (pDev)->HIFDevice)
304     
305 #define DEV_FREE_SCATTER_REQ(pDev,pR)           \
306     (pDev)->HifScatterInfo.pFreeReqFunc((pDev)->ScatterIsVirtual ? (pDev) : (pDev)->HIFDevice,(pR))
307
308 #define DEV_GET_MAX_BUNDLE_RECV_LENGTH(pDev)   (pDev)->MaxRecvBundleSize
309 #define DEV_GET_MAX_BUNDLE_SEND_LENGTH(pDev)   (pDev)->MaxSendBundleSize
310
311 #define DEV_SCATTER_READ  true
312 #define DEV_SCATTER_WRITE false
313 #define DEV_SCATTER_ASYNC true
314 #define DEV_SCATTER_SYNC  false
315 int DevSubmitScatterRequest(struct ar6k_device *pDev, struct hif_scatter_req *pScatterReq, bool Read, bool Async);
316
317 #ifdef MBOXHW_UNIT_TEST
318 int DoMboxHWTest(struct ar6k_device *pDev);
319 #endif
320
321     /* completely virtual */
322 struct dev_scatter_dma_virtual_info {
323     u8 *pVirtDmaBuffer;      /* dma-able buffer - CPU accessible address */
324     u8 DataArea[1];      /* start of data area */
325 };
326
327
328
329 void     DumpAR6KDevState(struct ar6k_device *pDev);
330
331 /**************************************************/
332 /****** GMBOX functions and definitions
333  * 
334  *  
335  */
336
337 #ifdef ATH_AR6K_ENABLE_GMBOX
338
339 void     DevCleanupGMbox(struct ar6k_device *pDev);
340 int DevSetupGMbox(struct ar6k_device *pDev);
341 int DevCheckGMboxInterrupts(struct ar6k_device *pDev);
342 void     DevNotifyGMboxTargetFailure(struct ar6k_device *pDev);
343
344 #else
345
346     /* compiled out */
347 #define DevCleanupGMbox(p)
348 #define DevCheckGMboxInterrupts(p) 0
349 #define DevNotifyGMboxTargetFailure(p)
350
351 static INLINE int DevSetupGMbox(struct ar6k_device *pDev) {
352     pDev->GMboxEnabled = false;
353     return 0;
354 }
355
356 #endif
357
358 #ifdef ATH_AR6K_ENABLE_GMBOX
359
360     /* GMBOX protocol modules must expose each of these internal APIs */
361 HCI_TRANSPORT_HANDLE GMboxAttachProtocol(struct ar6k_device *pDev, struct hci_transport_config_info *pInfo);
362 int             GMboxProtocolInstall(struct ar6k_device *pDev);
363 void                 GMboxProtocolUninstall(struct ar6k_device *pDev);
364
365     /* API used by GMBOX protocol modules */
366 struct ar6k_device  *HTCGetAR6KDevice(void *HTCHandle);
367 #define DEV_GMBOX_SET_PROTOCOL(pDev,recv_callback,credits_pending,failure,statedump,context) \
368 {                                                                  \
369     (pDev)->GMboxInfo.pProtocolContext = (context);                \
370     (pDev)->GMboxInfo.pMessagePendingCallBack = (recv_callback);   \
371     (pDev)->GMboxInfo.pCreditsPendingCallback = (credits_pending); \
372     (pDev)->GMboxInfo.pTargetFailureCallback = (failure);          \
373     (pDev)->GMboxInfo.pStateDumpCallback = (statedump);            \
374 }
375
376 #define DEV_GMBOX_GET_PROTOCOL(pDev)  (pDev)->GMboxInfo.pProtocolContext
377
378 int DevGMboxWrite(struct ar6k_device *pDev, struct htc_packet *pPacket, u32 WriteLength);
379 int DevGMboxRead(struct ar6k_device *pDev, struct htc_packet *pPacket, u32 ReadLength);
380
381 #define PROC_IO_ASYNC true
382 #define PROC_IO_SYNC  false
383 typedef enum GMBOX_IRQ_ACTION_TYPE {
384     GMBOX_ACTION_NONE = 0,
385     GMBOX_DISABLE_ALL,
386     GMBOX_ERRORS_IRQ_ENABLE,
387     GMBOX_RECV_IRQ_ENABLE,
388     GMBOX_RECV_IRQ_DISABLE,
389     GMBOX_CREDIT_IRQ_ENABLE,
390     GMBOX_CREDIT_IRQ_DISABLE,
391 } GMBOX_IRQ_ACTION_TYPE;
392
393 int DevGMboxIRQAction(struct ar6k_device *pDev, GMBOX_IRQ_ACTION_TYPE, bool AsyncMode);
394 int DevGMboxReadCreditCounter(struct ar6k_device *pDev, bool AsyncMode, int *pCredits);
395 int DevGMboxReadCreditSize(struct ar6k_device *pDev, int *pCreditSize);
396 int DevGMboxRecvLookAheadPeek(struct ar6k_device *pDev, u8 *pLookAheadBuffer, int *pLookAheadBytes);
397 int DevGMboxSetTargetInterrupt(struct ar6k_device *pDev, int SignalNumber, int AckTimeoutMS);
398
399 #endif
400
401 #endif /*AR6K_H_*/