1 /******************************************************************************
3 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
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.
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
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
19 ******************************************************************************/
22 #include <drv_types.h>
23 #include <rtw_bt_mp.h>
25 #if defined(CONFIG_RTL8723B)
26 #include <rtl8723b_hal.h>
29 #if defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8821A)
30 void MPh2c_timeout_handle(void *FunctionContext)
36 RTW_INFO("[MPT], MPh2c_timeout_handle\n");
38 pAdapter = (PADAPTER)FunctionContext;
39 pMptCtx = &pAdapter->mppriv.mpt_ctx;
41 pMptCtx->bMPh2c_timeout = _TRUE;
43 if ((_FALSE == pMptCtx->MptH2cRspEvent)
44 || ((_TRUE == pMptCtx->MptH2cRspEvent)
45 && (_FALSE == pMptCtx->MptBtC2hEvent)))
46 _rtw_up_sema(&pMptCtx->MPh2c_Sema);
49 u32 WaitC2Hevent(PADAPTER pAdapter, u8 *C2H_event, u32 delay_time)
51 PMPT_CONTEXT pMptCtx = &(pAdapter->mppriv.mpt_ctx);
52 pMptCtx->bMPh2c_timeout = _FALSE;
54 if (pAdapter->registrypriv.mp_mode == 0) {
55 RTW_INFO("[MPT], Error!! WaitC2Hevent mp_mode == 0!!\n");
59 _set_timer(&pMptCtx->MPh2c_timeout_timer, delay_time);
61 _rtw_down_sema(&pMptCtx->MPh2c_Sema);
63 if (pMptCtx->bMPh2c_timeout == _TRUE) {
69 /* for safty, cancel timer here again */
70 _cancel_timer_ex(&pMptCtx->MPh2c_timeout_timer);
82 BT_CTRL_STATUS c2hStatus = BT_STATUS_C2H_SUCCESS;
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); */
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");
108 /* KIRQL OldIrql = KeGetCurrentIrql(); */
109 BT_CTRL_STATUS h2cStatus = BT_STATUS_H2C_SUCCESS;
110 PMPT_CONTEXT pMptCtx = &(Adapter->mppriv.mpt_ctx);
113 RTW_INFO("[MPT], mptbt_SendH2c()=========>\n");
115 /* PlatformResetEvent(&pMptCtx->MptH2cRspEvent); */
116 /* PlatformResetEvent(&pMptCtx->MptBtC2hEvent); */
118 /* if(OldIrql == PASSIVE_LEVEL)
120 /* RTPRINT_DATA(FMPBT, FMPBT_H2C_CONTENT, ("[MPT], MPT H2C hex:\n"), pH2c, h2cCmdLen); */
122 for (i = 0; i < BT_H2C_MAX_RETRY; i++) {
123 RTW_INFO("[MPT], Send H2C command to wifi!!!\n");
125 pMptCtx->MptH2cRspEvent = _FALSE;
126 pMptCtx->MptBtC2hEvent = _FALSE;
128 #if defined(CONFIG_RTL8723B)
129 rtl8723b_set_FwBtMpOper_cmd(Adapter, pH2c->opCode, pH2c->opCodeVer, pH2c->reqNum, pH2c->buf);
131 pMptCtx->h2cReqNum++;
132 pMptCtx->h2cReqNum %= 16;
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");
140 RTW_INFO("[MPT], Error!!BT MptBtC2hEvent timeout!!\n");
141 h2cStatus = BT_STATUS_H2C_BT_NO_RSP;
144 RTW_INFO("[MPT], Error!!WiFi MptH2cRspEvent timeout!!\n");
145 h2cStatus = BT_STATUS_H2C_TIMTOUT;
151 * RT_ASSERT(FALSE, ("[MPT], mptbt_SendH2c() can only run under PASSIVE_LEVEL!!\n"));
152 * h2cStatus = BT_STATUS_WRONG_LEVEL;
155 RTW_INFO("[MPT], mptbt_SendH2c()<=========\n");
162 mptbt_CheckBtRspStatus(
167 BT_CTRL_STATUS retStatus = BT_OP_STATUS_SUCCESS;
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");
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");
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");
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");
187 retStatus = BT_STATUS_UNKNOWN_STATUS_L;
188 RTW_INFO("[MPT], BT status : BT_STATUS_UNKNOWN_STATUS_L\n");
198 mptbt_BtFwOpCodeProcess(
206 u1Byte H2C_Parameter[6] = {0};
207 PBT_H2C pH2c = (PBT_H2C)&H2C_Parameter[0];
208 PMPT_CONTEXT pMptCtx = &(Adapter->mppriv.mpt_ctx);
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;
214 if (Adapter->registrypriv.mp_mode == 0) {
215 RTW_INFO("[MPT], Error!! mptbt_BtFwOpCodeProces mp_mode == 0!!\n");
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);
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]);
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);
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;
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;
263 u1Byte h2cParaBuf[6] = {0};
264 u1Byte h2cParaLen = 0;
266 u1Byte retStatus = BT_STATUS_BT_OP_SUCCESS;
268 u1Byte btOpcodeVer = 0;
269 PMPT_CONTEXT pMptCtx = &(Adapter->mppriv.mpt_ctx);
270 PBT_EXT_C2H pExtC2h = (PBT_EXT_C2H)&pMptCtx->c2hBuf[0];
272 u1Byte btFwVer = 0, bdAddr[6] = {0};
273 u2Byte btRealFwVer = 0;
274 pu2Byte pu2Tmp = NULL;
277 /* check upper layer parameters */
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;
287 pBtRsp->pParamStart[0] = MP_BT_NOT_READY;
290 /* execute lower layer opcodes */
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);
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);
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);
321 bdAddr[5] = pExtC2h->buf[0];
322 bdAddr[4] = pExtC2h->buf[1];
323 bdAddr[3] = pExtC2h->buf[2];
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);
336 bdAddr[2] = pExtC2h->buf[0];
337 bdAddr[1] = pExtC2h->buf[1];
338 bdAddr[0] = pExtC2h->buf[2];
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];
354 void mptbt_close_WiFiRF(PADAPTER Adapter)
356 phy_set_bb_reg(Adapter, 0x824, 0xF, 0x0);
357 phy_set_bb_reg(Adapter, 0x824, 0x700000, 0x0);
358 phy_set_rf_reg(Adapter, RF_PATH_A, 0x0, 0xF0000, 0x0);
361 void mptbt_open_WiFiRF(PADAPTER Adapter)
363 phy_set_bb_reg(Adapter, 0x824, 0x700000, 0x3);
364 phy_set_bb_reg(Adapter, 0x824, 0xF, 0x2);
365 phy_set_rf_reg(Adapter, RF_PATH_A, 0x0, 0xF0000, 0x3);
368 u4Byte mptbt_switch_RF(PADAPTER Adapter, u1Byte Enter)
370 u2Byte tmp_2byte = 0;
372 /* Enter test mode */
374 /* 1>. close WiFi RF */
375 mptbt_close_WiFiRF(Adapter);
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);
384 /* 1>. Open WiFi RF */
385 mptbt_open_WiFiRF(Adapter);
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);
405 u1Byte h2cParaBuf[6] = {0};
406 u1Byte h2cParaLen = 0;
408 u1Byte retStatus = BT_STATUS_BT_OP_SUCCESS;
410 u1Byte btOpcodeVer = 0;
411 u1Byte btModeToSet = 0;
414 /* check upper layer parameters */
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;
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);
427 RTW_INFO("[MPT], Error!! wrong parameter length=%d (should be 1)\n", pBtReq->paraLength);
428 pBtRsp->status = BT_STATUS_PARAMETER_FORMAT_ERROR_U;
433 /* execute lower layer opcodes */
436 /* 1. fill h2c parameters */
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;
443 mptbt_switch_RF(Adapter, 1);
445 h2cParaBuf[0] = btModeToSet;
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);
451 /* 3. construct respond status code and data. */
452 if (BT_STATUS_BT_OP_SUCCESS == retStatus)
453 pBtRsp->status = BT_STATUS_SUCCESS;
455 pBtRsp->status = ((btOpcode << 8) | retStatus);
456 RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
471 PMPT_CONTEXT pMptCtx = &(Adapter->mppriv.mpt_ctx);
472 PBT_EXT_C2H pExtC2h = (PBT_EXT_C2H)tmpBuf;
474 if (Adapter->bBTFWReady == _FALSE || Adapter->registrypriv.mp_mode == 0) {
475 /* RTW_INFO("Ignore C2H BT MP Info since not in MP mode\n"); */
478 if (length > 32 || length < 3) {
479 RTW_INFO("\n [MPT], pExtC2h->buf hex: length=%d > 32 || < 3\n", length);
483 /* cancel_timeout for h2c handle */
484 _cancel_timer_ex(&pMptCtx->MPh2c_timeout_timer);
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);
490 switch (pExtC2h->extendId) {
491 case EXT_C2H_WIFI_FW_ACTIVE_RSP:
492 RTW_INFO("[MPT], EXT_C2H_WIFI_FW_ACTIVE_RSP\n");
494 RTW_INFO("[MPT], pExtC2h->buf hex:\n");
495 for (i = 0; i < (length - 3); i++)
496 RTW_INFO(" 0x%x ", pExtC2h->buf[i]);
498 if ((_FALSE == pMptCtx->bMPh2c_timeout)
499 && (_FALSE == pMptCtx->MptH2cRspEvent)) {
500 pMptCtx->MptH2cRspEvent = _TRUE;
501 _rtw_up_sema(&pMptCtx->MPh2c_Sema);
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]);
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);
524 RTW_INFO("[MPT], EXT_C2H Target not found,pExtC2h->extendId =%d ,pExtC2h->reqNum=%d\n", pExtC2h->extendId, pExtC2h->reqNum);
536 IN PBT_REQ_CMD pBtReq,
537 IN PBT_RSP_CMD pBtRsp
540 PMPT_CONTEXT pMptCtx = &(Adapter->mppriv.mpt_ctx);
541 PBT_EXT_C2H pExtC2h = (PBT_EXT_C2H)&pMptCtx->c2hBuf[0];
542 u1Byte h2cParaBuf[6] = {0};
543 u1Byte h2cParaLen = 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;
557 /* check upper layer parameters */
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;
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;
572 getParaLen = pBtReq->paraLength - 1;
573 getType = pBtReq->pParamStart[0];
575 RTW_INFO("[MPT], getType=%d, getParaLen=%d\n", getType, getParaLen);
577 /* check parameter first */
580 RTW_INFO("[MPT], [BT_GGET_REG]\n");
582 if (getParaLen == validParaLen) {
583 btOpcode = BT_LO_OP_READ_REG;
584 regType = pBtReq->pParamStart[1];
585 pu4Tmp = (pu4Byte)&pBtReq->pParamStart[2];
587 RTW_INFO("[MPT], BT_GGET_REG regType=0x%02x, regAddr=0x%08x!!\n",
589 if (regType >= BT_REG_MAX) {
590 pBtRsp->status = (btOpcode << 8) | BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
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;
605 RTW_INFO("[MPT], [BT_GGET_STATUS]\n");
609 RTW_INFO("[MPT], [BT_GGET_REPORT]\n");
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;
621 RTW_INFO("[MPT], Error!! getType=%d, out of range\n", getType);
622 pBtRsp->status = BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
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;
635 /* execute lower layer opcodes */
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];
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);
654 pu2Tmp = (pu2Byte)&pExtC2h->buf[0];
656 RTW_INFO("[MPT], read reg regType=0x%02x, regAddr=0x%08x, regValue=0x%04x\n",
657 regType, regAddr, regValue);
659 pu4Tmp = (pu4Byte)&pBtRsp->pParamStart[0];
662 } else if (BT_GGET_STATUS == getType) {
663 btOpcode = BT_LO_OP_GET_BT_STATUS;
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);
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]);
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;
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);
693 pBtRsp->pParamStart[0] = pExtC2h->buf[0];
694 pBtRsp->pParamStart[1] = pExtC2h->buf[1];
696 btOpcode = BT_LO_OP_GET_RX_PKT_CNT_H;
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);
706 pBtRsp->pParamStart[2] = pExtC2h->buf[0];
707 pBtRsp->pParamStart[3] = pExtC2h->buf[1];
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;
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);
723 pBtRsp->pParamStart[0] = pExtC2h->buf[0];
724 pBtRsp->pParamStart[1] = pExtC2h->buf[1];
726 btOpcode = BT_LO_OP_GET_RX_ERROR_BITS_H;
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);
736 pBtRsp->pParamStart[2] = pExtC2h->buf[0];
737 pBtRsp->pParamStart[3] = pExtC2h->buf[1];
741 case BT_REPORT_RSSI: {
742 RTW_INFO("[MPT], [RSSI]\n");
743 btOpcode = BT_LO_OP_GET_RSSI;
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);
753 pBtRsp->pParamStart[0] = pExtC2h->buf[0];
754 pBtRsp->pParamStart[1] = pExtC2h->buf[1];
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;
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);
770 pBtRsp->pParamStart[0] = pExtC2h->buf[0];
771 pBtRsp->pParamStart[1] = pExtC2h->buf[1];
773 btOpcode = BT_LO_OP_GET_CFO_HDR_QUALITY_H;
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);
783 pBtRsp->pParamStart[2] = pExtC2h->buf[0];
784 pBtRsp->pParamStart[3] = pExtC2h->buf[1];
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;
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);
800 bdAddr[5] = pExtC2h->buf[0];
801 bdAddr[4] = pExtC2h->buf[1];
802 bdAddr[3] = pExtC2h->buf[2];
804 btOpcode = BT_LO_OP_GET_TARGET_BD_ADDR_H;
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);
814 bdAddr[2] = pExtC2h->buf[0];
815 bdAddr[1] = pExtC2h->buf[1];
816 bdAddr[0] = pExtC2h->buf[2];
818 RTW_INFO("[MPT], Connected Target BDAddr:%s", bdAddr);
819 for (i = 0; i < 6; i++)
820 pBtRsp->pParamStart[i] = bdAddr[5 - i];
825 pBtRsp->status = BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
831 pBtRsp->status = BT_STATUS_SUCCESS;
840 IN PBT_REQ_CMD pBtReq,
841 IN PBT_RSP_CMD pBtRsp
844 u1Byte h2cParaBuf[6] = {0};
845 u1Byte h2cParaLen = 0;
847 u1Byte retStatus = BT_STATUS_BT_OP_SUCCESS;
849 u1Byte btOpcodeVer = 0;
851 u2Byte setParaLen = 0, validParaLen = 0;
852 u1Byte regType = 0, bdAddr[6] = {0}, calVal = 0;
853 u4Byte regAddr = 0, regValue = 0;
859 /* check upper layer parameters */
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;
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;
874 setParaLen = pBtReq->paraLength - 1;
875 setType = pBtReq->pParamStart[0];
877 RTW_INFO("[MPT], setType=%d, setParaLen=%d\n", setType, setParaLen);
879 /* check parameter first */
882 RTW_INFO("[MPT], [BT_GSET_REG]\n");
884 if (setParaLen == validParaLen) {
885 btOpcode = BT_LO_OP_WRITE_REG_VALUE;
886 regType = pBtReq->pParamStart[1];
887 pu4Tmp = (pu4Byte)&pBtReq->pParamStart[2];
889 pu4Tmp = (pu4Byte)&pBtReq->pParamStart[6];
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;
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;
909 RTW_INFO("[MPT], [BT_GSET_RESET]\n");
912 case BT_GSET_TARGET_BD_ADDR:
913 RTW_INFO("[MPT], [BT_GSET_TARGET_BD_ADDR]\n");
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;
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;
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]);
947 case BT_GSET_TX_PWR_FINETUNE:
948 RTW_INFO("[MPT], [BT_GSET_TX_PWR_FINETUNE]\n");
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;
957 RTW_INFO("[MPT], calVal=%d\n", calVal);
960 case BT_SET_TRACKING_INTERVAL:
961 RTW_INFO("[MPT], [BT_SET_TRACKING_INTERVAL] setParaLen =%d\n", setParaLen);
964 if (setParaLen == validParaLen)
965 calVal = pBtReq->pParamStart[1];
967 case BT_SET_THERMAL_METER:
968 RTW_INFO("[MPT], [BT_SET_THERMAL_METER] setParaLen =%d\n", setParaLen);
970 if (setParaLen == validParaLen)
971 calVal = pBtReq->pParamStart[1];
973 case BT_ENABLE_CFO_TRACKING:
974 RTW_INFO("[MPT], [BT_ENABLE_CFO_TRACKING] setParaLen =%d\n", setParaLen);
976 if (setParaLen == validParaLen)
977 calVal = pBtReq->pParamStart[1];
979 case BT_GSET_UPDATE_BT_PATCH:
983 RTW_INFO("[MPT], Error!! setType=%d, out of range\n", setType);
984 pBtRsp->status = BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
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;
997 /* execute lower layer opcodes */
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];
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);
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];
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);
1030 } else if (BT_GSET_RESET == setType) {
1031 btOpcode = BT_LO_OP_RESET;
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);
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];
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);
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];
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);
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;
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);
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;
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);
1094 } else if (BT_SET_THERMAL_METER == setType) {
1095 btOpcode = BT_LO_OP_SET_THERMAL_METER;
1096 h2cParaBuf[0] = calVal;
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);
1105 } else if (BT_ENABLE_CFO_TRACKING == setType) {
1106 btOpcode = BT_LO_OP_ENABLE_CFO_TRACKING;
1107 h2cParaBuf[0] = calVal;
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);
1118 pBtRsp->status = BT_STATUS_SUCCESS;
1125 mptbt_BtSetTxRxPars(
1126 IN PADAPTER Adapter,
1127 IN PBT_REQ_CMD pBtReq,
1128 IN PBT_RSP_CMD pBtRsp
1131 u1Byte h2cParaBuf[6] = {0};
1132 u1Byte h2cParaLen = 0;
1134 u1Byte retStatus = BT_STATUS_BT_OP_SUCCESS;
1136 u1Byte btOpcodeVer = 0;
1137 PBT_TXRX_PARAMETERS pTxRxPars = (PBT_TXRX_PARAMETERS)&pBtReq->pParamStart[0];
1138 u2Byte lenTxRx = sizeof(BT_TXRX_PARAMETERS);
1140 u1Byte bdAddr[6] = {0};
1143 /* check upper layer parameters */
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;
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);
1171 RTW_INFO("[MPT], Error!! pBtReq->paraLength=%d, correct Len=%d\n", pBtReq->paraLength, lenTxRx);
1172 pBtRsp->status = BT_STATUS_PARAMETER_FORMAT_ERROR_U;
1177 /* execute lower layer opcodes */
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;
1187 h2cParaBuf[0] = (u1Byte)(pTxRxPars->txrxPktHeader & 0xff);
1188 h2cParaBuf[1] = (u1Byte)((pTxRxPars->txrxPktHeader & 0xff00) >> 8);
1189 h2cParaBuf[2] = (u1Byte)((pTxRxPars->txrxPktHeader & 0xff0000) >> 16);
1191 retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
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);
1201 /* fill h2c parameters */
1202 btOpcode = BT_LO_OP_SET_PKT_TYPE_LEN;
1204 u2Byte payloadLenLimit = 0;
1205 switch (pTxRxPars->txrxPktType) {
1207 payloadLenLimit = 27 * 8;
1210 payloadLenLimit = 183 * 8;
1213 payloadLenLimit = 339 * 8;
1215 case MP_BT_PKT_2DH1:
1216 payloadLenLimit = 54 * 8;
1218 case MP_BT_PKT_2DH3:
1219 payloadLenLimit = 367 * 8;
1221 case MP_BT_PKT_2DH5:
1222 payloadLenLimit = 679 * 8;
1224 case MP_BT_PKT_3DH1:
1225 payloadLenLimit = 83 * 8;
1227 case MP_BT_PKT_3DH3:
1228 payloadLenLimit = 552 * 8;
1230 case MP_BT_PKT_3DH5:
1231 payloadLenLimit = 1021 * 8;
1234 payloadLenLimit = 39 * 8;
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;
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;
1251 h2cParaBuf[0] = pTxRxPars->txrxPktType;
1252 h2cParaBuf[1] = (u1Byte)((pTxRxPars->txrxPayloadLen & 0xff));
1253 h2cParaBuf[2] = (u1Byte)((pTxRxPars->txrxPayloadLen & 0xff00) >> 8);
1255 retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
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);
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;
1272 h2cParaBuf[0] = (u1Byte)((pTxRxPars->txrxTxPktCnt & 0xff));
1273 h2cParaBuf[1] = (u1Byte)((pTxRxPars->txrxTxPktCnt & 0xff00) >> 8);
1274 h2cParaBuf[2] = pTxRxPars->txrxPayloadType;
1276 retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
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);
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;
1293 h2cParaBuf[0] = (u1Byte)((pTxRxPars->txrxTxPktCnt & 0xff0000) >> 16);
1294 h2cParaBuf[1] = (u1Byte)((pTxRxPars->txrxTxPktCnt & 0xff000000) >> 24);
1295 h2cParaBuf[2] = pTxRxPars->txrxTxPktInterval;
1297 retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
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);
1307 /* fill h2c parameters */
1308 btOpcode = BT_LO_OP_SET_WHITENCOEFF;
1310 h2cParaBuf[0] = pTxRxPars->txrxWhitenCoeff;
1312 retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
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);
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;
1332 h2cParaBuf[0] = pTxRxPars->txrxChannel;
1333 h2cParaBuf[1] = pTxRxPars->txrxTxGainIndex;
1335 retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
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);
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;
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;
1369 h2cParaBuf[0] = pTxRxPars->txrxBdaddr[0];
1370 h2cParaBuf[1] = pTxRxPars->txrxBdaddr[1];
1371 h2cParaBuf[2] = pTxRxPars->txrxBdaddr[2];
1373 retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
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);
1382 btOpcode = BT_LO_OP_SET_BD_ADDR_H;
1384 h2cParaBuf[0] = pTxRxPars->txrxBdaddr[3];
1385 h2cParaBuf[1] = pTxRxPars->txrxBdaddr[4];
1386 h2cParaBuf[2] = pTxRxPars->txrxBdaddr[5];
1388 retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
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);
1397 pBtRsp->status = BT_STATUS_SUCCESS;
1405 IN PADAPTER Adapter,
1406 IN PBT_REQ_CMD pBtReq,
1407 IN PBT_RSP_CMD pBtRsp
1410 u1Byte h2cParaBuf[6] = {0};
1411 u1Byte h2cParaLen = 0;
1413 u1Byte retStatus = BT_STATUS_BT_OP_SUCCESS;
1415 u1Byte btOpcodeVer = 0;
1416 u1Byte testCtrl = 0;
1419 /* check upper layer parameters */
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;
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);
1433 RTW_INFO("[MPT], Error!! wrong parameter length=%d (should be 1)\n", pBtReq->paraLength);
1434 pBtRsp->status = BT_STATUS_PARAMETER_FORMAT_ERROR_U;
1439 /* execute lower layer opcodes */
1442 /* 1. fill h2c parameters */
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;
1451 h2cParaBuf[0] = testCtrl;
1453 retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
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);
1463 pBtRsp->status = BT_STATUS_SUCCESS;
1470 IN PADAPTER Adapter,
1471 IN PBT_REQ_CMD pBtReq,
1472 IN PBT_RSP_CMD pBtRsp
1476 u1Byte h2cParaBuf[6] = {0};
1477 u1Byte h2cParaLen = 0;
1479 u1Byte retStatus = BT_STATUS_BT_OP_SUCCESS;
1481 u1Byte btOpcodeVer = 0;
1482 u1Byte testCtrl = 0;
1484 /* 1. fill h2c parameters */
1486 h2cParaBuf[0] = 0x11;
1487 h2cParaBuf[1] = 0x0;
1488 h2cParaBuf[2] = 0x0;
1489 h2cParaBuf[3] = 0x0;
1490 h2cParaBuf[4] = 0x0;
1492 /* retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen); */
1493 retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, h2cParaBuf, h2cParaLen);
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);
1503 pBtRsp->status = BT_STATUS_SUCCESS;
1508 mptbt_BtControlProcess(
1513 u1Byte H2C_Parameter[6] = {0};
1514 PBT_H2C pH2c = (PBT_H2C)&H2C_Parameter[0];
1515 PMPT_CONTEXT pMptCtx = &(Adapter->mppriv.mpt_ctx);
1516 PBT_REQ_CMD pBtReq = (PBT_REQ_CMD)pInBuf;
1521 RTW_INFO("[MPT], mptbt_BtControlProcess()=========>\n");
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); */
1530 _rtw_memset((void *)pMptCtx->mptOutBuf, 0, 100);
1531 pMptCtx->mptOutLen = 4; /* length of (BT_RSP_CMD.status+BT_RSP_CMD.paraLength) */
1533 pBtRsp = (PBT_RSP_CMD)pMptCtx->mptOutBuf;
1534 pBtRsp->status = BT_STATUS_SUCCESS;
1535 pBtRsp->paraLength = 0x0;
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);
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);
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);
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);
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);
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);
1563 case BT_UP_OP_TEST_BT:
1564 RTW_INFO("[MPT], OPcode : [TEST_BT]\n");
1565 pBtRsp->paraLength = mptbt_TestBT(Adapter, pBtReq, pBtRsp);
1568 RTW_INFO("[MPT], Error!! OPcode : UNDEFINED!!!!\n");
1569 pBtRsp->status = BT_STATUS_UNKNOWN_OPCODE_U;
1570 pBtRsp->paraLength = 0x0;
1574 pMptCtx->mptOutLen += pBtRsp->paraLength;
1576 RTW_INFO("[MPT], pMptCtx->mptOutLen=%d, pBtRsp->paraLength=%d\n", pMptCtx->mptOutLen, pBtRsp->paraLength);
1577 RTW_INFO("[MPT], mptbt_BtControlProcess()<=========\n");