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