1
//------------------------------------------------------------------------------
2
// <copyright file="bmi.c" company="Atheros">
3
// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
6
// Permission to use, copy, modify, and/or distribute this software for any
7
// purpose with or without fee is hereby granted, provided that the above
8
// copyright notice and this permission notice appear in all copies.
10
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
//------------------------------------------------------------------------------
20
//==============================================================================
22
// Author(s): ="Atheros"
23
//==============================================================================
33
#include "bmi_internal.h"
35
#ifdef ATH_DEBUG_MODULE
36
static ATH_DEBUG_MASK_DESCRIPTION bmi_debug_desc[] = {
37
{ ATH_DEBUG_BMI , "BMI Tracing"},
40
ATH_DEBUG_INSTANTIATE_MODULE_VAR(bmi,
42
"Boot Manager Interface",
43
ATH_DEBUG_MASK_DEFAULTS,
44
ATH_DEBUG_DESCRIPTION_COUNT(bmi_debug_desc),
50
Although we had envisioned BMI to run on top of HTC, this is not how the
51
final implementation ended up. On the Target side, BMI is a part of the BSP
52
and does not use the HTC protocol nor even DMA -- it is intentionally kept
56
static A_BOOL pendingEventsFuncCheck = FALSE;
57
static A_UINT32 *pBMICmdCredits;
58
static A_UCHAR *pBMICmdBuf;
59
#define MAX_BMI_CMDBUF_SZ (BMI_DATASZ_MAX + \
60
sizeof(A_UINT32) /* cmd */ + \
61
sizeof(A_UINT32) /* addr */ + \
62
sizeof(A_UINT32))/* length */
63
#define BMI_COMMAND_FITS(sz) ((sz) <= MAX_BMI_CMDBUF_SZ)
65
/* APIs visible to the driver */
70
pendingEventsFuncCheck = FALSE;
73
* On some platforms, it's not possible to DMA to a static variable
74
* in a device driver (e.g. Linux loadable driver module).
75
* So we need to A_MALLOC space for "command credits" and for commands.
77
* Note: implicitly relies on A_MALLOC to provide a buffer that is
78
* suitable for DMA (or PIO). This buffer will be passed down the
81
if (!pBMICmdCredits) {
82
pBMICmdCredits = (A_UINT32 *)A_MALLOC_NOWAIT(4);
83
A_ASSERT(pBMICmdCredits);
87
pBMICmdBuf = (A_UCHAR *)A_MALLOC_NOWAIT(MAX_BMI_CMDBUF_SZ);
91
A_REGISTER_MODULE_DEBUG_INFO(bmi);
98
A_FREE(pBMICmdCredits);
99
pBMICmdCredits = NULL;
109
BMIDone(HIF_DEVICE *device)
115
AR_DEBUG_PRINTF (ATH_DEBUG_BMI, ("BMIDone skipped\n"));
119
AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Done: Enter (device: 0x%p)\n", device));
123
status = bmiBufferSend(device, (A_UCHAR *)&cid, sizeof(cid));
124
if (status != A_OK) {
125
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
129
if (pBMICmdCredits) {
130
A_FREE(pBMICmdCredits);
131
pBMICmdCredits = NULL;
139
AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Done: Exit\n"));
145
BMIGetTargetInfo(HIF_DEVICE *device, struct bmi_target_info *targ_info)
151
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
155
AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Get Target Info: Enter (device: 0x%p)\n", device));
156
cid = BMI_GET_TARGET_INFO;
158
status = bmiBufferSend(device, (A_UCHAR *)&cid, sizeof(cid));
159
if (status != A_OK) {
160
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
164
status = bmiBufferReceive(device, (A_UCHAR *)&targ_info->target_ver,
165
sizeof(targ_info->target_ver), TRUE);
166
if (status != A_OK) {
167
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read Target Version from the device\n"));
171
if (targ_info->target_ver == TARGET_VERSION_SENTINAL) {
172
/* Determine how many bytes are in the Target's targ_info */
173
status = bmiBufferReceive(device, (A_UCHAR *)&targ_info->target_info_byte_count,
174
sizeof(targ_info->target_info_byte_count), TRUE);
175
if (status != A_OK) {
176
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read Target Info Byte Count from the device\n"));
181
* The Target's targ_info doesn't match the Host's targ_info.
182
* We need to do some backwards compatibility work to make this OK.
184
A_ASSERT(targ_info->target_info_byte_count == sizeof(*targ_info));
186
/* Read the remainder of the targ_info */
187
status = bmiBufferReceive(device,
188
((A_UCHAR *)targ_info)+sizeof(targ_info->target_info_byte_count),
189
sizeof(*targ_info)-sizeof(targ_info->target_info_byte_count), TRUE);
190
if (status != A_OK) {
191
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read Target Info (%d bytes) from the device\n",
192
targ_info->target_info_byte_count));
197
AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Get Target Info: Exit (ver: 0x%x type: 0x%x)\n",
198
targ_info->target_ver, targ_info->target_type));
204
BMIReadMemory(HIF_DEVICE *device,
212
A_UINT32 remaining, rxlen;
214
A_ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX + sizeof(cid) + sizeof(address) + sizeof(length)));
215
memset (pBMICmdBuf, 0, BMI_DATASZ_MAX + sizeof(cid) + sizeof(address) + sizeof(length));
218
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
222
AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
223
("BMI Read Memory: Enter (device: 0x%p, address: 0x%x, length: %d)\n",
224
device, address, length));
226
cid = BMI_READ_MEMORY;
232
rxlen = (remaining < BMI_DATASZ_MAX) ? remaining : BMI_DATASZ_MAX;
234
A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
235
offset += sizeof(cid);
236
A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address));
237
offset += sizeof(address);
238
A_MEMCPY(&(pBMICmdBuf[offset]), &rxlen, sizeof(rxlen));
239
offset += sizeof(length);
241
status = bmiBufferSend(device, pBMICmdBuf, offset);
242
if (status != A_OK) {
243
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
246
status = bmiBufferReceive(device, pBMICmdBuf, rxlen, TRUE);
247
if (status != A_OK) {
248
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n"));
251
A_MEMCPY(&buffer[length - remaining], pBMICmdBuf, rxlen);
252
remaining -= rxlen; address += rxlen;
255
AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Read Memory: Exit\n"));
260
BMIWriteMemory(HIF_DEVICE *device,
268
A_UINT32 remaining, txlen;
269
const A_UINT32 header = sizeof(cid) + sizeof(address) + sizeof(length);
270
A_UCHAR alignedBuffer[BMI_DATASZ_MAX];
273
A_ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX + header));
274
memset (pBMICmdBuf, 0, BMI_DATASZ_MAX + header);
277
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
281
AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
282
("BMI Write Memory: Enter (device: 0x%p, address: 0x%x, length: %d)\n",
283
device, address, length));
285
cid = BMI_WRITE_MEMORY;
290
src = &buffer[length - remaining];
291
if (remaining < (BMI_DATASZ_MAX - header)) {
293
/* align it with 4 bytes */
294
remaining = remaining + (4 - (remaining & 3));
295
memcpy(alignedBuffer, src, remaining);
300
txlen = (BMI_DATASZ_MAX - header);
303
A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
304
offset += sizeof(cid);
305
A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address));
306
offset += sizeof(address);
307
A_MEMCPY(&(pBMICmdBuf[offset]), &txlen, sizeof(txlen));
308
offset += sizeof(txlen);
309
A_MEMCPY(&(pBMICmdBuf[offset]), src, txlen);
311
status = bmiBufferSend(device, pBMICmdBuf, offset);
312
if (status != A_OK) {
313
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
316
remaining -= txlen; address += txlen;
319
AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Write Memory: Exit\n"));
325
BMIExecute(HIF_DEVICE *device,
333
A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address) + sizeof(param)));
334
memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address) + sizeof(param));
337
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
341
AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
342
("BMI Execute: Enter (device: 0x%p, address: 0x%x, param: %d)\n",
343
device, address, *param));
348
A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
349
offset += sizeof(cid);
350
A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address));
351
offset += sizeof(address);
352
A_MEMCPY(&(pBMICmdBuf[offset]), param, sizeof(*param));
353
offset += sizeof(*param);
354
status = bmiBufferSend(device, pBMICmdBuf, offset);
355
if (status != A_OK) {
356
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
360
status = bmiBufferReceive(device, pBMICmdBuf, sizeof(*param), FALSE);
361
if (status != A_OK) {
362
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n"));
366
A_MEMCPY(param, pBMICmdBuf, sizeof(*param));
368
AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Execute: Exit (param: %d)\n", *param));
373
BMISetAppStart(HIF_DEVICE *device,
380
A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address)));
381
memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address));
384
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
388
AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
389
("BMI Set App Start: Enter (device: 0x%p, address: 0x%x)\n",
392
cid = BMI_SET_APP_START;
395
A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
396
offset += sizeof(cid);
397
A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address));
398
offset += sizeof(address);
399
status = bmiBufferSend(device, pBMICmdBuf, offset);
400
if (status != A_OK) {
401
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
405
AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Set App Start: Exit\n"));
410
BMIReadSOCRegister(HIF_DEVICE *device,
418
A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address)));
419
memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address));
422
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
426
AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
427
("BMI Read SOC Register: Enter (device: 0x%p, address: 0x%x)\n",
430
cid = BMI_READ_SOC_REGISTER;
433
A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
434
offset += sizeof(cid);
435
A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address));
436
offset += sizeof(address);
438
status = bmiBufferSend(device, pBMICmdBuf, offset);
439
if (status != A_OK) {
440
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
444
status = bmiBufferReceive(device, pBMICmdBuf, sizeof(*param), TRUE);
445
if (status != A_OK) {
446
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n"));
449
A_MEMCPY(param, pBMICmdBuf, sizeof(*param));
451
AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Read SOC Register: Exit (value: %d)\n", *param));
456
BMIWriteSOCRegister(HIF_DEVICE *device,
464
A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address) + sizeof(param)));
465
memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address) + sizeof(param));
468
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
472
AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
473
("BMI Write SOC Register: Enter (device: 0x%p, address: 0x%x, param: %d)\n",
474
device, address, param));
476
cid = BMI_WRITE_SOC_REGISTER;
479
A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
480
offset += sizeof(cid);
481
A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address));
482
offset += sizeof(address);
483
A_MEMCPY(&(pBMICmdBuf[offset]), ¶m, sizeof(param));
484
offset += sizeof(param);
485
status = bmiBufferSend(device, pBMICmdBuf, offset);
486
if (status != A_OK) {
487
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
491
AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Read SOC Register: Exit\n"));
496
BMIrompatchInstall(HIF_DEVICE *device,
500
A_UINT32 do_activate,
501
A_UINT32 *rompatch_id)
507
A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(ROM_addr) + sizeof(RAM_addr) +
508
sizeof(nbytes) + sizeof(do_activate)));
509
memset(pBMICmdBuf, 0, sizeof(cid) + sizeof(ROM_addr) + sizeof(RAM_addr) +
510
sizeof(nbytes) + sizeof(do_activate));
513
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
517
AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
518
("BMI rompatch Install: Enter (device: 0x%p, ROMaddr: 0x%x, RAMaddr: 0x%x length: %d activate: %d)\n",
519
device, ROM_addr, RAM_addr, nbytes, do_activate));
521
cid = BMI_ROMPATCH_INSTALL;
524
A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
525
offset += sizeof(cid);
526
A_MEMCPY(&(pBMICmdBuf[offset]), &ROM_addr, sizeof(ROM_addr));
527
offset += sizeof(ROM_addr);
528
A_MEMCPY(&(pBMICmdBuf[offset]), &RAM_addr, sizeof(RAM_addr));
529
offset += sizeof(RAM_addr);
530
A_MEMCPY(&(pBMICmdBuf[offset]), &nbytes, sizeof(nbytes));
531
offset += sizeof(nbytes);
532
A_MEMCPY(&(pBMICmdBuf[offset]), &do_activate, sizeof(do_activate));
533
offset += sizeof(do_activate);
534
status = bmiBufferSend(device, pBMICmdBuf, offset);
535
if (status != A_OK) {
536
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
540
status = bmiBufferReceive(device, pBMICmdBuf, sizeof(*rompatch_id), TRUE);
541
if (status != A_OK) {
542
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n"));
545
A_MEMCPY(rompatch_id, pBMICmdBuf, sizeof(*rompatch_id));
547
AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI rompatch Install: (rompatch_id=%d)\n", *rompatch_id));
552
BMIrompatchUninstall(HIF_DEVICE *device,
553
A_UINT32 rompatch_id)
559
A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(rompatch_id)));
560
memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(rompatch_id));
563
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
567
AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
568
("BMI rompatch Uninstall: Enter (device: 0x%p, rompatch_id: %d)\n",
569
device, rompatch_id));
571
cid = BMI_ROMPATCH_UNINSTALL;
574
A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
575
offset += sizeof(cid);
576
A_MEMCPY(&(pBMICmdBuf[offset]), &rompatch_id, sizeof(rompatch_id));
577
offset += sizeof(rompatch_id);
578
status = bmiBufferSend(device, pBMICmdBuf, offset);
579
if (status != A_OK) {
580
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
584
AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI rompatch UNinstall: (rompatch_id=0x%x)\n", rompatch_id));
589
_BMIrompatchChangeActivation(HIF_DEVICE *device,
590
A_UINT32 rompatch_count,
591
A_UINT32 *rompatch_list,
592
A_UINT32 do_activate)
599
A_ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX + sizeof(cid) + sizeof(rompatch_count)));
600
memset(pBMICmdBuf, 0, BMI_DATASZ_MAX + sizeof(cid) + sizeof(rompatch_count));
603
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
607
AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
608
("BMI Change rompatch Activation: Enter (device: 0x%p, count: %d)\n",
609
device, rompatch_count));
611
cid = do_activate ? BMI_ROMPATCH_ACTIVATE : BMI_ROMPATCH_DEACTIVATE;
614
A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
615
offset += sizeof(cid);
616
A_MEMCPY(&(pBMICmdBuf[offset]), &rompatch_count, sizeof(rompatch_count));
617
offset += sizeof(rompatch_count);
618
length = rompatch_count * sizeof(*rompatch_list);
619
A_MEMCPY(&(pBMICmdBuf[offset]), rompatch_list, length);
621
status = bmiBufferSend(device, pBMICmdBuf, offset);
622
if (status != A_OK) {
623
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
627
AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Change rompatch Activation: Exit\n"));
633
BMIrompatchActivate(HIF_DEVICE *device,
634
A_UINT32 rompatch_count,
635
A_UINT32 *rompatch_list)
637
return _BMIrompatchChangeActivation(device, rompatch_count, rompatch_list, 1);
641
BMIrompatchDeactivate(HIF_DEVICE *device,
642
A_UINT32 rompatch_count,
643
A_UINT32 *rompatch_list)
645
return _BMIrompatchChangeActivation(device, rompatch_count, rompatch_list, 0);
649
BMILZData(HIF_DEVICE *device,
656
A_UINT32 remaining, txlen;
657
const A_UINT32 header = sizeof(cid) + sizeof(length);
659
A_ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX+header));
660
memset (pBMICmdBuf, 0, BMI_DATASZ_MAX+header);
663
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
667
AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
668
("BMI Send LZ Data: Enter (device: 0x%p, length: %d)\n",
676
txlen = (remaining < (BMI_DATASZ_MAX - header)) ?
677
remaining : (BMI_DATASZ_MAX - header);
679
A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
680
offset += sizeof(cid);
681
A_MEMCPY(&(pBMICmdBuf[offset]), &txlen, sizeof(txlen));
682
offset += sizeof(txlen);
683
A_MEMCPY(&(pBMICmdBuf[offset]), &buffer[length - remaining], txlen);
685
status = bmiBufferSend(device, pBMICmdBuf, offset);
686
if (status != A_OK) {
687
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
693
AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI LZ Data: Exit\n"));
699
BMILZStreamStart(HIF_DEVICE *device,
706
A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address)));
707
memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address));
710
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
714
AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
715
("BMI LZ Stream Start: Enter (device: 0x%p, address: 0x%x)\n",
718
cid = BMI_LZ_STREAM_START;
720
A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
721
offset += sizeof(cid);
722
A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address));
723
offset += sizeof(address);
724
status = bmiBufferSend(device, pBMICmdBuf, offset);
725
if (status != A_OK) {
726
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to Start LZ Stream to the device\n"));
730
AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI LZ Stream Start: Exit\n"));
735
/* BMI Access routines */
737
bmiBufferSend(HIF_DEVICE *device,
744
A_UINT32 mboxAddress[HTC_MAILBOX_NUM_MAX];
746
HIFConfigureDevice(device, HIF_DEVICE_GET_MBOX_ADDR,
747
&mboxAddress[0], sizeof(mboxAddress));
750
timeout = BMI_COMMUNICATION_TIMEOUT;
752
while(timeout-- && !(*pBMICmdCredits)) {
753
/* Read the counter register to get the command credits */
754
address = COUNT_DEC_ADDRESS + (HTC_MAILBOX_NUM_MAX + ENDPOINT1) * 4;
755
/* hit the credit counter with a 4-byte access, the first byte read will hit the counter and cause
756
* a decrement, while the remaining 3 bytes has no effect. The rationale behind this is to
757
* make all HIF accesses 4-byte aligned */
758
status = HIFReadWrite(device, address, (A_UINT8 *)pBMICmdCredits, 4,
759
HIF_RD_SYNC_BYTE_INC, NULL);
760
if (status != A_OK) {
761
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to decrement the command credit count register\n"));
764
/* the counter is only 8=bits, ignore anything in the upper 3 bytes */
765
(*pBMICmdCredits) &= 0xFF;
768
if (*pBMICmdCredits) {
769
address = mboxAddress[ENDPOINT1];
770
status = HIFReadWrite(device, address, buffer, length,
771
HIF_WR_SYNC_BYTE_INC, NULL);
772
if (status != A_OK) {
773
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to send the BMI data to the device\n"));
777
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI Communication timeout - bmiBufferSend\n"));
785
bmiBufferReceive(HIF_DEVICE *device,
792
A_UINT32 mboxAddress[HTC_MAILBOX_NUM_MAX];
793
HIF_PENDING_EVENTS_INFO hifPendingEvents;
794
static HIF_PENDING_EVENTS_FUNC getPendingEventsFunc = NULL;
796
if (!pendingEventsFuncCheck) {
797
/* see if the HIF layer implements an alternative function to get pending events
798
* do this only once! */
799
HIFConfigureDevice(device,
800
HIF_DEVICE_GET_PENDING_EVENTS_FUNC,
801
&getPendingEventsFunc,
802
sizeof(getPendingEventsFunc));
803
pendingEventsFuncCheck = TRUE;
806
HIFConfigureDevice(device, HIF_DEVICE_GET_MBOX_ADDR,
807
&mboxAddress[0], sizeof(mboxAddress));
810
* During normal bootup, small reads may be required.
811
* Rather than issue an HIF Read and then wait as the Target
812
* adds successive bytes to the FIFO, we wait here until
813
* we know that response data is available.
815
* This allows us to cleanly timeout on an unexpected
816
* Target failure rather than risk problems at the HIF level. In
817
* particular, this avoids SDIO timeouts and possibly garbage
818
* data on some host controllers. And on an interconnect
819
* such as Compact Flash (as well as some SDIO masters) which
820
* does not provide any indication on data timeout, it avoids
821
* a potential hang or garbage response.
823
* Synchronization is more difficult for reads larger than the
824
* size of the MBOX FIFO (128B), because the Target is unable
825
* to push the 129th byte of data until AFTER the Host posts an
826
* HIF Read and removes some FIFO data. So for large reads the
827
* Host proceeds to post an HIF Read BEFORE all the data is
828
* actually available to read. Fortunately, large BMI reads do
829
* not occur in practice -- they're supported for debug/development.
831
* So Host/Target BMI synchronization is divided into these cases:
835
* CASE 2: 4 <= length <= 128
836
* Wait for first 4 bytes to be in FIFO
837
* If CONSERVATIVE_BMI_READ is enabled, also wait for
838
* a BMI command credit, which indicates that the ENTIRE
839
* response is available in the the FIFO
841
* CASE 3: length > 128
842
* Wait for the first 4 bytes to be in FIFO
844
* For most uses, a small timeout should be sufficient and we will
845
* usually see a response quickly; but there may be some unusual
846
* (debug) cases of BMI_EXECUTE where we want an larger timeout.
847
* For now, we use an unbounded busy loop while waiting for
850
* If BMI_EXECUTE ever needs to support longer-latency execution,
851
* especially in production, this code needs to be enhanced to sleep
852
* and yield. Also note that BMI_COMMUNICATION_TIMEOUT is currently
853
* a function of Host processor speed.
855
if (length >= 4) { /* NB: Currently, always true */
857
* NB: word_available is declared static for esoteric reasons
858
* having to do with protection on some OSes.
860
static A_UINT32 word_available;
864
timeout = BMI_COMMUNICATION_TIMEOUT;
865
while((!want_timeout || timeout--) && !word_available) {
867
if (getPendingEventsFunc != NULL) {
868
status = getPendingEventsFunc(device,
871
if (status != A_OK) {
872
AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMI: Failed to get pending events \n"));
876
if (hifPendingEvents.AvailableRecvBytes >= sizeof(A_UINT32)) {
882
status = HIFReadWrite(device, RX_LOOKAHEAD_VALID_ADDRESS, (A_UINT8 *)&word_available,
883
sizeof(word_available), HIF_RD_SYNC_BYTE_INC, NULL);
884
if (status != A_OK) {
885
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read RX_LOOKAHEAD_VALID register\n"));
888
/* We did a 4-byte read to the same register; all we really want is one bit */
889
word_available &= (1 << ENDPOINT1);
892
if (!word_available) {
893
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI Communication timeout - bmiBufferReceive FIFO empty\n"));
898
#define CONSERVATIVE_BMI_READ 0
899
#if CONSERVATIVE_BMI_READ
901
* This is an extra-conservative CREDIT check. It guarantees
902
* that ALL data is available in the FIFO before we start to
903
* read from the interconnect.
905
* This credit check is useless when firmware chooses to
906
* allow multiple outstanding BMI Command Credits, since the next
907
* credit will already be present. To restrict the Target to one
908
* BMI Command Credit, see HI_OPTION_BMI_CRED_LIMIT.
910
* And for large reads (when HI_OPTION_BMI_CRED_LIMIT is set)
911
* we cannot wait for the next credit because the Target's FIFO
912
* will not hold the entire response. So we need the Host to
913
* start to empty the FIFO sooner. (And again, large reads are
914
* not used in practice; they are for debug/development only.)
916
* For a more conservative Host implementation (which would be
917
* safer for a Compact Flash interconnect):
918
* Set CONSERVATIVE_BMI_READ (above) to 1
919
* Set HI_OPTION_BMI_CRED_LIMIT and
920
* reduce BMI_DATASZ_MAX to 32 or 64
922
if ((length > 4) && (length < 128)) { /* check against MBOX FIFO size */
926
timeout = BMI_COMMUNICATION_TIMEOUT;
927
while((!want_timeout || timeout--) && !(*pBMICmdCredits) {
928
/* Read the counter register to get the command credits */
929
address = COUNT_ADDRESS + (HTC_MAILBOX_NUM_MAX + ENDPOINT1) * 1;
930
/* read the counter using a 4-byte read. Since the counter is NOT auto-decrementing,
931
* we can read this counter multiple times using a non-incrementing address mode.
932
* The rationale here is to make all HIF accesses a multiple of 4 bytes */
933
status = HIFReadWrite(device, address, (A_UINT8 *)pBMICmdCredits, sizeof(*pBMICmdCredits),
934
HIF_RD_SYNC_BYTE_FIX, NULL);
935
if (status != A_OK) {
936
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read the command credit count register\n"));
939
/* we did a 4-byte read to the same count register so mask off upper bytes */
940
(*pBMICmdCredits) &= 0xFF;
943
if (!(*pBMICmdCredits)) {
944
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI Communication timeout- bmiBufferReceive no credit\n"));
950
address = mboxAddress[ENDPOINT1];
951
status = HIFReadWrite(device, address, buffer, length, HIF_RD_SYNC_BYTE_INC, NULL);
952
if (status != A_OK) {
953
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read the BMI data from the device\n"));
961
BMIFastDownload(HIF_DEVICE *device, A_UINT32 address, A_UCHAR *buffer, A_UINT32 length)
963
A_STATUS status = A_ERROR;
964
A_UINT32 lastWord = 0;
965
A_UINT32 lastWordOffset = length & ~0x3;
966
A_UINT32 unalignedBytes = length & 0x3;
968
status = BMILZStreamStart (device, address);
969
if (A_FAILED(status)) {
973
if (unalignedBytes) {
974
/* copy the last word into a zero padded buffer */
975
A_MEMCPY(&lastWord, &buffer[lastWordOffset], unalignedBytes);
978
status = BMILZData(device, buffer, lastWordOffset);
980
if (A_FAILED(status)) {
984
if (unalignedBytes) {
985
status = BMILZData(device, (A_UINT8 *)&lastWord, 4);
988
if (A_SUCCESS(status)) {
990
// Close compressed stream and open a new (fake) one. This serves mainly to flush Target caches.
992
status = BMILZStreamStart (device, 0x00);
993
if (A_FAILED(status)) {
1001
BMIRawWrite(HIF_DEVICE *device, A_UCHAR *buffer, A_UINT32 length)
1003
return bmiBufferSend(device, buffer, length);
1007
BMIRawRead(HIF_DEVICE *device, A_UCHAR *buffer, A_UINT32 length, A_BOOL want_timeout)
1009
return bmiBufferReceive(device, buffer, length, want_timeout);