/kern_2.6.32/drivers/net/wireless/bcm4329/src/wl/sys/wl_iw.c
http://omnia2droid.googlecode.com/ · C · 7874 lines · 6263 code · 1534 blank · 77 comment · 1031 complexity · 0d24aa2c9517cc7cfbefc1af7086e842 MD5 · raw file
Large files are truncated click here to view the full file
- /*
- * Linux Wireless Extensions support
- *
- * Copyright (C) 1999-2010, Broadcom Corporation
- *
- * Unless you and Broadcom execute a separate written software license
- * agreement governing use of this software, this software is licensed to you
- * under the terms of the GNU General Public License version 2 (the "GPL"),
- * available at http://www.broadcom.com/licenses/GPLv2.php, with the
- * following added to such license:
- *
- * As a special exception, the copyright holders of this software give you
- * permission to link this software with independent modules, and to copy and
- * distribute the resulting executable under terms of your choice, provided that
- * you also meet, for each linked independent module, the terms and conditions of
- * the license of that module. An independent module is a module which is not
- * derived from this software. The special exception does not apply to any
- * modifications of the software.
- *
- * Notwithstanding the above, under no circumstances may you combine this
- * software in any way with any other Broadcom software provided under a license
- * other than the GPL, without Broadcom's express prior written consent.
- *
- * $Id: wl_iw.c,v 1.51.4.9.2.6.4.107 2010/05/03 19:44:32 Exp $
- */
- #include <typedefs.h>
- #include <linuxver.h>
- #include <osl.h>
- #include <bcmutils.h>
- #include <bcmendian.h>
- #include <proto/ethernet.h>
- #include <linux/if_arp.h>
- #include <asm/uaccess.h>
- #include <dngl_stats.h>
- #include <dhd.h>
- #include <dhdioctl.h>
- typedef void wlc_info_t;
- typedef void wl_info_t;
- typedef const struct si_pub si_t;
- #include <wlioctl.h>
- #include <proto/ethernet.h>
- #include <dngl_stats.h>
- #include <dhd.h>
- #define WL_ERROR(x) printf x
- #define WL_TRACE(x)
- #define WL_ASSOC(x)
- #define WL_INFORM(x)
- #define WL_WSEC(x)
- #include <wl_iw.h>
- #ifndef IW_ENCODE_ALG_SM4
- #define IW_ENCODE_ALG_SM4 0x20
- #endif
- #ifndef IW_AUTH_WAPI_ENABLED
- #define IW_AUTH_WAPI_ENABLED 0x20
- #endif
- #ifndef IW_AUTH_WAPI_VERSION_1
- #define IW_AUTH_WAPI_VERSION_1 0x00000008
- #endif
- #ifndef IW_AUTH_CIPHER_SMS4
- #define IW_AUTH_CIPHER_SMS4 0x00000020
- #endif
- #ifndef IW_AUTH_KEY_MGMT_WAPI_PSK
- #define IW_AUTH_KEY_MGMT_WAPI_PSK 4
- #endif
- #ifndef IW_AUTH_KEY_MGMT_WAPI_CERT
- #define IW_AUTH_KEY_MGMT_WAPI_CERT 8
- #endif
- #define IW_WSEC_ENABLED(wsec) ((wsec) & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED))
- #include <linux/rtnetlink.h>
- #include <linux/sched.h>
- #define WL_IW_USE_ISCAN 1
- #define ENABLE_ACTIVE_PASSIVE_SCAN_SUPPRESS 1
- #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1
- struct mutex g_wl_ss_scan_lock;
- #endif
- #if defined(SOFTAP)
- #define WL_SOFTAP(x) printk x
- static struct net_device *priv_dev;
- static bool ap_cfg_running = FALSE;
- bool ap_fw_loaded = FALSE;
- static bool fw_reload_iscall = FALSE;
- struct net_device *ap_net_dev = NULL;
- struct semaphore ap_eth_sema;
- static int wl_iw_set_ap_security(struct net_device *dev, struct ap_profile *ap);
- static int wl_iw_softap_deassoc_stations(struct net_device *dev);
- #endif
- #define WL_IW_IOCTL_CALL(func_call) \
- do { \
- func_call; \
- } while (0)
- static int g_onoff = G_WLAN_SET_ON;
- extern bool wl_iw_conn_status_str(uint32 event_type, uint32 status,
- uint32 reason, char* stringBuf, uint buflen);
- #include <bcmsdbus.h>
- extern void dhd_customer_gpio_wlan_ctrl(int onoff);
- extern uint dhd_dev_reset(struct net_device *dev, uint8 flag);
- extern void dhd_dev_init_ioctl(struct net_device *dev);
- int dev_iw_write_cfg1_bss_var(struct net_device *dev, int val);
- extern int dhd_deepsleep(struct net_device *dev, int flag);
- extern int dhd_set_suspend(int value, dhd_pub_t *dhd);
- extern uint dhd_pkt_filter_enable;
- extern uint dhd_master_mode;
- extern void dhd_pktfilter_offload_enable(dhd_pub_t * dhd, char *arg, int enable, int master_mode);
- uint wl_msg_level = WL_ERROR_VAL;
- #define MAX_WLIW_IOCTL_LEN 1024
- #if defined(IL_BIGENDIAN)
- #include <bcmendian.h>
- #define htod32(i) (bcmswap32(i))
- #define htod16(i) (bcmswap16(i))
- #define dtoh32(i) (bcmswap32(i))
- #define dtoh16(i) (bcmswap16(i))
- #define htodchanspec(i) htod16(i)
- #define dtohchanspec(i) dtoh16(i)
- #else
- #define htod32(i) i
- #define htod16(i) i
- #define dtoh32(i) i
- #define dtoh16(i) i
- #define htodchanspec(i) i
- #define dtohchanspec(i) i
- #endif
- #ifdef CONFIG_WIRELESS_EXT
- extern struct iw_statistics *dhd_get_wireless_stats(struct net_device *dev);
- extern int dhd_wait_pend8021x(struct net_device *dev);
- #endif
- #if WIRELESS_EXT < 19
- #define IW_IOCTL_IDX(cmd) ((cmd) - SIOCIWFIRST)
- #define IW_EVENT_IDX(cmd) ((cmd) - IWEVFIRST)
- #endif
- static void *g_scan = NULL;
- static volatile uint g_scan_specified_ssid;
- static wlc_ssid_t g_specific_ssid;
- static wlc_ssid_t g_ssid;
- static wl_iw_ss_cache_ctrl_t g_ss_cache_ctrl;
- static volatile uint g_first_broadcast_scan;
- #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
- #define DAEMONIZE(a) daemonize(a); \
- allow_signal(SIGKILL); \
- allow_signal(SIGTERM);
- #else
- #define RAISE_RX_SOFTIRQ() \
- cpu_raise_softirq(smp_processor_id(), NET_RX_SOFTIRQ)
- #define DAEMONIZE(a) daemonize(); \
- do { if (a) \
- strncpy(current->comm, a, MIN(sizeof(current->comm), (strlen(a) + 1))); \
- } while (0);
- #endif
- /* regulation mapping information */
- struct country_rev {
- char country_abbrev[WLC_CNTRY_BUF_SZ];
- int32 rev; /*regulatory revision*/
- } country_rev_map[] = {
- {"KR",3}
- };
- #if defined(WL_IW_USE_ISCAN)
- static void wl_iw_free_ss_cache(void);
- static int wl_iw_run_ss_cache_timer(int kick_off);
- int wl_iw_iscan_set_scan_broadcast_prep(struct net_device *dev, uint flag);
- static int dev_wlc_bufvar_set(struct net_device *dev, char *name, char *buf, int len);
- #define ISCAN_STATE_IDLE 0
- #define ISCAN_STATE_SCANING 1
- #define WLC_IW_ISCAN_MAXLEN 2048
- typedef struct iscan_buf {
- struct iscan_buf * next;
- char iscan_buf[WLC_IW_ISCAN_MAXLEN];
- } iscan_buf_t;
- typedef struct iscan_info {
- struct net_device *dev;
- struct timer_list timer;
- uint32 timer_ms;
- uint32 timer_on;
- int iscan_state;
- iscan_buf_t * list_hdr;
- iscan_buf_t * list_cur;
-
- long sysioc_pid;
- struct semaphore sysioc_sem;
- struct completion sysioc_exited;
- uint32 scan_flag;
- char ioctlbuf[WLC_IOCTL_SMLEN];
- } iscan_info_t;
- #define COEX_DHCP 1
- static void wl_iw_bt_flag_set(struct net_device *dev, bool set);
- static void wl_iw_bt_release(void);
- typedef enum bt_coex_status {
- BT_DHCP_IDLE = 0,
- BT_DHCP_START,
- BT_DHCP_OPPORTUNITY_WINDOW,
- BT_DHCP_FLAG_FORCE_TIMEOUT
- } coex_status_t;
- /* BT COEX FIX */
- #define BT_DHCP_OPPORTUNITY_WINDOW_TIEM 100
- #define BT_DHCP_FLAG_FORCE_TIME 1000
- typedef struct bt_info {
- struct net_device *dev;
- struct timer_list timer;
- uint32 timer_ms;
- uint32 timer_on;
- int bt_state;
-
- long bt_pid;
- struct semaphore bt_sem;
- struct completion bt_exited;
- } bt_info_t;
- bt_info_t *g_bt = NULL;
- static void wl_iw_bt_timerfunc(ulong data);
- iscan_info_t *g_iscan = NULL;
- static void wl_iw_timerfunc(ulong data);
- static void wl_iw_set_event_mask(struct net_device *dev);
- static int
- wl_iw_iscan(iscan_info_t *iscan, wlc_ssid_t *ssid, uint16 action);
- #endif
- #ifdef FEATURE_HOTSPOT_EVENT
- #define HOTSPOT_INFO_MAX 30
- #define HOTSPOT_QUEUE_PROCESSING_SUCCESS 0
- #define HOTSPOT_QUEUE_PROCESSING_FAIL -1
- typedef struct _hotspot_info
- {
- char hotspot_info_str[HOTSPOT_INFO_MAX];
- struct net_device *hotspot_info_netdevice;
- struct _hotspot_info *prev;
- struct _hotspot_info *next;
- } hotspot_info;
- static int hot_spot_info_queue_cnt = 0;
- hotspot_info *hotspot_head_p, *hotspot_tail_p;
- int hotspot_init_flag = 0;
- int init_hotspot_info_queue(void);
- void clear_hotspot_info_queue(void);
- int enqueue_hotspot_info_queue(char *str);
- int dequeue_hotspot_info_queue(char *str);
- int dequeue_hotspot_info_queue_size(void);
- int init_hotspot_info_queue(void)
- {
- hotspot_info *t;
- if(hotspot_init_flag)
- {
- WL_SOFTAP(("[Lego]init_hotspot_info_queue is already initilized"));
- return HOTSPOT_QUEUE_PROCESSING_FAIL;
- }
- if (!(hotspot_head_p = (hotspot_info *)kmalloc(sizeof(hotspot_info), GFP_KERNEL)))
- return -ENOMEM;
- if (!(hotspot_tail_p = (hotspot_info *)kmalloc(sizeof(hotspot_info), GFP_KERNEL)))
- return -ENOMEM;
- t = hotspot_head_p;
- // t->cnt = 0;
- hot_spot_info_queue_cnt = 0;
- hotspot_head_p->prev = hotspot_head_p;
- hotspot_head_p->next = hotspot_tail_p;
- hotspot_tail_p->prev = hotspot_head_p;
- hotspot_tail_p->next = hotspot_tail_p;
- hotspot_init_flag = 1;
- #if 0
- WL_SOFTAP(("[Lego]enqueue_hotspot_info_queue:%s\n", "START_1"));
- enqueue_hotspot_info_queue("START_1");
- WL_SOFTAP(("[Lego]enqueue_hotspot_info_queue:%s\n", "START_2"));
- enqueue_hotspot_info_queue("START_2");
- WL_SOFTAP(("[Lego]enqueue_hotspot_info_queue:%s\n", "START_3"));
- enqueue_hotspot_info_queue("START_3");
- WL_SOFTAP(("[Lego]enqueue_hotspot_info_queue:%s\n", "START_4"));
- enqueue_hotspot_info_queue("START_4");
- WL_SOFTAP(("[Lego]enqueue_hotspot_info_queue:%s\n", "START_5"));
- enqueue_hotspot_info_queue("START_5");
- WL_SOFTAP(("[Lego]enqueue_hotspot_info_queue:%s\n", "START_6"));
- enqueue_hotspot_info_queue("START_6");
- WL_SOFTAP(("[Lego]enqueue_hotspot_info_queue:%s\n", "START_7"));
- enqueue_hotspot_info_queue("START_7");
- #endif
- return HOTSPOT_QUEUE_PROCESSING_SUCCESS;
- }
- void clear_hotspot_info_queue(void)
- {
- hotspot_info *t;
- hotspot_info *s;
- if(!hotspot_init_flag)
- {
- WL_SOFTAP(("[Lego]clear_hotspot_info_queue is not worked\n"));
- return;
- }
- t = hotspot_head_p->next;
- while(t != hotspot_tail_p)
- {
- s = t;
- t = t->next;
- kfree(s);
- }
-
- hot_spot_info_queue_cnt = 0;
- hotspot_head_p->next = hotspot_tail_p;
- hotspot_tail_p->prev = hotspot_head_p;
- hotspot_init_flag = 0;
- WL_SOFTAP(("[Lego]clear_hotspot_info_queue:%s\n", "CLEAR"));
- }
- int enqueue_hotspot_info_queue(char *str)
- {
- hotspot_info *t;
- #ifdef FEATURE_HOTSPOT_EVENT
- int hotspot_ret = 0;
- WL_SOFTAP(("init_hotspot_info_queue()"));
- hotspot_ret = init_hotspot_info_queue();
- if(hotspot_ret != HOTSPOT_QUEUE_PROCESSING_SUCCESS)
- printf("\nQueue initialization Fail!!\n");
- #endif
- WL_SOFTAP(("[Lego]enqueue_hotspot_info_queue:%s\n", str));
- if(!hotspot_init_flag)
- {
- WL_SOFTAP(("[Lego]hotspot_init_flag fail:%s\n", str));
- return HOTSPOT_QUEUE_PROCESSING_FAIL;
- }
- if(!(t = (hotspot_info *)kmalloc(sizeof(hotspot_info), GFP_KERNEL)))
- return -ENOMEM;
- if(strlen(str) <= HOTSPOT_INFO_MAX-1)
- {
- strncpy(t->hotspot_info_str, str, strlen(str)+1);
- }
- else
- {
- strncpy(t->hotspot_info_str, str, HOTSPOT_INFO_MAX-1);
- t->hotspot_info_str[HOTSPOT_INFO_MAX-1] = '\0';
- }
- hot_spot_info_queue_cnt++;
- hotspot_tail_p->prev->next = t;
- t->prev = hotspot_tail_p->prev;
- hotspot_tail_p->prev = t;
- t->next = hotspot_tail_p;
- return HOTSPOT_QUEUE_PROCESSING_SUCCESS;
- }
- int dequeue_hotspot_info_queue(char *str)
- {
- hotspot_info *t;
- t = hotspot_head_p->next;
- if(!hotspot_init_flag)
- {
- WL_SOFTAP(("[Lego]hotspot_init_flag fail:%s\n", str));
- return HOTSPOT_QUEUE_PROCESSING_FAIL;
- }
- if(t == hotspot_tail_p)
- {
- printf("\nHotspot Queue Underflow!!! \n");
- return HOTSPOT_QUEUE_PROCESSING_FAIL;
- }
- if(strlen(t->hotspot_info_str) <= HOTSPOT_INFO_MAX-1)
- {
- strncpy(str, t->hotspot_info_str, strlen(t->hotspot_info_str)+1);
- }
- else
- {
- strncpy(str, t->hotspot_info_str, HOTSPOT_INFO_MAX-1);
- str[HOTSPOT_INFO_MAX-1] = '\0';
- }
- if(hot_spot_info_queue_cnt)
- hot_spot_info_queue_cnt--;
- hotspot_head_p->next = t->next;
- t->next->prev = hotspot_head_p;
- kfree(t);
- return HOTSPOT_QUEUE_PROCESSING_SUCCESS;
- }
- int dequeue_hotspot_info_queue_size(void)
- {
- #if 0
- hotspot_info *t;
- int ret = -1;
- t = hotspot_head_p->next;
- if(t == hotspot_tail_p)
- {
- printf("\nHotspot Queue Underflow!!! \n");
- return ret;
- }
- hotspot_head_p->next = t->next;
- t->next->prev = hotspot_head_p;
- kfree(t);
- #endif
- return hot_spot_info_queue_cnt;
- }
- int get_hotspot_info_queue_wrapper(
- struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *dwrq, char *cmd_str)
- {
- static char get_str[HOTSPOT_INFO_MAX];
- int retval;
- memset(get_str, 0, sizeof(get_str));
-
- retval = dequeue_hotspot_info_queue(get_str);
- WL_SOFTAP(("[Lego]get_hotspot_info_queue_wrapper : %d\n", retval));
- if(get_str[0] == NULL)
- {
- copy_to_user(dwrq->data.pointer, get_str, sizeof(get_str));
- WL_SOFTAP(("[Lego]get_hotspot_info_queue_wrapper : get_str null %d\n", retval));
- return HOTSPOT_QUEUE_PROCESSING_FAIL;
- }
- else
- {
- WL_SOFTAP(("[Lego]get_hotspot_info_queue_wrapper : %s\n", get_str));
- copy_to_user(dwrq->data.pointer, get_str, sizeof(get_str));
- WL_SOFTAP(("[Lego]get_hotspot_info_queue_wrapper end : %s\n", get_str));
- return HOTSPOT_QUEUE_PROCESSING_SUCCESS;
- }
- }
- int get_hotspot_info_queue_size_wrapper(
- struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *dwrq, char *cmd_str)
- {
- int ret = dequeue_hotspot_info_queue_size();
- WL_SOFTAP(("[Lego]get_hotspot_info_queue_size_wrapper : %d\n", ret));
- if(ret < 0)
- {
- ret = 0;
- copy_to_user(dwrq->data.pointer, &ret, sizeof(int));
- WL_SOFTAP(("[Lego]get_hotspot_info_queue_size_wrapper : fail %d\n", ret));
- WL_SOFTAP(("[Lego]get_hotspot_info_queue_size_wrapper : fail %s\n", (char *)dwrq->data.pointer));
- return HOTSPOT_QUEUE_PROCESSING_FAIL;
- }
- else
- {
- WL_SOFTAP(("[Lego]get_hotspot_info_queue_size_wrapper : success1 %d\n", ret));
- copy_to_user(dwrq->data.pointer, &ret, sizeof(int));
- WL_SOFTAP(("[Lego]get_hotspot_info_queue_size_wrapper : success2 %s\n", (char *)dwrq->data.pointer));
- return HOTSPOT_QUEUE_PROCESSING_SUCCESS;
- }
- }
- #endif
- static int
- wl_iw_set_scan(
- struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra
- );
- static int
- wl_iw_get_scan(
- struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *dwrq,
- char *extra
- );
- static uint
- wl_iw_get_scan_prep(
- wl_scan_results_t *list,
- struct iw_request_info *info,
- char *extra,
- short max_size
- );
- static void swap_key_from_BE(
- wl_wsec_key_t *key
- )
- {
- key->index = htod32(key->index);
- key->len = htod32(key->len);
- key->algo = htod32(key->algo);
- key->flags = htod32(key->flags);
- key->rxiv.hi = htod32(key->rxiv.hi);
- key->rxiv.lo = htod16(key->rxiv.lo);
- key->iv_initialized = htod32(key->iv_initialized);
- }
- static void swap_key_to_BE(
- wl_wsec_key_t *key
- )
- {
- key->index = dtoh32(key->index);
- key->len = dtoh32(key->len);
- key->algo = dtoh32(key->algo);
- key->flags = dtoh32(key->flags);
- key->rxiv.hi = dtoh32(key->rxiv.hi);
- key->rxiv.lo = dtoh16(key->rxiv.lo);
- key->iv_initialized = dtoh32(key->iv_initialized);
- }
- static int
- dev_wlc_ioctl(
- struct net_device *dev,
- int cmd,
- void *arg,
- int len
- )
- {
- struct ifreq ifr;
- wl_ioctl_t ioc;
- mm_segment_t fs;
- int ret = -1;
- if (!dev) {
- WL_ERROR(("%s: dev is null\n", __FUNCTION__));
- return ret;
- }
- if (dev->reg_state >= NETREG_UNREGISTERING)
- return ret;
- WL_TRACE(("%s, PID:%x: send Local IOCTL -> dhd: cmd:0x%x, buf:%p, len:%d\n",
- __FUNCTION__, current->pid, cmd, arg, len));
- memset(&ioc, 0, sizeof(ioc));
- ioc.cmd = cmd;
- ioc.buf = arg;
- ioc.len = len;
- strcpy(ifr.ifr_name, dev->name);
- ifr.ifr_data = (caddr_t) &ioc;
-
- dev_open(dev);
- fs = get_fs();
- set_fs(get_ds());
- #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31)
- ret = dev->do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
- #else
- ret = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
- #endif
- set_fs(fs);
- return ret;
- }
- static int
- dev_wlc_intvar_get_reg(
- struct net_device *dev,
- char *name,
- uint reg,
- int *retval)
- {
- union {
- char buf[WLC_IOCTL_SMLEN];
- int val;
- } var;
- int error;
- uint len;
- len = bcm_mkiovar(name, (char *)(®), sizeof(reg), (char *)(&var), sizeof(var.buf));
- ASSERT(len);
- error = dev_wlc_ioctl(dev, WLC_GET_VAR, (void *)&var, len);
- *retval = dtoh32(var.val);
- return (error);
- }
- static int
- dev_wlc_intvar_set_reg(
- struct net_device *dev,
- char *name,
- char *addr,
- char * val)
- {
- char reg_addr[8];
- memset(reg_addr, 0, sizeof(reg_addr));
- memcpy((char *)®_addr[0], (char *)addr, 4);
- memcpy((char *)®_addr[4], (char *)val, 4);
- return (dev_wlc_bufvar_set(dev, name, (char *)®_addr[0], sizeof(reg_addr)));
- }
- static int
- dev_wlc_intvar_set(
- struct net_device *dev,
- char *name,
- int val)
- {
- char buf[WLC_IOCTL_SMLEN];
- uint len;
- val = htod32(val);
- len = bcm_mkiovar(name, (char *)(&val), sizeof(val), buf, sizeof(buf));
- ASSERT(len);
- return (dev_wlc_ioctl(dev, WLC_SET_VAR, buf, len));
- }
- #if defined(WL_IW_USE_ISCAN)
- static int
- dev_iw_iovar_setbuf(
- struct net_device *dev,
- char *iovar,
- void *param,
- int paramlen,
- void *bufptr,
- int buflen)
- {
- int iolen;
- iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen);
- ASSERT(iolen);
- return (dev_wlc_ioctl(dev, WLC_SET_VAR, bufptr, iolen));
- }
- static int
- dev_iw_iovar_getbuf(
- struct net_device *dev,
- char *iovar,
- void *param,
- int paramlen,
- void *bufptr,
- int buflen)
- {
- int iolen;
- iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen);
- ASSERT(iolen);
- return (dev_wlc_ioctl(dev, WLC_GET_VAR, bufptr, buflen));
- }
- #endif
- #if WIRELESS_EXT > 17
- static int
- dev_wlc_bufvar_set(
- struct net_device *dev,
- char *name,
- char *buf, int len)
- {
- #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31)
- char ioctlbuf[MAX_WLIW_IOCTL_LEN];
- #else
- static char ioctlbuf[MAX_WLIW_IOCTL_LEN];
- #endif
- uint buflen;
- buflen = bcm_mkiovar(name, buf, len, ioctlbuf, sizeof(ioctlbuf));
- ASSERT(buflen);
- return (dev_wlc_ioctl(dev, WLC_SET_VAR, ioctlbuf, buflen));
- }
- #endif
- static int
- dev_wlc_bufvar_get(
- struct net_device *dev,
- char *name,
- char *buf, int buflen)
- {
- #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31)
- char ioctlbuf[MAX_WLIW_IOCTL_LEN];
- #else
- static char ioctlbuf[MAX_WLIW_IOCTL_LEN];
- #endif
- int error;
- uint len;
- len = bcm_mkiovar(name, NULL, 0, ioctlbuf, sizeof(ioctlbuf));
- ASSERT(len);
- error = dev_wlc_ioctl(dev, WLC_GET_VAR, (void *)ioctlbuf, MAX_WLIW_IOCTL_LEN);
- if (!error)
- bcopy(ioctlbuf, buf, buflen);
- return (error);
- }
- static int
- dev_wlc_intvar_get(
- struct net_device *dev,
- char *name,
- int *retval)
- {
- union {
- char buf[WLC_IOCTL_SMLEN];
- int val;
- } var;
- int error;
- uint len;
- uint data_null;
- len = bcm_mkiovar(name, (char *)(&data_null), 0, (char *)(&var), sizeof(var.buf));
- ASSERT(len);
- error = dev_wlc_ioctl(dev, WLC_GET_VAR, (void *)&var, len);
- *retval = dtoh32(var.val);
- return (error);
- }
- #if WIRELESS_EXT > 12
- static int
- wl_iw_set_active_scan(
- struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra
- )
- {
- int as = 0;
- int error = 0;
- char *p = extra;
- #if defined(WL_IW_USE_ISCAN)
- if (g_iscan->iscan_state == ISCAN_STATE_IDLE)
- #endif
- error = dev_wlc_ioctl(dev, WLC_SET_PASSIVE_SCAN, &as, sizeof(as));
- #if defined(WL_IW_USE_ISCAN)
- else
- g_iscan->scan_flag = as;
- #endif
- p += snprintf(p, MAX_WX_STRING, "OK");
- wrqu->data.length = p - extra + 1;
- return error;
- }
- static int
- wl_iw_set_passive_scan(
- struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra
- )
- {
- int ps = 1;
- int error = 0;
- char *p = extra;
- #if defined(WL_IW_USE_ISCAN)
- if (g_iscan->iscan_state == ISCAN_STATE_IDLE) {
- #endif
-
- if (g_scan_specified_ssid == 0) {
- error = dev_wlc_ioctl(dev, WLC_SET_PASSIVE_SCAN, &ps, sizeof(ps));
- }
- #if defined(WL_IW_USE_ISCAN)
- }
- else
- g_iscan->scan_flag = ps;
- #endif
- p += snprintf(p, MAX_WX_STRING, "OK");
- wrqu->data.length = p - extra + 1;
- return error;
- }
- static int
- wl_iw_get_macaddr(
- struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra
- )
- {
- int error;
- char buf[128];
- struct ether_addr *id;
- char *p = extra;
-
- strcpy(buf, "cur_etheraddr");
- error = dev_wlc_ioctl(dev, WLC_GET_VAR, buf, sizeof(buf));
- id = (struct ether_addr *) buf;
- p += snprintf(p, MAX_WX_STRING, "Macaddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
- id->octet[0], id->octet[1], id->octet[2],
- id->octet[3], id->octet[4], id->octet[5]);
- wrqu->data.length = p - extra + 1;
- return error;
- }
- static int
- wl_iw_set_country(
- struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra
- )
- {
- char country_code[WLC_CNTRY_BUF_SZ];
- int error = 0;
- char *p = extra;
- int country_offset;
- int country_code_size;
- wl_country_t cspec = {{0},0,{0}};
- int size = 0;
- int i = 0;
- size = ARRAYSIZE(country_rev_map);
- memset(country_code, 0, sizeof(country_code));
-
- country_offset = strcspn(extra, " ");
- country_code_size = strlen(extra) - country_offset;
-
- if (country_offset != 0) {
- strncpy(country_code, extra + country_offset +1,
- MIN(country_code_size, sizeof(country_code)));
- if (!strncmp(country_code,"EU",2)) {
- strncpy(country_code,"GB",2);
- WL_TRACE(("wl_iw_set_country : set country from EU to GB\n"));
- }
- for (i = 0 ; i < size ; i++) {
- if(!strcmp(country_code,country_rev_map[i].country_abbrev)) {
- strncpy(cspec.ccode,country_rev_map[i].country_abbrev,2);
- strncpy(cspec.country_abbrev,country_rev_map[i].country_abbrev,2);
- cspec.rev = country_rev_map[i].rev;
-
- error = dev_wlc_bufvar_set(dev, "country",(char *)&cspec, sizeof(cspec));
- if (!error)
- goto exit;
- }
- }
- if ((error = dev_wlc_ioctl(dev, WLC_SET_COUNTRY,
- &country_code, sizeof(country_code))) >= 0) {
- p += snprintf(p, MAX_WX_STRING, "OK");
- WL_TRACE(("%s: set country %s OK\n", __FUNCTION__, country_code));
- goto exit;
- }
- }
- WL_ERROR(("%s: set country %s failed code %d\n", __FUNCTION__, country_code, error));
- p += snprintf(p, MAX_WX_STRING, "FAIL");
- exit:
- wrqu->data.length = p - extra + 1;
- return error;
- }
- #ifdef CUSTOMER_HW2
- static int
- wl_iw_set_power_mode(
- struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra
- )
- {
- int error = 0;
- char *p = extra;
- static int pm = PM_FAST;
- int pm_local = PM_OFF;
- char powermode_val = 0;
- strncpy((char *)&powermode_val, extra + strlen("POWERMODE") +1, 1);
- if (strnicmp((char *)&powermode_val, "1", strlen("1")) == 0) {
- WL_TRACE(("%s: DHCP session starts\n", __FUNCTION__));
- dev_wlc_ioctl(dev, WLC_GET_PM, &pm, sizeof(pm));
- dev_wlc_ioctl(dev, WLC_SET_PM, &pm_local, sizeof(pm_local));
- }
- else if (strnicmp((char *)&powermode_val, "0", strlen("0")) == 0) {
- WL_TRACE(("%s: DHCP session done\n", __FUNCTION__));
- dev_wlc_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm));
- }
- else {
- WL_ERROR(("Unkwown yet power setting, ignored\n"));
- }
- p += snprintf(p, MAX_WX_STRING, "OK");
- wrqu->data.length = p - extra + 1;
- return error;
- }
- #endif
- static int
- wl_iw_set_btcoex_dhcp(
- struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra
- )
- {
- int error = 0;
- char *p = extra;
- #ifndef CUSTOMER_HW2
- static int pm = PM_FAST;
- int pm_local = PM_OFF;
- #endif
- wl_iw_t * iw = *(wl_iw_t **)netdev_priv(dev);
- dhd_pub_t * dhd = iw->pub;
- int i = 0;
- char powermode_val = 0;
- char buf_reg66va_dhcp_on[8] = { 66, 00, 00, 00, 0x10, 0x27, 0x00, 0x00 };
- char buf_reg41va_dhcp_on[8] = { 41, 00, 00, 00, 0x33, 0x00, 0x00, 0x00 };
- char buf_reg68va_dhcp_on[8] = { 68, 00, 00, 00, 0x90, 0x01, 0x00, 0x00 };
- uint32 regaddr;
- static uint32 saved_reg66;
- static uint32 saved_reg41;
- static uint32 saved_reg68;
- static bool saved_status = FALSE;
- char buf_flag7_default[8] = { 7, 00, 00, 00, 0x0, 0x00, 0x00, 0x00};
- #ifndef CUSTOMER_HW2
- uint32 temp1, temp2, temp3;
- #endif
-
- #ifdef CUSTOMER_HW2
- strncpy((char *)&powermode_val, extra + strlen("BTCOEXMODE") +1, 1);
- #else
- strncpy((char *)&powermode_val, extra + strlen("POWERMODE") +1, 1);
- #endif
- if (strnicmp((char *)&powermode_val, "1", strlen("1")) == 0) {
- WL_TRACE(("%s: DHCP session starts\n", __FUNCTION__));
-
- dhd->dhcp_in_progress = 1;
-
- /*disable packet filtering*/
- if (dhd_pkt_filter_enable && dhd->early_suspended) {
- WL_TRACE(("DHCP in progressing , disable packet filter!!!\n"));
- for (i = 0; i < dhd->pktfilter_count; i++) {
- dhd_pktfilter_offload_enable(dhd, dhd->pktfilter[i],
- 0, dhd_master_mode);
- }
- }
-
- if ((saved_status == FALSE) &&
- #ifndef CUSTOMER_HW2
- (!dev_wlc_ioctl(dev, WLC_GET_PM, &pm, sizeof(pm))) &&
- #endif
- (!dev_wlc_intvar_get_reg(dev, "btc_params", 66, &saved_reg66)) &&
- (!dev_wlc_intvar_get_reg(dev, "btc_params", 41, &saved_reg41)) &&
- (!dev_wlc_intvar_get_reg(dev, "btc_params", 68, &saved_reg68))) {
- saved_status = TRUE;
- WL_TRACE(("Saved 0x%x 0x%x 0x%x\n", \
- saved_reg66, saved_reg41, saved_reg68));
-
- #ifndef CUSTOMER_HW2
- dev_wlc_ioctl(dev, WLC_SET_PM, &pm_local, sizeof(pm_local));
- #endif
-
- dev_wlc_bufvar_set(dev, "btc_params", \
- (char *)&buf_reg66va_dhcp_on[0], \
- sizeof(buf_reg66va_dhcp_on));
-
- dev_wlc_bufvar_set(dev, "btc_params", \
- (char *)&buf_reg41va_dhcp_on[0], \
- sizeof(buf_reg41va_dhcp_on));
-
- dev_wlc_bufvar_set(dev, "btc_params", \
- (char *)&buf_reg68va_dhcp_on[0], \
- sizeof(buf_reg68va_dhcp_on));
-
- #ifndef CUSTOMER_HW2
- if ( ((!dev_wlc_intvar_get_reg(dev, "btc_params", 12, &temp1)) &&
- (!dev_wlc_intvar_get_reg(dev, "btc_params", 13, &temp2)) ) ||
- (!dev_wlc_intvar_get_reg(dev, "btc_params", 27, &temp3)) )
- {
- if ( ((temp1 != 0) && (temp2 != 0)) ||
- (temp3 & 0xf) == 4 )
- {
- #endif
- g_bt->bt_state = BT_DHCP_START;
- g_bt->timer_on = 1;
- mod_timer(&g_bt->timer, g_bt->timer.expires);
- WL_TRACE(("%s enable BT DHCP Timer\n", \
- __FUNCTION__));
- #ifndef CUSTOMER_HW2
- }
- }
- #endif
- }
- else if (saved_status == TRUE) {
- WL_ERROR(("%s was called w/o DHCP OFF. Continue\n", __FUNCTION__));
- }
- }
- #ifdef CUSTOMER_HW2
- else if (strnicmp((char *)&powermode_val, "2", strlen("2")) == 0) {
- #else
- else if (strnicmp((char *)&powermode_val, "0", strlen("0")) == 0) {
- #endif
- dhd->dhcp_in_progress = 0;
- WL_TRACE(("%s: DHCP session done\n", __FUNCTION__));
- if (dhd_pkt_filter_enable && dhd->early_suspended) {
- for (i = 0; i < dhd->pktfilter_count; i++) {
- WL_TRACE(("DHCP is complete , enable packet filter!!!\n"));
- dhd_pktfilter_offload_enable(dhd, dhd->pktfilter[i],
- 1, dhd_master_mode);
- }
- }
-
- #ifndef CUSTOMER_HW2
- dev_wlc_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm));
- #endif
-
- WL_TRACE(("%s disable BT DHCP Timer\n", __FUNCTION__));
- if (g_bt->timer_on) {
- g_bt->timer_on = 0;
- del_timer_sync(&g_bt->timer);
- }
-
- dev_wlc_bufvar_set(dev, "btc_flags", \
- (char *)&buf_flag7_default[0], sizeof(buf_flag7_default));
-
- if (saved_status) {
- regaddr = 66;
- dev_wlc_intvar_set_reg(dev, "btc_params", \
- (char *)®addr, (char *)&saved_reg66);
- regaddr = 41;
- dev_wlc_intvar_set_reg(dev, "btc_params", \
- (char *)®addr, (char *)&saved_reg41);
- regaddr = 68;
- dev_wlc_intvar_set_reg(dev, "btc_params", \
- (char *)®addr, (char *)&saved_reg68);
- }
- saved_status = FALSE;
- }
- else {
- WL_ERROR(("Unkwown yet power setting, ignored\n"));
- }
- p += snprintf(p, MAX_WX_STRING, "OK");
- wrqu->data.length = p - extra + 1;
- return error;
- }
- int
- wl_format_ssid(char* ssid_buf, uint8* ssid, int ssid_len)
- {
- int i, c;
- char *p = ssid_buf;
- if (ssid_len > 32) ssid_len = 32;
- for (i = 0; i < ssid_len; i++) {
- c = (int)ssid[i];
- if (c == '\\') {
- *p++ = '\\';
- *p++ = '\\';
- } else if (isprint((uchar)c)) {
- *p++ = (char)c;
- } else {
- p += sprintf(p, "\\x%02X", c);
- }
- }
- *p = '\0';
- return p - ssid_buf;
- }
- static int
- wl_iw_get_link_speed(
- struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra
- )
- {
- int error = 0;
- char *p = extra;
- static int link_speed;
-
- if (g_onoff == G_WLAN_SET_ON) {
- error = dev_wlc_ioctl(dev, WLC_GET_RATE, &link_speed, sizeof(link_speed));
- link_speed *= 500000;
- }
- p += snprintf(p, MAX_WX_STRING, "LinkSpeed %d", link_speed/1000000);
- wrqu->data.length = p - extra + 1;
- return error;
- }
- static int
- wl_iw_get_rssi(
- struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra
- )
- {
- static int rssi = 0;
- static wlc_ssid_t ssid = {0};
- int error = 0;
- char *p = extra;
- static char ssidbuf[SSID_FMT_BUF_LEN];
- scb_val_t scb_val;
- bzero(&scb_val, sizeof(scb_val_t));
- if (g_onoff == G_WLAN_SET_ON) {
- error = dev_wlc_ioctl(dev, WLC_GET_RSSI, &scb_val, sizeof(scb_val_t));
- rssi = dtoh32(scb_val.val);
- error = dev_wlc_ioctl(dev, WLC_GET_SSID, &ssid, sizeof(ssid));
- ssid.SSID_len = dtoh32(ssid.SSID_len);
- }
- wl_format_ssid(ssidbuf, ssid.SSID, dtoh32(ssid.SSID_len));
- p += snprintf(p, MAX_WX_STRING, "%s rssi %d ", ssidbuf, rssi);
- wrqu->data.length = p - extra + 1;
- return error;
- }
- int
- wl_iw_send_priv_event(
- struct net_device *dev,
- char *flag
- )
- {
- union iwreq_data wrqu;
- char extra[IW_CUSTOM_MAX + 1];
- int cmd;
- #ifdef FEATURE_HOTSPOT_EVENT
- if(ap_cfg_running) {
- enqueue_hotspot_info_queue(flag);
- return 0;
- }
- #endif
- cmd = IWEVCUSTOM;
- memset(&wrqu, 0, sizeof(wrqu));
- if (strlen(flag) > sizeof(extra))
- return -1;
- strcpy(extra, flag);
- wrqu.data.length = strlen(extra);
- wireless_send_event(dev, cmd, &wrqu, extra);
- WL_TRACE(("Send IWEVCUSTOM Event as %s\n", extra));
- return 0;
- }
- int
- wl_control_wl_start(struct net_device *dev)
- {
- int ret = 0;
- wl_iw_t *iw;
- WL_ERROR(("Enter %s \n", __FUNCTION__));
- if (!dev) {
- WL_ERROR(("%s: dev is null\n", __FUNCTION__));
- return -1;
- }
- iw = *(wl_iw_t **)netdev_priv(dev);
- MUTEX_LOCK(iw->pub);
- if (g_onoff == G_WLAN_SET_OFF) {
- if ( fw_reload_iscall == TRUE ) {
- dhd_dev_reset(dev, 1);
- msleep(100);
- #if defined(BCMLXSDMMC)
- sdioh_stop(NULL);
- #endif
- dhd_customer_gpio_wlan_ctrl(WLAN_RESET_OFF);
- msleep(300);
- dhd_customer_gpio_wlan_ctrl(WLAN_RESET_ON);
- msleep(100);
- #if defined(BCMLXSDMMC)
- sdioh_start(NULL, 0);
- #endif
- dhd_dev_reset(dev, 0);
- #if defined(BCMLXSDMMC)
- sdioh_start(NULL, 1);
- #endif
- dhd_dev_init_ioctl(dev);
-
- fw_reload_iscall = FALSE;
- }else {
- dhd_deepsleep(dev, 0); /* DeepSleep Off */
- //dev_open(dev);
- dhd_set_suspend(0, iw->pub);
- }
- g_onoff = G_WLAN_SET_ON;
- }
- WL_ERROR(("Exited %s \n", __FUNCTION__));
- MUTEX_UNLOCK(iw->pub);
- return ret;
- }
- static int
- wl_iw_control_wl_off(
- struct net_device *dev,
- struct iw_request_info *info
- )
- {
- int ret = 0;
- wl_iw_t *iw;
- WL_ERROR(("Enter %s\n", __FUNCTION__));
- if (!dev) {
- WL_ERROR(("%s: dev is null\n", __FUNCTION__));
- return -1;
- }
- iw = *(wl_iw_t **)netdev_priv(dev);
- MUTEX_LOCK(iw->pub);
- if (g_onoff == G_WLAN_SET_OFF) {
- WL_TRACE(("Exited %s: already off\n", __FUNCTION__));
- return ret;
- }
- #ifdef SOFTAP
- ap_cfg_running = FALSE;
- #endif
- g_onoff = G_WLAN_SET_OFF;
- #if defined(WL_IW_USE_ISCAN)
- g_iscan->iscan_state = ISCAN_STATE_IDLE;
- #endif
- #ifdef WLAN_RESET_IN_SUSPEND
- dhd_dev_reset(dev, 1);
- #else
- if (dev == 0) {
- WL_ERROR(("%s: dev is NULL. Skipping deepsleep\n", __FUNCTION__));
- } else {
- dhd_deepsleep(dev, 1); /* DeepSleep On */
- }
- #endif
- #if defined(WL_IW_USE_ISCAN)
- wl_iw_free_ss_cache();
- wl_iw_run_ss_cache_timer(0);
- memset(g_scan, 0, G_SCAN_RESULTS);
- g_ss_cache_ctrl.m_link_down = 1;
- g_scan_specified_ssid = 0;
- g_first_broadcast_scan = BROADCAST_SCAN_FIRST_IDLE;
- #endif
- #ifdef WLAN_RESET_IN_SUSPEND
- #if defined(BCMLXSDMMC)
- sdioh_stop(NULL);
- #endif
- dhd_customer_gpio_wlan_ctrl(WLAN_RESET_OFF);
- #endif
- if (dev == 0) {
- WL_ERROR(("%s: dev is NULL. Skipping sending STOP\n", __FUNCTION__));
- } else {
- wl_iw_send_priv_event(dev, "STOP");
- }
- MUTEX_UNLOCK(iw->pub);
- WL_TRACE(("Exited %s\n", __FUNCTION__));
- return ret;
- }
- static int
- wl_iw_control_wl_on(
- struct net_device *dev,
- struct iw_request_info *info
- )
- {
- int ret = 0;
- WL_TRACE(("Enter %s \n", __FUNCTION__));
- ret = wl_control_wl_start(dev);
- wl_iw_send_priv_event(dev, "START");
- #ifdef SOFTAP
- if (!ap_fw_loaded) {
- wl_iw_iscan_set_scan_broadcast_prep(dev, 0);
- }
- #else
- wl_iw_iscan_set_scan_broadcast_prep(dev, 0);
- #endif
- WL_TRACE(("Exited %s \n", __FUNCTION__));
- return ret;
- }
- #ifdef SOFTAP
- static struct ap_profile my_ap;
- static int set_ap_cfg(struct net_device *dev, struct ap_profile *ap);
- static int get_assoc_sta_list(struct net_device *dev, char *buf, int len);
- static int set_ap_mac_list(struct net_device *dev, char *buf);
- #define PTYPE_STRING 0
- #define PTYPE_INTDEC 1
- #define PTYPE_INTHEX 2
- #define PTYPE_STR_HEX 3
- int get_parmeter_from_string(
- char **str_ptr, const char *token, int param_type, void *dst, int param_max_len);
- #endif
- int hex2num(char c)
- {
- if (c >= '0' && c <= '9')
- return c - '0';
- if (c >= 'a' && c <= 'f')
- return c - 'a' + 10;
- if (c >= 'A' && c <= 'F')
- return c - 'A' + 10;
- return -1;
- }
- int hex2byte(const char *hex)
- {
- int a, b;
- a = hex2num(*hex++);
- if (a < 0)
- return -1;
- b = hex2num(*hex++);
- if (b < 0)
- return -1;
- return (a << 4) | b;
- }
- int hstr_2_buf(const char *txt, u8 *buf, int len)
- {
- int i;
- for (i = 0; i < len; i++) {
- int a, b;
- a = hex2num(*txt++);
- if (a < 0)
- return -1;
- b = hex2num(*txt++);
- if (b < 0)
- return -1;
- *buf++ = (a << 4) | b;
- }
- return 0;
- }
- #ifdef SOFTAP
- int init_ap_profile_from_string(char *param_str, struct ap_profile *ap_cfg)
- {
- char *str_ptr = param_str;
- char sub_cmd[16];
- uint8 sec[SEC_LEN];
- int ret = 0;
- #ifdef NEW_AP_INTERFACE
- uint8 wepkey[KEY_LEN];
- int i, enc;
- struct mflist *maclist = 0;
- #endif
- memset(sub_cmd, 0, sizeof(sub_cmd));
- memset(ap_cfg, 0, sizeof(struct ap_profile));
- WL_SOFTAP(("init_ap_profile_from_string: param=%s\n", param_str));
-
- if (get_parmeter_from_string(&str_ptr, "ASCII_CMD=",
- PTYPE_STRING, sub_cmd, SSID_LEN) != 0) {
- return -1;
- }
- if (strncmp(sub_cmd, "AP_CFG", 6)) {
- WL_ERROR(("ERROR: sub_cmd:%s != 'AP_CFG'!\n", sub_cmd));
- return -1;
- }
-
-
- ret = get_parmeter_from_string(&str_ptr, "SSID=", PTYPE_STRING, ap_cfg->ssid, SSID_LEN);
- ret |= get_parmeter_from_string(&str_ptr, "SEC=", PTYPE_STRING, sec, SEC_LEN);
- ret |= get_parmeter_from_string(&str_ptr, "KEY=", PTYPE_STRING, ap_cfg->key, KEY_LEN);
- ret |= get_parmeter_from_string(&str_ptr, "CHANNEL=", PTYPE_INTDEC, &ap_cfg->channel, 5);
- ret |= get_parmeter_from_string(&str_ptr, "PREAMBLE=", PTYPE_INTDEC, &ap_cfg->preamble, 5);
- ret |= get_parmeter_from_string(&str_ptr, "MAX_SCB=", PTYPE_INTDEC, &ap_cfg->max_scb, 5);
- #ifdef NEW_AP_INTERFACE
- ret |= get_parmeter_from_string(&str_ptr, "HIDE=", PTYPE_INTDEC, &ap_cfg->hidden_ssid, 5);
- ret |= get_parmeter_from_string(&str_ptr, "GROUP_CIPHER=", PTYPE_INTDEC, &enc, SEC_LEN);
- strcpy(ap_cfg->sec, sec);
- if ((enc == 0) || (enc == 1)) {
- if (strcmp(sec, "open") == 0) {
- /* using WEP */
- strcpy(ap_cfg->sec, "wep");
- ap_cfg->is_wep = 1;
- } else {
- WL_ERROR(("%s: Invalid combo - sec=%s, enc=%d\n", __FUNCTION__, sec, enc));
- }
- } else if (enc == 2) {
- /* TKIP */
- strcpy(ap_cfg->sec, "wpa-psk");
- }
- ret |= get_parmeter_from_string(&str_ptr, "802.11_MODE=", PTYPE_INTDEC, &ap_cfg->op_mode, 5);
- ret |= get_parmeter_from_string(&str_ptr, "WEP_KEY_INDEX=", PTYPE_INTDEC, &ap_cfg->key_index, 5);
- ret |= get_parmeter_from_string(&str_ptr, "WEP_KEY=", PTYPE_STRING, wepkey, KEY_LEN);
- if (ap_cfg->is_wep) {
- strcpy(ap_cfg->key, wepkey);
- }
- ret |= get_parmeter_from_string(&str_ptr, "WHITELIST_MAC_COUNT=", PTYPE_INTDEC, &ap_cfg->mac_filter.white_list.count, 5);
- ret |= get_parmeter_from_string(&str_ptr, "WHITELIST_MAC_LIST=", PTYPE_STR_HEX, ap_cfg->mac_filter.white_list.ea, sizeof(ap_cfg->mac_filter.white_list.ea));
- ret |= get_parmeter_from_string(&str_ptr, "BLACKLIST_MAC_COUNT=", PTYPE_INTDEC, &ap_cfg->mac_filter.black_list.count, 5);
- ret |= get_parmeter_from_string(&str_ptr, "BLACKLIST_MAC_LIST=", PTYPE_STR_HEX, ap_cfg->mac_filter.black_list.ea, sizeof(ap_cfg->mac_filter.black_list.ea));
- if (ap_cfg->mac_filter.black_list.count && ap_cfg->mac_filter.black_list.count) {
- WL_ERROR(("%s: black list & white list are mutually exclusive. black count = %d, white count = %d\n", __FUNCTION__,
- ap_cfg->mac_filter.black_list.count, ap_cfg->mac_filter.white_list.count));
- return -1;
- }
- if (ap_cfg->mac_filter.black_list.count) {
- ap_cfg->mac_filter.mode = 1;
- maclist = &ap_cfg->mac_filter.black_list;
- }
- else if (ap_cfg->mac_filter.white_list.count) {
- ap_cfg->mac_filter.mode = 2;
- maclist = &ap_cfg->mac_filter.white_list;
- }
- if (maclist) {
- for(i=0; i<maclist->count; i++) {
- WL_SOFTAP(("%02d: %02X:%02X:%02X:%02X:%02X:%02X\n", i+1,
- maclist->ea[i].octet[0], maclist->ea[i].octet[1], maclist->ea[i].octet[2],
- maclist->ea[i].octet[3], maclist->ea[i].octet[4], maclist->ea[i].octet[5]));
- }
- }
- #endif /* NEW_AP_INTERFACE */
- return ret;
- }
- static int iwpriv_set_ap_config(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *ext)
- {
- int res = 0;
- char *extra = NULL;
- struct ap_profile *ap_cfg = &my_ap;
- WL_TRACE(("> Got IWPRIV SET_AP IOCTL: info->cmd:%x, info->flags:%x, u.data:%p, u.len:%d\n",
- info->cmd, info->flags,
- wrqu->data.pointer, wrqu->data.length));
- if (wrqu->data.length != 0) {
- char *str_ptr;
- if (!(extra = kmalloc(wrqu->data.length+1, GFP_KERNEL)))
- return -ENOMEM;
- if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length)) {
- kfree(extra);
- return -EFAULT;
- }
- extra[wrqu->data.length] = 0;
- WL_SOFTAP((" Got str param in iw_point:\n %s\n", extra));
- memset(ap_cfg, 0, sizeof(struct ap_profile));
-
- str_ptr = extra;
- if ((res = init_ap_profile_from_string(extra, ap_cfg)) < 0) {
- WL_ERROR(("%s failed to parse %d\n", __FUNCTION__, res));
- kfree(extra);
- return -1;
- }
- } else {
-
- WL_ERROR(("IWPRIV argument len = 0 \n"));
- return -1;
- }
- if ((res = set_ap_cfg(dev, ap_cfg)) < 0)
- WL_ERROR(("%s failed to set_ap_cfg %d\n", __FUNCTION__, res));
- kfree(extra);
- return res;
- }
- #ifndef NEW_AP_INTERFACE // namju - ifdef -> ifndef to use previous version of iwpriv_get_assoc_list()
- static int iwpriv_get_assoc_list(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *p_iwrq,
- char *extra)
- {
- int ret = 0;
- char mac_buf[256];
- struct maclist *sta_maclist = (struct maclist *)mac_buf;
- WL_TRACE(("%s: IWPRIV IOCTL: cmd:%hx, flags:%hx, extra:%p, iwp.len:%d, \
- iwp.len:%p, iwp.flags:%x\n", __FUNCTION__, info->cmd, info->flags, \
- extra, p_iwrq->data.length, p_iwrq->data.pointer, p_iwrq->data.flags));
- WL_SOFTAP(("extra:%s\n", extra));
- print_buf((u8 *)p_iwrq, 16, 0);
- memset(sta_maclist, 0, sizeof(mac_buf));
- sta_maclist->count = 8;
- WL_TRACE((" net device:%s, buf_sz:%d\n", dev->name, sizeof(mac_buf)));
- get_assoc_sta_list(dev, mac_buf, 256);
- WL_TRACE((" got %d stations\n", sta_maclist->count));
- if (p_iwrq->data.length > sizeof(mac_buf)) {
- if (copy_to_user(p_iwrq->data.pointer, mac_buf, sizeof(mac_buf))) {
- WL_ERROR(("%s: Can't copy to user\n", __FUNCTION__));
- return -EFAULT;
- }
- }
- WL_ERROR(("Exited %s \n", __FUNCTION__));
- return ret;
- }
- #else /* NEW_AP_INTERFACE */
- static int iwpriv_get_assoc_list(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *p_iwrq,
- char *extra)
- {
- int i, ret = 0;
- char mac_buf[256];
- struct maclist *sta_maclist = (struct maclist *)mac_buf;
- char mac_lst[256];
- char *p_mac_str;
- WL_TRACE(("\n %s: IWPRIV IOCTL: cmd:%hx, flags:%hx, extra:%p, iwp.len:%d, \
- iwp.len:%p, iwp.flags:%x \n", __FUNCTION__, info->cmd, info->flags, \
- extra, p_iwrq->data.length, p_iwrq->data.pointer, p_iwrq->data.flags));
- WL_SOFTAP(("extra:%s\n", extra));
- print_buf((u8 *)p_iwrq, 16, 0);
- memset(sta_maclist, 0, sizeof(mac_buf));
- sta_maclist->count = 8;
- WL_TRACE((" net device:%s, buf_sz:%d\n", dev->name, sizeof(mac_buf)));
- get_assoc_sta_list(dev, mac_buf, 256);
- WL_TRACE((" got %d stations\n", sta_maclist->count));
-
- memset(mac_lst, 0, sizeof(mac_lst));
- p_mac_str = mac_lst;
- for (i = 0; i < 8; i++) {
- struct ether_addr * id = &sta_maclist->ea[i];
- WL_SOFTAP(("dhd_drv>> sta_mac[%d] :", i));
- print_buf((unsigned char *)&sta_maclist->ea[i], 6, 0);
-
- p_mac_str += snprintf(p_mac_str, MAX_WX_STRING,
- "Mac[%d]=%02X:%02X:%02X:%02X:%02X:%02X\n", i,
- id->octet[0], id->octet[1], id->octet[2],
- id->octet[3], id->octet[4], id->octet[5]);
- }
- p_iwrq->data.length = strlen(mac_lst);
- WL_TRACE(("u.pointer:%p\n", p_iwrq->data.pointer));
- WL_TRACE(("resulting str:\n%s \n len:%d\n\n", mac_lst, p_iwrq->data.length));
- if (p_iwrq->data.length) {
- if (copy_to_user(p_iwrq->data.pointer, mac_lst, p_iwrq->data.length)) {
- WL_ERROR(("%s: Can't copy to user\n", __FUNCTION__));
- return -EFAULT;
- }
- }
- WL_ERROR(("Exited %s \n", __FUNCTION__));
- return ret;
- }
- #endif /* NEW_AP_INTERFACE */
- #ifdef NEW_AP_INTERFACE
- #define MAC_FILT_MAX 16
- static int iwpriv_set_mac_filters(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *ext)
- {
- int i, ret = -1;
- char * extra = NULL;
- int mac_cnt = 0;
- int mac_mode;
- char sub_cmd[16];
- struct mac_list_set mac_list_set;
- struct maclist *mac_list;
- WL_TRACE((">>> Got IWPRIV SET_MAC_FILTER IOCTL: info->cmd:%x, \
- info->flags:%x, u.data:%p, u.len:%d\n",
- info->cmd, info->flags,
- wrqu->data.pointer, wrqu->data.length));
- if (wrqu->data.length != 0) {
- char *str_ptr;
- if (!(extra = kmalloc(wrqu->data.length+1, GFP_KERNEL)))
- return -ENOMEM;
- if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length)) {
- kfree(extra);
- return -EFAULT;
- }
- extra[wrqu->data.length] = 0;
- WL_SOFTAP((" Got parameter string in iw_point:\n %s \n", extra));
- memset(&mac_list_set, 0, sizeof(mac_list_set));
- memset(sub_cmd, 0, sizeof(sub_cmd));
- str_ptr = extra;
-
- if (get_parmeter_from_string(&str_ptr, "ASCII_CMD=", PTYPE_STRING, sub_cmd, 15) != 0) {
- goto exit_proc;
- }
-
- if (0 == strncmp(sub_cmd, "MAC_FLT_W", strlen("MAC_FLT_W"))) {
- mac_mode = MACLIST_MODE_ALLOW;
- mac_list = (struct maclist *)&mac_list_set.white_list;
- } else if (0 == strncmp(sub_cmd, "MAC_FLT_B", strlen("MAC_FLT_B"))) {
- mac_mode = MACLIST_MODE_ENABLED;
- mac_list = (struct maclist *)&mac_list_set.black_list;
- } else {
- WL_ERROR(("ERROR: sub_cmd:%s != 'MAC_FLT_W' or 'MAC_FLT_B'!\n", sub_cmd));
- goto exit_proc;
- }
- if (get_parmeter_from_string(&str_ptr, "MAC_CNT=",
- PTYPE_INTDEC, &mac_cnt, 4) != 0) {
- WL_ERROR(("ERROR: MAC_CNT param is missing \n"));
- goto exit_proc;
- }
- if (mac_cnt == 0) {
- mac_mode = MACLIST_MODE_DISABLED;
- } else {
- if (mac_cnt > MAC_FILT_MAX) {
- WL_ERROR(("ERROR: number of MAC filters > MAX\n"));
- goto exit_proc;
- }
- for (i=0; i< mac_cnt; i++) {
- if (get_parmeter_from_string(&str_ptr, "MAC=",
- PTYPE_STR_HEX, &mac_list->ea[i], 12) != 0) {
- WL_ERROR(("ERROR: MAC_filter[%d] is missing !\n", i));
- goto exit_proc;
- }
- }
- for (i = 0; i < mac_cnt; i++) {
- WL_SOFTAP(("MAC[%d]:", i));
- print_buf(&mac_list->ea[i], 6, 0);
- }
- }
- mac_list_set.mode = mac_mode;
- mac_list->count = mac_cnt;
- ret = set_ap_mac_list(dev, (char *)&mac_list_set);
- wrqu->data.pointer = NULL;
- wrqu->data.length = 0;
- } else {
-
- WL_ERROR(("IWPRIV argument len is 0\n"));
- return -1;
- }
- exit_proc:
- kfree(extra);
- return ret;
- }
- #else /* NEW_AP_INTERFACE */
- static int iwpriv_set_mac_filters(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *ext)
- {
- int i, ret = -1;
- char * extra = NULL;
- u8 macfilt[8][6];
- int mac_cnt = 0;
- char sub_cmd[16];
- WL_TRACE((">>> Got IWPRIV SET_MAC_FILTER IOCTL: info->cmd:%x, \
- info->flags:%x, u.data:%p, u.len:%d\n",
- info->cmd, info->flags,
- wrqu->data.pointer, wrqu->data.length));
- if (wrqu->data.length != 0) {
- char *str_ptr;
- if (!(extra = kmalloc(wrqu->data.length+1, GFP_KERNEL)))
- return -ENOMEM;
- if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length)) {
- kfree(extra);
- return -EFAULT;
- }
- extra[wrqu->data.length] = 0;
- WL_SOFTAP((" Got parameter string in iw_point:\n %s \n", extra));
- memset(macfilt, 0, sizeof(macfilt));
- memset(sub_cmd, 0, sizeof(sub_cmd));
- str_ptr = extra;
- if (get_parmeter_from_string(&str_ptr, "ASCII_CMD=", PTYPE_STRING, sub_cmd, 15) != 0) {
- goto exit_proc;
- }
- #define MAC_FILT_MAX 8
-
- if (strncmp(sub_cmd, "MAC_FLT_W", strlen("MAC_FLT_W"))) {
- WL_ERROR(("ERROR: sub_cmd:%s != 'MAC_FLT_W'!\n", sub_cmd));
- goto exit_proc;
- }
- if (get_parmeter_from_string(&str_ptr, "MAC_CNT=",
- PTYPE_INTDEC, &mac_cnt, 4) != 0) {
- WL_ERROR(("ERROR: MAC_CNT param is missing \n"));
- goto exit_proc;
- }
- if (mac_cnt > MAC_FILT_MAX) {
- WL_ERROR(("ERROR: number of MAC filters > MAX\n"));
- goto exit_proc;
- }
- for (i=0; i< mac_cnt; i++)
- if (get_parmeter_from_string(&str_ptr, "MAC=",
- PTYPE_STR_HEX, macfilt[i], 12) != 0) {
- WL_ERROR(("ERROR: MAC_filter[%d] is missing !\n", i));
- goto exit_proc;
- }
- for (i = 0; i < mac_cnt; i++) {
- WL_SOFTAP(("mac_filt[%d]:", i));
- print_buf(macfilt[i], 6, 0);
- }
-
- wrqu->data.pointer = NULL;
- wrqu->data.length = 0;
- ret = 0;
- } else {
-
- WL_ERROR(("IWPRIV argument len is 0\n"));
- return -1;
- }
- exit_proc:
- kfree(extra);
- return ret;
- }
- #endif /* NEW_AP_INTERFACE */
- #endif /* SOFTAP */
- #endif /* WIRELESS_EXT > 12 */
- #if WIRELESS_EXT < 13
- struct iw_request_info
- {
- __u16 cmd;
- __u16 flags;
- };
- typedef int (*iw_handler)(struct net_device *dev,
- struct iw_request_info *info,
- void *wrqu,
- char *extra);
- #endif
- static int
- wl_iw_config_commit(
- struct net_device *dev,
- struct iw_request_info *info,
- void *zwrq,
- char *extra
- )
- {
- wlc_ssid_t ssid;
- int error;
- struct sockaddr bssid;
- WL_TRACE(("%s: SIOCSIWCOMMIT\n", dev->name));
- if ((error = dev_wlc_ioctl(dev, WLC_GET_SSID, &ssid, sizeof(ssid))))
- return error;
- ssid.SSID_len = dtoh32(ssid.SSID_len);
- if (!ssid.SSID_len)
- return 0;
- bzero(&bssid, sizeof(struct sockaddr));
- if ((error = dev_wlc_ioctl(dev, WLC_REASSOC, &bssid, ETHER_ADDR_LEN))) {
- WL_ERROR(("%s: WLC_REASSOC to %s failed \n", __FUNCTION__, ssid.SSID));
- return error;
- }
- return 0;
- }
- static int
- wl_iw_get_name(
- struct net_device *dev,
- struct iw_request_info *info,
- char *cwrq,
- char *extra
- )
- {
- WL_TRACE(("%s: SIOCGIWNAME\n", dev->name));
- strcpy(cwrq, "IEEE 802.11-DS");
- return 0;
- }
- static int
- wl_iw_set_freq(
- struct net_device *dev,
- struct iw_request_info *info,
- struct iw_freq *fwrq,
- char *extra
- )
- {
- int error, chan;
- uint sf = 0;
- WL_TRACE(("\n %s %s: SIOCSIWFREQ\n", __FUNCTION__, dev->name));
- #if defined(SOFTAP)
- if (ap_cfg_running) {
- WL_TRACE(("%s:>> not executed, 'SOFT_AP is active' \n", __FUNCTION__));
- return 0;
- }
- #endif
-
- if (fwrq->e == 0 && fwrq->m < MAXCHANNEL) {
- chan = fwrq->m;
- }
-
- else {
-
- if (fwrq->e >= 6) {
- fwrq->e -= 6;
- while (fwrq->e--)
- fwrq->m *= 10;
- } else if (fwrq->e < 6) {
- while (fwrq->e++ < 6)
- fwrq->m /= 10;
- }
-
- if (fwrq->m > 4000 && fwrq->m < 5000)
- sf = WF_CHAN_FACTOR_4_G;
- chan = wf_mhz2channel(fwrq->m, sf);
- }
- chan = htod32(chan);
- if ((error = dev_wlc_ioctl(dev, WLC_SET_CHANNEL, &chan, sizeof(chan))))
- return error;
-
- return -EINPROGRESS;
- }
- static int
- wl_iw_get_freq(
- struct net_device *dev,
- struct iw_request_info *info,
- struct iw_freq *fwrq,
- char *extra
- )
- {
- channel_info_t ci;
- int error;
- WL_TRACE(("%s: SIOCGIWFREQ\n", dev->name));
- if ((error = dev_wlc_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(ci))))
- return error;
-
- fwrq->m = dtoh32(ci.target_channel);
- fwrq->e = dtoh32(0);
- return 0;
- }
- static int
- wl_iw_set_mode(
- struct net_device *dev,
- struct iw_request_info *info,
- __u32 *uwrq,
- char *extra
- )
- {
- int infra = 0, ap = 0, error = 0;
- WL_TRACE(("%s: SIOCSIWMODE\n", dev->name));
- switch (*uwrq) {
- case IW_MODE_MASTER:
- infra = ap = 1;
- break;
- case IW_MODE_ADHOC:
- case IW_MODE_AUTO:
- break;
- case IW_MODE_INFRA:
- infra = 1;
- break;
- default:
- return -EINVAL;
- }
- infra = htod32(infra);
- ap = htod32(ap);
- if ((error = dev_wlc_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(infra))) ||
- (error = dev_wlc_ioctl(dev, WLC_SET_AP, &ap, sizeof(ap))))
- return error;
-
- return -EINPROGRESS;
- }
- static int
- wl_iw_get_mode(
- struct net_device *dev,
- struct iw_request_info *info,
- __u32 *uwrq,
- char *extra
- )
- {
- int error, infra = 0, ap = 0;
- WL_TRACE(("%s: SIOCGIWMODE\n", dev->name));
- if ((error = dev_wlc_ioctl(dev, WLC_GET_INFRA, &infra, sizeof(infra))) ||
- (error = dev_wlc_ioctl(dev, WLC_GET_AP, &ap, sizeof(ap))))
- return error;
- infra = dtoh32(infra);
- ap = dtoh32(ap);
- *uwrq = infra ? ap ? IW_MODE_MASTER : IW_MODE_INFRA : IW_MODE_ADHOC;
- return 0;
- }
- static int
- wl_iw_get_range(
- struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *dwrq,
- char *extra
- )
- {
- struct iw_range *range = (struct iw_range *) extra;
- wl_uint32_list_t *list;
- wl_rateset_t rateset;
- int8 *channels;
- int error, i, k;
- uint sf, ch;
- int phytype;
- int bw_cap = 0, sgi_tx = 0, nmode = 0;
- channel_info_t ci;
- uint8 nrate_list2copy = 0;
- uint16 nrate_list[4][8] = { {13, 26, 39, 52, 78, 104, 117, 130},
- {14, 29, 43, 58, 87, 116, 130, 144},
- {27, 54, 81, 108, 162, 216, 243, 270},
- {30, 60, 90, 120, 180, 240, 270, 300}};
- WL_TRACE(("%s: SIOCGIWRANGE\n", dev->name));
- if (!extra)
- return -EINVAL;
- channels = kmalloc((MAXCHANNEL+1)*4, GFP_KERNEL);
- if (!channels) {
- WL_ERROR(("Could not alloc channels\n"));
- return -ENOMEM;
- }
- list = (wl_uint32…