rtw_bt_mp.c 50 KB

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