rtw_rson.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595
  1. /******************************************************************************
  2. *
  3. * Copyright(c) 2007 - 2011 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_RSON_C_
  21. #include <drv_types.h>
  22. #ifdef CONFIG_RTW_REPEATER_SON
  23. /******** Custommize Part ***********************/
  24. unsigned char RTW_RSON_OUI[] = {0xFA, 0xFA, 0xFA};
  25. #define RSON_SCORE_DIFF_TH 8
  26. /*
  27. Calculate the corresponding score.
  28. */
  29. inline u8 rtw_cal_rson_score(struct rtw_rson_struct *cand_rson_data, NDIS_802_11_RSSI Rssi)
  30. {
  31. if ((cand_rson_data->hopcnt == RTW_RSON_HC_NOTREADY)
  32. || (cand_rson_data->connectible == RTW_RSON_DENYCONNECT))
  33. return RTW_RSON_SCORE_NOTCNNT;
  34. return RTW_RSON_SCORE_MAX - (cand_rson_data->hopcnt * 10) + (Rssi/10);
  35. }
  36. /*************************************************/
  37. static u8 rtw_rson_block_bssid_idx = 0;
  38. u8 rtw_rson_block_bssid[10][6] = {
  39. /*{0x02, 0xE0, 0x4C, 0x07, 0xC3, 0xF6}*/
  40. };
  41. /* fake root, regard a real AP as a SO root */
  42. static u8 rtw_rson_root_bssid_idx = 0;
  43. u8 rtw_rson_root_bssid[10][6] = {
  44. /*{0x1c, 0x5f, 0x2b, 0x5a, 0x60, 0x24}*/
  45. };
  46. int is_match_bssid(u8 *mac, u8 bssid_array[][6], int num)
  47. {
  48. int i;
  49. for (i = 0; i < num; i++)
  50. if (_rtw_memcmp(mac, bssid_array[i], 6) == _TRUE)
  51. return _TRUE;
  52. return _FALSE;
  53. }
  54. void init_rtw_rson_data(struct dvobj_priv *dvobj)
  55. {
  56. /*Aries todo. if pdvobj->rson_data.ver == 1 */
  57. dvobj->rson_data.ver = RTW_RSON_VER;
  58. dvobj->rson_data.id = CONFIG_RTW_REPEATER_SON_ID;
  59. #ifdef CONFIG_RTW_REPEATER_SON_ROOT
  60. dvobj->rson_data.hopcnt = RTW_RSON_HC_ROOT;
  61. dvobj->rson_data.connectible = RTW_RSON_ALLOWCONNECT;
  62. #else
  63. dvobj->rson_data.hopcnt = RTW_RSON_HC_NOTREADY;
  64. dvobj->rson_data.connectible = RTW_RSON_DENYCONNECT;
  65. #endif
  66. dvobj->rson_data.loading = 0;
  67. _rtw_memset(dvobj->rson_data.res, 0xAA, sizeof(dvobj->rson_data.res));
  68. }
  69. void rtw_rson_get_property_str(_adapter *padapter, char *rson_data_str)
  70. {
  71. struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
  72. sprintf(rson_data_str, "version : \t%d\nid : \t\t%08x\nhop count : \t%d\nconnectible : \t%s\nloading : \t%d\nreserve : \t%16ph\n",
  73. pdvobj->rson_data.ver,
  74. pdvobj->rson_data.id,
  75. pdvobj->rson_data.hopcnt,
  76. pdvobj->rson_data.connectible ? "connectable":"unconnectable",
  77. pdvobj->rson_data.loading,
  78. pdvobj->rson_data.res);
  79. }
  80. int str2hexbuf(char *str, u8 *hexbuf, int len)
  81. {
  82. u8 *p;
  83. int i, slen, idx = 0;
  84. p = (unsigned char *)str;
  85. if ((*p != '0') || (*(p+1) != 'x'))
  86. return _FALSE;
  87. slen = strlen(str);
  88. if (slen > (len*2) + 2)
  89. return _FALSE;
  90. p += 2;
  91. for (i = 0 ; i < len; i++, idx = idx+2) {
  92. hexbuf[i] = key_2char2num(p[idx], p[idx + 1]);
  93. if (slen <= idx+2)
  94. break;
  95. }
  96. return _TRUE;
  97. }
  98. int rtw_rson_set_property(_adapter *padapter, char *field, char *value)
  99. {
  100. struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
  101. int num = 0;
  102. if (_rtw_memcmp(field, (u8 *)"ver", 3) == _TRUE)
  103. pdvobj->rson_data.ver = rtw_atoi(value);
  104. else if (_rtw_memcmp(field, (u8 *)"id", 2) == _TRUE)
  105. num = sscanf(value, "%08x", &(pdvobj->rson_data.id));
  106. else if (_rtw_memcmp(field, (u8 *)"hc", 2) == _TRUE)
  107. num = sscanf(value, "%hhu", &(pdvobj->rson_data.hopcnt));
  108. else if (_rtw_memcmp(field, (u8 *)"cnt", 3) == _TRUE)
  109. num = sscanf(value, "%hhu", &(pdvobj->rson_data.connectible));
  110. else if (_rtw_memcmp(field, (u8 *)"loading", 2) == _TRUE)
  111. num = sscanf(value, "%hhu", &(pdvobj->rson_data.loading));
  112. else if (_rtw_memcmp(field, (u8 *)"res", 2) == _TRUE) {
  113. str2hexbuf(value, pdvobj->rson_data.res, 16);
  114. return 1;
  115. } else
  116. return _FALSE;
  117. return num;
  118. }
  119. /*
  120. return : TRUE -- competitor is taking advantage than condidate
  121. FALSE -- we should continue keeping candidate
  122. */
  123. int rtw_rson_choose(struct wlan_network **candidate, struct wlan_network *competitor)
  124. {
  125. s16 comp_score = 0, cand_score = 0;
  126. struct rtw_rson_struct rson_cand, rson_comp;
  127. if (is_match_bssid(competitor->network.MacAddress, rtw_rson_block_bssid, rtw_rson_block_bssid_idx) == _TRUE)
  128. return _FALSE;
  129. if ((competitor == NULL)
  130. || (rtw_get_rson_struct(&(competitor->network), &rson_comp) != _TRUE)
  131. || (rson_comp.id != CONFIG_RTW_REPEATER_SON_ID))
  132. return _FALSE;
  133. comp_score = rtw_cal_rson_score(&rson_comp, competitor->network.Rssi);
  134. if (comp_score == RTW_RSON_SCORE_NOTCNNT)
  135. return _FALSE;
  136. if (*candidate == NULL)
  137. return _TRUE;
  138. if (rtw_get_rson_struct(&((*candidate)->network), &rson_cand) != _TRUE)
  139. return _FALSE;
  140. cand_score = rtw_cal_rson_score(&rson_cand, (*candidate)->network.Rssi);
  141. RTW_INFO("%s: competitor_score=%d, candidate_score=%d\n", __func__, comp_score, cand_score);
  142. if (comp_score - cand_score > RSON_SCORE_DIFF_TH)
  143. return _TRUE;
  144. return _FALSE;
  145. }
  146. inline u8 rtw_rson_varify_ie(u8 *p)
  147. {
  148. u8 *ptr = NULL;
  149. u8 ver;
  150. u32 id;
  151. u8 hopcnt;
  152. u8 allcnnt;
  153. ptr = p + 2 + sizeof(RTW_RSON_OUI);
  154. ver = *ptr;
  155. /* for (ver == 1) */
  156. if (ver != 1)
  157. return _FALSE;
  158. return _TRUE;
  159. }
  160. /*
  161. Parsing RTK self-organization vendor IE
  162. */
  163. int rtw_get_rson_struct(WLAN_BSSID_EX *bssid, struct rtw_rson_struct *rson_data)
  164. {
  165. sint limit = 0;
  166. u32 len;
  167. u8 *p;
  168. if ((rson_data == NULL) || (bssid == NULL))
  169. return -EINVAL;
  170. /* Default */
  171. rson_data->id = 0;
  172. rson_data->ver = 0;
  173. rson_data->hopcnt = 0;
  174. rson_data->connectible = 0;
  175. rson_data->loading = 0;
  176. /* fake root */
  177. if (is_match_bssid(bssid->MacAddress, rtw_rson_root_bssid, rtw_rson_root_bssid_idx) == _TRUE) {
  178. rson_data->id = CONFIG_RTW_REPEATER_SON_ID;
  179. rson_data->ver = RTW_RSON_VER;
  180. rson_data->hopcnt = RTW_RSON_HC_ROOT;
  181. rson_data->connectible = RTW_RSON_ALLOWCONNECT;
  182. rson_data->loading = 0;
  183. return _TRUE;
  184. }
  185. limit = bssid->IELength - _BEACON_IE_OFFSET_;
  186. for (p = bssid->IEs + _BEACON_IE_OFFSET_; ; p += (len + 2)) {
  187. p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &len, limit);
  188. limit -= len;
  189. if ((p == NULL) || (len == 0))
  190. break;
  191. if (p && (_rtw_memcmp(p + 2, RTW_RSON_OUI, sizeof(RTW_RSON_OUI)) == _TRUE)
  192. && rtw_rson_varify_ie(p)) {
  193. p = p + 2 + sizeof(RTW_RSON_OUI);
  194. rson_data->ver = *p;
  195. /* for (ver == 1) */
  196. p = p + 1;
  197. rson_data->id = le32_to_cpup((__le32 *)p);
  198. p = p + 4;
  199. rson_data->hopcnt = *p;
  200. p = p + 1;
  201. rson_data->connectible = *p;
  202. p = p + 1;
  203. rson_data->loading = *p;
  204. return _TRUE;
  205. }
  206. }
  207. return -EBADMSG;
  208. }
  209. u32 rtw_rson_append_ie(_adapter *padapter, unsigned char *pframe, u32 *len)
  210. {
  211. u8 *ptr, *ori, ie_len = 0;
  212. struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
  213. struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
  214. /* static int iii = 0;*/
  215. if ((!pdvobj) || (!pframe))
  216. return 0;
  217. ptr = ori = pframe;
  218. *ptr++ = _VENDOR_SPECIFIC_IE_;
  219. *ptr++ = ie_len = sizeof(RTW_RSON_OUI)+sizeof(pdvobj->rson_data);
  220. _rtw_memcpy(ptr, RTW_RSON_OUI, sizeof(RTW_RSON_OUI));
  221. ptr = ptr + sizeof(RTW_RSON_OUI);
  222. *ptr++ = pdvobj->rson_data.ver;
  223. *(s32 *)ptr = cpu_to_le32(pdvobj->rson_data.id);
  224. ptr = ptr + sizeof(pdvobj->rson_data.id);
  225. *ptr++ = pdvobj->rson_data.hopcnt;
  226. *ptr++ = pdvobj->rson_data.connectible;
  227. *ptr++ = pdvobj->rson_data.loading;
  228. _rtw_memcpy(ptr, pdvobj->rson_data.res, sizeof(pdvobj->rson_data.res));
  229. pframe = ptr;
  230. /*
  231. iii = iii % 20;
  232. if (iii++ == 0)
  233. RTW_INFO("%s : RTW RSON IE : %20ph\n", __func__, ori);
  234. */
  235. *len += (ie_len+2);
  236. return ie_len;
  237. }
  238. void rtw_rson_do_disconnect(_adapter *padapter)
  239. {
  240. struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
  241. RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
  242. #ifndef CONFIG_RTW_REPEATER_SON_ROOT
  243. pdvobj->rson_data.ver = RTW_RSON_VER;
  244. pdvobj->rson_data.id = CONFIG_RTW_REPEATER_SON_ID;
  245. pdvobj->rson_data.hopcnt = RTW_RSON_HC_NOTREADY;
  246. pdvobj->rson_data.connectible = RTW_RSON_DENYCONNECT;
  247. pdvobj->rson_data.loading = 0;
  248. rtw_mi_tx_beacon_hdl(padapter);
  249. #endif
  250. }
  251. void rtw_rson_join_done(_adapter *padapter)
  252. {
  253. struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
  254. WLAN_BSSID_EX *cur_network = NULL;
  255. struct rtw_rson_struct rson_data;
  256. RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
  257. if (!padapter->mlmepriv.cur_network_scanned)
  258. return;
  259. cur_network = &(padapter->mlmepriv.cur_network_scanned->network);
  260. if (rtw_get_rson_struct(cur_network, &rson_data) != _TRUE) {
  261. RTW_ERR("%s: try to join a improper network(%s)\n", __func__, cur_network->Ssid.Ssid);
  262. return;
  263. }
  264. #ifndef CONFIG_RTW_REPEATER_SON_ROOT
  265. /* update rson_data */
  266. pdvobj->rson_data.ver = RTW_RSON_VER;
  267. pdvobj->rson_data.id = rson_data.id;
  268. pdvobj->rson_data.hopcnt = rson_data.hopcnt + 1;
  269. pdvobj->rson_data.connectible = RTW_RSON_ALLOWCONNECT;
  270. pdvobj->rson_data.loading = 0;
  271. rtw_mi_tx_beacon_hdl(padapter);
  272. #endif
  273. }
  274. int rtw_rson_isupdate_roamcan(struct mlme_priv *mlme
  275. , struct wlan_network **candidate, struct wlan_network *competitor)
  276. {
  277. struct rtw_rson_struct rson_cand, rson_comp, rson_curr;
  278. s16 comp_score, cand_score, curr_score;
  279. if ((competitor == NULL)
  280. || (rtw_get_rson_struct(&(competitor->network), &rson_comp) != _TRUE)
  281. || (rson_comp.id != CONFIG_RTW_REPEATER_SON_ID))
  282. return _FALSE;
  283. if (is_match_bssid(competitor->network.MacAddress, rtw_rson_block_bssid, rtw_rson_block_bssid_idx) == _TRUE)
  284. return _FALSE;
  285. if ((!mlme->cur_network_scanned)
  286. || (mlme->cur_network_scanned == competitor)
  287. || (rtw_get_rson_struct(&(mlme->cur_network_scanned->network), &rson_curr)) != _TRUE)
  288. return _FALSE;
  289. if (rtw_get_passing_time_ms((u32)competitor->last_scanned) >= mlme->roam_scanr_exp_ms)
  290. return _FALSE;
  291. comp_score = rtw_cal_rson_score(&rson_comp, competitor->network.Rssi);
  292. curr_score = rtw_cal_rson_score(&rson_curr, mlme->cur_network_scanned->network.Rssi);
  293. if (comp_score - curr_score < RSON_SCORE_DIFF_TH)
  294. return _FALSE;
  295. if (*candidate == NULL)
  296. return _TRUE;
  297. if (rtw_get_rson_struct(&((*candidate)->network), &rson_cand) != _TRUE) {
  298. RTW_ERR("%s : Unable to get rson_struct from candidate(%s -- " MAC_FMT")\n",
  299. __func__, (*candidate)->network.Ssid.Ssid, MAC_ARG((*candidate)->network.MacAddress));
  300. return _FALSE;
  301. }
  302. cand_score = rtw_cal_rson_score(&rson_cand, (*candidate)->network.Rssi);
  303. RTW_DBG("comp_score=%d , cand_score=%d , curr_score=%d\n", comp_score, cand_score, curr_score);
  304. if (cand_score < comp_score)
  305. return _TRUE;
  306. #if 0 /* Handle 11R protocol */
  307. #ifdef CONFIG_RTW_80211R
  308. if (rtw_chk_ft_flags(adapter, RTW_FT_SUPPORTED)) {
  309. ptmp = rtw_get_ie(&competitor->network.IEs[12], _MDIE_, &mdie_len, competitor->network.IELength-12);
  310. if (ptmp) {
  311. if (!_rtw_memcmp(&pftpriv->mdid, ptmp+2, 2))
  312. goto exit;
  313. /*The candidate don't support over-the-DS*/
  314. if (rtw_chk_ft_flags(adapter, RTW_FT_STA_OVER_DS_SUPPORTED)) {
  315. if ((rtw_chk_ft_flags(adapter, RTW_FT_OVER_DS_SUPPORTED) && !(*(ptmp+4) & 0x01)) ||
  316. (!rtw_chk_ft_flags(adapter, RTW_FT_OVER_DS_SUPPORTED) && (*(ptmp+4) & 0x01))) {
  317. RTW_INFO("FT: ignore the candidate(" MAC_FMT ") for over-the-DS\n", MAC_ARG(competitor->network.MacAddress));
  318. rtw_clr_ft_flags(adapter, RTW_FT_OVER_DS_SUPPORTED);
  319. goto exit;
  320. }
  321. }
  322. } else
  323. goto exit;
  324. }
  325. #endif
  326. #endif
  327. return _FALSE;
  328. }
  329. void rtw_rson_show_survey_info(struct seq_file *m, _list *plist, _list *phead)
  330. {
  331. struct wlan_network *pnetwork = NULL;
  332. struct rtw_rson_struct rson_data;
  333. s16 rson_score;
  334. u16 index = 0;
  335. RTW_PRINT_SEL(m, "%5s %-17s %3s %5s %14s %10s %-3s %5s %32s\n", "index", "bssid", "ch", "id", "hop_cnt", "loading", "RSSI", "score", "ssid");
  336. while (1) {
  337. if (rtw_end_of_queue_search(phead, plist) == _TRUE)
  338. break;
  339. pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
  340. if (!pnetwork)
  341. break;
  342. _rtw_memset(&rson_data, 0, sizeof(rson_data));
  343. rson_score = 0;
  344. if (rtw_get_rson_struct(&(pnetwork->network), &rson_data) == _TRUE)
  345. rson_score = rtw_cal_rson_score(&rson_data, pnetwork->network.Rssi);
  346. RTW_PRINT_SEL(m, "%5d "MAC_FMT" %3d 0x%08x %6d %10d %6d %6d %32s\n",
  347. ++index,
  348. MAC_ARG(pnetwork->network.MacAddress),
  349. pnetwork->network.Configuration.DSConfig,
  350. rson_data.id,
  351. rson_data.hopcnt,
  352. rson_data.loading,
  353. (int)pnetwork->network.Rssi,
  354. rson_score,
  355. pnetwork->network.Ssid.Ssid);
  356. plist = get_next(plist);
  357. }
  358. }
  359. /*
  360. Description : As a AP role, We need to check the qualify of associating STA.
  361. We also need to check if we are ready to be associated.
  362. return : TRUE -- AP REJECT this STA
  363. FALSE -- AP ACCEPT this STA
  364. */
  365. u8 rtw_rson_ap_check_sta(_adapter *padapter, u8 *pframe, uint pkt_len, unsigned short ie_offset)
  366. {
  367. struct wlan_network *pnetwork = NULL;
  368. struct rtw_rson_struct rson_target;
  369. struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
  370. int len = 0;
  371. u8 ret = _FALSE;
  372. u8 *p;
  373. #ifndef CONFIG_RTW_REPEATER_SON_ROOT
  374. _rtw_memset(&rson_target, 0, sizeof(rson_target));
  375. for (p = pframe + WLAN_HDR_A3_LEN + ie_offset; ; p += (len + 2)) {
  376. p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &len, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
  377. if ((p == NULL) || (len == 0))
  378. break;
  379. if (p && (_rtw_memcmp(p + 2, RTW_RSON_OUI, sizeof(RTW_RSON_OUI)) == _TRUE)
  380. && rtw_rson_varify_ie(p)) {
  381. p = p + 2 + sizeof(RTW_RSON_OUI);
  382. rson_target.ver = *p;
  383. /* for (ver == 1) */
  384. p = p + 1;
  385. rson_target.id = le32_to_cpup((__le32 *)p);
  386. p = p + 4;
  387. rson_target.hopcnt = *p;
  388. p = p + 1;
  389. rson_target.connectible = *p;
  390. p = p + 1;
  391. rson_target.loading = *p;
  392. break;
  393. }
  394. }
  395. if (rson_target.id == 0) /* Normal STA, not a RSON STA */
  396. ret = _FALSE;
  397. else if (rson_target.id != pdvobj->rson_data.id) {
  398. ret = _TRUE;
  399. RTW_INFO("%s : Reject AssoReq because RSON ID not match, STA=%08x, our=%08x\n",
  400. __func__, rson_target.id, pdvobj->rson_data.id);
  401. } else if ((pdvobj->rson_data.hopcnt == RTW_RSON_HC_NOTREADY)
  402. || (pdvobj->rson_data.connectible == RTW_RSON_DENYCONNECT)) {
  403. ret = _TRUE;
  404. RTW_INFO("%s : Reject AssoReq becuase our hopcnt=%d or connectbile=%d\n",
  405. __func__, pdvobj->rson_data.hopcnt, pdvobj->rson_data.connectible);
  406. }
  407. #endif
  408. return ret;
  409. }
  410. u8 rtw_rson_scan_wk_cmd(_adapter *padapter, int op)
  411. {
  412. struct cmd_obj *ph2c;
  413. struct drvextra_cmd_parm *pdrvextra_cmd_parm;
  414. struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
  415. u8 *extra_cmd_buf;
  416. u8 res = _SUCCESS;
  417. ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
  418. if (ph2c == NULL) {
  419. res = _FAIL;
  420. goto exit;
  421. }
  422. pdrvextra_cmd_parm = (struct drvextra_cmd_parm *)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
  423. if (pdrvextra_cmd_parm == NULL) {
  424. rtw_mfree((u8 *)ph2c, sizeof(struct cmd_obj));
  425. res = _FAIL;
  426. goto exit;
  427. }
  428. pdrvextra_cmd_parm->ec_id = RSON_SCAN_WK_CID;
  429. pdrvextra_cmd_parm->type = op;
  430. pdrvextra_cmd_parm->size = 0;
  431. pdrvextra_cmd_parm->pbuf = NULL;
  432. init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
  433. res = rtw_enqueue_cmd(pcmdpriv, ph2c);
  434. exit:
  435. return res;
  436. }
  437. void rtw_rson_scan_cmd_hdl(_adapter *padapter, int op)
  438. {
  439. struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
  440. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  441. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  442. u8 val8;
  443. if (mlmeext_chk_scan_state(pmlmeext, SCAN_DISABLE) != _TRUE)
  444. return;
  445. if (op == RSON_SCAN_PROCESS) {
  446. padapter->rtw_rson_scanstage = RSON_SCAN_PROCESS;
  447. val8 = 0x1e;
  448. rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &val8, _FALSE);
  449. val8 = 1;
  450. rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
  451. issue_probereq(padapter, NULL, NULL);
  452. /* stop rson_scan after 100ms */
  453. _set_timer(&(pmlmeext->rson_scan_timer), 100);
  454. } else if (op == RSON_SCAN_DISABLE) {
  455. padapter->rtw_rson_scanstage = RSON_SCAN_DISABLE;
  456. val8 = 0;
  457. rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
  458. val8 = 0xff;
  459. rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &val8, _FALSE);
  460. /* report_surveydone_event(padapter);*/
  461. if (pmlmepriv->to_join == _TRUE) {
  462. if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) != _TRUE) {
  463. int s_ret;
  464. set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
  465. pmlmepriv->to_join = _FALSE;
  466. s_ret = rtw_select_and_join_from_scanned_queue(pmlmepriv);
  467. if (s_ret == _SUCCESS)
  468. _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT);
  469. else if (s_ret == 2) {
  470. _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
  471. rtw_indicate_connect(padapter);
  472. } else {
  473. RTW_INFO("try_to_join, but select scanning queue fail, to_roam:%d\n", rtw_to_roam(padapter));
  474. if (rtw_to_roam(padapter) != 0) {
  475. if (rtw_dec_to_roam(padapter) == 0) {
  476. rtw_set_to_roam(padapter, 0);
  477. #ifdef CONFIG_INTEL_WIDI
  478. if (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_ROAMING) {
  479. _rtw_memset(pmlmepriv->sa_ext, 0x00, L2SDTA_SERVICE_VE_LEN);
  480. intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_WK, NULL, 0);
  481. RTW_INFO("change to widi listen\n");
  482. }
  483. #endif /* CONFIG_INTEL_WIDI */
  484. rtw_free_assoc_resources(padapter, _TRUE);
  485. rtw_indicate_disconnect(padapter, 0, _FALSE);
  486. } else
  487. pmlmepriv->to_join = _TRUE;
  488. } else
  489. rtw_indicate_disconnect(padapter, 0, _FALSE);
  490. _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
  491. }
  492. }
  493. } else {
  494. if (rtw_chk_roam_flags(padapter, RTW_ROAM_ACTIVE)) {
  495. if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)
  496. && check_fwstate(pmlmepriv, _FW_LINKED)) {
  497. if (rtw_select_roaming_candidate(pmlmepriv) == _SUCCESS) {
  498. #ifdef CONFIG_RTW_80211R
  499. if (rtw_chk_ft_flags(padapter, RTW_FT_OVER_DS_SUPPORTED)) {
  500. start_clnt_ft_action(adapter, (u8 *)pmlmepriv->roam_network->network.MacAddress);
  501. } else {
  502. /*wait a little time to retrieve packets buffered in the current ap while scan*/
  503. _set_timer(&pmlmeext->ft_roam_timer, 30);
  504. }
  505. #else
  506. receive_disconnect(padapter, pmlmepriv->cur_network.network.MacAddress
  507. , WLAN_REASON_ACTIVE_ROAM, _FALSE);
  508. #endif
  509. }
  510. }
  511. }
  512. issue_action_BSSCoexistPacket(padapter);
  513. issue_action_BSSCoexistPacket(padapter);
  514. issue_action_BSSCoexistPacket(padapter);
  515. }
  516. } else {
  517. RTW_ERR("%s : improper parameter -- op = %d\n", __func__, op);
  518. }
  519. }
  520. #endif /* CONFIG_RTW_REPEATER_SON */