rtw_btcoex.c 48 KB

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