Root/target/linux/s3c24xx/files-2.6.30/drivers/ar6000/bmi/bmi.c

1/*
2 * Copyright (c) 2004-2007 Atheros Communications Inc.
3 * All rights reserved.
4 *
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation;
9 *
10 * Software distributed under the License is distributed on an "AS
11 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
12 * implied. See the License for the specific language governing
13 * rights and limitations under the License.
14 *
15 *
16 *
17 */
18
19#include "hif.h"
20#include "bmi.h"
21#include "htc_api.h"
22#include "bmi_internal.h"
23
24/*
25Although we had envisioned BMI to run on top of HTC, this is not what the
26final implementation boiled down to on dragon. Its a part of BSP and does
27not use the HTC protocol either. On the host side, however, we were still
28living with the original idea. I think the time has come to accept the truth
29and separate it from HTC which has been carrying BMI's burden all this while.
30It shall make HTC state machine relatively simpler
31*/
32
33/* APIs visible to the driver */
34void
35BMIInit(void)
36{
37    bmiDone = FALSE;
38}
39
40A_STATUS
41BMIDone(HIF_DEVICE *device)
42{
43    A_STATUS status;
44    A_UINT32 cid;
45
46    if (bmiDone) {
47        AR_DEBUG_PRINTF (ATH_DEBUG_BMI, ("BMIDone skipped\n"));
48        return A_OK;
49    }
50
51    AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Done: Enter (device: 0x%p)\n", device));
52    bmiDone = TRUE;
53    cid = BMI_DONE;
54
55    status = bmiBufferSend(device, (A_UCHAR *)&cid, sizeof(cid));
56    if (status != A_OK) {
57        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
58        return A_ERROR;
59    }
60    AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Done: Exit\n"));
61
62    return A_OK;
63}
64
65A_STATUS
66BMIGetTargetInfo(HIF_DEVICE *device, struct bmi_target_info *targ_info)
67{
68    A_STATUS status;
69    A_UINT32 cid;
70
71    if (bmiDone) {
72        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
73        return A_ERROR;
74    }
75
76    AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Get Target Info: Enter (device: 0x%p)\n", device));
77    cid = BMI_GET_TARGET_INFO;
78
79    status = bmiBufferSend(device, (A_UCHAR *)&cid, sizeof(cid));
80    if (status != A_OK) {
81        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
82        return A_ERROR;
83    }
84
85    status = bmiBufferReceive(device, (A_UCHAR *)&targ_info->target_ver,
86                                                sizeof(targ_info->target_ver));
87    if (status != A_OK) {
88        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read Target Version from the device\n"));
89        return A_ERROR;
90    }
91
92    if (targ_info->target_ver == TARGET_VERSION_SENTINAL) {
93        /* Determine how many bytes are in the Target's targ_info */
94        status = bmiBufferReceive(device, (A_UCHAR *)&targ_info->target_info_byte_count,
95                                            sizeof(targ_info->target_info_byte_count));
96        if (status != A_OK) {
97            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read Target Info Byte Count from the device\n"));
98            return A_ERROR;
99        }
100
101        /*
102         * The Target's targ_info doesn't match the Host's targ_info.
103         * We need to do some backwards compatibility work to make this OK.
104         */
105        A_ASSERT(targ_info->target_info_byte_count == sizeof(*targ_info));
106
107        /* Read the remainder of the targ_info */
108        status = bmiBufferReceive(device,
109                        ((A_UCHAR *)targ_info)+sizeof(targ_info->target_info_byte_count),
110                        sizeof(*targ_info)-sizeof(targ_info->target_info_byte_count));
111        if (status != A_OK) {
112            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read Target Info (%d bytes) from the device\n",
113                                            targ_info->target_info_byte_count));
114            return A_ERROR;
115        }
116    } else {
117        /*
118         * Target must be an AR6001 whose firmware does not
119         * support BMI_GET_TARGET_INFO. Construct the data
120         * that it would have sent.
121         */
122        targ_info->target_info_byte_count = sizeof(targ_info);
123        targ_info->target_type = TARGET_TYPE_AR6001;
124    }
125
126    AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Get Target Info: Exit (ver: 0x%x type: 0x%x)\n",
127                                    targ_info->target_ver, targ_info->target_type));
128    printk("BMI Get Target Info: Exit (ver: 0x%x type: 0x%x)\n",
129       targ_info->target_ver, targ_info->target_type);
130
131    return A_OK;
132}
133
134A_STATUS
135BMIReadMemory(HIF_DEVICE *device,
136              A_UINT32 address,
137              A_UCHAR *buffer,
138              A_UINT32 length)
139{
140    A_UINT32 cid;
141    A_STATUS status;
142    A_UINT32 offset;
143    A_UINT32 remaining, rxlen;
144    static A_UCHAR data[BMI_DATASZ_MAX + sizeof(cid) + sizeof(address) + sizeof(length)];
145    memset (&data, 0, BMI_DATASZ_MAX + sizeof(cid) + sizeof(address) + sizeof(length));
146
147    if (bmiDone) {
148        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
149        return A_ERROR;
150    }
151
152    AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
153                   ("BMI Read Memory: Enter (device: 0x%p, address: 0x%x, length: %d)\n",
154                    device, address, length));
155
156    cid = BMI_READ_MEMORY;
157
158    remaining = length;
159
160    while (remaining)
161    {
162        rxlen = (remaining < BMI_DATASZ_MAX) ? remaining : BMI_DATASZ_MAX;
163        offset = 0;
164        A_MEMCPY(&data[offset], &cid, sizeof(cid));
165        offset += sizeof(cid);
166        A_MEMCPY(&data[offset], &address, sizeof(address));
167        offset += sizeof(address);
168        A_MEMCPY(&data[offset], &rxlen, sizeof(rxlen));
169        offset += sizeof(length);
170
171        status = bmiBufferSend(device, data, offset);
172        if (status != A_OK) {
173            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
174            return A_ERROR;
175        }
176        status = bmiBufferReceive(device, data, rxlen);
177        if (status != A_OK) {
178            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n"));
179            return A_ERROR;
180        }
181        A_MEMCPY(&buffer[length - remaining], data, rxlen);
182        remaining -= rxlen; address += rxlen;
183    }
184
185    AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Read Memory: Exit\n"));
186    return A_OK;
187}
188
189A_STATUS
190BMIWriteMemory(HIF_DEVICE *device,
191               A_UINT32 address,
192               A_UCHAR *buffer,
193               A_UINT32 length)
194{
195    A_UINT32 cid;
196    A_STATUS status;
197    A_UINT32 offset;
198    A_UINT32 remaining, txlen;
199    const A_UINT32 header = sizeof(cid) + sizeof(address) + sizeof(length);
200    static A_UCHAR data[BMI_DATASZ_MAX + sizeof(cid) + sizeof(address) + sizeof(length)];
201    memset (&data, 0, header);
202
203    if (bmiDone) {
204        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
205        return A_ERROR;
206    }
207
208    AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
209         ("BMI Write Memory: Enter (device: 0x%p, address: 0x%x, length: %d)\n",
210         device, address, length));
211
212    cid = BMI_WRITE_MEMORY;
213
214    remaining = length;
215    while (remaining)
216    {
217        txlen = (remaining < (BMI_DATASZ_MAX - header)) ?
218                                       remaining : (BMI_DATASZ_MAX - header);
219        offset = 0;
220        A_MEMCPY(&data[offset], &cid, sizeof(cid));
221        offset += sizeof(cid);
222        A_MEMCPY(&data[offset], &address, sizeof(address));
223        offset += sizeof(address);
224        A_MEMCPY(&data[offset], &txlen, sizeof(txlen));
225        offset += sizeof(txlen);
226        A_MEMCPY(&data[offset], &buffer[length - remaining], txlen);
227        offset += txlen;
228        status = bmiBufferSend(device, data, offset);
229        if (status != A_OK) {
230            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
231            return A_ERROR;
232        }
233        remaining -= txlen; address += txlen;
234    }
235
236    AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Write Memory: Exit\n"));
237
238    return A_OK;
239}
240
241A_STATUS
242BMIExecute(HIF_DEVICE *device,
243           A_UINT32 address,
244           A_UINT32 *param)
245{
246    A_UINT32 cid;
247    A_STATUS status;
248    A_UINT32 offset;
249    static A_UCHAR data[sizeof(cid) + sizeof(address) + sizeof(*param)];
250    memset (&data, 0, sizeof(cid) + sizeof(address) + sizeof(*param));
251
252    if (bmiDone) {
253        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
254        return A_ERROR;
255    }
256
257    AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
258       ("BMI Execute: Enter (device: 0x%p, address: 0x%x, param: %d)\n",
259        device, address, *param));
260
261    cid = BMI_EXECUTE;
262
263    offset = 0;
264    A_MEMCPY(&data[offset], &cid, sizeof(cid));
265    offset += sizeof(cid);
266    A_MEMCPY(&data[offset], &address, sizeof(address));
267    offset += sizeof(address);
268    A_MEMCPY(&data[offset], param, sizeof(*param));
269    offset += sizeof(*param);
270    status = bmiBufferSend(device, data, offset);
271    if (status != A_OK) {
272        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
273        return A_ERROR;
274    }
275
276    status = bmiBufferReceive(device, data, sizeof(*param));
277    if (status != A_OK) {
278        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n"));
279        return A_ERROR;
280    }
281
282    A_MEMCPY(param, data, sizeof(*param));
283
284    AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Execute: Exit (param: %d)\n", *param));
285    return A_OK;
286}
287
288A_STATUS
289BMISetAppStart(HIF_DEVICE *device,
290               A_UINT32 address)
291{
292    A_UINT32 cid;
293    A_STATUS status;
294    A_UINT32 offset;
295    static A_UCHAR data[sizeof(cid) + sizeof(address)];
296    memset (&data, 0, sizeof(cid) + sizeof(address));
297
298    if (bmiDone) {
299        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
300        return A_ERROR;
301    }
302
303    AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
304       ("BMI Set App Start: Enter (device: 0x%p, address: 0x%x)\n",
305        device, address));
306
307    cid = BMI_SET_APP_START;
308
309    offset = 0;
310    A_MEMCPY(&data[offset], &cid, sizeof(cid));
311    offset += sizeof(cid);
312    A_MEMCPY(&data[offset], &address, sizeof(address));
313    offset += sizeof(address);
314    status = bmiBufferSend(device, data, offset);
315    if (status != A_OK) {
316        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
317        return A_ERROR;
318    }
319
320    AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Set App Start: Exit\n"));
321    return A_OK;
322}
323
324A_STATUS
325BMIReadSOCRegister(HIF_DEVICE *device,
326                   A_UINT32 address,
327                   A_UINT32 *param)
328{
329    A_UINT32 cid;
330    A_STATUS status;
331    A_UINT32 offset;
332    static A_UCHAR data[sizeof(cid) + sizeof(address)];
333    memset (&data, 0, sizeof(cid) + sizeof(address));
334
335    if (bmiDone) {
336        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
337        return A_ERROR;
338    }
339
340    AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
341       ("BMI Read SOC Register: Enter (device: 0x%p, address: 0x%x)\n",
342       device, address));
343
344    cid = BMI_READ_SOC_REGISTER;
345
346    offset = 0;
347    A_MEMCPY(&data[offset], &cid, sizeof(cid));
348    offset += sizeof(cid);
349    A_MEMCPY(&data[offset], &address, sizeof(address));
350    offset += sizeof(address);
351
352    status = bmiBufferSend(device, data, offset);
353    if (status != A_OK) {
354        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
355        return A_ERROR;
356    }
357
358    status = bmiBufferReceive(device, data, sizeof(*param));
359    if (status != A_OK) {
360        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n"));
361        return A_ERROR;
362    }
363    A_MEMCPY(param, data, sizeof(*param));
364
365    AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Read SOC Register: Exit (value: %d)\n", *param));
366    return A_OK;
367}
368
369A_STATUS
370BMIWriteSOCRegister(HIF_DEVICE *device,
371                    A_UINT32 address,
372                    A_UINT32 param)
373{
374    A_UINT32 cid;
375    A_STATUS status;
376    A_UINT32 offset;
377    static A_UCHAR data[sizeof(cid) + sizeof(address) + sizeof(param)];
378
379    memset (&data, 0, sizeof(cid) + sizeof(address) + sizeof(param));
380
381    if (bmiDone) {
382        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
383        return A_ERROR;
384    }
385
386    AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
387     ("BMI Write SOC Register: Enter (device: 0x%p, address: 0x%x, param: %d)\n",
388     device, address, param));
389
390    cid = BMI_WRITE_SOC_REGISTER;
391
392    offset = 0;
393    A_MEMCPY(&data[offset], &cid, sizeof(cid));
394    offset += sizeof(cid);
395    A_MEMCPY(&data[offset], &address, sizeof(address));
396    offset += sizeof(address);
397    A_MEMCPY(&data[offset], &param, sizeof(param));
398    offset += sizeof(param);
399    status = bmiBufferSend(device, data, offset);
400    if (status != A_OK) {
401        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
402        return A_ERROR;
403    }
404
405    AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Read SOC Register: Exit\n"));
406    return A_OK;
407}
408
409A_STATUS
410BMIrompatchInstall(HIF_DEVICE *device,
411                   A_UINT32 ROM_addr,
412                   A_UINT32 RAM_addr,
413                   A_UINT32 nbytes,
414                   A_UINT32 do_activate,
415                   A_UINT32 *rompatch_id)
416{
417    A_UINT32 cid;
418    A_STATUS status;
419    A_UINT32 offset;
420    static A_UCHAR data[sizeof(cid) + sizeof(ROM_addr) + sizeof(RAM_addr) +
421                                sizeof(nbytes) + sizeof(do_activate)];
422
423    memset (&data, 0, sizeof(cid) + sizeof(ROM_addr) + sizeof(RAM_addr) +
424                      sizeof(nbytes) + sizeof(do_activate));
425
426    if (bmiDone) {
427        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
428        return A_ERROR;
429    }
430
431    AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
432         ("BMI rompatch Install: Enter (device: 0x%p, ROMaddr: 0x%x, RAMaddr: 0x%x length: %d activate: %d)\n",
433         device, ROM_addr, RAM_addr, nbytes, do_activate));
434
435    cid = BMI_ROMPATCH_INSTALL;
436
437    offset = 0;
438    A_MEMCPY(&data[offset], &cid, sizeof(cid));
439    offset += sizeof(cid);
440    A_MEMCPY(&data[offset], &ROM_addr, sizeof(ROM_addr));
441    offset += sizeof(ROM_addr);
442    A_MEMCPY(&data[offset], &RAM_addr, sizeof(RAM_addr));
443    offset += sizeof(RAM_addr);
444    A_MEMCPY(&data[offset], &nbytes, sizeof(nbytes));
445    offset += sizeof(nbytes);
446    A_MEMCPY(&data[offset], &do_activate, sizeof(do_activate));
447    offset += sizeof(do_activate);
448    status = bmiBufferSend(device, data, offset);
449    if (status != A_OK) {
450        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
451        return A_ERROR;
452    }
453
454    status = bmiBufferReceive(device, (A_UCHAR *)rompatch_id, sizeof(*rompatch_id));
455    if (status != A_OK) {
456        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n"));
457        return A_ERROR;
458    }
459
460    AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI rompatch Install: (rompatch_id=%d)\n", *rompatch_id));
461    return A_OK;
462}
463
464A_STATUS
465BMIrompatchUninstall(HIF_DEVICE *device,
466                     A_UINT32 rompatch_id)
467{
468    A_UINT32 cid;
469    A_STATUS status;
470    A_UINT32 offset;
471    static A_UCHAR data[sizeof(cid) + sizeof(rompatch_id)];
472    memset (&data, 0, sizeof(cid) + sizeof(rompatch_id));
473
474    if (bmiDone) {
475        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
476        return A_ERROR;
477    }
478
479    AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
480         ("BMI rompatch Uninstall: Enter (device: 0x%p, rompatch_id: %d)\n",
481                                          device, rompatch_id));
482
483    cid = BMI_ROMPATCH_UNINSTALL;
484
485    offset = 0;
486    A_MEMCPY(&data[offset], &cid, sizeof(cid));
487    offset += sizeof(cid);
488    A_MEMCPY(&data[offset], &rompatch_id, sizeof(rompatch_id));
489    offset += sizeof(rompatch_id);
490    status = bmiBufferSend(device, data, offset);
491    if (status != A_OK) {
492        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
493        return A_ERROR;
494    }
495
496    AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI rompatch UNinstall: (rompatch_id=0x%x)\n", rompatch_id));
497    return A_OK;
498}
499
500static A_STATUS
501_BMIrompatchChangeActivation(HIF_DEVICE *device,
502                             A_UINT32 rompatch_count,
503                             A_UINT32 *rompatch_list,
504                             A_UINT32 do_activate)
505{
506    A_UINT32 cid;
507    A_STATUS status;
508    A_UINT32 offset;
509    static A_UCHAR data[BMI_DATASZ_MAX + sizeof(cid) + sizeof(rompatch_count)];
510    A_UINT32 length;
511
512    memset (&data, 0, BMI_DATASZ_MAX + sizeof(cid) + sizeof(rompatch_count));
513
514    if (bmiDone) {
515        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
516        return A_ERROR;
517    }
518
519    AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
520         ("BMI Change rompatch Activation: Enter (device: 0x%p, count: %d)\n",
521           device, rompatch_count));
522
523    cid = do_activate ? BMI_ROMPATCH_ACTIVATE : BMI_ROMPATCH_DEACTIVATE;
524
525    offset = 0;
526    A_MEMCPY(&data[offset], &cid, sizeof(cid));
527    offset += sizeof(cid);
528    A_MEMCPY(&data[offset], &rompatch_count, sizeof(rompatch_count));
529    offset += sizeof(rompatch_count);
530    length = rompatch_count * sizeof(*rompatch_list);
531    A_MEMCPY(&data[offset], rompatch_list, length);
532    offset += length;
533    status = bmiBufferSend(device, data, offset);
534    if (status != A_OK) {
535        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
536        return A_ERROR;
537    }
538
539    AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Change rompatch Activation: Exit\n"));
540
541    return A_OK;
542}
543
544A_STATUS
545BMIrompatchActivate(HIF_DEVICE *device,
546                    A_UINT32 rompatch_count,
547                    A_UINT32 *rompatch_list)
548{
549    return _BMIrompatchChangeActivation(device, rompatch_count, rompatch_list, 1);
550}
551
552A_STATUS
553BMIrompatchDeactivate(HIF_DEVICE *device,
554                      A_UINT32 rompatch_count,
555                      A_UINT32 *rompatch_list)
556{
557    return _BMIrompatchChangeActivation(device, rompatch_count, rompatch_list, 0);
558}
559
560/* BMI Access routines */
561A_STATUS
562bmiBufferSend(HIF_DEVICE *device,
563              A_UCHAR *buffer,
564              A_UINT32 length)
565{
566    A_STATUS status;
567    A_UINT32 timeout;
568    A_UINT32 address;
569    static A_UINT32 cmdCredits;
570    A_UINT32 mboxAddress[HTC_MAILBOX_NUM_MAX];
571
572    HIFConfigureDevice(device, HIF_DEVICE_GET_MBOX_ADDR,
573                       &mboxAddress, sizeof(mboxAddress));
574
575    cmdCredits = 0;
576    timeout = BMI_COMMUNICATION_TIMEOUT;
577
578    while(timeout-- && !cmdCredits) {
579        /* Read the counter register to get the command credits */
580        address = COUNT_DEC_ADDRESS + (HTC_MAILBOX_NUM_MAX + ENDPOINT1) * 4;
581        /* hit the credit counter with a 4-byte access, the first byte read will hit the counter and cause
582         * a decrement, while the remaining 3 bytes has no effect. The rationale behind this is to
583         * make all HIF accesses 4-byte aligned */
584        status = HIFReadWrite(device, address, (A_UINT8 *)&cmdCredits, 4,
585            HIF_RD_SYNC_BYTE_INC, NULL);
586        if (status != A_OK) {
587            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to decrement the command credit count register\n"));
588            return A_ERROR;
589        }
590        /* the counter is only 8=bits, ignore anything in the upper 3 bytes */
591        cmdCredits &= 0xFF;
592    }
593
594    if (cmdCredits) {
595        address = mboxAddress[ENDPOINT1];
596        status = HIFReadWrite(device, address, buffer, length,
597            HIF_WR_SYNC_BYTE_INC, NULL);
598        if (status != A_OK) {
599            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to send the BMI data to the device\n"));
600            return A_ERROR;
601        }
602    } else {
603        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI Communication timeout\n"));
604        return A_ERROR;
605    }
606
607    return status;
608}
609
610A_STATUS
611bmiBufferReceive(HIF_DEVICE *device,
612                 A_UCHAR *buffer,
613                 A_UINT32 length)
614{
615    A_STATUS status;
616    A_UINT32 address;
617    A_UINT32 timeout;
618    static A_UINT32 cmdCredits;
619    A_UINT32 mboxAddress[HTC_MAILBOX_NUM_MAX];
620
621    HIFConfigureDevice(device, HIF_DEVICE_GET_MBOX_ADDR,
622                       &mboxAddress, sizeof(mboxAddress));
623
624    cmdCredits = 0;
625    timeout = BMI_COMMUNICATION_TIMEOUT;
626    while(timeout-- && !cmdCredits) {
627        /* Read the counter register to get the command credits */
628        address = COUNT_ADDRESS + (HTC_MAILBOX_NUM_MAX + ENDPOINT1) * 1;
629        /* read the counter using a 4-byte read. Since the counter is NOT auto-decrementing,
630         * we can read this counter multiple times using a non-incrementing address mode.
631         * The rationale here is to make all HIF accesses a multiple of 4 bytes */
632        status = HIFReadWrite(device, address, (A_UINT8 *)&cmdCredits, sizeof(cmdCredits),
633            HIF_RD_SYNC_BYTE_FIX, NULL);
634        if (status != A_OK) {
635            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read the command credit count register\n"));
636            return A_ERROR;
637        }
638            /* we did a 4-byte read to the same count register so mask off upper bytes */
639        cmdCredits &= 0xFF;
640        status = A_ERROR;
641    }
642
643    if (cmdCredits) {
644        address = mboxAddress[ENDPOINT1];
645        status = HIFReadWrite(device, address, buffer, length,
646            HIF_RD_SYNC_BYTE_INC, NULL);
647        if (status != A_OK) {
648            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read the BMI data from the device\n"));
649            return A_ERROR;
650        }
651    } else {
652        AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Communication timeout\n"));
653        return A_ERROR;
654    }
655
656    return status;
657}
658

Archive Download this file



interactive