Add ar6000 wireless driver.
[kernel.git] / drivers / ar6000 / htc / ar6k.h
1 /*
2  *
3  * Copyright (c) 2007 Atheros Communications Inc.
4  * All rights reserved.
5  *
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License version 2 as
9  *  published by the Free Software Foundation;
10  *
11  *  Software distributed under the License is distributed on an "AS
12  *  IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
13  *  implied. See the License for the specific language governing
14  *  rights and limitations under the License.
15  *
16  *
17  *
18  */
19
20 #ifndef AR6K_H_
21 #define AR6K_H_
22
23 #define AR6K_MAILBOXES 4
24
25 /* HTC runs over mailbox 0 */
26 #define HTC_MAILBOX          0
27
28 #define AR6K_TARGET_DEBUG_INTR_MASK     0x01
29
30 #define OTHER_INTS_ENABLED (INT_STATUS_ENABLE_ERROR_MASK |   \
31                             INT_STATUS_ENABLE_CPU_MASK   |   \
32                             INT_STATUS_ENABLE_COUNTER_MASK)
33
34 //#define MBOXHW_UNIT_TEST 1
35
36 #include "athstartpack.h"
37 typedef PREPACK struct _AR6K_IRQ_PROC_REGISTERS {
38     A_UINT8                      host_int_status;
39     A_UINT8                      cpu_int_status;
40     A_UINT8                      error_int_status;
41     A_UINT8                      counter_int_status;
42     A_UINT8                      mbox_frame;
43     A_UINT8                      rx_lookahead_valid;
44     A_UINT8                      hole[2];
45     A_UINT32                     rx_lookahead[2];
46 } POSTPACK AR6K_IRQ_PROC_REGISTERS;
47
48 #define AR6K_IRQ_PROC_REGS_SIZE sizeof(AR6K_IRQ_PROC_REGISTERS)
49
50
51
52 typedef PREPACK struct _AR6K_IRQ_ENABLE_REGISTERS {
53     A_UINT8                      int_status_enable;
54     A_UINT8                      cpu_int_status_enable;
55     A_UINT8                      error_status_enable;
56     A_UINT8                      counter_int_status_enable;
57 } POSTPACK AR6K_IRQ_ENABLE_REGISTERS;
58
59 #include "athendpack.h"
60
61 #define AR6K_IRQ_ENABLE_REGS_SIZE sizeof(AR6K_IRQ_ENABLE_REGISTERS)
62
63 #define AR6K_REG_IO_BUFFER_SIZE     32
64 #define AR6K_MAX_REG_IO_BUFFERS     8
65
66 /* buffers for ASYNC I/O */
67 typedef struct AR6K_ASYNC_REG_IO_BUFFER {
68     HTC_PACKET    HtcPacket;   /* we use an HTC packet as a wrapper for our async register-based I/O */
69     A_UINT8       Buffer[AR6K_REG_IO_BUFFER_SIZE];
70 } AR6K_ASYNC_REG_IO_BUFFER;
71
72 typedef struct _AR6K_DEVICE {
73     A_MUTEX_T                   Lock;
74     AR6K_IRQ_PROC_REGISTERS     IrqProcRegisters;
75     AR6K_IRQ_ENABLE_REGISTERS   IrqEnableRegisters;
76     void                        *HIFDevice;
77     A_UINT32                    BlockSize;
78     A_UINT32                    BlockMask;
79     A_UINT32                    MailboxAddress;
80     HIF_PENDING_EVENTS_FUNC     GetPendingEventsFunc;
81     void                        *HTCContext;
82     HTC_PACKET_QUEUE            RegisterIOList;
83     AR6K_ASYNC_REG_IO_BUFFER    RegIOBuffers[AR6K_MAX_REG_IO_BUFFERS];
84     void                        (*TargetFailureCallback)(void *Context);
85     A_STATUS                    (*MessagePendingCallback)(void *Context, A_UINT32 LookAhead, A_BOOL *pAsyncProc);
86     HIF_DEVICE_IRQ_PROCESSING_MODE  HifIRQProcessingMode;
87     HIF_MASK_UNMASK_RECV_EVENT      HifMaskUmaskRecvEvent;
88 } AR6K_DEVICE;
89
90 #define IS_DEV_IRQ_PROCESSING_ASYNC_ALLOWED(pDev) ((pDev)->HifIRQProcessingMode != HIF_DEVICE_IRQ_SYNC_ONLY)
91
92 A_STATUS DevSetup(AR6K_DEVICE *pDev);
93 A_STATUS DevUnmaskInterrupts(AR6K_DEVICE *pDev);
94 A_STATUS DevMaskInterrupts(AR6K_DEVICE *pDev);
95 A_STATUS DevPollMboxMsgRecv(AR6K_DEVICE *pDev,
96                             A_UINT32    *pLookAhead,
97                             int          TimeoutMS);
98 A_STATUS DevRWCompletionHandler(void *context, A_STATUS status);
99 A_STATUS DevDsrHandler(void *context);
100 A_STATUS DevCheckPendingRecvMsgsAsync(void *context);
101 void     DevDumpRegisters(AR6K_IRQ_PROC_REGISTERS   *pIrqProcRegs,
102                           AR6K_IRQ_ENABLE_REGISTERS *pIrqEnableRegs);
103
104 #define DEV_STOP_RECV_ASYNC TRUE
105 #define DEV_STOP_RECV_SYNC  FALSE
106 #define DEV_ENABLE_RECV_ASYNC TRUE
107 #define DEV_ENABLE_RECV_SYNC  FALSE
108 A_STATUS DevStopRecv(AR6K_DEVICE *pDev, A_BOOL ASyncMode);
109 A_STATUS DevEnableRecv(AR6K_DEVICE *pDev, A_BOOL ASyncMode);
110
111 static INLINE A_STATUS DevSendPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 SendLength) {
112     A_UINT32 paddedLength;
113     A_BOOL   sync = (pPacket->Completion == NULL) ? TRUE : FALSE;
114     A_STATUS status;
115
116        /* adjust the length to be a multiple of block size if appropriate */
117     paddedLength = (SendLength + (pDev->BlockMask)) &
118                     (~(pDev->BlockMask));
119 #if 0 // BufferLength may not be set in , fix this...
120     if (paddedLength > pPacket->BufferLength) {
121         AR_DEBUG_ASSERT(FALSE);
122         if (pPacket->Completion != NULL) {
123             COMPLETE_HTC_PACKET(pPacket,A_EINVAL);
124         }
125         return A_EINVAL;
126     }
127 #endif
128     AR_DEBUG_PRINTF(ATH_DEBUG_SEND,
129                 ("DevSendPacket, Padded Length: %d Mbox:0x%X (mode:%s)\n",
130                 paddedLength,
131                 pDev->MailboxAddress,
132                 sync ? "SYNC" : "ASYNC"));
133
134     status = HIFReadWrite(pDev->HIFDevice,
135                           pDev->MailboxAddress,
136                           pPacket->pBuffer,
137                           paddedLength,     /* the padded length */
138                           sync ? HIF_WR_SYNC_BLOCK_INC : HIF_WR_ASYNC_BLOCK_INC,
139                           sync ? NULL : pPacket);  /* pass the packet as the context to the HIF request */
140
141     if (sync) {
142         pPacket->Status = status;
143     }
144
145     return status;
146 }
147
148 static INLINE A_STATUS DevRecvPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 RecvLength) {
149     A_UINT32 paddedLength;
150     A_STATUS status;
151     A_BOOL   sync = (pPacket->Completion == NULL) ? TRUE : FALSE;
152
153         /* adjust the length to be a multiple of block size if appropriate */
154     paddedLength = (RecvLength + (pDev->BlockMask)) &
155                     (~(pDev->BlockMask));
156     if (paddedLength > pPacket->BufferLength) {
157         AR_DEBUG_ASSERT(FALSE);
158         AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
159                 ("DevRecvPacket, Not enough space for padlen:%d recvlen:%d bufferlen:%d \n",
160                     paddedLength,RecvLength,pPacket->BufferLength));
161         if (pPacket->Completion != NULL) {
162             COMPLETE_HTC_PACKET(pPacket,A_EINVAL);
163         }
164         return A_EINVAL;
165     }
166
167     AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
168                 ("DevRecvPacket, Padded Length: %d Mbox:0x%X (mode:%s)\n",
169                 paddedLength,
170                 pDev->MailboxAddress,
171                 sync ? "SYNC" : "ASYNC"));
172
173     status = HIFReadWrite(pDev->HIFDevice,
174                           pDev->MailboxAddress,
175                           pPacket->pBuffer,
176                           paddedLength,
177                           sync ? HIF_RD_SYNC_BLOCK_INC : HIF_RD_ASYNC_BLOCK_INC,
178                           sync ? NULL : pPacket);  /* pass the packet as the context to the HIF request */
179
180     if (sync) {
181         pPacket->Status = status;
182     }
183
184     return status;
185 }
186
187 #ifdef MBOXHW_UNIT_TEST
188 A_STATUS DoMboxHWTest(AR6K_DEVICE *pDev);
189 #endif
190
191 #endif /*AR6K_H_*/