OLD | NEW |
1 //------------------------------------------------------------------------------ | 1 //------------------------------------------------------------------------------ |
2 // <copyright file="ar6k.c" company="Atheros"> | 2 // <copyright file="ar6k.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 device layer that handles register level I/O | 21 // AR6K device layer that handles register level I/O |
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 27 matching lines...) Expand all Loading... |
50 LOCK_AR6K(pDev); | 54 LOCK_AR6K(pDev); |
51 pPacket = HTC_PACKET_DEQUEUE(&pDev->RegisterIOList); | 55 pPacket = HTC_PACKET_DEQUEUE(&pDev->RegisterIOList); |
52 UNLOCK_AR6K(pDev); | 56 UNLOCK_AR6K(pDev); |
53 | 57 |
54 return pPacket; | 58 return pPacket; |
55 } | 59 } |
56 | 60 |
57 void DevCleanup(AR6K_DEVICE *pDev) | 61 void DevCleanup(AR6K_DEVICE *pDev) |
58 { | 62 { |
59 DevCleanupGMbox(pDev); | 63 DevCleanupGMbox(pDev); |
60 | 64 |
61 if (pDev->HifAttached) { | 65 if (pDev->HifAttached) { |
62 HIFDetachHTC(pDev->HIFDevice); | 66 HIFDetachHTC(pDev->HIFDevice); |
63 pDev->HifAttached = FALSE; | 67 pDev->HifAttached = FALSE; |
64 } | 68 } |
65 | 69 |
66 DevCleanupVirtualScatterSupport(pDev); | 70 DevCleanupVirtualScatterSupport(pDev); |
67 | 71 |
68 if (A_IS_MUTEX_VALID(&pDev->Lock)) { | 72 if (A_IS_MUTEX_VALID(&pDev->Lock)) { |
69 A_MUTEX_DELETE(&pDev->Lock); | 73 A_MUTEX_DELETE(&pDev->Lock); |
70 } | 74 } |
71 } | 75 } |
72 | 76 |
73 A_STATUS DevSetup(AR6K_DEVICE *pDev) | 77 A_STATUS DevSetup(AR6K_DEVICE *pDev) |
74 { | 78 { |
75 A_UINT32 blocksizes[AR6K_MAILBOXES]; | 79 A_UINT32 blocksizes[AR6K_MAILBOXES]; |
76 A_STATUS status = A_OK; | 80 A_STATUS status = A_OK; |
77 int i; | 81 int i; |
78 HTC_CALLBACKS htcCallbacks; | 82 HTC_CALLBACKS htcCallbacks; |
79 | 83 |
80 do { | 84 do { |
81 | 85 |
82 DL_LIST_INIT(&pDev->ScatterReqHead); | 86 DL_LIST_INIT(&pDev->ScatterReqHead); |
83 /* initialize our free list of IO packets */ | 87 /* initialize our free list of IO packets */ |
84 INIT_HTC_PACKET_QUEUE(&pDev->RegisterIOList); | 88 INIT_HTC_PACKET_QUEUE(&pDev->RegisterIOList); |
85 A_MUTEX_INIT(&pDev->Lock); | 89 A_MUTEX_INIT(&pDev->Lock); |
86 | 90 |
87 A_MEMZERO(&htcCallbacks, sizeof(HTC_CALLBACKS)); | 91 A_MEMZERO(&htcCallbacks, sizeof(HTC_CALLBACKS)); |
88 /* the device layer handles these */ | 92 /* the device layer handles these */ |
89 htcCallbacks.rwCompletionHandler = DevRWCompletionHandler; | 93 htcCallbacks.rwCompletionHandler = DevRWCompletionHandler; |
90 htcCallbacks.dsrHandler = DevDsrHandler; | 94 htcCallbacks.dsrHandler = DevDsrHandler; |
91 htcCallbacks.context = pDev; | 95 htcCallbacks.context = pDev; |
92 | 96 |
93 status = HIFAttachHTC(pDev->HIFDevice, &htcCallbacks); | 97 status = HIFAttachHTC(pDev->HIFDevice, &htcCallbacks); |
94 | 98 |
95 if (A_FAILED(status)) { | 99 if (A_FAILED(status)) { |
96 break; | 100 break; |
97 } | 101 } |
98 | 102 |
99 pDev->HifAttached = TRUE; | 103 pDev->HifAttached = TRUE; |
100 | 104 |
101 /* get the addresses for all 4 mailboxes */ | 105 /* get the addresses for all 4 mailboxes */ |
102 status = HIFConfigureDevice(pDev->HIFDevice, HIF_DEVICE_GET_MBOX_ADDR, | 106 status = HIFConfigureDevice(pDev->HIFDevice, HIF_DEVICE_GET_MBOX_ADDR, |
103 &pDev->MailBoxInfo, sizeof(pDev->MailBoxInfo
)); | 107 &pDev->MailBoxInfo, sizeof(pDev->MailBoxInfo
)); |
104 | 108 |
105 if (status != A_OK) { | 109 if (status != A_OK) { |
106 A_ASSERT(FALSE); | 110 A_ASSERT(FALSE); |
107 break; | 111 break; |
108 } | 112 } |
109 | 113 |
110 /* carve up register I/O packets (these are for ASYNC register I/O )
*/ | 114 /* carve up register I/O packets (these are for ASYNC register I/O )
*/ |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
151 /* assume we can process HIF interrupt events asynchronously */ | 155 /* assume we can process HIF interrupt events asynchronously */ |
152 pDev->HifIRQProcessingMode = HIF_DEVICE_IRQ_ASYNC_SYNC; | 156 pDev->HifIRQProcessingMode = HIF_DEVICE_IRQ_ASYNC_SYNC; |
153 | 157 |
154 /* see if the HIF layer overrides this assumption */ | 158 /* see if the HIF layer overrides this assumption */ |
155 HIFConfigureDevice(pDev->HIFDevice, | 159 HIFConfigureDevice(pDev->HIFDevice, |
156 HIF_DEVICE_GET_IRQ_PROC_MODE, | 160 HIF_DEVICE_GET_IRQ_PROC_MODE, |
157 &pDev->HifIRQProcessingMode, | 161 &pDev->HifIRQProcessingMode, |
158 sizeof(pDev->HifIRQProcessingMode)); | 162 sizeof(pDev->HifIRQProcessingMode)); |
159 | 163 |
160 switch (pDev->HifIRQProcessingMode) { | 164 switch (pDev->HifIRQProcessingMode) { |
161 case HIF_DEVICE_IRQ_SYNC_ONLY: | 165 case HIF_DEVICE_IRQ_SYNC_ONLY: |
162 AR_DEBUG_PRINTF(ATH_DEBUG_WARN,("HIF Interrupt processing is SYN
C ONLY\n")); | 166 AR_DEBUG_PRINTF(ATH_DEBUG_WARN,("HIF Interrupt processing is SYN
C ONLY\n")); |
163 /* see if HIF layer wants HTC to yield */ | 167 /* see if HIF layer wants HTC to yield */ |
164 HIFConfigureDevice(pDev->HIFDevice, | 168 HIFConfigureDevice(pDev->HIFDevice, |
165 HIF_DEVICE_GET_IRQ_YIELD_PARAMS, | 169 HIF_DEVICE_GET_IRQ_YIELD_PARAMS, |
166 &pDev->HifIRQYieldParams, | 170 &pDev->HifIRQYieldParams, |
167 sizeof(pDev->HifIRQYieldParams)); | 171 sizeof(pDev->HifIRQYieldParams)); |
168 | 172 |
169 if (pDev->HifIRQYieldParams.RecvPacketYieldCount > 0) { | 173 if (pDev->HifIRQYieldParams.RecvPacketYieldCount > 0) { |
170 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, | 174 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, |
171 ("HIF requests that DSR yield per %d RECV packets \n", | 175 ("HIF requests that DSR yield per %d RECV packets \n", |
172 pDev->HifIRQYieldParams.RecvPacketYieldCount)); | 176 pDev->HifIRQYieldParams.RecvPacketYieldCount)); |
173 pDev->DSRCanYield = TRUE; | 177 pDev->DSRCanYield = TRUE; |
174 } | 178 } |
175 break; | 179 break; |
176 case HIF_DEVICE_IRQ_ASYNC_SYNC: | 180 case HIF_DEVICE_IRQ_ASYNC_SYNC: |
177 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("HIF Interrupt processing is ASYN
C and SYNC\n")); | 181 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("HIF Interrupt processing is ASYN
C and SYNC\n")); |
178 break; | 182 break; |
179 default: | 183 default: |
180 A_ASSERT(FALSE); | 184 A_ASSERT(FALSE); |
181 } | 185 } |
182 | 186 |
183 pDev->HifMaskUmaskRecvEvent = NULL; | 187 pDev->HifMaskUmaskRecvEvent = NULL; |
184 | 188 |
185 /* see if the HIF layer implements the mask/unmask recv events funct
ion */ | 189 /* see if the HIF layer implements the mask/unmask recv events funct
ion */ |
186 HIFConfigureDevice(pDev->HIFDevice, | 190 HIFConfigureDevice(pDev->HIFDevice, |
187 HIF_DEVICE_GET_RECV_EVENT_MASK_UNMASK_FUNC, | 191 HIF_DEVICE_GET_RECV_EVENT_MASK_UNMASK_FUNC, |
188 &pDev->HifMaskUmaskRecvEvent, | 192 &pDev->HifMaskUmaskRecvEvent, |
189 sizeof(pDev->HifMaskUmaskRecvEvent)); | 193 sizeof(pDev->HifMaskUmaskRecvEvent)); |
190 | 194 |
191 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("HIF special overrides : 0x%X , 0x%X\n", | 195 AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("HIF special overrides : 0x%lX , 0x%lX\n"
, |
192 (A_UINT32)pDev->GetPendingEventsFunc, (A_UINT32)pDev->HifMaskUm
askRecvEvent)); | 196 (unsigned long)pDev->GetPendingEventsFunc, (unsigned long)pDev-
>HifMaskUmaskRecvEvent)); |
193 | 197 |
194 status = DevDisableInterrupts(pDev); | 198 status = DevDisableInterrupts(pDev); |
195 | 199 |
196 if (A_FAILED(status)) { | 200 if (A_FAILED(status)) { |
197 break; | 201 break; |
198 } | 202 } |
199 | 203 |
200 status = DevSetupGMbox(pDev); | 204 status = DevSetupGMbox(pDev); |
201 | 205 |
202 } while (FALSE); | 206 } while (FALSE); |
203 | 207 |
204 if (A_FAILED(status)) { | 208 if (A_FAILED(status)) { |
205 if (pDev->HifAttached) { | 209 if (pDev->HifAttached) { |
206 HIFDetachHTC(pDev->HIFDevice); | 210 HIFDetachHTC(pDev->HIFDevice); |
207 pDev->HifAttached = FALSE; | 211 pDev->HifAttached = FALSE; |
208 } | 212 } |
209 } | 213 } |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 INT_STATUS_ENABLE_ADDRESS, | 296 INT_STATUS_ENABLE_ADDRESS, |
293 ®s.int_status_enable, | 297 ®s.int_status_enable, |
294 AR6K_IRQ_ENABLE_REGS_SIZE, | 298 AR6K_IRQ_ENABLE_REGS_SIZE, |
295 HIF_WR_SYNC_BYTE_INC, | 299 HIF_WR_SYNC_BYTE_INC, |
296 NULL); | 300 NULL); |
297 } | 301 } |
298 | 302 |
299 /* enable device interrupts */ | 303 /* enable device interrupts */ |
300 A_STATUS DevUnmaskInterrupts(AR6K_DEVICE *pDev) | 304 A_STATUS DevUnmaskInterrupts(AR6K_DEVICE *pDev) |
301 { | 305 { |
302 /* for good measure, make sure interrupt are disabled before unmasking a
t the HIF | 306 /* for good measure, make sure interrupt are disabled before unmasking at th
e HIF |
303 * layer. | 307 * layer. |
304 * The rationale here is that between device insertion (where we clear t
he interrupts the first time) | 308 * The rationale here is that between device insertion (where we clear the i
nterrupts the first time) |
305 * and when HTC is finally ready to handle interrupts, other software ca
n perform target "soft" resets. | 309 * and when HTC is finally ready to handle interrupts, other software can pe
rform target "soft" resets. |
306 * The AR6K interrupt enables reset back to an "enabled" state when this
happens. | 310 * The AR6K interrupt enables reset back to an "enabled" state when this hap
pens. |
307 * */ | 311 * */ |
| 312 A_STATUS IntStatus = A_OK; |
308 DevDisableInterrupts(pDev); | 313 DevDisableInterrupts(pDev); |
309 | 314 |
310 /* Unmask the host controller interrupts */ | 315 #ifdef THREAD_X |
| 316 // Tobe verified... |
| 317 IntStatus = DevEnableInterrupts(pDev); |
| 318 /* Unmask the host controller interrupts */ |
311 HIFUnMaskInterrupt(pDev->HIFDevice); | 319 HIFUnMaskInterrupt(pDev->HIFDevice); |
| 320 #else |
| 321 /* Unmask the host controller interrupts */ |
| 322 HIFUnMaskInterrupt(pDev->HIFDevice); |
| 323 IntStatus = DevEnableInterrupts(pDev); |
| 324 #endif |
312 | 325 |
313 return DevEnableInterrupts(pDev); | 326 return IntStatus; |
314 } | 327 } |
315 | 328 |
316 /* disable all device interrupts */ | 329 /* disable all device interrupts */ |
317 A_STATUS DevMaskInterrupts(AR6K_DEVICE *pDev) | 330 A_STATUS DevMaskInterrupts(AR6K_DEVICE *pDev) |
318 { | 331 { |
319 /* mask the interrupt at the HIF layer, we don't want a stray interrupt
taken while | 332 /* mask the interrupt at the HIF layer, we don't want a stray interrupt
taken while |
320 * we zero out our shadow registers in DevDisableInterrupts()*/ | 333 * we zero out our shadow registers in DevDisableInterrupts()*/ |
321 HIFMaskInterrupt(pDev->HIFDevice); | 334 HIFMaskInterrupt(pDev->HIFDevice); |
322 | 335 |
323 return DevDisableInterrupts(pDev); | 336 return DevDisableInterrupts(pDev); |
324 } | 337 } |
325 | 338 |
326 /* callback when our fetch to enable/disable completes */ | 339 /* callback when our fetch to enable/disable completes */ |
327 static void DevDoEnableDisableRecvAsyncHandler(void *Context, HTC_PACKET *pPacke
t) | 340 static void DevDoEnableDisableRecvAsyncHandler(void *Context, HTC_PACKET *pPacke
t) |
328 { | 341 { |
329 AR6K_DEVICE *pDev = (AR6K_DEVICE *)Context; | 342 AR6K_DEVICE *pDev = (AR6K_DEVICE *)Context; |
330 | 343 |
331 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevDoEnableDisableRecvAsyncHandler: (dev: 0
x%X)\n", (A_UINT32)pDev)); | 344 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevDoEnableDisableRecvAsyncHandler: (dev: 0
x%lX)\n", (unsigned long)pDev)); |
332 | 345 |
333 if (A_FAILED(pPacket->Status)) { | 346 if (A_FAILED(pPacket->Status)) { |
334 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, | 347 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, |
335 (" Failed to disable receiver, status:%d \n", pPacket->Status)); | 348 (" Failed to disable receiver, status:%d \n", pPacket->Status)); |
336 } | 349 } |
337 /* free this IO packet */ | 350 /* free this IO packet */ |
338 AR6KFreeIOPacket(pDev,pPacket); | 351 AR6KFreeIOPacket(pDev,pPacket); |
339 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevDoEnableDisableRecvAsyncHandler \n")); | 352 AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevDoEnableDisableRecvAsyncHandler \n")); |
340 } | 353 } |
341 | 354 |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
468 | 481 |
469 A_STATUS DevEnableRecv(AR6K_DEVICE *pDev, A_BOOL AsyncMode) | 482 A_STATUS DevEnableRecv(AR6K_DEVICE *pDev, A_BOOL AsyncMode) |
470 { | 483 { |
471 if (NULL == pDev->HifMaskUmaskRecvEvent) { | 484 if (NULL == pDev->HifMaskUmaskRecvEvent) { |
472 return DevDoEnableDisableRecvNormal(pDev,TRUE,AsyncMode); | 485 return DevDoEnableDisableRecvNormal(pDev,TRUE,AsyncMode); |
473 } else { | 486 } else { |
474 return DevDoEnableDisableRecvOverride(pDev,TRUE,AsyncMode); | 487 return DevDoEnableDisableRecvOverride(pDev,TRUE,AsyncMode); |
475 } | 488 } |
476 } | 489 } |
477 | 490 |
| 491 A_STATUS DevWaitForPendingRecv(AR6K_DEVICE *pDev,A_UINT32 TimeoutInMs,A_BOOL *pb
IsRecvPending) |
| 492 { |
| 493 A_STATUS status = A_OK; |
| 494 A_UCHAR host_int_status = 0x0; |
| 495 A_UINT32 counter = 0x0; |
| 496 |
| 497 if(TimeoutInMs < 100) |
| 498 { |
| 499 TimeoutInMs = 100; |
| 500 } |
| 501 |
| 502 counter = TimeoutInMs / 100; |
| 503 |
| 504 do |
| 505 { |
| 506 //Read the Host Interrupt Status Register |
| 507 status = HIFReadWrite(pDev->HIFDevice, |
| 508 HOST_INT_STATUS_ADDRESS, |
| 509 &host_int_status, |
| 510 sizeof(A_UCHAR), |
| 511 HIF_RD_SYNC_BYTE_INC, |
| 512 NULL); |
| 513 if(A_FAILED(status)) |
| 514 { |
| 515 AR_DEBUG_PRINTF(ATH_LOG_ERR,("DevWaitForPendingRecv:Read HOST_INT_ST
ATUS_ADDRESS Failed 0x%X\n",status)); |
| 516 break; |
| 517 } |
| 518 |
| 519 host_int_status = A_SUCCESS(status) ? (host_int_status & (1 << 0)):0; |
| 520 if(!host_int_status) |
| 521 { |
| 522 status = A_OK; |
| 523 *pbIsRecvPending = FALSE; |
| 524 break; |
| 525 } |
| 526 else |
| 527 { |
| 528 *pbIsRecvPending = TRUE; |
| 529 } |
| 530 |
| 531 A_MDELAY(100); |
| 532 |
| 533 counter--; |
| 534 |
| 535 }while(counter); |
| 536 return status; |
| 537 } |
| 538 |
478 void DevDumpRegisters(AR6K_DEVICE *pDev, | 539 void DevDumpRegisters(AR6K_DEVICE *pDev, |
479 AR6K_IRQ_PROC_REGISTERS *pIrqProcRegs, | 540 AR6K_IRQ_PROC_REGISTERS *pIrqProcRegs, |
480 AR6K_IRQ_ENABLE_REGISTERS *pIrqEnableRegs) | 541 AR6K_IRQ_ENABLE_REGISTERS *pIrqEnableRegs) |
481 { | 542 { |
482 | 543 |
483 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("\n<------- Register Table -------->\n")); | 544 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("\n<------- Register Table -------->\n")); |
484 | 545 |
485 if (pIrqProcRegs != NULL) { | 546 if (pIrqProcRegs != NULL) { |
486 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, | 547 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, |
487 ("Host Int Status: 0x%x\n",pIrqProcRegs->host_int_status))
; | 548 ("Host Int Status: 0x%x\n",pIrqProcRegs->host_int_status))
; |
488 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, | 549 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, |
489 ("CPU Int Status: 0x%x\n",pIrqProcRegs->cpu_int_status)); | 550 ("CPU Int Status: 0x%x\n",pIrqProcRegs->cpu_int_status)); |
490 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, | 551 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, |
491 ("Error Int Status: 0x%x\n",pIrqProcRegs->error_int_status)
); | 552 ("Error Int Status: 0x%x\n",pIrqProcRegs->error_int_status)
); |
492 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, | 553 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, |
493 ("Counter Int Status: 0x%x\n",pIrqProcRegs->counter_int_statu
s)); | 554 ("Counter Int Status: 0x%x\n",pIrqProcRegs->counter_int_statu
s)); |
494 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, | 555 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, |
495 ("Mbox Frame: 0x%x\n",pIrqProcRegs->mbox_frame)); | 556 ("Mbox Frame: 0x%x\n",pIrqProcRegs->mbox_frame)); |
496 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, | 557 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, |
497 ("Rx Lookahead Valid: 0x%x\n",pIrqProcRegs->rx_lookahead_vali
d)); | 558 ("Rx Lookahead Valid: 0x%x\n",pIrqProcRegs->rx_lookahead_vali
d)); |
498 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, | 559 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, |
499 ("Rx Lookahead 0: 0x%x\n",pIrqProcRegs->rx_lookahead[0]))
; | 560 ("Rx Lookahead 0: 0x%x\n",pIrqProcRegs->rx_lookahead[0]))
; |
500 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, | 561 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, |
501 ("Rx Lookahead 1: 0x%x\n",pIrqProcRegs->rx_lookahead[1]))
; | 562 ("Rx Lookahead 1: 0x%x\n",pIrqProcRegs->rx_lookahead[1]))
; |
502 | 563 |
503 if (pDev->MailBoxInfo.GMboxAddress != 0) { | 564 if (pDev->MailBoxInfo.GMboxAddress != 0) { |
504 /* if the target supports GMBOX hardware, dump some additional s
tate */ | 565 /* if the target supports GMBOX hardware, dump some additional s
tate */ |
505 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, | 566 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, |
506 ("GMBOX Host Int Status 2: 0x%x\n",pIrqProcRegs->host_int_stat
us2)); | 567 ("GMBOX Host Int Status 2: 0x%x\n",pIrqProcRegs->host_int_stat
us2)); |
507 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, | 568 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, |
508 ("GMBOX RX Avail: 0x%x\n",pIrqProcRegs->gmbox_rx_avai
l)); | 569 ("GMBOX RX Avail: 0x%x\n",pIrqProcRegs->gmbox_rx_avai
l)); |
509 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, | 570 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, |
510 ("GMBOX lookahead alias 0: 0x%x\n",pIrqProcRegs->rx_gmbox_look
ahead_alias[0])); | 571 ("GMBOX lookahead alias 0: 0x%x\n",pIrqProcRegs->rx_gmbox_look
ahead_alias[0])); |
511 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, | 572 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, |
512 ("GMBOX lookahead alias 1: 0x%x\n",pIrqProcRegs->rx_gmbox_look
ahead_alias[1])); | 573 ("GMBOX lookahead alias 1: 0x%x\n",pIrqProcRegs->rx_gmbox_look
ahead_alias[1])); |
513 } | 574 } |
514 | 575 |
515 } | 576 } |
516 | 577 |
517 if (pIrqEnableRegs != NULL) { | 578 if (pIrqEnableRegs != NULL) { |
518 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, | 579 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, |
519 ("Int Status Enable: 0x%x\n",pIrqEnableRegs->int_status_enab
le)); | 580 ("Int Status Enable: 0x%x\n",pIrqEnableRegs->int_status_enab
le)); |
520 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, | 581 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, |
521 ("Counter Int Status Enable: 0x%x\n",pIrqEnableRegs->counter_int_sta
tus_enable)); | 582 ("Counter Int Status Enable: 0x%x\n",pIrqEnableRegs->counter_int_sta
tus_enable)); |
522 } | 583 } |
523 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("<------------------------------->\n")); | 584 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("<------------------------------->\n")); |
524 } | 585 } |
525 | 586 |
526 | 587 |
527 #define DEV_GET_VIRT_DMA_INFO(p) ((DEV_SCATTER_DMA_VIRTUAL_INFO *)((p)->HIFPriv
ate[0])) | 588 #define DEV_GET_VIRT_DMA_INFO(p) ((DEV_SCATTER_DMA_VIRTUAL_INFO *)((p)->HIFPriv
ate[0])) |
528 | 589 |
529 static HIF_SCATTER_REQ *DevAllocScatterReq(HIF_DEVICE *Context) | 590 static HIF_SCATTER_REQ *DevAllocScatterReq(HIF_DEVICE *Context) |
530 { | 591 { |
531 DL_LIST *pItem; | 592 DL_LIST *pItem; |
532 AR6K_DEVICE *pDev = (AR6K_DEVICE *)Context; | 593 AR6K_DEVICE *pDev = (AR6K_DEVICE *)Context; |
533 LOCK_AR6K(pDev); | 594 LOCK_AR6K(pDev); |
534 pItem = DL_ListRemoveItemFromHead(&pDev->ScatterReqHead); | 595 pItem = DL_ListRemoveItemFromHead(&pDev->ScatterReqHead); |
535 UNLOCK_AR6K(pDev); | 596 UNLOCK_AR6K(pDev); |
536 if (pItem != NULL) { | 597 if (pItem != NULL) { |
537 return A_CONTAINING_STRUCT(pItem, HIF_SCATTER_REQ, ListLink); | 598 return A_CONTAINING_STRUCT(pItem, HIF_SCATTER_REQ, ListLink); |
538 } | 599 } |
539 return NULL; | 600 return NULL; |
540 } | 601 } |
541 | 602 |
542 static void DevFreeScatterReq(HIF_DEVICE *Context, HIF_SCATTER_REQ *pReq) | 603 static void DevFreeScatterReq(HIF_DEVICE *Context, HIF_SCATTER_REQ *pReq) |
543 { | 604 { |
544 AR6K_DEVICE *pDev = (AR6K_DEVICE *)Context; | 605 AR6K_DEVICE *pDev = (AR6K_DEVICE *)Context; |
545 LOCK_AR6K(pDev); | 606 LOCK_AR6K(pDev); |
546 DL_ListInsertTail(&pDev->ScatterReqHead, &pReq->ListLink); | 607 DL_ListInsertTail(&pDev->ScatterReqHead, &pReq->ListLink); |
547 UNLOCK_AR6K(pDev); | 608 UNLOCK_AR6K(pDev); |
548 } | 609 } |
549 | 610 |
550 A_STATUS DevCopyScatterListToFromDMABuffer(HIF_SCATTER_REQ *pReq, A_BOOL FromDMA
) | 611 A_STATUS DevCopyScatterListToFromDMABuffer(HIF_SCATTER_REQ *pReq, A_BOOL FromDMA
) |
551 { | 612 { |
552 A_UINT8 *pDMABuffer = NULL; | 613 A_UINT8 *pDMABuffer = NULL; |
553 int i, remaining; | 614 int i, remaining; |
554 A_UINT32 length; | 615 A_UINT32 length; |
555 | 616 |
556 pDMABuffer = pReq->pScatterBounceBuffer; | 617 pDMABuffer = pReq->pScatterBounceBuffer; |
557 | 618 |
558 if (pDMABuffer == NULL) { | 619 if (pDMABuffer == NULL) { |
559 A_ASSERT(FALSE); | 620 A_ASSERT(FALSE); |
560 return A_EINVAL; | 621 return A_EINVAL; |
561 } | 622 } |
562 | 623 |
563 remaining = (int)pReq->TotalLength; | 624 remaining = (int)pReq->TotalLength; |
564 | 625 |
565 for (i = 0; i < pReq->ValidScatterEntries; i++) { | 626 for (i = 0; i < pReq->ValidScatterEntries; i++) { |
566 | 627 |
567 length = min((int)pReq->ScatterList[i].Length, remaining); | 628 length = min((int)pReq->ScatterList[i].Length, remaining); |
568 | 629 |
569 if (length != (int)pReq->ScatterList[i].Length) { | 630 if (length != (int)pReq->ScatterList[i].Length) { |
570 A_ASSERT(FALSE); | 631 A_ASSERT(FALSE); |
571 /* there is a problem with the scatter list */ | 632 /* there is a problem with the scatter list */ |
572 return A_EINVAL; | 633 return A_EINVAL; |
573 } | 634 } |
574 | 635 |
575 if (FromDMA) { | 636 if (FromDMA) { |
576 /* from DMA buffer */ | 637 /* from DMA buffer */ |
577 A_MEMCPY(pReq->ScatterList[i].pBuffer, pDMABuffer , length); | 638 A_MEMCPY(pReq->ScatterList[i].pBuffer, pDMABuffer , length); |
578 } else { | 639 } else { |
579 /* to DMA buffer */ | 640 /* to DMA buffer */ |
580 A_MEMCPY(pDMABuffer, pReq->ScatterList[i].pBuffer, length); | 641 A_MEMCPY(pDMABuffer, pReq->ScatterList[i].pBuffer, length); |
581 } | 642 } |
582 | 643 |
583 pDMABuffer += length; | 644 pDMABuffer += length; |
584 remaining -= length; | 645 remaining -= length; |
585 } | 646 } |
586 | 647 |
587 return A_OK; | 648 return A_OK; |
588 } | 649 } |
589 | 650 |
590 static void DevReadWriteScatterAsyncHandler(void *Context, HTC_PACKET *pPacket) | 651 static void DevReadWriteScatterAsyncHandler(void *Context, HTC_PACKET *pPacket) |
591 { | 652 { |
592 AR6K_DEVICE *pDev = (AR6K_DEVICE *)Context; | 653 AR6K_DEVICE *pDev = (AR6K_DEVICE *)Context; |
593 HIF_SCATTER_REQ *pReq = (HIF_SCATTER_REQ *)pPacket->pPktContext; | 654 HIF_SCATTER_REQ *pReq = (HIF_SCATTER_REQ *)pPacket->pPktContext; |
594 | 655 |
595 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+DevReadWriteScatterAsyncHandler: (dev: 0x%
X)\n", (A_UINT32)pDev)); | 656 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+DevReadWriteScatterAsyncHandler: (dev: 0x%
lX)\n", (unsigned long)pDev)); |
596 | 657 |
597 pReq->CompletionStatus = pPacket->Status; | 658 pReq->CompletionStatus = pPacket->Status; |
598 | 659 |
599 AR6KFreeIOPacket(pDev,pPacket); | 660 AR6KFreeIOPacket(pDev,pPacket); |
600 | 661 |
601 pReq->CompletionRoutine(pReq); | 662 pReq->CompletionRoutine(pReq); |
602 | 663 |
603 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-DevReadWriteScatterAsyncHandler \n")); | 664 AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-DevReadWriteScatterAsyncHandler \n")); |
604 } | 665 } |
605 | 666 |
606 static A_STATUS DevReadWriteScatter(HIF_DEVICE *Context, HIF_SCATTER_REQ *pReq) | 667 static A_STATUS DevReadWriteScatter(HIF_DEVICE *Context, HIF_SCATTER_REQ *pReq) |
607 { | 668 { |
608 AR6K_DEVICE *pDev = (AR6K_DEVICE *)Context; | 669 AR6K_DEVICE *pDev = (AR6K_DEVICE *)Context; |
609 A_STATUS status = A_OK; | 670 A_STATUS status = A_OK; |
610 HTC_PACKET *pIOPacket = NULL; | 671 HTC_PACKET *pIOPacket = NULL; |
611 A_UINT32 request = pReq->Request; | 672 A_UINT32 request = pReq->Request; |
612 | 673 |
613 do { | 674 do { |
614 | 675 |
615 if (pReq->TotalLength > AR6K_MAX_TRANSFER_SIZE_PER_SCATTER) { | 676 if (pReq->TotalLength > AR6K_MAX_TRANSFER_SIZE_PER_SCATTER) { |
616 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, | 677 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, |
617 ("Invalid length: %d \n", pReq->TotalLength)); | 678 ("Invalid length: %d \n", pReq->TotalLength)); |
618 break; | 679 break; |
619 } | 680 } |
620 | 681 |
621 if (pReq->TotalLength == 0) { | 682 if (pReq->TotalLength == 0) { |
622 A_ASSERT(FALSE); | 683 A_ASSERT(FALSE); |
623 break; | 684 break; |
624 } | 685 } |
625 | 686 |
626 if (request & HIF_ASYNCHRONOUS) { | 687 if (request & HIF_ASYNCHRONOUS) { |
627 /* use an I/O packet to carry this request */ | 688 /* use an I/O packet to carry this request */ |
628 pIOPacket = AR6KAllocIOPacket(pDev); | 689 pIOPacket = AR6KAllocIOPacket(pDev); |
629 if (NULL == pIOPacket) { | 690 if (NULL == pIOPacket) { |
630 status = A_NO_MEMORY; | 691 status = A_NO_MEMORY; |
631 break; | 692 break; |
632 } | 693 } |
633 | 694 |
634 /* save the request */ | 695 /* save the request */ |
635 pIOPacket->pPktContext = pReq; | 696 pIOPacket->pPktContext = pReq; |
636 /* stick in our completion routine when the I/O operation comple
tes */ | 697 /* stick in our completion routine when the I/O operation comple
tes */ |
637 pIOPacket->Completion = DevReadWriteScatterAsyncHandler; | 698 pIOPacket->Completion = DevReadWriteScatterAsyncHandler; |
638 pIOPacket->pContext = pDev; | 699 pIOPacket->pContext = pDev; |
639 } | 700 } |
640 | 701 |
641 if (request & HIF_WRITE) { | 702 if (request & HIF_WRITE) { |
642 /* in virtual DMA, we are issuing the requests through the legacy HI
FReadWrite API | 703 /* in virtual DMA, we are issuing the requests through the legacy HI
FReadWrite API |
643 * this API will adjust the address automatically for the last byte
to fall on the mailbox | 704 * this API will adjust the address automatically for the last byte
to fall on the mailbox |
644 * EOM. */ | 705 * EOM. */ |
645 | 706 |
646 /* if the address is an extended address, we can adjust the address
here since the extended | 707 /* if the address is an extended address, we can adjust the address
here since the extended |
647 * address will bypass the normal checks in legacy HIF layers */ | 708 * address will bypass the normal checks in legacy HIF layers */ |
648 if (pReq->Address == pDev->MailBoxInfo.MboxProp[HTC_MAILBOX].Extende
dAddress) { | 709 if (pReq->Address == pDev->MailBoxInfo.MboxProp[HTC_MAILBOX].Extende
dAddress) { |
649 pReq->Address += pDev->MailBoxInfo.MboxProp[HTC_MAILBOX].Extende
dSize - pReq->TotalLength; | 710 pReq->Address += pDev->MailBoxInfo.MboxProp[HTC_MAILBOX].Extende
dSize - pReq->TotalLength; |
650 } | 711 } |
651 } | 712 } |
652 | 713 |
653 /* use legacy readwrite */ | 714 /* use legacy readwrite */ |
654 status = HIFReadWrite(pDev->HIFDevice, | 715 status = HIFReadWrite(pDev->HIFDevice, |
655 pReq->Address, | 716 pReq->Address, |
656 DEV_GET_VIRT_DMA_INFO(pReq)->pVirtDmaBuffer, | 717 DEV_GET_VIRT_DMA_INFO(pReq)->pVirtDmaBuffer, |
657 pReq->TotalLength, | 718 pReq->TotalLength, |
658 request, | 719 request, |
659 (request & HIF_ASYNCHRONOUS) ? pIOPacket : NULL); | 720 (request & HIF_ASYNCHRONOUS) ? pIOPacket : NULL); |
660 | 721 |
661 } while (FALSE); | 722 } while (FALSE); |
662 | 723 |
663 if ((status != A_PENDING) && A_FAILED(status) && (request & HIF_ASYNCHRONOUS
)) { | 724 if ((status != A_PENDING) && A_FAILED(status) && (request & HIF_ASYNCHRONOUS
)) { |
664 if (pIOPacket != NULL) { | 725 if (pIOPacket != NULL) { |
665 AR6KFreeIOPacket(pDev,pIOPacket); | 726 AR6KFreeIOPacket(pDev,pIOPacket); |
666 } | 727 } |
667 pReq->CompletionStatus = status; | 728 pReq->CompletionStatus = status; |
668 pReq->CompletionRoutine(pReq); | 729 pReq->CompletionRoutine(pReq); |
669 status = A_OK; | 730 status = A_OK; |
670 } | 731 } |
671 | 732 |
672 return status; | 733 return status; |
673 } | 734 } |
674 | 735 |
675 | 736 |
676 static void DevCleanupVirtualScatterSupport(AR6K_DEVICE *pDev) | 737 static void DevCleanupVirtualScatterSupport(AR6K_DEVICE *pDev) |
677 { | 738 { |
678 HIF_SCATTER_REQ *pReq; | 739 HIF_SCATTER_REQ *pReq; |
679 | 740 |
680 while (1) { | 741 while (1) { |
681 pReq = DevAllocScatterReq((HIF_DEVICE *)pDev); | 742 pReq = DevAllocScatterReq((HIF_DEVICE *)pDev); |
682 if (NULL == pReq) { | 743 if (NULL == pReq) { |
683 break; | 744 break; |
684 } | 745 } |
685 A_FREE(pReq); | 746 A_FREE(pReq); |
686 } | 747 } |
687 | 748 |
688 } | 749 } |
689 | 750 |
690 /* function to set up virtual scatter support if HIF layer has not implement
ed the interface */ | 751 /* function to set up virtual scatter support if HIF layer has not implement
ed the interface */ |
691 static A_STATUS DevSetupVirtualScatterSupport(AR6K_DEVICE *pDev) | 752 static A_STATUS DevSetupVirtualScatterSupport(AR6K_DEVICE *pDev) |
692 { | 753 { |
693 A_STATUS status = A_OK; | 754 A_STATUS status = A_OK; |
694 int bufferSize, sgreqSize; | 755 int bufferSize, sgreqSize; |
695 int i; | 756 int i; |
696 DEV_SCATTER_DMA_VIRTUAL_INFO *pVirtualInfo; | 757 DEV_SCATTER_DMA_VIRTUAL_INFO *pVirtualInfo; |
697 HIF_SCATTER_REQ *pReq; | 758 HIF_SCATTER_REQ *pReq; |
698 | 759 |
699 bufferSize = sizeof(DEV_SCATTER_DMA_VIRTUAL_INFO) + | 760 bufferSize = sizeof(DEV_SCATTER_DMA_VIRTUAL_INFO) + |
700 2 * (A_GET_CACHE_LINE_BYTES()) + AR6K_MAX_TRANSFER_SIZE_PER_SCAT
TER; | 761 2 * (A_GET_CACHE_LINE_BYTES()) + AR6K_MAX_TRANSFER_SIZE_PER_SCAT
TER; |
701 | 762 |
702 sgreqSize = sizeof(HIF_SCATTER_REQ) + | 763 sgreqSize = sizeof(HIF_SCATTER_REQ) + |
703 (AR6K_SCATTER_ENTRIES_PER_REQ - 1) * (sizeof(HIF_SCATTER_ITE
M)); | 764 (AR6K_SCATTER_ENTRIES_PER_REQ - 1) * (sizeof(HIF_SCATTER_ITE
M)); |
704 | 765 |
705 for (i = 0; i < AR6K_SCATTER_REQS; i++) { | 766 for (i = 0; i < AR6K_SCATTER_REQS; i++) { |
706 /* allocate the scatter request, buffer info and the actual virtual
buffer itself */ | 767 /* allocate the scatter request, buffer info and the actual virtual
buffer itself */ |
707 pReq = (HIF_SCATTER_REQ *)A_MALLOC(sgreqSize + bufferSize); | 768 pReq = (HIF_SCATTER_REQ *)A_MALLOC(sgreqSize + bufferSize); |
708 | 769 |
709 if (NULL == pReq) { | 770 if (NULL == pReq) { |
710 status = A_NO_MEMORY; | 771 status = A_NO_MEMORY; |
711 break; | 772 break; |
712 } | 773 } |
713 | 774 |
714 A_MEMZERO(pReq, sgreqSize); | 775 A_MEMZERO(pReq, sgreqSize); |
715 | 776 |
716 /* the virtual DMA starts after the scatter request struct */ | 777 /* the virtual DMA starts after the scatter request struct */ |
717 pVirtualInfo = (DEV_SCATTER_DMA_VIRTUAL_INFO *)((A_UINT8 *)pReq + sgreqS
ize); | 778 pVirtualInfo = (DEV_SCATTER_DMA_VIRTUAL_INFO *)((A_UINT8 *)pReq + sgreqS
ize); |
718 A_MEMZERO(pVirtualInfo, sizeof(DEV_SCATTER_DMA_VIRTUAL_INFO)); | 779 A_MEMZERO(pVirtualInfo, sizeof(DEV_SCATTER_DMA_VIRTUAL_INFO)); |
719 | 780 |
720 pVirtualInfo->pVirtDmaBuffer = &pVirtualInfo->DataArea[0]; | 781 pVirtualInfo->pVirtDmaBuffer = &pVirtualInfo->DataArea[0]; |
721 /* align buffer to cache line in case host controller can actually D
MA this */ | 782 /* align buffer to cache line in case host controller can actually D
MA this */ |
722 pVirtualInfo->pVirtDmaBuffer = A_ALIGN_TO_CACHE_LINE(pVirtualInfo->pVirt
DmaBuffer); | 783 pVirtualInfo->pVirtDmaBuffer = A_ALIGN_TO_CACHE_LINE(pVirtualInfo->pVirt
DmaBuffer); |
723 /* store the structure in the private area */ | 784 /* store the structure in the private area */ |
724 pReq->HIFPrivate[0] = pVirtualInfo; | 785 pReq->HIFPrivate[0] = pVirtualInfo; |
725 /* we emulate a DMA bounce interface */ | 786 /* we emulate a DMA bounce interface */ |
726 pReq->ScatterMethod = HIF_SCATTER_DMA_BOUNCE; | 787 pReq->ScatterMethod = HIF_SCATTER_DMA_BOUNCE; |
727 pReq->pScatterBounceBuffer = pVirtualInfo->pVirtDmaBuffer; | 788 pReq->pScatterBounceBuffer = pVirtualInfo->pVirtDmaBuffer; |
728 /* free request to the list */ | 789 /* free request to the list */ |
729 DevFreeScatterReq((HIF_DEVICE *)pDev,pReq); | 790 DevFreeScatterReq((HIF_DEVICE *)pDev,pReq); |
730 } | 791 } |
731 | 792 |
732 if (A_FAILED(status)) { | 793 if (A_FAILED(status)) { |
733 DevCleanupVirtualScatterSupport(pDev); | 794 DevCleanupVirtualScatterSupport(pDev); |
734 } else { | 795 } else { |
735 pDev->HifScatterInfo.pAllocateReqFunc = DevAllocScatterReq; | 796 pDev->HifScatterInfo.pAllocateReqFunc = DevAllocScatterReq; |
736 pDev->HifScatterInfo.pFreeReqFunc = DevFreeScatterReq; | 797 pDev->HifScatterInfo.pFreeReqFunc = DevFreeScatterReq; |
737 pDev->HifScatterInfo.pReadWriteScatterFunc = DevReadWriteScatter; | 798 pDev->HifScatterInfo.pReadWriteScatterFunc = DevReadWriteScatter; |
738 pDev->HifScatterInfo.MaxScatterEntries = AR6K_SCATTER_ENTRIES_PER_REQ; | 799 if (pDev->MailBoxInfo.MboxBusIFType == MBOX_BUS_IF_SPI) { |
739 pDev->HifScatterInfo.MaxTransferSizePerScatterReq = AR6K_MAX_TRANSFER_SI
ZE_PER_SCATTER; | 800 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("AR6K: SPI bus requires RX scatter
limits\n")); |
740 pDev->ScatterIsVirtual = TRUE; | 801 pDev->HifScatterInfo.MaxScatterEntries = AR6K_MIN_SCATTER_ENTRIES_PE
R_REQ; |
741 } | 802 pDev->HifScatterInfo.MaxTransferSizePerScatterReq = AR6K_MIN_TRANSFE
R_SIZE_PER_SCATTER; |
742 | 803 } else { |
743 return status; | 804 pDev->HifScatterInfo.MaxScatterEntries = AR6K_SCATTER_ENTRIES_PER_RE
Q; |
| 805 pDev->HifScatterInfo.MaxTransferSizePerScatterReq = AR6K_MAX_TRANSFE
R_SIZE_PER_SCATTER; |
| 806 } |
| 807 pDev->ScatterIsVirtual = TRUE; |
| 808 } |
| 809 |
| 810 return status; |
744 } | 811 } |
745 | 812 |
746 | 813 |
747 A_STATUS DevSetupMsgBundling(AR6K_DEVICE *pDev, int MaxMsgsPerTransfer) | 814 A_STATUS DevSetupMsgBundling(AR6K_DEVICE *pDev, int MaxMsgsPerTransfer) |
748 { | 815 { |
749 A_STATUS status; | 816 A_STATUS status; |
750 | 817 |
751 if (pDev->MailBoxInfo.Flags & HIF_MBOX_FLAG_NO_BUNDLING) { | 818 if (pDev->MailBoxInfo.Flags & HIF_MBOX_FLAG_NO_BUNDLING) { |
752 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("HIF requires bundling disabled\n"));
| 819 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("HIF requires bundling disabled\n")); |
753 return A_ENOTSUP; | 820 return A_ENOTSUP; |
754 } | 821 } |
755 | 822 |
756 status = HIFConfigureDevice(pDev->HIFDevice, | 823 status = HIFConfigureDevice(pDev->HIFDevice, |
757 HIF_CONFIGURE_QUERY_SCATTER_REQUEST_SUPPORT, | 824 HIF_CONFIGURE_QUERY_SCATTER_REQUEST_SUPPORT, |
758 &pDev->HifScatterInfo, | 825 &pDev->HifScatterInfo, |
759 sizeof(pDev->HifScatterInfo)); | 826 sizeof(pDev->HifScatterInfo)); |
760 | 827 |
761 if (A_FAILED(status)) { | 828 if (A_FAILED(status)) { |
762 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, | 829 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, |
763 ("AR6K: ** HIF layer does not support scatter requests (%d) \n",stat
us)); | 830 ("AR6K: ** HIF layer does not support scatter requests (%d) \n",stat
us)); |
764 | 831 |
765 /* we can try to use a virtual DMA scatter mechanism using legacy HI
FReadWrite() */ | 832 /* we can try to use a virtual DMA scatter mechanism using legacy HI
FReadWrite() */ |
766 status = DevSetupVirtualScatterSupport(pDev); | 833 status = DevSetupVirtualScatterSupport(pDev); |
767 | 834 |
768 if (A_SUCCESS(status)) { | 835 if (A_SUCCESS(status)) { |
769 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, | 836 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, |
770 ("AR6K: virtual scatter transfers enabled (max scatter items:%d:
maxlen:%d) \n", | 837 ("AR6K: virtual scatter transfers enabled (max scatter items:%d:
maxlen:%d) \n", |
771 DEV_GET_MAX_MSG_PER_BUNDLE(pDev), DEV_GET_MAX_BUNDLE_LENGTH(
pDev))); | 838 DEV_GET_MAX_MSG_PER_BUNDLE(pDev), DEV_GET_MAX_BUNDLE_LENGTH(
pDev))); |
772 } | 839 } |
773 | 840 |
774 } else { | 841 } else { |
775 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, | 842 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, |
776 ("AR6K: HIF layer supports scatter requests (max scatter items:%d: m
axlen:%d) \n", | 843 ("AR6K: HIF layer supports scatter requests (max scatter items:%d: m
axlen:%d) \n", |
777 DEV_GET_MAX_MSG_PER_BUNDLE(pDev), DEV_GET_MAX_BUNDLE_LENGTH(
pDev))); | 844 DEV_GET_MAX_MSG_PER_BUNDLE(pDev), DEV_GET_MAX_BUNDLE_LENGTH(
pDev))); |
778 } | 845 } |
779 | 846 |
780 if (A_SUCCESS(status)) { | 847 if (A_SUCCESS(status)) { |
781 /* for the recv path, the maximum number of bytes per recv bundle is
just limited | 848 /* for the recv path, the maximum number of bytes per recv bundle is
just limited |
782 * by the maximum transfer size at the HIF layer */ | 849 * by the maximum transfer size at the HIF layer */ |
783 pDev->MaxRecvBundleSize = pDev->HifScatterInfo.MaxTransferSizePerScatter
Req; | 850 pDev->MaxRecvBundleSize = pDev->HifScatterInfo.MaxTransferSizePerScatter
Req; |
784 | 851 |
785 /* for the send path, the max transfer size is limited by the existe
nce and size of | 852 if (pDev->MailBoxInfo.MboxBusIFType == MBOX_BUS_IF_SPI) { |
786 * the extended mailbox address range */ | 853 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("AR6K : SPI bus requires TX bundlin
g disabled\n")); |
787 if (pDev->MailBoxInfo.MboxProp[0].ExtendedAddress != 0) { | 854 pDev->MaxSendBundleSize = 0; |
788 pDev->MaxSendBundleSize = pDev->MailBoxInfo.MboxProp[0].ExtendedSize
; | |
789 } else { | 855 } else { |
790 /* legacy */ | 856 /* for the send path, the max transfer size is limited by the ex
istence and size of |
791 pDev->MaxSendBundleSize = AR6K_LEGACY_MAX_WRITE_LENGTH; | 857 * the extended mailbox address range */ |
| 858 if (pDev->MailBoxInfo.MboxProp[0].ExtendedAddress != 0) { |
| 859 pDev->MaxSendBundleSize = pDev->MailBoxInfo.MboxProp[0].Extended
Size; |
| 860 } else { |
| 861 /* legacy */ |
| 862 pDev->MaxSendBundleSize = AR6K_LEGACY_MAX_WRITE_LENGTH; |
| 863 } |
| 864 |
| 865 if (pDev->MaxSendBundleSize > pDev->HifScatterInfo.MaxTransferSizePe
rScatterReq) { |
| 866 /* limit send bundle size to what the HIF can support for sc
atter requests */ |
| 867 pDev->MaxSendBundleSize = pDev->HifScatterInfo.MaxTransferSizePe
rScatterReq; |
| 868 } |
792 } | 869 } |
793 | 870 |
794 if (pDev->MaxSendBundleSize > pDev->HifScatterInfo.MaxTransferSizePerSca
tterReq) { | |
795 /* limit send bundle size to what the HIF can support for scatte
r requests */ | |
796 pDev->MaxSendBundleSize = pDev->HifScatterInfo.MaxTransferSizePerSca
tterReq; | |
797 } | |
798 | |
799 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, | 871 AR_DEBUG_PRINTF(ATH_DEBUG_ANY, |
800 ("AR6K: max recv: %d max send: %d \n", | 872 ("AR6K: max recv: %d max send: %d \n", |
801 DEV_GET_MAX_BUNDLE_RECV_LENGTH(pDev), DEV_GET_MAX_BUNDLE_SEN
D_LENGTH(pDev))); | 873 DEV_GET_MAX_BUNDLE_RECV_LENGTH(pDev), DEV_GET_MAX_BUNDLE_SEN
D_LENGTH(pDev))); |
802 | 874 |
803 } | 875 } |
804 return status; | 876 return status; |
805 } | 877 } |
806 | 878 |
807 A_STATUS DevSubmitScatterRequest(AR6K_DEVICE *pDev, HIF_SCATTER_REQ *pScatterReq
, A_BOOL Read, A_BOOL Async) | 879 A_STATUS DevSubmitScatterRequest(AR6K_DEVICE *pDev, HIF_SCATTER_REQ *pScatterReq
, A_BOOL Read, A_BOOL Async) |
808 { | 880 { |
809 A_STATUS status; | 881 A_STATUS status; |
810
| 882 |
811 if (Read) { | 883 if (Read) { |
812 /* read operation */ | 884 /* read operation */ |
813 pScatterReq->Request = (Async) ? HIF_RD_ASYNC_BLOCK_FIX : HIF_RD_SYNC_BL
OCK_FIX; | 885 pScatterReq->Request = (Async) ? HIF_RD_ASYNC_BLOCK_FIX : HIF_RD_SYNC_BL
OCK_FIX; |
814 pScatterReq->Address = pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX]; | 886 pScatterReq->Address = pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX]; |
815 A_ASSERT(pScatterReq->TotalLength <= (A_UINT32)DEV_GET_MAX_BUNDLE_RECV_L
ENGTH(pDev)); | 887 A_ASSERT(pScatterReq->TotalLength <= (A_UINT32)DEV_GET_MAX_BUNDLE_RECV_L
ENGTH(pDev)); |
816 } else { | 888 } else { |
817 A_UINT32 mailboxWidth; | 889 A_UINT32 mailboxWidth; |
818 | 890 |
819 /* write operation */ | 891 /* write operation */ |
820 pScatterReq->Request = (Async) ? HIF_WR_ASYNC_BLOCK_INC : HIF_WR_SYNC_BL
OCK_INC; | 892 pScatterReq->Request = (Async) ? HIF_WR_ASYNC_BLOCK_INC : HIF_WR_SYNC_BL
OCK_INC; |
821 A_ASSERT(pScatterReq->TotalLength <= (A_UINT32)DEV_GET_MAX_BUNDLE_SEND_L
ENGTH(pDev)); | 893 A_ASSERT(pScatterReq->TotalLength <= (A_UINT32)DEV_GET_MAX_BUNDLE_SEND_L
ENGTH(pDev)); |
822 if (pScatterReq->TotalLength > AR6K_LEGACY_MAX_WRITE_LENGTH) { | 894 if (pScatterReq->TotalLength > AR6K_LEGACY_MAX_WRITE_LENGTH) { |
823 /* for large writes use the extended address */ | 895 /* for large writes use the extended address */ |
824 pScatterReq->Address = pDev->MailBoxInfo.MboxProp[HTC_MAILBOX].Exten
dedAddress; | 896 pScatterReq->Address = pDev->MailBoxInfo.MboxProp[HTC_MAILBOX].Exten
dedAddress; |
825 mailboxWidth = pDev->MailBoxInfo.MboxProp[HTC_MAILBOX].ExtendedSize; | 897 mailboxWidth = pDev->MailBoxInfo.MboxProp[HTC_MAILBOX].ExtendedSize; |
826 } else { | 898 } else { |
827 pScatterReq->Address = pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX];
| 899 pScatterReq->Address = pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX]; |
828 mailboxWidth = AR6K_LEGACY_MAX_WRITE_LENGTH; | 900 mailboxWidth = AR6K_LEGACY_MAX_WRITE_LENGTH; |
829 } | 901 } |
830 | 902 |
831 if (!pDev->ScatterIsVirtual) { | 903 if (!pDev->ScatterIsVirtual) { |
832 /* we are passing this scatter list down to the HIF layer' scatter r
equest handler, fixup the address | 904 /* we are passing this scatter list down to the HIF layer' scatter r
equest handler, fixup the address |
833 * so that the last byte falls on the EOM, we do this for those HIFs
that support the | 905 * so that the last byte falls on the EOM, we do this for those HIFs
that support the |
834 * scatter API */ | 906 * scatter API */ |
835 pScatterReq->Address += (mailboxWidth - pScatterReq->TotalLength);
| 907 pScatterReq->Address += (mailboxWidth - pScatterReq->TotalLength); |
836 } | 908 } |
837 | 909 |
838 } | 910 } |
839 | 911 |
840 AR_DEBUG_PRINTF(ATH_DEBUG_RECV | ATH_DEBUG_SEND, | 912 AR_DEBUG_PRINTF(ATH_DEBUG_RECV | ATH_DEBUG_SEND, |
841 ("DevSubmitScatterRequest, Entries: %d, Total Length: %d Mbox:0x
%X (mode: %s : %s)\n", | 913 ("DevSubmitScatterRequest, Entries: %d, Total Length: %d Mbox:0x
%X (mode: %s : %s)\n", |
842 pScatterReq->ValidScatterEntries, | 914 pScatterReq->ValidScatterEntries, |
843 pScatterReq->TotalLength, | 915 pScatterReq->TotalLength, |
844 pScatterReq->Address, | 916 pScatterReq->Address, |
845 Async ? "ASYNC" : "SYNC", | 917 Async ? "ASYNC" : "SYNC", |
846 (Read) ? "RD" : "WR")); | 918 (Read) ? "RD" : "WR")); |
847 | 919 |
848 status = DEV_PREPARE_SCATTER_OPERATION(pScatterReq); | 920 status = DEV_PREPARE_SCATTER_OPERATION(pScatterReq); |
849 | 921 |
850 if (A_FAILED(status)) { | 922 if (A_FAILED(status)) { |
851 if (Async) { | 923 if (Async) { |
852 pScatterReq->CompletionStatus = status; | 924 pScatterReq->CompletionStatus = status; |
853 pScatterReq->CompletionRoutine(pScatterReq); | 925 pScatterReq->CompletionRoutine(pScatterReq); |
854 return A_OK; | 926 return A_OK; |
855 } | 927 } |
856 return status; | 928 return status; |
857 } | 929 } |
858 | 930 |
859 status = pDev->HifScatterInfo.pReadWriteScatterFunc(pDev->ScatterIsVirtual ?
pDev : pDev->HIFDevice, | 931 status = pDev->HifScatterInfo.pReadWriteScatterFunc(pDev->ScatterIsVirtual ?
pDev : pDev->HIFDevice, |
860 pScatterReq); | 932 pScatterReq); |
861 if (!Async) { | 933 if (!Async) { |
862 /* in sync mode, we can touch the scatter request */ | 934 /* in sync mode, we can touch the scatter request */ |
863 pScatterReq->CompletionStatus = status; | 935 pScatterReq->CompletionStatus = status; |
864 DEV_FINISH_SCATTER_OPERATION(pScatterReq); | 936 DEV_FINISH_SCATTER_OPERATION(pScatterReq); |
865 } else { | 937 } else { |
866 if (status == A_PENDING) { | 938 if (status == A_PENDING) { |
867 status = A_OK; | 939 status = A_OK; |
868 } | 940 } |
869 } | 941 } |
870 | 942 |
871 return status; | 943 return status; |
872 } | 944 } |
873 | 945 |
874 | 946 |
875 #ifdef MBOXHW_UNIT_TEST | 947 #ifdef MBOXHW_UNIT_TEST |
876 | 948 |
877 | 949 |
878 /* This is a mailbox hardware unit test that must be called in a schedulable con
text | 950 /* This is a mailbox hardware unit test that must be called in a schedulable con
text |
879 * This test is very simple, it will send a list of buffers with a counting patt
ern | 951 * This test is very simple, it will send a list of buffers with a counting patt
ern |
880 * and the target will invert the data and send the message back | 952 * and the target will invert the data and send the message back |
(...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1390 } else { | 1462 } else { |
1391 AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, (" DoMboxHWTest DONE - FAILED! - \n
")); | 1463 AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, (" DoMboxHWTest DONE - FAILED! - \n
")); |
1392 } | 1464 } |
1393 /* don't let HTC_Start continue, the target is actually not running any
HTC code */ | 1465 /* don't let HTC_Start continue, the target is actually not running any
HTC code */ |
1394 return A_ERROR; | 1466 return A_ERROR; |
1395 } | 1467 } |
1396 #endif | 1468 #endif |
1397 | 1469 |
1398 | 1470 |
1399 | 1471 |
OLD | NEW |