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