1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29#include "ar3kpsconfig.h"
30#ifndef HCI_TRANSPORT_SDIO
31#include "hci_ath.h"
32#include "hci_uart.h"
33#endif
34
35#define MAX_FW_PATH_LEN 50
36#define MAX_BDADDR_FORMAT_LENGTH 30
37
38
39
40
41
42typedef struct {
43
44 struct ps_cmd_packet *HciCmdList;
45 u32 num_packets;
46 struct ar3k_config_info *dev;
47}HciCommandListParam;
48
49int SendHCICommandWaitCommandComplete(struct ar3k_config_info *pConfig,
50 u8 *pHCICommand,
51 int CmdLength,
52 u8 **ppEventBuffer,
53 u8 **ppBufferToFree);
54
55u32 Rom_Version;
56u32 Build_Version;
57extern bool BDADDR;
58
59int getDeviceType(struct ar3k_config_info *pConfig, u32 *code);
60int ReadVersionInfo(struct ar3k_config_info *pConfig);
61#ifndef HCI_TRANSPORT_SDIO
62
63DECLARE_WAIT_QUEUE_HEAD(PsCompleteEvent);
64DECLARE_WAIT_QUEUE_HEAD(HciEvent);
65u8 *HciEventpacket;
66rwlock_t syncLock;
67wait_queue_t Eventwait;
68
69int PSHciWritepacket(struct hci_dev*,u8* Data, u32 len);
70extern char *bdaddr;
71#endif
72
73int write_bdaddr(struct ar3k_config_info *pConfig,u8 *bdaddr,int type);
74
75int PSSendOps(void *arg);
76
77#ifdef BT_PS_DEBUG
78void Hci_log(u8 * log_string,u8 *data,u32 len)
79{
80 int i;
81 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s : ",log_string));
82 for (i = 0; i < len; i++) {
83 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("0x%02x ", data[i]));
84 }
85 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("\n...................................\n"));
86}
87#else
88#define Hci_log(string,data,len)
89#endif
90
91
92
93
94int AthPSInitialize(struct ar3k_config_info *hdev)
95{
96 int status = 0;
97 if(hdev == NULL) {
98 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Invalid Device handle received\n"));
99 return A_ERROR;
100 }
101
102#ifndef HCI_TRANSPORT_SDIO
103 DECLARE_WAITQUEUE(wait, current);
104#endif
105
106
107#ifdef HCI_TRANSPORT_SDIO
108 status = PSSendOps((void*)hdev);
109#else
110 if(InitPSState(hdev) == -1) {
111 return A_ERROR;
112 }
113 allow_signal(SIGKILL);
114 add_wait_queue(&PsCompleteEvent,&wait);
115 set_current_state(TASK_INTERRUPTIBLE);
116 if(!kernel_thread(PSSendOps,(void*)hdev,CLONE_FS|CLONE_FILES|CLONE_SIGHAND|SIGCHLD)) {
117 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Kthread Failed\n"));
118 remove_wait_queue(&PsCompleteEvent,&wait);
119 return A_ERROR;
120 }
121 wait_event_interruptible(PsCompleteEvent,(PSTagMode == false));
122 set_current_state(TASK_RUNNING);
123 remove_wait_queue(&PsCompleteEvent,&wait);
124
125#endif
126
127
128 return status;
129
130}
131
132int PSSendOps(void *arg)
133{
134 int i;
135 int status = 0;
136 struct ps_cmd_packet *HciCmdList;
137 const struct firmware* firmware;
138 u32 numCmds;
139 u8 *event;
140 u8 *bufferToFree;
141 struct hci_dev *device;
142 u8 *buffer;
143 u32 len;
144 u32 DevType;
145 u8 *PsFileName;
146 u8 *patchFileName;
147 u8 *path = NULL;
148 u8 *config_path = NULL;
149 u8 config_bdaddr[MAX_BDADDR_FORMAT_LENGTH];
150 struct ar3k_config_info *hdev = (struct ar3k_config_info*)arg;
151 struct device *firmwareDev = NULL;
152 status = 0;
153 HciCmdList = NULL;
154#ifdef HCI_TRANSPORT_SDIO
155 device = hdev->pBtStackHCIDev;
156 firmwareDev = device->parent;
157#else
158 device = hdev;
159 firmwareDev = &device->dev;
160 AthEnableSyncCommandOp(true);
161#endif
162
163
164
165 path =(u8 *)A_MALLOC(MAX_FW_PATH_LEN);
166 if(path == NULL) {
167 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Malloc failed to allocate %d bytes for path\n", MAX_FW_PATH_LEN));
168 goto complete;
169 }
170 config_path = (u8 *) A_MALLOC(MAX_FW_PATH_LEN);
171 if(config_path == NULL) {
172 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Malloc failed to allocate %d bytes for config_path\n", MAX_FW_PATH_LEN));
173 goto complete;
174 }
175
176 if(A_ERROR == getDeviceType(hdev,&DevType)) {
177 status = 1;
178 goto complete;
179 }
180 if(A_ERROR == ReadVersionInfo(hdev)) {
181 status = 1;
182 goto complete;
183 }
184
185 patchFileName = PATCH_FILE;
186 snprintf(path, MAX_FW_PATH_LEN, "%s/%xcoex/",CONFIG_PATH,Rom_Version);
187 if(DevType){
188 if(DevType == 0xdeadc0de){
189 PsFileName = PS_ASIC_FILE;
190 } else{
191 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" FPGA Test Image : %x %x \n",Rom_Version,Build_Version));
192 if((Rom_Version == 0x99999999) && (Build_Version == 1)){
193
194 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("FPGA Test Image : Skipping Patch File load\n"));
195 patchFileName = NULL;
196 }
197 PsFileName = PS_FPGA_FILE;
198 }
199 }
200 else{
201 PsFileName = PS_ASIC_FILE;
202 }
203
204 snprintf(config_path, MAX_FW_PATH_LEN, "%s%s",path,PsFileName);
205 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%x: FPGA/ASIC PS File Name %s\n", DevType,config_path));
206
207 if(A_REQUEST_FIRMWARE(&firmware,config_path,firmwareDev) < 0) {
208 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: firmware file open error\n", __FUNCTION__ ));
209 status = 1;
210 goto complete;
211
212 }
213 if(NULL == firmware || firmware->size == 0) {
214 status = 1;
215 goto complete;
216 }
217 buffer = (u8 *)A_MALLOC(firmware->size);
218 if(buffer != NULL) {
219
220 memcpy(buffer,firmware->data,firmware->size);
221 len = firmware->size;
222 A_RELEASE_FIRMWARE(firmware);
223
224 status = AthDoParsePS(buffer,len);
225 kfree(buffer);
226 } else {
227 A_RELEASE_FIRMWARE(firmware);
228 }
229
230
231
232 if(patchFileName != NULL)
233 snprintf(config_path,
234 MAX_FW_PATH_LEN, "%s%s",path,patchFileName);
235 else {
236 status = 0;
237 }
238 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Patch File Name %s\n", config_path));
239 if((patchFileName == NULL) || (A_REQUEST_FIRMWARE(&firmware,config_path,firmwareDev) < 0)) {
240 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: firmware file open error\n", __FUNCTION__ ));
241
242
243
244
245 status = 0;
246
247 } else {
248 if(NULL == firmware || firmware->size == 0) {
249 status = 0;
250 } else {
251 buffer = (u8 *)A_MALLOC(firmware->size);
252 if(buffer != NULL) {
253
254 memcpy(buffer,firmware->data,firmware->size);
255 len = firmware->size;
256 A_RELEASE_FIRMWARE(firmware);
257
258 status = AthDoParsePatch(buffer,len);
259 kfree(buffer);
260 } else {
261 A_RELEASE_FIRMWARE(firmware);
262 }
263 }
264 }
265
266
267 AthCreateCommandList(&HciCmdList,&numCmds);
268
269
270
271
272
273
274
275
276
277
278 if(SendHCICommandWaitCommandComplete
279 (hdev,
280 HciCmdList[0].Hcipacket,
281 HciCmdList[0].packetLen,
282 &event,
283 &bufferToFree) == 0) {
284 if(ReadPSEvent(event) == 0) {
285 if(bufferToFree != NULL) {
286 kfree(bufferToFree);
287 }
288
289#ifndef HCI_TRANSPORT_SDIO
290 if(bdaddr && bdaddr[0] !='\0') {
291 write_bdaddr(hdev,bdaddr,BDADDR_TYPE_STRING);
292 }
293#endif
294 status = 1;
295 goto complete;
296 }
297 if(bufferToFree != NULL) {
298 kfree(bufferToFree);
299 }
300 } else {
301 status = 0;
302 goto complete;
303 }
304
305 for(i = 1; i <numCmds; i++) {
306
307 if(SendHCICommandWaitCommandComplete
308 (hdev,
309 HciCmdList[i].Hcipacket,
310 HciCmdList[i].packetLen,
311 &event,
312 &bufferToFree) == 0) {
313 if(ReadPSEvent(event) != 0) {
314 if(bufferToFree != NULL) {
315 kfree(bufferToFree);
316 }
317 status = 1;
318 goto complete;
319 }
320 if(bufferToFree != NULL) {
321 kfree(bufferToFree);
322 }
323 } else {
324 status = 0;
325 goto complete;
326 }
327 }
328#ifdef HCI_TRANSPORT_SDIO
329 if(BDADDR == false)
330 if(hdev->bdaddr[0] !=0x00 ||
331 hdev->bdaddr[1] !=0x00 ||
332 hdev->bdaddr[2] !=0x00 ||
333 hdev->bdaddr[3] !=0x00 ||
334 hdev->bdaddr[4] !=0x00 ||
335 hdev->bdaddr[5] !=0x00)
336 write_bdaddr(hdev,hdev->bdaddr,BDADDR_TYPE_HEX);
337
338#ifndef HCI_TRANSPORT_SDIO
339
340 if(bdaddr && bdaddr[0] != '\0') {
341 write_bdaddr(hdev,bdaddr,BDADDR_TYPE_STRING);
342 } else
343#endif
344
345
346
347
348#endif
349
350 {
351
352 snprintf(config_path,MAX_FW_PATH_LEN, "%s%s",path,BDADDR_FILE);
353 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Patch File Name %s\n", config_path));
354 if(A_REQUEST_FIRMWARE(&firmware,config_path,firmwareDev) < 0) {
355 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: firmware file open error\n", __FUNCTION__ ));
356 status = 1;
357 goto complete;
358 }
359 if(NULL == firmware || firmware->size == 0) {
360 status = 1;
361 goto complete;
362 }
363 len = min_t(size_t, firmware->size, MAX_BDADDR_FORMAT_LENGTH - 1);
364 memcpy(config_bdaddr, firmware->data, len);
365 config_bdaddr[len] = '\0';
366 write_bdaddr(hdev,config_bdaddr,BDADDR_TYPE_STRING);
367 A_RELEASE_FIRMWARE(firmware);
368 }
369complete:
370#ifndef HCI_TRANSPORT_SDIO
371 AthEnableSyncCommandOp(false);
372 PSTagMode = false;
373 wake_up_interruptible(&PsCompleteEvent);
374#endif
375 if(NULL != HciCmdList) {
376 AthFreeCommandList(&HciCmdList,numCmds);
377 }
378 if(path) {
379 kfree(path);
380 }
381 if(config_path) {
382 kfree(config_path);
383 }
384 return status;
385}
386#ifndef HCI_TRANSPORT_SDIO
387
388
389
390
391
392int SendHCICommandWaitCommandComplete(struct ar3k_config_info *pConfig,
393 u8 *pHCICommand,
394 int CmdLength,
395 u8 **ppEventBuffer,
396 u8 **ppBufferToFree)
397{
398 if(CmdLength == 0) {
399 return A_ERROR;
400 }
401 Hci_log("COM Write -->",pHCICommand,CmdLength);
402 PSAcked = false;
403 if(PSHciWritepacket(pConfig,pHCICommand,CmdLength) == 0) {
404
405 return A_ERROR;
406 }
407
408 wait_event_interruptible(HciEvent,(PSAcked == true));
409 if(NULL != HciEventpacket) {
410 *ppEventBuffer = HciEventpacket;
411 *ppBufferToFree = HciEventpacket;
412 } else {
413
414 *ppBufferToFree = NULL;
415 return A_ERROR;
416 }
417
418 return 0;
419}
420#endif
421
422int ReadPSEvent(u8* Data){
423 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" PS Event %x %x %x\n",Data[4],Data[5],Data[3]));
424
425 if(Data[4] == 0xFC && Data[5] == 0x00)
426 {
427 switch(Data[3]){
428 case 0x0B:
429 return 0;
430 break;
431 case 0x0C:
432
433 return 0;
434 break;
435 case 0x04:
436 return 0;
437 break;
438 case 0x1E:
439 Rom_Version = Data[9];
440 Rom_Version = ((Rom_Version << 8) |Data[8]);
441 Rom_Version = ((Rom_Version << 8) |Data[7]);
442 Rom_Version = ((Rom_Version << 8) |Data[6]);
443
444 Build_Version = Data[13];
445 Build_Version = ((Build_Version << 8) |Data[12]);
446 Build_Version = ((Build_Version << 8) |Data[11]);
447 Build_Version = ((Build_Version << 8) |Data[10]);
448 return 0;
449 break;
450
451
452 }
453 }
454
455 return A_ERROR;
456}
457int str2ba(unsigned char *str_bdaddr,unsigned char *bdaddr)
458{
459 unsigned char bdbyte[3];
460 unsigned char *str_byte = str_bdaddr;
461 int i,j;
462 unsigned char colon_present = 0;
463
464 if(NULL != strstr(str_bdaddr,":")) {
465 colon_present = 1;
466 }
467
468
469 bdbyte[2] = '\0';
470
471 for( i = 0,j = 5; i < 6; i++, j--) {
472 bdbyte[0] = str_byte[0];
473 bdbyte[1] = str_byte[1];
474 bdaddr[j] = A_STRTOL(bdbyte,NULL,16);
475 if(colon_present == 1) {
476 str_byte+=3;
477 } else {
478 str_byte+=2;
479 }
480 }
481 return 0;
482}
483
484int write_bdaddr(struct ar3k_config_info *pConfig,u8 *bdaddr,int type)
485{
486 u8 bdaddr_cmd[] = { 0x0B, 0xFC, 0x0A, 0x01, 0x01,
487 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
488
489 u8 *event;
490 u8 *bufferToFree = NULL;
491 int result = A_ERROR;
492 int inc,outc;
493
494 if (type == BDADDR_TYPE_STRING)
495 str2ba(bdaddr,&bdaddr_cmd[7]);
496 else {
497
498 for(inc = 5 ,outc = 7; inc >=0; inc--, outc++)
499 bdaddr_cmd[outc] = bdaddr[inc];
500 }
501
502 if(0 == SendHCICommandWaitCommandComplete(pConfig,bdaddr_cmd,
503 sizeof(bdaddr_cmd),
504 &event,&bufferToFree)) {
505
506 if(event[4] == 0xFC && event[5] == 0x00){
507 if(event[3] == 0x0B){
508 result = 0;
509 }
510 }
511
512 }
513 if(bufferToFree != NULL) {
514 kfree(bufferToFree);
515 }
516 return result;
517
518}
519int ReadVersionInfo(struct ar3k_config_info *pConfig)
520{
521 u8 hciCommand[] = {0x1E,0xfc,0x00};
522 u8 *event;
523 u8 *bufferToFree = NULL;
524 int result = A_ERROR;
525 if(0 == SendHCICommandWaitCommandComplete(pConfig,hciCommand,sizeof(hciCommand),&event,&bufferToFree)) {
526 result = ReadPSEvent(event);
527
528 }
529 if(bufferToFree != NULL) {
530 kfree(bufferToFree);
531 }
532 return result;
533}
534int getDeviceType(struct ar3k_config_info *pConfig, u32 *code)
535{
536 u8 hciCommand[] = {0x05,0xfc,0x05,0x00,0x00,0x00,0x00,0x04};
537 u8 *event;
538 u8 *bufferToFree = NULL;
539 u32 reg;
540 int result = A_ERROR;
541 *code = 0;
542 hciCommand[3] = (u8)(FPGA_REGISTER & 0xFF);
543 hciCommand[4] = (u8)((FPGA_REGISTER >> 8) & 0xFF);
544 hciCommand[5] = (u8)((FPGA_REGISTER >> 16) & 0xFF);
545 hciCommand[6] = (u8)((FPGA_REGISTER >> 24) & 0xFF);
546 if(0 == SendHCICommandWaitCommandComplete(pConfig,hciCommand,sizeof(hciCommand),&event,&bufferToFree)) {
547
548 if(event[4] == 0xFC && event[5] == 0x00){
549 switch(event[3]){
550 case 0x05:
551 reg = event[9];
552 reg = ((reg << 8) |event[8]);
553 reg = ((reg << 8) |event[7]);
554 reg = ((reg << 8) |event[6]);
555 *code = reg;
556 result = 0;
557
558 break;
559 case 0x06:
560
561 break;
562 }
563 }
564
565 }
566 if(bufferToFree != NULL) {
567 kfree(bufferToFree);
568 }
569 return result;
570}
571
572
573