2308 lines
49 KiB
C
2308 lines
49 KiB
C
/*
|
|
******************************************************************************
|
|
* INTERPEAK SOURCE FILE
|
|
*
|
|
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipwlan_atheros.c,v $ $Revision: 1.12.16.2 $
|
|
* $Source: /home/interpeak/CVSRoot/ipwlan/src/ipwlan_atheros.c,v $
|
|
* $Author: hxu4 $
|
|
* $State: Exp $ $: $
|
|
*
|
|
* INTERPEAK_COPYRIGHT_STRING
|
|
* Design and implementation by Markus Carlstedt <markus@interpeak.se>
|
|
******************************************************************************
|
|
*/
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 1 DESCRIPTION
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 2 CONFIGURATION
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 3 INCLUDE FILES
|
|
****************************************************************************
|
|
*/
|
|
|
|
#define IPCOM_USE_CLIB_PROTO
|
|
#include <ipcom_type.h>
|
|
#include <ipcom_cstyle.h>
|
|
#include <ipcom_err.h>
|
|
#include <ipcom_sock.h>
|
|
#include <ipcom_clib.h>
|
|
#include <ipcom_syslog.h>
|
|
#include <ipcom_errno.h>
|
|
#include <ipcom_sysvar.h>
|
|
#include <ipcom_os.h>
|
|
#include <ipcom_time.h>
|
|
#include <ipcom_netif.h>
|
|
#include <ipwlan_wlan.h>
|
|
#include <ipwlan_atheros.h>
|
|
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 4 DEFINES
|
|
****************************************************************************
|
|
*/
|
|
|
|
#ifdef IPCOM_SYSLOG_FACILITY
|
|
#undef IPCOM_SYSLOG_FACILITY
|
|
#endif
|
|
#define IPCOM_SYSLOG_FACILITY IPCOM_LOG_WLAN
|
|
|
|
#ifdef IPCOM_SYSLOG_PRIORITY
|
|
#undef IPCOM_SYSLOG_PRIORITY
|
|
#endif
|
|
|
|
#if defined(_WRS_CONFIG_IPWLAN_SYSLOG_PRIORITY)
|
|
#define IPCOM_SYSLOG_PRIORITY _WRS_CONFIG_IPWLAN_SYSLOG_PRIORITY
|
|
#else
|
|
#define IPCOM_SYSLOG_PRIORITY IPCOM_LOG_WARNING
|
|
#endif
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 5 TYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 6 EXTERN PROTOTYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
#ifndef IP_PORT_LKM
|
|
IP_GLOBAL int ipwlan_atheros_boot(void);
|
|
#endif
|
|
|
|
IP_EXTERN int dot11Ioctl(char *, int, void *);
|
|
IP_EXTERN int dot11DebugLevelGet(int);
|
|
IP_EXTERN int dot11DebugLevelSet(int,int);
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 7 LOCAL PROTOTYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
IP_PUBLIC const char *ipwlan_atheros_version(void);
|
|
IP_PUBLIC Ip_err ipwlan_atheros_start(void);
|
|
IP_PUBLIC Ip_err ipwlan_atheros_create(void);
|
|
IP_PUBLIC int ipwlan_atheros_cmd_broadcom(int argc, char **argv);
|
|
IP_PUBLIC int ipwlan_atheros_ioctl_if(void *mux_cookie, Ip_u32 cmd, Ipcom_iwreq *iw);
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 8 DATA
|
|
****************************************************************************
|
|
*/
|
|
|
|
/* Convert between a channel and the corresponding 802.11b/g frequency */
|
|
IP_CONST int ipwlan_atheros_freq[] = { 2412000, 2417000, 2422000, 2427000, 2432000, 2437000, 2442000,
|
|
2447000, 2452000, 2457000, 2462000, 2467000, 2472000, 2484000 };
|
|
|
|
IP_CONST Ipcom_iw_debug_level ipwlan_atheros_debuglevels[] = {
|
|
{ATH_DBG_ALL_NONE, "all|none"},
|
|
{ATH_DBG_ALL_ALL, "all|all"},
|
|
{ATH_DBG_ALL_INFO, "all|info"},
|
|
{ATH_DBG_ALL_ERROR, "all|error"},
|
|
{ATH_DBG_ALL_FATAL, "all|fatal"},
|
|
{ATH_DBG_INIT_NONE, "init|none"},
|
|
{ATH_DBG_INIT_ALL, "init|all"},
|
|
{ATH_DBG_INIT_INFO, "init|info"},
|
|
{ATH_DBG_INIT_ERROR, "init|error"},
|
|
{ATH_DBG_INIT_FATAL, "init|fatal"},
|
|
{ATH_DBG_STATE_NONE, "state|none"},
|
|
{ATH_DBG_STATE_ALL, "state|all"},
|
|
{ATH_DBG_STATE_INFO, "state|info"},
|
|
{ATH_DBG_STATE_ERROR, "state|error"},
|
|
{ATH_DBG_STATE_FATAL, "state|fatal"},
|
|
{ATH_DBG_DATA_NONE, "datapath|none"},
|
|
{ATH_DBG_DATA_ALL, "datapath|all"},
|
|
{ATH_DBG_DATA_INFO, "datapath|info"},
|
|
{ATH_DBG_DATA_ERROR, "datapath|error"},
|
|
{ATH_DBG_DATA_FATAL, "datapath|fatal"},
|
|
{ATH_DBG_HW_NONE, "hardware|none"},
|
|
{ATH_DBG_HW_ALL, "hardware|all"},
|
|
{ATH_DBG_HW_INFO, "hardware|info"},
|
|
{ATH_DBG_HW_ERROR, "hardware|error"},
|
|
{ATH_DBG_HW_FATAL, "hardware|fatal"},
|
|
{ATH_DBG_ISR_NONE, "isr|none"},
|
|
{ATH_DBG_ISR_ALL, "isr|all"},
|
|
{ATH_DBG_ISR_INFO, "isr|info"},
|
|
{ATH_DBG_ISR_ERROR, "isr|error"},
|
|
{ATH_DBG_ISR_FATAL, "isr|fatal"},
|
|
{0, IP_NULL}
|
|
};
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 9 STATIC FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipwlan_atheros_set_debug_level
|
|
*===========================================================================
|
|
* Description: Sets debug level in atheros driver
|
|
* Parameters: 'value' ==> gets converted to appropriate driver area/level
|
|
* Returns: 0
|
|
*/
|
|
IP_STATIC int
|
|
ipwlan_atheros_set_debug_level(Ip_u32 value)
|
|
{
|
|
int area = -1;
|
|
int level = -1;
|
|
int ret = 0;
|
|
|
|
if (value & ATH_DBG_INIT_NONE)
|
|
{
|
|
area = DOT11_AREA_INIT;
|
|
level = (value & ~ATH_DBG_INIT_NONE) >> ATH_DBG_INIT_SHIFT;
|
|
}
|
|
else if (value & ATH_DBG_STATE_NONE)
|
|
{
|
|
area = DOT11_AREA_SME;
|
|
level = (value & ~ATH_DBG_STATE_NONE) >> ATH_DBG_STATE_SHIFT;
|
|
}
|
|
else if (value & ATH_DBG_DATA_NONE)
|
|
{
|
|
area = DOT11_AREA_DPE;
|
|
level = (value & ~ATH_DBG_DATA_NONE) >> ATH_DBG_DATA_SHIFT;
|
|
}
|
|
else if (value & ATH_DBG_HW_NONE)
|
|
{
|
|
area = DOT11_AREA_HDD;
|
|
level = (value & ~ATH_DBG_HW_NONE) >> ATH_DBG_HW_SHIFT;
|
|
}
|
|
else if (value & ATH_DBG_ISR_NONE)
|
|
{
|
|
area = DOT11_AREA_INT;
|
|
level = (value & ~ATH_DBG_ISR_NONE) >> ATH_DBG_ISR_SHIFT;
|
|
}
|
|
else
|
|
{
|
|
area = DOT11_AREA_ALL;
|
|
level = (value & ~ATH_DBG_ALL_NONE) >> ATH_DBG_ALL_SHIFT;
|
|
}
|
|
|
|
ret = dot11DebugLevelSet(area,level);
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipwlan_atheros_make_statistic
|
|
*===========================================================================
|
|
* Description: Sets debug level in atheros driver
|
|
* Parameters: 'value' ==> gets converted to appropriate driver area/level
|
|
* Returns: 0
|
|
*/
|
|
|
|
IP_STATIC char*
|
|
ipwlan_atheros_make_statistic(Ip_u64 value,char *description,char *destination)
|
|
{
|
|
Ipcom_iw_statistic stat;
|
|
|
|
ipcom_memset(&stat, 0, sizeof(stat));
|
|
|
|
stat.value = value;
|
|
stat.description = description;
|
|
ipcom_memcpy(destination,&stat,sizeof(Ipcom_iw_statistic));
|
|
destination += sizeof(Ipcom_iw_statistic);
|
|
|
|
return destination;
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipwlan_atheros_parse_key
|
|
*===========================================================================
|
|
* Description: Parse 64 hex-character wpa/wpa2 key into 32 byte binary
|
|
* equivalent
|
|
* Parameters: 'key_string' ==> gets converted into 32 byte key_data
|
|
* Returns: length of key
|
|
*/
|
|
IP_STATIC Ip_u32
|
|
ipwlan_atheros_parse_key(Ip_u8 *key_data, char *key_string)
|
|
{
|
|
int j;
|
|
int k;
|
|
|
|
if (ipcom_strspn(key_string, "0123456789ABCDEFabcdef") != ipcom_strlen(key_string) ||
|
|
ipcom_strlen(key_string) > IP_IW_KEY_WPA_LEN)
|
|
{
|
|
return 0;
|
|
}
|
|
for (j = 0; ipcom_sscanf(key_string + 2 * j, "%2x", &k), j < IP_IW_KEY_WPA_LEN; j++)
|
|
{
|
|
key_data[j] = (unsigned char)k;
|
|
}
|
|
|
|
return j;
|
|
}
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 10 GLOBAL FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 11 PUBLIC FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipwlan_atheros_create
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*/
|
|
IP_PUBLIC Ip_err
|
|
ipwlan_atheros_create(void)
|
|
{
|
|
return IPCOM_SUCCESS;
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipwlan_atheros_start
|
|
*===========================================================================
|
|
* Description: Configure ipwlan_atheros according to the configuration defined in
|
|
* 'ipwlan_atheros_config'
|
|
* Parameters:
|
|
* Returns:
|
|
*/
|
|
IP_PUBLIC Ip_err
|
|
ipwlan_atheros_start(void)
|
|
{
|
|
#ifndef IP_PORT_LKM
|
|
return ipwlan_atheros_boot();
|
|
#else
|
|
return IPCOM_SUCCESS;
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipwlan_atheros_version
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_PUBLIC const char *
|
|
ipwlan_atheros_version(void)
|
|
{
|
|
return "@(#) IPWLAN_ATHEROS $Name: VXWORKS_ITER40_2019102207 $ - INTERPEAK_COPYRIGHT_STRING";
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipwlan_atheros_ioctl_if
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*/
|
|
IP_PUBLIC int
|
|
ipwlan_atheros_ioctl_if(void *mux_cookie, Ip_u32 cmd, Ipcom_iwreq *iw)
|
|
{
|
|
Ip_u32 i;
|
|
Ip_u32 j;
|
|
Ip_u32 k;
|
|
int ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
Ip_u32 value = 0;
|
|
Ip_u32 scan_ap_len;
|
|
Ip_u32 scan_len_left;
|
|
Ip_u8 *scan_data;
|
|
Ip_u16 vlan;
|
|
char *data;
|
|
Ipcom_iw_event iwe;
|
|
DOT11_SSID ssid;
|
|
DOT11_SCAN_REQ req;
|
|
DOT11_SCAN_RESULTS* res;
|
|
DOT11_ACL* acl;
|
|
DOT11_RATES rates;
|
|
DOT11_CHANNEL_LIST chanList;
|
|
DOT11_KEY key;
|
|
DOT11_4WAYHSSTATE fourway_handshake;
|
|
DOT11_DEAUTH_REQ deauth_req;
|
|
DOT11_CALLBACK_PARAMS dot11_cb;
|
|
DOT11_STATS stats;
|
|
END_VLAN_REQ pVlanReq;
|
|
Ip_u32 acl_ap_len;
|
|
Ip_u32 acl_len_left;
|
|
Ip_u8 *acl_data;
|
|
Ip_u8 macAddr[DOT11_ADDR_LEN];
|
|
Ip_u8 psk[DOT11_PSK_LEN];
|
|
res = (DOT11_SCAN_RESULTS*)ipcom_malloc(sizeof(DOT11_SCAN_RESULTS)*DOT11_MAX_SCANRESULTS);
|
|
if(res == IP_NULL)
|
|
{
|
|
return IPWLAN_ATHEROS_ERR_FAILED;
|
|
}
|
|
acl = (DOT11_ACL*)ipcom_malloc(sizeof(DOT11_ACL)*DOT11_KSL_MAX_HASH);
|
|
if(acl == IP_NULL)
|
|
{
|
|
ipcom_free(res);
|
|
return IPWLAN_ATHEROS_ERR_FAILED;
|
|
}
|
|
switch (cmd)
|
|
{
|
|
case IP_SIOCIWFIRSTPRIV:
|
|
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
|
|
#ifndef IP_PORT_LKM
|
|
case IP_SIOCSIWATTACHFUNC:
|
|
|
|
ret = 0;
|
|
break;
|
|
|
|
case IP_SIOCSIWREMOVEFUNC:
|
|
|
|
ret = 0;
|
|
break;
|
|
#endif /* IP_PORT_LKM */
|
|
|
|
case IP_SIOCSIWMODE:
|
|
|
|
if (iw->u.mode == IP_IW_MODE_AUTO)
|
|
{
|
|
value = DOT11_MODE_NONE;
|
|
}
|
|
else if (iw->u.mode == IP_IW_MODE_MASTER)
|
|
{
|
|
value = DOT11_MODE_AP;
|
|
}
|
|
else if (iw->u.mode == IP_IW_MODE_INFRA)
|
|
{
|
|
value = DOT11_MODE_ESS;
|
|
}
|
|
else if (iw->u.mode == IP_IW_MODE_ADHOC)
|
|
{
|
|
value = DOT11_MODE_IBSS;
|
|
}
|
|
else
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCSDOT11MODE, (Ip_u32 *)value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
case IP_SIOCGIWMODE:
|
|
|
|
ipcom_memset(&value, 0, sizeof(value));
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCGDOT11MODE, &value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
if (value == DOT11_MODE_NONE)
|
|
{
|
|
iw->u.mode = IP_IW_MODE_AUTO;
|
|
}
|
|
else if (value == DOT11_MODE_AP)
|
|
{
|
|
iw->u.mode = IP_IW_MODE_MASTER;
|
|
}
|
|
else if (value == DOT11_MODE_ESS)
|
|
{
|
|
iw->u.mode = IP_IW_MODE_INFRA;
|
|
}
|
|
else if (value == DOT11_MODE_IBSS)
|
|
{
|
|
iw->u.mode = IP_IW_MODE_ADHOC;
|
|
}
|
|
else
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
case IP_SIOCSIWAUTHTYPE:
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCGAUTHPOL, &i);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCGSECPOL, &j);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
switch (iw->u.auth_type)
|
|
{
|
|
case IP_IW_AUTHPOL_WPA:
|
|
i |= DOT11_AUTHPOL_8021X;
|
|
j |= DOT11_SECPOL_WPA;
|
|
k = DOT11_AUTHTYPE_OPEN;
|
|
break;
|
|
|
|
case IP_IW_AUTHPOL_WPA_PSK:
|
|
i |= DOT11_AUTHPOL_PSK;
|
|
j |= DOT11_SECPOL_WPA;
|
|
k = DOT11_AUTHTYPE_OPEN;
|
|
break;
|
|
|
|
case IP_IW_AUTHPOL_WPA2:
|
|
i |= DOT11_AUTHPOL_8021X;
|
|
j |= DOT11_SECPOL_11i;
|
|
k = DOT11_AUTHTYPE_OPEN;
|
|
break;
|
|
|
|
case IP_IW_AUTHPOL_WPA2_PSK:
|
|
i |= DOT11_AUTHPOL_PSK;
|
|
j |= DOT11_SECPOL_11i;
|
|
k = DOT11_AUTHTYPE_OPEN;
|
|
break;
|
|
|
|
case IP_IW_AUTHPOL_SHARED_KEY:
|
|
i = DOT11_AUTHPOL_NONE;
|
|
j = DOT11_SECPOL_NONE;
|
|
k = DOT11_AUTHTYPE_SKA;
|
|
break;
|
|
|
|
case IP_IW_AUTHPOL_OPEN:
|
|
i = DOT11_AUTHPOL_NONE;
|
|
j = DOT11_SECPOL_NONE;
|
|
k = DOT11_AUTHTYPE_OPEN;
|
|
break;
|
|
|
|
default:
|
|
ipcom_free(res);
|
|
ipcom_free(acl);
|
|
return IPWLAN_ATHEROS_ERR_FAILED;
|
|
}
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCSAUTHPOL, (Ip_u32 *)i);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCSSECPOL, (Ip_u32 *)j);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCSAUTHTYPE, (Ip_u32 *)k);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
case IP_SIOCGIWAUTHTYPE:
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCGAUTHPOL, &i);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCGSECPOL, &j);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCGAUTHTYPE, &k);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
iw->u.auth_type = 0;
|
|
|
|
if(i & DOT11_AUTHPOL_8021X)
|
|
{
|
|
if (j & DOT11_SECPOL_WPA)
|
|
{
|
|
iw->u.auth_type |= IP_IW_AUTHPOL_WPA;
|
|
}
|
|
if (j & DOT11_SECPOL_11i)
|
|
{
|
|
iw->u.auth_type |= IP_IW_AUTHPOL_WPA2;
|
|
}
|
|
}
|
|
|
|
if(i & DOT11_AUTHPOL_PSK)
|
|
{
|
|
if (j & DOT11_SECPOL_WPA)
|
|
{
|
|
iw->u.auth_type |= IP_IW_AUTHPOL_WPA_PSK;
|
|
}
|
|
if (j & DOT11_SECPOL_11i)
|
|
{
|
|
iw->u.auth_type |= IP_IW_AUTHPOL_WPA2_PSK;
|
|
}
|
|
}
|
|
|
|
if(i == DOT11_AUTHPOL_NONE)
|
|
{
|
|
k ++;
|
|
|
|
if (k == DOT11_AUTHTYPE_SKA)
|
|
{
|
|
iw->u.auth_type = IP_IW_AUTHPOL_SHARED_KEY;
|
|
}
|
|
else if (k == DOT11_AUTHTYPE_OPEN)
|
|
{
|
|
iw->u.auth_type = IP_IW_AUTHPOL_OPEN;
|
|
}
|
|
}
|
|
|
|
if(i & ~(DOT11_AUTHPOL_8021X|DOT11_AUTHPOL_PSK|DOT11_AUTHPOL_NONE))
|
|
{
|
|
ipcom_free(res);
|
|
ipcom_free(acl);
|
|
return IPWLAN_ATHEROS_ERR_FAILED;
|
|
}
|
|
|
|
break;
|
|
|
|
case IP_SIOCSIWCOMMIT:
|
|
|
|
ret = IPCOM_SUCCESS;
|
|
break;
|
|
|
|
case IP_SIOCSIWPMKKEY:
|
|
|
|
if ((iw->u.key.flags & IP_IW_KEY_FLAG_PASS) == IP_IW_KEY_FLAG_PASS)
|
|
{
|
|
ret = dot11Ioctl(iw->if_name, WIOCSPASSPHRASE, (Ip_u8 *)iw->u.key.key);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ipwlan_atheros_parse_key(psk, (char *)iw->u.key.key);
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCSPSK, (Ip_u8 *)psk);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
}
|
|
|
|
break;
|
|
case IP_SIOCSIWENCRKEY:
|
|
|
|
ipcom_memset(&key, 0, sizeof(DOT11_KEY));
|
|
key.keySlot = iw->u.key.index;
|
|
|
|
if (iw->u.key.type == IP_IW_KEY_WEP40_TYPE || iw->u.key.type == IP_IW_KEY_WEP104_TYPE)
|
|
{
|
|
if (iw->u.key.flags & IP_IW_KEY_FLAG_GROUP && iw->u.key.index > DOT11_MAX_WEP_KEY_INDEX)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_INVALID_ARG;
|
|
break;
|
|
}
|
|
if(!(iw->u.key.flags & IP_IW_KEY_FLAG_NOKEY))
|
|
{
|
|
if (iw->u.key.len == DOT11_WEP40_KEY_SIZE)
|
|
{
|
|
key.keyType = DOT11_CIPHPOL_WEP40;
|
|
}
|
|
else if (iw->u.key.len == DOT11_WEP104_KEY_SIZE)
|
|
{
|
|
key.keyType = DOT11_CIPHPOL_WEP104;
|
|
}
|
|
else
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_INVALID_ARG;
|
|
break;
|
|
}
|
|
ipcom_memcpy(&key.type.wep40[0], iw->u.key.key, iw->u.key.len);
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCSENCRYPTTYPE, (Ip_u32 *)key.keyType);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCSWEPDEFAULTKEY, (Ip_u32 *)key.keySlot);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if((iw->u.key.flags & IP_IW_KEY_FLAG_GROUP) == IP_IW_KEY_FLAG_GROUP)
|
|
{
|
|
ret = dot11Ioctl(iw->if_name, WIOCSWEPDEFAULTKEY, (Ip_u32 *)key.keySlot);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (iw->u.key.type == IP_IW_KEY_TKIP_TYPE)
|
|
{
|
|
if ((iw->u.key.len != DOT11_TKIP_KEY_SIZE) && (iw->u.key.len != 0))
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_INVALID_ARG;
|
|
break;
|
|
}
|
|
key.keyType = DOT11_CIPHPOL_TKIP;
|
|
ipcom_memcpy(&key.type.tkip[0], iw->u.key.key, iw->u.key.len);
|
|
}
|
|
else if (iw->u.key.type == IP_IW_KEY_AES_TYPE)
|
|
{
|
|
if ((iw->u.key.len != DOT11_AES_KEY_SIZE) && (iw->u.key.len != 0))
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
key.keyType = DOT11_CIPHPOL_AES;
|
|
ipcom_memcpy(&key.type.aes[0], iw->u.key.key, iw->u.key.len);
|
|
}
|
|
if ((iw->u.key.flags & IP_IW_KEY_FLAG_PAIR) == IP_IW_KEY_FLAG_PAIR)
|
|
{
|
|
key.keySlot = DOT11_KEYINDEX_SEARCH;
|
|
|
|
ipcom_memcpy(&key.macAddr, iw->u.key.addr, DOT11_ADDR_LEN);
|
|
|
|
if (iw->u.key.len > 0)
|
|
{
|
|
ret = dot11Ioctl(iw->if_name, WIOCAPAIRWISEKEY, &key);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCDPAIRWISEKEY, &key.macAddr);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else if ((iw->u.key.flags & IP_IW_KEY_FLAG_GROUP) == IP_IW_KEY_FLAG_GROUP)
|
|
{
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCSWEPKEY0 + key.keySlot, &key);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
}
|
|
else if ((iw->u.key.flags & IP_IW_KEY_FLAG_PASS) == IP_IW_KEY_FLAG_PASS)
|
|
{
|
|
ret = dot11Ioctl(iw->if_name, WIOCSPASSPHRASE, iw->u.key.key);
|
|
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case IP_SIOCGIWRSNCAP:
|
|
|
|
iw->u.rsn_cap = 0x0000; /* This is hardcoded in dot11RsnIeCreate() in "dot11RsnLib.c" */
|
|
ret = IPCOM_SUCCESS;
|
|
break;
|
|
|
|
case IP_SIOCSIW4WAYHSSTATE:
|
|
if(iw->u.data.length != DOT11_ADDR_LEN)
|
|
{
|
|
ipcom_free(res);
|
|
ipcom_free(acl);
|
|
return IPCOM_ERR_INVALID_ARG;
|
|
}
|
|
ipcom_memset(&fourway_handshake, 0, sizeof(fourway_handshake));
|
|
ipcom_memcpy(fourway_handshake.macAddr, iw->u.data.pointer, DOT11_ADDR_LEN);
|
|
fourway_handshake.established = (iw->u.data.flags == IP_IW_4WAYHS_FLAG_DONE);
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCS4WAYHSSTATE, &fourway_handshake);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case IP_SIOCSIWPSMODE:
|
|
/* wps mode on/off */
|
|
ret = IPCOM_ERR_NOT_SUPPORTED;
|
|
|
|
break;
|
|
case IP_SIOCSIWENCRTYPE:
|
|
|
|
value = 0;
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCGCIPHPOL, &value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
if (iw->u.encr_type == IP_IW_CIPHPOL_NONE)
|
|
value = DOT11_CIPHPOL_NONE;
|
|
if ((iw->u.encr_type & IP_IW_CIPHPOL_WEP40) == IP_IW_CIPHPOL_WEP40)
|
|
value |= DOT11_CIPHPOL_WEP40;
|
|
if ((iw->u.encr_type & IP_IW_CIPHPOL_WEP104) == IP_IW_CIPHPOL_WEP104)
|
|
value |= DOT11_CIPHPOL_WEP104;
|
|
if ((iw->u.encr_type & IP_IW_CIPHPOL_TKIP) == IP_IW_CIPHPOL_TKIP)
|
|
value |= DOT11_CIPHPOL_TKIP;
|
|
if ((iw->u.encr_type & IP_IW_CIPHPOL_CCMP) == IP_IW_CIPHPOL_CCMP)
|
|
value |= DOT11_CIPHPOL_AES;
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCSCIPHPOL, (Ip_u32 *)value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
value &= ~(DOT11_CIPHPOL_AES | DOT11_CIPHPOL_TKIP);
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCSENCRYPTTYPE, (Ip_u32 *)value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
case IP_SIOCGIWENCRTYPE: /* get encoding token & mode */
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCGCIPHPOL, &value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
if (value == DOT11_CIPHPOL_NONE)
|
|
iw->u.encr_type = IP_IW_CIPHPOL_NONE;
|
|
if ((value & DOT11_CIPHPOL_WEP40) == DOT11_CIPHPOL_WEP40)
|
|
iw->u.encr_type |= IP_IW_CIPHPOL_WEP40;
|
|
if ((value & DOT11_CIPHPOL_WEP104) == DOT11_CIPHPOL_WEP104)
|
|
iw->u.encr_type |= IP_IW_CIPHPOL_WEP104;
|
|
if ((value & DOT11_CIPHPOL_TKIP) == DOT11_CIPHPOL_TKIP)
|
|
iw->u.encr_type |= IP_IW_CIPHPOL_TKIP;
|
|
if ((value & DOT11_CIPHPOL_AES) == DOT11_CIPHPOL_AES)
|
|
iw->u.encr_type |= IP_IW_CIPHPOL_CCMP;
|
|
|
|
break;
|
|
|
|
case IP_SIOCGIWMCASTENCRTYPE: /* get encoding token & mode */
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCGENCRYPTTYPE, &value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
if (value == DOT11_CIPHPOL_NONE)
|
|
iw->u.encr_type = IP_IW_CIPHPOL_NONE;
|
|
if ((value & DOT11_CIPHPOL_WEP40) == DOT11_CIPHPOL_WEP40)
|
|
iw->u.encr_type |= IP_IW_CIPHPOL_WEP40;
|
|
if ((value & DOT11_CIPHPOL_WEP104) == DOT11_CIPHPOL_WEP104)
|
|
iw->u.encr_type |= IP_IW_CIPHPOL_WEP104;
|
|
if ((value & DOT11_CIPHPOL_TKIP) == DOT11_CIPHPOL_TKIP)
|
|
iw->u.encr_type |= IP_IW_CIPHPOL_TKIP;
|
|
if ((value & DOT11_CIPHPOL_AES) == DOT11_CIPHPOL_AES)
|
|
iw->u.encr_type |= IP_IW_CIPHPOL_CCMP;
|
|
|
|
break;
|
|
|
|
case IP_SIOCSIWAP:
|
|
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
|
|
case IP_SIOCGIWAP: /* get access point MAC addresses (BSSID) */
|
|
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
|
|
case IP_SIOCSIWESSID: /* Set name of network to join */
|
|
|
|
/* ssid.SSID_len = iw->u.essid.length; */
|
|
ipcom_memcpy(ssid, iw->u.essid.pointer, iw->u.essid.length + 1);
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCSSSID, ssid);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
case IP_SIOCGIWESSID: /* Get the network joined */
|
|
|
|
ipcom_memset(&ssid, 0, sizeof(ssid));
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCGDESIREDSSID, &ssid);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
ipcom_memcpy(iw->u.essid.pointer, ssid, sizeof(ssid));
|
|
|
|
break;
|
|
|
|
case IP_SIOCSIWSCAN: /* Start a new scan */
|
|
|
|
ret = IPCOM_SUCCESS;
|
|
break;
|
|
|
|
case IP_SIOCGIWSCAN:
|
|
|
|
ipcom_memset(&req, 0, sizeof(req));
|
|
|
|
req.maxResults = DOT11_MAX_SCANRESULTS;
|
|
req.pResults = &res[0];
|
|
|
|
if (iw->u.essid.length > 0 && iw->u.essid.length <= DOT11_SSID_LEN)
|
|
{
|
|
ipcom_strncpy((char *)req.ssid, (char *)iw->u.essid.pointer,iw->u.essid.length);
|
|
}
|
|
else
|
|
{
|
|
ipcom_strcpy((char *)req.ssid, "");
|
|
}
|
|
|
|
|
|
if ((ret = dot11Ioctl(iw->if_name, WIOCBSSSCAN, &req)) != 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
iw->u.data.pointer = &iw->u.data + 1;
|
|
scan_data = iw->u.data.pointer;
|
|
scan_len_left = MIN(iw->u.data.length, MAX_IWREQ_LARGE_DATA);
|
|
|
|
for (i = 0, iw->u.data.length = 0; i < req.numResults; i++, iw->u.data.length += scan_ap_len)
|
|
{
|
|
scan_ap_len = 0;
|
|
|
|
/* BSSID */
|
|
|
|
iwe.cmd = SIOCGIWAP;
|
|
iwe.len = IP_IW_EV_ADDR_LEN;
|
|
iwe.u.addr.sa_family = 0;
|
|
|
|
ipcom_memcpy(iwe.u.addr.sa_data, req.pResults[i].macAddr, DOT11_ADDR_LEN);
|
|
if (scan_len_left < iwe.len)
|
|
{
|
|
break;
|
|
}
|
|
|
|
ipcom_memcpy(scan_data, &iwe, IP_IW_EV_ADDR_LEN);
|
|
scan_data += IP_IW_EV_ADDR_LEN;
|
|
scan_len_left -= IP_IW_EV_ADDR_LEN;
|
|
scan_ap_len += IP_IW_EV_ADDR_LEN;
|
|
|
|
/* ESSID */
|
|
|
|
iwe.cmd = SIOCGIWESSID;
|
|
|
|
iwe.u.data.flags = 1;
|
|
|
|
iwe.u.essid.pointer = req.pResults[i].ssid;
|
|
iwe.u.essid.length = DOT11_SSID_LEN + 1;
|
|
|
|
iwe.u.essid.flags = 0;
|
|
if (scan_len_left < IP_IW_EV_POINT_LEN + ALIGN_UP_4(iwe.u.essid.length))
|
|
{
|
|
break;
|
|
}
|
|
iwe.len = IP_IW_EV_POINT_LEN + ALIGN_UP_4(iwe.u.essid.length);
|
|
|
|
ipcom_memcpy(scan_data, &iwe, IP_IW_EV_POINT_LEN);
|
|
scan_data += IP_IW_EV_POINT_LEN;
|
|
|
|
ipcom_memcpy(scan_data, iwe.u.data.pointer, iwe.u.data.length);
|
|
scan_data += ALIGN_UP_4(iwe.u.data.length);
|
|
scan_len_left -= iwe.len;
|
|
scan_ap_len += iwe.len;
|
|
|
|
/* Mode */
|
|
|
|
if (scan_len_left < IP_IW_EV_UINT_LEN)
|
|
{
|
|
break;
|
|
}
|
|
iwe.cmd = SIOCGIWMODE;
|
|
iwe.len = IP_IW_EV_UINT_LEN;
|
|
iwe.u.mode = 0;
|
|
|
|
if (req.pResults[i].capabilities & (DOT11_CAP_ESS | DOT11_CAP_IBSS))
|
|
{
|
|
iwe.u.mode = (req.pResults[i].capabilities & DOT11_CAP_ESS) ? IP_IW_MODE_INFRA : IP_IW_MODE_ADHOC;
|
|
}
|
|
|
|
ipcom_memcpy(scan_data, &iwe, IP_IW_EV_UINT_LEN);
|
|
|
|
scan_data += IP_IW_EV_UINT_LEN;
|
|
scan_len_left -= IP_IW_EV_UINT_LEN;
|
|
scan_ap_len += IP_IW_EV_UINT_LEN;
|
|
|
|
|
|
/* Channel */
|
|
|
|
if (scan_len_left < IP_IW_EV_FREQ_LEN)
|
|
{
|
|
break;
|
|
}
|
|
iwe.cmd = SIOCGIWFREQ;
|
|
iwe.len = IP_IW_EV_FREQ_LEN;
|
|
memset(&iwe.u.freq, 0, sizeof(iwe.u.freq));
|
|
iwe.u.freq.m = req.pResults[i].channel;
|
|
iwe.u.freq.e = 0;
|
|
iwe.u.freq.i = 0;
|
|
|
|
ipcom_memcpy(scan_data, &iwe, IP_IW_EV_FREQ_LEN);
|
|
|
|
scan_data += IP_IW_EV_FREQ_LEN;
|
|
scan_len_left -= IP_IW_EV_FREQ_LEN;
|
|
scan_ap_len += IP_IW_EV_FREQ_LEN;
|
|
|
|
|
|
|
|
/* Signal quality */
|
|
|
|
if (scan_len_left < IP_IW_EV_QUAL_LEN)
|
|
{
|
|
break;
|
|
}
|
|
iwe.cmd = SIOCGIWSPY;
|
|
iwe.len = IP_IW_EV_QUAL_LEN;
|
|
memset(&iwe.u.quality, 0, sizeof(iwe.u.quality));
|
|
iwe.u.quality.level = req.pResults[i].ssi - 100;
|
|
iwe.u.quality.noise = 0; /* noise not provided by atheros */
|
|
|
|
ipcom_memcpy(scan_data, &iwe, IP_IW_EV_UINT_LEN);
|
|
|
|
scan_data += IP_IW_EV_QUAL_LEN;
|
|
scan_len_left -= IP_IW_EV_QUAL_LEN;
|
|
scan_ap_len += IP_IW_EV_QUAL_LEN;
|
|
}
|
|
|
|
break;
|
|
|
|
case IP_SIOCGIWFREQ:
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCGCHANNEL, &value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
iw->u.freq.m = ipwlan_atheros_freq[value];
|
|
iw->u.freq.e = 0;
|
|
iw->u.freq.i = 0;
|
|
iw->u.freq.flags |= IP_IW_FREQ_FIXED;
|
|
|
|
break;
|
|
|
|
case IP_SIOCSIWFREQ: /* set channel or frequency */
|
|
|
|
if (iw->u.freq.flags != IP_IW_FREQ_FIXED && iw->u.freq.flags != IP_IW_FREQ_AUTO)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_INVALID_ARG;
|
|
break;
|
|
}
|
|
|
|
value = iw->u.freq.m;
|
|
if (value > 1000)
|
|
{
|
|
/* Frequency */
|
|
for (i = 0; i < iw->u.freq.e; i++)
|
|
{
|
|
value *= 10;
|
|
}
|
|
value /= 1000;
|
|
for (i = 0; i < MAX_CHANNEL_NO; i++)
|
|
{
|
|
if (value == ipwlan_atheros_freq[i])
|
|
{
|
|
value = i + 1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (value < 1 || value > MAX_CHANNEL_NO)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_INVALID_ARG;
|
|
break;
|
|
}
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCSCHANNEL, (Ip_u32 *)value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
case IP_SIOCGIWRSC:
|
|
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
|
|
case IP_SIOCSIWRSC:
|
|
ret = IPCOM_SUCCESS;
|
|
break;
|
|
|
|
case IP_SIOCSIWRESET:
|
|
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
|
|
case IP_SIOCSAUTHCALLBACK:
|
|
dot11_cb.callback = (Ip_u32)iw->u.callback.ptr;
|
|
dot11_cb.cookie = iw->u.callback.param;
|
|
ret = dot11Ioctl(iw->if_name, (int)WIOCSAUTHCALLBACK, &dot11_cb);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
}
|
|
break;
|
|
|
|
case IP_SIOCSIWDOT1XPORTSTATUS:
|
|
{
|
|
DOT11_DOT1X_PORTSTATUS port;
|
|
switch (iw->u.dot1xport.status) {
|
|
case IP_IW_DOT1X_PORTSTATUS_UNCONTROLLED:
|
|
port.status = DOT11_DOT1XPORT_UNCONTROLLED;
|
|
break;
|
|
case IP_IW_DOT1X_PORTSTATUS_CLOSED:
|
|
port.status = DOT11_DOT1XPORT_CLOSED;
|
|
break;
|
|
case IP_IW_DOT1X_PORTSTATUS_OPEN:
|
|
port.status = DOT11_DOT1XPORT_OPEN;
|
|
break;
|
|
default:
|
|
ipcom_free(acl);
|
|
ipcom_free(res);
|
|
return IPWLAN_ATHEROS_ERR_FAILED;
|
|
|
|
}
|
|
ipcom_memcpy(port.macAddr, iw->u.dot1xport.addr, 6);
|
|
ret = dot11Ioctl(iw->if_name, (int)WIOCSDOT1XPORTSTATUS, &port);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case IP_SIOCSIWDEAUTH:
|
|
ipcom_memset(&deauth_req, 0, sizeof(deauth_req));
|
|
ipcom_memcpy(&deauth_req.macAddr, iw->u.deauth_req.addr, DOT11_ADDR_LEN);
|
|
deauth_req.reason = (Ip_u32) iw->u.deauth_req.reason;
|
|
ret = dot11Ioctl(iw->if_name, WIOCSDEAUTH, &deauth_req);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
} else
|
|
{
|
|
ret = IPCOM_SUCCESS;
|
|
}
|
|
break;
|
|
|
|
case IP_SIOCSTKIPCMSTART:
|
|
ipcom_memset(&macAddr, 0, sizeof(macAddr));
|
|
ipcom_memcpy(&macAddr,iw->u.macAddr,DOT11_ADDR_LEN);
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCSTKIPCMSTART, &macAddr);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case IP_SIOCSIWOPENPORT:
|
|
ret = IPCOM_SUCCESS;
|
|
break;
|
|
|
|
case IP_SIOCGIWQUALITY:
|
|
|
|
ipcom_memset(&req, 0, sizeof(req));
|
|
ipcom_memset(&ssid, 0, sizeof(ssid));
|
|
ipcom_memset(&value, 0, sizeof(value));
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCGCONNECTEDSSID, &ssid);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
ipcom_strcpy((char *)req.ssid, ssid);
|
|
req.maxResults = 1;
|
|
req.pResults = &res[0];
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCBSSSCAN, &req);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCGTXRATE, &value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
iw->u.quality.level = req.pResults[0].ssi - 100;
|
|
iw->u.quality.noise = 0; /* noise not provided by atheros */
|
|
iw->u.quality.qual = value;
|
|
|
|
break;
|
|
|
|
case IP_SIOCSIWPOWERMAN:
|
|
|
|
value = iw->u.pm;
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCSPWRMAN, (Ip_u32 *)value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
case IP_SIOCGIWPOWERMAN:
|
|
|
|
ipcom_memset(&value, 0, sizeof(value));
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCGPWRMAN, &value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
iw->u.pm = value;
|
|
|
|
break;
|
|
|
|
case IP_SIOCSIWCHANNEL:
|
|
|
|
value = iw->u.channel;
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCSCHANNEL, (Ip_u32 *)value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
case IP_SIOCGIWCHANNEL:
|
|
|
|
ipcom_memset(&value, 0, sizeof(value));
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCGCHANNEL, &value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
iw->u.channel = value;
|
|
|
|
break;
|
|
|
|
case IP_SIOCSIWLRL:
|
|
|
|
value = iw->u.lrl;
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCSLONGRETRY, (Ip_u32 *)value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
case IP_SIOCGIWLRL:
|
|
|
|
ipcom_memset(&value, 0, sizeof(value));
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCGLONGRETRY, &value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
iw->u.lrl = value;
|
|
|
|
break;
|
|
|
|
case IP_SIOCSIWSRL:
|
|
|
|
value = iw->u.srl;
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCSSHORTRETRY, (Ip_u32 *)value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
case IP_SIOCGIWSRL:
|
|
|
|
ipcom_memset(&value, 0, sizeof(value));
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCGSHORTRETRY, &value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
iw->u.srl = value;
|
|
|
|
break;
|
|
|
|
case IP_SIOCSIWBEACONINT:
|
|
|
|
value = iw->u.bi;
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCSBEACONRATE, (Ip_u32 *)value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
case IP_SIOCGIWBEACONINT:
|
|
|
|
ipcom_memset(&value, 0, sizeof(value));
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCGBEACONRATE, &value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
iw->u.bi = value;
|
|
|
|
break;
|
|
|
|
case IP_SIOCSIWRATE:
|
|
|
|
value = iw->u.rate;
|
|
|
|
rates.length = 1;
|
|
|
|
rates.rates[0] = iw->u.rate;
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCSTXRATE, &rates);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
case IP_SIOCGIWRATE:
|
|
|
|
ipcom_memset(&value, 0, sizeof(value));
|
|
|
|
/* Command only supported if we are a station */
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCGDOT11MODE, &value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
if (value == DOT11_MODE_AP || value == DOT11_MODE_IBSS)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCGTXRATE, &value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
iw->u.rate = value;
|
|
|
|
break;
|
|
|
|
case IP_SIOCSIWSUPPRATES:
|
|
|
|
rates.length = iw->u.supprates.count;
|
|
|
|
for (i = 0; i < iw->u.supprates.count; i ++)
|
|
{
|
|
rates.rates[i] = iw->u.supprates.rates[i];
|
|
}
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCSTXRATE, &rates);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
case IP_SIOCGIWSUPPRATES:
|
|
|
|
rates.length = 0;
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCGSUPPTXRATE, &rates);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
iw->u.supprates.count = rates.length;
|
|
for (i = 0; i < iw->u.supprates.count; i ++)
|
|
{
|
|
iw->u.supprates.rates[i] = rates.rates[i];
|
|
}
|
|
|
|
break;
|
|
|
|
case IP_SIOCSIWFRAGTHRESH:
|
|
|
|
value = iw->u.fragthresh;
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCSFRAGTHRESH, (Ip_u32 *)value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
case IP_SIOCGIWFRAGTHRESH:
|
|
|
|
ipcom_memset(&value, 0, sizeof(value));
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCGFRAGTHRESH, &value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
iw->u.fragthresh = value;
|
|
|
|
break;
|
|
|
|
case IP_SIOCSIWEXTRSN:
|
|
value = iw->u.value32;
|
|
ret = dot11Ioctl(iw->if_name, WIOCSEXTRSN, (Ip_u32 *)value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
case IP_SIOCSIWRADIOMODE:
|
|
|
|
if (iw->u.radiomode == IP_IW_RADIOMODE_AUTO)
|
|
{
|
|
value = DOT11_RADIO_ANY;
|
|
}
|
|
else if (iw->u.radiomode == IP_IW_RADIOMODE_11A)
|
|
{
|
|
value = DOT11_RADIO_11a;
|
|
}
|
|
else if (iw->u.radiomode == IP_IW_RADIOMODE_11B)
|
|
{
|
|
value = DOT11_RADIO_11b;
|
|
}
|
|
else if (iw->u.radiomode == IP_IW_RADIOMODE_11G)
|
|
{
|
|
value = DOT11_RADIO_11g;
|
|
}
|
|
else
|
|
{
|
|
value = iw->u.radiomode;
|
|
}
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCSRADIOMODE, (Ip_u32 *)value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
case IP_SIOCGIWRADIOMODE:
|
|
|
|
ipcom_memset(&value, 0, sizeof(value));
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCGRADIOMODE, &value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
iw->u.radiomode = value;
|
|
|
|
if (value == DOT11_RADIO_ANY)
|
|
{
|
|
iw->u.radiomode = IP_IW_RADIOMODE_AUTO;
|
|
}
|
|
else if (value == DOT11_RADIO_11a)
|
|
{
|
|
iw->u.radiomode = IP_IW_RADIOMODE_11A;
|
|
}
|
|
else if (value == DOT11_RADIO_11b)
|
|
{
|
|
iw->u.radiomode = IP_IW_RADIOMODE_11B;
|
|
}
|
|
else if (value == DOT11_RADIO_11g)
|
|
{
|
|
iw->u.radiomode = IP_IW_RADIOMODE_11G;
|
|
}
|
|
|
|
break;
|
|
|
|
case IP_SIOCGIWSUPPCHAN:
|
|
|
|
ipcom_memset(&value, 0, sizeof(value));
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCGRADIOMODE, &value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
chanList.numChannels = 0;
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCGCHANNELLIST, &chanList);
|
|
if (ret < 0 || chanList.numChannels == 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
for (i = 0, j=0; i < chanList.numChannels; i ++)
|
|
{
|
|
if (chanList.channels[i].mode & value)
|
|
{
|
|
iw->u.suppchan.chan[j] = chanList.channels[i].channel;
|
|
j ++;
|
|
}
|
|
}
|
|
|
|
iw->u.suppchan.count = j;
|
|
|
|
break;
|
|
|
|
case IP_SIOCSIWRTSTHRESH:
|
|
|
|
value = iw->u.rtsthresh;
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCSCTSRTS, (Ip_u32 *)value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
case IP_SIOCGIWRTSTHRESH:
|
|
|
|
ipcom_memset(&value, 0, sizeof(value));
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCGCTSRTS, &value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
iw->u.rtsthresh = value;
|
|
|
|
break;
|
|
|
|
case IP_SIOCSIWHIDESSID:
|
|
|
|
value = iw->u.hidessid;
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCSADVSECURITY, (Ip_u32 *)value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
case IP_SIOCGIWHIDESSID:
|
|
|
|
ipcom_memset(&value, 0, sizeof(value));
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCGADVSECURITY, &value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
iw->u.hidessid = value;
|
|
|
|
break;
|
|
|
|
case IP_SIOCSIWRADIONRATE:
|
|
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
|
|
case IP_SIOCGIWRADIONRATE:
|
|
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
|
|
case IP_SIOCSIWRADIONSTAT:
|
|
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
|
|
case IP_SIOCGIWRADIONSTAT:
|
|
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
|
|
case IP_SIOCSIWACL:
|
|
|
|
ret = IPCOM_SUCCESS;
|
|
break;
|
|
|
|
case IP_SIOCGIWACL:
|
|
|
|
ipcom_memset(acl, 0, (sizeof(DOT11_ACL)*DOT11_KSL_MAX_HASH));
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCGACL, acl);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
iw->u.data.pointer = &iw->u.data + 1;
|
|
acl_data = iw->u.data.pointer;
|
|
acl_len_left = MIN(iw->u.data.length, MAX_IWREQ_LARGE_DATA);
|
|
|
|
for (i = 0, iw->u.data.length = 0; i < acl->numStations; i++, iw->u.data.length += acl_ap_len)
|
|
{
|
|
acl_ap_len = 0;
|
|
|
|
/* BSSID */
|
|
|
|
iwe.cmd = SIOCGIWAP;
|
|
iwe.len = IP_IW_EV_ADDR_LEN;
|
|
iwe.u.addr.sa_family = 0;
|
|
|
|
ipcom_memcpy(iwe.u.addr.sa_data, acl[i].macAddr, DOT11_ADDR_LEN);
|
|
if (acl_len_left < iwe.len)
|
|
{
|
|
break;
|
|
}
|
|
|
|
ipcom_memcpy(acl_data, &iwe, IP_IW_EV_ADDR_LEN);
|
|
acl_data += IP_IW_EV_ADDR_LEN;
|
|
acl_len_left -= IP_IW_EV_ADDR_LEN;
|
|
acl_ap_len += IP_IW_EV_ADDR_LEN;
|
|
}
|
|
|
|
break;
|
|
|
|
case IP_SIOCGIWACLMODE:
|
|
|
|
ipcom_memset(&value, 0, sizeof(value));
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCGACLMODE, &value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
if (value == DOT11_ACL_DISABLED)
|
|
{
|
|
value = IP_IW_ACL_NONE;
|
|
}
|
|
else if (value == DOT11_ACL_ALLOW)
|
|
{
|
|
value = IP_IW_ACL_ALLOW;
|
|
}
|
|
else if (value == DOT11_ACL_DENY)
|
|
{
|
|
value = IP_IW_ACL_DENY;
|
|
}
|
|
|
|
iw->u.aclmode = value;
|
|
|
|
break;
|
|
|
|
case IP_SIOCSIWACLMODE:
|
|
|
|
value = iw->u.aclmode;
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCSACLMODE, (Ip_u32 *)value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
case IP_SIOCSIWACLADD:
|
|
|
|
ipcom_memset(&macAddr, 0, sizeof(macAddr));
|
|
|
|
ipcom_memcpy(&macAddr,iw->u.addr.sa_data,DOT11_ADDR_LEN);
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCAACLSTA, &macAddr);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
case IP_SIOCSIWACLDEL:
|
|
|
|
ipcom_memset(&macAddr, 0, sizeof(macAddr));
|
|
|
|
ipcom_memcpy(&macAddr,iw->u.addr.sa_data,DOT11_ADDR_LEN);
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCDACLSTA, &macAddr);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
case IP_SIOCGIWSCANMODE:
|
|
|
|
ipcom_memset(&value, 0, sizeof(value));
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCGSCANTYPE, &value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
if (value == DOT11_SCANTYPE_ACTIVE)
|
|
{
|
|
value = IP_IW_SCANMODE_ACTIVE;
|
|
}
|
|
else if (value == DOT11_SCANTYPE_PASSIVE)
|
|
{
|
|
value = IP_IW_SCANMODE_PASSIVE;
|
|
}
|
|
|
|
|
|
iw->u.scanmode = value;
|
|
|
|
|
|
break;
|
|
|
|
case IP_SIOCSIWSCANMODE:
|
|
|
|
value = iw->u.scanmode;
|
|
|
|
if(value==IP_IW_SCANMODE_ACTIVE)
|
|
value = DOT11_SCANTYPE_ACTIVE;
|
|
else
|
|
value = DOT11_SCANTYPE_PASSIVE;
|
|
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCSSCANTYPE, (Ip_u32 *)value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
case IP_SIOCSIWPOWERSCALE:
|
|
|
|
if (iw->u.ps < 100)
|
|
{
|
|
value = DOT11_TXPOWER_MAX;
|
|
}
|
|
if (iw->u.ps < 66)
|
|
{
|
|
value = DOT11_TXPOWER_66;
|
|
}
|
|
if (iw->u.ps < 50)
|
|
{
|
|
value = DOT11_TXPOWER_33;
|
|
}
|
|
if (iw->u.ps < 33)
|
|
{
|
|
value = DOT11_TXPOWER_MIN;
|
|
}
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCSTXPOWERSCALE, (Ip_u32 *)value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
case IP_SIOCGIWPOWERSCALE:
|
|
|
|
ipcom_memset(&value, 0, sizeof(value));
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCGTXPOWERSCALE, &value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
if (value == DOT11_TXPOWER_MAX)
|
|
{
|
|
iw->u.ps = 100;
|
|
}
|
|
if (value == DOT11_TXPOWER_66)
|
|
{
|
|
iw->u.ps = 66;
|
|
}
|
|
if (value == DOT11_TXPOWER_50)
|
|
{
|
|
iw->u.ps = 50;
|
|
}
|
|
if (value == DOT11_TXPOWER_33)
|
|
{
|
|
iw->u.ps = 33;
|
|
}
|
|
if (value == DOT11_TXPOWER_MIN)
|
|
{
|
|
iw->u.ps = 25;
|
|
}
|
|
|
|
break;
|
|
|
|
case IP_SIOCSIWCOUNTRYCODE:
|
|
|
|
value = iw->u.countrycode;
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCSCOUNTRYCODE, (Ip_u32 *)value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
case IP_SIOCGIWCOUNTRYCODE:
|
|
|
|
ipcom_memset(&value, 0, sizeof(value));
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCGCOUNTRYCODE, &value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
iw->u.countrycode = value;
|
|
|
|
break;
|
|
|
|
case IP_SIOCSIWBSSINDEX:
|
|
|
|
value = iw->u.bssindex;
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCSBSS, (Ip_u32 *)value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
case IP_SIOCGIWBSSINDEX:
|
|
|
|
ipcom_memset(&value, 0, sizeof(value));
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCGBSS, &value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
iw->u.bssindex = value;
|
|
|
|
break;
|
|
|
|
case IP_SIOCSIWBSSADD:
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCABSS, &value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
case IP_SIOCSIWBSSDEL:
|
|
|
|
value = iw->u.bssindex;
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCDBSS, (Ip_u32 *)value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
case IP_SIOCSIWREGMODE:
|
|
|
|
value = iw->u.bssindex;
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCS80211D, (Ip_u32 *)value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
case IP_SIOCGIWREGMODE:
|
|
|
|
ipcom_memset(&value, 0, sizeof(value));
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCG80211D, &value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
iw->u.regmode = value;
|
|
|
|
break;
|
|
|
|
case IP_SIOCSIWSECTYPE:
|
|
|
|
ipcom_memset(&value, 0, sizeof(value));
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCGSECPOL, &value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
if (iw->u.sec_type == IP_IW_SECPOL_NONE)
|
|
value = DOT11_SECPOL_NONE;
|
|
if ((iw->u.sec_type & IP_IW_SECPOL_TSN) == IP_IW_SECPOL_TSN)
|
|
value |= DOT11_SECPOL_TSN;
|
|
if ((iw->u.sec_type & IP_IW_SECPOL_WPA) == IP_IW_SECPOL_WPA)
|
|
value |= DOT11_SECPOL_WPA;
|
|
if ((iw->u.sec_type & IP_IW_SECPOL_RSN) == IP_IW_SECPOL_RSN)
|
|
value |= DOT11_SECPOL_11i;
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCSSECPOL, (Ip_u32 *)value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
case IP_SIOCGIWSECTYPE:
|
|
|
|
ipcom_memset(&value, 0, sizeof(value));
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCGSECPOL, &value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
if (value == DOT11_SECPOL_NONE)
|
|
value = IP_IW_SECPOL_NONE;
|
|
if ((value & DOT11_SECPOL_TSN) == DOT11_SECPOL_TSN)
|
|
value |= IP_IW_SECPOL_TSN;
|
|
if ((value & DOT11_SECPOL_WPA) == DOT11_SECPOL_WPA)
|
|
value |= IP_IW_SECPOL_WPA;
|
|
if ((value & DOT11_SECPOL_11i) == DOT11_SECPOL_11i)
|
|
value |= IP_IW_SECPOL_RSN;
|
|
|
|
iw->u.sec_type = value;
|
|
|
|
break;
|
|
|
|
case IP_SIOCSIWDEBUGLEVEL:
|
|
|
|
value = iw->u.debuglevel;
|
|
|
|
if (value > 0xffffffff)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
if (value & ATH_DBG_INIT_NONE)
|
|
{
|
|
ret = ipwlan_atheros_set_debug_level(value);
|
|
}
|
|
else if (value & ATH_DBG_STATE_NONE)
|
|
{
|
|
ret = ipwlan_atheros_set_debug_level(value);
|
|
}
|
|
else if (value & ATH_DBG_DATA_NONE)
|
|
{
|
|
ret = ipwlan_atheros_set_debug_level(value);
|
|
}
|
|
else if (value & ATH_DBG_HW_NONE)
|
|
{
|
|
ret = ipwlan_atheros_set_debug_level(value);
|
|
}
|
|
else if (value & ATH_DBG_ISR_NONE)
|
|
{
|
|
ret = ipwlan_atheros_set_debug_level(value);
|
|
}
|
|
else
|
|
{
|
|
ret = ipwlan_atheros_set_debug_level(value);
|
|
}
|
|
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
case IP_SIOCGIWDEBUGLEVEL:
|
|
|
|
ipcom_memset(&value, 0, sizeof(value));
|
|
|
|
value |= ATH_DBG_ALL_NONE;
|
|
|
|
j = dot11DebugLevelGet(DOT11_AREA_ALL);
|
|
|
|
if (j > DOT11_DEBUG_NONE)
|
|
{
|
|
value |= (j << ATH_DBG_ALL_SHIFT);
|
|
}
|
|
|
|
value |= ATH_DBG_INIT_NONE;
|
|
|
|
j = dot11DebugLevelGet(DOT11_AREA_INIT);
|
|
|
|
if (j > DOT11_DEBUG_NONE)
|
|
{
|
|
value |= (j << ATH_DBG_INIT_SHIFT);
|
|
}
|
|
|
|
value |= ATH_DBG_STATE_NONE;
|
|
|
|
j = dot11DebugLevelGet(DOT11_AREA_SME);
|
|
|
|
if (j > DOT11_DEBUG_NONE)
|
|
{
|
|
value |= (j << ATH_DBG_STATE_SHIFT);
|
|
}
|
|
|
|
value |= ATH_DBG_DATA_NONE;
|
|
|
|
j = dot11DebugLevelGet(DOT11_AREA_DPE);
|
|
|
|
if (j > DOT11_DEBUG_NONE)
|
|
{
|
|
value |= (j << ATH_DBG_DATA_SHIFT);
|
|
}
|
|
|
|
value |= ATH_DBG_HW_NONE;
|
|
|
|
j = dot11DebugLevelGet(DOT11_AREA_HDD);
|
|
|
|
if (j > DOT11_DEBUG_NONE)
|
|
{
|
|
value |= (j << ATH_DBG_HW_SHIFT);
|
|
}
|
|
|
|
value |= ATH_DBG_ISR_NONE;
|
|
|
|
j = dot11DebugLevelGet(DOT11_AREA_INT);
|
|
|
|
if (j > DOT11_DEBUG_NONE)
|
|
{
|
|
value |= (j << ATH_DBG_ISR_SHIFT);
|
|
}
|
|
|
|
iw->u.debuglevel = value;
|
|
|
|
break;
|
|
|
|
case IP_SIOCGIWDEBUGOPTIONS:
|
|
|
|
ipcom_memset(&value, 0, sizeof(value));
|
|
|
|
iw->u.data.pointer = &iw->u.data;
|
|
data = iw->u.data.pointer;
|
|
|
|
for (i = 0; i < IPWLAN_ATHEROS_MAX_DEBUG; i ++)
|
|
{
|
|
ipcom_memcpy(data,&ipwlan_atheros_debuglevels[i],sizeof(Ipcom_iw_debug_level));
|
|
data += sizeof(Ipcom_iw_debug_level);
|
|
}
|
|
|
|
break;
|
|
|
|
case IP_SIOCGIWSTATISTICS:
|
|
|
|
ipcom_memset(&stats, 0, sizeof(stats));
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCGSTATS, &stats);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
iw->u.data.pointer = &iw->u.data + 1;
|
|
data = iw->u.data.pointer;
|
|
|
|
data = ipwlan_atheros_make_statistic(stats.rxFrames,"rxFrames",data);
|
|
data = ipwlan_atheros_make_statistic(stats.rxFragments,"rxFragments",data);
|
|
data = ipwlan_atheros_make_statistic(stats.rxMcastFragments,"rxMcastFragments",data);
|
|
data = ipwlan_atheros_make_statistic(stats.rxTotalBytes,"rxTotalBytes",data);
|
|
data = ipwlan_atheros_make_statistic(stats.rxDuplicates,"rxDuplicates",data);
|
|
data = ipwlan_atheros_make_statistic(stats.rxFCSError,"rxFCSError",data);
|
|
data = ipwlan_atheros_make_statistic(stats.rxHardwareError,"rxHardwareError",data);
|
|
data = ipwlan_atheros_make_statistic(stats.rxDecryptError,"rxDecryptError",data);
|
|
data = ipwlan_atheros_make_statistic(stats.rxMicFailure,"rxMicFailure",data);
|
|
data = ipwlan_atheros_make_statistic(stats.rxExcludeUnencrypted,"rxExcludeUnencrypted",data);
|
|
data = ipwlan_atheros_make_statistic(stats.rxDot1xDropped,"rxDot1xDropped",data);
|
|
data = ipwlan_atheros_make_statistic(stats.rxCantReassemble,"rxCantReassemble",data);
|
|
data = ipwlan_atheros_make_statistic(stats.rxBytesPerSec,"rxBytesPerSec",data);
|
|
data = ipwlan_atheros_make_statistic(stats.rxBytesPer16Sec,"rxBytesPer16Sec",data);
|
|
data = ipwlan_atheros_make_statistic(stats.txFrames,"txFrames",data);
|
|
data = ipwlan_atheros_make_statistic(stats.txFragments,"txFragments",data);
|
|
data = ipwlan_atheros_make_statistic(stats.txMcastFragments,"txMcastFragments",data);
|
|
data = ipwlan_atheros_make_statistic(stats.txTotalBytes,"txTotalBytes",data);
|
|
data = ipwlan_atheros_make_statistic(stats.txRetry,"txRetry",data);
|
|
data = ipwlan_atheros_make_statistic(stats.txRetryMultiple,"txRetryMultiple",data);
|
|
data = ipwlan_atheros_make_statistic(stats.txRetryFailure,"txRetryFailure",data);
|
|
data = ipwlan_atheros_make_statistic(stats.txAckFailure,"txAckFailure",data);
|
|
data = ipwlan_atheros_make_statistic(stats.txRTSFailure,"txRTSFailure",data);
|
|
data = ipwlan_atheros_make_statistic(stats.txRTSSuccess,"txRTSSuccess",data);
|
|
data = ipwlan_atheros_make_statistic(stats.txHardwareError,"txHardwareError",data);
|
|
data = ipwlan_atheros_make_statistic(stats.txDot1xDropped,"txDot1xDropped",data);
|
|
data = ipwlan_atheros_make_statistic(stats.txBytesPerSec,"txBytesPerSec",data);
|
|
data = ipwlan_atheros_make_statistic(stats.txBytesPer16Sec,"txBytesPer16Sec",data);
|
|
data = ipwlan_atheros_make_statistic(stats.fourWaySuccess,"fourWaySuccess",data);
|
|
data = ipwlan_atheros_make_statistic(stats.fourWayFailure,"fourWayFailure",data);
|
|
data = ipwlan_atheros_make_statistic(stats.groupExchangeSuccess,"groupExchangeSuccess",data);
|
|
data = ipwlan_atheros_make_statistic(stats.groupExchangeFailure,"groupExchangeFailure",data);
|
|
(void)ipwlan_atheros_make_statistic(IP_NULL,IP_NULL,data);
|
|
|
|
break;
|
|
|
|
case IP_SIOCSIWVLAN:
|
|
|
|
ipcom_memset(&value, 0, sizeof(value));
|
|
|
|
value = (int)iw->u.vlan;
|
|
|
|
ret = dot11Ioctl(iw->if_name, EIOCVLANJOIN, (Ip_u32 *)value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
case IP_SIOCGIWVLAN:
|
|
|
|
ipcom_memset(&pVlanReq, 0, sizeof(pVlanReq));
|
|
|
|
pVlanReq.vlanTagCount = 1;
|
|
pVlanReq.pVlanTagData = &vlan;
|
|
|
|
ret = dot11Ioctl(iw->if_name, EIOCVLANGET, &pVlanReq);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
if (pVlanReq.vlanTagCount > 0)
|
|
{
|
|
iw->u.vlan = pVlanReq.pVlanTagData[0];
|
|
}
|
|
else
|
|
{
|
|
iw->u.vlan = 0;
|
|
}
|
|
|
|
break;
|
|
|
|
case IP_SIOCSIWVLANADD:
|
|
|
|
ret = IPCOM_SUCCESS;
|
|
break;
|
|
|
|
case IP_SIOCSIWVLANDEL:
|
|
|
|
ret = IPCOM_SUCCESS;
|
|
break;
|
|
|
|
case IP_SIOCSIWDEFAULTKEY:
|
|
|
|
if (iw->u.key.index > DOT11_MAX_DEFAULT_KEY)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_INVALID_ARG;
|
|
break;
|
|
}
|
|
|
|
value = (int)iw->u.key.index;
|
|
|
|
ret = dot11Ioctl(iw->if_name, WIOCSWEPDEFAULTKEY, (Ip_u32 *)value);
|
|
if (ret < 0)
|
|
{
|
|
ret = IPWLAN_ATHEROS_ERR_FAILED;
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ret = 1; /* > 0 means unhandled command */
|
|
break;
|
|
}
|
|
ipcom_free(acl);
|
|
ipcom_free(res);
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
****************************************************************************
|
|
* END OF FILE
|
|
****************************************************************************
|
|
*/
|
|
|