]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blob - drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c
Merge branch 'for-2.6.39' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu
[mirror_ubuntu-bionic-kernel.git] / drivers / staging / ath6kl / miscdrv / ar3kps / ar3kpsconfig.c
1 /*
2 * Copyright (c) 2004-2010 Atheros Communications Inc.
3 * All rights reserved.
4 *
5 * This file implements the Atheros PS and patch downloaded for HCI UART Transport driver.
6 * This file can be used for HCI SDIO transport implementation for AR6002 with HCI_TRANSPORT_SDIO
7 * defined.
8 *
9 *
10 * ar3kcpsconfig.c
11 *
12 *
13 *
14 * The software source and binaries included in this development package are
15 * licensed, not sold. You, or your company, received the package under one
16 * or more license agreements. The rights granted to you are specifically
17 * listed in these license agreement(s). All other rights remain with Atheros
18 * Communications, Inc., its subsidiaries, or the respective owner including
19 * those listed on the included copyright notices.. Distribution of any
20 * portion of this package must be in strict compliance with the license
21 * agreement(s) terms.
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 /* #ifndef HCI_TRANSPORT_SDIO */
34
35 #define MAX_FW_PATH_LEN 50
36 #define MAX_BDADDR_FORMAT_LENGTH 30
37
38 /*
39 * Structure used to send HCI packet, hci packet length and device info
40 * together as parameter to PSThread.
41 */
42 typedef struct {
43
44 PSCmdPacket *HciCmdList;
45 A_UINT32 num_packets;
46 AR3K_CONFIG_INFO *dev;
47 }HciCommandListParam;
48
49 A_STATUS SendHCICommandWaitCommandComplete(AR3K_CONFIG_INFO *pConfig,
50 A_UINT8 *pHCICommand,
51 int CmdLength,
52 A_UINT8 **ppEventBuffer,
53 A_UINT8 **ppBufferToFree);
54
55 A_UINT32 Rom_Version;
56 A_UINT32 Build_Version;
57 extern A_BOOL BDADDR;
58
59 A_STATUS getDeviceType(AR3K_CONFIG_INFO *pConfig, A_UINT32 * code);
60 A_STATUS ReadVersionInfo(AR3K_CONFIG_INFO *pConfig);
61 #ifndef HCI_TRANSPORT_SDIO
62
63 DECLARE_WAIT_QUEUE_HEAD(PsCompleteEvent);
64 DECLARE_WAIT_QUEUE_HEAD(HciEvent);
65 A_UCHAR *HciEventpacket;
66 rwlock_t syncLock;
67 wait_queue_t Eventwait;
68
69 int PSHciWritepacket(struct hci_dev*,A_UCHAR* Data, A_UINT32 len);
70 extern char *bdaddr;
71 #endif /* HCI_TRANSPORT_SDIO */
72
73 A_STATUS write_bdaddr(AR3K_CONFIG_INFO *pConfig,A_UCHAR *bdaddr,int type);
74
75 int PSSendOps(void *arg);
76
77 #ifdef BT_PS_DEBUG
78 void Hci_log(A_UCHAR * log_string,A_UCHAR *data,A_UINT32 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 /* BT_PS_DEBUG */
90
91
92
93
94 A_STATUS AthPSInitialize(AR3K_CONFIG_INFO *hdev)
95 {
96 A_STATUS status = A_OK;
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 /* HCI_TRANSPORT_SDIO */
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 /* HCI_TRANSPORT_SDIO */
126
127
128 return status;
129
130 }
131
132 int PSSendOps(void *arg)
133 {
134 int i;
135 int status = 0;
136 PSCmdPacket *HciCmdList; /* List storing the commands */
137 const struct firmware* firmware;
138 A_UINT32 numCmds;
139 A_UINT8 *event;
140 A_UINT8 *bufferToFree;
141 struct hci_dev *device;
142 A_UCHAR *buffer;
143 A_UINT32 len;
144 A_UINT32 DevType;
145 A_UCHAR *PsFileName;
146 A_UCHAR *patchFileName;
147 A_UCHAR *path = NULL;
148 A_UCHAR *config_path = NULL;
149 A_UCHAR config_bdaddr[MAX_BDADDR_FORMAT_LENGTH];
150 AR3K_CONFIG_INFO *hdev = (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 /* HCI_TRANSPORT_SDIO */
162 /* First verify if the controller is an FPGA or ASIC, so depending on the device type the PS file to be written will be different.
163 */
164
165 path =(A_UCHAR *)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 = (A_UCHAR *) 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 /* Read the PS file to a dynamically allocated buffer */
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 = (A_UCHAR *)A_MALLOC(firmware->size);
218 if(buffer != NULL) {
219 /* Copy the read file to a local Dynamic buffer */
220 memcpy(buffer,firmware->data,firmware->size);
221 len = firmware->size;
222 A_RELEASE_FIRMWARE(firmware);
223 /* Parse the PS buffer to a global variable */
224 status = AthDoParsePS(buffer,len);
225 A_FREE(buffer);
226 } else {
227 A_RELEASE_FIRMWARE(firmware);
228 }
229
230
231 /* Read the patch file to a dynamically allocated buffer */
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 * It is not necessary that Patch file be available, continue with PS Operations if.
243 * failed.
244 */
245 status = 0;
246
247 } else {
248 if(NULL == firmware || firmware->size == 0) {
249 status = 0;
250 } else {
251 buffer = (A_UCHAR *)A_MALLOC(firmware->size);
252 if(buffer != NULL) {
253 /* Copy the read file to a local Dynamic buffer */
254 memcpy(buffer,firmware->data,firmware->size);
255 len = firmware->size;
256 A_RELEASE_FIRMWARE(firmware);
257 /* parse and store the Patch file contents to a global variables */
258 status = AthDoParsePatch(buffer,len);
259 A_FREE(buffer);
260 } else {
261 A_RELEASE_FIRMWARE(firmware);
262 }
263 }
264 }
265
266 /* Create an HCI command list from the parsed PS and patch information */
267 AthCreateCommandList(&HciCmdList,&numCmds);
268
269 /* Form the parameter for PSSendOps() API */
270
271
272 /*
273 * First Send the CRC packet,
274 * We have to continue with the PS operations only if the CRC packet has been replied with
275 * a Command complete event with status Error.
276 */
277
278 if(SendHCICommandWaitCommandComplete
279 (hdev,
280 HciCmdList[0].Hcipacket,
281 HciCmdList[0].packetLen,
282 &event,
283 &bufferToFree) == A_OK) {
284 if(ReadPSEvent(event) == A_OK) { /* Exit if the status is success */
285 if(bufferToFree != NULL) {
286 A_FREE(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 A_FREE(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) == A_OK) {
313 if(ReadPSEvent(event) != A_OK) { /* Exit if the status is success */
314 if(bufferToFree != NULL) {
315 A_FREE(bufferToFree);
316 }
317 status = 1;
318 goto complete;
319 }
320 if(bufferToFree != NULL) {
321 A_FREE(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 /* HCI_TRANSPORT_SDIO */
344 /* Write BDADDR Read from OTP here */
345
346
347
348 #endif
349
350 {
351 /* Read Contents of BDADDR file if user has not provided any option */
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(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 }
369 complete:
370 #ifndef HCI_TRANSPORT_SDIO
371 AthEnableSyncCommandOp(FALSE);
372 PSTagMode = FALSE;
373 wake_up_interruptible(&PsCompleteEvent);
374 #endif /* HCI_TRANSPORT_SDIO */
375 if(NULL != HciCmdList) {
376 AthFreeCommandList(&HciCmdList,numCmds);
377 }
378 if(path) {
379 A_FREE(path);
380 }
381 if(config_path) {
382 A_FREE(config_path);
383 }
384 return status;
385 }
386 #ifndef HCI_TRANSPORT_SDIO
387 /*
388 * This API is used to send the HCI command to controller and return
389 * with a HCI Command Complete event.
390 * For HCI SDIO transport, this will be internally defined.
391 */
392 A_STATUS SendHCICommandWaitCommandComplete(AR3K_CONFIG_INFO *pConfig,
393 A_UINT8 *pHCICommand,
394 int CmdLength,
395 A_UINT8 **ppEventBuffer,
396 A_UINT8 **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 /* If the controller is not available, return Error */
405 return A_ERROR;
406 }
407 //add_timer(&psCmdTimer);
408 wait_event_interruptible(HciEvent,(PSAcked == TRUE));
409 if(NULL != HciEventpacket) {
410 *ppEventBuffer = HciEventpacket;
411 *ppBufferToFree = HciEventpacket;
412 } else {
413 /* Did not get an event from controller. return error */
414 *ppBufferToFree = NULL;
415 return A_ERROR;
416 }
417
418 return A_OK;
419 }
420 #endif /* HCI_TRANSPORT_SDIO */
421
422 A_STATUS ReadPSEvent(A_UCHAR* 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 A_OK;
430 break;
431 case 0x0C:
432 /* Change Baudrate */
433 return A_OK;
434 break;
435 case 0x04:
436 return A_OK;
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 A_OK;
449 break;
450
451
452 }
453 }
454
455 return A_ERROR;
456 }
457 int 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
484 A_STATUS write_bdaddr(AR3K_CONFIG_INFO *pConfig,A_UCHAR *bdaddr,int type)
485 {
486 A_UCHAR bdaddr_cmd[] = { 0x0B, 0xFC, 0x0A, 0x01, 0x01,
487 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
488
489 A_UINT8 *event;
490 A_UINT8 *bufferToFree = NULL;
491 A_STATUS result = A_ERROR;
492 int inc,outc;
493
494 if (type == BDADDR_TYPE_STRING)
495 str2ba(bdaddr,&bdaddr_cmd[7]);
496 else {
497 /* Bdaddr has to be sent as LAP first */
498 for(inc = 5 ,outc = 7; inc >=0; inc--, outc++)
499 bdaddr_cmd[outc] = bdaddr[inc];
500 }
501
502 if(A_OK == 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 = A_OK;
509 }
510 }
511
512 }
513 if(bufferToFree != NULL) {
514 A_FREE(bufferToFree);
515 }
516 return result;
517
518 }
519 A_STATUS ReadVersionInfo(AR3K_CONFIG_INFO *pConfig)
520 {
521 A_UINT8 hciCommand[] = {0x1E,0xfc,0x00};
522 A_UINT8 *event;
523 A_UINT8 *bufferToFree = NULL;
524 A_STATUS result = A_ERROR;
525 if(A_OK == SendHCICommandWaitCommandComplete(pConfig,hciCommand,sizeof(hciCommand),&event,&bufferToFree)) {
526 result = ReadPSEvent(event);
527
528 }
529 if(bufferToFree != NULL) {
530 A_FREE(bufferToFree);
531 }
532 return result;
533 }
534 A_STATUS getDeviceType(AR3K_CONFIG_INFO *pConfig, A_UINT32 * code)
535 {
536 A_UINT8 hciCommand[] = {0x05,0xfc,0x05,0x00,0x00,0x00,0x00,0x04};
537 A_UINT8 *event;
538 A_UINT8 *bufferToFree = NULL;
539 A_UINT32 reg;
540 A_STATUS result = A_ERROR;
541 *code = 0;
542 hciCommand[3] = (A_UINT8)(FPGA_REGISTER & 0xFF);
543 hciCommand[4] = (A_UINT8)((FPGA_REGISTER >> 8) & 0xFF);
544 hciCommand[5] = (A_UINT8)((FPGA_REGISTER >> 16) & 0xFF);
545 hciCommand[6] = (A_UINT8)((FPGA_REGISTER >> 24) & 0xFF);
546 if(A_OK == 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 = A_OK;
557
558 break;
559 case 0x06:
560 //Sleep(500);
561 break;
562 }
563 }
564
565 }
566 if(bufferToFree != NULL) {
567 A_FREE(bufferToFree);
568 }
569 return result;
570 }
571
572