2269 lines
69 KiB
C
2269 lines
69 KiB
C
|
/*
|
||
|
* Handle routines to communicate with AUTH daemon (802.1x authenticator)
|
||
|
*
|
||
|
* $Id: 8192cd_security.c,v 1.10.2.9 2011/01/10 08:19:42 jimmylin Exp $
|
||
|
*
|
||
|
* 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.
|
||
|
*/
|
||
|
|
||
|
#define _8192CD_SECURITY_C_
|
||
|
#ifdef __KERNEL__
|
||
|
#include <asm/uaccess.h>
|
||
|
#include <linux/module.h>
|
||
|
#elif defined(__ECOS)
|
||
|
#include <cyg/io/eth/rltk/819x/wrapper/sys_support.h>
|
||
|
#include <cyg/io/eth/rltk/819x/wrapper/skbuff.h>
|
||
|
#include <cyg/io/eth/rltk/819x/wrapper/timer.h>
|
||
|
#include <cyg/io/eth/rltk/819x/wrapper/wrapper.h>
|
||
|
#endif
|
||
|
|
||
|
#include "./8192cd_cfg.h"
|
||
|
|
||
|
#if !defined(__KERNEL__) && !defined(__ECOS)
|
||
|
#include "./sys-support.h"
|
||
|
#endif
|
||
|
|
||
|
#include "./8192cd.h"
|
||
|
#include "./8192cd_security.h"
|
||
|
#include "./8192cd_headers.h"
|
||
|
#include "./8192cd_debug.h"
|
||
|
|
||
|
#if defined(CONFIG_RTL_WAPI_SUPPORT)
|
||
|
#include "wapi_wai.h"
|
||
|
#endif
|
||
|
|
||
|
#ifdef INCLUDE_WPS
|
||
|
#include "./wps/wsc.h"
|
||
|
#endif
|
||
|
|
||
|
#ifdef RTK_NL80211
|
||
|
#include "8192cd_cfg80211.h"
|
||
|
#endif
|
||
|
|
||
|
|
||
|
#define E_MSG_DOT11_2LARGE "ItemSize Too Large"
|
||
|
#define E_MSG_DOT11_QFULL "Event Queue Full"
|
||
|
#define E_MSG_DOT11_QEMPTY "Event Queue Empty"
|
||
|
|
||
|
|
||
|
void DOT11_InitQueue(DOT11_QUEUE * q)
|
||
|
{
|
||
|
q->Head = 0;
|
||
|
q->Tail = 0;
|
||
|
q->NumItem = 0;
|
||
|
q->MaxItem = MAXQUEUESIZE;
|
||
|
}
|
||
|
|
||
|
#ifndef WITHOUT_ENQUEUE
|
||
|
/*--------------------------------------------------------------------------------
|
||
|
Return Value
|
||
|
Success : return 0;
|
||
|
Fail : return E_DOT11_QFULL if queue is full
|
||
|
return E_DOT1ZX_2LARGE if the item size is large than allocated
|
||
|
--------------------------------------------------------------------------------*/
|
||
|
int DOT11_EnQueue(unsigned long task_priv, DOT11_QUEUE *q, unsigned char *item, int itemsize)
|
||
|
{
|
||
|
#ifdef __KERNEL__
|
||
|
struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)task_priv;
|
||
|
#endif
|
||
|
#ifndef SMP_SYNC
|
||
|
unsigned long flags;
|
||
|
#endif
|
||
|
|
||
|
if (itemsize > MAXDATALEN)
|
||
|
return E_DOT11_2LARGE;
|
||
|
|
||
|
SAVE_INT_AND_CLI(flags);
|
||
|
|
||
|
if (DOT11_IsFullQueue(q)) {
|
||
|
RESTORE_INT(flags);
|
||
|
return E_DOT11_QFULL;
|
||
|
}
|
||
|
|
||
|
q->ItemArray[q->Tail].ItemSize = itemsize;
|
||
|
memset(q->ItemArray[q->Tail].Item, 0, sizeof(q->ItemArray[q->Tail].Item));
|
||
|
memcpy(q->ItemArray[q->Tail].Item, item, itemsize);
|
||
|
q->NumItem++;
|
||
|
if((q->Tail+1) == MAXQUEUESIZE)
|
||
|
q->Tail = 0;
|
||
|
else
|
||
|
q->Tail++;
|
||
|
|
||
|
RESTORE_INT(flags);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
int DOT11_DeQueue(unsigned long task_priv, DOT11_QUEUE *q, unsigned char *item, int *itemsize)
|
||
|
{
|
||
|
#ifdef __KERNEL__
|
||
|
struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)task_priv;
|
||
|
#endif
|
||
|
#ifndef SMP_SYNC
|
||
|
unsigned long flags;
|
||
|
#endif
|
||
|
|
||
|
SAVE_INT_AND_CLI(flags);
|
||
|
|
||
|
if (DOT11_IsEmptyQueue(q)) {
|
||
|
RESTORE_INT(flags);
|
||
|
return E_DOT11_QEMPTY;
|
||
|
}
|
||
|
|
||
|
memcpy(item, q->ItemArray[q->Head].Item, q->ItemArray[q->Head].ItemSize);
|
||
|
*itemsize = q->ItemArray[q->Head].ItemSize;
|
||
|
q->NumItem--;
|
||
|
if((q->Head+1) == MAXQUEUESIZE)
|
||
|
q->Head = 0;
|
||
|
else
|
||
|
q->Head++;
|
||
|
|
||
|
RESTORE_INT(flags);
|
||
|
return 0;
|
||
|
}
|
||
|
#endif // !WITHOUT_ENQUEUE
|
||
|
|
||
|
|
||
|
#if 0
|
||
|
void DOT11_PrintQueue(DOT11_QUEUE *q)
|
||
|
{
|
||
|
int i, j, index;
|
||
|
|
||
|
printk("\n/-------------------------------------------------\n[DOT11_PrintQueue]: MaxItem = %d, NumItem = %d, Head = %d, Tail = %d\n", q->MaxItem, q->NumItem, q->Head, q->Tail);
|
||
|
for(i=0; i<q->NumItem; i++) {
|
||
|
index = (i + q->Head) % q->MaxItem;
|
||
|
printk("Queue[%d].ItemSize = %d ", index, q->ItemArray[index].ItemSize);
|
||
|
for(j=0; j<q->ItemArray[index].ItemSize; j++)
|
||
|
printk(" %x", q->ItemArray[index].Item[j]);
|
||
|
printk("\n");
|
||
|
}
|
||
|
printk("------------------------------------------------/\n");
|
||
|
}
|
||
|
|
||
|
|
||
|
char *DOT11_ErrMsgQueue(int err)
|
||
|
{
|
||
|
switch(err)
|
||
|
{
|
||
|
case E_DOT11_2LARGE:
|
||
|
return E_MSG_DOT11_2LARGE;
|
||
|
case E_DOT11_QFULL:
|
||
|
return E_MSG_DOT11_QFULL;
|
||
|
case E_DOT11_QEMPTY:
|
||
|
return E_MSG_DOT11_QEMPTY;
|
||
|
default:
|
||
|
return "E_MSG_DOT11_QNOERR";
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void DOT11_Dump(char *fun, UINT8 *buf, int size, char *comment)
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
printk("$$ %s $$: %s", fun, comment);
|
||
|
if (buf != NULL) {
|
||
|
printk("\nMessage is %d bytes %x hex", size, size);
|
||
|
for (i = 0; i < size; i++) {
|
||
|
if (i % 16 == 0) printk("\n\t");
|
||
|
printk("%2x ", *(buf+i));
|
||
|
}
|
||
|
}
|
||
|
printk("\n");
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
|
||
|
/*------------------------------------------------------------
|
||
|
Set RSNIE is to set Information Element of AP
|
||
|
Return Value
|
||
|
Success : 0
|
||
|
------------------------------------------------------------*/
|
||
|
static int DOT11_Process_Set_RSNIE(struct net_device *dev, struct iw_point *data)
|
||
|
{
|
||
|
struct Dot11RsnIE *pdot11RsnIE;
|
||
|
struct wifi_mib *pmib;
|
||
|
struct rtl8192cd_priv *priv = GET_DEV_PRIV(dev);
|
||
|
|
||
|
|
||
|
#ifdef HS2_SUPPORT
|
||
|
unsigned char rsnie_hdr_OSEN[4]={0x50, 0x6F, 0x9A, 0x12};
|
||
|
#endif
|
||
|
DOT11_SET_RSNIE *Set_RSNIE = (DOT11_SET_RSNIE *)data->pointer;
|
||
|
|
||
|
DEBUG_INFO("going to set rsnie\n");
|
||
|
pmib = priv->pmib;
|
||
|
pdot11RsnIE = &pmib->dot11RsnIE;
|
||
|
if(Set_RSNIE->Flag == DOT11_Ioctl_Set)
|
||
|
{
|
||
|
pdot11RsnIE->rsnielen = Set_RSNIE->RSNIELen;
|
||
|
memcpy((void *)pdot11RsnIE->rsnie, Set_RSNIE->RSNIE, pdot11RsnIE->rsnielen);
|
||
|
priv->pmib->dot118021xAuthEntry.dot118021xAlgrthm = 1;
|
||
|
DEBUG_INFO("DOT11_Process_Set_RSNIE rsnielen=%d\n", pdot11RsnIE->rsnielen);
|
||
|
|
||
|
// see whether if driver is open. If not, do not enable tx/rx, david
|
||
|
if (!netif_running(priv->dev)) {
|
||
|
#ifdef __OSK__
|
||
|
if (IS_VXD_INTERFACE(priv) && pdot11RsnIE->rsnielen > 0)
|
||
|
priv->pmib->dot11OperationEntry.keep_rsnie = 1;
|
||
|
#endif
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
// Alway enable tx/rx in rtl8190_init_hw_PCI()
|
||
|
//RTL_W8(_CR_, BIT(2) | BIT(3));
|
||
|
#if defined(INCLUDE_WPA_PSK) || defined(WIFI_HAPD) || defined(RTK_NL80211)
|
||
|
if (!priv->pmib->dot1180211AuthEntry.dot11EnablePSK)
|
||
|
#endif
|
||
|
{
|
||
|
if (OPMODE & WIFI_AP_STATE) {
|
||
|
#ifdef MBSSID
|
||
|
if (IS_ROOT_INTERFACE(priv))
|
||
|
#endif
|
||
|
{
|
||
|
if (priv->auto_channel) {
|
||
|
priv->ss_ssidlen = 0;
|
||
|
DEBUG_INFO("start_clnt_ss, trigger by %s, ss_ssidlen=0\n", (char *)__FUNCTION__);
|
||
|
start_clnt_ss(priv);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
//for openwrt 8021x donot trigger site survey when rsnie init in init sw
|
||
|
#if defined(CLIENT_MODE) && !defined(RTK_NL80211) && !defined(WIFI_WPAS_CLI)
|
||
|
if (OPMODE & (WIFI_STATION_STATE | WIFI_ADHOC_STATE))
|
||
|
start_clnt_lookup(priv, RESCAN);
|
||
|
#endif
|
||
|
}
|
||
|
}
|
||
|
else if(Set_RSNIE->Flag == DOT11_Ioctl_Query)
|
||
|
{
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
#if 0
|
||
|
char *DOT11_Parse_RSNIE_Err(int err)
|
||
|
{
|
||
|
switch(err)
|
||
|
{
|
||
|
case ERROR_BUFFER_TOO_SMALL:
|
||
|
return RSN_STRERROR_BUFFER_TOO_SMALL;
|
||
|
case ERROR_INVALID_PARA:
|
||
|
return RSN_STRERROR_INVALID_PARAMETER;
|
||
|
case ERROR_INVALID_RSNIE:
|
||
|
return RSN_STRERROR_INVALID_RSNIE;
|
||
|
case ERROR_INVALID_MULTICASTCIPHER:
|
||
|
return RSN_STRERROR_INVALID_MULTICASTCIPHER;
|
||
|
case ERROR_INVALID_UNICASTCIPHER:
|
||
|
return RSN_STRERROR_INVALID_UNICASTCIPHER;
|
||
|
case ERROR_INVALID_AUTHKEYMANAGE:
|
||
|
return RSN_STRERROR_INVALID_AUTHKEYMANAGE;
|
||
|
case ERROR_UNSUPPORTED_RSNEVERSION:
|
||
|
return RSN_STRERROR_UNSUPPORTED_RSNEVERSION;
|
||
|
case ERROR_INVALID_CAPABILITIES:
|
||
|
return RSN_STRERROR_INVALID_CAPABILITIES;
|
||
|
default:
|
||
|
return "Uknown Failure";
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
|
||
|
/*-------------------------------------------------
|
||
|
Send association response to STA
|
||
|
Return Value
|
||
|
Success : 0
|
||
|
---------------------------------------------------*/
|
||
|
static int DOT11_Process_Association_Rsp(struct net_device *dev, struct iw_point *data, int frame_type)
|
||
|
{
|
||
|
#ifndef SMP_SYNC
|
||
|
unsigned long flags;
|
||
|
#endif
|
||
|
struct stat_info *pstat;
|
||
|
unsigned char *hwaddr;
|
||
|
struct rtl8192cd_priv *priv = GET_DEV_PRIV(dev);
|
||
|
DOT11_ASSOCIATIIN_RSP *Assoc_Rsp = (DOT11_ASSOCIATIIN_RSP *)data->pointer;
|
||
|
|
||
|
pstat = get_stainfo(priv, (UINT8 *)Assoc_Rsp->MACAddr);
|
||
|
|
||
|
if (pstat == NULL)
|
||
|
return (-1);
|
||
|
|
||
|
hwaddr = (unsigned char *)Assoc_Rsp->MACAddr;
|
||
|
DEBUG_INFO("802.1x issue assoc_rsp sta:%02X%02X%02X%02X%02X%02X status:%d\n",
|
||
|
hwaddr[0],hwaddr[1],hwaddr[2],hwaddr[3],hwaddr[4],hwaddr[5], Assoc_Rsp->Status);
|
||
|
|
||
|
issue_asocrsp(priv, Assoc_Rsp->Status, pstat, frame_type);
|
||
|
|
||
|
if (Assoc_Rsp->Status != 0)
|
||
|
{
|
||
|
SAVE_INT_AND_CLI(flags);
|
||
|
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);
|
||
|
LOG_MSG("A STA is rejected by 802.1x daemon - %02X:%02X:%02X:%02X:%02X:%02X\n",
|
||
|
pstat->hwaddr[0],pstat->hwaddr[1],pstat->hwaddr[2],pstat->hwaddr[3],pstat->hwaddr[4],pstat->hwaddr[5]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
free_stainfo(priv, pstat);
|
||
|
RESTORE_INT(flags);
|
||
|
}
|
||
|
else
|
||
|
update_fwtbl_asoclst(priv, pstat);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*-------------------------------------------------
|
||
|
Send Disassociation request to STA
|
||
|
Return Value
|
||
|
Success : 0
|
||
|
---------------------------------------------------*/
|
||
|
#ifdef CONFIG_PCI_HCI
|
||
|
static inline
|
||
|
#endif
|
||
|
int __DOT11_Process_Disconnect_Req(struct net_device *dev, struct iw_point *data)
|
||
|
{
|
||
|
#ifndef SMP_SYNC
|
||
|
unsigned long flags;
|
||
|
#endif
|
||
|
struct stat_info *pstat;
|
||
|
unsigned char *hwaddr;
|
||
|
struct rtl8192cd_priv *priv = GET_DEV_PRIV(dev);
|
||
|
DOT11_DISCONNECT_REQ *Disconnect_Req = (DOT11_DISCONNECT_REQ *)data->pointer;
|
||
|
|
||
|
pstat = get_stainfo(priv, (UINT8 *)Disconnect_Req->MACAddr);
|
||
|
|
||
|
if (pstat == NULL)
|
||
|
return (-1);
|
||
|
|
||
|
hwaddr = (unsigned char *)Disconnect_Req->MACAddr;
|
||
|
|
||
|
#ifdef WIFI_SIMPLE_CONFIG
|
||
|
if (wsc_disconn_list_check(priv, hwaddr)) {
|
||
|
DEBUG_INFO("Ignore issue disassoc sta:%02X%02X%02X%02X%02X%02X due to STA had reconnected\n",
|
||
|
hwaddr[0],hwaddr[1],hwaddr[2],hwaddr[3],hwaddr[4],hwaddr[5]);
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
DEBUG_INFO("802.1x issue disassoc sta:%02X%02X%02X%02X%02X%02X reason:%d\n",
|
||
|
hwaddr[0],hwaddr[1],hwaddr[2],hwaddr[3],hwaddr[4],hwaddr[5], Disconnect_Req->Reason);
|
||
|
|
||
|
#ifdef CLIENT_MODE
|
||
|
if(OPMODE & WIFI_STATION_STATE){
|
||
|
|
||
|
if((OPMODE&( WIFI_AUTH_SUCCESS | WIFI_ASOC_STATE))
|
||
|
==( WIFI_AUTH_SUCCESS | WIFI_ASOC_STATE))
|
||
|
{
|
||
|
issue_deauth(priv, BSSID, _RSON_DEAUTH_STA_LEAVING_);
|
||
|
OPMODE_VAL(OPMODE & ~(WIFI_AUTH_SUCCESS | WIFI_ASOC_STATE));
|
||
|
#ifndef WIFI_WPAS_CLI
|
||
|
#ifdef SMART_REPEATER_MODE
|
||
|
if(GET_MIB(priv)->ap_profile.enable_profile && GET_MIB(priv)->ap_profile.profile_num > 0)
|
||
|
{
|
||
|
if((priv->site_survey->count_target > 0) && ((priv->join_index+1) > priv->site_survey->count_target)){
|
||
|
start_clnt_lookup(priv, RESCAN);
|
||
|
}else{
|
||
|
start_clnt_lookup(priv, DONTRESCAN);
|
||
|
}
|
||
|
} else
|
||
|
#endif
|
||
|
{
|
||
|
start_clnt_lookup(priv, RESCAN);
|
||
|
}
|
||
|
#endif // !WIFI_WPAS_CLI
|
||
|
//SME_DEBUG("!!issue disconnect at wlan!!\n");
|
||
|
}else{
|
||
|
return (-1);
|
||
|
}
|
||
|
|
||
|
}else
|
||
|
#endif
|
||
|
{
|
||
|
issue_deauth(priv, pstat->hwaddr, Disconnect_Req->Reason);
|
||
|
}
|
||
|
|
||
|
SAVE_INT_AND_CLI(flags);
|
||
|
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);
|
||
|
LOG_MSG("A STA is rejected by 802.1x daemon - %02X:%02X:%02X:%02X:%02X:%02X\n",
|
||
|
pstat->hwaddr[0],pstat->hwaddr[1],pstat->hwaddr[2],pstat->hwaddr[3],pstat->hwaddr[4],pstat->hwaddr[5]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
free_stainfo(priv, pstat);
|
||
|
RESTORE_INT(flags);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int DOT11_Process_Disconnect_Req(struct net_device *dev, struct iw_point *data)
|
||
|
{
|
||
|
#if defined(CONFIG_PCI_HCI)
|
||
|
return __DOT11_Process_Disconnect_Req(dev, data);
|
||
|
#elif defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI)
|
||
|
notify_disconnect_sta(dev, (DOT11_DISCONNECT_REQ *)data->pointer);
|
||
|
return 0;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
/*---------------------------------------------------------------------
|
||
|
Delete Group Key for AP and Pairwise Key for specific STA
|
||
|
Return Value
|
||
|
Success : 0
|
||
|
-----------------------------------------------------------------------*/
|
||
|
int DOT11_Process_Delete_Key(struct net_device *dev, struct iw_point *data)
|
||
|
{
|
||
|
struct stat_info *pstat = NULL;
|
||
|
struct rtl8192cd_priv *priv = GET_DEV_PRIV(dev);
|
||
|
DOT11_DELETE_KEY *Delete_Key = (DOT11_DELETE_KEY *)data->pointer;
|
||
|
struct wifi_mib *pmib = priv->pmib;
|
||
|
|
||
|
unsigned char MULTICAST_ADD[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
|
||
|
|
||
|
if (Delete_Key->KeyType == DOT11_KeyType_Group)
|
||
|
{
|
||
|
pmib->dot11GroupKeysTable.dot11EncryptKey.dot11TTKeyLen = 0;
|
||
|
pmib->dot11GroupKeysTable.dot11EncryptKey.dot11TMicKeyLen = 0;
|
||
|
|
||
|
DEBUG_INFO("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 if (Delete_Key->KeyType == DOT11_KeyType_Pairwise)
|
||
|
{
|
||
|
pstat = get_stainfo(priv, (UINT8 *)Delete_Key->MACAddr);
|
||
|
if (pstat == NULL)
|
||
|
return (-1);
|
||
|
|
||
|
pstat->dot11KeyMapping.dot11EncryptKey.dot11TTKeyLen = 0;
|
||
|
pstat->dot11KeyMapping.dot11EncryptKey.dot11TMicKeyLen = 0;
|
||
|
|
||
|
DEBUG_INFO("Delete Unicast Key\n");
|
||
|
if (pstat->dot11KeyMapping.keyInCam == TRUE) {
|
||
|
if (CamDeleteOneEntry(priv, (unsigned char *)Delete_Key->MACAddr, 0, 0)) {
|
||
|
priv->pshare->CamEntryOccupied--;
|
||
|
if (pstat) pstat->dot11KeyMapping.keyInCam = FALSE;
|
||
|
}
|
||
|
#if defined(CONFIG_RTL_HW_WAPI_SUPPORT)
|
||
|
if (CamDeleteOneEntry(priv, (unsigned char *)Delete_Key->MACAddr, 0, 0)) {
|
||
|
priv->pshare->CamEntryOccupied--;
|
||
|
if (pstat) pstat->dot11KeyMapping.keyInCam = FALSE;
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
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);
|
||
|
}
|
||
|
|
||
|
|
||
|
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 __inline__ void clean_pn(unsigned char *pn)
|
||
|
{
|
||
|
memset(pn, 0, 6);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*---------------------------------------------------------------------
|
||
|
Set Group Key for AP and Pairwise Key for specific STA
|
||
|
Return Value
|
||
|
Success : 0
|
||
|
-----------------------------------------------------------------------*/
|
||
|
int DOT11_Process_Set_Key(struct net_device *dev, struct iw_point *data,
|
||
|
DOT11_SET_KEY *pSetKey, unsigned char *pKey)
|
||
|
{
|
||
|
struct rtl8192cd_priv *priv = GET_DEV_PRIV(dev);
|
||
|
struct wifi_mib *pmib = priv->pmib;
|
||
|
struct Dot11EncryptKey *pEncryptKey = NULL;
|
||
|
struct stat_info *pstat = NULL;
|
||
|
DOT11_SET_KEY Set_Key;
|
||
|
unsigned char key_combo[32];
|
||
|
unsigned char MULTICAST_ADD[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
|
||
|
int retVal;
|
||
|
|
||
|
if (data) {
|
||
|
#if defined(INCLUDE_WPA_PSK) || defined(WIFI_HAPD) || defined(RTK_NL80211)
|
||
|
memcpy((void *)&Set_Key, (void *)data->pointer, sizeof(DOT11_SET_KEY));
|
||
|
memcpy((void *)key_combo,
|
||
|
((DOT11_SET_KEY *)data->pointer)->KeyMaterial, 32);
|
||
|
#else
|
||
|
if (copy_from_user((void *)&Set_Key, (void *)data->pointer, sizeof(DOT11_SET_KEY))) {
|
||
|
DEBUG_ERR("copy_from_user error!\n");
|
||
|
return -1;
|
||
|
}
|
||
|
if (copy_from_user((void *)key_combo,
|
||
|
((DOT11_SET_KEY *)data->pointer)->KeyMaterial, 32)) {
|
||
|
DEBUG_ERR("copy_from_user error!\n");
|
||
|
return -1;
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
else {
|
||
|
Set_Key = *pSetKey;
|
||
|
memcpy(key_combo, pKey, 32);
|
||
|
}
|
||
|
|
||
|
#ifdef WDS
|
||
|
#ifdef LAZY_WDS
|
||
|
if ((priv->pmib->dot11WdsInfo.wdsEnabled == WDS_LAZY_ENABLE ||
|
||
|
(priv->pmib->dot11WdsInfo.wdsEnabled && priv->pmib->dot11WdsInfo.wdsNum)) &&
|
||
|
#else
|
||
|
if (priv->pmib->dot11WdsInfo.wdsEnabled && priv->pmib->dot11WdsInfo.wdsNum &&
|
||
|
#endif
|
||
|
((priv->pmib->dot11WdsInfo.wdsPrivacy == _TKIP_PRIVACY_) ||
|
||
|
(priv->pmib->dot11WdsInfo.wdsPrivacy == _CCMP_PRIVACY_)) &&
|
||
|
(Set_Key.KeyType == DOT11_KeyType_Group) &&
|
||
|
!memcmp(Set_Key.MACAddr, NULL_MAC_ADDR, 6)) {
|
||
|
int i;
|
||
|
|
||
|
for (i=0; i<32; i++)
|
||
|
sprintf((char *)&priv->pmib->dot11WdsInfo.wdsPskPassPhrase[i*2], "%02x", key_combo[i]);
|
||
|
priv->pmib->dot11WdsInfo.wdsPskPassPhrase[i*2] = '\0';
|
||
|
|
||
|
for (i=0; i<NUM_WDS; i++) {
|
||
|
#ifdef LAZY_WDS
|
||
|
if (priv->pmib->dot11WdsInfo.wdsEnabled == WDS_LAZY_ENABLE) {
|
||
|
if (!memcmp(priv->pmib->dot11WdsInfo.entry[i].macAddr,
|
||
|
NULL_MAC_ADDR, 6))
|
||
|
continue;
|
||
|
}
|
||
|
else
|
||
|
#endif
|
||
|
{
|
||
|
if (i+1 > pmib->dot11WdsInfo.wdsNum)
|
||
|
break;
|
||
|
}
|
||
|
memcpy(Set_Key.MACAddr, priv->pmib->dot11WdsInfo.entry[i].macAddr, 6);
|
||
|
Set_Key.KeyType = DOT11_KeyType_Pairwise;
|
||
|
Set_Key.EncType = priv->pmib->dot11WdsInfo.wdsPrivacy;
|
||
|
Set_Key.KeyIndex = 0;
|
||
|
DOT11_Process_Set_Key(priv->dev, NULL, &Set_Key, key_combo);
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
if(Set_Key.KeyType == DOT11_KeyType_Group)
|
||
|
{
|
||
|
int set_gkey_to_cam = 0;
|
||
|
#ifdef CONFIG_RTL_88E_SUPPORT
|
||
|
if (GET_CHIP_VER(priv) == VERSION_8188E)
|
||
|
set_gkey_to_cam = 1;
|
||
|
#endif
|
||
|
|
||
|
#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
|
||
|
|
||
|
pmib->dot11GroupKeysTable.dot11Privacy = Set_Key.EncType;
|
||
|
pEncryptKey = &pmib->dot11GroupKeysTable.dot11EncryptKey;
|
||
|
pmib->dot11GroupKeysTable.keyid = (UINT)Set_Key.KeyIndex;
|
||
|
|
||
|
|
||
|
switch(Set_Key.EncType)
|
||
|
{
|
||
|
case DOT11_ENC_TKIP:
|
||
|
set_ttkeylen(pEncryptKey, 16);
|
||
|
set_tmickeylen(pEncryptKey, 8);
|
||
|
set_tkip_key(pEncryptKey, key_combo);
|
||
|
|
||
|
DEBUG_INFO("going to set TKIP group key! id %X\n", (UINT)Set_Key.KeyIndex);
|
||
|
if (!SWCRYPTO) {
|
||
|
if (set_gkey_to_cam)
|
||
|
{
|
||
|
retVal = CamDeleteOneEntry(priv, MULTICAST_ADD, Set_Key.KeyIndex, 0);
|
||
|
if (retVal) {
|
||
|
priv->pshare->CamEntryOccupied--;
|
||
|
pmib->dot11GroupKeysTable.keyInCam = FALSE;
|
||
|
}
|
||
|
retVal = CamAddOneEntry(priv, MULTICAST_ADD, Set_Key.KeyIndex, DOT11_ENC_TKIP<<2, 0, key_combo);
|
||
|
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, key_combo);
|
||
|
|
||
|
DEBUG_INFO("going to set WEP40 group key!\n");
|
||
|
if (!SWCRYPTO) {
|
||
|
if (set_gkey_to_cam)
|
||
|
{
|
||
|
retVal = CamDeleteOneEntry(priv, MULTICAST_ADD, Set_Key.KeyIndex, 0);
|
||
|
if (retVal) {
|
||
|
priv->pshare->CamEntryOccupied--;
|
||
|
pmib->dot11GroupKeysTable.keyInCam = FALSE;
|
||
|
}
|
||
|
retVal = CamAddOneEntry(priv, MULTICAST_ADD, Set_Key.KeyIndex, DOT11_ENC_WEP40<<2, 0, key_combo);
|
||
|
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, key_combo);
|
||
|
|
||
|
DEBUG_INFO("going to set WEP104 group key!\n");
|
||
|
if (!SWCRYPTO) {
|
||
|
if (set_gkey_to_cam)
|
||
|
{
|
||
|
retVal = CamDeleteOneEntry(priv, MULTICAST_ADD, Set_Key.KeyIndex, 0);
|
||
|
if (retVal) {
|
||
|
priv->pshare->CamEntryOccupied--;
|
||
|
pmib->dot11GroupKeysTable.keyInCam = FALSE;
|
||
|
}
|
||
|
retVal = CamAddOneEntry(priv, MULTICAST_ADD, Set_Key.KeyIndex, DOT11_ENC_WEP104<<2, 0, key_combo);
|
||
|
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, key_combo);
|
||
|
|
||
|
DEBUG_INFO("going to set CCMP-AES group key!\n");
|
||
|
|
||
|
if (!SWCRYPTO) {
|
||
|
if (set_gkey_to_cam)
|
||
|
{
|
||
|
retVal = CamDeleteOneEntry(priv, MULTICAST_ADD, Set_Key.KeyIndex, 0);
|
||
|
if (retVal) {
|
||
|
priv->pshare->CamEntryOccupied--;
|
||
|
pmib->dot11GroupKeysTable.keyInCam = FALSE;
|
||
|
}
|
||
|
retVal = CamAddOneEntry(priv, MULTICAST_ADD, Set_Key.KeyIndex, DOT11_ENC_CCMP<<2, 0, key_combo);
|
||
|
if (retVal) {
|
||
|
priv->pshare->CamEntryOccupied++;
|
||
|
pmib->dot11GroupKeysTable.keyInCam = TRUE;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case DOT11_ENC_NONE:
|
||
|
default:
|
||
|
DEBUG_ERR("No group encryption key is set!\n");
|
||
|
set_ttkeylen(pEncryptKey, 0);
|
||
|
set_tmickeylen(pEncryptKey, 0);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
#ifdef CONFIG_IEEE80211W
|
||
|
else if(Set_Key.KeyType == DOT11_KeyType_IGTK)
|
||
|
{
|
||
|
int set_gkey_to_cam = 0;
|
||
|
|
||
|
#ifdef CONFIG_RTL_88E_SUPPORT
|
||
|
if (GET_CHIP_VER(priv) == VERSION_8188E)
|
||
|
set_gkey_to_cam = 1;
|
||
|
#endif //CONFIG_RTL_88E_SUPPORT
|
||
|
|
||
|
#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
|
||
|
|
||
|
pmib->dot11IGTKTable.dot11Privacy = Set_Key.EncType;
|
||
|
pEncryptKey = &pmib->dot11IGTKTable.dot11EncryptKey;
|
||
|
pmib->dot11IGTKTable.keyid = (UINT)Set_Key.KeyIndex;
|
||
|
|
||
|
set_ttkeylen(pEncryptKey, 16);
|
||
|
set_tmickeylen(pEncryptKey, 16);
|
||
|
set_aes_key(pEncryptKey, key_combo);
|
||
|
|
||
|
}
|
||
|
#endif // CONFIG_IEEE80211W
|
||
|
else if(Set_Key.KeyType == DOT11_KeyType_Pairwise)
|
||
|
{
|
||
|
#ifdef WDS
|
||
|
// always to store WDS key for tx-hangup re-init
|
||
|
#if 0
|
||
|
// if driver is not opened, save the WDS key into mib. The key value will
|
||
|
// be updated into CAM when driver opened. david
|
||
|
if ( !IS_DRV_OPEN(priv)) { // not open or not in open
|
||
|
// if interface is not open and STA is a WDS entry, save the key
|
||
|
// to mib and restore it to STA table when driver is open, david
|
||
|
struct net_device *pNet = getWdsDevByAddr(priv, Set_Key.MACAddr);
|
||
|
if (pNet) {
|
||
|
int widx = getWdsIdxByDev(priv, pNet);
|
||
|
if (widx >= 0) {
|
||
|
if (Set_Key.EncType == _WEP_40_PRIVACY_ ||
|
||
|
Set_Key.EncType == _WEP_104_PRIVACY_)
|
||
|
memcpy(pmib->dot11WdsInfo.wdsWepKey, key_combo, 32);
|
||
|
else {
|
||
|
memcpy(pmib->dot11WdsInfo.wdsMapingKey[widx], key_combo, 32);
|
||
|
pmib->dot11WdsInfo.wdsMappingKeyLen[widx] = 32;
|
||
|
}
|
||
|
|
||
|
pmib->dot11WdsInfo.wdsKeyId = Set_Key.KeyIndex;
|
||
|
pmib->dot11WdsInfo.wdsPrivacy = Set_Key.EncType;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
return -1;
|
||
|
}
|
||
|
#endif
|
||
|
int widx = -1;
|
||
|
struct net_device *pNet = getWdsDevByAddr(priv, Set_Key.MACAddr);
|
||
|
if (pNet) {
|
||
|
widx = getWdsIdxByDev(priv, pNet);
|
||
|
if (widx >= 0) {
|
||
|
if (Set_Key.EncType == _WEP_40_PRIVACY_ ||
|
||
|
Set_Key.EncType == _WEP_104_PRIVACY_)
|
||
|
memcpy(pmib->dot11WdsInfo.wdsWepKey, key_combo, 32);
|
||
|
else {
|
||
|
memcpy(pmib->dot11WdsInfo.wdsMapingKey[widx], key_combo, 32);
|
||
|
pmib->dot11WdsInfo.wdsMappingKeyLen[widx] = 32;
|
||
|
}
|
||
|
pmib->dot11WdsInfo.wdsKeyId = Set_Key.KeyIndex;
|
||
|
pmib->dot11WdsInfo.wdsPrivacy = Set_Key.EncType;
|
||
|
}
|
||
|
}
|
||
|
if ( !IS_DRV_OPEN(priv)) {
|
||
|
if (widx > 0 && pmib->dot11WdsInfo.wdsMappingKeyLen[widx] > 0)
|
||
|
pmib->dot11WdsInfo.wdsMappingKeyLen[widx] |= 0x80000000;
|
||
|
return 0;
|
||
|
}
|
||
|
//----------------------------------- david+2006-06-30
|
||
|
#endif // WDS
|
||
|
|
||
|
#ifdef MULTI_MAC_CLONE
|
||
|
if ((OPMODE & WIFI_STATION_STATE) && priv->pmib->ethBrExtInfo.macclone_enable) {
|
||
|
ACTIVE_ID = mclone_find_address(priv, Set_Key.MACAddr, NULL, MAC_CLONE_NOCARE_FIND);
|
||
|
if (ACTIVE_ID < 0) {
|
||
|
DEBUG_ERR("Invalid mac address!\n");
|
||
|
return 0;
|
||
|
}
|
||
|
pstat = get_stainfo(priv, priv->pmib->dot11Bss.bssid);
|
||
|
}
|
||
|
else
|
||
|
#endif
|
||
|
pstat = get_stainfo(priv, Set_Key.MACAddr);
|
||
|
if (pstat == NULL) {
|
||
|
DEBUG_ERR("Set key failed, invalid mac address: %02x%02x%02x%02x%02x%02x\n",
|
||
|
Set_Key.MACAddr[0], Set_Key.MACAddr[1], Set_Key.MACAddr[2], Set_Key.MACAddr[3],
|
||
|
Set_Key.MACAddr[4], Set_Key.MACAddr[5]);
|
||
|
return (-1);
|
||
|
}
|
||
|
|
||
|
pstat->dot11KeyMapping.dot11Privacy = Set_Key.EncType;
|
||
|
pEncryptKey = &pstat->dot11KeyMapping.dot11EncryptKey;
|
||
|
pstat->keyid = Set_Key.KeyIndex;
|
||
|
|
||
|
#if defined(__DRAYTEK_OS__) && defined(WDS)
|
||
|
if (pstat->state & WIFI_WDS)
|
||
|
priv->pmib->dot11WdsInfo.wdsPrivacy = Set_Key.EncType;
|
||
|
#endif
|
||
|
|
||
|
switch(Set_Key.EncType)
|
||
|
{
|
||
|
case DOT11_ENC_TKIP:
|
||
|
set_ttkeylen(pEncryptKey, 16);
|
||
|
set_tmickeylen(pEncryptKey, 8);
|
||
|
set_tkip_key(pEncryptKey, key_combo);
|
||
|
|
||
|
DEBUG_INFO("going to set TKIP Unicast key for sta %02X%02X%02X%02X%02X%02X, id=%d\n",
|
||
|
Set_Key.MACAddr[0], Set_Key.MACAddr[1], Set_Key.MACAddr[2],
|
||
|
Set_Key.MACAddr[3], Set_Key.MACAddr[4], Set_Key.MACAddr[5], pstat->keyid);
|
||
|
if (!SWCRYPTO) {
|
||
|
retVal = CamDeleteOneEntry(priv, Set_Key.MACAddr, Set_Key.KeyIndex, 0);
|
||
|
if (retVal) {
|
||
|
priv->pshare->CamEntryOccupied--;
|
||
|
if (pstat) pstat->dot11KeyMapping.keyInCam = FALSE;
|
||
|
}
|
||
|
retVal = CamAddOneEntry(priv, Set_Key.MACAddr, Set_Key.KeyIndex, DOT11_ENC_TKIP<<2, 0, key_combo);
|
||
|
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, key_combo);
|
||
|
|
||
|
DEBUG_INFO("going to set WEP40 unicast key for sta %02X%02X%02X%02X%02X%02X, id=%d\n",
|
||
|
Set_Key.MACAddr[0], Set_Key.MACAddr[1], Set_Key.MACAddr[2],
|
||
|
Set_Key.MACAddr[3], Set_Key.MACAddr[4], Set_Key.MACAddr[5], pstat->keyid);
|
||
|
if (!SWCRYPTO) {
|
||
|
retVal = CamDeleteOneEntry(priv, Set_Key.MACAddr, Set_Key.KeyIndex, 0);
|
||
|
if (retVal) {
|
||
|
priv->pshare->CamEntryOccupied--;
|
||
|
if (pstat) pstat->dot11KeyMapping.keyInCam = FALSE;
|
||
|
}
|
||
|
retVal = CamAddOneEntry(priv, Set_Key.MACAddr, Set_Key.KeyIndex, DOT11_ENC_WEP40<<2, 0, key_combo);
|
||
|
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, key_combo);
|
||
|
|
||
|
DEBUG_INFO("going to set WEP104 unicast key for sta %02X%02X%02X%02X%02X%02X, id=%d\n",
|
||
|
Set_Key.MACAddr[0], Set_Key.MACAddr[1], Set_Key.MACAddr[2],
|
||
|
Set_Key.MACAddr[3], Set_Key.MACAddr[4], Set_Key.MACAddr[5], pstat->keyid);
|
||
|
if (!SWCRYPTO) {
|
||
|
retVal = CamDeleteOneEntry(priv, Set_Key.MACAddr, Set_Key.KeyIndex, 0);
|
||
|
if (retVal) {
|
||
|
priv->pshare->CamEntryOccupied--;
|
||
|
if (pstat) pstat->dot11KeyMapping.keyInCam = FALSE;
|
||
|
}
|
||
|
retVal = CamAddOneEntry(priv, Set_Key.MACAddr, Set_Key.KeyIndex, DOT11_ENC_WEP104<<2, 0, key_combo);
|
||
|
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, key_combo);
|
||
|
|
||
|
DEBUG_INFO("going to set CCMP-AES unicast key for sta %02X%02X%02X%02X%02X%02X, id=%d\n",
|
||
|
Set_Key.MACAddr[0], Set_Key.MACAddr[1], Set_Key.MACAddr[2],
|
||
|
Set_Key.MACAddr[3], Set_Key.MACAddr[4], Set_Key.MACAddr[5], pstat->keyid);
|
||
|
if (!SWCRYPTO) {
|
||
|
retVal = CamDeleteOneEntry(priv, Set_Key.MACAddr, Set_Key.KeyIndex, 0);
|
||
|
if (retVal) {
|
||
|
priv->pshare->CamEntryOccupied--;
|
||
|
if (pstat) pstat->dot11KeyMapping.keyInCam = FALSE;
|
||
|
}
|
||
|
retVal = CamAddOneEntry(priv, Set_Key.MACAddr, Set_Key.KeyIndex, DOT11_ENC_CCMP<<2, 0, key_combo);
|
||
|
if (retVal) {
|
||
|
priv->pshare->CamEntryOccupied++;
|
||
|
if (pstat) pstat->dot11KeyMapping.keyInCam = TRUE;
|
||
|
assign_aggre_mthod(priv, pstat);
|
||
|
}
|
||
|
else {
|
||
|
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;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*---------------------------------------------------------------------
|
||
|
Set Port Enable of Disable for STA
|
||
|
Return Value
|
||
|
Success : 0
|
||
|
-----------------------------------------------------------------------*/
|
||
|
static int DOT11_Process_Set_Port(struct net_device *dev, struct iw_point *data)
|
||
|
{
|
||
|
struct stat_info *pstat;
|
||
|
struct rtl8192cd_priv *priv = GET_DEV_PRIV(dev);
|
||
|
struct wifi_mib *pmib = priv->pmib;
|
||
|
DOT11_SET_PORT *Set_Port = (DOT11_SET_PORT *)data->pointer;
|
||
|
|
||
|
DEBUG_INFO("Set_Port sta %02X%02X%02X%02X%02X%02X Status %X\n",
|
||
|
Set_Port->MACAddr[0],Set_Port->MACAddr[1],Set_Port->MACAddr[2],
|
||
|
Set_Port->MACAddr[3],Set_Port->MACAddr[4],Set_Port->MACAddr[5],
|
||
|
Set_Port->PortStatus);
|
||
|
|
||
|
// if driver is not opened, return immediately, david
|
||
|
if (!netif_running(priv->dev))
|
||
|
return (-1);
|
||
|
|
||
|
pstat = get_stainfo(priv, Set_Port->MACAddr);
|
||
|
|
||
|
if ((pstat == NULL) || (!(pstat->state & WIFI_ASOC_STATE)))
|
||
|
return (-1);
|
||
|
|
||
|
if (Set_Port->PortStatus)
|
||
|
{
|
||
|
pstat->ieee8021x_ctrlport = Set_Port->PortStatus;
|
||
|
#ifdef INDICATE_LINK_CHANGE
|
||
|
indicate_sta_link_change(priv, pstat, INCREASE, __FUNCTION__);
|
||
|
#endif
|
||
|
}
|
||
|
else
|
||
|
pstat->ieee8021x_ctrlport = pmib->dot118021xAuthEntry.dot118021xDefaultPort;
|
||
|
|
||
|
#ifdef P2P_SUPPORT
|
||
|
if((OPMODE&WIFI_P2P_SUPPORT)&&( P2PMODE ==P2P_CLIENT)){
|
||
|
|
||
|
/*to indicate web server that data path is connected done(can start issue udhcpc daemon)*/
|
||
|
P2P_STATE = P2P_S_CLIENT_CONNECTED_DHCPC;
|
||
|
priv->p2pPtr->clientmode_try_connect = 0;
|
||
|
P2P_DEBUG("Set_Port Sta[%02X%02X%02X%02X%02X%02X],Status=%X\n\n\n",
|
||
|
Set_Port->MACAddr[0],Set_Port->MACAddr[1],Set_Port->MACAddr[2],
|
||
|
Set_Port->MACAddr[3],Set_Port->MACAddr[4],Set_Port->MACAddr[5],
|
||
|
Set_Port->PortStatus);
|
||
|
}
|
||
|
#endif
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
static int DOT11_Process_QueryRSC(struct net_device *dev, struct iw_point *data)
|
||
|
{
|
||
|
DOT11_GKEY_TSC *pGkey_TSC = (DOT11_GKEY_TSC *)data->pointer;
|
||
|
struct rtl8192cd_priv *priv = GET_DEV_PRIV(dev);
|
||
|
struct wifi_mib *pmib = priv->pmib;
|
||
|
|
||
|
pGkey_TSC->EventId = DOT11_EVENT_GKEY_TSC;
|
||
|
pGkey_TSC->IsMoreEvent = FALSE;
|
||
|
|
||
|
// Fix bug of getting RSC for auth (should consider endian issue)
|
||
|
//memcpy((void *)pGkey_TSC->KeyTSC,
|
||
|
// (void *)&(pmib->dot11GroupKeysTable.dot11EncryptKey.dot11TXPN48.val48), 6);
|
||
|
pGkey_TSC->KeyTSC[0] = pmib->dot11GroupKeysTable.dot11EncryptKey.dot11TXPN48._byte_.TSC0;
|
||
|
pGkey_TSC->KeyTSC[1] = pmib->dot11GroupKeysTable.dot11EncryptKey.dot11TXPN48._byte_.TSC1;
|
||
|
pGkey_TSC->KeyTSC[2] = pmib->dot11GroupKeysTable.dot11EncryptKey.dot11TXPN48._byte_.TSC2;
|
||
|
pGkey_TSC->KeyTSC[3] = pmib->dot11GroupKeysTable.dot11EncryptKey.dot11TXPN48._byte_.TSC3;
|
||
|
pGkey_TSC->KeyTSC[4] = pmib->dot11GroupKeysTable.dot11EncryptKey.dot11TXPN48._byte_.TSC4;
|
||
|
pGkey_TSC->KeyTSC[5] = pmib->dot11GroupKeysTable.dot11EncryptKey.dot11TXPN48._byte_.TSC5;
|
||
|
pGkey_TSC->KeyTSC[6] = 0x00;
|
||
|
pGkey_TSC->KeyTSC[7] = 0x00;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
static int DOT11_Porcess_EAPOL_MICReport(struct net_device *dev, struct iw_point *data)
|
||
|
{
|
||
|
#ifdef _DEBUG_RTL8192CD_
|
||
|
struct rtl8192cd_priv *priv = GET_DEV_PRIV(dev);
|
||
|
#endif
|
||
|
struct stat_info *pstat = NULL;
|
||
|
#ifdef _SINUX_
|
||
|
DOT11_MIC_FAILURE *MIC_Failure = (DOT11_MIC_FAILURE *)data->pointer;
|
||
|
|
||
|
printk("MIC fail report from 802.1x daemon\n");
|
||
|
printk("mac: %02x%02x%02x%02x%02x%02x\n", MIC_Failure->MACAddr[0], MIC_Failure->MACAddr[1],
|
||
|
MIC_Failure->MACAddr[2], MIC_Failure->MACAddr[3], MIC_Failure->MACAddr[4], MIC_Failure->MACAddr[5]);
|
||
|
mic_error_report(1);
|
||
|
#else
|
||
|
//DOT11_MIC_FAILURE *MIC_Failure = (DOT11_MIC_FAILURE *)data->pointer;
|
||
|
|
||
|
DEBUG_INFO("MIC fail report from 802.1x daemon\n");
|
||
|
//DEBUG_INFO("mac: %02x%02x%02x%02x%02x%02x\n", MIC_Failure->MACAddr[0], MIC_Failure->MACAddr[1],
|
||
|
//MIC_Failure->MACAddr[2], MIC_Failure->MACAddr[3], MIC_Failure->MACAddr[4], MIC_Failure->MACAddr[5]);
|
||
|
#endif
|
||
|
#ifdef RTL_WPA2
|
||
|
PRINT_INFO("%s: DOT11_Indicate_MIC_Failure \n", (char *)__FUNCTION__);
|
||
|
#endif
|
||
|
|
||
|
DOT11_Indicate_MIC_Failure(dev, pstat);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
#ifdef CONFIG_PCI_HCI
|
||
|
static inline
|
||
|
#endif
|
||
|
int __DOT11_Indicate_MIC_Failure(struct net_device *dev, struct stat_info *pstat)
|
||
|
{
|
||
|
struct rtl8192cd_priv *priv = GET_DEV_PRIV(dev);
|
||
|
struct stat_info *pstat_del;
|
||
|
DOT11_MIC_FAILURE Mic_Failure;
|
||
|
DOT11_DISASSOCIATION_IND Disassociation_Ind;
|
||
|
int i;
|
||
|
|
||
|
if (priv->pshare->skip_mic_chk || ((priv->ext_stats.tx_avarage + priv->ext_stats.rx_avarage) > (1024*1024/8)))
|
||
|
return 0;
|
||
|
|
||
|
// Indicate to upper layer
|
||
|
if (pstat != NULL) // if pstat==NULL, it is called by upper layer
|
||
|
{
|
||
|
DEBUG_INFO("MIC error indicate to 1x in driver\n");
|
||
|
//DEBUG_INFO("mac: %02x%02x%02x%02x%02x%02x\n", pstat->hwaddr[0], pstat->hwaddr[1],
|
||
|
//pstat->hwaddr[2], pstat->hwaddr[3], pstat->hwaddr[4], pstat->hwaddr[5]);
|
||
|
|
||
|
#ifdef __DRAYTEK_OS__
|
||
|
cb_tkip_micFailure(dev, pstat->hwaddr);
|
||
|
return 0;
|
||
|
#endif
|
||
|
|
||
|
#if !defined(WITHOUT_ENQUEUE) && (!defined(RTK_NL80211) || defined(NON_NL80211_AP))
|
||
|
Mic_Failure.EventId = DOT11_EVENT_MIC_FAILURE;
|
||
|
Mic_Failure.IsMoreEvent = 0;
|
||
|
memcpy(&Mic_Failure.MACAddr, pstat->hwaddr, MACADDRLEN);
|
||
|
DOT11_EnQueue((unsigned long)priv, priv->pevent_queue, (UINT8 *)&Mic_Failure, sizeof(DOT11_MIC_FAILURE));
|
||
|
#endif
|
||
|
#ifdef INCLUDE_WPA_PSK
|
||
|
psk_indicate_evt(priv, DOT11_EVENT_MIC_FAILURE, pstat->hwaddr, NULL, 0);
|
||
|
#endif
|
||
|
|
||
|
#ifdef WIFI_HAPD
|
||
|
event_indicate_hapd(priv, pstat->hwaddr, HAPD_MIC_FAILURE, NULL);
|
||
|
#ifdef HAPD_DRV_PSK_WPS
|
||
|
event_indicate(priv, pstat->hwaddr, 5);
|
||
|
#endif
|
||
|
#else
|
||
|
event_indicate(priv, pstat->hwaddr, 5);
|
||
|
#endif
|
||
|
#if 0//def WIFI_WPAS //_Eric ??
|
||
|
event_indicate_wpas(priv, pstat->hwaddr, WPAS_MIC_FAILURE, NULL);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
if (priv->MIC_timer_on)
|
||
|
{
|
||
|
// Second time to detect MIC error in a time period
|
||
|
|
||
|
// Stop Timer (fill a timer before than now)
|
||
|
if (timer_pending(&priv->MIC_check_timer))
|
||
|
del_timer_sync(&priv->MIC_check_timer);
|
||
|
priv->MIC_timer_on = FALSE;
|
||
|
|
||
|
// Start Timer to reject assocaiton request from STA, and reject all the packet
|
||
|
mod_timer(&priv->assoc_reject_timer, jiffies + REJECT_ASSOC_PERIOD);
|
||
|
priv->assoc_reject_on = TRUE;
|
||
|
for(i=0; i<NUM_STAT; i++)
|
||
|
{
|
||
|
if (priv->pshare->aidarray[i] && (priv->pshare->aidarray[i]->used == TRUE)
|
||
|
#ifdef WDS
|
||
|
&& !(priv->pshare->aidarray[i]->station.state & WIFI_WDS)
|
||
|
#endif
|
||
|
) {
|
||
|
#if defined(UNIVERSAL_REPEATER) || defined(MBSSID)
|
||
|
if (priv != priv->pshare->aidarray[i]->priv)
|
||
|
continue;
|
||
|
#endif
|
||
|
|
||
|
pstat_del = &(priv->pshare->aidarray[i]->station);
|
||
|
if (!list_empty(&pstat_del->asoc_list))
|
||
|
{
|
||
|
#ifdef _SINUX_
|
||
|
printk("Second time to detect MIC error in a time period so disassociate the all client\n");
|
||
|
mic_error_report(2);
|
||
|
#endif
|
||
|
#ifndef WITHOUT_ENQUEUE
|
||
|
memcpy((void *)Disassociation_Ind.MACAddr, (void *)pstat_del->hwaddr, MACADDRLEN);
|
||
|
Disassociation_Ind.EventId = DOT11_EVENT_DISASSOCIATION_IND;
|
||
|
Disassociation_Ind.IsMoreEvent = 0;
|
||
|
Disassociation_Ind.Reason = _STATS_OTHER_;
|
||
|
Disassociation_Ind.tx_packets = pstat_del->tx_pkts;
|
||
|
Disassociation_Ind.rx_packets = pstat_del->rx_pkts;
|
||
|
Disassociation_Ind.tx_bytes = pstat_del->tx_bytes;
|
||
|
Disassociation_Ind.rx_bytes = pstat_del->rx_bytes;
|
||
|
DOT11_EnQueue((unsigned long)priv, priv->pevent_queue, (UINT8 *)&Disassociation_Ind,
|
||
|
sizeof(DOT11_DISASSOCIATION_IND));
|
||
|
#endif
|
||
|
#if defined(INCLUDE_WPA_PSK)
|
||
|
psk_indicate_evt(priv, DOT11_EVENT_DISASSOCIATION_IND, pstat_del->hwaddr, NULL, 0);
|
||
|
#elif defined(WIFI_HAPD) || defined(RTK_NL80211)
|
||
|
nl80211_psk_indicate_evt(priv, DOT11_EVENT_DISASSOCIATION_IND, pstat_del->hwaddr, NULL, 0);
|
||
|
#endif
|
||
|
|
||
|
#if defined(RTK_NL80211) && !defined(NON_NL80211_AP)
|
||
|
event_indicate_cfg80211(priv, pstat_del->hwaddr, CFG80211_DEL_STA, NULL);
|
||
|
#elif defined(WIFI_HAPD)
|
||
|
event_indicate_hapd(priv, pstat_del->hwaddr, HAPD_EXIRED, NULL);
|
||
|
#ifdef HAPD_DRV_PSK_WPS
|
||
|
event_indicate(priv, pstat_del->hwaddr, 2);
|
||
|
#endif
|
||
|
#else
|
||
|
event_indicate(priv, pstat_del->hwaddr, 2);
|
||
|
#endif
|
||
|
|
||
|
issue_disassoc(priv, pstat_del->hwaddr, _RSON_MIC_FAILURE_);
|
||
|
}
|
||
|
free_stainfo(priv, pstat_del);
|
||
|
}
|
||
|
}
|
||
|
priv->assoc_num = 0;
|
||
|
if (priv->pmib->dot11BssType.net_work_type & WIRELESS_11G) {
|
||
|
priv->pmib->dot11ErpInfo.nonErpStaNum = 0;
|
||
|
check_protection_shortslot(priv);
|
||
|
priv->pmib->dot11ErpInfo.longPreambleStaNum = 0;
|
||
|
}
|
||
|
if (priv->pmib->dot11BssType.net_work_type & WIRELESS_11N)
|
||
|
priv->ht_legacy_sta_num = 0;
|
||
|
|
||
|
// ToDo: Should we delete group key?
|
||
|
#ifdef _SINUX_
|
||
|
printk("-------------------------------------------------------\n");
|
||
|
printk("Second time of MIC failure in a time period \n");
|
||
|
printk("-------------------------------------------------------\n");
|
||
|
#else
|
||
|
DEBUG_INFO("-------------------------------------------------------\n");
|
||
|
DEBUG_INFO("Second time of MIC failure in a time period \n");
|
||
|
DEBUG_INFO("-------------------------------------------------------\n");
|
||
|
#endif
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// First time to detect MIC error, start the timer
|
||
|
mod_timer(&priv->MIC_check_timer, jiffies + MIC_TIMER_PERIOD);
|
||
|
priv->MIC_timer_on = TRUE;
|
||
|
|
||
|
DEBUG_INFO("-------------------------------------------------------\n");
|
||
|
DEBUG_INFO("First time of MIC failure in a time period, start timer\n");
|
||
|
DEBUG_INFO("-------------------------------------------------------\n");
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int DOT11_Indicate_MIC_Failure(struct net_device *dev, struct stat_info *pstat)
|
||
|
{
|
||
|
#if defined(CONFIG_PCI_HCI)
|
||
|
return __DOT11_Indicate_MIC_Failure(dev, pstat);
|
||
|
#elif defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI)
|
||
|
notify_indicate_MIC_failure(dev, pstat);
|
||
|
return 0;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void DOT11_Process_MIC_Timerup(unsigned long data)
|
||
|
{
|
||
|
struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)data;
|
||
|
|
||
|
if (!(priv->drv_state & DRV_STATE_OPEN))
|
||
|
return;
|
||
|
|
||
|
DEBUG_INFO("MIC Timer is up. Cancel Timer\n");
|
||
|
priv->MIC_timer_on = FALSE;
|
||
|
}
|
||
|
|
||
|
void DOT11_Process_Reject_Assoc_Timerup(unsigned long data)
|
||
|
{
|
||
|
struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)data;
|
||
|
|
||
|
if (!(priv->drv_state & DRV_STATE_OPEN))
|
||
|
return;
|
||
|
|
||
|
DEBUG_INFO("Reject Association Request Timer is up. Cancel Timer\n");
|
||
|
memset(priv->assoc_reject_mac,0,MACADDRLEN);
|
||
|
#ifdef CLIENT_MODE
|
||
|
if (OPMODE & WIFI_STATION_STATE)
|
||
|
start_clnt_lookup(priv, 0);
|
||
|
#endif
|
||
|
priv->assoc_reject_on = FALSE;
|
||
|
}
|
||
|
|
||
|
#ifdef CONFIG_PCI_HCI
|
||
|
static inline
|
||
|
#endif
|
||
|
void __DOT11_Indicate_MIC_Failure_Clnt(struct rtl8192cd_priv *priv, unsigned char *sa)
|
||
|
{
|
||
|
DOT11_MIC_FAILURE Mic_Failure;
|
||
|
struct stat_info *pstat_del;
|
||
|
DOT11_DISASSOCIATION_IND Disassociation_Ind;
|
||
|
// int i;
|
||
|
#ifndef WITHOUT_ENQUEUE
|
||
|
Mic_Failure.EventId = DOT11_EVENT_MIC_FAILURE;
|
||
|
Mic_Failure.IsMoreEvent = 0;
|
||
|
memcpy(&Mic_Failure.MACAddr, sa, MACADDRLEN);
|
||
|
DOT11_EnQueue((unsigned long)priv, priv->pevent_queue, (UINT8 *)&Mic_Failure, sizeof(DOT11_MIC_FAILURE));
|
||
|
#endif
|
||
|
#if defined(INCLUDE_WPA_PSK) && !defined(NON_NL80211_AP) && !defined(WIFI_WPAS_CLI)
|
||
|
if (OPMODE & (WIFI_STATION_STATE | WIFI_ASOC_STATE))
|
||
|
psk_indicate_evt(priv, DOT11_EVENT_MIC_FAILURE, BSSID, NULL, 0);
|
||
|
#endif
|
||
|
|
||
|
#if defined(RTK_NL80211) && !defined(NON_NL80211_WPAS)
|
||
|
event_indicate_cfg80211(priv, sa, CFG80211_MIC_FAILURE, NULL);
|
||
|
#elif defined(WIFI_WPAS)
|
||
|
event_indicate_wpas(priv, sa, WPAS_MIC_FAILURE, NULL);
|
||
|
#else
|
||
|
event_indicate(priv, sa, 5);
|
||
|
#endif
|
||
|
if (priv->MIC_timer_on) {
|
||
|
// Second time to detect MIC error in a time period
|
||
|
|
||
|
// Stop Timer (fill a timer before than now)
|
||
|
if (timer_pending(&priv->MIC_check_timer))
|
||
|
del_timer_sync(&priv->MIC_check_timer);
|
||
|
priv->MIC_timer_on = FALSE;
|
||
|
|
||
|
// Start Timer to reject assocaiton request from STA, and reject all the packet
|
||
|
mod_timer(&priv->assoc_reject_timer, jiffies + REJECT_ASSOC_PERIOD);
|
||
|
priv->assoc_reject_on = TRUE;
|
||
|
memcpy(priv->assoc_reject_mac, BSSID, MACADDRLEN);
|
||
|
|
||
|
pstat_del = get_stainfo(priv, BSSID);
|
||
|
memcpy((void *)Disassociation_Ind.MACAddr, (void *)pstat_del->hwaddr, MACADDRLEN);
|
||
|
DEBUG_INFO("%s() disassoc %02X:%02X:%02X:%02X:%02X:%02X\n",__func__,pstat_del->hwaddr[0],pstat_del->hwaddr[1],pstat_del->hwaddr[2],pstat_del->hwaddr[3],pstat_del->hwaddr[4],pstat_del->hwaddr[5]);
|
||
|
|
||
|
Disassociation_Ind.EventId = DOT11_EVENT_DISASSOCIATION_IND;
|
||
|
Disassociation_Ind.IsMoreEvent = 0;
|
||
|
Disassociation_Ind.Reason = _STATS_OTHER_;
|
||
|
Disassociation_Ind.tx_packets = pstat_del->tx_pkts;
|
||
|
Disassociation_Ind.rx_packets = pstat_del->rx_pkts;
|
||
|
Disassociation_Ind.tx_bytes = pstat_del->tx_bytes;
|
||
|
Disassociation_Ind.rx_bytes = pstat_del->rx_bytes;
|
||
|
DOT11_EnQueue((unsigned long)priv, priv->pevent_queue, (UINT8 *)&Disassociation_Ind,
|
||
|
sizeof(DOT11_DISASSOCIATION_IND));
|
||
|
|
||
|
/*
|
||
|
* To make sure the MIC Failure Report is sent before disassoc
|
||
|
*/
|
||
|
delay_ms(20);
|
||
|
issue_disassoc(priv, pstat_del->hwaddr, _RSON_MIC_FAILURE_);
|
||
|
free_stainfo(priv, pstat_del);
|
||
|
|
||
|
priv->assoc_num = 0;
|
||
|
if (priv->pmib->dot11BssType.net_work_type & WIRELESS_11G) {
|
||
|
priv->pmib->dot11ErpInfo.nonErpStaNum = 0;
|
||
|
check_protection_shortslot(priv);
|
||
|
priv->pmib->dot11ErpInfo.longPreambleStaNum = 0;
|
||
|
}
|
||
|
if (priv->pmib->dot11BssType.net_work_type & WIRELESS_11N)
|
||
|
priv->ht_legacy_sta_num = 0;
|
||
|
|
||
|
DEBUG_INFO("-------------------------------------------------------\n");
|
||
|
DEBUG_INFO("Second time of MIC failure in a time period \n");
|
||
|
DEBUG_INFO("-------------------------------------------------------\n");
|
||
|
} else {
|
||
|
// First time to detect MIC error, start the timer
|
||
|
mod_timer(&priv->MIC_check_timer, jiffies + MIC_TIMER_PERIOD);
|
||
|
priv->MIC_timer_on = TRUE;
|
||
|
|
||
|
DEBUG_INFO("-------------------------------------------------------\n");
|
||
|
DEBUG_INFO("First time of MIC failure in a time period, start timer\n");
|
||
|
DEBUG_INFO("-------------------------------------------------------\n");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void DOT11_Indicate_MIC_Failure_Clnt(struct rtl8192cd_priv *priv, unsigned char *sa)
|
||
|
{
|
||
|
#if defined(WIFI_WPAS_CLI)
|
||
|
event_indicate_wpas(priv, sa, WPAS_MIC_FAILURE, NULL);
|
||
|
#elif defined(CONFIG_PCI_HCI)
|
||
|
__DOT11_Indicate_MIC_Failure_Clnt(priv, sa);
|
||
|
#elif defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI)
|
||
|
notify_indicate_MIC_failure_clnt(priv, sa);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
#ifdef RADIUS_ACCOUNTING
|
||
|
void DOT11_Process_Acc_SetExpiredTime(struct net_device *dev, struct iw_point *data)
|
||
|
{
|
||
|
struct rtl8192cd_priv *priv = GET_DEV_PRIV(dev);
|
||
|
|
||
|
//WLAN_CTX *wCtx = (WLAN_CTX *) ( priv->pwlanCtx );
|
||
|
DOT11_SET_EXPIREDTIME *Set_ExpireTime = (DOT11_SET_EXPIREDTIME *)data->pointer;
|
||
|
struct stat_info *pstat=NULL;
|
||
|
|
||
|
if( Set_ExpireTime != NULL ){
|
||
|
Set_ExpireTime->EventId = DOT11_EVENT_ACC_SET_EXPIREDTIME;
|
||
|
Set_ExpireTime->IsMoreEvent = 0;
|
||
|
|
||
|
if( (pstat = get_stainfo(priv, Set_ExpireTime->MACAddr)) ){
|
||
|
pstat->def_expired_time = Set_ExpireTime->ExpireTime;
|
||
|
DEBUG_INFO("%s: Set %02x:%02x:%02x:%02x:%02x:%02x def_expired_time = %ld!\n", (char *)__FUNCTION__,
|
||
|
pstat->hwaddr[0],pstat->hwaddr[1],pstat->hwaddr[2],pstat->hwaddr[3],pstat->hwaddr[4],pstat->hwaddr[5],
|
||
|
Set_ExpireTime->ExpireTime);
|
||
|
}
|
||
|
else{
|
||
|
DEBUG_ERR("%s: ERRO, CAN NOT GET STA INFO!\n", (char *)__FUNCTION__);
|
||
|
}
|
||
|
}
|
||
|
else{
|
||
|
DEBUG_ERR("%s: NULL POINTER!\n", (char *)__FUNCTION__);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void DOT11_Process_Acc_QueryStats(struct net_device *dev, struct iw_point *data)
|
||
|
{
|
||
|
struct rtl8192cd_priv *priv = GET_DEV_PRIV(dev);
|
||
|
|
||
|
//WLAN_CTX *wCtx = (WLAN_CTX *) ( priv->pwlanCtx );
|
||
|
struct stat_info *pstat=NULL;
|
||
|
DOT11_QUERY_STATS *pStats = (DOT11_QUERY_STATS *)data->pointer;
|
||
|
|
||
|
if( pStats != NULL ){
|
||
|
pStats->EventId = DOT11_EVENT_ACC_QUERY_STATS;
|
||
|
pStats->IsMoreEvent = 0;
|
||
|
|
||
|
if( (pstat = get_stainfo(priv, pStats->MACAddr)) ){
|
||
|
pStats->tx_packets = pstat->tx_pkts;
|
||
|
pStats->rx_packets = pstat->rx_pkts;
|
||
|
pStats->tx_bytes = pstat->tx_bytes;
|
||
|
pStats->rx_bytes = pstat->rx_bytes;
|
||
|
|
||
|
pStats->IsSuccess = TRUE;
|
||
|
DEBUG_INFO("%s: Get %02x:%02x:%02x:%02x:%02x:%02x stats!\n", (char *)__FUNCTION__,
|
||
|
pstat->hwaddr[0],pstat->hwaddr[1],pstat->hwaddr[2],pstat->hwaddr[3],pstat->hwaddr[4],pstat->hwaddr[5]);
|
||
|
}
|
||
|
else{
|
||
|
pStats->IsSuccess = FALSE;
|
||
|
DEBUG_ERR("%s: ERROR, CAN NOT GET STA INFO!\n", (char *)__FUNCTION__);
|
||
|
}
|
||
|
}
|
||
|
else{
|
||
|
DEBUG_ERR("%s: NULL POINTER!\n", (char *)__FUNCTION__);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//-------------------------
|
||
|
//DOT11_QUERY_STATS stats[RTL_AP_MAX_STA_NUM+1];
|
||
|
//data->pointer = (unsigned char *)stats;
|
||
|
void DOT11_Process_Acc_QueryStats_All(struct net_device *dev, struct iw_point *data)
|
||
|
{
|
||
|
struct rtl8192cd_priv *priv = GET_DEV_PRIV(dev);
|
||
|
struct list_head *phead=NULL, *plist=NULL;
|
||
|
struct stat_info *pstat=NULL;
|
||
|
//WLAN_CTX *wCtx = (WLAN_CTX *) ( priv->pwlanCtx );
|
||
|
DOT11_QUERY_STATS *pStats = (DOT11_QUERY_STATS *)data->pointer;
|
||
|
//int i;
|
||
|
int cnt = 0;
|
||
|
#ifdef SMP_SYNC
|
||
|
unsigned long flags=0;
|
||
|
#endif
|
||
|
|
||
|
if( pStats != NULL ){
|
||
|
phead = &priv->asoc_list;
|
||
|
|
||
|
SMP_LOCK_ASOC_LIST(flags);
|
||
|
|
||
|
plist = phead->next;
|
||
|
while (plist != phead) {
|
||
|
pstat = list_entry(plist, struct stat_info, asoc_list);
|
||
|
plist = plist->next;
|
||
|
|
||
|
pStats[cnt].EventId = DOT11_EVENT_ACC_QUERY_STATS_ALL;
|
||
|
pStats[cnt].IsMoreEvent = 0;
|
||
|
memcpy( pStats[cnt].MACAddr, pstat->hwaddr, MACADDRLEN );
|
||
|
pStats[cnt].tx_packets = pstat->tx_pkts;
|
||
|
pStats[cnt].rx_packets = pstat->rx_pkts;
|
||
|
pStats[cnt].tx_bytes = pstat->tx_bytes;
|
||
|
pStats[cnt].rx_bytes = pstat->rx_bytes;
|
||
|
|
||
|
cnt++;
|
||
|
}
|
||
|
SMP_UNLOCK_ASOC_LIST(flags);
|
||
|
}
|
||
|
else{
|
||
|
printk("%s: NULL POINTER!\n", (char *)__FUNCTION__);
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
|
||
|
static int DOT11_Process_STA_Query_Bssid(struct net_device *dev, struct iw_point *data)
|
||
|
{
|
||
|
DOT11_STA_QUERY_BSSID *pQuery = (DOT11_STA_QUERY_BSSID *)data->pointer;
|
||
|
struct rtl8192cd_priv *priv = GET_DEV_PRIV(dev);
|
||
|
|
||
|
pQuery->EventId = DOT11_EVENT_STA_QUERY_BSSID;
|
||
|
pQuery->IsMoreEvent = FALSE;
|
||
|
if ((OPMODE & (WIFI_STATION_STATE | WIFI_ASOC_STATE)) ==
|
||
|
(WIFI_STATION_STATE | WIFI_ASOC_STATE))
|
||
|
{
|
||
|
pQuery->IsValid = TRUE;
|
||
|
memcpy(pQuery->Bssid, BSSID, 6);
|
||
|
}
|
||
|
else
|
||
|
pQuery->IsValid = FALSE;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
static int DOT11_Process_STA_Query_Ssid(struct net_device *dev, struct iw_point *data)
|
||
|
{
|
||
|
DOT11_STA_QUERY_SSID *pQuery = (DOT11_STA_QUERY_SSID *)data->pointer;
|
||
|
struct rtl8192cd_priv *priv = GET_DEV_PRIV(dev);
|
||
|
|
||
|
pQuery->EventId = DOT11_EVENT_STA_QUERY_SSID;
|
||
|
pQuery->IsMoreEvent = FALSE;
|
||
|
if ((OPMODE & (WIFI_STATION_STATE | WIFI_ASOC_STATE)) ==
|
||
|
(WIFI_STATION_STATE | WIFI_ASOC_STATE))
|
||
|
{
|
||
|
pQuery->IsValid = TRUE;
|
||
|
memcpy(pQuery->ssid, SSID, 32);
|
||
|
pQuery->ssid_len = SSID_LEN;
|
||
|
}
|
||
|
else
|
||
|
pQuery->IsValid = FALSE;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
#ifdef WIFI_SIMPLE_CONFIG
|
||
|
static int DOT11_WSC_set_ie(struct net_device *dev, struct iw_point *data)
|
||
|
{
|
||
|
struct rtl8192cd_priv *priv = GET_DEV_PRIV(dev);
|
||
|
DOT11_SET_RSNIE *Set_RSNIE = (DOT11_SET_RSNIE *)data->pointer;
|
||
|
|
||
|
if (Set_RSNIE->Flag == SET_IE_FLAG_BEACON) {
|
||
|
DEBUG_INFO("WSC: set beacon IE\n");
|
||
|
priv->pmib->wscEntry.beacon_ielen = Set_RSNIE->RSNIELen;
|
||
|
memcpy((void *)priv->pmib->wscEntry.beacon_ie, Set_RSNIE->RSNIE, Set_RSNIE->RSNIELen);
|
||
|
#ifdef SDIO_AP_OFFLOAD
|
||
|
{
|
||
|
#define TAG_SELECTED_REGISTRAR 0x1041
|
||
|
|
||
|
int attr_len;
|
||
|
if (search_wsc_tag(Set_RSNIE->RSNIE+6, TAG_SELECTED_REGISTRAR,
|
||
|
Set_RSNIE->RSNIELen-6, &attr_len)) // found
|
||
|
ap_offload_deactivate(priv, OFFLOAD_PROHIBIT_WPS);
|
||
|
else
|
||
|
ap_offload_activate(priv, OFFLOAD_PROHIBIT_WPS);
|
||
|
}
|
||
|
#endif // SDIO_AP_OFFLOAD
|
||
|
}
|
||
|
else if (Set_RSNIE->Flag == SET_IE_FLAG_PROBE_RSP) {
|
||
|
DEBUG_INFO("WSC: set probe response IE\n");
|
||
|
priv->pmib->wscEntry.probe_rsp_ielen = Set_RSNIE->RSNIELen;
|
||
|
memcpy((void *)priv->pmib->wscEntry.probe_rsp_ie, Set_RSNIE->RSNIE, Set_RSNIE->RSNIELen);
|
||
|
}
|
||
|
else if (Set_RSNIE->Flag == SET_IE_FLAG_PROBE_REQ) {
|
||
|
DEBUG_INFO("WSC: set probe request IE\n");
|
||
|
priv->pmib->wscEntry.probe_req_ielen = Set_RSNIE->RSNIELen;
|
||
|
memcpy((void *)priv->pmib->wscEntry.probe_req_ie, Set_RSNIE->RSNIE, Set_RSNIE->RSNIELen);
|
||
|
}
|
||
|
else if (Set_RSNIE->Flag == SET_IE_FLAG_ASSOC_REQ ||
|
||
|
Set_RSNIE->Flag == SET_IE_FLAG_ASSOC_RSP) {
|
||
|
DEBUG_INFO("WSC: set assoc IE\n");
|
||
|
priv->pmib->wscEntry.assoc_ielen = Set_RSNIE->RSNIELen;
|
||
|
memcpy((void *)priv->pmib->wscEntry.assoc_ie, Set_RSNIE->RSNIE, Set_RSNIE->RSNIELen);
|
||
|
}
|
||
|
#if 0
|
||
|
else if (Set_RSNIE->Flag == 3) {
|
||
|
printk("WSC: set RSN IE\n");
|
||
|
priv->pmib->dot11RsnIE.rsnielen = Set_RSNIE->RSNIELen;
|
||
|
memcpy((void *)priv->pmib->dot11RsnIE.rsnie, Set_RSNIE->RSNIE, Set_RSNIE->RSNIELen);
|
||
|
}
|
||
|
#endif
|
||
|
else {
|
||
|
DEBUG_ERR("Invalid flag of set IE [%d]!\n", Set_RSNIE->Flag);
|
||
|
}
|
||
|
|
||
|
#ifdef PCIE_POWER_SAVING
|
||
|
if ((Set_RSNIE->Flag == SET_IE_FLAG_BEACON) || (Set_RSNIE->Flag == SET_IE_FLAG_PROBE_RSP))
|
||
|
PCIeWakeUp(priv, (POWER_DOWN_T0));
|
||
|
#endif
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
#ifdef INCLUDE_WPS
|
||
|
#ifndef CONFIG_MSC
|
||
|
static int dispatch_wscsoap(struct rtl8192cd_priv *priv ,pDOT11_WSC_SOAP soap)
|
||
|
{
|
||
|
struct WSC_packet *packet=NULL;
|
||
|
|
||
|
printk("\nWlan Driver receive SOAP request:%s\n",soap->action);
|
||
|
|
||
|
packet = &soap->packet;
|
||
|
|
||
|
if( strcmp(soap->action,"WFAGetDeviceInfo") ){
|
||
|
packet->EventType = WSC_NOT_PROXY;
|
||
|
packet->EventID = WSC_GETDEVINFO;
|
||
|
} else if ( strcmp(soap->action,"SendMsgToSM_Dir_In") ){
|
||
|
packet->EventID = WSC_SETSELECTEDREGISTRA;
|
||
|
} else if ( strcmp(soap->action,"SendMsgToSM_Dir_InOut") ){
|
||
|
packet->EventID = WSC_M2M4M6M8;
|
||
|
} else if ( strcmp(soap->action,"WFAPutWLANResponse") ) {
|
||
|
packet->EventID = WSC_PUTWLANRESPONSE;
|
||
|
}
|
||
|
#ifdef SUPPORT_UPNP
|
||
|
if (PWSCUpnpCallbackEventHandler(packet) != WSC_UPNP_SUCCESS) {
|
||
|
DEBUG_ERR("WSCCallBack Fail!\n");
|
||
|
goto error_handle;
|
||
|
}
|
||
|
#endif
|
||
|
return 0;
|
||
|
|
||
|
error_handle:
|
||
|
return -1;
|
||
|
}
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
#endif // WIFI_SIMPLE_CONFIG
|
||
|
|
||
|
#ifdef USER_ADDIE
|
||
|
static int DOT11_USER_set_ie(struct net_device *dev, struct iw_point *data)
|
||
|
{
|
||
|
struct rtl8192cd_priv *priv = GET_DEV_PRIV(dev);
|
||
|
DOT11_SET_USERIE *Set_USERIE = (DOT11_SET_USERIE *)data->pointer;
|
||
|
unsigned int i;
|
||
|
|
||
|
if (Set_USERIE->Flag == SET_IE_FLAG_INSERT) {
|
||
|
DEBUG_INFO("USER: add beacon IE\n");
|
||
|
for (i=0; i<MAX_USER_IE; i++) {
|
||
|
if (!priv->user_ie_list[i].used)
|
||
|
break;
|
||
|
}
|
||
|
if (i == MAX_USER_IE)
|
||
|
return -1;
|
||
|
priv->user_ie_list[i].used = 1;
|
||
|
priv->user_ie_list[i].ie_len = Set_USERIE->USERIELen;
|
||
|
memcpy((void *)priv->user_ie_list[i].ie, Set_USERIE->USERIE, Set_USERIE->USERIELen);
|
||
|
}
|
||
|
else if (Set_USERIE->Flag == SET_IE_FLAG_DELETE) {
|
||
|
DEBUG_INFO("USER: remove beacon IE\n");
|
||
|
for (i=0; i<MAX_USER_IE; i++) {
|
||
|
if (priv->user_ie_list[i].used &&
|
||
|
!memcmp(priv->user_ie_list[i].ie, Set_USERIE->USERIE, Set_USERIE->USERIELen)) {
|
||
|
priv->user_ie_list[i].used = 0;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if (i == MAX_USER_IE)
|
||
|
return -1;
|
||
|
}
|
||
|
else {
|
||
|
DEBUG_ERR("Invalid flag of set IE [%d]!\n", Set_USERIE->Flag);
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
|
||
|
#ifdef CONFIG_IEEE80211W
|
||
|
static int DOT11_PMF_set_ie(struct net_device *dev, struct iw_point *data)
|
||
|
{
|
||
|
struct rtl8192cd_priv *priv = GET_DEV_PRIV(dev);
|
||
|
|
||
|
struct stat_info *pstat;
|
||
|
DOT11_SET_11W_Flags flags;
|
||
|
if (!memcpy((void *)(&flags),(void *)(data->pointer), data->length))
|
||
|
{
|
||
|
PMFDEBUG("memcpy fail!, data=%x, length=%d\n", data->pointer, data->length);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
pstat= get_stainfo(priv,flags.macAddr);
|
||
|
|
||
|
if (!pstat) {
|
||
|
//PMFDEBUG("psta is NULL\n");
|
||
|
} else {
|
||
|
pstat->isPMF = flags.isPMF;
|
||
|
PMFDEBUG("set sta[%02x%02x%02x:%02x%02x%02x]'s PMF=[%d]\n",pstat->hwaddr[0],pstat->hwaddr[1],pstat->hwaddr[2],pstat->hwaddr[3],pstat->hwaddr[4],pstat->hwaddr[5], flags.isPMF);
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#ifdef HS2_SUPPORT
|
||
|
/* Hotspot 2.0 Release 1*/
|
||
|
static int DOT11_HS2_set_ie(struct net_device *dev, struct iw_point *data)
|
||
|
{
|
||
|
struct rtl8192cd_priv *priv = GET_DEV_PRIV(dev);
|
||
|
DOT11_SET_RSNIE *Set_RSNIE = (DOT11_SET_RSNIE *)data->pointer;
|
||
|
HS2_DEBUG_INFO("HS2 set ie, flag=%d\n",Set_RSNIE->Flag);
|
||
|
if (Set_RSNIE->Flag == SET_IE_FLAG_INTERWORKING)
|
||
|
{
|
||
|
//DEBUG_INFO
|
||
|
HS2_DEBUG_TRACE(1, "HS2: set interworking IE,%x,%x\n",Set_RSNIE->RSNIE[0], Set_RSNIE->RSNIE[1]);
|
||
|
priv->pmib->hs2Entry.interworking_ielen = Set_RSNIE->RSNIELen;
|
||
|
memcpy((void *)priv->pmib->hs2Entry.interworking_ie, Set_RSNIE->RSNIE, Set_RSNIE->RSNIELen);
|
||
|
}
|
||
|
else if (Set_RSNIE->Flag == SET_IE_FLAG_ADVT_PROTO)
|
||
|
{
|
||
|
HS2_DEBUG_TRACE(1, "HS2: set advt proto IE\n");
|
||
|
priv->pmib->hs2Entry.advt_proto_ielen = Set_RSNIE->RSNIELen;
|
||
|
memcpy((void *)priv->pmib->hs2Entry.advt_proto_ie, Set_RSNIE->RSNIE, Set_RSNIE->RSNIELen);
|
||
|
}
|
||
|
else if (Set_RSNIE->Flag == SET_IE_FLAG_ROAMING)
|
||
|
{
|
||
|
HS2_DEBUG_TRACE(1, "HS2: set roaming IE\n");
|
||
|
priv->pmib->hs2Entry.roam_ielen = Set_RSNIE->RSNIELen;
|
||
|
memcpy((void *)priv->pmib->hs2Entry.roam_ie, Set_RSNIE->RSNIE, Set_RSNIE->RSNIELen);
|
||
|
}
|
||
|
else if (Set_RSNIE->Flag == SET_IE_FLAG_HS2)
|
||
|
{
|
||
|
HS2_DEBUG_TRACE(1, "HS2: set HS2 IE\n");
|
||
|
priv->pmib->hs2Entry.hs2_ielen = Set_RSNIE->RSNIELen;
|
||
|
memcpy((void *)priv->pmib->hs2Entry.hs2_ie, Set_RSNIE->RSNIE, Set_RSNIE->RSNIELen);
|
||
|
if (priv->pmib->hs2Entry.hs2_ie[4] & 0x01)
|
||
|
{
|
||
|
HS2_DEBUG_TRACE(1, "dgaf enable\n");
|
||
|
priv->dgaf_disable = 1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
HS2_DEBUG_TRACE(1, "dgaf disable\n");
|
||
|
priv->dgaf_disable = 0;
|
||
|
}
|
||
|
|
||
|
//channel utilization
|
||
|
init_timer(&priv->cu_cntdwn_timer);
|
||
|
priv->cu_cntdwn_timer.data = (unsigned long) priv;
|
||
|
priv->cu_cntdwn_timer.function = rtl8192cd_cu_cntdwn_timer;
|
||
|
priv->cu_cntdwn = priv->cu_initialcnt = (priv->pmib->hs2Entry.channel_utili_beaconIntval * priv->pmib->dot11StationConfigEntry.dot11BeaconPeriod)/CU_Intval;
|
||
|
start_bbp_ch_load(priv, 50000);
|
||
|
priv->cu_cntdwn_timer.expires = jiffies + CU_TO;
|
||
|
mod_timer(&priv->cu_cntdwn_timer, jiffies + CU_TO);
|
||
|
}
|
||
|
else if (Set_RSNIE->Flag == SET_IE_FLAG_TIMEADVT)
|
||
|
{
|
||
|
HS2_DEBUG_TRACE(1, "HS2: set timeadvt IE\n");
|
||
|
priv->pmib->hs2Entry.timeadvt_ielen = Set_RSNIE->RSNIELen;
|
||
|
memcpy((void *)priv->pmib->hs2Entry.timeadvt_ie, Set_RSNIE->RSNIE, Set_RSNIE->RSNIELen);
|
||
|
}
|
||
|
else if (Set_RSNIE->Flag == SET_IE_FLAG_TIMEZONE)
|
||
|
{
|
||
|
HS2_DEBUG_TRACE(1, "HS2: set time zone IE\n");
|
||
|
priv->pmib->hs2Entry.timezone_ielen = Set_RSNIE->RSNIELen;
|
||
|
memcpy((void *)priv->pmib->hs2Entry.timezone_ie, Set_RSNIE->RSNIE, Set_RSNIE->RSNIELen);
|
||
|
}
|
||
|
else if (Set_RSNIE->Flag == SET_IE_FLAG_PROXYARP)
|
||
|
{
|
||
|
priv->proxy_arp = *Set_RSNIE->RSNIE;
|
||
|
HS2_DEBUG_INFO("\n\n\n\nproxy arp in driver=%d\n\n\n\n\n", priv->proxy_arp);
|
||
|
}
|
||
|
else if (Set_RSNIE->Flag == SET_IE_FLAG_ICMPv4ECHO)
|
||
|
{
|
||
|
priv->pmib->hs2Entry.ICMPv4ECHO = *Set_RSNIE->RSNIE;
|
||
|
HS2_DEBUG_INFO("\n\n\n\nICMPv4ECHO in driver=%d\n\n\n\n\n", priv->pmib->hs2Entry.ICMPv4ECHO);
|
||
|
}
|
||
|
else if (Set_RSNIE->Flag == SET_IE_FLAG_MMPDULIMIT) {
|
||
|
memcpy((void *)(&priv->pmib->hs2Entry.mmpdu_limit), Set_RSNIE->RSNIE, Set_RSNIE->RSNIELen);
|
||
|
HS2_DEBUG_INFO("mmpdu_limit:%d\n",priv->pmib->hs2Entry.mmpdu_limit);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
HS2_DEBUG_ERR("HS2: unknown ioctl flag\n");
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
/*-----------------------------------------------------------------------------
|
||
|
Most of the time, we don't have to worry about the racing condition of
|
||
|
"event_queue" in wlan drivers, since all the queue/dequeue are handled
|
||
|
in non-isr context.
|
||
|
However, my guess is, someone always want to port these driver to fit different
|
||
|
OS platform. At that time, please always keep in mind all the possilbe racing
|
||
|
condition... That could be big disasters...
|
||
|
------------------------------------------------------------------------------*/
|
||
|
#if defined(CONFIG_RTL_KERNEL_MIPS16_WLAN) && defined(CONFIG_RTL8196C)
|
||
|
__NOMIPS16
|
||
|
#endif
|
||
|
int rtl8192cd_ioctl_priv_daemonreq(struct net_device *dev, struct iw_point *data)
|
||
|
{
|
||
|
int ret;
|
||
|
#ifndef WITHOUT_ENQUEUE
|
||
|
static UINT8 QueueData[MAXDATALEN];
|
||
|
int QueueDataLen;
|
||
|
#elif defined(CONFIG_RTL_WAPI_SUPPORT)
|
||
|
static UINT8 QueueData[MAXDATALEN];
|
||
|
int QueueDataLen;
|
||
|
#endif
|
||
|
UINT8 val8;
|
||
|
DOT11_REQUEST req;
|
||
|
struct rtl8192cd_priv *priv = GET_DEV_PRIV(dev);
|
||
|
|
||
|
#if defined(INCLUDE_WPA_PSK) || defined(WIFI_HAPD) || defined(RTK_NL80211)
|
||
|
memcpy((void *)&req, (void *)(data->pointer), sizeof(DOT11_REQUEST));
|
||
|
#else
|
||
|
if (copy_from_user((void *)&req, (void *)(data->pointer), sizeof(DOT11_REQUEST))) {
|
||
|
DEBUG_ERR("copy_from_user error!\n");
|
||
|
return -1;
|
||
|
}
|
||
|
#endif
|
||
|
#ifdef INCLUDE_WPS
|
||
|
DOT11_GETSET_MIB *getset_mib_t;
|
||
|
#endif
|
||
|
switch(req.EventId)
|
||
|
{
|
||
|
case DOT11_EVENT_NO_EVENT:
|
||
|
break;
|
||
|
|
||
|
#ifndef WITHOUT_ENQUEUE
|
||
|
case DOT11_EVENT_REQUEST:
|
||
|
if((ret = DOT11_DeQueue((unsigned long)priv, priv->pevent_queue, QueueData, &QueueDataLen)) != 0)
|
||
|
{
|
||
|
val8 = DOT11_EVENT_NO_EVENT;
|
||
|
if (copy_to_user((void *)((unsigned long)(data->pointer)), &val8, 1)) {
|
||
|
DEBUG_ERR("copy_to_user fail!\n");
|
||
|
return -1;
|
||
|
}
|
||
|
val8 = 0;
|
||
|
if (copy_to_user((void *)((unsigned long)(data->pointer) + 1), &val8, 1)) {
|
||
|
DEBUG_ERR("copy_to_user fail!\n");
|
||
|
return -1;
|
||
|
}
|
||
|
data->length = sizeof(DOT11_NO_EVENT);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
QueueData[1] = (priv->pevent_queue->NumItem != 0)? 1 : 0;
|
||
|
if (copy_to_user((void *)data->pointer, (void *)QueueData, QueueDataLen)) {
|
||
|
DEBUG_ERR("copy_to_user fail!\n");
|
||
|
return -1;
|
||
|
}
|
||
|
data->length = QueueDataLen;
|
||
|
}
|
||
|
break;
|
||
|
#ifdef INCLUDE_WPS
|
||
|
case DOT11_EVENT_REQUEST_F_INCLUDE_WPS:
|
||
|
if((ret = DOT11_DeQueue((unsigned long)priv, priv->pevent_queue, QueueData, &QueueDataLen)) != 0)
|
||
|
{
|
||
|
val8 = DOT11_EVENT_NO_EVENT;
|
||
|
memcpy((void *)((unsigned long)(data->pointer)), &val8, 1);
|
||
|
|
||
|
val8 = 0;
|
||
|
memcpy((void *)((unsigned long)(data->pointer) + 1), &val8, 1);
|
||
|
data->length = sizeof(DOT11_NO_EVENT);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
QueueData[1] = (priv->pevent_queue->NumItem != 0)? 1 : 0;
|
||
|
memcpy((void *)data->pointer, (void *)QueueData, QueueDataLen);
|
||
|
data->length = QueueDataLen;
|
||
|
//DEBUG_INFO("%d de-queue ; pMsg=%s\n", __LINE__ , (char *)data->pointer);
|
||
|
}
|
||
|
break;
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
case DOT11_EVENT_ASSOCIATION_RSP:
|
||
|
if(!DOT11_Process_Association_Rsp(dev, data, WIFI_ASSOCRSP))
|
||
|
{}
|
||
|
break;
|
||
|
|
||
|
case DOT11_EVENT_DISCONNECT_REQ:
|
||
|
if(!DOT11_Process_Disconnect_Req(dev, data))
|
||
|
{}
|
||
|
break;
|
||
|
|
||
|
case DOT11_EVENT_SET_802DOT11:
|
||
|
break;
|
||
|
|
||
|
case DOT11_EVENT_SET_KEY:
|
||
|
#if defined(CONFIG_PCI_HCI)
|
||
|
if(!DOT11_Process_Set_Key(dev, data, NULL, NULL))
|
||
|
{}
|
||
|
#elif defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI)
|
||
|
notify_set_key(dev, (DOT11_SET_KEY *)data->pointer, NULL);
|
||
|
#endif
|
||
|
break;
|
||
|
|
||
|
case DOT11_EVENT_SET_PORT:
|
||
|
if(!DOT11_Process_Set_Port(dev, data))
|
||
|
{}
|
||
|
break;
|
||
|
|
||
|
case DOT11_EVENT_DELETE_KEY:
|
||
|
if(!DOT11_Process_Delete_Key(dev, data))
|
||
|
{}
|
||
|
break;
|
||
|
|
||
|
case DOT11_EVENT_SET_RSNIE:
|
||
|
if(priv->pmib->dot1180211AuthEntry.dot11PrivacyAlgrthm != _NO_PRIVACY_ &&
|
||
|
priv->pmib->dot1180211AuthEntry.dot11PrivacyAlgrthm != _WEP_40_PRIVACY_ &&
|
||
|
priv->pmib->dot1180211AuthEntry.dot11PrivacyAlgrthm != _WEP_104_PRIVACY_)
|
||
|
if(!DOT11_Process_Set_RSNIE(dev, data))
|
||
|
{}
|
||
|
break;
|
||
|
|
||
|
case DOT11_EVENT_GKEY_TSC:
|
||
|
if(!DOT11_Process_QueryRSC(dev, data))
|
||
|
{}
|
||
|
break;
|
||
|
|
||
|
case DOT11_EVENT_MIC_FAILURE:
|
||
|
if(!DOT11_Porcess_EAPOL_MICReport(dev, data))
|
||
|
{}
|
||
|
break;
|
||
|
|
||
|
case DOT11_EVENT_ASSOCIATION_INFO:
|
||
|
#if 0
|
||
|
if(!DOT11_Process_Association_Info(dev, data))
|
||
|
{}
|
||
|
#endif
|
||
|
DEBUG_INFO("trying to process assoc info\n");
|
||
|
break;
|
||
|
|
||
|
case DOT11_EVENT_INIT_QUEUE:
|
||
|
DOT11_InitQueue(priv->pevent_queue);
|
||
|
break;
|
||
|
|
||
|
case DOT11_EVENT_ACC_SET_EXPIREDTIME:
|
||
|
#ifdef RADIUS_ACCOUNTING
|
||
|
DOT11_Process_Acc_SetExpiredTime(dev, data);
|
||
|
#endif
|
||
|
DEBUG_INFO("trying to Set ACC Expiredtime\n");
|
||
|
break;
|
||
|
|
||
|
case DOT11_EVENT_ACC_QUERY_STATS:
|
||
|
#ifdef RADIUS_ACCOUNTING
|
||
|
DOT11_Process_Acc_QueryStats(dev, data);
|
||
|
#endif
|
||
|
DEBUG_INFO("trying to Set ACC Expiredtime\n");
|
||
|
break;
|
||
|
|
||
|
case DOT11_EVENT_REASSOCIATION_RSP:
|
||
|
if(!DOT11_Process_Association_Rsp(dev, data, WIFI_REASSOCRSP))
|
||
|
{}
|
||
|
break;
|
||
|
|
||
|
case DOT11_EVENT_STA_QUERY_BSSID:
|
||
|
if(!DOT11_Process_STA_Query_Bssid(dev, data))
|
||
|
{};
|
||
|
break;
|
||
|
|
||
|
case DOT11_EVENT_STA_QUERY_SSID:
|
||
|
if(!DOT11_Process_STA_Query_Ssid(dev, data))
|
||
|
{};
|
||
|
break;
|
||
|
|
||
|
#ifdef WIFI_SIMPLE_CONFIG
|
||
|
case DOT11_EVENT_WSC_SET_IE:
|
||
|
if(!DOT11_WSC_set_ie(dev, data))
|
||
|
{};
|
||
|
break;
|
||
|
|
||
|
#ifdef INCLUDE_WPS
|
||
|
#ifndef CONFIG_MSC
|
||
|
// procress ioctl request from upnp
|
||
|
|
||
|
case DOT11_EVENT_WSC_SOAP:{
|
||
|
CTX_Tp tmp = &(priv->pshare->WSC_CONT_S);
|
||
|
DOT11_WSC_SOAP *soap_evt; //chris 0328
|
||
|
DOT11_EAP_PACKET *upnp_pkt; //chris 0328
|
||
|
struct soap_t *soap_pkt; //chris 0328
|
||
|
|
||
|
soap_evt = (DOT11_WSC_SOAP *) kmalloc(sizeof(DOT11_WSC_SOAP), GFP_ATOMIC);
|
||
|
upnp_pkt = (DOT11_EAP_PACKET *) kmalloc(sizeof(DOT11_EAP_PACKET), GFP_ATOMIC);
|
||
|
soap_pkt = (struct soap_t *) kmalloc(sizeof(struct soap_t), GFP_ATOMIC);
|
||
|
|
||
|
memset(soap_evt, 0, sizeof(DOT11_WSC_SOAP));
|
||
|
memset(upnp_pkt, 0, sizeof(DOT11_EAP_PACKET));
|
||
|
memset(soap_pkt, 0, sizeof(struct soap_t));
|
||
|
|
||
|
if (copy_from_user((void *)soap_evt, (void *)(data->pointer), sizeof(DOT11_WSC_SOAP))) {
|
||
|
//DEBUG_ERR("copy_from_user error!\n");
|
||
|
printk("copy_from_user error!\n");
|
||
|
kfree(soap_evt);
|
||
|
kfree(upnp_pkt);
|
||
|
kfree(soap_pkt);
|
||
|
return -1;
|
||
|
}
|
||
|
memcpy(soap_pkt->EventMac, soap_evt->packet.EventMac, MACLEN);
|
||
|
memcpy(soap_pkt->IP, soap_evt->packet.IP, IP_ADDRLEN);
|
||
|
memcpy(soap_pkt->packet, soap_evt->packet.buffer, soap_evt->packet.size);
|
||
|
soap_pkt->length = soap_evt->packet.size;
|
||
|
|
||
|
if( soap_evt->packet.EventID == WSC_GETDEVINFO ){
|
||
|
upnp_pkt->EventId = DOT11_EVENT_WSC_GETDEVINFO;
|
||
|
tmp->wps_profile.soap_mathods.upnpGetDeviceInfoHandler(soap_pkt);
|
||
|
printk("%s %d ; call upnpGetDeviceInfoHandler\n",__FUNCTION__,__LINE__);
|
||
|
}else if ( soap_evt->packet.EventID == WSC_M2M4M6M8 ) {
|
||
|
upnp_pkt->EventId = DOT11_EVENT_WSC_M2M4M6M8;
|
||
|
tmp->wps_profile.soap_mathods.upnpPutMessageHandler(soap_pkt);
|
||
|
}else if ( soap_evt->packet.EventID == WSC_SETSELECTEDREGISTRA ) {
|
||
|
upnp_pkt->EventId = DOT11_EVENT_WSC_PUTMESSAGE;
|
||
|
tmp->wps_profile.soap_mathods.upnpSelectedRegistrarHandler(soap_pkt);
|
||
|
}else if ( soap_evt->packet.EventID == WSC_PUTWLANRESPONSE ) {
|
||
|
upnp_pkt->EventId = DOT11_EVENT_WSC_PUTWLANRESPONSE;
|
||
|
tmp->wps_profile.soap_mathods.upnpWlanResponseHandler(soap_pkt);
|
||
|
}
|
||
|
|
||
|
upnp_pkt->IsMoreEvent = FALSE;
|
||
|
/*
|
||
|
if( packet.tx_size < MAX_MSG_SIZE ){
|
||
|
upnp_packet.packet_len = packet.tx_size;
|
||
|
memcpy(upnp_packet.packet, packet.tx_buffer, packet.tx_size);
|
||
|
} else {
|
||
|
upnp_packet.packet_len = 0;
|
||
|
}*/
|
||
|
if( soap_pkt->length > 0 && soap_pkt->length < MAX_MSG_SIZE ){
|
||
|
upnp_pkt->packet_len = soap_pkt->length;
|
||
|
memcpy(upnp_pkt->packet, soap_pkt->packet, soap_pkt->length);
|
||
|
} else {
|
||
|
upnp_pkt->packet_len = 0;
|
||
|
}
|
||
|
|
||
|
printk("Rx ; En-Queue UPnP Packet %s %d \n",__FUNCTION__ , __LINE__);
|
||
|
wsc_debug_out(">>>>>>>>>>>>>upnp_packet", upnp_pkt, sizeof(DOT11_EAP_PACKET));
|
||
|
DOT11_EnQueue((unsigned long)priv, priv->pevent_queue, (unsigned char*)upnp_pkt, sizeof(DOT11_EAP_PACKET));
|
||
|
event_indicate(priv, NULL, -1);
|
||
|
|
||
|
kfree(soap_evt);
|
||
|
kfree(upnp_pkt);
|
||
|
kfree(soap_pkt);
|
||
|
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case DOT11_EVENT_WSC_PIN:{
|
||
|
CTX_Tp tmp = &(priv->pshare->WSC_CONT_S);
|
||
|
DOT11_WSC_METHOD wps_pin;
|
||
|
if (copy_from_user((void *)&wps_pin, (void *)(data->pointer), sizeof(DOT11_WSC_PIN_IND))) {
|
||
|
//DEBUG_ERR("copy_from_user error!\n");
|
||
|
printk("copy_from_user error!\n");
|
||
|
return -1;
|
||
|
}
|
||
|
tmp->start = 3;
|
||
|
memcpy(tmp->peer_pin_code, wps_pin.code, PIN_LEN);
|
||
|
//evHandler_pin_input(wps_pin.code);
|
||
|
printk("PIN method invoked (from wscd)\n");
|
||
|
}
|
||
|
break;
|
||
|
case DOT11_EVENT_WSC_PBC:{
|
||
|
CTX_Tp tmp = &(priv->pshare->WSC_CONT_S);
|
||
|
tmp->start = 2;
|
||
|
//evHandler_pb_press();
|
||
|
printk("PBC method invoked from wscd\n");
|
||
|
}
|
||
|
break;
|
||
|
case DOT11_EVENT_WSC_PUTCONF:{
|
||
|
DOT11_WSC_GETCONF wps_getconf;
|
||
|
CTX_Tp tmp = &(priv->pshare->WSC_CONT_S);
|
||
|
memset(&wps_getconf,0,sizeof(DOT11_WSC_GETCONF));
|
||
|
WSC_CONFp wps_config = &(wps_getconf.config);
|
||
|
if (copy_from_user((void *)&wps_getconf, (void *)(data->pointer), sizeof(WSC_CONF))) {
|
||
|
DEBUG_ERR("copy_from_user error!\n");
|
||
|
return -1;
|
||
|
}
|
||
|
/*
|
||
|
for verify ,wscd-deamon will report config-info at WSC_CONF
|
||
|
call to kernel-mode-wps , receive_config_setting();
|
||
|
|
||
|
in sercomm case , will not via here,sercomm will direct call wps_start()
|
||
|
*/
|
||
|
printk("[wlan ioctl]:receive \"DOT11_EVENT_WSC_PUTCONF\" from wscd \n");
|
||
|
//receive_config_setting(priv , wps_config);
|
||
|
read_config_file(tmp, DEFAULT_CONFIG_FILENAME);
|
||
|
}
|
||
|
break;
|
||
|
case DOT11_EVENT_WSC_PROXY_ON: {
|
||
|
printk("[%s] switch proxy on\n",__FUNCTION__);
|
||
|
priv->pshare->WSC_CONT_S.TotalSubscriptions = 1;
|
||
|
}
|
||
|
break;
|
||
|
case DOT11_EVENT_WSC_PROXY_OFF: {
|
||
|
printk("[%s] switch proxy off\n",__FUNCTION__);
|
||
|
priv->pshare->WSC_CONT_S.TotalSubscriptions = 0;
|
||
|
}
|
||
|
break;
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
#ifdef INCLUDE_WPS
|
||
|
case DOT11_EVENT_WSC_SET_MIB:
|
||
|
|
||
|
getset_mib_t = (DOT11_GETSET_MIB *)data->pointer;
|
||
|
set_mib(dev->priv, getset_mib_t->cmd);
|
||
|
break;
|
||
|
|
||
|
case DOT11_EVENT_WSC_GET_MIB:
|
||
|
getset_mib_t = (DOT11_GETSET_MIB*)data->pointer;
|
||
|
get_mib(dev->priv, getset_mib_t->cmd);
|
||
|
break;
|
||
|
#endif
|
||
|
#endif //WIFI_SIMPLE_CONFIG
|
||
|
|
||
|
#ifdef CONFIG_RTL_WAPI_SUPPORT
|
||
|
case DOT11_EVENT_WAPI_INIT_QUEUE:
|
||
|
DOT11_InitQueue(priv->wapiEvent_queue);
|
||
|
break;
|
||
|
case DOT11_EVENT_WAPI_READ_QUEUE:
|
||
|
if((ret = DOT11_DeQueue((unsigned long)priv, priv->wapiEvent_queue, QueueData, &QueueDataLen)) != 0)
|
||
|
{
|
||
|
val8 = DOT11_EVENT_NO_EVENT;
|
||
|
if (copy_to_user((void *)((unsigned long)(data->pointer)), &val8, 1)) {
|
||
|
DEBUG_ERR("copy_to_user fail!\n");
|
||
|
return -1;
|
||
|
}
|
||
|
val8 = 0;
|
||
|
if (copy_to_user((void *)((unsigned long)(data->pointer) + 1), &val8, 1)) {
|
||
|
DEBUG_ERR("copy_to_user fail!\n");
|
||
|
return -1;
|
||
|
}
|
||
|
data->length = sizeof(DOT11_NO_EVENT);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
QueueData[1] = (priv->wapiEvent_queue->NumItem != 0)? 1 : 0;
|
||
|
if (copy_to_user((void *)data->pointer, (void *)QueueData, QueueDataLen)) {
|
||
|
DEBUG_ERR("copy_to_user fail!\n");
|
||
|
return -1;
|
||
|
}
|
||
|
data->length = QueueDataLen;
|
||
|
}
|
||
|
break;
|
||
|
case DOT11_EVENT_WAPI_WRITE_QUEUE:
|
||
|
{
|
||
|
unsigned char *kernelbuf;
|
||
|
kernelbuf = (unsigned char *)kmalloc(data->length,GFP_ATOMIC);
|
||
|
if(NULL == kernelbuf)
|
||
|
{
|
||
|
DEBUG_ERR("Memory alloc fail!\n");
|
||
|
return -1;
|
||
|
}
|
||
|
if (copy_from_user((void *)kernelbuf, (void *)(data->pointer), data->length)) {
|
||
|
DEBUG_ERR("copy_from_user error!\n");
|
||
|
kfree(kernelbuf);
|
||
|
return -1;
|
||
|
}
|
||
|
DOT11_Process_WAPI_Info(priv,kernelbuf,data->length);
|
||
|
kfree(kernelbuf);
|
||
|
}
|
||
|
break;
|
||
|
#endif
|
||
|
#ifdef HS2_SUPPORT
|
||
|
/* Hotsport 2.0 Release 1 */
|
||
|
case DOT11_EVENT_HS2_SET_IE:
|
||
|
if(!DOT11_HS2_set_ie(dev, data)) {};
|
||
|
break;
|
||
|
case DOT11_EVENT_HS2_GET_TSF:
|
||
|
{
|
||
|
unsigned long long tsf;
|
||
|
unsigned long tsf_sec;
|
||
|
tsf = RTL_R32(TSFTR+4);
|
||
|
tsf = (tsf<<32) + RTL_R32(TSFTR);
|
||
|
tsf_sec = (unsigned long)tsf/1000000;
|
||
|
if (copy_to_user((void *)(data->pointer), &tsf_sec, sizeof(unsigned long)))
|
||
|
{
|
||
|
HS2_DEBUG_ERR("copy_to_user fail!\n");
|
||
|
return -1;
|
||
|
}
|
||
|
data->length = sizeof(unsigned long);
|
||
|
}
|
||
|
break;
|
||
|
case DOT11_EVENT_HS2_GAS_RSP:
|
||
|
issue_GASrsp(priv, data->pointer);
|
||
|
break;
|
||
|
case DOT11_EVENT_HS2_TSM_REQ:
|
||
|
issue_BSS_TSM_req(priv, data->pointer);
|
||
|
break;
|
||
|
case DOT11_EVENT_HS2_GET_RSN:
|
||
|
{
|
||
|
struct wifi_mib *pmib;
|
||
|
pmib = GET_MIB(priv);
|
||
|
if (pmib->dot11RsnIE.rsnielen) {
|
||
|
if (copy_to_user((void *)(data->pointer), pmib->dot11RsnIE.rsnie, pmib->dot11RsnIE.rsnielen))
|
||
|
{
|
||
|
HS2_DEBUG_ERR("copy_to_user fail!\n");
|
||
|
return -1;
|
||
|
}
|
||
|
data->length = pmib->dot11RsnIE.rsnielen;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
case DOT11_EVENT_HS2_GET_MMPDULIMIT:
|
||
|
{
|
||
|
struct wifi_mib *pmib;
|
||
|
pmib = GET_MIB(priv);
|
||
|
if (copy_to_user((void *)(data->pointer), (void *)(&pmib->hs2Entry.mmpdu_limit), sizeof(unsigned int)))
|
||
|
{
|
||
|
HS2_DEBUG_ERR("copy_to_user fail!\n");
|
||
|
return -1;
|
||
|
}
|
||
|
data->length = sizeof(unsigned int);
|
||
|
}
|
||
|
break;
|
||
|
#endif // HS2_SUPPORT
|
||
|
#ifdef CONFIG_IEEE80211W
|
||
|
/*HS2 R2 logo test*/
|
||
|
case DOT11_EVENT_INIT_PMF:
|
||
|
{
|
||
|
int i;
|
||
|
DOT11_INIT_11W_Flags flags;
|
||
|
if (copy_from_user((void *)(&flags),(void *)(data->pointer), data->length))
|
||
|
{
|
||
|
PMFDEBUG("copy_from_user fail!\n");
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
PMFDEBUG("init pmf:11W[%d],SHA256[%d]\n",flags.dot11IEEE80211W, flags.dot11EnableSHA256);
|
||
|
|
||
|
priv->pmib->dot1180211AuthEntry.dot11IEEE80211W = flags.dot11IEEE80211W;
|
||
|
priv->pmib->dot1180211AuthEntry.dot11EnableSHA256 = flags.dot11EnableSHA256;
|
||
|
|
||
|
if(priv->pmib->dot1180211AuthEntry.dot11IEEE80211W == 0 && priv->pmib->dot1180211AuthEntry.dot11EnableSHA256) {
|
||
|
priv->pmib->dot1180211AuthEntry.dot11EnableSHA256 = 0;
|
||
|
panic_printk("disable SHA256 when PMF is disable\n");
|
||
|
}
|
||
|
}
|
||
|
case DOT11_EVENT_SET_PMF:
|
||
|
if(!DOT11_PMF_set_ie(dev, data))
|
||
|
{}
|
||
|
break;
|
||
|
case DOT11_EVENT_GET_IGTK_PN:
|
||
|
{
|
||
|
struct wifi_mib *pmib;
|
||
|
int i;
|
||
|
unsigned char *tt;
|
||
|
pmib = GET_MIB(priv);
|
||
|
|
||
|
#ifdef PMF_DEBUGMSG
|
||
|
PMFDEBUG("get IGTK_PN:");
|
||
|
tt = (unsigned char *) & pmib->dot11IGTKTable.dot11EncryptKey.dot11TXPN48;
|
||
|
for (i=0;i<sizeof(unsigned long long);i++){
|
||
|
panic_printk("%02X ",tt[i]);
|
||
|
}
|
||
|
panic_printk("\n");
|
||
|
#if 0
|
||
|
PMFDEBUG("dot11TXPN48.val48=%x %x %x %x %x %x\n",pmib->dot11IGTKTable.dot11EncryptKey.dot11TXPN48._byte_.TSC0
|
||
|
,pmib->dot11IGTKTable.dot11EncryptKey.dot11TXPN48._byte_.TSC1
|
||
|
,pmib->dot11IGTKTable.dot11EncryptKey.dot11TXPN48._byte_.TSC2
|
||
|
,pmib->dot11IGTKTable.dot11EncryptKey.dot11TXPN48._byte_.TSC3
|
||
|
,pmib->dot11IGTKTable.dot11EncryptKey.dot11TXPN48._byte_.TSC4
|
||
|
,pmib->dot11IGTKTable.dot11EncryptKey.dot11TXPN48._byte_.TSC5);
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
if (copy_to_user((void *)(data->pointer), (void *) (&pmib->dot11IGTKTable.dot11EncryptKey.dot11TXPN48.val48), sizeof(pmib->dot11IGTKTable.dot11EncryptKey.dot11TXPN48.val48)))
|
||
|
{
|
||
|
DEBUG_ERR("copy_to_user fail!\n");
|
||
|
return -1;
|
||
|
}
|
||
|
data->length = sizeof(pmib->dot11IGTKTable.dot11EncryptKey.dot11TXPN48.val48);
|
||
|
}
|
||
|
break;
|
||
|
case DOT11_EVENT_SA_QUERY_RSP:
|
||
|
{
|
||
|
DOT11_SA_QUERY_RSP resp;
|
||
|
if (copy_from_user((void *)(&resp),(void *)(data->pointer), data->length))
|
||
|
{
|
||
|
DEBUG_ERR("copy_from_user fail!\n");
|
||
|
return -1;
|
||
|
}
|
||
|
issue_SA_Query_Rsp(dev, resp.MACAddr, resp.trans_id);
|
||
|
}
|
||
|
break;
|
||
|
#endif // CONFIG_IEEE80211W
|
||
|
#ifdef USER_ADDIE
|
||
|
case DOT11_EVENT_USER_SETIE:
|
||
|
{
|
||
|
if(DOT11_USER_set_ie(dev, data) < 0) {
|
||
|
DEBUG_ERR("DOT11_USER_set_ie failed\n");
|
||
|
return -1;
|
||
|
};
|
||
|
}
|
||
|
break;
|
||
|
#endif
|
||
|
|
||
|
default:
|
||
|
DEBUG_ERR("unknown user daemon command\n");
|
||
|
break;
|
||
|
} // switch(req->EventId)
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|