1 //------------------------------------------------------------------------------
2 // <copyright file="ar6k_gmbox.c" company="Atheros">
3 // Copyright (c) 2007-2010 Atheros Corporation. All rights reserved.
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.
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.
19 //------------------------------------------------------------------------------
20 //==============================================================================
21 // Generic MBOX API implementation
23 // Author(s): ="Atheros"
24 //==============================================================================
29 #include "../htc_debug.h"
31 #include "htc_packet.h"
33 #include "hw/mbox_host_reg.h"
37 * This file provides management functions and a toolbox for GMBOX protocol modules.
38 * Only one protocol module can be installed at a time. The determination of which protocol
39 * module is installed is determined at compile time.
42 #ifdef ATH_AR6K_ENABLE_GMBOX
43 /* GMBOX definitions */
44 #define GMBOX_INT_STATUS_ENABLE_REG 0x488
45 #define GMBOX_INT_STATUS_RX_DATA (1 << 0)
46 #define GMBOX_INT_STATUS_TX_OVERFLOW (1 << 1)
47 #define GMBOX_INT_STATUS_RX_OVERFLOW (1 << 2)
49 #define GMBOX_LOOKAHEAD_MUX_REG 0x498
50 #define GMBOX_LA_MUX_OVERRIDE_2_3 (1 << 0)
52 #define AR6K_GMBOX_CREDIT_DEC_ADDRESS (COUNT_DEC_ADDRESS + 4 * AR6K_GMBOX_CREDIT_COUNTER)
53 #define AR6K_GMBOX_CREDIT_SIZE_ADDRESS (COUNT_ADDRESS + AR6K_GMBOX_CREDIT_SIZE_COUNTER)
56 /* external APIs for allocating and freeing internal I/O packets to handle ASYNC I/O */
57 extern void AR6KFreeIOPacket(AR6K_DEVICE
*pDev
, HTC_PACKET
*pPacket
);
58 extern HTC_PACKET
*AR6KAllocIOPacket(AR6K_DEVICE
*pDev
);
61 /* callback when our fetch to enable/disable completes */
62 static void DevGMboxIRQActionAsyncHandler(void *Context
, HTC_PACKET
*pPacket
)
64 AR6K_DEVICE
*pDev
= (AR6K_DEVICE
*)Context
;
66 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ
,("+DevGMboxIRQActionAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev
));
68 if (A_FAILED(pPacket
->Status
)) {
69 AR_DEBUG_PRINTF(ATH_DEBUG_ERR
,
70 ("IRQAction Operation (%d) failed! status:%d \n", pPacket
->PktInfo
.AsRx
.HTCRxFlags
,pPacket
->Status
));
72 /* free this IO packet */
73 AR6KFreeIOPacket(pDev
,pPacket
);
74 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ
,("-DevGMboxIRQActionAsyncHandler \n"));
77 static int DevGMboxCounterEnableDisable(AR6K_DEVICE
*pDev
, GMBOX_IRQ_ACTION_TYPE IrqAction
, A_BOOL AsyncMode
)
80 AR6K_IRQ_ENABLE_REGISTERS regs
;
81 HTC_PACKET
*pIOPacket
= NULL
;
85 if (GMBOX_CREDIT_IRQ_ENABLE
== IrqAction
) {
86 pDev
->GMboxInfo
.CreditCountIRQEnabled
= TRUE
;
87 pDev
->IrqEnableRegisters
.counter_int_status_enable
|=
88 COUNTER_INT_STATUS_ENABLE_BIT_SET(1 << AR6K_GMBOX_CREDIT_COUNTER
);
89 pDev
->IrqEnableRegisters
.int_status_enable
|= INT_STATUS_ENABLE_COUNTER_SET(0x01);
91 pDev
->GMboxInfo
.CreditCountIRQEnabled
= FALSE
;
92 pDev
->IrqEnableRegisters
.counter_int_status_enable
&=
93 ~(COUNTER_INT_STATUS_ENABLE_BIT_SET(1 << AR6K_GMBOX_CREDIT_COUNTER
));
95 /* copy into our temp area */
96 A_MEMCPY(®s
,&pDev
->IrqEnableRegisters
,AR6K_IRQ_ENABLE_REGS_SIZE
);
104 pIOPacket
= AR6KAllocIOPacket(pDev
);
106 if (NULL
== pIOPacket
) {
107 status
= A_NO_MEMORY
;
112 /* copy values to write to our async I/O buffer */
113 A_MEMCPY(pIOPacket
->pBuffer
,&pDev
->IrqEnableRegisters
,AR6K_IRQ_ENABLE_REGS_SIZE
);
115 /* stick in our completion routine when the I/O operation completes */
116 pIOPacket
->Completion
= DevGMboxIRQActionAsyncHandler
;
117 pIOPacket
->pContext
= pDev
;
118 pIOPacket
->PktInfo
.AsRx
.HTCRxFlags
= IrqAction
;
119 /* write it out asynchronously */
120 HIFReadWrite(pDev
->HIFDevice
,
121 INT_STATUS_ENABLE_ADDRESS
,
123 AR6K_IRQ_ENABLE_REGS_SIZE
,
124 HIF_WR_ASYNC_BYTE_INC
,
131 /* if we get here we are doing it synchronously */
132 status
= HIFReadWrite(pDev
->HIFDevice
,
133 INT_STATUS_ENABLE_ADDRESS
,
134 ®s
.int_status_enable
,
135 AR6K_IRQ_ENABLE_REGS_SIZE
,
136 HIF_WR_SYNC_BYTE_INC
,
140 if (A_FAILED(status
)) {
141 AR_DEBUG_PRINTF(ATH_DEBUG_ERR
,
142 (" IRQAction Operation (%d) failed! status:%d \n", IrqAction
, status
));
145 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ
,
146 (" IRQAction Operation (%d) success \n", IrqAction
));
150 if (pIOPacket
!= NULL
) {
151 AR6KFreeIOPacket(pDev
,pIOPacket
);
158 int DevGMboxIRQAction(AR6K_DEVICE
*pDev
, GMBOX_IRQ_ACTION_TYPE IrqAction
, A_BOOL AsyncMode
)
161 HTC_PACKET
*pIOPacket
= NULL
;
162 A_UINT8 GMboxIntControl
[4];
164 if (GMBOX_CREDIT_IRQ_ENABLE
== IrqAction
) {
165 return DevGMboxCounterEnableDisable(pDev
, GMBOX_CREDIT_IRQ_ENABLE
, AsyncMode
);
166 } else if(GMBOX_CREDIT_IRQ_DISABLE
== IrqAction
) {
167 return DevGMboxCounterEnableDisable(pDev
, GMBOX_CREDIT_IRQ_DISABLE
, AsyncMode
);
170 if (GMBOX_DISABLE_ALL
== IrqAction
) {
171 /* disable credit IRQ, those are on a different set of registers */
172 DevGMboxCounterEnableDisable(pDev
, GMBOX_CREDIT_IRQ_DISABLE
, AsyncMode
);
175 /* take the lock to protect interrupt enable shadows */
180 case GMBOX_DISABLE_ALL
:
181 pDev
->GMboxControlRegisters
.int_status_enable
= 0;
183 case GMBOX_ERRORS_IRQ_ENABLE
:
184 pDev
->GMboxControlRegisters
.int_status_enable
|= GMBOX_INT_STATUS_TX_OVERFLOW
|
185 GMBOX_INT_STATUS_RX_OVERFLOW
;
187 case GMBOX_RECV_IRQ_ENABLE
:
188 pDev
->GMboxControlRegisters
.int_status_enable
|= GMBOX_INT_STATUS_RX_DATA
;
190 case GMBOX_RECV_IRQ_DISABLE
:
191 pDev
->GMboxControlRegisters
.int_status_enable
&= ~GMBOX_INT_STATUS_RX_DATA
;
193 case GMBOX_ACTION_NONE
:
199 GMboxIntControl
[0] = pDev
->GMboxControlRegisters
.int_status_enable
;
200 GMboxIntControl
[1] = GMboxIntControl
[0];
201 GMboxIntControl
[2] = GMboxIntControl
[0];
202 GMboxIntControl
[3] = GMboxIntControl
[0];
210 pIOPacket
= AR6KAllocIOPacket(pDev
);
212 if (NULL
== pIOPacket
) {
213 status
= A_NO_MEMORY
;
218 /* copy values to write to our async I/O buffer */
219 A_MEMCPY(pIOPacket
->pBuffer
,GMboxIntControl
,sizeof(GMboxIntControl
));
221 /* stick in our completion routine when the I/O operation completes */
222 pIOPacket
->Completion
= DevGMboxIRQActionAsyncHandler
;
223 pIOPacket
->pContext
= pDev
;
224 pIOPacket
->PktInfo
.AsRx
.HTCRxFlags
= IrqAction
;
225 /* write it out asynchronously */
226 HIFReadWrite(pDev
->HIFDevice
,
227 GMBOX_INT_STATUS_ENABLE_REG
,
229 sizeof(GMboxIntControl
),
230 HIF_WR_ASYNC_BYTE_FIX
,
236 /* if we get here we are doing it synchronously */
238 status
= HIFReadWrite(pDev
->HIFDevice
,
239 GMBOX_INT_STATUS_ENABLE_REG
,
241 sizeof(GMboxIntControl
),
242 HIF_WR_SYNC_BYTE_FIX
,
247 if (A_FAILED(status
)) {
248 AR_DEBUG_PRINTF(ATH_DEBUG_ERR
,
249 (" IRQAction Operation (%d) failed! status:%d \n", IrqAction
, status
));
252 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ
,
253 (" IRQAction Operation (%d) success \n", IrqAction
));
257 if (pIOPacket
!= NULL
) {
258 AR6KFreeIOPacket(pDev
,pIOPacket
);
264 void DevCleanupGMbox(AR6K_DEVICE
*pDev
)
266 if (pDev
->GMboxEnabled
) {
267 pDev
->GMboxEnabled
= FALSE
;
268 GMboxProtocolUninstall(pDev
);
272 int DevSetupGMbox(AR6K_DEVICE
*pDev
)
275 A_UINT8 muxControl
[4];
279 if (0 == pDev
->MailBoxInfo
.GMboxAddress
) {
283 AR_DEBUG_PRINTF(ATH_DEBUG_ANY
,(" GMBOX Advertised: Address:0x%X , size:%d \n",
284 pDev
->MailBoxInfo
.GMboxAddress
, pDev
->MailBoxInfo
.GMboxSize
));
286 status
= DevGMboxIRQAction(pDev
, GMBOX_DISABLE_ALL
, PROC_IO_SYNC
);
288 if (A_FAILED(status
)) {
292 /* write to mailbox look ahead mux control register, we want the
293 * GMBOX lookaheads to appear on lookaheads 2 and 3
294 * the register is 1-byte wide so we need to hit it 4 times to align the operation
296 muxControl
[0] = GMBOX_LA_MUX_OVERRIDE_2_3
;
297 muxControl
[1] = GMBOX_LA_MUX_OVERRIDE_2_3
;
298 muxControl
[2] = GMBOX_LA_MUX_OVERRIDE_2_3
;
299 muxControl
[3] = GMBOX_LA_MUX_OVERRIDE_2_3
;
301 status
= HIFReadWrite(pDev
->HIFDevice
,
302 GMBOX_LOOKAHEAD_MUX_REG
,
305 HIF_WR_SYNC_BYTE_FIX
, /* hit this register 4 times */
308 if (A_FAILED(status
)) {
312 status
= GMboxProtocolInstall(pDev
);
314 if (A_FAILED(status
)) {
318 pDev
->GMboxEnabled
= TRUE
;
325 int DevCheckGMboxInterrupts(AR6K_DEVICE
*pDev
)
328 A_UINT8 counter_int_status
;
330 A_UINT8 host_int_status2
;
332 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ
, ("+DevCheckGMboxInterrupts \n"));
334 /* the caller guarantees that this is a context that allows for blocking I/O */
338 host_int_status2
= pDev
->IrqProcRegisters
.host_int_status2
&
339 pDev
->GMboxControlRegisters
.int_status_enable
;
341 if (host_int_status2
& GMBOX_INT_STATUS_TX_OVERFLOW
) {
342 AR_DEBUG_PRINTF(ATH_DEBUG_ERR
, ("GMBOX : TX Overflow \n"));
346 if (host_int_status2
& GMBOX_INT_STATUS_RX_OVERFLOW
) {
347 AR_DEBUG_PRINTF(ATH_DEBUG_ERR
, ("GMBOX : RX Overflow \n"));
351 if (A_FAILED(status
)) {
352 if (pDev
->GMboxInfo
.pTargetFailureCallback
!= NULL
) {
353 pDev
->GMboxInfo
.pTargetFailureCallback(pDev
->GMboxInfo
.pProtocolContext
, status
);
358 if (host_int_status2
& GMBOX_INT_STATUS_RX_DATA
) {
359 if (pDev
->IrqProcRegisters
.gmbox_rx_avail
> 0) {
360 A_ASSERT(pDev
->GMboxInfo
.pMessagePendingCallBack
!= NULL
);
361 status
= pDev
->GMboxInfo
.pMessagePendingCallBack(
362 pDev
->GMboxInfo
.pProtocolContext
,
363 (A_UINT8
*)&pDev
->IrqProcRegisters
.rx_gmbox_lookahead_alias
[0],
364 pDev
->IrqProcRegisters
.gmbox_rx_avail
);
368 if (A_FAILED(status
)) {
372 counter_int_status
= pDev
->IrqProcRegisters
.counter_int_status
&
373 pDev
->IrqEnableRegisters
.counter_int_status_enable
;
375 /* check if credit interrupt is pending */
376 if (counter_int_status
& (COUNTER_INT_STATUS_ENABLE_BIT_SET(1 << AR6K_GMBOX_CREDIT_COUNTER
))) {
378 /* do synchronous read */
379 status
= DevGMboxReadCreditCounter(pDev
, PROC_IO_SYNC
, &credits
);
381 if (A_FAILED(status
)) {
385 A_ASSERT(pDev
->GMboxInfo
.pCreditsPendingCallback
!= NULL
);
386 status
= pDev
->GMboxInfo
.pCreditsPendingCallback(pDev
->GMboxInfo
.pProtocolContext
,
388 pDev
->GMboxInfo
.CreditCountIRQEnabled
);
393 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ
, ("-DevCheckGMboxInterrupts (%d) \n",status
));
399 int DevGMboxWrite(AR6K_DEVICE
*pDev
, HTC_PACKET
*pPacket
, A_UINT32 WriteLength
)
401 A_UINT32 paddedLength
;
402 A_BOOL sync
= (pPacket
->Completion
== NULL
) ? TRUE
: FALSE
;
406 /* adjust the length to be a multiple of block size if appropriate */
407 paddedLength
= DEV_CALC_SEND_PADDED_LEN(pDev
, WriteLength
);
409 AR_DEBUG_PRINTF(ATH_DEBUG_SEND
,
410 ("DevGMboxWrite, Padded Length: %d Mbox:0x%X (mode:%s)\n",
412 pDev
->MailBoxInfo
.GMboxAddress
,
413 sync
? "SYNC" : "ASYNC"));
415 /* last byte of packet has to hit the EOM marker */
416 address
= pDev
->MailBoxInfo
.GMboxAddress
+ pDev
->MailBoxInfo
.GMboxSize
- paddedLength
;
418 status
= HIFReadWrite(pDev
->HIFDevice
,
421 paddedLength
, /* the padded length */
422 sync
? HIF_WR_SYNC_BLOCK_INC
: HIF_WR_ASYNC_BLOCK_INC
,
423 sync
? NULL
: pPacket
); /* pass the packet as the context to the HIF request */
426 pPacket
->Status
= status
;
428 if (status
== A_PENDING
) {
436 int DevGMboxRead(AR6K_DEVICE
*pDev
, HTC_PACKET
*pPacket
, A_UINT32 ReadLength
)
439 A_UINT32 paddedLength
;
441 A_BOOL sync
= (pPacket
->Completion
== NULL
) ? TRUE
: FALSE
;
443 /* adjust the length to be a multiple of block size if appropriate */
444 paddedLength
= DEV_CALC_RECV_PADDED_LEN(pDev
, ReadLength
);
446 if (paddedLength
> pPacket
->BufferLength
) {
448 AR_DEBUG_PRINTF(ATH_DEBUG_ERR
,
449 ("DevGMboxRead, Not enough space for padlen:%d recvlen:%d bufferlen:%d \n",
450 paddedLength
,ReadLength
,pPacket
->BufferLength
));
451 if (pPacket
->Completion
!= NULL
) {
452 COMPLETE_HTC_PACKET(pPacket
,A_EINVAL
);
458 AR_DEBUG_PRINTF(ATH_DEBUG_RECV
,
459 ("DevGMboxRead (0x%lX : hdr:0x%X) Padded Length: %d Mbox:0x%X (mode:%s)\n",
460 (unsigned long)pPacket
, pPacket
->PktInfo
.AsRx
.ExpectedHdr
,
462 pDev
->MailBoxInfo
.GMboxAddress
,
463 sync
? "SYNC" : "ASYNC"));
465 status
= HIFReadWrite(pDev
->HIFDevice
,
466 pDev
->MailBoxInfo
.GMboxAddress
,
469 sync
? HIF_RD_SYNC_BLOCK_FIX
: HIF_RD_ASYNC_BLOCK_FIX
,
470 sync
? NULL
: pPacket
); /* pass the packet as the context to the HIF request */
473 pPacket
->Status
= status
;
480 static int ProcessCreditCounterReadBuffer(A_UINT8
*pBuffer
, int Length
)
484 /* theory of how this works:
485 * We read the credit decrement register multiple times on a byte-wide basis.
486 * The number of times (32) aligns the I/O operation to be a multiple of 4 bytes and provides a
487 * reasonable chance to acquire "all" pending credits in a single I/O operation.
489 * Once we obtain the filled buffer, we can walk through it looking for credit decrement transitions.
490 * Each non-zero byte represents a single credit decrement (which is a credit given back to the host)
491 * For example if the target provides 3 credits and added 4 more during the 32-byte read operation the following
492 * pattern "could" appear:
494 * 0x3 0x2 0x1 0x0 0x0 0x0 0x0 0x0 0x1 0x0 0x1 0x0 0x1 0x0 0x1 0x0 ......rest zeros
495 * <---------> <----------------------------->
496 * \_ credits aleady there \_ target adding 4 more credits
498 * The total available credits would be 7, since there are 7 non-zero bytes in the buffer.
502 if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV
)) {
503 DebugDumpBytes(pBuffer
, Length
, "GMBOX Credit read buffer");
518 /* callback when our fetch to enable/disable completes */
519 static void DevGMboxReadCreditsAsyncHandler(void *Context
, HTC_PACKET
*pPacket
)
521 AR6K_DEVICE
*pDev
= (AR6K_DEVICE
*)Context
;
523 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ
,("+DevGMboxReadCreditsAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev
));
525 if (A_FAILED(pPacket
->Status
)) {
526 AR_DEBUG_PRINTF(ATH_DEBUG_ERR
,
527 ("Read Credit Operation failed! status:%d \n", pPacket
->Status
));
530 credits
= ProcessCreditCounterReadBuffer(pPacket
->pBuffer
, AR6K_REG_IO_BUFFER_SIZE
);
531 pDev
->GMboxInfo
.pCreditsPendingCallback(pDev
->GMboxInfo
.pProtocolContext
,
533 pDev
->GMboxInfo
.CreditCountIRQEnabled
);
537 /* free this IO packet */
538 AR6KFreeIOPacket(pDev
,pPacket
);
539 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ
,("-DevGMboxReadCreditsAsyncHandler \n"));
542 int DevGMboxReadCreditCounter(AR6K_DEVICE
*pDev
, A_BOOL AsyncMode
, int *pCredits
)
545 HTC_PACKET
*pIOPacket
= NULL
;
547 AR_DEBUG_PRINTF(ATH_DEBUG_SEND
,("+DevGMboxReadCreditCounter (%s) \n", AsyncMode
? "ASYNC" : "SYNC"));
551 pIOPacket
= AR6KAllocIOPacket(pDev
);
553 if (NULL
== pIOPacket
) {
554 status
= A_NO_MEMORY
;
559 A_MEMZERO(pIOPacket
->pBuffer
,AR6K_REG_IO_BUFFER_SIZE
);
562 /* stick in our completion routine when the I/O operation completes */
563 pIOPacket
->Completion
= DevGMboxReadCreditsAsyncHandler
;
564 pIOPacket
->pContext
= pDev
;
565 /* read registers asynchronously */
566 HIFReadWrite(pDev
->HIFDevice
,
567 AR6K_GMBOX_CREDIT_DEC_ADDRESS
,
569 AR6K_REG_IO_BUFFER_SIZE
, /* hit the register multiple times */
570 HIF_RD_ASYNC_BYTE_FIX
,
576 pIOPacket
->Completion
= NULL
;
577 /* if we get here we are doing it synchronously */
578 status
= HIFReadWrite(pDev
->HIFDevice
,
579 AR6K_GMBOX_CREDIT_DEC_ADDRESS
,
581 AR6K_REG_IO_BUFFER_SIZE
,
582 HIF_RD_SYNC_BYTE_FIX
,
586 if (A_FAILED(status
)) {
587 AR_DEBUG_PRINTF(ATH_DEBUG_ERR
,
588 (" DevGMboxReadCreditCounter failed! status:%d \n", status
));
591 if (pIOPacket
!= NULL
) {
592 if (A_SUCCESS(status
)) {
593 /* sync mode processing */
594 *pCredits
= ProcessCreditCounterReadBuffer(pIOPacket
->pBuffer
, AR6K_REG_IO_BUFFER_SIZE
);
596 AR6KFreeIOPacket(pDev
,pIOPacket
);
599 AR_DEBUG_PRINTF(ATH_DEBUG_SEND
,("-DevGMboxReadCreditCounter (%s) (%d) \n",
600 AsyncMode
? "ASYNC" : "SYNC", status
));
605 int DevGMboxReadCreditSize(AR6K_DEVICE
*pDev
, int *pCreditSize
)
610 status
= HIFReadWrite(pDev
->HIFDevice
,
611 AR6K_GMBOX_CREDIT_SIZE_ADDRESS
,
614 HIF_RD_SYNC_BYTE_FIX
, /* hit the register 4 times to align the I/O */
617 if (A_SUCCESS(status
)) {
618 if (buffer
[0] == 0) {
621 *pCreditSize
= buffer
[0];
629 void DevNotifyGMboxTargetFailure(AR6K_DEVICE
*pDev
)
631 /* Target ASSERTED!!! */
632 if (pDev
->GMboxInfo
.pTargetFailureCallback
!= NULL
) {
633 pDev
->GMboxInfo
.pTargetFailureCallback(pDev
->GMboxInfo
.pProtocolContext
, A_HARDWARE
);
637 int DevGMboxRecvLookAheadPeek(AR6K_DEVICE
*pDev
, A_UINT8
*pLookAheadBuffer
, int *pLookAheadBytes
)
641 AR6K_IRQ_PROC_REGISTERS procRegs
;
645 /* on entry the caller provides the length of the lookahead buffer */
646 if (*pLookAheadBytes
> sizeof(procRegs
.rx_gmbox_lookahead_alias
)) {
652 maxCopy
= *pLookAheadBytes
;
653 *pLookAheadBytes
= 0;
654 /* load the register table from the device */
655 status
= HIFReadWrite(pDev
->HIFDevice
,
656 HOST_INT_STATUS_ADDRESS
,
657 (A_UINT8
*)&procRegs
,
658 AR6K_IRQ_PROC_REGS_SIZE
,
659 HIF_RD_SYNC_BYTE_INC
,
662 if (A_FAILED(status
)) {
663 AR_DEBUG_PRINTF(ATH_DEBUG_ERR
,
664 ("DevGMboxRecvLookAheadPeek : Failed to read register table (%d) \n",status
));
668 if (procRegs
.gmbox_rx_avail
> 0) {
669 int bytes
= procRegs
.gmbox_rx_avail
> maxCopy
? maxCopy
: procRegs
.gmbox_rx_avail
;
670 A_MEMCPY(pLookAheadBuffer
,&procRegs
.rx_gmbox_lookahead_alias
[0],bytes
);
671 *pLookAheadBytes
= bytes
;
679 int DevGMboxSetTargetInterrupt(AR6K_DEVICE
*pDev
, int Signal
, int AckTimeoutMS
)
685 A_MEMZERO(buffer
, sizeof(buffer
));
689 if (Signal
>= MBOX_SIG_HCI_BRIDGE_MAX
) {
694 /* set the last buffer to do the actual signal trigger */
695 buffer
[3] = (1 << Signal
);
697 status
= HIFReadWrite(pDev
->HIFDevice
,
701 HIF_WR_SYNC_BYTE_FIX
, /* hit the register 4 times to align the I/O */
704 if (A_FAILED(status
)) {
711 if (A_SUCCESS(status
)) {
712 /* now read back the register to see if the bit cleared */
713 while (AckTimeoutMS
) {
714 status
= HIFReadWrite(pDev
->HIFDevice
,
718 HIF_RD_SYNC_BYTE_FIX
,
721 if (A_FAILED(status
)) {
725 for (i
= 0; i
< sizeof(buffer
); i
++) {
726 if (buffer
[i
] & (1 << Signal
)) {
727 /* bit is still set */
732 if (i
>= sizeof(buffer
)) {
741 if (0 == AckTimeoutMS
) {
742 AR_DEBUG_PRINTF(ATH_DEBUG_ERR
,
743 ("DevGMboxSetTargetInterrupt : Ack Timed-out (sig:%d) \n",Signal
));
752 #endif //ATH_AR6K_ENABLE_GMBOX