~ubuntu-branches/ubuntu/trusty/linux-armadaxp/trusty

« back to all changes in this revision

Viewing changes to drivers/staging/ath6kl/miscdrv/common_drv.c

  • Committer: Package Import Robot
  • Author(s): Michael Casadevall, Bryan Wu, Dann Frazier, Michael Casadeall
  • Date: 2012-03-10 15:00:54 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20120310150054-flugb39zon8vvgwe
Tags: 3.2.0-1600.1
[ Bryan Wu ]
* UBUNTU: import debian/debian.env and debian.armadaxp

[ Dann Frazier ]
* ARM: Armada XP: remove trailing '/' in dirnames in mvRules.mk

[ Michael Casadeall ]
* tools: add some tools for Marvell Armada XP processor
* kernel: timer tick hacking from Marvell
* kernel: Sheeva Errata: add delay on Sheeva when powering down
* net: add Marvell NFP netfilter
* net: socket and skb modifications made by Marvell
* miscdevice: add minor IDs for some Marvell Armada drivers
* fs: introduce memory pool for splice()
* video: EDID detection updates from Marvell Armada XP patchset
* video: backlight: add Marvell Dove LCD backlight driver
* video: display: add THS8200 display driver
* video: framebuffer: add Marvell Dove and Armada XP processor onchip LCD controller driver
* usbtest: add Interrupt transfer testing by Marvell Armada XP code
* usb: ehci: add support for Marvell EHCI controler
* tty/serial: 8250: add support for Marvell Armada XP processor and DeviceTree work
* rtc: add support for Marvell Armada XP onchip RTC controller
* net: pppoe: add Marvell ethernet NFP hook in PPPoE networking driver
* mtd: nand: add support for Marvell Armada XP Nand Flash Controller
* mtd: maps: add Marvell Armada XP specific map driver
* mmc: add support for Marvell Armada XP MMC/SD host controller
* i2c: add support for Marvell Armada XP onchip i2c bus controller
* hwmon: add Kconfig option for Armada XP onchip thermal sensor driver
* dmaengine: add Net DMA support for splice and update Marvell XOR DMA engine driver
* ata: add support for Marvell Armada XP SATA controller and update some quirks
* ARM: add Marvell Armada XP machine to mach-types
* ARM: oprofile: add support for Marvell PJ4B core
* ARM: mm: more ARMv6 switches for Marvell Armada XP
* ARM: remove static declaration to allow compilation
* ARM: alignment access fault trick
* ARM: mm: skip some fault fixing when run on NONE SMP ARMv6 mode during early abort event
* ARM: mm: add Marvell Sheeva CPU Architecture for PJ4B
* ARM: introduce optimized copy operation for Marvell Armada XP
* ARM: SAUCE: hardware breakpoint trick for Marvell Armada XP
* ARM: big endian and little endian tricks for Marvell Armada XP
* ARM: SAUCE: Add Marvell Armada XP build rules to arch/arm/kernel/Makefile
* ARM: vfp: add special handling for Marvell Armada XP
* ARM: add support for Marvell U-Boot
* ARM: add mv_controller_num for ARM PCI drivers
* ARM: add support for local PMUs, general SMP tweaks and cache flushing
* ARM: add Marvell device identifies in glue-proc.h
* ARM: add IPC driver support for Marvell platforms
* ARM: add DMA mapping for Marvell platforms
* ARM: add Sheeva errata and PJ4B code for booting
* ARM: update Kconfig and Makefile to include Marvell Armada XP platforms
* ARM: Armada XP: import LSP from Marvell for Armada XP 3.2 kernel enablement

Show diffs side-by-side

added added

removed removed

Lines of Context:
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