Merge branch 'sh-latest' of git://git.kernel.org/pub/scm/linux/kernel/git/lethal...
[pandora-kernel.git] / drivers / staging / ath6kl / miscdrv / common_drv.c
1 //------------------------------------------------------------------------------
2 // <copyright file="common_drv.c" company="Atheros">
3 //    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
4 // 
5 //
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.
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.
17 //
18 //
19 //------------------------------------------------------------------------------
20 //==============================================================================
21 // Author(s): ="Atheros"
22 //==============================================================================
23
24 #include "a_config.h"
25 #include "athdefs.h"
26
27 #include "hw/mbox_host_reg.h"
28 #include "gpio_reg.h"
29 #include "hw/rtc_reg.h"
30 #include "hw/mbox_reg.h"
31 #include "hw/apb_map.h"
32
33 #include "a_osapi.h"
34 #include "targaddrs.h"
35 #include "hif.h"
36 #include "htc_api.h"
37 #include "wmi.h"
38 #include "bmi.h"
39 #include "bmi_msg.h"
40 #include "common_drv.h"
41 #define ATH_MODULE_NAME misc
42 #include "a_debug.h"
43 #include "ar6000_diag.h"
44
45 static ATH_DEBUG_MODULE_DBG_INFO *g_pModuleInfoHead = NULL;
46 static A_MUTEX_T                 g_ModuleListLock;
47 static bool                    g_ModuleDebugInit = false;
48
49 #ifdef ATH_DEBUG_MODULE
50
51 ATH_DEBUG_INSTANTIATE_MODULE_VAR(misc,
52                                  "misc",
53                                  "Common and misc APIs",
54                                  ATH_DEBUG_MASK_DEFAULTS,
55                                  0,
56                                  NULL);
57
58 #endif
59
60 #define HOST_INTEREST_ITEM_ADDRESS(target, item) \
61         ((((target) == TARGET_TYPE_AR6002) ? AR6002_HOST_INTEREST_ITEM_ADDRESS(item) : \
62          (((target) == TARGET_TYPE_AR6003) ? AR6003_HOST_INTEREST_ITEM_ADDRESS(item) : 0)))
63
64
65 #define AR6001_LOCAL_COUNT_ADDRESS 0x0c014080
66 #define AR6002_LOCAL_COUNT_ADDRESS 0x00018080
67 #define AR6003_LOCAL_COUNT_ADDRESS 0x00018080
68 #define CPU_DBG_SEL_ADDRESS                      0x00000483
69 #define CPU_DBG_ADDRESS                          0x00000484
70
71 static u8 custDataAR6002[AR6002_CUST_DATA_SIZE];
72 static u8 custDataAR6003[AR6003_CUST_DATA_SIZE];
73
74 /* Compile the 4BYTE version of the window register setup routine,
75  * This mitigates host interconnect issues with non-4byte aligned bus requests, some
76  * interconnects use bus adapters that impose strict limitations.
77  * Since diag window access is not intended for performance critical operations, the 4byte mode should
78  * be satisfactory even though it generates 4X the bus activity. */
79
80 #ifdef USE_4BYTE_REGISTER_ACCESS
81
82     /* set the window address register (using 4-byte register access ). */
83 int ar6000_SetAddressWindowRegister(struct hif_device *hifDevice, u32 RegisterAddr, u32 Address)
84 {
85     int status;
86     u8 addrValue[4];
87     s32 i;
88
89         /* write bytes 1,2,3 of the register to set the upper address bytes, the LSB is written
90          * last to initiate the access cycle */
91
92     for (i = 1; i <= 3; i++) {
93             /* fill the buffer with the address byte value we want to hit 4 times*/
94         addrValue[0] = ((u8 *)&Address)[i];
95         addrValue[1] = addrValue[0];
96         addrValue[2] = addrValue[0];
97         addrValue[3] = addrValue[0];
98
99             /* hit each byte of the register address with a 4-byte write operation to the same address,
100              * this is a harmless operation */
101         status = HIFReadWrite(hifDevice,
102                               RegisterAddr+i,
103                               addrValue,
104                               4,
105                               HIF_WR_SYNC_BYTE_FIX,
106                               NULL);
107         if (status) {
108             break;
109         }
110     }
111
112     if (status) {
113         AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write initial bytes of 0x%x to window reg: 0x%X \n",
114             Address, RegisterAddr));
115         return status;
116     }
117
118         /* write the address register again, this time write the whole 4-byte value.
119          * The effect here is that the LSB write causes the cycle to start, the extra
120          * 3 byte write to bytes 1,2,3 has no effect since we are writing the same values again */
121     status = HIFReadWrite(hifDevice,
122                           RegisterAddr,
123                           (u8 *)(&Address),
124                           4,
125                           HIF_WR_SYNC_BYTE_INC,
126                           NULL);
127
128     if (status) {
129         AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write 0x%x to window reg: 0x%X \n",
130             Address, RegisterAddr));
131         return status;
132     }
133
134     return 0;
135
136
137
138 }
139
140
141 #else
142
143     /* set the window address register */
144 int ar6000_SetAddressWindowRegister(struct hif_device *hifDevice, u32 RegisterAddr, u32 Address)
145 {
146     int status;
147
148         /* write bytes 1,2,3 of the register to set the upper address bytes, the LSB is written
149          * last to initiate the access cycle */
150     status = HIFReadWrite(hifDevice,
151                           RegisterAddr+1,  /* write upper 3 bytes */
152                           ((u8 *)(&Address))+1,
153                           sizeof(u32)-1,
154                           HIF_WR_SYNC_BYTE_INC,
155                           NULL);
156
157     if (status) {
158         AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write initial bytes of 0x%x to window reg: 0x%X \n",
159              RegisterAddr, Address));
160         return status;
161     }
162
163         /* write the LSB of the register, this initiates the operation */
164     status = HIFReadWrite(hifDevice,
165                           RegisterAddr,
166                           (u8 *)(&Address),
167                           sizeof(u8),
168                           HIF_WR_SYNC_BYTE_INC,
169                           NULL);
170
171     if (status) {
172         AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write 0x%x to window reg: 0x%X \n",
173             RegisterAddr, Address));
174         return status;
175     }
176
177     return 0;
178 }
179
180 #endif
181
182 /*
183  * Read from the AR6000 through its diagnostic window.
184  * No cooperation from the Target is required for this.
185  */
186 int
187 ar6000_ReadRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data)
188 {
189     int status;
190
191         /* set window register to start read cycle */
192     status = ar6000_SetAddressWindowRegister(hifDevice,
193                                              WINDOW_READ_ADDR_ADDRESS,
194                                              *address);
195
196     if (status) {
197         return status;
198     }
199
200         /* read the data */
201     status = HIFReadWrite(hifDevice,
202                           WINDOW_DATA_ADDRESS,
203                           (u8 *)data,
204                           sizeof(u32),
205                           HIF_RD_SYNC_BYTE_INC,
206                           NULL);
207     if (status) {
208         AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot read from WINDOW_DATA_ADDRESS\n"));
209         return status;
210     }
211
212     return status;
213 }
214
215
216 /*
217  * Write to the AR6000 through its diagnostic window.
218  * No cooperation from the Target is required for this.
219  */
220 int
221 ar6000_WriteRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data)
222 {
223     int status;
224
225         /* set write data */
226     status = HIFReadWrite(hifDevice,
227                           WINDOW_DATA_ADDRESS,
228                           (u8 *)data,
229                           sizeof(u32),
230                           HIF_WR_SYNC_BYTE_INC,
231                           NULL);
232     if (status) {
233         AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write 0x%x to WINDOW_DATA_ADDRESS\n", *data));
234         return status;
235     }
236
237         /* set window register, which starts the write cycle */
238     return ar6000_SetAddressWindowRegister(hifDevice,
239                                            WINDOW_WRITE_ADDR_ADDRESS,
240                                            *address);
241     }
242
243 int
244 ar6000_ReadDataDiag(struct hif_device *hifDevice, u32 address,
245                     u8 *data, u32 length)
246 {
247     u32 count;
248     int status = 0;
249
250     for (count = 0; count < length; count += 4, address += 4) {
251         if ((status = ar6000_ReadRegDiag(hifDevice, &address,
252                                          (u32 *)&data[count])) != 0)
253         {
254             break;
255         }
256     }
257
258     return status;
259 }
260
261 int
262 ar6000_WriteDataDiag(struct hif_device *hifDevice, u32 address,
263                     u8 *data, u32 length)
264 {
265     u32 count;
266     int status = 0;
267
268     for (count = 0; count < length; count += 4, address += 4) {
269         if ((status = ar6000_WriteRegDiag(hifDevice, &address,
270                                          (u32 *)&data[count])) != 0)
271         {
272             break;
273         }
274     }
275
276     return status;
277 }
278
279 int
280 ar6k_ReadTargetRegister(struct hif_device *hifDevice, int regsel, u32 *regval)
281 {
282     int status;
283     u8 vals[4];
284     u8 register_selection[4];
285
286     register_selection[0] = register_selection[1] = register_selection[2] = register_selection[3] = (regsel & 0xff);
287     status = HIFReadWrite(hifDevice,
288                           CPU_DBG_SEL_ADDRESS,
289                           register_selection,
290                           4,
291                           HIF_WR_SYNC_BYTE_FIX,
292                           NULL);
293
294     if (status) {
295         AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write CPU_DBG_SEL (%d)\n", regsel));
296         return status;
297     }
298
299     status = HIFReadWrite(hifDevice,
300                           CPU_DBG_ADDRESS,
301                           (u8 *)vals,
302                           sizeof(vals),
303                           HIF_RD_SYNC_BYTE_INC,
304                           NULL);
305     if (status) {
306         AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot read from CPU_DBG_ADDRESS\n"));
307         return status;
308     }
309
310     *regval = vals[0]<<0 | vals[1]<<8 | vals[2]<<16 | vals[3]<<24;
311
312     return status;
313 }
314
315 void
316 ar6k_FetchTargetRegs(struct hif_device *hifDevice, u32 *targregs)
317 {
318     int i;
319     u32 val;
320
321     for (i=0; i<AR6003_FETCH_TARG_REGS_COUNT; i++) {
322         val=0xffffffff;
323         (void)ar6k_ReadTargetRegister(hifDevice, i, &val);
324         targregs[i] = val;
325     }
326 }
327
328 #if 0
329 static int
330 _do_write_diag(struct hif_device *hifDevice, u32 addr, u32 value)
331 {
332     int status;
333
334     status = ar6000_WriteRegDiag(hifDevice, &addr, &value);
335     if (status)
336     {
337         AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot force Target to execute ROM!\n"));
338     }
339
340     return status;
341 }
342 #endif
343
344
345 /*
346  * Delay up to wait_msecs millisecs to allow Target to enter BMI phase,
347  * which is a good sign that it's alive and well.  This is used after
348  * explicitly forcing the Target to reset.
349  *
350  * The wait_msecs time should be sufficiently long to cover any reasonable
351  * boot-time delay.  For instance, AR6001 firmware allow one second for a
352  * low frequency crystal to settle before it calibrates the refclk frequency.
353  *
354  * TBD: Might want to add special handling for AR6K_OPTION_BMI_DISABLE.
355  */
356 #if 0
357 static int
358 _delay_until_target_alive(struct hif_device *hifDevice, s32 wait_msecs, u32 TargetType)
359 {
360     s32 actual_wait;
361     s32 i;
362     u32 address;
363
364     actual_wait = 0;
365
366     /* Hardcode the address of LOCAL_COUNT_ADDRESS based on the target type */
367     if (TargetType == TARGET_TYPE_AR6002) {
368        address = AR6002_LOCAL_COUNT_ADDRESS;
369     } else if (TargetType == TARGET_TYPE_AR6003) {
370        address = AR6003_LOCAL_COUNT_ADDRESS;
371     } else {
372        A_ASSERT(0);
373     }
374     address += 0x10;
375     for (i=0; actual_wait < wait_msecs; i++) {
376         u32 data;
377
378         A_MDELAY(100);
379         actual_wait += 100;
380
381         data = 0;
382         if (ar6000_ReadRegDiag(hifDevice, &address, &data) != 0) {
383             return A_ERROR;
384         }
385
386         if (data != 0) {
387             /* No need to wait longer -- we have a BMI credit */
388             return 0;
389         }
390     }
391     return A_ERROR; /* timed out */
392 }
393 #endif
394
395 #define AR6001_RESET_CONTROL_ADDRESS 0x0C000000
396 #define AR6002_RESET_CONTROL_ADDRESS 0x00004000
397 #define AR6003_RESET_CONTROL_ADDRESS 0x00004000
398 /* reset device */
399 int ar6000_reset_device(struct hif_device *hifDevice, u32 TargetType, bool waitForCompletion, bool coldReset)
400 {
401     int status = 0;
402     u32 address;
403     u32 data;
404
405     do {
406 // Workaround BEGIN
407         // address = RESET_CONTROL_ADDRESS;
408         
409         if (coldReset) {
410             data = RESET_CONTROL_COLD_RST_MASK;
411         }
412         else {
413             data = RESET_CONTROL_MBOX_RST_MASK;
414         }
415
416           /* Hardcode the address of RESET_CONTROL_ADDRESS based on the target type */
417         if (TargetType == TARGET_TYPE_AR6002) {
418             address = AR6002_RESET_CONTROL_ADDRESS;
419         } else if (TargetType == TARGET_TYPE_AR6003) {
420             address = AR6003_RESET_CONTROL_ADDRESS;
421         } else {
422             A_ASSERT(0);
423         }
424
425
426         status = ar6000_WriteRegDiag(hifDevice, &address, &data);
427
428         if (status) {
429             break;
430         }
431
432         if (!waitForCompletion) {
433             break;
434         }
435
436 #if 0
437         /* Up to 2 second delay to allow things to settle down */
438         (void)_delay_until_target_alive(hifDevice, 2000, TargetType);
439
440         /*
441          * Read back the RESET CAUSE register to ensure that the cold reset
442          * went through.
443          */
444
445         // address = RESET_CAUSE_ADDRESS;
446         /* Hardcode the address of RESET_CAUSE_ADDRESS based on the target type */
447         if (TargetType == TARGET_TYPE_AR6002) {
448             address = 0x000040C0;
449         } else if (TargetType == TARGET_TYPE_AR6003) {
450             address = 0x000040C0;
451         } else {
452             A_ASSERT(0);
453         }
454
455         data = 0;
456         status = ar6000_ReadRegDiag(hifDevice, &address, &data);
457
458         if (status) {
459             break;
460         }
461
462         AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Reset Cause readback: 0x%X \n",data));
463         data &= RESET_CAUSE_LAST_MASK;
464         if (data != 2) {
465             AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Unable to cold reset the target \n"));
466         }
467 #endif
468 // Workaroud END
469
470     } while (false);
471
472     if (status) {
473         AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Failed to reset target \n"));
474     }
475
476     return 0;
477 }
478
479 /* This should be called in BMI phase after firmware is downloaded */
480 void
481 ar6000_copy_cust_data_from_target(struct hif_device *hifDevice, u32 TargetType)
482 {
483     u32 eepHeaderAddr;
484     u8 AR6003CustDataShadow[AR6003_CUST_DATA_SIZE+4];
485     s32 i;
486
487     if (BMIReadMemory(hifDevice,
488             HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_board_data),
489             (u8 *)&eepHeaderAddr,
490             4)!= 0)
491     {
492         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMIReadMemory for reading board data address failed \n"));
493         return;
494     }
495
496     if (TargetType == TARGET_TYPE_AR6003) {
497         eepHeaderAddr += 36;  /* AR6003 customer data section offset is 37 */
498
499         for (i=0; i<AR6003_CUST_DATA_SIZE+4; i+=4){
500             if (BMIReadSOCRegister(hifDevice, eepHeaderAddr, (u32 *)&AR6003CustDataShadow[i])!= 0) {
501                 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMIReadSOCRegister () failed \n"));
502                 return ;
503             }  
504             eepHeaderAddr +=4;
505         }
506
507         memcpy(custDataAR6003, AR6003CustDataShadow+1, AR6003_CUST_DATA_SIZE);
508     }
509
510     if (TargetType == TARGET_TYPE_AR6002) {
511         eepHeaderAddr += 64;  /* AR6002 customer data sectioin offset is 64 */
512
513         for (i=0; i<AR6002_CUST_DATA_SIZE; i+=4){
514             if (BMIReadSOCRegister(hifDevice, eepHeaderAddr, (u32 *)&custDataAR6002[i])!= 0) {
515                 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMIReadSOCRegister () failed \n"));
516                 return ;
517             }  
518             eepHeaderAddr +=4;
519         }
520     }
521
522     return;
523 }
524
525 /* This is the function to call when need to use the cust data */
526 u8 *ar6000_get_cust_data_buffer(u32 TargetType)
527 {
528     if (TargetType == TARGET_TYPE_AR6003)
529         return custDataAR6003;
530
531     if (TargetType == TARGET_TYPE_AR6002)
532         return custDataAR6002;
533
534     return NULL;
535 }
536
537 #define REG_DUMP_COUNT_AR6001   38  /* WORDs, derived from AR600x_regdump.h */
538 #define REG_DUMP_COUNT_AR6002   60
539 #define REG_DUMP_COUNT_AR6003   60
540 #define REGISTER_DUMP_LEN_MAX   60
541 #if REG_DUMP_COUNT_AR6001 > REGISTER_DUMP_LEN_MAX
542 #error "REG_DUMP_COUNT_AR6001 too large"
543 #endif
544 #if REG_DUMP_COUNT_AR6002 > REGISTER_DUMP_LEN_MAX
545 #error "REG_DUMP_COUNT_AR6002 too large"
546 #endif
547 #if REG_DUMP_COUNT_AR6003 > REGISTER_DUMP_LEN_MAX
548 #error "REG_DUMP_COUNT_AR6003 too large"
549 #endif
550
551
552 void ar6000_dump_target_assert_info(struct hif_device *hifDevice, u32 TargetType)
553 {
554     u32 address;
555     u32 regDumpArea = 0;
556     int status;
557     u32 regDumpValues[REGISTER_DUMP_LEN_MAX];
558     u32 regDumpCount = 0;
559     u32 i;
560
561     do {
562
563             /* the reg dump pointer is copied to the host interest area */
564         address = HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_failure_state);
565         address = TARG_VTOP(TargetType, address);
566
567         if (TargetType == TARGET_TYPE_AR6002) {
568             regDumpCount = REG_DUMP_COUNT_AR6002;
569         } else  if (TargetType == TARGET_TYPE_AR6003) {
570             regDumpCount = REG_DUMP_COUNT_AR6003;
571         } else {
572             A_ASSERT(0);
573         }
574
575             /* read RAM location through diagnostic window */
576         status = ar6000_ReadRegDiag(hifDevice, &address, &regDumpArea);
577
578         if (status) {
579             AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Failed to get ptr to register dump area \n"));
580             break;
581         }
582
583         AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Location of register dump data: 0x%X \n",regDumpArea));
584
585         if (regDumpArea == 0) {
586                 /* no reg dump */
587             break;
588         }
589
590         regDumpArea = TARG_VTOP(TargetType, regDumpArea);
591
592             /* fetch register dump data */
593         status = ar6000_ReadDataDiag(hifDevice,
594                                      regDumpArea,
595                                      (u8 *)&regDumpValues[0],
596                                      regDumpCount * (sizeof(u32)));
597
598         if (status) {
599             AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Failed to get register dump \n"));
600             break;
601         }
602         AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Register Dump: \n"));
603
604         for (i = 0; i < regDumpCount; i++) {
605             //ATHR_DISPLAY_MSG (_T(" %d :  0x%8.8X \n"), i, regDumpValues[i]);
606             AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" %d :  0x%8.8X \n",i, regDumpValues[i]));
607
608 #ifdef UNDER_CE
609         /*
610          * For Every logPrintf() Open the File so that in case of Crashes
611          * We will have until the Last Message Flushed on to the File
612          * So use logPrintf Sparingly..!!
613          */
614         tgtassertPrintf (ATH_DEBUG_TRC," %d:  0x%8.8X \n",i, regDumpValues[i]);
615 #endif
616         }
617
618     } while (false);
619
620 }
621
622 /* set HTC/Mbox operational parameters, this can only be called when the target is in the
623  * BMI phase */
624 int ar6000_set_htc_params(struct hif_device *hifDevice,
625                                u32 TargetType,
626                                u32 MboxIsrYieldValue,
627                                u8 HtcControlBuffers)
628 {
629     int status;
630     u32 blocksizes[HTC_MAILBOX_NUM_MAX];
631
632     do {
633             /* get the block sizes */
634         status = HIFConfigureDevice(hifDevice, HIF_DEVICE_GET_MBOX_BLOCK_SIZE,
635                                     blocksizes, sizeof(blocksizes));
636
637         if (status) {
638             AR_DEBUG_PRINTF(ATH_LOG_ERR,("Failed to get block size info from HIF layer...\n"));
639             break;
640         }
641             /* note: we actually get the block size for mailbox 1, for SDIO the block
642              * size on mailbox 0 is artificially set to 1 */
643             /* must be a power of 2 */
644         A_ASSERT((blocksizes[1] & (blocksizes[1] - 1)) == 0);
645
646         if (HtcControlBuffers != 0) {
647                 /* set override for number of control buffers to use */
648             blocksizes[1] |=  ((u32)HtcControlBuffers) << 16;
649         }
650
651             /* set the host interest area for the block size */
652         status = BMIWriteMemory(hifDevice,
653                                 HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_mbox_io_block_sz),
654                                 (u8 *)&blocksizes[1],
655                                 4);
656
657         if (status) {
658             AR_DEBUG_PRINTF(ATH_LOG_ERR,("BMIWriteMemory for IO block size failed \n"));
659             break;
660         }
661
662         AR_DEBUG_PRINTF(ATH_LOG_INF,("Block Size Set: %d (target address:0x%X)\n",
663                 blocksizes[1], HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_mbox_io_block_sz)));
664
665         if (MboxIsrYieldValue != 0) {
666                 /* set the host interest area for the mbox ISR yield limit */
667             status = BMIWriteMemory(hifDevice,
668                                     HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_mbox_isr_yield_limit),
669                                     (u8 *)&MboxIsrYieldValue,
670                                     4);
671
672             if (status) {
673                 AR_DEBUG_PRINTF(ATH_LOG_ERR,("BMIWriteMemory for yield limit failed \n"));
674                 break;
675             }
676         }
677
678     } while (false);
679
680     return status;
681 }
682
683 void DebugDumpBytes(u8 *buffer, u16 length, char *pDescription)
684 {
685     char stream[60];
686     char byteOffsetStr[10];
687     u32 i;
688     u16 offset, count, byteOffset;
689
690     A_PRINTF("<---------Dumping %d Bytes : %s ------>\n", length, pDescription);
691
692     count = 0;
693     offset = 0;
694     byteOffset = 0;
695     for(i = 0; i < length; i++) {
696         A_SPRINTF(stream + offset, "%2.2X ", buffer[i]);
697         count ++;
698         offset += 3;
699
700         if(count == 16) {
701             count = 0;
702             offset = 0;
703             A_SPRINTF(byteOffsetStr,"%4.4X",byteOffset);
704             A_PRINTF("[%s]: %s\n", byteOffsetStr, stream);
705             A_MEMZERO(stream, 60);
706             byteOffset += 16;
707         }
708     }
709
710     if(offset != 0) {
711         A_SPRINTF(byteOffsetStr,"%4.4X",byteOffset);
712         A_PRINTF("[%s]: %s\n", byteOffsetStr, stream);
713     }
714
715     A_PRINTF("<------------------------------------------------->\n");
716 }
717
718 void a_dump_module_debug_info(ATH_DEBUG_MODULE_DBG_INFO *pInfo)
719 {
720     int                         i;
721     struct ath_debug_mask_description *pDesc;
722
723     if (pInfo == NULL) {
724         return;
725     }
726
727     pDesc = pInfo->pMaskDescriptions;
728
729     A_PRINTF("========================================================\n\n");
730     A_PRINTF("Module Debug Info => Name   : %s    \n", pInfo->ModuleName);
731     A_PRINTF("                  => Descr. : %s \n", pInfo->ModuleDescription);
732     A_PRINTF("\n  Current mask    => 0x%8.8X \n", pInfo->CurrentMask);
733     A_PRINTF("\n  Avail. Debug Masks :\n\n");
734
735     for (i = 0; i < pInfo->MaxDescriptions; i++,pDesc++) {
736         A_PRINTF("                  => 0x%8.8X -- %s \n", pDesc->Mask, pDesc->Description);
737     }
738
739     if (0 == i) {
740         A_PRINTF("                  => * none defined * \n");
741     }
742
743     A_PRINTF("\n  Standard Debug Masks :\n\n");
744         /* print standard masks */
745     A_PRINTF("                  => 0x%8.8X -- Errors \n", ATH_DEBUG_ERR);
746     A_PRINTF("                  => 0x%8.8X -- Warnings \n", ATH_DEBUG_WARN);
747     A_PRINTF("                  => 0x%8.8X -- Informational \n", ATH_DEBUG_INFO);
748     A_PRINTF("                  => 0x%8.8X -- Tracing \n", ATH_DEBUG_TRC);
749     A_PRINTF("\n========================================================\n");
750
751 }
752
753
754 static ATH_DEBUG_MODULE_DBG_INFO *FindModule(char *module_name)
755 {
756     ATH_DEBUG_MODULE_DBG_INFO *pInfo = g_pModuleInfoHead;
757
758     if (!g_ModuleDebugInit) {
759         return NULL;
760     }
761
762     while (pInfo != NULL) {
763             /* TODO: need to use something other than strlen */
764         if (memcmp(pInfo->ModuleName,module_name,strlen(module_name)) == 0) {
765             break;
766         }
767         pInfo = pInfo->pNext;
768     }
769
770     return pInfo;
771 }
772
773
774 void a_register_module_debug_info(ATH_DEBUG_MODULE_DBG_INFO *pInfo)
775 {
776     if (!g_ModuleDebugInit) {
777         return;
778     }
779
780     A_MUTEX_LOCK(&g_ModuleListLock);
781
782     if (!(pInfo->Flags & ATH_DEBUG_INFO_FLAGS_REGISTERED)) {
783         if (g_pModuleInfoHead == NULL) {
784             g_pModuleInfoHead = pInfo;
785         } else {
786            pInfo->pNext = g_pModuleInfoHead;
787            g_pModuleInfoHead = pInfo;
788         }
789         pInfo->Flags |= ATH_DEBUG_INFO_FLAGS_REGISTERED;
790     }
791
792     A_MUTEX_UNLOCK(&g_ModuleListLock);
793 }
794
795 void a_dump_module_debug_info_by_name(char *module_name)
796 {
797     ATH_DEBUG_MODULE_DBG_INFO *pInfo = g_pModuleInfoHead;
798
799     if (!g_ModuleDebugInit) {
800         return;
801     }
802
803     if (memcmp(module_name,"all",3) == 0) {
804             /* dump all */
805         while (pInfo != NULL) {
806             a_dump_module_debug_info(pInfo);
807             pInfo = pInfo->pNext;
808         }
809         return;
810     }
811
812     pInfo = FindModule(module_name);
813
814     if (pInfo != NULL) {
815          a_dump_module_debug_info(pInfo);
816     }
817
818 }
819
820 int a_get_module_mask(char *module_name, u32 *pMask)
821 {
822     ATH_DEBUG_MODULE_DBG_INFO *pInfo = FindModule(module_name);
823
824     if (NULL == pInfo) {
825         return A_ERROR;
826     }
827
828     *pMask = pInfo->CurrentMask;
829     return 0;
830 }
831
832 int a_set_module_mask(char *module_name, u32 Mask)
833 {
834     ATH_DEBUG_MODULE_DBG_INFO *pInfo = FindModule(module_name);
835
836     if (NULL == pInfo) {
837         return A_ERROR;
838     }
839
840     pInfo->CurrentMask = Mask;
841     A_PRINTF("Module %s,  new mask: 0x%8.8X \n",module_name,pInfo->CurrentMask);
842     return 0;
843 }
844
845
846 void a_module_debug_support_init(void)
847 {
848     if (g_ModuleDebugInit) {
849         return;
850     }
851     A_MUTEX_INIT(&g_ModuleListLock);
852     g_pModuleInfoHead = NULL;
853     g_ModuleDebugInit = true;
854     A_REGISTER_MODULE_DEBUG_INFO(misc);
855 }
856
857 void a_module_debug_support_cleanup(void)
858 {
859     ATH_DEBUG_MODULE_DBG_INFO *pInfo = g_pModuleInfoHead;
860     ATH_DEBUG_MODULE_DBG_INFO *pCur;
861
862     if (!g_ModuleDebugInit) {
863         return;
864     }
865
866     g_ModuleDebugInit = false;
867
868     A_MUTEX_LOCK(&g_ModuleListLock);
869
870     while (pInfo != NULL) {
871         pCur = pInfo;
872         pInfo = pInfo->pNext;
873         pCur->pNext = NULL;
874             /* clear registered flag */
875         pCur->Flags &= ~ATH_DEBUG_INFO_FLAGS_REGISTERED;
876     }
877
878     A_MUTEX_UNLOCK(&g_ModuleListLock);
879
880     A_MUTEX_DELETE(&g_ModuleListLock);
881     g_pModuleInfoHead = NULL;
882 }
883
884     /* can only be called during bmi init stage */
885 int ar6000_set_hci_bridge_flags(struct hif_device *hifDevice,
886                                      u32 TargetType,
887                                      u32 Flags)
888 {
889     int status = 0;
890
891     do {
892
893         if (TargetType != TARGET_TYPE_AR6003) {
894             AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("Target Type:%d, does not support HCI bridging! \n",
895                 TargetType));
896             break;
897         }
898
899             /* set hci bridge flags */
900         status = BMIWriteMemory(hifDevice,
901                                 HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_hci_bridge_flags),
902                                 (u8 *)&Flags,
903                                 4);
904
905
906     } while (false);
907
908     return status;
909 }
910