1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#define _RTW_IOCTL_SET_C_
16
17#include <osdep_service.h>
18#include <drv_types.h>
19#include <rtw_ioctl_set.h>
20#include <hal_intf.h>
21
22extern void indicate_wx_scan_complete_event(struct adapter *padapter);
23
24u8 rtw_do_join(struct adapter *padapter)
25{
26 struct list_head *plist, *phead;
27 u8 *pibss = NULL;
28 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
29 struct __queue *queue = &(pmlmepriv->scanned_queue);
30 u8 ret = _SUCCESS;
31
32
33 spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
34 phead = get_list_head(queue);
35 plist = phead->next;
36
37 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("\n rtw_do_join: phead = %p; plist = %p\n\n\n", phead, plist));
38
39 pmlmepriv->cur_network.join_res = -2;
40
41 set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
42
43 pmlmepriv->pscanned = plist;
44
45 pmlmepriv->to_join = true;
46
47 if (list_empty(&queue->queue)) {
48 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
49 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
50
51
52
53
54 if (!pmlmepriv->LinkDetectInfo.bBusyTraffic ||
55 pmlmepriv->to_roaming > 0) {
56 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("rtw_do_join(): site survey if scanned_queue is empty\n."));
57
58 ret = rtw_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid, 1, NULL, 0);
59 if (_SUCCESS != ret) {
60 pmlmepriv->to_join = false;
61 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("rtw_do_join(): site survey return error\n."));
62 }
63 } else {
64 pmlmepriv->to_join = false;
65 ret = _FAIL;
66 }
67
68 goto exit;
69 } else {
70 int select_ret;
71
72 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
73 select_ret = rtw_select_and_join_from_scanned_queue(pmlmepriv);
74 if (select_ret == _SUCCESS) {
75 pmlmepriv->to_join = false;
76 mod_timer(&pmlmepriv->assoc_timer,
77 jiffies + msecs_to_jiffies(MAX_JOIN_TIMEOUT));
78 } else {
79 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true) {
80
81
82
83 struct wlan_bssid_ex *pdev_network = &(padapter->registrypriv.dev_network);
84
85 pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;
86
87 pibss = padapter->registrypriv.dev_network.MacAddress;
88
89 memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid));
90
91 rtw_update_registrypriv_dev_network(padapter);
92
93 rtw_generate_random_ibss(pibss);
94
95 if (rtw_createbss_cmd(padapter) != _SUCCESS) {
96 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("***Error =>do_goin: rtw_createbss_cmd status FAIL***\n "));
97 ret = false;
98 goto exit;
99 }
100 pmlmepriv->to_join = false;
101
102 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
103 ("***Error => rtw_select_and_join_from_scanned_queue FAIL under STA_Mode***\n "));
104 } else {
105
106 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
107
108
109
110 if (!pmlmepriv->LinkDetectInfo.bBusyTraffic ||
111 pmlmepriv->to_roaming > 0) {
112 ret = rtw_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid, 1, NULL, 0);
113 if (_SUCCESS != ret) {
114 pmlmepriv->to_join = false;
115 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("do_join(): site survey return error\n."));
116 }
117 } else {
118 ret = _FAIL;
119 pmlmepriv->to_join = false;
120 }
121 }
122 }
123 }
124
125exit:
126
127
128 return ret;
129}
130
131u8 rtw_set_802_11_bssid(struct adapter *padapter, u8 *bssid)
132{
133 u8 status = _SUCCESS;
134 u32 cur_time = 0;
135 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
136
137
138 DBG_88E_LEVEL(_drv_info_, "set bssid:%pM\n", bssid);
139
140 if ((bssid[0] == 0x00 && bssid[1] == 0x00 && bssid[2] == 0x00 &&
141 bssid[3] == 0x00 && bssid[4] == 0x00 && bssid[5] == 0x00) ||
142 (bssid[0] == 0xFF && bssid[1] == 0xFF && bssid[2] == 0xFF &&
143 bssid[3] == 0xFF && bssid[4] == 0xFF && bssid[5] == 0xFF)) {
144 status = _FAIL;
145 goto exit;
146 }
147
148 spin_lock_bh(&pmlmepriv->lock);
149
150
151 DBG_88E("Set BSSID under fw_state = 0x%08x\n", get_fwstate(pmlmepriv));
152 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true)
153 goto handle_tkip_countermeasure;
154 else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
155 goto release_mlme_lock;
156
157 if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE)) {
158 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_bssid: _FW_LINKED||WIFI_ADHOC_MASTER_STATE\n"));
159
160 if (!memcmp(&pmlmepriv->cur_network.network.MacAddress, bssid, ETH_ALEN)) {
161 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == false)
162 goto release_mlme_lock;
163 } else {
164 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("Set BSSID not the same bssid\n"));
165 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_bssid =%pM\n", (bssid)));
166 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("cur_bssid =%pM\n", (pmlmepriv->cur_network.network.MacAddress)));
167
168 rtw_disassoc_cmd(padapter, 0, true);
169
170 if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
171 rtw_indicate_disconnect(padapter);
172
173 rtw_free_assoc_resources(padapter);
174
175 if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true)) {
176 _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
177 set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
178 }
179 }
180 }
181
182handle_tkip_countermeasure:
183
184
185 if (padapter->securitypriv.btkip_countermeasure) {
186 cur_time = jiffies;
187
188 if ((cur_time - padapter->securitypriv.btkip_countermeasure_time) > 60 * HZ) {
189 padapter->securitypriv.btkip_countermeasure = false;
190 padapter->securitypriv.btkip_countermeasure_time = 0;
191 } else {
192 status = _FAIL;
193 goto release_mlme_lock;
194 }
195 }
196
197 memcpy(&pmlmepriv->assoc_bssid, bssid, ETH_ALEN);
198 pmlmepriv->assoc_by_bssid = true;
199
200 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
201 pmlmepriv->to_join = true;
202 else
203 status = rtw_do_join(padapter);
204
205release_mlme_lock:
206 spin_unlock_bh(&pmlmepriv->lock);
207
208exit:
209 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
210 ("rtw_set_802_11_bssid: status=%d\n", status));
211
212
213 return status;
214}
215
216u8 rtw_set_802_11_ssid(struct adapter *padapter, struct ndis_802_11_ssid *ssid)
217{
218 u8 status = _SUCCESS;
219 u32 cur_time = 0;
220
221 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
222 struct wlan_network *pnetwork = &pmlmepriv->cur_network;
223
224
225 DBG_88E_LEVEL(_drv_info_, "set ssid [%s] fw_state=0x%08x\n",
226 ssid->Ssid, get_fwstate(pmlmepriv));
227
228 if (!padapter->hw_init_completed) {
229 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
230 ("set_ssid: hw_init_completed == false =>exit!!!\n"));
231 status = _FAIL;
232 goto exit;
233 }
234
235 spin_lock_bh(&pmlmepriv->lock);
236
237 DBG_88E("Set SSID under fw_state = 0x%08x\n", get_fwstate(pmlmepriv));
238 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true)
239 goto handle_tkip_countermeasure;
240 else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true)
241 goto release_mlme_lock;
242
243 if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE)) {
244 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
245 ("set_ssid: _FW_LINKED||WIFI_ADHOC_MASTER_STATE\n"));
246
247 if ((pmlmepriv->assoc_ssid.SsidLength == ssid->SsidLength) &&
248 (!memcmp(&pmlmepriv->assoc_ssid.Ssid, ssid->Ssid, ssid->SsidLength))) {
249 if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == false)) {
250 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
251 ("Set SSID is the same ssid, fw_state = 0x%08x\n",
252 get_fwstate(pmlmepriv)));
253
254 if (!rtw_is_same_ibss(padapter, pnetwork)) {
255
256 rtw_disassoc_cmd(padapter, 0, true);
257
258 if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
259 rtw_indicate_disconnect(padapter);
260
261 rtw_free_assoc_resources(padapter);
262
263 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) {
264 _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
265 set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
266 }
267 } else {
268 goto release_mlme_lock;
269 }
270 } else {
271 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_JOINBSS, 1);
272 }
273 } else {
274 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("Set SSID not the same ssid\n"));
275 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_ssid =[%s] len = 0x%x\n", ssid->Ssid, (unsigned int)ssid->SsidLength));
276 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("assoc_ssid =[%s] len = 0x%x\n", pmlmepriv->assoc_ssid.Ssid, (unsigned int)pmlmepriv->assoc_ssid.SsidLength));
277
278 rtw_disassoc_cmd(padapter, 0, true);
279
280 if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
281 rtw_indicate_disconnect(padapter);
282
283 rtw_free_assoc_resources(padapter);
284
285 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) {
286 _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
287 set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
288 }
289 }
290 }
291
292handle_tkip_countermeasure:
293
294 if (padapter->securitypriv.btkip_countermeasure) {
295 cur_time = jiffies;
296
297 if ((cur_time - padapter->securitypriv.btkip_countermeasure_time) > 60 * HZ) {
298 padapter->securitypriv.btkip_countermeasure = false;
299 padapter->securitypriv.btkip_countermeasure_time = 0;
300 } else {
301 status = _FAIL;
302 goto release_mlme_lock;
303 }
304 }
305
306 memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(struct ndis_802_11_ssid));
307 pmlmepriv->assoc_by_bssid = false;
308
309 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true)
310 pmlmepriv->to_join = true;
311 else
312 status = rtw_do_join(padapter);
313
314release_mlme_lock:
315 spin_unlock_bh(&pmlmepriv->lock);
316
317exit:
318 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
319 ("-rtw_set_802_11_ssid: status =%d\n", status));
320 return status;
321}
322
323u8 rtw_set_802_11_infrastructure_mode(struct adapter *padapter,
324 enum ndis_802_11_network_infra networktype)
325{
326 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
327 struct wlan_network *cur_network = &pmlmepriv->cur_network;
328 enum ndis_802_11_network_infra *pold_state = &(cur_network->network.InfrastructureMode);
329
330
331 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_notice_,
332 ("+rtw_set_802_11_infrastructure_mode: old =%d new =%d fw_state = 0x%08x\n",
333 *pold_state, networktype, get_fwstate(pmlmepriv)));
334
335 if (*pold_state != networktype) {
336 spin_lock_bh(&pmlmepriv->lock);
337
338 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, (" change mode!"));
339
340
341 if (*pold_state == Ndis802_11APMode) {
342
343 cur_network->join_res = -1;
344
345#ifdef CONFIG_88EU_AP_MODE
346 stop_ap_mode(padapter);
347#endif
348 }
349
350 if ((check_fwstate(pmlmepriv, _FW_LINKED)) ||
351 (*pold_state == Ndis802_11IBSS))
352 rtw_disassoc_cmd(padapter, 0, true);
353
354 if ((check_fwstate(pmlmepriv, _FW_LINKED)) ||
355 (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)))
356 rtw_free_assoc_resources(padapter);
357
358 if ((*pold_state == Ndis802_11Infrastructure) || (*pold_state == Ndis802_11IBSS)) {
359 if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
360 rtw_indicate_disconnect(padapter);
361 }
362
363 *pold_state = networktype;
364
365 _clr_fwstate_(pmlmepriv, ~WIFI_NULL_STATE);
366
367 switch (networktype) {
368 case Ndis802_11IBSS:
369 set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
370 break;
371 case Ndis802_11Infrastructure:
372 set_fwstate(pmlmepriv, WIFI_STATION_STATE);
373 break;
374 case Ndis802_11APMode:
375 set_fwstate(pmlmepriv, WIFI_AP_STATE);
376#ifdef CONFIG_88EU_AP_MODE
377 start_ap_mode(padapter);
378#endif
379 break;
380 case Ndis802_11AutoUnknown:
381 case Ndis802_11InfrastructureMax:
382 break;
383 }
384 spin_unlock_bh(&pmlmepriv->lock);
385 }
386
387
388 return true;
389}
390
391
392u8 rtw_set_802_11_disassociate(struct adapter *padapter)
393{
394 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
395
396
397 spin_lock_bh(&pmlmepriv->lock);
398
399 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
400 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
401 ("MgntActrtw_set_802_11_disassociate: rtw_indicate_disconnect\n"));
402
403 rtw_disassoc_cmd(padapter, 0, true);
404 rtw_indicate_disconnect(padapter);
405 rtw_free_assoc_resources(padapter);
406 rtw_pwr_wakeup(padapter);
407 }
408
409 spin_unlock_bh(&pmlmepriv->lock);
410
411
412 return true;
413}
414
415u8 rtw_set_802_11_bssid_list_scan(struct adapter *padapter, struct ndis_802_11_ssid *pssid, int ssid_max_num)
416{
417 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
418 u8 res = true;
419
420
421 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("+rtw_set_802_11_bssid_list_scan(), fw_state =%x\n", get_fwstate(pmlmepriv)));
422
423 if (padapter == NULL) {
424 res = false;
425 goto exit;
426 }
427 if (!padapter->hw_init_completed) {
428 res = false;
429 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("\n === rtw_set_802_11_bssid_list_scan:hw_init_completed == false ===\n"));
430 goto exit;
431 }
432
433 if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) ||
434 (pmlmepriv->LinkDetectInfo.bBusyTraffic)) {
435
436 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("rtw_set_802_11_bssid_list_scan fail since fw_state = %x\n", get_fwstate(pmlmepriv)));
437 res = true;
438
439 if (check_fwstate(pmlmepriv,
440 (_FW_UNDER_SURVEY|_FW_UNDER_LINKING)) == true)
441 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("\n###_FW_UNDER_SURVEY|_FW_UNDER_LINKING\n\n"));
442 else
443 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("\n###pmlmepriv->sitesurveyctrl.traffic_busy == true\n\n"));
444
445 } else {
446 if (rtw_is_scan_deny(padapter)) {
447 DBG_88E(FUNC_ADPT_FMT": scan deny\n", FUNC_ADPT_ARG(padapter));
448 indicate_wx_scan_complete_event(padapter);
449 return _SUCCESS;
450 }
451
452 spin_lock_bh(&pmlmepriv->lock);
453
454 res = rtw_sitesurvey_cmd(padapter, pssid, ssid_max_num, NULL, 0);
455
456 spin_unlock_bh(&pmlmepriv->lock);
457 }
458exit:
459
460
461 return res;
462}
463
464u8 rtw_set_802_11_authentication_mode(struct adapter *padapter, enum ndis_802_11_auth_mode authmode)
465{
466 struct security_priv *psecuritypriv = &padapter->securitypriv;
467 int res;
468 u8 ret;
469
470
471 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_802_11_auth.mode(): mode =%x\n", authmode));
472
473 psecuritypriv->ndisauthtype = authmode;
474
475 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
476 ("rtw_set_802_11_authentication_mode:psecuritypriv->ndisauthtype=%d",
477 psecuritypriv->ndisauthtype));
478
479 if (psecuritypriv->ndisauthtype > 3)
480 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
481
482 res = rtw_set_auth(padapter, psecuritypriv);
483
484 if (res == _SUCCESS)
485 ret = true;
486 else
487 ret = false;
488
489
490 return ret;
491}
492
493u8 rtw_set_802_11_add_wep(struct adapter *padapter, struct ndis_802_11_wep *wep)
494{
495 int keyid, res;
496 struct security_priv *psecuritypriv = &(padapter->securitypriv);
497 u8 ret = _SUCCESS;
498
499
500 keyid = wep->KeyIndex & 0x3fffffff;
501
502 if (keyid >= 4) {
503 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("MgntActrtw_set_802_11_add_wep:keyid>4 =>fail\n"));
504 ret = false;
505 goto exit;
506 }
507
508 switch (wep->KeyLength) {
509 case 5:
510 psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
511 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("MgntActrtw_set_802_11_add_wep:wep->KeyLength = 5\n"));
512 break;
513 case 13:
514 psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
515 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("MgntActrtw_set_802_11_add_wep:wep->KeyLength = 13\n"));
516 break;
517 default:
518 psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
519 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("MgntActrtw_set_802_11_add_wep:wep->KeyLength!= 5 or 13\n"));
520 break;
521 }
522 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
523 ("rtw_set_802_11_add_wep:before memcpy, wep->KeyLength = 0x%x wep->KeyIndex = 0x%x keyid =%x\n",
524 wep->KeyLength, wep->KeyIndex, keyid));
525
526 memcpy(&(psecuritypriv->dot11DefKey[keyid].skey[0]), &(wep->KeyMaterial), wep->KeyLength);
527
528 psecuritypriv->dot11DefKeylen[keyid] = wep->KeyLength;
529
530 psecuritypriv->dot11PrivacyKeyIndex = keyid;
531
532 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
533 ("rtw_set_802_11_add_wep:security key material : %x %x %x %x %x %x %x %x %x %x %x %x %x\n",
534 psecuritypriv->dot11DefKey[keyid].skey[0],
535 psecuritypriv->dot11DefKey[keyid].skey[1],
536 psecuritypriv->dot11DefKey[keyid].skey[2],
537 psecuritypriv->dot11DefKey[keyid].skey[3],
538 psecuritypriv->dot11DefKey[keyid].skey[4],
539 psecuritypriv->dot11DefKey[keyid].skey[5],
540 psecuritypriv->dot11DefKey[keyid].skey[6],
541 psecuritypriv->dot11DefKey[keyid].skey[7],
542 psecuritypriv->dot11DefKey[keyid].skey[8],
543 psecuritypriv->dot11DefKey[keyid].skey[9],
544 psecuritypriv->dot11DefKey[keyid].skey[10],
545 psecuritypriv->dot11DefKey[keyid].skey[11],
546 psecuritypriv->dot11DefKey[keyid].skey[12]));
547
548 res = rtw_set_key(padapter, psecuritypriv, keyid, 1);
549
550 if (res == _FAIL)
551 ret = false;
552exit:
553 return ret;
554}
555
556
557
558
559
560
561
562u16 rtw_get_cur_max_rate(struct adapter *adapter)
563{
564 int i = 0;
565 u8 *p;
566 u16 rate = 0, max_rate = 0;
567 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
568 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
569 struct registry_priv *pregistrypriv = &adapter->registrypriv;
570 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
571 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
572 u8 rf_type = 0;
573 u8 bw_40MHz = 0, short_GI_20 = 0, short_GI_40 = 0;
574 u32 ht_ielen = 0;
575
576 if (adapter->registrypriv.mp_mode == 1) {
577 if (check_fwstate(pmlmepriv, WIFI_MP_STATE))
578 return 0;
579 }
580
581 if ((!check_fwstate(pmlmepriv, _FW_LINKED)) &&
582 (!check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)))
583 return 0;
584
585 if (pmlmeext->cur_wireless_mode & (WIRELESS_11_24N|WIRELESS_11_5N)) {
586 p = rtw_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pcur_bss->IELength-12);
587 if (p && ht_ielen > 0) {
588
589 bw_40MHz = (pmlmeext->cur_bwmode && (HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH & pmlmeinfo->HT_info.infos[0])) ? 1 : 0;
590
591 short_GI_20 = (le16_to_cpu(pmlmeinfo->HT_caps.cap_info) & IEEE80211_HT_CAP_SGI_20) ? 1 : 0;
592 short_GI_40 = (le16_to_cpu(pmlmeinfo->HT_caps.cap_info) & IEEE80211_HT_CAP_SGI_40) ? 1 : 0;
593
594 rtw_hal_get_hwreg(adapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
595 max_rate = rtw_mcs_rate(
596 rf_type,
597 bw_40MHz & (pregistrypriv->cbw40_enable),
598 short_GI_20,
599 short_GI_40,
600 pmlmeinfo->HT_caps.mcs.rx_mask
601 );
602 }
603 } else {
604 while ((pcur_bss->SupportedRates[i] != 0) && (pcur_bss->SupportedRates[i] != 0xFF)) {
605 rate = pcur_bss->SupportedRates[i]&0x7F;
606 if (rate > max_rate)
607 max_rate = rate;
608 i++;
609 }
610
611 max_rate = max_rate*10/2;
612 }
613
614 return max_rate;
615}
616
617
618
619
620
621
622
623
624int rtw_set_country(struct adapter *adapter, const char *country_code)
625{
626 int i;
627 int channel_plan = RT_CHANNEL_DOMAIN_WORLD_WIDE_5G;
628
629 DBG_88E("%s country_code:%s\n", __func__, country_code);
630 for (i = 0; i < ARRAY_SIZE(channel_table); i++) {
631 if (0 == strcmp(channel_table[i].name, country_code)) {
632 channel_plan = channel_table[i].channel_plan;
633 break;
634 }
635 }
636
637 if (i == ARRAY_SIZE(channel_table))
638 DBG_88E("%s unknown country_code:%s\n", __func__, country_code);
639
640 return rtw_set_chplan_cmd(adapter, channel_plan, 1);
641}
642