rtw_mi.c 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572
  1. /******************************************************************************
  2. *
  3. * Copyright(c) 2007 - 2017 Realtek Corporation.
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms of version 2 of the GNU General Public License as
  7. * published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12. * more details.
  13. *
  14. *****************************************************************************/
  15. #define _RTW_MI_C_
  16. #include <drv_types.h>
  17. #include <hal_data.h>
  18. void rtw_mi_update_union_chan_inf(_adapter *adapter, u8 ch, u8 offset , u8 bw)
  19. {
  20. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  21. struct mi_state *iface_state = &dvobj->iface_state;
  22. iface_state->union_ch = ch;
  23. iface_state->union_bw = bw;
  24. iface_state->union_offset = offset;
  25. }
  26. #ifdef DBG_IFACE_STATUS
  27. #ifdef CONFIG_P2P
  28. static u8 _rtw_mi_p2p_listen_scan_chk(_adapter *adapter)
  29. {
  30. int i;
  31. _adapter *iface;
  32. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  33. u8 p2p_listen_scan_state = _FALSE;
  34. for (i = 0; i < dvobj->iface_nums; i++) {
  35. iface = dvobj->padapters[i];
  36. if (rtw_p2p_chk_state(&iface->wdinfo, P2P_STATE_LISTEN) ||
  37. rtw_p2p_chk_state(&iface->wdinfo, P2P_STATE_SCAN)) {
  38. p2p_listen_scan_state = _TRUE;
  39. break;
  40. }
  41. }
  42. return p2p_listen_scan_state;
  43. }
  44. #endif
  45. #endif
  46. u8 rtw_mi_stayin_union_ch_chk(_adapter *adapter)
  47. {
  48. u8 rst = _TRUE;
  49. u8 u_ch, u_bw, u_offset;
  50. u8 o_ch, o_bw, o_offset;
  51. u_ch = rtw_mi_get_union_chan(adapter);
  52. u_bw = rtw_mi_get_union_bw(adapter);
  53. u_offset = rtw_mi_get_union_offset(adapter);
  54. o_ch = rtw_get_oper_ch(adapter);
  55. o_bw = rtw_get_oper_bw(adapter);
  56. o_offset = rtw_get_oper_choffset(adapter);
  57. if ((u_ch != o_ch) || (u_bw != o_bw) || (u_offset != o_offset))
  58. rst = _FALSE;
  59. #ifdef DBG_IFACE_STATUS
  60. if (rst == _FALSE) {
  61. RTW_ERR("%s Not stay in union channel\n", __func__);
  62. if (GET_HAL_DATA(adapter)->bScanInProcess == _TRUE)
  63. RTW_ERR("ScanInProcess\n");
  64. #ifdef CONFIG_P2P
  65. if (_rtw_mi_p2p_listen_scan_chk(adapter))
  66. RTW_ERR("P2P in listen or scan state\n");
  67. #endif
  68. RTW_ERR("union ch, bw, offset: %u,%u,%u\n", u_ch, u_bw, u_offset);
  69. RTW_ERR("oper ch, bw, offset: %u,%u,%u\n", o_ch, o_bw, o_offset);
  70. RTW_ERR("=========================\n");
  71. }
  72. #endif
  73. return rst;
  74. }
  75. u8 rtw_mi_stayin_union_band_chk(_adapter *adapter)
  76. {
  77. u8 rst = _TRUE;
  78. u8 u_ch, o_ch;
  79. u8 u_band, o_band;
  80. u_ch = rtw_mi_get_union_chan(adapter);
  81. o_ch = rtw_get_oper_ch(adapter);
  82. u_band = (u_ch > 14) ? BAND_ON_5G : BAND_ON_2_4G;
  83. o_band = (o_ch > 14) ? BAND_ON_5G : BAND_ON_2_4G;
  84. if (u_ch != o_ch)
  85. if(u_band != o_band)
  86. rst = _FALSE;
  87. #ifdef DBG_IFACE_STATUS
  88. if (rst == _FALSE)
  89. RTW_ERR("%s Not stay in union band\n", __func__);
  90. #endif
  91. return rst;
  92. }
  93. /* Find union about ch, bw, ch_offset of all linked/linking interfaces */
  94. int rtw_mi_get_ch_setting_union_by_ifbmp(struct dvobj_priv *dvobj, u8 ifbmp, u8 *ch, u8 *bw, u8 *offset)
  95. {
  96. _adapter *iface;
  97. struct mlme_ext_priv *mlmeext;
  98. int i;
  99. u8 ch_ret = 0;
  100. u8 bw_ret = CHANNEL_WIDTH_20;
  101. u8 offset_ret = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
  102. int num = 0;
  103. if (ch)
  104. *ch = 0;
  105. if (bw)
  106. *bw = CHANNEL_WIDTH_20;
  107. if (offset)
  108. *offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
  109. for (i = 0; i < dvobj->iface_nums; i++) {
  110. iface = dvobj->padapters[i];
  111. if (!iface || !(ifbmp & BIT(iface->iface_id)))
  112. continue;
  113. mlmeext = &iface->mlmeextpriv;
  114. if (!check_fwstate(&iface->mlmepriv, _FW_LINKED | _FW_UNDER_LINKING))
  115. continue;
  116. if (check_fwstate(&iface->mlmepriv, WIFI_OP_CH_SWITCHING))
  117. continue;
  118. if (num == 0) {
  119. ch_ret = mlmeext->cur_channel;
  120. bw_ret = mlmeext->cur_bwmode;
  121. offset_ret = mlmeext->cur_ch_offset;
  122. num++;
  123. continue;
  124. }
  125. if (ch_ret != mlmeext->cur_channel) {
  126. num = 0;
  127. break;
  128. }
  129. if (bw_ret < mlmeext->cur_bwmode) {
  130. bw_ret = mlmeext->cur_bwmode;
  131. offset_ret = mlmeext->cur_ch_offset;
  132. } else if (bw_ret == mlmeext->cur_bwmode && offset_ret != mlmeext->cur_ch_offset) {
  133. num = 0;
  134. break;
  135. }
  136. num++;
  137. }
  138. if (num) {
  139. if (ch)
  140. *ch = ch_ret;
  141. if (bw)
  142. *bw = bw_ret;
  143. if (offset)
  144. *offset = offset_ret;
  145. }
  146. return num;
  147. }
  148. inline int rtw_mi_get_ch_setting_union(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset)
  149. {
  150. return rtw_mi_get_ch_setting_union_by_ifbmp(adapter_to_dvobj(adapter), 0xFF, ch, bw, offset);
  151. }
  152. inline int rtw_mi_get_ch_setting_union_no_self(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset)
  153. {
  154. return rtw_mi_get_ch_setting_union_by_ifbmp(adapter_to_dvobj(adapter), 0xFF & ~BIT(adapter->iface_id), ch, bw, offset);
  155. }
  156. /* For now, not return union_ch/bw/offset */
  157. void rtw_mi_status_by_ifbmp(struct dvobj_priv *dvobj, u8 ifbmp, struct mi_state *mstate)
  158. {
  159. _adapter *iface;
  160. int i;
  161. _rtw_memset(mstate, 0, sizeof(struct mi_state));
  162. for (i = 0; i < dvobj->iface_nums; i++) {
  163. iface = dvobj->padapters[i];
  164. if (!iface || !(ifbmp & BIT(iface->iface_id)))
  165. continue;
  166. if (check_fwstate(&iface->mlmepriv, WIFI_STATION_STATE) == _TRUE) {
  167. MSTATE_STA_NUM(mstate)++;
  168. if (check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE) {
  169. MSTATE_STA_LD_NUM(mstate)++;
  170. #ifdef CONFIG_TDLS
  171. if (iface->tdlsinfo.link_established == _TRUE)
  172. MSTATE_TDLS_LD_NUM(mstate)++;
  173. #endif
  174. #ifdef CONFIG_P2P
  175. if (MLME_IS_GC(iface))
  176. MSTATE_P2P_GC_NUM(mstate)++;
  177. #endif
  178. }
  179. if (check_fwstate(&iface->mlmepriv, _FW_UNDER_LINKING) == _TRUE)
  180. MSTATE_STA_LG_NUM(mstate)++;
  181. #ifdef CONFIG_AP_MODE
  182. } else if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE ) {
  183. if (check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE) {
  184. MSTATE_AP_NUM(mstate)++;
  185. if (iface->stapriv.asoc_sta_count > 2)
  186. MSTATE_AP_LD_NUM(mstate)++;
  187. #ifdef CONFIG_P2P
  188. if (MLME_IS_GO(iface))
  189. MSTATE_P2P_GO_NUM(mstate)++;
  190. #endif
  191. } else
  192. MSTATE_AP_STARTING_NUM(mstate)++;
  193. #endif
  194. } else if (check_fwstate(&iface->mlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE) == _TRUE
  195. && check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE
  196. ) {
  197. MSTATE_ADHOC_NUM(mstate)++;
  198. if (iface->stapriv.asoc_sta_count > 2)
  199. MSTATE_ADHOC_LD_NUM(mstate)++;
  200. #ifdef CONFIG_RTW_MESH
  201. } else if (check_fwstate(&iface->mlmepriv, WIFI_MESH_STATE) == _TRUE
  202. && check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE
  203. ) {
  204. MSTATE_MESH_NUM(mstate)++;
  205. if (iface->stapriv.asoc_sta_count > 2)
  206. MSTATE_MESH_LD_NUM(mstate)++;
  207. #endif
  208. }
  209. if (check_fwstate(&iface->mlmepriv, WIFI_UNDER_WPS) == _TRUE)
  210. MSTATE_WPS_NUM(mstate)++;
  211. if (check_fwstate(&iface->mlmepriv, WIFI_SITE_MONITOR) == _TRUE) {
  212. MSTATE_SCAN_NUM(mstate)++;
  213. if (mlmeext_scan_state(&iface->mlmeextpriv) != SCAN_DISABLE
  214. && mlmeext_scan_state(&iface->mlmeextpriv) != SCAN_BACK_OP)
  215. MSTATE_SCAN_ENTER_NUM(mstate)++;
  216. }
  217. #ifdef CONFIG_IOCTL_CFG80211
  218. if (rtw_cfg80211_get_is_mgmt_tx(iface))
  219. MSTATE_MGMT_TX_NUM(mstate)++;
  220. #ifdef CONFIG_P2P
  221. if (rtw_cfg80211_get_is_roch(iface) == _TRUE)
  222. MSTATE_ROCH_NUM(mstate)++;
  223. #endif
  224. #endif /* CONFIG_IOCTL_CFG80211 */
  225. #ifdef CONFIG_P2P
  226. if (MLME_IS_PD(iface))
  227. MSTATE_P2P_DV_NUM(mstate)++;
  228. #endif
  229. }
  230. }
  231. inline void rtw_mi_status(_adapter *adapter, struct mi_state *mstate)
  232. {
  233. return rtw_mi_status_by_ifbmp(adapter_to_dvobj(adapter), 0xFF, mstate);
  234. }
  235. inline void rtw_mi_status_no_self(_adapter *adapter, struct mi_state *mstate)
  236. {
  237. return rtw_mi_status_by_ifbmp(adapter_to_dvobj(adapter), 0xFF & ~BIT(adapter->iface_id), mstate);
  238. }
  239. inline void rtw_mi_status_no_others(_adapter *adapter, struct mi_state *mstate)
  240. {
  241. return rtw_mi_status_by_ifbmp(adapter_to_dvobj(adapter), BIT(adapter->iface_id), mstate);
  242. }
  243. /* For now, not handle union_ch/bw/offset */
  244. inline void rtw_mi_status_merge(struct mi_state *d, struct mi_state *a)
  245. {
  246. d->sta_num += a->sta_num;
  247. d->ld_sta_num += a->ld_sta_num;
  248. d->lg_sta_num += a->lg_sta_num;
  249. #ifdef CONFIG_TDLS
  250. d->ld_tdls_num += a->ld_tdls_num;
  251. #endif
  252. #ifdef CONFIG_AP_MODE
  253. d->ap_num += a->ap_num;
  254. d->ld_ap_num += a->ld_ap_num;
  255. #endif
  256. d->adhoc_num += a->adhoc_num;
  257. d->ld_adhoc_num += a->ld_adhoc_num;
  258. #ifdef CONFIG_RTW_MESH
  259. d->mesh_num += a->mesh_num;
  260. d->ld_mesh_num += a->ld_mesh_num;
  261. #endif
  262. d->scan_num += a->scan_num;
  263. d->scan_enter_num += a->scan_enter_num;
  264. d->uwps_num += a->uwps_num;
  265. #ifdef CONFIG_IOCTL_CFG80211
  266. #ifdef CONFIG_P2P
  267. d->roch_num += a->roch_num;
  268. #endif
  269. d->mgmt_tx_num += a->mgmt_tx_num;
  270. #endif
  271. }
  272. void dump_mi_status(void *sel, struct dvobj_priv *dvobj)
  273. {
  274. RTW_PRINT_SEL(sel, "== dvobj-iface_state ==\n");
  275. RTW_PRINT_SEL(sel, "sta_num:%d\n", DEV_STA_NUM(dvobj));
  276. RTW_PRINT_SEL(sel, "linking_sta_num:%d\n", DEV_STA_LG_NUM(dvobj));
  277. RTW_PRINT_SEL(sel, "linked_sta_num:%d\n", DEV_STA_LD_NUM(dvobj));
  278. #ifdef CONFIG_TDLS
  279. RTW_PRINT_SEL(sel, "linked_tdls_num:%d\n", DEV_TDLS_LD_NUM(dvobj));
  280. #endif
  281. #ifdef CONFIG_AP_MODE
  282. RTW_PRINT_SEL(sel, "ap_num:%d\n", DEV_AP_NUM(dvobj));
  283. RTW_PRINT_SEL(sel, "starting_ap_num:%d\n", DEV_AP_STARTING_NUM(dvobj));
  284. RTW_PRINT_SEL(sel, "linked_ap_num:%d\n", DEV_AP_LD_NUM(dvobj));
  285. #endif
  286. RTW_PRINT_SEL(sel, "adhoc_num:%d\n", DEV_ADHOC_NUM(dvobj));
  287. RTW_PRINT_SEL(sel, "linked_adhoc_num:%d\n", DEV_ADHOC_LD_NUM(dvobj));
  288. #ifdef CONFIG_RTW_MESH
  289. RTW_PRINT_SEL(sel, "mesh_num:%d\n", DEV_MESH_NUM(dvobj));
  290. RTW_PRINT_SEL(sel, "linked_mesh_num:%d\n", DEV_MESH_LD_NUM(dvobj));
  291. #endif
  292. #ifdef CONFIG_P2P
  293. RTW_PRINT_SEL(sel, "p2p_device_num:%d\n", DEV_P2P_DV_NUM(dvobj));
  294. RTW_PRINT_SEL(sel, "p2p_gc_num:%d\n", DEV_P2P_GC_NUM(dvobj));
  295. RTW_PRINT_SEL(sel, "p2p_go_num:%d\n", DEV_P2P_GO_NUM(dvobj));
  296. #endif
  297. RTW_PRINT_SEL(sel, "scan_num:%d\n", DEV_SCAN_NUM(dvobj));
  298. RTW_PRINT_SEL(sel, "under_wps_num:%d\n", DEV_WPS_NUM(dvobj));
  299. #if defined(CONFIG_IOCTL_CFG80211)
  300. #if defined(CONFIG_P2P)
  301. RTW_PRINT_SEL(sel, "roch_num:%d\n", DEV_ROCH_NUM(dvobj));
  302. #endif
  303. RTW_PRINT_SEL(sel, "mgmt_tx_num:%d\n", DEV_MGMT_TX_NUM(dvobj));
  304. #endif
  305. RTW_PRINT_SEL(sel, "union_ch:%d\n", DEV_U_CH(dvobj));
  306. RTW_PRINT_SEL(sel, "union_bw:%d\n", DEV_U_BW(dvobj));
  307. RTW_PRINT_SEL(sel, "union_offset:%d\n", DEV_U_OFFSET(dvobj));
  308. RTW_PRINT_SEL(sel, "================\n\n");
  309. }
  310. void dump_dvobj_mi_status(void *sel, const char *fun_name, _adapter *adapter)
  311. {
  312. RTW_INFO("\n[ %s ] call %s\n", fun_name, __func__);
  313. dump_mi_status(sel, adapter_to_dvobj(adapter));
  314. }
  315. inline void rtw_mi_update_iface_status(struct mlme_priv *pmlmepriv, sint state)
  316. {
  317. _adapter *adapter = container_of(pmlmepriv, _adapter, mlmepriv);
  318. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  319. struct mi_state *iface_state = &dvobj->iface_state;
  320. struct mi_state tmp_mstate;
  321. u8 u_ch, u_offset, u_bw;
  322. if (state == WIFI_MONITOR_STATE
  323. || state == 0xFFFFFFFF
  324. )
  325. return;
  326. if (0)
  327. RTW_INFO("%s => will change or clean state to 0x%08x\n", __func__, state);
  328. rtw_mi_status(adapter, &tmp_mstate);
  329. _rtw_memcpy(iface_state, &tmp_mstate, sizeof(struct mi_state));
  330. if (rtw_mi_get_ch_setting_union(adapter, &u_ch, &u_bw, &u_offset))
  331. rtw_mi_update_union_chan_inf(adapter , u_ch, u_offset , u_bw);
  332. else {
  333. if (0) {
  334. dump_adapters_status(RTW_DBGDUMP , dvobj);
  335. RTW_INFO("%s-[ERROR] cannot get union channel\n", __func__);
  336. rtw_warn_on(1);
  337. }
  338. }
  339. #ifdef DBG_IFACE_STATUS
  340. DBG_IFACE_STATUS_DUMP(adapter);
  341. #endif
  342. }
  343. u8 rtw_mi_check_status(_adapter *adapter, u8 type)
  344. {
  345. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  346. struct mi_state *iface_state = &dvobj->iface_state;
  347. u8 ret = _FALSE;
  348. #ifdef DBG_IFACE_STATUS
  349. DBG_IFACE_STATUS_DUMP(adapter);
  350. RTW_INFO("%s-"ADPT_FMT" check type:%d\n", __func__, ADPT_ARG(adapter), type);
  351. #endif
  352. switch (type) {
  353. case MI_LINKED:
  354. if (MSTATE_STA_LD_NUM(iface_state) || MSTATE_AP_NUM(iface_state) || MSTATE_ADHOC_NUM(iface_state) || MSTATE_MESH_NUM(iface_state)) /*check_fwstate(&iface->mlmepriv, _FW_LINKED)*/
  355. ret = _TRUE;
  356. break;
  357. case MI_ASSOC:
  358. if (MSTATE_STA_LD_NUM(iface_state) || MSTATE_AP_LD_NUM(iface_state) || MSTATE_ADHOC_LD_NUM(iface_state) || MSTATE_MESH_LD_NUM(iface_state))
  359. ret = _TRUE;
  360. break;
  361. case MI_UNDER_WPS:
  362. if (MSTATE_WPS_NUM(iface_state))
  363. ret = _TRUE;
  364. break;
  365. case MI_AP_MODE:
  366. if (MSTATE_AP_NUM(iface_state))
  367. ret = _TRUE;
  368. break;
  369. case MI_AP_ASSOC:
  370. if (MSTATE_AP_LD_NUM(iface_state))
  371. ret = _TRUE;
  372. break;
  373. case MI_ADHOC:
  374. if (MSTATE_ADHOC_NUM(iface_state))
  375. ret = _TRUE;
  376. break;
  377. case MI_ADHOC_ASSOC:
  378. if (MSTATE_ADHOC_LD_NUM(iface_state))
  379. ret = _TRUE;
  380. break;
  381. #ifdef CONFIG_RTW_MESH
  382. case MI_MESH:
  383. if (MSTATE_MESH_NUM(iface_state))
  384. ret = _TRUE;
  385. break;
  386. case MI_MESH_ASSOC:
  387. if (MSTATE_MESH_LD_NUM(iface_state))
  388. ret = _TRUE;
  389. break;
  390. #endif
  391. case MI_STA_NOLINK: /* this is misleading, but not used now */
  392. if (MSTATE_STA_NUM(iface_state) && (!(MSTATE_STA_LD_NUM(iface_state) || MSTATE_STA_LG_NUM(iface_state))))
  393. ret = _TRUE;
  394. break;
  395. case MI_STA_LINKED:
  396. if (MSTATE_STA_LD_NUM(iface_state))
  397. ret = _TRUE;
  398. break;
  399. case MI_STA_LINKING:
  400. if (MSTATE_STA_LG_NUM(iface_state))
  401. ret = _TRUE;
  402. break;
  403. default:
  404. break;
  405. }
  406. return ret;
  407. }
  408. /*
  409. * return value : 0 is failed or have not interface meet condition
  410. * return value : !0 is success or interface numbers which meet condition
  411. * return value of ops_func must be _TRUE or _FALSE
  412. */
  413. static u8 _rtw_mi_process(_adapter *padapter, bool exclude_self,
  414. void *data, u8(*ops_func)(_adapter *padapter, void *data))
  415. {
  416. int i;
  417. _adapter *iface;
  418. struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
  419. u8 ret = 0;
  420. for (i = 0; i < dvobj->iface_nums; i++) {
  421. iface = dvobj->padapters[i];
  422. if ((iface) && rtw_is_adapter_up(iface)) {
  423. if ((exclude_self) && (iface == padapter))
  424. continue;
  425. if (ops_func)
  426. if (_TRUE == ops_func(iface, data))
  427. ret++;
  428. }
  429. }
  430. return ret;
  431. }
  432. static u8 _rtw_mi_process_without_schk(_adapter *padapter, bool exclude_self,
  433. void *data, u8(*ops_func)(_adapter *padapter, void *data))
  434. {
  435. int i;
  436. _adapter *iface;
  437. struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
  438. u8 ret = 0;
  439. for (i = 0; i < dvobj->iface_nums; i++) {
  440. iface = dvobj->padapters[i];
  441. if (iface) {
  442. if ((exclude_self) && (iface == padapter))
  443. continue;
  444. if (ops_func)
  445. if (ops_func(iface, data) == _TRUE)
  446. ret++;
  447. }
  448. }
  449. return ret;
  450. }
  451. static u8 _rtw_mi_netif_caroff_qstop(_adapter *padapter, void *data)
  452. {
  453. struct net_device *pnetdev = padapter->pnetdev;
  454. rtw_netif_carrier_off(pnetdev);
  455. rtw_netif_stop_queue(pnetdev);
  456. return _TRUE;
  457. }
  458. u8 rtw_mi_netif_caroff_qstop(_adapter *padapter)
  459. {
  460. return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_netif_caroff_qstop);
  461. }
  462. u8 rtw_mi_buddy_netif_caroff_qstop(_adapter *padapter)
  463. {
  464. return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_netif_caroff_qstop);
  465. }
  466. static u8 _rtw_mi_netif_caron_qstart(_adapter *padapter, void *data)
  467. {
  468. struct net_device *pnetdev = padapter->pnetdev;
  469. rtw_netif_carrier_on(pnetdev);
  470. rtw_netif_start_queue(pnetdev);
  471. return _TRUE;
  472. }
  473. u8 rtw_mi_netif_caron_qstart(_adapter *padapter)
  474. {
  475. return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_netif_caron_qstart);
  476. }
  477. u8 rtw_mi_buddy_netif_caron_qstart(_adapter *padapter)
  478. {
  479. return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_netif_caron_qstart);
  480. }
  481. static u8 _rtw_mi_netif_stop_queue(_adapter *padapter, void *data)
  482. {
  483. struct net_device *pnetdev = padapter->pnetdev;
  484. rtw_netif_stop_queue(pnetdev);
  485. return _TRUE;
  486. }
  487. u8 rtw_mi_netif_stop_queue(_adapter *padapter)
  488. {
  489. return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_netif_stop_queue);
  490. }
  491. u8 rtw_mi_buddy_netif_stop_queue(_adapter *padapter)
  492. {
  493. return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_netif_stop_queue);
  494. }
  495. static u8 _rtw_mi_netif_wake_queue(_adapter *padapter, void *data)
  496. {
  497. struct net_device *pnetdev = padapter->pnetdev;
  498. if (pnetdev)
  499. rtw_netif_wake_queue(pnetdev);
  500. return _TRUE;
  501. }
  502. u8 rtw_mi_netif_wake_queue(_adapter *padapter)
  503. {
  504. return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_netif_wake_queue);
  505. }
  506. u8 rtw_mi_buddy_netif_wake_queue(_adapter *padapter)
  507. {
  508. return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_netif_wake_queue);
  509. }
  510. static u8 _rtw_mi_netif_carrier_on(_adapter *padapter, void *data)
  511. {
  512. struct net_device *pnetdev = padapter->pnetdev;
  513. if (pnetdev)
  514. rtw_netif_carrier_on(pnetdev);
  515. return _TRUE;
  516. }
  517. u8 rtw_mi_netif_carrier_on(_adapter *padapter)
  518. {
  519. return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_netif_carrier_on);
  520. }
  521. u8 rtw_mi_buddy_netif_carrier_on(_adapter *padapter)
  522. {
  523. return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_netif_carrier_on);
  524. }
  525. static u8 _rtw_mi_netif_carrier_off(_adapter *padapter, void *data)
  526. {
  527. struct net_device *pnetdev = padapter->pnetdev;
  528. if (pnetdev)
  529. rtw_netif_carrier_off(pnetdev);
  530. return _TRUE;
  531. }
  532. u8 rtw_mi_netif_carrier_off(_adapter *padapter)
  533. {
  534. return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_netif_carrier_off);
  535. }
  536. u8 rtw_mi_buddy_netif_carrier_off(_adapter *padapter)
  537. {
  538. return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_netif_carrier_off);
  539. }
  540. static u8 _rtw_mi_scan_abort(_adapter *adapter, void *data)
  541. {
  542. bool bwait = *(bool *)data;
  543. if (bwait)
  544. rtw_scan_abort(adapter);
  545. else
  546. rtw_scan_abort_no_wait(adapter);
  547. return _TRUE;
  548. }
  549. void rtw_mi_scan_abort(_adapter *adapter, bool bwait)
  550. {
  551. bool in_data = bwait;
  552. _rtw_mi_process(adapter, _FALSE, &in_data, _rtw_mi_scan_abort);
  553. }
  554. void rtw_mi_buddy_scan_abort(_adapter *adapter, bool bwait)
  555. {
  556. bool in_data = bwait;
  557. _rtw_mi_process(adapter, _TRUE, &in_data, _rtw_mi_scan_abort);
  558. }
  559. static u32 _rtw_mi_start_drv_threads(_adapter *adapter, bool exclude_self)
  560. {
  561. int i;
  562. _adapter *iface = NULL;
  563. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  564. u32 _status = _SUCCESS;
  565. for (i = 0; i < dvobj->iface_nums; i++) {
  566. iface = dvobj->padapters[i];
  567. if (iface) {
  568. if ((exclude_self) && (iface == adapter))
  569. continue;
  570. if (rtw_start_drv_threads(iface) == _FAIL) {
  571. _status = _FAIL;
  572. break;
  573. }
  574. }
  575. }
  576. return _status;
  577. }
  578. u32 rtw_mi_start_drv_threads(_adapter *adapter)
  579. {
  580. return _rtw_mi_start_drv_threads(adapter, _FALSE);
  581. }
  582. u32 rtw_mi_buddy_start_drv_threads(_adapter *adapter)
  583. {
  584. return _rtw_mi_start_drv_threads(adapter, _TRUE);
  585. }
  586. static void _rtw_mi_stop_drv_threads(_adapter *adapter, bool exclude_self)
  587. {
  588. int i;
  589. _adapter *iface = NULL;
  590. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  591. for (i = 0; i < dvobj->iface_nums; i++) {
  592. iface = dvobj->padapters[i];
  593. if (iface) {
  594. if ((exclude_self) && (iface == adapter))
  595. continue;
  596. rtw_stop_drv_threads(iface);
  597. }
  598. }
  599. }
  600. void rtw_mi_stop_drv_threads(_adapter *adapter)
  601. {
  602. _rtw_mi_stop_drv_threads(adapter, _FALSE);
  603. }
  604. void rtw_mi_buddy_stop_drv_threads(_adapter *adapter)
  605. {
  606. _rtw_mi_stop_drv_threads(adapter, _TRUE);
  607. }
  608. static u8 _rtw_mi_cancel_all_timer(_adapter *adapter, void *data)
  609. {
  610. rtw_cancel_all_timer(adapter);
  611. return _TRUE;
  612. }
  613. void rtw_mi_cancel_all_timer(_adapter *adapter)
  614. {
  615. _rtw_mi_process(adapter, _FALSE, NULL, _rtw_mi_cancel_all_timer);
  616. }
  617. void rtw_mi_buddy_cancel_all_timer(_adapter *adapter)
  618. {
  619. _rtw_mi_process(adapter, _TRUE, NULL, _rtw_mi_cancel_all_timer);
  620. }
  621. static u8 _rtw_mi_reset_drv_sw(_adapter *adapter, void *data)
  622. {
  623. rtw_reset_drv_sw(adapter);
  624. return _TRUE;
  625. }
  626. void rtw_mi_reset_drv_sw(_adapter *adapter)
  627. {
  628. _rtw_mi_process_without_schk(adapter, _FALSE, NULL, _rtw_mi_reset_drv_sw);
  629. }
  630. void rtw_mi_buddy_reset_drv_sw(_adapter *adapter)
  631. {
  632. _rtw_mi_process_without_schk(adapter, _TRUE, NULL, _rtw_mi_reset_drv_sw);
  633. }
  634. static u8 _rtw_mi_intf_start(_adapter *adapter, void *data)
  635. {
  636. rtw_intf_start(adapter);
  637. return _TRUE;
  638. }
  639. void rtw_mi_intf_start(_adapter *adapter)
  640. {
  641. _rtw_mi_process(adapter, _FALSE, NULL, _rtw_mi_intf_start);
  642. }
  643. void rtw_mi_buddy_intf_start(_adapter *adapter)
  644. {
  645. _rtw_mi_process(adapter, _TRUE, NULL, _rtw_mi_intf_start);
  646. }
  647. static u8 _rtw_mi_intf_stop(_adapter *adapter, void *data)
  648. {
  649. rtw_intf_stop(adapter);
  650. return _TRUE;
  651. }
  652. void rtw_mi_intf_stop(_adapter *adapter)
  653. {
  654. _rtw_mi_process(adapter, _FALSE, NULL, _rtw_mi_intf_stop);
  655. }
  656. void rtw_mi_buddy_intf_stop(_adapter *adapter)
  657. {
  658. _rtw_mi_process(adapter, _TRUE, NULL, _rtw_mi_intf_stop);
  659. }
  660. #ifdef CONFIG_NEW_NETDEV_HDL
  661. static u8 _rtw_mi_hal_iface_init(_adapter *padapter, void *data)
  662. {
  663. if (rtw_hal_iface_init(padapter) == _SUCCESS)
  664. return _TRUE;
  665. return _FALSE;
  666. }
  667. u8 rtw_mi_hal_iface_init(_adapter *padapter)
  668. {
  669. int i;
  670. _adapter *iface;
  671. struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
  672. u8 ret = _TRUE;
  673. for (i = 0; i < dvobj->iface_nums; i++) {
  674. iface = dvobj->padapters[i];
  675. if (iface && iface->netif_up)
  676. rtw_hal_iface_init(padapter);
  677. }
  678. return ret;
  679. }
  680. #endif
  681. static u8 _rtw_mi_suspend_free_assoc_resource(_adapter *padapter, void *data)
  682. {
  683. return rtw_suspend_free_assoc_resource(padapter);
  684. }
  685. void rtw_mi_suspend_free_assoc_resource(_adapter *adapter)
  686. {
  687. _rtw_mi_process(adapter, _FALSE, NULL, _rtw_mi_suspend_free_assoc_resource);
  688. }
  689. void rtw_mi_buddy_suspend_free_assoc_resource(_adapter *adapter)
  690. {
  691. _rtw_mi_process(adapter, _TRUE, NULL, _rtw_mi_suspend_free_assoc_resource);
  692. }
  693. static u8 _rtw_mi_is_scan_deny(_adapter *adapter, void *data)
  694. {
  695. return rtw_is_scan_deny(adapter);
  696. }
  697. u8 rtw_mi_is_scan_deny(_adapter *adapter)
  698. {
  699. return _rtw_mi_process(adapter, _FALSE, NULL, _rtw_mi_is_scan_deny);
  700. }
  701. u8 rtw_mi_buddy_is_scan_deny(_adapter *adapter)
  702. {
  703. return _rtw_mi_process(adapter, _TRUE, NULL, _rtw_mi_is_scan_deny);
  704. }
  705. #ifdef CONFIG_SET_SCAN_DENY_TIMER
  706. static u8 _rtw_mi_set_scan_deny(_adapter *adapter, void *data)
  707. {
  708. u32 ms = *(u32 *)data;
  709. rtw_set_scan_deny(adapter, ms);
  710. return _TRUE;
  711. }
  712. void rtw_mi_set_scan_deny(_adapter *adapter, u32 ms)
  713. {
  714. u32 in_data = ms;
  715. _rtw_mi_process(adapter, _FALSE, &in_data, _rtw_mi_set_scan_deny);
  716. }
  717. void rtw_mi_buddy_set_scan_deny(_adapter *adapter, u32 ms)
  718. {
  719. u32 in_data = ms;
  720. _rtw_mi_process(adapter, _TRUE, &in_data, _rtw_mi_set_scan_deny);
  721. }
  722. #endif /*CONFIG_SET_SCAN_DENY_TIMER*/
  723. static u8 _rtw_mi_beacon_update(_adapter *padapter, void *data)
  724. {
  725. if (!MLME_IS_STA(padapter)
  726. && check_fwstate(&padapter->mlmepriv, _FW_LINKED) == _TRUE) {
  727. RTW_INFO(ADPT_FMT" - update_beacon\n", ADPT_ARG(padapter));
  728. update_beacon(padapter, 0xFF, NULL, _TRUE);
  729. }
  730. return _TRUE;
  731. }
  732. void rtw_mi_beacon_update(_adapter *padapter)
  733. {
  734. _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_beacon_update);
  735. }
  736. void rtw_mi_buddy_beacon_update(_adapter *padapter)
  737. {
  738. _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_beacon_update);
  739. }
  740. static u8 _rtw_mi_hal_dump_macaddr(_adapter *padapter, void *data)
  741. {
  742. u8 mac_addr[ETH_ALEN] = {0};
  743. rtw_hal_get_hwreg(padapter, HW_VAR_MAC_ADDR, mac_addr);
  744. RTW_INFO(ADPT_FMT"MAC Address ="MAC_FMT"\n", ADPT_ARG(padapter), MAC_ARG(mac_addr));
  745. return _TRUE;
  746. }
  747. void rtw_mi_hal_dump_macaddr(_adapter *padapter)
  748. {
  749. _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_hal_dump_macaddr);
  750. }
  751. void rtw_mi_buddy_hal_dump_macaddr(_adapter *padapter)
  752. {
  753. _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_hal_dump_macaddr);
  754. }
  755. #ifdef CONFIG_PCI_HCI
  756. static u8 _rtw_mi_xmit_tasklet_schedule(_adapter *padapter, void *data)
  757. {
  758. if (rtw_txframes_pending(padapter)) {
  759. /* try to deal with the pending packets */
  760. tasklet_hi_schedule(&(padapter->xmitpriv.xmit_tasklet));
  761. }
  762. return _TRUE;
  763. }
  764. void rtw_mi_xmit_tasklet_schedule(_adapter *padapter)
  765. {
  766. _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_xmit_tasklet_schedule);
  767. }
  768. void rtw_mi_buddy_xmit_tasklet_schedule(_adapter *padapter)
  769. {
  770. _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_xmit_tasklet_schedule);
  771. }
  772. #endif
  773. u8 _rtw_mi_busy_traffic_check(_adapter *padapter, void *data)
  774. {
  775. u32 passtime;
  776. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  777. bool check_sc_interval = *(bool *)data;
  778. if (pmlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE) {
  779. if (check_sc_interval) {
  780. /* Miracast can't do AP scan*/
  781. passtime = rtw_get_passing_time_ms(pmlmepriv->lastscantime);
  782. pmlmepriv->lastscantime = rtw_get_current_time();
  783. if (passtime > BUSY_TRAFFIC_SCAN_DENY_PERIOD) {
  784. RTW_INFO(ADPT_FMT" bBusyTraffic == _TRUE\n", ADPT_ARG(padapter));
  785. return _TRUE;
  786. }
  787. } else
  788. return _TRUE;
  789. }
  790. return _FALSE;
  791. }
  792. u8 rtw_mi_busy_traffic_check(_adapter *padapter, bool check_sc_interval)
  793. {
  794. bool in_data = check_sc_interval;
  795. return _rtw_mi_process(padapter, _FALSE, &in_data, _rtw_mi_busy_traffic_check);
  796. }
  797. u8 rtw_mi_buddy_busy_traffic_check(_adapter *padapter, bool check_sc_interval)
  798. {
  799. bool in_data = check_sc_interval;
  800. return _rtw_mi_process(padapter, _TRUE, &in_data, _rtw_mi_busy_traffic_check);
  801. }
  802. static u8 _rtw_mi_check_mlmeinfo_state(_adapter *padapter, void *data)
  803. {
  804. u32 state = *(u32 *)data;
  805. struct mlme_ext_priv *mlmeext = &padapter->mlmeextpriv;
  806. /*if (mlmeext_msr(mlmeext) == state)*/
  807. if (check_mlmeinfo_state(mlmeext, state))
  808. return _TRUE;
  809. else
  810. return _FALSE;
  811. }
  812. u8 rtw_mi_check_mlmeinfo_state(_adapter *padapter, u32 state)
  813. {
  814. u32 in_data = state;
  815. return _rtw_mi_process(padapter, _FALSE, &in_data, _rtw_mi_check_mlmeinfo_state);
  816. }
  817. u8 rtw_mi_buddy_check_mlmeinfo_state(_adapter *padapter, u32 state)
  818. {
  819. u32 in_data = state;
  820. return _rtw_mi_process(padapter, _TRUE, &in_data, _rtw_mi_check_mlmeinfo_state);
  821. }
  822. /*#define DBG_DUMP_FW_STATE*/
  823. #ifdef DBG_DUMP_FW_STATE
  824. static void rtw_dbg_dump_fwstate(_adapter *padapter, sint state)
  825. {
  826. u8 buf[32] = {0};
  827. if (state & WIFI_FW_NULL_STATE) {
  828. _rtw_memset(buf, 0, 32);
  829. sprintf(buf, "WIFI_FW_NULL_STATE");
  830. RTW_INFO(FUNC_ADPT_FMT"fwstate-%s\n", FUNC_ADPT_ARG(padapter), buf);
  831. }
  832. if (state & _FW_LINKED) {
  833. _rtw_memset(buf, 0, 32);
  834. sprintf(buf, "_FW_LINKED");
  835. RTW_INFO(FUNC_ADPT_FMT"fwstate-%s\n", FUNC_ADPT_ARG(padapter), buf);
  836. }
  837. if (state & _FW_UNDER_LINKING) {
  838. _rtw_memset(buf, 0, 32);
  839. sprintf(buf, "_FW_UNDER_LINKING");
  840. RTW_INFO(FUNC_ADPT_FMT"fwstate-%s\n", FUNC_ADPT_ARG(padapter), buf);
  841. }
  842. if (state & _FW_UNDER_SURVEY) {
  843. _rtw_memset(buf, 0, 32);
  844. sprintf(buf, "_FW_UNDER_SURVEY");
  845. RTW_INFO(FUNC_ADPT_FMT"fwstate-%s\n", FUNC_ADPT_ARG(padapter), buf);
  846. }
  847. }
  848. #endif
  849. static u8 _rtw_mi_check_fwstate(_adapter *padapter, void *data)
  850. {
  851. u8 ret = _FALSE;
  852. sint state = *(sint *)data;
  853. if ((state == WIFI_FW_NULL_STATE) &&
  854. (padapter->mlmepriv.fw_state == WIFI_FW_NULL_STATE))
  855. ret = _TRUE;
  856. else if (_TRUE == check_fwstate(&padapter->mlmepriv, state))
  857. ret = _TRUE;
  858. #ifdef DBG_DUMP_FW_STATE
  859. if (ret)
  860. rtw_dbg_dump_fwstate(padapter, state);
  861. #endif
  862. return ret;
  863. }
  864. u8 rtw_mi_check_fwstate(_adapter *padapter, sint state)
  865. {
  866. sint in_data = state;
  867. return _rtw_mi_process(padapter, _FALSE, &in_data, _rtw_mi_check_fwstate);
  868. }
  869. u8 rtw_mi_buddy_check_fwstate(_adapter *padapter, sint state)
  870. {
  871. sint in_data = state;
  872. return _rtw_mi_process(padapter, _TRUE, &in_data, _rtw_mi_check_fwstate);
  873. }
  874. static u8 _rtw_mi_traffic_statistics(_adapter *padapter , void *data)
  875. {
  876. struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
  877. /* Tx */
  878. pdvobjpriv->traffic_stat.tx_bytes += padapter->xmitpriv.tx_bytes;
  879. pdvobjpriv->traffic_stat.tx_pkts += padapter->xmitpriv.tx_pkts;
  880. pdvobjpriv->traffic_stat.tx_drop += padapter->xmitpriv.tx_drop;
  881. /* Rx */
  882. pdvobjpriv->traffic_stat.rx_bytes += padapter->recvpriv.rx_bytes;
  883. pdvobjpriv->traffic_stat.rx_pkts += padapter->recvpriv.rx_pkts;
  884. pdvobjpriv->traffic_stat.rx_drop += padapter->recvpriv.rx_drop;
  885. return _TRUE;
  886. }
  887. u8 rtw_mi_traffic_statistics(_adapter *padapter)
  888. {
  889. return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_traffic_statistics);
  890. }
  891. static u8 _rtw_mi_check_miracast_enabled(_adapter *padapter , void *data)
  892. {
  893. return is_miracast_enabled(padapter);
  894. }
  895. u8 rtw_mi_check_miracast_enabled(_adapter *padapter)
  896. {
  897. return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_check_miracast_enabled);
  898. }
  899. #ifdef CONFIG_XMIT_THREAD_MODE
  900. static u8 _rtw_mi_check_pending_xmitbuf(_adapter *padapter , void *data)
  901. {
  902. struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
  903. return check_pending_xmitbuf(pxmitpriv);
  904. }
  905. u8 rtw_mi_check_pending_xmitbuf(_adapter *padapter)
  906. {
  907. return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_check_pending_xmitbuf);
  908. }
  909. u8 rtw_mi_buddy_check_pending_xmitbuf(_adapter *padapter)
  910. {
  911. return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_check_pending_xmitbuf);
  912. }
  913. #endif
  914. #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
  915. static u8 _rtw_mi_dequeue_writeport(_adapter *padapter , bool exclude_self)
  916. {
  917. int i;
  918. u8 queue_empty = _TRUE;
  919. _adapter *iface;
  920. struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
  921. for (i = 0; i < dvobj->iface_nums; i++) {
  922. iface = dvobj->padapters[i];
  923. if ((iface) && rtw_is_adapter_up(iface)) {
  924. if ((exclude_self) && (iface == padapter))
  925. continue;
  926. queue_empty &= _dequeue_writeport(iface);
  927. }
  928. }
  929. return queue_empty;
  930. }
  931. u8 rtw_mi_dequeue_writeport(_adapter *padapter)
  932. {
  933. return _rtw_mi_dequeue_writeport(padapter, _FALSE);
  934. }
  935. u8 rtw_mi_buddy_dequeue_writeport(_adapter *padapter)
  936. {
  937. return _rtw_mi_dequeue_writeport(padapter, _TRUE);
  938. }
  939. #endif
  940. static void _rtw_mi_adapter_reset(_adapter *padapter , u8 exclude_self)
  941. {
  942. int i;
  943. struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
  944. for (i = 0; i < dvobj->iface_nums; i++) {
  945. if (dvobj->padapters[i]) {
  946. if ((exclude_self) && (dvobj->padapters[i] == padapter))
  947. continue;
  948. dvobj->padapters[i] = NULL;
  949. }
  950. }
  951. }
  952. void rtw_mi_adapter_reset(_adapter *padapter)
  953. {
  954. _rtw_mi_adapter_reset(padapter, _FALSE);
  955. }
  956. void rtw_mi_buddy_adapter_reset(_adapter *padapter)
  957. {
  958. _rtw_mi_adapter_reset(padapter, _TRUE);
  959. }
  960. static u8 _rtw_mi_dynamic_check_timer_handlder(_adapter *adapter, void *data)
  961. {
  962. rtw_iface_dynamic_check_timer_handlder(adapter);
  963. return _TRUE;
  964. }
  965. u8 rtw_mi_dynamic_check_timer_handlder(_adapter *padapter)
  966. {
  967. return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_dynamic_check_timer_handlder);
  968. }
  969. u8 rtw_mi_buddy_dynamic_check_timer_handlder(_adapter *padapter)
  970. {
  971. return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_dynamic_check_timer_handlder);
  972. }
  973. static u8 _rtw_mi_dynamic_chk_wk_hdl(_adapter *adapter, void *data)
  974. {
  975. rtw_iface_dynamic_chk_wk_hdl(adapter);
  976. return _TRUE;
  977. }
  978. u8 rtw_mi_dynamic_chk_wk_hdl(_adapter *padapter)
  979. {
  980. return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_dynamic_chk_wk_hdl);
  981. }
  982. u8 rtw_mi_buddy_dynamic_chk_wk_hdl(_adapter *padapter)
  983. {
  984. return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_dynamic_chk_wk_hdl);
  985. }
  986. static u8 _rtw_mi_os_xmit_schedule(_adapter *adapter, void *data)
  987. {
  988. rtw_os_xmit_schedule(adapter);
  989. return _TRUE;
  990. }
  991. u8 rtw_mi_os_xmit_schedule(_adapter *padapter)
  992. {
  993. return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_os_xmit_schedule);
  994. }
  995. u8 rtw_mi_buddy_os_xmit_schedule(_adapter *padapter)
  996. {
  997. return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_os_xmit_schedule);
  998. }
  999. static u8 _rtw_mi_report_survey_event(_adapter *adapter, void *data)
  1000. {
  1001. union recv_frame *precv_frame = (union recv_frame *)data;
  1002. report_survey_event(adapter, precv_frame);
  1003. return _TRUE;
  1004. }
  1005. u8 rtw_mi_report_survey_event(_adapter *padapter, union recv_frame *precv_frame)
  1006. {
  1007. return _rtw_mi_process(padapter, _FALSE, precv_frame, _rtw_mi_report_survey_event);
  1008. }
  1009. u8 rtw_mi_buddy_report_survey_event(_adapter *padapter, union recv_frame *precv_frame)
  1010. {
  1011. return _rtw_mi_process(padapter, _TRUE, precv_frame, _rtw_mi_report_survey_event);
  1012. }
  1013. static u8 _rtw_mi_sreset_adapter_hdl(_adapter *adapter, void *data)
  1014. {
  1015. u8 bstart = *(u8 *)data;
  1016. if (bstart)
  1017. sreset_start_adapter(adapter);
  1018. else
  1019. sreset_stop_adapter(adapter);
  1020. return _TRUE;
  1021. }
  1022. u8 rtw_mi_sreset_adapter_hdl(_adapter *padapter, u8 bstart)
  1023. {
  1024. u8 in_data = bstart;
  1025. return _rtw_mi_process(padapter, _FALSE, &in_data, _rtw_mi_sreset_adapter_hdl);
  1026. }
  1027. #if defined(DBG_CONFIG_ERROR_RESET) && defined(CONFIG_CONCURRENT_MODE)
  1028. void rtw_mi_ap_info_restore(_adapter *adapter)
  1029. {
  1030. int i;
  1031. _adapter *iface;
  1032. struct mlme_priv *pmlmepriv;
  1033. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  1034. for (i = 0; i < dvobj->iface_nums; i++) {
  1035. iface = dvobj->padapters[i];
  1036. if (iface) {
  1037. pmlmepriv = &iface->mlmepriv;
  1038. if (MLME_IS_AP(iface) || MLME_IS_MESH(iface)) {
  1039. RTW_INFO(FUNC_ADPT_FMT" %s\n", FUNC_ADPT_ARG(iface), MLME_IS_AP(iface) ? "AP" : "MESH");
  1040. rtw_iface_bcmc_sec_cam_map_restore(iface);
  1041. }
  1042. }
  1043. }
  1044. }
  1045. #endif /*#if defined(DBG_CONFIG_ERROR_RESET) && defined(CONFIG_CONCURRENT_MODE)*/
  1046. u8 rtw_mi_buddy_sreset_adapter_hdl(_adapter *padapter, u8 bstart)
  1047. {
  1048. u8 in_data = bstart;
  1049. return _rtw_mi_process(padapter, _TRUE, &in_data, _rtw_mi_sreset_adapter_hdl);
  1050. }
  1051. static u8 _rtw_mi_tx_beacon_hdl(_adapter *adapter, void *data)
  1052. {
  1053. if ((MLME_IS_AP(adapter) || MLME_IS_MESH(adapter))
  1054. && check_fwstate(&adapter->mlmepriv, WIFI_ASOC_STATE) == _TRUE
  1055. ) {
  1056. adapter->mlmepriv.update_bcn = _TRUE;
  1057. #ifndef CONFIG_INTERRUPT_BASED_TXBCN
  1058. #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
  1059. tx_beacon_hdl(adapter, NULL);
  1060. #endif
  1061. #endif
  1062. }
  1063. return _TRUE;
  1064. }
  1065. u8 rtw_mi_tx_beacon_hdl(_adapter *padapter)
  1066. {
  1067. return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_tx_beacon_hdl);
  1068. }
  1069. u8 rtw_mi_buddy_tx_beacon_hdl(_adapter *padapter)
  1070. {
  1071. return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_sreset_adapter_hdl);
  1072. }
  1073. static u8 _rtw_mi_set_tx_beacon_cmd(_adapter *adapter, void *data)
  1074. {
  1075. struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
  1076. if (MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)) {
  1077. if (pmlmepriv->update_bcn == _TRUE)
  1078. set_tx_beacon_cmd(adapter);
  1079. }
  1080. return _TRUE;
  1081. }
  1082. u8 rtw_mi_set_tx_beacon_cmd(_adapter *padapter)
  1083. {
  1084. return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_set_tx_beacon_cmd);
  1085. }
  1086. u8 rtw_mi_buddy_set_tx_beacon_cmd(_adapter *padapter)
  1087. {
  1088. return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_set_tx_beacon_cmd);
  1089. }
  1090. #ifdef CONFIG_P2P
  1091. static u8 _rtw_mi_p2p_chk_state(_adapter *adapter, void *data)
  1092. {
  1093. struct wifidirect_info *pwdinfo = &(adapter->wdinfo);
  1094. enum P2P_STATE state = *(enum P2P_STATE *)data;
  1095. return rtw_p2p_chk_state(pwdinfo, state);
  1096. }
  1097. u8 rtw_mi_p2p_chk_state(_adapter *padapter, enum P2P_STATE p2p_state)
  1098. {
  1099. u8 in_data = p2p_state;
  1100. return _rtw_mi_process(padapter, _FALSE, &in_data, _rtw_mi_p2p_chk_state);
  1101. }
  1102. u8 rtw_mi_buddy_p2p_chk_state(_adapter *padapter, enum P2P_STATE p2p_state)
  1103. {
  1104. u8 in_data = p2p_state;
  1105. return _rtw_mi_process(padapter, _TRUE, &in_data, _rtw_mi_p2p_chk_state);
  1106. }
  1107. static u8 _rtw_mi_stay_in_p2p_mode(_adapter *adapter, void *data)
  1108. {
  1109. struct wifidirect_info *pwdinfo = &(adapter->wdinfo);
  1110. if (rtw_p2p_role(pwdinfo) != P2P_ROLE_DISABLE)
  1111. return _TRUE;
  1112. return _FALSE;
  1113. }
  1114. u8 rtw_mi_stay_in_p2p_mode(_adapter *padapter)
  1115. {
  1116. return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_stay_in_p2p_mode);
  1117. }
  1118. u8 rtw_mi_buddy_stay_in_p2p_mode(_adapter *padapter)
  1119. {
  1120. return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_stay_in_p2p_mode);
  1121. }
  1122. #endif /*CONFIG_P2P*/
  1123. _adapter *rtw_get_iface_by_id(_adapter *padapter, u8 iface_id)
  1124. {
  1125. _adapter *iface = NULL;
  1126. struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
  1127. if ((padapter == NULL) || (iface_id >= CONFIG_IFACE_NUMBER)) {
  1128. rtw_warn_on(1);
  1129. return iface;
  1130. }
  1131. return dvobj->padapters[iface_id];
  1132. }
  1133. _adapter *rtw_get_iface_by_macddr(_adapter *padapter, const u8 *mac_addr)
  1134. {
  1135. int i;
  1136. _adapter *iface = NULL;
  1137. u8 bmatch = _FALSE;
  1138. struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
  1139. for (i = 0; i < dvobj->iface_nums; i++) {
  1140. iface = dvobj->padapters[i];
  1141. if ((iface) && (_rtw_memcmp(mac_addr, adapter_mac_addr(iface), ETH_ALEN))) {
  1142. bmatch = _TRUE;
  1143. break;
  1144. }
  1145. }
  1146. if (bmatch)
  1147. return iface;
  1148. else
  1149. return NULL;
  1150. }
  1151. _adapter *rtw_get_iface_by_hwport(_adapter *padapter, u8 hw_port)
  1152. {
  1153. int i;
  1154. _adapter *iface = NULL;
  1155. u8 bmatch = _FALSE;
  1156. struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
  1157. for (i = 0; i < dvobj->iface_nums; i++) {
  1158. iface = dvobj->padapters[i];
  1159. if ((iface) && (hw_port == iface->hw_port)) {
  1160. bmatch = _TRUE;
  1161. break;
  1162. }
  1163. }
  1164. if (bmatch)
  1165. return iface;
  1166. else
  1167. return NULL;
  1168. }
  1169. /*#define CONFIG_SKB_ALLOCATED*/
  1170. #define DBG_SKB_PROCESS
  1171. #ifdef DBG_SKB_PROCESS
  1172. void rtw_dbg_skb_process(_adapter *padapter, union recv_frame *precvframe, union recv_frame *pcloneframe)
  1173. {
  1174. _pkt *pkt_copy, *pkt_org;
  1175. pkt_org = precvframe->u.hdr.pkt;
  1176. pkt_copy = pcloneframe->u.hdr.pkt;
  1177. /*
  1178. RTW_INFO("%s ===== ORG SKB =====\n", __func__);
  1179. RTW_INFO(" SKB head(%p)\n", pkt_org->head);
  1180. RTW_INFO(" SKB data(%p)\n", pkt_org->data);
  1181. RTW_INFO(" SKB tail(%p)\n", pkt_org->tail);
  1182. RTW_INFO(" SKB end(%p)\n", pkt_org->end);
  1183. RTW_INFO(" recv frame head(%p)\n", precvframe->u.hdr.rx_head);
  1184. RTW_INFO(" recv frame data(%p)\n", precvframe->u.hdr.rx_data);
  1185. RTW_INFO(" recv frame tail(%p)\n", precvframe->u.hdr.rx_tail);
  1186. RTW_INFO(" recv frame end(%p)\n", precvframe->u.hdr.rx_end);
  1187. RTW_INFO("%s ===== COPY SKB =====\n", __func__);
  1188. RTW_INFO(" SKB head(%p)\n", pkt_copy->head);
  1189. RTW_INFO(" SKB data(%p)\n", pkt_copy->data);
  1190. RTW_INFO(" SKB tail(%p)\n", pkt_copy->tail);
  1191. RTW_INFO(" SKB end(%p)\n", pkt_copy->end);
  1192. RTW_INFO(" recv frame head(%p)\n", pcloneframe->u.hdr.rx_head);
  1193. RTW_INFO(" recv frame data(%p)\n", pcloneframe->u.hdr.rx_data);
  1194. RTW_INFO(" recv frame tail(%p)\n", pcloneframe->u.hdr.rx_tail);
  1195. RTW_INFO(" recv frame end(%p)\n", pcloneframe->u.hdr.rx_end);
  1196. */
  1197. /*
  1198. RTW_INFO("%s => recv_frame adapter(%p,%p)\n", __func__, precvframe->u.hdr.adapter, pcloneframe->u.hdr.adapter);
  1199. RTW_INFO("%s => recv_frame dev(%p,%p)\n", __func__, pkt_org->dev , pkt_copy->dev);
  1200. RTW_INFO("%s => recv_frame len(%d,%d)\n", __func__, precvframe->u.hdr.len, pcloneframe->u.hdr.len);
  1201. */
  1202. if (precvframe->u.hdr.len != pcloneframe->u.hdr.len)
  1203. RTW_INFO("%s [WARN] recv_frame length(%d:%d) compare failed\n", __func__, precvframe->u.hdr.len, pcloneframe->u.hdr.len);
  1204. if (_rtw_memcmp(&precvframe->u.hdr.attrib, &pcloneframe->u.hdr.attrib, sizeof(struct rx_pkt_attrib)) == _FALSE)
  1205. RTW_INFO("%s [WARN] recv_frame attrib compare failed\n", __func__);
  1206. if (_rtw_memcmp(precvframe->u.hdr.rx_data, pcloneframe->u.hdr.rx_data, precvframe->u.hdr.len) == _FALSE)
  1207. RTW_INFO("%s [WARN] recv_frame rx_data compare failed\n", __func__);
  1208. }
  1209. #endif
  1210. static s32 _rtw_mi_buddy_clone_bcmc_packet(_adapter *adapter, union recv_frame *precvframe, u8 *pphy_status, union recv_frame *pcloneframe)
  1211. {
  1212. s32 ret = _SUCCESS;
  1213. #ifdef CONFIG_SKB_ALLOCATED
  1214. u8 *pbuf = precvframe->u.hdr.rx_data;
  1215. #endif
  1216. struct rx_pkt_attrib *pattrib = NULL;
  1217. if (pcloneframe) {
  1218. pcloneframe->u.hdr.adapter = adapter;
  1219. _rtw_init_listhead(&pcloneframe->u.hdr.list);
  1220. pcloneframe->u.hdr.precvbuf = NULL; /*can't access the precvbuf for new arch.*/
  1221. pcloneframe->u.hdr.len = 0;
  1222. _rtw_memcpy(&pcloneframe->u.hdr.attrib, &precvframe->u.hdr.attrib, sizeof(struct rx_pkt_attrib));
  1223. pattrib = &pcloneframe->u.hdr.attrib;
  1224. #ifdef CONFIG_SKB_ALLOCATED
  1225. if (rtw_os_alloc_recvframe(adapter, pcloneframe, pbuf, NULL) == _SUCCESS)
  1226. #else
  1227. if (rtw_os_recvframe_duplicate_skb(adapter, pcloneframe, precvframe->u.hdr.pkt) == _SUCCESS)
  1228. #endif
  1229. {
  1230. #ifdef CONFIG_SKB_ALLOCATED
  1231. recvframe_put(pcloneframe, pattrib->pkt_len);
  1232. #endif
  1233. #ifdef DBG_SKB_PROCESS
  1234. rtw_dbg_skb_process(adapter, precvframe, pcloneframe);
  1235. #endif
  1236. if (pphy_status)
  1237. rx_query_phy_status(pcloneframe, pphy_status);
  1238. ret = rtw_recv_entry(pcloneframe);
  1239. } else {
  1240. ret = -1;
  1241. RTW_INFO("%s()-%d: rtw_os_alloc_recvframe() failed!\n", __func__, __LINE__);
  1242. }
  1243. }
  1244. return ret;
  1245. }
  1246. void rtw_mi_buddy_clone_bcmc_packet(_adapter *padapter, union recv_frame *precvframe, u8 *pphy_status)
  1247. {
  1248. int i;
  1249. s32 ret = _SUCCESS;
  1250. _adapter *iface = NULL;
  1251. union recv_frame *pcloneframe = NULL;
  1252. struct recv_priv *precvpriv = &padapter->recvpriv;/*primary_padapter*/
  1253. _queue *pfree_recv_queue = &precvpriv->free_recv_queue;
  1254. struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
  1255. u8 *fhead = get_recvframe_data(precvframe);
  1256. u8 type = GetFrameType(fhead);
  1257. for (i = 0; i < dvobj->iface_nums; i++) {
  1258. iface = dvobj->padapters[i];
  1259. if (!iface || iface == padapter)
  1260. continue;
  1261. if (rtw_is_adapter_up(iface) == _FALSE || iface->registered == 0)
  1262. continue;
  1263. if (type == WIFI_DATA_TYPE && !adapter_allow_bmc_data_rx(iface))
  1264. continue;
  1265. pcloneframe = rtw_alloc_recvframe(pfree_recv_queue);
  1266. if (pcloneframe) {
  1267. ret = _rtw_mi_buddy_clone_bcmc_packet(iface, precvframe, pphy_status, pcloneframe);
  1268. if (_SUCCESS != ret) {
  1269. if (ret == -1)
  1270. rtw_free_recvframe(pcloneframe, pfree_recv_queue);
  1271. /*RTW_INFO(ADPT_FMT"-clone BC/MC frame failed\n", ADPT_ARG(iface));*/
  1272. }
  1273. }
  1274. }
  1275. }
  1276. #ifdef CONFIG_PCI_HCI
  1277. /*API be created temporary for MI, caller is interrupt-handler, PCIE's interrupt handler cannot apply to multi-AP*/
  1278. _adapter *rtw_mi_get_ap_adapter(_adapter *padapter)
  1279. {
  1280. struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
  1281. int i;
  1282. _adapter *iface = NULL;
  1283. for (i = 0; i < dvobj->iface_nums; i++) {
  1284. iface = dvobj->padapters[i];
  1285. if (!iface)
  1286. continue;
  1287. if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE
  1288. && check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE)
  1289. break;
  1290. }
  1291. return iface;
  1292. }
  1293. #endif
  1294. u8 rtw_mi_get_ld_sta_ifbmp(_adapter *adapter)
  1295. {
  1296. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  1297. int i;
  1298. _adapter *iface = NULL;
  1299. u8 ifbmp = 0;
  1300. for (i = 0; i < dvobj->iface_nums; i++) {
  1301. iface = dvobj->padapters[i];
  1302. if (!iface)
  1303. continue;
  1304. if (MLME_IS_STA(iface) && MLME_IS_ASOC(iface))
  1305. ifbmp |= BIT(i);
  1306. }
  1307. return ifbmp;
  1308. }
  1309. u8 rtw_mi_get_ap_mesh_ifbmp(_adapter *adapter)
  1310. {
  1311. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  1312. int i;
  1313. _adapter *iface = NULL;
  1314. u8 ifbmp = 0;
  1315. for (i = 0; i < dvobj->iface_nums; i++) {
  1316. iface = dvobj->padapters[i];
  1317. if (!iface)
  1318. continue;
  1319. if (CHK_MLME_STATE(iface, WIFI_AP_STATE | WIFI_MESH_STATE)
  1320. && MLME_IS_ASOC(iface))
  1321. ifbmp |= BIT(i);
  1322. }
  1323. return ifbmp;
  1324. }
  1325. void rtw_mi_update_ap_bmc_camid(_adapter *padapter, u8 camid_a, u8 camid_b)
  1326. {
  1327. #ifdef CONFIG_CONCURRENT_MODE
  1328. struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
  1329. struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
  1330. int i;
  1331. _adapter *iface = NULL;
  1332. for (i = 0; i < dvobj->iface_nums; i++) {
  1333. iface = dvobj->padapters[i];
  1334. if (!iface)
  1335. continue;
  1336. if (macid_ctl->iface_bmc[iface->iface_id] != INVALID_SEC_MAC_CAM_ID) {
  1337. if (macid_ctl->iface_bmc[iface->iface_id] == camid_a)
  1338. macid_ctl->iface_bmc[iface->iface_id] = camid_b;
  1339. else if (macid_ctl->iface_bmc[iface->iface_id] == camid_b)
  1340. macid_ctl->iface_bmc[iface->iface_id] = camid_a;
  1341. iface->securitypriv.dot118021x_bmc_cam_id = macid_ctl->iface_bmc[iface->iface_id];
  1342. }
  1343. }
  1344. #endif
  1345. }
  1346. u8 rtw_mi_get_assoc_if_num(_adapter *adapter)
  1347. {
  1348. struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
  1349. u8 n_assoc_iface = 0;
  1350. #if 1
  1351. u8 i;
  1352. for (i = 0; i < dvobj->iface_nums; i++) {
  1353. if (check_fwstate(&(dvobj->padapters[i]->mlmepriv), WIFI_ASOC_STATE))
  1354. n_assoc_iface++;
  1355. }
  1356. #else
  1357. n_assoc_iface = DEV_STA_LD_NUM(dvobj) + DEV_AP_NUM(dvobj) + DEV_ADHOC_NUM(dvobj) + DEV_MESH_NUM(dvobj);
  1358. #endif
  1359. return n_assoc_iface;
  1360. }