#include #include #include #include #include #include #include #include "hgicf.h" #include "cfg.h" struct hgpriv_set { char *name; int (*set)(struct net_device *dev, char *args); }; struct hgpriv_get { char *name; int (*get)(struct net_device *dev, struct iwreq *wrqin); }; #define hgicf_pick_values(pick_type, str, array, size) do{\ char *ptr = NULL;\ if(str && strlen(str) > 0){\ while ((ptr = strsep((char **)&str, ",")) != NULL) {\ if (count >= size) break;\ array[count++] = (pick_type)simple_strtol(ptr, 0, 10);\ }\ }\ }while(0) static int hgicf_copyfrom_iwreq(struct iwreq *wrqin, char *buf, int len) { int ret = 0; if (len > 0) { memset(buf, 0, len); if (ACCESS_OK(VERIFY_READ, wrqin->u.data.pointer, wrqin->u.data.length)) { ret = copy_from_user(buf, wrqin->u.data.pointer, wrqin->u.data.length); } else { memcpy(buf, wrqin->u.data.pointer, wrqin->u.data.length); } } return ret; } static void hgicf_copyto_iwreq(struct iwreq *wrqin, char *buf, int len) { if (len > 0) { if (ACCESS_OK(VERIFY_WRITE, wrqin->u.data.pointer, len)) { if (!__copy_to_user(wrqin->u.data.pointer, buf, len)){ wrqin->u.data.length = (u16)len; } } else { memset(wrqin->u.data.pointer, 0, len + 1); memcpy(wrqin->u.data.pointer, buf, len); } } } static int hgicf_ioctl_set_countryregion(struct net_device *dev, char *args) { struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); if (args == NULL) { return -EINVAL; } return hgic_fwctrl_set_countryregion(&(vif->hg->ctrl), args); } static int hgicf_ioctl_set_ssid(struct net_device *dev, char *args) { int ret = -1; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); ret = hgic_fwctrl_set_ssid(&(vif->hg->ctrl), args); if (!ret) { strcpy(vif->hw_ssid, args); } return ret; } static int hgicf_ioctl_set_bssid(struct net_device *dev, char *args) { int ret = -1; u8 bssid[6]; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); if (args == NULL || vif->fwifidx != HGIC_WDEV_ID_STA) { return -EINVAL; } hgic_pick_macaddr(args, bssid); ret = hgic_fwctrl_set_bssid(&(vif->hg->ctrl), bssid); if (!ret) { memcpy(vif->hw_bssid, args, ETH_ALEN); } return ret; } static int hgicf_ioctl_set_channel(struct net_device *dev, char *args) { struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); if (args == NULL) { return -EINVAL; } return hgic_fwctrl_set_channel(&(vif->hg->ctrl), simple_strtol(args, 0, 10)); } static int hgicf_ioctl_set_bssid_filter(struct net_device *dev, char *args) { struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); return hgic_fwctrl_set_bssid_filter(&(vif->hg->ctrl), args); } static int hgicf_ioctl_set_rts_threshold(struct net_device *dev, char *args) { struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); if (args == NULL) { return -EINVAL; } return hgic_fwctrl_set_rts_threshold(&(vif->hg->ctrl), simple_strtol(args, 0, 10)); } static int hgicf_ioctl_set_frag_threshold(struct net_device *dev, char *args) { struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); if (args == NULL) { return -EINVAL; } return hgic_fwctrl_set_frag_threshold(&(vif->hg->ctrl), simple_strtol(args, 0, 10)); } static int hgicf_ioctl_set_key_mgmt(struct net_device *dev, char *args) { struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); return hgic_fwctrl_set_key_mgmt(&(vif->hg->ctrl), args); } static int hgicf_ioctl_set_wpa_psk(struct net_device *dev, char *args) { struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); return hgic_fwctrl_set_wpa_psk(&(vif->hg->ctrl), args); } static int hgicf_ioctl_reset_counter(struct net_device *dev, char *args) { //struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); hgic_dbg("%s\r\n", args); return 0; } static int hgicf_ioctl_set_freq_range(struct net_device *dev, char *args) { struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); u32 vals[3] = {0, 0, 0}; int count = 0; if (args == NULL || strlen(args) == 0) { return -EINVAL; } hgicf_pick_values(u32, args, vals, 3); if ((vals[0] < 7200 || vals[0] > 9300) || (vals[1] < vals[0] || vals[1] > 9300) || (vals[2] < 1 || vals[2] > 8)) { return -EINVAL; } return hgic_fwctrl_set_freq_range(&(vif->hg->ctrl), vals[0], vals[1], vals[2]); } static int hgicf_ioctl_set_bss_bw(struct net_device *dev, char *args) { struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); u8 bss_bw = (u8)simple_strtol(args, 0, 10); if (bss_bw != 1 && bss_bw != 2 && bss_bw != 4 && bss_bw != 8) { bss_bw = 8; } return hgic_fwctrl_set_bss_bw(&(vif->hg->ctrl), bss_bw); } static int hgicf_ioctl_set_tx_bw(struct net_device *dev, char *args) { struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); u8 tx_bw = (u8)simple_strtol(args, 0, 10); if (tx_bw != 1 && tx_bw != 2 && tx_bw != 4 && tx_bw != 8) { tx_bw = 0; } return hgic_fwctrl_set_tx_bw(&(vif->hg->ctrl), tx_bw); } static int hgicf_ioctl_set_tx_mcs(struct net_device *dev, char *args) { struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); u8 tx_mcs = (u8)simple_strtol(args, 0, 10); return hgic_fwctrl_set_tx_mcs(&(vif->hg->ctrl), tx_mcs); } static int hgicf_ioctl_set_acs(struct net_device *dev, char *args) { struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); u16 vals[2] = {0, 0}; int count = 0; if (args == NULL || strlen(args) == 0) { return -EINVAL; } hgicf_pick_values(u16, args, vals, 2); return hgic_fwctrl_set_acs(&(vif->hg->ctrl), vals[0], vals[1]); } static int hgicf_ioctl_set_bgrssi(struct net_device *dev, char *args) { struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); u8 rssi = (u8)simple_strtol(args, 0, 10); return hgic_fwctrl_set_bgrssi(&(vif->hg->ctrl), rssi); } static int hgicf_ioctl_set_chan_list(struct net_device *dev, char *args) { struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); u16 vals[32] = {0}; int count = 0; if (args == NULL || strlen(args) == 0) { return -EINVAL; } hgicf_pick_values(u16, args, vals, 32); return hgic_fwctrl_set_chan_list(&(vif->hg->ctrl), vals, count); } static int hgicf_ioctl_set_mode(struct net_device *dev, char *args) { struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); if (args == NULL) { return -EINVAL; } return hgic_fwctrl_set_mode(&(vif->hg->ctrl), args); } static int hgicf_ioctl_set_paired_stas(struct net_device *dev, char *args) { u8 *buf = NULL; int len = 0; int ret = 0, i = 0; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); if (args == NULL || strlen(args) == 0) { return -EINVAL; } len = ALIGN(strlen(args), 17); buf = kzalloc(len, GFP_KERNEL); if (buf == NULL) { return -ENOMEM; } while ((i + 1) * 17 <= len) { if (hgic_pick_macaddr(args + i * 17, buf + i * 6)) { i++; } else { break; } } //hgic_dbg("set paired stas:%s\r\n", args); ret = hgic_fwctrl_set_paired_stas(&(vif->hg->ctrl), buf, i * 6); kfree(buf); return ret; } static int hgicf_ioctl_set_pairing(struct net_device *dev, char *args) { u8 enable = 0; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); if (args == NULL) { return -EINVAL; } enable = simple_strtol(args, 0, 10); return hgic_fwctrl_set_pairing(&(vif->hg->ctrl), enable); } static int hgicf_ioctl_set_beacon_int(struct net_device *dev, char *args) { struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); u8 beacon_int = (u8)simple_strtol(args, 0, 10); return hgic_fwctrl_set_beacon_int(&(vif->hg->ctrl), beacon_int); } static int hgicf_ioctl_set_radio_off(struct net_device *dev, char *args) { struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); vif->hg->radio_off = (u8)simple_strtol(args, 0, 10); return hgic_fwctrl_radio_onoff(&(vif->hg->ctrl), !vif->hg->radio_off); } static int hgicf_ioctl_join_group(struct net_device *dev, char *args) { u8 addr[6]; u32 aid = 0; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); if (args == NULL) { return -EINVAL; } hgic_pick_macaddr(args, addr); aid = simple_strtol(args + 18, 0, 10); return hgic_fwctrl_join_group(&(vif->hg->ctrl), addr, aid); } static int hgicf_ioctl_set_ethertype(struct net_device *dev, char *args) { u16 type = 0; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); if (args == NULL) { return -EINVAL; } type = simple_strtol(args, 0, 16); return hgic_fwctrl_set_ethertype(&(vif->hg->ctrl), type); } static int hgicf_ioctl_set_txpower(struct net_device *dev, char *args) { u16 type = 0; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); if (args == NULL) { return -EINVAL; } type = simple_strtol(args, 0, 10); return hgic_fwctrl_set_txpower(&(vif->hg->ctrl), type); } static int hgicf_ioctl_set_aggcnt(struct net_device *dev, char *args) { u8 aggcnt = 0; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); if (args == NULL) { return -EINVAL; } aggcnt = simple_strtol(args, 0, 10); return hgic_fwctrl_set_agg_cnt(&(vif->hg->ctrl), aggcnt); } static int hgicf_ioctl_set_ps_connect(struct net_device *dev, char *args) { int count = 0; u8 vals[2]; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); if (args == NULL) { return -EINVAL; } hgicf_pick_values(u8, args, vals, 2); return hgic_fwctrl_set_ps_connect(&(vif->hg->ctrl), vals[0], vals[1]); } static int hgicf_ioctl_set_bss_max_idle(struct net_device *dev, char *args) { u32 max_idle = 0; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); if (args == NULL) { return -EINVAL; } max_idle = simple_strtol(args, 0, 10); return hgic_fwctrl_set_bss_max_idle(&(vif->hg->ctrl), max_idle); } static int hgicf_ioctl_set_dtim_period(struct net_device *dev, char *args) { u32 period = 0; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); if (args == NULL) { return -EINVAL; } period = simple_strtol(args, 0, 10); return hgic_fwctrl_set_dtim_period(&(vif->hg->ctrl), period); } static int hgicf_ioctl_set_wkio_mode(struct net_device *dev, char *args) { u32 mode = 0; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); if (args == NULL) { return -EINVAL; } mode = simple_strtol(args, 0, 10); return hgic_fwctrl_set_wkio_mode(&(vif->hg->ctrl), mode); } static int hgicf_ioctl_set_load_def(struct net_device *dev, char *args) { u32 rst = 0; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); if (args == NULL) { return -EINVAL; } rst = simple_strtol(args, 0, 10); return hgic_fwctrl_set_load_def(&(vif->hg->ctrl), rst); } static int hgicf_ioctl_set_disassoc_sta(struct net_device *dev, char *args) { u8 addr[6]; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); if (args == NULL) { return -EINVAL; } hgic_pick_macaddr(args, addr); return hgic_fwctrl_disassoc_sta(&(vif->hg->ctrl), addr); } static int hgicf_ioctl_set_ps_mode(struct net_device *dev, char *args) { u32 mode = 0; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); if (args == NULL) { return -EINVAL; } mode = simple_strtol(args, 0, 10); return hgic_fwctrl_set_ps_mode(&(vif->hg->ctrl), mode); } static int hgicf_ioctl_set_aplost_time(struct net_device *dev, char *args) { u32 time = 0; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); if (args == NULL) { return -EINVAL; } time = simple_strtol(args, 0, 10); return hgic_fwctrl_set_aplost_time(&(vif->hg->ctrl), time); } static int hgicf_ioctl_set_unpair(struct net_device *dev, char *args) { u8 addr[6]; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); hgic_pick_macaddr(args, addr); return hgic_fwctrl_unpair(&(vif->hg->ctrl), addr); } static int hgicf_ioctl_set_auto_chswitch(struct net_device *dev, char *args) { u32 enable = 0; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); if (args == NULL) { return -EINVAL; } enable = simple_strtol(args, 0, 10); return hgic_fwctrl_set_auto_chswitch(&(vif->hg->ctrl), enable == 1); } static int hgicf_ioctl_set_mcast_key(struct net_device *dev, char *args) { struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); if (args == NULL) { return -EINVAL; } return hgic_fwctrl_set_mcast_key(&(vif->hg->ctrl), args); } static int hgicf_ioctl_set_reassoc_wkhost(struct net_device *dev, char *args) { u32 enable = 0; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); if (args == NULL) { return -EINVAL; } enable = simple_strtol(args, 0, 10); return hgic_fwctrl_set_reassoc_wkhost(&(vif->hg->ctrl), enable == 1); } static int hgicf_ioctl_set_wakeup_io(struct net_device *dev, char *args) { struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); u8 vals[2] = {0, 0}; int count = 0; hgicf_pick_values(u8, args, vals, 2); return hgic_fwctrl_set_wakeup_io(&(vif->hg->ctrl), vals[0], vals[1]); } static int hgicf_ioctl_set_dbginfo_output(struct net_device *dev, char *args) { u32 enable = 0; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); if (args) { enable = simple_strtol(args, 0, 10); } return hgic_fwctrl_set_dbginfo_output(&(vif->hg->ctrl), enable == 1); } static int hgicf_ioctl_set_sysdbg(struct net_device *dev, char *args) { struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); if (args == NULL) { return -EINVAL; } return hgic_fwctrl_set_sysdbg(&(vif->hg->ctrl), args); } static int hgicf_ioctl_set_primary_chan(struct net_device *dev, char *args) { u32 chan = 0; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); if (args == NULL) { return -EINVAL; } chan = simple_strtol(args, 0, 10); return hgic_fwctrl_set_primary_chan(&(vif->hg->ctrl), chan); } static int hgicf_ioctl_set_autosleep_time(struct net_device *dev, char *args) { u32 time = 0; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); if (args == NULL) { return -EINVAL; } time = simple_strtol(args, 0, 10); return hgic_fwctrl_set_autosleep_time(&(vif->hg->ctrl), time); } static int hgicf_ioctl_set_supper_pwr(struct net_device *dev, char *args) { u32 enable = 0; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); if (args == NULL) { return -EINVAL; } enable = simple_strtol(args, 0, 10); return hgic_fwctrl_set_supper_pwr(&(vif->hg->ctrl), enable); } static int hgicf_ioctl_set_repeater_ssid(struct net_device *dev, char *args) { struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); return hgic_fwctrl_set_repeater_ssid(&(vif->hg->ctrl), args); } static int hgicf_ioctl_set_repeater_psk(struct net_device *dev, char *args) { struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); return hgic_fwctrl_set_repeater_psk(&(vif->hg->ctrl), args); } static int hgicf_ioctl_set_auto_save(struct net_device *dev, char *args) { u32 enable = 0; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); if (args == NULL) { return -EINVAL; } enable = simple_strtol(args, 0, 10); return hgic_fwctrl_set_auto_save(&(vif->hg->ctrl), enable); } static int hgicf_ioctl_set_pair_autostop(struct net_device *dev, char *args) { u32 enable = 0; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); if (args == NULL) { return -EINVAL; } enable = simple_strtol(args, 0, 10); return hgic_fwctrl_set_pair_autostop(&(vif->hg->ctrl), enable); } static int hgicf_ioctl_set_dcdc13v(struct net_device *dev, char *args) { u32 enable = 0; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); if (args == NULL) { return -EINVAL; } enable = simple_strtol(args, 0, 10); return hgic_fwctrl_set_dcdc13v(&(vif->hg->ctrl), enable); } static int hgicf_ioctl_set_acktmo(struct net_device *dev, char *args) { u32 tmo = 0; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); if (args == NULL) { return -EINVAL; } tmo = simple_strtol(args, 0, 10); return hgic_fwctrl_set_acktmo(&(vif->hg->ctrl), tmo); } static int hgicf_ioctl_set_pa_pwrctl_dis(struct net_device *dev, char *args) { u32 dis = 0; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); if (args == NULL) { return -EINVAL; } dis = simple_strtol(args, 0, 10); return hgic_fwctrl_set_pa_pwrctl_dis(&(vif->hg->ctrl), dis); } static int hgicf_ioctl_set_dhcpc(struct net_device *dev, char *args) { u32 en = 0; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); if (args == NULL) { return -EINVAL; } en = simple_strtol(args, 0, 10); return hgic_fwctrl_set_dhcpc(&(vif->hg->ctrl), en); } static int hgicf_ioctl_set_wkdata_save(struct net_device *dev, char *args) { u32 en = 0; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); if (args == NULL) { return -EINVAL; } en = simple_strtol(args, 0, 10); return hgic_fwctrl_set_wkdata_save(&(vif->hg->ctrl), en); } static int hgicf_ioctl_set_mcast_txparam(struct net_device *dev, char *args) { struct hgic_mcast_txparam txparam; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); u8 *vals = (u8 *)&txparam; int count = 0; if (args == NULL) { return -EINVAL; } hgicf_pick_values(u8, args, vals, 4); return hgic_fwctrl_set_mcast_txparam(&(vif->hg->ctrl), &txparam); } static int hgicf_ioctl_set_resetsta(struct net_device *dev, char *args) { u8 addr[6]; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); if (args == NULL || vif->fwifidx != HGIC_WDEV_ID_STA) { return -EINVAL; } hgic_pick_macaddr(args, addr); return hgic_fwctrl_reset_sta(&(vif->hg->ctrl), addr); } static int hgicf_ioctl_set_ant_auto(struct net_device *dev, char *args) { u32 en = 0; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); if (args == NULL) { return -EINVAL; } en = simple_strtol(args, 0, 10); return hgic_fwctrl_set_ant_auto(&(vif->hg->ctrl), en); } static int hgicf_ioctl_select_ant(struct net_device *dev, char *args) { u32 ant = 0; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); if (args == NULL) { return -EINVAL; } ant = simple_strtol(args, 0, 10); return hgic_fwctrl_select_ant(&(vif->hg->ctrl), ant); } static int hgicf_ioctl_set_wkhost_reasons(struct net_device *dev, char *args) { int count = 0; u8 reasons[33]; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); if (args == NULL) { return -EINVAL; } memset(reasons, 0, sizeof(reasons)); hgicf_pick_values(u8, args, reasons, 32); return hgic_fwctrl_set_wkhost_reasons(&(vif->hg->ctrl), reasons, count + 1); } static int hgicf_ioctl_set_mac_filter(struct net_device *dev, char *args) { u32 en = 0; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); if (args == NULL) { return -EINVAL; } en = simple_strtol(args, 0, 10); return hgic_fwctrl_set_mac_filter(&(vif->hg->ctrl), en); } static int hgicf_ioctl_set_atcmd(struct net_device *dev, char *args) { struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); return hgic_fwctrl_set_atcmd(&(vif->hg->ctrl), args); } static int hgicf_ioctl_set_roaming(struct net_device *dev, char *args) { int count = 0; u8 vals[2]; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); if (args == NULL) { return -EINVAL; } hgicf_pick_values(u8, args, vals, 2); return hgic_fwctrl_set_roaming(&(vif->hg->ctrl), vals[0], vals[2]); } static int hgicf_ioctl_set_ap_hide(struct net_device *dev, char *args) { u32 hide = 0; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); if (args == NULL) { return -EINVAL; } hide = simple_strtol(args, 0, 10); return hgic_fwctrl_set_ap_hide(&(vif->hg->ctrl), hide); } static int hgicf_ioctl_set_max_txcnt(struct net_device *dev, char *args) { u32 txcnt = 0; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); if (args == NULL) { return -EINVAL; } txcnt = simple_strtol(args, 0, 10); return hgic_fwctrl_set_frm_tx_maxcnt(&(vif->hg->ctrl), txcnt); } static int hgicf_ioctl_set_assert_holdup(struct net_device *dev, char *args) { u32 holdup = 0; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); if (args == NULL) { return -EINVAL; } holdup = simple_strtol(args, 0, 10); return hgic_fwctrl_set_assert_holdup(&(vif->hg->ctrl), holdup); } static struct hgpriv_set hgpriv_sets[] = { {"country_region", hgicf_ioctl_set_countryregion}, {"ssid", hgicf_ioctl_set_ssid}, {"bssid", hgicf_ioctl_set_bssid}, {"channel", hgicf_ioctl_set_channel}, {"rts_threshold", hgicf_ioctl_set_rts_threshold}, {"frag_threshold", hgicf_ioctl_set_frag_threshold}, {"key_mgmt", hgicf_ioctl_set_key_mgmt}, {"wpa_psk", hgicf_ioctl_set_wpa_psk}, {"reset_counter", hgicf_ioctl_reset_counter}, {"bssid_filter", hgicf_ioctl_set_bssid_filter}, {"freq_range", hgicf_ioctl_set_freq_range}, {"bss_bw", hgicf_ioctl_set_bss_bw}, {"tx_bw", hgicf_ioctl_set_tx_bw}, {"tx_mcs", hgicf_ioctl_set_tx_mcs}, {"acs", hgicf_ioctl_set_acs}, {"bgrssi", hgicf_ioctl_set_bgrssi}, {"chan_list", hgicf_ioctl_set_chan_list}, {"mode", hgicf_ioctl_set_mode}, {"paired_stas", hgicf_ioctl_set_paired_stas}, {"pairing", hgicf_ioctl_set_pairing}, {"beacon_int", hgicf_ioctl_set_beacon_int}, {"radio_off", hgicf_ioctl_set_radio_off}, {"join_group", hgicf_ioctl_join_group}, {"ether_type", hgicf_ioctl_set_ethertype}, {"txpower", hgicf_ioctl_set_txpower}, {"agg_cnt", hgicf_ioctl_set_aggcnt}, {"ps_connect", hgicf_ioctl_set_ps_connect}, {"bss_max_idle", hgicf_ioctl_set_bss_max_idle}, {"wkio_mode", hgicf_ioctl_set_wkio_mode}, {"loaddef", hgicf_ioctl_set_load_def}, {"disassoc_sta", hgicf_ioctl_set_disassoc_sta}, {"dtim_period", hgicf_ioctl_set_dtim_period}, {"ps_mode", hgicf_ioctl_set_ps_mode}, {"aplost_time", hgicf_ioctl_set_aplost_time}, {"unpair", hgicf_ioctl_set_unpair}, {"auto_chswitch", hgicf_ioctl_set_auto_chswitch}, {"mcast_key", hgicf_ioctl_set_mcast_key}, {"reassoc_wkhost", hgicf_ioctl_set_reassoc_wkhost}, {"wakeup_io", hgicf_ioctl_set_wakeup_io}, {"dbginfo", hgicf_ioctl_set_dbginfo_output}, {"sysdbg", hgicf_ioctl_set_sysdbg}, {"primary_chan", hgicf_ioctl_set_primary_chan}, {"autosleep_time", hgicf_ioctl_set_autosleep_time}, {"supper_pwr", hgicf_ioctl_set_supper_pwr}, {"r_ssid", hgicf_ioctl_set_repeater_ssid}, {"r_psk", hgicf_ioctl_set_repeater_psk}, {"auto_save", hgicf_ioctl_set_auto_save}, {"pair_autostop", hgicf_ioctl_set_pair_autostop}, {"dcdc13", hgicf_ioctl_set_dcdc13v}, {"acktmo", hgicf_ioctl_set_acktmo}, {"pa_pwrctl_dis", hgicf_ioctl_set_pa_pwrctl_dis}, {"dhcpc", hgicf_ioctl_set_dhcpc}, {"wkdata_save", hgicf_ioctl_set_wkdata_save}, {"mcast_txparam", hgicf_ioctl_set_mcast_txparam}, {"reset_sta", hgicf_ioctl_set_resetsta}, {"ant_auto", hgicf_ioctl_set_ant_auto}, {"ant_sel", hgicf_ioctl_select_ant}, {"wkhost_reason", hgicf_ioctl_set_wkhost_reasons}, {"macfilter", hgicf_ioctl_set_mac_filter}, {"atcmd", hgicf_ioctl_set_atcmd}, {"roaming", hgicf_ioctl_set_roaming}, {"ap_hide", hgicf_ioctl_set_ap_hide}, {"max_txcnt", hgicf_ioctl_set_max_txcnt}, {"assert_holdup", hgicf_ioctl_set_assert_holdup}, {NULL,} }; int hgicf_ioctl_set_proc(struct net_device *dev, struct iwreq *wrqin) { int ret = 0; char *field, *val; struct hgpriv_set *set = NULL; u8 *cmd = kmalloc(wrqin->u.data.length + 1, GFP_KERNEL); if (cmd == NULL){ return -ENOMEM; } ret = hgicf_copyfrom_iwreq(wrqin, cmd, wrqin->u.data.length + 1); //hgic_dbg("%s\r\n", cmd); while (!ret && (field = strsep((char **)&cmd, ";")) != NULL) { if (!*field) { continue; } if ((val = strchr(field, '=')) != NULL) { *val++ = 0; } for (set = hgpriv_sets; val && set->name; set++) { if (strcmp(field, set->name) == 0) { //printk("set [%s=%s]\r\n", set->name, val); ret = set->set(dev, val); break; } } if (set->name == NULL) { hgic_dbg("not support:%s=%s\r\n", field, val); ret = -1; break; } } kfree(cmd); return ret; } static int hgicf_ioctl_get_scan_list(struct net_device *dev, struct iwreq *wrqin) { int ret = 0; int i = 0; int count = 0; int len = 0; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); struct hgic_bss_info *bss = NULL; char *buf = kzalloc(1024, GFP_ATOMIC); char *print_buf = kzalloc(4096, GFP_ATOMIC); if (buf == NULL || print_buf == NULL) { if (buf) { kfree(buf); } if (print_buf) { kfree(print_buf); } return -ENOMEM; } ret = hgic_fwctrl_get_scan_list(&(vif->hg->ctrl), buf, 1024); if (ret > 0) { bss = (struct hgic_bss_info *)buf; count = ret / sizeof(struct hgic_bss_info); len += sprintf(print_buf + len, "\r\nBSSID \tSSID \tEncryption\tFrequence\tSignal\r\n"); for (i = 0; i < count; i++) { len += sprintf(print_buf + len, "%pM\t%s\t%10s\t%10d\t%d\r\n", bss[i].bssid, bss[i].ssid, bss[i].encrypt ? (bss[i].encrypt == 1 ? "WPA" : "WPA2") : "NONE", bss[i].freq, bss[i].signal); } wrqin->u.data.length = (u16)len; } else { len = 2; } hgicf_copyto_iwreq(wrqin, print_buf, len); kfree(buf); kfree(print_buf); return (0); } static int hgicf_ioctl_get_sta_list(struct net_device *dev, struct iwreq *wrqin) { //int i = 0; int count = 0; int len = 0; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); char *buf = kzalloc(1024, GFP_ATOMIC); char *print_buf = kzalloc(4096, GFP_ATOMIC); //char *ptr = buf; struct hgic_sta_info *sta = (struct hgic_sta_info *)buf; if (buf == NULL || print_buf == NULL) { if (buf) { kfree(buf); } if (print_buf) { kfree(print_buf); } return -ENOMEM; } count = hgic_fwctrl_get_sta_list(&(vif->hg->ctrl), (struct hgic_sta_info *)buf, (1024 / sizeof(struct hgic_sta_info))); if (count > 0) { len += sprintf(print_buf, "%d sta:\r\n", count); while (count-- > 0) { len += sprintf(print_buf + len, "aid:%d, %pM, ps:%d, rssi:%d, evm:%d\r\n", sta->aid, sta->addr, sta->ps, (s8)sta->rssi, (s8)sta->evm); sta++; } wrqin->u.data.length = (u16)len; } else { len = 2; } hgicf_copyto_iwreq(wrqin, print_buf, len); kfree(buf); kfree(print_buf); return (0); } static int hgicf_ioctl_get_ssid(struct net_device *dev, struct iwreq *wrqin) { int len = 0; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); char *buf = kzalloc(40, GFP_ATOMIC); if (buf == NULL) { return -ENOMEM; } len = hgic_fwctrl_get_ssid(&(vif->hg->ctrl), buf, 32); hgicf_copyto_iwreq(wrqin, buf, len); kfree(buf); return (0); } static int hgicf_ioctl_get_bssid(struct net_device *dev, struct iwreq *wrqin) { int len = 0; char buf[24] = {0}; char bssid[6]; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); len = hgic_fwctrl_get_bssid(&(vif->hg->ctrl), bssid); if (len == 6) { sprintf(buf, "%pM", bssid); } len = strlen(buf); hgicf_copyto_iwreq(wrqin, buf, len); return (0); } static int hgicf_ioctl_get_wpa_psk(struct net_device *dev, struct iwreq *wrqin) { int len = 0; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); char *buf = kzalloc(80, GFP_ATOMIC); if (buf == NULL) { return -ENOMEM; } len = hgic_fwctrl_get_wpapsk(&(vif->hg->ctrl), buf, 64); hgicf_copyto_iwreq(wrqin, buf, len); kfree(buf); return (0); } static int hgicf_ioctl_get_txpower(struct net_device *dev, struct iwreq *wrqin) { char str[4]; int txpower = 0; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); txpower = hgic_fwctrl_get_txpower(&(vif->hg->ctrl)); sprintf(str, "%d", txpower); hgicf_copyto_iwreq(wrqin, str, strlen(str)); return (0); } static int hgicf_ioctl_get_bss_bw(struct net_device *dev, struct iwreq *wrqin) { char str[4]; int bss_bw = 0; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); bss_bw = hgic_fwctrl_get_bss_bw(&(vif->hg->ctrl)); sprintf(str, "%d", bss_bw); hgicf_copyto_iwreq(wrqin, str, strlen(str)); return (0); } static int hgicf_ioctl_get_aggcnt(struct net_device *dev, struct iwreq *wrqin) { char str[4]; int aggcnt = 0; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); aggcnt = hgic_fwctrl_get_agg_cnt(&(vif->hg->ctrl)); sprintf(str, "%d", aggcnt); hgicf_copyto_iwreq(wrqin, str, strlen(str)); return (0); } static int hgicf_ioctl_get_chan_list(struct net_device *dev, struct iwreq *wrqin) { int cnt = 0, i = 0; int len = 0; u16 chan_list[16]; char *buf = kzalloc(128, GFP_KERNEL); struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); if (buf) { cnt = hgic_fwctrl_get_chan_list(&(vif->hg->ctrl), chan_list, 16); for (i = 0; i < cnt; i++) { len += sprintf(buf + len, "%d,", chan_list[i]); } if (len > 0) { len--; buf[len] = 0; hgicf_copyto_iwreq(wrqin, buf, len); } kfree(buf); } return (0); } static int hgicf_ioctl_get_freq_range(struct net_device *dev, struct iwreq *wrqin) { char str[32] = {0}; int ret; u32 vals[3]; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); ret = hgic_fwctrl_get_freq_range(&(vif->hg->ctrl), &vals[0], &vals[1], &vals[2]); if (ret) { sprintf(str, "%d,%d,%d", vals[0], vals[1], vals[2]); } hgicf_copyto_iwreq(wrqin, str, strlen(str)); return (0); } static int hgicf_ioctl_get_key_mgmt(struct net_device *dev, struct iwreq *wrqin) { int len = 0; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); char *buf = kzalloc(40, GFP_ATOMIC); if (buf == NULL) { return -ENOMEM; } len = hgic_fwctrl_get_key_mgmt(&(vif->hg->ctrl), buf, 32); hgicf_copyto_iwreq(wrqin, buf, len); kfree(buf); return (0); } static int hgicf_ioctl_get_battery_level(struct net_device *dev, struct iwreq *wrqin) { char str[4]; int val = 0; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); val = hgic_fwctrl_get_battery_level(&(vif->hg->ctrl)); sprintf(str, "%d", val); hgicf_copyto_iwreq(wrqin, str, strlen(str)); return (0); } static int hgicf_ioctl_get_module_type(struct net_device *dev, struct iwreq *wrqin) { u16 type = 0; char str[12]; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); type = (u16)hgic_fwctrl_get_module_type(&(vif->hg->ctrl)); if (type) { sprintf(str, "%d", type); hgicf_copyto_iwreq(wrqin, str, strlen(str)); } return (0); } static int hgicf_ioctl_get_disassoc_reason(struct net_device *dev, struct iwreq *wrqin) { char str[12]; int reason = 0; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); reason = hgic_fwctrl_get_disassoc_reason(&(vif->hg->ctrl)); sprintf(str, "%d", reason); hgicf_copyto_iwreq(wrqin, str, strlen(str)); return (0); } static int hgicf_ioctl_get_ant_sel(struct net_device *dev, struct iwreq *wrqin) { char str[12]; int ant = 0; struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); ant = hgic_fwctrl_get_ant_sel(&(vif->hg->ctrl)); sprintf(str, "%d", ant); hgicf_copyto_iwreq(wrqin, str, strlen(str)); return (0); } static struct hgpriv_get hgpriv_gets[] = { {"sta_list", hgicf_ioctl_get_sta_list}, {"scan_list", hgicf_ioctl_get_scan_list}, {"ssid", hgicf_ioctl_get_ssid}, {"bssid", hgicf_ioctl_get_bssid}, {"wpa_psk", hgicf_ioctl_get_wpa_psk}, {"txpower", hgicf_ioctl_get_txpower}, {"agg_cnt", hgicf_ioctl_get_aggcnt}, {"bss_bw", hgicf_ioctl_get_bss_bw}, {"chan_list", hgicf_ioctl_get_chan_list}, {"freq_range", hgicf_ioctl_get_freq_range}, {"key_mgmt", hgicf_ioctl_get_key_mgmt}, {"battery_level", hgicf_ioctl_get_battery_level}, {"module_type", hgicf_ioctl_get_module_type}, {"disassoc_reason", hgicf_ioctl_get_disassoc_reason}, {"ant_sel", hgicf_ioctl_get_ant_sel}, {NULL,} }; int hgicf_ioctl_get_proc(struct net_device *dev, struct iwreq *wrqin) { int ret = 0; char field[64]; struct hgpriv_get *get = NULL; ret = hgicf_copyfrom_iwreq(wrqin, field, 64); for (get = hgpriv_gets; !ret && get->name; get++) { if (strcmp(field, get->name) == 0) { return get->get(dev, wrqin); } } hgic_dbg("not support:%s\r\n", field); return -ENOTSUPP; } int hgicf_ioctl_stat(struct net_device *dev, struct iwreq *wrqin) { //struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); return 0; } int hgicf_ioctl_e2p(struct net_device *dev, struct iwreq *wrqin) { //struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); return 0; } int hgicf_ioctl_savecfg(struct net_device *dev, struct iwreq *wrqin) { struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); return hgic_fwctrl_save_cfg(&(vif->hg->ctrl)); } int hgicf_ioctl_scan(struct net_device *dev, struct iwreq *wrqin) { struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); return hgic_fwctrl_scan(&(vif->hg->ctrl)); }