aboutsummaryrefslogtreecommitdiff
path: root/drivers/sdio/function/wlan/ar6000/htc/ar6k.h
blob: 301ab34a37edf7f1fc490fbb6c255f01b5af6654 (plain)
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
/*
 *
 * Copyright (c) 2007 Atheros Communications Inc.
 * All rights reserved.
 *
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as
 *  published by the Free Software Foundation;
 *
 *  Software distributed under the License is distributed on an "AS
 *  IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 *  implied. See the License for the specific language governing
 *  rights and limitations under the License.
 *
 *
 *
 */

#ifndef AR6K_H_
#define AR6K_H_

#define AR6K_MAILBOXES 4

/* HTC runs over mailbox 0 */
#define HTC_MAILBOX          0

#define AR6K_TARGET_DEBUG_INTR_MASK     0x01

#define OTHER_INTS_ENABLED (INT_STATUS_ENABLE_ERROR_MASK |   \
                            INT_STATUS_ENABLE_CPU_MASK   |   \
                            INT_STATUS_ENABLE_COUNTER_MASK)

//#define MBOXHW_UNIT_TEST 1

#include "athstartpack.h"
typedef PREPACK struct _AR6K_IRQ_PROC_REGISTERS {
    A_UINT8                      host_int_status;
    A_UINT8                      cpu_int_status;
    A_UINT8                      error_int_status;
    A_UINT8                      counter_int_status;
    A_UINT8                      mbox_frame;
    A_UINT8                      rx_lookahead_valid;
    A_UINT8                      hole[2];
    A_UINT32                     rx_lookahead[2];
} POSTPACK AR6K_IRQ_PROC_REGISTERS;

#define AR6K_IRQ_PROC_REGS_SIZE sizeof(AR6K_IRQ_PROC_REGISTERS)



typedef PREPACK struct _AR6K_IRQ_ENABLE_REGISTERS {
    A_UINT8                      int_status_enable;
    A_UINT8                      cpu_int_status_enable;
    A_UINT8                      error_status_enable;
    A_UINT8                      counter_int_status_enable;
} POSTPACK AR6K_IRQ_ENABLE_REGISTERS;

#include "athendpack.h"

#define AR6K_IRQ_ENABLE_REGS_SIZE sizeof(AR6K_IRQ_ENABLE_REGISTERS)

#define AR6K_REG_IO_BUFFER_SIZE     32
#define AR6K_MAX_REG_IO_BUFFERS     8

/* buffers for ASYNC I/O */
typedef struct AR6K_ASYNC_REG_IO_BUFFER {
    HTC_PACKET    HtcPacket;   /* we use an HTC packet as a wrapper for our async register-based I/O */
    A_UINT8       Buffer[AR6K_REG_IO_BUFFER_SIZE];
} AR6K_ASYNC_REG_IO_BUFFER;

typedef struct _AR6K_DEVICE {
    A_MUTEX_T                   Lock;
    AR6K_IRQ_PROC_REGISTERS     IrqProcRegisters;
    AR6K_IRQ_ENABLE_REGISTERS   IrqEnableRegisters;
    void                        *HIFDevice;
    A_UINT32                    BlockSize;
    A_UINT32                    BlockMask;
    A_UINT32                    MailboxAddress;
    HIF_PENDING_EVENTS_FUNC     GetPendingEventsFunc;
    void                        *HTCContext;
    HTC_PACKET_QUEUE            RegisterIOList;
    AR6K_ASYNC_REG_IO_BUFFER    RegIOBuffers[AR6K_MAX_REG_IO_BUFFERS];
    void                        (*TargetFailureCallback)(void *Context);
    A_STATUS                    (*MessagePendingCallback)(void *Context, A_UINT32 LookAhead, A_BOOL *pAsyncProc);
    HIF_DEVICE_IRQ_PROCESSING_MODE  HifIRQProcessingMode;
    HIF_MASK_UNMASK_RECV_EVENT      HifMaskUmaskRecvEvent;
} AR6K_DEVICE;

#define IS_DEV_IRQ_PROCESSING_ASYNC_ALLOWED(pDev) ((pDev)->HifIRQProcessingMode != HIF_DEVICE_IRQ_SYNC_ONLY)

A_STATUS DevSetup(AR6K_DEVICE *pDev);
A_STATUS DevUnmaskInterrupts(AR6K_DEVICE *pDev);
A_STATUS DevMaskInterrupts(AR6K_DEVICE *pDev);
A_STATUS DevPollMboxMsgRecv(AR6K_DEVICE *pDev,
                            A_UINT32    *pLookAhead,
                            int          TimeoutMS);
A_STATUS DevRWCompletionHandler(void *context, A_STATUS status);
A_STATUS DevDsrHandler(void *context);
A_STATUS DevCheckPendingRecvMsgsAsync(void *context);
void     DevDumpRegisters(AR6K_IRQ_PROC_REGISTERS   *pIrqProcRegs,
                          AR6K_IRQ_ENABLE_REGISTERS *pIrqEnableRegs);

#define DEV_STOP_RECV_ASYNC TRUE
#define DEV_STOP_RECV_SYNC  FALSE
#define DEV_ENABLE_RECV_ASYNC TRUE
#define DEV_ENABLE_RECV_SYNC  FALSE
A_STATUS DevStopRecv(AR6K_DEVICE *pDev, A_BOOL ASyncMode);
A_STATUS DevEnableRecv(AR6K_DEVICE *pDev, A_BOOL ASyncMode);

static INLINE A_STATUS DevSendPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 SendLength) {
    A_UINT32 paddedLength;
    A_BOOL   sync = (pPacket->Completion == NULL) ? TRUE : FALSE;
    A_STATUS status;

       /* adjust the length to be a multiple of block size if appropriate */
    paddedLength = (SendLength + (pDev->BlockMask)) &
                    (~(pDev->BlockMask));
#if 0 // BufferLength may not be set in , fix this...
    if (paddedLength > pPacket->BufferLength) {
        AR_DEBUG_ASSERT(FALSE);
        if (pPacket->Completion != NULL) {
            COMPLETE_HTC_PACKET(pPacket,A_EINVAL);
        }
        return A_EINVAL;
    }
#endif
    AR_DEBUG_PRINTF(ATH_DEBUG_SEND,
                ("DevSendPacket, Padded Length: %d Mbox:0x%X (mode:%s)\n",
                paddedLength,
                pDev->MailboxAddress,
                sync ? "SYNC" : "ASYNC"));

    status = HIFReadWrite(pDev->HIFDevice,
                          pDev->MailboxAddress,
                          pPacket->pBuffer,
                          paddedLength,     /* the padded length */
                          sync ? HIF_WR_SYNC_BLOCK_INC : HIF_WR_ASYNC_BLOCK_INC,
                          sync ? NULL : pPacket);  /* pass the packet as the context to the HIF request */

    if (sync) {
        pPacket->Status = status;
    }

    return status;
}

static INLINE A_STATUS DevRecvPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 RecvLength) {
    A_UINT32 paddedLength;
    A_STATUS status;
    A_BOOL   sync = (pPacket->Completion == NULL) ? TRUE : FALSE;

        /* adjust the length to be a multiple of block size if appropriate */
    paddedLength = (RecvLength + (pDev->BlockMask)) &
                    (~(pDev->BlockMask));
    if (paddedLength > pPacket->BufferLength) {
        AR_DEBUG_ASSERT(FALSE);
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                ("DevRecvPacket, Not enough space for padlen:%d recvlen:%d bufferlen:%d \n",
                    paddedLength,RecvLength,pPacket->BufferLength));
        if (pPacket->Completion != NULL) {
            COMPLETE_HTC_PACKET(pPacket,A_EINVAL);
        }
        return A_EINVAL;
    }

    AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
                ("DevRecvPacket, Padded Length: %d Mbox:0x%X (mode:%s)\n",
                paddedLength,
                pDev->MailboxAddress,
                sync ? "SYNC" : "ASYNC"));

    status = HIFReadWrite(pDev->HIFDevice,
                          pDev->MailboxAddress,
                          pPacket->pBuffer,
                          paddedLength,
                          sync ? HIF_RD_SYNC_BLOCK_INC : HIF_RD_ASYNC_BLOCK_INC,
                          sync ? NULL : pPacket);  /* pass the packet as the context to the HIF request */

    if (sync) {
        pPacket->Status = status;
    }

    return status;
}

#ifdef MBOXHW_UNIT_TEST
A_STATUS DoMboxHWTest(AR6K_DEVICE *pDev);
#endif

#endif /*AR6K_H_*/