Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(138)

Side by Side Diff: chromeos/drivers/ath6kl/htc2/AR6000/ar6k_gmbox.c

Issue 646055: Atheros AR600x driver + build glue (Closed)
Patch Set: Created 10 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 //------------------------------------------------------------------------------
2 // <copyright file="ar6k_gmbox.c" company="Atheros">
3 // Copyright (c) 2007-2008 Atheros Corporation. All rights reserved.
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License version 2 as
7 // published by the Free Software Foundation;
8 //
9 // Software distributed under the License is distributed on an "AS
10 // IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
11 // implied. See the License for the specific language governing
12 // rights and limitations under the License.
13 //
14 //
15 //------------------------------------------------------------------------------
16 //==============================================================================
17 // Generic MBOX API implementation
18 //
19 // Author(s): ="Atheros"
20 //==============================================================================
21 #include "a_config.h"
22 #include "athdefs.h"
23 #include "a_types.h"
24 #include "a_osapi.h"
25 #include "../htc_debug.h"
26 #include "hif.h"
27 #include "htc_packet.h"
28 #include "ar6k.h"
29 #include "hw/mbox_host_reg.h"
30 #include "gmboxif.h"
31
32 /*
33 * This file provides management functions and a toolbox for GMBOX protocol modu les.
34 * Only one protocol module can be installed at a time. The determination of whi ch protocol
35 * module is installed is determined at compile time.
36 *
37 */
38 #ifdef ATH_AR6K_ENABLE_GMBOX
39 /* GMBOX definitions */
40 #define GMBOX_INT_STATUS_ENABLE_REG 0x488
41 #define GMBOX_INT_STATUS_RX_DATA (1 << 0)
42 #define GMBOX_INT_STATUS_TX_OVERFLOW (1 << 1)
43 #define GMBOX_INT_STATUS_RX_OVERFLOW (1 << 2)
44
45 #define GMBOX_LOOKAHEAD_MUX_REG 0x498
46 #define GMBOX_LA_MUX_OVERRIDE_2_3 (1 << 0)
47
48 #define AR6K_GMBOX_CREDIT_DEC_ADDRESS (COUNT_DEC_ADDRESS + 4 * AR6K_GMBOX_CRED IT_COUNTER)
49 #define AR6K_GMBOX_CREDIT_SIZE_ADDRESS (COUNT_ADDRESS + AR6K_GMBOX_CREDIT_S IZE_COUNTER)
50
51
52 /* external APIs for allocating and freeing internal I/O packets to handle A SYNC I/O */
53 extern void AR6KFreeIOPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket);
54 extern HTC_PACKET *AR6KAllocIOPacket(AR6K_DEVICE *pDev);
55
56
57 /* callback when our fetch to enable/disable completes */
58 static void DevGMboxIRQActionAsyncHandler(void *Context, HTC_PACKET *pPacket)
59 {
60 AR6K_DEVICE *pDev = (AR6K_DEVICE *)Context;
61
62 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevGMboxIRQActionAsyncHandler: (dev: 0x%X)\ n", (A_UINT32)pDev));
63
64 if (A_FAILED(pPacket->Status)) {
65 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
66 ("IRQAction Operation (%d) failed! status:%d \n", pPacket->PktIn fo.AsRx.HTCRxFlags,pPacket->Status));
67 }
68 /* free this IO packet */
69 AR6KFreeIOPacket(pDev,pPacket);
70 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevGMboxIRQActionAsyncHandler \n"));
71 }
72
73 static A_STATUS DevGMboxCounterEnableDisable(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION _TYPE IrqAction, A_BOOL AsyncMode)
74 {
75 A_STATUS status = A_OK;
76 AR6K_IRQ_ENABLE_REGISTERS regs;
77 HTC_PACKET *pIOPacket = NULL;
78
79 LOCK_AR6K(pDev);
80
81 if (GMBOX_CREDIT_IRQ_ENABLE == IrqAction) {
82 pDev->GMboxInfo.CreditCountIRQEnabled = TRUE;
83 pDev->IrqEnableRegisters.counter_int_status_enable |=
84 COUNTER_INT_STATUS_ENABLE_BIT_SET(1 << AR6K_GMBOX_CREDIT_COUNTER);
85 pDev->IrqEnableRegisters.int_status_enable |= INT_STATUS_ENABLE_COUNTER_ SET(0x01);
86 } else {
87 pDev->GMboxInfo.CreditCountIRQEnabled = FALSE;
88 pDev->IrqEnableRegisters.counter_int_status_enable &=
89 ~(COUNTER_INT_STATUS_ENABLE_BIT_SET(1 << AR6K_GMBOX_CREDIT_COUNTER)) ;
90 }
91 /* copy into our temp area */
92 A_MEMCPY(&regs,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE);
93
94 UNLOCK_AR6K(pDev);
95
96 do {
97
98 if (AsyncMode) {
99
100 pIOPacket = AR6KAllocIOPacket(pDev);
101
102 if (NULL == pIOPacket) {
103 status = A_NO_MEMORY;
104 A_ASSERT(FALSE);
105 break;
106 }
107
108 /* copy values to write to our async I/O buffer */
109 A_MEMCPY(pIOPacket->pBuffer,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABL E_REGS_SIZE);
110
111 /* stick in our completion routine when the I/O operation comple tes */
112 pIOPacket->Completion = DevGMboxIRQActionAsyncHandler;
113 pIOPacket->pContext = pDev;
114 pIOPacket->PktInfo.AsRx.HTCRxFlags = IrqAction;
115 /* write it out asynchronously */
116 HIFReadWrite(pDev->HIFDevice,
117 INT_STATUS_ENABLE_ADDRESS,
118 pIOPacket->pBuffer,
119 AR6K_IRQ_ENABLE_REGS_SIZE,
120 HIF_WR_ASYNC_BYTE_INC,
121 pIOPacket);
122
123 pIOPacket = NULL;
124 break;
125 }
126
127 /* if we get here we are doing it synchronously */
128 status = HIFReadWrite(pDev->HIFDevice,
129 INT_STATUS_ENABLE_ADDRESS,
130 &regs.int_status_enable,
131 AR6K_IRQ_ENABLE_REGS_SIZE,
132 HIF_WR_SYNC_BYTE_INC,
133 NULL);
134 } while (FALSE);
135
136 if (A_FAILED(status)) {
137 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
138 (" IRQAction Operation (%d) failed! status:%d \n", IrqAction, st atus));
139 } else {
140 if (!AsyncMode) {
141 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
142 (" IRQAction Operation (%d) success \n", IrqAction));
143 }
144 }
145
146 if (pIOPacket != NULL) {
147 AR6KFreeIOPacket(pDev,pIOPacket);
148 }
149
150 return status;
151 }
152
153
154 A_STATUS DevGMboxIRQAction(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION_TYPE IrqAction, A _BOOL AsyncMode)
155 {
156 A_STATUS status = A_OK;
157 HTC_PACKET *pIOPacket = NULL;
158 A_UINT8 GMboxIntControl[4];
159
160 if (GMBOX_CREDIT_IRQ_ENABLE == IrqAction) {
161 return DevGMboxCounterEnableDisable(pDev, GMBOX_CREDIT_IRQ_ENABLE, Async Mode);
162 } else if(GMBOX_CREDIT_IRQ_DISABLE == IrqAction) {
163 return DevGMboxCounterEnableDisable(pDev, GMBOX_CREDIT_IRQ_DISABLE, Asyn cMode);
164 }
165
166 if (GMBOX_DISABLE_ALL == IrqAction) {
167 /* disable credit IRQ, those are on a different set of registers */
168 DevGMboxCounterEnableDisable(pDev, GMBOX_CREDIT_IRQ_DISABLE, AsyncMode);
169 }
170
171 /* take the lock to protect interrupt enable shadows */
172 LOCK_AR6K(pDev);
173
174 switch (IrqAction) {
175
176 case GMBOX_DISABLE_ALL:
177 pDev->GMboxControlRegisters.int_status_enable = 0;
178 break;
179 case GMBOX_ERRORS_IRQ_ENABLE:
180 pDev->GMboxControlRegisters.int_status_enable |= GMBOX_INT_STATUS_TX _OVERFLOW |
181 GMBOX_INT_STATUS_RX _OVERFLOW;
182 break;
183 case GMBOX_RECV_IRQ_ENABLE:
184 pDev->GMboxControlRegisters.int_status_enable |= GMBOX_INT_STATUS_RX _DATA;
185 break;
186 case GMBOX_RECV_IRQ_DISABLE:
187 pDev->GMboxControlRegisters.int_status_enable &= ~GMBOX_INT_STATUS_R X_DATA;
188 break;
189 case GMBOX_ACTION_NONE:
190 default:
191 A_ASSERT(FALSE);
192 break;
193 }
194
195 GMboxIntControl[0] = pDev->GMboxControlRegisters.int_status_enable;
196 GMboxIntControl[1] = GMboxIntControl[0];
197 GMboxIntControl[2] = GMboxIntControl[0];
198 GMboxIntControl[3] = GMboxIntControl[0];
199
200 UNLOCK_AR6K(pDev);
201
202 do {
203
204 if (AsyncMode) {
205
206 pIOPacket = AR6KAllocIOPacket(pDev);
207
208 if (NULL == pIOPacket) {
209 status = A_NO_MEMORY;
210 A_ASSERT(FALSE);
211 break;
212 }
213
214 /* copy values to write to our async I/O buffer */
215 A_MEMCPY(pIOPacket->pBuffer,GMboxIntControl,sizeof(GMboxIntControl)) ;
216
217 /* stick in our completion routine when the I/O operation comple tes */
218 pIOPacket->Completion = DevGMboxIRQActionAsyncHandler;
219 pIOPacket->pContext = pDev;
220 pIOPacket->PktInfo.AsRx.HTCRxFlags = IrqAction;
221 /* write it out asynchronously */
222 HIFReadWrite(pDev->HIFDevice,
223 GMBOX_INT_STATUS_ENABLE_REG,
224 pIOPacket->pBuffer,
225 sizeof(GMboxIntControl),
226 HIF_WR_ASYNC_BYTE_FIX,
227 pIOPacket);
228 pIOPacket = NULL;
229 break;
230 }
231
232 /* if we get here we are doing it synchronously */
233
234 status = HIFReadWrite(pDev->HIFDevice,
235 GMBOX_INT_STATUS_ENABLE_REG,
236 GMboxIntControl,
237 sizeof(GMboxIntControl),
238 HIF_WR_SYNC_BYTE_FIX,
239 NULL);
240
241 } while (FALSE);
242
243 if (A_FAILED(status)) {
244 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
245 (" IRQAction Operation (%d) failed! status:%d \n", IrqAction, st atus));
246 } else {
247 if (!AsyncMode) {
248 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,
249 (" IRQAction Operation (%d) success \n", IrqAction));
250 }
251 }
252
253 if (pIOPacket != NULL) {
254 AR6KFreeIOPacket(pDev,pIOPacket);
255 }
256
257 return status;
258 }
259
260 void DevCleanupGMbox(AR6K_DEVICE *pDev)
261 {
262 if (pDev->GMboxEnabled) {
263 pDev->GMboxEnabled = FALSE;
264 GMboxProtocolUninstall(pDev);
265 }
266 }
267
268 A_STATUS DevSetupGMbox(AR6K_DEVICE *pDev)
269 {
270 A_STATUS status = A_OK;
271 A_UINT8 muxControl[4];
272
273 do {
274
275 if (0 == pDev->MailBoxInfo.GMboxAddress) {
276 break;
277 }
278
279 AR_DEBUG_PRINTF(ATH_DEBUG_ANY,(" GMBOX Advertised: Address:0x%X , size:% d \n",
280 pDev->MailBoxInfo.GMboxAddress, pDev->MailBoxInfo.GMboxSize) );
281
282 status = DevGMboxIRQAction(pDev, GMBOX_DISABLE_ALL, PROC_IO_SYNC);
283
284 if (A_FAILED(status)) {
285 break;
286 }
287
288 /* write to mailbox look ahead mux control register, we want the
289 * GMBOX lookaheads to appear on lookaheads 2 and 3
290 * the register is 1-byte wide so we need to hit it 4 times to align the operation
291 * to 4-bytes */
292 muxControl[0] = GMBOX_LA_MUX_OVERRIDE_2_3;
293 muxControl[1] = GMBOX_LA_MUX_OVERRIDE_2_3;
294 muxControl[2] = GMBOX_LA_MUX_OVERRIDE_2_3;
295 muxControl[3] = GMBOX_LA_MUX_OVERRIDE_2_3;
296
297 status = HIFReadWrite(pDev->HIFDevice,
298 GMBOX_LOOKAHEAD_MUX_REG,
299 muxControl,
300 sizeof(muxControl),
301 HIF_WR_SYNC_BYTE_FIX, /* hit this register 4 time s */
302 NULL);
303
304 if (A_FAILED(status)) {
305 break;
306 }
307
308 status = GMboxProtocolInstall(pDev);
309
310 if (A_FAILED(status)) {
311 break;
312 }
313
314 pDev->GMboxEnabled = TRUE;
315
316 } while (FALSE);
317
318 return status;
319 }
320
321 A_STATUS DevCheckGMboxInterrupts(AR6K_DEVICE *pDev)
322 {
323 A_STATUS status = A_OK;
324 A_UINT8 counter_int_status;
325 int credits;
326 A_UINT8 host_int_status2;
327
328 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("+DevCheckGMboxInterrupts \n"));
329
330 /* the caller guarantees that this is a context that allows for blocking I/O */
331
332 do {
333
334 host_int_status2 = pDev->IrqProcRegisters.host_int_status2 &
335 pDev->GMboxControlRegisters.int_status_enable;
336
337 if (host_int_status2 & GMBOX_INT_STATUS_TX_OVERFLOW) {
338 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("GMBOX : TX Overflow \n"));
339 status = A_ECOMM;
340 }
341
342 if (host_int_status2 & GMBOX_INT_STATUS_RX_OVERFLOW) {
343 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("GMBOX : RX Overflow \n"));
344 status = A_ECOMM;
345 }
346
347 if (A_FAILED(status)) {
348 if (pDev->GMboxInfo.pTargetFailureCallback != NULL) {
349 pDev->GMboxInfo.pTargetFailureCallback(pDev->GMboxInfo.pProtocol Context, status);
350 }
351 break;
352 }
353
354 if (host_int_status2 & GMBOX_INT_STATUS_RX_DATA) {
355 if (pDev->IrqProcRegisters.gmbox_rx_avail > 0) {
356 A_ASSERT(pDev->GMboxInfo.pMessagePendingCallBack != NULL);
357 status = pDev->GMboxInfo.pMessagePendingCallBack(
358 pDev->GMboxInfo.pProtocolContext,
359 (A_UINT8 *)&pDev->IrqProcRegisters.rx_gmbox_look ahead_alias[0],
360 pDev->IrqProcRegisters.gmbox_rx_avail);
361 }
362 }
363
364 if (A_FAILED(status)) {
365 break;
366 }
367
368 counter_int_status = pDev->IrqProcRegisters.counter_int_status &
369 pDev->IrqEnableRegisters.counter_int_status_enable;
370
371 /* check if credit interrupt is pending */
372 if (counter_int_status & (COUNTER_INT_STATUS_ENABLE_BIT_SET(1 << AR6K_GM BOX_CREDIT_COUNTER))) {
373
374 /* do synchronous read */
375 status = DevGMboxReadCreditCounter(pDev, PROC_IO_SYNC, &credits);
376
377 if (A_FAILED(status)) {
378 break;
379 }
380
381 A_ASSERT(pDev->GMboxInfo.pCreditsPendingCallback != NULL);
382 status = pDev->GMboxInfo.pCreditsPendingCallback(pDev->GMboxInfo.pPr otocolContext,
383 credits,
384 pDev->GMboxInfo.Cre ditCountIRQEnabled);
385 }
386
387 } while (FALSE);
388
389 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("-DevCheckGMboxInterrupts (%d) \n",status));
390
391 return status;
392 }
393
394
395 A_STATUS DevGMboxWrite(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 WriteLen gth)
396 {
397 A_UINT32 paddedLength;
398 A_BOOL sync = (pPacket->Completion == NULL) ? TRUE : FALSE;
399 A_STATUS status;
400 A_UINT32 address;
401
402 /* adjust the length to be a multiple of block size if appropriate */
403 paddedLength = DEV_CALC_SEND_PADDED_LEN(pDev, WriteLength);
404
405 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,
406 ("DevGMboxWrite, Padded Length: %d Mbox:0x%X (mode:%s)\n",
407 WriteLength,
408 pDev->MailBoxInfo.GMboxAddress,
409 sync ? "SYNC" : "ASYNC"));
410
411 /* last byte of packet has to hit the EOM marker */
412 address = pDev->MailBoxInfo.GMboxAddress + pDev->MailBoxInfo.GMboxSize - pad dedLength;
413
414 status = HIFReadWrite(pDev->HIFDevice,
415 address,
416 pPacket->pBuffer,
417 paddedLength, /* the padded length */
418 sync ? HIF_WR_SYNC_BLOCK_INC : HIF_WR_ASYNC_BLOCK_INC,
419 sync ? NULL : pPacket); /* pass the packet as the con text to the HIF request */
420
421 if (sync) {
422 pPacket->Status = status;
423 } else {
424 if (status == A_PENDING) {
425 status = A_OK;
426 }
427 }
428
429 return status;
430 }
431
432 A_STATUS DevGMboxRead(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 ReadLengt h)
433 {
434
435 A_UINT32 paddedLength;
436 A_STATUS status;
437 A_BOOL sync = (pPacket->Completion == NULL) ? TRUE : FALSE;
438
439 /* adjust the length to be a multiple of block size if appropriate */
440 paddedLength = DEV_CALC_RECV_PADDED_LEN(pDev, ReadLength);
441
442 if (paddedLength > pPacket->BufferLength) {
443 A_ASSERT(FALSE);
444 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
445 ("DevGMboxRead, Not enough space for padlen:%d recvlen:%d buffer len:%d \n",
446 paddedLength,ReadLength,pPacket->BufferLength));
447 if (pPacket->Completion != NULL) {
448 COMPLETE_HTC_PACKET(pPacket,A_EINVAL);
449 return A_OK;
450 }
451 return A_EINVAL;
452 }
453
454 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,
455 ("DevGMboxRead (0x%X : hdr:0x%X) Padded Length: %d Mbox:0x%X (mo de:%s)\n",
456 (A_UINT32)pPacket, pPacket->PktInfo.AsRx.ExpectedHdr,
457 paddedLength,
458 pDev->MailBoxInfo.GMboxAddress,
459 sync ? "SYNC" : "ASYNC"));
460
461 status = HIFReadWrite(pDev->HIFDevice,
462 pDev->MailBoxInfo.GMboxAddress,
463 pPacket->pBuffer,
464 paddedLength,
465 sync ? HIF_RD_SYNC_BLOCK_FIX : HIF_RD_ASYNC_BLOCK_FIX,
466 sync ? NULL : pPacket); /* pass the packet as the con text to the HIF request */
467
468 if (sync) {
469 pPacket->Status = status;
470 }
471
472 return status;
473 }
474
475
476 static int ProcessCreditCounterReadBuffer(A_UINT8 *pBuffer, int Length)
477 {
478 int credits = 0;
479
480 /* theory of how this works:
481 * We read the credit decrement register multiple times on a byte-wide basis .
482 * The number of times (32) aligns the I/O operation to be a multiple of 4 b ytes and provides a
483 * reasonable chance to acquire "all" pending credits in a single I/O operat ion.
484 *
485 * Once we obtain the filled buffer, we can walk through it looking for cred it decrement transitions.
486 * Each non-zero byte represents a single credit decrement (which is a credi t given back to the host)
487 * For example if the target provides 3 credits and added 4 more during the 32-byte read operation the following
488 * pattern "could" appear:
489 *
490 * 0x3 0x2 0x1 0x0 0x0 0x0 0x0 0x0 0x1 0x0 0x1 0x0 0x1 0x0 0x1 0x0 ...... rest zeros
491 * <---------> <----------------------------->
492 * \_ credits aleady there \_ target adding 4 more cred its
493 *
494 * The total available credits would be 7, since there are 7 non-zero byt es in the buffer.
495 *
496 * */
497
498 if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) {
499 DebugDumpBytes(pBuffer, Length, "GMBOX Credit read buffer");
500 }
501
502 while (Length) {
503 if (*pBuffer != 0) {
504 credits++;
505 }
506 Length--;
507 pBuffer++;
508 }
509
510 return credits;
511 }
512
513
514 /* callback when our fetch to enable/disable completes */
515 static void DevGMboxReadCreditsAsyncHandler(void *Context, HTC_PACKET *pPacket)
516 {
517 AR6K_DEVICE *pDev = (AR6K_DEVICE *)Context;
518
519 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevGMboxReadCreditsAsyncHandler: (dev: 0x%X )\n", (A_UINT32)pDev));
520
521 if (A_FAILED(pPacket->Status)) {
522 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
523 ("Read Credit Operation failed! status:%d \n", pPacket->Status)) ;
524 } else {
525 int credits = 0;
526 credits = ProcessCreditCounterReadBuffer(pPacket->pBuffer, AR6K_REG_IO_B UFFER_SIZE);
527 pDev->GMboxInfo.pCreditsPendingCallback(pDev->GMboxInfo.pProtocolContext ,
528 credits,
529 pDev->GMboxInfo.CreditCountIRQEn abled);
530
531
532 }
533 /* free this IO packet */
534 AR6KFreeIOPacket(pDev,pPacket);
535 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevGMboxReadCreditsAsyncHandler \n"));
536 }
537
538 A_STATUS DevGMboxReadCreditCounter(AR6K_DEVICE *pDev, A_BOOL AsyncMode, int *pCr edits)
539 {
540 A_STATUS status = A_OK;
541 HTC_PACKET *pIOPacket = NULL;
542
543 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+DevGMboxReadCreditCounter (%s) \n", AsyncM ode ? "ASYNC" : "SYNC"));
544
545 do {
546
547 pIOPacket = AR6KAllocIOPacket(pDev);
548
549 if (NULL == pIOPacket) {
550 status = A_NO_MEMORY;
551 A_ASSERT(FALSE);
552 break;
553 }
554
555 A_MEMZERO(pIOPacket->pBuffer,AR6K_REG_IO_BUFFER_SIZE);
556
557 if (AsyncMode) {
558 /* stick in our completion routine when the I/O operation comple tes */
559 pIOPacket->Completion = DevGMboxReadCreditsAsyncHandler;
560 pIOPacket->pContext = pDev;
561 /* read registers asynchronously */
562 HIFReadWrite(pDev->HIFDevice,
563 AR6K_GMBOX_CREDIT_DEC_ADDRESS,
564 pIOPacket->pBuffer,
565 AR6K_REG_IO_BUFFER_SIZE, /* hit the register multiple times */
566 HIF_RD_ASYNC_BYTE_FIX,
567 pIOPacket);
568 pIOPacket = NULL;
569 break;
570 }
571
572 pIOPacket->Completion = NULL;
573 /* if we get here we are doing it synchronously */
574 status = HIFReadWrite(pDev->HIFDevice,
575 AR6K_GMBOX_CREDIT_DEC_ADDRESS,
576 pIOPacket->pBuffer,
577 AR6K_REG_IO_BUFFER_SIZE,
578 HIF_RD_SYNC_BYTE_FIX,
579 NULL);
580 } while (FALSE);
581
582 if (A_FAILED(status)) {
583 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
584 (" DevGMboxReadCreditCounter failed! status:%d \n", status));
585 }
586
587 if (pIOPacket != NULL) {
588 if (A_SUCCESS(status)) {
589 /* sync mode processing */
590 *pCredits = ProcessCreditCounterReadBuffer(pIOPacket->pBuffer, AR6K_ REG_IO_BUFFER_SIZE);
591 }
592 AR6KFreeIOPacket(pDev,pIOPacket);
593 }
594
595 AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-DevGMboxReadCreditCounter (%s) (%d) \n",
596 AsyncMode ? "ASYNC" : "SYNC", status));
597
598 return status;
599 }
600
601 A_STATUS DevGMboxReadCreditSize(AR6K_DEVICE *pDev, int *pCreditSize)
602 {
603 A_STATUS status;
604 A_UINT8 buffer[4];
605
606 status = HIFReadWrite(pDev->HIFDevice,
607 AR6K_GMBOX_CREDIT_SIZE_ADDRESS,
608 buffer,
609 sizeof(buffer),
610 HIF_RD_SYNC_BYTE_FIX, /* hit the register 4 times to a lign the I/O */
611 NULL);
612
613 if (A_SUCCESS(status)) {
614 if (buffer[0] == 0) {
615 *pCreditSize = 256;
616 } else {
617 *pCreditSize = buffer[0];
618 }
619
620 }
621
622 return status;
623 }
624
625 void DevNotifyGMboxTargetFailure(AR6K_DEVICE *pDev)
626 {
627 /* Target ASSERTED!!! */
628 if (pDev->GMboxInfo.pTargetFailureCallback != NULL) {
629 pDev->GMboxInfo.pTargetFailureCallback(pDev->GMboxInfo.pProtocolContext, A_HARDWARE);
630 }
631 }
632
633 A_STATUS DevGMboxRecvLookAheadPeek(AR6K_DEVICE *pDev, A_UINT8 *pLookAheadBuffer, int *pLookAheadBytes)
634 {
635
636 A_STATUS status = A_OK;
637 AR6K_IRQ_PROC_REGISTERS procRegs;
638 int maxCopy;
639
640 do {
641 /* on entry the caller provides the length of the lookahead buffer * /
642 if (*pLookAheadBytes > sizeof(procRegs.rx_gmbox_lookahead_alias)) {
643 A_ASSERT(FALSE);
644 status = A_EINVAL;
645 break;
646 }
647
648 maxCopy = *pLookAheadBytes;
649 *pLookAheadBytes = 0;
650 /* load the register table from the device */
651 status = HIFReadWrite(pDev->HIFDevice,
652 HOST_INT_STATUS_ADDRESS,
653 (A_UINT8 *)&procRegs,
654 AR6K_IRQ_PROC_REGS_SIZE,
655 HIF_RD_SYNC_BYTE_INC,
656 NULL);
657
658 if (A_FAILED(status)) {
659 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
660 ("DevGMboxRecvLookAheadPeek : Failed to read register table (%d) \n",status));
661 break;
662 }
663
664 if (procRegs.gmbox_rx_avail > 0) {
665 int bytes = procRegs.gmbox_rx_avail > maxCopy ? maxCopy : procRegs.g mbox_rx_avail;
666 A_MEMCPY(pLookAheadBuffer,&procRegs.rx_gmbox_lookahead_alias[0],byte s);
667 *pLookAheadBytes = bytes;
668 }
669
670 } while (FALSE);
671
672 return status;
673 }
674
675 A_STATUS DevGMboxSetTargetInterrupt(AR6K_DEVICE *pDev, int Signal, int AckTimeou tMS)
676 {
677 A_STATUS status = A_OK;
678 int i;
679 A_UINT8 buffer[4];
680
681 A_MEMZERO(buffer, sizeof(buffer));
682
683 do {
684
685 if (Signal >= MBOX_SIG_HCI_BRIDGE_MAX) {
686 status = A_EINVAL;
687 break;
688 }
689
690 /* set the last buffer to do the actual signal trigger */
691 buffer[3] = (1 << Signal);
692
693 status = HIFReadWrite(pDev->HIFDevice,
694 INT_WLAN_ADDRESS,
695 buffer,
696 sizeof(buffer),
697 HIF_WR_SYNC_BYTE_FIX, /* hit the register 4 times to align the I/O */
698 NULL);
699
700 if (A_FAILED(status)) {
701 break;
702 }
703
704 } while (FALSE);
705
706
707 if (A_SUCCESS(status)) {
708 /* now read back the register to see if the bit cleared */
709 while (AckTimeoutMS) {
710 status = HIFReadWrite(pDev->HIFDevice,
711 INT_WLAN_ADDRESS,
712 buffer,
713 sizeof(buffer),
714 HIF_RD_SYNC_BYTE_FIX,
715 NULL);
716
717 if (A_FAILED(status)) {
718 break;
719 }
720
721 for (i = 0; i < sizeof(buffer); i++) {
722 if (buffer[i] & (1 << Signal)) {
723 /* bit is still set */
724 break;
725 }
726 }
727
728 if (i >= sizeof(buffer)) {
729 /* done */
730 break;
731 }
732
733 AckTimeoutMS--;
734 A_MDELAY(1);
735 }
736
737 if (0 == AckTimeoutMS) {
738 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
739 ("DevGMboxSetTargetInterrupt : Ack Timed-out (sig:%d) \n",Signal ));
740 status = A_ERROR;
741 }
742 }
743
744 return status;
745
746 }
747
748 #endif //ATH_AR6K_ENABLE_GMBOX
749
750
751
752
OLDNEW
« no previous file with comments | « chromeos/drivers/ath6kl/htc2/AR6000/ar6k_events.c ('k') | chromeos/drivers/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698