1 /******************************************************************************
3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
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.
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
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
19 ******************************************************************************/
20 #define _RTW_IOCTL_SET_C_
22 #include <drv_types.h>
26 extern void indicate_wx_scan_complete_event(_adapter *padapter);
28 #define IS_MAC_ADDRESS_BROADCAST(addr) \
30 ((addr[0] == 0xff) && (addr[1] == 0xff) && \
31 (addr[2] == 0xff) && (addr[3] == 0xff) && \
32 (addr[4] == 0xff) && (addr[5] == 0xff)) ? _TRUE : _FALSE \
35 u8 rtw_validate_bssid(u8 *bssid)
39 if (is_zero_mac_addr(bssid)
40 || is_broadcast_mac_addr(bssid)
41 || is_multicast_mac_addr(bssid)
48 u8 rtw_validate_ssid(NDIS_802_11_SSID *ssid)
54 if (ssid->SsidLength > 32) {
59 #ifdef CONFIG_VALIDATE_SSID
60 for (i = 0; i < ssid->SsidLength; i++) {
61 /* wifi, printable ascii code must be supported */
62 if (!((ssid->Ssid[i] >= 0x20) && (ssid->Ssid[i] <= 0x7e))) {
67 #endif /* CONFIG_VALIDATE_SSID */
75 u8 rtw_do_join(_adapter *padapter);
76 u8 rtw_do_join(_adapter *padapter)
81 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
82 _queue *queue = &(pmlmepriv->scanned_queue);
86 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
87 phead = get_list_head(queue);
88 plist = get_next(phead);
91 pmlmepriv->cur_network.join_res = -2;
93 set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
95 pmlmepriv->pscanned = plist;
97 pmlmepriv->to_join = _TRUE;
99 if (_rtw_queue_empty(queue) == _TRUE) {
100 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
101 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
103 /* when set_ssid/set_bssid for rtw_do_join(), but scanning queue is empty */
104 /* we try to issue sitesurvey firstly */
106 if (pmlmepriv->LinkDetectInfo.bBusyTraffic == _FALSE
107 || rtw_to_roam(padapter) > 0
109 /* submit site_survey_cmd */
110 ret = rtw_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid, 1, NULL, 0);
111 if (_SUCCESS != ret) {
112 pmlmepriv->to_join = _FALSE;
115 pmlmepriv->to_join = _FALSE;
122 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
123 select_ret = rtw_select_and_join_from_scanned_queue(pmlmepriv);
124 if (select_ret == _SUCCESS) {
125 pmlmepriv->to_join = _FALSE;
126 _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT);
128 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) {
129 /* submit createbss_cmd to change to a ADHOC_MASTER */
131 /* pmlmepriv->lock has been acquired by caller... */
132 WLAN_BSSID_EX *pdev_network = &(padapter->registrypriv.dev_network);
134 /*pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;*/
135 init_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
137 pibss = padapter->registrypriv.dev_network.MacAddress;
139 _rtw_memset(&pdev_network->Ssid, 0, sizeof(NDIS_802_11_SSID));
140 _rtw_memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(NDIS_802_11_SSID));
142 rtw_update_registrypriv_dev_network(padapter);
144 rtw_generate_random_ibss(pibss);
146 if (rtw_create_ibss_cmd(padapter, 0) != _SUCCESS) {
151 pmlmepriv->to_join = _FALSE;
155 /* can't associate ; reset under-linking */
156 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
159 if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)) {
160 if (_rtw_memcmp(pmlmepriv->cur_network.network.Ssid.Ssid, pmlmepriv->assoc_ssid.Ssid, pmlmepriv->assoc_ssid.SsidLength)) {
161 /* for funk to do roaming */
162 /* funk will reconnect, but funk will not sitesurvey before reconnect */
163 if (pmlmepriv->sitesurveyctrl.traffic_busy == _FALSE)
164 rtw_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid, 1, NULL, 0);
170 /* when set_ssid/set_bssid for rtw_do_join(), but there are no desired bss in scanning queue */
171 /* we try to issue sitesurvey firstly */
172 if (pmlmepriv->LinkDetectInfo.bBusyTraffic == _FALSE
173 || rtw_to_roam(padapter) > 0
175 /* RTW_INFO("rtw_do_join() when no desired bss in scanning queue\n"); */
176 ret = rtw_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid, 1, NULL, 0);
177 if (_SUCCESS != ret) {
178 pmlmepriv->to_join = _FALSE;
182 pmlmepriv->to_join = _FALSE;
195 #ifdef PLATFORM_WINDOWS
196 u8 rtw_pnp_set_power_wakeup(_adapter *padapter)
202 res = rtw_setstandby_cmd(padapter, 0);
209 u8 rtw_pnp_set_power_sleep(_adapter *padapter)
214 /* DbgPrint("+rtw_pnp_set_power_sleep\n"); */
216 res = rtw_setstandby_cmd(padapter, 1);
223 u8 rtw_set_802_11_reload_defaults(_adapter *padapter, NDIS_802_11_RELOAD_DEFAULTS reloadDefaults)
228 /* SecClearAllKeys(Adapter); */
229 /* 8711 CAM was not for En/Decrypt only */
230 /* so, we can't clear all keys. */
231 /* should we disable WPAcfg (ox0088) bit 1-2, instead of clear all CAM */
239 u8 set_802_11_test(_adapter *padapter, NDIS_802_11_TEST *test)
244 switch (test->Type) {
246 NdisMIndicateStatus(padapter->hndis_adapter, NDIS_STATUS_MEDIA_SPECIFIC_INDICATION, (PVOID)&test->AuthenticationEvent, test->Length - 8);
247 NdisMIndicateStatusComplete(padapter->hndis_adapter);
251 NdisMIndicateStatus(padapter->hndis_adapter, NDIS_STATUS_MEDIA_SPECIFIC_INDICATION, (PVOID)&test->RssiTrigger, sizeof(NDIS_802_11_RSSI));
252 NdisMIndicateStatusComplete(padapter->hndis_adapter);
264 u8 rtw_set_802_11_pmkid(_adapter *padapter, NDIS_802_11_PMKID *pmkid)
273 u8 rtw_set_802_11_bssid(_adapter *padapter, u8 *bssid)
276 u8 status = _SUCCESS;
278 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
281 RTW_PRINT("set bssid:%pM\n", bssid);
283 if ((bssid[0] == 0x00 && bssid[1] == 0x00 && bssid[2] == 0x00 && bssid[3] == 0x00 && bssid[4] == 0x00 && bssid[5] == 0x00) ||
284 (bssid[0] == 0xFF && bssid[1] == 0xFF && bssid[2] == 0xFF && bssid[3] == 0xFF && bssid[4] == 0xFF && bssid[5] == 0xFF)) {
289 _enter_critical_bh(&pmlmepriv->lock, &irqL);
292 RTW_INFO("Set BSSID under fw_state=0x%08x\n", get_fwstate(pmlmepriv));
293 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE)
294 goto handle_tkip_countermeasure;
295 else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE)
296 goto release_mlme_lock;
298 if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE) == _TRUE) {
300 if (_rtw_memcmp(&pmlmepriv->cur_network.network.MacAddress, bssid, ETH_ALEN) == _TRUE) {
301 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _FALSE)
302 goto release_mlme_lock;/* it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. */
305 rtw_disassoc_cmd(padapter, 0, 0);
307 if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
308 rtw_indicate_disconnect(padapter, 0, _FALSE);
310 rtw_free_assoc_resources(padapter, 1);
312 if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)) {
313 _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
314 set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
319 handle_tkip_countermeasure:
320 if (rtw_handle_tkip_countermeasure(padapter, __func__) == _FAIL) {
322 goto release_mlme_lock;
325 _rtw_memset(&pmlmepriv->assoc_ssid, 0, sizeof(NDIS_802_11_SSID));
326 _rtw_memcpy(&pmlmepriv->assoc_bssid, bssid, ETH_ALEN);
327 pmlmepriv->assoc_by_bssid = _TRUE;
329 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE)
330 pmlmepriv->to_join = _TRUE;
332 status = rtw_do_join(padapter);
335 _exit_critical_bh(&pmlmepriv->lock, &irqL);
343 u8 rtw_set_802_11_ssid(_adapter *padapter, NDIS_802_11_SSID *ssid)
346 u8 status = _SUCCESS;
349 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
350 struct wlan_network *pnetwork = &pmlmepriv->cur_network;
353 RTW_PRINT("set ssid [%s] fw_state=0x%08x\n",
354 ssid->Ssid, get_fwstate(pmlmepriv));
356 if (!rtw_is_hw_init_completed(padapter)) {
361 _enter_critical_bh(&pmlmepriv->lock, &irqL);
363 RTW_INFO("Set SSID under fw_state=0x%08x\n", get_fwstate(pmlmepriv));
364 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE)
365 goto handle_tkip_countermeasure;
366 else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE)
367 goto release_mlme_lock;
369 if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE) == _TRUE) {
371 if ((pmlmepriv->assoc_ssid.SsidLength == ssid->SsidLength) &&
372 (_rtw_memcmp(&pmlmepriv->assoc_ssid.Ssid, ssid->Ssid, ssid->SsidLength) == _TRUE)) {
373 if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _FALSE)) {
375 if (rtw_is_same_ibss(padapter, pnetwork) == _FALSE) {
376 /* if in WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE, create bss or rejoin again */
377 rtw_disassoc_cmd(padapter, 0, 0);
379 if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
380 rtw_indicate_disconnect(padapter, 0, _FALSE);
382 rtw_free_assoc_resources(padapter, 1);
384 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) {
385 _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
386 set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
389 goto release_mlme_lock;/* it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. */
394 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_JOINBSS, 1);
398 rtw_disassoc_cmd(padapter, 0, 0);
400 if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
401 rtw_indicate_disconnect(padapter, 0, _FALSE);
403 rtw_free_assoc_resources(padapter, 1);
405 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) {
406 _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
407 set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
412 handle_tkip_countermeasure:
413 if (rtw_handle_tkip_countermeasure(padapter, __func__) == _FAIL) {
415 goto release_mlme_lock;
418 if (rtw_validate_ssid(ssid) == _FALSE) {
420 goto release_mlme_lock;
423 _rtw_memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(NDIS_802_11_SSID));
424 pmlmepriv->assoc_by_bssid = _FALSE;
426 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE)
427 pmlmepriv->to_join = _TRUE;
429 status = rtw_do_join(padapter);
432 _exit_critical_bh(&pmlmepriv->lock, &irqL);
441 u8 rtw_set_802_11_connect(_adapter *padapter, u8 *bssid, NDIS_802_11_SSID *ssid)
444 u8 status = _SUCCESS;
446 bool bssid_valid = _TRUE;
447 bool ssid_valid = _TRUE;
448 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
451 if (!ssid || rtw_validate_ssid(ssid) == _FALSE)
454 if (!bssid || rtw_validate_bssid(bssid) == _FALSE)
455 bssid_valid = _FALSE;
457 if (ssid_valid == _FALSE && bssid_valid == _FALSE) {
458 RTW_INFO(FUNC_ADPT_FMT" ssid:%p, ssid_valid:%d, bssid:%p, bssid_valid:%d\n",
459 FUNC_ADPT_ARG(padapter), ssid, ssid_valid, bssid, bssid_valid);
464 if (!rtw_is_hw_init_completed(padapter)) {
469 _enter_critical_bh(&pmlmepriv->lock, &irqL);
471 RTW_PRINT(FUNC_ADPT_FMT" fw_state=0x%08x\n",
472 FUNC_ADPT_ARG(padapter), get_fwstate(pmlmepriv));
474 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE)
475 goto handle_tkip_countermeasure;
476 else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE)
477 goto release_mlme_lock;
479 handle_tkip_countermeasure:
480 if (rtw_handle_tkip_countermeasure(padapter, __func__) == _FAIL) {
482 goto release_mlme_lock;
485 if (ssid && ssid_valid)
486 _rtw_memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(NDIS_802_11_SSID));
488 _rtw_memset(&pmlmepriv->assoc_ssid, 0, sizeof(NDIS_802_11_SSID));
490 if (bssid && bssid_valid) {
491 _rtw_memcpy(&pmlmepriv->assoc_bssid, bssid, ETH_ALEN);
492 pmlmepriv->assoc_by_bssid = _TRUE;
494 pmlmepriv->assoc_by_bssid = _FALSE;
496 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE)
497 pmlmepriv->to_join = _TRUE;
499 status = rtw_do_join(padapter);
502 _exit_critical_bh(&pmlmepriv->lock, &irqL);
510 u8 rtw_set_802_11_infrastructure_mode(_adapter *padapter,
511 NDIS_802_11_NETWORK_INFRASTRUCTURE networktype)
514 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
515 struct wlan_network *cur_network = &pmlmepriv->cur_network;
516 NDIS_802_11_NETWORK_INFRASTRUCTURE *pold_state = &(cur_network->network.InfrastructureMode);
517 u8 ap2sta_mode = _FALSE;
521 if (*pold_state != networktype) {
522 /* RTW_INFO("change mode, old_mode=%d, new_mode=%d, fw_state=0x%x\n", *pold_state, networktype, get_fwstate(pmlmepriv)); */
524 if (*pold_state == Ndis802_11APMode) {
525 /* change to other mode from Ndis802_11APMode */
526 cur_network->join_res = -1;
528 #ifdef CONFIG_NATIVEAP_MLME
529 stop_ap_mode(padapter);
533 _enter_critical_bh(&pmlmepriv->lock, &irqL);
535 if ((check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) || (*pold_state == Ndis802_11IBSS))
536 rtw_disassoc_cmd(padapter, 0, 0);
538 if ((check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) ||
539 (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE))
540 rtw_free_assoc_resources(padapter, 1);
542 if ((*pold_state == Ndis802_11Infrastructure) || (*pold_state == Ndis802_11IBSS)) {
543 if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
544 rtw_indicate_disconnect(padapter, 0, _FALSE); /*will clr Linked_state; before this function, we must have checked whether issue dis-assoc_cmd or not*/
548 *pold_state = networktype;
550 _clr_fwstate_(pmlmepriv, ~WIFI_NULL_STATE);
552 switch (networktype) {
554 set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
557 case Ndis802_11Infrastructure:
558 set_fwstate(pmlmepriv, WIFI_STATION_STATE);
561 rtw_init_bcmc_stainfo(padapter);
564 case Ndis802_11APMode:
565 set_fwstate(pmlmepriv, WIFI_AP_STATE);
566 #ifdef CONFIG_NATIVEAP_MLME
567 start_ap_mode(padapter);
568 /* rtw_indicate_connect(padapter); */
573 case Ndis802_11AutoUnknown:
574 case Ndis802_11InfrastructureMax:
576 case Ndis802_11Monitor:
577 set_fwstate(pmlmepriv, WIFI_MONITOR_STATE);
581 /* SecClearAllKeys(adapter); */
584 _exit_critical_bh(&pmlmepriv->lock, &irqL);
592 u8 rtw_set_802_11_disassociate(_adapter *padapter)
595 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
598 _enter_critical_bh(&pmlmepriv->lock, &irqL);
600 if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
602 rtw_disassoc_cmd(padapter, 0, 0);
603 rtw_indicate_disconnect(padapter, 0, _FALSE);
604 /* modify for CONFIG_IEEE80211W, none 11w can use it */
605 rtw_free_assoc_resources_cmd(padapter);
606 if (_FAIL == rtw_pwr_wakeup(padapter))
607 RTW_INFO("%s(): rtw_pwr_wakeup fail !!!\n", __FUNCTION__);
610 _exit_critical_bh(&pmlmepriv->lock, &irqL);
617 u8 rtw_set_802_11_bssid_list_scan(_adapter *padapter, NDIS_802_11_SSID *pssid, int ssid_max_num, struct rtw_ieee80211_channel *ch, int ch_num)
620 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
623 _enter_critical_bh(&pmlmepriv->lock, &irqL);
624 res = rtw_sitesurvey_cmd(padapter, pssid, ssid_max_num, ch, ch_num);
625 _exit_critical_bh(&pmlmepriv->lock, &irqL);
631 u8 rtw_set_802_11_bssid_list_scan(_adapter *padapter, NDIS_802_11_SSID *pssid, int ssid_max_num, struct rtw_ieee80211_channel *ch, int ch_num)
634 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
639 if (padapter == NULL) {
643 if (!rtw_is_hw_init_completed(padapter)) {
648 if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING) == _TRUE) ||
649 (pmlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE)) {
650 /* Scan or linking is in progress, do nothing. */
655 if (rtw_is_scan_deny(padapter)) {
656 RTW_INFO(FUNC_ADPT_FMT": scan deny\n", FUNC_ADPT_ARG(padapter));
657 indicate_wx_scan_complete_event(padapter);
661 _enter_critical_bh(&pmlmepriv->lock, &irqL);
663 res = rtw_sitesurvey_cmd(padapter, pssid, ssid_max_num, NULL, 0, ch, ch_num);
665 _exit_critical_bh(&pmlmepriv->lock, &irqL);
673 u8 rtw_set_802_11_authentication_mode(_adapter *padapter, NDIS_802_11_AUTHENTICATION_MODE authmode)
675 struct security_priv *psecuritypriv = &padapter->securitypriv;
681 psecuritypriv->ndisauthtype = authmode;
684 if (psecuritypriv->ndisauthtype > 3)
685 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
687 #ifdef CONFIG_WAPI_SUPPORT
688 if (psecuritypriv->ndisauthtype == 6)
689 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
692 res = rtw_set_auth(padapter, psecuritypriv);
703 u8 rtw_set_802_11_add_wep(_adapter *padapter, NDIS_802_11_WEP *wep)
709 struct security_priv *psecuritypriv = &(padapter->securitypriv);
713 bdefaultkey = (wep->KeyIndex & 0x40000000) > 0 ? _FALSE : _TRUE; /* for ??? */
714 btransmitkey = (wep->KeyIndex & 0x80000000) > 0 ? _TRUE : _FALSE; /* for ??? */
715 keyid = wep->KeyIndex & 0x3fffffff;
722 switch (wep->KeyLength) {
724 psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
727 psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
730 psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
735 _rtw_memcpy(&(psecuritypriv->dot11DefKey[keyid].skey[0]), &(wep->KeyMaterial), wep->KeyLength);
737 psecuritypriv->dot11DefKeylen[keyid] = wep->KeyLength;
739 psecuritypriv->dot11PrivacyKeyIndex = keyid;
742 res = rtw_set_key(padapter, psecuritypriv, keyid, 1, _TRUE);
753 u8 rtw_set_802_11_remove_wep(_adapter *padapter, u32 keyindex)
759 if (keyindex >= 0x80000000 || padapter == NULL) {
766 struct security_priv *psecuritypriv = &(padapter->securitypriv);
769 _rtw_memset(&psecuritypriv->dot11DefKey[keyindex], 0, 16);
771 res = rtw_set_key(padapter, psecuritypriv, keyindex, 0, _TRUE);
773 psecuritypriv->dot11DefKeylen[keyindex] = 0;
790 u8 rtw_set_802_11_add_key(_adapter *padapter, NDIS_802_11_KEY *key)
795 struct sta_info *stainfo;
797 u8 bgrouptkey = _FALSE;/* can be remove later */
801 if (((key->KeyIndex & 0x80000000) == 0) && ((key->KeyIndex & 0x40000000) > 0)) {
803 /* It is invalid to clear bit 31 and set bit 30. If the miniport driver encounters this combination, */
804 /* it must fail the request and return NDIS_STATUS_INVALID_DATA. */
809 if (key->KeyIndex & 0x40000000) {
813 pbssid = get_bssid(&padapter->mlmepriv);
814 stainfo = rtw_get_stainfo(&padapter->stapriv, pbssid);
816 if ((stainfo != NULL) && (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)) {
817 encryptionalgo = stainfo->dot118021XPrivacy;
819 encryptionalgo = padapter->securitypriv.dot11PrivacyAlgrthm;
825 if (key->KeyIndex & 0x000000FF) {
826 /* The key index is specified in the lower 8 bits by values of zero to 255. */
827 /* The key index should be set to zero for a Pairwise key, and the driver should fail with */
828 /* NDIS_STATUS_INVALID_DATA if the lower 8 bits is not zero */
834 if (IS_MAC_ADDRESS_BROADCAST(key->BSSID) == _TRUE) {
840 /* Check key length for TKIP. */
841 /* if(encryptionAlgorithm == RT_ENC_TKIP_ENCRYPTION && key->KeyLength != 32) */
842 if ((encryptionalgo == _TKIP_) && (key->KeyLength != 32)) {
848 /* Check key length for AES. */
849 if ((encryptionalgo == _AES_) && (key->KeyLength != 16)) {
850 /* For our supplicant, EAPPkt9x.vxd, cannot differentiate TKIP and AES case. */
851 if (key->KeyLength == 32)
859 /* Check key length for WEP. For NDTEST, 2005.01.27, by rcnjko. -> modify checking condition*/
860 if (((encryptionalgo == _WEP40_) && (key->KeyLength != 5)) || ((encryptionalgo == _WEP104_) && (key->KeyLength != 13))) {
867 /* Check the pairwise key. Added by Annie, 2005-07-06. */
870 /* Group key - KeyIndex(BIT30==0) */
873 /* when add wep key through add key and didn't assigned encryption type before */
874 if ((padapter->securitypriv.ndisauthtype <= 3) && (padapter->securitypriv.dot118021XGrpPrivacy == 0)) {
876 switch (key->KeyLength) {
878 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
881 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
884 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
888 encryptionalgo = padapter->securitypriv.dot11PrivacyAlgrthm;
892 encryptionalgo = padapter->securitypriv.dot118021XGrpPrivacy;
896 if ((check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE) == _TRUE) && (IS_MAC_ADDRESS_BROADCAST(key->BSSID) == _FALSE)) {
901 /* Check key length for TKIP */
902 if ((encryptionalgo == _TKIP_) && (key->KeyLength != 32)) {
907 } else if (encryptionalgo == _AES_ && (key->KeyLength != 16 && key->KeyLength != 32)) {
909 /* Check key length for AES */
910 /* For NDTEST, we allow keylen=32 in this case. 2005.01.27, by rcnjko. */
915 /* Change the key length for EAPPkt9x.vxd. Added by Annie, 2005-11-03. */
916 if ((encryptionalgo == _AES_) && (key->KeyLength == 32)) {
920 if (key->KeyIndex & 0x8000000) /* error ??? 0x8000_0000 */
923 if ((check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE) == _TRUE) && (check_fwstate(&padapter->mlmepriv, _FW_LINKED) == _TRUE))
931 /* If WEP encryption algorithm, just call rtw_set_802_11_add_wep(). */
932 if ((padapter->securitypriv.dot11AuthAlgrthm != dot11AuthAlgrthm_8021X) && (encryptionalgo == _WEP40_ || encryptionalgo == _WEP104_)) {
935 u32 len = FIELD_OFFSET(NDIS_802_11_KEY, KeyMaterial) + key->KeyLength;
936 NDIS_802_11_WEP *wep = &padapter->securitypriv.ndiswep;
940 keyindex = key->KeyIndex & 0x7fffffff;
941 wep->KeyIndex = keyindex ;
942 wep->KeyLength = key->KeyLength;
945 _rtw_memcpy(wep->KeyMaterial, key->KeyMaterial, key->KeyLength);
946 _rtw_memcpy(&(padapter->securitypriv.dot11DefKey[keyindex].skey[0]), key->KeyMaterial, key->KeyLength);
948 padapter->securitypriv.dot11DefKeylen[keyindex] = key->KeyLength;
949 padapter->securitypriv.dot11PrivacyKeyIndex = keyindex;
951 ret = rtw_set_802_11_add_wep(padapter, wep);
957 if (key->KeyIndex & 0x20000000) {
959 if (bgroup == _TRUE) {
960 NDIS_802_11_KEY_RSC keysrc = key->KeyRSC & 0x00FFFFFFFFFFFFULL;
961 _rtw_memcpy(&padapter->securitypriv.dot11Grprxpn, &keysrc, 8);
963 NDIS_802_11_KEY_RSC keysrc = key->KeyRSC & 0x00FFFFFFFFFFFFULL;
964 _rtw_memcpy(&padapter->securitypriv.dot11Grptxpn, &keysrc, 8);
969 /* Indicate this key idx is used for TX */
970 /* Save the key in KeyMaterial */
971 if (bgroup == _TRUE) { /* Group transmit key */
974 if (bgrouptkey == _TRUE)
975 padapter->securitypriv.dot118021XGrpKeyid = (u8)key->KeyIndex;
977 if ((key->KeyIndex & 0x3) == 0) {
982 _rtw_memset(&padapter->securitypriv.dot118021XGrpKey[(u8)((key->KeyIndex) & 0x03)], 0, 16);
983 _rtw_memset(&padapter->securitypriv.dot118021XGrptxmickey[(u8)((key->KeyIndex) & 0x03)], 0, 16);
984 _rtw_memset(&padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)], 0, 16);
986 if ((key->KeyIndex & 0x10000000)) {
987 _rtw_memcpy(&padapter->securitypriv.dot118021XGrptxmickey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial + 16, 8);
988 _rtw_memcpy(&padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial + 24, 8);
992 _rtw_memcpy(&padapter->securitypriv.dot118021XGrptxmickey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial + 24, 8);
993 _rtw_memcpy(&padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial + 16, 8);
998 /* set group key by index */
999 _rtw_memcpy(&padapter->securitypriv.dot118021XGrpKey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial, key->KeyLength);
1001 key->KeyIndex = key->KeyIndex & 0x03;
1003 padapter->securitypriv.binstallGrpkey = _TRUE;
1005 padapter->securitypriv.bcheck_grpkey = _FALSE;
1008 res = rtw_set_key(padapter, &padapter->securitypriv, key->KeyIndex, 1, _TRUE);
1015 } else { /* Pairwise Key */
1018 pbssid = get_bssid(&padapter->mlmepriv);
1019 stainfo = rtw_get_stainfo(&padapter->stapriv , pbssid);
1021 if (stainfo != NULL) {
1022 _rtw_memset(&stainfo->dot118021x_UncstKey, 0, 16); /* clear keybuffer */
1024 _rtw_memcpy(&stainfo->dot118021x_UncstKey, key->KeyMaterial, 16);
1026 if (encryptionalgo == _TKIP_) {
1027 padapter->securitypriv.busetkipkey = _FALSE;
1029 /* _set_timer(&padapter->securitypriv.tkip_timer, 50); */
1032 /* if TKIP, save the Receive/Transmit MIC key in KeyMaterial[128-255] */
1033 if ((key->KeyIndex & 0x10000000)) {
1034 _rtw_memcpy(&stainfo->dot11tkiptxmickey, key->KeyMaterial + 16, 8);
1035 _rtw_memcpy(&stainfo->dot11tkiprxmickey, key->KeyMaterial + 24, 8);
1038 _rtw_memcpy(&stainfo->dot11tkiptxmickey, key->KeyMaterial + 24, 8);
1039 _rtw_memcpy(&stainfo->dot11tkiprxmickey, key->KeyMaterial + 16, 8);
1043 } else if (encryptionalgo == _AES_) {
1048 /* Set key to CAM through H2C command */
1050 if (bgrouptkey) { /* never go to here */
1051 res = rtw_setstakey_cmd(padapter, stainfo, GROUP_KEY, _TRUE);
1053 res = rtw_setstakey_cmd(padapter, stainfo, UNICAST_KEY, _TRUE);
1057 res = rtw_setstakey_cmd(padapter, stainfo, UNICAST_KEY, _TRUE);
1073 u8 rtw_set_802_11_remove_key(_adapter *padapter, NDIS_802_11_REMOVE_KEY *key)
1076 uint encryptionalgo;
1078 struct sta_info *stainfo;
1079 u8 bgroup = (key->KeyIndex & 0x4000000) > 0 ? _FALSE : _TRUE;
1080 u8 keyIndex = (u8)key->KeyIndex & 0x03;
1084 if ((key->KeyIndex & 0xbffffffc) > 0) {
1089 if (bgroup == _TRUE) {
1090 encryptionalgo = padapter->securitypriv.dot118021XGrpPrivacy;
1091 /* clear group key by index */
1092 /* NdisZeroMemory(Adapter->MgntInfo.SecurityInfo.KeyBuf[keyIndex], MAX_WEP_KEY_LEN); */
1093 /* Adapter->MgntInfo.SecurityInfo.KeyLen[keyIndex] = 0; */
1095 _rtw_memset(&padapter->securitypriv.dot118021XGrpKey[keyIndex], 0, 16);
1097 /* ! \todo Send a H2C Command to Firmware for removing this Key in CAM Entry. */
1101 pbssid = get_bssid(&padapter->mlmepriv);
1102 stainfo = rtw_get_stainfo(&padapter->stapriv , pbssid);
1103 if (stainfo != NULL) {
1104 encryptionalgo = stainfo->dot118021XPrivacy;
1106 /* clear key by BSSID */
1107 _rtw_memset(&stainfo->dot118021x_UncstKey, 0, 16);
1109 /* ! \todo Send a H2C Command to Firmware for disable this Key in CAM Entry. */
1125 * rtw_get_cur_max_rate -
1126 * @adapter: pointer to _adapter structure
1128 * Return 0 or 100Kbps
1130 u16 rtw_get_cur_max_rate(_adapter *adapter)
1133 u16 rate = 0, max_rate = 0;
1134 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1135 WLAN_BSSID_EX *pcur_bss = &pmlmepriv->cur_network.network;
1136 struct sta_info *psta = NULL;
1138 #ifdef CONFIG_80211N_HT
1142 #ifdef CONFIG_MP_INCLUDED
1143 if (adapter->registrypriv.mp_mode == 1) {
1144 if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE)
1149 if ((check_fwstate(pmlmepriv, _FW_LINKED) != _TRUE)
1150 && (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) != _TRUE))
1153 psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
1157 short_GI = query_ra_short_GI(psta, psta->bw_mode);
1159 #ifdef CONFIG_80211N_HT
1160 if (is_supported_ht(psta->wireless_mode)) {
1161 rtw_hal_get_hwreg(adapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
1162 max_rate = rtw_mcs_rate(rf_type
1163 , (psta->bw_mode == CHANNEL_WIDTH_40) ? 1 : 0
1165 , psta->htpriv.ht_cap.supp_mcs_set
1168 #ifdef CONFIG_80211AC_VHT
1169 else if (is_supported_vht(psta->wireless_mode))
1170 max_rate = ((rtw_vht_mcs_to_data_rate(psta->bw_mode, short_GI, pmlmepriv->vhtpriv.vht_highest_rate) + 1) >> 1) * 10;
1171 #endif /* CONFIG_80211AC_VHT */
1173 #endif /* CONFIG_80211N_HT */
1175 while ((pcur_bss->SupportedRates[i] != 0) && (pcur_bss->SupportedRates[i] != 0xFF)) {
1176 rate = pcur_bss->SupportedRates[i] & 0x7F;
1177 if (rate > max_rate)
1182 max_rate = max_rate * 10 / 2;
1189 * rtw_set_scan_mode -
1190 * @adapter: pointer to _adapter structure
1193 * Return _SUCCESS or _FAIL
1195 int rtw_set_scan_mode(_adapter *adapter, RT_SCAN_TYPE scan_mode)
1197 if (scan_mode != SCAN_ACTIVE && scan_mode != SCAN_PASSIVE)
1200 adapter->mlmepriv.scan_mode = scan_mode;
1206 * rtw_set_channel_plan -
1207 * @adapter: pointer to _adapter structure
1210 * Return _SUCCESS or _FAIL
1212 int rtw_set_channel_plan(_adapter *adapter, u8 channel_plan)
1214 struct registry_priv *pregistrypriv = &adapter->registrypriv;
1215 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1217 /* handle by cmd_thread to sync with scan operation */
1218 return rtw_set_chplan_cmd(adapter, RTW_CMDF_WAIT_ACK, channel_plan, 1);
1223 * @adapter: pointer to _adapter structure
1224 * @country_code: string of country code
1226 * Return _SUCCESS or _FAIL
1228 int rtw_set_country(_adapter *adapter, const char *country_code)
1230 #ifdef CONFIG_RTW_IOCTL_SET_COUNTRY
1231 return rtw_set_country_cmd(adapter, RTW_CMDF_WAIT_ACK, country_code, 1);
1239 * @adapter: pointer to _adapter structure
1240 * @band: band to set
1242 * Return _SUCCESS or _FAIL
1244 int rtw_set_band(_adapter *adapter, u8 band)
1246 if (rtw_band_valid(band)) {
1247 RTW_INFO(FUNC_ADPT_FMT" band:%d\n", FUNC_ADPT_ARG(adapter), band);
1248 adapter->setband = band;
1252 RTW_PRINT(FUNC_ADPT_FMT" band:%d fail\n", FUNC_ADPT_ARG(adapter), band);