2025 lines
65 KiB
C
2025 lines
65 KiB
C
|
/*
|
||
|
* 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"
|
||
|
|
||
|
#if defined(WIFI_HAPD) || defined(RTK_NL80211)
|
||
|
|
||
|
#ifdef __LINUX_2_6__
|
||
|
#include <linux/initrd.h>
|
||
|
#include <linux/syscalls.h>
|
||
|
#endif
|
||
|
|
||
|
#include "./8192cd_debug.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"
|
||
|
|
||
|
#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_for_wpas(struct Dot11EncryptKey *pEncryptKey, UINT8 *src)
|
||
|
{
|
||
|
memcpy(pEncryptKey->dot11TTKey.skey, src, pEncryptKey->dot11TTKeyLen);
|
||
|
|
||
|
memcpy(pEncryptKey->dot11TMicKey2.skey, src + 16, pEncryptKey->dot11TMicKeyLen);
|
||
|
memcpy(pEncryptKey->dot11TMicKey1.skey, src + 24, pEncryptKey->dot11TMicKeyLen);
|
||
|
|
||
|
memcpy(src + 16, pEncryptKey->dot11TMicKey2.skey, pEncryptKey->dot11TMicKeyLen);
|
||
|
memcpy(src + 24, pEncryptKey->dot11TMicKey1.skey, pEncryptKey->dot11TMicKeyLen);
|
||
|
|
||
|
pEncryptKey->dot11TXPN48.val48 = 0;
|
||
|
}
|
||
|
|
||
|
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;
|
||
|
struct rtl8192cd_priv *priv = GET_DEV_PRIV(dev);
|
||
|
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) && defined(CLIENT_MODE))
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
#if defined(RTK_NL80211)
|
||
|
memcpy((void *)&(priv->pmib->dot11Bss) ,
|
||
|
(void *)&priv->site_survey->bss_target[bss_num] , sizeof(struct bss_desc));
|
||
|
#else
|
||
|
memcpy((void *)&(priv->pmib->dot11Bss) ,
|
||
|
(void *)&priv->site_survey->bss_backup[bss_num] , sizeof(struct bss_desc));
|
||
|
#endif
|
||
|
|
||
|
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';
|
||
|
|
||
|
NDEBUG3(" going to join bss: [%s] [channel=%d]\n", tmpbuf, priv->pmib->dot11Bss.channel);
|
||
|
|
||
|
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);
|
||
|
|
||
|
#ifdef RTK_NL80211
|
||
|
if(priv->pmib->dot11Bss.channel >=36)
|
||
|
{
|
||
|
if(GET_CHIP_VER(priv)==VERSION_8812E || GET_CHIP_VER(priv)==VERSION_8881A)
|
||
|
priv->pmib->dot11BssType.net_work_type = WIRELESS_11A|WIRELESS_11N|WIRELESS_11AC;
|
||
|
else
|
||
|
priv->pmib->dot11BssType.net_work_type = WIRELESS_11A|WIRELESS_11N;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
#ifdef P2P_SUPPORT
|
||
|
if(rtk_p2p_is_enabled(priv))
|
||
|
priv->pmib->dot11BssType.net_work_type = WIRELESS_11G|WIRELESS_11N; // p2p mode no included 11B
|
||
|
else
|
||
|
#endif
|
||
|
priv->pmib->dot11BssType.net_work_type = WIRELESS_11B|WIRELESS_11G|WIRELESS_11N;
|
||
|
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
priv->pmib->dot11nConfigEntry.dot11nAMPDU = 1;
|
||
|
priv->pmib->dot11nConfigEntry.dot11nShortGIfor20M = 1;
|
||
|
priv->pmib->dot11nConfigEntry.dot11nShortGIfor40M = 1;
|
||
|
|
||
|
#if defined(CONFIG_PCI_HCI)
|
||
|
start_clnt_join(priv);
|
||
|
#elif defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI)
|
||
|
// avoid IQK handling race condition between start_clnt_auth and TXPowerTracking
|
||
|
// so we indicate WPAS_JOIN event to cmd_thread to do start_clnt_join()
|
||
|
notify_wpas_join(priv);
|
||
|
#endif
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
|
||
|
|
||
|
void rtl_net80311_authmode(struct net_device *dev, int authtype, int encmode,
|
||
|
int pskenable, int dot11802_1x)
|
||
|
{
|
||
|
struct rtl8192cd_priv *priv = GET_DEV_PRIV(dev);
|
||
|
|
||
|
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)
|
||
|
{
|
||
|
struct rtl8192cd_priv *priv = GET_DEV_PRIV(dev);
|
||
|
|
||
|
int *i = (int *) extra;
|
||
|
int param = wrqu->mode; /* parameter id is 1st */
|
||
|
int value = 0; /* NB: most values are TYPE_INT */
|
||
|
int ret = 0;
|
||
|
|
||
|
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;
|
||
|
|
||
|
memcpy(&value, wrqu->name+sizeof(value), sizeof(value));
|
||
|
|
||
|
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(1)//((!(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)
|
||
|
{
|
||
|
struct rtl8192cd_priv *priv = GET_DEV_PRIV(dev);
|
||
|
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)
|
||
|
{
|
||
|
struct rtl8192cd_priv *priv = GET_DEV_PRIV(dev);
|
||
|
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)
|
||
|
{
|
||
|
struct rtl8192cd_priv *priv = GET_DEV_PRIV(dev);
|
||
|
struct ieee80211req_mlme *mlme = (struct ieee80211req_mlme *)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;
|
||
|
}
|
||
|
pstat->state |= (WIFI_AUTH_SUCCESS | WIFI_ASOC_STATE);
|
||
|
pstat->expire_to = priv->assoc_to;
|
||
|
asoc_list_add(priv, pstat);
|
||
|
}
|
||
|
|
||
|
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 (asoc_list_del(priv, pstat))
|
||
|
{
|
||
|
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;
|
||
|
auth_list_add(priv, pstat);
|
||
|
}
|
||
|
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 (asoc_list_del(priv, pstat))
|
||
|
{
|
||
|
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)
|
||
|
{
|
||
|
struct rtl8192cd_priv *priv = GET_DEV_PRIV(dev);
|
||
|
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;
|
||
|
DOT11_KEY_TYPE keyType = DOT11_KeyType_Pairwise;
|
||
|
|
||
|
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 (group_key)
|
||
|
keyType = DOT11_KeyType_Group;
|
||
|
|
||
|
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);
|
||
|
}
|
||
|
#ifdef CONFIG_IEEE80211W
|
||
|
else if (wk->ik_type == IEEE80211_CIPHER_AES_CMAC)
|
||
|
{
|
||
|
cipher = DOT11_ENC_BIP;
|
||
|
keyType = DOT11_KeyType_IGTK;
|
||
|
}
|
||
|
#endif
|
||
|
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 (keyType == DOT11_KeyType_Group)
|
||
|
{
|
||
|
int set_gkey_to_cam = 0;
|
||
|
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);
|
||
|
#ifdef RTK_NL80211
|
||
|
if(OPMODE & WIFI_STATION_STATE)
|
||
|
set_tkip_key_for_wpas(pEncryptKey, wk->ik_keydata);
|
||
|
else
|
||
|
#endif
|
||
|
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 if (keyType == DOT11_KeyType_Pairwise)
|
||
|
{
|
||
|
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
|
||
|
|
||
|
#ifdef RTK_NL80211 //eric-ath
|
||
|
//printk(" +++ pstat->state=0x%x wps_join=%d \n", pstat->state, (pstat->state & WIFI_WPS_JOIN));
|
||
|
|
||
|
if(OPMODE & WIFI_STATION_STATE)
|
||
|
{
|
||
|
if(pstat->state & WIFI_WPS_JOIN)
|
||
|
{
|
||
|
//printk("REMOVE WIFI_WPS_JOIN State !!\n");
|
||
|
pstat->state &= (~(WIFI_WPS_JOIN));
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
switch(cipher)
|
||
|
{
|
||
|
case DOT11_ENC_TKIP:
|
||
|
set_ttkeylen(pEncryptKey, 16);
|
||
|
set_tmickeylen(pEncryptKey, 8);
|
||
|
|
||
|
#ifdef RTK_NL80211
|
||
|
if(OPMODE & WIFI_STATION_STATE)
|
||
|
set_tkip_key_for_wpas(pEncryptKey, wk->ik_keydata);
|
||
|
else
|
||
|
#endif
|
||
|
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;
|
||
|
}
|
||
|
}
|
||
|
#ifdef CONFIG_IEEE80211W
|
||
|
else if (keyType == DOT11_KeyType_IGTK)
|
||
|
{
|
||
|
HAPD_MSG("going to set BIP group key!\n");
|
||
|
pmib->dot11IGTKTable.dot11Privacy = cipher;
|
||
|
pEncryptKey = &pmib->dot11IGTKTable.dot11EncryptKey;
|
||
|
pmib->dot11IGTKTable.keyid = wk->ik_keyix;
|
||
|
|
||
|
set_ttkeylen(pEncryptKey, 16);
|
||
|
set_tmickeylen(pEncryptKey, 16);
|
||
|
set_aes_key(pEncryptKey, wk->ik_keydata);
|
||
|
}
|
||
|
#endif
|
||
|
else
|
||
|
{
|
||
|
HAPD_MSG("keyType(%d) not support\n", keyType);
|
||
|
}
|
||
|
|
||
|
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)
|
||
|
{
|
||
|
struct rtl8192cd_priv *priv = GET_DEV_PRIV(dev);
|
||
|
|
||
|
#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)
|
||
|
{
|
||
|
struct rtl8192cd_priv *priv = GET_DEV_PRIV(dev);
|
||
|
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(RTK_NL80211)) && 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)
|
||
|
{
|
||
|
struct rtl8192cd_priv *priv = GET_DEV_PRIV(dev);
|
||
|
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)
|
||
|
{
|
||
|
struct rtl8192cd_priv *priv = GET_DEV_PRIV(dev);
|
||
|
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)
|
||
|
{
|
||
|
struct rtl8192cd_priv *priv = GET_DEV_PRIV(dev);
|
||
|
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;
|
||
|
|
||
|
}
|
||
|
#if defined(CUSTOMIZE_WLAN_IF_NAME)
|
||
|
else if(!strcmp(priv->dev->name, ROOT_IFNAME_5G))
|
||
|
#else
|
||
|
else if(!strcmp(priv->dev->name, "wlan0"))
|
||
|
#endif
|
||
|
{
|
||
|
priv->pmib->dot11RFEntry.macPhyMode = DUALMAC_DUALPHY;
|
||
|
rtl_wpas_config_5G(priv);
|
||
|
}
|
||
|
#if defined(CUSTOMIZE_WLAN_IF_NAME)
|
||
|
else if(!strcmp(priv->dev->name, ROOT_IFNAME_2G))
|
||
|
#else
|
||
|
else if(!strcmp(priv->dev->name, "wlan1"))
|
||
|
#endif
|
||
|
{
|
||
|
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)
|
||
|
{
|
||
|
struct rtl8192cd_priv *priv = GET_DEV_PRIV(dev);
|
||
|
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;
|
||
|
|
||
|
#ifdef RTK_NL80211
|
||
|
for (ulIndex=0; ulIndex<priv->wpa_global_info->NumOfUnicastCipher; ulIndex++)
|
||
|
{
|
||
|
int i = ulIndex<priv->wpa_global_info->NumOfUnicastCipher - ulIndex - 1;
|
||
|
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[i];
|
||
|
usSuitCount++;
|
||
|
}
|
||
|
#else
|
||
|
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++;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
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;
|
||
|
|
||
|
#ifdef RTK_NL80211
|
||
|
for (ulIndex=0; ulIndex<priv->wpa_global_info->NumOfUnicastCipherWPA2; ulIndex++)
|
||
|
{
|
||
|
int i = priv->wpa_global_info->NumOfUnicastCipherWPA2 - ulIndex - 1;
|
||
|
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[i];
|
||
|
usSuitCount++;
|
||
|
}
|
||
|
#else
|
||
|
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++;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
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;
|
||
|
|
||
|
#if (defined(WIFI_HAPD) & defined(WIFI_WMM)) || (defined(RTK_NL80211) & defined(WIFI_WMM)) //eric-eap
|
||
|
if(QOS_ENABLE){
|
||
|
/* 4 PTKSA replay counters when using WMM consistent with hostapd code*/
|
||
|
dot11RSNCapability.field.PtksaReplayCounter = 3;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
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
|