rtw_btcoex.c 49 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773
  1. /******************************************************************************
  2. *
  3. * Copyright(c) 2013 - 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 <hal_data.h>
  17. #ifdef CONFIG_BT_COEXIST
  18. #include <hal_btcoex.h>
  19. void rtw_btcoex_Initialize(PADAPTER padapter)
  20. {
  21. hal_btcoex_Initialize(padapter);
  22. }
  23. void rtw_btcoex_PowerOnSetting(PADAPTER padapter)
  24. {
  25. hal_btcoex_PowerOnSetting(padapter);
  26. }
  27. void rtw_btcoex_AntInfoSetting(PADAPTER padapter)
  28. {
  29. hal_btcoex_AntInfoSetting(padapter);
  30. }
  31. void rtw_btcoex_PowerOffSetting(PADAPTER padapter)
  32. {
  33. hal_btcoex_PowerOffSetting(padapter);
  34. }
  35. void rtw_btcoex_PreLoadFirmware(PADAPTER padapter)
  36. {
  37. hal_btcoex_PreLoadFirmware(padapter);
  38. }
  39. void rtw_btcoex_HAL_Initialize(PADAPTER padapter, u8 bWifiOnly)
  40. {
  41. hal_btcoex_InitHwConfig(padapter, bWifiOnly);
  42. }
  43. void rtw_btcoex_IpsNotify(PADAPTER padapter, u8 type)
  44. {
  45. PHAL_DATA_TYPE pHalData;
  46. pHalData = GET_HAL_DATA(padapter);
  47. if (_FALSE == pHalData->EEPROMBluetoothCoexist)
  48. return;
  49. hal_btcoex_IpsNotify(padapter, type);
  50. }
  51. void rtw_btcoex_LpsNotify(PADAPTER padapter, u8 type)
  52. {
  53. PHAL_DATA_TYPE pHalData;
  54. pHalData = GET_HAL_DATA(padapter);
  55. if (_FALSE == pHalData->EEPROMBluetoothCoexist)
  56. return;
  57. hal_btcoex_LpsNotify(padapter, type);
  58. }
  59. void rtw_btcoex_ScanNotify(PADAPTER padapter, u8 type)
  60. {
  61. PHAL_DATA_TYPE pHalData;
  62. #ifdef CONFIG_BT_COEXIST_SOCKET_TRX
  63. struct bt_coex_info *pcoex_info = &padapter->coex_info;
  64. PBT_MGNT pBtMgnt = &pcoex_info->BtMgnt;
  65. #endif /* CONFIG_BT_COEXIST_SOCKET_TRX */
  66. pHalData = GET_HAL_DATA(padapter);
  67. if (_FALSE == pHalData->EEPROMBluetoothCoexist)
  68. return;
  69. if (_FALSE == type) {
  70. #ifdef CONFIG_CONCURRENT_MODE
  71. if (rtw_mi_buddy_check_fwstate(padapter, WIFI_SITE_MONITOR))
  72. return;
  73. #endif
  74. if (DEV_MGMT_TX_NUM(adapter_to_dvobj(padapter))
  75. || DEV_ROCH_NUM(adapter_to_dvobj(padapter)))
  76. return;
  77. }
  78. #ifdef CONFIG_BT_COEXIST_SOCKET_TRX
  79. if (pBtMgnt->ExtConfig.bEnableWifiScanNotify)
  80. rtw_btcoex_SendScanNotify(padapter, type);
  81. #endif /* CONFIG_BT_COEXIST_SOCKET_TRX */
  82. hal_btcoex_ScanNotify(padapter, type);
  83. }
  84. void rtw_btcoex_ConnectNotify(PADAPTER padapter, u8 action)
  85. {
  86. PHAL_DATA_TYPE pHalData;
  87. pHalData = GET_HAL_DATA(padapter);
  88. if (_FALSE == pHalData->EEPROMBluetoothCoexist)
  89. return;
  90. #ifdef DBG_CONFIG_ERROR_RESET
  91. if (_TRUE == rtw_hal_sreset_inprogress(padapter)) {
  92. RTW_INFO(FUNC_ADPT_FMT ": [BTCoex] under reset, skip notify!\n",
  93. FUNC_ADPT_ARG(padapter));
  94. return;
  95. }
  96. #endif /* DBG_CONFIG_ERROR_RESET */
  97. #ifdef CONFIG_CONCURRENT_MODE
  98. if (_FALSE == action) {
  99. if (rtw_mi_buddy_check_fwstate(padapter, WIFI_UNDER_LINKING))
  100. return;
  101. }
  102. #endif
  103. hal_btcoex_ConnectNotify(padapter, action);
  104. }
  105. void rtw_btcoex_MediaStatusNotify(PADAPTER padapter, u8 mediaStatus)
  106. {
  107. PHAL_DATA_TYPE pHalData;
  108. pHalData = GET_HAL_DATA(padapter);
  109. if (_FALSE == pHalData->EEPROMBluetoothCoexist)
  110. return;
  111. #ifdef DBG_CONFIG_ERROR_RESET
  112. if (_TRUE == rtw_hal_sreset_inprogress(padapter)) {
  113. RTW_INFO(FUNC_ADPT_FMT ": [BTCoex] under reset, skip notify!\n",
  114. FUNC_ADPT_ARG(padapter));
  115. return;
  116. }
  117. #endif /* DBG_CONFIG_ERROR_RESET */
  118. #ifdef CONFIG_CONCURRENT_MODE
  119. if (RT_MEDIA_DISCONNECT == mediaStatus) {
  120. if (rtw_mi_buddy_check_fwstate(padapter, WIFI_ASOC_STATE))
  121. return;
  122. }
  123. #endif /* CONFIG_CONCURRENT_MODE */
  124. if ((RT_MEDIA_CONNECT == mediaStatus)
  125. && (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE))
  126. rtw_hal_set_hwreg(padapter, HW_VAR_DL_RSVD_PAGE, NULL);
  127. hal_btcoex_MediaStatusNotify(padapter, mediaStatus);
  128. }
  129. void rtw_btcoex_SpecialPacketNotify(PADAPTER padapter, u8 pktType)
  130. {
  131. PHAL_DATA_TYPE pHalData;
  132. pHalData = GET_HAL_DATA(padapter);
  133. if (_FALSE == pHalData->EEPROMBluetoothCoexist)
  134. return;
  135. hal_btcoex_SpecialPacketNotify(padapter, pktType);
  136. }
  137. void rtw_btcoex_IQKNotify(PADAPTER padapter, u8 state)
  138. {
  139. PHAL_DATA_TYPE pHalData;
  140. pHalData = GET_HAL_DATA(padapter);
  141. if (_FALSE == pHalData->EEPROMBluetoothCoexist)
  142. return;
  143. hal_btcoex_IQKNotify(padapter, state);
  144. }
  145. void rtw_btcoex_BtInfoNotify(PADAPTER padapter, u8 length, u8 *tmpBuf)
  146. {
  147. PHAL_DATA_TYPE pHalData;
  148. pHalData = GET_HAL_DATA(padapter);
  149. if (_FALSE == pHalData->EEPROMBluetoothCoexist)
  150. return;
  151. hal_btcoex_BtInfoNotify(padapter, length, tmpBuf);
  152. }
  153. void rtw_btcoex_BtMpRptNotify(PADAPTER padapter, u8 length, u8 *tmpBuf)
  154. {
  155. PHAL_DATA_TYPE pHalData;
  156. pHalData = GET_HAL_DATA(padapter);
  157. if (_FALSE == pHalData->EEPROMBluetoothCoexist)
  158. return;
  159. if (padapter->registrypriv.mp_mode == 1)
  160. return;
  161. hal_btcoex_BtMpRptNotify(padapter, length, tmpBuf);
  162. }
  163. void rtw_btcoex_SuspendNotify(PADAPTER padapter, u8 state)
  164. {
  165. PHAL_DATA_TYPE pHalData;
  166. pHalData = GET_HAL_DATA(padapter);
  167. if (_FALSE == pHalData->EEPROMBluetoothCoexist)
  168. return;
  169. hal_btcoex_SuspendNotify(padapter, state);
  170. }
  171. void rtw_btcoex_HaltNotify(PADAPTER padapter)
  172. {
  173. PHAL_DATA_TYPE pHalData;
  174. u8 do_halt = 1;
  175. pHalData = GET_HAL_DATA(padapter);
  176. if (_FALSE == pHalData->EEPROMBluetoothCoexist)
  177. do_halt = 0;
  178. if (_FALSE == padapter->bup) {
  179. RTW_INFO(FUNC_ADPT_FMT ": bup=%d Skip!\n",
  180. FUNC_ADPT_ARG(padapter), padapter->bup);
  181. do_halt = 0;
  182. }
  183. if (rtw_is_surprise_removed(padapter)) {
  184. RTW_INFO(FUNC_ADPT_FMT ": bSurpriseRemoved=%s Skip!\n",
  185. FUNC_ADPT_ARG(padapter), rtw_is_surprise_removed(padapter) ? "True" : "False");
  186. do_halt = 0;
  187. }
  188. hal_btcoex_HaltNotify(padapter, do_halt);
  189. }
  190. void rtw_btcoex_switchband_notify(u8 under_scan, u8 band_type)
  191. {
  192. hal_btcoex_switchband_notify(under_scan, band_type);
  193. }
  194. void rtw_btcoex_WlFwDbgInfoNotify(PADAPTER padapter, u8* tmpBuf, u8 length)
  195. {
  196. hal_btcoex_WlFwDbgInfoNotify(padapter, tmpBuf, length);
  197. }
  198. void rtw_btcoex_rx_rate_change_notify(PADAPTER padapter, u8 is_data_frame, u8 rate_id)
  199. {
  200. hal_btcoex_rx_rate_change_notify(padapter, is_data_frame, rate_id);
  201. }
  202. void rtw_btcoex_SwitchBtTRxMask(PADAPTER padapter)
  203. {
  204. hal_btcoex_SwitchBtTRxMask(padapter);
  205. }
  206. void rtw_btcoex_Switch(PADAPTER padapter, u8 enable)
  207. {
  208. hal_btcoex_SetBTCoexist(padapter, enable);
  209. }
  210. u8 rtw_btcoex_IsBtDisabled(PADAPTER padapter)
  211. {
  212. return hal_btcoex_IsBtDisabled(padapter);
  213. }
  214. void rtw_btcoex_Handler(PADAPTER padapter)
  215. {
  216. PHAL_DATA_TYPE pHalData;
  217. pHalData = GET_HAL_DATA(padapter);
  218. if (_FALSE == pHalData->EEPROMBluetoothCoexist)
  219. return;
  220. hal_btcoex_Hanlder(padapter);
  221. }
  222. s32 rtw_btcoex_IsBTCoexRejectAMPDU(PADAPTER padapter)
  223. {
  224. s32 coexctrl;
  225. coexctrl = hal_btcoex_IsBTCoexRejectAMPDU(padapter);
  226. return coexctrl;
  227. }
  228. s32 rtw_btcoex_IsBTCoexCtrlAMPDUSize(PADAPTER padapter)
  229. {
  230. s32 coexctrl;
  231. coexctrl = hal_btcoex_IsBTCoexCtrlAMPDUSize(padapter);
  232. return coexctrl;
  233. }
  234. u32 rtw_btcoex_GetAMPDUSize(PADAPTER padapter)
  235. {
  236. u32 size;
  237. size = hal_btcoex_GetAMPDUSize(padapter);
  238. return size;
  239. }
  240. void rtw_btcoex_SetManualControl(PADAPTER padapter, u8 manual)
  241. {
  242. if (_TRUE == manual)
  243. hal_btcoex_SetManualControl(padapter, _TRUE);
  244. else
  245. hal_btcoex_SetManualControl(padapter, _FALSE);
  246. }
  247. u8 rtw_btcoex_1Ant(PADAPTER padapter)
  248. {
  249. return hal_btcoex_1Ant(padapter);
  250. }
  251. u8 rtw_btcoex_IsBtControlLps(PADAPTER padapter)
  252. {
  253. return hal_btcoex_IsBtControlLps(padapter);
  254. }
  255. u8 rtw_btcoex_IsLpsOn(PADAPTER padapter)
  256. {
  257. return hal_btcoex_IsLpsOn(padapter);
  258. }
  259. u8 rtw_btcoex_RpwmVal(PADAPTER padapter)
  260. {
  261. return hal_btcoex_RpwmVal(padapter);
  262. }
  263. u8 rtw_btcoex_LpsVal(PADAPTER padapter)
  264. {
  265. return hal_btcoex_LpsVal(padapter);
  266. }
  267. u32 rtw_btcoex_GetRaMask(PADAPTER padapter)
  268. {
  269. return hal_btcoex_GetRaMask(padapter);
  270. }
  271. void rtw_btcoex_RecordPwrMode(PADAPTER padapter, u8 *pCmdBuf, u8 cmdLen)
  272. {
  273. hal_btcoex_RecordPwrMode(padapter, pCmdBuf, cmdLen);
  274. }
  275. void rtw_btcoex_DisplayBtCoexInfo(PADAPTER padapter, u8 *pbuf, u32 bufsize)
  276. {
  277. hal_btcoex_DisplayBtCoexInfo(padapter, pbuf, bufsize);
  278. }
  279. void rtw_btcoex_SetDBG(PADAPTER padapter, u32 *pDbgModule)
  280. {
  281. hal_btcoex_SetDBG(padapter, pDbgModule);
  282. }
  283. u32 rtw_btcoex_GetDBG(PADAPTER padapter, u8 *pStrBuf, u32 bufSize)
  284. {
  285. return hal_btcoex_GetDBG(padapter, pStrBuf, bufSize);
  286. }
  287. u8 rtw_btcoex_IncreaseScanDeviceNum(PADAPTER padapter)
  288. {
  289. return hal_btcoex_IncreaseScanDeviceNum(padapter);
  290. }
  291. u8 rtw_btcoex_IsBtLinkExist(PADAPTER padapter)
  292. {
  293. return hal_btcoex_IsBtLinkExist(padapter);
  294. }
  295. void rtw_btcoex_SetBtPatchVersion(PADAPTER padapter, u16 btHciVer, u16 btPatchVer)
  296. {
  297. hal_btcoex_SetBtPatchVersion(padapter, btHciVer, btPatchVer);
  298. }
  299. void rtw_btcoex_SetHciVersion(PADAPTER padapter, u16 hciVersion)
  300. {
  301. hal_btcoex_SetHciVersion(padapter, hciVersion);
  302. }
  303. void rtw_btcoex_StackUpdateProfileInfo(void)
  304. {
  305. hal_btcoex_StackUpdateProfileInfo();
  306. }
  307. void rtw_btcoex_pta_off_on_notify(PADAPTER padapter, u8 bBTON)
  308. {
  309. hal_btcoex_pta_off_on_notify(padapter, bBTON);
  310. }
  311. #ifdef CONFIG_RF4CE_COEXIST
  312. void rtw_btcoex_SetRf4ceLinkState(PADAPTER padapter, u8 state)
  313. {
  314. hal_btcoex_set_rf4ce_link_state(state);
  315. }
  316. u8 rtw_btcoex_GetRf4ceLinkState(PADAPTER padapter)
  317. {
  318. return hal_btcoex_get_rf4ce_link_state();
  319. }
  320. #endif
  321. /* ==================================================
  322. * Below Functions are called by BT-Coex
  323. * ================================================== */
  324. void rtw_btcoex_rx_ampdu_apply(PADAPTER padapter)
  325. {
  326. rtw_rx_ampdu_apply(padapter);
  327. }
  328. void rtw_btcoex_LPS_Enter(PADAPTER padapter)
  329. {
  330. struct pwrctrl_priv *pwrpriv;
  331. u8 lpsVal;
  332. pwrpriv = adapter_to_pwrctl(padapter);
  333. pwrpriv->bpower_saving = _TRUE;
  334. lpsVal = rtw_btcoex_LpsVal(padapter);
  335. rtw_set_ps_mode(padapter, PS_MODE_MIN, 0, lpsVal, "BTCOEX");
  336. }
  337. u8 rtw_btcoex_LPS_Leave(PADAPTER padapter)
  338. {
  339. struct pwrctrl_priv *pwrpriv;
  340. pwrpriv = adapter_to_pwrctl(padapter);
  341. if (pwrpriv->pwr_mode != PS_MODE_ACTIVE) {
  342. rtw_set_ps_mode(padapter, PS_MODE_ACTIVE, 0, 0, "BTCOEX");
  343. LPS_RF_ON_check(padapter, 100);
  344. pwrpriv->bpower_saving = _FALSE;
  345. }
  346. return _TRUE;
  347. }
  348. u16 rtw_btcoex_btreg_read(PADAPTER padapter, u8 type, u16 addr, u32 *data)
  349. {
  350. return hal_btcoex_btreg_read(padapter, type, addr, data);
  351. }
  352. u16 rtw_btcoex_btreg_write(PADAPTER padapter, u8 type, u16 addr, u16 val)
  353. {
  354. return hal_btcoex_btreg_write(padapter, type, addr, val);
  355. }
  356. u8 rtw_btcoex_get_bt_coexist(PADAPTER padapter)
  357. {
  358. HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
  359. return pHalData->EEPROMBluetoothCoexist;
  360. }
  361. u8 rtw_btcoex_get_chip_type(PADAPTER padapter)
  362. {
  363. HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
  364. return pHalData->EEPROMBluetoothType;
  365. }
  366. u8 rtw_btcoex_get_pg_ant_num(PADAPTER padapter)
  367. {
  368. HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
  369. return pHalData->EEPROMBluetoothAntNum == Ant_x2 ? 2 : 1;
  370. }
  371. u8 rtw_btcoex_get_pg_single_ant_path(PADAPTER padapter)
  372. {
  373. HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
  374. return pHalData->ant_path;
  375. }
  376. u8 rtw_btcoex_get_pg_rfe_type(PADAPTER padapter)
  377. {
  378. HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
  379. return pHalData->rfe_type;
  380. }
  381. u8 rtw_btcoex_is_tfbga_package_type(PADAPTER padapter)
  382. {
  383. HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
  384. #ifdef CONFIG_RTL8723B
  385. if ((pHalData->PackageType == PACKAGE_TFBGA79) || (pHalData->PackageType == PACKAGE_TFBGA80)
  386. || (pHalData->PackageType == PACKAGE_TFBGA90))
  387. return _TRUE;
  388. #endif
  389. return _FALSE;
  390. }
  391. u8 rtw_btcoex_get_ant_div_cfg(PADAPTER padapter)
  392. {
  393. PHAL_DATA_TYPE pHalData;
  394. pHalData = GET_HAL_DATA(padapter);
  395. return (pHalData->AntDivCfg == 0) ? _FALSE : _TRUE;
  396. }
  397. /* ==================================================
  398. * Below Functions are BT-Coex socket related function
  399. * ================================================== */
  400. #ifdef CONFIG_BT_COEXIST_SOCKET_TRX
  401. _adapter *pbtcoexadapter; /* = NULL; */ /* do not initialise globals to 0 or NULL */
  402. u8 rtw_btcoex_btinfo_cmd(_adapter *adapter, u8 *buf, u16 len)
  403. {
  404. struct cmd_obj *ph2c;
  405. struct drvextra_cmd_parm *pdrvextra_cmd_parm;
  406. u8 *btinfo;
  407. struct cmd_priv *pcmdpriv = &adapter->cmdpriv;
  408. u8 res = _SUCCESS;
  409. ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
  410. if (ph2c == NULL) {
  411. res = _FAIL;
  412. goto exit;
  413. }
  414. pdrvextra_cmd_parm = (struct drvextra_cmd_parm *)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
  415. if (pdrvextra_cmd_parm == NULL) {
  416. rtw_mfree((u8 *)ph2c, sizeof(struct cmd_obj));
  417. res = _FAIL;
  418. goto exit;
  419. }
  420. btinfo = rtw_zmalloc(len);
  421. if (btinfo == NULL) {
  422. rtw_mfree((u8 *)ph2c, sizeof(struct cmd_obj));
  423. rtw_mfree((u8 *)pdrvextra_cmd_parm, sizeof(struct drvextra_cmd_parm));
  424. res = _FAIL;
  425. goto exit;
  426. }
  427. pdrvextra_cmd_parm->ec_id = BTINFO_WK_CID;
  428. pdrvextra_cmd_parm->type = 0;
  429. pdrvextra_cmd_parm->size = len;
  430. pdrvextra_cmd_parm->pbuf = btinfo;
  431. _rtw_memcpy(btinfo, buf, len);
  432. init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
  433. res = rtw_enqueue_cmd(pcmdpriv, ph2c);
  434. exit:
  435. return res;
  436. }
  437. u8 rtw_btcoex_send_event_to_BT(_adapter *padapter, u8 status, u8 event_code, u8 opcode_low, u8 opcode_high, u8 *dbg_msg)
  438. {
  439. u8 localBuf[6] = "";
  440. u8 *pRetPar;
  441. u8 len = 0, tx_event_length = 0;
  442. rtw_HCI_event *pEvent;
  443. pEvent = (rtw_HCI_event *)(&localBuf[0]);
  444. pEvent->EventCode = event_code;
  445. pEvent->Data[0] = 0x1; /* packet # */
  446. pEvent->Data[1] = opcode_low;
  447. pEvent->Data[2] = opcode_high;
  448. len = len + 3;
  449. /* Return parameters starts from here */
  450. pRetPar = &pEvent->Data[len];
  451. pRetPar[0] = status; /* status */
  452. len++;
  453. pEvent->Length = len;
  454. /* total tx event length + EventCode length + sizeof(length) */
  455. tx_event_length = pEvent->Length + 2;
  456. #if 0
  457. rtw_btcoex_dump_tx_msg((u8 *)pEvent, tx_event_length, dbg_msg);
  458. #endif
  459. status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
  460. return status;
  461. }
  462. /*
  463. Ref:
  464. Realtek Wi-Fi Driver
  465. Host Controller Interface for
  466. Bluetooth 3.0 + HS V1.4 2013/02/07
  467. Window team code & BT team code
  468. */
  469. u8 rtw_btcoex_parse_BT_info_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)
  470. {
  471. #define BT_INFO_LENGTH 8
  472. u8 curPollEnable = pcmd[0];
  473. u8 curPollTime = pcmd[1];
  474. u8 btInfoReason = pcmd[2];
  475. u8 btInfoLen = pcmd[3];
  476. u8 btinfo[BT_INFO_LENGTH];
  477. u8 localBuf[6] = "";
  478. u8 *pRetPar;
  479. u8 len = 0, tx_event_length = 0;
  480. RTW_HCI_STATUS status = HCI_STATUS_SUCCESS;
  481. rtw_HCI_event *pEvent;
  482. /* RTW_INFO("%s\n",__func__);
  483. RTW_INFO("current Poll Enable: %d, currrent Poll Time: %d\n",curPollEnable,curPollTime);
  484. RTW_INFO("BT Info reason: %d, BT Info length: %d\n",btInfoReason,btInfoLen);
  485. RTW_INFO("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n"
  486. ,pcmd[4],pcmd[5],pcmd[6],pcmd[7],pcmd[8],pcmd[9],pcmd[10],pcmd[11]);*/
  487. _rtw_memset(btinfo, 0, BT_INFO_LENGTH);
  488. #if 1
  489. if (BT_INFO_LENGTH != btInfoLen) {
  490. status = HCI_STATUS_INVALID_HCI_CMD_PARA_VALUE;
  491. RTW_INFO("Error BT Info Length: %d\n", btInfoLen);
  492. /* return _FAIL; */
  493. } else
  494. #endif
  495. {
  496. if (0x1 == btInfoReason || 0x2 == btInfoReason) {
  497. _rtw_memcpy(btinfo, &pcmd[4], btInfoLen);
  498. btinfo[0] = btInfoReason;
  499. rtw_btcoex_btinfo_cmd(padapter, btinfo, btInfoLen);
  500. } else
  501. RTW_INFO("Other BT info reason\n");
  502. }
  503. /* send complete event to BT */
  504. {
  505. pEvent = (rtw_HCI_event *)(&localBuf[0]);
  506. pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;
  507. pEvent->Data[0] = 0x1; /* packet # */
  508. pEvent->Data[1] = HCIOPCODELOW(HCI_BT_INFO_NOTIFY, OGF_EXTENSION);
  509. pEvent->Data[2] = HCIOPCODEHIGHT(HCI_BT_INFO_NOTIFY, OGF_EXTENSION);
  510. len = len + 3;
  511. /* Return parameters starts from here */
  512. pRetPar = &pEvent->Data[len];
  513. pRetPar[0] = status; /* status */
  514. len++;
  515. pEvent->Length = len;
  516. /* total tx event length + EventCode length + sizeof(length) */
  517. tx_event_length = pEvent->Length + 2;
  518. #if 0
  519. rtw_btcoex_dump_tx_msg((u8 *)pEvent, tx_event_length, "BT_info_event");
  520. #endif
  521. status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
  522. return status;
  523. /* bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); */
  524. }
  525. }
  526. u8 rtw_btcoex_parse_BT_patch_ver_info_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)
  527. {
  528. RTW_HCI_STATUS status = HCI_STATUS_SUCCESS;
  529. u16 btPatchVer = 0x0, btHciVer = 0x0;
  530. /* u16 *pU2tmp; */
  531. u8 localBuf[6] = "";
  532. u8 *pRetPar;
  533. u8 len = 0, tx_event_length = 0;
  534. rtw_HCI_event *pEvent;
  535. btHciVer = pcmd[0] | pcmd[1] << 8;
  536. btPatchVer = pcmd[2] | pcmd[3] << 8;
  537. RTW_INFO("%s, cmd:%02x %02x %02x %02x\n", __func__, pcmd[0] , pcmd[1] , pcmd[2] , pcmd[3]);
  538. RTW_INFO("%s, HCI Ver:%d, Patch Ver:%d\n", __func__, btHciVer, btPatchVer);
  539. rtw_btcoex_SetBtPatchVersion(padapter, btHciVer, btPatchVer);
  540. /* send complete event to BT */
  541. {
  542. pEvent = (rtw_HCI_event *)(&localBuf[0]);
  543. pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;
  544. pEvent->Data[0] = 0x1; /* packet # */
  545. pEvent->Data[1] = HCIOPCODELOW(HCI_BT_PATCH_VERSION_NOTIFY, OGF_EXTENSION);
  546. pEvent->Data[2] = HCIOPCODEHIGHT(HCI_BT_PATCH_VERSION_NOTIFY, OGF_EXTENSION);
  547. len = len + 3;
  548. /* Return parameters starts from here */
  549. pRetPar = &pEvent->Data[len];
  550. pRetPar[0] = status; /* status */
  551. len++;
  552. pEvent->Length = len;
  553. /* total tx event length + EventCode length + sizeof(length) */
  554. tx_event_length = pEvent->Length + 2;
  555. #if 0
  556. rtw_btcoex_dump_tx_msg((u8 *)pEvent, tx_event_length, "BT_patch_event");
  557. #endif
  558. status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
  559. return status;
  560. /* bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); */
  561. }
  562. }
  563. u8 rtw_btcoex_parse_HCI_Ver_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)
  564. {
  565. RTW_HCI_STATUS status = HCI_STATUS_SUCCESS;
  566. u16 hciver = pcmd[0] | pcmd[1] << 8;
  567. u8 localBuf[6] = "";
  568. u8 *pRetPar;
  569. u8 len = 0, tx_event_length = 0;
  570. rtw_HCI_event *pEvent;
  571. struct bt_coex_info *pcoex_info = &padapter->coex_info;
  572. PBT_MGNT pBtMgnt = &pcoex_info->BtMgnt;
  573. pBtMgnt->ExtConfig.HCIExtensionVer = hciver;
  574. RTW_INFO("%s, HCI Version: %d\n", __func__, pBtMgnt->ExtConfig.HCIExtensionVer);
  575. if (pBtMgnt->ExtConfig.HCIExtensionVer < 4) {
  576. status = HCI_STATUS_INVALID_HCI_CMD_PARA_VALUE;
  577. RTW_INFO("%s, Version = %d, HCI Version < 4\n", __func__, pBtMgnt->ExtConfig.HCIExtensionVer);
  578. } else
  579. rtw_btcoex_SetHciVersion(padapter, hciver);
  580. /* send complete event to BT */
  581. {
  582. pEvent = (rtw_HCI_event *)(&localBuf[0]);
  583. pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;
  584. pEvent->Data[0] = 0x1; /* packet # */
  585. pEvent->Data[1] = HCIOPCODELOW(HCI_EXTENSION_VERSION_NOTIFY, OGF_EXTENSION);
  586. pEvent->Data[2] = HCIOPCODEHIGHT(HCI_EXTENSION_VERSION_NOTIFY, OGF_EXTENSION);
  587. len = len + 3;
  588. /* Return parameters starts from here */
  589. pRetPar = &pEvent->Data[len];
  590. pRetPar[0] = status; /* status */
  591. len++;
  592. pEvent->Length = len;
  593. /* total tx event length + EventCode length + sizeof(length) */
  594. tx_event_length = pEvent->Length + 2;
  595. status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
  596. return status;
  597. /* bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); */
  598. }
  599. }
  600. u8 rtw_btcoex_parse_WIFI_scan_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)
  601. {
  602. RTW_HCI_STATUS status = HCI_STATUS_SUCCESS;
  603. u8 localBuf[6] = "";
  604. u8 *pRetPar;
  605. u8 len = 0, tx_event_length = 0;
  606. rtw_HCI_event *pEvent;
  607. struct bt_coex_info *pcoex_info = &padapter->coex_info;
  608. PBT_MGNT pBtMgnt = &pcoex_info->BtMgnt;
  609. pBtMgnt->ExtConfig.bEnableWifiScanNotify = pcmd[0];
  610. RTW_INFO("%s, bEnableWifiScanNotify: %d\n", __func__, pBtMgnt->ExtConfig.bEnableWifiScanNotify);
  611. /* send complete event to BT */
  612. {
  613. pEvent = (rtw_HCI_event *)(&localBuf[0]);
  614. pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;
  615. pEvent->Data[0] = 0x1; /* packet # */
  616. pEvent->Data[1] = HCIOPCODELOW(HCI_ENABLE_WIFI_SCAN_NOTIFY, OGF_EXTENSION);
  617. pEvent->Data[2] = HCIOPCODEHIGHT(HCI_ENABLE_WIFI_SCAN_NOTIFY, OGF_EXTENSION);
  618. len = len + 3;
  619. /* Return parameters starts from here */
  620. pRetPar = &pEvent->Data[len];
  621. pRetPar[0] = status; /* status */
  622. len++;
  623. pEvent->Length = len;
  624. /* total tx event length + EventCode length + sizeof(length) */
  625. tx_event_length = pEvent->Length + 2;
  626. status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
  627. return status;
  628. /* bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); */
  629. }
  630. }
  631. u8 rtw_btcoex_parse_HCI_link_status_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)
  632. {
  633. RTW_HCI_STATUS status = HCI_STATUS_SUCCESS;
  634. struct bt_coex_info *pcoex_info = &padapter->coex_info;
  635. PBT_MGNT pBtMgnt = &pcoex_info->BtMgnt;
  636. /* PBT_DBG pBtDbg=&padapter->MgntInfo.BtInfo.BtDbg; */
  637. u8 i, numOfHandle = 0, numOfAcl = 0;
  638. u16 conHandle;
  639. u8 btProfile, btCoreSpec, linkRole;
  640. u8 *pTriple;
  641. u8 localBuf[6] = "";
  642. u8 *pRetPar;
  643. u8 len = 0, tx_event_length = 0;
  644. rtw_HCI_event *pEvent;
  645. /* pBtDbg->dbgHciInfo.hciCmdCntLinkStatusNotify++; */
  646. /* RT_DISP_DATA(FIOCTL, IOCTL_BT_HCICMD_EXT, "LinkStatusNotify, Hex Data :\n", */
  647. /* &pHciCmd->Data[0], pHciCmd->Length); */
  648. RTW_INFO("BTLinkStatusNotify\n");
  649. /* Current only RTL8723 support this command. */
  650. /* pBtMgnt->bSupportProfile = TRUE; */
  651. pBtMgnt->bSupportProfile = _FALSE;
  652. pBtMgnt->ExtConfig.NumberOfACL = 0;
  653. pBtMgnt->ExtConfig.NumberOfSCO = 0;
  654. numOfHandle = pcmd[0];
  655. /* RT_DISP(FIOCTL, IOCTL_BT_HCICMD_EXT, ("numOfHandle = 0x%x\n", numOfHandle)); */
  656. /* RT_DISP(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCIExtensionVer = %d\n", pBtMgnt->ExtConfig.HCIExtensionVer)); */
  657. RTW_INFO("numOfHandle = 0x%x\n", numOfHandle);
  658. RTW_INFO("HCIExtensionVer = %d\n", pBtMgnt->ExtConfig.HCIExtensionVer);
  659. pTriple = &pcmd[1];
  660. for (i = 0; i < numOfHandle; i++) {
  661. if (pBtMgnt->ExtConfig.HCIExtensionVer < 1) {
  662. conHandle = *((u8 *)&pTriple[0]);
  663. btProfile = pTriple[2];
  664. btCoreSpec = pTriple[3];
  665. if (BT_PROFILE_SCO == btProfile)
  666. pBtMgnt->ExtConfig.NumberOfSCO++;
  667. else {
  668. pBtMgnt->ExtConfig.NumberOfACL++;
  669. pBtMgnt->ExtConfig.aclLink[i].ConnectHandle = conHandle;
  670. pBtMgnt->ExtConfig.aclLink[i].BTProfile = btProfile;
  671. pBtMgnt->ExtConfig.aclLink[i].BTCoreSpec = btCoreSpec;
  672. }
  673. /* RT_DISP(FIOCTL, IOCTL_BT_HCICMD_EXT, */
  674. /* ("Connection_Handle=0x%x, BTProfile=%d, BTSpec=%d\n", */
  675. /* conHandle, btProfile, btCoreSpec)); */
  676. RTW_INFO("Connection_Handle=0x%x, BTProfile=%d, BTSpec=%d\n", conHandle, btProfile, btCoreSpec);
  677. pTriple += 4;
  678. } else if (pBtMgnt->ExtConfig.HCIExtensionVer >= 1) {
  679. conHandle = *((pu2Byte)&pTriple[0]);
  680. btProfile = pTriple[2];
  681. btCoreSpec = pTriple[3];
  682. linkRole = pTriple[4];
  683. if (BT_PROFILE_SCO == btProfile)
  684. pBtMgnt->ExtConfig.NumberOfSCO++;
  685. else {
  686. pBtMgnt->ExtConfig.NumberOfACL++;
  687. pBtMgnt->ExtConfig.aclLink[i].ConnectHandle = conHandle;
  688. pBtMgnt->ExtConfig.aclLink[i].BTProfile = btProfile;
  689. pBtMgnt->ExtConfig.aclLink[i].BTCoreSpec = btCoreSpec;
  690. pBtMgnt->ExtConfig.aclLink[i].linkRole = linkRole;
  691. }
  692. /* RT_DISP(FIOCTL, IOCTL_BT_HCICMD_EXT, */
  693. RTW_INFO("Connection_Handle=0x%x, BTProfile=%d, BTSpec=%d, LinkRole=%d\n",
  694. conHandle, btProfile, btCoreSpec, linkRole);
  695. pTriple += 5;
  696. }
  697. }
  698. rtw_btcoex_StackUpdateProfileInfo();
  699. /* send complete event to BT */
  700. {
  701. pEvent = (rtw_HCI_event *)(&localBuf[0]);
  702. pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;
  703. pEvent->Data[0] = 0x1; /* packet # */
  704. pEvent->Data[1] = HCIOPCODELOW(HCI_LINK_STATUS_NOTIFY, OGF_EXTENSION);
  705. pEvent->Data[2] = HCIOPCODEHIGHT(HCI_LINK_STATUS_NOTIFY, OGF_EXTENSION);
  706. len = len + 3;
  707. /* Return parameters starts from here */
  708. pRetPar = &pEvent->Data[len];
  709. pRetPar[0] = status; /* status */
  710. len++;
  711. pEvent->Length = len;
  712. /* total tx event length + EventCode length + sizeof(length) */
  713. tx_event_length = pEvent->Length + 2;
  714. status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
  715. return status;
  716. /* bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); */
  717. }
  718. }
  719. u8 rtw_btcoex_parse_HCI_BT_coex_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)
  720. {
  721. u8 localBuf[6] = "";
  722. u8 *pRetPar;
  723. u8 len = 0, tx_event_length = 0;
  724. rtw_HCI_event *pEvent;
  725. RTW_HCI_STATUS status = HCI_STATUS_SUCCESS;
  726. {
  727. pEvent = (rtw_HCI_event *)(&localBuf[0]);
  728. pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;
  729. pEvent->Data[0] = 0x1; /* packet # */
  730. pEvent->Data[1] = HCIOPCODELOW(HCI_BT_COEX_NOTIFY, OGF_EXTENSION);
  731. pEvent->Data[2] = HCIOPCODEHIGHT(HCI_BT_COEX_NOTIFY, OGF_EXTENSION);
  732. len = len + 3;
  733. /* Return parameters starts from here */
  734. pRetPar = &pEvent->Data[len];
  735. pRetPar[0] = status; /* status */
  736. len++;
  737. pEvent->Length = len;
  738. /* total tx event length + EventCode length + sizeof(length) */
  739. tx_event_length = pEvent->Length + 2;
  740. status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
  741. return status;
  742. /* bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); */
  743. }
  744. }
  745. u8 rtw_btcoex_parse_HCI_BT_operation_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)
  746. {
  747. u8 localBuf[6] = "";
  748. u8 *pRetPar;
  749. u8 len = 0, tx_event_length = 0;
  750. rtw_HCI_event *pEvent;
  751. RTW_HCI_STATUS status = HCI_STATUS_SUCCESS;
  752. RTW_INFO("%s, OP code: %d\n", __func__, pcmd[0]);
  753. switch (pcmd[0]) {
  754. case HCI_BT_OP_NONE:
  755. RTW_INFO("[bt operation] : Operation None!!\n");
  756. break;
  757. case HCI_BT_OP_INQUIRY_START:
  758. RTW_INFO("[bt operation] : Inquiry start!!\n");
  759. break;
  760. case HCI_BT_OP_INQUIRY_FINISH:
  761. RTW_INFO("[bt operation] : Inquiry finished!!\n");
  762. break;
  763. case HCI_BT_OP_PAGING_START:
  764. RTW_INFO("[bt operation] : Paging is started!!\n");
  765. break;
  766. case HCI_BT_OP_PAGING_SUCCESS:
  767. RTW_INFO("[bt operation] : Paging complete successfully!!\n");
  768. break;
  769. case HCI_BT_OP_PAGING_UNSUCCESS:
  770. RTW_INFO("[bt operation] : Paging complete unsuccessfully!!\n");
  771. break;
  772. case HCI_BT_OP_PAIRING_START:
  773. RTW_INFO("[bt operation] : Pairing start!!\n");
  774. break;
  775. case HCI_BT_OP_PAIRING_FINISH:
  776. RTW_INFO("[bt operation] : Pairing finished!!\n");
  777. break;
  778. case HCI_BT_OP_BT_DEV_ENABLE:
  779. RTW_INFO("[bt operation] : BT Device is enabled!!\n");
  780. break;
  781. case HCI_BT_OP_BT_DEV_DISABLE:
  782. RTW_INFO("[bt operation] : BT Device is disabled!!\n");
  783. break;
  784. default:
  785. RTW_INFO("[bt operation] : Unknown, error!!\n");
  786. break;
  787. }
  788. /* send complete event to BT */
  789. {
  790. pEvent = (rtw_HCI_event *)(&localBuf[0]);
  791. pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;
  792. pEvent->Data[0] = 0x1; /* packet # */
  793. pEvent->Data[1] = HCIOPCODELOW(HCI_BT_OPERATION_NOTIFY, OGF_EXTENSION);
  794. pEvent->Data[2] = HCIOPCODEHIGHT(HCI_BT_OPERATION_NOTIFY, OGF_EXTENSION);
  795. len = len + 3;
  796. /* Return parameters starts from here */
  797. pRetPar = &pEvent->Data[len];
  798. pRetPar[0] = status; /* status */
  799. len++;
  800. pEvent->Length = len;
  801. /* total tx event length + EventCode length + sizeof(length) */
  802. tx_event_length = pEvent->Length + 2;
  803. status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
  804. return status;
  805. /* bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); */
  806. }
  807. }
  808. u8 rtw_btcoex_parse_BT_AFH_MAP_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)
  809. {
  810. u8 localBuf[6] = "";
  811. u8 *pRetPar;
  812. u8 len = 0, tx_event_length = 0;
  813. rtw_HCI_event *pEvent;
  814. RTW_HCI_STATUS status = HCI_STATUS_SUCCESS;
  815. {
  816. pEvent = (rtw_HCI_event *)(&localBuf[0]);
  817. pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;
  818. pEvent->Data[0] = 0x1; /* packet # */
  819. pEvent->Data[1] = HCIOPCODELOW(HCI_BT_AFH_MAP_NOTIFY, OGF_EXTENSION);
  820. pEvent->Data[2] = HCIOPCODEHIGHT(HCI_BT_AFH_MAP_NOTIFY, OGF_EXTENSION);
  821. len = len + 3;
  822. /* Return parameters starts from here */
  823. pRetPar = &pEvent->Data[len];
  824. pRetPar[0] = status; /* status */
  825. len++;
  826. pEvent->Length = len;
  827. /* total tx event length + EventCode length + sizeof(length) */
  828. tx_event_length = pEvent->Length + 2;
  829. status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
  830. return status;
  831. /* bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); */
  832. }
  833. }
  834. u8 rtw_btcoex_parse_BT_register_val_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)
  835. {
  836. u8 localBuf[6] = "";
  837. u8 *pRetPar;
  838. u8 len = 0, tx_event_length = 0;
  839. rtw_HCI_event *pEvent;
  840. RTW_HCI_STATUS status = HCI_STATUS_SUCCESS;
  841. {
  842. pEvent = (rtw_HCI_event *)(&localBuf[0]);
  843. pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;
  844. pEvent->Data[0] = 0x1; /* packet # */
  845. pEvent->Data[1] = HCIOPCODELOW(HCI_BT_REGISTER_VALUE_NOTIFY, OGF_EXTENSION);
  846. pEvent->Data[2] = HCIOPCODEHIGHT(HCI_BT_REGISTER_VALUE_NOTIFY, OGF_EXTENSION);
  847. len = len + 3;
  848. /* Return parameters starts from here */
  849. pRetPar = &pEvent->Data[len];
  850. pRetPar[0] = status; /* status */
  851. len++;
  852. pEvent->Length = len;
  853. /* total tx event length + EventCode length + sizeof(length) */
  854. tx_event_length = pEvent->Length + 2;
  855. status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
  856. return status;
  857. /* bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); */
  858. }
  859. }
  860. u8 rtw_btcoex_parse_HCI_BT_abnormal_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)
  861. {
  862. u8 localBuf[6] = "";
  863. u8 *pRetPar;
  864. u8 len = 0, tx_event_length = 0;
  865. rtw_HCI_event *pEvent;
  866. RTW_HCI_STATUS status = HCI_STATUS_SUCCESS;
  867. {
  868. pEvent = (rtw_HCI_event *)(&localBuf[0]);
  869. pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;
  870. pEvent->Data[0] = 0x1; /* packet # */
  871. pEvent->Data[1] = HCIOPCODELOW(HCI_BT_ABNORMAL_NOTIFY, OGF_EXTENSION);
  872. pEvent->Data[2] = HCIOPCODEHIGHT(HCI_BT_ABNORMAL_NOTIFY, OGF_EXTENSION);
  873. len = len + 3;
  874. /* Return parameters starts from here */
  875. pRetPar = &pEvent->Data[len];
  876. pRetPar[0] = status; /* status */
  877. len++;
  878. pEvent->Length = len;
  879. /* total tx event length + EventCode length + sizeof(length) */
  880. tx_event_length = pEvent->Length + 2;
  881. status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
  882. return status;
  883. /* bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); */
  884. }
  885. }
  886. u8 rtw_btcoex_parse_HCI_query_RF_status_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)
  887. {
  888. u8 localBuf[6] = "";
  889. u8 *pRetPar;
  890. u8 len = 0, tx_event_length = 0;
  891. rtw_HCI_event *pEvent;
  892. RTW_HCI_STATUS status = HCI_STATUS_SUCCESS;
  893. {
  894. pEvent = (rtw_HCI_event *)(&localBuf[0]);
  895. pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;
  896. pEvent->Data[0] = 0x1; /* packet # */
  897. pEvent->Data[1] = HCIOPCODELOW(HCI_QUERY_RF_STATUS, OGF_EXTENSION);
  898. pEvent->Data[2] = HCIOPCODEHIGHT(HCI_QUERY_RF_STATUS, OGF_EXTENSION);
  899. len = len + 3;
  900. /* Return parameters starts from here */
  901. pRetPar = &pEvent->Data[len];
  902. pRetPar[0] = status; /* status */
  903. len++;
  904. pEvent->Length = len;
  905. /* total tx event length + EventCode length + sizeof(length) */
  906. tx_event_length = pEvent->Length + 2;
  907. status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
  908. return status;
  909. /* bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); */
  910. }
  911. }
  912. /*****************************************
  913. * HCI cmd format :
  914. *| 15 - 0 |
  915. *| OPcode (OCF|OGF<<10) |
  916. *| 15 - 8 |7 - 0 |
  917. *|Cmd para |Cmd para Length |
  918. *|Cmd para...... |
  919. ******************************************/
  920. /* bit 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
  921. * | OCF | OGF | */
  922. void rtw_btcoex_parse_hci_extend_cmd(_adapter *padapter, u8 *pcmd, u16 len, const u16 hci_OCF)
  923. {
  924. RTW_INFO("%s: OCF: %x\n", __func__, hci_OCF);
  925. switch (hci_OCF) {
  926. case HCI_EXTENSION_VERSION_NOTIFY:
  927. RTW_INFO("HCI_EXTENSION_VERSION_NOTIFY\n");
  928. rtw_btcoex_parse_HCI_Ver_notify_cmd(padapter, pcmd, len);
  929. break;
  930. case HCI_LINK_STATUS_NOTIFY:
  931. RTW_INFO("HCI_LINK_STATUS_NOTIFY\n");
  932. rtw_btcoex_parse_HCI_link_status_notify_cmd(padapter, pcmd, len);
  933. break;
  934. case HCI_BT_OPERATION_NOTIFY:
  935. /* only for 8723a 2ant */
  936. RTW_INFO("HCI_BT_OPERATION_NOTIFY\n");
  937. rtw_btcoex_parse_HCI_BT_operation_notify_cmd(padapter, pcmd, len);
  938. /* */
  939. break;
  940. case HCI_ENABLE_WIFI_SCAN_NOTIFY:
  941. RTW_INFO("HCI_ENABLE_WIFI_SCAN_NOTIFY\n");
  942. rtw_btcoex_parse_WIFI_scan_notify_cmd(padapter, pcmd, len);
  943. break;
  944. case HCI_QUERY_RF_STATUS:
  945. /* only for 8723b 2ant */
  946. RTW_INFO("HCI_QUERY_RF_STATUS\n");
  947. rtw_btcoex_parse_HCI_query_RF_status_cmd(padapter, pcmd, len);
  948. break;
  949. case HCI_BT_ABNORMAL_NOTIFY:
  950. RTW_INFO("HCI_BT_ABNORMAL_NOTIFY\n");
  951. rtw_btcoex_parse_HCI_BT_abnormal_notify_cmd(padapter, pcmd, len);
  952. break;
  953. case HCI_BT_INFO_NOTIFY:
  954. RTW_INFO("HCI_BT_INFO_NOTIFY\n");
  955. rtw_btcoex_parse_BT_info_notify_cmd(padapter, pcmd, len);
  956. break;
  957. case HCI_BT_COEX_NOTIFY:
  958. RTW_INFO("HCI_BT_COEX_NOTIFY\n");
  959. rtw_btcoex_parse_HCI_BT_coex_notify_cmd(padapter, pcmd, len);
  960. break;
  961. case HCI_BT_PATCH_VERSION_NOTIFY:
  962. RTW_INFO("HCI_BT_PATCH_VERSION_NOTIFY\n");
  963. rtw_btcoex_parse_BT_patch_ver_info_cmd(padapter, pcmd, len);
  964. break;
  965. case HCI_BT_AFH_MAP_NOTIFY:
  966. RTW_INFO("HCI_BT_AFH_MAP_NOTIFY\n");
  967. rtw_btcoex_parse_BT_AFH_MAP_notify_cmd(padapter, pcmd, len);
  968. break;
  969. case HCI_BT_REGISTER_VALUE_NOTIFY:
  970. RTW_INFO("HCI_BT_REGISTER_VALUE_NOTIFY\n");
  971. rtw_btcoex_parse_BT_register_val_notify_cmd(padapter, pcmd, len);
  972. break;
  973. default:
  974. RTW_INFO("ERROR!!! Unknown OCF: %x\n", hci_OCF);
  975. break;
  976. }
  977. }
  978. void rtw_btcoex_parse_hci_cmd(_adapter *padapter, u8 *pcmd, u16 len)
  979. {
  980. u16 opcode = pcmd[0] | pcmd[1] << 8;
  981. u16 hci_OGF = HCI_OGF(opcode);
  982. u16 hci_OCF = HCI_OCF(opcode);
  983. u8 cmdlen = len - 3;
  984. u8 pare_len = pcmd[2];
  985. RTW_INFO("%s OGF: %x,OCF: %x\n", __func__, hci_OGF, hci_OCF);
  986. switch (hci_OGF) {
  987. case OGF_EXTENSION:
  988. RTW_INFO("HCI_EXTENSION_CMD_OGF\n");
  989. rtw_btcoex_parse_hci_extend_cmd(padapter, &pcmd[3], cmdlen, hci_OCF);
  990. break;
  991. default:
  992. RTW_INFO("Other OGF: %x\n", hci_OGF);
  993. break;
  994. }
  995. }
  996. u16 rtw_btcoex_parse_recv_data(u8 *msg, u8 msg_size)
  997. {
  998. u8 cmp_msg1[32] = attend_ack;
  999. u8 cmp_msg2[32] = leave_ack;
  1000. u8 cmp_msg3[32] = bt_leave;
  1001. u8 cmp_msg4[32] = invite_req;
  1002. u8 cmp_msg5[32] = attend_req;
  1003. u8 cmp_msg6[32] = invite_rsp;
  1004. u8 res = OTHER;
  1005. if (_rtw_memcmp(cmp_msg1, msg, msg_size) == _TRUE) {
  1006. /*RTW_INFO("%s, msg:%s\n",__func__,msg);*/
  1007. res = RX_ATTEND_ACK;
  1008. } else if (_rtw_memcmp(cmp_msg2, msg, msg_size) == _TRUE) {
  1009. /*RTW_INFO("%s, msg:%s\n",__func__,msg);*/
  1010. res = RX_LEAVE_ACK;
  1011. } else if (_rtw_memcmp(cmp_msg3, msg, msg_size) == _TRUE) {
  1012. /*RTW_INFO("%s, msg:%s\n",__func__,msg);*/
  1013. res = RX_BT_LEAVE;
  1014. } else if (_rtw_memcmp(cmp_msg4, msg, msg_size) == _TRUE) {
  1015. /*RTW_INFO("%s, msg:%s\n",__func__,msg);*/
  1016. res = RX_INVITE_REQ;
  1017. } else if (_rtw_memcmp(cmp_msg5, msg, msg_size) == _TRUE)
  1018. res = RX_ATTEND_REQ;
  1019. else if (_rtw_memcmp(cmp_msg6, msg, msg_size) == _TRUE)
  1020. res = RX_INVITE_RSP;
  1021. else {
  1022. /*RTW_INFO("%s, %s\n", __func__, msg);*/
  1023. res = OTHER;
  1024. }
  1025. /*RTW_INFO("%s, res:%d\n", __func__, res);*/
  1026. return res;
  1027. }
  1028. void rtw_btcoex_recvmsgbysocket(void *data)
  1029. {
  1030. u8 recv_data[255];
  1031. u8 tx_msg[255] = leave_ack;
  1032. u32 len = 0;
  1033. u16 recv_length = 0;
  1034. u16 parse_res = 0;
  1035. #if 0
  1036. u8 para_len = 0, polling_enable = 0, poling_interval = 0, reason = 0, btinfo_len = 0;
  1037. u8 btinfo[BT_INFO_LEN] = {0};
  1038. #endif
  1039. struct bt_coex_info *pcoex_info = NULL;
  1040. struct sock *sk = NULL;
  1041. struct sk_buff *skb = NULL;
  1042. /*RTW_INFO("%s\n",__func__);*/
  1043. if (pbtcoexadapter == NULL) {
  1044. RTW_INFO("%s: btcoexadapter NULL!\n", __func__);
  1045. return;
  1046. }
  1047. pcoex_info = &pbtcoexadapter->coex_info;
  1048. sk = pcoex_info->sk_store;
  1049. if (sk == NULL) {
  1050. RTW_INFO("%s: critical error when receive socket data!\n", __func__);
  1051. return;
  1052. }
  1053. len = skb_queue_len(&sk->sk_receive_queue);
  1054. while (len > 0) {
  1055. skb = skb_dequeue(&sk->sk_receive_queue);
  1056. /*important: cut the udp header from skb->data! header length is 8 byte*/
  1057. recv_length = skb->len - 8;
  1058. _rtw_memset(recv_data, 0, sizeof(recv_data));
  1059. _rtw_memcpy(recv_data, skb->data + 8, recv_length);
  1060. parse_res = rtw_btcoex_parse_recv_data(recv_data, recv_length);
  1061. #if 0
  1062. if (RX_ATTEND_ACK == parse_res) {
  1063. /* attend ack */
  1064. pcoex_info->BT_attend = _TRUE;
  1065. RTW_INFO("RX_ATTEND_ACK!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);
  1066. } else if (RX_ATTEND_REQ == parse_res) {
  1067. /* attend req from BT */
  1068. pcoex_info->BT_attend = _TRUE;
  1069. RTW_INFO("RX_BT_ATTEND_REQ!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);
  1070. rtw_btcoex_sendmsgbysocket(pbtcoexadapter, attend_ack, sizeof(attend_ack), _FALSE);
  1071. } else if (RX_INVITE_REQ == parse_res) {
  1072. /* invite req from BT */
  1073. pcoex_info->BT_attend = _TRUE;
  1074. RTW_INFO("RX_INVITE_REQ!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);
  1075. rtw_btcoex_sendmsgbysocket(pbtcoexadapter, invite_rsp, sizeof(invite_rsp), _FALSE);
  1076. } else if (RX_INVITE_RSP == parse_res) {
  1077. /* invite rsp */
  1078. pcoex_info->BT_attend = _TRUE;
  1079. RTW_INFO("RX_INVITE_RSP!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);
  1080. } else if (RX_LEAVE_ACK == parse_res) {
  1081. /* mean BT know wifi will leave */
  1082. pcoex_info->BT_attend = _FALSE;
  1083. RTW_INFO("RX_LEAVE_ACK!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);
  1084. } else if (RX_BT_LEAVE == parse_res) {
  1085. /* BT leave */
  1086. rtw_btcoex_sendmsgbysocket(pbtcoexadapter, leave_ack, sizeof(leave_ack), _FALSE); /* no ack */
  1087. pcoex_info->BT_attend = _FALSE;
  1088. RTW_INFO("RX_BT_LEAVE!sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);
  1089. } else {
  1090. /* todo: check if recv data are really hci cmds */
  1091. if (_TRUE == pcoex_info->BT_attend)
  1092. rtw_btcoex_parse_hci_cmd(pbtcoexadapter, recv_data, recv_length);
  1093. }
  1094. #endif
  1095. switch (parse_res) {
  1096. case RX_ATTEND_ACK:
  1097. /* attend ack */
  1098. pcoex_info->BT_attend = _TRUE;
  1099. RTW_INFO("RX_ATTEND_ACK!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);
  1100. rtw_btcoex_pta_off_on_notify(pbtcoexadapter, pcoex_info->BT_attend);
  1101. break;
  1102. case RX_ATTEND_REQ:
  1103. pcoex_info->BT_attend = _TRUE;
  1104. RTW_INFO("RX_BT_ATTEND_REQ!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);
  1105. rtw_btcoex_sendmsgbysocket(pbtcoexadapter, attend_ack, sizeof(attend_ack), _FALSE);
  1106. rtw_btcoex_pta_off_on_notify(pbtcoexadapter, pcoex_info->BT_attend);
  1107. break;
  1108. case RX_INVITE_REQ:
  1109. /* invite req from BT */
  1110. pcoex_info->BT_attend = _TRUE;
  1111. RTW_INFO("RX_INVITE_REQ!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);
  1112. rtw_btcoex_sendmsgbysocket(pbtcoexadapter, invite_rsp, sizeof(invite_rsp), _FALSE);
  1113. rtw_btcoex_pta_off_on_notify(pbtcoexadapter, pcoex_info->BT_attend);
  1114. break;
  1115. case RX_INVITE_RSP:
  1116. /*invite rsp*/
  1117. pcoex_info->BT_attend = _TRUE;
  1118. RTW_INFO("RX_INVITE_RSP!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);
  1119. rtw_btcoex_pta_off_on_notify(pbtcoexadapter, pcoex_info->BT_attend);
  1120. break;
  1121. case RX_LEAVE_ACK:
  1122. /* mean BT know wifi will leave */
  1123. pcoex_info->BT_attend = _FALSE;
  1124. RTW_INFO("RX_LEAVE_ACK!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);
  1125. rtw_btcoex_pta_off_on_notify(pbtcoexadapter, pcoex_info->BT_attend);
  1126. break;
  1127. case RX_BT_LEAVE:
  1128. /* BT leave */
  1129. rtw_btcoex_sendmsgbysocket(pbtcoexadapter, leave_ack, sizeof(leave_ack), _FALSE); /* no ack */
  1130. pcoex_info->BT_attend = _FALSE;
  1131. RTW_INFO("RX_BT_LEAVE!sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);
  1132. rtw_btcoex_pta_off_on_notify(pbtcoexadapter, pcoex_info->BT_attend);
  1133. break;
  1134. default:
  1135. if (_TRUE == pcoex_info->BT_attend)
  1136. rtw_btcoex_parse_hci_cmd(pbtcoexadapter, recv_data, recv_length);
  1137. else
  1138. RTW_INFO("ERROR!! BT is UP\n");
  1139. break;
  1140. }
  1141. len--;
  1142. kfree_skb(skb);
  1143. }
  1144. }
  1145. #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 15, 0))
  1146. void rtw_btcoex_recvmsg_init(struct sock *sk_in, s32 bytes)
  1147. #else
  1148. void rtw_btcoex_recvmsg_init(struct sock *sk_in)
  1149. #endif
  1150. {
  1151. struct bt_coex_info *pcoex_info = NULL;
  1152. if (pbtcoexadapter == NULL) {
  1153. RTW_INFO("%s: btcoexadapter NULL\n", __func__);
  1154. return;
  1155. }
  1156. pcoex_info = &pbtcoexadapter->coex_info;
  1157. pcoex_info->sk_store = sk_in;
  1158. if (pcoex_info->btcoex_wq != NULL)
  1159. queue_delayed_work(pcoex_info->btcoex_wq, &pcoex_info->recvmsg_work, 0);
  1160. else
  1161. RTW_INFO("%s: BTCOEX workqueue NULL\n", __func__);
  1162. }
  1163. u8 rtw_btcoex_sendmsgbysocket(_adapter *padapter, u8 *msg, u8 msg_size, bool force)
  1164. {
  1165. u8 error;
  1166. struct msghdr udpmsg;
  1167. mm_segment_t oldfs;
  1168. struct iovec iov;
  1169. struct bt_coex_info *pcoex_info = &padapter->coex_info;
  1170. /* RTW_INFO("%s: msg:%s, force:%s\n", __func__, msg, force == _TRUE?"TRUE":"FALSE"); */
  1171. if (_FALSE == force) {
  1172. if (_FALSE == pcoex_info->BT_attend) {
  1173. RTW_INFO("TX Blocked: WiFi-BT disconnected\n");
  1174. return _FAIL;
  1175. }
  1176. }
  1177. iov.iov_base = (void *)msg;
  1178. iov.iov_len = msg_size;
  1179. udpmsg.msg_name = &pcoex_info->bt_sockaddr;
  1180. udpmsg.msg_namelen = sizeof(struct sockaddr_in);
  1181. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0))
  1182. /* referece:sock_xmit in kernel code
  1183. * WRITE for sock_sendmsg, READ for sock_recvmsg
  1184. * third parameter for msg_iovlen
  1185. * last parameter for iov_len
  1186. */
  1187. iov_iter_init(&udpmsg.msg_iter, WRITE, &iov, 1, msg_size);
  1188. #else
  1189. udpmsg.msg_iov = &iov;
  1190. udpmsg.msg_iovlen = 1;
  1191. #endif
  1192. udpmsg.msg_control = NULL;
  1193. udpmsg.msg_controllen = 0;
  1194. udpmsg.msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL;
  1195. #if (LINUX_VERSION_CODE <= KERNEL_VERSION(5, 10, 0))
  1196. oldfs = get_fs();
  1197. set_fs(KERNEL_DS);
  1198. #else
  1199. oldfs = (current_thread_info()->addr_limit);
  1200. current_thread_info()->addr_limit = (MAKE_MM_SEG(-1UL));
  1201. #endif
  1202. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0))
  1203. error = sock_sendmsg(pcoex_info->udpsock, &udpmsg);
  1204. #else
  1205. error = sock_sendmsg(pcoex_info->udpsock, &udpmsg, msg_size);
  1206. #endif
  1207. #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0))
  1208. set_fs(oldfs);
  1209. #else
  1210. current_thread_info()->addr_limit = (oldfs);
  1211. #endif
  1212. if (error < 0) {
  1213. RTW_INFO("Error when sendimg msg, error:%d\n", error);
  1214. return _FAIL;
  1215. } else
  1216. return _SUCCESS;
  1217. }
  1218. u8 rtw_btcoex_create_kernel_socket(_adapter *padapter)
  1219. {
  1220. s8 kernel_socket_err;
  1221. u8 tx_msg[255] = attend_req;
  1222. struct bt_coex_info *pcoex_info = &padapter->coex_info;
  1223. s32 sock_reuse = 1;
  1224. u8 status = _FAIL;
  1225. RTW_INFO("%s CONNECT_PORT %d\n", __func__, CONNECT_PORT);
  1226. if (NULL == pcoex_info) {
  1227. RTW_INFO("coex_info: NULL\n");
  1228. status = _FAIL;
  1229. }
  1230. kernel_socket_err = sock_create(PF_INET, SOCK_DGRAM, 0, &pcoex_info->udpsock);
  1231. if (kernel_socket_err < 0) {
  1232. RTW_INFO("Error during creation of socket error:%d\n", kernel_socket_err);
  1233. status = _FAIL;
  1234. } else {
  1235. _rtw_memset(&(pcoex_info->wifi_sockaddr), 0, sizeof(pcoex_info->wifi_sockaddr));
  1236. pcoex_info->wifi_sockaddr.sin_family = AF_INET;
  1237. pcoex_info->wifi_sockaddr.sin_port = htons(CONNECT_PORT);
  1238. pcoex_info->wifi_sockaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
  1239. _rtw_memset(&(pcoex_info->bt_sockaddr), 0, sizeof(pcoex_info->bt_sockaddr));
  1240. pcoex_info->bt_sockaddr.sin_family = AF_INET;
  1241. pcoex_info->bt_sockaddr.sin_port = htons(CONNECT_PORT_BT);
  1242. pcoex_info->bt_sockaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
  1243. pcoex_info->sk_store = NULL;
  1244. kernel_socket_err = pcoex_info->udpsock->ops->bind(pcoex_info->udpsock, (struct sockaddr *)&pcoex_info->wifi_sockaddr,
  1245. sizeof(pcoex_info->wifi_sockaddr));
  1246. if (kernel_socket_err == 0) {
  1247. RTW_INFO("binding socket success\n");
  1248. pcoex_info->udpsock->sk->sk_data_ready = rtw_btcoex_recvmsg_init;
  1249. pcoex_info->sock_open |= KERNEL_SOCKET_OK;
  1250. pcoex_info->BT_attend = _FALSE;
  1251. RTW_INFO("WIFI sending attend_req\n");
  1252. rtw_btcoex_sendmsgbysocket(padapter, attend_req, sizeof(attend_req), _TRUE);
  1253. status = _SUCCESS;
  1254. } else {
  1255. pcoex_info->BT_attend = _FALSE;
  1256. sock_release(pcoex_info->udpsock); /* bind fail release socket */
  1257. RTW_INFO("Error binding socket: %d\n", kernel_socket_err);
  1258. status = _FAIL;
  1259. }
  1260. }
  1261. return status;
  1262. }
  1263. void rtw_btcoex_close_kernel_socket(_adapter *padapter)
  1264. {
  1265. struct bt_coex_info *pcoex_info = &padapter->coex_info;
  1266. if (pcoex_info->sock_open & KERNEL_SOCKET_OK) {
  1267. RTW_INFO("release kernel socket\n");
  1268. sock_release(pcoex_info->udpsock);
  1269. pcoex_info->sock_open &= ~(KERNEL_SOCKET_OK);
  1270. if (_TRUE == pcoex_info->BT_attend)
  1271. pcoex_info->BT_attend = _FALSE;
  1272. RTW_INFO("sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);
  1273. }
  1274. }
  1275. void rtw_btcoex_init_socket(_adapter *padapter)
  1276. {
  1277. u8 is_invite = _FALSE;
  1278. struct bt_coex_info *pcoex_info = &padapter->coex_info;
  1279. RTW_INFO("%s\n", __func__);
  1280. if (_FALSE == pcoex_info->is_exist) {
  1281. _rtw_memset(pcoex_info, 0, sizeof(struct bt_coex_info));
  1282. pcoex_info->btcoex_wq = create_workqueue("BTCOEX");
  1283. INIT_DELAYED_WORK(&pcoex_info->recvmsg_work,
  1284. (void *)rtw_btcoex_recvmsgbysocket);
  1285. pbtcoexadapter = padapter;
  1286. /* We expect BT is off if BT don't send ack to wifi */
  1287. RTW_INFO("We expect BT is off if BT send ack to wifi\n");
  1288. rtw_btcoex_pta_off_on_notify(pbtcoexadapter, _FALSE);
  1289. if (rtw_btcoex_create_kernel_socket(padapter) == _SUCCESS)
  1290. pcoex_info->is_exist = _TRUE;
  1291. else {
  1292. pcoex_info->is_exist = _FALSE;
  1293. pbtcoexadapter = NULL;
  1294. }
  1295. RTW_INFO("%s: pbtcoexadapter:%p, coex_info->is_exist: %s\n"
  1296. , __func__, pbtcoexadapter, pcoex_info->is_exist == _TRUE ? "TRUE" : "FALSE");
  1297. }
  1298. }
  1299. void rtw_btcoex_close_socket(_adapter *padapter)
  1300. {
  1301. struct bt_coex_info *pcoex_info = &padapter->coex_info;
  1302. RTW_INFO("%s--coex_info->is_exist: %s, pcoex_info->BT_attend:%s\n"
  1303. , __func__, pcoex_info->is_exist == _TRUE ? "TRUE" : "FALSE", pcoex_info->BT_attend == _TRUE ? "TRUE" : "FALSE");
  1304. if (_TRUE == pcoex_info->is_exist) {
  1305. if (_TRUE == pcoex_info->BT_attend) {
  1306. /*inform BT wifi leave*/
  1307. rtw_btcoex_sendmsgbysocket(padapter, wifi_leave, sizeof(wifi_leave), _FALSE);
  1308. msleep(50);
  1309. }
  1310. if (pcoex_info->btcoex_wq != NULL) {
  1311. flush_workqueue(pcoex_info->btcoex_wq);
  1312. destroy_workqueue(pcoex_info->btcoex_wq);
  1313. }
  1314. rtw_btcoex_close_kernel_socket(padapter);
  1315. pbtcoexadapter = NULL;
  1316. pcoex_info->is_exist = _FALSE;
  1317. }
  1318. }
  1319. void rtw_btcoex_dump_tx_msg(u8 *tx_msg, u8 len, u8 *msg_name)
  1320. {
  1321. u8 i = 0;
  1322. RTW_INFO("======> Msg name: %s\n", msg_name);
  1323. for (i = 0; i < len; i++)
  1324. printk("%02x ", tx_msg[i]);
  1325. printk("\n");
  1326. RTW_INFO("Msg name: %s <======\n", msg_name);
  1327. }
  1328. /* Porting from Windows team */
  1329. void rtw_btcoex_SendEventExtBtCoexControl(PADAPTER padapter, u8 bNeedDbgRsp, u8 dataLen, void *pData)
  1330. {
  1331. u8 len = 0, tx_event_length = 0;
  1332. u8 localBuf[32] = "";
  1333. u8 *pRetPar;
  1334. u8 opCode = 0;
  1335. u8 *pInBuf = (pu1Byte)pData;
  1336. u8 *pOpCodeContent;
  1337. rtw_HCI_event *pEvent;
  1338. opCode = pInBuf[0];
  1339. RTW_INFO("%s, OPCode:%02x\n", __func__, opCode);
  1340. pEvent = (rtw_HCI_event *)(&localBuf[0]);
  1341. /* len += bthci_ExtensionEventHeaderRtk(&localBuf[0], */
  1342. /* HCI_EVENT_EXT_BT_COEX_CONTROL); */
  1343. pEvent->EventCode = HCI_EVENT_EXTENSION_RTK;
  1344. pEvent->Data[0] = HCI_EVENT_EXT_BT_COEX_CONTROL; /* extension event code */
  1345. len++;
  1346. /* Return parameters starts from here */
  1347. pRetPar = &pEvent->Data[len];
  1348. _rtw_memcpy(&pRetPar[0], pData, dataLen);
  1349. len += dataLen;
  1350. pEvent->Length = len;
  1351. /* total tx event length + EventCode length + sizeof(length) */
  1352. tx_event_length = pEvent->Length + 2;
  1353. #if 0
  1354. rtw_btcoex_dump_tx_msg((u8 *)pEvent, tx_event_length, "BT COEX CONTROL", _FALSE);
  1355. #endif
  1356. rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
  1357. }
  1358. /* Porting from Windows team */
  1359. void rtw_btcoex_SendEventExtBtInfoControl(PADAPTER padapter, u8 dataLen, void *pData)
  1360. {
  1361. rtw_HCI_event *pEvent;
  1362. u8 *pRetPar;
  1363. u8 len = 0, tx_event_length = 0;
  1364. u8 localBuf[32] = "";
  1365. struct bt_coex_info *pcoex_info = &padapter->coex_info;
  1366. PBT_MGNT pBtMgnt = &pcoex_info->BtMgnt;
  1367. /* RTW_INFO("%s\n",__func__);*/
  1368. if (pBtMgnt->ExtConfig.HCIExtensionVer < 4) { /* not support */
  1369. RTW_INFO("ERROR: HCIExtensionVer = %d, HCIExtensionVer<4 !!!!\n", pBtMgnt->ExtConfig.HCIExtensionVer);
  1370. return;
  1371. }
  1372. pEvent = (rtw_HCI_event *)(&localBuf[0]);
  1373. /* len += bthci_ExtensionEventHeaderRtk(&localBuf[0], */
  1374. /* HCI_EVENT_EXT_BT_INFO_CONTROL); */
  1375. pEvent->EventCode = HCI_EVENT_EXTENSION_RTK;
  1376. pEvent->Data[0] = HCI_EVENT_EXT_BT_INFO_CONTROL; /* extension event code */
  1377. len++;
  1378. /* Return parameters starts from here */
  1379. pRetPar = &pEvent->Data[len];
  1380. _rtw_memcpy(&pRetPar[0], pData, dataLen);
  1381. len += dataLen;
  1382. pEvent->Length = len;
  1383. /* total tx event length + EventCode length + sizeof(length) */
  1384. tx_event_length = pEvent->Length + 2;
  1385. #if 0
  1386. rtw_btcoex_dump_tx_msg((u8 *)pEvent, tx_event_length, "BT INFO CONTROL");
  1387. #endif
  1388. rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
  1389. }
  1390. void rtw_btcoex_SendScanNotify(PADAPTER padapter, u8 scanType)
  1391. {
  1392. u8 len = 0, tx_event_length = 0;
  1393. u8 localBuf[7] = "";
  1394. u8 *pRetPar;
  1395. u8 *pu1Temp;
  1396. rtw_HCI_event *pEvent;
  1397. struct bt_coex_info *pcoex_info = &padapter->coex_info;
  1398. PBT_MGNT pBtMgnt = &pcoex_info->BtMgnt;
  1399. /* if(!pBtMgnt->BtOperationOn)
  1400. * return; */
  1401. pEvent = (rtw_HCI_event *)(&localBuf[0]);
  1402. /* len += bthci_ExtensionEventHeaderRtk(&localBuf[0],
  1403. * HCI_EVENT_EXT_WIFI_SCAN_NOTIFY); */
  1404. pEvent->EventCode = HCI_EVENT_EXTENSION_RTK;
  1405. pEvent->Data[0] = HCI_EVENT_EXT_WIFI_SCAN_NOTIFY; /* extension event code */
  1406. len++;
  1407. /* Return parameters starts from here */
  1408. /* pRetPar = &PPacketIrpEvent->Data[len]; */
  1409. /* pu1Temp = (u8 *)&pRetPar[0]; */
  1410. /* *pu1Temp = scanType; */
  1411. pEvent->Data[len] = scanType;
  1412. len += 1;
  1413. pEvent->Length = len;
  1414. /* total tx event length + EventCode length + sizeof(length) */
  1415. tx_event_length = pEvent->Length + 2;
  1416. #if 0
  1417. rtw_btcoex_dump_tx_msg((u8 *)pEvent, tx_event_length, "WIFI SCAN OPERATION");
  1418. #endif
  1419. rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
  1420. }
  1421. #endif /* CONFIG_BT_COEXIST_SOCKET_TRX */
  1422. #endif /* CONFIG_BT_COEXIST */
  1423. void rtw_btcoex_set_ant_info(PADAPTER padapter)
  1424. {
  1425. #ifdef CONFIG_BT_COEXIST
  1426. PHAL_DATA_TYPE hal = GET_HAL_DATA(padapter);
  1427. if (hal->EEPROMBluetoothCoexist == _TRUE) {
  1428. u8 bMacPwrCtrlOn = _FALSE;
  1429. rtw_btcoex_AntInfoSetting(padapter);
  1430. rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
  1431. if (bMacPwrCtrlOn == _TRUE)
  1432. rtw_btcoex_PowerOnSetting(padapter);
  1433. }
  1434. else
  1435. #endif
  1436. rtw_btcoex_wifionly_AntInfoSetting(padapter);
  1437. }