/* ****************************************************************************** * 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 ****************************************************************************** */ /* **************************************************************************** * 1 DESCRIPTION **************************************************************************** */ /* **************************************************************************** * 2 CONFIGURATION **************************************************************************** */ /* **************************************************************************** * 3 INCLUDE FILES **************************************************************************** */ #define IPCOM_USE_CLIB_PROTO #include #include #include #include #include #include #include #include #include #include #include #include #include /* **************************************************************************** * 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 **************************************************************************** */