rtw_mi.c 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309
  1. /******************************************************************************
  2. *
  3. * Copyright(c) 2007 - 2015 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. #define _RTW_MI_C_
  21. #include <drv_types.h>
  22. #include <hal_data.h>
  23. void rtw_mi_update_union_chan_inf(_adapter *adapter, u8 ch, u8 offset , u8 bw)
  24. {
  25. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  26. struct mi_state *iface_state = &dvobj->iface_state;
  27. iface_state->union_ch = ch;
  28. iface_state->union_bw = bw;
  29. iface_state->union_offset = offset;
  30. }
  31. /* Find union about ch, bw, ch_offset of all linked/linking interfaces */
  32. int _rtw_mi_get_ch_setting_union(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset, bool include_self)
  33. {
  34. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  35. _adapter *iface;
  36. struct mlme_ext_priv *mlmeext;
  37. int i;
  38. u8 ch_ret = 0;
  39. u8 bw_ret = CHANNEL_WIDTH_20;
  40. u8 offset_ret = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
  41. int num = 0;
  42. if (ch)
  43. *ch = 0;
  44. if (bw)
  45. *bw = CHANNEL_WIDTH_20;
  46. if (offset)
  47. *offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
  48. for (i = 0; i < dvobj->iface_nums; i++) {
  49. iface = dvobj->padapters[i];
  50. mlmeext = &iface->mlmeextpriv;
  51. if (!check_fwstate(&iface->mlmepriv, _FW_LINKED | _FW_UNDER_LINKING))
  52. continue;
  53. if (check_fwstate(&iface->mlmepriv, WIFI_OP_CH_SWITCHING))
  54. continue;
  55. if (include_self == _FALSE && adapter == iface)
  56. continue;
  57. if (num == 0) {
  58. ch_ret = mlmeext->cur_channel;
  59. bw_ret = mlmeext->cur_bwmode;
  60. offset_ret = mlmeext->cur_ch_offset;
  61. num++;
  62. continue;
  63. }
  64. if (ch_ret != mlmeext->cur_channel) {
  65. num = 0;
  66. break;
  67. }
  68. if (bw_ret < mlmeext->cur_bwmode) {
  69. bw_ret = mlmeext->cur_bwmode;
  70. offset_ret = mlmeext->cur_ch_offset;
  71. } else if (bw_ret == mlmeext->cur_bwmode && offset_ret != mlmeext->cur_ch_offset) {
  72. num = 0;
  73. break;
  74. }
  75. num++;
  76. }
  77. if (num) {
  78. if (ch)
  79. *ch = ch_ret;
  80. if (bw)
  81. *bw = bw_ret;
  82. if (offset)
  83. *offset = offset_ret;
  84. }
  85. return num;
  86. }
  87. inline int rtw_mi_get_ch_setting_union(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset)
  88. {
  89. return _rtw_mi_get_ch_setting_union(adapter, ch, bw, offset, 1);
  90. }
  91. inline int rtw_mi_get_ch_setting_union_no_self(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset)
  92. {
  93. return _rtw_mi_get_ch_setting_union(adapter, ch, bw, offset, 0);
  94. }
  95. /* For now, not return union_ch/bw/offset */
  96. void _rtw_mi_status(_adapter *adapter, struct mi_state *mstate, bool include_self)
  97. {
  98. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  99. _adapter *iface;
  100. int i;
  101. _rtw_memset(mstate, 0, sizeof(struct mi_state));
  102. for (i = 0; i < dvobj->iface_nums; i++) {
  103. iface = dvobj->padapters[i];
  104. if (include_self == _FALSE && iface == adapter)
  105. continue;
  106. if (check_fwstate(&iface->mlmepriv, WIFI_STATION_STATE) == _TRUE) {
  107. MSTATE_STA_NUM(mstate)++;
  108. if (check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE)
  109. MSTATE_STA_LD_NUM(mstate)++;
  110. if (check_fwstate(&iface->mlmepriv, _FW_UNDER_LINKING) == _TRUE)
  111. MSTATE_STA_LG_NUM(mstate)++;
  112. } else if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE
  113. && check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE
  114. ) {
  115. MSTATE_AP_NUM(mstate)++;
  116. if (iface->stapriv.asoc_sta_count > 2)
  117. MSTATE_AP_LD_NUM(mstate)++;
  118. } else if (check_fwstate(&iface->mlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE) == _TRUE
  119. && check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE
  120. ) {
  121. MSTATE_ADHOC_NUM(mstate)++;
  122. if (iface->stapriv.asoc_sta_count > 2)
  123. MSTATE_ADHOC_LD_NUM(mstate)++;
  124. }
  125. if (check_fwstate(&iface->mlmepriv, WIFI_UNDER_WPS) == _TRUE)
  126. MSTATE_WPS_NUM(mstate)++;
  127. #ifdef CONFIG_IOCTL_CFG80211
  128. if (rtw_cfg80211_get_is_mgmt_tx(iface))
  129. MSTATE_MGMT_TX_NUM(mstate)++;
  130. #ifdef CONFIG_P2P
  131. if (rtw_cfg80211_get_is_roch(iface) == _TRUE)
  132. MSTATE_ROCH_NUM(mstate)++;
  133. #endif
  134. #endif /* CONFIG_IOCTL_CFG80211 */
  135. }
  136. }
  137. inline void rtw_mi_status(_adapter *adapter, struct mi_state *mstate)
  138. {
  139. return _rtw_mi_status(adapter, mstate, 1);
  140. }
  141. inline void rtw_mi_status_no_self(_adapter *adapter, struct mi_state *mstate)
  142. {
  143. return _rtw_mi_status(adapter, mstate, 0);
  144. }
  145. void dump_mi_status(void *sel, struct dvobj_priv *dvobj)
  146. {
  147. RTW_PRINT_SEL(sel, "== dvobj-iface_state ==\n");
  148. RTW_PRINT_SEL(sel, "sta_num:%d\n", DEV_STA_NUM(dvobj));
  149. RTW_PRINT_SEL(sel, "linking_sta_num:%d\n", DEV_STA_LG_NUM(dvobj));
  150. RTW_PRINT_SEL(sel, "linked_sta_num:%d\n", DEV_STA_LD_NUM(dvobj));
  151. RTW_PRINT_SEL(sel, "ap_num:%d\n", DEV_AP_NUM(dvobj));
  152. RTW_PRINT_SEL(sel, "linked_ap_num:%d\n", DEV_AP_LD_NUM(dvobj));
  153. RTW_PRINT_SEL(sel, "adhoc_num:%d\n", DEV_ADHOC_NUM(dvobj));
  154. RTW_PRINT_SEL(sel, "linked_adhoc_num:%d\n", DEV_ADHOC_LD_NUM(dvobj));
  155. #ifdef CONFIG_P2P
  156. RTW_PRINT_SEL(sel, "p2p_device_num:%d\n", rtw_mi_stay_in_p2p_mode(dvobj->padapters[IFACE_ID0]));
  157. #endif
  158. #if defined(CONFIG_IOCTL_CFG80211)
  159. #if defined(CONFIG_P2P)
  160. RTW_PRINT_SEL(sel, "roch_num:%d\n", DEV_ROCH_NUM(dvobj));
  161. #endif
  162. RTW_PRINT_SEL(sel, "mgmt_tx_num:%d\n", DEV_MGMT_TX_NUM(dvobj));
  163. #endif
  164. RTW_PRINT_SEL(sel, "under_wps_num:%d\n", DEV_WPS_NUM(dvobj));
  165. RTW_PRINT_SEL(sel, "union_ch:%d\n", DEV_U_CH(dvobj));
  166. RTW_PRINT_SEL(sel, "union_bw:%d\n", DEV_U_BW(dvobj));
  167. RTW_PRINT_SEL(sel, "union_offset:%d\n", DEV_U_OFFSET(dvobj));
  168. RTW_PRINT_SEL(sel, "================\n\n");
  169. }
  170. void dump_dvobj_mi_status(void *sel, const char *fun_name, _adapter *adapter)
  171. {
  172. RTW_INFO("\n[ %s ] call %s\n", fun_name, __func__);
  173. dump_mi_status(sel, adapter_to_dvobj(adapter));
  174. }
  175. inline void rtw_mi_update_iface_status(struct mlme_priv *pmlmepriv, sint state)
  176. {
  177. _adapter *adapter = container_of(pmlmepriv, _adapter, mlmepriv);
  178. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  179. struct mi_state *iface_state = &dvobj->iface_state;
  180. struct mi_state tmp_mstate;
  181. u8 i;
  182. u8 u_ch, u_offset, u_bw;
  183. _adapter *iface;
  184. if (state == WIFI_MONITOR_STATE
  185. || state == WIFI_SITE_MONITOR
  186. || state == 0xFFFFFFFF
  187. )
  188. return;
  189. if (0)
  190. RTW_INFO("%s => will change or clean state to 0x%08x\n", __func__, state);
  191. rtw_mi_status(adapter, &tmp_mstate);
  192. _rtw_memcpy(iface_state, &tmp_mstate, sizeof(struct mi_state));
  193. if (rtw_mi_get_ch_setting_union(adapter, &u_ch, &u_bw, &u_offset))
  194. rtw_mi_update_union_chan_inf(adapter , u_ch, u_offset , u_bw);
  195. else {
  196. if (0) {
  197. dump_adapters_status(RTW_DBGDUMP , dvobj);
  198. RTW_INFO("%s-[ERROR] cannot get union channel\n", __func__);
  199. rtw_warn_on(1);
  200. }
  201. }
  202. #ifdef DBG_IFACE_STATUS
  203. DBG_IFACE_STATUS_DUMP(adapter);
  204. #endif
  205. }
  206. u8 rtw_mi_check_status(_adapter *adapter, u8 type)
  207. {
  208. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  209. struct mi_state *iface_state = &dvobj->iface_state;
  210. u8 ret = _FALSE;
  211. #ifdef DBG_IFACE_STATUS
  212. DBG_IFACE_STATUS_DUMP(adapter);
  213. RTW_INFO("%s-"ADPT_FMT" check type:%d\n", __func__, ADPT_ARG(adapter), type);
  214. #endif
  215. switch (type) {
  216. case MI_LINKED:
  217. if (MSTATE_STA_LD_NUM(iface_state) || MSTATE_AP_NUM(iface_state) || MSTATE_ADHOC_NUM(iface_state)) /*check_fwstate(&iface->mlmepriv, _FW_LINKED)*/
  218. ret = _TRUE;
  219. break;
  220. case MI_ASSOC:
  221. if (MSTATE_STA_LD_NUM(iface_state) || MSTATE_AP_LD_NUM(iface_state) || MSTATE_ADHOC_LD_NUM(iface_state))
  222. ret = _TRUE;
  223. break;
  224. case MI_UNDER_WPS:
  225. if (MSTATE_WPS_NUM(iface_state))
  226. ret = _TRUE;
  227. break;
  228. case MI_AP_MODE:
  229. if (MSTATE_AP_NUM(iface_state))
  230. ret = _TRUE;
  231. break;
  232. case MI_AP_ASSOC:
  233. if (MSTATE_AP_LD_NUM(iface_state))
  234. ret = _TRUE;
  235. break;
  236. case MI_ADHOC:
  237. if (MSTATE_ADHOC_NUM(iface_state))
  238. ret = _TRUE;
  239. break;
  240. case MI_ADHOC_ASSOC:
  241. if (MSTATE_ADHOC_LD_NUM(iface_state))
  242. ret = _TRUE;
  243. break;
  244. case MI_STA_NOLINK: /* this is misleading, but not used now */
  245. if (MSTATE_STA_NUM(iface_state) && (!(MSTATE_STA_LD_NUM(iface_state) || MSTATE_STA_LG_NUM(iface_state))))
  246. ret = _TRUE;
  247. break;
  248. case MI_STA_LINKED:
  249. if (MSTATE_STA_LD_NUM(iface_state))
  250. ret = _TRUE;
  251. break;
  252. case MI_STA_LINKING:
  253. if (MSTATE_STA_LG_NUM(iface_state))
  254. ret = _TRUE;
  255. break;
  256. default:
  257. break;
  258. }
  259. return ret;
  260. }
  261. u8 rtw_mi_mp_mode_check(_adapter *padapter)
  262. {
  263. #ifdef CONFIG_MP_INCLUDED
  264. #ifdef CONFIG_CONCURRENT_MODE
  265. int i;
  266. struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
  267. _adapter *iface = NULL;
  268. for (i = 0; i < dvobj->iface_nums; i++) {
  269. iface = dvobj->padapters[i];
  270. if ((iface) && (iface->registrypriv.mp_mode == 1))
  271. return _TRUE;
  272. }
  273. #else
  274. if (padapter->registrypriv.mp_mode == 1)
  275. return _TRUE;
  276. #endif
  277. #endif /* CONFIG_MP_INCLUDED */
  278. return _FALSE;
  279. }
  280. /*
  281. * return value : 0 is failed or have not interface meet condition
  282. * return value : !0 is success or interface numbers which meet condition
  283. * return value of ops_func must be _TRUE or _FALSE
  284. */
  285. static u8 _rtw_mi_process(_adapter *padapter, bool exclude_self,
  286. void *data, u8(*ops_func)(_adapter *padapter, void *data))
  287. {
  288. int i;
  289. _adapter *iface;
  290. struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
  291. u8 ret = 0;
  292. for (i = 0; i < dvobj->iface_nums; i++) {
  293. iface = dvobj->padapters[i];
  294. if ((iface) && rtw_is_adapter_up(iface)) {
  295. if ((exclude_self) && (iface == padapter))
  296. continue;
  297. if (ops_func)
  298. if (_TRUE == ops_func(iface, data))
  299. ret++;
  300. }
  301. }
  302. return ret;
  303. }
  304. static u8 _rtw_mi_process_without_schk(_adapter *padapter, bool exclude_self,
  305. void *data, u8(*ops_func)(_adapter *padapter, void *data))
  306. {
  307. int i;
  308. _adapter *iface;
  309. struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
  310. u8 ret = 0;
  311. for (i = 0; i < dvobj->iface_nums; i++) {
  312. iface = dvobj->padapters[i];
  313. if (iface) {
  314. if ((exclude_self) && (iface == padapter))
  315. continue;
  316. if (ops_func)
  317. if (ops_func(iface, data) == _TRUE)
  318. ret++;
  319. }
  320. }
  321. return ret;
  322. }
  323. static u8 _rtw_mi_netif_stop_queue(_adapter *padapter, void *data)
  324. {
  325. bool carrier_off = *(bool *)data;
  326. struct net_device *pnetdev = padapter->pnetdev;
  327. if (carrier_off)
  328. netif_carrier_off(pnetdev);
  329. rtw_netif_stop_queue(pnetdev);
  330. return _TRUE;
  331. }
  332. u8 rtw_mi_netif_stop_queue(_adapter *padapter, bool carrier_off)
  333. {
  334. bool in_data = carrier_off;
  335. return _rtw_mi_process(padapter, _FALSE, &in_data, _rtw_mi_netif_stop_queue);
  336. }
  337. u8 rtw_mi_buddy_netif_stop_queue(_adapter *padapter, bool carrier_off)
  338. {
  339. bool in_data = carrier_off;
  340. return _rtw_mi_process(padapter, _TRUE, &in_data, _rtw_mi_netif_stop_queue);
  341. }
  342. static u8 _rtw_mi_netif_wake_queue(_adapter *padapter, void *data)
  343. {
  344. struct net_device *pnetdev = padapter->pnetdev;
  345. if (pnetdev)
  346. rtw_netif_wake_queue(pnetdev);
  347. return _TRUE;
  348. }
  349. u8 rtw_mi_netif_wake_queue(_adapter *padapter)
  350. {
  351. return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_netif_wake_queue);
  352. }
  353. u8 rtw_mi_buddy_netif_wake_queue(_adapter *padapter)
  354. {
  355. return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_netif_wake_queue);
  356. }
  357. static u8 _rtw_mi_netif_carrier_on(_adapter *padapter, void *data)
  358. {
  359. struct net_device *pnetdev = padapter->pnetdev;
  360. if (pnetdev)
  361. rtw_netif_carrier_on(pnetdev);
  362. return _TRUE;
  363. }
  364. u8 rtw_mi_netif_carrier_on(_adapter *padapter)
  365. {
  366. return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_netif_carrier_on);
  367. }
  368. u8 rtw_mi_buddy_netif_carrier_on(_adapter *padapter)
  369. {
  370. return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_netif_carrier_on);
  371. }
  372. static u8 _rtw_mi_scan_abort(_adapter *adapter, void *data)
  373. {
  374. bool bwait = *(bool *)data;
  375. if (bwait)
  376. rtw_scan_abort(adapter);
  377. else
  378. rtw_scan_abort_no_wait(adapter);
  379. return _TRUE;
  380. }
  381. void rtw_mi_scan_abort(_adapter *adapter, bool bwait)
  382. {
  383. bool in_data = bwait;
  384. _rtw_mi_process(adapter, _FALSE, &in_data, _rtw_mi_scan_abort);
  385. }
  386. void rtw_mi_buddy_scan_abort(_adapter *adapter, bool bwait)
  387. {
  388. bool in_data = bwait;
  389. _rtw_mi_process(adapter, _TRUE, &in_data, _rtw_mi_scan_abort);
  390. }
  391. static u8 _rtw_mi_start_drv_threads(_adapter *adapter, void *data)
  392. {
  393. rtw_start_drv_threads(adapter);
  394. return _TRUE;
  395. }
  396. void rtw_mi_start_drv_threads(_adapter *adapter)
  397. {
  398. _rtw_mi_process(adapter, _FALSE, NULL, _rtw_mi_start_drv_threads);
  399. }
  400. void rtw_mi_buddy_start_drv_threads(_adapter *adapter)
  401. {
  402. _rtw_mi_process(adapter, _TRUE, NULL, _rtw_mi_start_drv_threads);
  403. }
  404. static u8 _rtw_mi_stop_drv_threads(_adapter *adapter, void *data)
  405. {
  406. rtw_stop_drv_threads(adapter);
  407. return _TRUE;
  408. }
  409. void rtw_mi_stop_drv_threads(_adapter *adapter)
  410. {
  411. _rtw_mi_process(adapter, _FALSE, NULL, _rtw_mi_stop_drv_threads);
  412. }
  413. void rtw_mi_buddy_stop_drv_threads(_adapter *adapter)
  414. {
  415. _rtw_mi_process(adapter, _TRUE, NULL, _rtw_mi_stop_drv_threads);
  416. }
  417. static u8 _rtw_mi_cancel_all_timer(_adapter *adapter, void *data)
  418. {
  419. rtw_cancel_all_timer(adapter);
  420. return _TRUE;
  421. }
  422. void rtw_mi_cancel_all_timer(_adapter *adapter)
  423. {
  424. _rtw_mi_process(adapter, _FALSE, NULL, _rtw_mi_cancel_all_timer);
  425. }
  426. void rtw_mi_buddy_cancel_all_timer(_adapter *adapter)
  427. {
  428. _rtw_mi_process(adapter, _TRUE, NULL, _rtw_mi_cancel_all_timer);
  429. }
  430. static u8 _rtw_mi_reset_drv_sw(_adapter *adapter, void *data)
  431. {
  432. rtw_reset_drv_sw(adapter);
  433. return _TRUE;
  434. }
  435. void rtw_mi_reset_drv_sw(_adapter *adapter)
  436. {
  437. _rtw_mi_process_without_schk(adapter, _FALSE, NULL, _rtw_mi_reset_drv_sw);
  438. }
  439. void rtw_mi_buddy_reset_drv_sw(_adapter *adapter)
  440. {
  441. _rtw_mi_process_without_schk(adapter, _TRUE, NULL, _rtw_mi_reset_drv_sw);
  442. }
  443. static u8 _rtw_mi_intf_start(_adapter *adapter, void *data)
  444. {
  445. rtw_intf_start(adapter);
  446. return _TRUE;
  447. }
  448. void rtw_mi_intf_start(_adapter *adapter)
  449. {
  450. _rtw_mi_process(adapter, _FALSE, NULL, _rtw_mi_intf_start);
  451. }
  452. void rtw_mi_buddy_intf_start(_adapter *adapter)
  453. {
  454. _rtw_mi_process(adapter, _TRUE, NULL, _rtw_mi_intf_start);
  455. }
  456. static u8 _rtw_mi_intf_stop(_adapter *adapter, void *data)
  457. {
  458. rtw_intf_stop(adapter);
  459. return _TRUE;
  460. }
  461. void rtw_mi_intf_stop(_adapter *adapter)
  462. {
  463. _rtw_mi_process(adapter, _FALSE, NULL, _rtw_mi_intf_stop);
  464. }
  465. void rtw_mi_buddy_intf_stop(_adapter *adapter)
  466. {
  467. _rtw_mi_process(adapter, _TRUE, NULL, _rtw_mi_intf_stop);
  468. }
  469. static u8 _rtw_mi_suspend_free_assoc_resource(_adapter *padapter, void *data)
  470. {
  471. return rtw_suspend_free_assoc_resource(padapter);
  472. }
  473. void rtw_mi_suspend_free_assoc_resource(_adapter *adapter)
  474. {
  475. _rtw_mi_process(adapter, _FALSE, NULL, _rtw_mi_suspend_free_assoc_resource);
  476. }
  477. void rtw_mi_buddy_suspend_free_assoc_resource(_adapter *adapter)
  478. {
  479. _rtw_mi_process(adapter, _TRUE, NULL, _rtw_mi_suspend_free_assoc_resource);
  480. }
  481. static u8 _rtw_mi_is_scan_deny(_adapter *adapter, void *data)
  482. {
  483. return rtw_is_scan_deny(adapter);
  484. }
  485. u8 rtw_mi_is_scan_deny(_adapter *adapter)
  486. {
  487. return _rtw_mi_process(adapter, _FALSE, NULL, _rtw_mi_is_scan_deny);
  488. }
  489. u8 rtw_mi_buddy_is_scan_deny(_adapter *adapter)
  490. {
  491. return _rtw_mi_process(adapter, _TRUE, NULL, _rtw_mi_is_scan_deny);
  492. }
  493. #ifdef CONFIG_SET_SCAN_DENY_TIMER
  494. static u8 _rtw_mi_set_scan_deny(_adapter *adapter, void *data)
  495. {
  496. u32 ms = *(u32 *)data;
  497. rtw_set_scan_deny(adapter, ms);
  498. return _TRUE;
  499. }
  500. void rtw_mi_set_scan_deny(_adapter *adapter, u32 ms)
  501. {
  502. u32 in_data = ms;
  503. _rtw_mi_process(adapter, _FALSE, &in_data, _rtw_mi_set_scan_deny);
  504. }
  505. void rtw_mi_buddy_set_scan_deny(_adapter *adapter, u32 ms)
  506. {
  507. u32 in_data = ms;
  508. _rtw_mi_process(adapter, _TRUE, &in_data, _rtw_mi_set_scan_deny);
  509. }
  510. #endif
  511. struct nulldata_param {
  512. unsigned char *da;
  513. unsigned int power_mode;
  514. int try_cnt;
  515. int wait_ms;
  516. };
  517. static u8 _rtw_mi_issue_nulldata(_adapter *padapter, void *data)
  518. {
  519. struct nulldata_param *pnulldata_param = (struct nulldata_param *)data;
  520. if (is_client_associated_to_ap(padapter) == _TRUE) {
  521. /* TODO: TDLS peers */
  522. issue_nulldata(padapter, pnulldata_param->da, pnulldata_param->power_mode, pnulldata_param->try_cnt, pnulldata_param->wait_ms);
  523. return _TRUE;
  524. }
  525. return _FALSE;
  526. }
  527. u8 rtw_mi_issue_nulldata(_adapter *padapter, unsigned char *da, unsigned int power_mode, int try_cnt, int wait_ms)
  528. {
  529. struct nulldata_param nparam;
  530. nparam.da = da;
  531. nparam.power_mode = power_mode;/*0 or 1*/
  532. nparam.try_cnt = try_cnt;
  533. nparam.wait_ms = wait_ms;
  534. return _rtw_mi_process(padapter, _FALSE, &nparam, _rtw_mi_issue_nulldata);
  535. }
  536. u8 rtw_mi_buddy_issue_nulldata(_adapter *padapter, unsigned char *da, unsigned int power_mode, int try_cnt, int wait_ms)
  537. {
  538. struct nulldata_param nparam;
  539. nparam.da = da;
  540. nparam.power_mode = power_mode;
  541. nparam.try_cnt = try_cnt;
  542. nparam.wait_ms = wait_ms;
  543. return _rtw_mi_process(padapter, _TRUE, &nparam, _rtw_mi_issue_nulldata);
  544. }
  545. static u8 _rtw_mi_beacon_update(_adapter *padapter, void *data)
  546. {
  547. struct mlme_ext_priv *mlmeext = &padapter->mlmeextpriv;
  548. if (mlmeext_msr(mlmeext) == WIFI_FW_AP_STATE
  549. && check_fwstate(&padapter->mlmepriv, _FW_LINKED) == _TRUE) {
  550. RTW_INFO(ADPT_FMT"-WIFI_FW_AP_STATE - update_beacon\n", ADPT_ARG(padapter));
  551. update_beacon(padapter, 0, NULL, _TRUE);
  552. }
  553. return _TRUE;
  554. }
  555. void rtw_mi_beacon_update(_adapter *padapter)
  556. {
  557. _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_beacon_update);
  558. }
  559. void rtw_mi_buddy_beacon_update(_adapter *padapter)
  560. {
  561. _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_beacon_update);
  562. }
  563. static u8 _rtw_mi_hal_dump_macaddr(_adapter *padapter, void *data)
  564. {
  565. u8 mac_addr[ETH_ALEN] = {0};
  566. rtw_hal_get_macaddr_port(padapter, mac_addr);
  567. RTW_INFO(ADPT_FMT"MAC Address ="MAC_FMT"\n", ADPT_ARG(padapter), MAC_ARG(mac_addr));
  568. return _TRUE;
  569. }
  570. void rtw_mi_hal_dump_macaddr(_adapter *padapter)
  571. {
  572. _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_hal_dump_macaddr);
  573. }
  574. void rtw_mi_buddy_hal_dump_macaddr(_adapter *padapter)
  575. {
  576. _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_hal_dump_macaddr);
  577. }
  578. #ifdef CONFIG_PCI_HCI
  579. static u8 _rtw_mi_xmit_tasklet_schedule(_adapter *padapter, void *data)
  580. {
  581. if (rtw_txframes_pending(padapter)) {
  582. /* try to deal with the pending packets */
  583. tasklet_hi_schedule(&(padapter->xmitpriv.xmit_tasklet));
  584. }
  585. return _TRUE;
  586. }
  587. void rtw_mi_xmit_tasklet_schedule(_adapter *padapter)
  588. {
  589. _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_xmit_tasklet_schedule);
  590. }
  591. void rtw_mi_buddy_xmit_tasklet_schedule(_adapter *padapter)
  592. {
  593. _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_xmit_tasklet_schedule);
  594. }
  595. #endif
  596. u8 _rtw_mi_busy_traffic_check(_adapter *padapter, void *data)
  597. {
  598. u32 passtime;
  599. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  600. bool check_sc_interval = *(bool *)data;
  601. if (pmlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE) {
  602. if (check_sc_interval) {
  603. /* Miracast can't do AP scan*/
  604. passtime = rtw_get_passing_time_ms(pmlmepriv->lastscantime);
  605. pmlmepriv->lastscantime = rtw_get_current_time();
  606. if (passtime > BUSY_TRAFFIC_SCAN_DENY_PERIOD) {
  607. RTW_INFO(ADPT_FMT" bBusyTraffic == _TRUE\n", ADPT_ARG(padapter));
  608. return _TRUE;
  609. }
  610. } else
  611. return _TRUE;
  612. }
  613. return _FALSE;
  614. }
  615. u8 rtw_mi_busy_traffic_check(_adapter *padapter, bool check_sc_interval)
  616. {
  617. bool in_data = check_sc_interval;
  618. return _rtw_mi_process(padapter, _FALSE, &in_data, _rtw_mi_busy_traffic_check);
  619. }
  620. u8 rtw_mi_buddy_busy_traffic_check(_adapter *padapter, bool check_sc_interval)
  621. {
  622. bool in_data = check_sc_interval;
  623. return _rtw_mi_process(padapter, _TRUE, &in_data, _rtw_mi_busy_traffic_check);
  624. }
  625. static u8 _rtw_mi_check_mlmeinfo_state(_adapter *padapter, void *data)
  626. {
  627. u32 state = *(u32 *)data;
  628. struct mlme_ext_priv *mlmeext = &padapter->mlmeextpriv;
  629. /*if (mlmeext_msr(mlmeext) == state)*/
  630. if (check_mlmeinfo_state(mlmeext, state))
  631. return _TRUE;
  632. else
  633. return _FALSE;
  634. }
  635. u8 rtw_mi_check_mlmeinfo_state(_adapter *padapter, u32 state)
  636. {
  637. u32 in_data = state;
  638. return _rtw_mi_process(padapter, _FALSE, &in_data, _rtw_mi_check_mlmeinfo_state);
  639. }
  640. u8 rtw_mi_buddy_check_mlmeinfo_state(_adapter *padapter, u32 state)
  641. {
  642. u32 in_data = state;
  643. return _rtw_mi_process(padapter, _TRUE, &in_data, _rtw_mi_check_mlmeinfo_state);
  644. }
  645. /*#define DBG_DUMP_FW_STATE*/
  646. #ifdef DBG_DUMP_FW_STATE
  647. static void rtw_dbg_dump_fwstate(_adapter *padapter, sint state)
  648. {
  649. u8 buf[32] = {0};
  650. if (state & WIFI_FW_NULL_STATE) {
  651. _rtw_memset(buf, 0, 32);
  652. sprintf(buf, "WIFI_FW_NULL_STATE");
  653. RTW_INFO(FUNC_ADPT_FMT"fwstate-%s\n", FUNC_ADPT_ARG(padapter), buf);
  654. }
  655. if (state & _FW_LINKED) {
  656. _rtw_memset(buf, 0, 32);
  657. sprintf(buf, "_FW_LINKED");
  658. RTW_INFO(FUNC_ADPT_FMT"fwstate-%s\n", FUNC_ADPT_ARG(padapter), buf);
  659. }
  660. if (state & _FW_UNDER_LINKING) {
  661. _rtw_memset(buf, 0, 32);
  662. sprintf(buf, "_FW_UNDER_LINKING");
  663. RTW_INFO(FUNC_ADPT_FMT"fwstate-%s\n", FUNC_ADPT_ARG(padapter), buf);
  664. }
  665. if (state & _FW_UNDER_SURVEY) {
  666. _rtw_memset(buf, 0, 32);
  667. sprintf(buf, "_FW_UNDER_SURVEY");
  668. RTW_INFO(FUNC_ADPT_FMT"fwstate-%s\n", FUNC_ADPT_ARG(padapter), buf);
  669. }
  670. }
  671. #endif
  672. static u8 _rtw_mi_check_fwstate(_adapter *padapter, void *data)
  673. {
  674. u8 ret = _FALSE;
  675. sint state = *(sint *)data;
  676. if ((state == WIFI_FW_NULL_STATE) &&
  677. (padapter->mlmepriv.fw_state == WIFI_FW_NULL_STATE))
  678. ret = _TRUE;
  679. else if (_TRUE == check_fwstate(&padapter->mlmepriv, state))
  680. ret = _TRUE;
  681. #ifdef DBG_DUMP_FW_STATE
  682. if (ret)
  683. rtw_dbg_dump_fwstate(padapter, state);
  684. #endif
  685. return ret;
  686. }
  687. u8 rtw_mi_check_fwstate(_adapter *padapter, sint state)
  688. {
  689. sint in_data = state;
  690. return _rtw_mi_process(padapter, _FALSE, &in_data, _rtw_mi_check_fwstate);
  691. }
  692. u8 rtw_mi_buddy_check_fwstate(_adapter *padapter, sint state)
  693. {
  694. sint in_data = state;
  695. return _rtw_mi_process(padapter, _TRUE, &in_data, _rtw_mi_check_fwstate);
  696. }
  697. static u8 _rtw_mi_traffic_statistics(_adapter *padapter , void *data)
  698. {
  699. struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
  700. /* Tx */
  701. pdvobjpriv->traffic_stat.tx_bytes += padapter->xmitpriv.tx_bytes;
  702. pdvobjpriv->traffic_stat.tx_pkts += padapter->xmitpriv.tx_pkts;
  703. pdvobjpriv->traffic_stat.tx_drop += padapter->xmitpriv.tx_drop;
  704. /* Rx */
  705. pdvobjpriv->traffic_stat.rx_bytes += padapter->recvpriv.rx_bytes;
  706. pdvobjpriv->traffic_stat.rx_pkts += padapter->recvpriv.rx_pkts;
  707. pdvobjpriv->traffic_stat.rx_drop += padapter->recvpriv.rx_drop;
  708. return _TRUE;
  709. }
  710. u8 rtw_mi_traffic_statistics(_adapter *padapter)
  711. {
  712. return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_traffic_statistics);
  713. }
  714. static u8 _rtw_mi_check_miracast_enabled(_adapter *padapter , void *data)
  715. {
  716. return is_miracast_enabled(padapter);
  717. }
  718. u8 rtw_mi_check_miracast_enabled(_adapter *padapter)
  719. {
  720. return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_check_miracast_enabled);
  721. }
  722. #ifdef CONFIG_XMIT_THREAD_MODE
  723. static u8 _rtw_mi_check_pending_xmitbuf(_adapter *padapter , void *data)
  724. {
  725. struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
  726. return check_pending_xmitbuf(pxmitpriv);
  727. }
  728. u8 rtw_mi_check_pending_xmitbuf(_adapter *padapter)
  729. {
  730. return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_check_pending_xmitbuf);
  731. }
  732. u8 rtw_mi_buddy_check_pending_xmitbuf(_adapter *padapter)
  733. {
  734. return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_check_pending_xmitbuf);
  735. }
  736. #endif
  737. #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
  738. static u8 _rtw_mi_dequeue_writeport(_adapter *padapter , bool exclude_self)
  739. {
  740. int i;
  741. u8 queue_empty = _TRUE;
  742. _adapter *iface;
  743. struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
  744. for (i = 0; i < dvobj->iface_nums; i++) {
  745. iface = dvobj->padapters[i];
  746. if ((iface) && rtw_is_adapter_up(iface)) {
  747. if ((exclude_self) && (iface == padapter))
  748. continue;
  749. queue_empty &= _dequeue_writeport(iface);
  750. }
  751. }
  752. return queue_empty;
  753. }
  754. u8 rtw_mi_dequeue_writeport(_adapter *padapter)
  755. {
  756. return _rtw_mi_dequeue_writeport(padapter, _FALSE);
  757. }
  758. u8 rtw_mi_buddy_dequeue_writeport(_adapter *padapter)
  759. {
  760. return _rtw_mi_dequeue_writeport(padapter, _TRUE);
  761. }
  762. #endif
  763. static void _rtw_mi_adapter_reset(_adapter *padapter , u8 exclude_self)
  764. {
  765. int i;
  766. struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
  767. for (i = 0; i < dvobj->iface_nums; i++) {
  768. if (dvobj->padapters[i]) {
  769. if ((exclude_self) && (dvobj->padapters[i] == padapter))
  770. continue;
  771. dvobj->padapters[i] = NULL;
  772. }
  773. }
  774. }
  775. void rtw_mi_adapter_reset(_adapter *padapter)
  776. {
  777. _rtw_mi_adapter_reset(padapter, _FALSE);
  778. }
  779. void rtw_mi_buddy_adapter_reset(_adapter *padapter)
  780. {
  781. _rtw_mi_adapter_reset(padapter, _TRUE);
  782. }
  783. static u8 _rtw_mi_dynamic_check_timer_handlder(_adapter *adapter, void *data)
  784. {
  785. rtw_iface_dynamic_check_timer_handlder(adapter);
  786. return _TRUE;
  787. }
  788. u8 rtw_mi_dynamic_check_timer_handlder(_adapter *padapter)
  789. {
  790. return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_dynamic_check_timer_handlder);
  791. }
  792. u8 rtw_mi_buddy_dynamic_check_timer_handlder(_adapter *padapter)
  793. {
  794. return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_dynamic_check_timer_handlder);
  795. }
  796. static u8 _rtw_mi_dev_unload(_adapter *adapter, void *data)
  797. {
  798. rtw_dev_unload(adapter);
  799. return _TRUE;
  800. }
  801. u8 rtw_mi_dev_unload(_adapter *padapter)
  802. {
  803. return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_dev_unload);
  804. }
  805. u8 rtw_mi_buddy_dev_unload(_adapter *padapter)
  806. {
  807. return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_dev_unload);
  808. }
  809. static u8 _rtw_mi_dynamic_chk_wk_hdl(_adapter *adapter, void *data)
  810. {
  811. rtw_iface_dynamic_chk_wk_hdl(adapter);
  812. return _TRUE;
  813. }
  814. u8 rtw_mi_dynamic_chk_wk_hdl(_adapter *padapter)
  815. {
  816. return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_dynamic_chk_wk_hdl);
  817. }
  818. u8 rtw_mi_buddy_dynamic_chk_wk_hdl(_adapter *padapter)
  819. {
  820. return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_dynamic_chk_wk_hdl);
  821. }
  822. static u8 _rtw_mi_os_xmit_schedule(_adapter *adapter, void *data)
  823. {
  824. rtw_os_xmit_schedule(adapter);
  825. return _TRUE;
  826. }
  827. u8 rtw_mi_os_xmit_schedule(_adapter *padapter)
  828. {
  829. return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_os_xmit_schedule);
  830. }
  831. u8 rtw_mi_buddy_os_xmit_schedule(_adapter *padapter)
  832. {
  833. return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_os_xmit_schedule);
  834. }
  835. static u8 _rtw_mi_report_survey_event(_adapter *adapter, void *data)
  836. {
  837. union recv_frame *precv_frame = (union recv_frame *)data;
  838. report_survey_event(adapter, precv_frame);
  839. return _TRUE;
  840. }
  841. u8 rtw_mi_report_survey_event(_adapter *padapter, union recv_frame *precv_frame)
  842. {
  843. return _rtw_mi_process(padapter, _FALSE, precv_frame, _rtw_mi_report_survey_event);
  844. }
  845. u8 rtw_mi_buddy_report_survey_event(_adapter *padapter, union recv_frame *precv_frame)
  846. {
  847. return _rtw_mi_process(padapter, _TRUE, precv_frame, _rtw_mi_report_survey_event);
  848. }
  849. static u8 _rtw_mi_sreset_adapter_hdl(_adapter *adapter, void *data)
  850. {
  851. u8 bstart = *(u8 *)data;
  852. if (bstart)
  853. sreset_start_adapter(adapter);
  854. else
  855. sreset_stop_adapter(adapter);
  856. return _TRUE;
  857. }
  858. u8 rtw_mi_sreset_adapter_hdl(_adapter *padapter, u8 bstart)
  859. {
  860. u8 in_data = bstart;
  861. return _rtw_mi_process(padapter, _FALSE, &in_data, _rtw_mi_sreset_adapter_hdl);
  862. }
  863. u8 rtw_mi_buddy_sreset_adapter_hdl(_adapter *padapter, u8 bstart)
  864. {
  865. u8 in_data = bstart;
  866. return _rtw_mi_process(padapter, _TRUE, &in_data, _rtw_mi_sreset_adapter_hdl);
  867. }
  868. static u8 _rtw_mi_tx_beacon_hdl(_adapter *adapter, void *data)
  869. {
  870. if (check_fwstate(&adapter->mlmepriv, WIFI_AP_STATE) == _TRUE
  871. && check_fwstate(&adapter->mlmepriv, WIFI_ASOC_STATE) == _TRUE
  872. ) {
  873. adapter->mlmepriv.update_bcn = _TRUE;
  874. #ifndef CONFIG_INTERRUPT_BASED_TXBCN
  875. #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
  876. tx_beacon_hdl(adapter, NULL);
  877. #endif
  878. #endif
  879. }
  880. return _TRUE;
  881. }
  882. u8 rtw_mi_tx_beacon_hdl(_adapter *padapter)
  883. {
  884. return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_tx_beacon_hdl);
  885. }
  886. u8 rtw_mi_buddy_tx_beacon_hdl(_adapter *padapter)
  887. {
  888. return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_sreset_adapter_hdl);
  889. }
  890. static u8 _rtw_mi_set_tx_beacon_cmd(_adapter *adapter, void *data)
  891. {
  892. struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
  893. if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
  894. if (pmlmepriv->update_bcn == _TRUE)
  895. set_tx_beacon_cmd(adapter);
  896. }
  897. return _TRUE;
  898. }
  899. u8 rtw_mi_set_tx_beacon_cmd(_adapter *padapter)
  900. {
  901. return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_set_tx_beacon_cmd);
  902. }
  903. u8 rtw_mi_buddy_set_tx_beacon_cmd(_adapter *padapter)
  904. {
  905. return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_set_tx_beacon_cmd);
  906. }
  907. #ifdef CONFIG_P2P
  908. static u8 _rtw_mi_p2p_chk_state(_adapter *adapter, void *data)
  909. {
  910. struct wifidirect_info *pwdinfo = &(adapter->wdinfo);
  911. enum P2P_STATE state = *(enum P2P_STATE *)data;
  912. return rtw_p2p_chk_state(pwdinfo, state);
  913. }
  914. u8 rtw_mi_p2p_chk_state(_adapter *padapter, enum P2P_STATE p2p_state)
  915. {
  916. u8 in_data = p2p_state;
  917. return _rtw_mi_process(padapter, _FALSE, &in_data, _rtw_mi_p2p_chk_state);
  918. }
  919. u8 rtw_mi_buddy_p2p_chk_state(_adapter *padapter, enum P2P_STATE p2p_state)
  920. {
  921. u8 in_data = p2p_state;
  922. return _rtw_mi_process(padapter, _TRUE, &in_data, _rtw_mi_p2p_chk_state);
  923. }
  924. static u8 _rtw_mi_stay_in_p2p_mode(_adapter *adapter, void *data)
  925. {
  926. struct wifidirect_info *pwdinfo = &(adapter->wdinfo);
  927. if (rtw_p2p_role(pwdinfo) != P2P_ROLE_DISABLE)
  928. return _TRUE;
  929. return _FALSE;
  930. }
  931. u8 rtw_mi_stay_in_p2p_mode(_adapter *padapter)
  932. {
  933. return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_stay_in_p2p_mode);
  934. }
  935. u8 rtw_mi_buddy_stay_in_p2p_mode(_adapter *padapter)
  936. {
  937. return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_stay_in_p2p_mode);
  938. }
  939. #endif /*CONFIG_P2P*/
  940. _adapter *rtw_get_iface_by_id(_adapter *padapter, u8 iface_id)
  941. {
  942. _adapter *iface = NULL;
  943. struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
  944. if ((padapter == NULL) || (iface_id >= CONFIG_IFACE_NUMBER)) {
  945. rtw_warn_on(1);
  946. return iface;
  947. }
  948. return dvobj->padapters[iface_id];
  949. }
  950. _adapter *rtw_get_iface_by_macddr(_adapter *padapter, u8 *mac_addr)
  951. {
  952. int i;
  953. _adapter *iface = NULL;
  954. u8 bmatch = _FALSE;
  955. struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
  956. for (i = 0; i < dvobj->iface_nums; i++) {
  957. iface = dvobj->padapters[i];
  958. if ((iface) && (_rtw_memcmp(mac_addr, adapter_mac_addr(iface), ETH_ALEN))) {
  959. bmatch = _TRUE;
  960. break;
  961. }
  962. }
  963. if (bmatch)
  964. return iface;
  965. else
  966. return NULL;
  967. }
  968. _adapter *rtw_get_iface_by_hwport(_adapter *padapter, u8 hw_port)
  969. {
  970. int i;
  971. _adapter *iface = NULL;
  972. u8 bmatch = _FALSE;
  973. struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
  974. for (i = 0; i < dvobj->iface_nums; i++) {
  975. iface = dvobj->padapters[i];
  976. if ((iface) && (hw_port == iface->hw_port)) {
  977. bmatch = _TRUE;
  978. break;
  979. }
  980. }
  981. if (bmatch)
  982. return iface;
  983. else
  984. return NULL;
  985. }
  986. /*#define CONFIG_SKB_ALLOCATED*/
  987. #define DBG_SKB_PROCESS
  988. #ifdef DBG_SKB_PROCESS
  989. void rtw_dbg_skb_process(_adapter *padapter, union recv_frame *precvframe, union recv_frame *pcloneframe)
  990. {
  991. _pkt *pkt_copy, *pkt_org;
  992. pkt_org = precvframe->u.hdr.pkt;
  993. pkt_copy = pcloneframe->u.hdr.pkt;
  994. /*
  995. RTW_INFO("%s ===== ORG SKB =====\n", __func__);
  996. RTW_INFO(" SKB head(%p)\n", pkt_org->head);
  997. RTW_INFO(" SKB data(%p)\n", pkt_org->data);
  998. RTW_INFO(" SKB tail(%p)\n", pkt_org->tail);
  999. RTW_INFO(" SKB end(%p)\n", pkt_org->end);
  1000. RTW_INFO(" recv frame head(%p)\n", precvframe->u.hdr.rx_head);
  1001. RTW_INFO(" recv frame data(%p)\n", precvframe->u.hdr.rx_data);
  1002. RTW_INFO(" recv frame tail(%p)\n", precvframe->u.hdr.rx_tail);
  1003. RTW_INFO(" recv frame end(%p)\n", precvframe->u.hdr.rx_end);
  1004. RTW_INFO("%s ===== COPY SKB =====\n", __func__);
  1005. RTW_INFO(" SKB head(%p)\n", pkt_copy->head);
  1006. RTW_INFO(" SKB data(%p)\n", pkt_copy->data);
  1007. RTW_INFO(" SKB tail(%p)\n", pkt_copy->tail);
  1008. RTW_INFO(" SKB end(%p)\n", pkt_copy->end);
  1009. RTW_INFO(" recv frame head(%p)\n", pcloneframe->u.hdr.rx_head);
  1010. RTW_INFO(" recv frame data(%p)\n", pcloneframe->u.hdr.rx_data);
  1011. RTW_INFO(" recv frame tail(%p)\n", pcloneframe->u.hdr.rx_tail);
  1012. RTW_INFO(" recv frame end(%p)\n", pcloneframe->u.hdr.rx_end);
  1013. */
  1014. /*
  1015. RTW_INFO("%s => recv_frame adapter(%p,%p)\n", __func__, precvframe->u.hdr.adapter, pcloneframe->u.hdr.adapter);
  1016. RTW_INFO("%s => recv_frame dev(%p,%p)\n", __func__, pkt_org->dev , pkt_copy->dev);
  1017. RTW_INFO("%s => recv_frame len(%d,%d)\n", __func__, precvframe->u.hdr.len, pcloneframe->u.hdr.len);
  1018. */
  1019. if (precvframe->u.hdr.len != pcloneframe->u.hdr.len)
  1020. RTW_INFO("%s [WARN] recv_frame length(%d:%d) compare failed\n", __func__, precvframe->u.hdr.len, pcloneframe->u.hdr.len);
  1021. if (_rtw_memcmp(&precvframe->u.hdr.attrib, &pcloneframe->u.hdr.attrib, sizeof(struct rx_pkt_attrib)) == _FALSE)
  1022. RTW_INFO("%s [WARN] recv_frame attrib compare failed\n", __func__);
  1023. if (_rtw_memcmp(precvframe->u.hdr.rx_data, pcloneframe->u.hdr.rx_data, precvframe->u.hdr.len) == _FALSE)
  1024. RTW_INFO("%s [WARN] recv_frame rx_data compare failed\n", __func__);
  1025. }
  1026. #endif
  1027. static s32 _rtw_mi_buddy_clone_bcmc_packet(_adapter *adapter, union recv_frame *precvframe, u8 *pphy_status, union recv_frame *pcloneframe)
  1028. {
  1029. s32 ret = _SUCCESS;
  1030. u8 *pbuf = precvframe->u.hdr.rx_data;
  1031. struct rx_pkt_attrib *pattrib = NULL;
  1032. HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
  1033. if (pcloneframe) {
  1034. pcloneframe->u.hdr.adapter = adapter;
  1035. _rtw_init_listhead(&pcloneframe->u.hdr.list);
  1036. pcloneframe->u.hdr.precvbuf = NULL; /*can't access the precvbuf for new arch.*/
  1037. pcloneframe->u.hdr.len = 0;
  1038. _rtw_memcpy(&pcloneframe->u.hdr.attrib, &precvframe->u.hdr.attrib, sizeof(struct rx_pkt_attrib));
  1039. pattrib = &pcloneframe->u.hdr.attrib;
  1040. #ifdef CONFIG_SKB_ALLOCATED
  1041. if (rtw_os_alloc_recvframe(adapter, pcloneframe, pbuf, NULL) == _SUCCESS)
  1042. #else
  1043. if (rtw_os_recvframe_duplicate_skb(adapter, pcloneframe, precvframe->u.hdr.pkt) == _SUCCESS)
  1044. #endif
  1045. {
  1046. #ifdef CONFIG_SKB_ALLOCATED
  1047. recvframe_put(pcloneframe, pattrib->pkt_len);
  1048. #endif
  1049. #ifdef DBG_SKB_PROCESS
  1050. rtw_dbg_skb_process(adapter, precvframe, pcloneframe);
  1051. #endif
  1052. if (pattrib->physt && pphy_status)
  1053. rx_query_phy_status(pcloneframe, pphy_status);
  1054. ret = rtw_recv_entry(pcloneframe);
  1055. } else {
  1056. ret = -1;
  1057. RTW_INFO("%s()-%d: rtw_os_alloc_recvframe() failed!\n", __func__, __LINE__);
  1058. }
  1059. }
  1060. return ret;
  1061. }
  1062. void rtw_mi_buddy_clone_bcmc_packet(_adapter *padapter, union recv_frame *precvframe, u8 *pphy_status)
  1063. {
  1064. int i;
  1065. s32 ret = _SUCCESS;
  1066. _adapter *iface = NULL;
  1067. union recv_frame *pcloneframe = NULL;
  1068. struct recv_priv *precvpriv = &padapter->recvpriv;/*primary_padapter*/
  1069. _queue *pfree_recv_queue = &precvpriv->free_recv_queue;
  1070. struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
  1071. for (i = 0; i < dvobj->iface_nums; i++) {
  1072. iface = dvobj->padapters[i];
  1073. if (!iface || iface == padapter)
  1074. continue;
  1075. if (rtw_is_adapter_up(iface) == _FALSE || iface->registered == 0)
  1076. continue;
  1077. pcloneframe = rtw_alloc_recvframe(pfree_recv_queue);
  1078. if (pcloneframe) {
  1079. ret = _rtw_mi_buddy_clone_bcmc_packet(iface, precvframe, pphy_status, pcloneframe);
  1080. if (_SUCCESS != ret) {
  1081. if (ret == -1)
  1082. rtw_free_recvframe(pcloneframe, pfree_recv_queue);
  1083. /*RTW_INFO(ADPT_FMT"-clone BC/MC frame failed\n", ADPT_ARG(iface));*/
  1084. }
  1085. }
  1086. }
  1087. }
  1088. #ifdef CONFIG_PCI_HCI
  1089. /*API be created temporary for MI, caller is interrupt-handler, PCIE's interrupt handler cannot apply to multi-AP*/
  1090. _adapter *rtw_mi_get_ap_adapter(_adapter *padapter)
  1091. {
  1092. struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
  1093. int i;
  1094. _adapter *iface = NULL;
  1095. for (i = 0; i < dvobj->iface_nums; i++) {
  1096. iface = dvobj->padapters[i];
  1097. if (!iface)
  1098. continue;
  1099. if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE
  1100. && check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE)
  1101. break;
  1102. }
  1103. return iface;
  1104. }
  1105. #endif
  1106. void rtw_mi_update_ap_bmc_camid(_adapter *padapter, u8 camid_a, u8 camid_b)
  1107. {
  1108. #ifdef CONFIG_CONCURRENT_MODE
  1109. struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
  1110. struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
  1111. int i;
  1112. _adapter *iface = NULL;
  1113. for (i = 0; i < dvobj->iface_nums; i++) {
  1114. iface = dvobj->padapters[i];
  1115. if (!iface)
  1116. continue;
  1117. if (macid_ctl->iface_bmc[iface->iface_id] != INVALID_SEC_MAC_CAM_ID) {
  1118. if (macid_ctl->iface_bmc[iface->iface_id] == camid_a)
  1119. macid_ctl->iface_bmc[iface->iface_id] = camid_b;
  1120. else if (macid_ctl->iface_bmc[iface->iface_id] == camid_b)
  1121. macid_ctl->iface_bmc[iface->iface_id] = camid_a;
  1122. iface->securitypriv.dot118021x_bmc_cam_id = macid_ctl->iface_bmc[iface->iface_id];
  1123. }
  1124. }
  1125. #endif
  1126. }