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