0
0
Fork 0
hgicf/hgic_fmac/cfg.c

1178 lines
37 KiB
C

#include <linux/version.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/net.h>
#include <linux/etherdevice.h>
#include <linux/wireless.h>
#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));
}