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