summaryrefslogtreecommitdiffstats
path: root/target/linux/realtek/files/drivers/net/wireless/rtl8192e/8192cd_net80211.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/realtek/files/drivers/net/wireless/rtl8192e/8192cd_net80211.c')
-rw-r--r--target/linux/realtek/files/drivers/net/wireless/rtl8192e/8192cd_net80211.c1928
1 files changed, 1928 insertions, 0 deletions
diff --git a/target/linux/realtek/files/drivers/net/wireless/rtl8192e/8192cd_net80211.c b/target/linux/realtek/files/drivers/net/wireless/rtl8192e/8192cd_net80211.c
new file mode 100644
index 000000000..552e481b3
--- /dev/null
+++ b/target/linux/realtek/files/drivers/net/wireless/rtl8192e/8192cd_net80211.c
@@ -0,0 +1,1928 @@
+/*
+ * 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 <linux/module.h>
+#include <linux/init.h>
+#include <asm/uaccess.h>
+#include <linux/unistd.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/delay.h>
+#endif
+
+#include "./8192cd_cfg.h"
+
+#ifdef WIFI_HAPD
+
+#ifdef __LINUX_2_6__
+#include <linux/initrd.h>
+#include <linux/syscalls.h>
+#endif
+
+#include "./8192cd_debug.h"
+#include "./8192cd_net80211.h"
+#include "./8192cd_headers.h"
+
+#include <linux/if_arp.h>
+#include <linux/wireless.h>
+#include <net/iw_handler.h>
+#include <net80211/ieee80211.h>
+#include <net80211/ieee80211_crypto.h>
+#include <net80211/ieee80211_ioctl.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;
+}
+
+#ifdef WIFI_WPAS
+
+static 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<<IEEE80211_CIPHER_WEP))
+ return -EINVAL;
+ if(value & (1<<IEEE80211_CIPHER_AES_OCB))
+ return -EINVAL;
+ if(value & (1<<IEEE80211_CIPHER_CKIP))
+ return -EINVAL;
+ if(value & (1<<IEEE80211_CIPHER_NONE))
+ return -EINVAL;
+
+ if(value & (1<<IEEE80211_CIPHER_TKIP))
+ {
+ if((!(priv->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<<IEEE80211_CIPHER_AES_CCM))
+ {
+ priv->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
+ 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
+ struct ieee80211req_del_key *wk = (struct ieee80211req_del_key *)wrqu->name;
+ 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; ulIndex<priv->wpa_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; ulIndex<priv->wpa_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<<i)) {
+ pGblInfo->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<<i)) {
+ pGblInfo->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; i<pGblInfo->NumOfUnicastCipher; i++)
+ HAPD_MSG("%x ", pGblInfo->UnicastCipher[i]);
+ HAPD_MSG("\n");
+
+#ifdef RTL_WPA2
+ HAPD_MSG("RSN: WPA2 unicast cipher= ");
+ for (i=0; i<pGblInfo->NumOfUnicastCipherWPA2; 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