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