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

Side by Side Diff: chromeos/drivers/ath6kl/bmi/src/bmi.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="bmi.c" company="Atheros">
3 // Copyright (c) 2004-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 //
18 // Author(s): ="Atheros"
19 //==============================================================================
20
21 #include "hif.h"
22 #include "bmi.h"
23 #include "htc_api.h"
24 #include "bmi_internal.h"
25
26 #ifdef DEBUG
27 static ATH_DEBUG_MASK_DESCRIPTION bmi_debug_desc[] = {
28 { ATH_DEBUG_BMI , "BMI Tracing"},
29 };
30
31 ATH_DEBUG_INSTANTIATE_MODULE_VAR(bmi,
32 "bmi",
33 "Boot Manager Interface",
34 ATH_DEBUG_MASK_DEFAULTS,
35 ATH_DEBUG_DESCRIPTION_COUNT(bmi_debug_desc),
36 bmi_debug_desc);
37
38 #endif
39
40 /*
41 Although we had envisioned BMI to run on top of HTC, this is not how the
42 final implementation ended up. On the Target side, BMI is a part of the BSP
43 and does not use the HTC protocol nor even DMA -- it is intentionally kept
44 very simple.
45 */
46
47 static A_BOOL pendingEventsFuncCheck = FALSE;
48 static A_UINT32 *pBMICmdCredits;
49 static A_UCHAR *pBMICmdBuf;
50 #define MAX_BMI_CMDBUF_SZ (BMI_DATASZ_MAX + \
51 sizeof(A_UINT32) /* cmd */ + \
52 sizeof(A_UINT32) /* addr */ + \
53 sizeof(A_UINT32))/* length */
54 #define BMI_COMMAND_FITS(sz) ((sz) <= MAX_BMI_CMDBUF_SZ)
55
56 /* APIs visible to the driver */
57 void
58 BMIInit(void)
59 {
60 bmiDone = FALSE;
61 pendingEventsFuncCheck = FALSE;
62
63 /*
64 * On some platforms, it's not possible to DMA to a static variable
65 * in a device driver (e.g. Linux loadable driver module).
66 * So we need to A_MALLOC space for "command credits" and for commands.
67 *
68 * Note: implicitly relies on A_MALLOC to provide a buffer that is
69 * suitable for DMA (or PIO). This buffer will be passed down the
70 * bus stack.
71 */
72 if (!pBMICmdCredits) {
73 pBMICmdCredits = (A_UINT32 *)A_MALLOC_NOWAIT(4);
74 A_ASSERT(pBMICmdCredits);
75 }
76
77 if (!pBMICmdBuf) {
78 pBMICmdBuf = (A_UCHAR *)A_MALLOC_NOWAIT(MAX_BMI_CMDBUF_SZ);
79 A_ASSERT(pBMICmdBuf);
80 }
81
82 A_REGISTER_MODULE_DEBUG_INFO(bmi);
83 }
84
85 A_STATUS
86 BMIDone(HIF_DEVICE *device)
87 {
88 A_STATUS status;
89 A_UINT32 cid;
90
91 if (bmiDone) {
92 AR_DEBUG_PRINTF (ATH_DEBUG_BMI, ("BMIDone skipped\n"));
93 return A_OK;
94 }
95
96 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Done: Enter (device: 0x%p)\n", device)) ;
97 bmiDone = TRUE;
98 cid = BMI_DONE;
99
100 status = bmiBufferSend(device, (A_UCHAR *)&cid, sizeof(cid));
101 if (status != A_OK) {
102 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
103 return A_ERROR;
104 }
105
106 if (pBMICmdCredits) {
107 A_FREE(pBMICmdCredits);
108 pBMICmdCredits = NULL;
109 }
110
111 if (pBMICmdBuf) {
112 A_FREE(pBMICmdBuf);
113 pBMICmdBuf = NULL;
114 }
115
116 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Done: Exit\n"));
117
118 return A_OK;
119 }
120
121 A_STATUS
122 BMIGetTargetInfo(HIF_DEVICE *device, struct bmi_target_info *targ_info)
123 {
124 A_STATUS status;
125 A_UINT32 cid;
126
127 if (bmiDone) {
128 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
129 return A_ERROR;
130 }
131
132 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Get Target Info: Enter (device: 0x%p)\n ", device));
133 cid = BMI_GET_TARGET_INFO;
134
135 status = bmiBufferSend(device, (A_UCHAR *)&cid, sizeof(cid));
136 if (status != A_OK) {
137 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
138 return A_ERROR;
139 }
140
141 status = bmiBufferReceive(device, (A_UCHAR *)&targ_info->target_ver,
142 sizeof(targ_info->target_ver), T RUE);
143 if (status != A_OK) {
144 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read Target Version from the device\n"));
145 return A_ERROR;
146 }
147
148 if (targ_info->target_ver == TARGET_VERSION_SENTINAL) {
149 /* Determine how many bytes are in the Target's targ_info */
150 status = bmiBufferReceive(device, (A_UCHAR *)&targ_info->target_info_byt e_count,
151 sizeof(targ_info->target_info_byte_c ount), TRUE);
152 if (status != A_OK) {
153 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read Target Info Byte Cou nt from the device\n"));
154 return A_ERROR;
155 }
156
157 /*
158 * The Target's targ_info doesn't match the Host's targ_info.
159 * We need to do some backwards compatibility work to make this OK.
160 */
161 A_ASSERT(targ_info->target_info_byte_count == sizeof(*targ_info));
162
163 /* Read the remainder of the targ_info */
164 status = bmiBufferReceive(device,
165 ((A_UCHAR *)targ_info)+sizeof(targ_info->target_info_byt e_count),
166 sizeof(*targ_info)-sizeof(targ_info->target_info_byte_co unt), TRUE);
167 if (status != A_OK) {
168 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read Target Info (%d byte s) from the device\n",
169 targ_info->targe t_info_byte_count));
170 return A_ERROR;
171 }
172 } else {
173 /*
174 * Target must be an AR6001 whose firmware does not
175 * support BMI_GET_TARGET_INFO. Construct the data
176 * that it would have sent.
177 */
178 targ_info->target_info_byte_count=sizeof(*targ_info);
179 targ_info->target_type=TARGET_TYPE_AR6001;
180 }
181
182 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Get Target Info: Exit (ver: 0x%x type: 0x%x)\n",
183 targ_info->targe t_ver, targ_info->target_type));
184
185 return A_OK;
186 }
187
188 A_STATUS
189 BMIReadMemory(HIF_DEVICE *device,
190 A_UINT32 address,
191 A_UCHAR *buffer,
192 A_UINT32 length)
193 {
194 A_UINT32 cid;
195 A_STATUS status;
196 A_UINT32 offset;
197 A_UINT32 remaining, rxlen;
198
199 A_ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX + sizeof(cid) + sizeof(address) + s izeof(length)));
200 memset (pBMICmdBuf, 0, BMI_DATASZ_MAX + sizeof(cid) + sizeof(address) + size of(length));
201
202 if (bmiDone) {
203 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
204 return A_ERROR;
205 }
206
207 AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
208 ("BMI Read Memory: Enter (device: 0x%p, address: 0x%x, l ength: %d)\n",
209 device, address, length));
210
211 cid = BMI_READ_MEMORY;
212
213 remaining = length;
214
215 while (remaining)
216 {
217 rxlen = (remaining < BMI_DATASZ_MAX) ? remaining : BMI_DATASZ_MAX;
218 offset = 0;
219 A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
220 offset += sizeof(cid);
221 A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address));
222 offset += sizeof(address);
223 A_MEMCPY(&(pBMICmdBuf[offset]), &rxlen, sizeof(rxlen));
224 offset += sizeof(length);
225
226 status = bmiBufferSend(device, pBMICmdBuf, offset);
227 if (status != A_OK) {
228 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
229 return A_ERROR;
230 }
231 status = bmiBufferReceive(device, pBMICmdBuf, rxlen, TRUE);
232 if (status != A_OK) {
233 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n")) ;
234 return A_ERROR;
235 }
236 A_MEMCPY(&buffer[length - remaining], pBMICmdBuf, rxlen);
237 remaining -= rxlen; address += rxlen;
238 }
239
240 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Read Memory: Exit\n"));
241 return A_OK;
242 }
243
244 A_STATUS
245 BMIWriteMemory(HIF_DEVICE *device,
246 A_UINT32 address,
247 A_UCHAR *buffer,
248 A_UINT32 length)
249 {
250 A_UINT32 cid;
251 A_STATUS status;
252 A_UINT32 offset;
253 A_UINT32 remaining, txlen;
254 const A_UINT32 header = sizeof(cid) + sizeof(address) + sizeof(length);
255
256 A_ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX + header));
257 memset (pBMICmdBuf, 0, BMI_DATASZ_MAX + header);
258
259 if (bmiDone) {
260 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
261 return A_ERROR;
262 }
263
264 AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
265 ("BMI Write Memory: Enter (device: 0x%p, address: 0x%x, length: %d)\n",
266 device, address, length));
267
268 cid = BMI_WRITE_MEMORY;
269
270 remaining = length;
271 while (remaining)
272 {
273 txlen = (remaining < (BMI_DATASZ_MAX - header)) ?
274 remaining : (BMI_DATASZ_MAX - header);
275 offset = 0;
276 A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
277 offset += sizeof(cid);
278 A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address));
279 offset += sizeof(address);
280 A_MEMCPY(&(pBMICmdBuf[offset]), &txlen, sizeof(txlen));
281 offset += sizeof(txlen);
282 A_MEMCPY(&(pBMICmdBuf[offset]), &buffer[length - remaining], txlen);
283 offset += txlen;
284 status = bmiBufferSend(device, pBMICmdBuf, offset);
285 if (status != A_OK) {
286 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
287 return A_ERROR;
288 }
289 remaining -= txlen; address += txlen;
290 }
291
292 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Write Memory: Exit\n"));
293
294 return A_OK;
295 }
296
297 A_STATUS
298 BMIExecute(HIF_DEVICE *device,
299 A_UINT32 address,
300 A_UINT32 *param)
301 {
302 A_UINT32 cid;
303 A_STATUS status;
304 A_UINT32 offset;
305
306 A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address) + sizeof(param)));
307 memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address) + sizeof(param));
308
309 if (bmiDone) {
310 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
311 return A_ERROR;
312 }
313
314 AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
315 ("BMI Execute: Enter (device: 0x%p, address: 0x%x, param: %d)\n",
316 device, address, *param));
317
318 cid = BMI_EXECUTE;
319
320 offset = 0;
321 A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
322 offset += sizeof(cid);
323 A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address));
324 offset += sizeof(address);
325 A_MEMCPY(&(pBMICmdBuf[offset]), param, sizeof(*param));
326 offset += sizeof(*param);
327 status = bmiBufferSend(device, pBMICmdBuf, offset);
328 if (status != A_OK) {
329 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
330 return A_ERROR;
331 }
332
333 status = bmiBufferReceive(device, pBMICmdBuf, sizeof(*param), FALSE);
334 if (status != A_OK) {
335 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n"));
336 return A_ERROR;
337 }
338
339 A_MEMCPY(param, pBMICmdBuf, sizeof(*param));
340
341 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Execute: Exit (param: %d)\n", *param));
342 return A_OK;
343 }
344
345 A_STATUS
346 BMISetAppStart(HIF_DEVICE *device,
347 A_UINT32 address)
348 {
349 A_UINT32 cid;
350 A_STATUS status;
351 A_UINT32 offset;
352
353 A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address)));
354 memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address));
355
356 if (bmiDone) {
357 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
358 return A_ERROR;
359 }
360
361 AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
362 ("BMI Set App Start: Enter (device: 0x%p, address: 0x%x)\n",
363 device, address));
364
365 cid = BMI_SET_APP_START;
366
367 offset = 0;
368 A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
369 offset += sizeof(cid);
370 A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address));
371 offset += sizeof(address);
372 status = bmiBufferSend(device, pBMICmdBuf, offset);
373 if (status != A_OK) {
374 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
375 return A_ERROR;
376 }
377
378 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Set App Start: Exit\n"));
379 return A_OK;
380 }
381
382 A_STATUS
383 BMIReadSOCRegister(HIF_DEVICE *device,
384 A_UINT32 address,
385 A_UINT32 *param)
386 {
387 A_UINT32 cid;
388 A_STATUS status;
389 A_UINT32 offset;
390
391 A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address)));
392 memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address));
393
394 if (bmiDone) {
395 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
396 return A_ERROR;
397 }
398
399 AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
400 ("BMI Read SOC Register: Enter (device: 0x%p, address: 0x%x)\n",
401 device, address));
402
403 cid = BMI_READ_SOC_REGISTER;
404
405 offset = 0;
406 A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
407 offset += sizeof(cid);
408 A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address));
409 offset += sizeof(address);
410
411 status = bmiBufferSend(device, pBMICmdBuf, offset);
412 if (status != A_OK) {
413 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
414 return A_ERROR;
415 }
416
417 status = bmiBufferReceive(device, pBMICmdBuf, sizeof(*param), TRUE);
418 if (status != A_OK) {
419 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n"));
420 return A_ERROR;
421 }
422 A_MEMCPY(param, pBMICmdBuf, sizeof(*param));
423
424 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Read SOC Register: Exit (value: %d)\n", *param));
425 return A_OK;
426 }
427
428 A_STATUS
429 BMIWriteSOCRegister(HIF_DEVICE *device,
430 A_UINT32 address,
431 A_UINT32 param)
432 {
433 A_UINT32 cid;
434 A_STATUS status;
435 A_UINT32 offset;
436
437 A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address) + sizeof(param)));
438 memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address) + sizeof(param));
439
440 if (bmiDone) {
441 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
442 return A_ERROR;
443 }
444
445 AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
446 ("BMI Write SOC Register: Enter (device: 0x%p, address: 0x%x, param: %d)\n" ,
447 device, address, param));
448
449 cid = BMI_WRITE_SOC_REGISTER;
450
451 offset = 0;
452 A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
453 offset += sizeof(cid);
454 A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address));
455 offset += sizeof(address);
456 A_MEMCPY(&(pBMICmdBuf[offset]), &param, sizeof(param));
457 offset += sizeof(param);
458 status = bmiBufferSend(device, pBMICmdBuf, offset);
459 if (status != A_OK) {
460 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
461 return A_ERROR;
462 }
463
464 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Read SOC Register: Exit\n"));
465 return A_OK;
466 }
467
468 A_STATUS
469 BMIrompatchInstall(HIF_DEVICE *device,
470 A_UINT32 ROM_addr,
471 A_UINT32 RAM_addr,
472 A_UINT32 nbytes,
473 A_UINT32 do_activate,
474 A_UINT32 *rompatch_id)
475 {
476 A_UINT32 cid;
477 A_STATUS status;
478 A_UINT32 offset;
479
480 A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(ROM_addr) + sizeof(RAM_addr) +
481 sizeof(nbytes) + sizeof(do_activate)));
482 memset(pBMICmdBuf, 0, sizeof(cid) + sizeof(ROM_addr) + sizeof(RAM_addr) +
483 sizeof(nbytes) + sizeof(do_activate));
484
485 if (bmiDone) {
486 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
487 return A_ERROR;
488 }
489
490 AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
491 ("BMI rompatch Install: Enter (device: 0x%p, ROMaddr: 0x%x, RAMaddr: 0x %x length: %d activate: %d)\n",
492 device, ROM_addr, RAM_addr, nbytes, do_activate));
493
494 cid = BMI_ROMPATCH_INSTALL;
495
496 offset = 0;
497 A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
498 offset += sizeof(cid);
499 A_MEMCPY(&(pBMICmdBuf[offset]), &ROM_addr, sizeof(ROM_addr));
500 offset += sizeof(ROM_addr);
501 A_MEMCPY(&(pBMICmdBuf[offset]), &RAM_addr, sizeof(RAM_addr));
502 offset += sizeof(RAM_addr);
503 A_MEMCPY(&(pBMICmdBuf[offset]), &nbytes, sizeof(nbytes));
504 offset += sizeof(nbytes);
505 A_MEMCPY(&(pBMICmdBuf[offset]), &do_activate, sizeof(do_activate));
506 offset += sizeof(do_activate);
507 status = bmiBufferSend(device, pBMICmdBuf, offset);
508 if (status != A_OK) {
509 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
510 return A_ERROR;
511 }
512
513 status = bmiBufferReceive(device, pBMICmdBuf, sizeof(*rompatch_id), TRUE);
514 if (status != A_OK) {
515 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n"));
516 return A_ERROR;
517 }
518 A_MEMCPY(rompatch_id, pBMICmdBuf, sizeof(*rompatch_id));
519
520 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI rompatch Install: (rompatch_id=%d)\n", *rompatch_id));
521 return A_OK;
522 }
523
524 A_STATUS
525 BMIrompatchUninstall(HIF_DEVICE *device,
526 A_UINT32 rompatch_id)
527 {
528 A_UINT32 cid;
529 A_STATUS status;
530 A_UINT32 offset;
531
532 A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(rompatch_id)));
533 memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(rompatch_id));
534
535 if (bmiDone) {
536 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
537 return A_ERROR;
538 }
539
540 AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
541 ("BMI rompatch Uninstall: Enter (device: 0x%p, rompatch_id: %d)\n",
542 device, rompatch_id));
543
544 cid = BMI_ROMPATCH_UNINSTALL;
545
546 offset = 0;
547 A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
548 offset += sizeof(cid);
549 A_MEMCPY(&(pBMICmdBuf[offset]), &rompatch_id, sizeof(rompatch_id));
550 offset += sizeof(rompatch_id);
551 status = bmiBufferSend(device, pBMICmdBuf, offset);
552 if (status != A_OK) {
553 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
554 return A_ERROR;
555 }
556
557 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI rompatch UNinstall: (rompatch_id=0x%x)\ n", rompatch_id));
558 return A_OK;
559 }
560
561 static A_STATUS
562 _BMIrompatchChangeActivation(HIF_DEVICE *device,
563 A_UINT32 rompatch_count,
564 A_UINT32 *rompatch_list,
565 A_UINT32 do_activate)
566 {
567 A_UINT32 cid;
568 A_STATUS status;
569 A_UINT32 offset;
570 A_UINT32 length;
571
572 A_ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX + sizeof(cid) + sizeof(rompatch_cou nt)));
573 memset(pBMICmdBuf, 0, BMI_DATASZ_MAX + sizeof(cid) + sizeof(rompatch_count)) ;
574
575 if (bmiDone) {
576 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
577 return A_ERROR;
578 }
579
580 AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
581 ("BMI Change rompatch Activation: Enter (device: 0x%p, count: %d)\n",
582 device, rompatch_count));
583
584 cid = do_activate ? BMI_ROMPATCH_ACTIVATE : BMI_ROMPATCH_DEACTIVATE;
585
586 offset = 0;
587 A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
588 offset += sizeof(cid);
589 A_MEMCPY(&(pBMICmdBuf[offset]), &rompatch_count, sizeof(rompatch_count));
590 offset += sizeof(rompatch_count);
591 length = rompatch_count * sizeof(*rompatch_list);
592 A_MEMCPY(&(pBMICmdBuf[offset]), rompatch_list, length);
593 offset += length;
594 status = bmiBufferSend(device, pBMICmdBuf, offset);
595 if (status != A_OK) {
596 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
597 return A_ERROR;
598 }
599
600 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Change rompatch Activation: Exit\n"));
601
602 return A_OK;
603 }
604
605 A_STATUS
606 BMIrompatchActivate(HIF_DEVICE *device,
607 A_UINT32 rompatch_count,
608 A_UINT32 *rompatch_list)
609 {
610 return _BMIrompatchChangeActivation(device, rompatch_count, rompatch_list, 1 );
611 }
612
613 A_STATUS
614 BMIrompatchDeactivate(HIF_DEVICE *device,
615 A_UINT32 rompatch_count,
616 A_UINT32 *rompatch_list)
617 {
618 return _BMIrompatchChangeActivation(device, rompatch_count, rompatch_list, 0 );
619 }
620
621 A_STATUS
622 BMILZData(HIF_DEVICE *device,
623 A_UCHAR *buffer,
624 A_UINT32 length)
625 {
626 A_UINT32 cid;
627 A_STATUS status;
628 A_UINT32 offset;
629 A_UINT32 remaining, txlen;
630 const A_UINT32 header = sizeof(cid) + sizeof(length);
631
632 A_ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX+header));
633 memset (pBMICmdBuf, 0, BMI_DATASZ_MAX+header);
634
635 if (bmiDone) {
636 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
637 return A_ERROR;
638 }
639
640 AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
641 ("BMI Send LZ Data: Enter (device: 0x%p, length: %d)\n",
642 device, length));
643
644 cid = BMI_LZ_DATA;
645
646 remaining = length;
647 while (remaining)
648 {
649 txlen = (remaining < (BMI_DATASZ_MAX - header)) ?
650 remaining : (BMI_DATASZ_MAX - header);
651 offset = 0;
652 A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
653 offset += sizeof(cid);
654 A_MEMCPY(&(pBMICmdBuf[offset]), &txlen, sizeof(txlen));
655 offset += sizeof(txlen);
656 A_MEMCPY(&(pBMICmdBuf[offset]), &buffer[length - remaining], txlen);
657 offset += txlen;
658 status = bmiBufferSend(device, pBMICmdBuf, offset);
659 if (status != A_OK) {
660 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
661 return A_ERROR;
662 }
663 remaining -= txlen;
664 }
665
666 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI LZ Data: Exit\n"));
667
668 return A_OK;
669 }
670
671 A_STATUS
672 BMILZStreamStart(HIF_DEVICE *device,
673 A_UINT32 address)
674 {
675 A_UINT32 cid;
676 A_STATUS status;
677 A_UINT32 offset;
678
679 A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address)));
680 memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address));
681
682 if (bmiDone) {
683 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
684 return A_ERROR;
685 }
686
687 AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
688 ("BMI LZ Stream Start: Enter (device: 0x%p, address: 0x%x)\n",
689 device, address));
690
691 cid = BMI_LZ_STREAM_START;
692 offset = 0;
693 A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
694 offset += sizeof(cid);
695 A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address));
696 offset += sizeof(address);
697 status = bmiBufferSend(device, pBMICmdBuf, offset);
698 if (status != A_OK) {
699 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to Start LZ Stream to the device \n"));
700 return A_ERROR;
701 }
702
703 AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI LZ Stream Start: Exit\n"));
704
705 return A_OK;
706 }
707
708 /* BMI Access routines */
709 A_STATUS
710 bmiBufferSend(HIF_DEVICE *device,
711 A_UCHAR *buffer,
712 A_UINT32 length)
713 {
714 A_STATUS status;
715 A_UINT32 timeout;
716 A_UINT32 address;
717 A_UINT32 mboxAddress[HTC_MAILBOX_NUM_MAX];
718
719 HIFConfigureDevice(device, HIF_DEVICE_GET_MBOX_ADDR,
720 &mboxAddress[0], sizeof(mboxAddress));
721
722 *pBMICmdCredits = 0;
723 timeout = BMI_COMMUNICATION_TIMEOUT;
724
725 while(timeout-- && !(*pBMICmdCredits)) {
726 /* Read the counter register to get the command credits */
727 address = COUNT_DEC_ADDRESS + (HTC_MAILBOX_NUM_MAX + ENDPOINT1) * 4;
728 /* hit the credit counter with a 4-byte access, the first byte read will hit the counter and cause
729 * a decrement, while the remaining 3 bytes has no effect. The rational e behind this is to
730 * make all HIF accesses 4-byte aligned */
731 status = HIFReadWrite(device, address, (A_UINT8 *)pBMICmdCredits, 4,
732 HIF_RD_SYNC_BYTE_INC, NULL);
733 if (status != A_OK) {
734 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to decrement the command cre dit count register\n"));
735 return A_ERROR;
736 }
737 /* the counter is only 8=bits, ignore anything in the upper 3 bytes */
738 (*pBMICmdCredits) &= 0xFF;
739 }
740
741 if (*pBMICmdCredits) {
742 address = mboxAddress[ENDPOINT1];
743 status = HIFReadWrite(device, address, buffer, length,
744 HIF_WR_SYNC_BYTE_INC, NULL);
745 if (status != A_OK) {
746 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to send the BMI data to the device\n"));
747 return A_ERROR;
748 }
749 } else {
750 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI Communication timeout - bmiBufferSe nd\n"));
751 return A_ERROR;
752 }
753
754 return status;
755 }
756
757 A_STATUS
758 bmiBufferReceive(HIF_DEVICE *device,
759 A_UCHAR *buffer,
760 A_UINT32 length,
761 A_BOOL want_timeout)
762 {
763 A_STATUS status;
764 A_UINT32 address;
765 A_UINT32 mboxAddress[HTC_MAILBOX_NUM_MAX];
766 HIF_PENDING_EVENTS_INFO hifPendingEvents;
767 static HIF_PENDING_EVENTS_FUNC getPendingEventsFunc = NULL;
768
769 if (!pendingEventsFuncCheck) {
770 /* see if the HIF layer implements an alternative function to get pe nding events
771 * do this only once! */
772 HIFConfigureDevice(device,
773 HIF_DEVICE_GET_PENDING_EVENTS_FUNC,
774 &getPendingEventsFunc,
775 sizeof(getPendingEventsFunc));
776 pendingEventsFuncCheck = TRUE;
777 }
778
779 HIFConfigureDevice(device, HIF_DEVICE_GET_MBOX_ADDR,
780 &mboxAddress[0], sizeof(mboxAddress));
781
782 /*
783 * During normal bootup, small reads may be required.
784 * Rather than issue an HIF Read and then wait as the Target
785 * adds successive bytes to the FIFO, we wait here until
786 * we know that response data is available.
787 *
788 * This allows us to cleanly timeout on an unexpected
789 * Target failure rather than risk problems at the HIF level. In
790 * particular, this avoids SDIO timeouts and possibly garbage
791 * data on some host controllers. And on an interconnect
792 * such as Compact Flash (as well as some SDIO masters) which
793 * does not provide any indication on data timeout, it avoids
794 * a potential hang or garbage response.
795 *
796 * Synchronization is more difficult for reads larger than the
797 * size of the MBOX FIFO (128B), because the Target is unable
798 * to push the 129th byte of data until AFTER the Host posts an
799 * HIF Read and removes some FIFO data. So for large reads the
800 * Host proceeds to post an HIF Read BEFORE all the data is
801 * actually available to read. Fortunately, large BMI reads do
802 * not occur in practice -- they're supported for debug/development.
803 *
804 * So Host/Target BMI synchronization is divided into these cases:
805 * CASE 1: length < 4
806 * Should not happen
807 *
808 * CASE 2: 4 <= length <= 128
809 * Wait for first 4 bytes to be in FIFO
810 * If CONSERVATIVE_BMI_READ is enabled, also wait for
811 * a BMI command credit, which indicates that the ENTIRE
812 * response is available in the the FIFO
813 *
814 * CASE 3: length > 128
815 * Wait for the first 4 bytes to be in FIFO
816 *
817 * For most uses, a small timeout should be sufficient and we will
818 * usually see a response quickly; but there may be some unusual
819 * (debug) cases of BMI_EXECUTE where we want an larger timeout.
820 * For now, we use an unbounded busy loop while waiting for
821 * BMI_EXECUTE.
822 *
823 * If BMI_EXECUTE ever needs to support longer-latency execution,
824 * especially in production, this code needs to be enhanced to sleep
825 * and yield. Also note that BMI_COMMUNICATION_TIMEOUT is currently
826 * a function of Host processor speed.
827 */
828 if (length >= 4) { /* NB: Currently, always true */
829 /*
830 * NB: word_available is declared static for esoteric reasons
831 * having to do with protection on some OSes.
832 */
833 static A_UINT32 word_available;
834 A_UINT32 timeout;
835
836 word_available = 0;
837 timeout = BMI_COMMUNICATION_TIMEOUT;
838 while((!want_timeout || timeout--) && !word_available) {
839
840 if (getPendingEventsFunc != NULL) {
841 status = getPendingEventsFunc(device,
842 &hifPendingEvents,
843 NULL);
844 if (status != A_OK) {
845 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMI: Failed to get pending e vents \n"));
846 break;
847 }
848
849 if (hifPendingEvents.AvailableRecvBytes >= sizeof(A_UINT32)) {
850 word_available = 1;
851 }
852 continue;
853 }
854
855 status = HIFReadWrite(device, RX_LOOKAHEAD_VALID_ADDRESS, (A_UINT8 * )&word_available,
856 sizeof(word_available), HIF_RD_SYNC_BYTE_INC, NULL);
857 if (status != A_OK) {
858 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read RX_LOOKAHEAD_VAL ID register\n"));
859 return A_ERROR;
860 }
861 /* We did a 4-byte read to the same register; all we really want is one bit */
862 word_available &= (1 << ENDPOINT1);
863 }
864
865 if (!word_available) {
866 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI Communication timeout - bmiBuff erReceive FIFO empty\n"));
867 return A_ERROR;
868 }
869 }
870
871 #define CONSERVATIVE_BMI_READ 0
872 #if CONSERVATIVE_BMI_READ
873 /*
874 * This is an extra-conservative CREDIT check. It guarantees
875 * that ALL data is available in the FIFO before we start to
876 * read from the interconnect.
877 *
878 * This credit check is useless when firmware chooses to
879 * allow multiple outstanding BMI Command Credits, since the next
880 * credit will already be present. To restrict the Target to one
881 * BMI Command Credit, see HI_OPTION_BMI_CRED_LIMIT.
882 *
883 * And for large reads (when HI_OPTION_BMI_CRED_LIMIT is set)
884 * we cannot wait for the next credit because the Target's FIFO
885 * will not hold the entire response. So we need the Host to
886 * start to empty the FIFO sooner. (And again, large reads are
887 * not used in practice; they are for debug/development only.)
888 *
889 * For a more conservative Host implementation (which would be
890 * safer for a Compact Flash interconnect):
891 * Set CONSERVATIVE_BMI_READ (above) to 1
892 * Set HI_OPTION_BMI_CRED_LIMIT and
893 * reduce BMI_DATASZ_MAX to 32 or 64
894 */
895 if ((length > 4) && (length < 128)) { /* check against MBOX FIFO size */
896 A_UINT32 timeout;
897
898 *pBMICmdCredits = 0;
899 timeout = BMI_COMMUNICATION_TIMEOUT;
900 while((!want_timeout || timeout--) && !(*pBMICmdCredits) {
901 /* Read the counter register to get the command credits */
902 address = COUNT_ADDRESS + (HTC_MAILBOX_NUM_MAX + ENDPOINT1) * 1;
903 /* read the counter using a 4-byte read. Since the counter is NOT a uto-decrementing,
904 * we can read this counter multiple times using a non-incrementing address mode.
905 * The rationale here is to make all HIF accesses a multiple of 4 by tes */
906 status = HIFReadWrite(device, address, (A_UINT8 *)pBMICmdCredits, si zeof(*pBMICmdCredits),
907 HIF_RD_SYNC_BYTE_FIX, NULL);
908 if (status != A_OK) {
909 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read the command cred it count register\n"));
910 return A_ERROR;
911 }
912 /* we did a 4-byte read to the same count register so mask off u pper bytes */
913 (*pBMICmdCredits) &= 0xFF;
914 }
915
916 if (!(*pBMICmdCredits)) {
917 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI Communication timeout- bmiBuffe rReceive no credit\n"));
918 return A_ERROR;
919 }
920 }
921 #endif
922
923 address = mboxAddress[ENDPOINT1];
924 status = HIFReadWrite(device, address, buffer, length, HIF_RD_SYNC_BYTE_INC, NULL);
925 if (status != A_OK) {
926 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read the BMI data from the de vice\n"));
927 return A_ERROR;
928 }
929
930 return A_OK;
931 }
932
933 A_STATUS
934 BMIFastDownload(HIF_DEVICE *device, A_UINT32 address, A_UCHAR *buffer, A_UINT32 length)
935 {
936 A_STATUS status = A_ERROR;
937 A_UINT32 lastWord = 0;
938 A_UINT32 lastWordOffset = length & ~0x3;
939 A_UINT32 unalignedBytes = length & 0x3;
940
941 status = BMILZStreamStart (device, address);
942 if (A_FAILED(status)) {
943 return A_ERROR;
944 }
945
946 if (unalignedBytes) {
947 /* copy the last word into a zero padded buffer */
948 A_MEMCPY(&lastWord, &buffer[lastWordOffset], unalignedBytes);
949 }
950
951 status = BMILZData(device, buffer, lastWordOffset);
952
953 if (A_FAILED(status)) {
954 return A_ERROR;
955 }
956
957 if (unalignedBytes) {
958 status = BMILZData(device, (A_UINT8 *)&lastWord, 4);
959 }
960
961 if (A_SUCCESS(status)) {
962 //
963 // Close compressed stream and open a new (fake) one. This serves mainl y to flush Target caches.
964 //
965 status = BMILZStreamStart (device, 0x00);
966 if (A_FAILED(status)) {
967 return A_ERROR;
968 }
969 }
970 return status;
971 }
972
973 A_STATUS
974 BMIRawWrite(HIF_DEVICE *device, A_UCHAR *buffer, A_UINT32 length)
975 {
976 return bmiBufferSend(device, buffer, length);
977 }
978
979 A_STATUS
980 BMIRawRead(HIF_DEVICE *device, A_UCHAR *buffer, A_UINT32 length, A_BOOL want_tim eout)
981 {
982 return bmiBufferReceive(device, buffer, length, want_timeout);
983 }
OLDNEW
« no previous file with comments | « chromeos/drivers/ath6kl/bmi/include/bmi_internal.h ('k') | chromeos/drivers/ath6kl/bmi/src/makefile » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698