~ubuntu-branches/ubuntu/natty/linux-backports-modules-2.6.38/natty-proposed

« back to all changes in this revision

Viewing changes to updates/cw-2.6.39/drivers/staging/ath6kl/miscdrv/ar3kconfig.c

  • Committer: Bazaar Package Importer
  • Author(s): Tim Gardner, Tim Gardner
  • Date: 2011-06-08 10:44:09 UTC
  • Revision ID: james.westby@ubuntu.com-20110608104409-fnl8carkdo15bwsz
Tags: 2.6.38-10.6
[ Tim Gardner ]

Shorten compat-wireless package name to cw to accomodate
CDROM file name length restrictions.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//------------------------------------------------------------------------------
 
2
// Copyright (c) 2009-2010 Atheros Corporation.  All rights reserved.
 
3
// 
 
4
//
 
5
// Permission to use, copy, modify, and/or distribute this software for any
 
6
// purpose with or without fee is hereby granted, provided that the above
 
7
// copyright notice and this permission notice appear in all copies.
 
8
//
 
9
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 
10
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 
11
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 
12
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 
13
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 
14
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 
15
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
16
//
 
17
//
 
18
//------------------------------------------------------------------------------
 
19
//==============================================================================
 
20
// AR3K configuration implementation
 
21
//
 
22
// Author(s): ="Atheros"
 
23
//==============================================================================
 
24
 
 
25
#include "a_config.h"
 
26
#include "athdefs.h"
 
27
#include "a_types.h"
 
28
#include "a_osapi.h"
 
29
#define ATH_MODULE_NAME misc
 
30
#include "a_debug.h"
 
31
#include "common_drv.h"
 
32
#ifdef EXPORT_HCI_BRIDGE_INTERFACE
 
33
#include "export_hci_transport.h"
 
34
#else
 
35
#include "hci_transport_api.h"
 
36
#endif
 
37
#include "ar3kconfig.h"
 
38
#include "tlpm.h"
 
39
 
 
40
#define BAUD_CHANGE_COMMAND_STATUS_OFFSET   5
 
41
#define HCI_EVENT_RESP_TIMEOUTMS            3000
 
42
#define HCI_CMD_OPCODE_BYTE_LOW_OFFSET      0
 
43
#define HCI_CMD_OPCODE_BYTE_HI_OFFSET       1
 
44
#define HCI_EVENT_OPCODE_BYTE_LOW           3
 
45
#define HCI_EVENT_OPCODE_BYTE_HI            4
 
46
#define HCI_CMD_COMPLETE_EVENT_CODE         0xE
 
47
#define HCI_MAX_EVT_RECV_LENGTH             257
 
48
#define EXIT_MIN_BOOT_COMMAND_STATUS_OFFSET  5
 
49
 
 
50
int AthPSInitialize(struct ar3k_config_info *hdev);
 
51
 
 
52
static int SendHCICommand(struct ar3k_config_info *pConfig,
 
53
                               u8 *pBuffer,
 
54
                               int              Length)
 
55
{
 
56
    struct htc_packet  *pPacket = NULL;
 
57
    int    status = 0;
 
58
       
 
59
    do {   
 
60
        
 
61
        pPacket = (struct htc_packet *)A_MALLOC(sizeof(struct htc_packet));     
 
62
        if (NULL == pPacket) {
 
63
            status = A_NO_MEMORY;
 
64
            break;    
 
65
        }       
 
66
        
 
67
        A_MEMZERO(pPacket,sizeof(struct htc_packet));      
 
68
        SET_HTC_PACKET_INFO_TX(pPacket,
 
69
                               NULL,
 
70
                               pBuffer, 
 
71
                               Length,
 
72
                               HCI_COMMAND_TYPE, 
 
73
                               AR6K_CONTROL_PKT_TAG);
 
74
        
 
75
            /* issue synchronously */                                      
 
76
        status = HCI_TransportSendPkt(pConfig->pHCIDev,pPacket,true);
 
77
        
 
78
    } while (false);
 
79
   
 
80
    if (pPacket != NULL) {
 
81
        A_FREE(pPacket);
 
82
    }
 
83
        
 
84
    return status;
 
85
}
 
86
 
 
87
static int RecvHCIEvent(struct ar3k_config_info *pConfig,
 
88
                             u8 *pBuffer,
 
89
                             int              *pLength)
 
90
{
 
91
    int    status = 0;
 
92
    struct htc_packet  *pRecvPacket = NULL;
 
93
    
 
94
    do {
 
95
                 
 
96
        pRecvPacket = (struct htc_packet *)A_MALLOC(sizeof(struct htc_packet));
 
97
        if (NULL == pRecvPacket) {
 
98
            status = A_NO_MEMORY;
 
99
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to alloc HTC struct \n"));
 
100
            break;    
 
101
        }     
 
102
        
 
103
        A_MEMZERO(pRecvPacket,sizeof(struct htc_packet)); 
 
104
         
 
105
        SET_HTC_PACKET_INFO_RX_REFILL(pRecvPacket,NULL,pBuffer,*pLength,HCI_EVENT_TYPE);
 
106
        
 
107
        status = HCI_TransportRecvHCIEventSync(pConfig->pHCIDev,
 
108
                                               pRecvPacket,
 
109
                                               HCI_EVENT_RESP_TIMEOUTMS);
 
110
        if (status) {
 
111
            break;    
 
112
        }
 
113
 
 
114
        *pLength = pRecvPacket->ActualLength;
 
115
        
 
116
    } while (false);
 
117
       
 
118
    if (pRecvPacket != NULL) {
 
119
        A_FREE(pRecvPacket);    
 
120
    }
 
121
    
 
122
    return status;
 
123
 
124
    
 
125
int SendHCICommandWaitCommandComplete(struct ar3k_config_info *pConfig,
 
126
                                           u8 *pHCICommand,
 
127
                                           int              CmdLength,
 
128
                                           u8 **ppEventBuffer,
 
129
                                           u8 **ppBufferToFree)
 
130
{
 
131
    int    status = 0;
 
132
    u8 *pBuffer = NULL;
 
133
    u8 *pTemp;
 
134
    int         length;
 
135
    bool      commandComplete = false;
 
136
    u8 opCodeBytes[2];
 
137
                               
 
138
    do {
 
139
        
 
140
        length = max(HCI_MAX_EVT_RECV_LENGTH,CmdLength);
 
141
        length += pConfig->pHCIProps->HeadRoom + pConfig->pHCIProps->TailRoom;
 
142
        length += pConfig->pHCIProps->IOBlockPad;
 
143
                                     
 
144
        pBuffer = (u8 *)A_MALLOC(length);
 
145
        if (NULL == pBuffer) {
 
146
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: Failed to allocate bt buffer \n"));
 
147
            status = A_NO_MEMORY;
 
148
            break;    
 
149
        }
 
150
        
 
151
            /* get the opcodes to check the command complete event */
 
152
        opCodeBytes[0] = pHCICommand[HCI_CMD_OPCODE_BYTE_LOW_OFFSET];
 
153
        opCodeBytes[1] = pHCICommand[HCI_CMD_OPCODE_BYTE_HI_OFFSET];
 
154
        
 
155
            /* copy HCI command */
 
156
        memcpy(pBuffer + pConfig->pHCIProps->HeadRoom,pHCICommand,CmdLength);         
 
157
            /* send command */
 
158
        status = SendHCICommand(pConfig,
 
159
                                pBuffer + pConfig->pHCIProps->HeadRoom,
 
160
                                CmdLength);
 
161
        if (status) {
 
162
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: Failed to send HCI Command (%d) \n", status));
 
163
            AR_DEBUG_PRINTBUF(pHCICommand,CmdLength,"HCI Bridge Failed HCI Command");
 
164
            break;    
 
165
        }   
 
166
        
 
167
            /* reuse buffer to capture command complete event */
 
168
        A_MEMZERO(pBuffer,length);
 
169
        status = RecvHCIEvent(pConfig,pBuffer,&length);        
 
170
        if (status) {
 
171
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: HCI event recv failed \n"));
 
172
            AR_DEBUG_PRINTBUF(pHCICommand,CmdLength,"HCI Bridge Failed HCI Command");
 
173
            break;    
 
174
        }
 
175
        
 
176
        pTemp = pBuffer + pConfig->pHCIProps->HeadRoom;        
 
177
        if (pTemp[0] == HCI_CMD_COMPLETE_EVENT_CODE) {
 
178
            if ((pTemp[HCI_EVENT_OPCODE_BYTE_LOW] == opCodeBytes[0]) &&
 
179
                (pTemp[HCI_EVENT_OPCODE_BYTE_HI] == opCodeBytes[1])) {
 
180
                commandComplete = true;
 
181
            }
 
182
        }
 
183
        
 
184
        if (!commandComplete) {
 
185
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: Unexpected HCI event : %d \n",pTemp[0]));
 
186
            AR_DEBUG_PRINTBUF(pTemp,pTemp[1],"Unexpected HCI event");
 
187
            status = A_ECOMM;
 
188
            break;    
 
189
        }       
 
190
        
 
191
        if (ppEventBuffer != NULL) {
 
192
                /* caller wants to look at the event */
 
193
            *ppEventBuffer = pTemp;
 
194
            if (ppBufferToFree == NULL) {
 
195
                status = A_EINVAL;
 
196
                break;        
 
197
            }
 
198
                /* caller must free the buffer */
 
199
            *ppBufferToFree = pBuffer;
 
200
            pBuffer = NULL;            
 
201
        }
 
202
        
 
203
    } while (false);
 
204
 
 
205
    if (pBuffer != NULL) {
 
206
        A_FREE(pBuffer);    
 
207
    }
 
208
    
 
209
    return status;    
 
210
}
 
211
 
 
212
static int AR3KConfigureHCIBaud(struct ar3k_config_info *pConfig)
 
213
{
 
214
    int    status = 0;
 
215
    u8 hciBaudChangeCommand[] =  {0x0c,0xfc,0x2,0,0};
 
216
    u16 baudVal;
 
217
    u8 *pEvent = NULL;
 
218
    u8 *pBufferToFree = NULL;
 
219
    
 
220
    do {
 
221
        
 
222
        if (pConfig->Flags & AR3K_CONFIG_FLAG_SET_AR3K_BAUD) {
 
223
            baudVal = (u16)(pConfig->AR3KBaudRate / 100);
 
224
            hciBaudChangeCommand[3] = (u8)baudVal;
 
225
            hciBaudChangeCommand[4] = (u8)(baudVal >> 8);
 
226
            
 
227
            status = SendHCICommandWaitCommandComplete(pConfig,
 
228
                                                       hciBaudChangeCommand,
 
229
                                                       sizeof(hciBaudChangeCommand),
 
230
                                                       &pEvent,
 
231
                                                       &pBufferToFree);          
 
232
            if (status) {
 
233
                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: Baud rate change failed! \n"));  
 
234
                break;    
 
235
            }
 
236
            
 
237
            if (pEvent[BAUD_CHANGE_COMMAND_STATUS_OFFSET] != 0) {
 
238
                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
 
239
                    ("AR3K Config: Baud change command event status failed: %d \n", 
 
240
                                pEvent[BAUD_CHANGE_COMMAND_STATUS_OFFSET]));
 
241
                status = A_ECOMM; 
 
242
                break;           
 
243
            } 
 
244
            
 
245
            AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
 
246
                    ("AR3K Config: Baud Changed to %d \n",pConfig->AR3KBaudRate));  
 
247
        }
 
248
        
 
249
        if (pConfig->Flags & AR3K_CONFIG_FLAG_AR3K_BAUD_CHANGE_DELAY) {
 
250
                /* some versions of AR3K do not switch baud immediately, up to 300MS */
 
251
            A_MDELAY(325);
 
252
        }
 
253
        
 
254
        if (pConfig->Flags & AR3K_CONFIG_FLAG_SET_AR6K_SCALE_STEP) {
 
255
            /* Tell target to change UART baud rate for AR6K */
 
256
            status = HCI_TransportSetBaudRate(pConfig->pHCIDev, pConfig->AR3KBaudRate);
 
257
 
 
258
            if (status) {
 
259
                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
 
260
                    ("AR3K Config: failed to set scale and step values: %d \n", status));
 
261
                break;    
 
262
            }
 
263
    
 
264
            AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
 
265
                    ("AR3K Config: Baud changed to %d for AR6K\n", pConfig->AR3KBaudRate));            
 
266
        }
 
267
                
 
268
    } while (false);
 
269
                        
 
270
    if (pBufferToFree != NULL) {
 
271
        A_FREE(pBufferToFree);    
 
272
    }
 
273
        
 
274
    return status;
 
275
}
 
276
 
 
277
static int AR3KExitMinBoot(struct ar3k_config_info *pConfig)
 
278
{
 
279
    int  status;
 
280
    char exitMinBootCmd[] = {0x25,0xFC,0x0c,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
 
281
                                  0x00,0x00,0x00,0x00,0x00};
 
282
    u8 *pEvent = NULL;
 
283
    u8 *pBufferToFree = NULL;
 
284
    
 
285
    status = SendHCICommandWaitCommandComplete(pConfig,
 
286
                                               exitMinBootCmd,
 
287
                                               sizeof(exitMinBootCmd),
 
288
                                               &pEvent,
 
289
                                               &pBufferToFree);
 
290
    
 
291
    if (!status) {
 
292
        if (pEvent[EXIT_MIN_BOOT_COMMAND_STATUS_OFFSET] != 0) {
 
293
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
 
294
                ("AR3K Config: MinBoot exit command event status failed: %d \n", 
 
295
                            pEvent[EXIT_MIN_BOOT_COMMAND_STATUS_OFFSET]));
 
296
            status = A_ECOMM;            
 
297
        } else {
 
298
            AR_DEBUG_PRINTF(ATH_DEBUG_INFO, 
 
299
                                ("AR3K Config: MinBoot Exit Command Complete (Success) \n"));
 
300
            A_MDELAY(1);
 
301
        }
 
302
    } else {
 
303
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: MinBoot Exit Failed! \n"));    
 
304
    }
 
305
    
 
306
    if (pBufferToFree != NULL) {
 
307
        A_FREE(pBufferToFree);    
 
308
    }
 
309
    
 
310
    return status;                                              
 
311
}
 
312
                                 
 
313
static int AR3KConfigureSendHCIReset(struct ar3k_config_info *pConfig)
 
314
{
 
315
    int status = 0;
 
316
    u8 hciResetCommand[] = {0x03,0x0c,0x0};
 
317
    u8 *pEvent = NULL;
 
318
    u8 *pBufferToFree = NULL;
 
319
 
 
320
    status = SendHCICommandWaitCommandComplete( pConfig,
 
321
                                                hciResetCommand,
 
322
                                                sizeof(hciResetCommand),
 
323
                                                &pEvent,
 
324
                                                &pBufferToFree );
 
325
 
 
326
    if (status) {
 
327
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: HCI reset failed! \n"));
 
328
    }
 
329
 
 
330
    if (pBufferToFree != NULL) {
 
331
        A_FREE(pBufferToFree);
 
332
    }
 
333
 
 
334
    return status;
 
335
}
 
336
 
 
337
static int AR3KEnableTLPM(struct ar3k_config_info *pConfig)
 
338
{
 
339
    int  status;
 
340
    /* AR3K vendor specific command for Host Wakeup Config */
 
341
    char hostWakeupConfig[] = {0x31,0xFC,0x18,
 
342
                                    0x02,0x00,0x00,0x00,
 
343
                                    0x01,0x00,0x00,0x00,
 
344
                                    TLPM_DEFAULT_IDLE_TIMEOUT_LSB,TLPM_DEFAULT_IDLE_TIMEOUT_MSB,0x00,0x00,    //idle timeout in ms
 
345
                                    0x00,0x00,0x00,0x00,
 
346
                                    TLPM_DEFAULT_WAKEUP_TIMEOUT_MS,0x00,0x00,0x00,    //wakeup timeout in ms
 
347
                                    0x00,0x00,0x00,0x00};
 
348
    /* AR3K vendor specific command for Target Wakeup Config */
 
349
    char targetWakeupConfig[] = {0x31,0xFC,0x18,
 
350
                                      0x04,0x00,0x00,0x00,
 
351
                                      0x01,0x00,0x00,0x00,
 
352
                                      TLPM_DEFAULT_IDLE_TIMEOUT_LSB,TLPM_DEFAULT_IDLE_TIMEOUT_MSB,0x00,0x00,  //idle timeout in ms
 
353
                                      0x00,0x00,0x00,0x00,
 
354
                                      TLPM_DEFAULT_WAKEUP_TIMEOUT_MS,0x00,0x00,0x00,  //wakeup timeout in ms
 
355
                                      0x00,0x00,0x00,0x00};
 
356
    /* AR3K vendor specific command for Host Wakeup Enable */
 
357
    char hostWakeupEnable[] = {0x31,0xFC,0x4,
 
358
                                    0x01,0x00,0x00,0x00};
 
359
    /* AR3K vendor specific command for Target Wakeup Enable */
 
360
    char targetWakeupEnable[] = {0x31,0xFC,0x4,
 
361
                                      0x06,0x00,0x00,0x00};
 
362
    /* AR3K vendor specific command for Sleep Enable */
 
363
    char sleepEnable[] = {0x4,0xFC,0x1,
 
364
                               0x1};
 
365
    u8 *pEvent = NULL;
 
366
    u8 *pBufferToFree = NULL;
 
367
    
 
368
    if (0 != pConfig->IdleTimeout) {
 
369
        u8 idle_lsb = pConfig->IdleTimeout & 0xFF;
 
370
        u8 idle_msb = (pConfig->IdleTimeout & 0xFF00) >> 8;
 
371
        hostWakeupConfig[11] = targetWakeupConfig[11] = idle_lsb;
 
372
        hostWakeupConfig[12] = targetWakeupConfig[12] = idle_msb;
 
373
    }
 
374
 
 
375
    if (0 != pConfig->WakeupTimeout) {
 
376
        hostWakeupConfig[19] = targetWakeupConfig[19] = (pConfig->WakeupTimeout & 0xFF);
 
377
    }
 
378
 
 
379
    status = SendHCICommandWaitCommandComplete(pConfig,
 
380
                                               hostWakeupConfig,
 
381
                                               sizeof(hostWakeupConfig),
 
382
                                               &pEvent,
 
383
                                               &pBufferToFree);
 
384
    if (pBufferToFree != NULL) {
 
385
        A_FREE(pBufferToFree);    
 
386
    }
 
387
    if (status) {
 
388
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HostWakeup Config Failed! \n"));    
 
389
        return status;
 
390
    }
 
391
    
 
392
    pEvent = NULL;
 
393
    pBufferToFree = NULL;
 
394
    status = SendHCICommandWaitCommandComplete(pConfig,
 
395
                                               targetWakeupConfig,
 
396
                                               sizeof(targetWakeupConfig),
 
397
                                               &pEvent,
 
398
                                               &pBufferToFree);
 
399
    if (pBufferToFree != NULL) {
 
400
        A_FREE(pBufferToFree);    
 
401
    }
 
402
    if (status) {
 
403
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Target Wakeup Config Failed! \n"));    
 
404
        return status;
 
405
    }
 
406
 
 
407
    pEvent = NULL;
 
408
    pBufferToFree = NULL;
 
409
    status = SendHCICommandWaitCommandComplete(pConfig,
 
410
                                               hostWakeupEnable,
 
411
                                               sizeof(hostWakeupEnable),
 
412
                                               &pEvent,
 
413
                                               &pBufferToFree);
 
414
    if (pBufferToFree != NULL) {
 
415
        A_FREE(pBufferToFree);    
 
416
    }
 
417
    if (status) {
 
418
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HostWakeup Enable Failed! \n"));    
 
419
        return status;
 
420
    }
 
421
 
 
422
    pEvent = NULL;
 
423
    pBufferToFree = NULL;
 
424
    status = SendHCICommandWaitCommandComplete(pConfig,
 
425
                                               targetWakeupEnable,
 
426
                                               sizeof(targetWakeupEnable),
 
427
                                               &pEvent,
 
428
                                               &pBufferToFree);
 
429
    if (pBufferToFree != NULL) {
 
430
        A_FREE(pBufferToFree);    
 
431
    }
 
432
    if (status) {
 
433
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Target Wakeup Enable Failed! \n"));    
 
434
        return status;
 
435
    }
 
436
 
 
437
    pEvent = NULL;
 
438
    pBufferToFree = NULL;
 
439
    status = SendHCICommandWaitCommandComplete(pConfig,
 
440
                                               sleepEnable,
 
441
                                               sizeof(sleepEnable),
 
442
                                               &pEvent,
 
443
                                               &pBufferToFree);
 
444
    if (pBufferToFree != NULL) {
 
445
        A_FREE(pBufferToFree);    
 
446
    }
 
447
    if (status) {
 
448
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Sleep Enable Failed! \n"));    
 
449
    }
 
450
    
 
451
    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: Enable TLPM Completed (status = %d) \n",status));
 
452
 
 
453
    return status;                                              
 
454
}
 
455
 
 
456
int AR3KConfigure(struct ar3k_config_info *pConfig)
 
457
{
 
458
    int        status = 0;
 
459
        
 
460
    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR3K Config: Configuring AR3K ...\n"));
 
461
                                
 
462
    do {
 
463
        
 
464
        if ((pConfig->pHCIDev == NULL) || (pConfig->pHCIProps == NULL) || (pConfig->pHIFDevice == NULL)) {
 
465
            status = A_EINVAL;
 
466
            break;    
 
467
        }
 
468
        
 
469
            /* disable asynchronous recv while we issue commands and receive events synchronously */
 
470
        status = HCI_TransportEnableDisableAsyncRecv(pConfig->pHCIDev,false);
 
471
        if (status) {
 
472
            break;    
 
473
        }
 
474
      
 
475
        if (pConfig->Flags & AR3K_CONFIG_FLAG_FORCE_MINBOOT_EXIT) {
 
476
            status =  AR3KExitMinBoot(pConfig);   
 
477
            if (status) {
 
478
                break;    
 
479
            }    
 
480
        }
 
481
        
 
482
       
 
483
        /* Load patching and PST file if available*/
 
484
        if (0 != AthPSInitialize(pConfig)) {
 
485
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Patch Download Failed!\n"));
 
486
        }
 
487
 
 
488
        /* Send HCI reset to make PS tags take effect*/
 
489
        AR3KConfigureSendHCIReset(pConfig);
 
490
 
 
491
        if (pConfig->Flags & 
 
492
                (AR3K_CONFIG_FLAG_SET_AR3K_BAUD | AR3K_CONFIG_FLAG_SET_AR6K_SCALE_STEP)) {
 
493
            status = AR3KConfigureHCIBaud(pConfig);      
 
494
            if (status) {
 
495
                break;    
 
496
            }
 
497
        }     
 
498
 
 
499
 
 
500
 
 
501
        if (pConfig->PwrMgmtEnabled) {
 
502
            /* the delay is required after the previous HCI reset before further
 
503
             * HCI commands can be issued
 
504
             */
 
505
            A_MDELAY(200);
 
506
            AR3KEnableTLPM(pConfig);
 
507
        }
 
508
               
 
509
           /* re-enable asynchronous recv */
 
510
        status = HCI_TransportEnableDisableAsyncRecv(pConfig->pHCIDev,true);
 
511
        if (status) {
 
512
            break;    
 
513
        }     
 
514
    
 
515
    
 
516
    } while (false);
 
517
    
 
518
  
 
519
    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR3K Config: Configuration Complete (status = %d) \n",status));
 
520
    
 
521
    return status;
 
522
}
 
523
 
 
524
int AR3KConfigureExit(void *config)
 
525
{
 
526
    int        status = 0;
 
527
    struct ar3k_config_info *pConfig = (struct ar3k_config_info *)config;
 
528
        
 
529
    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR3K Config: Cleaning up AR3K ...\n"));
 
530
                                
 
531
    do {
 
532
        
 
533
        if ((pConfig->pHCIDev == NULL) || (pConfig->pHCIProps == NULL) || (pConfig->pHIFDevice == NULL)) {
 
534
            status = A_EINVAL;
 
535
            break;    
 
536
        }
 
537
        
 
538
            /* disable asynchronous recv while we issue commands and receive events synchronously */
 
539
        status = HCI_TransportEnableDisableAsyncRecv(pConfig->pHCIDev,false);
 
540
        if (status) {
 
541
            break;    
 
542
        }
 
543
      
 
544
        if (pConfig->Flags & 
 
545
                (AR3K_CONFIG_FLAG_SET_AR3K_BAUD | AR3K_CONFIG_FLAG_SET_AR6K_SCALE_STEP)) {
 
546
            status = AR3KConfigureHCIBaud(pConfig);      
 
547
            if (status) {
 
548
                break;    
 
549
            }
 
550
        }
 
551
 
 
552
           /* re-enable asynchronous recv */
 
553
        status = HCI_TransportEnableDisableAsyncRecv(pConfig->pHCIDev,true);
 
554
        if (status) {
 
555
            break;    
 
556
        }     
 
557
    
 
558
    
 
559
    } while (false);
 
560
    
 
561
  
 
562
    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR3K Config: Cleanup Complete (status = %d) \n",status));
 
563
    
 
564
    return status;
 
565
}
 
566