net: wireless: rockchip_wlan: add rtl8723ds support
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8723ds / core / rtw_bt_mp.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17  *
18  *
19  ******************************************************************************/
20
21
22 #include <drv_types.h>
23 #include <rtw_bt_mp.h>
24
25 #if defined(CONFIG_RTL8723B)
26         #include <rtl8723b_hal.h>
27 #endif
28
29 #if defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8821A)
30 void MPh2c_timeout_handle(void *FunctionContext)
31 {
32         PADAPTER pAdapter;
33         PMPT_CONTEXT pMptCtx;
34
35
36         RTW_INFO("[MPT], MPh2c_timeout_handle\n");
37
38         pAdapter = (PADAPTER)FunctionContext;
39         pMptCtx = &pAdapter->mppriv.MptCtx;
40
41         pMptCtx->bMPh2c_timeout = _TRUE;
42
43         if ((_FALSE == pMptCtx->MptH2cRspEvent)
44             || ((_TRUE == pMptCtx->MptH2cRspEvent)
45                 && (_FALSE == pMptCtx->MptBtC2hEvent)))
46                 _rtw_up_sema(&pMptCtx->MPh2c_Sema);
47 }
48
49 u32 WaitC2Hevent(PADAPTER pAdapter, u8 *C2H_event, u32 delay_time)
50 {
51         PMPT_CONTEXT            pMptCtx = &(pAdapter->mppriv.MptCtx);
52         pMptCtx->bMPh2c_timeout = _FALSE;
53
54         if (pAdapter->registrypriv.mp_mode == 0) {
55                 RTW_INFO("[MPT], Error!! WaitC2Hevent mp_mode == 0!!\n");
56                 return _FALSE;
57         }
58
59         _set_timer(&pMptCtx->MPh2c_timeout_timer, delay_time);
60
61         _rtw_down_sema(&pMptCtx->MPh2c_Sema);
62
63         if (pMptCtx->bMPh2c_timeout == _TRUE) {
64                 *C2H_event = _FALSE;
65
66                 return _FALSE;
67         }
68
69         /* for safty, cancel timer here again */
70         _cancel_timer_ex(&pMptCtx->MPh2c_timeout_timer);
71
72         return _TRUE;
73 }
74
75 BT_CTRL_STATUS
76 mptbt_CheckC2hFrame(
77         PADAPTER                Adapter,
78         PBT_H2C                 pH2c,
79         PBT_EXT_C2H             pExtC2h
80 )
81 {
82         BT_CTRL_STATUS  c2hStatus = BT_STATUS_C2H_SUCCESS;
83
84         /* RTW_INFO("[MPT], MPT rsp C2H hex: %x %x %x  %x %x %x\n"), pExtC2h , pExtC2h+1 ,pExtC2h+2 ,pExtC2h+3 ,pExtC2h+4 ,pExtC2h+5); */
85
86         RTW_INFO("[MPT], statusCode = 0x%x\n", pExtC2h->statusCode);
87         RTW_INFO("[MPT], retLen = %d\n", pExtC2h->retLen);
88         RTW_INFO("[MPT], opCodeVer : req/rsp=%d/%d\n", pH2c->opCodeVer, pExtC2h->opCodeVer);
89         RTW_INFO("[MPT], reqNum : req/rsp=%d/%d\n", pH2c->reqNum, pExtC2h->reqNum);
90         if (pExtC2h->reqNum != pH2c->reqNum) {
91                 c2hStatus = BT_STATUS_C2H_REQNUM_MISMATCH;
92                 RTW_INFO("[MPT], Error!! C2H reqNum Mismatch!!\n");
93         } else if (pExtC2h->opCodeVer != pH2c->opCodeVer) {
94                 c2hStatus = BT_STATUS_OPCODE_L_VERSION_MISMATCH;
95                 RTW_INFO("[MPT], Error!! OPCode version L mismatch!!\n");
96         }
97
98         return c2hStatus;
99 }
100
101 BT_CTRL_STATUS
102 mptbt_SendH2c(
103         PADAPTER        Adapter,
104         PBT_H2C pH2c,
105         u2Byte          h2cCmdLen
106 )
107 {
108         /* KIRQL                                OldIrql = KeGetCurrentIrql(); */
109         BT_CTRL_STATUS  h2cStatus = BT_STATUS_H2C_SUCCESS;
110         PMPT_CONTEXT            pMptCtx = &(Adapter->mppriv.MptCtx);
111         u1Byte                          i;
112
113         RTW_INFO("[MPT], mptbt_SendH2c()=========>\n");
114
115         /* PlatformResetEvent(&pMptCtx->MptH2cRspEvent); */
116         /* PlatformResetEvent(&pMptCtx->MptBtC2hEvent); */
117
118         /*      if(OldIrql == PASSIVE_LEVEL)
119          *      { */
120         /* RTPRINT_DATA(FMPBT, FMPBT_H2C_CONTENT, ("[MPT], MPT H2C hex:\n"), pH2c, h2cCmdLen); */
121
122         for (i = 0; i < BT_H2C_MAX_RETRY; i++) {
123                 RTW_INFO("[MPT], Send H2C command to wifi!!!\n");
124
125                 pMptCtx->MptH2cRspEvent = _FALSE;
126                 pMptCtx->MptBtC2hEvent = _FALSE;
127
128 #if defined(CONFIG_RTL8723B)
129                 rtl8723b_set_FwBtMpOper_cmd(Adapter, pH2c->opCode, pH2c->opCodeVer, pH2c->reqNum, pH2c->buf);
130 #endif
131                 pMptCtx->h2cReqNum++;
132                 pMptCtx->h2cReqNum %= 16;
133
134                 if (WaitC2Hevent(Adapter, &pMptCtx->MptH2cRspEvent, 100)) {
135                         RTW_INFO("[MPT], Received WiFi MptH2cRspEvent!!!\n");
136                         if (WaitC2Hevent(Adapter, &pMptCtx->MptBtC2hEvent, 400)) {
137                                 RTW_INFO("[MPT], Received MptBtC2hEvent!!!\n");
138                                 break;
139                         } else {
140                                 RTW_INFO("[MPT], Error!!BT MptBtC2hEvent timeout!!\n");
141                                 h2cStatus = BT_STATUS_H2C_BT_NO_RSP;
142                         }
143                 } else {
144                         RTW_INFO("[MPT], Error!!WiFi  MptH2cRspEvent timeout!!\n");
145                         h2cStatus = BT_STATUS_H2C_TIMTOUT;
146                 }
147         }
148         /*      }
149          *      else
150          *      {
151          *              RT_ASSERT(FALSE, ("[MPT],  mptbt_SendH2c() can only run under PASSIVE_LEVEL!!\n"));
152          *              h2cStatus = BT_STATUS_WRONG_LEVEL;
153          *      } */
154
155         RTW_INFO("[MPT], mptbt_SendH2c()<=========\n");
156         return h2cStatus;
157 }
158
159
160
161 BT_CTRL_STATUS
162 mptbt_CheckBtRspStatus(
163         PADAPTER                        Adapter,
164         PBT_EXT_C2H                     pExtC2h
165 )
166 {
167         BT_CTRL_STATUS  retStatus = BT_OP_STATUS_SUCCESS;
168
169         switch (pExtC2h->statusCode) {
170         case BT_OP_STATUS_SUCCESS:
171                 retStatus = BT_STATUS_BT_OP_SUCCESS;
172                 RTW_INFO("[MPT], BT status : BT_STATUS_SUCCESS\n");
173                 break;
174         case BT_OP_STATUS_VERSION_MISMATCH:
175                 retStatus = BT_STATUS_OPCODE_L_VERSION_MISMATCH;
176                 RTW_INFO("[MPT], BT status : BT_STATUS_OPCODE_L_VERSION_MISMATCH\n");
177                 break;
178         case BT_OP_STATUS_UNKNOWN_OPCODE:
179                 retStatus = BT_STATUS_UNKNOWN_OPCODE_L;
180                 RTW_INFO("[MPT], BT status : BT_STATUS_UNKNOWN_OPCODE_L\n");
181                 break;
182         case BT_OP_STATUS_ERROR_PARAMETER:
183                 retStatus = BT_STATUS_PARAMETER_FORMAT_ERROR_L;
184                 RTW_INFO("[MPT], BT status : BT_STATUS_PARAMETER_FORMAT_ERROR_L\n");
185                 break;
186         default:
187                 retStatus = BT_STATUS_UNKNOWN_STATUS_L;
188                 RTW_INFO("[MPT], BT status : BT_STATUS_UNKNOWN_STATUS_L\n");
189                 break;
190         }
191
192         return retStatus;
193 }
194
195
196
197 BT_CTRL_STATUS
198 mptbt_BtFwOpCodeProcess(
199         PADAPTER                Adapter,
200         u1Byte                  btFwOpCode,
201         u1Byte                  opCodeVer,
202         pu1Byte                 pH2cPar,
203         u1Byte                  h2cParaLen
204 )
205 {
206         u1Byte                          H2C_Parameter[6] = {0};
207         PBT_H2C                         pH2c = (PBT_H2C)&H2C_Parameter[0];
208         PMPT_CONTEXT            pMptCtx = &(Adapter->mppriv.MptCtx);
209         PBT_EXT_C2H                     pExtC2h = (PBT_EXT_C2H)&pMptCtx->c2hBuf[0];
210         u2Byte                          paraLen = 0, i;
211         BT_CTRL_STATUS  h2cStatus = BT_STATUS_H2C_SUCCESS, c2hStatus = BT_STATUS_C2H_SUCCESS;
212         BT_CTRL_STATUS  retStatus = BT_STATUS_H2C_BT_NO_RSP;
213
214         if (Adapter->registrypriv.mp_mode == 0) {
215                 RTW_INFO("[MPT], Error!! mptbt_BtFwOpCodeProces mp_mode == 0!!\n");
216                 return _FALSE;
217         }
218
219         pH2c->opCode = btFwOpCode;
220         pH2c->opCodeVer = opCodeVer;
221         pH2c->reqNum = pMptCtx->h2cReqNum;
222         /* PlatformMoveMemory(&pH2c->buf[0], pH2cPar, h2cParaLen); */
223         /* _rtw_memcpy(&pH2c->buf[0], pH2cPar, h2cParaLen); */
224         _rtw_memcpy(pH2c->buf, pH2cPar, h2cParaLen);
225
226         RTW_INFO("[MPT], pH2c->opCode=%d\n", pH2c->opCode);
227         RTW_INFO("[MPT], pH2c->opCodeVer=%d\n", pH2c->opCodeVer);
228         RTW_INFO("[MPT], pH2c->reqNum=%d\n", pH2c->reqNum);
229         RTW_INFO("[MPT], h2c parameter length=%d\n", h2cParaLen);
230         for (i = 0; i < h2cParaLen; i++)
231                 RTW_INFO("[MPT], parameter[%d]=0x%02x\n", i, pH2c->buf[i]);
232
233         h2cStatus = mptbt_SendH2c(Adapter, pH2c, h2cParaLen + 2);
234         if (BT_STATUS_H2C_SUCCESS == h2cStatus) {
235                 /* if reach here, it means H2C get the correct c2h response, */
236                 c2hStatus = mptbt_CheckC2hFrame(Adapter, pH2c, pExtC2h);
237                 if (BT_STATUS_C2H_SUCCESS == c2hStatus)
238                         retStatus = mptbt_CheckBtRspStatus(Adapter, pExtC2h);
239                 else {
240                         RTW_INFO("[MPT], Error!! C2H failed for pH2c->opCode=%d\n", pH2c->opCode);
241                         /* check c2h status error, return error status code to upper layer. */
242                         retStatus = c2hStatus;
243                 }
244         } else {
245                 RTW_INFO("[MPT], Error!! H2C failed for pH2c->opCode=%d\n", pH2c->opCode);
246                 /* check h2c status error, return error status code to upper layer. */
247                 retStatus = h2cStatus;
248         }
249
250         return retStatus;
251 }
252
253
254
255
256 u2Byte
257 mptbt_BtReady(
258         PADAPTER                Adapter,
259         PBT_REQ_CMD     pBtReq,
260         PBT_RSP_CMD     pBtRsp
261 )
262 {
263         u1Byte                          h2cParaBuf[6] = {0};
264         u1Byte                          h2cParaLen = 0;
265         u2Byte                          paraLen = 0;
266         u1Byte                          retStatus = BT_STATUS_BT_OP_SUCCESS;
267         u1Byte                          btOpcode;
268         u1Byte                          btOpcodeVer = 0;
269         PMPT_CONTEXT            pMptCtx = &(Adapter->mppriv.MptCtx);
270         PBT_EXT_C2H                     pExtC2h = (PBT_EXT_C2H)&pMptCtx->c2hBuf[0];
271         u1Byte                          i;
272         u1Byte                          btFwVer = 0, bdAddr[6] = {0};
273         u2Byte                          btRealFwVer = 0;
274         pu2Byte                 pu2Tmp = NULL;
275
276         /*  */
277         /* check upper layer parameters */
278         /*  */
279
280         /* 1. check upper layer opcode version */
281         if (pBtReq->opCodeVer != 1) {
282                 RTW_INFO("[MPT], Error!! Upper OP code version not match!!!\n");
283                 pBtRsp->status = BT_STATUS_OPCODE_U_VERSION_MISMATCH;
284                 return paraLen;
285         }
286
287         pBtRsp->pParamStart[0] = MP_BT_NOT_READY;
288         paraLen = 10;
289         /*  */
290         /* execute lower layer opcodes */
291         /*  */
292
293         /* Get BT FW version */
294         /* fill h2c parameters */
295         btOpcode = BT_LO_OP_GET_BT_VERSION;
296         /* execute h2c and check respond c2h from bt fw is correct or not */
297         retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
298         /* ckeck bt return status. */
299         if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
300                 pBtRsp->status = ((btOpcode << 8) | retStatus);
301                 RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
302                 return paraLen;
303         } else {
304                 pu2Tmp = (pu2Byte)&pExtC2h->buf[0];
305                 btRealFwVer = *pu2Tmp;
306                 btFwVer = pExtC2h->buf[1];
307                 RTW_INFO("[MPT], btRealFwVer=0x%x, btFwVer=0x%x\n", btRealFwVer, btFwVer);
308         }
309
310         /* Get BD Address */
311         /* fill h2c parameters */
312         btOpcode = BT_LO_OP_GET_BD_ADDR_L;
313         /* execute h2c and check respond c2h from bt fw is correct or not */
314         retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
315         /* ckeck bt return status. */
316         if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
317                 pBtRsp->status = ((btOpcode << 8) | retStatus);
318                 RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
319                 return paraLen;
320         } else {
321                 bdAddr[5] = pExtC2h->buf[0];
322                 bdAddr[4] = pExtC2h->buf[1];
323                 bdAddr[3] = pExtC2h->buf[2];
324         }
325
326         /* fill h2c parameters */
327         btOpcode = BT_LO_OP_GET_BD_ADDR_H;
328         /* execute h2c and check respond c2h from bt fw is correct or not */
329         retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
330         /* ckeck bt return status. */
331         if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
332                 pBtRsp->status = ((btOpcode << 8) | retStatus);
333                 RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
334                 return paraLen;
335         } else {
336                 bdAddr[2] = pExtC2h->buf[0];
337                 bdAddr[1] = pExtC2h->buf[1];
338                 bdAddr[0] = pExtC2h->buf[2];
339         }
340         RTW_INFO("[MPT], Local BDAddr:");
341         for (i = 0; i < 6; i++)
342                 RTW_INFO(" 0x%x ", bdAddr[i]);
343         pBtRsp->status = BT_STATUS_SUCCESS;
344         pBtRsp->pParamStart[0] = MP_BT_READY;
345         pu2Tmp = (pu2Byte)&pBtRsp->pParamStart[1];
346         *pu2Tmp = btRealFwVer;
347         pBtRsp->pParamStart[3] = btFwVer;
348         for (i = 0; i < 6; i++)
349                 pBtRsp->pParamStart[4 + i] = bdAddr[5 - i];
350
351         return paraLen;
352 }
353
354 void mptbt_close_WiFiRF(PADAPTER Adapter)
355 {
356         PHY_SetBBReg(Adapter, 0x824, 0xF, 0x0);
357         PHY_SetBBReg(Adapter, 0x824, 0x700000, 0x0);
358         PHY_SetRFReg(Adapter, RF_PATH_A, 0x0, 0xF0000, 0x0);
359 }
360
361 void mptbt_open_WiFiRF(PADAPTER Adapter)
362 {
363         PHY_SetBBReg(Adapter, 0x824, 0x700000, 0x3);
364         PHY_SetBBReg(Adapter, 0x824, 0xF, 0x2);
365         PHY_SetRFReg(Adapter, RF_PATH_A, 0x0, 0xF0000, 0x3);
366 }
367
368 u4Byte mptbt_switch_RF(PADAPTER Adapter, u1Byte Enter)
369 {
370         u2Byte  tmp_2byte = 0;
371
372         /* Enter test mode */
373         if (Enter) {
374                 /* 1>. close WiFi RF */
375                 mptbt_close_WiFiRF(Adapter);
376
377                 /* 2>. change ant switch to BT */
378                 tmp_2byte = rtw_read16(Adapter, 0x860);
379                 tmp_2byte = tmp_2byte | BIT(9);
380                 tmp_2byte = tmp_2byte & (~BIT(8));
381                 rtw_write16(Adapter, 0x860, tmp_2byte);
382                 rtw_write16(Adapter, 0x870, 0x300);
383         } else {
384                 /* 1>. Open WiFi RF */
385                 mptbt_open_WiFiRF(Adapter);
386
387                 /* 2>. change ant switch back */
388                 tmp_2byte = rtw_read16(Adapter, 0x860);
389                 tmp_2byte = tmp_2byte | BIT(8);
390                 tmp_2byte = tmp_2byte & (~BIT(9));
391                 rtw_write16(Adapter, 0x860, tmp_2byte);
392                 rtw_write16(Adapter, 0x870, 0x300);
393         }
394
395         return 0;
396 }
397
398 u2Byte
399 mptbt_BtSetMode(
400         PADAPTER                Adapter,
401         PBT_REQ_CMD     pBtReq,
402         PBT_RSP_CMD     pBtRsp
403 )
404 {
405         u1Byte                          h2cParaBuf[6] = {0};
406         u1Byte                          h2cParaLen = 0;
407         u2Byte                          paraLen = 0;
408         u1Byte                          retStatus = BT_STATUS_BT_OP_SUCCESS;
409         u1Byte                          btOpcode;
410         u1Byte                          btOpcodeVer = 0;
411         u1Byte                          btModeToSet = 0;
412
413         /*  */
414         /* check upper layer parameters */
415         /*  */
416         /* 1. check upper layer opcode version */
417         if (pBtReq->opCodeVer != 1) {
418                 RTW_INFO("[MPT], Error!! Upper OP code version not match!!!\n");
419                 pBtRsp->status = BT_STATUS_OPCODE_U_VERSION_MISMATCH;
420                 return paraLen;
421         }
422         /* 2. check upper layer parameter length */
423         if (1 == pBtReq->paraLength) {
424                 btModeToSet = pBtReq->pParamStart[0];
425                 RTW_INFO("[MPT], BtTestMode=%d\n", btModeToSet);
426         } else {
427                 RTW_INFO("[MPT], Error!! wrong parameter length=%d (should be 1)\n", pBtReq->paraLength);
428                 pBtRsp->status = BT_STATUS_PARAMETER_FORMAT_ERROR_U;
429                 return paraLen;
430         }
431
432         /*  */
433         /* execute lower layer opcodes */
434         /*  */
435
436         /* 1. fill h2c parameters        */
437         /* check bt mode */
438         btOpcode = BT_LO_OP_SET_BT_MODE;
439         if (btModeToSet >= MP_BT_MODE_MAX) {
440                 pBtRsp->status = BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
441                 return paraLen;
442         } else {
443                 mptbt_switch_RF(Adapter, 1);
444
445                 h2cParaBuf[0] = btModeToSet;
446                 h2cParaLen = 1;
447                 /* 2. execute h2c and check respond c2h from bt fw is correct or not */
448                 retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
449         }
450
451         /* 3. construct respond status code and data. */
452         if (BT_STATUS_BT_OP_SUCCESS == retStatus)
453                 pBtRsp->status = BT_STATUS_SUCCESS;
454         else {
455                 pBtRsp->status = ((btOpcode << 8) | retStatus);
456                 RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
457         }
458
459         return paraLen;
460 }
461
462
463 VOID
464 MPTBT_FwC2hBtMpCtrl(
465         PADAPTER        Adapter,
466         pu1Byte tmpBuf,
467         u1Byte          length
468 )
469 {
470         u32 i;
471         PMPT_CONTEXT    pMptCtx = &(Adapter->mppriv.MptCtx);
472         PBT_EXT_C2H pExtC2h = (PBT_EXT_C2H)tmpBuf;
473
474         if (Adapter->bBTFWReady == _FALSE || Adapter->registrypriv.mp_mode == 0) {
475                 /* RTW_INFO("Ignore C2H BT MP Info since not in MP mode\n"); */
476                 return;
477         }
478         if (length > 32 || length < 3) {
479                 RTW_INFO("\n [MPT], pExtC2h->buf hex: length=%d > 32 || < 3\n", length);
480                 return;
481         }
482
483         /* cancel_timeout for h2c handle */
484         _cancel_timer_ex(&pMptCtx->MPh2c_timeout_timer);
485
486         for (i = 0; i < length; i++)
487                 RTW_INFO("[MPT], %s, buf[%d]=0x%02x ", __FUNCTION__, i, tmpBuf[i]);
488         RTW_INFO("[MPT], pExtC2h->extendId=0x%x\n", pExtC2h->extendId);
489
490         switch (pExtC2h->extendId) {
491         case EXT_C2H_WIFI_FW_ACTIVE_RSP:
492                 RTW_INFO("[MPT], EXT_C2H_WIFI_FW_ACTIVE_RSP\n");
493 #if 0
494                 RTW_INFO("[MPT], pExtC2h->buf hex:\n");
495                 for (i = 0; i < (length - 3); i++)
496                         RTW_INFO(" 0x%x ", pExtC2h->buf[i]);
497 #endif
498                 if ((_FALSE == pMptCtx->bMPh2c_timeout)
499                     && (_FALSE == pMptCtx->MptH2cRspEvent)) {
500                         pMptCtx->MptH2cRspEvent = _TRUE;
501                         _rtw_up_sema(&pMptCtx->MPh2c_Sema);
502                 }
503                 break;
504
505         case EXT_C2H_TRIG_BY_BT_FW:
506                 RTW_INFO("[MPT], EXT_C2H_TRIG_BY_BT_FW\n");
507                 _rtw_memcpy(&pMptCtx->c2hBuf[0], tmpBuf, length);
508                 RTW_INFO("[MPT], pExtC2h->statusCode=0x%x\n", pExtC2h->statusCode);
509                 RTW_INFO("[MPT], pExtC2h->retLen=0x%x\n", pExtC2h->retLen);
510                 RTW_INFO("[MPT], pExtC2h->opCodeVer=0x%x\n", pExtC2h->opCodeVer);
511                 RTW_INFO("[MPT], pExtC2h->reqNum=0x%x\n", pExtC2h->reqNum);
512                 for (i = 0; i < (length - 3); i++)
513                         RTW_INFO("[MPT], pExtC2h->buf[%d]=0x%02x\n", i, pExtC2h->buf[i]);
514
515                 if ((_FALSE == pMptCtx->bMPh2c_timeout)
516                     && (_TRUE == pMptCtx->MptH2cRspEvent)
517                     && (_FALSE == pMptCtx->MptBtC2hEvent)) {
518                         pMptCtx->MptBtC2hEvent = _TRUE;
519                         _rtw_up_sema(&pMptCtx->MPh2c_Sema);
520                 }
521                 break;
522
523         default:
524                 RTW_INFO("[MPT], EXT_C2H Target not found,pExtC2h->extendId =%d ,pExtC2h->reqNum=%d\n", pExtC2h->extendId, pExtC2h->reqNum);
525                 break;
526         }
527
528
529
530 }
531
532
533 u2Byte
534 mptbt_BtGetGeneral(
535         IN      PADAPTER                Adapter,
536         IN      PBT_REQ_CMD     pBtReq,
537         IN      PBT_RSP_CMD     pBtRsp
538 )
539 {
540         PMPT_CONTEXT            pMptCtx = &(Adapter->mppriv.MptCtx);
541         PBT_EXT_C2H             pExtC2h = (PBT_EXT_C2H)&pMptCtx->c2hBuf[0];
542         u1Byte                          h2cParaBuf[6] = {0};
543         u1Byte                          h2cParaLen = 0;
544         u2Byte                          paraLen = 0;
545         u1Byte                          retStatus = BT_STATUS_BT_OP_SUCCESS;
546         u1Byte                          btOpcode, bdAddr[6] = {0};
547         u1Byte                          btOpcodeVer = 0;
548         u1Byte                          getType = 0, i;
549         u2Byte                          getParaLen = 0, validParaLen = 0;
550         u1Byte                          regType = 0, reportType = 0;
551         u4Byte                          regAddr = 0, regValue = 0;
552         pu4Byte                 pu4Tmp;
553         pu2Byte                 pu2Tmp;
554         pu1Byte                 pu1Tmp;
555
556         /*  */
557         /* check upper layer parameters */
558         /*  */
559
560         /* check upper layer opcode version */
561         if (pBtReq->opCodeVer != 1) {
562                 RTW_INFO("[MPT], Error!! Upper OP code version not match!!!\n");
563                 pBtRsp->status = BT_STATUS_OPCODE_U_VERSION_MISMATCH;
564                 return paraLen;
565         }
566         /* check upper layer parameter length */
567         if (pBtReq->paraLength < 1) {
568                 RTW_INFO("[MPT], Error!! wrong parameter length=%d (should larger than 1)\n", pBtReq->paraLength);
569                 pBtRsp->status = BT_STATUS_PARAMETER_FORMAT_ERROR_U;
570                 return paraLen;
571         }
572         getParaLen = pBtReq->paraLength - 1;
573         getType = pBtReq->pParamStart[0];
574
575         RTW_INFO("[MPT], getType=%d, getParaLen=%d\n", getType, getParaLen);
576
577         /* check parameter first */
578         switch (getType) {
579         case BT_GGET_REG:
580                 RTW_INFO("[MPT], [BT_GGET_REG]\n");
581                 validParaLen = 5;
582                 if (getParaLen == validParaLen) {
583                         btOpcode = BT_LO_OP_READ_REG;
584                         regType = pBtReq->pParamStart[1];
585                         pu4Tmp = (pu4Byte)&pBtReq->pParamStart[2];
586                         regAddr = *pu4Tmp;
587                         RTW_INFO("[MPT], BT_GGET_REG regType=0x%02x, regAddr=0x%08x!!\n",
588                                  regType, regAddr);
589                         if (regType >= BT_REG_MAX) {
590                                 pBtRsp->status = (btOpcode << 8) | BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
591                                 return paraLen;
592                         } else {
593                                 if (((BT_REG_RF == regType) && (regAddr > 0x7f)) ||
594                                     ((BT_REG_MODEM == regType) && (regAddr > 0x1ff)) ||
595                                     ((BT_REG_BLUEWIZE == regType) && (regAddr > 0xfff)) ||
596                                     ((BT_REG_VENDOR == regType) && (regAddr > 0xfff)) ||
597                                     ((BT_REG_LE == regType) && (regAddr > 0xfff))) {
598                                         pBtRsp->status = (btOpcode << 8) | BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
599                                         return paraLen;
600                                 }
601                         }
602                 }
603                 break;
604         case BT_GGET_STATUS:
605                 RTW_INFO("[MPT], [BT_GGET_STATUS]\n");
606                 validParaLen = 0;
607                 break;
608         case BT_GGET_REPORT:
609                 RTW_INFO("[MPT], [BT_GGET_REPORT]\n");
610                 validParaLen = 1;
611                 if (getParaLen == validParaLen) {
612                         reportType = pBtReq->pParamStart[1];
613                         RTW_INFO("[MPT], BT_GGET_REPORT reportType=0x%x!!\n", reportType);
614                         if (reportType >= BT_REPORT_MAX) {
615                                 pBtRsp->status = BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
616                                 return paraLen;
617                         }
618                 }
619                 break;
620         default: {
621                 RTW_INFO("[MPT], Error!! getType=%d, out of range\n", getType);
622                 pBtRsp->status = BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
623                 return paraLen;
624         }
625         break;
626         }
627         if (getParaLen != validParaLen) {
628                 RTW_INFO("[MPT], Error!! wrong parameter length=%d for BT_GET_GEN_CMD cmd id=0x%x, paraLen should=0x%x\n",
629                          getParaLen, getType, validParaLen);
630                 pBtRsp->status = BT_STATUS_PARAMETER_FORMAT_ERROR_U;
631                 return paraLen;
632         }
633
634         /*  */
635         /* execute lower layer opcodes */
636         /*  */
637         if (BT_GGET_REG == getType) {
638                 /* fill h2c parameters */
639                 /* here we should write reg value first then write the address, adviced by Austin */
640                 btOpcode = BT_LO_OP_READ_REG;
641                 h2cParaBuf[0] = regType;
642                 h2cParaBuf[1] = pBtReq->pParamStart[2];
643                 h2cParaBuf[2] = pBtReq->pParamStart[3];
644                 h2cParaLen = 3;
645                 /* execute h2c and check respond c2h from bt fw is correct or not */
646                 retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
647                 /* construct respond status code and data. */
648                 if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
649                         pBtRsp->status = ((btOpcode << 8) | retStatus);
650                         RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
651                         return paraLen;
652                 }
653
654                 pu2Tmp = (pu2Byte)&pExtC2h->buf[0];
655                 regValue = *pu2Tmp;
656                 RTW_INFO("[MPT], read reg regType=0x%02x, regAddr=0x%08x, regValue=0x%04x\n",
657                          regType, regAddr, regValue);
658
659                 pu4Tmp = (pu4Byte)&pBtRsp->pParamStart[0];
660                 *pu4Tmp = regValue;
661                 paraLen = 4;
662         } else if (BT_GGET_STATUS == getType) {
663                 btOpcode = BT_LO_OP_GET_BT_STATUS;
664                 h2cParaLen = 0;
665                 /* execute h2c and check respond c2h from bt fw is correct or not */
666                 retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
667                 /* construct respond status code and data. */
668                 if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
669                         pBtRsp->status = ((btOpcode << 8) | retStatus);
670                         RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
671                         return paraLen;
672                 }
673
674                 pBtRsp->pParamStart[0] = pExtC2h->buf[0];
675                 pBtRsp->pParamStart[1] = pExtC2h->buf[1];
676                 RTW_INFO("[MPT], read bt status, testMode=0x%x, testStatus=0x%x\n",
677                          pBtRsp->pParamStart[0], pBtRsp->pParamStart[1]);
678                 paraLen = 2;
679         } else if (BT_GGET_REPORT == getType) {
680                 switch (reportType) {
681                 case BT_REPORT_RX_PACKET_CNT: {
682                         RTW_INFO("[MPT], [Rx Packet Counts]\n");
683                         btOpcode = BT_LO_OP_GET_RX_PKT_CNT_L;
684                         h2cParaLen = 0;
685                         /* execute h2c and check respond c2h from bt fw is correct or not */
686                         retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
687                         /* construct respond status code and data. */
688                         if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
689                                 pBtRsp->status = ((btOpcode << 8) | retStatus);
690                                 RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
691                                 return paraLen;
692                         }
693                         pBtRsp->pParamStart[0] = pExtC2h->buf[0];
694                         pBtRsp->pParamStart[1] = pExtC2h->buf[1];
695
696                         btOpcode = BT_LO_OP_GET_RX_PKT_CNT_H;
697                         h2cParaLen = 0;
698                         /* execute h2c and check respond c2h from bt fw is correct or not */
699                         retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
700                         /* construct respond status code and data. */
701                         if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
702                                 pBtRsp->status = ((btOpcode << 8) | retStatus);
703                                 RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
704                                 return paraLen;
705                         }
706                         pBtRsp->pParamStart[2] = pExtC2h->buf[0];
707                         pBtRsp->pParamStart[3] = pExtC2h->buf[1];
708                         paraLen = 4;
709                 }
710                 break;
711                 case BT_REPORT_RX_ERROR_BITS: {
712                         RTW_INFO("[MPT], [Rx Error Bits]\n");
713                         btOpcode = BT_LO_OP_GET_RX_ERROR_BITS_L;
714                         h2cParaLen = 0;
715                         /* execute h2c and check respond c2h from bt fw is correct or not */
716                         retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
717                         /* construct respond status code and data. */
718                         if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
719                                 pBtRsp->status = ((btOpcode << 8) | retStatus);
720                                 RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
721                                 return paraLen;
722                         }
723                         pBtRsp->pParamStart[0] = pExtC2h->buf[0];
724                         pBtRsp->pParamStart[1] = pExtC2h->buf[1];
725
726                         btOpcode = BT_LO_OP_GET_RX_ERROR_BITS_H;
727                         h2cParaLen = 0;
728                         /* execute h2c and check respond c2h from bt fw is correct or not */
729                         retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
730                         /* construct respond status code and data. */
731                         if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
732                                 pBtRsp->status = ((btOpcode << 8) | retStatus);
733                                 RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
734                                 return paraLen;
735                         }
736                         pBtRsp->pParamStart[2] = pExtC2h->buf[0];
737                         pBtRsp->pParamStart[3] = pExtC2h->buf[1];
738                         paraLen = 4;
739                 }
740                 break;
741                 case BT_REPORT_RSSI: {
742                         RTW_INFO("[MPT], [RSSI]\n");
743                         btOpcode = BT_LO_OP_GET_RSSI;
744                         h2cParaLen = 0;
745                         /* execute h2c and check respond c2h from bt fw is correct or not */
746                         retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
747                         /* construct respond status code and data. */
748                         if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
749                                 pBtRsp->status = ((btOpcode << 8) | retStatus);
750                                 RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
751                                 return paraLen;
752                         }
753                         pBtRsp->pParamStart[0] = pExtC2h->buf[0];
754                         pBtRsp->pParamStart[1] = pExtC2h->buf[1];
755                         paraLen = 2;
756                 }
757                 break;
758                 case BT_REPORT_CFO_HDR_QUALITY: {
759                         RTW_INFO("[MPT], [CFO & Header Quality]\n");
760                         btOpcode = BT_LO_OP_GET_CFO_HDR_QUALITY_L;
761                         h2cParaLen = 0;
762                         /* execute h2c and check respond c2h from bt fw is correct or not */
763                         retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
764                         /* construct respond status code and data. */
765                         if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
766                                 pBtRsp->status = ((btOpcode << 8) | retStatus);
767                                 RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
768                                 return paraLen;
769                         }
770                         pBtRsp->pParamStart[0] = pExtC2h->buf[0];
771                         pBtRsp->pParamStart[1] = pExtC2h->buf[1];
772
773                         btOpcode = BT_LO_OP_GET_CFO_HDR_QUALITY_H;
774                         h2cParaLen = 0;
775                         /* execute h2c and check respond c2h from bt fw is correct or not */
776                         retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
777                         /* construct respond status code and data. */
778                         if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
779                                 pBtRsp->status = ((btOpcode << 8) | retStatus);
780                                 RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
781                                 return paraLen;
782                         }
783                         pBtRsp->pParamStart[2] = pExtC2h->buf[0];
784                         pBtRsp->pParamStart[3] = pExtC2h->buf[1];
785                         paraLen = 4;
786                 }
787                 break;
788                 case BT_REPORT_CONNECT_TARGET_BD_ADDR: {
789                         RTW_INFO("[MPT], [Connected Target BD ADDR]\n");
790                         btOpcode = BT_LO_OP_GET_TARGET_BD_ADDR_L;
791                         h2cParaLen = 0;
792                         /* execute h2c and check respond c2h from bt fw is correct or not */
793                         retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
794                         /* construct respond status code and data. */
795                         if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
796                                 pBtRsp->status = ((btOpcode << 8) | retStatus);
797                                 RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
798                                 return paraLen;
799                         }
800                         bdAddr[5] = pExtC2h->buf[0];
801                         bdAddr[4] = pExtC2h->buf[1];
802                         bdAddr[3] = pExtC2h->buf[2];
803
804                         btOpcode = BT_LO_OP_GET_TARGET_BD_ADDR_H;
805                         h2cParaLen = 0;
806                         /* execute h2c and check respond c2h from bt fw is correct or not */
807                         retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
808                         /* construct respond status code and data. */
809                         if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
810                                 pBtRsp->status = ((btOpcode << 8) | retStatus);
811                                 RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
812                                 return paraLen;
813                         }
814                         bdAddr[2] = pExtC2h->buf[0];
815                         bdAddr[1] = pExtC2h->buf[1];
816                         bdAddr[0] = pExtC2h->buf[2];
817
818                         RTW_INFO("[MPT], Connected Target BDAddr:%s", bdAddr);
819                         for (i = 0; i < 6; i++)
820                                 pBtRsp->pParamStart[i] = bdAddr[5 - i];
821                         paraLen = 6;
822                 }
823                 break;
824                 default:
825                         pBtRsp->status = BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
826                         return paraLen;
827                         break;
828                 }
829         }
830
831         pBtRsp->status = BT_STATUS_SUCCESS;
832         return paraLen;
833 }
834
835
836
837 u2Byte
838 mptbt_BtSetGeneral(
839         IN      PADAPTER                Adapter,
840         IN      PBT_REQ_CMD     pBtReq,
841         IN      PBT_RSP_CMD     pBtRsp
842 )
843 {
844         u1Byte                          h2cParaBuf[6] = {0};
845         u1Byte                          h2cParaLen = 0;
846         u2Byte                          paraLen = 0;
847         u1Byte                          retStatus = BT_STATUS_BT_OP_SUCCESS;
848         u1Byte                          btOpcode;
849         u1Byte                          btOpcodeVer = 0;
850         u1Byte                          setType = 0;
851         u2Byte                          setParaLen = 0, validParaLen = 0;
852         u1Byte                          regType = 0, bdAddr[6] = {0}, calVal = 0;
853         u4Byte                          regAddr = 0, regValue = 0;
854         pu4Byte                 pu4Tmp;
855         pu2Byte                 pu2Tmp;
856         pu1Byte                 pu1Tmp;
857
858         /*  */
859         /* check upper layer parameters */
860         /*  */
861
862         /* check upper layer opcode version */
863         if (pBtReq->opCodeVer != 1) {
864                 RTW_INFO("[MPT], Error!! Upper OP code version not match!!!\n");
865                 pBtRsp->status = BT_STATUS_OPCODE_U_VERSION_MISMATCH;
866                 return paraLen;
867         }
868         /* check upper layer parameter length */
869         if (pBtReq->paraLength < 1) {
870                 RTW_INFO("[MPT], Error!! wrong parameter length=%d (should larger than 1)\n", pBtReq->paraLength);
871                 pBtRsp->status = BT_STATUS_PARAMETER_FORMAT_ERROR_U;
872                 return paraLen;
873         }
874         setParaLen = pBtReq->paraLength - 1;
875         setType = pBtReq->pParamStart[0];
876
877         RTW_INFO("[MPT], setType=%d, setParaLen=%d\n", setType, setParaLen);
878
879         /* check parameter first */
880         switch (setType) {
881         case BT_GSET_REG:
882                 RTW_INFO("[MPT], [BT_GSET_REG]\n");
883                 validParaLen = 9;
884                 if (setParaLen == validParaLen) {
885                         btOpcode = BT_LO_OP_WRITE_REG_VALUE;
886                         regType = pBtReq->pParamStart[1];
887                         pu4Tmp = (pu4Byte)&pBtReq->pParamStart[2];
888                         regAddr = *pu4Tmp;
889                         pu4Tmp = (pu4Byte)&pBtReq->pParamStart[6];
890                         regValue = *pu4Tmp;
891                         RTW_INFO("[MPT], BT_GSET_REG regType=0x%x, regAddr=0x%x, regValue=0x%x!!\n",
892                                  regType, regAddr, regValue);
893                         if (regType >= BT_REG_MAX) {
894                                 pBtRsp->status = (btOpcode << 8) | BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
895                                 return paraLen;
896                         } else {
897                                 if (((BT_REG_RF == regType) && (regAddr > 0x7f)) ||
898                                     ((BT_REG_MODEM == regType) && (regAddr > 0x1ff)) ||
899                                     ((BT_REG_BLUEWIZE == regType) && (regAddr > 0xfff)) ||
900                                     ((BT_REG_VENDOR == regType) && (regAddr > 0xfff)) ||
901                                     ((BT_REG_LE == regType) && (regAddr > 0xfff))) {
902                                         pBtRsp->status = (btOpcode << 8) | BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
903                                         return paraLen;
904                                 }
905                         }
906                 }
907                 break;
908         case BT_GSET_RESET:
909                 RTW_INFO("[MPT], [BT_GSET_RESET]\n");
910                 validParaLen = 0;
911                 break;
912         case BT_GSET_TARGET_BD_ADDR:
913                 RTW_INFO("[MPT], [BT_GSET_TARGET_BD_ADDR]\n");
914                 validParaLen = 6;
915                 if (setParaLen == validParaLen) {
916                         btOpcode = BT_LO_OP_SET_TARGET_BD_ADDR_H;
917                         if ((pBtReq->pParamStart[1] == 0) &&
918                             (pBtReq->pParamStart[2] == 0) &&
919                             (pBtReq->pParamStart[3] == 0) &&
920                             (pBtReq->pParamStart[4] == 0) &&
921                             (pBtReq->pParamStart[5] == 0) &&
922                             (pBtReq->pParamStart[6] == 0)) {
923                                 RTW_INFO("[MPT], Error!! targetBDAddr=all zero\n");
924                                 pBtRsp->status = (btOpcode << 8) | BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
925                                 return paraLen;
926                         }
927                         if ((pBtReq->pParamStart[1] == 0xff) &&
928                             (pBtReq->pParamStart[2] == 0xff) &&
929                             (pBtReq->pParamStart[3] == 0xff) &&
930                             (pBtReq->pParamStart[4] == 0xff) &&
931                             (pBtReq->pParamStart[5] == 0xff) &&
932                             (pBtReq->pParamStart[6] == 0xff)) {
933                                 RTW_INFO("[MPT], Error!! targetBDAddr=all 0xf\n");
934                                 pBtRsp->status = (btOpcode << 8) | BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
935                                 return paraLen;
936                         }
937                         bdAddr[0] = pBtReq->pParamStart[6];
938                         bdAddr[1] = pBtReq->pParamStart[5];
939                         bdAddr[2] = pBtReq->pParamStart[4];
940                         bdAddr[3] = pBtReq->pParamStart[3];
941                         bdAddr[4] = pBtReq->pParamStart[2];
942                         bdAddr[5] = pBtReq->pParamStart[1];
943                         RTW_INFO("[MPT], target BDAddr:%x,%x,%x,%x,%x,%x\n",
944                                 bdAddr[0], bdAddr[1], bdAddr[2], bdAddr[3], bdAddr[4], bdAddr[5]);
945                 }
946                 break;
947         case BT_GSET_TX_PWR_FINETUNE:
948                 RTW_INFO("[MPT], [BT_GSET_TX_PWR_FINETUNE]\n");
949                 validParaLen = 1;
950                 if (setParaLen == validParaLen) {
951                         btOpcode = BT_LO_OP_SET_TX_POWER_CALIBRATION;
952                         calVal = pBtReq->pParamStart[1];
953                         if ((calVal < 1) || (calVal > 9)) {
954                                 pBtRsp->status = (btOpcode << 8) | BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
955                                 return paraLen;
956                         }
957                         RTW_INFO("[MPT], calVal=%d\n", calVal);
958                 }
959                 break;
960         case BT_SET_TRACKING_INTERVAL:
961                 RTW_INFO("[MPT], [BT_SET_TRACKING_INTERVAL] setParaLen =%d\n", setParaLen);
962
963                 validParaLen = 1;
964                 if (setParaLen == validParaLen)
965                         calVal = pBtReq->pParamStart[1];
966                 break;
967         case BT_SET_THERMAL_METER:
968                 RTW_INFO("[MPT], [BT_SET_THERMAL_METER] setParaLen =%d\n", setParaLen);
969                 validParaLen = 1;
970                 if (setParaLen == validParaLen)
971                         calVal = pBtReq->pParamStart[1];
972                 break;
973         case BT_ENABLE_CFO_TRACKING:
974                 RTW_INFO("[MPT], [BT_ENABLE_CFO_TRACKING] setParaLen =%d\n", setParaLen);
975                 validParaLen = 1;
976                 if (setParaLen == validParaLen)
977                         calVal = pBtReq->pParamStart[1];
978                 break;
979         case BT_GSET_UPDATE_BT_PATCH:
980
981                 break;
982         default: {
983                 RTW_INFO("[MPT], Error!! setType=%d, out of range\n", setType);
984                 pBtRsp->status = BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
985                 return paraLen;
986         }
987         break;
988         }
989         if (setParaLen != validParaLen) {
990                 RTW_INFO("[MPT], Error!! wrong parameter length=%d for BT_SET_GEN_CMD cmd id=0x%x, paraLen should=0x%x\n",
991                          setParaLen, setType, validParaLen);
992                 pBtRsp->status = BT_STATUS_PARAMETER_FORMAT_ERROR_U;
993                 return paraLen;
994         }
995
996         /*  */
997         /* execute lower layer opcodes */
998         /*  */
999         if (BT_GSET_REG == setType) {
1000                 /* fill h2c parameters */
1001                 /* here we should write reg value first then write the address, adviced by Austin */
1002                 btOpcode = BT_LO_OP_WRITE_REG_VALUE;
1003                 h2cParaBuf[0] = pBtReq->pParamStart[6];
1004                 h2cParaBuf[1] = pBtReq->pParamStart[7];
1005                 h2cParaBuf[2] = pBtReq->pParamStart[8];
1006                 h2cParaLen = 3;
1007                 /* execute h2c and check respond c2h from bt fw is correct or not */
1008                 retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
1009                 /* construct respond status code and data. */
1010                 if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
1011                         pBtRsp->status = ((btOpcode << 8) | retStatus);
1012                         RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
1013                         return paraLen;
1014                 }
1015
1016                 /* write reg address */
1017                 btOpcode = BT_LO_OP_WRITE_REG_ADDR;
1018                 h2cParaBuf[0] = regType;
1019                 h2cParaBuf[1] = pBtReq->pParamStart[2];
1020                 h2cParaBuf[2] = pBtReq->pParamStart[3];
1021                 h2cParaLen = 3;
1022                 /* execute h2c and check respond c2h from bt fw is correct or not */
1023                 retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
1024                 /* construct respond status code and data. */
1025                 if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
1026                         pBtRsp->status = ((btOpcode << 8) | retStatus);
1027                         RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
1028                         return paraLen;
1029                 }
1030         } else if (BT_GSET_RESET == setType) {
1031                 btOpcode = BT_LO_OP_RESET;
1032                 h2cParaLen = 0;
1033                 /* execute h2c and check respond c2h from bt fw is correct or not */
1034                 retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
1035                 /* construct respond status code and data. */
1036                 if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
1037                         pBtRsp->status = ((btOpcode << 8) | retStatus);
1038                         RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
1039                         return paraLen;
1040                 }
1041         } else if (BT_GSET_TARGET_BD_ADDR == setType) {
1042                 /* fill h2c parameters */
1043                 btOpcode = BT_LO_OP_SET_TARGET_BD_ADDR_L;
1044                 h2cParaBuf[0] = pBtReq->pParamStart[1];
1045                 h2cParaBuf[1] = pBtReq->pParamStart[2];
1046                 h2cParaBuf[2] = pBtReq->pParamStart[3];
1047                 h2cParaLen = 3;
1048                 retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
1049                 /* ckeck bt return status. */
1050                 if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
1051                         pBtRsp->status = ((btOpcode << 8) | retStatus);
1052                         RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
1053                         return paraLen;
1054                 }
1055
1056                 btOpcode = BT_LO_OP_SET_TARGET_BD_ADDR_H;
1057                 h2cParaBuf[0] = pBtReq->pParamStart[4];
1058                 h2cParaBuf[1] = pBtReq->pParamStart[5];
1059                 h2cParaBuf[2] = pBtReq->pParamStart[6];
1060                 h2cParaLen = 3;
1061                 retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
1062                 /* ckeck bt return status. */
1063                 if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
1064                         pBtRsp->status = ((btOpcode << 8) | retStatus);
1065                         RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
1066                         return paraLen;
1067                 }
1068         } else if (BT_GSET_TX_PWR_FINETUNE == setType) {
1069                 /* fill h2c parameters */
1070                 btOpcode = BT_LO_OP_SET_TX_POWER_CALIBRATION;
1071                 h2cParaBuf[0] = calVal;
1072                 h2cParaLen = 1;
1073                 retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
1074                 /* ckeck bt return status. */
1075                 if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
1076                         pBtRsp->status = ((btOpcode << 8) | retStatus);
1077                         RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
1078                         return paraLen;
1079                 }
1080         } else if (BT_SET_TRACKING_INTERVAL == setType) {
1081                 /*      BT_LO_OP_SET_TRACKING_INTERVAL                                                          = 0x22, */
1082                 /*      BT_LO_OP_SET_THERMAL_METER                                                                      = 0x23, */
1083                 /*      BT_LO_OP_ENABLE_CFO_TRACKING                                                                    = 0x24, */
1084                 btOpcode = BT_LO_OP_SET_TRACKING_INTERVAL;
1085                 h2cParaBuf[0] = calVal;
1086                 h2cParaLen = 1;
1087                 retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
1088                 /* ckeck bt return status. */
1089                 if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
1090                         pBtRsp->status = ((btOpcode << 8) | retStatus);
1091                         RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
1092                         return paraLen;
1093                 }
1094         } else if (BT_SET_THERMAL_METER == setType) {
1095                 btOpcode = BT_LO_OP_SET_THERMAL_METER;
1096                 h2cParaBuf[0] = calVal;
1097                 h2cParaLen = 1;
1098                 retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
1099                 /* ckeck bt return status. */
1100                 if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
1101                         pBtRsp->status = ((btOpcode << 8) | retStatus);
1102                         RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
1103                         return paraLen;
1104                 }
1105         } else if (BT_ENABLE_CFO_TRACKING == setType) {
1106                 btOpcode = BT_LO_OP_ENABLE_CFO_TRACKING;
1107                 h2cParaBuf[0] = calVal;
1108                 h2cParaLen = 1;
1109                 retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
1110                 /* ckeck bt return status. */
1111                 if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
1112                         pBtRsp->status = ((btOpcode << 8) | retStatus);
1113                         RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
1114                         return paraLen;
1115                 }
1116         }
1117
1118         pBtRsp->status = BT_STATUS_SUCCESS;
1119         return paraLen;
1120 }
1121
1122
1123
1124 u2Byte
1125 mptbt_BtSetTxRxPars(
1126         IN      PADAPTER                Adapter,
1127         IN      PBT_REQ_CMD     pBtReq,
1128         IN      PBT_RSP_CMD     pBtRsp
1129 )
1130 {
1131         u1Byte                          h2cParaBuf[6] = {0};
1132         u1Byte                          h2cParaLen = 0;
1133         u2Byte                          paraLen = 0;
1134         u1Byte                          retStatus = BT_STATUS_BT_OP_SUCCESS;
1135         u1Byte                          btOpcode;
1136         u1Byte                          btOpcodeVer = 0;
1137         PBT_TXRX_PARAMETERS pTxRxPars = (PBT_TXRX_PARAMETERS)&pBtReq->pParamStart[0];
1138         u2Byte                          lenTxRx = sizeof(BT_TXRX_PARAMETERS);
1139         u1Byte                          i;
1140         u1Byte                          bdAddr[6] = {0};
1141
1142         /*  */
1143         /* check upper layer parameters */
1144         /*  */
1145
1146         /* 1. check upper layer opcode version */
1147         if (pBtReq->opCodeVer != 1) {
1148                 RTW_INFO("[MPT], Error!! Upper OP code version not match!!!\n");
1149                 pBtRsp->status = BT_STATUS_OPCODE_U_VERSION_MISMATCH;
1150                 return paraLen;
1151         }
1152         /* 2. check upper layer parameter length */
1153         if (pBtReq->paraLength == sizeof(BT_TXRX_PARAMETERS)) {
1154                 RTW_INFO("[MPT], pTxRxPars->txrxChannel=0x%x\n", pTxRxPars->txrxChannel);
1155                 RTW_INFO("[MPT], pTxRxPars->txrxTxPktCnt=0x%8x\n", pTxRxPars->txrxTxPktCnt);
1156                 RTW_INFO("[MPT], pTxRxPars->txrxTxPktInterval=0x%x\n", pTxRxPars->txrxTxPktInterval);
1157                 RTW_INFO("[MPT], pTxRxPars->txrxPayloadType=0x%x\n", pTxRxPars->txrxPayloadType);
1158                 RTW_INFO("[MPT], pTxRxPars->txrxPktType=0x%x\n", pTxRxPars->txrxPktType);
1159                 RTW_INFO("[MPT], pTxRxPars->txrxPayloadLen=0x%x\n", pTxRxPars->txrxPayloadLen);
1160                 RTW_INFO("[MPT], pTxRxPars->txrxPktHeader=0x%x\n", pTxRxPars->txrxPktHeader);
1161                 RTW_INFO("[MPT], pTxRxPars->txrxWhitenCoeff=0x%x\n", pTxRxPars->txrxWhitenCoeff);
1162                 bdAddr[0] = pTxRxPars->txrxBdaddr[5];
1163                 bdAddr[1] = pTxRxPars->txrxBdaddr[4];
1164                 bdAddr[2] = pTxRxPars->txrxBdaddr[3];
1165                 bdAddr[3] = pTxRxPars->txrxBdaddr[2];
1166                 bdAddr[4] = pTxRxPars->txrxBdaddr[1];
1167                 bdAddr[5] = pTxRxPars->txrxBdaddr[0];
1168                 RTW_INFO("[MPT], pTxRxPars->txrxBdaddr: %s", &bdAddr[0]);
1169                 RTW_INFO("[MPT], pTxRxPars->txrxTxGainIndex=0x%x\n", pTxRxPars->txrxTxGainIndex);
1170         } else {
1171                 RTW_INFO("[MPT], Error!! pBtReq->paraLength=%d, correct Len=%d\n", pBtReq->paraLength, lenTxRx);
1172                 pBtRsp->status = BT_STATUS_PARAMETER_FORMAT_ERROR_U;
1173                 return paraLen;
1174         }
1175
1176         /*  */
1177         /* execute lower layer opcodes */
1178         /*  */
1179
1180         /* fill h2c parameters */
1181         btOpcode = BT_LO_OP_SET_PKT_HEADER;
1182         if (pTxRxPars->txrxPktHeader > 0x3ffff) {
1183                 RTW_INFO("[MPT], Error!! pTxRxPars->txrxPktHeader=0x%x is out of range, (should be between 0x0~0x3ffff)\n", pTxRxPars->txrxPktHeader);
1184                 pBtRsp->status = (btOpcode << 8) | BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
1185                 return paraLen;
1186         } else {
1187                 h2cParaBuf[0] = (u1Byte)(pTxRxPars->txrxPktHeader & 0xff);
1188                 h2cParaBuf[1] = (u1Byte)((pTxRxPars->txrxPktHeader & 0xff00) >> 8);
1189                 h2cParaBuf[2] = (u1Byte)((pTxRxPars->txrxPktHeader & 0xff0000) >> 16);
1190                 h2cParaLen = 3;
1191                 retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
1192         }
1193
1194         /* ckeck bt return status. */
1195         if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
1196                 pBtRsp->status = ((btOpcode << 8) | retStatus);
1197                 RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
1198                 return paraLen;
1199         }
1200
1201         /* fill h2c parameters */
1202         btOpcode = BT_LO_OP_SET_PKT_TYPE_LEN;
1203         {
1204                 u2Byte  payloadLenLimit = 0;
1205                 switch (pTxRxPars->txrxPktType) {
1206                 case MP_BT_PKT_DH1:
1207                         payloadLenLimit = 27 * 8;
1208                         break;
1209                 case MP_BT_PKT_DH3:
1210                         payloadLenLimit = 183 * 8;
1211                         break;
1212                 case MP_BT_PKT_DH5:
1213                         payloadLenLimit = 339 * 8;
1214                         break;
1215                 case MP_BT_PKT_2DH1:
1216                         payloadLenLimit = 54 * 8;
1217                         break;
1218                 case MP_BT_PKT_2DH3:
1219                         payloadLenLimit = 367 * 8;
1220                         break;
1221                 case MP_BT_PKT_2DH5:
1222                         payloadLenLimit = 679 * 8;
1223                         break;
1224                 case MP_BT_PKT_3DH1:
1225                         payloadLenLimit = 83 * 8;
1226                         break;
1227                 case MP_BT_PKT_3DH3:
1228                         payloadLenLimit = 552 * 8;
1229                         break;
1230                 case MP_BT_PKT_3DH5:
1231                         payloadLenLimit = 1021 * 8;
1232                         break;
1233                 case MP_BT_PKT_LE:
1234                         payloadLenLimit = 39 * 8;
1235                         break;
1236                 default: {
1237                         RTW_INFO("[MPT], Error!! Unknown pTxRxPars->txrxPktType=0x%x\n", pTxRxPars->txrxPktType);
1238                         pBtRsp->status = (btOpcode << 8) | BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
1239                         return paraLen;
1240                 }
1241                 break;
1242                 }
1243
1244                 if (pTxRxPars->txrxPayloadLen > payloadLenLimit) {
1245                         RTW_INFO("[MPT], Error!! pTxRxPars->txrxPayloadLen=0x%x, (should smaller than %d)\n",
1246                                  pTxRxPars->txrxPayloadLen, payloadLenLimit);
1247                         pBtRsp->status = (btOpcode << 8) | BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
1248                         return paraLen;
1249                 }
1250
1251                 h2cParaBuf[0] = pTxRxPars->txrxPktType;
1252                 h2cParaBuf[1] = (u1Byte)((pTxRxPars->txrxPayloadLen & 0xff));
1253                 h2cParaBuf[2] = (u1Byte)((pTxRxPars->txrxPayloadLen & 0xff00) >> 8);
1254                 h2cParaLen = 3;
1255                 retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
1256         }
1257
1258         /* ckeck bt return status. */
1259         if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
1260                 pBtRsp->status = ((btOpcode << 8) | retStatus);
1261                 RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
1262                 return paraLen;
1263         }
1264
1265         /* fill h2c parameters */
1266         btOpcode = BT_LO_OP_SET_PKT_CNT_L_PL_TYPE;
1267         if (pTxRxPars->txrxPayloadType > MP_BT_PAYLOAD_MAX) {
1268                 RTW_INFO("[MPT], Error!! pTxRxPars->txrxPayloadType=0x%x, (should be between 0~4)\n", pTxRxPars->txrxPayloadType);
1269                 pBtRsp->status = (btOpcode << 8) | BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
1270                 return paraLen;
1271         } else {
1272                 h2cParaBuf[0] = (u1Byte)((pTxRxPars->txrxTxPktCnt & 0xff));
1273                 h2cParaBuf[1] = (u1Byte)((pTxRxPars->txrxTxPktCnt & 0xff00) >> 8);
1274                 h2cParaBuf[2] = pTxRxPars->txrxPayloadType;
1275                 h2cParaLen = 3;
1276                 retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
1277         }
1278
1279         /* ckeck bt return status. */
1280         if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
1281                 pBtRsp->status = ((btOpcode << 8) | retStatus);
1282                 RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
1283                 return paraLen;
1284         }
1285
1286         /* fill h2c parameters */
1287         btOpcode = BT_LO_OP_SET_PKT_CNT_H_PKT_INTV;
1288         if (pTxRxPars->txrxTxPktInterval > 15) {
1289                 RTW_INFO("[MPT], Error!! pTxRxPars->txrxTxPktInterval=0x%x, (should be between 0~15)\n", pTxRxPars->txrxTxPktInterval);
1290                 pBtRsp->status = (btOpcode << 8) | BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
1291                 return paraLen;
1292         } else {
1293                 h2cParaBuf[0] = (u1Byte)((pTxRxPars->txrxTxPktCnt & 0xff0000) >> 16);
1294                 h2cParaBuf[1] = (u1Byte)((pTxRxPars->txrxTxPktCnt & 0xff000000) >> 24);
1295                 h2cParaBuf[2] = pTxRxPars->txrxTxPktInterval;
1296                 h2cParaLen = 3;
1297                 retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
1298         }
1299
1300         /* ckeck bt return status. */
1301         if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
1302                 pBtRsp->status = ((btOpcode << 8) | retStatus);
1303                 RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
1304                 return paraLen;
1305         }
1306
1307         /* fill h2c parameters */
1308         btOpcode = BT_LO_OP_SET_WHITENCOEFF;
1309         {
1310                 h2cParaBuf[0] = pTxRxPars->txrxWhitenCoeff;
1311                 h2cParaLen = 1;
1312                 retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
1313         }
1314
1315         /* ckeck bt return status. */
1316         if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
1317                 pBtRsp->status = ((btOpcode << 8) | retStatus);
1318                 RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
1319                 return paraLen;
1320         }
1321
1322
1323         /* fill h2c parameters */
1324         btOpcode = BT_LO_OP_SET_CHNL_TX_GAIN;
1325         if ((pTxRxPars->txrxChannel > 78) ||
1326             (pTxRxPars->txrxTxGainIndex > 7)) {
1327                 RTW_INFO("[MPT], Error!! pTxRxPars->txrxChannel=0x%x, (should be between 0~78)\n", pTxRxPars->txrxChannel);
1328                 RTW_INFO("[MPT], Error!! pTxRxPars->txrxTxGainIndex=0x%x, (should be between 0~7)\n", pTxRxPars->txrxTxGainIndex);
1329                 pBtRsp->status = (btOpcode << 8) | BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
1330                 return paraLen;
1331         } else {
1332                 h2cParaBuf[0] = pTxRxPars->txrxChannel;
1333                 h2cParaBuf[1] = pTxRxPars->txrxTxGainIndex;
1334                 h2cParaLen = 2;
1335                 retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
1336         }
1337
1338         /* ckeck bt return status. */
1339         if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
1340                 pBtRsp->status = ((btOpcode << 8) | retStatus);
1341                 RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
1342                 return paraLen;
1343         }
1344
1345         /* fill h2c parameters */
1346         btOpcode = BT_LO_OP_SET_BD_ADDR_L;
1347         if ((pTxRxPars->txrxBdaddr[0] == 0) &&
1348             (pTxRxPars->txrxBdaddr[1] == 0) &&
1349             (pTxRxPars->txrxBdaddr[2] == 0) &&
1350             (pTxRxPars->txrxBdaddr[3] == 0) &&
1351             (pTxRxPars->txrxBdaddr[4] == 0) &&
1352             (pTxRxPars->txrxBdaddr[5] == 0)) {
1353                 RTW_INFO("[MPT], Error!! pTxRxPars->txrxBdaddr=all zero\n");
1354                 pBtRsp->status = (btOpcode << 8) | BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
1355                 return paraLen;
1356         }
1357         if ((pTxRxPars->txrxBdaddr[0] == 0xff) &&
1358             (pTxRxPars->txrxBdaddr[1] == 0xff) &&
1359             (pTxRxPars->txrxBdaddr[2] == 0xff) &&
1360             (pTxRxPars->txrxBdaddr[3] == 0xff) &&
1361             (pTxRxPars->txrxBdaddr[4] == 0xff) &&
1362             (pTxRxPars->txrxBdaddr[5] == 0xff)) {
1363                 RTW_INFO("[MPT], Error!! pTxRxPars->txrxBdaddr=all 0xf\n");
1364                 pBtRsp->status = (btOpcode << 8) | BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
1365                 return paraLen;
1366         }
1367
1368         {
1369                 h2cParaBuf[0] = pTxRxPars->txrxBdaddr[0];
1370                 h2cParaBuf[1] = pTxRxPars->txrxBdaddr[1];
1371                 h2cParaBuf[2] = pTxRxPars->txrxBdaddr[2];
1372                 h2cParaLen = 3;
1373                 retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
1374         }
1375         /* ckeck bt return status. */
1376         if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
1377                 pBtRsp->status = ((btOpcode << 8) | retStatus);
1378                 RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
1379                 return paraLen;
1380         }
1381
1382         btOpcode = BT_LO_OP_SET_BD_ADDR_H;
1383         {
1384                 h2cParaBuf[0] = pTxRxPars->txrxBdaddr[3];
1385                 h2cParaBuf[1] = pTxRxPars->txrxBdaddr[4];
1386                 h2cParaBuf[2] = pTxRxPars->txrxBdaddr[5];
1387                 h2cParaLen = 3;
1388                 retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
1389         }
1390         /* ckeck bt return status. */
1391         if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
1392                 pBtRsp->status = ((btOpcode << 8) | retStatus);
1393                 RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
1394                 return paraLen;
1395         }
1396
1397         pBtRsp->status = BT_STATUS_SUCCESS;
1398         return paraLen;
1399 }
1400
1401
1402
1403 u2Byte
1404 mptbt_BtTestCtrl(
1405         IN      PADAPTER                Adapter,
1406         IN      PBT_REQ_CMD     pBtReq,
1407         IN      PBT_RSP_CMD     pBtRsp
1408 )
1409 {
1410         u1Byte                          h2cParaBuf[6] = {0};
1411         u1Byte                          h2cParaLen = 0;
1412         u2Byte                          paraLen = 0;
1413         u1Byte                          retStatus = BT_STATUS_BT_OP_SUCCESS;
1414         u1Byte                          btOpcode;
1415         u1Byte                          btOpcodeVer = 0;
1416         u1Byte                          testCtrl = 0;
1417
1418         /*  */
1419         /* check upper layer parameters */
1420         /*  */
1421
1422         /* 1. check upper layer opcode version */
1423         if (pBtReq->opCodeVer != 1) {
1424                 RTW_INFO("[MPT], Error!! Upper OP code version not match!!!\n");
1425                 pBtRsp->status = BT_STATUS_OPCODE_U_VERSION_MISMATCH;
1426                 return paraLen;
1427         }
1428         /* 2. check upper layer parameter length */
1429         if (1 == pBtReq->paraLength) {
1430                 testCtrl = pBtReq->pParamStart[0];
1431                 RTW_INFO("[MPT], testCtrl=%d\n", testCtrl);
1432         } else {
1433                 RTW_INFO("[MPT], Error!! wrong parameter length=%d (should be 1)\n", pBtReq->paraLength);
1434                 pBtRsp->status = BT_STATUS_PARAMETER_FORMAT_ERROR_U;
1435                 return paraLen;
1436         }
1437
1438         /*  */
1439         /* execute lower layer opcodes */
1440         /*  */
1441
1442         /* 1. fill h2c parameters        */
1443         /* check bt mode */
1444         btOpcode = BT_LO_OP_TEST_CTRL;
1445         if (testCtrl >= MP_BT_TEST_MAX) {
1446                 RTW_INFO("[MPT], Error!! testCtrl=0x%x, (should be between smaller or equal to 0x%x)\n",
1447                          testCtrl, MP_BT_TEST_MAX - 1);
1448                 pBtRsp->status = BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
1449                 return paraLen;
1450         } else {
1451                 h2cParaBuf[0] = testCtrl;
1452                 h2cParaLen = 1;
1453                 retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
1454         }
1455
1456         /* 3. construct respond status code and data. */
1457         if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
1458                 pBtRsp->status = ((btOpcode << 8) | retStatus);
1459                 RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
1460                 return paraLen;
1461         }
1462
1463         pBtRsp->status = BT_STATUS_SUCCESS;
1464         return paraLen;
1465 }
1466
1467
1468 u2Byte
1469 mptbt_TestBT(
1470         IN      PADAPTER                Adapter,
1471         IN      PBT_REQ_CMD     pBtReq,
1472         IN      PBT_RSP_CMD     pBtRsp
1473 )
1474 {
1475
1476         u1Byte                          h2cParaBuf[6] = {0};
1477         u1Byte                          h2cParaLen = 0;
1478         u2Byte                          paraLen = 0;
1479         u1Byte                          retStatus = BT_STATUS_BT_OP_SUCCESS;
1480         u1Byte                          btOpcode;
1481         u1Byte                          btOpcodeVer = 0;
1482         u1Byte                          testCtrl = 0;
1483
1484         /* 1. fill h2c parameters        */
1485         btOpcode =  0x11;
1486         h2cParaBuf[0] = 0x11;
1487         h2cParaBuf[1] = 0x0;
1488         h2cParaBuf[2] = 0x0;
1489         h2cParaBuf[3] = 0x0;
1490         h2cParaBuf[4] = 0x0;
1491         h2cParaLen = 1;
1492         /*      retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen); */
1493         retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, h2cParaBuf, h2cParaLen);
1494
1495
1496         /* 3. construct respond status code and data. */
1497         if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
1498                 pBtRsp->status = ((btOpcode << 8) | retStatus);
1499                 RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
1500                 return paraLen;
1501         }
1502
1503         pBtRsp->status = BT_STATUS_SUCCESS;
1504         return paraLen;
1505 }
1506
1507 VOID
1508 mptbt_BtControlProcess(
1509         PADAPTER        Adapter,
1510         PVOID           pInBuf
1511 )
1512 {
1513         u1Byte                  H2C_Parameter[6] = {0};
1514         PBT_H2C         pH2c = (PBT_H2C)&H2C_Parameter[0];
1515         PMPT_CONTEXT    pMptCtx = &(Adapter->mppriv.MptCtx);
1516         PBT_REQ_CMD     pBtReq = (PBT_REQ_CMD)pInBuf;
1517         PBT_RSP_CMD     pBtRsp;
1518         u1Byte                  i;
1519
1520
1521         RTW_INFO("[MPT], mptbt_BtControlProcess()=========>\n");
1522
1523         RTW_INFO("[MPT], input opCodeVer=%d\n", pBtReq->opCodeVer);
1524         RTW_INFO("[MPT], input OpCode=%d\n", pBtReq->OpCode);
1525         RTW_INFO("[MPT], paraLength=%d\n", pBtReq->paraLength);
1526         if (pBtReq->paraLength) {
1527                 /* RTW_INFO("[MPT], parameters(hex):0x%x %d\n",&pBtReq->pParamStart[0], pBtReq->paraLength); */
1528         }
1529
1530         _rtw_memset((void *)pMptCtx->mptOutBuf, 0, 100);
1531         pMptCtx->mptOutLen = 4; /* length of (BT_RSP_CMD.status+BT_RSP_CMD.paraLength) */
1532
1533         pBtRsp = (PBT_RSP_CMD)pMptCtx->mptOutBuf;
1534         pBtRsp->status = BT_STATUS_SUCCESS;
1535         pBtRsp->paraLength = 0x0;
1536
1537         /* The following we should maintain the User OP codes sent by upper layer */
1538         switch (pBtReq->OpCode) {
1539         case BT_UP_OP_BT_READY:
1540                 RTW_INFO("[MPT], OPcode : [BT_READY]\n");
1541                 pBtRsp->paraLength = mptbt_BtReady(Adapter, pBtReq, pBtRsp);
1542                 break;
1543         case BT_UP_OP_BT_SET_MODE:
1544                 RTW_INFO("[MPT], OPcode : [BT_SET_MODE]\n");
1545                 pBtRsp->paraLength = mptbt_BtSetMode(Adapter, pBtReq, pBtRsp);
1546                 break;
1547         case BT_UP_OP_BT_SET_TX_RX_PARAMETER:
1548                 RTW_INFO("[MPT], OPcode : [BT_SET_TXRX_PARAMETER]\n");
1549                 pBtRsp->paraLength = mptbt_BtSetTxRxPars(Adapter, pBtReq, pBtRsp);
1550                 break;
1551         case BT_UP_OP_BT_SET_GENERAL:
1552                 RTW_INFO("[MPT], OPcode : [BT_SET_GENERAL]\n");
1553                 pBtRsp->paraLength = mptbt_BtSetGeneral(Adapter, pBtReq, pBtRsp);
1554                 break;
1555         case BT_UP_OP_BT_GET_GENERAL:
1556                 RTW_INFO("[MPT], OPcode : [BT_GET_GENERAL]\n");
1557                 pBtRsp->paraLength = mptbt_BtGetGeneral(Adapter, pBtReq, pBtRsp);
1558                 break;
1559         case BT_UP_OP_BT_TEST_CTRL:
1560                 RTW_INFO("[MPT], OPcode : [BT_TEST_CTRL]\n");
1561                 pBtRsp->paraLength = mptbt_BtTestCtrl(Adapter, pBtReq, pBtRsp);
1562                 break;
1563         case BT_UP_OP_TEST_BT:
1564                 RTW_INFO("[MPT], OPcode : [TEST_BT]\n");
1565                 pBtRsp->paraLength = mptbt_TestBT(Adapter, pBtReq, pBtRsp);
1566                 break;
1567         default:
1568                 RTW_INFO("[MPT], Error!! OPcode : UNDEFINED!!!!\n");
1569                 pBtRsp->status = BT_STATUS_UNKNOWN_OPCODE_U;
1570                 pBtRsp->paraLength = 0x0;
1571                 break;
1572         }
1573
1574         pMptCtx->mptOutLen += pBtRsp->paraLength;
1575
1576         RTW_INFO("[MPT], pMptCtx->mptOutLen=%d, pBtRsp->paraLength=%d\n", pMptCtx->mptOutLen, pBtRsp->paraLength);
1577         RTW_INFO("[MPT], mptbt_BtControlProcess()<=========\n");
1578 }
1579
1580 #endif