Files
m241Neelima/components/ip_net2-6.9/ipwlan/src/ipwlan_atheros.c
T
2026-07-30 11:19:44 +05:30

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
****************************************************************************
*/