OLD | NEW |
1 //------------------------------------------------------------------------------ | 1 //------------------------------------------------------------------------------ |
2 // <copyright file="ar6k_events.c" company="Atheros"> | 2 // <copyright file="ar6k_events.c" company="Atheros"> |
3 // Copyright (c) 2007-2008 Atheros Corporation. All rights reserved. | 3 // Copyright (c) 2007-2010 Atheros Corporation. All rights reserved. |
4 // | 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 // | 5 // |
9 // Software distributed under the License is distributed on an "AS | 6 // Permission to use, copy, modify, and/or distribute this software for any |
10 // IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or | 7 // purpose with or without fee is hereby granted, provided that the above |
11 // implied. See the License for the specific language governing | 8 // copyright notice and this permission notice appear in all copies. |
12 // rights and limitations under the License. | 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. |
13 // | 17 // |
14 // | 18 // |
15 //------------------------------------------------------------------------------ | 19 //------------------------------------------------------------------------------ |
16 //============================================================================== | 20 //============================================================================== |
17 // AR6K Driver layer event handling (i.e. interrupts, message polling) | 21 // AR6K Driver layer event handling (i.e. interrupts, message polling) |
18 // | 22 // |
19 // Author(s): ="Atheros" | 23 // Author(s): ="Atheros" |
20 //============================================================================== | 24 //============================================================================== |
21 | 25 |
22 #include "a_config.h" | 26 #include "a_config.h" |
(...skipping 12 matching lines...) Expand all Loading... |
35 static A_STATUS DevServiceDebugInterrupt(AR6K_DEVICE *pDev); | 39 static A_STATUS DevServiceDebugInterrupt(AR6K_DEVICE *pDev); |
36 | 40 |
37 #define DELAY_PER_INTERVAL_MS 10 /* 10 MS delay per polling interval */ | 41 #define DELAY_PER_INTERVAL_MS 10 /* 10 MS delay per polling interval */ |
38 | 42 |
39 /* completion routine for ALL HIF layer async I/O */ | 43 /* completion routine for ALL HIF layer async I/O */ |
40 A_STATUS DevRWCompletionHandler(void *context, A_STATUS status) | 44 A_STATUS DevRWCompletionHandler(void *context, A_STATUS status) |
41 { | 45 { |
42 HTC_PACKET *pPacket = (HTC_PACKET *)context; | 46 HTC_PACKET *pPacket = (HTC_PACKET *)context; |
43 | 47 |
44 AR_DEBUG_PRINTF(ATH_DEBUG_RECV, | 48 AR_DEBUG_PRINTF(ATH_DEBUG_RECV, |
45 ("+DevRWCompletionHandler (Pkt:0x%X) , Status: %d \n", | 49 ("+DevRWCompletionHandler (Pkt:0x%lX) , Status: %d \n", |
46 (A_UINT32)pPacket, | 50 (unsigned long)pPacket, |
47 status)); | 51 status)); |
48 | 52 |
49 COMPLETE_HTC_PACKET(pPacket,status); | 53 COMPLETE_HTC_PACKET(pPacket,status); |
50 | 54 |
51 AR_DEBUG_PRINTF(ATH_DEBUG_RECV, | 55 AR_DEBUG_PRINTF(ATH_DEBUG_RECV, |
52 ("-DevRWCompletionHandler\n")); | 56 ("-DevRWCompletionHandler\n")); |
53 | 57 |
54 return A_OK; | 58 return A_OK; |
55 } | 59 } |
56 | 60 |
57 /* mailbox recv message polling */ | 61 /* mailbox recv message polling */ |
58 A_STATUS DevPollMboxMsgRecv(AR6K_DEVICE *pDev, | 62 A_STATUS DevPollMboxMsgRecv(AR6K_DEVICE *pDev, |
59 A_UINT32 *pLookAhead, | 63 A_UINT32 *pLookAhead, |
60 int TimeoutMS) | 64 int TimeoutMS) |
61 { | 65 { |
62 A_STATUS status = A_OK; | 66 A_STATUS status = A_OK; |
63 int timeout = TimeoutMS/DELAY_PER_INTERVAL_MS; | 67 int timeout = TimeoutMS/DELAY_PER_INTERVAL_MS; |
64 | 68 |
65 A_ASSERT(timeout > 0); | 69 A_ASSERT(timeout > 0); |
66 | 70 |
67 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+DevPollMboxMsgRecv \n")); | 71 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+DevPollMboxMsgRecv \n")); |
68 | 72 |
69 while (TRUE) { | 73 while (TRUE) { |
70 | 74 |
71 if (pDev->GetPendingEventsFunc != NULL) { | 75 if (pDev->GetPendingEventsFunc != NULL) { |
72 | 76 |
73 HIF_PENDING_EVENTS_INFO events; | 77 HIF_PENDING_EVENTS_INFO events; |
74 | 78 |
| 79 #ifdef THREAD_X |
| 80 events.Polling =1; |
| 81 #endif |
| 82 |
75 /* the HIF layer uses a special mechanism to get events, do this | 83 /* the HIF layer uses a special mechanism to get events, do this |
76 * synchronously */ | 84 * synchronously */ |
77 status = pDev->GetPendingEventsFunc(pDev->HIFDevice, | 85 status = pDev->GetPendingEventsFunc(pDev->HIFDevice, |
78 &events, | 86 &events, |
79 NULL); | 87 NULL); |
80 if (A_FAILED(status)) | 88 if (A_FAILED(status)) |
81 { | 89 { |
82 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to get pending events \n"
)); | 90 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to get pending events \n"
)); |
83 break; | 91 break; |
84 } | 92 } |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
241 { | 249 { |
242 A_UINT32 dummy; | 250 A_UINT32 dummy; |
243 A_STATUS status; | 251 A_STATUS status; |
244 | 252 |
245 /* Send a target failure event to the application */ | 253 /* Send a target failure event to the application */ |
246 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Target debug interrupt\n")); | 254 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Target debug interrupt\n")); |
247 | 255 |
248 if (pDev->TargetFailureCallback != NULL) { | 256 if (pDev->TargetFailureCallback != NULL) { |
249 pDev->TargetFailureCallback(pDev->HTCContext); | 257 pDev->TargetFailureCallback(pDev->HTCContext); |
250 } | 258 } |
251 | 259 |
252 if (pDev->GMboxEnabled) { | 260 if (pDev->GMboxEnabled) { |
253 DevNotifyGMboxTargetFailure(pDev); | 261 DevNotifyGMboxTargetFailure(pDev); |
254 } | 262 } |
255 | 263 |
256 /* clear the interrupt , the debug error interrupt is | 264 /* clear the interrupt , the debug error interrupt is |
257 * counter 0 */ | 265 * counter 0 */ |
258 /* read counter to clear interrupt */ | 266 /* read counter to clear interrupt */ |
259 status = HIFReadWrite(pDev->HIFDevice, | 267 status = HIFReadWrite(pDev->HIFDevice, |
260 COUNT_DEC_ADDRESS, | 268 COUNT_DEC_ADDRESS, |
261 (A_UINT8 *)&dummy, | 269 (A_UINT8 *)&dummy, |
(...skipping 13 matching lines...) Expand all Loading... |
275 | 283 |
276 counter_int_status = pDev->IrqProcRegisters.counter_int_status & | 284 counter_int_status = pDev->IrqProcRegisters.counter_int_status & |
277 pDev->IrqEnableRegisters.counter_int_status_enable; | 285 pDev->IrqEnableRegisters.counter_int_status_enable; |
278 | 286 |
279 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, | 287 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, |
280 ("Valid interrupt source(s) in COUNTER_INT_STATUS: 0x%x\n", | 288 ("Valid interrupt source(s) in COUNTER_INT_STATUS: 0x%x\n", |
281 counter_int_status)); | 289 counter_int_status)); |
282 | 290 |
283 /* Check if the debug interrupt is pending | 291 /* Check if the debug interrupt is pending |
284 * NOTE: other modules like GMBOX may use the counter interrupt for | 292 * NOTE: other modules like GMBOX may use the counter interrupt for |
285 * credit flow control on other counters, we only need to check for the
debug assertion | 293 * credit flow control on other counters, we only need to check for the
debug assertion |
286 * counter interrupt */ | 294 * counter interrupt */ |
287 if (counter_int_status & AR6K_TARGET_DEBUG_INTR_MASK) { | 295 if (counter_int_status & AR6K_TARGET_DEBUG_INTR_MASK) { |
288 return DevServiceDebugInterrupt(pDev); | 296 return DevServiceDebugInterrupt(pDev); |
289 } | 297 } |
290 | 298 |
291 return A_OK; | 299 return A_OK; |
292 } | 300 } |
293 | 301 |
294 /* callback when our fetch to get interrupt status registers completes */ | 302 /* callback when our fetch to get interrupt status registers completes */ |
295 static void DevGetEventAsyncHandler(void *Context, HTC_PACKET *pPacket) | 303 static void DevGetEventAsyncHandler(void *Context, HTC_PACKET *pPacket) |
296 { | 304 { |
297 AR6K_DEVICE *pDev = (AR6K_DEVICE *)Context; | 305 AR6K_DEVICE *pDev = (AR6K_DEVICE *)Context; |
298 A_UINT32 lookAhead = 0; | 306 A_UINT32 lookAhead = 0; |
299 A_BOOL otherInts = FALSE; | 307 A_BOOL otherInts = FALSE; |
300 | 308 |
301 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevGetEventAsyncHandler: (dev: 0x%X)\n", (A
_UINT32)pDev)); | 309 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevGetEventAsyncHandler: (dev: 0x%lX)\n", (
unsigned long)pDev)); |
302 | 310 |
303 do { | 311 do { |
304 | 312 |
305 if (A_FAILED(pPacket->Status)) { | 313 if (A_FAILED(pPacket->Status)) { |
306 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, | 314 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, |
307 (" GetEvents I/O request failed, status:%d \n", pPacket->Sta
tus)); | 315 (" GetEvents I/O request failed, status:%d \n", pPacket->Sta
tus)); |
308 /* bail out, don't unmask HIF interrupt */ | 316 /* bail out, don't unmask HIF interrupt */ |
309 break; | 317 break; |
310 } | 318 } |
311 | 319 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
349 /* if there are other interrupts to process, we cannot do this in th
e async handler so | 357 /* if there are other interrupts to process, we cannot do this in th
e async handler so |
350 * ack the interrupt which will cause our sync handler to run again | 358 * ack the interrupt which will cause our sync handler to run again |
351 * if however there are no more messages, we can now ack the interru
pt */ | 359 * if however there are no more messages, we can now ack the interru
pt */ |
352 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, | 360 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, |
353 (" Acking interrupt from DevGetEventAsyncHandler (otherints:%d,
lookahead:0x%X)\n", | 361 (" Acking interrupt from DevGetEventAsyncHandler (otherints:%d,
lookahead:0x%X)\n", |
354 otherInts, lookAhead)); | 362 otherInts, lookAhead)); |
355 HIFAckInterrupt(pDev->HIFDevice); | 363 HIFAckInterrupt(pDev->HIFDevice); |
356 } else { | 364 } else { |
357 int fetched = 0; | 365 int fetched = 0; |
358 A_STATUS status; | 366 A_STATUS status; |
359 | 367 |
360 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, | 368 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, |
361 (" DevGetEventAsyncHandler : detected another message, looka
head :0x%X \n", | 369 (" DevGetEventAsyncHandler : detected another message, looka
head :0x%X \n", |
362 lookAhead)); | 370 lookAhead)); |
363 /* lookahead is non-zero and there are no other interrupts to se
rvice, | 371 /* lookahead is non-zero and there are no other interrupts to se
rvice, |
364 * go get the next message */ | 372 * go get the next message */ |
365 status = pDev->MessagePendingCallback(pDev->HTCContext, &lookAhead,
1, NULL, &fetched); | 373 status = pDev->MessagePendingCallback(pDev->HTCContext, &lookAhead,
1, NULL, &fetched); |
366 | 374 |
367 if (A_SUCCESS(status) && !fetched) { | 375 if (A_SUCCESS(status) && !fetched) { |
368 /* HTC layer could not pull out messages due to lack of reso
urces, stop IRQ processing */ | 376 /* HTC layer could not pull out messages due to lack of reso
urces, stop IRQ processing */ |
369 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("MessagePendingCallback did not p
ull any messages, force-ack \n")); | 377 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("MessagePendingCallback did not p
ull any messages, force-ack \n")); |
370 DevAsyncIrqProcessComplete(pDev); | 378 DevAsyncIrqProcessComplete(pDev); |
371 } | 379 } |
372 } | 380 } |
373 | 381 |
374 } while (FALSE); | 382 } while (FALSE); |
375 | 383 |
376 /* free this IO packet */ | 384 /* free this IO packet */ |
377 AR6KFreeIOPacket(pDev,pPacket); | 385 AR6KFreeIOPacket(pDev,pPacket); |
378 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevGetEventAsyncHandler \n")); | 386 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevGetEventAsyncHandler \n")); |
379 } | 387 } |
380 | 388 |
381 /* called by the HTC layer when it wants us to check if the device has any more
pending | 389 /* called by the HTC layer when it wants us to check if the device has any more
pending |
382 * recv messages, this starts off a series of async requests to read interrupt r
egisters */ | 390 * recv messages, this starts off a series of async requests to read interrupt r
egisters */ |
383 A_STATUS DevCheckPendingRecvMsgsAsync(void *context) | 391 A_STATUS DevCheckPendingRecvMsgsAsync(void *context) |
384 { | 392 { |
385 AR6K_DEVICE *pDev = (AR6K_DEVICE *)context; | 393 AR6K_DEVICE *pDev = (AR6K_DEVICE *)context; |
386 A_STATUS status = A_OK; | 394 A_STATUS status = A_OK; |
387 HTC_PACKET *pIOPacket; | 395 HTC_PACKET *pIOPacket; |
388 | 396 |
389 /* this is called in an ASYNC only context, we may NOT block, sleep or call
any apis that can | 397 /* this is called in an ASYNC only context, we may NOT block, sleep or call
any apis that can |
390 * cause us to switch contexts */ | 398 * cause us to switch contexts */ |
391 | 399 |
392 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevCheckPendingRecvMsgsAsync: (dev: 0x%X)\n"
, (A_UINT32)pDev)); | 400 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevCheckPendingRecvMsgsAsync: (dev: 0x%lX)\n
", (unsigned long)pDev)); |
393 | 401 |
394 do { | 402 do { |
395 | 403 |
396 if (HIF_DEVICE_IRQ_SYNC_ONLY == pDev->HifIRQProcessingMode) { | 404 if (HIF_DEVICE_IRQ_SYNC_ONLY == pDev->HifIRQProcessingMode) { |
397 /* break the async processing chain right here, no need to conti
nue. | 405 /* break the async processing chain right here, no need to conti
nue. |
398 * The DevDsrHandler() will handle things in a loop when things
are driven | 406 * The DevDsrHandler() will handle things in a loop when things
are driven |
399 * synchronously */ | 407 * synchronously */ |
400 break; | 408 break; |
401 } | 409 } |
402 | 410 |
403 /* an optimization to bypass reading the IRQ status registers uneces
sarily which can re-wake | 411 /* an optimization to bypass reading the IRQ status registers uneces
sarily which can re-wake |
404 * the target, if upper layers determine that we are in a low-throug
hput mode, we can | 412 * the target, if upper layers determine that we are in a low-throug
hput mode, we can |
405 * rely on taking another interrupt rather than re-checking the stat
us registers which can | 413 * rely on taking another interrupt rather than re-checking the stat
us registers which can |
406 * re-wake the target */ | 414 * re-wake the target */ |
407 if (pDev->RecheckIRQStatusCnt == 0) { | 415 if (pDev->RecheckIRQStatusCnt == 0) { |
408 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("Bypassing IRQ Status re-check, re-ac
king HIF interrupts\n")); | 416 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("Bypassing IRQ Status re-check, re-ac
king HIF interrupts\n")); |
409 /* ack interrupt */ | 417 /* ack interrupt */ |
410 HIFAckInterrupt(pDev->HIFDevice); | 418 HIFAckInterrupt(pDev->HIFDevice); |
411 break; | 419 break; |
412 } | 420 } |
413 | 421 |
414 /* first allocate one of our HTC packets we created for async I/O | 422 /* first allocate one of our HTC packets we created for async I/O |
415 * we reuse HTC packet definitions so that we can use the completion
mechanism | 423 * we reuse HTC packet definitions so that we can use the completion
mechanism |
416 * in DevRWCompletionHandler() */ | 424 * in DevRWCompletionHandler() */ |
417 pIOPacket = AR6KAllocIOPacket(pDev); | 425 pIOPacket = AR6KAllocIOPacket(pDev); |
418 | 426 |
419 if (NULL == pIOPacket) { | 427 if (NULL == pIOPacket) { |
420 /* there should be only 1 asynchronous request out at a time to
read these registers | 428 /* there should be only 1 asynchronous request out at a time to
read these registers |
421 * so this should actually never happen */ | 429 * so this should actually never happen */ |
422 status = A_NO_MEMORY; | 430 status = A_NO_MEMORY; |
423 A_ASSERT(FALSE); | 431 A_ASSERT(FALSE); |
(...skipping 22 matching lines...) Expand all Loading... |
446 | 454 |
447 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,(" Async IO issued to get interrupt status
...\n")); | 455 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,(" Async IO issued to get interrupt status
...\n")); |
448 } while (FALSE); | 456 } while (FALSE); |
449 | 457 |
450 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevCheckPendingRecvMsgsAsync \n")); | 458 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevCheckPendingRecvMsgsAsync \n")); |
451 | 459 |
452 return status; | 460 return status; |
453 } | 461 } |
454 | 462 |
455 void DevAsyncIrqProcessComplete(AR6K_DEVICE *pDev) | 463 void DevAsyncIrqProcessComplete(AR6K_DEVICE *pDev) |
456 { | 464 { |
457 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("DevAsyncIrqProcessComplete - forcing HIF IRQ
ACK \n")); | 465 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("DevAsyncIrqProcessComplete - forcing HIF IRQ
ACK \n")); |
458 HIFAckInterrupt(pDev->HIFDevice); | 466 HIFAckInterrupt(pDev->HIFDevice); |
459 } | 467 } |
460 | 468 |
461 /* process pending interrupts synchronously */ | 469 /* process pending interrupts synchronously */ |
462 static A_STATUS ProcessPendingIRQs(AR6K_DEVICE *pDev, A_BOOL *pDone, A_BOOL *pAS
yncProcessing) | 470 static A_STATUS ProcessPendingIRQs(AR6K_DEVICE *pDev, A_BOOL *pDone, A_BOOL *pAS
yncProcessing) |
463 { | 471 { |
464 A_STATUS status = A_OK; | 472 A_STATUS status = A_OK; |
465 A_UINT8 host_int_status = 0; | 473 A_UINT8 host_int_status = 0; |
466 A_UINT32 lookAhead = 0; | 474 A_UINT32 lookAhead = 0; |
467 | 475 |
468 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+ProcessPendingIRQs: (dev: 0x%X)\n", (A_UINT
32)pDev)); | 476 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+ProcessPendingIRQs: (dev: 0x%lX)\n", (unsig
ned long)pDev)); |
469 | 477 |
470 /*** NOTE: the HIF implementation guarantees that the context of this call a
llows | 478 /*** NOTE: the HIF implementation guarantees that the context of this call a
llows |
471 * us to perform SYNCHRONOUS I/O, that is we can block, sleep or cal
l any API that | 479 * us to perform SYNCHRONOUS I/O, that is we can block, sleep or cal
l any API that |
472 * can block or switch thread/task ontexts. | 480 * can block or switch thread/task ontexts. |
473 * This is a fully schedulable context. | 481 * This is a fully schedulable context. |
474 * */ | 482 * */ |
475 do { | 483 do { |
476 | 484 |
477 if (pDev->IrqEnableRegisters.int_status_enable == 0) { | 485 if (pDev->IrqEnableRegisters.int_status_enable == 0) { |
478 /* interrupt enables have been cleared, do not try to process any pe
nding interrupts that | 486 /* interrupt enables have been cleared, do not try to process an
y pending interrupts that |
479 * may result in more bus transactions. The target may be unrespons
ive at this | 487 * may result in more bus transactions. The target may be unres
ponsive at this |
480 * point. */ | 488 * point. */ |
481 break; | 489 break; |
482 } | 490 } |
483 | |
484 if (pDev->GetPendingEventsFunc != NULL) { | |
485 HIF_PENDING_EVENTS_INFO events; | |
486 | 491 |
| 492 if (pDev->GetPendingEventsFunc != NULL) { |
| 493 HIF_PENDING_EVENTS_INFO events; |
| 494 |
| 495 #ifdef THREAD_X |
| 496 events.Polling= 0; |
| 497 #endif |
487 /* the HIF layer uses a special mechanism to get events | 498 /* the HIF layer uses a special mechanism to get events |
488 * get this synchronously */ | 499 * get this synchronously */ |
489 status = pDev->GetPendingEventsFunc(pDev->HIFDevice, | 500 status = pDev->GetPendingEventsFunc(pDev->HIFDevice, |
490 &events, | 501 &events, |
491 NULL); | 502 NULL); |
492 | 503 |
493 if (A_FAILED(status)) { | 504 if (A_FAILED(status)) { |
494 break; | 505 break; |
495 } | 506 } |
496 | 507 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
536 HOST_INT_STATUS_ADDRESS, | 547 HOST_INT_STATUS_ADDRESS, |
537 (A_UINT8 *)&pDev->IrqProcRegisters, | 548 (A_UINT8 *)&pDev->IrqProcRegisters, |
538 AR6K_IRQ_PROC_REGS_SIZE, | 549 AR6K_IRQ_PROC_REGS_SIZE, |
539 HIF_RD_SYNC_BYTE_INC, | 550 HIF_RD_SYNC_BYTE_INC, |
540 NULL); | 551 NULL); |
541 | 552 |
542 if (A_FAILED(status)) { | 553 if (A_FAILED(status)) { |
543 break; | 554 break; |
544 } | 555 } |
545 | 556 |
| 557 #ifdef ATH_DEBUG_MODULE |
546 if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_IRQ)) { | 558 if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_IRQ)) { |
547 DevDumpRegisters(pDev, | 559 DevDumpRegisters(pDev, |
548 &pDev->IrqProcRegisters, | 560 &pDev->IrqProcRegisters, |
549 &pDev->IrqEnableRegisters); | 561 &pDev->IrqEnableRegisters); |
550 } | 562 } |
| 563 #endif |
551 | 564 |
552 /* Update only those registers that are enabled */ | 565 /* Update only those registers that are enabled */ |
553 host_int_status = pDev->IrqProcRegisters.host_int_status & | 566 host_int_status = pDev->IrqProcRegisters.host_int_status & |
554 pDev->IrqEnableRegisters.int_status_enable; | 567 pDev->IrqEnableRegisters.int_status_enable; |
555 | 568 |
556 if (NULL == pDev->GetPendingEventsFunc) { | 569 if (NULL == pDev->GetPendingEventsFunc) { |
557 /* only look at mailbox status if the HIF layer did not provide
this function, | 570 /* only look at mailbox status if the HIF layer did not provide
this function, |
558 * on some HIF interfaces reading the RX lookahead is not valid
to do */ | 571 * on some HIF interfaces reading the RX lookahead is not valid
to do */ |
559 if (host_int_status & (1 << HTC_MAILBOX)) { | 572 if (host_int_status & (1 << HTC_MAILBOX)) { |
560 /* mask out pending mailbox value, we use "lookAhead" as the
real flag for | 573 /* mask out pending mailbox value, we use "lookAhead" as the
real flag for |
561 * mailbox processing below */ | 574 * mailbox processing below */ |
562 host_int_status &= ~(1 << HTC_MAILBOX); | 575 host_int_status &= ~(1 << HTC_MAILBOX); |
563 if (pDev->IrqProcRegisters.rx_lookahead_valid & (1 << HTC_MAILBO
X)) { | 576 if (pDev->IrqProcRegisters.rx_lookahead_valid & (1 << HTC_MAILBO
X)) { |
564 /* mailbox has a message and the look ahead is valid */ | 577 /* mailbox has a message and the look ahead is valid */ |
565 lookAhead = pDev->IrqProcRegisters.rx_lookahead[HTC_MAILBOX]
; | 578 lookAhead = pDev->IrqProcRegisters.rx_lookahead[HTC_MAILBOX]
; |
566 if (0 == lookAhead) { | 579 if (0 == lookAhead) { |
567 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" ProcessPendingIRQs2, lo
okAhead is zero! \n")); | 580 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" ProcessPendingIRQs2, lo
okAhead is zero! \n")); |
568 } | 581 } |
569 } | 582 } |
570 } | 583 } |
571 } else { | 584 } else { |
572 /* not valid to check if the HIF has another mechanism for readi
ng mailbox pending status*/ | 585 /* not valid to check if the HIF has another mechanism for readi
ng mailbox pending status*/ |
573 host_int_status &= ~(1 << HTC_MAILBOX); | 586 host_int_status &= ~(1 << HTC_MAILBOX); |
574 } | 587 } |
575 | 588 |
576 if (pDev->GMboxEnabled) { | 589 if (pDev->GMboxEnabled) { |
577 /*call GMBOX layer to process any interrupts of interest */ | 590 /*call GMBOX layer to process any interrupts of interest */ |
578 status = DevCheckGMboxInterrupts(pDev); | 591 status = DevCheckGMboxInterrupts(pDev); |
579 } | 592 } |
580 | 593 |
581 } while (FALSE); | 594 } while (FALSE); |
582 | 595 |
583 | 596 |
584 do { | 597 do { |
585 | 598 |
586 /* did the interrupt status fetches succeed? */ | 599 /* did the interrupt status fetches succeed? */ |
587 if (A_FAILED(status)) { | 600 if (A_FAILED(status)) { |
588 break; | 601 break; |
589 } | 602 } |
590 | 603 |
591 if ((0 == host_int_status) && (0 == lookAhead)) { | 604 if ((0 == host_int_status) && (0 == lookAhead)) { |
592 /* nothing to process, the caller can use this to break out of a
loop */ | 605 /* nothing to process, the caller can use this to break out of a
loop */ |
593 *pDone = TRUE; | 606 *pDone = TRUE; |
594 break; | 607 break; |
595 } | 608 } |
596 | 609 |
597 if (lookAhead != 0) { | 610 if (lookAhead != 0) { |
598 int fetched = 0; | 611 int fetched = 0; |
599 | 612 |
600 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("Pending mailbox message, LookAhead:
0x%X\n",lookAhead)); | 613 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("Pending mailbox message, LookAhead:
0x%X\n",lookAhead)); |
601 /* Mailbox Interrupt, the HTC layer may issue async requests to
empty the | 614 /* Mailbox Interrupt, the HTC layer may issue async requests to
empty the |
602 * mailbox... | 615 * mailbox... |
603 * When emptying the recv mailbox we use the async handler above
called from the | 616 * When emptying the recv mailbox we use the async handler above
called from the |
604 * completion routine of the callers read request. This can impr
ove performance | 617 * completion routine of the callers read request. This can impr
ove performance |
605 * by reducing context switching when we rapidly pull packets */ | 618 * by reducing context switching when we rapidly pull packets */ |
606 status = pDev->MessagePendingCallback(pDev->HTCContext, &lookAhead,
1, pASyncProcessing, &fetched); | 619 status = pDev->MessagePendingCallback(pDev->HTCContext, &lookAhead,
1, pASyncProcessing, &fetched); |
607 if (A_FAILED(status)) { | 620 if (A_FAILED(status)) { |
608 break; | 621 break; |
609 } | 622 } |
610 | 623 |
611 if (!fetched) { | 624 if (!fetched) { |
612 /* HTC could not pull any messages out due to lack of resour
ces */ | 625 /* HTC could not pull any messages out due to lack of resour
ces */ |
613 /* force DSR handler to ack the interrupt */ | 626 /* force DSR handler to ack the interrupt */ |
614 *pASyncProcessing = FALSE; | 627 *pASyncProcessing = FALSE; |
615 pDev->RecheckIRQStatusCnt = 0; | 628 pDev->RecheckIRQStatusCnt = 0; |
616 } | 629 } |
617 } | 630 } |
618 | 631 |
619 /* now handle the rest of them */ | 632 /* now handle the rest of them */ |
620 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, | 633 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, |
621 (" Valid interrupt source(s) for OTHER interrupts: 0
x%x\n", | 634 (" Valid interrupt source(s) for OTHER interrupts: 0
x%x\n", |
622 host_int_status)); | 635 host_int_status)); |
623 | 636 |
624 if (HOST_INT_STATUS_CPU_GET(host_int_status)) { | 637 if (HOST_INT_STATUS_CPU_GET(host_int_status)) { |
625 /* CPU Interrupt */ | 638 /* CPU Interrupt */ |
(...skipping 18 matching lines...) Expand all Loading... |
644 break; | 657 break; |
645 } | 658 } |
646 } | 659 } |
647 | 660 |
648 } while (FALSE); | 661 } while (FALSE); |
649 | 662 |
650 /* an optimization to bypass reading the IRQ status registers unecessari
ly which can re-wake | 663 /* an optimization to bypass reading the IRQ status registers unecessari
ly which can re-wake |
651 * the target, if upper layers determine that we are in a low-throughput
mode, we can | 664 * the target, if upper layers determine that we are in a low-throughput
mode, we can |
652 * rely on taking another interrupt rather than re-checking the status r
egisters which can | 665 * rely on taking another interrupt rather than re-checking the status r
egisters which can |
653 * re-wake the target. | 666 * re-wake the target. |
654 * | 667 * |
655 * NOTE : for host interfaces that use the special GetPendingEventsFunc,
this optimization cannot | 668 * NOTE : for host interfaces that use the special GetPendingEventsFunc,
this optimization cannot |
656 * be used due to possible side-effects. For example, SPI requires the
host to drain all | 669 * be used due to possible side-effects. For example, SPI requires the
host to drain all |
657 * messages from the mailbox before exiting the ISR routine. */ | 670 * messages from the mailbox before exiting the ISR routine. */ |
658 if (!(*pASyncProcessing) && (pDev->RecheckIRQStatusCnt == 0) && (pDev->GetPe
ndingEventsFunc == NULL)) { | 671 if (!(*pASyncProcessing) && (pDev->RecheckIRQStatusCnt == 0) && (pDev->GetPe
ndingEventsFunc == NULL)) { |
659 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("Bypassing IRQ Status re-check, forcing d
one \n")); | 672 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("Bypassing IRQ Status re-check, forcing d
one \n")); |
660 *pDone = TRUE; | 673 *pDone = TRUE; |
661 } | 674 } |
662 | 675 |
663 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-ProcessPendingIRQs: (done:%d, async:%d) sta
tus=%d \n", | 676 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-ProcessPendingIRQs: (done:%d, async:%d) sta
tus=%d \n", |
664 *pDone, *pASyncProcessing, status)); | 677 *pDone, *pASyncProcessing, status)); |
665 | 678 |
666 return status; | 679 return status; |
667 } | 680 } |
668 | 681 |
669 | 682 |
670 /* Synchronousinterrupt handler, this handler kicks off all interrupt processing
.*/ | 683 /* Synchronousinterrupt handler, this handler kicks off all interrupt processing
.*/ |
671 A_STATUS DevDsrHandler(void *context) | 684 A_STATUS DevDsrHandler(void *context) |
672 { | 685 { |
673 AR6K_DEVICE *pDev = (AR6K_DEVICE *)context; | 686 AR6K_DEVICE *pDev = (AR6K_DEVICE *)context; |
674 A_STATUS status = A_OK; | 687 A_STATUS status = A_OK; |
675 A_BOOL done = FALSE; | 688 A_BOOL done = FALSE; |
676 A_BOOL asyncProc = FALSE; | 689 A_BOOL asyncProc = FALSE; |
677 | 690 |
678 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevDsrHandler: (dev: 0x%X)\n", (A_UINT32)pD
ev)); | 691 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevDsrHandler: (dev: 0x%lX)\n", (unsigned l
ong)pDev)); |
679 | 692 |
680 /* reset the recv counter that tracks when we need to yield from the DSR
*/ | 693 /* reset the recv counter that tracks when we need to yield from the DSR
*/ |
681 pDev->CurrentDSRRecvCount = 0; | 694 pDev->CurrentDSRRecvCount = 0; |
682 /* reset counter used to flag a re-scan of IRQ status registers on the t
arget */ | 695 /* reset counter used to flag a re-scan of IRQ status registers on the t
arget */ |
683 pDev->RecheckIRQStatusCnt = 0; | 696 pDev->RecheckIRQStatusCnt = 0; |
684 | 697 |
685 while (!done) { | 698 while (!done) { |
686 status = ProcessPendingIRQs(pDev, &done, &asyncProc); | 699 status = ProcessPendingIRQs(pDev, &done, &asyncProc); |
687 if (A_FAILED(status)) { | 700 if (A_FAILED(status)) { |
688 break; | 701 break; |
689 } | 702 } |
690 | 703 |
691 if (HIF_DEVICE_IRQ_SYNC_ONLY == pDev->HifIRQProcessingMode) { | 704 if (HIF_DEVICE_IRQ_SYNC_ONLY == pDev->HifIRQProcessingMode) { |
692 /* the HIF layer does not allow async IRQ processing, override the a
syncProc flag */ | 705 /* the HIF layer does not allow async IRQ processing, override the a
syncProc flag */ |
693 asyncProc = FALSE; | 706 asyncProc = FALSE; |
694 /* this will cause us to re-enter ProcessPendingIRQ() and re-read in
terrupt status registers. | 707 /* this will cause us to re-enter ProcessPendingIRQ() and re-read in
terrupt status registers. |
695 * this has a nice side effect of blocking us until all async read r
equests are completed. | 708 * this has a nice side effect of blocking us until all async read r
equests are completed. |
696 * This behavior is required on some HIF implementations that do not
allow ASYNC | 709 * This behavior is required on some HIF implementations that do not
allow ASYNC |
697 * processing in interrupt handlers (like Windows CE) */ | 710 * processing in interrupt handlers (like Windows CE) */ |
698 | 711 |
699 if (pDev->DSRCanYield && DEV_CHECK_RECV_YIELD(pDev)) { | 712 if (pDev->DSRCanYield && DEV_CHECK_RECV_YIELD(pDev)) { |
700 /* ProcessPendingIRQs() pulled enough recv messages to satisfy t
he yield count, stop | 713 /* ProcessPendingIRQs() pulled enough recv messages to satisfy t
he yield count, stop |
701 * checking for more messages and return */ | 714 * checking for more messages and return */ |
702 break; | 715 break; |
703 } | 716 } |
704 } | 717 } |
705 | 718 |
706 if (asyncProc) { | 719 if (asyncProc) { |
707 /* the function performed some async I/O for performance, we | 720 /* the function performed some async I/O for performance, we |
708 need to exit the ISR immediately, the check below will preven
t the interrupt from being | 721 need to exit the ISR immediately, the check below will preven
t the interrupt from being |
709 Ack'd while we handle it asynchronously */ | 722 Ack'd while we handle it asynchronously */ |
710 break; | 723 break; |
711 } | 724 } |
712 | 725 |
713 } | 726 } |
714 | 727 |
715 if (A_SUCCESS(status) && !asyncProc) { | 728 if (A_SUCCESS(status) && !asyncProc) { |
716 /* Ack the interrupt only if : | 729 /* Ack the interrupt only if : |
717 * 1. we did not get any errors in processing interrupts | 730 * 1. we did not get any errors in processing interrupts |
718 * 2. there are no outstanding async processing requests */ | 731 * 2. there are no outstanding async processing requests */ |
719 if (pDev->DSRCanYield) { | 732 if (pDev->DSRCanYield) { |
720 /* if the DSR can yield do not ACK the interrupt, there could be
more pending messages. | 733 /* if the DSR can yield do not ACK the interrupt, there could be
more pending messages. |
721 * The HIF layer must ACK the interrupt on behalf of HTC */ | 734 * The HIF layer must ACK the interrupt on behalf of HTC */ |
722 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,(" Yield in effect (cur RX count: %d)
\n", pDev->CurrentDSRRecvCount)); | 735 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,(" Yield in effect (cur RX count: %d)
\n", pDev->CurrentDSRRecvCount)); |
723 } else { | 736 } else { |
724 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,(" Acking interrupt from DevDsrHandler
\n")); | 737 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,(" Acking interrupt from DevDsrHandler
\n")); |
725 HIFAckInterrupt(pDev->HIFDevice); | 738 HIFAckInterrupt(pDev->HIFDevice); |
726 } | 739 } |
727 } | 740 } |
728 | 741 |
729 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevDsrHandler \n")); | 742 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevDsrHandler \n")); |
730 return status; | 743 return status; |
731 } | 744 } |
732 | 745 |
| 746 #ifdef ATH_DEBUG_MODULE |
733 void DumpAR6KDevState(AR6K_DEVICE *pDev) | 747 void DumpAR6KDevState(AR6K_DEVICE *pDev) |
734 { | 748 { |
735 A_STATUS status; | 749 A_STATUS status; |
736 AR6K_IRQ_ENABLE_REGISTERS regs; | 750 AR6K_IRQ_ENABLE_REGISTERS regs; |
737 AR6K_IRQ_PROC_REGISTERS procRegs; | 751 AR6K_IRQ_PROC_REGISTERS procRegs; |
738 | 752 |
739 LOCK_AR6K(pDev); | 753 LOCK_AR6K(pDev); |
740 /* copy into our temp area */ | 754 /* copy into our temp area */ |
741 A_MEMCPY(®s,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE); | 755 A_MEMCPY(®s,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE); |
742 UNLOCK_AR6K(pDev); | 756 UNLOCK_AR6K(pDev); |
743 | 757 |
744 /* load the register table from the device */ | 758 /* load the register table from the device */ |
745 status = HIFReadWrite(pDev->HIFDevice, | 759 status = HIFReadWrite(pDev->HIFDevice, |
746 HOST_INT_STATUS_ADDRESS, | 760 HOST_INT_STATUS_ADDRESS, |
747 (A_UINT8 *)&procRegs, | 761 (A_UINT8 *)&procRegs, |
748 AR6K_IRQ_PROC_REGS_SIZE, | 762 AR6K_IRQ_PROC_REGS_SIZE, |
749 HIF_RD_SYNC_BYTE_INC, | 763 HIF_RD_SYNC_BYTE_INC, |
750 NULL); | 764 NULL); |
751 | 765 |
752 if (A_FAILED(status)) { | 766 if (A_FAILED(status)) { |
753 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, | 767 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, |
754 ("DumpAR6KDevState : Failed to read register table (%d) \n",status))
; | 768 ("DumpAR6KDevState : Failed to read register table (%d) \n",status))
; |
755 return; | 769 return; |
756 } | 770 } |
757 | 771 |
758 DevDumpRegisters(pDev,&procRegs,®s); | 772 DevDumpRegisters(pDev,&procRegs,®s); |
759 | 773 |
760 if (pDev->GMboxInfo.pStateDumpCallback != NULL) { | 774 if (pDev->GMboxInfo.pStateDumpCallback != NULL) { |
761 pDev->GMboxInfo.pStateDumpCallback(pDev->GMboxInfo.pProtocolContext);
| 775 pDev->GMboxInfo.pStateDumpCallback(pDev->GMboxInfo.pProtocolContext); |
762 } | 776 } |
763 | 777 |
764 /* dump any bus state at the HIF layer */ | 778 /* dump any bus state at the HIF layer */ |
765 HIFConfigureDevice(pDev->HIFDevice,HIF_DEVICE_DEBUG_BUS_STATE,NULL,0); | 779 HIFConfigureDevice(pDev->HIFDevice,HIF_DEVICE_DEBUG_BUS_STATE,NULL,0); |
766 | 780 |
767 } | 781 } |
| 782 #endif |
768 | 783 |
769 | 784 |
OLD | NEW |