/* * API-compatible handling routines * * * * Copyright (c) 2009 Realtek Semiconductor Corp. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #ifdef __KERNEL__ #include #include #include #include #include #include #include #endif #include "./8192cd_cfg.h" #if defined(WIFI_HAPD) || defined(RTK_NL80211) #ifdef __LINUX_2_6__ #include #include #endif #include "./8192cd_debug.h" #include "./8192cd_headers.h" #include #include #include #include #include #include #include "./8192cd_net80211.h" #define HAPD_DEBUG void void_printk(const char *fmt, ...) { ; } #ifdef HAPD_DEBUG #define HAPD_MSG printk #else #define HAPD_MSG void_printk #endif const char* ether_sprintf(const u_int8_t *mac) { static char etherbuf[18]; /* XXX */ snprintf(etherbuf, sizeof(etherbuf), "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); return etherbuf; } static __inline__ void set_ttkeylen(struct Dot11EncryptKey *pEncryptKey, UINT8 len) { pEncryptKey->dot11TTKeyLen = len; } static __inline__ void set_tmickeylen(struct Dot11EncryptKey *pEncryptKey, UINT8 len) { pEncryptKey->dot11TMicKeyLen = len; } static __inline__ void set_tkip_key(struct Dot11EncryptKey *pEncryptKey, UINT8 *src) { memcpy(pEncryptKey->dot11TTKey.skey, src, pEncryptKey->dot11TTKeyLen); memcpy(pEncryptKey->dot11TMicKey1.skey, src + 16, pEncryptKey->dot11TMicKeyLen); memcpy(pEncryptKey->dot11TMicKey2.skey, src + 24, pEncryptKey->dot11TMicKeyLen); pEncryptKey->dot11TXPN48.val48 = 0; } static __inline__ void set_aes_key(struct Dot11EncryptKey *pEncryptKey, UINT8 *src) { memcpy(pEncryptKey->dot11TTKey.skey, src, pEncryptKey->dot11TTKeyLen); memcpy(pEncryptKey->dot11TMicKey1.skey, src, pEncryptKey->dot11TMicKeyLen); } static __inline__ void set_wep40_key(struct Dot11EncryptKey *pEncryptKey, UINT8 *src) { memcpy(pEncryptKey->dot11TTKey.skey, src, pEncryptKey->dot11TTKeyLen); } static __inline__ void set_wep104_key(struct Dot11EncryptKey *pEncryptKey, UINT8 *src) { memcpy(pEncryptKey->dot11TTKey.skey, src, pEncryptKey->dot11TTKeyLen); } static int HAPD_Process_Set_Port(struct net_device *dev, unsigned char *MACAddr, int PortStatus) { struct stat_info *pstat; #ifdef NETDEV_NO_PRIV struct rtl8192cd_priv *priv = ((struct rtl8192cd_priv *)netdev_priv(dev))->wlan_priv; #else struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)dev->priv; #endif struct wifi_mib *pmib = priv->pmib; HAPD_MSG("HAPD_Process_Set_Port +++ sta: %02X%02X%02X%02X%02X%02X Status %X\n", MACAddr[0],MACAddr[1],MACAddr[2], MACAddr[3],MACAddr[4],MACAddr[5], PortStatus); // if driver is not opened, return immediately, david if (!netif_running(priv->dev)) return (-1); pstat = get_stainfo(priv, MACAddr); if ((pstat == NULL) || (!(pstat->state & WIFI_ASOC_STATE))) return (-1); if (PortStatus) pstat->ieee8021x_ctrlport = PortStatus; else pstat->ieee8021x_ctrlport = pmib->dot118021xAuthEntry.dot118021xDefaultPort; HAPD_MSG("HAPD_Process_Set_Port ---\n"); return 0; } #if defined(WIFI_WPAS) || defined(RTK_NL80211) int rtl_wpas_join(struct rtl8192cd_priv *priv, int bss_num) { char tmpbuf[33]; if (!netif_running(priv->dev)) { printk("WiFi driver is NOT open!!\n"); return -1; } else if (priv->ss_req_ongoing) { printk("Site Survey is not finished yet!!\n"); return -1; } memcpy((void *)&(priv->pmib->dot11Bss) , (void *)&priv->site_survey.bss_backup[bss_num] , sizeof(struct bss_desc)); #ifdef WIFI_SIMPLE_CONFIG //_Eric if (priv->pmib->wscEntry.wsc_enable && (priv->pmib->dot11Bss.bsstype&WIFI_WPS)) if (priv->pmib->wscEntry.wsc_enable) { //priv->pmib->dot11Bss.bsstype &= ~WIFI_WPS; priv->wps_issue_join_req = 1; } else #endif { if (check_bss_encrypt(priv) == FAIL) { printk("Encryption mismatch!\n"); return -1; } } if ((priv->pmib->dot11Bss.ssidlen == 0) || (priv->pmib->dot11Bss.ssid[0] == '\0')) { printk("Error !! Join to a hidden AP!\n"); return -1; } #ifdef UNIVERSAL_REPEATER disable_vxd_ap(GET_VXD_PRIV(priv)); #endif memcpy(tmpbuf, priv->pmib->dot11Bss.ssid, priv->pmib->dot11Bss.ssidlen); tmpbuf[priv->pmib->dot11Bss.ssidlen] = '\0'; printk("going to join bss: %s\n", tmpbuf); memcpy(SSID2SCAN, priv->pmib->dot11Bss.ssid, priv->pmib->dot11Bss.ssidlen); SSID2SCAN_LEN = priv->pmib->dot11Bss.ssidlen; SSID_LEN = SSID2SCAN_LEN; memcpy(SSID, SSID2SCAN, SSID_LEN); memset(BSSID, 0, MACADDRLEN); #ifdef INCLUDE_WPA_PSK //_Eric ?? //if (priv->pmib->dot1180211AuthEntry.dot11EnablePSK) //derivePSK(priv); #endif priv->join_req_ongoing = 1; priv->authModeRetry = 0; //mod_timer(&priv->WPAS_timer, jiffies + 300); start_clnt_join(priv); return 0; } #endif void rtl_net80311_authmode(struct net_device *dev, int authtype, int encmode, int pskenable, int dot11802_1x) { #ifdef NETDEV_NO_PRIV struct rtl8192cd_priv *priv = ((struct rtl8192cd_priv *)netdev_priv(dev))->wlan_priv; #else struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)dev->priv; #endif HAPD_MSG("rtl_net80311_authmode +++\n"); HAPD_MSG("authtype=%d, encmode=%d, pskenable=%d, dot11802_1x=%d \n", authtype, encmode, pskenable, dot11802_1x); priv->pmib->dot1180211AuthEntry.dot11AuthAlgrthm = authtype; priv->pmib->dot1180211AuthEntry.dot11PrivacyAlgrthm = encmode; priv->pmib->dot1180211AuthEntry.dot11EnablePSK = pskenable; priv->pmib->dot118021xAuthEntry.dot118021xAlgrthm = dot11802_1x; } int rtl_net80211_setparam(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { #ifdef NETDEV_NO_PRIV struct rtl8192cd_priv *priv = ((struct rtl8192cd_priv *)netdev_priv(dev))->wlan_priv; #else struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)dev->priv; #endif int *i = (int *) extra; int param = wrqu->mode; /* parameter id is 1st */ int value = 0; /* NB: most values are TYPE_INT */ int ret = 0; memcpy(&value, wrqu->name+sizeof(value), sizeof(value)); int authtype = priv->pmib->dot1180211AuthEntry.dot11AuthAlgrthm; int encmode = priv->pmib->dot1180211AuthEntry.dot11PrivacyAlgrthm; int pskenable = priv->pmib->dot1180211AuthEntry.dot11EnablePSK; int dot11802_1x = priv->pmib->dot118021xAuthEntry.dot118021xAlgrthm; HAPD_MSG("rtl_net80211_setparam +++\n"); HAPD_MSG("rtl8192cd_net80211_ioctl, param = %d, value =%d\n", param, value); switch (param) { case IEEE80211_PARAM_TURBO: /* turbo mode */ break; case IEEE80211_PARAM_MODE: /* phy mode (11a, 11b, etc.) */ break; case IEEE80211_PARAM_AUTHMODE: /* authentication mode */ switch (value) { case IEEE80211_AUTH_NONE: {//Disable authtype = 0; encmode = 0; pskenable = 0; dot11802_1x = 0; rtl_net80311_authmode(dev, authtype, encmode, pskenable, dot11802_1x); break; } case IEEE80211_AUTH_OPEN: {//WEP Open authtype = 0; //WEP encmode depends on key length //encmode = 1; pskenable = 0; dot11802_1x = 0; rtl_net80311_authmode(dev, authtype, encmode, pskenable, dot11802_1x); break; } case IEEE80211_AUTH_SHARED: {//WEP Shared authtype = 1; //WEP encmode depends on key length //encmode = 1; pskenable = 0; dot11802_1x = 0; rtl_net80311_authmode(dev, authtype, encmode, pskenable, dot11802_1x); break; } case IEEE80211_AUTH_AUTO: {//WEP Auto authtype = 2; //WEP encmode depends on key length //encmode = 1; pskenable = 0; dot11802_1x = 0; rtl_net80311_authmode(dev, authtype, encmode, pskenable, dot11802_1x); break; } case IEEE80211_AUTH_WPA: {//WPA-PSK-AES //_Eric ?? if there is no valid passphrase ?? authtype = 2; encmode = 2; //_Eric pskmode (WPA 0,1,2) will be set by IEEE80211_PARAM_WPA //pskenable = 1; dot11802_1x = 1; rtl_net80311_authmode(dev, authtype, encmode, pskenable, dot11802_1x); break; } case IEEE80211_AUTH_8021X: { //8021x encmode depends on key length if((encmode == _WEP_40_PRIVACY_) || (encmode == _WEP_104_PRIVACY_)) authtype = 2; else authtype = 0; pskenable = 0; dot11802_1x = 1; rtl_net80311_authmode(dev, authtype, encmode, pskenable, dot11802_1x); break; } default: return -EINVAL; } case IEEE80211_PARAM_PROTMODE: /* 802.11g protection */ break; case IEEE80211_PARAM_MCASTCIPHER: /* multicast/default cipher */ break; case IEEE80211_PARAM_MCASTKEYLEN: /* multicast key length */ break; case IEEE80211_PARAM_UCASTCIPHERS: /* unicast cipher suites */ /* 1. Only support AES & TKIP for WPA1&WPA2 2. Set both wpa_cipher and wpa2_cipher, because IEEE80211_PARAM_WPA will clear unused cipher mode */ HAPD_MSG("IEEE80211_PARAM_UCASTCIPHERS\n"); if(value & (1<pmib->dot11BssType.net_work_type & WIRELESS_11N)) || (OPMODE & WIFI_STATION_STATE)) { priv->pmib->dot1180211AuthEntry.dot11WPACipher |= BIT(1); priv->pmib->dot1180211AuthEntry.dot11WPA2Cipher |= BIT(1); } else return -EINVAL; } else { priv->pmib->dot1180211AuthEntry.dot11WPACipher &= ~(BIT(1)); priv->pmib->dot1180211AuthEntry.dot11WPA2Cipher &= ~(BIT(1)); } if(value & (1<pmib->dot1180211AuthEntry.dot11WPACipher |= BIT(3); priv->pmib->dot1180211AuthEntry.dot11WPA2Cipher |= BIT(3); } else { priv->pmib->dot1180211AuthEntry.dot11WPACipher &= ~(BIT(3)); priv->pmib->dot1180211AuthEntry.dot11WPA2Cipher &= ~(BIT(3)); } priv->pmib->dot118021xAuthEntry.dot118021xAlgrthm = 1; return 0; //_Eric if value > BIT(8) ? case IEEE80211_PARAM_UCASTCIPHER: /* unicast cipher */ break; case IEEE80211_PARAM_UCASTKEYLEN: /* unicast key length */ if(value == 5) priv->pmib->dot1180211AuthEntry.dot11PrivacyAlgrthm = _WEP_40_PRIVACY_; else if(value == 13) priv->pmib->dot1180211AuthEntry.dot11PrivacyAlgrthm = _WEP_104_PRIVACY_; else priv->pmib->dot1180211AuthEntry.dot11PrivacyAlgrthm = _NO_PRIVACY_; break; case IEEE80211_PARAM_WPA: /* WPA mode (0,1,2) */ HAPD_MSG("IEEE80211_PARAM_WPA\n"); if((value & BIT(0)) && (value & BIT(1))) return 0; else if((value & BIT(0))) {//only WPA1, so clear mib of wpa2_cipher & wpa2_psk priv->pmib->dot1180211AuthEntry.dot11WPA2Cipher = 0; priv->pmib->dot1180211AuthEntry.dot11EnablePSK & ~(BIT(1)); return 0; } else if((value & BIT(1))) {//only WPA2, so clear mib of wpa_cipher & wps2_psk priv->pmib->dot1180211AuthEntry.dot11WPACipher = 0; priv->pmib->dot1180211AuthEntry.dot11EnablePSK & ~(BIT(0)); return 0; } case IEEE80211_PARAM_ROAMING: /* roaming mode */ #ifdef WIFI_WPAS if(value == IEEE80211_ROAMING_DEVICE) priv->pmib->dot11StationConfigEntry.fastRoaming = 1; else if(value == IEEE80211_ROAMING_MANUAL) priv->pmib->dot11StationConfigEntry.fastRoaming = 0; else return EINVAL; #endif break; case IEEE80211_PARAM_PRIVACY: /* privacy invoked */ ret =0; //It seems useless, just return status OK for hostapd. break; case IEEE80211_PARAM_COUNTERMEASURES: /* WPA/TKIP countermeasures */ //_Eric ?? realtek do not have to support ?? break; case IEEE80211_PARAM_DROPUNENCRYPTED: /* discard unencrypted frames */ break; case IEEE80211_PARAM_DRIVER_CAPS: /* driver capabilities */ break; case IEEE80211_PARAM_MACCMD: /* MAC ACL operation */ break; case IEEE80211_PARAM_WMM: /* WMM mode (on, off) */ break; case IEEE80211_PARAM_HIDESSID: /* hide SSID mode (on, off) */ break; case IEEE80211_PARAM_APBRIDGE: /* AP inter-sta bridging */ break; case IEEE80211_PARAM_KEYMGTALGS: /* key management algorithms */ HAPD_MSG("IEEE80211_PARAM_KEYMGTALGS\n"); if((0<=value) && (value<=3)) { priv->pmib->dot1180211AuthEntry.dot11EnablePSK = value; break; } else return EINVAL; case IEEE80211_PARAM_RSNCAPS: /* RSN capabilities */ break; case IEEE80211_PARAM_INACT: /* station inactivity timeout */ break; case IEEE80211_PARAM_INACT_AUTH: /* station auth inact timeout */ break; case IEEE80211_PARAM_INACT_INIT: /* station init inact timeout */ break; case IEEE80211_PARAM_ABOLT: /* Atheros Adv. Capabilities */ break; case IEEE80211_PARAM_DTIM_PERIOD: /* DTIM period (beacons) */ break; case IEEE80211_PARAM_BEACON_INTERVAL: /* beacon interval (ms) */ break; case IEEE80211_PARAM_DOTH: /* 11.h is on/off */ break; case IEEE80211_PARAM_PWRTARGET: /* Current Channel Pwr Constraint */ break; case IEEE80211_PARAM_GENREASSOC: /* Generate a reassociation request */ break; case IEEE80211_PARAM_COMPRESSION: /* compression */ break; case IEEE80211_PARAM_FF: /* fast frames support */ break; case IEEE80211_PARAM_XR: /* XR support */ break; case IEEE80211_PARAM_BURST: /* burst mode */ break; case IEEE80211_PARAM_PUREG: /* pure 11g (no 11b stations) */ break; case IEEE80211_PARAM_AR: /* AR support */ break; case IEEE80211_PARAM_WDS: /* Enable 4 address processing */ break; case IEEE80211_PARAM_BGSCAN: /* bg scanning (on, off) */ break; case IEEE80211_PARAM_BGSCAN_IDLE: /* bg scan idle threshold */ break; case IEEE80211_PARAM_BGSCAN_INTERVAL: /* bg scan interval */ break; case IEEE80211_PARAM_MCAST_RATE: /* Multicast Tx Rate */ break; case IEEE80211_PARAM_COVERAGE_CLASS: /* coverage class */ break; case IEEE80211_PARAM_COUNTRY_IE: /* enable country IE */ break; case IEEE80211_PARAM_SCANVALID: /* scan cache valid threshold */ break; case IEEE80211_PARAM_ROAM_RSSI_11A: /* rssi threshold in 11a */ break; case IEEE80211_PARAM_ROAM_RSSI_11B: /* rssi threshold in 11b */ break; case IEEE80211_PARAM_ROAM_RSSI_11G: /* rssi threshold in 11g */ break; case IEEE80211_PARAM_ROAM_RATE_11A: /* tx rate threshold in 11a */ break; case IEEE80211_PARAM_ROAM_RATE_11B: /* tx rate threshold in 11b */ break; case IEEE80211_PARAM_ROAM_RATE_11G: /* tx rate threshold in 11g */ break; case IEEE80211_PARAM_UAPSDINFO: /* value for qos info field */ break; case IEEE80211_PARAM_SLEEP: /* force sleep/wake */ break; case IEEE80211_PARAM_QOSNULL: /* force sleep/wake */ break; case IEEE80211_PARAM_PSPOLL: /* force ps-poll generation (sta only) */ break; case IEEE80211_PARAM_EOSPDROP: /* force uapsd EOSP drop (ap only) */ break; case IEEE80211_PARAM_MARKDFS: /* mark a dfs interference channel when found */ break; case IEEE80211_PARAM_REGCLASS: /* enable regclass ids in country IE */ break; case IEEE80211_PARAM_DROPUNENC_EAPOL: /* drop unencrypted eapol frames */ break; case IEEE80211_PARAM_SHPREAMBLE: /* Short Preamble */ break; } HAPD_MSG("rtl_net80211_setparam ---\n"); return ret; } /* Management frame type to which application IE is added enum { IEEE80211_APPIE_FRAME_BEACON = 0, IEEE80211_APPIE_FRAME_PROBE_REQ = 1, IEEE80211_APPIE_FRAME_PROBE_RESP = 2, IEEE80211_APPIE_FRAME_ASSOC_REQ = 3, IEEE80211_APPIE_FRAME_ASSOC_RESP = 4, IEEE80211_APPIE_NUM_OF_FRAME = 5 }; */ int rtl_net80211_setappiebuf(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { #ifdef NETDEV_NO_PRIV struct rtl8192cd_priv *priv = ((struct rtl8192cd_priv *)netdev_priv(dev))->wlan_priv; #else struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)dev->priv; #endif struct ieee80211req_getset_appiebuf * ie = (struct ieee80211req_getset_appiebuf *)wrqu->data.pointer; int ret = 0; HAPD_MSG("rtl_net80211_setappiebuf +++\n"); HAPD_MSG("frametype =%d, iebuflen=%d \n", ie->app_frmtype, ie->app_buflen); //_Eric ???? hostapd has no interface to set wsc_enable. if((ie->app_buflen == 0) && (ie->app_frmtype != IEEE80211_APPIE_FRAME_ASSOC_RESP)) priv->pmib->wscEntry.wsc_enable = 0; else if(ie->app_buflen <= 256) priv->pmib->wscEntry.wsc_enable = 2; //Work as AP else return -EINVAL; if (ie->app_frmtype == IEEE80211_APPIE_FRAME_BEACON) { HAPD_MSG("WSC: set beacon IE\n"); priv->pmib->wscEntry.beacon_ielen = ie->app_buflen; memcpy((void *)priv->pmib->wscEntry.beacon_ie, ie->app_buf, ie->app_buflen); } else if (ie->app_frmtype == IEEE80211_APPIE_FRAME_PROBE_RESP) { HAPD_MSG("WSC: set probe response IE\n"); priv->pmib->wscEntry.probe_rsp_ielen = ie->app_buflen; memcpy((void *)priv->pmib->wscEntry.probe_rsp_ie, ie->app_buf, ie->app_buflen); } else if (ie->app_frmtype == IEEE80211_APPIE_FRAME_ASSOC_RESP) { HAPD_MSG("WSC: set association response IE\n"); priv->pmib->wscEntry.assoc_ielen = ie->app_buflen; memcpy((void *)priv->pmib->wscEntry.assoc_ie, ie->app_buf, ie->app_buflen); } #ifdef WIFI_WPAS else if (ie->app_frmtype == IEEE80211_APPIE_FRAME_PROBE_REQ) { HAPD_MSG("WSC: set probe request IE\n"); priv->pmib->wscEntry.probe_req_ielen = ie->app_buflen; memcpy((void *)priv->pmib->wscEntry.probe_req_ie, ie->app_buf, ie->app_buflen); } #endif else return -EINVAL; HAPD_MSG("rtl_net80211_setappiebuf ---\n"); return ret; } #ifdef WIFI_WPAS int rtl_net80211_setoptie(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { #ifdef NETDEV_NO_PRIV struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)netdev_priv(dev); #else struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)dev->priv; #endif WPAS_ASSOCIATION_INFO Assoc_Info; //Check if WPS IE UINT8 WSC_IE_OUI[4] = {0x00, 0x50, 0xf2, 0x04}; int x; unsigned char *ie = (unsigned char *)wrqu->data.pointer; if( ie[0] == _WPS_IE_) if (!memcmp(ie+2, WSC_IE_OUI, 4)) { priv->pmib->wscEntry.assoc_ielen = wrqu->data.length; memcpy((void *)priv->pmib->wscEntry.assoc_ie, wrqu->data.pointer, wrqu->data.length); priv->pmib->wscEntry.wsc_enable = 1; return 0; } priv->pmib->wscEntry.wsc_enable = 0; memset(priv->pmib->dot11RsnIE.rsnie, 0x0, 128); memcpy(priv->pmib->dot11RsnIE.rsnie, wrqu->data.pointer, wrqu->data.length); priv->pmib->dot11RsnIE.rsnielen = wrqu->data.length; memset((void *)&Assoc_Info, 0, sizeof(struct _WPAS_ASSOCIATION_INFO)); Assoc_Info.ReqIELen = priv->pmib->dot11RsnIE.rsnie[1]+ 2; memcpy(Assoc_Info.ReqIE, priv->pmib->dot11RsnIE.rsnie, Assoc_Info.ReqIELen); //event_indicate_wpas(priv, NULL, WPAS_ASSOC_INFO, (UINT8 *)&Assoc_Info); return 0; } #endif int rtl_net80211_setmlme(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { #ifdef NETDEV_NO_PRIV struct rtl8192cd_priv *priv = ((struct rtl8192cd_priv *)netdev_priv(dev))->wlan_priv; #else struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)dev->priv; #endif struct ieee80211req_mlme *mlme = (struct ieee80211req_key *)wrqu->data.pointer; struct stat_info *pstat = get_stainfo(priv, mlme->im_macaddr); int ret = 0; HAPD_MSG("rtl_net80211_setmlme +++\n"); HAPD_MSG("auth_state =%d, mac = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n" , mlme->im_op, mlme->im_macaddr[0], mlme->im_macaddr[1], mlme->im_macaddr[2], mlme->im_macaddr[3], mlme->im_macaddr[4], mlme->im_macaddr[5]); //_Eric ???? if(mlme->im_op == IEEE80211_MLME_AUTHORIZE) { if (pstat == NULL){ pstat = alloc_stainfo(priv, mlme->im_macaddr, -1); if (pstat == NULL) { printk("Exceed the upper limit of supported clients...\n"); return -1; } init_stainfo(priv, pstat); pstat->state |= (WIFI_AUTH_SUCCESS | WIFI_ASOC_STATE); pstat->expire_to = priv->assoc_to; list_add_tail(&(pstat->asoc_list), &(priv->asoc_list)); } HAPD_Process_Set_Port(dev, mlme->im_macaddr ,DOT11_PortStatus_Authorized); } else if(mlme->im_op == IEEE80211_MLME_UNAUTHORIZE) { if (pstat == NULL) return -EINVAL; //pstat->state |= WIFI_AUTH_NULL; HAPD_Process_Set_Port(dev, mlme->im_macaddr ,DOT11_PortStatus_Authorized); } else if(mlme->im_op == IEEE80211_MLME_DISASSOC) { if (pstat == NULL) return -EINVAL; #ifdef WIFI_WPAS if(OPMODE & WIFI_STATION_STATE) { HAPD_MSG("An AP is disconnected by WPAS \n"); issue_disassoc(priv, mlme->im_macaddr, _RSON_UNSPECIFIED_); if (pstat->expire_to > 0) { cnt_assoc_num(priv, pstat, DECREASE, (char *)__FUNCTION__); check_sta_characteristic(priv, pstat, DECREASE); } free_stainfo(priv, pstat); memset(&priv->pmib->dot11Bss, 0, sizeof(struct bss_desc)); memset(priv->pmib->dot11StationConfigEntry.dot11Bssid, 0, MACADDRLEN); memset(priv->pmib->dot11StationConfigEntry.dot11DesiredSSID, 0, sizeof(priv->pmib->dot11StationConfigEntry.dot11DesiredSSID)); priv->pmib->dot11StationConfigEntry.dot11DesiredSSIDLen = 0; memset(priv->pmib->dot11StationConfigEntry.dot11DefaultSSID, 0, sizeof(priv->pmib->dot11StationConfigEntry.dot11DesiredSSID)); priv->pmib->dot11StationConfigEntry.dot11DefaultSSIDLen = 0; memset(priv->pmib->dot11StationConfigEntry.dot11SSIDtoScan, 0, sizeof(priv->pmib->dot11StationConfigEntry.dot11SSIDtoScan)); priv->pmib->dot11StationConfigEntry.dot11SSIDtoScanLen = 0; memset(priv->pmib->dot11StationConfigEntry.dot11DesiredBssid, 0, 6); priv->wpas_manual_assoc = 1; //_Eric ?? when to let driver auto-connect ?? priv->join_res = STATE_Sta_No_Bss; pstat->state &= (~WIFI_ASOC_STATE); return ret; } #endif if (!list_empty(&pstat->asoc_list)) { list_del_init(&pstat->asoc_list); if (pstat->expire_to > 0) { cnt_assoc_num(priv, pstat, DECREASE, (char *)__FUNCTION__); check_sta_characteristic(priv, pstat, DECREASE); } } // Need change state back to autehnticated release_stainfo(priv, pstat); init_stainfo(priv, pstat); pstat->state |= WIFI_AUTH_SUCCESS; pstat->expire_to = priv->assoc_to; list_add_tail(&(pstat->auth_list), &(priv->auth_list)); } else if(mlme->im_op == IEEE80211_MLME_DEAUTH) { unsigned char MULTICAST_ADD[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; if(!memcmp(mlme->im_macaddr, MULTICAST_ADD, 6)) //_Eric ??How to free all stainfo?? return 0; if (pstat == NULL) return -EINVAL; if (!list_empty(&pstat->asoc_list)) { list_del_init(&pstat->asoc_list); if (pstat->expire_to > 0) { cnt_assoc_num(priv, pstat, DECREASE, (char *)__FUNCTION__); check_sta_characteristic(priv, pstat, DECREASE); } } release_stainfo(priv, pstat); } #ifdef WIFI_WPAS else if(mlme->im_op == IEEE80211_MLME_ASSOC) { int ix = 0, found = 0; if((OPMODE & WIFI_STATION_STATE) == 0) { HAPD_MSG("NOT in Client Mode, can NOT Associate !!!\n"); return -1; } for(ix = 0 ; ix < priv->site_survey.count_backup ; ix++) //_Eric ?? will bss_backup be cleaned?? -> Not found in codes { if(!memcmp(priv->site_survey.bss_backup[ix].bssid , mlme->im_macaddr, 6)) { found = 1; break; } } if(found == 0) { printk("BSSID NOT Found !!\n"); return -EINVAL; } else ret = rtl_wpas_join(priv, ix); if(ret != 0) printk("rtl_wpas_join Failed !!\n"); } #endif else { HAPD_MSG("unknown auth_state !!!\n"); return -EINVAL; } HAPD_MSG("rtl_net80211_setmlme ---\n"); return ret; } int rtl_net80211_setkey(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { #ifdef NETDEV_NO_PRIV struct rtl8192cd_priv *priv = ((struct rtl8192cd_priv *)netdev_priv(dev))->wlan_priv; #else struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)dev->priv; #endif struct ieee80211req_key *wk = (struct ieee80211req_key *)wrqu->data.pointer; struct wifi_mib *pmib = priv->pmib; struct Dot11EncryptKey *pEncryptKey = NULL; struct stat_info *pstat = NULL; unsigned char MULTICAST_ADD[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; #ifdef WIFI_WPAS unsigned char GROUP_ADD[6]={0x0,0x0,0x0,0x0,0x0,0x0}; #endif int cipher =0; int retVal = 0; int group_key = 0; HAPD_MSG("rtl_net80211_setkey +++\n"); HAPD_MSG("keyid = %d, mac = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n" , wk->ik_keyix, wk->ik_macaddr[0], wk->ik_macaddr[1], wk->ik_macaddr[2], wk->ik_macaddr[3], wk->ik_macaddr[4], wk->ik_macaddr[5]); HAPD_MSG("type = 0x%x, flags = 0x%x, keylen = 0x%x \n" , wk->ik_type, wk->ik_flags, wk->ik_keylen); //check if the interface is down if (!netif_running(priv->dev)) { if(wk->ik_type == IEEE80211_CIPHER_WEP) { HAPD_MSG("set WEP Key in driver DOWN\n"); memcpy(&priv->pmib->dot11DefaultKeysTable.keytype[wk->ik_keyix].skey[0], wk->ik_keydata, wk->ik_keylen); return 0; } HAPD_MSG("\nFail: interface not opened\n"); return 0; } if(!memcmp(wk->ik_macaddr, MULTICAST_ADD, 6)) group_key = 1; #ifdef WIFI_WPAS //_Eric ?? if oxff not group addr in wpas ?? if(OPMODE & WIFI_STATION_STATE) if(!memcmp(wk->ik_macaddr, GROUP_ADD, 6)) group_key = 1; #endif if(wk->ik_type == IEEE80211_CIPHER_WEP) { #ifdef WIFI_WPAS if(OPMODE & WIFI_STATION_STATE) if(priv->pmib->dot118021xAuthEntry.dot118021xAlgrthm == 0) { memcpy(&priv->pmib->dot11DefaultKeysTable.keytype[wk->ik_keyix].skey[0], wk->ik_keydata, wk->ik_keylen); return 0; } #endif #ifdef RTK_NL80211 HAPD_MSG("set WEP Key for NL80211\n"); memcpy(&priv->pmib->dot11DefaultKeysTable.keytype[wk->ik_keyix].skey[0], wk->ik_keydata, wk->ik_keylen); #endif if(priv->pmib->dot1180211AuthEntry.dot11PrivacyAlgrthm == _WEP_40_PRIVACY_) cipher = (DOT11_ENC_WEP40); else if(priv->pmib->dot1180211AuthEntry.dot11PrivacyAlgrthm == _WEP_104_PRIVACY_) cipher = (DOT11_ENC_WEP104); else return -EINVAL; } else if(wk->ik_type == IEEE80211_CIPHER_TKIP) cipher = (DOT11_ENC_TKIP); else if(wk->ik_type == IEEE80211_CIPHER_AES_CCM) cipher = (DOT11_ENC_CCMP); else { HAPD_MSG("unknown encAlg !!!\n"); return -EINVAL; } //_Eric ?? if call DOT11_Process_Set_Key //CamAddOneEntry(priv, wk->ik_macaddr, wk->ik_keyix, cipher, 0, wk->ik_keydata); if(group_key) { int set_gkey_to_cam = 1; HAPD_MSG("set group key !!\n"); #ifdef UNIVERSAL_REPEATER if (IS_VXD_INTERFACE(priv)) set_gkey_to_cam = 0; else { if (IS_ROOT_INTERFACE(priv)) { if (IS_DRV_OPEN(GET_VXD_PRIV(priv))) set_gkey_to_cam = 0; } } #endif #ifdef MBSSID if (GET_ROOT(priv)->pmib->miscEntry.vap_enable) { // No matter root or vap, don't set key to cam if vap is enabled. set_gkey_to_cam = 0; } #endif #ifdef CONFIG_RTK_MESH //modify by Joule for SECURITY if (dev == priv->mesh_dev) { pmib->dot11sKeysTable.dot11Privacy = cipher; pEncryptKey = &pmib->dot11sKeysTable.dot11EncryptKey; pmib->dot11sKeysTable.keyid = (UINT)wk->ik_keyix; } else #endif { pmib->dot11GroupKeysTable.dot11Privacy = cipher; pEncryptKey = &pmib->dot11GroupKeysTable.dot11EncryptKey; pmib->dot11GroupKeysTable.keyid = (UINT)wk->ik_keyix; } switch(cipher) { case DOT11_ENC_TKIP: set_ttkeylen(pEncryptKey, 16); set_tmickeylen(pEncryptKey, 8); set_tkip_key(pEncryptKey, wk->ik_keydata); HAPD_MSG("going to set TKIP group key! id %X\n", (UINT)wk->ik_keyix); if (!SWCRYPTO) { if (set_gkey_to_cam) { retVal = CamDeleteOneEntry(priv, MULTICAST_ADD, wk->ik_keyix, 0); if (retVal) { priv->pshare->CamEntryOccupied--; pmib->dot11GroupKeysTable.keyInCam = FALSE; } retVal = CamAddOneEntry(priv, MULTICAST_ADD, wk->ik_keyix, DOT11_ENC_TKIP<<2, 0, wk->ik_keydata); if (retVal) { priv->pshare->CamEntryOccupied++; pmib->dot11GroupKeysTable.keyInCam = TRUE; } } } break; case DOT11_ENC_WEP40: set_ttkeylen(pEncryptKey, 5); set_tmickeylen(pEncryptKey, 0); set_wep40_key(pEncryptKey, wk->ik_keydata); HAPD_MSG("going to set WEP40 group key!\n"); if (!SWCRYPTO) { if (set_gkey_to_cam) { retVal = CamDeleteOneEntry(priv, MULTICAST_ADD, wk->ik_keyix, 0); if (retVal) { priv->pshare->CamEntryOccupied--; pmib->dot11GroupKeysTable.keyInCam = FALSE; } retVal = CamAddOneEntry(priv, MULTICAST_ADD, wk->ik_keyix, DOT11_ENC_WEP40<<2, 0, wk->ik_keydata); if (retVal) { priv->pshare->CamEntryOccupied++; pmib->dot11GroupKeysTable.keyInCam = TRUE; } } } break; case DOT11_ENC_WEP104: set_ttkeylen(pEncryptKey, 13); set_tmickeylen(pEncryptKey, 0); set_wep104_key(pEncryptKey, wk->ik_keydata); HAPD_MSG("going to set WEP104 group key!\n"); if (!SWCRYPTO) { if (set_gkey_to_cam) { retVal = CamDeleteOneEntry(priv, MULTICAST_ADD, wk->ik_keyix, 0); if (retVal) { priv->pshare->CamEntryOccupied--; pmib->dot11GroupKeysTable.keyInCam = FALSE; } retVal = CamAddOneEntry(priv, MULTICAST_ADD, wk->ik_keyix, DOT11_ENC_WEP104<<2, 0, wk->ik_keydata); if (retVal) { priv->pshare->CamEntryOccupied++; pmib->dot11GroupKeysTable.keyInCam = TRUE; } } } break; case DOT11_ENC_CCMP: set_ttkeylen(pEncryptKey, 16); set_tmickeylen(pEncryptKey, 16); set_aes_key(pEncryptKey, wk->ik_keydata); HAPD_MSG("going to set CCMP-AES group key!\n"); #ifdef CONFIG_RTK_MESH if (dev == priv->mesh_dev) pmib->dot11sKeysTable.keyInCam = TRUE; // keyInCam means key in driver else #endif if (!SWCRYPTO) { if (set_gkey_to_cam) { retVal = CamDeleteOneEntry(priv, MULTICAST_ADD, wk->ik_keyix, 0); if (retVal) { priv->pshare->CamEntryOccupied--; pmib->dot11GroupKeysTable.keyInCam = FALSE; } retVal = CamAddOneEntry(priv, MULTICAST_ADD, wk->ik_keyix, DOT11_ENC_CCMP<<2, 0, wk->ik_keydata); if (retVal) { priv->pshare->CamEntryOccupied++; pmib->dot11GroupKeysTable.keyInCam = TRUE; } } } break; case DOT11_ENC_NONE: default: HAPD_MSG("No group encryption key is set!\n"); set_ttkeylen(pEncryptKey, 0); set_tmickeylen(pEncryptKey, 0); break; } } else { pstat = get_stainfo(priv, wk->ik_macaddr); if (pstat == NULL) { DEBUG_ERR("Set key failed, invalid mac address: %02x%02x%02x%02x%02x%02x\n", wk->ik_macaddr[0], wk->ik_macaddr[1], wk->ik_macaddr[2], wk->ik_macaddr[3], wk->ik_macaddr[4], wk->ik_macaddr[5]); return (-1); } pstat->dot11KeyMapping.dot11Privacy = cipher; pEncryptKey = &pstat->dot11KeyMapping.dot11EncryptKey; pstat->keyid = wk->ik_keyix; #if defined(__DRAYTEK_OS__) && defined(WDS) if (pstat->state & WIFI_WDS) priv->pmib->dot11WdsInfo.wdsPrivacy = cipher; #endif switch(cipher) { case DOT11_ENC_TKIP: set_ttkeylen(pEncryptKey, 16); set_tmickeylen(pEncryptKey, 8); set_tkip_key(pEncryptKey, wk->ik_keydata); HAPD_MSG("going to set TKIP Unicast key for sta %02X%02X%02X%02X%02X%02X, id=%d\n", wk->ik_macaddr[0], wk->ik_macaddr[1], wk->ik_macaddr[2], wk->ik_macaddr[3], wk->ik_macaddr[4], wk->ik_macaddr[5], pstat->keyid); if (!SWCRYPTO) { retVal = CamDeleteOneEntry(priv, wk->ik_macaddr, wk->ik_keyix, 0); if (retVal) { priv->pshare->CamEntryOccupied--; if (pstat) pstat->dot11KeyMapping.keyInCam = FALSE; } retVal = CamAddOneEntry(priv, wk->ik_macaddr, wk->ik_keyix, DOT11_ENC_TKIP<<2, 0, wk->ik_keydata); if (retVal) { priv->pshare->CamEntryOccupied++; if (pstat) pstat->dot11KeyMapping.keyInCam = TRUE; } else { if (pstat->aggre_mthd != AGGRE_MTHD_NONE) pstat->aggre_mthd = AGGRE_MTHD_NONE; } } break; case DOT11_ENC_WEP40: set_ttkeylen(pEncryptKey, 5); set_tmickeylen(pEncryptKey, 0); set_wep40_key(pEncryptKey, wk->ik_keydata); HAPD_MSG("going to set WEP40 unicast key for sta %02X%02X%02X%02X%02X%02X, id=%d\n", wk->ik_macaddr[0], wk->ik_macaddr[1], wk->ik_macaddr[2], wk->ik_macaddr[3], wk->ik_macaddr[4], wk->ik_macaddr[5], pstat->keyid); if (!SWCRYPTO) { retVal = CamDeleteOneEntry(priv, wk->ik_macaddr, wk->ik_keyix, 0); if (retVal) { priv->pshare->CamEntryOccupied--; if (pstat) pstat->dot11KeyMapping.keyInCam = FALSE; } retVal = CamAddOneEntry(priv, wk->ik_macaddr, wk->ik_keyix, DOT11_ENC_WEP40<<2, 0, wk->ik_keydata); if (retVal) { priv->pshare->CamEntryOccupied++; if (pstat) pstat->dot11KeyMapping.keyInCam = TRUE; } else { if (pstat->aggre_mthd != AGGRE_MTHD_NONE) pstat->aggre_mthd = AGGRE_MTHD_NONE; } } break; case DOT11_ENC_WEP104: set_ttkeylen(pEncryptKey, 13); set_tmickeylen(pEncryptKey, 0); set_wep104_key(pEncryptKey, wk->ik_keydata); HAPD_MSG("going to set WEP104 unicast key for sta %02X%02X%02X%02X%02X%02X, id=%d\n", wk->ik_macaddr[0], wk->ik_macaddr[1], wk->ik_macaddr[2], wk->ik_macaddr[3], wk->ik_macaddr[4], wk->ik_macaddr[5], pstat->keyid); if (!SWCRYPTO) { retVal = CamDeleteOneEntry(priv, wk->ik_macaddr, wk->ik_keyix, 0); if (retVal) { priv->pshare->CamEntryOccupied--; if (pstat) pstat->dot11KeyMapping.keyInCam = FALSE; } retVal = CamAddOneEntry(priv, wk->ik_macaddr, wk->ik_keyix, DOT11_ENC_WEP104<<2, 0, wk->ik_keydata); if (retVal) { priv->pshare->CamEntryOccupied++; if (pstat) pstat->dot11KeyMapping.keyInCam = TRUE; } else { if (pstat->aggre_mthd != AGGRE_MTHD_NONE) pstat->aggre_mthd = AGGRE_MTHD_NONE; } } break; case DOT11_ENC_CCMP: set_ttkeylen(pEncryptKey, 16); set_tmickeylen(pEncryptKey, 16); set_aes_key(pEncryptKey, wk->ik_keydata); HAPD_MSG("going to set CCMP-AES unicast key for sta %02X%02X%02X%02X%02X%02X, id=%d\n", wk->ik_macaddr[0], wk->ik_macaddr[1], wk->ik_macaddr[2], wk->ik_macaddr[3], wk->ik_macaddr[4], wk->ik_macaddr[5], pstat->keyid); if (!SWCRYPTO) { retVal = CamDeleteOneEntry(priv, wk->ik_macaddr, wk->ik_keyix, 0); if (retVal) { priv->pshare->CamEntryOccupied--; if (pstat) pstat->dot11KeyMapping.keyInCam = FALSE; } retVal = CamAddOneEntry(priv, wk->ik_macaddr, wk->ik_keyix, DOT11_ENC_CCMP<<2, 0, wk->ik_keydata); if (retVal) { HAPD_MSG("CamAddOneEntry of CCMP OK\n"); priv->pshare->CamEntryOccupied++; if (pstat) pstat->dot11KeyMapping.keyInCam = TRUE; assign_aggre_mthod(priv, pstat); } else { HAPD_MSG("CamAddOneEntry of CCMP FAIL\n"); if (pstat->aggre_mthd != AGGRE_MTHD_NONE) pstat->aggre_mthd = AGGRE_MTHD_NONE; } } break; case DOT11_ENC_NONE: default: DEBUG_ERR("No pairewise encryption key is set!\n"); set_ttkeylen(pEncryptKey, 0); set_tmickeylen(pEncryptKey, 0); break; } } HAPD_MSG("rtl_net80211_setkey ---\n"); return 0; } int rtl_net80211_delkey(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { #ifdef NETDEV_NO_PRIV struct rtl8192cd_priv *priv = ((struct rtl8192cd_priv *)netdev_priv(dev))->wlan_priv; #else struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)dev->priv; #endif #ifdef RTK_NL80211 struct ieee80211req_del_key *wk = (struct ieee80211req_del_key *)wrqu->data.pointer; #else struct ieee80211req_del_key *wk = (struct ieee80211req_del_key *)wrqu->name; #endif struct stat_info *pstat = NULL; struct wifi_mib *pmib = priv->pmib; unsigned char MULTICAST_ADD[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; int ret = 0; //check if the interface is down if (!netif_running(priv->dev)) { HAPD_MSG("\nFail: interface not opened\n"); return 0; } HAPD_MSG("rtl_net80211_delkey +++ \n"); HAPD_MSG("keyid = %d, mac = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n" , wk->idk_keyix, wk->idk_macaddr[0], wk->idk_macaddr[1], wk->idk_macaddr[2], wk->idk_macaddr[3], wk->idk_macaddr[4], wk->idk_macaddr[5]); if(!memcmp(wk->idk_macaddr, "\x00\x00\x00\x00\x00\x00", 6)) { HAPD_MSG("reset ALL key !!!!!\n"); CamResetAllEntry(priv); } if (!memcmp(wk->idk_macaddr, MULTICAST_ADD, 6)) { pmib->dot11GroupKeysTable.dot11EncryptKey.dot11TTKeyLen = 0; pmib->dot11GroupKeysTable.dot11EncryptKey.dot11TMicKeyLen = 0; HAPD_MSG("Delete Group Key\n"); if (CamDeleteOneEntry(priv, MULTICAST_ADD, 1, 0)) priv->pshare->CamEntryOccupied--; #if defined(CONFIG_RTL_HW_WAPI_SUPPORT) if (CamDeleteOneEntry(priv, MULTICAST_ADD, 1, 0)) priv->pshare->CamEntryOccupied--; #endif } else { pstat = get_stainfo(priv, (UINT8 *)wk->idk_macaddr); if (pstat == NULL) return (-1); pstat->dot11KeyMapping.dot11EncryptKey.dot11TTKeyLen = 0; pstat->dot11KeyMapping.dot11EncryptKey.dot11TMicKeyLen = 0; HAPD_MSG("Delete Unicast Key\n"); if (pstat->dot11KeyMapping.keyInCam == TRUE) { if (CamDeleteOneEntry(priv, (unsigned char *)wk->idk_macaddr, 0, 0)) { priv->pshare->CamEntryOccupied--; if (pstat) pstat->dot11KeyMapping.keyInCam = FALSE; } #if defined(CONFIG_RTL_HW_WAPI_SUPPORT) if (CamDeleteOneEntry(priv, (unsigned char *)wk->idk_macaddr, 0, 0)) { priv->pshare->CamEntryOccupied--; if (pstat) pstat->dot11KeyMapping.keyInCam = FALSE; } #endif } } HAPD_MSG("rtl_net80211_delkey --- \n"); return ret; } int rtl_net80211_getwpaie(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { #ifdef NETDEV_NO_PRIV struct rtl8192cd_priv *priv = ((struct rtl8192cd_priv *)netdev_priv(dev))->wlan_priv; #else struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)dev->priv; #endif struct ieee80211req_wpaie *ie = (struct ieee80211req_wpaie *)wrqu->data.pointer; struct stat_info *pstat = get_stainfo(priv, ie->wpa_macaddr); int ret = 0; HAPD_MSG("rtl_net80211_getwpaie +++ \n"); HAPD_MSG("mac = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", ie->wpa_macaddr[0], ie->wpa_macaddr[1], ie->wpa_macaddr[2], ie->wpa_macaddr[3], ie->wpa_macaddr[4], ie->wpa_macaddr[5]); if(pstat == NULL) return -EINVAL; #ifndef HAPD_DRV_PSK_WPS HAPD_MSG("RSNEnabled = %d\n" "wpa_ie = 0x%02x 0x%02x 0x%02x \n" "wps_ie = 0x%02x 0x%02x 0x%02x \n" ,pstat->wpa_sta_info->RSNEnabled, pstat->wpa_ie[0], pstat->wpa_ie[1], pstat->wpa_ie[2], pstat->wps_ie[0], pstat->wps_ie[1], pstat->wps_ie[2] ); #else HAPD_MSG("RSNEnabled = %d\n" "wpa_ie = 0x%02x 0x%02x 0x%02x \n" ,pstat->wpa_sta_info->RSNEnabled, pstat->wpa_ie[0], pstat->wpa_ie[1], pstat->wpa_ie[2] ); #endif if(pstat->wpa_sta_info->RSNEnabled & BIT(0)) memcpy(ie->wpa_ie, pstat->wpa_ie, pstat->wpa_ie[1]+2); else if(pstat->wpa_sta_info->RSNEnabled & BIT(1)) memcpy(ie->rsn_ie, pstat->wpa_ie, pstat->wpa_ie[1]+2); #ifndef HAPD_DRV_PSK_WPS if((priv->pmib->wscEntry.wsc_enable & 2) && (pstat->wps_ie[1])) memcpy(ie->wps_ie, pstat->wps_ie, pstat->wps_ie[1]+2); #endif HAPD_MSG("rtl_net80211_getwpaie --- \n"); return ret; } #if (defined(WIFI_HAPD) && defined(WDS)) && !defined(HAPD_DRV_PSK_WPS) int rtl_net80211_wdsaddmac(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { #ifdef NETDEV_NO_PRIV struct rtl8192cd_priv *priv = ((struct rtl8192cd_priv *)netdev_priv(dev))->wlan_priv; #else struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)dev->priv; #endif struct rtk_wds_config *wds = (struct hapd_wds_info *)wrqu->data.pointer; int ret = 0; int num = 0; HAPD_MSG("rtl_net80211_wdsaddmac +++ \n"); if(wds->wdsEnabled == 0) goto bad; if(wds->wdsNum > NUM_WDS) goto bad; if( (wds->wdsPrivacy != _NO_PRIVACY_) && (wds->wdsPrivacy != _WEP_40_PRIVACY_) && (wds->wdsPrivacy != _TKIP_PRIVACY_) && (wds->wdsPrivacy != _CCMP_PRIVACY_) && (wds->wdsPrivacy != _WEP_104_PRIVACY_)) goto bad; if((wds->wdsPrivacy == _WEP_40_PRIVACY_) && (wds->wdsWepKeyLen != 5)) goto bad; if((wds->wdsPrivacy == _WEP_104_PRIVACY_) && (wds->wdsWepKeyLen != 13)) goto bad; priv->pmib->dot11WdsInfo.wdsEnabled = 1; priv->pmib->dot11WdsInfo.wdsNum = wds->wdsNum; for(num=0 ; num < wds->wdsNum; num++) memcpy(priv->pmib->dot11WdsInfo.entry[num].macAddr, wds->macAddr[num], MACADDRLEN); priv->pmib->dot11WdsInfo.wdsPrivacy = wds->wdsPrivacy; if((wds->wdsPrivacy == _WEP_40_PRIVACY_)||(wds->wdsPrivacy == _WEP_104_PRIVACY_)) memcpy(priv->pmib->dot11WdsInfo.wdsWepKey, wds->wdsWepKey, wds->wdsWepKeyLen); else if((wds->wdsPrivacy == _TKIP_PRIVACY_)||(wds->wdsPrivacy == _CCMP_PRIVACY_)) hapd_set_wdskey(dev, wds->wdsPskPassPhrase, wds->ssid, wds->wdsNum); HAPD_MSG("rtl_net80211_wdsaddmac --- \n"); return 0; bad: priv->pmib->dot11WdsInfo.wdsEnabled = 0; return -EINVAL; } int rtl_net80211_wdsdelmac(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { #ifdef NETDEV_NO_PRIV struct rtl8192cd_priv *priv = ((struct rtl8192cd_priv *)netdev_priv(dev))->wlan_priv; #else struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)dev->priv; #endif struct rtk_wds_config *wds = (struct rtk_wds_config *)wrqu->data.pointer; HAPD_MSG("rtl_net80211_wdsdelmac +++ \n"); priv->pmib->dot11WdsInfo.wdsEnabled = 0; priv->pmib->dot11WdsInfo.wdsNum = 0; HAPD_MSG("rtl_net80211_wdsdelmac --- \n"); return 0; } #endif int rtl_hapd_config(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { #ifdef NETDEV_NO_PRIV struct rtl8192cd_priv *priv = ((struct rtl8192cd_priv *)netdev_priv(dev))->wlan_priv; #else struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)dev->priv; #endif struct rtk_hapd_config *config = (struct rtk_hapd_config *)wrqu->data.pointer; int size = 0; HAPD_MSG("rtl_hapd_config +++\n"); priv->pmib->dot11BssType.net_work_type = config->band; priv->pmib->dot11RFEntry.dot11channel = config->channel; priv->pmib->dot11StationConfigEntry.dot11BeaconPeriod = config->bcnint; priv->pmib->dot11StationConfigEntry.dot11DTIMPeriod = config->dtimperiod; if(config->stanum <= NUM_STAT) priv->pmib->dot11StationConfigEntry.supportedStaNum = config->stanum; else { HAPD_MSG("Invalid Station Number!!!\n"); return -1; } priv->pmib->dot11OperationEntry.dot11RTSThreshold = config->rtsthres; priv->pmib->dot11OperationEntry.dot11FragmentationThreshold = config->fragthres; priv->pmib->dot11StationConfigEntry.dot11SupportedRates = config->oprates; priv->pmib->dot11StationConfigEntry.dot11BasicRates = config->basicrates; priv->pmib->dot11RFEntry.shortpreamble = config->preamble; priv->pmib->dot11StationConfigEntry.dot11AclMode = config->aclmode; priv->pmib->dot11StationConfigEntry.dot11AclNum = config->aclnum; size = sizeof(priv->pmib->dot11StationConfigEntry.dot11AclAddr); memcpy(priv->pmib->dot11StationConfigEntry.dot11AclAddr, config->acladdr, size); priv->pmib->dot11OperationEntry.hiddenAP = config->hiddenAP; #ifdef WIFI_WMM priv->pmib->dot11QosEntry.dot11QosEnable = config->qos_enable; #endif priv->pmib->dot11OperationEntry.expiretime = config->expired_time * 100; // 10ms unit vs 1s unit priv->pmib->dot11OperationEntry.block_relay = config->block_relay; priv->pmib->dot11nConfigEntry.dot11nShortGIfor20M = config->shortGI20M; priv->pmib->dot11nConfigEntry.dot11nShortGIfor40M = config->shortGI40M; //Above are for Hostapd owned configurations //===================================================== //Below are for RTK private configurations size = sizeof(priv->pmib->dot11RFEntry.pwrlevelCCK_A); memcpy(priv->pmib->dot11RFEntry.pwrlevelCCK_A, config->pwrlevelCCK_A, size); size = sizeof(priv->pmib->dot11RFEntry.pwrlevelCCK_B); memcpy(priv->pmib->dot11RFEntry.pwrlevelCCK_B, config->pwrlevelCCK_B, size); size = sizeof(priv->pmib->dot11RFEntry.pwrlevelHT40_1S_A); memcpy(priv->pmib->dot11RFEntry.pwrlevelHT40_1S_A, config->pwrlevelHT40_1S_A, size); size = sizeof(priv->pmib->dot11RFEntry.pwrlevelHT40_1S_B); memcpy(priv->pmib->dot11RFEntry.pwrlevelHT40_1S_B, config->pwrlevelHT40_1S_A, size); size = sizeof(priv->pmib->dot11RFEntry.pwrdiffHT40_2S); memcpy(priv->pmib->dot11RFEntry.pwrdiffHT40_2S, config->pwrdiffHT40_2S, size); size = sizeof(priv->pmib->dot11RFEntry.pwrdiffHT20); memcpy(priv->pmib->dot11RFEntry.pwrdiffHT20, config->pwrdiffHT20, size); size = sizeof(priv->pmib->dot11RFEntry.pwrdiffOFDM); memcpy(priv->pmib->dot11RFEntry.pwrdiffOFDM, config->pwrdiffOFDM, size); priv->pmib->dot11RFEntry.ther = config->ther; #ifdef CONFIG_RTL_92D_SUPPORT priv->pmib->dot11RFEntry.phyBandSelect = config->phyBandSelect; #endif priv->pmib->dot11StationConfigEntry.dot11swcrypto = config->swcrypto; priv->pmib->dot11StationConfigEntry.dot11RegDomain = config->regdomain; priv->pmib->dot11StationConfigEntry.autoRate = config->autorate; priv->pmib->dot11StationConfigEntry.fixedTxRate = config->fixrate; priv->pmib->dot11StationConfigEntry.protectionDisabled = config->disable_protection; priv->pmib->dot11StationConfigEntry.olbcDetectDisabled = config->disable_olbc; priv->pmib->dot11StationConfigEntry.legacySTADeny = config->deny_legacy; priv->pmib->dot11OperationEntry.opmode = config->opmode; priv->pmib->dot11nConfigEntry.dot11nUse40M = config->use40M; priv->pmib->dot11nConfigEntry.dot11n2ndChOffset = config->_2ndchoffset; priv->pmib->dot11nConfigEntry.dot11nAMPDU = config->ampdu; priv->pmib->dot11OperationEntry.guest_access = config->guest_access; priv->pmib->dot11RFEntry.macPhyMode = config->macPhyMode; #ifdef WIFI_11N_2040_COEXIST priv->pmib->dot11nConfigEntry.dot11nCoexist = config->coexist; #endif #ifdef MBSSID priv->pmib->miscEntry.vap_enable = config->vap_enable; #endif priv->pshare->rf_ft_var.rssi_dump = config->rssi_dump; #ifdef MP_TEST priv->pshare->rf_ft_var.mp_specific = config->mp_specific; #endif #ifdef HIGH_POWER_EXT_PA priv->pshare->rf_ft_var.use_ext_pa = config->use_ext_pa; #endif HAPD_MSG("rtl_hapd_config ---\n"); return 0; } #ifdef WIFI_WPAS int rtl_wpas_config_2G(struct rtl8192cd_priv *priv) { HAPD_MSG("wpas config wlan 2.4G\n"); priv->pmib->dot11BssType.net_work_type = 1 + 2 + 8; priv->pmib->dot11RFEntry.dot11channel = 11; priv->pmib->dot11nConfigEntry.dot11nShortGIfor20M = 1; priv->pmib->dot11nConfigEntry.dot11nShortGIfor40M = 1; priv->pmib->dot11StationConfigEntry.autoRate = 1; priv->pmib->dot11nConfigEntry.dot11nUse40M = 1; priv->pmib->dot11nConfigEntry.dot11nAMPDU = 1; //priv->pmib->dot11RFEntry.macPhyMode = DUALMAC_DUALPHY; priv->pmib->dot11nConfigEntry.dot11n2ndChOffset = HT_2NDCH_OFFSET_BELOW; priv->pmib->dot11StationConfigEntry.dot11SupportedRates = 0xfff; priv->pmib->dot11StationConfigEntry.dot11BasicRates = 0xf; priv->pmib->dot11OperationEntry.wifi_specific = 2; //_Eric ?? priv->pmib->dot11OperationEntry.dot11FragmentationThreshold = 2346; #ifdef CONFIG_RTL_92D_SUPPORT priv->pmib->dot11RFEntry.phyBandSelect = PHY_BAND_2G; #endif #ifdef WIFI_WMM priv->pmib->dot11QosEntry.dot11QosEnable = 1; #endif } int rtl_wpas_config_5G(struct rtl8192cd_priv *priv) { printk("wpas config wlan 5G\n"); priv->pmib->dot11BssType.net_work_type = 4 + 8; priv->pmib->dot11RFEntry.dot11channel = 44; priv->pmib->dot11nConfigEntry.dot11nShortGIfor20M = 1; priv->pmib->dot11nConfigEntry.dot11nShortGIfor40M = 1; priv->pmib->dot11StationConfigEntry.autoRate = 1; priv->pmib->dot11nConfigEntry.dot11nUse40M = 1; priv->pmib->dot11nConfigEntry.dot11nAMPDU = 1; //priv->pmib->dot11RFEntry.macPhyMode = DUALMAC_DUALPHY; //_Eric ?? How to judge ?? priv->pmib->dot11nConfigEntry.dot11n2ndChOffset = HT_2NDCH_OFFSET_ABOVE; priv->pmib->dot11StationConfigEntry.dot11SupportedRates = 0xff0; priv->pmib->dot11StationConfigEntry.dot11BasicRates = 0xff0; priv->pmib->dot11OperationEntry.wifi_specific = 2; priv->pmib->dot11OperationEntry.dot11FragmentationThreshold = 2346; #ifdef CONFIG_RTL_92D_SUPPORT priv->pmib->dot11RFEntry.phyBandSelect = PHY_BAND_5G; #endif #ifdef WIFI_WMM priv->pmib->dot11QosEntry.dot11QosEnable = 1; #endif } int rtl_wpas_config(struct rtl8192cd_priv *priv, unsigned char bandmode, unsigned char phymode) { HAPD_MSG("wpas config interface: %s\n", priv->dev->name); priv->pmib->dot11OperationEntry.opmode = WIFI_STATION_STATE; if(bandmode == SINGLEMAC_SINGLEPHY) { priv->pmib->dot11RFEntry.macPhyMode = SINGLEMAC_SINGLEPHY; if(phymode == PHY_BAND_5G) rtl_wpas_config_5G(priv); else if(phymode == PHY_BAND_2G) rtl_wpas_config_2G(priv); else return -1; } else if(!strcmp(priv->dev->name, "wlan0")) { priv->pmib->dot11RFEntry.macPhyMode = DUALMAC_DUALPHY; rtl_wpas_config_5G(priv); } else if(!strcmp(priv->dev->name, "wlan1")) { priv->pmib->dot11RFEntry.macPhyMode = DUALMAC_DUALPHY; rtl_wpas_config_2G(priv); } else return -1; return 0; } int rtl_wpas_custom(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { #ifdef NETDEV_NO_PRIV struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)netdev_priv(dev); #else struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)dev->priv; #endif struct rtk_wpas_config *config = (struct rtk_wpas_config *)wrqu->data.pointer; int ret = 0; switch (config->type) { case WPAS_CONFIG_MIB: HAPD_MSG("bandmode %d phymode %d \n", config->bandmode, config->phymode); if((config->bandmode == SINGLEMAC_SINGLEPHY) || (config->bandmode == DUALMAC_DUALPHY)) ret = rtl_wpas_config(priv, config->bandmode, config->phymode); else return -EINVAL; break; case WPAS_CONFIG_WEPKEY: HAPD_MSG("WPAS_CONFIG_WEPKEY !!! \n"); memcpy(&priv->pmib->dot11DefaultKeysTable.keytype[config->wep_keyidx].skey[0], config->wep_key, config->wep_keylen); break; } return ret; } #endif static void Construct_RSNIE(struct rtl8192cd_priv *priv, unsigned char *pucOut, int *usOutLen) { DOT11_RSN_IE_HEADER dot11RSNIEHeader = { 0 }; DOT11_RSN_IE_SUITE dot11RSNGroupSuite; DOT11_RSN_IE_COUNT_SUITE *pDot11RSNPairwiseSuite = NULL; DOT11_RSN_IE_COUNT_SUITE *pDot11RSNAuthSuite = NULL; unsigned short usSuitCount; unsigned long ulIELength = 0; unsigned long ulIndex = 0; unsigned long ulPairwiseLength = 0; unsigned long ulAuthLength = 0; unsigned char *pucBlob; DOT11_RSN_IE_COUNT_SUITE countSuite, authCountSuite; #ifdef RTL_WPA2 DOT11_RSN_CAPABILITY dot11RSNCapability = { 0 }; unsigned long uCipherAlgo = 0; int bCipherAlgoEnabled = FALSE; unsigned long uAuthAlgo = 0; int bAuthAlgoEnabled = FALSE; unsigned long ulRSNCapabilityLength = 0; #endif *usOutLen = 0; if ( priv->pmib->dot1180211AuthEntry.dot11WPACipher != 0 ) { // // Construct Information Header // dot11RSNIEHeader.ElementID = RSN_ELEMENT_ID; dot11RSNIEHeader.OUI[0] = 0x00; dot11RSNIEHeader.OUI[1] = 0x50; dot11RSNIEHeader.OUI[2] = 0xf2; dot11RSNIEHeader.OUI[3] = 0x01; dot11RSNIEHeader.Version = cpu_to_le16(RSN_VER1); ulIELength += sizeof(DOT11_RSN_IE_HEADER); // Construct Cipher Suite: // - Multicast Suite: memset(&dot11RSNGroupSuite, 0, sizeof dot11RSNGroupSuite); dot11RSNGroupSuite.OUI[0] = 0x00; dot11RSNGroupSuite.OUI[1] = 0x50; dot11RSNGroupSuite.OUI[2] = 0xF2; dot11RSNGroupSuite.Type = priv->wpa_global_info->MulticastCipher; ulIELength += sizeof(DOT11_RSN_IE_SUITE); // - UnicastSuite pDot11RSNPairwiseSuite = &countSuite; memset(pDot11RSNPairwiseSuite, 0, sizeof(DOT11_RSN_IE_COUNT_SUITE)); usSuitCount = 0; for (ulIndex=0; ulIndexwpa_global_info->NumOfUnicastCipher; ulIndex++) { pDot11RSNPairwiseSuite->dot11RSNIESuite[usSuitCount].OUI[0] = 0x00; pDot11RSNPairwiseSuite->dot11RSNIESuite[usSuitCount].OUI[1] = 0x50; pDot11RSNPairwiseSuite->dot11RSNIESuite[usSuitCount].OUI[2] = 0xF2; pDot11RSNPairwiseSuite->dot11RSNIESuite[usSuitCount].Type = priv->wpa_global_info->UnicastCipher[ulIndex]; usSuitCount++; } pDot11RSNPairwiseSuite->SuiteCount = cpu_to_le16(usSuitCount); ulPairwiseLength = sizeof(pDot11RSNPairwiseSuite->SuiteCount) + usSuitCount*sizeof(DOT11_RSN_IE_SUITE); ulIELength += ulPairwiseLength; // // Construction of Auth Algo List // pDot11RSNAuthSuite = &authCountSuite; memset(pDot11RSNAuthSuite, 0, sizeof(DOT11_RSN_IE_COUNT_SUITE)); usSuitCount = 0; pDot11RSNAuthSuite->dot11RSNIESuite[usSuitCount].OUI[0] = 0x00; pDot11RSNAuthSuite->dot11RSNIESuite[usSuitCount].OUI[1] = 0x50; pDot11RSNAuthSuite->dot11RSNIESuite[usSuitCount].OUI[2] = 0xF2; pDot11RSNAuthSuite->dot11RSNIESuite[usSuitCount].Type = DOT11_AuthKeyType_RSN; usSuitCount++; pDot11RSNAuthSuite->SuiteCount = cpu_to_le16(usSuitCount); ulAuthLength = sizeof(pDot11RSNAuthSuite->SuiteCount) + usSuitCount*sizeof(DOT11_RSN_IE_SUITE); ulIELength += ulAuthLength; pucBlob = pucOut; pucBlob += sizeof(DOT11_RSN_IE_HEADER); memcpy(pucBlob, &dot11RSNGroupSuite, sizeof(DOT11_RSN_IE_SUITE)); pucBlob += sizeof(DOT11_RSN_IE_SUITE); memcpy(pucBlob, pDot11RSNPairwiseSuite, ulPairwiseLength); pucBlob += ulPairwiseLength; memcpy(pucBlob, pDot11RSNAuthSuite, ulAuthLength); pucBlob += ulAuthLength; *usOutLen = (int)ulIELength; pucBlob = pucOut; dot11RSNIEHeader.Length = (unsigned char)ulIELength - 2; //This -2 is to minus elementID and Length in OUI header memcpy(pucBlob, &dot11RSNIEHeader, sizeof(DOT11_RSN_IE_HEADER)); } #ifdef RTL_WPA2 if ( priv->pmib->dot1180211AuthEntry.dot11WPA2Cipher != 0 ) { DOT11_WPA2_IE_HEADER dot11WPA2IEHeader = { 0 }; ulIELength = 0; ulIndex = 0; ulPairwiseLength = 0; uCipherAlgo = 0; bCipherAlgoEnabled = FALSE; ulAuthLength = 0; uAuthAlgo = 0; bAuthAlgoEnabled = FALSE; ulRSNCapabilityLength = 0; // // Construct Information Header // dot11WPA2IEHeader.ElementID = WPA2_ELEMENT_ID; dot11WPA2IEHeader.Version = cpu_to_le16(RSN_VER1); ulIELength += sizeof(DOT11_WPA2_IE_HEADER); // Construct Cipher Suite: // - Multicast Suite: // memset(&dot11RSNGroupSuite, 0, sizeof(dot11RSNGroupSuite)); dot11RSNGroupSuite.OUI[0] = 0x00; dot11RSNGroupSuite.OUI[1] = 0x0F; dot11RSNGroupSuite.OUI[2] = 0xAC; dot11RSNGroupSuite.Type = priv->wpa_global_info->MulticastCipher;; ulIELength += sizeof(DOT11_RSN_IE_SUITE); // - UnicastSuite pDot11RSNPairwiseSuite = &countSuite; memset(pDot11RSNPairwiseSuite, 0, sizeof(DOT11_RSN_IE_COUNT_SUITE)); usSuitCount = 0; for (ulIndex=0; ulIndexwpa_global_info->NumOfUnicastCipherWPA2; ulIndex++) { pDot11RSNPairwiseSuite->dot11RSNIESuite[usSuitCount].OUI[0] = 0x00; pDot11RSNPairwiseSuite->dot11RSNIESuite[usSuitCount].OUI[1] = 0x0F; pDot11RSNPairwiseSuite->dot11RSNIESuite[usSuitCount].OUI[2] = 0xAC; pDot11RSNPairwiseSuite->dot11RSNIESuite[usSuitCount].Type = priv->wpa_global_info->UnicastCipherWPA2[ulIndex]; usSuitCount++; } pDot11RSNPairwiseSuite->SuiteCount = cpu_to_le16(usSuitCount); ulPairwiseLength = sizeof(pDot11RSNPairwiseSuite->SuiteCount) + usSuitCount*sizeof(DOT11_RSN_IE_SUITE); ulIELength += ulPairwiseLength; // // Construction of Auth Algo List // pDot11RSNAuthSuite = &authCountSuite; memset(pDot11RSNAuthSuite, 0, sizeof(DOT11_RSN_IE_COUNT_SUITE)); usSuitCount = 0; pDot11RSNAuthSuite->dot11RSNIESuite[usSuitCount].OUI[0] = 0x00; pDot11RSNAuthSuite->dot11RSNIESuite[usSuitCount].OUI[1] = 0x0F; pDot11RSNAuthSuite->dot11RSNIESuite[usSuitCount].OUI[2] = 0xAC; pDot11RSNAuthSuite->dot11RSNIESuite[usSuitCount].Type = DOT11_AuthKeyType_RSN; usSuitCount++; pDot11RSNAuthSuite->SuiteCount = cpu_to_le16(usSuitCount); ulAuthLength = sizeof(pDot11RSNAuthSuite->SuiteCount) + usSuitCount*sizeof(DOT11_RSN_IE_SUITE); ulIELength += ulAuthLength; //--------------------------------------------------------------------------------------------- // Do not encapsulate capability field to solve TI WPA issue //--------------------------------------------------------------------------------------------- dot11RSNCapability.field.PreAuthentication = 0; ulRSNCapabilityLength = sizeof(DOT11_RSN_CAPABILITY); ulIELength += ulRSNCapabilityLength; pucBlob = pucOut + *usOutLen; pucBlob += sizeof(DOT11_WPA2_IE_HEADER); memcpy(pucBlob, &dot11RSNGroupSuite, sizeof(DOT11_RSN_IE_SUITE)); pucBlob += sizeof(DOT11_RSN_IE_SUITE); memcpy(pucBlob, pDot11RSNPairwiseSuite, ulPairwiseLength); pucBlob += ulPairwiseLength; memcpy(pucBlob, pDot11RSNAuthSuite, ulAuthLength); pucBlob += ulAuthLength; memcpy(pucBlob, &dot11RSNCapability, ulRSNCapabilityLength); pucBlob = pucOut + *usOutLen; dot11WPA2IEHeader.Length = (unsigned char)ulIELength - 2; //This -2 is to minus elementID and Length in OUI header memcpy(pucBlob, &dot11WPA2IEHeader, sizeof(DOT11_WPA2_IE_HEADER)); *usOutLen = *usOutLen + (int)ulIELength; } #endif // RTL_WPA2 } static void ToDrv_SetRSNIE(struct rtl8192cd_priv *priv) { struct iw_point wrq; DOT11_SET_RSNIE Set_Rsnie; debug_out("RSN: Set RSNIE", priv->wpa_global_info->AuthInfoElement.Octet, priv->wpa_global_info->AuthInfoElement.Length); wrq.pointer = (caddr_t)&Set_Rsnie; wrq.length = sizeof(DOT11_SET_RSNIE); Set_Rsnie.EventId = DOT11_EVENT_SET_RSNIE; Set_Rsnie.IsMoreEvent = FALSE; Set_Rsnie.Flag = DOT11_Ioctl_Set; Set_Rsnie.RSNIELen = priv->wpa_global_info->AuthInfoElement.Length; memcpy(&Set_Rsnie.RSNIE, priv->wpa_global_info->AuthInfoElement.Octet, priv->wpa_global_info->AuthInfoElement.Length); rtl8192cd_ioctl_priv_daemonreq(priv->dev, &wrq); } void rsn_init(struct rtl8192cd_priv *priv) { WPA_GLOBAL_INFO *pGblInfo=priv->wpa_global_info; int i, j, low_cipher=0; DEBUG_TRACE; HAPD_MSG("rsn_init\n"); memset((char *)pGblInfo, '\0', sizeof(WPA_GLOBAL_INFO)); if (priv->pmib->dot1180211AuthEntry.dot11WPACipher) { for (i=0, j=0; i<_WEP_104_PRIVACY_; i++) { if (priv->pmib->dot1180211AuthEntry.dot11WPACipher & (1<UnicastCipher[j] = i+1; if (low_cipher == 0) low_cipher = pGblInfo->UnicastCipher[j]; else { if (low_cipher == _WEP_104_PRIVACY_ && pGblInfo->UnicastCipher[j] == _WEP_40_PRIVACY_) low_cipher = pGblInfo->UnicastCipher[j]; else if (low_cipher == _TKIP_PRIVACY_ && (pGblInfo->UnicastCipher[j] == _WEP_40_PRIVACY_ || pGblInfo->UnicastCipher[j] == _WEP_104_PRIVACY_)) low_cipher = pGblInfo->UnicastCipher[j]; else if (low_cipher == _CCMP_PRIVACY_) low_cipher = pGblInfo->UnicastCipher[j]; } if (++j >= MAX_UNICAST_CIPHER) break; } } pGblInfo->NumOfUnicastCipher = j; } #ifdef RTL_WPA2 if (priv->pmib->dot1180211AuthEntry.dot11WPA2Cipher) { for (i=0, j=0; i<_WEP_104_PRIVACY_; i++) { if (priv->pmib->dot1180211AuthEntry.dot11WPA2Cipher & (1<UnicastCipherWPA2[j] = i+1; if (low_cipher == 0) low_cipher = pGblInfo->UnicastCipherWPA2[j]; else { if (low_cipher == _WEP_104_PRIVACY_ && pGblInfo->UnicastCipherWPA2[j] == _WEP_40_PRIVACY_) low_cipher = pGblInfo->UnicastCipherWPA2[j]; else if (low_cipher == _TKIP_PRIVACY_ && (pGblInfo->UnicastCipherWPA2[j] == _WEP_40_PRIVACY_ || pGblInfo->UnicastCipherWPA2[j] == _WEP_104_PRIVACY_)) low_cipher = pGblInfo->UnicastCipherWPA2[j]; else if (low_cipher == _CCMP_PRIVACY_) low_cipher = pGblInfo->UnicastCipherWPA2[j]; } if (++j >= MAX_UNICAST_CIPHER) break; } } pGblInfo->NumOfUnicastCipherWPA2= j; } #endif pGblInfo->MulticastCipher = low_cipher; HAPD_MSG("RSN: WPA unicast cipher= "); for (i=0; iNumOfUnicastCipher; i++) HAPD_MSG("%x ", pGblInfo->UnicastCipher[i]); HAPD_MSG("\n"); #ifdef RTL_WPA2 HAPD_MSG("RSN: WPA2 unicast cipher= "); for (i=0; iNumOfUnicastCipherWPA2; i++) HAPD_MSG("%x ", pGblInfo->UnicastCipherWPA2[i]); HAPD_MSG("\n"); #endif HAPD_MSG("RSN: multicast cipher= %x\n", pGblInfo->MulticastCipher); pGblInfo->AuthInfoElement.Octet = pGblInfo->AuthInfoBuf; Construct_RSNIE(priv, pGblInfo->AuthInfoElement.Octet, &pGblInfo->AuthInfoElement.Length); ToDrv_SetRSNIE(priv); } #endif //WIFI_HAPD