rtw_ioctl_set.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919
  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_IOCTL_SET_C_
  16. #include <drv_types.h>
  17. #include <hal_data.h>
  18. extern void indicate_wx_scan_complete_event(_adapter *padapter);
  19. #define IS_MAC_ADDRESS_BROADCAST(addr) \
  20. (\
  21. ((addr[0] == 0xff) && (addr[1] == 0xff) && \
  22. (addr[2] == 0xff) && (addr[3] == 0xff) && \
  23. (addr[4] == 0xff) && (addr[5] == 0xff)) ? _TRUE : _FALSE \
  24. )
  25. u8 rtw_validate_bssid(u8 *bssid)
  26. {
  27. u8 ret = _TRUE;
  28. if (is_zero_mac_addr(bssid)
  29. || is_broadcast_mac_addr(bssid)
  30. || is_multicast_mac_addr(bssid)
  31. )
  32. ret = _FALSE;
  33. return ret;
  34. }
  35. u8 rtw_validate_ssid(NDIS_802_11_SSID *ssid)
  36. {
  37. #ifdef CONFIG_VALIDATE_SSID
  38. u8 i;
  39. #endif
  40. u8 ret = _TRUE;
  41. if (ssid->SsidLength > 32) {
  42. ret = _FALSE;
  43. goto exit;
  44. }
  45. #ifdef CONFIG_VALIDATE_SSID
  46. for (i = 0; i < ssid->SsidLength; i++) {
  47. /* wifi, printable ascii code must be supported */
  48. if (!((ssid->Ssid[i] >= 0x20) && (ssid->Ssid[i] <= 0x7e))) {
  49. ret = _FALSE;
  50. break;
  51. }
  52. }
  53. #endif /* CONFIG_VALIDATE_SSID */
  54. exit:
  55. return ret;
  56. }
  57. u8 rtw_do_join(_adapter *padapter);
  58. u8 rtw_do_join(_adapter *padapter)
  59. {
  60. _irqL irqL;
  61. _list *plist, *phead;
  62. u8 *pibss = NULL;
  63. struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
  64. struct sitesurvey_parm parm;
  65. _queue *queue = &(pmlmepriv->scanned_queue);
  66. u8 ret = _SUCCESS;
  67. _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
  68. phead = get_list_head(queue);
  69. plist = get_next(phead);
  70. pmlmepriv->cur_network.join_res = -2;
  71. set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
  72. pmlmepriv->pscanned = plist;
  73. pmlmepriv->to_join = _TRUE;
  74. rtw_init_sitesurvey_parm(padapter, &parm);
  75. _rtw_memcpy(&parm.ssid[0], &pmlmepriv->assoc_ssid, sizeof(NDIS_802_11_SSID));
  76. parm.ssid_num = 1;
  77. if (_rtw_queue_empty(queue) == _TRUE) {
  78. _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
  79. _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
  80. /* when set_ssid/set_bssid for rtw_do_join(), but scanning queue is empty */
  81. /* we try to issue sitesurvey firstly */
  82. if (pmlmepriv->LinkDetectInfo.bBusyTraffic == _FALSE
  83. || rtw_to_roam(padapter) > 0
  84. ) {
  85. u8 ssc_chk = rtw_sitesurvey_condition_check(padapter, _FALSE);
  86. if ((ssc_chk == SS_ALLOW) || (ssc_chk == SS_DENY_BUSY_TRAFFIC) ){
  87. /* submit site_survey_cmd */
  88. ret = rtw_sitesurvey_cmd(padapter, &parm);
  89. if (_SUCCESS != ret)
  90. pmlmepriv->to_join = _FALSE;
  91. } else {
  92. /*if (ssc_chk == SS_DENY_BUDDY_UNDER_SURVEY)*/
  93. pmlmepriv->to_join = _FALSE;
  94. ret = _FAIL;
  95. }
  96. } else {
  97. pmlmepriv->to_join = _FALSE;
  98. ret = _FAIL;
  99. }
  100. goto exit;
  101. } else {
  102. int select_ret;
  103. _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
  104. select_ret = rtw_select_and_join_from_scanned_queue(pmlmepriv);
  105. if (select_ret == _SUCCESS) {
  106. pmlmepriv->to_join = _FALSE;
  107. _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT);
  108. } else {
  109. if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) {
  110. /* submit createbss_cmd to change to a ADHOC_MASTER */
  111. /* pmlmepriv->lock has been acquired by caller... */
  112. WLAN_BSSID_EX *pdev_network = &(padapter->registrypriv.dev_network);
  113. /*pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;*/
  114. init_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
  115. pibss = padapter->registrypriv.dev_network.MacAddress;
  116. _rtw_memset(&pdev_network->Ssid, 0, sizeof(NDIS_802_11_SSID));
  117. _rtw_memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(NDIS_802_11_SSID));
  118. rtw_update_registrypriv_dev_network(padapter);
  119. rtw_generate_random_ibss(pibss);
  120. if (rtw_create_ibss_cmd(padapter, 0) != _SUCCESS) {
  121. ret = _FALSE;
  122. goto exit;
  123. }
  124. pmlmepriv->to_join = _FALSE;
  125. } else {
  126. /* can't associate ; reset under-linking */
  127. _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
  128. /* when set_ssid/set_bssid for rtw_do_join(), but there are no desired bss in scanning queue */
  129. /* we try to issue sitesurvey firstly */
  130. if (pmlmepriv->LinkDetectInfo.bBusyTraffic == _FALSE
  131. || rtw_to_roam(padapter) > 0
  132. ) {
  133. u8 ssc_chk = rtw_sitesurvey_condition_check(padapter, _FALSE);
  134. if ((ssc_chk == SS_ALLOW) || (ssc_chk == SS_DENY_BUSY_TRAFFIC)){
  135. /* RTW_INFO(("rtw_do_join() when no desired bss in scanning queue\n"); */
  136. ret = rtw_sitesurvey_cmd(padapter, &parm);
  137. if (_SUCCESS != ret)
  138. pmlmepriv->to_join = _FALSE;
  139. } else {
  140. /*if (ssc_chk == SS_DENY_BUDDY_UNDER_SURVEY) {
  141. } else {*/
  142. ret = _FAIL;
  143. pmlmepriv->to_join = _FALSE;
  144. }
  145. } else {
  146. ret = _FAIL;
  147. pmlmepriv->to_join = _FALSE;
  148. }
  149. }
  150. }
  151. }
  152. exit:
  153. return ret;
  154. }
  155. #ifdef PLATFORM_WINDOWS
  156. u8 rtw_pnp_set_power_wakeup(_adapter *padapter)
  157. {
  158. u8 res = _SUCCESS;
  159. res = rtw_setstandby_cmd(padapter, 0);
  160. return res;
  161. }
  162. u8 rtw_pnp_set_power_sleep(_adapter *padapter)
  163. {
  164. u8 res = _SUCCESS;
  165. /* DbgPrint("+rtw_pnp_set_power_sleep\n"); */
  166. res = rtw_setstandby_cmd(padapter, 1);
  167. return res;
  168. }
  169. u8 rtw_set_802_11_reload_defaults(_adapter *padapter, NDIS_802_11_RELOAD_DEFAULTS reloadDefaults)
  170. {
  171. /* SecClearAllKeys(Adapter); */
  172. /* 8711 CAM was not for En/Decrypt only */
  173. /* so, we can't clear all keys. */
  174. /* should we disable WPAcfg (ox0088) bit 1-2, instead of clear all CAM */
  175. /* TO DO... */
  176. return _TRUE;
  177. }
  178. u8 set_802_11_test(_adapter *padapter, NDIS_802_11_TEST *test)
  179. {
  180. u8 ret = _TRUE;
  181. switch (test->Type) {
  182. case 1:
  183. NdisMIndicateStatus(padapter->hndis_adapter, NDIS_STATUS_MEDIA_SPECIFIC_INDICATION, (PVOID)&test->AuthenticationEvent, test->Length - 8);
  184. NdisMIndicateStatusComplete(padapter->hndis_adapter);
  185. break;
  186. case 2:
  187. NdisMIndicateStatus(padapter->hndis_adapter, NDIS_STATUS_MEDIA_SPECIFIC_INDICATION, (PVOID)&test->RssiTrigger, sizeof(NDIS_802_11_RSSI));
  188. NdisMIndicateStatusComplete(padapter->hndis_adapter);
  189. break;
  190. default:
  191. ret = _FALSE;
  192. break;
  193. }
  194. return ret;
  195. }
  196. u8 rtw_set_802_11_pmkid(_adapter *padapter, NDIS_802_11_PMKID *pmkid)
  197. {
  198. u8 ret = _SUCCESS;
  199. return ret;
  200. }
  201. #endif
  202. u8 rtw_set_802_11_bssid(_adapter *padapter, u8 *bssid)
  203. {
  204. _irqL irqL;
  205. u8 status = _SUCCESS;
  206. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  207. RTW_PRINT("set bssid:%pM\n", bssid);
  208. if ((bssid[0] == 0x00 && bssid[1] == 0x00 && bssid[2] == 0x00 && bssid[3] == 0x00 && bssid[4] == 0x00 && bssid[5] == 0x00) ||
  209. (bssid[0] == 0xFF && bssid[1] == 0xFF && bssid[2] == 0xFF && bssid[3] == 0xFF && bssid[4] == 0xFF && bssid[5] == 0xFF)) {
  210. status = _FAIL;
  211. goto exit;
  212. }
  213. _enter_critical_bh(&pmlmepriv->lock, &irqL);
  214. RTW_INFO("Set BSSID under fw_state=0x%08x\n", get_fwstate(pmlmepriv));
  215. if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE)
  216. goto handle_tkip_countermeasure;
  217. else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE)
  218. goto release_mlme_lock;
  219. if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE) == _TRUE) {
  220. if (_rtw_memcmp(&pmlmepriv->cur_network.network.MacAddress, bssid, ETH_ALEN) == _TRUE) {
  221. if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _FALSE)
  222. goto release_mlme_lock;/* it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. */
  223. } else {
  224. rtw_disassoc_cmd(padapter, 0, 0);
  225. if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
  226. rtw_indicate_disconnect(padapter, 0, _FALSE);
  227. rtw_free_assoc_resources_cmd(padapter, _TRUE, 0);
  228. if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)) {
  229. _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
  230. set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
  231. }
  232. }
  233. }
  234. handle_tkip_countermeasure:
  235. if (rtw_handle_tkip_countermeasure(padapter, __func__) == _FAIL) {
  236. status = _FAIL;
  237. goto release_mlme_lock;
  238. }
  239. _rtw_memset(&pmlmepriv->assoc_ssid, 0, sizeof(NDIS_802_11_SSID));
  240. _rtw_memcpy(&pmlmepriv->assoc_bssid, bssid, ETH_ALEN);
  241. pmlmepriv->assoc_by_bssid = _TRUE;
  242. if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE)
  243. pmlmepriv->to_join = _TRUE;
  244. else
  245. status = rtw_do_join(padapter);
  246. release_mlme_lock:
  247. _exit_critical_bh(&pmlmepriv->lock, &irqL);
  248. exit:
  249. return status;
  250. }
  251. u8 rtw_set_802_11_ssid(_adapter *padapter, NDIS_802_11_SSID *ssid)
  252. {
  253. _irqL irqL;
  254. u8 status = _SUCCESS;
  255. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  256. struct wlan_network *pnetwork = &pmlmepriv->cur_network;
  257. RTW_PRINT("set ssid [%s] fw_state=0x%08x\n",
  258. ssid->Ssid, get_fwstate(pmlmepriv));
  259. if (!rtw_is_hw_init_completed(padapter)) {
  260. status = _FAIL;
  261. goto exit;
  262. }
  263. _enter_critical_bh(&pmlmepriv->lock, &irqL);
  264. RTW_INFO("Set SSID under fw_state=0x%08x\n", get_fwstate(pmlmepriv));
  265. if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE)
  266. goto handle_tkip_countermeasure;
  267. else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE)
  268. goto release_mlme_lock;
  269. if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE) == _TRUE) {
  270. if ((pmlmepriv->assoc_ssid.SsidLength == ssid->SsidLength) &&
  271. (_rtw_memcmp(&pmlmepriv->assoc_ssid.Ssid, ssid->Ssid, ssid->SsidLength) == _TRUE)) {
  272. if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _FALSE)) {
  273. if (rtw_is_same_ibss(padapter, pnetwork) == _FALSE) {
  274. /* if in WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE, create bss or rejoin again */
  275. rtw_disassoc_cmd(padapter, 0, 0);
  276. if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
  277. rtw_indicate_disconnect(padapter, 0, _FALSE);
  278. rtw_free_assoc_resources_cmd(padapter, _TRUE, 0);
  279. if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) {
  280. _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
  281. set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
  282. }
  283. } else {
  284. goto release_mlme_lock;/* it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. */
  285. }
  286. }
  287. #ifdef CONFIG_LPS
  288. else
  289. rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_JOINBSS, 1);
  290. #endif
  291. } else {
  292. rtw_disassoc_cmd(padapter, 0, 0);
  293. if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
  294. rtw_indicate_disconnect(padapter, 0, _FALSE);
  295. rtw_free_assoc_resources_cmd(padapter, _TRUE, 0);
  296. if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) {
  297. _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
  298. set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
  299. }
  300. }
  301. }
  302. handle_tkip_countermeasure:
  303. if (rtw_handle_tkip_countermeasure(padapter, __func__) == _FAIL) {
  304. status = _FAIL;
  305. goto release_mlme_lock;
  306. }
  307. if (rtw_validate_ssid(ssid) == _FALSE) {
  308. status = _FAIL;
  309. goto release_mlme_lock;
  310. }
  311. _rtw_memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(NDIS_802_11_SSID));
  312. pmlmepriv->assoc_by_bssid = _FALSE;
  313. if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE)
  314. pmlmepriv->to_join = _TRUE;
  315. else
  316. status = rtw_do_join(padapter);
  317. release_mlme_lock:
  318. _exit_critical_bh(&pmlmepriv->lock, &irqL);
  319. exit:
  320. return status;
  321. }
  322. u8 rtw_set_802_11_connect(_adapter *padapter, u8 *bssid, NDIS_802_11_SSID *ssid)
  323. {
  324. _irqL irqL;
  325. u8 status = _SUCCESS;
  326. bool bssid_valid = _TRUE;
  327. bool ssid_valid = _TRUE;
  328. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  329. if (!ssid || rtw_validate_ssid(ssid) == _FALSE)
  330. ssid_valid = _FALSE;
  331. if (!bssid || rtw_validate_bssid(bssid) == _FALSE)
  332. bssid_valid = _FALSE;
  333. if (ssid_valid == _FALSE && bssid_valid == _FALSE) {
  334. RTW_INFO(FUNC_ADPT_FMT" ssid:%p, ssid_valid:%d, bssid:%p, bssid_valid:%d\n",
  335. FUNC_ADPT_ARG(padapter), ssid, ssid_valid, bssid, bssid_valid);
  336. status = _FAIL;
  337. goto exit;
  338. }
  339. if (!rtw_is_hw_init_completed(padapter)) {
  340. status = _FAIL;
  341. goto exit;
  342. }
  343. _enter_critical_bh(&pmlmepriv->lock, &irqL);
  344. RTW_PRINT(FUNC_ADPT_FMT" fw_state=0x%08x\n",
  345. FUNC_ADPT_ARG(padapter), get_fwstate(pmlmepriv));
  346. if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE)
  347. goto handle_tkip_countermeasure;
  348. else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE)
  349. goto release_mlme_lock;
  350. handle_tkip_countermeasure:
  351. if (rtw_handle_tkip_countermeasure(padapter, __func__) == _FAIL) {
  352. status = _FAIL;
  353. goto release_mlme_lock;
  354. }
  355. if (ssid && ssid_valid)
  356. _rtw_memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(NDIS_802_11_SSID));
  357. else
  358. _rtw_memset(&pmlmepriv->assoc_ssid, 0, sizeof(NDIS_802_11_SSID));
  359. if (bssid && bssid_valid) {
  360. _rtw_memcpy(&pmlmepriv->assoc_bssid, bssid, ETH_ALEN);
  361. pmlmepriv->assoc_by_bssid = _TRUE;
  362. } else
  363. pmlmepriv->assoc_by_bssid = _FALSE;
  364. if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE)
  365. pmlmepriv->to_join = _TRUE;
  366. else
  367. status = rtw_do_join(padapter);
  368. release_mlme_lock:
  369. _exit_critical_bh(&pmlmepriv->lock, &irqL);
  370. exit:
  371. return status;
  372. }
  373. u8 rtw_set_802_11_infrastructure_mode(_adapter *padapter,
  374. NDIS_802_11_NETWORK_INFRASTRUCTURE networktype)
  375. {
  376. _irqL irqL;
  377. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  378. struct wlan_network *cur_network = &pmlmepriv->cur_network;
  379. NDIS_802_11_NETWORK_INFRASTRUCTURE *pold_state = &(cur_network->network.InfrastructureMode);
  380. u8 ap2sta_mode = _FALSE;
  381. u8 ret = _TRUE;
  382. if (*pold_state != networktype) {
  383. /* RTW_INFO("change mode, old_mode=%d, new_mode=%d, fw_state=0x%x\n", *pold_state, networktype, get_fwstate(pmlmepriv)); */
  384. if (*pold_state == Ndis802_11APMode
  385. || *pold_state == Ndis802_11_mesh
  386. ) {
  387. /* change to other mode from Ndis802_11APMode/Ndis802_11_mesh */
  388. cur_network->join_res = -1;
  389. ap2sta_mode = _TRUE;
  390. #ifdef CONFIG_NATIVEAP_MLME
  391. stop_ap_mode(padapter);
  392. #endif
  393. }
  394. _enter_critical_bh(&pmlmepriv->lock, &irqL);
  395. if ((check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) || (*pold_state == Ndis802_11IBSS))
  396. rtw_disassoc_cmd(padapter, 0, 0);
  397. if ((check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) ||
  398. (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE))
  399. rtw_free_assoc_resources_cmd(padapter, _TRUE, 0);
  400. if ((*pold_state == Ndis802_11Infrastructure) || (*pold_state == Ndis802_11IBSS)) {
  401. if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
  402. rtw_indicate_disconnect(padapter, 0, _FALSE); /*will clr Linked_state; before this function, we must have checked whether issue dis-assoc_cmd or not*/
  403. }
  404. }
  405. *pold_state = networktype;
  406. _clr_fwstate_(pmlmepriv, ~WIFI_NULL_STATE);
  407. switch (networktype) {
  408. case Ndis802_11IBSS:
  409. set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
  410. break;
  411. case Ndis802_11Infrastructure:
  412. set_fwstate(pmlmepriv, WIFI_STATION_STATE);
  413. if (ap2sta_mode)
  414. rtw_init_bcmc_stainfo(padapter);
  415. break;
  416. case Ndis802_11APMode:
  417. set_fwstate(pmlmepriv, WIFI_AP_STATE);
  418. #ifdef CONFIG_NATIVEAP_MLME
  419. start_ap_mode(padapter);
  420. /* rtw_indicate_connect(padapter); */
  421. #endif
  422. break;
  423. #ifdef CONFIG_RTW_MESH
  424. case Ndis802_11_mesh:
  425. set_fwstate(pmlmepriv, WIFI_MESH_STATE);
  426. start_ap_mode(padapter);
  427. break;
  428. #endif
  429. case Ndis802_11AutoUnknown:
  430. case Ndis802_11InfrastructureMax:
  431. break;
  432. case Ndis802_11Monitor:
  433. set_fwstate(pmlmepriv, WIFI_MONITOR_STATE);
  434. break;
  435. default:
  436. ret = _FALSE;
  437. rtw_warn_on(1);
  438. }
  439. /* SecClearAllKeys(adapter); */
  440. _exit_critical_bh(&pmlmepriv->lock, &irqL);
  441. }
  442. return ret;
  443. }
  444. u8 rtw_set_802_11_disassociate(_adapter *padapter)
  445. {
  446. _irqL irqL;
  447. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  448. _enter_critical_bh(&pmlmepriv->lock, &irqL);
  449. if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
  450. rtw_disassoc_cmd(padapter, 0, 0);
  451. rtw_indicate_disconnect(padapter, 0, _FALSE);
  452. /* modify for CONFIG_IEEE80211W, none 11w can use it */
  453. rtw_free_assoc_resources_cmd(padapter, _TRUE, 0);
  454. if (_FAIL == rtw_pwr_wakeup(padapter))
  455. RTW_INFO("%s(): rtw_pwr_wakeup fail !!!\n", __FUNCTION__);
  456. }
  457. _exit_critical_bh(&pmlmepriv->lock, &irqL);
  458. return _TRUE;
  459. }
  460. #if 1
  461. u8 rtw_set_802_11_bssid_list_scan(_adapter *padapter, struct sitesurvey_parm *pparm)
  462. {
  463. _irqL irqL;
  464. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  465. u8 res = _TRUE;
  466. _enter_critical_bh(&pmlmepriv->lock, &irqL);
  467. res = rtw_sitesurvey_cmd(padapter, pparm);
  468. _exit_critical_bh(&pmlmepriv->lock, &irqL);
  469. return res;
  470. }
  471. #else
  472. u8 rtw_set_802_11_bssid_list_scan(_adapter *padapter, struct sitesurvey_parm *pparm)
  473. {
  474. _irqL irqL;
  475. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  476. u8 res = _TRUE;
  477. if (padapter == NULL) {
  478. res = _FALSE;
  479. goto exit;
  480. }
  481. if (!rtw_is_hw_init_completed(padapter)) {
  482. res = _FALSE;
  483. goto exit;
  484. }
  485. if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING) == _TRUE) ||
  486. (pmlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE)) {
  487. /* Scan or linking is in progress, do nothing. */
  488. res = _TRUE;
  489. } else {
  490. if (rtw_is_scan_deny(padapter)) {
  491. RTW_INFO(FUNC_ADPT_FMT": scan deny\n", FUNC_ADPT_ARG(padapter));
  492. indicate_wx_scan_complete_event(padapter);
  493. return _SUCCESS;
  494. }
  495. _enter_critical_bh(&pmlmepriv->lock, &irqL);
  496. res = rtw_sitesurvey_cmd(padapter, pparm);
  497. _exit_critical_bh(&pmlmepriv->lock, &irqL);
  498. }
  499. exit:
  500. return res;
  501. }
  502. #endif
  503. u8 rtw_set_802_11_authentication_mode(_adapter *padapter, NDIS_802_11_AUTHENTICATION_MODE authmode)
  504. {
  505. struct security_priv *psecuritypriv = &padapter->securitypriv;
  506. int res;
  507. u8 ret;
  508. psecuritypriv->ndisauthtype = authmode;
  509. if (psecuritypriv->ndisauthtype > 3)
  510. psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
  511. #ifdef CONFIG_WAPI_SUPPORT
  512. if (psecuritypriv->ndisauthtype == 6)
  513. psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
  514. #endif
  515. res = rtw_set_auth(padapter, psecuritypriv);
  516. if (res == _SUCCESS)
  517. ret = _TRUE;
  518. else
  519. ret = _FALSE;
  520. return ret;
  521. }
  522. u8 rtw_set_802_11_add_wep(_adapter *padapter, NDIS_802_11_WEP *wep)
  523. {
  524. u8 bdefaultkey;
  525. u8 btransmitkey;
  526. sint keyid, res;
  527. struct security_priv *psecuritypriv = &(padapter->securitypriv);
  528. u8 ret = _SUCCESS;
  529. bdefaultkey = (wep->KeyIndex & 0x40000000) > 0 ? _FALSE : _TRUE; /* for ??? */
  530. btransmitkey = (wep->KeyIndex & 0x80000000) > 0 ? _TRUE : _FALSE; /* for ??? */
  531. keyid = wep->KeyIndex & 0x3fffffff;
  532. if (keyid >= 4) {
  533. ret = _FALSE;
  534. goto exit;
  535. }
  536. switch (wep->KeyLength) {
  537. case 5:
  538. psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
  539. break;
  540. case 13:
  541. psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
  542. break;
  543. default:
  544. psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
  545. break;
  546. }
  547. _rtw_memcpy(&(psecuritypriv->dot11DefKey[keyid].skey[0]), &(wep->KeyMaterial), wep->KeyLength);
  548. psecuritypriv->dot11DefKeylen[keyid] = wep->KeyLength;
  549. psecuritypriv->dot11PrivacyKeyIndex = keyid;
  550. res = rtw_set_key(padapter, psecuritypriv, keyid, 1, _TRUE);
  551. if (res == _FAIL)
  552. ret = _FALSE;
  553. exit:
  554. return ret;
  555. }
  556. /*
  557. * rtw_get_cur_max_rate -
  558. * @adapter: pointer to _adapter structure
  559. *
  560. * Return 0 or 100Kbps
  561. */
  562. u16 rtw_get_cur_max_rate(_adapter *adapter)
  563. {
  564. int j;
  565. int i = 0;
  566. u16 rate = 0, max_rate = 0;
  567. struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
  568. WLAN_BSSID_EX *pcur_bss = &pmlmepriv->cur_network.network;
  569. int sta_bssrate_len = 0;
  570. unsigned char sta_bssrate[NumRates];
  571. struct sta_info *psta = NULL;
  572. u8 short_GI = 0;
  573. #ifdef CONFIG_80211N_HT
  574. u8 rf_type = 0;
  575. #endif
  576. #ifdef CONFIG_MP_INCLUDED
  577. if (adapter->registrypriv.mp_mode == 1) {
  578. if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE)
  579. return 0;
  580. }
  581. #endif
  582. if ((check_fwstate(pmlmepriv, _FW_LINKED) != _TRUE)
  583. && (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) != _TRUE))
  584. return 0;
  585. psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
  586. if (psta == NULL)
  587. return 0;
  588. short_GI = query_ra_short_GI(psta, rtw_get_tx_bw_mode(adapter, psta));
  589. #ifdef CONFIG_80211N_HT
  590. if (is_supported_ht(psta->wireless_mode)) {
  591. rtw_hal_get_hwreg(adapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
  592. max_rate = rtw_mcs_rate(rf_type
  593. , (psta->cmn.bw_mode == CHANNEL_WIDTH_40) ? 1 : 0
  594. , short_GI
  595. , psta->htpriv.ht_cap.supp_mcs_set
  596. );
  597. }
  598. #ifdef CONFIG_80211AC_VHT
  599. else if (is_supported_vht(psta->wireless_mode))
  600. max_rate = ((rtw_vht_mcs_to_data_rate(psta->cmn.bw_mode, short_GI, pmlmepriv->vhtpriv.vht_highest_rate) + 1) >> 1) * 10;
  601. #endif /* CONFIG_80211AC_VHT */
  602. else
  603. #endif /* CONFIG_80211N_HT */
  604. {
  605. /*station mode show :station && ap support rate; softap :show ap support rate*/
  606. if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
  607. get_rate_set(adapter, sta_bssrate, &sta_bssrate_len);/*get sta rate and length*/
  608. while ((pcur_bss->SupportedRates[i] != 0) && (pcur_bss->SupportedRates[i] != 0xFF)) {
  609. rate = pcur_bss->SupportedRates[i] & 0x7F;/*AP support rates*/
  610. /*RTW_INFO("%s rate=%02X \n", __func__, rate);*/
  611. /*check STA support rate or not */
  612. if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) {
  613. for (j = 0; j < sta_bssrate_len; j++) {
  614. /* Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP */
  615. if ((rate | IEEE80211_BASIC_RATE_MASK)
  616. == (sta_bssrate[j] | IEEE80211_BASIC_RATE_MASK)) {
  617. if (rate > max_rate) {
  618. max_rate = rate;
  619. }
  620. break;
  621. }
  622. }
  623. } else {
  624. if (rate > max_rate)
  625. max_rate = rate;
  626. }
  627. i++;
  628. }
  629. max_rate = max_rate * 10 / 2;
  630. }
  631. return max_rate;
  632. }
  633. /*
  634. * rtw_set_scan_mode -
  635. * @adapter: pointer to _adapter structure
  636. * @scan_mode:
  637. *
  638. * Return _SUCCESS or _FAIL
  639. */
  640. int rtw_set_scan_mode(_adapter *adapter, RT_SCAN_TYPE scan_mode)
  641. {
  642. if (scan_mode != SCAN_ACTIVE && scan_mode != SCAN_PASSIVE)
  643. return _FAIL;
  644. adapter->mlmepriv.scan_mode = scan_mode;
  645. return _SUCCESS;
  646. }
  647. /*
  648. * rtw_set_channel_plan -
  649. * @adapter: pointer to _adapter structure
  650. * @channel_plan:
  651. *
  652. * Return _SUCCESS or _FAIL
  653. */
  654. int rtw_set_channel_plan(_adapter *adapter, u8 channel_plan)
  655. {
  656. /* handle by cmd_thread to sync with scan operation */
  657. return rtw_set_chplan_cmd(adapter, RTW_CMDF_WAIT_ACK, channel_plan, 1);
  658. }
  659. /*
  660. * rtw_set_country -
  661. * @adapter: pointer to _adapter structure
  662. * @country_code: string of country code
  663. *
  664. * Return _SUCCESS or _FAIL
  665. */
  666. int rtw_set_country(_adapter *adapter, const char *country_code)
  667. {
  668. #ifdef CONFIG_RTW_IOCTL_SET_COUNTRY
  669. return rtw_set_country_cmd(adapter, RTW_CMDF_WAIT_ACK, country_code, 1);
  670. #else
  671. RTW_INFO("%s(): not applied\n", __func__);
  672. return _SUCCESS;
  673. #endif
  674. }
  675. /*
  676. * rtw_set_band -
  677. * @adapter: pointer to _adapter structure
  678. * @band: band to set
  679. *
  680. * Return _SUCCESS or _FAIL
  681. */
  682. int rtw_set_band(_adapter *adapter, u8 band)
  683. {
  684. if (rtw_band_valid(band)) {
  685. RTW_INFO(FUNC_ADPT_FMT" band:%d\n", FUNC_ADPT_ARG(adapter), band);
  686. adapter->setband = band;
  687. return _SUCCESS;
  688. }
  689. RTW_PRINT(FUNC_ADPT_FMT" band:%d fail\n", FUNC_ADPT_ARG(adapter), band);
  690. return _FAIL;
  691. }